Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: adc: stm32: add oversampling support

Add oversampling support for STM32H7, STM32MP15 & STM32MP13.
STM32F4 ADC has no oversampling feature.

The current support of the oversampling feature aims at increasing the
data SNR, without changing the data resolution.
As the oversampling by itself increases data resolution, a right shift
is applied to keep the initial resolution.
Only the oversampling ratio corresponding to a power of two are
supported here, to get a direct link between right shift and
oversampling ratio. (2^n ratio <=> n right shift)

The oversampling ratio is shared by all channels, whatever channel type.
(e.g. single ended or differential).

Oversampling can be configured using IIO ABI:
- oversampling_ratio_available
- oversampling_ratio

Co-developed-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>
Reviewed-by: David Lechner <dlechner@baylibre.com>
Reviewed-by: Andy Shevchenko <andy@kernel.org>
Link: https://patch.msgid.link/20250424151604.626758-1-olivier.moysan@foss.st.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Olivier Moysan and committed by
Jonathan Cameron
dadf2477 60638e2a

+167
+17
drivers/iio/adc/stm32-adc-core.h
··· 10 10 #ifndef __STM32_ADC_H 11 11 #define __STM32_ADC_H 12 12 13 + #include <linux/bitfield.h> 14 + #include <linux/bits.h> 15 + 13 16 /* 14 17 * STM32 - ADC global register map 15 18 * ________________________________________________________ ··· 94 91 #define STM32H7_ADC_IER 0x04 95 92 #define STM32H7_ADC_CR 0x08 96 93 #define STM32H7_ADC_CFGR 0x0C 94 + #define STM32H7_ADC_CFGR2 0x10 97 95 #define STM32H7_ADC_SMPR1 0x14 98 96 #define STM32H7_ADC_SMPR2 0x18 99 97 #define STM32H7_ADC_PCSEL 0x1C ··· 164 160 #define STM32H7_DMNGT_SHIFT 0 165 161 #define STM32H7_DMNGT_MASK GENMASK(1, 0) 166 162 163 + /* STM32H7_ADC_CFGR2 bit fields */ 164 + #define STM32H7_OVSR_MASK GENMASK(25, 16) /* Correspond to OSVR field in datasheet */ 165 + #define STM32H7_OVSR(v) FIELD_PREP(STM32H7_OVSR_MASK, v) 166 + #define STM32H7_OVSS_MASK GENMASK(8, 5) 167 + #define STM32H7_OVSS(v) FIELD_PREP(STM32H7_OVSS_MASK, v) 168 + #define STM32H7_ROVSE BIT(0) 169 + 167 170 enum stm32h7_adc_dmngt { 168 171 STM32H7_DMNGT_DR_ONLY, /* Regular data in DR only */ 169 172 STM32H7_DMNGT_DMA_ONESHOT, /* DMA one shot mode */ ··· 236 225 #define STM32MP13_DFSDMCFG BIT(2) 237 226 #define STM32MP13_RES_SHIFT 3 238 227 #define STM32MP13_RES_MASK GENMASK(4, 3) 228 + 229 + /* STM32MP13_ADC_CFGR2 bit fields */ 230 + #define STM32MP13_OVSR_MASK GENMASK(4, 2) 231 + #define STM32MP13_OVSR(v) FIELD_PREP(STM32MP13_OVSR_MASK, v) 232 + #define STM32MP13_OVSS_MASK GENMASK(8, 5) 233 + #define STM32MP13_OVSS(v) FIELD_PREP(STM32MP13_OVSS_MASK, v) 239 234 240 235 /* STM32MP13_ADC_DIFSEL - bit fields */ 241 236 #define STM32MP13_DIFSEL_MASK GENMASK(18, 0)
+150
drivers/iio/adc/stm32-adc.c
··· 6 6 * Author: Fabrice Gasnier <fabrice.gasnier@st.com>. 7 7 */ 8 8 9 + #include <linux/array_size.h> 9 10 #include <linux/clk.h> 10 11 #include <linux/debugfs.h> 11 12 #include <linux/delay.h> ··· 203 202 * @has_boostmode: boost mode support flag 204 203 * @has_linearcal: linear calibration support flag 205 204 * @has_presel: channel preselection support flag 205 + * @has_oversampling: oversampling support flag 206 206 * @prepare: optional prepare routine (power-up, enable) 207 207 * @start_conv: routine to start conversions 208 208 * @stop_conv: routine to stop conversions 209 209 * @unprepare: optional unprepare routine (disable, power-down) 210 210 * @irq_clear: routine to clear irqs 211 + * @set_ovs: routine to set oversampling configuration 211 212 * @smp_cycles: programmable sampling time (ADC clock cycles) 212 213 * @ts_int_ch: pointer to array of internal channels minimum sampling time in ns 213 214 */ ··· 222 219 bool has_boostmode; 223 220 bool has_linearcal; 224 221 bool has_presel; 222 + bool has_oversampling; 225 223 int (*prepare)(struct iio_dev *); 226 224 void (*start_conv)(struct iio_dev *, bool dma); 227 225 void (*stop_conv)(struct iio_dev *); 228 226 void (*unprepare)(struct iio_dev *); 229 227 void (*irq_clear)(struct iio_dev *indio_dev, u32 msk); 228 + void (*set_ovs)(struct iio_dev *indio_dev, u32 ovs_idx); 230 229 const unsigned int *smp_cycles; 231 230 const unsigned int *ts_int_ch; 232 231 }; ··· 260 255 * @num_diff: number of differential channels 261 256 * @int_ch: internal channel indexes array 262 257 * @nsmps: number of channels with optional sample time 258 + * @ovs_idx: current oversampling ratio index (in oversampling array) 263 259 */ 264 260 struct stm32_adc { 265 261 struct stm32_adc_common *common; ··· 288 282 u32 num_diff; 289 283 int int_ch[STM32_ADC_INT_CH_NB]; 290 284 int nsmps; 285 + int ovs_idx; 291 286 }; 292 287 293 288 struct stm32_adc_diff_channel { ··· 300 293 * struct stm32_adc_info - stm32 ADC, per instance config data 301 294 * @max_channels: Number of channels 302 295 * @resolutions: available resolutions 296 + * @oversampling: available oversampling ratios 303 297 * @num_res: number of available resolutions 298 + * @num_ovs: number of available oversampling ratios 304 299 */ 305 300 struct stm32_adc_info { 306 301 int max_channels; 307 302 const unsigned int *resolutions; 303 + const unsigned int *oversampling; 308 304 const unsigned int num_res; 305 + const unsigned int num_ovs; 306 + }; 307 + 308 + static const unsigned int stm32h7_adc_oversampling_avail[] = { 309 + 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 310 + }; 311 + 312 + static const unsigned int stm32mp13_adc_oversampling_avail[] = { 313 + 1, 2, 4, 8, 16, 32, 64, 128, 256, 309 314 }; 310 315 311 316 static const unsigned int stm32f4_adc_resolutions[] = { ··· 341 322 static const struct stm32_adc_info stm32h7_adc_info = { 342 323 .max_channels = STM32_ADC_CH_MAX, 343 324 .resolutions = stm32h7_adc_resolutions, 325 + .oversampling = stm32h7_adc_oversampling_avail, 344 326 .num_res = ARRAY_SIZE(stm32h7_adc_resolutions), 327 + .num_ovs = ARRAY_SIZE(stm32h7_adc_oversampling_avail), 345 328 }; 346 329 347 330 /* stm32mp13 can have up to 19 channels */ 348 331 static const struct stm32_adc_info stm32mp13_adc_info = { 349 332 .max_channels = 19, 350 333 .resolutions = stm32f4_adc_resolutions, 334 + .oversampling = stm32mp13_adc_oversampling_avail, 351 335 .num_res = ARRAY_SIZE(stm32f4_adc_resolutions), 336 + .num_ovs = ARRAY_SIZE(stm32mp13_adc_oversampling_avail), 352 337 }; 353 338 354 339 /* ··· 910 887 STM32MP13_DMAEN | STM32MP13_DMACFG); 911 888 912 889 stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADSTART); 890 + } 891 + 892 + static void stm32h7_adc_set_ovs(struct iio_dev *indio_dev, u32 ovs_idx) 893 + { 894 + struct stm32_adc *adc = iio_priv(indio_dev); 895 + u32 ovsr_bits, bits, msk; 896 + 897 + msk = STM32H7_ROVSE | STM32H7_OVSR_MASK | STM32H7_OVSS_MASK; 898 + stm32_adc_clr_bits(adc, STM32H7_ADC_CFGR2, msk); 899 + 900 + if (!ovs_idx) 901 + return; 902 + 903 + /* 904 + * Only the oversampling ratios corresponding to 2^ovs_idx are exposed in sysfs. 905 + * Oversampling ratios [2,3,...,1024] are mapped on OVSR register values [1,2,...,1023]. 906 + * OVSR = 2^ovs_idx - 1 907 + * These ratio increase the resolution by ovs_idx bits. Apply a right shift to keep initial 908 + * resolution given by "assigned-resolution-bits" property. 909 + * OVSS = ovs_idx 910 + */ 911 + ovsr_bits = GENMASK(ovs_idx - 1, 0); 912 + bits = STM32H7_ROVSE | STM32H7_OVSS(ovs_idx) | STM32H7_OVSR(ovsr_bits); 913 + 914 + stm32_adc_set_bits(adc, STM32H7_ADC_CFGR2, bits & msk); 915 + } 916 + 917 + static void stm32mp13_adc_set_ovs(struct iio_dev *indio_dev, u32 ovs_idx) 918 + { 919 + struct stm32_adc *adc = iio_priv(indio_dev); 920 + u32 bits, msk; 921 + 922 + msk = STM32H7_ROVSE | STM32MP13_OVSR_MASK | STM32MP13_OVSS_MASK; 923 + stm32_adc_clr_bits(adc, STM32H7_ADC_CFGR2, msk); 924 + 925 + if (!ovs_idx) 926 + return; 927 + 928 + /* 929 + * The oversampling ratios [2,4,8,..,256] are mapped on OVSR register values [0,1,...,7]. 930 + * OVSR = ovs_idx - 1 931 + * These ratio increase the resolution by ovs_idx bits. Apply a right shift to keep initial 932 + * resolution given by "assigned-resolution-bits" property. 933 + * OVSS = ovs_idx 934 + */ 935 + bits = STM32H7_ROVSE | STM32MP13_OVSS(ovs_idx); 936 + if (ovs_idx - 1) 937 + bits |= STM32MP13_OVSR(ovs_idx - 1); 938 + 939 + stm32_adc_set_bits(adc, STM32H7_ADC_CFGR2, bits & msk); 913 940 } 914 941 915 942 static int stm32h7_adc_exit_pwr_down(struct iio_dev *indio_dev) ··· 1534 1461 return ret; 1535 1462 } 1536 1463 1464 + static int stm32_adc_write_raw(struct iio_dev *indio_dev, 1465 + struct iio_chan_spec const *chan, 1466 + int val, int val2, long mask) 1467 + { 1468 + struct stm32_adc *adc = iio_priv(indio_dev); 1469 + struct device *dev = indio_dev->dev.parent; 1470 + int nb = adc->cfg->adc_info->num_ovs; 1471 + unsigned int idx; 1472 + int ret; 1473 + 1474 + switch (mask) { 1475 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 1476 + if (val2) 1477 + return -EINVAL; 1478 + 1479 + for (idx = 0; idx < nb; idx++) 1480 + if (adc->cfg->adc_info->oversampling[idx] == val) 1481 + break; 1482 + if (idx >= nb) 1483 + return -EINVAL; 1484 + 1485 + if (!iio_device_claim_direct(indio_dev)) 1486 + return -EBUSY; 1487 + 1488 + ret = pm_runtime_resume_and_get(dev); 1489 + if (ret < 0) 1490 + goto err; 1491 + 1492 + adc->cfg->set_ovs(indio_dev, idx); 1493 + 1494 + pm_runtime_mark_last_busy(dev); 1495 + pm_runtime_put_autosuspend(dev); 1496 + 1497 + adc->ovs_idx = idx; 1498 + 1499 + err: 1500 + iio_device_release_direct(indio_dev); 1501 + 1502 + return ret; 1503 + default: 1504 + return -EINVAL; 1505 + } 1506 + } 1507 + 1508 + static int stm32_adc_read_avail(struct iio_dev *indio_dev, 1509 + struct iio_chan_spec const *chan, 1510 + const int **vals, int *type, int *length, long m) 1511 + { 1512 + struct stm32_adc *adc = iio_priv(indio_dev); 1513 + 1514 + switch (m) { 1515 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 1516 + *type = IIO_VAL_INT; 1517 + *length = adc->cfg->adc_info->num_ovs; 1518 + *vals = adc->cfg->adc_info->oversampling; 1519 + return IIO_AVAIL_LIST; 1520 + default: 1521 + return -EINVAL; 1522 + } 1523 + } 1524 + 1537 1525 static int stm32_adc_read_raw(struct iio_dev *indio_dev, 1538 1526 struct iio_chan_spec const *chan, 1539 1527 int *val, int *val2, long mask) ··· 1634 1500 *val = -((1 << chan->scan_type.realbits) / 2); 1635 1501 else 1636 1502 *val = 0; 1503 + return IIO_VAL_INT; 1504 + 1505 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 1506 + *val = adc->cfg->adc_info->oversampling[adc->ovs_idx]; 1637 1507 return IIO_VAL_INT; 1638 1508 1639 1509 default: ··· 1816 1678 1817 1679 static const struct iio_info stm32_adc_iio_info = { 1818 1680 .read_raw = stm32_adc_read_raw, 1681 + .write_raw = stm32_adc_write_raw, 1682 + .read_avail = stm32_adc_read_avail, 1819 1683 .validate_trigger = stm32_adc_validate_trigger, 1820 1684 .hwfifo_set_watermark = stm32_adc_set_watermark, 1821 1685 .update_scan_mode = stm32_adc_update_scan_mode, ··· 2111 1971 chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); 2112 1972 chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | 2113 1973 BIT(IIO_CHAN_INFO_OFFSET); 1974 + if (adc->cfg->has_oversampling) { 1975 + chan->info_mask_shared_by_all |= BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); 1976 + chan->info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); 1977 + } 2114 1978 chan->scan_type.sign = 'u'; 2115 1979 chan->scan_type.realbits = adc->cfg->adc_info->resolutions[adc->res]; 2116 1980 chan->scan_type.storagebits = 16; ··· 2731 2587 .has_boostmode = true, 2732 2588 .has_linearcal = true, 2733 2589 .has_presel = true, 2590 + .has_oversampling = true, 2734 2591 .start_conv = stm32h7_adc_start_conv, 2735 2592 .stop_conv = stm32h7_adc_stop_conv, 2736 2593 .prepare = stm32h7_adc_prepare, ··· 2739 2594 .smp_cycles = stm32h7_adc_smp_cycles, 2740 2595 .irq_clear = stm32h7_adc_irq_clear, 2741 2596 .ts_int_ch = stm32_adc_min_ts_h7, 2597 + .set_ovs = stm32h7_adc_set_ovs, 2742 2598 }; 2743 2599 2744 2600 static const unsigned int stm32_adc_min_ts_mp1[] = { 100, 100, 100, 4300, 9800 }; ··· 2753 2607 .has_boostmode = true, 2754 2608 .has_linearcal = true, 2755 2609 .has_presel = true, 2610 + .has_oversampling = true, 2756 2611 .start_conv = stm32h7_adc_start_conv, 2757 2612 .stop_conv = stm32h7_adc_stop_conv, 2758 2613 .prepare = stm32h7_adc_prepare, ··· 2761 2614 .smp_cycles = stm32h7_adc_smp_cycles, 2762 2615 .irq_clear = stm32h7_adc_irq_clear, 2763 2616 .ts_int_ch = stm32_adc_min_ts_mp1, 2617 + .set_ovs = stm32h7_adc_set_ovs, 2764 2618 }; 2765 2619 2766 2620 static const unsigned int stm32_adc_min_ts_mp13[] = { 100, 0, 0, 4300, 9800 }; ··· 2771 2623 .regs = &stm32mp13_adc_regspec, 2772 2624 .adc_info = &stm32mp13_adc_info, 2773 2625 .trigs = stm32h7_adc_trigs, 2626 + .has_oversampling = true, 2774 2627 .start_conv = stm32mp13_adc_start_conv, 2775 2628 .stop_conv = stm32h7_adc_stop_conv, 2776 2629 .prepare = stm32h7_adc_prepare, ··· 2779 2630 .smp_cycles = stm32mp13_adc_smp_cycles, 2780 2631 .irq_clear = stm32h7_adc_irq_clear, 2781 2632 .ts_int_ch = stm32_adc_min_ts_mp13, 2633 + .set_ovs = stm32mp13_adc_set_ovs, 2782 2634 }; 2783 2635 2784 2636 static const struct of_device_id stm32_adc_of_match[] = {