diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index e747f17fa6d..7e3ca9a9a3e 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -489,10 +489,18 @@ static int spi_stm32_configure(const struct device *dev, #endif } - if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t) &cfg->pclken, &clock) < 0) { - LOG_ERR("Failed call clock_control_get_rate"); - return -EIO; + if (IS_ENABLED(STM32_SPI_OPT_CLOCK_SUPPORT) && (cfg->pclk_len > 1)) { + if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &cfg->pclken[1], &clock) < 0) { + LOG_ERR("Failed call clock_control_get_rate(pclk[1])"); + return -EIO; + } + } else { + if (clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &cfg->pclken[0], &clock) < 0) { + LOG_ERR("Failed call clock_control_get_rate(pclk[0])"); + return -EIO; + } } for (br = 1 ; br <= ARRAY_SIZE(scaler) ; ++br) { @@ -860,10 +868,21 @@ static int spi_stm32_init(const struct device *dev) const struct spi_stm32_config *cfg = dev->config; int err; - if (clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t) &cfg->pclken) != 0) { + err = clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &cfg->pclken[0]); + if (err < 0) { LOG_ERR("Could not enable SPI clock"); - return -EIO; + return err; + } + + if (IS_ENABLED(STM32_SPI_OPT_CLOCK_SUPPORT) && (cfg->pclk_len > 1)) { + err = clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t) &cfg->pclken[1], + NULL); + if (err < 0) { + LOG_ERR("Could not select SPI source clock"); + return err; + } } if (!spi_stm32_is_subghzspi(dev)) { @@ -971,17 +990,20 @@ static void spi_stm32_irq_config_func_##id(const struct device *dev) \ #define STM32_SPI_USE_SUBGHZSPI_NSS_CONFIG(id) #endif + + #define STM32_SPI_INIT(id) \ STM32_SPI_IRQ_HANDLER_DECL(id); \ \ PINCTRL_DT_INST_DEFINE(id); \ \ +static const struct stm32_pclken pclken_##id[] = \ + STM32_DT_INST_CLOCKS(id);\ + \ static const struct spi_stm32_config spi_stm32_cfg_##id = { \ .spi = (SPI_TypeDef *) DT_INST_REG_ADDR(id), \ - .pclken = { \ - .enr = DT_INST_CLOCKS_CELL(id, bits), \ - .bus = DT_INST_CLOCKS_CELL(id, bus) \ - }, \ + .pclken = pclken_##id, \ + .pclk_len = DT_INST_NUM_CLOCKS(id), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(id), \ STM32_SPI_IRQ_HANDLER_FUNC(id) \ STM32_SPI_USE_SUBGHZSPI_NSS_CONFIG(id) \ diff --git a/drivers/spi/spi_ll_stm32.h b/drivers/spi/spi_ll_stm32.h index 7d8206ee333..969c0b9624c 100644 --- a/drivers/spi/spi_ll_stm32.h +++ b/drivers/spi/spi_ll_stm32.h @@ -11,8 +11,15 @@ typedef void (*irq_config_func_t)(const struct device *port); +/* This symbol takes the value 1 if one of the device instances */ +/* is configured in dts with an optional clock */ +#if STM32_DT_INST_DEV_OPT_CLOCK_SUPPORT +#define STM32_SPI_OPT_CLOCK_SUPPORT 1 +#else +#define STM32_SPI_OPT_CLOCK_SUPPORT 0 +#endif + struct spi_stm32_config { - struct stm32_pclken pclken; SPI_TypeDef *spi; const struct pinctrl_dev_config *pcfg; #ifdef CONFIG_SPI_STM32_INTERRUPT @@ -21,6 +28,8 @@ struct spi_stm32_config { #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_spi_subghz) bool use_subghzspi_nss; #endif + size_t pclk_len; + const struct stm32_pclken *pclken; }; #ifdef CONFIG_SPI_STM32_DMA