Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions boards/st/nucleo_c031c6/nucleo_c031c6.dts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
&adc1 {
clocks = <&rcc STM32_CLOCK(APB1_2, 20)>,
<&rcc STM32_SRC_SYSCLK ADC_SEL(0)>;
clock-names = "adcx", "adc_ker";
pinctrl-0 = <&adc1_in0_pa0 &adc1_in1_pa1 &adc1_in4_pa4>;
pinctrl-names = "default";
st,adc-clock-source = "ASYNC";
Expand Down
1 change: 1 addition & 0 deletions boards/st/nucleo_c071rb/nucleo_c071rb.dts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
st,adc-clock-source = "ASYNC";
clocks = <&rcc STM32_CLOCK(APB1_2, 20)>,
<&rcc STM32_SRC_HSI ADC_SEL(2)>;
clock-names = "adcx", "adc_ker";
st,adc-prescaler = <4>;
status = "okay";
vref-mv = <3300>;
Expand Down
1 change: 1 addition & 0 deletions boards/st/nucleo_c092rc/nucleo_c092rc.dts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@
st,adc-clock-source = "ASYNC";
clocks = <&rcc STM32_CLOCK(APB1_2, 20)>,
<&rcc STM32_SRC_HSI ADC_SEL(2)>;
clock-names = "adcx", "adc_ker";
st,adc-prescaler = <4>;
status = "okay";
vref-mv = <3300>;
Expand Down
1 change: 0 additions & 1 deletion boards/st/nucleo_f103rb/nucleo_f103rb.dts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@
ahb-prescaler = <1>;
apb1-prescaler = <2>;
apb2-prescaler = <1>;
adc-prescaler = <2>;
};

&usart1 {
Expand Down
1 change: 0 additions & 1 deletion boards/st/nucleo_f303k8/nucleo_f303k8.dts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
ahb-prescaler = <1>;
apb1-prescaler = <2>;
apb2-prescaler = <1>;
adc12-prescaler = <0>;
};

&timers2 {
Expand Down
2 changes: 0 additions & 2 deletions boards/st/nucleo_f303re/nucleo_f303re.dts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@
ahb-prescaler = <1>;
apb1-prescaler = <2>;
apb2-prescaler = <1>;
adc12-prescaler = <0>;
adc34-prescaler = <0>;
};

&usart2 {
Expand Down
1 change: 1 addition & 0 deletions boards/st/nucleo_g071rb/nucleo_g071rb.dts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
&adc1 {
clocks = <&rcc STM32_CLOCK(APB1_2, 20)>,
<&rcc STM32_SRC_SYSCLK ADC_SEL(0)>;
clock-names = "adcx", "adc_ker";
pinctrl-0 = <&adc1_in0_pa0 &adc1_in1_pa1>;
pinctrl-names = "default";
st,adc-clock-source = "ASYNC";
Expand Down
1 change: 1 addition & 0 deletions boards/st/nucleo_h533re/nucleo_h533re.dts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
&adc1 {
clocks = <&rcc STM32_CLOCK(AHB2, 10)>,
<&rcc STM32_SRC_HCLK ADCDAC_SEL(0)>;
clock-names = "adcx", "adc_ker";
pinctrl-0 = <&adc1_inp0_pa0>; /* Arduino A0 */
pinctrl-names = "default";
st,adc-clock-source = "ASYNC";
Expand Down
1 change: 1 addition & 0 deletions boards/st/nucleo_h563zi/nucleo_h563zi-common.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@
&adc1 {
clocks = <&rcc STM32_CLOCK(AHB2, 10)>,
<&rcc STM32_SRC_HCLK ADCDAC_SEL(0)>;
clock-names = "adcx", "adc_ker";
pinctrl-0 = <&adc1_inp3_pa6 &adc1_inp15_pa3>; /* Zio A0, Zio D35 */
pinctrl-names = "default";
st,adc-clock-source = "ASYNC";
Expand Down
5 changes: 3 additions & 2 deletions boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@
#gpio-cells = <2>;
gpio-map-mask = <0xffffffff 0xffffffc0>;
gpio-map-pass-thru = <0 0x3f>;
gpio-map = <CSI_IO0 0 &gpioo 5 0>,
<CSI_IO1 0 &gpioa 0 0>;
gpio-map = <CSI_IO0 0 &gpioo 5 0>,
<CSI_IO1 0 &gpioa 0 0>;
};
};

Expand Down Expand Up @@ -170,6 +170,7 @@
&adc1 {
clocks = <&rcc STM32_CLOCK(AHB1, 5)>,
<&rcc STM32_SRC_CKPER ADC12_SEL(1)>;
clock-names = "adcx", "adc_ker";
pinctrl-0 = <&adc1_inp10_pa9 &adc1_inp11_pa10>; /* Arduino A1 & A2 */
pinctrl-names = "default";
vref-mv = <1800>;
Expand Down
1 change: 1 addition & 0 deletions boards/st/nucleo_u083rc/nucleo_u083rc.dts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
st,adc-clock-source = "ASYNC";
clocks = <&rcc STM32_CLOCK(APB1_2, 20)>,
<&rcc STM32_SRC_HSI ADC_SEL(2)>;
clock-names = "adcx", "adc_ker";
st,adc-prescaler = <4>;
status = "okay";
vref-mv = <3300>;
Expand Down
1 change: 1 addition & 0 deletions boards/st/stm32h573i_dk/stm32h573i_dk-common.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@
&adc1 {
clocks = <&rcc STM32_CLOCK(AHB2, 10)>,
<&rcc STM32_SRC_HCLK ADCDAC_SEL(0)>;
clock-names = "adcx", "adc_ker";
pinctrl-0 = <&adc1_inp6_pf12>; /* Arduino A5 */
pinctrl-names = "default";
st,adc-clock-source = "ASYNC";
Expand Down
1 change: 1 addition & 0 deletions boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@
&adc1 {
clocks = <&rcc STM32_CLOCK(AHB1, 5)>,
<&rcc STM32_SRC_CKPER ADC12_SEL(1)>;
clock-names = "adcx", "adc_ker";
pinctrl-0 = <&adc1_inp10_pa9 &adc1_inp11_pa10>; /* Arduino A1 & A2 */
pinctrl-names = "default";
vref-mv = <1800>;
Expand Down
1 change: 1 addition & 0 deletions boards/st/stm32u083c_dk/stm32u083c_dk.dts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
st,adc-clock-source = "ASYNC";
clocks = <&rcc STM32_CLOCK(APB1_2, 20)>,
<&rcc STM32_SRC_HSI ADC_SEL(2)>;
clock-names = "adcx", "adc_ker";
st,adc-prescaler = <4>;
status = "okay";
vref-mv = <3300>;
Expand Down
1 change: 1 addition & 0 deletions boards/weact/blackpill_h523ce/blackpill_h523ce.dts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ zephyr_udc0: &usb {

&adc1 {
clocks = <&rcc STM32_CLOCK(AHB2, 10)>, <&rcc STM32_SRC_HCLK ADCDAC_SEL(0)>;
clock-names = "adcx", "adc_ker";
pinctrl-0 = <&adc1_inp1_pa1>;
pinctrl-names = "default";
st,adc-clock-source = "ASYNC";
Expand Down
10 changes: 10 additions & 0 deletions doc/releases/migration-guide-4.3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ ADC
* ``iadc_gecko.c`` driver is replaced by ``adc_silabs_iadc.c``.
:dtcompatible:`silabs,gecko-iadc` is replaced by :dtcompatible:`silabs,iadc`.

* :dtcompatible:`st,stm32-adc` and its derivatives now require the ``clock-names`` property to be
defined and to match the number of clocks in the ``clocks`` property. The expected clock names are
``adcx`` for the register clock, ``adc-ker`` for the kernel source clock, and ``adc-pre`` to set
the ADC prescaler (for series where it is located in the RCC registers).

Clock Control
=============

Expand All @@ -104,6 +109,11 @@ Clock Control
is enabled (otherwise, the symbol is not defined). This change should only affect STM32 MPU-based
platforms and aligns them with existing practice from STM32 MCU platforms.

* :dtcompatible:`st,stm32f1-rcc` and :dtcompatible:`st,stm32f3-rcc` do not exist anymore. Therefore
``adc-prescaler``, ``adc12-prescaler`` and ``adc34-prescaler`` properties are no longer defined
either. They are replaced by adding the prescaler as an additional clock in the ADC ``clocks``
property.

Comparator
==========

Expand Down
63 changes: 33 additions & 30 deletions drivers/adc/adc_stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,18 @@ struct adc_stm32_data {
struct adc_stm32_cfg {
ADC_TypeDef *base;
void (*irq_cfg_func)(void);
const struct stm32_pclken *pclken;
size_t pclk_len;
const struct stm32_pclken pclken;
const struct stm32_pclken pclken_ker;
const struct stm32_pclken pclken_pre;
uint32_t clk_prescaler;
const struct pinctrl_dev_config *pcfg;
const uint16_t sampling_time_table[STM32_NB_SAMPLING_TIME];
int8_t num_sampling_time_common_channels;
int8_t sequencer_type;
int8_t oversampler_type;
int8_t internal_regulator;
bool has_pclken_ker :1;
bool has_pclken_pre :1;
bool has_deep_powerdown :1;
bool has_channel_preselection :1;
bool has_differential_support :1;
Expand Down Expand Up @@ -471,8 +474,7 @@ static void adc_stm32_calibration_delay(const struct device *dev)
const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
uint32_t adc_rate, wait_cycles;

if (clock_control_get_rate(clk,
(clock_control_subsys_t) &config->pclken[0], &adc_rate) < 0) {
if (clock_control_get_rate(clk, (clock_control_subsys_t)&config->pclken, &adc_rate) < 0) {
LOG_ERR("ADC clock rate get error.");
}

Expand Down Expand Up @@ -1496,8 +1498,8 @@ static int adc_stm32h7_setup_boost(const struct adc_stm32_cfg *config, ADC_TypeD
int presc;

/* Get the input frequency */
clk_src = (clock_control_subsys_t)(adc_stm32_is_clk_sync(config) ? &config->pclken[0]
: &config->pclken[1]);
clk_src = (clock_control_subsys_t)(adc_stm32_is_clk_sync(config) ? &config->pclken
: &config->pclken_ker);

if (clock_control_get_rate(clk, clk_src, &input_freq) != 0) {
LOG_ERR("Failed to get ADC clock frequency");
Expand Down Expand Up @@ -1534,33 +1536,27 @@ static int adc_stm32h7_setup_boost(const struct adc_stm32_cfg *config, ADC_TypeD
}
#endif

/* This symbol takes the value 1 if one of the device instances */
/* is configured in dts with a domain clock */
#if STM32_DT_INST_DEV_DOMAIN_CLOCK_SUPPORT
#define STM32_ADC_DOMAIN_CLOCK_SUPPORT 1
#else
#define STM32_ADC_DOMAIN_CLOCK_SUPPORT 0
#endif

static int adc_stm32_set_clock(const struct device *dev)
{
const struct adc_stm32_cfg *config = dev->config;
const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
__maybe_unused ADC_TypeDef *adc = config->base;
int ret = 0;

if (clock_control_on(clk,
(clock_control_subsys_t) &config->pclken[0]) != 0) {
if (clock_control_on(clk, (clock_control_subsys_t)&config->pclken) != 0) {
return -EIO;
}

if (IS_ENABLED(STM32_ADC_DOMAIN_CLOCK_SUPPORT) && (config->pclk_len > 1)) {
/* Enable ADC clock source */
if (clock_control_configure(clk,
(clock_control_subsys_t) &config->pclken[1],
NULL) != 0) {
return -EIO;
}
/* Enable ADC clock source if applicable */
if (config->has_pclken_ker &&
clock_control_configure(clk, (clock_control_subsys_t)&config->pclken_ker, NULL) != 0) {
return -EIO;
}

/* Configure ADC prescaler (at RCC level) if applicable */
if (config->has_pclken_pre &&
clock_control_configure(clk, (clock_control_subsys_t)&config->pclken_pre, NULL) != 0) {
return -EIO;
}

#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(st_adc_clock_source)
Expand Down Expand Up @@ -1735,7 +1731,7 @@ static int adc_stm32_suspend_setup(const struct device *dev)
adc_stm32_disable_analog_supply();

/* Stop device clock. Note: fixed clocks are not handled yet. */
err = clock_control_off(clk, (clock_control_subsys_t)&config->pclken[0]);
err = clock_control_off(clk, (clock_control_subsys_t)&config->pclken);
if (err != 0) {
LOG_ERR("Could not disable ADC clock");
return err;
Expand Down Expand Up @@ -1806,7 +1802,7 @@ static DEVICE_API(adc, api_stm32_driver_api) = {

/* Macro to check if the ADC instance clock setup is correct */
#define ADC_STM32_CHECK_DT_CLOCK(x) \
BUILD_ASSERT(IS_EQ(ADC_STM32_CLOCK(x), SYNC) || (DT_INST_NUM_CLOCKS(x) > 1), \
BUILD_ASSERT(IS_EQ(ADC_STM32_CLOCK(x), SYNC) || DT_INST_CLOCKS_HAS_NAME(x, adc_ker), \
"ASYNC clock mode defined without ASYNC clock defined in device tree")

#else /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(st_adc_clock_source) */
Expand Down Expand Up @@ -1963,14 +1959,21 @@ ADC_STM32_CHECK_DT_CLOCK(index); \
\
PINCTRL_DT_INST_DEFINE(index); \
\
static const struct stm32_pclken pclken_##index[] = \
STM32_DT_INST_CLOCKS(index); \
\
static const struct adc_stm32_cfg adc_stm32_cfg_##index = { \
.base = (ADC_TypeDef *)DT_INST_REG_ADDR(index), \
ADC_STM32_IRQ_FUNC(index) \
.pclken = pclken_##index, \
.pclk_len = DT_INST_NUM_CLOCKS(index), \
.pclken = {.bus = DT_INST_CLOCKS_CELL_BY_NAME(index, adcx, bus), \
.enr = DT_INST_CLOCKS_CELL_BY_NAME(index, adcx, bits)}, \
Comment on lines +1965 to +1966
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I would make a STM32-level macro for this. Basically all drivers are "wrong" today (div field left uninitialized) because they don't use the shared macro.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a change for another PR. As you say, all drivers are impacted, so I'm not going to introduce such a change in this one. There are enough as it is.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My 2 cents. div is not left uninitialized, It's 0 which is fine if division is not used (as per the various stm32_clock_control_get_subsys_rate() implemenations), no?
That said, I agree using an STM32 helper macro for these would be worth it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My 2 cents. div is not left uninitialized, It's 0

By uninitialized, I meant that it doesn't take its value from DT 🙂

COND_CODE_1(DT_INST_CLOCKS_HAS_NAME(index, adc_ker), \
(.pclken_ker = {.bus = DT_INST_CLOCKS_CELL_BY_NAME(index, adc_ker, bus), \
.enr = DT_INST_CLOCKS_CELL_BY_NAME(index, adc_ker, bits)}, \
.has_pclken_ker = true,), \
(.has_pclken_ker = false,)) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: could be IF_ENABLED() and leave has_pclken_ker not initialized => default to false.

But I don't mind the extra verbosity.

COND_CODE_1(DT_INST_CLOCKS_HAS_NAME(index, adc_pre), \
(.pclken_pre = {.bus = DT_INST_CLOCKS_CELL_BY_NAME(index, adc_pre, bus), \
.enr = DT_INST_CLOCKS_CELL_BY_NAME(index, adc_pre, bits)}, \
.has_pclken_pre = true,), \
(.has_pclken_pre = false,)) \
.clk_prescaler = ADC_STM32_DT_PRESC(index), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \
.differential_channels_used = (ANY_CHILD_NODE_IS_DIFFERENTIAL(index) > 0), \
Expand Down
9 changes: 0 additions & 9 deletions drivers/clock_control/clock_stm32_ll_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1142,15 +1142,6 @@ int stm32_clock_control_init(const struct device *dev)
#if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb4_prescaler)
LL_RCC_SetAHB4Prescaler(ahb_prescaler(STM32_AHB4_PRESCALER));
#endif
#if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), adc_prescaler)
LL_RCC_SetADCClockSource(adc12_prescaler(STM32_ADC_PRESCALER));
#endif
#if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), adc12_prescaler)
LL_RCC_SetADCClockSource(adc12_prescaler(STM32_ADC12_PRESCALER));
#endif
#if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), adc34_prescaler)
LL_RCC_SetADCClockSource(adc34_prescaler(STM32_ADC34_PRESCALER));
#endif
#if defined(RCC_DCKCFGR_TIMPRE) || defined(RCC_DCKCFGR1_TIMPRE)
if (IS_ENABLED(STM32_TIMER_PRESCALER)) {
LL_RCC_SetTIMPrescaler(LL_RCC_TIM_PRESCALER_FOUR_TIMES);
Expand Down
1 change: 1 addition & 0 deletions dts/arm/st/c0/stm32c0.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@
compatible = "st,stm32-adc";
reg = <0x40012400 0x400>;
clocks = <&rcc STM32_CLOCK(APB1_2, 20)>;
clock-names = "adcx";
interrupts = <12 0>;
#io-channel-cells = <1>;
resolutions = <STM32_ADC_RES(12, 0x00)
Expand Down
1 change: 1 addition & 0 deletions dts/arm/st/f0/stm32f0.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@
compatible = "st,stm32-adc";
reg = <0x40012400 0x400>;
clocks = <&rcc STM32_CLOCK(APB2, 9)>;
clock-names = "adcx";
interrupts = <12 0>;
#io-channel-cells = <1>;
resolutions = <STM32_ADC_RES(12, 0x00)
Expand Down
3 changes: 2 additions & 1 deletion dts/arm/st/f1/stm32f1.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
};

rcc: rcc@40021000 {
compatible = "st,stm32f1-rcc";
compatible = "st,stm32-rcc";
#clock-cells = <2>;
reg = <0x40021000 0x400>;

Expand Down Expand Up @@ -394,6 +394,7 @@
compatible = "st,stm32f1-adc", "st,stm32-adc";
reg = <0x40012400 0x400>;
clocks = <&rcc STM32_CLOCK(APB2, 9)>;
clock-names = "adcx";
interrupts = <18 0>;
#io-channel-cells = <1>;
resolutions = <STM32F1_ADC_RES(12)>;
Expand Down
2 changes: 2 additions & 0 deletions dts/arm/st/f1/stm32f103Xc.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
compatible = "st,stm32-adc";
reg = <0x40012800 0x400>;
clocks = <&rcc STM32_CLOCK(APB2, 10)>;
clock-names = "adcx";
/* Shares vector with ADC1 */
interrupts = <18 0>;
#io-channel-cells = <1>;
Expand All @@ -146,6 +147,7 @@
compatible = "st,stm32-adc";
reg = <0x40013c00 0x400>;
clocks = <&rcc STM32_CLOCK(APB2, 15)>;
clock-names = "adcx";
interrupts = <47 0>;
#io-channel-cells = <1>;
resolutions = <STM32F1_ADC_RES(12)>;
Expand Down
1 change: 1 addition & 0 deletions dts/arm/st/f2/stm32f2.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@
compatible = "st,stm32f4-adc", "st,stm32-adc";
reg = <0x40012000 0x400>;
clocks = <&rcc STM32_CLOCK(APB2, 8)>;
clock-names = "adcx";
interrupts = <18 0>;
#io-channel-cells = <1>;
resolutions = <STM32_ADC_RES(12, 0x00)
Expand Down
2 changes: 1 addition & 1 deletion dts/arm/st/f3/stm32f3.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
};

rcc: rcc@40021000 {
compatible = "st,stm32f3-rcc";
compatible = "st,stm32-rcc";
#clock-cells = <2>;
reg = <0x40021000 0x400>;

Expand Down
1 change: 1 addition & 0 deletions dts/arm/st/f3/stm32f302.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
compatible = "st,stm32-adc";
reg = <0x50000000 0x400>;
clocks = <&rcc STM32_CLOCK(AHB1, 28)>;
clock-names = "adcx";
interrupts = <18 0>;
#io-channel-cells = <1>;
resolutions = <STM32_ADC_RES(12, 0x00)
Expand Down
2 changes: 2 additions & 0 deletions dts/arm/st/f3/stm32f303.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@
compatible = "st,stm32-adc";
reg = <0x50000000 0x400>;
clocks = <&rcc STM32_CLOCK(AHB1, 28)>;
clock-names = "adcx";
interrupts = <18 0>;
vref-mv = <3000>;
#io-channel-cells = <1>;
Expand All @@ -165,6 +166,7 @@
compatible = "st,stm32-adc";
reg = <0x50000100 0x4c>;
clocks = <&rcc STM32_CLOCK(AHB1, 28)>;
clock-names = "adcx";
interrupts = <18 0>;
vref-mv = <3000>;
#io-channel-cells = <1>;
Expand Down
Loading