drivers: adc: stm32: use dts to set the clock prescaler

Now that everything is in place, the prescaler value picked from dts is
used to properly configure the clock.
The code is moved into its own function.
There are four main cases:
- F1 and F37x don't have prescaler (in ADC register) so nothing is done.
- F0 only has individual registers.
- C0, G0, L0, WB1x and WL have both invidual and common registers. The
  individual one is used to define either synchronous mode with its
  prescaler, or asynchronous mode. The common one is only used to store
  the value of the asynchronous prescaler.
- All others only have a common register where both the mode and the
  prescaler is stored.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
This commit is contained in:
Guillaume Gautier 2023-06-23 17:14:54 +02:00 committed by Fabio Baltieri
commit 484028306d

View file

@ -1217,6 +1217,37 @@ static int adc_stm32_channel_setup(const struct device *dev,
return 0;
}
static int adc_stm32_set_clock(const struct device *dev)
{
const struct adc_stm32_cfg *config = dev->config;
ADC_TypeDef *adc = (ADC_TypeDef *)config->base;
ARG_UNUSED(adc); /* Necessary to avoid warnings on some series */
#if defined(CONFIG_SOC_SERIES_STM32F0X)
LL_ADC_SetClock(adc, config->clk_prescaler);
#elif defined(CONFIG_SOC_SERIES_STM32C0X) || \
defined(CONFIG_SOC_SERIES_STM32G0X) || \
defined(CONFIG_SOC_SERIES_STM32L0X) || \
(defined(CONFIG_SOC_SERIES_STM32WBX) && defined(ADC_SUPPORT_2_5_MSPS)) || \
defined(CONFIG_SOC_SERIES_STM32WLX)
if ((config->clk_prescaler == LL_ADC_CLOCK_SYNC_PCLK_DIV1) ||
(config->clk_prescaler == LL_ADC_CLOCK_SYNC_PCLK_DIV2) ||
(config->clk_prescaler == LL_ADC_CLOCK_SYNC_PCLK_DIV4)) {
LL_ADC_SetClock(adc, config->clk_prescaler);
} else {
LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(adc),
config->clk_prescaler);
LL_ADC_SetClock(adc, LL_ADC_CLOCK_ASYNC);
}
#elif !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc)
LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(adc),
config->clk_prescaler);
#endif
return 0;
}
static int adc_stm32_init(const struct device *dev)
{
struct adc_stm32_data *data = dev->data;
@ -1250,6 +1281,8 @@ static int adc_stm32_init(const struct device *dev)
return -EIO;
}
adc_stm32_set_clock(dev);
/* Configure dt provided device signals when available */
err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
if (err < 0) {
@ -1298,38 +1331,6 @@ static int adc_stm32_init(const struct device *dev)
k_busy_wait(LL_ADC_DELAY_INTERNAL_REGUL_STAB_US);
#endif
#if defined(CONFIG_SOC_SERIES_STM32F0X) || \
defined(CONFIG_SOC_SERIES_STM32L0X) || \
defined(CONFIG_SOC_SERIES_STM32WLX)
LL_ADC_SetClock(adc, LL_ADC_CLOCK_SYNC_PCLK_DIV4);
#elif defined(CONFIG_SOC_SERIES_STM32C0X) || \
defined(CONFIG_SOC_SERIES_STM32L4X) || \
defined(CONFIG_SOC_SERIES_STM32L5X) || \
defined(CONFIG_SOC_SERIES_STM32WBX) || \
defined(CONFIG_SOC_SERIES_STM32G0X) || \
defined(CONFIG_SOC_SERIES_STM32G4X) || \
defined(CONFIG_SOC_SERIES_STM32H7X)
LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(adc),
LL_ADC_CLOCK_SYNC_PCLK_DIV4);
#elif defined(CONFIG_SOC_SERIES_STM32H5X)
LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(adc),
LL_ADC_CLOCK_ASYNC_DIV6);
#elif defined(STM32F3X_ADC_V1_1)
/*
* Set the synchronous clock mode to HCLK/1 (DIV1) or HCLK/2 (DIV2)
* Both are valid common clock setting values.
* The HCLK/1(DIV1) is possible only if
* the ahb-prescaler = <1> in the RCC_CFGR.
*/
LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(adc),
LL_ADC_CLOCK_SYNC_PCLK_DIV2);
#elif defined(CONFIG_SOC_SERIES_STM32L1X) || \
defined(CONFIG_SOC_SERIES_STM32U5X) || \
defined(CONFIG_SOC_SERIES_STM32WBAX)
LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(adc),
LL_ADC_CLOCK_ASYNC_DIV4);
#endif
#if defined(HAS_CALIBRATION) && !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc)
adc_stm32_disable(adc);
adc_stm32_calib(dev);