[PATCH v2 07/14] iio: adc: stm32-adc: add support for stm32mp25
From: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Date: 2026-09-23 15:40:02
Also in:
linux-devicetree, linux-iio, lkml
Subsystem:
iio subsystem and drivers, the rest · Maintainers:
Jonathan Cameron, Linus Torvalds
Add support for ADC on STM32MP25 SoC. It has 3 ADCs, split into two blocks: - ADC1 & ADC2 are tightly coupled. - ADC3 is managed independently. Trigger list slightly changes between these blocks (ADC1 & ADC2). Other differences are found on channels interconnects (similar between ADC2 and ADC3): - ADC1 is connected to 18 external channels + 2 internal channels - ADC2 is connected to 14 external channels + 6 internal channels - ADC3 is connected to 14 external channels + 6 internal channels Each ADC is a 12-bits successive approximation analog-to-digital converter, with up to 20 multiplexed channels that can be configured as single ended or differential. ADC resolution ranges from 6 to 12 bits. It introduces diversity regarding IRQs, clocks, software calibration procedure, internal voltage channels, sampling time (prescaler) and trigger list. Most of the architecture, and the driver engine remains similar. So, handle the differences w.r.t. other STM32 ADCs family with a dedicated compatible and compatible data. Co-developed-by: Cheick Traore <redacted> Signed-off-by: Cheick Traore <redacted> Co-developed-by: Olivier Moysan <olivier.moysan@foss.st.com> Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com> --- Changes in v2: - Split as advised by Jonathan and Andy. Added precursor patches to prepare all the infrastructure. Keep only the new hardware support. - Adopt separate compatible for ADC1, ADC2 and ADC3 to better describe internal channels (split regs descriptions) and trigger list. Drop "st,adc-trigger-sel". - Cosmetic updates whilst at it: remove trailing comma - Refactor calibration routine, to avoid twisted goto chain, as advised by Andy - One patch per new SoC --- drivers/iio/adc/stm32-adc-core.c | 43 ++++- drivers/iio/adc/stm32-adc-core.h | 20 +++ drivers/iio/adc/stm32-adc.c | 372 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 434 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c
index 5845173e288c..7027d86f7457 100644
--- a/drivers/iio/adc/stm32-adc-core.c
+++ b/drivers/iio/adc/stm32-adc-core.c@@ -138,6 +138,9 @@ static struct stm32_adc_priv *to_stm32_adc_priv(struct stm32_adc_common *com) /* STM32F4 ADC internal common clock prescaler division ratios */ static unsigned int stm32f4_pclk_div[] = { 2, 4, 6, 8 }; +/* STM32MP25 ADC internal common clock prescaler division ratios */ +static unsigned int stm32mp25_presc_div[] = { 1, 2, 4, 6, 8, 10, 12, 16, 32, 64, 128, 256 }; + /** * stm32_adc_clk_sel() - Select stm32f4 ADC common clock prescaler * @pdev: platform device
@@ -348,6 +351,18 @@ static const struct stm32_adc_common_regs stm32mp13_adc_common_regs = { .eocie_msk = STM32H7_EOCIE, }; +/* STM32MP25 common registers definitions */ +static const struct stm32_adc_common_regs stm32mp25_adc_common_regs = { + .csr = STM32H7_ADC_CSR, + .ccr = STM32H7_ADC_CCR, + .eoc_msk = { STM32H7_EOC_MST, STM32H7_EOC_SLV}, + .ovr_msk = { STM32H7_OVR_MST, STM32H7_OVR_SLV}, + .ier = STM32H7_ADC_IER, + .eocie_msk = STM32H7_EOCIE, + .presc_msk = STM32H7_PRESC_MASK, + .presc_shift = STM32H7_PRESC_SHIFT, +}; + static const unsigned int stm32_adc_offset[STM32_ADC_MAX_ADCS] = { 0, STM32_ADC_OFFSET, STM32_ADC_OFFSET * 2, };
@@ -425,6 +440,8 @@ static int stm32_adc_irq_probe(struct platform_device *pdev, * Interrupt(s) must be provided, depending on the compatible: * - stm32f4/h7 shares a common interrupt line. * - stm32mp1, has one line per ADC + * - stm32mp25, has a dual ADC1/ADC2 and standalone ADC3. Each ADC has an IRQ + * (two for ADC1/ADC2, one for ADC3) */ for (i = 0; i < priv->nb_irqs; i++) { priv->irq[i] = platform_get_irq(pdev, i);
@@ -705,6 +722,17 @@ static int stm32_adc_probe_identification(struct platform_device *pdev, return -EINVAL; } + if (priv->cfg->ipid == STM32MP25_IPIDR_NUMBER) { + /* + * ADC diversity on STM32MP25 is handled here. There may be: + * - 2 IRQs for ADC1/ADC2 block + * - 1 IRQ for ADC3 block. + * There cannot be more IRQs than the actual number of ADCs. + */ + if (priv->nb_irqs > priv->nb_adc_max) + priv->nb_irqs = priv->nb_adc_max; + } + val = readl_relaxed(priv->common.base + STM32MP1_ADC_VERR); dev_dbg(&pdev->dev, "ADC version: %lu.%lu\n", FIELD_GET(STM32MP1_MAJREV_MASK, val),
@@ -897,6 +925,16 @@ static const struct stm32_adc_priv_cfg stm32mp13_adc_priv_cfg = { .num_irqs = 1, }; +static const struct stm32_adc_priv_cfg stm32mp25_adc_priv_cfg = { + .regs = &stm32mp25_adc_common_regs, + .clk_sel = stm32_adc_clk_sel, + .presc = stm32mp25_presc_div, + .num_presc = ARRAY_SIZE(stm32mp25_presc_div), + .max_clk_rate_hz = 70000000, + .ipid = STM32MP25_IPIDR_NUMBER, + .num_irqs = 2, /* 2 IRQs for ADC1/ADC2, 1 irq for ADC3 */ +}; + static const struct of_device_id stm32_adc_of_match[] = { { .compatible = "st,stm32f4-adc-core",
@@ -911,7 +949,10 @@ static const struct of_device_id stm32_adc_of_match[] = { .compatible = "st,stm32mp13-adc-core", .data = (void *)&stm32mp13_adc_priv_cfg }, { - }, + .compatible = "st,stm32mp25-adc-core", + .data = (void *)&stm32mp25_adc_priv_cfg + }, { + } }; MODULE_DEVICE_TABLE(of, stm32_adc_of_match);
diff --git a/drivers/iio/adc/stm32-adc-core.h b/drivers/iio/adc/stm32-adc-core.h
index db50a9f3b922..68b937e3819f 100644
--- a/drivers/iio/adc/stm32-adc-core.h
+++ b/drivers/iio/adc/stm32-adc-core.h@@ -121,6 +121,9 @@ #define STM32MP13_ADC_CALFACT 0xB4 #define STM32MP13_ADC2_OR 0xC8 +/* STM32MP25 - ADC2 and ADC3 option register */ +#define STM32MP25_ADC23_OR 0xD0 + /* STM32H7 - common registers for all ADC instances */ #define STM32H7_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00) #define STM32H7_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x08)
@@ -257,8 +260,25 @@ enum stm32h7_adc_dmngt { #define STM32MP13_OP1 BIT(1) #define STM32MP13_OP0 BIT(0) +/* STM32MP25 - Registers for each ADC instance */ +#define STM32MP25_ADC_CALFACT 0xC4 + +/* STM32MP25_ADC_CALFACT - bit fields */ +#define STM32MP25_CALFACT_CALADDOS BIT(31) +#define STM32MP25_CALFACT_D_MASK GENMASK(24, 16) +#define STM32MP25_CALFACT_S_MASK GENMASK(8, 0) + +/* STM32MP25_ADC_CFGR specific bit fields */ +#define STM32MP25_RES_SHIFT 2 +#define STM32MP25_RES_MASK GENMASK(3, 2) + +/* STM32MP25_ADC23_OR - specific bit fields */ +#define STM32MP25_VDDCPUEN BIT(3) +#define STM32MP25_VDDCOREEN BIT(2) + #define STM32MP15_IPIDR_NUMBER 0x00110005 #define STM32MP13_IPIDR_NUMBER 0x00110006 +#define STM32MP25_IPIDR_NUMBER 0x00110008 /** * struct stm32_adc_common - stm32 ADC driver common data (for all instances)
diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
index eecdc4cce1b4..a5bffc09898b 100644
--- a/drivers/iio/adc/stm32-adc.c
+++ b/drivers/iio/adc/stm32-adc.c@@ -33,6 +33,9 @@ /* Number of linear calibration shadow registers / LINCALRDYW control bits */ #define STM32H7_LINCALFACT_NUM 6 +/* Number of loops in the calibration procedure to average data on STM32MP25 */ +#define STM32MP25_CALIB_LOOP 8 + /* BOOST bit must be set on STM32H7 when ADC clock is above 20MHz */ #define STM32H7_BOOST_CLKRATE 20000000UL
@@ -77,6 +80,14 @@ enum stm32_adc_extsel { STM32_EXT18, STM32_EXT19, STM32_EXT20, + STM32_EXT21, + STM32_EXT22, + STM32_EXT23, + STM32_EXT24, + STM32_EXT25, + STM32_EXT26, + STM32_EXT27, + STM32_EXT28 }; enum stm32_adc_int_ch {
@@ -348,6 +359,20 @@ static const struct stm32_adc_info stm32mp13_adc_info = { .num_ovs = ARRAY_SIZE(stm32mp13_adc_oversampling_avail), }; +/* + * stm32mp25 can have up to 20 channels. + * Keep channel 19 (VREF+) hidden on STM32MP25: it is the ADC reference + * supply itself, so exposing it as a regular input is meaningless. + * Reference voltage must be derived from VREFINT with calibration data. + */ +static const struct stm32_adc_info stm32mp25_adc_info = { + .max_channels = STM32_ADC_CH_MAX - 1, + .resolutions = stm32f4_adc_resolutions, + .oversampling = stm32h7_adc_oversampling_avail, + .num_res = ARRAY_SIZE(stm32f4_adc_resolutions), + .num_ovs = ARRAY_SIZE(stm32h7_adc_oversampling_avail), +}; + /* * stm32f4_sq - describe regular sequence registers * - L: sequence len (register & bit field)
@@ -538,6 +563,114 @@ static const struct stm32_adc_regspec stm32h7_adc_regspec = { .smp_bits = stm32h7_smp_bits, }; +/* STM32MP25 external trigger sources for ADC1 and ADC2 */ +static struct stm32_adc_trig_info stm32mp25_adc1_adc2_trigs[] = { + { TIM1_TRGO, STM32_EXT0 }, + { TIM1_TRGO2, STM32_EXT1 }, + { TIM8_TRGO, STM32_EXT2 }, + { TIM8_TRGO2, STM32_EXT3 }, + { TIM20_TRGO, STM32_EXT4 }, + { TIM20_TRGO2, STM32_EXT5 }, + { TIM2_TRGO, STM32_EXT6 }, + { TIM3_TRGO, STM32_EXT7 }, + { TIM4_TRGO, STM32_EXT8 }, + { TIM5_TRGO, STM32_EXT9 }, + { TIM6_TRGO, STM32_EXT10 }, + { TIM15_TRGO, STM32_EXT11 }, + { TIM1_CH1, STM32_EXT12 }, + { TIM1_CH2, STM32_EXT13 }, + { TIM1_CH3, STM32_EXT14 }, + { TIM20_OC1, STM32_EXT15 }, + { TIM20_OC2, STM32_EXT16 }, + { TIM20_OC3, STM32_EXT17 }, + { TIM2_CH2, STM32_EXT18 }, + { TIM3_CH4, STM32_EXT19 }, + { TIM4_CH4, STM32_EXT20 }, + { TIM5_CH1, STM32_EXT21 }, + { TIM12_CH1, STM32_EXT22 }, + { LPTIM1_CH1, STM32_EXT24 }, + { LPTIM2_CH1, STM32_EXT25 }, + { LPTIM3_CH1, STM32_EXT26 }, + { LPTIM4_CH1, STM32_EXT27 }, + { LPTIM5_OUT, STM32_EXT28 }, + { } +}; + +/* STM32MP25 external trigger sources for ADC3 */ +static struct stm32_adc_trig_info stm32mp25_adc3_trigs[] = { + { TIM1_TRGO, STM32_EXT0 }, + { TIM1_TRGO2, STM32_EXT1 }, + { TIM8_TRGO, STM32_EXT2 }, + { TIM8_TRGO2, STM32_EXT3 }, + { TIM20_TRGO, STM32_EXT4 }, + { TIM20_TRGO2, STM32_EXT5 }, + { TIM2_TRGO, STM32_EXT6 }, + { TIM3_TRGO, STM32_EXT7 }, + { TIM4_TRGO, STM32_EXT8 }, + { TIM5_TRGO, STM32_EXT9 }, + { TIM6_TRGO, STM32_EXT10 }, + { TIM7_TRGO, STM32_EXT11 }, + { TIM15_TRGO, STM32_EXT12 }, + { TIM17_OC1, STM32_EXT13 }, + { TIM1_CH3, STM32_EXT14 }, + { TIM8_CH1, STM32_EXT15 }, + { TIM20_OC1, STM32_EXT16 }, + { TIM2_CH1, STM32_EXT17 }, + { TIM2_CH3, STM32_EXT18 }, + { TIM3_CH1, STM32_EXT19 }, + { TIM4_CH1, STM32_EXT20 }, + { TIM5_CH3, STM32_EXT21 }, + { TIM12_CH1, STM32_EXT22 }, + { LPTIM1_CH1, STM32_EXT24 }, + { LPTIM2_CH1, STM32_EXT25 }, + { LPTIM3_CH1, STM32_EXT26 }, + { LPTIM4_CH1, STM32_EXT27 }, + { LPTIM5_OUT, STM32_EXT28 }, + { } +}; + +/* STM32MP25 programmable sampling time (ADC clock cycles, rounded down) */ +static const unsigned int stm32mp25_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = { + 2, 3, 7, 12, 24, 47, 247, 1501, +}; + +static const struct stm32_adc_regspec stm32mp25_adc1_regspec = { + .dr = STM32H7_ADC_DR, + .ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE }, + .ier_ovr = { STM32H7_ADC_IER, STM32H7_OVRIE }, + .isr_eoc = { STM32H7_ADC_ISR, STM32H7_EOC }, + .isr_ovr = { STM32H7_ADC_ISR, STM32H7_OVR }, + .sqr = stm32h7_sq, + .exten = { STM32H7_ADC_CFGR, STM32H7_EXTEN_MASK, STM32H7_EXTEN_SHIFT }, + .extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK, + STM32H7_EXTSEL_SHIFT }, + .res = { STM32H7_ADC_CFGR, STM32MP25_RES_MASK, STM32MP25_RES_SHIFT }, + .difsel = { STM32H7_ADC_DIFSEL, STM32H7_DIFSEL_MASK}, + .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, + .smp_bits = stm32h7_smp_bits, + .ccr_vref = { STM32H7_ADC_CCR, STM32H7_VREFEN }, +}; + +static const struct stm32_adc_regspec stm32mp25_adc2_adc3_regspec = { + .dr = STM32H7_ADC_DR, + .ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE }, + .ier_ovr = { STM32H7_ADC_IER, STM32H7_OVRIE }, + .isr_eoc = { STM32H7_ADC_ISR, STM32H7_EOC }, + .isr_ovr = { STM32H7_ADC_ISR, STM32H7_OVR }, + .sqr = stm32h7_sq, + .exten = { STM32H7_ADC_CFGR, STM32H7_EXTEN_MASK, STM32H7_EXTEN_SHIFT }, + .extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK, + STM32H7_EXTSEL_SHIFT }, + .res = { STM32H7_ADC_CFGR, STM32MP25_RES_MASK, STM32MP25_RES_SHIFT }, + .difsel = { STM32H7_ADC_DIFSEL, STM32H7_DIFSEL_MASK}, + .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, + .smp_bits = stm32h7_smp_bits, + .or_vddcore = { STM32MP25_ADC23_OR, STM32MP25_VDDCOREEN }, + .or_vddcpu = { STM32MP25_ADC23_OR, STM32MP25_VDDCPUEN }, + .ccr_vbat = { STM32H7_ADC_CCR, STM32H7_VBATEN }, + .ccr_vref = { STM32H7_ADC_CCR, STM32H7_VREFEN }, +}; + /* STM32MP13 programmable sampling time (ADC clock cycles, rounded down) */ static const unsigned int stm32mp13_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = { 2, 6, 12, 24, 47, 92, 247, 640,
@@ -1304,6 +1437,184 @@ static void stm32h7_adc_unprepare(struct iio_dev *indio_dev) stm32h7_adc_enter_pwr_down(adc); } +/* + * STM32MP25 offset calibration software procedure. Basically the calibration routine is + * expected to average (for example) 8 samples in calibration mode, for single-ended and + * differential channels, to calibrate the zero offset. In case offset is "negative", an + * additional offset can be added, to determine calibration factor. It must be kept later + * for all conversions. + */ +static int stm32mp25_adc_calib_get_average_data(struct iio_dev *indio_dev, u32 *average) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + const struct stm32_adc_regspec *regs = adc->cfg->regs; + u32 val, avg = 0; + int ret; + + /* Repeat several conversions in calibration mode, average the results */ + for (unsigned int i = 0; i < STM32MP25_CALIB_LOOP; i++) { + stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADSTART); + ret = stm32_adc_readl_poll_timeout(STM32H7_ADC_CR, val, + !(val & (STM32H7_ADSTART)), + 100, STM32_ADC_TIMEOUT_US); + if (ret) { + dev_err(&indio_dev->dev, "calibration average error %d\n", ret); + return ret; + } + + val = stm32_adc_readl(adc, regs->dr); + dev_vdbg(&indio_dev->dev, "dr[%d]=0x%08x\n", i, val); + avg += val; + } + + *average = DIV_ROUND_CLOSEST(avg, STM32MP25_CALIB_LOOP); + dev_vdbg(&indio_dev->dev, "average=0x%08x\n", *average); + + return 0; +} + +static int stm32mp25_adc_calib_single_ended_offset(struct iio_dev *indio_dev, bool *add_offset) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + u32 average; + int ret; + + /* Select single ended input calibration */ + stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_ADCALDIF); + +retry: + /* Clears or set CALADDOS (also clear old calibration data if any) */ + stm32_adc_writel(adc, STM32MP25_ADC_CALFACT, + FIELD_PREP(STM32MP25_CALFACT_CALADDOS, *add_offset)); + + ret = stm32mp25_adc_calib_get_average_data(indio_dev, &average); + if (ret) + return ret; + + /* Add offset and retry single-ended calibration if the averaged data is zero */ + if (!average && !*add_offset) { + *add_offset = true; + goto retry; + } + + if (!average) { + /* If average data is still zero with additional offset, just warn about it */ + dev_warn(&indio_dev->dev, "Single-ended calibration average: 0\n"); + } else { + u32 calfact = stm32_adc_readl(adc, STM32MP25_ADC_CALFACT); + + calfact |= FIELD_PREP(STM32MP25_CALFACT_S_MASK, average); + stm32_adc_writel(adc, STM32MP25_ADC_CALFACT, calfact); + } + + return 0; +} + +static int stm32mp25_adc_calib(struct iio_dev *indio_dev) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + bool add_offset = false; + bool diff_below_zero; + u32 average, calfact; + int ret; + + stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADCAL); + /* Use default resolution (e.g. 12 bits) */ + stm32_adc_clr_bits(adc, STM32H7_ADC_CFGR, STM32MP25_RES_MASK); + +retry: + /* Single ended input calibration */ + ret = stm32mp25_adc_calib_single_ended_offset(indio_dev, &add_offset); + if (ret) + goto out; + + /* Differential input calibration (keep previous CALADDOS value) */ + stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADCALDIF); + ret = stm32mp25_adc_calib_get_average_data(indio_dev, &average); + if (ret) + goto out; + + /* Averaged diff data is below 0x800 (half value in 12-bits mode) */ + diff_below_zero = average < BIT(adc->cfg->adc_info->resolutions[0] - 1); + + if (diff_below_zero && !add_offset) { + /* Retry the whole calibration with additional offset */ + add_offset = true; + goto retry; + } + + calfact = stm32_adc_readl(adc, STM32MP25_ADC_CALFACT); + + if (diff_below_zero) { + /* + * Averaged data is still below center value. It needs to be clamped to zero, + * so don't use the result here, warn about it. + */ + dev_warn(&indio_dev->dev, "Differential calibration clamped(0): 0x%x\n", average); + } else { + calfact |= FIELD_PREP(STM32MP25_CALFACT_D_MASK, average); + stm32_adc_writel(adc, STM32MP25_ADC_CALFACT, calfact); + } + + dev_dbg(&indio_dev->dev, "set calfact_s=0x%03lx, calfact_d=0x%03lx, calados=%ld\n", + FIELD_GET(STM32MP25_CALFACT_S_MASK, calfact), + FIELD_GET(STM32MP25_CALFACT_D_MASK, calfact), + FIELD_GET(STM32MP25_CALFACT_CALADDOS, calfact)); +out: + stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_ADCAL); + stm32_adc_set_res(adc); + + return ret; +} + +static int stm32mp25_adc_prepare(struct iio_dev *indio_dev) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + int ret; + + ret = stm32h7_adc_exit_pwr_down(indio_dev); + if (ret) + return ret; + + /* Must enable the ADC before running software-assisted calibration */ + ret = stm32h7_adc_enable(indio_dev); + if (ret) + goto pwr_dwn; + + /* Always run offset calibration */ + ret = stm32mp25_adc_calib(indio_dev); + if (ret) + goto adc_dis; + + stm32_adc_int_ch_enable(indio_dev); + + stm32_adc_writel(adc, adc->cfg->regs->difsel.reg, adc->difsel); + + if (adc->cfg->has_presel) + stm32_adc_writel(adc, STM32H7_ADC_PCSEL, adc->pcsel); + + return 0; + +adc_dis: + stm32h7_adc_disable(indio_dev); +pwr_dwn: + stm32h7_adc_enter_pwr_down(adc); + + return ret; +} + +static void stm32mp25_adc_unprepare(struct iio_dev *indio_dev) +{ + struct stm32_adc *adc = iio_priv(indio_dev); + + /* Undo things in the reverse order */ + if (adc->cfg->has_presel) + stm32_adc_writel(adc, STM32H7_ADC_PCSEL, 0); + stm32_adc_int_ch_disable(adc); + stm32h7_adc_disable(indio_dev); + stm32h7_adc_enter_pwr_down(adc); +} + /** * stm32_adc_conf_scan_seq() - Build regular channels scan sequence * @indio_dev: IIO device
@@ -2786,11 +3097,72 @@ static const struct stm32_adc_cfg stm32mp13_adc_cfg = { .vref_charac_mv = 3300, }; +static const unsigned int stm32_adc_min_ts_mp25[STM32_ADC_INT_CH_NB] = { + [STM32_ADC_INT_CH_VDDCORE] = 34, + [STM32_ADC_INT_CH_VDDCPU] = 34, + [STM32_ADC_INT_CH_VREFINT] = 34, + [STM32_ADC_INT_CH_VBAT] = 34, +}; + +static const struct stm32_adc_cfg stm32mp25_adc1_cfg = { + .regs = &stm32mp25_adc1_regspec, + .adc_info = &stm32mp25_adc_info, + .trigs = stm32mp25_adc1_adc2_trigs, + .has_oversampling = true, + .has_presel = true, + .start_conv = stm32h7_adc_start_conv, + .stop_conv = stm32h7_adc_stop_conv, + .prepare = stm32mp25_adc_prepare, + .unprepare = stm32mp25_adc_unprepare, + .smp_cycles = stm32mp25_adc_smp_cycles, + .irq_clear = stm32h7_adc_irq_clear, + .set_ovs = stm32h7_adc_set_ovs, + .ts_int_ch = stm32_adc_min_ts_mp25, + .vref_charac_mv = 1800, +}; + +static const struct stm32_adc_cfg stm32mp25_adc2_cfg = { + .regs = &stm32mp25_adc2_adc3_regspec, + .adc_info = &stm32mp25_adc_info, + .trigs = stm32mp25_adc1_adc2_trigs, + .has_oversampling = true, + .has_presel = true, + .start_conv = stm32h7_adc_start_conv, + .stop_conv = stm32h7_adc_stop_conv, + .prepare = stm32mp25_adc_prepare, + .unprepare = stm32mp25_adc_unprepare, + .smp_cycles = stm32mp25_adc_smp_cycles, + .irq_clear = stm32h7_adc_irq_clear, + .set_ovs = stm32h7_adc_set_ovs, + .ts_int_ch = stm32_adc_min_ts_mp25, + .vref_charac_mv = 1800, +}; + +static const struct stm32_adc_cfg stm32mp25_adc3_cfg = { + .regs = &stm32mp25_adc2_adc3_regspec, + .adc_info = &stm32mp25_adc_info, + .trigs = stm32mp25_adc3_trigs, + .has_oversampling = true, + .has_presel = true, + .start_conv = stm32h7_adc_start_conv, + .stop_conv = stm32h7_adc_stop_conv, + .prepare = stm32mp25_adc_prepare, + .unprepare = stm32mp25_adc_unprepare, + .smp_cycles = stm32mp25_adc_smp_cycles, + .irq_clear = stm32h7_adc_irq_clear, + .set_ovs = stm32h7_adc_set_ovs, + .ts_int_ch = stm32_adc_min_ts_mp25, + .vref_charac_mv = 1800, +}; + static const struct of_device_id stm32_adc_of_match[] = { { .compatible = "st,stm32f4-adc", .data = (void *)&stm32f4_adc_cfg }, { .compatible = "st,stm32h7-adc", .data = (void *)&stm32h7_adc_cfg }, { .compatible = "st,stm32mp1-adc", .data = (void *)&stm32mp1_adc_cfg }, { .compatible = "st,stm32mp13-adc", .data = (void *)&stm32mp13_adc_cfg }, + { .compatible = "st,stm32mp25-adc1", .data = (void *)&stm32mp25_adc1_cfg }, + { .compatible = "st,stm32mp25-adc2", .data = (void *)&stm32mp25_adc2_cfg }, + { .compatible = "st,stm32mp25-adc3", .data = (void *)&stm32mp25_adc3_cfg }, { } }; MODULE_DEVICE_TABLE(of, stm32_adc_of_match);
--
2.43.0