drivers: adc: Simplify STM32 ADC channels setup

Now that we have the information of internal channel number for STM32
ADCs in the dts, we can use it to remove a lot of specific code and
make it clearer.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
This commit is contained in:
Guillaume Gautier 2023-01-17 16:33:02 +01:00 committed by Fabio Baltieri
commit 9c6d44ef5a

View file

@ -271,6 +271,9 @@ struct adc_stm32_cfg {
bool has_temp_channel;
bool has_vref_channel;
bool has_vbat_channel;
int8_t temp_channel;
int8_t vref_channel;
int8_t vbat_channel;
};
#ifdef CONFIG_ADC_STM32_SHARED_IRQS
@ -544,78 +547,26 @@ static void adc_stm32_setup_channel(const struct device *dev, uint8_t channel_id
const struct adc_stm32_cfg *config = dev->config;
ADC_TypeDef *adc = (ADC_TypeDef *)config->base;
#ifdef CONFIG_SOC_SERIES_STM32G4X
if (config->has_temp_channel) {
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay)
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR_ADC1) == channel_id)
&& (config->base == ADC1)) {
adc_stm32_disable(adc);
adc_stm32_set_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
k_usleep(LL_ADC_DELAY_TEMPSENSOR_STAB_US);
}
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc5), okay)
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR_ADC5) == channel_id)
&& (config->base == ADC5)) {
adc_stm32_disable(adc);
adc_stm32_set_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
k_usleep(LL_ADC_DELAY_TEMPSENSOR_STAB_US);
}
#endif
}
#elif CONFIG_SOC_SERIES_STM32U5X
if (config->has_temp_channel) {
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay)
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR) == channel_id)
&& (config->base == ADC1)) {
adc_stm32_disable(adc);
adc_stm32_set_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
/* Wait for the sensor stabilization */
k_usleep(LL_ADC_DELAY_TEMPSENSOR_STAB_US);
}
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc4), okay)
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR_ADC4) == channel_id)
&& (config->base == ADC4)) {
adc_stm32_disable(adc);
adc_stm32_set_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
LL_ADC_SetCommonPathInternalChAdd(__LL_ADC_COMMON_INSTANCE(adc),
LL_ADC_PATH_INTERNAL_TEMPSENSOR);
/* Wait for the sensor stabilization */
k_usleep(LL_ADC_DELAY_TEMPSENSOR_STAB_US);
}
#endif
}
#else
if (config->has_temp_channel &&
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR) == channel_id)) {
if (config->temp_channel == channel_id) {
adc_stm32_disable(adc);
adc_stm32_set_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
#ifdef LL_ADC_DELAY_TEMPSENSOR_STAB_US
k_usleep(LL_ADC_DELAY_TEMPSENSOR_STAB_US);
#endif
}
#endif /* CONFIG_SOC_SERIES_STM32G4X */
if (config->has_vref_channel &&
__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_VREFINT) == channel_id) {
if (config->vref_channel == channel_id) {
adc_stm32_disable(adc);
adc_stm32_set_common_path(dev, LL_ADC_PATH_INTERNAL_VREFINT);
#ifdef LL_ADC_DELAY_VREFINT_STAB_US
k_usleep(LL_ADC_DELAY_VREFINT_STAB_US);
#endif
}
#if defined(LL_ADC_CHANNEL_VBAT)
/* Enable the bridge divider only when needed for ADC conversion. */
if (config->has_vbat_channel && (
#if defined(LL_ADC_CHANNEL_VBAT_ADC4)
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_VBAT_ADC4) == channel_id) ||
#endif /* LL_ADC_CHANNEL_VBAT_ADC4 */
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_VBAT) == channel_id))) {
if (config->vbat_channel == channel_id) {
adc_stm32_disable(adc);
adc_stm32_set_common_path(dev, LL_ADC_PATH_INTERNAL_VBAT);
}
#endif /* LL_ADC_CHANNEL_VBAT */
}
@ -640,64 +591,19 @@ static void adc_stm32_teardown_channels(const struct device *dev)
for (uint32_t channels = data->channels; channels; channels &= ~BIT(channel_id)) {
channel_id = find_lsb_set(channels) - 1;
#ifdef CONFIG_SOC_SERIES_STM32G4X
if (config->has_temp_channel) {
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay)
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR_ADC1) ==
channel_id) &&
(config->base == ADC1)) {
adc_stm32_disable(adc);
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
}
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc5), okay)
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR_ADC5) ==
channel_id) &&
(config->base == ADC5)) {
adc_stm32_disable(adc);
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
}
#endif
}
#elif CONFIG_SOC_SERIES_STM32U5X
if (config->has_temp_channel) {
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay)
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR) ==
channel_id) &&
(config->base == ADC1)) {
adc_stm32_disable(adc);
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
}
#endif
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc4), okay)
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR_ADC4) ==
channel_id) &&
(config->base == ADC4)) {
adc_stm32_disable(adc);
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
}
#endif
}
#else
if (config->has_temp_channel &&
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR) == channel_id)) {
if (config->temp_channel == channel_id) {
adc_stm32_disable(adc);
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
}
#endif /* CONFIG_SOC_SERIES_STM32G4X */
if (config->has_vref_channel &&
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_VREFINT) == channel_id)) {
if (config->vref_channel == channel_id) {
adc_stm32_disable(adc);
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_VREFINT);
}
#if defined(LL_ADC_CHANNEL_VBAT)
/* Enable the bridge divider only when needed for ADC conversion. */
if (config->has_vbat_channel && (
#if defined(LL_ADC_CHANNEL_VBAT_ADC4)
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_VBAT_ADC4) == channel_id) ||
#endif /* LL_ADC_CHANNEL_VBAT_ADC4 */
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_VBAT) == channel_id))) {
if (config->vbat_channel == channel_id) {
adc_stm32_disable(adc);
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_VBAT);
}
@ -1494,6 +1400,9 @@ static const struct adc_stm32_cfg adc_stm32_cfg_##index = { \
.has_temp_channel = DT_INST_PROP(index, has_temp_channel), \
.has_vref_channel = DT_INST_PROP(index, has_vref_channel), \
.has_vbat_channel = DT_INST_PROP(index, has_vbat_channel), \
.temp_channel = DT_INST_PROP_OR(index, temp_channel, 0xFF), \
.vref_channel = DT_INST_PROP_OR(index, vref_channel, 0xFF), \
.vbat_channel = DT_INST_PROP_OR(index, vbat_channel, 0xFF), \
}; \
\
static struct adc_stm32_data adc_stm32_data_##index = { \