It is very common to have an STB pin in CAN transceivers, which allows putting the transceiver in standby or normal operation mode. Add support for handling the STB pin. Signed-off-by: Fabio Estevam <festevam@xxxxxxxxx> --- drivers/net/can/flexcan.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 038fe1036df2..094050b4b461 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -17,6 +17,7 @@ #include <linux/can/rx-offload.h> #include <linux/clk.h> #include <linux/delay.h> +#include <linux/gpio/consumer.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/mfd/syscon.h> @@ -358,6 +359,8 @@ struct flexcan_priv { struct regulator *reg_xceiver; struct flexcan_stop_mode stm; + struct gpio_desc *stb; + /* Read and Write APIs */ u32 (*read)(void __iomem *addr); void (*write)(u32 val, void __iomem *addr); @@ -617,6 +620,8 @@ static void flexcan_clks_disable(const struct flexcan_priv *priv) static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv) { + gpiod_set_value_cansleep(priv->stb, 0); + if (!priv->reg_xceiver) return 0; @@ -625,6 +630,8 @@ static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv) static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv) { + gpiod_set_value_cansleep(priv->stb, 1); + if (!priv->reg_xceiver) return 0; @@ -2044,6 +2051,10 @@ static int flexcan_probe(struct platform_device *pdev) priv->can.bittiming_const = &flexcan_bittiming_const; } + priv->stb = devm_gpiod_get_optional(&pdev->dev, "stb", GPIOD_OUT_HIGH); + if (IS_ERR(priv->stb)) + return PTR_ERR(priv->stb); + pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); -- 2.17.1