drivers/spi: stm32: Use alt clock freq if available

Add support for an alternate clock. If available,
alternate clock is enabled and used to get the
device clock rate.

Fixes #41650

Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
This commit is contained in:
Erwan Gouriou 2022-01-31 15:53:07 +01:00 committed by Carles Cufí
parent 3f503e87cc
commit 0b65c1c619
2 changed files with 43 additions and 12 deletions

View file

@ -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) \

View file

@ -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