From 109a624c85d3d35d4d3cbaae5d0968a465fb676b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Fri, 9 Oct 2020 10:54:44 +0200 Subject: [PATCH] drivers: can: stm32: add support for pinmux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for DT based pinmux configurations. Signed-off-by: Martin Jäger --- drivers/can/can_stm32.c | 62 +++++++++++++++++++++++++++++- drivers/can/can_stm32.h | 2 + dts/bindings/can/st,stm32-can.yaml | 9 +++++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/drivers/can/can_stm32.c b/drivers/can/can_stm32.c index a8b3943a3e9..a4d6d5fdfcb 100644 --- a/drivers/can/can_stm32.c +++ b/drivers/can/can_stm32.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -409,6 +410,53 @@ static int can_stm32_init(const struct device *dev) return -EIO; } + /* configure pinmux */ + if (cfg->pinctrl_len != 0U) { +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl) + int remap; + /* Check that remap configuration is coherent across pins */ + remap = stm32_dt_pinctrl_remap_check(cfg->pinctrl, + cfg->pinctrl_len); + if (remap < 0) { + return remap; + } + + /* A valid remapping configuration is provided */ + /* Apply remapping before proceeding with pin configuration */ + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO); + + switch ((uint32_t)cfg->can) { +#if defined(AFIO_MAPR_CAN_REMAP_REMAP1) + case DT_REG_ADDR(DT_NODELABEL(can1)): + if (remap == REMAP_1) { + /* PB8/PB9 */ + LL_GPIO_AF_RemapPartial2_CAN1(); + } else if (remap == REMAP_2) { + /* PD0/PD1 */ + LL_GPIO_AF_RemapPartial3_CAN1(); + } else { + /* NO_REMAP: PA11/PA12 */ + LL_GPIO_AF_RemapPartial1_CAN1(); + } + break; +#endif +#if defined(AFIO_MAPR_CAN2_REMAP) + case DT_REG_ADDR(DT_NODELABEL(can2)): + if (remap == REMAP_1) { + /* PB5/PB6 */ + LL_GPIO_AF_EnableRemap_CAN2(); + } else { + /* PB12/PB13 */ + LL_GPIO_AF_DisableRemap_CAN2(); + } + break; +#endif + } +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl) */ + + stm32_dt_pinctrl_configure(cfg->pinctrl, cfg->pinctrl_len); + } + ret = can_leave_sleep_mode(can); if (ret) { LOG_ERR("Failed to exit sleep mode"); @@ -1042,6 +1090,9 @@ static const struct can_driver_api can_api_funcs = { static void config_can_1_irq(CAN_TypeDef *can); +static const struct soc_gpio_pinctrl pins_can_1[] = + ST_STM32_DT_PINCTRL(can1, 0); + static const struct can_stm32_config can_stm32_cfg_1 = { .can = (CAN_TypeDef *)DT_REG_ADDR(DT_NODELABEL(can1)), .master_can = (CAN_TypeDef *)DT_REG_ADDR(DT_NODELABEL(can1)), @@ -1054,7 +1105,9 @@ static const struct can_stm32_config can_stm32_cfg_1 = { .enr = DT_CLOCKS_CELL(DT_NODELABEL(can1), bits), .bus = DT_CLOCKS_CELL(DT_NODELABEL(can1), bus), }, - .config_irq = config_can_1_irq + .config_irq = config_can_1_irq, + .pinctrl = pins_can_1, + .pinctrl_len = ARRAY_SIZE(pins_can_1) }; static struct can_stm32_data can_stm32_dev_data_1; @@ -1131,6 +1184,9 @@ NET_DEVICE_INIT(socket_can_stm32_1, SOCKET_CAN_NAME_1, socket_can_init_1, static void config_can_2_irq(CAN_TypeDef *can); +static const struct soc_gpio_pinctrl pins_can_2[] = + ST_STM32_DT_PINCTRL(can2, 0); + static const struct can_stm32_config can_stm32_cfg_2 = { .can = (CAN_TypeDef *)DT_REG_ADDR(DT_NODELABEL(can2)), .master_can = (CAN_TypeDef *)DT_PROP(DT_NODELABEL(can2), @@ -1144,7 +1200,9 @@ static const struct can_stm32_config can_stm32_cfg_2 = { .enr = DT_CLOCKS_CELL(DT_NODELABEL(can2), bits), .bus = DT_CLOCKS_CELL(DT_NODELABEL(can2), bus), }, - .config_irq = config_can_2_irq + .config_irq = config_can_2_irq, + .pinctrl = pins_can_2, + .pinctrl_len = ARRAY_SIZE(pins_can_2) }; static struct can_stm32_data can_stm32_dev_data_2; diff --git a/drivers/can/can_stm32.h b/drivers/can/can_stm32.h index 9fa58c04741..cae25fa0893 100644 --- a/drivers/can/can_stm32.h +++ b/drivers/can/can_stm32.h @@ -76,6 +76,8 @@ struct can_stm32_config { uint8_t ts2; struct stm32_pclken pclken; void (*config_irq)(CAN_TypeDef *can); + const struct soc_gpio_pinctrl *pinctrl; + size_t pinctrl_len; }; #endif /*ZEPHYR_DRIVERS_CAN_STM32_CAN_H_*/ diff --git a/dts/bindings/can/st,stm32-can.yaml b/dts/bindings/can/st,stm32-can.yaml index cb5293826ae..0d018bd6f87 100644 --- a/dts/bindings/can/st,stm32-can.yaml +++ b/dts/bindings/can/st,stm32-can.yaml @@ -14,6 +14,15 @@ properties: clocks: required: true + pinctrl-0: + type: phandles + required: false + description: | + GPIO pin configuration for CAN RX and TX. The phandles are + expected to reference pinctrl nodes, e.g. + + pinctrl-0 = <&can1_rx_pa11 &can1_tx_pa12>; + master-can-reg: type: int required: false