iio: adc: stm32: manage min sampling time on all internal channels
authorOlivier Moysan <olivier.moysan@foss.st.com>
Wed, 12 Oct 2022 14:22:01 +0000 (16:22 +0200)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Wed, 23 Nov 2022 19:43:59 +0000 (19:43 +0000)
Force minimum sampling time for all internal channels according
to datasheet requirement. This value can be increased through
DT st,min-sample-time-ns property.

Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Link: https://lore.kernel.org/r/20221012142205.13041-5-olivier.moysan@foss.st.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/stm32-adc.c

index d36c024..8d03d21 100644 (file)
@@ -215,7 +215,7 @@ struct stm32_adc;
  * @unprepare:         optional unprepare routine (disable, power-down)
  * @irq_clear:         routine to clear irqs
  * @smp_cycles:                programmable sampling time (ADC clock cycles)
- * @ts_vrefint_ns:     vrefint minimum sampling time in ns
+ * @ts_int_ch:         pointer to array of internal channels minimum sampling time in ns
  */
 struct stm32_adc_cfg {
        const struct stm32_adc_regspec  *regs;
@@ -232,7 +232,7 @@ struct stm32_adc_cfg {
        void (*unprepare)(struct iio_dev *);
        void (*irq_clear)(struct iio_dev *indio_dev, u32 msk);
        const unsigned int *smp_cycles;
-       const unsigned int ts_vrefint_ns;
+       const unsigned int *ts_int_ch;
 };
 
 /**
@@ -1910,14 +1910,15 @@ static void stm32_adc_smpr_init(struct stm32_adc *adc, int channel, u32 smp_ns)
 {
        const struct stm32_adc_regs *smpr = &adc->cfg->regs->smp_bits[channel];
        u32 period_ns, shift = smpr->shift, mask = smpr->mask;
-       unsigned int smp, r = smpr->reg;
+       unsigned int i, smp, r = smpr->reg;
 
        /*
-        * For vrefint channel, ensure that the sampling time cannot
+        * For internal channels, ensure that the sampling time cannot
         * be lower than the one specified in the datasheet
         */
-       if (channel == adc->int_ch[STM32_ADC_INT_CH_VREFINT])
-               smp_ns = max(smp_ns, adc->cfg->ts_vrefint_ns);
+       for (i = 0; i < STM32_ADC_INT_CH_NB; i++)
+               if (channel == adc->int_ch[i] && adc->int_ch[i] != STM32_ADC_INT_CH_NONE)
+                       smp_ns = max(smp_ns, adc->cfg->ts_int_ch[i]);
 
        /* Determine sampling time (ADC clock cycles) */
        period_ns = NSEC_PER_SEC / adc->common->rate;
@@ -2568,6 +2569,9 @@ static const struct stm32_adc_cfg stm32f4_adc_cfg = {
        .irq_clear = stm32f4_adc_irq_clear,
 };
 
+const unsigned int stm32_adc_min_ts_h7[] = { 0, 0, 0, 4300, 9000 };
+static_assert(ARRAY_SIZE(stm32_adc_min_ts_h7) == STM32_ADC_INT_CH_NB);
+
 static const struct stm32_adc_cfg stm32h7_adc_cfg = {
        .regs = &stm32h7_adc_regspec,
        .adc_info = &stm32h7_adc_info,
@@ -2581,8 +2585,12 @@ static const struct stm32_adc_cfg stm32h7_adc_cfg = {
        .unprepare = stm32h7_adc_unprepare,
        .smp_cycles = stm32h7_adc_smp_cycles,
        .irq_clear = stm32h7_adc_irq_clear,
+       .ts_int_ch = stm32_adc_min_ts_h7,
 };
 
+const unsigned int stm32_adc_min_ts_mp1[] = { 100, 100, 100, 4300, 9800 };
+static_assert(ARRAY_SIZE(stm32_adc_min_ts_mp1) == STM32_ADC_INT_CH_NB);
+
 static const struct stm32_adc_cfg stm32mp1_adc_cfg = {
        .regs = &stm32mp1_adc_regspec,
        .adc_info = &stm32h7_adc_info,
@@ -2597,9 +2605,12 @@ static const struct stm32_adc_cfg stm32mp1_adc_cfg = {
        .unprepare = stm32h7_adc_unprepare,
        .smp_cycles = stm32h7_adc_smp_cycles,
        .irq_clear = stm32h7_adc_irq_clear,
-       .ts_vrefint_ns = 4300,
+       .ts_int_ch = stm32_adc_min_ts_mp1,
 };
 
+const unsigned int stm32_adc_min_ts_mp13[] = { 100, 0, 0, 4300, 9800 };
+static_assert(ARRAY_SIZE(stm32_adc_min_ts_mp13) == STM32_ADC_INT_CH_NB);
+
 static const struct stm32_adc_cfg stm32mp13_adc_cfg = {
        .regs = &stm32mp13_adc_regspec,
        .adc_info = &stm32mp13_adc_info,
@@ -2610,6 +2621,7 @@ static const struct stm32_adc_cfg stm32mp13_adc_cfg = {
        .unprepare = stm32h7_adc_unprepare,
        .smp_cycles = stm32mp13_adc_smp_cycles,
        .irq_clear = stm32h7_adc_irq_clear,
+       .ts_int_ch = stm32_adc_min_ts_mp13,
 };
 
 static const struct of_device_id stm32_adc_of_match[] = {