drivers: pwm: stm32: add support for pinmux
Add support for DT based pinmux configurations. Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
This commit is contained in:
parent
aa45e0a90c
commit
af1b9442ca
2 changed files with 167 additions and 1 deletions
|
@ -16,6 +16,7 @@
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
|
|
||||||
#include <drivers/clock_control/stm32_clock_control.h>
|
#include <drivers/clock_control/stm32_clock_control.h>
|
||||||
|
#include <pinmux/stm32/pinmux_stm32.h>
|
||||||
|
|
||||||
#include <logging/log.h>
|
#include <logging/log.h>
|
||||||
LOG_MODULE_REGISTER(pwm_stm32, CONFIG_PWM_LOG_LEVEL);
|
LOG_MODULE_REGISTER(pwm_stm32, CONFIG_PWM_LOG_LEVEL);
|
||||||
|
@ -34,6 +35,10 @@ struct pwm_stm32_config {
|
||||||
uint32_t prescaler;
|
uint32_t prescaler;
|
||||||
/** Clock configuration. */
|
/** Clock configuration. */
|
||||||
struct stm32_pclken pclken;
|
struct stm32_pclken pclken;
|
||||||
|
/** pinctrl configurations. */
|
||||||
|
const struct soc_gpio_pinctrl *pinctrl;
|
||||||
|
/** Number of pinctrl configurations. */
|
||||||
|
size_t pinctrl_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Series F3, F7, G0, G4, H7, L4, MP1 and WB have up to 6 channels, others up
|
/** Series F3, F7, G0, G4, H7, L4, MP1 and WB have up to 6 channels, others up
|
||||||
|
@ -276,6 +281,153 @@ static int pwm_stm32_init(const struct device *dev)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* configure pinmux */
|
||||||
|
if (cfg->pinctrl_len != 0U) {
|
||||||
|
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl)
|
||||||
|
/* apply F1 series remaps */
|
||||||
|
int remap;
|
||||||
|
|
||||||
|
remap = stm32_dt_pinctrl_remap_check(cfg->pinctrl,
|
||||||
|
cfg->pinctrl_len);
|
||||||
|
if (remap < 0) {
|
||||||
|
LOG_ERR("pinctrl remap check failed (%d)", remap);
|
||||||
|
return remap;
|
||||||
|
}
|
||||||
|
|
||||||
|
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);
|
||||||
|
|
||||||
|
switch ((uint32_t)cfg->timer) {
|
||||||
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers1), okay)
|
||||||
|
case DT_REG_ADDR(DT_NODELABEL(timers1)):
|
||||||
|
if (remap == REMAP_1) {
|
||||||
|
LL_GPIO_AF_RemapPartial_TIM1();
|
||||||
|
} else if (remap == REMAP_FULL) {
|
||||||
|
LL_GPIO_AF_EnableRemap_TIM1();
|
||||||
|
} else {
|
||||||
|
LL_GPIO_AF_DisableRemap_TIM1();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers2), okay)
|
||||||
|
case DT_REG_ADDR(DT_NODELABEL(timers2)):
|
||||||
|
if (remap == REMAP_1) {
|
||||||
|
LL_GPIO_AF_RemapPartial1_TIM2();
|
||||||
|
} else if (remap == REMAP_2) {
|
||||||
|
LL_GPIO_AF_RemapPartial2_TIM2();
|
||||||
|
} else if (remap == REMAP_FULL) {
|
||||||
|
LL_GPIO_AF_EnableRemap_TIM2();
|
||||||
|
} else {
|
||||||
|
LL_GPIO_AF_DisableRemap_TIM2();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers3), okay)
|
||||||
|
case DT_REG_ADDR(DT_NODELABEL(timers3)):
|
||||||
|
if (remap == REMAP_1) {
|
||||||
|
LL_GPIO_AF_RemapPartial_TIM3();
|
||||||
|
} else if (remap == REMAP_FULL) {
|
||||||
|
LL_GPIO_AF_EnableRemap_TIM3();
|
||||||
|
} else {
|
||||||
|
LL_GPIO_AF_DisableRemap_TIM3();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers4), okay)
|
||||||
|
case DT_REG_ADDR(DT_NODELABEL(timers4)):
|
||||||
|
if (remap == REMAP_FULL) {
|
||||||
|
LL_GPIO_AF_EnableRemap_TIM4();
|
||||||
|
} else {
|
||||||
|
LL_GPIO_AF_DisableRemap_TIM4();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers9), okay)
|
||||||
|
case DT_REG_ADDR(DT_NODELABEL(timers9)):
|
||||||
|
if (remap == REMAP_FULL) {
|
||||||
|
LL_GPIO_AF_EnableRemap_TIM9();
|
||||||
|
} else {
|
||||||
|
LL_GPIO_AF_DisableRemap_TIM9();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers10), okay)
|
||||||
|
case DT_REG_ADDR(DT_NODELABEL(timers10)):
|
||||||
|
if (remap == REMAP_FULL) {
|
||||||
|
LL_GPIO_AF_EnableRemap_TIM10();
|
||||||
|
} else {
|
||||||
|
LL_GPIO_AF_DisableRemap_TIM10();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers11), okay)
|
||||||
|
case DT_REG_ADDR(DT_NODELABEL(timers11)):
|
||||||
|
if (remap == REMAP_FULL) {
|
||||||
|
LL_GPIO_AF_EnableRemap_TIM11();
|
||||||
|
} else {
|
||||||
|
LL_GPIO_AF_DisableRemap_TIM11();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers12), okay)
|
||||||
|
case DT_REG_ADDR(DT_NODELABEL(timers12)):
|
||||||
|
if (remap == REMAP_FULL) {
|
||||||
|
LL_GPIO_AF_EnableRemap_TIM12();
|
||||||
|
} else {
|
||||||
|
LL_GPIO_AF_DisableRemap_TIM12();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers13), okay)
|
||||||
|
case DT_REG_ADDR(DT_NODELABEL(timers13)):
|
||||||
|
if (remap == REMAP_FULL) {
|
||||||
|
LL_GPIO_AF_EnableRemap_TIM13();
|
||||||
|
} else {
|
||||||
|
LL_GPIO_AF_DisableRemap_TIM13();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers14), okay)
|
||||||
|
case DT_REG_ADDR(DT_NODELABEL(timers14)):
|
||||||
|
if (remap == REMAP_FULL) {
|
||||||
|
LL_GPIO_AF_EnableRemap_TIM14();
|
||||||
|
} else {
|
||||||
|
LL_GPIO_AF_DisableRemap_TIM14();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers15), okay)
|
||||||
|
case DT_REG_ADDR(DT_NODELABEL(timers15)):
|
||||||
|
if (remap == REMAP_FULL) {
|
||||||
|
LL_GPIO_AF_EnableRemap_TIM15();
|
||||||
|
} else {
|
||||||
|
LL_GPIO_AF_DisableRemap_TIM15();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers16), okay)
|
||||||
|
case DT_REG_ADDR(DT_NODELABEL(timers16)):
|
||||||
|
if (remap == REMAP_FULL) {
|
||||||
|
LL_GPIO_AF_EnableRemap_TIM16();
|
||||||
|
} else {
|
||||||
|
LL_GPIO_AF_DisableRemap_TIM16();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(timers17), okay)
|
||||||
|
case DT_REG_ADDR(DT_NODELABEL(timers17)):
|
||||||
|
if (remap == REMAP_FULL) {
|
||||||
|
LL_GPIO_AF_EnableRemap_TIM17();
|
||||||
|
} else {
|
||||||
|
LL_GPIO_AF_DisableRemap_TIM17();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl) */
|
||||||
|
|
||||||
|
stm32_dt_pinctrl_configure(cfg->pinctrl, cfg->pinctrl_len);
|
||||||
|
}
|
||||||
|
|
||||||
/* initialize timer */
|
/* initialize timer */
|
||||||
LL_TIM_StructInit(&init);
|
LL_TIM_StructInit(&init);
|
||||||
|
|
||||||
|
@ -308,11 +460,16 @@ static int pwm_stm32_init(const struct device *dev)
|
||||||
#define PWM_DEVICE_INIT(index) \
|
#define PWM_DEVICE_INIT(index) \
|
||||||
static struct pwm_stm32_data pwm_stm32_data_##index; \
|
static struct pwm_stm32_data pwm_stm32_data_##index; \
|
||||||
\
|
\
|
||||||
|
static const struct soc_gpio_pinctrl pwm_pins_##index[] = \
|
||||||
|
ST_STM32_DT_PINCTRL(0, index); \
|
||||||
|
\
|
||||||
static const struct pwm_stm32_config pwm_stm32_config_##index = { \
|
static const struct pwm_stm32_config pwm_stm32_config_##index = { \
|
||||||
.timer = (TIM_TypeDef *)DT_REG_ADDR( \
|
.timer = (TIM_TypeDef *)DT_REG_ADDR( \
|
||||||
DT_INST(index, st_stm32_timers)), \
|
DT_INST(index, st_stm32_timers)), \
|
||||||
.prescaler = DT_INST_PROP(index, st_prescaler), \
|
.prescaler = DT_INST_PROP(index, st_prescaler), \
|
||||||
.pclken = DT_INST_CLK(index, timer) \
|
.pclken = DT_INST_CLK(index, timer), \
|
||||||
|
.pinctrl = pwm_pins_##index, \
|
||||||
|
.pinctrl_len = ARRAY_SIZE(pwm_pins_##index), \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
DEVICE_AND_API_INIT(pwm_stm32_##index, DT_INST_LABEL(index), \
|
DEVICE_AND_API_INIT(pwm_stm32_##index, DT_INST_LABEL(index), \
|
||||||
|
|
|
@ -13,6 +13,15 @@ properties:
|
||||||
required: true
|
required: true
|
||||||
description: Clock prescaler at the input of the timer
|
description: Clock prescaler at the input of the timer
|
||||||
|
|
||||||
|
pinctrl-0:
|
||||||
|
type: phandles
|
||||||
|
required: false
|
||||||
|
description: |
|
||||||
|
GPIO pin configuration for PWM signal/s. We expect that the phandles
|
||||||
|
will reference pinctrl nodes, e.g.
|
||||||
|
|
||||||
|
pinctrl-0 = <&tim1_ch1_pwm_pa8 &tim1_ch2_pwm_pa9>;
|
||||||
|
|
||||||
"#pwm-cells":
|
"#pwm-cells":
|
||||||
const: 3
|
const: 3
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue