Skip to content

Commit

Permalink
drivers: adc: stm32: use dts to set the clock prescaler
Browse files Browse the repository at this point in the history
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.

(cherry picked from commit 4840283)

Original-Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
GitOrigin-RevId: 4840283
Change-Id: Ibd2e89f5f852dc9e13bc41be7253a0b6b32f8966
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/zephyr/+/4822199
Tested-by: ChromeOS Prod (Robot) <chromeos-ci-prod@chromeos-bot.iam.gserviceaccount.com>
Tested-by: Yuval Peress <peress@google.com>
Reviewed-by: Yuval Peress <peress@google.com>
Commit-Queue: Yuval Peress <peress@google.com>
  • Loading branch information
gautierg-st authored and Chromeos LUCI committed Aug 29, 2023
1 parent 3bc69a1 commit cdbaa5f
Showing 1 changed file with 33 additions and 32 deletions.
65 changes: 33 additions & 32 deletions drivers/adc/adc_stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit cdbaa5f

Please sign in to comment.