16e93e261SBenjamin Gaignard // SPDX-License-Identifier: GPL-2.0 20f883b22SFabrice Gasnier /* 30f883b22SFabrice Gasnier * This file is part of STM32 ADC driver 40f883b22SFabrice Gasnier * 50f883b22SFabrice Gasnier * Copyright (C) 2016, STMicroelectronics - All Rights Reserved 60f883b22SFabrice Gasnier * Author: Fabrice Gasnier <fabrice.gasnier@st.com>. 70f883b22SFabrice Gasnier */ 80f883b22SFabrice Gasnier 90f883b22SFabrice Gasnier #include <linux/clk.h> 100f883b22SFabrice Gasnier #include <linux/delay.h> 112763ea05SFabrice Gasnier #include <linux/dma-mapping.h> 122763ea05SFabrice Gasnier #include <linux/dmaengine.h> 130f883b22SFabrice Gasnier #include <linux/iio/iio.h> 14da9b9485SFabrice Gasnier #include <linux/iio/buffer.h> 15f0b638a7SFabrice Gasnier #include <linux/iio/timer/stm32-lptim-trigger.h> 16f24a33b3SFabrice Gasnier #include <linux/iio/timer/stm32-timer-trigger.h> 17da9b9485SFabrice Gasnier #include <linux/iio/trigger.h> 18da9b9485SFabrice Gasnier #include <linux/iio/trigger_consumer.h> 19da9b9485SFabrice Gasnier #include <linux/iio/triggered_buffer.h> 200f883b22SFabrice Gasnier #include <linux/interrupt.h> 210f883b22SFabrice Gasnier #include <linux/io.h> 2295e339b6SFabrice Gasnier #include <linux/iopoll.h> 230f883b22SFabrice Gasnier #include <linux/module.h> 240e346b2cSOlivier Moysan #include <linux/nvmem-consumer.h> 250f883b22SFabrice Gasnier #include <linux/platform_device.h> 269bdbb113SFabrice Gasnier #include <linux/pm_runtime.h> 270f883b22SFabrice Gasnier #include <linux/of.h> 2864ad7f64SFabrice Gasnier #include <linux/of_device.h> 290f883b22SFabrice Gasnier 300f883b22SFabrice Gasnier #include "stm32-adc-core.h" 310f883b22SFabrice Gasnier 3295e339b6SFabrice Gasnier /* Number of linear calibration shadow registers / LINCALRDYW control bits */ 3395e339b6SFabrice Gasnier #define STM32H7_LINCALFACT_NUM 6 3495e339b6SFabrice Gasnier 3595e339b6SFabrice Gasnier /* BOOST bit must be set on STM32H7 when ADC clock is above 20MHz */ 3695e339b6SFabrice Gasnier #define STM32H7_BOOST_CLKRATE 20000000UL 3795e339b6SFabrice Gasnier 380bae72aaSFabrice Gasnier #define STM32_ADC_CH_MAX 20 /* max number of channels */ 3995bc8184SOlivier Moysan #define STM32_ADC_CH_SZ 16 /* max channel name size */ 40da9b9485SFabrice Gasnier #define STM32_ADC_MAX_SQ 16 /* SQ1..SQ16 */ 41ee2ac1cdSFabrice Gasnier #define STM32_ADC_MAX_SMP 7 /* SMPx range is [0..7] */ 420f883b22SFabrice Gasnier #define STM32_ADC_TIMEOUT_US 100000 430f883b22SFabrice Gasnier #define STM32_ADC_TIMEOUT (msecs_to_jiffies(STM32_ADC_TIMEOUT_US / 1000)) 449bdbb113SFabrice Gasnier #define STM32_ADC_HW_STOP_DELAY_MS 100 450e346b2cSOlivier Moysan #define STM32_ADC_VREFINT_VOLTAGE 3300 460f883b22SFabrice Gasnier 472763ea05SFabrice Gasnier #define STM32_DMA_BUFFER_SIZE PAGE_SIZE 482763ea05SFabrice Gasnier 49da9b9485SFabrice Gasnier /* External trigger enable */ 50da9b9485SFabrice Gasnier enum stm32_adc_exten { 51da9b9485SFabrice Gasnier STM32_EXTEN_SWTRIG, 52da9b9485SFabrice Gasnier STM32_EXTEN_HWTRIG_RISING_EDGE, 53da9b9485SFabrice Gasnier STM32_EXTEN_HWTRIG_FALLING_EDGE, 54da9b9485SFabrice Gasnier STM32_EXTEN_HWTRIG_BOTH_EDGES, 55da9b9485SFabrice Gasnier }; 56da9b9485SFabrice Gasnier 57f24a33b3SFabrice Gasnier /* extsel - trigger mux selection value */ 58f24a33b3SFabrice Gasnier enum stm32_adc_extsel { 59f24a33b3SFabrice Gasnier STM32_EXT0, 60f24a33b3SFabrice Gasnier STM32_EXT1, 61f24a33b3SFabrice Gasnier STM32_EXT2, 62f24a33b3SFabrice Gasnier STM32_EXT3, 63f24a33b3SFabrice Gasnier STM32_EXT4, 64f24a33b3SFabrice Gasnier STM32_EXT5, 65f24a33b3SFabrice Gasnier STM32_EXT6, 66f24a33b3SFabrice Gasnier STM32_EXT7, 67f24a33b3SFabrice Gasnier STM32_EXT8, 68f24a33b3SFabrice Gasnier STM32_EXT9, 69f24a33b3SFabrice Gasnier STM32_EXT10, 70f24a33b3SFabrice Gasnier STM32_EXT11, 71f24a33b3SFabrice Gasnier STM32_EXT12, 72f24a33b3SFabrice Gasnier STM32_EXT13, 73f24a33b3SFabrice Gasnier STM32_EXT14, 74f24a33b3SFabrice Gasnier STM32_EXT15, 75f0b638a7SFabrice Gasnier STM32_EXT16, 76f0b638a7SFabrice Gasnier STM32_EXT17, 77f0b638a7SFabrice Gasnier STM32_EXT18, 78f0b638a7SFabrice Gasnier STM32_EXT19, 79f0b638a7SFabrice Gasnier STM32_EXT20, 80f24a33b3SFabrice Gasnier }; 81f24a33b3SFabrice Gasnier 82aec6e0d8SOlivier Moysan enum stm32_adc_int_ch { 83aec6e0d8SOlivier Moysan STM32_ADC_INT_CH_NONE = -1, 84aec6e0d8SOlivier Moysan STM32_ADC_INT_CH_VDDCORE, 85aec6e0d8SOlivier Moysan STM32_ADC_INT_CH_VREFINT, 86aec6e0d8SOlivier Moysan STM32_ADC_INT_CH_VBAT, 87aec6e0d8SOlivier Moysan STM32_ADC_INT_CH_NB, 88aec6e0d8SOlivier Moysan }; 89aec6e0d8SOlivier Moysan 90aec6e0d8SOlivier Moysan /** 91aec6e0d8SOlivier Moysan * struct stm32_adc_ic - ADC internal channels 92aec6e0d8SOlivier Moysan * @name: name of the internal channel 93aec6e0d8SOlivier Moysan * @idx: internal channel enum index 94aec6e0d8SOlivier Moysan */ 95aec6e0d8SOlivier Moysan struct stm32_adc_ic { 96aec6e0d8SOlivier Moysan const char *name; 97aec6e0d8SOlivier Moysan u32 idx; 98aec6e0d8SOlivier Moysan }; 99aec6e0d8SOlivier Moysan 100aec6e0d8SOlivier Moysan static const struct stm32_adc_ic stm32_adc_ic[STM32_ADC_INT_CH_NB] = { 101aec6e0d8SOlivier Moysan { "vddcore", STM32_ADC_INT_CH_VDDCORE }, 102aec6e0d8SOlivier Moysan { "vrefint", STM32_ADC_INT_CH_VREFINT }, 103aec6e0d8SOlivier Moysan { "vbat", STM32_ADC_INT_CH_VBAT }, 104aec6e0d8SOlivier Moysan }; 105aec6e0d8SOlivier Moysan 106f24a33b3SFabrice Gasnier /** 107f24a33b3SFabrice Gasnier * struct stm32_adc_trig_info - ADC trigger info 108f24a33b3SFabrice Gasnier * @name: name of the trigger, corresponding to its source 109f24a33b3SFabrice Gasnier * @extsel: trigger selection 110f24a33b3SFabrice Gasnier */ 111f24a33b3SFabrice Gasnier struct stm32_adc_trig_info { 112f24a33b3SFabrice Gasnier const char *name; 113f24a33b3SFabrice Gasnier enum stm32_adc_extsel extsel; 114f24a33b3SFabrice Gasnier }; 115f24a33b3SFabrice Gasnier 116da9b9485SFabrice Gasnier /** 11795e339b6SFabrice Gasnier * struct stm32_adc_calib - optional adc calibration data 11895e339b6SFabrice Gasnier * @calfact_s: Calibration offset for single ended channels 11995e339b6SFabrice Gasnier * @calfact_d: Calibration offset in differential 12095e339b6SFabrice Gasnier * @lincalfact: Linearity calibration factor 1210da98c7bSFabrice Gasnier * @calibrated: Indicates calibration status 12295e339b6SFabrice Gasnier */ 12395e339b6SFabrice Gasnier struct stm32_adc_calib { 12495e339b6SFabrice Gasnier u32 calfact_s; 12595e339b6SFabrice Gasnier u32 calfact_d; 12695e339b6SFabrice Gasnier u32 lincalfact[STM32H7_LINCALFACT_NUM]; 1270da98c7bSFabrice Gasnier bool calibrated; 12895e339b6SFabrice Gasnier }; 12995e339b6SFabrice Gasnier 13095e339b6SFabrice Gasnier /** 1311cd92d42SFabrice Gasnier * struct stm32_adc_regs - stm32 ADC misc registers & bitfield desc 132da9b9485SFabrice Gasnier * @reg: register offset 133da9b9485SFabrice Gasnier * @mask: bitfield mask 134da9b9485SFabrice Gasnier * @shift: left shift 135da9b9485SFabrice Gasnier */ 136da9b9485SFabrice Gasnier struct stm32_adc_regs { 137da9b9485SFabrice Gasnier int reg; 138da9b9485SFabrice Gasnier int mask; 139da9b9485SFabrice Gasnier int shift; 140da9b9485SFabrice Gasnier }; 141da9b9485SFabrice Gasnier 1420f883b22SFabrice Gasnier /** 1430e346b2cSOlivier Moysan * struct stm32_adc_vrefint - stm32 ADC internal reference voltage data 1440e346b2cSOlivier Moysan * @vrefint_cal: vrefint calibration value from nvmem 1450e346b2cSOlivier Moysan * @vrefint_data: vrefint actual value 1460e346b2cSOlivier Moysan */ 1470e346b2cSOlivier Moysan struct stm32_adc_vrefint { 1480e346b2cSOlivier Moysan u32 vrefint_cal; 1490e346b2cSOlivier Moysan u32 vrefint_data; 1500e346b2cSOlivier Moysan }; 1510e346b2cSOlivier Moysan 1520e346b2cSOlivier Moysan /** 1531cd92d42SFabrice Gasnier * struct stm32_adc_regspec - stm32 registers definition 15464ad7f64SFabrice Gasnier * @dr: data register offset 15564ad7f64SFabrice Gasnier * @ier_eoc: interrupt enable register & eocie bitfield 156cc06e67dSFabrice Gasnier * @ier_ovr: interrupt enable register & overrun bitfield 15764ad7f64SFabrice Gasnier * @isr_eoc: interrupt status register & eoc bitfield 158cc06e67dSFabrice Gasnier * @isr_ovr: interrupt status register & overrun bitfield 15964ad7f64SFabrice Gasnier * @sqr: reference to sequence registers array 16064ad7f64SFabrice Gasnier * @exten: trigger control register & bitfield 16164ad7f64SFabrice Gasnier * @extsel: trigger selection register & bitfield 16264ad7f64SFabrice Gasnier * @res: resolution selection register & bitfield 163ee2ac1cdSFabrice Gasnier * @smpr: smpr1 & smpr2 registers offset array 164ee2ac1cdSFabrice Gasnier * @smp_bits: smpr1 & smpr2 index and bitfields 165aec6e0d8SOlivier Moysan * @or_vdd: option register & vddcore bitfield 166aec6e0d8SOlivier Moysan * @ccr_vbat: common register & vbat bitfield 167aec6e0d8SOlivier Moysan * @ccr_vref: common register & vrefint bitfield 16864ad7f64SFabrice Gasnier */ 16964ad7f64SFabrice Gasnier struct stm32_adc_regspec { 17064ad7f64SFabrice Gasnier const u32 dr; 17164ad7f64SFabrice Gasnier const struct stm32_adc_regs ier_eoc; 172cc06e67dSFabrice Gasnier const struct stm32_adc_regs ier_ovr; 17364ad7f64SFabrice Gasnier const struct stm32_adc_regs isr_eoc; 174cc06e67dSFabrice Gasnier const struct stm32_adc_regs isr_ovr; 17564ad7f64SFabrice Gasnier const struct stm32_adc_regs *sqr; 17664ad7f64SFabrice Gasnier const struct stm32_adc_regs exten; 17764ad7f64SFabrice Gasnier const struct stm32_adc_regs extsel; 17864ad7f64SFabrice Gasnier const struct stm32_adc_regs res; 179ee2ac1cdSFabrice Gasnier const u32 smpr[2]; 180ee2ac1cdSFabrice Gasnier const struct stm32_adc_regs *smp_bits; 181aec6e0d8SOlivier Moysan const struct stm32_adc_regs or_vdd; 182aec6e0d8SOlivier Moysan const struct stm32_adc_regs ccr_vbat; 183aec6e0d8SOlivier Moysan const struct stm32_adc_regs ccr_vref; 18464ad7f64SFabrice Gasnier }; 18564ad7f64SFabrice Gasnier 18664ad7f64SFabrice Gasnier struct stm32_adc; 18764ad7f64SFabrice Gasnier 18864ad7f64SFabrice Gasnier /** 1891cd92d42SFabrice Gasnier * struct stm32_adc_cfg - stm32 compatible configuration data 19064ad7f64SFabrice Gasnier * @regs: registers descriptions 19164ad7f64SFabrice Gasnier * @adc_info: per instance input channels definitions 19264ad7f64SFabrice Gasnier * @trigs: external trigger sources 193204a6a25SFabrice Gasnier * @clk_required: clock is required 194d58c67d1SFabrice Gasnier * @has_vregready: vregready status flag presence 19595e339b6SFabrice Gasnier * @prepare: optional prepare routine (power-up, enable) 19664ad7f64SFabrice Gasnier * @start_conv: routine to start conversions 19764ad7f64SFabrice Gasnier * @stop_conv: routine to stop conversions 19895e339b6SFabrice Gasnier * @unprepare: optional unprepare routine (disable, power-down) 199695e2f5cSOlivier Moysan * @irq_clear: routine to clear irqs 200ee2ac1cdSFabrice Gasnier * @smp_cycles: programmable sampling time (ADC clock cycles) 2010e346b2cSOlivier Moysan * @ts_vrefint_ns: vrefint minimum sampling time in ns 20264ad7f64SFabrice Gasnier */ 20364ad7f64SFabrice Gasnier struct stm32_adc_cfg { 20464ad7f64SFabrice Gasnier const struct stm32_adc_regspec *regs; 20564ad7f64SFabrice Gasnier const struct stm32_adc_info *adc_info; 20664ad7f64SFabrice Gasnier struct stm32_adc_trig_info *trigs; 207204a6a25SFabrice Gasnier bool clk_required; 208d58c67d1SFabrice Gasnier bool has_vregready; 209cd64d357SAlexandru Ardelean int (*prepare)(struct iio_dev *); 210cd64d357SAlexandru Ardelean void (*start_conv)(struct iio_dev *, bool dma); 211cd64d357SAlexandru Ardelean void (*stop_conv)(struct iio_dev *); 212cd64d357SAlexandru Ardelean void (*unprepare)(struct iio_dev *); 213695e2f5cSOlivier Moysan void (*irq_clear)(struct iio_dev *indio_dev, u32 msk); 214ee2ac1cdSFabrice Gasnier const unsigned int *smp_cycles; 2150e346b2cSOlivier Moysan const unsigned int ts_vrefint_ns; 21664ad7f64SFabrice Gasnier }; 21764ad7f64SFabrice Gasnier 21864ad7f64SFabrice Gasnier /** 2190f883b22SFabrice Gasnier * struct stm32_adc - private data of each ADC IIO instance 2200f883b22SFabrice Gasnier * @common: reference to ADC block common data 2210f883b22SFabrice Gasnier * @offset: ADC instance register offset in ADC block 22264ad7f64SFabrice Gasnier * @cfg: compatible configuration data 2230f883b22SFabrice Gasnier * @completion: end of single conversion completion 2248a09054fSAhmad Fatoum * @buffer: data buffer + 8 bytes for timestamp if enabled 2250f883b22SFabrice Gasnier * @clk: clock for this adc instance 2260f883b22SFabrice Gasnier * @irq: interrupt for this adc instance 2270f883b22SFabrice Gasnier * @lock: spinlock 228da9b9485SFabrice Gasnier * @bufi: data buffer index 229da9b9485SFabrice Gasnier * @num_conv: expected number of scan conversions 23025a85bedSFabrice Gasnier * @res: data resolution (e.g. RES bitfield value) 231732f2dc4SFabrice Gasnier * @trigger_polarity: external trigger polarity (e.g. exten) 2322763ea05SFabrice Gasnier * @dma_chan: dma channel 2332763ea05SFabrice Gasnier * @rx_buf: dma rx buffer cpu address 2342763ea05SFabrice Gasnier * @rx_dma_buf: dma rx buffer bus address 2352763ea05SFabrice Gasnier * @rx_buf_sz: dma rx buffer size 2361cd92d42SFabrice Gasnier * @difsel: bitmask to set single-ended/differential channel 2371cd92d42SFabrice Gasnier * @pcsel: bitmask to preselect channels on some devices 238ee2ac1cdSFabrice Gasnier * @smpr_val: sampling time settings (e.g. smpr1 / smpr2) 23995e339b6SFabrice Gasnier * @cal: optional calibration data on some devices 2400e346b2cSOlivier Moysan * @vrefint: internal reference voltage data 2410bae72aaSFabrice Gasnier * @chan_name: channel name array 24245571a36SOlivier Moysan * @num_diff: number of differential channels 243aec6e0d8SOlivier Moysan * @int_ch: internal channel indexes array 2440f883b22SFabrice Gasnier */ 2450f883b22SFabrice Gasnier struct stm32_adc { 2460f883b22SFabrice Gasnier struct stm32_adc_common *common; 2470f883b22SFabrice Gasnier u32 offset; 24864ad7f64SFabrice Gasnier const struct stm32_adc_cfg *cfg; 2490f883b22SFabrice Gasnier struct completion completion; 2508a09054fSAhmad Fatoum u16 buffer[STM32_ADC_MAX_SQ + 4] __aligned(8); 2510f883b22SFabrice Gasnier struct clk *clk; 2520f883b22SFabrice Gasnier int irq; 2530f883b22SFabrice Gasnier spinlock_t lock; /* interrupt lock */ 254da9b9485SFabrice Gasnier unsigned int bufi; 255da9b9485SFabrice Gasnier unsigned int num_conv; 25625a85bedSFabrice Gasnier u32 res; 257732f2dc4SFabrice Gasnier u32 trigger_polarity; 2582763ea05SFabrice Gasnier struct dma_chan *dma_chan; 2592763ea05SFabrice Gasnier u8 *rx_buf; 2602763ea05SFabrice Gasnier dma_addr_t rx_dma_buf; 2612763ea05SFabrice Gasnier unsigned int rx_buf_sz; 2623fb2e24eSFabrice Gasnier u32 difsel; 26395e339b6SFabrice Gasnier u32 pcsel; 264ee2ac1cdSFabrice Gasnier u32 smpr_val[2]; 26595e339b6SFabrice Gasnier struct stm32_adc_calib cal; 2660e346b2cSOlivier Moysan struct stm32_adc_vrefint vrefint; 2670bae72aaSFabrice Gasnier char chan_name[STM32_ADC_CH_MAX][STM32_ADC_CH_SZ]; 26845571a36SOlivier Moysan u32 num_diff; 269aec6e0d8SOlivier Moysan int int_ch[STM32_ADC_INT_CH_NB]; 2700f883b22SFabrice Gasnier }; 2710f883b22SFabrice Gasnier 2723fb2e24eSFabrice Gasnier struct stm32_adc_diff_channel { 2733fb2e24eSFabrice Gasnier u32 vinp; 2743fb2e24eSFabrice Gasnier u32 vinn; 2753fb2e24eSFabrice Gasnier }; 2763fb2e24eSFabrice Gasnier 27764ad7f64SFabrice Gasnier /** 27864ad7f64SFabrice Gasnier * struct stm32_adc_info - stm32 ADC, per instance config data 27964ad7f64SFabrice Gasnier * @max_channels: Number of channels 28064ad7f64SFabrice Gasnier * @resolutions: available resolutions 28164ad7f64SFabrice Gasnier * @num_res: number of available resolutions 28264ad7f64SFabrice Gasnier */ 28364ad7f64SFabrice Gasnier struct stm32_adc_info { 28464ad7f64SFabrice Gasnier int max_channels; 28564ad7f64SFabrice Gasnier const unsigned int *resolutions; 28664ad7f64SFabrice Gasnier const unsigned int num_res; 28764ad7f64SFabrice Gasnier }; 28864ad7f64SFabrice Gasnier 28925a85bedSFabrice Gasnier static const unsigned int stm32f4_adc_resolutions[] = { 29025a85bedSFabrice Gasnier /* sorted values so the index matches RES[1:0] in STM32F4_ADC_CR1 */ 29125a85bedSFabrice Gasnier 12, 10, 8, 6, 29225a85bedSFabrice Gasnier }; 29325a85bedSFabrice Gasnier 2940bae72aaSFabrice Gasnier /* stm32f4 can have up to 16 channels */ 29564ad7f64SFabrice Gasnier static const struct stm32_adc_info stm32f4_adc_info = { 29664ad7f64SFabrice Gasnier .max_channels = 16, 29764ad7f64SFabrice Gasnier .resolutions = stm32f4_adc_resolutions, 29864ad7f64SFabrice Gasnier .num_res = ARRAY_SIZE(stm32f4_adc_resolutions), 29964ad7f64SFabrice Gasnier }; 30064ad7f64SFabrice Gasnier 30195e339b6SFabrice Gasnier static const unsigned int stm32h7_adc_resolutions[] = { 30295e339b6SFabrice Gasnier /* sorted values so the index matches RES[2:0] in STM32H7_ADC_CFGR */ 30395e339b6SFabrice Gasnier 16, 14, 12, 10, 8, 30495e339b6SFabrice Gasnier }; 30595e339b6SFabrice Gasnier 3060bae72aaSFabrice Gasnier /* stm32h7 can have up to 20 channels */ 30795e339b6SFabrice Gasnier static const struct stm32_adc_info stm32h7_adc_info = { 3080bae72aaSFabrice Gasnier .max_channels = STM32_ADC_CH_MAX, 30995e339b6SFabrice Gasnier .resolutions = stm32h7_adc_resolutions, 31095e339b6SFabrice Gasnier .num_res = ARRAY_SIZE(stm32h7_adc_resolutions), 31195e339b6SFabrice Gasnier }; 31295e339b6SFabrice Gasnier 3131cd92d42SFabrice Gasnier /* 314da9b9485SFabrice Gasnier * stm32f4_sq - describe regular sequence registers 315da9b9485SFabrice Gasnier * - L: sequence len (register & bit field) 316da9b9485SFabrice Gasnier * - SQ1..SQ16: sequence entries (register & bit field) 317da9b9485SFabrice Gasnier */ 318da9b9485SFabrice Gasnier static const struct stm32_adc_regs stm32f4_sq[STM32_ADC_MAX_SQ + 1] = { 319da9b9485SFabrice Gasnier /* L: len bit field description to be kept as first element */ 320da9b9485SFabrice Gasnier { STM32F4_ADC_SQR1, GENMASK(23, 20), 20 }, 321da9b9485SFabrice Gasnier /* SQ1..SQ16 registers & bit fields (reg, mask, shift) */ 322da9b9485SFabrice Gasnier { STM32F4_ADC_SQR3, GENMASK(4, 0), 0 }, 323da9b9485SFabrice Gasnier { STM32F4_ADC_SQR3, GENMASK(9, 5), 5 }, 324da9b9485SFabrice Gasnier { STM32F4_ADC_SQR3, GENMASK(14, 10), 10 }, 325da9b9485SFabrice Gasnier { STM32F4_ADC_SQR3, GENMASK(19, 15), 15 }, 326da9b9485SFabrice Gasnier { STM32F4_ADC_SQR3, GENMASK(24, 20), 20 }, 327da9b9485SFabrice Gasnier { STM32F4_ADC_SQR3, GENMASK(29, 25), 25 }, 328da9b9485SFabrice Gasnier { STM32F4_ADC_SQR2, GENMASK(4, 0), 0 }, 329da9b9485SFabrice Gasnier { STM32F4_ADC_SQR2, GENMASK(9, 5), 5 }, 330da9b9485SFabrice Gasnier { STM32F4_ADC_SQR2, GENMASK(14, 10), 10 }, 331da9b9485SFabrice Gasnier { STM32F4_ADC_SQR2, GENMASK(19, 15), 15 }, 332da9b9485SFabrice Gasnier { STM32F4_ADC_SQR2, GENMASK(24, 20), 20 }, 333da9b9485SFabrice Gasnier { STM32F4_ADC_SQR2, GENMASK(29, 25), 25 }, 334da9b9485SFabrice Gasnier { STM32F4_ADC_SQR1, GENMASK(4, 0), 0 }, 335da9b9485SFabrice Gasnier { STM32F4_ADC_SQR1, GENMASK(9, 5), 5 }, 336da9b9485SFabrice Gasnier { STM32F4_ADC_SQR1, GENMASK(14, 10), 10 }, 337da9b9485SFabrice Gasnier { STM32F4_ADC_SQR1, GENMASK(19, 15), 15 }, 338da9b9485SFabrice Gasnier }; 339da9b9485SFabrice Gasnier 340f24a33b3SFabrice Gasnier /* STM32F4 external trigger sources for all instances */ 341f24a33b3SFabrice Gasnier static struct stm32_adc_trig_info stm32f4_adc_trigs[] = { 342f24a33b3SFabrice Gasnier { TIM1_CH1, STM32_EXT0 }, 343f24a33b3SFabrice Gasnier { TIM1_CH2, STM32_EXT1 }, 344f24a33b3SFabrice Gasnier { TIM1_CH3, STM32_EXT2 }, 345f24a33b3SFabrice Gasnier { TIM2_CH2, STM32_EXT3 }, 346f24a33b3SFabrice Gasnier { TIM2_CH3, STM32_EXT4 }, 347f24a33b3SFabrice Gasnier { TIM2_CH4, STM32_EXT5 }, 348f24a33b3SFabrice Gasnier { TIM2_TRGO, STM32_EXT6 }, 349f24a33b3SFabrice Gasnier { TIM3_CH1, STM32_EXT7 }, 350f24a33b3SFabrice Gasnier { TIM3_TRGO, STM32_EXT8 }, 351f24a33b3SFabrice Gasnier { TIM4_CH4, STM32_EXT9 }, 352f24a33b3SFabrice Gasnier { TIM5_CH1, STM32_EXT10 }, 353f24a33b3SFabrice Gasnier { TIM5_CH2, STM32_EXT11 }, 354f24a33b3SFabrice Gasnier { TIM5_CH3, STM32_EXT12 }, 355f24a33b3SFabrice Gasnier { TIM8_CH1, STM32_EXT13 }, 356f24a33b3SFabrice Gasnier { TIM8_TRGO, STM32_EXT14 }, 357f24a33b3SFabrice Gasnier {}, /* sentinel */ 358f24a33b3SFabrice Gasnier }; 359f24a33b3SFabrice Gasnier 3601cd92d42SFabrice Gasnier /* 361ee2ac1cdSFabrice Gasnier * stm32f4_smp_bits[] - describe sampling time register index & bit fields 362ee2ac1cdSFabrice Gasnier * Sorted so it can be indexed by channel number. 363ee2ac1cdSFabrice Gasnier */ 364ee2ac1cdSFabrice Gasnier static const struct stm32_adc_regs stm32f4_smp_bits[] = { 365ee2ac1cdSFabrice Gasnier /* STM32F4_ADC_SMPR2: smpr[] index, mask, shift for SMP0 to SMP9 */ 366ee2ac1cdSFabrice Gasnier { 1, GENMASK(2, 0), 0 }, 367ee2ac1cdSFabrice Gasnier { 1, GENMASK(5, 3), 3 }, 368ee2ac1cdSFabrice Gasnier { 1, GENMASK(8, 6), 6 }, 369ee2ac1cdSFabrice Gasnier { 1, GENMASK(11, 9), 9 }, 370ee2ac1cdSFabrice Gasnier { 1, GENMASK(14, 12), 12 }, 371ee2ac1cdSFabrice Gasnier { 1, GENMASK(17, 15), 15 }, 372ee2ac1cdSFabrice Gasnier { 1, GENMASK(20, 18), 18 }, 373ee2ac1cdSFabrice Gasnier { 1, GENMASK(23, 21), 21 }, 374ee2ac1cdSFabrice Gasnier { 1, GENMASK(26, 24), 24 }, 375ee2ac1cdSFabrice Gasnier { 1, GENMASK(29, 27), 27 }, 376ee2ac1cdSFabrice Gasnier /* STM32F4_ADC_SMPR1, smpr[] index, mask, shift for SMP10 to SMP18 */ 377ee2ac1cdSFabrice Gasnier { 0, GENMASK(2, 0), 0 }, 378ee2ac1cdSFabrice Gasnier { 0, GENMASK(5, 3), 3 }, 379ee2ac1cdSFabrice Gasnier { 0, GENMASK(8, 6), 6 }, 380ee2ac1cdSFabrice Gasnier { 0, GENMASK(11, 9), 9 }, 381ee2ac1cdSFabrice Gasnier { 0, GENMASK(14, 12), 12 }, 382ee2ac1cdSFabrice Gasnier { 0, GENMASK(17, 15), 15 }, 383ee2ac1cdSFabrice Gasnier { 0, GENMASK(20, 18), 18 }, 384ee2ac1cdSFabrice Gasnier { 0, GENMASK(23, 21), 21 }, 385ee2ac1cdSFabrice Gasnier { 0, GENMASK(26, 24), 24 }, 386ee2ac1cdSFabrice Gasnier }; 387ee2ac1cdSFabrice Gasnier 388ee2ac1cdSFabrice Gasnier /* STM32F4 programmable sampling time (ADC clock cycles) */ 389ee2ac1cdSFabrice Gasnier static const unsigned int stm32f4_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = { 390ee2ac1cdSFabrice Gasnier 3, 15, 28, 56, 84, 112, 144, 480, 391ee2ac1cdSFabrice Gasnier }; 392ee2ac1cdSFabrice Gasnier 39364ad7f64SFabrice Gasnier static const struct stm32_adc_regspec stm32f4_adc_regspec = { 39464ad7f64SFabrice Gasnier .dr = STM32F4_ADC_DR, 39564ad7f64SFabrice Gasnier .ier_eoc = { STM32F4_ADC_CR1, STM32F4_EOCIE }, 396cc06e67dSFabrice Gasnier .ier_ovr = { STM32F4_ADC_CR1, STM32F4_OVRIE }, 39764ad7f64SFabrice Gasnier .isr_eoc = { STM32F4_ADC_SR, STM32F4_EOC }, 398cc06e67dSFabrice Gasnier .isr_ovr = { STM32F4_ADC_SR, STM32F4_OVR }, 39964ad7f64SFabrice Gasnier .sqr = stm32f4_sq, 40064ad7f64SFabrice Gasnier .exten = { STM32F4_ADC_CR2, STM32F4_EXTEN_MASK, STM32F4_EXTEN_SHIFT }, 40164ad7f64SFabrice Gasnier .extsel = { STM32F4_ADC_CR2, STM32F4_EXTSEL_MASK, 40264ad7f64SFabrice Gasnier STM32F4_EXTSEL_SHIFT }, 40364ad7f64SFabrice Gasnier .res = { STM32F4_ADC_CR1, STM32F4_RES_MASK, STM32F4_RES_SHIFT }, 404ee2ac1cdSFabrice Gasnier .smpr = { STM32F4_ADC_SMPR1, STM32F4_ADC_SMPR2 }, 405ee2ac1cdSFabrice Gasnier .smp_bits = stm32f4_smp_bits, 40664ad7f64SFabrice Gasnier }; 40764ad7f64SFabrice Gasnier 40895e339b6SFabrice Gasnier static const struct stm32_adc_regs stm32h7_sq[STM32_ADC_MAX_SQ + 1] = { 40995e339b6SFabrice Gasnier /* L: len bit field description to be kept as first element */ 41095e339b6SFabrice Gasnier { STM32H7_ADC_SQR1, GENMASK(3, 0), 0 }, 41195e339b6SFabrice Gasnier /* SQ1..SQ16 registers & bit fields (reg, mask, shift) */ 41295e339b6SFabrice Gasnier { STM32H7_ADC_SQR1, GENMASK(10, 6), 6 }, 41395e339b6SFabrice Gasnier { STM32H7_ADC_SQR1, GENMASK(16, 12), 12 }, 41495e339b6SFabrice Gasnier { STM32H7_ADC_SQR1, GENMASK(22, 18), 18 }, 41595e339b6SFabrice Gasnier { STM32H7_ADC_SQR1, GENMASK(28, 24), 24 }, 41695e339b6SFabrice Gasnier { STM32H7_ADC_SQR2, GENMASK(4, 0), 0 }, 41795e339b6SFabrice Gasnier { STM32H7_ADC_SQR2, GENMASK(10, 6), 6 }, 41895e339b6SFabrice Gasnier { STM32H7_ADC_SQR2, GENMASK(16, 12), 12 }, 41995e339b6SFabrice Gasnier { STM32H7_ADC_SQR2, GENMASK(22, 18), 18 }, 42095e339b6SFabrice Gasnier { STM32H7_ADC_SQR2, GENMASK(28, 24), 24 }, 42195e339b6SFabrice Gasnier { STM32H7_ADC_SQR3, GENMASK(4, 0), 0 }, 42295e339b6SFabrice Gasnier { STM32H7_ADC_SQR3, GENMASK(10, 6), 6 }, 42395e339b6SFabrice Gasnier { STM32H7_ADC_SQR3, GENMASK(16, 12), 12 }, 42495e339b6SFabrice Gasnier { STM32H7_ADC_SQR3, GENMASK(22, 18), 18 }, 42595e339b6SFabrice Gasnier { STM32H7_ADC_SQR3, GENMASK(28, 24), 24 }, 42695e339b6SFabrice Gasnier { STM32H7_ADC_SQR4, GENMASK(4, 0), 0 }, 42795e339b6SFabrice Gasnier { STM32H7_ADC_SQR4, GENMASK(10, 6), 6 }, 42895e339b6SFabrice Gasnier }; 42995e339b6SFabrice Gasnier 43095e339b6SFabrice Gasnier /* STM32H7 external trigger sources for all instances */ 43195e339b6SFabrice Gasnier static struct stm32_adc_trig_info stm32h7_adc_trigs[] = { 43295e339b6SFabrice Gasnier { TIM1_CH1, STM32_EXT0 }, 43395e339b6SFabrice Gasnier { TIM1_CH2, STM32_EXT1 }, 43495e339b6SFabrice Gasnier { TIM1_CH3, STM32_EXT2 }, 43595e339b6SFabrice Gasnier { TIM2_CH2, STM32_EXT3 }, 43695e339b6SFabrice Gasnier { TIM3_TRGO, STM32_EXT4 }, 43795e339b6SFabrice Gasnier { TIM4_CH4, STM32_EXT5 }, 43895e339b6SFabrice Gasnier { TIM8_TRGO, STM32_EXT7 }, 43995e339b6SFabrice Gasnier { TIM8_TRGO2, STM32_EXT8 }, 44095e339b6SFabrice Gasnier { TIM1_TRGO, STM32_EXT9 }, 44195e339b6SFabrice Gasnier { TIM1_TRGO2, STM32_EXT10 }, 44295e339b6SFabrice Gasnier { TIM2_TRGO, STM32_EXT11 }, 44395e339b6SFabrice Gasnier { TIM4_TRGO, STM32_EXT12 }, 44495e339b6SFabrice Gasnier { TIM6_TRGO, STM32_EXT13 }, 4453a069904SFabrice Gasnier { TIM15_TRGO, STM32_EXT14 }, 44695e339b6SFabrice Gasnier { TIM3_CH4, STM32_EXT15 }, 447f0b638a7SFabrice Gasnier { LPTIM1_OUT, STM32_EXT18 }, 448f0b638a7SFabrice Gasnier { LPTIM2_OUT, STM32_EXT19 }, 449f0b638a7SFabrice Gasnier { LPTIM3_OUT, STM32_EXT20 }, 45095e339b6SFabrice Gasnier {}, 45195e339b6SFabrice Gasnier }; 45295e339b6SFabrice Gasnier 4531cd92d42SFabrice Gasnier /* 454ee2ac1cdSFabrice Gasnier * stm32h7_smp_bits - describe sampling time register index & bit fields 455ee2ac1cdSFabrice Gasnier * Sorted so it can be indexed by channel number. 456ee2ac1cdSFabrice Gasnier */ 457ee2ac1cdSFabrice Gasnier static const struct stm32_adc_regs stm32h7_smp_bits[] = { 458ee2ac1cdSFabrice Gasnier /* STM32H7_ADC_SMPR1, smpr[] index, mask, shift for SMP0 to SMP9 */ 459ee2ac1cdSFabrice Gasnier { 0, GENMASK(2, 0), 0 }, 460ee2ac1cdSFabrice Gasnier { 0, GENMASK(5, 3), 3 }, 461ee2ac1cdSFabrice Gasnier { 0, GENMASK(8, 6), 6 }, 462ee2ac1cdSFabrice Gasnier { 0, GENMASK(11, 9), 9 }, 463ee2ac1cdSFabrice Gasnier { 0, GENMASK(14, 12), 12 }, 464ee2ac1cdSFabrice Gasnier { 0, GENMASK(17, 15), 15 }, 465ee2ac1cdSFabrice Gasnier { 0, GENMASK(20, 18), 18 }, 466ee2ac1cdSFabrice Gasnier { 0, GENMASK(23, 21), 21 }, 467ee2ac1cdSFabrice Gasnier { 0, GENMASK(26, 24), 24 }, 468ee2ac1cdSFabrice Gasnier { 0, GENMASK(29, 27), 27 }, 469ee2ac1cdSFabrice Gasnier /* STM32H7_ADC_SMPR2, smpr[] index, mask, shift for SMP10 to SMP19 */ 470ee2ac1cdSFabrice Gasnier { 1, GENMASK(2, 0), 0 }, 471ee2ac1cdSFabrice Gasnier { 1, GENMASK(5, 3), 3 }, 472ee2ac1cdSFabrice Gasnier { 1, GENMASK(8, 6), 6 }, 473ee2ac1cdSFabrice Gasnier { 1, GENMASK(11, 9), 9 }, 474ee2ac1cdSFabrice Gasnier { 1, GENMASK(14, 12), 12 }, 475ee2ac1cdSFabrice Gasnier { 1, GENMASK(17, 15), 15 }, 476ee2ac1cdSFabrice Gasnier { 1, GENMASK(20, 18), 18 }, 477ee2ac1cdSFabrice Gasnier { 1, GENMASK(23, 21), 21 }, 478ee2ac1cdSFabrice Gasnier { 1, GENMASK(26, 24), 24 }, 479ee2ac1cdSFabrice Gasnier { 1, GENMASK(29, 27), 27 }, 480ee2ac1cdSFabrice Gasnier }; 481ee2ac1cdSFabrice Gasnier 482ee2ac1cdSFabrice Gasnier /* STM32H7 programmable sampling time (ADC clock cycles, rounded down) */ 483ee2ac1cdSFabrice Gasnier static const unsigned int stm32h7_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = { 484ee2ac1cdSFabrice Gasnier 1, 2, 8, 16, 32, 64, 387, 810, 485ee2ac1cdSFabrice Gasnier }; 486ee2ac1cdSFabrice Gasnier 48795e339b6SFabrice Gasnier static const struct stm32_adc_regspec stm32h7_adc_regspec = { 48895e339b6SFabrice Gasnier .dr = STM32H7_ADC_DR, 48995e339b6SFabrice Gasnier .ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE }, 490cc06e67dSFabrice Gasnier .ier_ovr = { STM32H7_ADC_IER, STM32H7_OVRIE }, 49195e339b6SFabrice Gasnier .isr_eoc = { STM32H7_ADC_ISR, STM32H7_EOC }, 492cc06e67dSFabrice Gasnier .isr_ovr = { STM32H7_ADC_ISR, STM32H7_OVR }, 49395e339b6SFabrice Gasnier .sqr = stm32h7_sq, 49495e339b6SFabrice Gasnier .exten = { STM32H7_ADC_CFGR, STM32H7_EXTEN_MASK, STM32H7_EXTEN_SHIFT }, 49595e339b6SFabrice Gasnier .extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK, 49695e339b6SFabrice Gasnier STM32H7_EXTSEL_SHIFT }, 49795e339b6SFabrice Gasnier .res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT }, 498ee2ac1cdSFabrice Gasnier .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, 499ee2ac1cdSFabrice Gasnier .smp_bits = stm32h7_smp_bits, 50095e339b6SFabrice Gasnier }; 50195e339b6SFabrice Gasnier 502aec6e0d8SOlivier Moysan static const struct stm32_adc_regspec stm32mp1_adc_regspec = { 503aec6e0d8SOlivier Moysan .dr = STM32H7_ADC_DR, 504aec6e0d8SOlivier Moysan .ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE }, 505aec6e0d8SOlivier Moysan .ier_ovr = { STM32H7_ADC_IER, STM32H7_OVRIE }, 506aec6e0d8SOlivier Moysan .isr_eoc = { STM32H7_ADC_ISR, STM32H7_EOC }, 507aec6e0d8SOlivier Moysan .isr_ovr = { STM32H7_ADC_ISR, STM32H7_OVR }, 508aec6e0d8SOlivier Moysan .sqr = stm32h7_sq, 509aec6e0d8SOlivier Moysan .exten = { STM32H7_ADC_CFGR, STM32H7_EXTEN_MASK, STM32H7_EXTEN_SHIFT }, 510aec6e0d8SOlivier Moysan .extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK, 511aec6e0d8SOlivier Moysan STM32H7_EXTSEL_SHIFT }, 512aec6e0d8SOlivier Moysan .res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT }, 513aec6e0d8SOlivier Moysan .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 }, 514aec6e0d8SOlivier Moysan .smp_bits = stm32h7_smp_bits, 515aec6e0d8SOlivier Moysan .or_vdd = { STM32MP1_ADC2_OR, STM32MP1_VDDCOREEN }, 516aec6e0d8SOlivier Moysan .ccr_vbat = { STM32H7_ADC_CCR, STM32H7_VBATEN }, 517aec6e0d8SOlivier Moysan .ccr_vref = { STM32H7_ADC_CCR, STM32H7_VREFEN }, 518aec6e0d8SOlivier Moysan }; 519aec6e0d8SOlivier Moysan 520fb6da706SJonathan Cameron /* 5210f883b22SFabrice Gasnier * STM32 ADC registers access routines 5220f883b22SFabrice Gasnier * @adc: stm32 adc instance 5230f883b22SFabrice Gasnier * @reg: reg offset in adc instance 5240f883b22SFabrice Gasnier * 5250f883b22SFabrice Gasnier * Note: All instances share same base, with 0x0, 0x100 or 0x200 offset resp. 5260f883b22SFabrice Gasnier * for adc1, adc2 and adc3. 5270f883b22SFabrice Gasnier */ 5280f883b22SFabrice Gasnier static u32 stm32_adc_readl(struct stm32_adc *adc, u32 reg) 5290f883b22SFabrice Gasnier { 5300f883b22SFabrice Gasnier return readl_relaxed(adc->common->base + adc->offset + reg); 5310f883b22SFabrice Gasnier } 5320f883b22SFabrice Gasnier 53395e339b6SFabrice Gasnier #define stm32_adc_readl_addr(addr) stm32_adc_readl(adc, addr) 53495e339b6SFabrice Gasnier 53595e339b6SFabrice Gasnier #define stm32_adc_readl_poll_timeout(reg, val, cond, sleep_us, timeout_us) \ 53695e339b6SFabrice Gasnier readx_poll_timeout(stm32_adc_readl_addr, reg, val, \ 53795e339b6SFabrice Gasnier cond, sleep_us, timeout_us) 53895e339b6SFabrice Gasnier 5390f883b22SFabrice Gasnier static u16 stm32_adc_readw(struct stm32_adc *adc, u32 reg) 5400f883b22SFabrice Gasnier { 5410f883b22SFabrice Gasnier return readw_relaxed(adc->common->base + adc->offset + reg); 5420f883b22SFabrice Gasnier } 5430f883b22SFabrice Gasnier 5440f883b22SFabrice Gasnier static void stm32_adc_writel(struct stm32_adc *adc, u32 reg, u32 val) 5450f883b22SFabrice Gasnier { 5460f883b22SFabrice Gasnier writel_relaxed(val, adc->common->base + adc->offset + reg); 5470f883b22SFabrice Gasnier } 5480f883b22SFabrice Gasnier 5490f883b22SFabrice Gasnier static void stm32_adc_set_bits(struct stm32_adc *adc, u32 reg, u32 bits) 5500f883b22SFabrice Gasnier { 5510f883b22SFabrice Gasnier unsigned long flags; 5520f883b22SFabrice Gasnier 5530f883b22SFabrice Gasnier spin_lock_irqsave(&adc->lock, flags); 5540f883b22SFabrice Gasnier stm32_adc_writel(adc, reg, stm32_adc_readl(adc, reg) | bits); 5550f883b22SFabrice Gasnier spin_unlock_irqrestore(&adc->lock, flags); 5560f883b22SFabrice Gasnier } 5570f883b22SFabrice Gasnier 558aec6e0d8SOlivier Moysan static void stm32_adc_set_bits_common(struct stm32_adc *adc, u32 reg, u32 bits) 559aec6e0d8SOlivier Moysan { 560aec6e0d8SOlivier Moysan spin_lock(&adc->common->lock); 561aec6e0d8SOlivier Moysan writel_relaxed(readl_relaxed(adc->common->base + reg) | bits, 562aec6e0d8SOlivier Moysan adc->common->base + reg); 563aec6e0d8SOlivier Moysan spin_unlock(&adc->common->lock); 564aec6e0d8SOlivier Moysan } 565aec6e0d8SOlivier Moysan 5660f883b22SFabrice Gasnier static void stm32_adc_clr_bits(struct stm32_adc *adc, u32 reg, u32 bits) 5670f883b22SFabrice Gasnier { 5680f883b22SFabrice Gasnier unsigned long flags; 5690f883b22SFabrice Gasnier 5700f883b22SFabrice Gasnier spin_lock_irqsave(&adc->lock, flags); 5710f883b22SFabrice Gasnier stm32_adc_writel(adc, reg, stm32_adc_readl(adc, reg) & ~bits); 5720f883b22SFabrice Gasnier spin_unlock_irqrestore(&adc->lock, flags); 5730f883b22SFabrice Gasnier } 5740f883b22SFabrice Gasnier 575aec6e0d8SOlivier Moysan static void stm32_adc_clr_bits_common(struct stm32_adc *adc, u32 reg, u32 bits) 576aec6e0d8SOlivier Moysan { 577aec6e0d8SOlivier Moysan spin_lock(&adc->common->lock); 578aec6e0d8SOlivier Moysan writel_relaxed(readl_relaxed(adc->common->base + reg) & ~bits, 579aec6e0d8SOlivier Moysan adc->common->base + reg); 580aec6e0d8SOlivier Moysan spin_unlock(&adc->common->lock); 581aec6e0d8SOlivier Moysan } 582aec6e0d8SOlivier Moysan 5830f883b22SFabrice Gasnier /** 5840f883b22SFabrice Gasnier * stm32_adc_conv_irq_enable() - Enable end of conversion interrupt 5850f883b22SFabrice Gasnier * @adc: stm32 adc instance 5860f883b22SFabrice Gasnier */ 5870f883b22SFabrice Gasnier static void stm32_adc_conv_irq_enable(struct stm32_adc *adc) 5880f883b22SFabrice Gasnier { 58964ad7f64SFabrice Gasnier stm32_adc_set_bits(adc, adc->cfg->regs->ier_eoc.reg, 59064ad7f64SFabrice Gasnier adc->cfg->regs->ier_eoc.mask); 5910f883b22SFabrice Gasnier }; 5920f883b22SFabrice Gasnier 5930f883b22SFabrice Gasnier /** 5940f883b22SFabrice Gasnier * stm32_adc_conv_irq_disable() - Disable end of conversion interrupt 5950f883b22SFabrice Gasnier * @adc: stm32 adc instance 5960f883b22SFabrice Gasnier */ 5970f883b22SFabrice Gasnier static void stm32_adc_conv_irq_disable(struct stm32_adc *adc) 5980f883b22SFabrice Gasnier { 59964ad7f64SFabrice Gasnier stm32_adc_clr_bits(adc, adc->cfg->regs->ier_eoc.reg, 60064ad7f64SFabrice Gasnier adc->cfg->regs->ier_eoc.mask); 6010f883b22SFabrice Gasnier } 6020f883b22SFabrice Gasnier 603cc06e67dSFabrice Gasnier static void stm32_adc_ovr_irq_enable(struct stm32_adc *adc) 604cc06e67dSFabrice Gasnier { 605cc06e67dSFabrice Gasnier stm32_adc_set_bits(adc, adc->cfg->regs->ier_ovr.reg, 606cc06e67dSFabrice Gasnier adc->cfg->regs->ier_ovr.mask); 607cc06e67dSFabrice Gasnier } 608cc06e67dSFabrice Gasnier 609cc06e67dSFabrice Gasnier static void stm32_adc_ovr_irq_disable(struct stm32_adc *adc) 610cc06e67dSFabrice Gasnier { 611cc06e67dSFabrice Gasnier stm32_adc_clr_bits(adc, adc->cfg->regs->ier_ovr.reg, 612cc06e67dSFabrice Gasnier adc->cfg->regs->ier_ovr.mask); 613cc06e67dSFabrice Gasnier } 614cc06e67dSFabrice Gasnier 61525a85bedSFabrice Gasnier static void stm32_adc_set_res(struct stm32_adc *adc) 61625a85bedSFabrice Gasnier { 61764ad7f64SFabrice Gasnier const struct stm32_adc_regs *res = &adc->cfg->regs->res; 61864ad7f64SFabrice Gasnier u32 val; 61925a85bedSFabrice Gasnier 62064ad7f64SFabrice Gasnier val = stm32_adc_readl(adc, res->reg); 62164ad7f64SFabrice Gasnier val = (val & ~res->mask) | (adc->res << res->shift); 62264ad7f64SFabrice Gasnier stm32_adc_writel(adc, res->reg, val); 62325a85bedSFabrice Gasnier } 62425a85bedSFabrice Gasnier 6259bdbb113SFabrice Gasnier static int stm32_adc_hw_stop(struct device *dev) 6269bdbb113SFabrice Gasnier { 627cd64d357SAlexandru Ardelean struct iio_dev *indio_dev = dev_get_drvdata(dev); 628cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 6299bdbb113SFabrice Gasnier 6309bdbb113SFabrice Gasnier if (adc->cfg->unprepare) 631cd64d357SAlexandru Ardelean adc->cfg->unprepare(indio_dev); 6329bdbb113SFabrice Gasnier 6339bdbb113SFabrice Gasnier clk_disable_unprepare(adc->clk); 6349bdbb113SFabrice Gasnier 6359bdbb113SFabrice Gasnier return 0; 6369bdbb113SFabrice Gasnier } 6379bdbb113SFabrice Gasnier 6389bdbb113SFabrice Gasnier static int stm32_adc_hw_start(struct device *dev) 6399bdbb113SFabrice Gasnier { 640cd64d357SAlexandru Ardelean struct iio_dev *indio_dev = dev_get_drvdata(dev); 641cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 6429bdbb113SFabrice Gasnier int ret; 6439bdbb113SFabrice Gasnier 6449bdbb113SFabrice Gasnier ret = clk_prepare_enable(adc->clk); 6459bdbb113SFabrice Gasnier if (ret) 6469bdbb113SFabrice Gasnier return ret; 6479bdbb113SFabrice Gasnier 6489bdbb113SFabrice Gasnier stm32_adc_set_res(adc); 6499bdbb113SFabrice Gasnier 6509bdbb113SFabrice Gasnier if (adc->cfg->prepare) { 651cd64d357SAlexandru Ardelean ret = adc->cfg->prepare(indio_dev); 6529bdbb113SFabrice Gasnier if (ret) 6539bdbb113SFabrice Gasnier goto err_clk_dis; 6549bdbb113SFabrice Gasnier } 6559bdbb113SFabrice Gasnier 6569bdbb113SFabrice Gasnier return 0; 6579bdbb113SFabrice Gasnier 6589bdbb113SFabrice Gasnier err_clk_dis: 6599bdbb113SFabrice Gasnier clk_disable_unprepare(adc->clk); 6609bdbb113SFabrice Gasnier 6619bdbb113SFabrice Gasnier return ret; 6629bdbb113SFabrice Gasnier } 6639bdbb113SFabrice Gasnier 664aec6e0d8SOlivier Moysan static void stm32_adc_int_ch_enable(struct iio_dev *indio_dev) 665aec6e0d8SOlivier Moysan { 666aec6e0d8SOlivier Moysan struct stm32_adc *adc = iio_priv(indio_dev); 667aec6e0d8SOlivier Moysan u32 i; 668aec6e0d8SOlivier Moysan 669aec6e0d8SOlivier Moysan for (i = 0; i < STM32_ADC_INT_CH_NB; i++) { 670aec6e0d8SOlivier Moysan if (adc->int_ch[i] == STM32_ADC_INT_CH_NONE) 671aec6e0d8SOlivier Moysan continue; 672aec6e0d8SOlivier Moysan 673aec6e0d8SOlivier Moysan switch (i) { 674aec6e0d8SOlivier Moysan case STM32_ADC_INT_CH_VDDCORE: 675aec6e0d8SOlivier Moysan dev_dbg(&indio_dev->dev, "Enable VDDCore\n"); 676aec6e0d8SOlivier Moysan stm32_adc_set_bits(adc, adc->cfg->regs->or_vdd.reg, 677aec6e0d8SOlivier Moysan adc->cfg->regs->or_vdd.mask); 678aec6e0d8SOlivier Moysan break; 679aec6e0d8SOlivier Moysan case STM32_ADC_INT_CH_VREFINT: 680aec6e0d8SOlivier Moysan dev_dbg(&indio_dev->dev, "Enable VREFInt\n"); 681aec6e0d8SOlivier Moysan stm32_adc_set_bits_common(adc, adc->cfg->regs->ccr_vref.reg, 682aec6e0d8SOlivier Moysan adc->cfg->regs->ccr_vref.mask); 683aec6e0d8SOlivier Moysan break; 684aec6e0d8SOlivier Moysan case STM32_ADC_INT_CH_VBAT: 685aec6e0d8SOlivier Moysan dev_dbg(&indio_dev->dev, "Enable VBAT\n"); 686aec6e0d8SOlivier Moysan stm32_adc_set_bits_common(adc, adc->cfg->regs->ccr_vbat.reg, 687aec6e0d8SOlivier Moysan adc->cfg->regs->ccr_vbat.mask); 688aec6e0d8SOlivier Moysan break; 689aec6e0d8SOlivier Moysan } 690aec6e0d8SOlivier Moysan } 691aec6e0d8SOlivier Moysan } 692aec6e0d8SOlivier Moysan 693aec6e0d8SOlivier Moysan static void stm32_adc_int_ch_disable(struct stm32_adc *adc) 694aec6e0d8SOlivier Moysan { 695aec6e0d8SOlivier Moysan u32 i; 696aec6e0d8SOlivier Moysan 697aec6e0d8SOlivier Moysan for (i = 0; i < STM32_ADC_INT_CH_NB; i++) { 698aec6e0d8SOlivier Moysan if (adc->int_ch[i] == STM32_ADC_INT_CH_NONE) 699aec6e0d8SOlivier Moysan continue; 700aec6e0d8SOlivier Moysan 701aec6e0d8SOlivier Moysan switch (i) { 702aec6e0d8SOlivier Moysan case STM32_ADC_INT_CH_VDDCORE: 703aec6e0d8SOlivier Moysan stm32_adc_clr_bits(adc, adc->cfg->regs->or_vdd.reg, 704aec6e0d8SOlivier Moysan adc->cfg->regs->or_vdd.mask); 705aec6e0d8SOlivier Moysan break; 706aec6e0d8SOlivier Moysan case STM32_ADC_INT_CH_VREFINT: 707aec6e0d8SOlivier Moysan stm32_adc_clr_bits_common(adc, adc->cfg->regs->ccr_vref.reg, 708aec6e0d8SOlivier Moysan adc->cfg->regs->ccr_vref.mask); 709aec6e0d8SOlivier Moysan break; 710aec6e0d8SOlivier Moysan case STM32_ADC_INT_CH_VBAT: 711aec6e0d8SOlivier Moysan stm32_adc_clr_bits_common(adc, adc->cfg->regs->ccr_vbat.reg, 712aec6e0d8SOlivier Moysan adc->cfg->regs->ccr_vbat.mask); 713aec6e0d8SOlivier Moysan break; 714aec6e0d8SOlivier Moysan } 715aec6e0d8SOlivier Moysan } 716aec6e0d8SOlivier Moysan } 717aec6e0d8SOlivier Moysan 7180f883b22SFabrice Gasnier /** 71964ad7f64SFabrice Gasnier * stm32f4_adc_start_conv() - Start conversions for regular channels. 720cd64d357SAlexandru Ardelean * @indio_dev: IIO device instance 7212763ea05SFabrice Gasnier * @dma: use dma to transfer conversion result 7222763ea05SFabrice Gasnier * 7232763ea05SFabrice Gasnier * Start conversions for regular channels. 7242763ea05SFabrice Gasnier * Also take care of normal or DMA mode. Circular DMA may be used for regular 7252763ea05SFabrice Gasnier * conversions, in IIO buffer modes. Otherwise, use ADC interrupt with direct 7262763ea05SFabrice Gasnier * DR read instead (e.g. read_raw, or triggered buffer mode without DMA). 7270f883b22SFabrice Gasnier */ 728cd64d357SAlexandru Ardelean static void stm32f4_adc_start_conv(struct iio_dev *indio_dev, bool dma) 7290f883b22SFabrice Gasnier { 730cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 731cd64d357SAlexandru Ardelean 7320f883b22SFabrice Gasnier stm32_adc_set_bits(adc, STM32F4_ADC_CR1, STM32F4_SCAN); 7332763ea05SFabrice Gasnier 7342763ea05SFabrice Gasnier if (dma) 7352763ea05SFabrice Gasnier stm32_adc_set_bits(adc, STM32F4_ADC_CR2, 7362763ea05SFabrice Gasnier STM32F4_DMA | STM32F4_DDS); 7372763ea05SFabrice Gasnier 7380f883b22SFabrice Gasnier stm32_adc_set_bits(adc, STM32F4_ADC_CR2, STM32F4_EOCS | STM32F4_ADON); 7390f883b22SFabrice Gasnier 7400f883b22SFabrice Gasnier /* Wait for Power-up time (tSTAB from datasheet) */ 7410f883b22SFabrice Gasnier usleep_range(2, 3); 7420f883b22SFabrice Gasnier 7430f883b22SFabrice Gasnier /* Software start ? (e.g. trigger detection disabled ?) */ 7440f883b22SFabrice Gasnier if (!(stm32_adc_readl(adc, STM32F4_ADC_CR2) & STM32F4_EXTEN_MASK)) 7450f883b22SFabrice Gasnier stm32_adc_set_bits(adc, STM32F4_ADC_CR2, STM32F4_SWSTART); 7460f883b22SFabrice Gasnier } 7470f883b22SFabrice Gasnier 748cd64d357SAlexandru Ardelean static void stm32f4_adc_stop_conv(struct iio_dev *indio_dev) 7490f883b22SFabrice Gasnier { 750cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 751cd64d357SAlexandru Ardelean 7520f883b22SFabrice Gasnier stm32_adc_clr_bits(adc, STM32F4_ADC_CR2, STM32F4_EXTEN_MASK); 7530f883b22SFabrice Gasnier stm32_adc_clr_bits(adc, STM32F4_ADC_SR, STM32F4_STRT); 7540f883b22SFabrice Gasnier 7550f883b22SFabrice Gasnier stm32_adc_clr_bits(adc, STM32F4_ADC_CR1, STM32F4_SCAN); 7562763ea05SFabrice Gasnier stm32_adc_clr_bits(adc, STM32F4_ADC_CR2, 7572763ea05SFabrice Gasnier STM32F4_ADON | STM32F4_DMA | STM32F4_DDS); 7580f883b22SFabrice Gasnier } 7590f883b22SFabrice Gasnier 760695e2f5cSOlivier Moysan static void stm32f4_adc_irq_clear(struct iio_dev *indio_dev, u32 msk) 761695e2f5cSOlivier Moysan { 762695e2f5cSOlivier Moysan struct stm32_adc *adc = iio_priv(indio_dev); 763695e2f5cSOlivier Moysan 764695e2f5cSOlivier Moysan stm32_adc_clr_bits(adc, adc->cfg->regs->isr_eoc.reg, msk); 765695e2f5cSOlivier Moysan } 766695e2f5cSOlivier Moysan 767cd64d357SAlexandru Ardelean static void stm32h7_adc_start_conv(struct iio_dev *indio_dev, bool dma) 76895e339b6SFabrice Gasnier { 769cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 77095e339b6SFabrice Gasnier enum stm32h7_adc_dmngt dmngt; 77195e339b6SFabrice Gasnier unsigned long flags; 77295e339b6SFabrice Gasnier u32 val; 77395e339b6SFabrice Gasnier 77495e339b6SFabrice Gasnier if (dma) 77595e339b6SFabrice Gasnier dmngt = STM32H7_DMNGT_DMA_CIRC; 77695e339b6SFabrice Gasnier else 77795e339b6SFabrice Gasnier dmngt = STM32H7_DMNGT_DR_ONLY; 77895e339b6SFabrice Gasnier 77995e339b6SFabrice Gasnier spin_lock_irqsave(&adc->lock, flags); 78095e339b6SFabrice Gasnier val = stm32_adc_readl(adc, STM32H7_ADC_CFGR); 78195e339b6SFabrice Gasnier val = (val & ~STM32H7_DMNGT_MASK) | (dmngt << STM32H7_DMNGT_SHIFT); 78295e339b6SFabrice Gasnier stm32_adc_writel(adc, STM32H7_ADC_CFGR, val); 78395e339b6SFabrice Gasnier spin_unlock_irqrestore(&adc->lock, flags); 78495e339b6SFabrice Gasnier 78595e339b6SFabrice Gasnier stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADSTART); 78695e339b6SFabrice Gasnier } 78795e339b6SFabrice Gasnier 788cd64d357SAlexandru Ardelean static void stm32h7_adc_stop_conv(struct iio_dev *indio_dev) 78995e339b6SFabrice Gasnier { 790cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 79195e339b6SFabrice Gasnier int ret; 79295e339b6SFabrice Gasnier u32 val; 79395e339b6SFabrice Gasnier 79495e339b6SFabrice Gasnier stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADSTP); 79595e339b6SFabrice Gasnier 79695e339b6SFabrice Gasnier ret = stm32_adc_readl_poll_timeout(STM32H7_ADC_CR, val, 79795e339b6SFabrice Gasnier !(val & (STM32H7_ADSTART)), 79895e339b6SFabrice Gasnier 100, STM32_ADC_TIMEOUT_US); 79995e339b6SFabrice Gasnier if (ret) 80095e339b6SFabrice Gasnier dev_warn(&indio_dev->dev, "stop failed\n"); 80195e339b6SFabrice Gasnier 80295e339b6SFabrice Gasnier stm32_adc_clr_bits(adc, STM32H7_ADC_CFGR, STM32H7_DMNGT_MASK); 80395e339b6SFabrice Gasnier } 80495e339b6SFabrice Gasnier 805695e2f5cSOlivier Moysan static void stm32h7_adc_irq_clear(struct iio_dev *indio_dev, u32 msk) 806695e2f5cSOlivier Moysan { 807695e2f5cSOlivier Moysan struct stm32_adc *adc = iio_priv(indio_dev); 808695e2f5cSOlivier Moysan /* On STM32H7 IRQs are cleared by writing 1 into ISR register */ 809695e2f5cSOlivier Moysan stm32_adc_set_bits(adc, adc->cfg->regs->isr_eoc.reg, msk); 810695e2f5cSOlivier Moysan } 811695e2f5cSOlivier Moysan 812cd64d357SAlexandru Ardelean static int stm32h7_adc_exit_pwr_down(struct iio_dev *indio_dev) 81395e339b6SFabrice Gasnier { 814cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 815d58c67d1SFabrice Gasnier int ret; 816d58c67d1SFabrice Gasnier u32 val; 817d58c67d1SFabrice Gasnier 81895e339b6SFabrice Gasnier /* Exit deep power down, then enable ADC voltage regulator */ 81995e339b6SFabrice Gasnier stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_DEEPPWD); 82095e339b6SFabrice Gasnier stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADVREGEN); 82195e339b6SFabrice Gasnier 82295e339b6SFabrice Gasnier if (adc->common->rate > STM32H7_BOOST_CLKRATE) 82395e339b6SFabrice Gasnier stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_BOOST); 82495e339b6SFabrice Gasnier 82595e339b6SFabrice Gasnier /* Wait for startup time */ 826d58c67d1SFabrice Gasnier if (!adc->cfg->has_vregready) { 82795e339b6SFabrice Gasnier usleep_range(10, 20); 828d58c67d1SFabrice Gasnier return 0; 829d58c67d1SFabrice Gasnier } 830d58c67d1SFabrice Gasnier 831d58c67d1SFabrice Gasnier ret = stm32_adc_readl_poll_timeout(STM32H7_ADC_ISR, val, 832d58c67d1SFabrice Gasnier val & STM32MP1_VREGREADY, 100, 833d58c67d1SFabrice Gasnier STM32_ADC_TIMEOUT_US); 834d58c67d1SFabrice Gasnier if (ret) { 835d58c67d1SFabrice Gasnier stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_DEEPPWD); 836d58c67d1SFabrice Gasnier dev_err(&indio_dev->dev, "Failed to exit power down\n"); 837d58c67d1SFabrice Gasnier } 838d58c67d1SFabrice Gasnier 839d58c67d1SFabrice Gasnier return ret; 84095e339b6SFabrice Gasnier } 84195e339b6SFabrice Gasnier 84295e339b6SFabrice Gasnier static void stm32h7_adc_enter_pwr_down(struct stm32_adc *adc) 84395e339b6SFabrice Gasnier { 84495e339b6SFabrice Gasnier stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_BOOST); 84595e339b6SFabrice Gasnier 84695e339b6SFabrice Gasnier /* Setting DEEPPWD disables ADC vreg and clears ADVREGEN */ 84795e339b6SFabrice Gasnier stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_DEEPPWD); 84895e339b6SFabrice Gasnier } 84995e339b6SFabrice Gasnier 850cd64d357SAlexandru Ardelean static int stm32h7_adc_enable(struct iio_dev *indio_dev) 85195e339b6SFabrice Gasnier { 852cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 85395e339b6SFabrice Gasnier int ret; 85495e339b6SFabrice Gasnier u32 val; 85595e339b6SFabrice Gasnier 85695e339b6SFabrice Gasnier stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADEN); 85795e339b6SFabrice Gasnier 85895e339b6SFabrice Gasnier /* Poll for ADRDY to be set (after adc startup time) */ 85995e339b6SFabrice Gasnier ret = stm32_adc_readl_poll_timeout(STM32H7_ADC_ISR, val, 86095e339b6SFabrice Gasnier val & STM32H7_ADRDY, 86195e339b6SFabrice Gasnier 100, STM32_ADC_TIMEOUT_US); 86295e339b6SFabrice Gasnier if (ret) { 863a3b5655eSFabrice Gasnier stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADDIS); 86495e339b6SFabrice Gasnier dev_err(&indio_dev->dev, "Failed to enable ADC\n"); 865a3b5655eSFabrice Gasnier } else { 866a3b5655eSFabrice Gasnier /* Clear ADRDY by writing one */ 867a3b5655eSFabrice Gasnier stm32_adc_set_bits(adc, STM32H7_ADC_ISR, STM32H7_ADRDY); 86895e339b6SFabrice Gasnier } 86995e339b6SFabrice Gasnier 87095e339b6SFabrice Gasnier return ret; 87195e339b6SFabrice Gasnier } 87295e339b6SFabrice Gasnier 873cd64d357SAlexandru Ardelean static void stm32h7_adc_disable(struct iio_dev *indio_dev) 87495e339b6SFabrice Gasnier { 875cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 87695e339b6SFabrice Gasnier int ret; 87795e339b6SFabrice Gasnier u32 val; 87895e339b6SFabrice Gasnier 87995e339b6SFabrice Gasnier /* Disable ADC and wait until it's effectively disabled */ 88095e339b6SFabrice Gasnier stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADDIS); 88195e339b6SFabrice Gasnier ret = stm32_adc_readl_poll_timeout(STM32H7_ADC_CR, val, 88295e339b6SFabrice Gasnier !(val & STM32H7_ADEN), 100, 88395e339b6SFabrice Gasnier STM32_ADC_TIMEOUT_US); 88495e339b6SFabrice Gasnier if (ret) 88595e339b6SFabrice Gasnier dev_warn(&indio_dev->dev, "Failed to disable\n"); 88695e339b6SFabrice Gasnier } 88795e339b6SFabrice Gasnier 88895e339b6SFabrice Gasnier /** 88995e339b6SFabrice Gasnier * stm32h7_adc_read_selfcalib() - read calibration shadow regs, save result 890cd64d357SAlexandru Ardelean * @indio_dev: IIO device instance 8910da98c7bSFabrice Gasnier * Note: Must be called once ADC is enabled, so LINCALRDYW[1..6] are writable 89295e339b6SFabrice Gasnier */ 893cd64d357SAlexandru Ardelean static int stm32h7_adc_read_selfcalib(struct iio_dev *indio_dev) 89495e339b6SFabrice Gasnier { 895cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 89695e339b6SFabrice Gasnier int i, ret; 89795e339b6SFabrice Gasnier u32 lincalrdyw_mask, val; 89895e339b6SFabrice Gasnier 89995e339b6SFabrice Gasnier /* Read linearity calibration */ 90095e339b6SFabrice Gasnier lincalrdyw_mask = STM32H7_LINCALRDYW6; 90195e339b6SFabrice Gasnier for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { 90295e339b6SFabrice Gasnier /* Clear STM32H7_LINCALRDYW[6..1]: transfer calib to CALFACT2 */ 90395e339b6SFabrice Gasnier stm32_adc_clr_bits(adc, STM32H7_ADC_CR, lincalrdyw_mask); 90495e339b6SFabrice Gasnier 90595e339b6SFabrice Gasnier /* Poll: wait calib data to be ready in CALFACT2 register */ 90695e339b6SFabrice Gasnier ret = stm32_adc_readl_poll_timeout(STM32H7_ADC_CR, val, 90795e339b6SFabrice Gasnier !(val & lincalrdyw_mask), 90895e339b6SFabrice Gasnier 100, STM32_ADC_TIMEOUT_US); 90995e339b6SFabrice Gasnier if (ret) { 91095e339b6SFabrice Gasnier dev_err(&indio_dev->dev, "Failed to read calfact\n"); 9110da98c7bSFabrice Gasnier return ret; 91295e339b6SFabrice Gasnier } 91395e339b6SFabrice Gasnier 91495e339b6SFabrice Gasnier val = stm32_adc_readl(adc, STM32H7_ADC_CALFACT2); 91595e339b6SFabrice Gasnier adc->cal.lincalfact[i] = (val & STM32H7_LINCALFACT_MASK); 91695e339b6SFabrice Gasnier adc->cal.lincalfact[i] >>= STM32H7_LINCALFACT_SHIFT; 91795e339b6SFabrice Gasnier 91895e339b6SFabrice Gasnier lincalrdyw_mask >>= 1; 91995e339b6SFabrice Gasnier } 92095e339b6SFabrice Gasnier 92195e339b6SFabrice Gasnier /* Read offset calibration */ 92295e339b6SFabrice Gasnier val = stm32_adc_readl(adc, STM32H7_ADC_CALFACT); 92395e339b6SFabrice Gasnier adc->cal.calfact_s = (val & STM32H7_CALFACT_S_MASK); 92495e339b6SFabrice Gasnier adc->cal.calfact_s >>= STM32H7_CALFACT_S_SHIFT; 92595e339b6SFabrice Gasnier adc->cal.calfact_d = (val & STM32H7_CALFACT_D_MASK); 92695e339b6SFabrice Gasnier adc->cal.calfact_d >>= STM32H7_CALFACT_D_SHIFT; 9270da98c7bSFabrice Gasnier adc->cal.calibrated = true; 92895e339b6SFabrice Gasnier 9290da98c7bSFabrice Gasnier return 0; 93095e339b6SFabrice Gasnier } 93195e339b6SFabrice Gasnier 93295e339b6SFabrice Gasnier /** 93395e339b6SFabrice Gasnier * stm32h7_adc_restore_selfcalib() - Restore saved self-calibration result 934cd64d357SAlexandru Ardelean * @indio_dev: IIO device instance 93595e339b6SFabrice Gasnier * Note: ADC must be enabled, with no on-going conversions. 93695e339b6SFabrice Gasnier */ 937cd64d357SAlexandru Ardelean static int stm32h7_adc_restore_selfcalib(struct iio_dev *indio_dev) 93895e339b6SFabrice Gasnier { 939cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 94095e339b6SFabrice Gasnier int i, ret; 94195e339b6SFabrice Gasnier u32 lincalrdyw_mask, val; 94295e339b6SFabrice Gasnier 94395e339b6SFabrice Gasnier val = (adc->cal.calfact_s << STM32H7_CALFACT_S_SHIFT) | 94495e339b6SFabrice Gasnier (adc->cal.calfact_d << STM32H7_CALFACT_D_SHIFT); 94595e339b6SFabrice Gasnier stm32_adc_writel(adc, STM32H7_ADC_CALFACT, val); 94695e339b6SFabrice Gasnier 94795e339b6SFabrice Gasnier lincalrdyw_mask = STM32H7_LINCALRDYW6; 94895e339b6SFabrice Gasnier for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { 94995e339b6SFabrice Gasnier /* 95095e339b6SFabrice Gasnier * Write saved calibration data to shadow registers: 95195e339b6SFabrice Gasnier * Write CALFACT2, and set LINCALRDYW[6..1] bit to trigger 95295e339b6SFabrice Gasnier * data write. Then poll to wait for complete transfer. 95395e339b6SFabrice Gasnier */ 95495e339b6SFabrice Gasnier val = adc->cal.lincalfact[i] << STM32H7_LINCALFACT_SHIFT; 95595e339b6SFabrice Gasnier stm32_adc_writel(adc, STM32H7_ADC_CALFACT2, val); 95695e339b6SFabrice Gasnier stm32_adc_set_bits(adc, STM32H7_ADC_CR, lincalrdyw_mask); 95795e339b6SFabrice Gasnier ret = stm32_adc_readl_poll_timeout(STM32H7_ADC_CR, val, 95895e339b6SFabrice Gasnier val & lincalrdyw_mask, 95995e339b6SFabrice Gasnier 100, STM32_ADC_TIMEOUT_US); 96095e339b6SFabrice Gasnier if (ret) { 96195e339b6SFabrice Gasnier dev_err(&indio_dev->dev, "Failed to write calfact\n"); 96295e339b6SFabrice Gasnier return ret; 96395e339b6SFabrice Gasnier } 96495e339b6SFabrice Gasnier 96595e339b6SFabrice Gasnier /* 96695e339b6SFabrice Gasnier * Read back calibration data, has two effects: 96795e339b6SFabrice Gasnier * - It ensures bits LINCALRDYW[6..1] are kept cleared 96895e339b6SFabrice Gasnier * for next time calibration needs to be restored. 96995e339b6SFabrice Gasnier * - BTW, bit clear triggers a read, then check data has been 97095e339b6SFabrice Gasnier * correctly written. 97195e339b6SFabrice Gasnier */ 97295e339b6SFabrice Gasnier stm32_adc_clr_bits(adc, STM32H7_ADC_CR, lincalrdyw_mask); 97395e339b6SFabrice Gasnier ret = stm32_adc_readl_poll_timeout(STM32H7_ADC_CR, val, 97495e339b6SFabrice Gasnier !(val & lincalrdyw_mask), 97595e339b6SFabrice Gasnier 100, STM32_ADC_TIMEOUT_US); 97695e339b6SFabrice Gasnier if (ret) { 97795e339b6SFabrice Gasnier dev_err(&indio_dev->dev, "Failed to read calfact\n"); 97895e339b6SFabrice Gasnier return ret; 97995e339b6SFabrice Gasnier } 98095e339b6SFabrice Gasnier val = stm32_adc_readl(adc, STM32H7_ADC_CALFACT2); 98195e339b6SFabrice Gasnier if (val != adc->cal.lincalfact[i] << STM32H7_LINCALFACT_SHIFT) { 98295e339b6SFabrice Gasnier dev_err(&indio_dev->dev, "calfact not consistent\n"); 98395e339b6SFabrice Gasnier return -EIO; 98495e339b6SFabrice Gasnier } 98595e339b6SFabrice Gasnier 98695e339b6SFabrice Gasnier lincalrdyw_mask >>= 1; 98795e339b6SFabrice Gasnier } 98895e339b6SFabrice Gasnier 98995e339b6SFabrice Gasnier return 0; 99095e339b6SFabrice Gasnier } 99195e339b6SFabrice Gasnier 992fb6da706SJonathan Cameron /* 99395e339b6SFabrice Gasnier * Fixed timeout value for ADC calibration. 99495e339b6SFabrice Gasnier * worst cases: 99595e339b6SFabrice Gasnier * - low clock frequency 99695e339b6SFabrice Gasnier * - maximum prescalers 99795e339b6SFabrice Gasnier * Calibration requires: 99895e339b6SFabrice Gasnier * - 131,072 ADC clock cycle for the linear calibration 99995e339b6SFabrice Gasnier * - 20 ADC clock cycle for the offset calibration 100095e339b6SFabrice Gasnier * 100195e339b6SFabrice Gasnier * Set to 100ms for now 100295e339b6SFabrice Gasnier */ 100395e339b6SFabrice Gasnier #define STM32H7_ADC_CALIB_TIMEOUT_US 100000 100495e339b6SFabrice Gasnier 100595e339b6SFabrice Gasnier /** 10060da98c7bSFabrice Gasnier * stm32h7_adc_selfcalib() - Procedure to calibrate ADC 1007cd64d357SAlexandru Ardelean * @indio_dev: IIO device instance 10080da98c7bSFabrice Gasnier * Note: Must be called once ADC is out of power down. 100995e339b6SFabrice Gasnier */ 1010cd64d357SAlexandru Ardelean static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev) 101195e339b6SFabrice Gasnier { 1012cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 101395e339b6SFabrice Gasnier int ret; 101495e339b6SFabrice Gasnier u32 val; 101595e339b6SFabrice Gasnier 10160da98c7bSFabrice Gasnier if (adc->cal.calibrated) 10170da98c7bSFabrice Gasnier return true; 101895e339b6SFabrice Gasnier 101995e339b6SFabrice Gasnier /* 102095e339b6SFabrice Gasnier * Select calibration mode: 102195e339b6SFabrice Gasnier * - Offset calibration for single ended inputs 102295e339b6SFabrice Gasnier * - No linearity calibration (do it later, before reading it) 102395e339b6SFabrice Gasnier */ 102495e339b6SFabrice Gasnier stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_ADCALDIF); 102595e339b6SFabrice Gasnier stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_ADCALLIN); 102695e339b6SFabrice Gasnier 102795e339b6SFabrice Gasnier /* Start calibration, then wait for completion */ 102895e339b6SFabrice Gasnier stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADCAL); 102995e339b6SFabrice Gasnier ret = stm32_adc_readl_poll_timeout(STM32H7_ADC_CR, val, 103095e339b6SFabrice Gasnier !(val & STM32H7_ADCAL), 100, 103195e339b6SFabrice Gasnier STM32H7_ADC_CALIB_TIMEOUT_US); 103295e339b6SFabrice Gasnier if (ret) { 103395e339b6SFabrice Gasnier dev_err(&indio_dev->dev, "calibration failed\n"); 10340da98c7bSFabrice Gasnier goto out; 103595e339b6SFabrice Gasnier } 103695e339b6SFabrice Gasnier 103795e339b6SFabrice Gasnier /* 103895e339b6SFabrice Gasnier * Select calibration mode, then start calibration: 103995e339b6SFabrice Gasnier * - Offset calibration for differential input 104095e339b6SFabrice Gasnier * - Linearity calibration (needs to be done only once for single/diff) 104195e339b6SFabrice Gasnier * will run simultaneously with offset calibration. 104295e339b6SFabrice Gasnier */ 104395e339b6SFabrice Gasnier stm32_adc_set_bits(adc, STM32H7_ADC_CR, 104495e339b6SFabrice Gasnier STM32H7_ADCALDIF | STM32H7_ADCALLIN); 104595e339b6SFabrice Gasnier stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADCAL); 104695e339b6SFabrice Gasnier ret = stm32_adc_readl_poll_timeout(STM32H7_ADC_CR, val, 104795e339b6SFabrice Gasnier !(val & STM32H7_ADCAL), 100, 104895e339b6SFabrice Gasnier STM32H7_ADC_CALIB_TIMEOUT_US); 104995e339b6SFabrice Gasnier if (ret) { 105095e339b6SFabrice Gasnier dev_err(&indio_dev->dev, "calibration failed\n"); 10510da98c7bSFabrice Gasnier goto out; 105295e339b6SFabrice Gasnier } 105395e339b6SFabrice Gasnier 10540da98c7bSFabrice Gasnier out: 105595e339b6SFabrice Gasnier stm32_adc_clr_bits(adc, STM32H7_ADC_CR, 105695e339b6SFabrice Gasnier STM32H7_ADCALDIF | STM32H7_ADCALLIN); 105795e339b6SFabrice Gasnier 105895e339b6SFabrice Gasnier return ret; 105995e339b6SFabrice Gasnier } 106095e339b6SFabrice Gasnier 106195e339b6SFabrice Gasnier /** 106295e339b6SFabrice Gasnier * stm32h7_adc_prepare() - Leave power down mode to enable ADC. 1063cd64d357SAlexandru Ardelean * @indio_dev: IIO device instance 106495e339b6SFabrice Gasnier * Leave power down mode. 10653fb2e24eSFabrice Gasnier * Configure channels as single ended or differential before enabling ADC. 106695e339b6SFabrice Gasnier * Enable ADC. 106795e339b6SFabrice Gasnier * Restore calibration data. 10683fb2e24eSFabrice Gasnier * Pre-select channels that may be used in PCSEL (required by input MUX / IO): 10693fb2e24eSFabrice Gasnier * - Only one input is selected for single ended (e.g. 'vinp') 10703fb2e24eSFabrice Gasnier * - Two inputs are selected for differential channels (e.g. 'vinp' & 'vinn') 107195e339b6SFabrice Gasnier */ 1072cd64d357SAlexandru Ardelean static int stm32h7_adc_prepare(struct iio_dev *indio_dev) 107395e339b6SFabrice Gasnier { 1074cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 10750da98c7bSFabrice Gasnier int calib, ret; 107695e339b6SFabrice Gasnier 1077cd64d357SAlexandru Ardelean ret = stm32h7_adc_exit_pwr_down(indio_dev); 1078d58c67d1SFabrice Gasnier if (ret) 1079d58c67d1SFabrice Gasnier return ret; 1080d58c67d1SFabrice Gasnier 1081cd64d357SAlexandru Ardelean ret = stm32h7_adc_selfcalib(indio_dev); 10820da98c7bSFabrice Gasnier if (ret < 0) 10830da98c7bSFabrice Gasnier goto pwr_dwn; 10840da98c7bSFabrice Gasnier calib = ret; 10850da98c7bSFabrice Gasnier 1086aec6e0d8SOlivier Moysan stm32_adc_int_ch_enable(indio_dev); 1087aec6e0d8SOlivier Moysan 10883fb2e24eSFabrice Gasnier stm32_adc_writel(adc, STM32H7_ADC_DIFSEL, adc->difsel); 108995e339b6SFabrice Gasnier 1090cd64d357SAlexandru Ardelean ret = stm32h7_adc_enable(indio_dev); 109195e339b6SFabrice Gasnier if (ret) 1092aec6e0d8SOlivier Moysan goto ch_disable; 109395e339b6SFabrice Gasnier 10940da98c7bSFabrice Gasnier /* Either restore or read calibration result for future reference */ 10950da98c7bSFabrice Gasnier if (calib) 1096cd64d357SAlexandru Ardelean ret = stm32h7_adc_restore_selfcalib(indio_dev); 10970da98c7bSFabrice Gasnier else 1098cd64d357SAlexandru Ardelean ret = stm32h7_adc_read_selfcalib(indio_dev); 109995e339b6SFabrice Gasnier if (ret) 110095e339b6SFabrice Gasnier goto disable; 110195e339b6SFabrice Gasnier 110295e339b6SFabrice Gasnier stm32_adc_writel(adc, STM32H7_ADC_PCSEL, adc->pcsel); 110395e339b6SFabrice Gasnier 110495e339b6SFabrice Gasnier return 0; 110595e339b6SFabrice Gasnier 110695e339b6SFabrice Gasnier disable: 1107cd64d357SAlexandru Ardelean stm32h7_adc_disable(indio_dev); 1108aec6e0d8SOlivier Moysan ch_disable: 1109aec6e0d8SOlivier Moysan stm32_adc_int_ch_disable(adc); 111095e339b6SFabrice Gasnier pwr_dwn: 111195e339b6SFabrice Gasnier stm32h7_adc_enter_pwr_down(adc); 111295e339b6SFabrice Gasnier 111395e339b6SFabrice Gasnier return ret; 111495e339b6SFabrice Gasnier } 111595e339b6SFabrice Gasnier 1116cd64d357SAlexandru Ardelean static void stm32h7_adc_unprepare(struct iio_dev *indio_dev) 111795e339b6SFabrice Gasnier { 1118cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 1119cd64d357SAlexandru Ardelean 1120cd64d357SAlexandru Ardelean stm32h7_adc_disable(indio_dev); 1121aec6e0d8SOlivier Moysan stm32_adc_int_ch_disable(adc); 112295e339b6SFabrice Gasnier stm32h7_adc_enter_pwr_down(adc); 112395e339b6SFabrice Gasnier } 112495e339b6SFabrice Gasnier 11250f883b22SFabrice Gasnier /** 1126da9b9485SFabrice Gasnier * stm32_adc_conf_scan_seq() - Build regular channels scan sequence 1127da9b9485SFabrice Gasnier * @indio_dev: IIO device 1128da9b9485SFabrice Gasnier * @scan_mask: channels to be converted 1129da9b9485SFabrice Gasnier * 1130da9b9485SFabrice Gasnier * Conversion sequence : 1131ee2ac1cdSFabrice Gasnier * Apply sampling time settings for all channels. 1132da9b9485SFabrice Gasnier * Configure ADC scan sequence based on selected channels in scan_mask. 1133da9b9485SFabrice Gasnier * Add channels to SQR registers, from scan_mask LSB to MSB, then 1134da9b9485SFabrice Gasnier * program sequence len. 1135da9b9485SFabrice Gasnier */ 1136da9b9485SFabrice Gasnier static int stm32_adc_conf_scan_seq(struct iio_dev *indio_dev, 1137da9b9485SFabrice Gasnier const unsigned long *scan_mask) 1138da9b9485SFabrice Gasnier { 1139da9b9485SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 114064ad7f64SFabrice Gasnier const struct stm32_adc_regs *sqr = adc->cfg->regs->sqr; 1141da9b9485SFabrice Gasnier const struct iio_chan_spec *chan; 1142da9b9485SFabrice Gasnier u32 val, bit; 1143da9b9485SFabrice Gasnier int i = 0; 1144da9b9485SFabrice Gasnier 1145ee2ac1cdSFabrice Gasnier /* Apply sampling time settings */ 1146ee2ac1cdSFabrice Gasnier stm32_adc_writel(adc, adc->cfg->regs->smpr[0], adc->smpr_val[0]); 1147ee2ac1cdSFabrice Gasnier stm32_adc_writel(adc, adc->cfg->regs->smpr[1], adc->smpr_val[1]); 1148ee2ac1cdSFabrice Gasnier 1149da9b9485SFabrice Gasnier for_each_set_bit(bit, scan_mask, indio_dev->masklength) { 1150da9b9485SFabrice Gasnier chan = indio_dev->channels + bit; 1151da9b9485SFabrice Gasnier /* 1152da9b9485SFabrice Gasnier * Assign one channel per SQ entry in regular 1153da9b9485SFabrice Gasnier * sequence, starting with SQ1. 1154da9b9485SFabrice Gasnier */ 1155da9b9485SFabrice Gasnier i++; 1156da9b9485SFabrice Gasnier if (i > STM32_ADC_MAX_SQ) 1157da9b9485SFabrice Gasnier return -EINVAL; 1158da9b9485SFabrice Gasnier 1159da9b9485SFabrice Gasnier dev_dbg(&indio_dev->dev, "%s chan %d to SQ%d\n", 1160da9b9485SFabrice Gasnier __func__, chan->channel, i); 1161da9b9485SFabrice Gasnier 116264ad7f64SFabrice Gasnier val = stm32_adc_readl(adc, sqr[i].reg); 116364ad7f64SFabrice Gasnier val &= ~sqr[i].mask; 116464ad7f64SFabrice Gasnier val |= chan->channel << sqr[i].shift; 116564ad7f64SFabrice Gasnier stm32_adc_writel(adc, sqr[i].reg, val); 1166da9b9485SFabrice Gasnier } 1167da9b9485SFabrice Gasnier 1168da9b9485SFabrice Gasnier if (!i) 1169da9b9485SFabrice Gasnier return -EINVAL; 1170da9b9485SFabrice Gasnier 1171da9b9485SFabrice Gasnier /* Sequence len */ 117264ad7f64SFabrice Gasnier val = stm32_adc_readl(adc, sqr[0].reg); 117364ad7f64SFabrice Gasnier val &= ~sqr[0].mask; 117464ad7f64SFabrice Gasnier val |= ((i - 1) << sqr[0].shift); 117564ad7f64SFabrice Gasnier stm32_adc_writel(adc, sqr[0].reg, val); 1176da9b9485SFabrice Gasnier 1177da9b9485SFabrice Gasnier return 0; 1178da9b9485SFabrice Gasnier } 1179da9b9485SFabrice Gasnier 1180da9b9485SFabrice Gasnier /** 1181da9b9485SFabrice Gasnier * stm32_adc_get_trig_extsel() - Get external trigger selection 11821cd92d42SFabrice Gasnier * @indio_dev: IIO device structure 1183da9b9485SFabrice Gasnier * @trig: trigger 1184da9b9485SFabrice Gasnier * 1185da9b9485SFabrice Gasnier * Returns trigger extsel value, if trig matches, -EINVAL otherwise. 1186da9b9485SFabrice Gasnier */ 118764ad7f64SFabrice Gasnier static int stm32_adc_get_trig_extsel(struct iio_dev *indio_dev, 118864ad7f64SFabrice Gasnier struct iio_trigger *trig) 1189da9b9485SFabrice Gasnier { 119064ad7f64SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 1191f24a33b3SFabrice Gasnier int i; 1192f24a33b3SFabrice Gasnier 1193f24a33b3SFabrice Gasnier /* lookup triggers registered by stm32 timer trigger driver */ 119464ad7f64SFabrice Gasnier for (i = 0; adc->cfg->trigs[i].name; i++) { 1195f24a33b3SFabrice Gasnier /** 1196f24a33b3SFabrice Gasnier * Checking both stm32 timer trigger type and trig name 1197f24a33b3SFabrice Gasnier * should be safe against arbitrary trigger names. 1198f24a33b3SFabrice Gasnier */ 1199f0b638a7SFabrice Gasnier if ((is_stm32_timer_trigger(trig) || 1200f0b638a7SFabrice Gasnier is_stm32_lptim_trigger(trig)) && 120164ad7f64SFabrice Gasnier !strcmp(adc->cfg->trigs[i].name, trig->name)) { 120264ad7f64SFabrice Gasnier return adc->cfg->trigs[i].extsel; 1203f24a33b3SFabrice Gasnier } 1204f24a33b3SFabrice Gasnier } 1205f24a33b3SFabrice Gasnier 1206da9b9485SFabrice Gasnier return -EINVAL; 1207da9b9485SFabrice Gasnier } 1208da9b9485SFabrice Gasnier 1209da9b9485SFabrice Gasnier /** 1210da9b9485SFabrice Gasnier * stm32_adc_set_trig() - Set a regular trigger 1211da9b9485SFabrice Gasnier * @indio_dev: IIO device 1212da9b9485SFabrice Gasnier * @trig: IIO trigger 1213da9b9485SFabrice Gasnier * 1214da9b9485SFabrice Gasnier * Set trigger source/polarity (e.g. SW, or HW with polarity) : 1215da9b9485SFabrice Gasnier * - if HW trigger disabled (e.g. trig == NULL, conversion launched by sw) 1216da9b9485SFabrice Gasnier * - if HW trigger enabled, set source & polarity 1217da9b9485SFabrice Gasnier */ 1218da9b9485SFabrice Gasnier static int stm32_adc_set_trig(struct iio_dev *indio_dev, 1219da9b9485SFabrice Gasnier struct iio_trigger *trig) 1220da9b9485SFabrice Gasnier { 1221da9b9485SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 1222da9b9485SFabrice Gasnier u32 val, extsel = 0, exten = STM32_EXTEN_SWTRIG; 1223da9b9485SFabrice Gasnier unsigned long flags; 1224da9b9485SFabrice Gasnier int ret; 1225da9b9485SFabrice Gasnier 1226da9b9485SFabrice Gasnier if (trig) { 122764ad7f64SFabrice Gasnier ret = stm32_adc_get_trig_extsel(indio_dev, trig); 1228da9b9485SFabrice Gasnier if (ret < 0) 1229da9b9485SFabrice Gasnier return ret; 1230da9b9485SFabrice Gasnier 1231da9b9485SFabrice Gasnier /* set trigger source and polarity (default to rising edge) */ 1232da9b9485SFabrice Gasnier extsel = ret; 1233732f2dc4SFabrice Gasnier exten = adc->trigger_polarity + STM32_EXTEN_HWTRIG_RISING_EDGE; 1234da9b9485SFabrice Gasnier } 1235da9b9485SFabrice Gasnier 1236da9b9485SFabrice Gasnier spin_lock_irqsave(&adc->lock, flags); 123764ad7f64SFabrice Gasnier val = stm32_adc_readl(adc, adc->cfg->regs->exten.reg); 123864ad7f64SFabrice Gasnier val &= ~(adc->cfg->regs->exten.mask | adc->cfg->regs->extsel.mask); 123964ad7f64SFabrice Gasnier val |= exten << adc->cfg->regs->exten.shift; 124064ad7f64SFabrice Gasnier val |= extsel << adc->cfg->regs->extsel.shift; 124164ad7f64SFabrice Gasnier stm32_adc_writel(adc, adc->cfg->regs->exten.reg, val); 1242da9b9485SFabrice Gasnier spin_unlock_irqrestore(&adc->lock, flags); 1243da9b9485SFabrice Gasnier 1244da9b9485SFabrice Gasnier return 0; 1245da9b9485SFabrice Gasnier } 1246da9b9485SFabrice Gasnier 1247732f2dc4SFabrice Gasnier static int stm32_adc_set_trig_pol(struct iio_dev *indio_dev, 1248732f2dc4SFabrice Gasnier const struct iio_chan_spec *chan, 1249732f2dc4SFabrice Gasnier unsigned int type) 1250732f2dc4SFabrice Gasnier { 1251732f2dc4SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 1252732f2dc4SFabrice Gasnier 1253732f2dc4SFabrice Gasnier adc->trigger_polarity = type; 1254732f2dc4SFabrice Gasnier 1255732f2dc4SFabrice Gasnier return 0; 1256732f2dc4SFabrice Gasnier } 1257732f2dc4SFabrice Gasnier 1258732f2dc4SFabrice Gasnier static int stm32_adc_get_trig_pol(struct iio_dev *indio_dev, 1259732f2dc4SFabrice Gasnier const struct iio_chan_spec *chan) 1260732f2dc4SFabrice Gasnier { 1261732f2dc4SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 1262732f2dc4SFabrice Gasnier 1263732f2dc4SFabrice Gasnier return adc->trigger_polarity; 1264732f2dc4SFabrice Gasnier } 1265732f2dc4SFabrice Gasnier 1266732f2dc4SFabrice Gasnier static const char * const stm32_trig_pol_items[] = { 1267732f2dc4SFabrice Gasnier "rising-edge", "falling-edge", "both-edges", 1268732f2dc4SFabrice Gasnier }; 1269732f2dc4SFabrice Gasnier 12702763ea05SFabrice Gasnier static const struct iio_enum stm32_adc_trig_pol = { 1271732f2dc4SFabrice Gasnier .items = stm32_trig_pol_items, 1272732f2dc4SFabrice Gasnier .num_items = ARRAY_SIZE(stm32_trig_pol_items), 1273732f2dc4SFabrice Gasnier .get = stm32_adc_get_trig_pol, 1274732f2dc4SFabrice Gasnier .set = stm32_adc_set_trig_pol, 1275732f2dc4SFabrice Gasnier }; 1276732f2dc4SFabrice Gasnier 1277da9b9485SFabrice Gasnier /** 12780f883b22SFabrice Gasnier * stm32_adc_single_conv() - Performs a single conversion 12790f883b22SFabrice Gasnier * @indio_dev: IIO device 12800f883b22SFabrice Gasnier * @chan: IIO channel 12810f883b22SFabrice Gasnier * @res: conversion result 12820f883b22SFabrice Gasnier * 12830f883b22SFabrice Gasnier * The function performs a single conversion on a given channel: 1284ee2ac1cdSFabrice Gasnier * - Apply sampling time settings 12850f883b22SFabrice Gasnier * - Program sequencer with one channel (e.g. in SQ1 with len = 1) 12860f883b22SFabrice Gasnier * - Use SW trigger 12870f883b22SFabrice Gasnier * - Start conversion, then wait for interrupt completion. 12880f883b22SFabrice Gasnier */ 12890f883b22SFabrice Gasnier static int stm32_adc_single_conv(struct iio_dev *indio_dev, 12900f883b22SFabrice Gasnier const struct iio_chan_spec *chan, 12910f883b22SFabrice Gasnier int *res) 12920f883b22SFabrice Gasnier { 12930f883b22SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 12949bdbb113SFabrice Gasnier struct device *dev = indio_dev->dev.parent; 129564ad7f64SFabrice Gasnier const struct stm32_adc_regspec *regs = adc->cfg->regs; 12960f883b22SFabrice Gasnier long timeout; 12970f883b22SFabrice Gasnier u32 val; 12980f883b22SFabrice Gasnier int ret; 12990f883b22SFabrice Gasnier 13000f883b22SFabrice Gasnier reinit_completion(&adc->completion); 13010f883b22SFabrice Gasnier 1302da9b9485SFabrice Gasnier adc->bufi = 0; 13030f883b22SFabrice Gasnier 1304265028b8SJonathan Cameron ret = pm_runtime_resume_and_get(dev); 1305265028b8SJonathan Cameron if (ret < 0) 130695e339b6SFabrice Gasnier return ret; 130795e339b6SFabrice Gasnier 1308ee2ac1cdSFabrice Gasnier /* Apply sampling time settings */ 1309ee2ac1cdSFabrice Gasnier stm32_adc_writel(adc, regs->smpr[0], adc->smpr_val[0]); 1310ee2ac1cdSFabrice Gasnier stm32_adc_writel(adc, regs->smpr[1], adc->smpr_val[1]); 1311ee2ac1cdSFabrice Gasnier 1312da9b9485SFabrice Gasnier /* Program chan number in regular sequence (SQ1) */ 131364ad7f64SFabrice Gasnier val = stm32_adc_readl(adc, regs->sqr[1].reg); 131464ad7f64SFabrice Gasnier val &= ~regs->sqr[1].mask; 131564ad7f64SFabrice Gasnier val |= chan->channel << regs->sqr[1].shift; 131664ad7f64SFabrice Gasnier stm32_adc_writel(adc, regs->sqr[1].reg, val); 13170f883b22SFabrice Gasnier 13180f883b22SFabrice Gasnier /* Set regular sequence len (0 for 1 conversion) */ 131964ad7f64SFabrice Gasnier stm32_adc_clr_bits(adc, regs->sqr[0].reg, regs->sqr[0].mask); 13200f883b22SFabrice Gasnier 13210f883b22SFabrice Gasnier /* Trigger detection disabled (conversion can be launched in SW) */ 132264ad7f64SFabrice Gasnier stm32_adc_clr_bits(adc, regs->exten.reg, regs->exten.mask); 13230f883b22SFabrice Gasnier 13240f883b22SFabrice Gasnier stm32_adc_conv_irq_enable(adc); 13250f883b22SFabrice Gasnier 1326cd64d357SAlexandru Ardelean adc->cfg->start_conv(indio_dev, false); 13270f883b22SFabrice Gasnier 13280f883b22SFabrice Gasnier timeout = wait_for_completion_interruptible_timeout( 13290f883b22SFabrice Gasnier &adc->completion, STM32_ADC_TIMEOUT); 13300f883b22SFabrice Gasnier if (timeout == 0) { 13310f883b22SFabrice Gasnier ret = -ETIMEDOUT; 13320f883b22SFabrice Gasnier } else if (timeout < 0) { 13330f883b22SFabrice Gasnier ret = timeout; 13340f883b22SFabrice Gasnier } else { 1335da9b9485SFabrice Gasnier *res = adc->buffer[0]; 13360f883b22SFabrice Gasnier ret = IIO_VAL_INT; 13370f883b22SFabrice Gasnier } 13380f883b22SFabrice Gasnier 1339cd64d357SAlexandru Ardelean adc->cfg->stop_conv(indio_dev); 13400f883b22SFabrice Gasnier 13410f883b22SFabrice Gasnier stm32_adc_conv_irq_disable(adc); 13420f883b22SFabrice Gasnier 13439bdbb113SFabrice Gasnier pm_runtime_mark_last_busy(dev); 13449bdbb113SFabrice Gasnier pm_runtime_put_autosuspend(dev); 134595e339b6SFabrice Gasnier 13460f883b22SFabrice Gasnier return ret; 13470f883b22SFabrice Gasnier } 13480f883b22SFabrice Gasnier 13490f883b22SFabrice Gasnier static int stm32_adc_read_raw(struct iio_dev *indio_dev, 13500f883b22SFabrice Gasnier struct iio_chan_spec const *chan, 13510f883b22SFabrice Gasnier int *val, int *val2, long mask) 13520f883b22SFabrice Gasnier { 13530f883b22SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 13540f883b22SFabrice Gasnier int ret; 13550f883b22SFabrice Gasnier 13560f883b22SFabrice Gasnier switch (mask) { 13570f883b22SFabrice Gasnier case IIO_CHAN_INFO_RAW: 13580e346b2cSOlivier Moysan case IIO_CHAN_INFO_PROCESSED: 13590f883b22SFabrice Gasnier ret = iio_device_claim_direct_mode(indio_dev); 13600f883b22SFabrice Gasnier if (ret) 13610f883b22SFabrice Gasnier return ret; 13620f883b22SFabrice Gasnier if (chan->type == IIO_VOLTAGE) 13630f883b22SFabrice Gasnier ret = stm32_adc_single_conv(indio_dev, chan, val); 13640f883b22SFabrice Gasnier else 13650f883b22SFabrice Gasnier ret = -EINVAL; 13660e346b2cSOlivier Moysan 13670e346b2cSOlivier Moysan if (mask == IIO_CHAN_INFO_PROCESSED && adc->vrefint.vrefint_cal) 13680e346b2cSOlivier Moysan *val = STM32_ADC_VREFINT_VOLTAGE * adc->vrefint.vrefint_cal / *val; 13690e346b2cSOlivier Moysan 13700f883b22SFabrice Gasnier iio_device_release_direct_mode(indio_dev); 13710f883b22SFabrice Gasnier return ret; 13720f883b22SFabrice Gasnier 13730f883b22SFabrice Gasnier case IIO_CHAN_INFO_SCALE: 13743fb2e24eSFabrice Gasnier if (chan->differential) { 13753fb2e24eSFabrice Gasnier *val = adc->common->vref_mv * 2; 13763fb2e24eSFabrice Gasnier *val2 = chan->scan_type.realbits; 13773fb2e24eSFabrice Gasnier } else { 13780f883b22SFabrice Gasnier *val = adc->common->vref_mv; 13790f883b22SFabrice Gasnier *val2 = chan->scan_type.realbits; 13803fb2e24eSFabrice Gasnier } 13810f883b22SFabrice Gasnier return IIO_VAL_FRACTIONAL_LOG2; 13820f883b22SFabrice Gasnier 13833fb2e24eSFabrice Gasnier case IIO_CHAN_INFO_OFFSET: 13843fb2e24eSFabrice Gasnier if (chan->differential) 13853fb2e24eSFabrice Gasnier /* ADC_full_scale / 2 */ 13863fb2e24eSFabrice Gasnier *val = -((1 << chan->scan_type.realbits) / 2); 13873fb2e24eSFabrice Gasnier else 13883fb2e24eSFabrice Gasnier *val = 0; 13893fb2e24eSFabrice Gasnier return IIO_VAL_INT; 13903fb2e24eSFabrice Gasnier 13910f883b22SFabrice Gasnier default: 13920f883b22SFabrice Gasnier return -EINVAL; 13930f883b22SFabrice Gasnier } 13940f883b22SFabrice Gasnier } 13950f883b22SFabrice Gasnier 1396695e2f5cSOlivier Moysan static void stm32_adc_irq_clear(struct iio_dev *indio_dev, u32 msk) 1397695e2f5cSOlivier Moysan { 1398695e2f5cSOlivier Moysan struct stm32_adc *adc = iio_priv(indio_dev); 1399695e2f5cSOlivier Moysan 1400695e2f5cSOlivier Moysan adc->cfg->irq_clear(indio_dev, msk); 1401695e2f5cSOlivier Moysan } 1402695e2f5cSOlivier Moysan 1403cc06e67dSFabrice Gasnier static irqreturn_t stm32_adc_threaded_isr(int irq, void *data) 1404cc06e67dSFabrice Gasnier { 1405cd64d357SAlexandru Ardelean struct iio_dev *indio_dev = data; 1406cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 1407cc06e67dSFabrice Gasnier const struct stm32_adc_regspec *regs = adc->cfg->regs; 1408cc06e67dSFabrice Gasnier u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg); 1409695e2f5cSOlivier Moysan u32 mask = stm32_adc_readl(adc, regs->ier_eoc.reg); 1410cc06e67dSFabrice Gasnier 1411695e2f5cSOlivier Moysan /* Check ovr status right now, as ovr mask should be already disabled */ 1412695e2f5cSOlivier Moysan if (status & regs->isr_ovr.mask) { 1413695e2f5cSOlivier Moysan /* 1414695e2f5cSOlivier Moysan * Clear ovr bit to avoid subsequent calls to IRQ handler. 1415695e2f5cSOlivier Moysan * This requires to stop ADC first. OVR bit state in ISR, 1416695e2f5cSOlivier Moysan * is propaged to CSR register by hardware. 1417695e2f5cSOlivier Moysan */ 1418695e2f5cSOlivier Moysan adc->cfg->stop_conv(indio_dev); 1419695e2f5cSOlivier Moysan stm32_adc_irq_clear(indio_dev, regs->isr_ovr.mask); 1420cc06e67dSFabrice Gasnier dev_err(&indio_dev->dev, "Overrun, stopping: restart needed\n"); 1421cc06e67dSFabrice Gasnier return IRQ_HANDLED; 1422cc06e67dSFabrice Gasnier } 1423cc06e67dSFabrice Gasnier 1424695e2f5cSOlivier Moysan if (!(status & mask)) 1425695e2f5cSOlivier Moysan dev_err_ratelimited(&indio_dev->dev, 1426695e2f5cSOlivier Moysan "Unexpected IRQ: IER=0x%08x, ISR=0x%08x\n", 1427695e2f5cSOlivier Moysan mask, status); 1428695e2f5cSOlivier Moysan 1429695e2f5cSOlivier Moysan return IRQ_NONE; 1430695e2f5cSOlivier Moysan } 1431695e2f5cSOlivier Moysan 14320f883b22SFabrice Gasnier static irqreturn_t stm32_adc_isr(int irq, void *data) 14330f883b22SFabrice Gasnier { 1434cd64d357SAlexandru Ardelean struct iio_dev *indio_dev = data; 1435cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 143664ad7f64SFabrice Gasnier const struct stm32_adc_regspec *regs = adc->cfg->regs; 143764ad7f64SFabrice Gasnier u32 status = stm32_adc_readl(adc, regs->isr_eoc.reg); 1438695e2f5cSOlivier Moysan u32 mask = stm32_adc_readl(adc, regs->ier_eoc.reg); 1439695e2f5cSOlivier Moysan 1440695e2f5cSOlivier Moysan if (!(status & mask)) 1441695e2f5cSOlivier Moysan return IRQ_WAKE_THREAD; 14420f883b22SFabrice Gasnier 1443cc06e67dSFabrice Gasnier if (status & regs->isr_ovr.mask) { 1444cc06e67dSFabrice Gasnier /* 1445cc06e67dSFabrice Gasnier * Overrun occurred on regular conversions: data for wrong 1446cc06e67dSFabrice Gasnier * channel may be read. Unconditionally disable interrupts 1447cc06e67dSFabrice Gasnier * to stop processing data and print error message. 1448cc06e67dSFabrice Gasnier * Restarting the capture can be done by disabling, then 1449cc06e67dSFabrice Gasnier * re-enabling it (e.g. write 0, then 1 to buffer/enable). 1450cc06e67dSFabrice Gasnier */ 1451cc06e67dSFabrice Gasnier stm32_adc_ovr_irq_disable(adc); 1452cc06e67dSFabrice Gasnier stm32_adc_conv_irq_disable(adc); 1453cc06e67dSFabrice Gasnier return IRQ_WAKE_THREAD; 1454cc06e67dSFabrice Gasnier } 1455cc06e67dSFabrice Gasnier 145664ad7f64SFabrice Gasnier if (status & regs->isr_eoc.mask) { 1457da9b9485SFabrice Gasnier /* Reading DR also clears EOC status flag */ 145864ad7f64SFabrice Gasnier adc->buffer[adc->bufi] = stm32_adc_readw(adc, regs->dr); 1459da9b9485SFabrice Gasnier if (iio_buffer_enabled(indio_dev)) { 1460da9b9485SFabrice Gasnier adc->bufi++; 1461da9b9485SFabrice Gasnier if (adc->bufi >= adc->num_conv) { 1462da9b9485SFabrice Gasnier stm32_adc_conv_irq_disable(adc); 1463da9b9485SFabrice Gasnier iio_trigger_poll(indio_dev->trig); 1464da9b9485SFabrice Gasnier } 1465da9b9485SFabrice Gasnier } else { 14660f883b22SFabrice Gasnier complete(&adc->completion); 1467da9b9485SFabrice Gasnier } 14680f883b22SFabrice Gasnier return IRQ_HANDLED; 14690f883b22SFabrice Gasnier } 14700f883b22SFabrice Gasnier 14710f883b22SFabrice Gasnier return IRQ_NONE; 14720f883b22SFabrice Gasnier } 14730f883b22SFabrice Gasnier 1474da9b9485SFabrice Gasnier /** 1475da9b9485SFabrice Gasnier * stm32_adc_validate_trigger() - validate trigger for stm32 adc 1476da9b9485SFabrice Gasnier * @indio_dev: IIO device 1477da9b9485SFabrice Gasnier * @trig: new trigger 1478da9b9485SFabrice Gasnier * 1479da9b9485SFabrice Gasnier * Returns: 0 if trig matches one of the triggers registered by stm32 adc 1480da9b9485SFabrice Gasnier * driver, -EINVAL otherwise. 1481da9b9485SFabrice Gasnier */ 1482da9b9485SFabrice Gasnier static int stm32_adc_validate_trigger(struct iio_dev *indio_dev, 1483da9b9485SFabrice Gasnier struct iio_trigger *trig) 1484da9b9485SFabrice Gasnier { 148564ad7f64SFabrice Gasnier return stm32_adc_get_trig_extsel(indio_dev, trig) < 0 ? -EINVAL : 0; 1486da9b9485SFabrice Gasnier } 1487da9b9485SFabrice Gasnier 14882763ea05SFabrice Gasnier static int stm32_adc_set_watermark(struct iio_dev *indio_dev, unsigned int val) 14892763ea05SFabrice Gasnier { 14902763ea05SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 14912763ea05SFabrice Gasnier unsigned int watermark = STM32_DMA_BUFFER_SIZE / 2; 149204e491caSFabrice Gasnier unsigned int rx_buf_sz = STM32_DMA_BUFFER_SIZE; 14932763ea05SFabrice Gasnier 14942763ea05SFabrice Gasnier /* 14952763ea05SFabrice Gasnier * dma cyclic transfers are used, buffer is split into two periods. 14962763ea05SFabrice Gasnier * There should be : 14972763ea05SFabrice Gasnier * - always one buffer (period) dma is working on 1498499da8bdSOlivier Moysan * - one buffer (period) driver can push data. 14992763ea05SFabrice Gasnier */ 15002763ea05SFabrice Gasnier watermark = min(watermark, val * (unsigned)(sizeof(u16))); 150104e491caSFabrice Gasnier adc->rx_buf_sz = min(rx_buf_sz, watermark * 2 * adc->num_conv); 15022763ea05SFabrice Gasnier 15032763ea05SFabrice Gasnier return 0; 15042763ea05SFabrice Gasnier } 15052763ea05SFabrice Gasnier 1506da9b9485SFabrice Gasnier static int stm32_adc_update_scan_mode(struct iio_dev *indio_dev, 1507da9b9485SFabrice Gasnier const unsigned long *scan_mask) 1508da9b9485SFabrice Gasnier { 1509da9b9485SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 15109bdbb113SFabrice Gasnier struct device *dev = indio_dev->dev.parent; 1511da9b9485SFabrice Gasnier int ret; 1512da9b9485SFabrice Gasnier 1513265028b8SJonathan Cameron ret = pm_runtime_resume_and_get(dev); 1514265028b8SJonathan Cameron if (ret < 0) 15159bdbb113SFabrice Gasnier return ret; 15169bdbb113SFabrice Gasnier 1517da9b9485SFabrice Gasnier adc->num_conv = bitmap_weight(scan_mask, indio_dev->masklength); 1518da9b9485SFabrice Gasnier 1519da9b9485SFabrice Gasnier ret = stm32_adc_conf_scan_seq(indio_dev, scan_mask); 15209bdbb113SFabrice Gasnier pm_runtime_mark_last_busy(dev); 15219bdbb113SFabrice Gasnier pm_runtime_put_autosuspend(dev); 1522da9b9485SFabrice Gasnier 15239bdbb113SFabrice Gasnier return ret; 1524da9b9485SFabrice Gasnier } 1525da9b9485SFabrice Gasnier 15260f883b22SFabrice Gasnier static int stm32_adc_of_xlate(struct iio_dev *indio_dev, 15270f883b22SFabrice Gasnier const struct of_phandle_args *iiospec) 15280f883b22SFabrice Gasnier { 15290f883b22SFabrice Gasnier int i; 15300f883b22SFabrice Gasnier 15310f883b22SFabrice Gasnier for (i = 0; i < indio_dev->num_channels; i++) 15320f883b22SFabrice Gasnier if (indio_dev->channels[i].channel == iiospec->args[0]) 15330f883b22SFabrice Gasnier return i; 15340f883b22SFabrice Gasnier 15350f883b22SFabrice Gasnier return -EINVAL; 15360f883b22SFabrice Gasnier } 15370f883b22SFabrice Gasnier 15380f883b22SFabrice Gasnier /** 15390f883b22SFabrice Gasnier * stm32_adc_debugfs_reg_access - read or write register value 15401cd92d42SFabrice Gasnier * @indio_dev: IIO device structure 15411cd92d42SFabrice Gasnier * @reg: register offset 15421cd92d42SFabrice Gasnier * @writeval: value to write 15431cd92d42SFabrice Gasnier * @readval: value to read 15440f883b22SFabrice Gasnier * 15450f883b22SFabrice Gasnier * To read a value from an ADC register: 15460f883b22SFabrice Gasnier * echo [ADC reg offset] > direct_reg_access 15470f883b22SFabrice Gasnier * cat direct_reg_access 15480f883b22SFabrice Gasnier * 15490f883b22SFabrice Gasnier * To write a value in a ADC register: 15500f883b22SFabrice Gasnier * echo [ADC_reg_offset] [value] > direct_reg_access 15510f883b22SFabrice Gasnier */ 15520f883b22SFabrice Gasnier static int stm32_adc_debugfs_reg_access(struct iio_dev *indio_dev, 15530f883b22SFabrice Gasnier unsigned reg, unsigned writeval, 15540f883b22SFabrice Gasnier unsigned *readval) 15550f883b22SFabrice Gasnier { 15560f883b22SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 15579bdbb113SFabrice Gasnier struct device *dev = indio_dev->dev.parent; 15589bdbb113SFabrice Gasnier int ret; 15599bdbb113SFabrice Gasnier 1560265028b8SJonathan Cameron ret = pm_runtime_resume_and_get(dev); 1561265028b8SJonathan Cameron if (ret < 0) 15629bdbb113SFabrice Gasnier return ret; 15630f883b22SFabrice Gasnier 15640f883b22SFabrice Gasnier if (!readval) 15650f883b22SFabrice Gasnier stm32_adc_writel(adc, reg, writeval); 15660f883b22SFabrice Gasnier else 15670f883b22SFabrice Gasnier *readval = stm32_adc_readl(adc, reg); 15680f883b22SFabrice Gasnier 15699bdbb113SFabrice Gasnier pm_runtime_mark_last_busy(dev); 15709bdbb113SFabrice Gasnier pm_runtime_put_autosuspend(dev); 15719bdbb113SFabrice Gasnier 15720f883b22SFabrice Gasnier return 0; 15730f883b22SFabrice Gasnier } 15740f883b22SFabrice Gasnier 15750f883b22SFabrice Gasnier static const struct iio_info stm32_adc_iio_info = { 15760f883b22SFabrice Gasnier .read_raw = stm32_adc_read_raw, 1577da9b9485SFabrice Gasnier .validate_trigger = stm32_adc_validate_trigger, 15782763ea05SFabrice Gasnier .hwfifo_set_watermark = stm32_adc_set_watermark, 1579da9b9485SFabrice Gasnier .update_scan_mode = stm32_adc_update_scan_mode, 15800f883b22SFabrice Gasnier .debugfs_reg_access = stm32_adc_debugfs_reg_access, 15810f883b22SFabrice Gasnier .of_xlate = stm32_adc_of_xlate, 15820f883b22SFabrice Gasnier }; 15830f883b22SFabrice Gasnier 15842763ea05SFabrice Gasnier static unsigned int stm32_adc_dma_residue(struct stm32_adc *adc) 15852763ea05SFabrice Gasnier { 15862763ea05SFabrice Gasnier struct dma_tx_state state; 15872763ea05SFabrice Gasnier enum dma_status status; 15882763ea05SFabrice Gasnier 15892763ea05SFabrice Gasnier status = dmaengine_tx_status(adc->dma_chan, 15902763ea05SFabrice Gasnier adc->dma_chan->cookie, 15912763ea05SFabrice Gasnier &state); 15922763ea05SFabrice Gasnier if (status == DMA_IN_PROGRESS) { 15932763ea05SFabrice Gasnier /* Residue is size in bytes from end of buffer */ 15942763ea05SFabrice Gasnier unsigned int i = adc->rx_buf_sz - state.residue; 15952763ea05SFabrice Gasnier unsigned int size; 15962763ea05SFabrice Gasnier 15972763ea05SFabrice Gasnier /* Return available bytes */ 15982763ea05SFabrice Gasnier if (i >= adc->bufi) 15992763ea05SFabrice Gasnier size = i - adc->bufi; 16002763ea05SFabrice Gasnier else 16012763ea05SFabrice Gasnier size = adc->rx_buf_sz + i - adc->bufi; 16022763ea05SFabrice Gasnier 16032763ea05SFabrice Gasnier return size; 16042763ea05SFabrice Gasnier } 16052763ea05SFabrice Gasnier 16062763ea05SFabrice Gasnier return 0; 16072763ea05SFabrice Gasnier } 16082763ea05SFabrice Gasnier 16092763ea05SFabrice Gasnier static void stm32_adc_dma_buffer_done(void *data) 16102763ea05SFabrice Gasnier { 16112763ea05SFabrice Gasnier struct iio_dev *indio_dev = data; 1612e2042d29SOlivier Moysan struct stm32_adc *adc = iio_priv(indio_dev); 1613e2042d29SOlivier Moysan int residue = stm32_adc_dma_residue(adc); 16142763ea05SFabrice Gasnier 1615e2042d29SOlivier Moysan /* 1616e2042d29SOlivier Moysan * In DMA mode the trigger services of IIO are not used 1617e2042d29SOlivier Moysan * (e.g. no call to iio_trigger_poll). 1618e2042d29SOlivier Moysan * Calling irq handler associated to the hardware trigger is not 1619e2042d29SOlivier Moysan * relevant as the conversions have already been done. Data 1620e2042d29SOlivier Moysan * transfers are performed directly in DMA callback instead. 1621e2042d29SOlivier Moysan * This implementation avoids to call trigger irq handler that 1622e2042d29SOlivier Moysan * may sleep, in an atomic context (DMA irq handler context). 1623e2042d29SOlivier Moysan */ 1624e2042d29SOlivier Moysan dev_dbg(&indio_dev->dev, "%s bufi=%d\n", __func__, adc->bufi); 1625e2042d29SOlivier Moysan 1626e2042d29SOlivier Moysan while (residue >= indio_dev->scan_bytes) { 1627e2042d29SOlivier Moysan u16 *buffer = (u16 *)&adc->rx_buf[adc->bufi]; 1628e2042d29SOlivier Moysan 1629e2042d29SOlivier Moysan iio_push_to_buffers(indio_dev, buffer); 1630e2042d29SOlivier Moysan 1631e2042d29SOlivier Moysan residue -= indio_dev->scan_bytes; 1632e2042d29SOlivier Moysan adc->bufi += indio_dev->scan_bytes; 1633e2042d29SOlivier Moysan if (adc->bufi >= adc->rx_buf_sz) 1634e2042d29SOlivier Moysan adc->bufi = 0; 1635e2042d29SOlivier Moysan } 16362763ea05SFabrice Gasnier } 16372763ea05SFabrice Gasnier 16382763ea05SFabrice Gasnier static int stm32_adc_dma_start(struct iio_dev *indio_dev) 16392763ea05SFabrice Gasnier { 16402763ea05SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 16412763ea05SFabrice Gasnier struct dma_async_tx_descriptor *desc; 16422763ea05SFabrice Gasnier dma_cookie_t cookie; 16432763ea05SFabrice Gasnier int ret; 16442763ea05SFabrice Gasnier 16452763ea05SFabrice Gasnier if (!adc->dma_chan) 16462763ea05SFabrice Gasnier return 0; 16472763ea05SFabrice Gasnier 16482763ea05SFabrice Gasnier dev_dbg(&indio_dev->dev, "%s size=%d watermark=%d\n", __func__, 16492763ea05SFabrice Gasnier adc->rx_buf_sz, adc->rx_buf_sz / 2); 16502763ea05SFabrice Gasnier 16512763ea05SFabrice Gasnier /* Prepare a DMA cyclic transaction */ 16522763ea05SFabrice Gasnier desc = dmaengine_prep_dma_cyclic(adc->dma_chan, 16532763ea05SFabrice Gasnier adc->rx_dma_buf, 16542763ea05SFabrice Gasnier adc->rx_buf_sz, adc->rx_buf_sz / 2, 16552763ea05SFabrice Gasnier DMA_DEV_TO_MEM, 16562763ea05SFabrice Gasnier DMA_PREP_INTERRUPT); 16572763ea05SFabrice Gasnier if (!desc) 16582763ea05SFabrice Gasnier return -EBUSY; 16592763ea05SFabrice Gasnier 16602763ea05SFabrice Gasnier desc->callback = stm32_adc_dma_buffer_done; 16612763ea05SFabrice Gasnier desc->callback_param = indio_dev; 16622763ea05SFabrice Gasnier 16632763ea05SFabrice Gasnier cookie = dmaengine_submit(desc); 16642763ea05SFabrice Gasnier ret = dma_submit_error(cookie); 16652763ea05SFabrice Gasnier if (ret) { 1666e6afcf6cSFabrice Gasnier dmaengine_terminate_sync(adc->dma_chan); 16672763ea05SFabrice Gasnier return ret; 16682763ea05SFabrice Gasnier } 16692763ea05SFabrice Gasnier 16702763ea05SFabrice Gasnier /* Issue pending DMA requests */ 16712763ea05SFabrice Gasnier dma_async_issue_pending(adc->dma_chan); 16722763ea05SFabrice Gasnier 16732763ea05SFabrice Gasnier return 0; 16742763ea05SFabrice Gasnier } 16752763ea05SFabrice Gasnier 1676f11d59d8SLars-Peter Clausen static int stm32_adc_buffer_postenable(struct iio_dev *indio_dev) 1677da9b9485SFabrice Gasnier { 1678da9b9485SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 16799bdbb113SFabrice Gasnier struct device *dev = indio_dev->dev.parent; 1680da9b9485SFabrice Gasnier int ret; 1681da9b9485SFabrice Gasnier 1682265028b8SJonathan Cameron ret = pm_runtime_resume_and_get(dev); 1683265028b8SJonathan Cameron if (ret < 0) 168495e339b6SFabrice Gasnier return ret; 168595e339b6SFabrice Gasnier 1686da9b9485SFabrice Gasnier ret = stm32_adc_set_trig(indio_dev, indio_dev->trig); 1687da9b9485SFabrice Gasnier if (ret) { 1688da9b9485SFabrice Gasnier dev_err(&indio_dev->dev, "Can't set trigger\n"); 16899bdbb113SFabrice Gasnier goto err_pm_put; 1690da9b9485SFabrice Gasnier } 1691da9b9485SFabrice Gasnier 16922763ea05SFabrice Gasnier ret = stm32_adc_dma_start(indio_dev); 16932763ea05SFabrice Gasnier if (ret) { 16942763ea05SFabrice Gasnier dev_err(&indio_dev->dev, "Can't start dma\n"); 16952763ea05SFabrice Gasnier goto err_clr_trig; 16962763ea05SFabrice Gasnier } 16972763ea05SFabrice Gasnier 1698da9b9485SFabrice Gasnier /* Reset adc buffer index */ 1699da9b9485SFabrice Gasnier adc->bufi = 0; 1700da9b9485SFabrice Gasnier 1701cc06e67dSFabrice Gasnier stm32_adc_ovr_irq_enable(adc); 1702cc06e67dSFabrice Gasnier 17032763ea05SFabrice Gasnier if (!adc->dma_chan) 1704da9b9485SFabrice Gasnier stm32_adc_conv_irq_enable(adc); 17052763ea05SFabrice Gasnier 1706cd64d357SAlexandru Ardelean adc->cfg->start_conv(indio_dev, !!adc->dma_chan); 1707da9b9485SFabrice Gasnier 1708da9b9485SFabrice Gasnier return 0; 1709da9b9485SFabrice Gasnier 1710da9b9485SFabrice Gasnier err_clr_trig: 1711da9b9485SFabrice Gasnier stm32_adc_set_trig(indio_dev, NULL); 17129bdbb113SFabrice Gasnier err_pm_put: 17139bdbb113SFabrice Gasnier pm_runtime_mark_last_busy(dev); 17149bdbb113SFabrice Gasnier pm_runtime_put_autosuspend(dev); 1715da9b9485SFabrice Gasnier 1716da9b9485SFabrice Gasnier return ret; 1717da9b9485SFabrice Gasnier } 1718da9b9485SFabrice Gasnier 1719f11d59d8SLars-Peter Clausen static int stm32_adc_buffer_predisable(struct iio_dev *indio_dev) 1720da9b9485SFabrice Gasnier { 1721da9b9485SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 17229bdbb113SFabrice Gasnier struct device *dev = indio_dev->dev.parent; 1723da9b9485SFabrice Gasnier 1724cd64d357SAlexandru Ardelean adc->cfg->stop_conv(indio_dev); 17252763ea05SFabrice Gasnier if (!adc->dma_chan) 1726da9b9485SFabrice Gasnier stm32_adc_conv_irq_disable(adc); 1727da9b9485SFabrice Gasnier 1728cc06e67dSFabrice Gasnier stm32_adc_ovr_irq_disable(adc); 1729cc06e67dSFabrice Gasnier 17302763ea05SFabrice Gasnier if (adc->dma_chan) 1731e6afcf6cSFabrice Gasnier dmaengine_terminate_sync(adc->dma_chan); 17322763ea05SFabrice Gasnier 1733da9b9485SFabrice Gasnier if (stm32_adc_set_trig(indio_dev, NULL)) 1734da9b9485SFabrice Gasnier dev_err(&indio_dev->dev, "Can't clear trigger\n"); 1735da9b9485SFabrice Gasnier 17369bdbb113SFabrice Gasnier pm_runtime_mark_last_busy(dev); 17379bdbb113SFabrice Gasnier pm_runtime_put_autosuspend(dev); 173849ad8d28SFabrice Gasnier 1739f11d59d8SLars-Peter Clausen return 0; 1740da9b9485SFabrice Gasnier } 1741da9b9485SFabrice Gasnier 1742da9b9485SFabrice Gasnier static const struct iio_buffer_setup_ops stm32_adc_buffer_setup_ops = { 1743da9b9485SFabrice Gasnier .postenable = &stm32_adc_buffer_postenable, 1744da9b9485SFabrice Gasnier .predisable = &stm32_adc_buffer_predisable, 1745da9b9485SFabrice Gasnier }; 1746da9b9485SFabrice Gasnier 1747da9b9485SFabrice Gasnier static irqreturn_t stm32_adc_trigger_handler(int irq, void *p) 1748da9b9485SFabrice Gasnier { 1749da9b9485SFabrice Gasnier struct iio_poll_func *pf = p; 1750da9b9485SFabrice Gasnier struct iio_dev *indio_dev = pf->indio_dev; 1751da9b9485SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 1752da9b9485SFabrice Gasnier 1753da9b9485SFabrice Gasnier dev_dbg(&indio_dev->dev, "%s bufi=%d\n", __func__, adc->bufi); 1754da9b9485SFabrice Gasnier 1755da9b9485SFabrice Gasnier /* reset buffer index */ 1756da9b9485SFabrice Gasnier adc->bufi = 0; 1757da9b9485SFabrice Gasnier iio_push_to_buffers_with_timestamp(indio_dev, adc->buffer, 1758da9b9485SFabrice Gasnier pf->timestamp); 1759da9b9485SFabrice Gasnier iio_trigger_notify_done(indio_dev->trig); 1760da9b9485SFabrice Gasnier 1761da9b9485SFabrice Gasnier /* re-enable eoc irq */ 1762da9b9485SFabrice Gasnier stm32_adc_conv_irq_enable(adc); 1763da9b9485SFabrice Gasnier 1764da9b9485SFabrice Gasnier return IRQ_HANDLED; 1765da9b9485SFabrice Gasnier } 1766da9b9485SFabrice Gasnier 1767732f2dc4SFabrice Gasnier static const struct iio_chan_spec_ext_info stm32_adc_ext_info[] = { 1768732f2dc4SFabrice Gasnier IIO_ENUM("trigger_polarity", IIO_SHARED_BY_ALL, &stm32_adc_trig_pol), 1769732f2dc4SFabrice Gasnier { 1770732f2dc4SFabrice Gasnier .name = "trigger_polarity_available", 1771732f2dc4SFabrice Gasnier .shared = IIO_SHARED_BY_ALL, 1772732f2dc4SFabrice Gasnier .read = iio_enum_available_read, 1773732f2dc4SFabrice Gasnier .private = (uintptr_t)&stm32_adc_trig_pol, 1774732f2dc4SFabrice Gasnier }, 1775732f2dc4SFabrice Gasnier {}, 1776732f2dc4SFabrice Gasnier }; 1777732f2dc4SFabrice Gasnier 177825a85bedSFabrice Gasnier static int stm32_adc_of_get_resolution(struct iio_dev *indio_dev) 177925a85bedSFabrice Gasnier { 178025a85bedSFabrice Gasnier struct device_node *node = indio_dev->dev.of_node; 178125a85bedSFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 178225a85bedSFabrice Gasnier unsigned int i; 178325a85bedSFabrice Gasnier u32 res; 178425a85bedSFabrice Gasnier 178525a85bedSFabrice Gasnier if (of_property_read_u32(node, "assigned-resolution-bits", &res)) 178664ad7f64SFabrice Gasnier res = adc->cfg->adc_info->resolutions[0]; 178725a85bedSFabrice Gasnier 178864ad7f64SFabrice Gasnier for (i = 0; i < adc->cfg->adc_info->num_res; i++) 178964ad7f64SFabrice Gasnier if (res == adc->cfg->adc_info->resolutions[i]) 179025a85bedSFabrice Gasnier break; 179164ad7f64SFabrice Gasnier if (i >= adc->cfg->adc_info->num_res) { 179225a85bedSFabrice Gasnier dev_err(&indio_dev->dev, "Bad resolution: %u bits\n", res); 179325a85bedSFabrice Gasnier return -EINVAL; 179425a85bedSFabrice Gasnier } 179525a85bedSFabrice Gasnier 179625a85bedSFabrice Gasnier dev_dbg(&indio_dev->dev, "Using %u bits resolution\n", res); 179725a85bedSFabrice Gasnier adc->res = i; 179825a85bedSFabrice Gasnier 179925a85bedSFabrice Gasnier return 0; 180025a85bedSFabrice Gasnier } 180125a85bedSFabrice Gasnier 1802ee2ac1cdSFabrice Gasnier static void stm32_adc_smpr_init(struct stm32_adc *adc, int channel, u32 smp_ns) 1803ee2ac1cdSFabrice Gasnier { 1804ee2ac1cdSFabrice Gasnier const struct stm32_adc_regs *smpr = &adc->cfg->regs->smp_bits[channel]; 1805ee2ac1cdSFabrice Gasnier u32 period_ns, shift = smpr->shift, mask = smpr->mask; 1806ee2ac1cdSFabrice Gasnier unsigned int smp, r = smpr->reg; 1807ee2ac1cdSFabrice Gasnier 1808*796e5d0bSOlivier Moysan /* 1809*796e5d0bSOlivier Moysan * For vrefint channel, ensure that the sampling time cannot 1810*796e5d0bSOlivier Moysan * be lower than the one specified in the datasheet 1811*796e5d0bSOlivier Moysan */ 1812*796e5d0bSOlivier Moysan if (channel == adc->int_ch[STM32_ADC_INT_CH_VREFINT]) 1813*796e5d0bSOlivier Moysan smp_ns = max(smp_ns, adc->cfg->ts_vrefint_ns); 1814*796e5d0bSOlivier Moysan 1815ee2ac1cdSFabrice Gasnier /* Determine sampling time (ADC clock cycles) */ 1816ee2ac1cdSFabrice Gasnier period_ns = NSEC_PER_SEC / adc->common->rate; 1817ee2ac1cdSFabrice Gasnier for (smp = 0; smp <= STM32_ADC_MAX_SMP; smp++) 1818ee2ac1cdSFabrice Gasnier if ((period_ns * adc->cfg->smp_cycles[smp]) >= smp_ns) 1819ee2ac1cdSFabrice Gasnier break; 1820ee2ac1cdSFabrice Gasnier if (smp > STM32_ADC_MAX_SMP) 1821ee2ac1cdSFabrice Gasnier smp = STM32_ADC_MAX_SMP; 1822ee2ac1cdSFabrice Gasnier 1823ee2ac1cdSFabrice Gasnier /* pre-build sampling time registers (e.g. smpr1, smpr2) */ 1824ee2ac1cdSFabrice Gasnier adc->smpr_val[r] = (adc->smpr_val[r] & ~mask) | (smp << shift); 1825ee2ac1cdSFabrice Gasnier } 1826ee2ac1cdSFabrice Gasnier 18270f883b22SFabrice Gasnier static void stm32_adc_chan_init_one(struct iio_dev *indio_dev, 18280bae72aaSFabrice Gasnier struct iio_chan_spec *chan, u32 vinp, 18293fb2e24eSFabrice Gasnier u32 vinn, int scan_index, bool differential) 18300f883b22SFabrice Gasnier { 183125a85bedSFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 18320bae72aaSFabrice Gasnier char *name = adc->chan_name[vinp]; 183325a85bedSFabrice Gasnier 18340bae72aaSFabrice Gasnier chan->type = IIO_VOLTAGE; 18350bae72aaSFabrice Gasnier chan->channel = vinp; 18363fb2e24eSFabrice Gasnier if (differential) { 18373fb2e24eSFabrice Gasnier chan->differential = 1; 18383fb2e24eSFabrice Gasnier chan->channel2 = vinn; 18393fb2e24eSFabrice Gasnier snprintf(name, STM32_ADC_CH_SZ, "in%d-in%d", vinp, vinn); 18403fb2e24eSFabrice Gasnier } else { 18410bae72aaSFabrice Gasnier snprintf(name, STM32_ADC_CH_SZ, "in%d", vinp); 18423fb2e24eSFabrice Gasnier } 18430bae72aaSFabrice Gasnier chan->datasheet_name = name; 18440f883b22SFabrice Gasnier chan->scan_index = scan_index; 18450f883b22SFabrice Gasnier chan->indexed = 1; 18460e346b2cSOlivier Moysan if (chan->channel == adc->int_ch[STM32_ADC_INT_CH_VREFINT]) 18470e346b2cSOlivier Moysan chan->info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED); 18480e346b2cSOlivier Moysan else 18490f883b22SFabrice Gasnier chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); 18503fb2e24eSFabrice Gasnier chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | 18513fb2e24eSFabrice Gasnier BIT(IIO_CHAN_INFO_OFFSET); 18520f883b22SFabrice Gasnier chan->scan_type.sign = 'u'; 185364ad7f64SFabrice Gasnier chan->scan_type.realbits = adc->cfg->adc_info->resolutions[adc->res]; 18540f883b22SFabrice Gasnier chan->scan_type.storagebits = 16; 1855732f2dc4SFabrice Gasnier chan->ext_info = stm32_adc_ext_info; 185695e339b6SFabrice Gasnier 185795e339b6SFabrice Gasnier /* pre-build selected channels mask */ 185895e339b6SFabrice Gasnier adc->pcsel |= BIT(chan->channel); 18593fb2e24eSFabrice Gasnier if (differential) { 18603fb2e24eSFabrice Gasnier /* pre-build diff channels mask */ 18613fb2e24eSFabrice Gasnier adc->difsel |= BIT(chan->channel); 18623fb2e24eSFabrice Gasnier /* Also add negative input to pre-selected channels */ 18633fb2e24eSFabrice Gasnier adc->pcsel |= BIT(chan->channel2); 18643fb2e24eSFabrice Gasnier } 18650f883b22SFabrice Gasnier } 18660f883b22SFabrice Gasnier 186745571a36SOlivier Moysan static int stm32_adc_get_legacy_chan_count(struct iio_dev *indio_dev, struct stm32_adc *adc) 18680f883b22SFabrice Gasnier { 18690f883b22SFabrice Gasnier struct device_node *node = indio_dev->dev.of_node; 187064ad7f64SFabrice Gasnier const struct stm32_adc_info *adc_info = adc->cfg->adc_info; 187145571a36SOlivier Moysan int num_channels = 0, ret; 18720f883b22SFabrice Gasnier 18733fb2e24eSFabrice Gasnier ret = of_property_count_u32_elems(node, "st,adc-channels"); 18743fb2e24eSFabrice Gasnier if (ret > adc_info->max_channels) { 18750f883b22SFabrice Gasnier dev_err(&indio_dev->dev, "Bad st,adc-channels?\n"); 18763fb2e24eSFabrice Gasnier return -EINVAL; 18773fb2e24eSFabrice Gasnier } else if (ret > 0) { 18783fb2e24eSFabrice Gasnier num_channels += ret; 18793fb2e24eSFabrice Gasnier } 18803fb2e24eSFabrice Gasnier 18813fb2e24eSFabrice Gasnier ret = of_property_count_elems_of_size(node, "st,adc-diff-channels", 188245571a36SOlivier Moysan sizeof(struct stm32_adc_diff_channel)); 18833fb2e24eSFabrice Gasnier if (ret > adc_info->max_channels) { 18843fb2e24eSFabrice Gasnier dev_err(&indio_dev->dev, "Bad st,adc-diff-channels?\n"); 18853fb2e24eSFabrice Gasnier return -EINVAL; 18863fb2e24eSFabrice Gasnier } else if (ret > 0) { 188745571a36SOlivier Moysan adc->num_diff = ret; 18883fb2e24eSFabrice Gasnier num_channels += ret; 188945571a36SOlivier Moysan } 189045571a36SOlivier Moysan 1891*796e5d0bSOlivier Moysan /* Optional sample time is provided either for each, or all channels */ 1892*796e5d0bSOlivier Moysan ret = of_property_count_u32_elems(node, "st,min-sample-time-nsecs"); 1893*796e5d0bSOlivier Moysan if (ret > 1 && ret != num_channels) { 1894*796e5d0bSOlivier Moysan dev_err(&indio_dev->dev, "Invalid st,min-sample-time-nsecs\n"); 1895*796e5d0bSOlivier Moysan return -EINVAL; 1896*796e5d0bSOlivier Moysan } 1897*796e5d0bSOlivier Moysan 189845571a36SOlivier Moysan return num_channels; 189945571a36SOlivier Moysan } 190045571a36SOlivier Moysan 190145571a36SOlivier Moysan static int stm32_adc_legacy_chan_init(struct iio_dev *indio_dev, 190245571a36SOlivier Moysan struct stm32_adc *adc, 190345571a36SOlivier Moysan struct iio_chan_spec *channels) 190445571a36SOlivier Moysan { 190545571a36SOlivier Moysan struct device_node *node = indio_dev->dev.of_node; 190645571a36SOlivier Moysan const struct stm32_adc_info *adc_info = adc->cfg->adc_info; 190745571a36SOlivier Moysan struct stm32_adc_diff_channel diff[STM32_ADC_CH_MAX]; 190845571a36SOlivier Moysan u32 num_diff = adc->num_diff; 190945571a36SOlivier Moysan int size = num_diff * sizeof(*diff) / sizeof(u32); 191045571a36SOlivier Moysan int scan_index = 0, val, ret, i; 191145571a36SOlivier Moysan struct property *prop; 191245571a36SOlivier Moysan const __be32 *cur; 1913*796e5d0bSOlivier Moysan u32 smp = 0; 191445571a36SOlivier Moysan 191545571a36SOlivier Moysan if (num_diff) { 19163fb2e24eSFabrice Gasnier ret = of_property_read_u32_array(node, "st,adc-diff-channels", 19173fb2e24eSFabrice Gasnier (u32 *)diff, size); 191845571a36SOlivier Moysan if (ret) { 191945571a36SOlivier Moysan dev_err(&indio_dev->dev, "Failed to get diff channels %d\n", ret); 19203fb2e24eSFabrice Gasnier return ret; 19213fb2e24eSFabrice Gasnier } 19223fb2e24eSFabrice Gasnier 192345571a36SOlivier Moysan for (i = 0; i < num_diff; i++) { 192445571a36SOlivier Moysan if (diff[i].vinp >= adc_info->max_channels || 192545571a36SOlivier Moysan diff[i].vinn >= adc_info->max_channels) { 192645571a36SOlivier Moysan dev_err(&indio_dev->dev, "Invalid channel in%d-in%d\n", 192745571a36SOlivier Moysan diff[i].vinp, diff[i].vinn); 192845571a36SOlivier Moysan return -EINVAL; 192945571a36SOlivier Moysan } 193045571a36SOlivier Moysan 193145571a36SOlivier Moysan stm32_adc_chan_init_one(indio_dev, &channels[scan_index], 193245571a36SOlivier Moysan diff[i].vinp, diff[i].vinn, 193345571a36SOlivier Moysan scan_index, true); 193445571a36SOlivier Moysan scan_index++; 193545571a36SOlivier Moysan } 193645571a36SOlivier Moysan } 193745571a36SOlivier Moysan 193845571a36SOlivier Moysan of_property_for_each_u32(node, "st,adc-channels", prop, cur, val) { 193945571a36SOlivier Moysan if (val >= adc_info->max_channels) { 194045571a36SOlivier Moysan dev_err(&indio_dev->dev, "Invalid channel %d\n", val); 194145571a36SOlivier Moysan return -EINVAL; 194245571a36SOlivier Moysan } 194345571a36SOlivier Moysan 194445571a36SOlivier Moysan /* Channel can't be configured both as single-ended & diff */ 194545571a36SOlivier Moysan for (i = 0; i < num_diff; i++) { 194645571a36SOlivier Moysan if (val == diff[i].vinp) { 194745571a36SOlivier Moysan dev_err(&indio_dev->dev, "channel %d misconfigured\n", val); 194845571a36SOlivier Moysan return -EINVAL; 194945571a36SOlivier Moysan } 195045571a36SOlivier Moysan } 195145571a36SOlivier Moysan stm32_adc_chan_init_one(indio_dev, &channels[scan_index], val, 195245571a36SOlivier Moysan 0, scan_index, false); 195345571a36SOlivier Moysan scan_index++; 195445571a36SOlivier Moysan } 195545571a36SOlivier Moysan 1956*796e5d0bSOlivier Moysan for (i = 0; i < scan_index; i++) { 1957*796e5d0bSOlivier Moysan /* 1958*796e5d0bSOlivier Moysan * Using of_property_read_u32_index(), smp value will only be 1959*796e5d0bSOlivier Moysan * modified if valid u32 value can be decoded. This allows to 1960*796e5d0bSOlivier Moysan * get either no value, 1 shared value for all indexes, or one 1961*796e5d0bSOlivier Moysan * value per channel. 1962*796e5d0bSOlivier Moysan */ 1963*796e5d0bSOlivier Moysan of_property_read_u32_index(node, "st,min-sample-time-nsecs", i, &smp); 1964*796e5d0bSOlivier Moysan 1965*796e5d0bSOlivier Moysan /* Prepare sampling time settings */ 1966*796e5d0bSOlivier Moysan stm32_adc_smpr_init(adc, channels[i].channel, smp); 1967*796e5d0bSOlivier Moysan } 1968*796e5d0bSOlivier Moysan 196945571a36SOlivier Moysan return scan_index; 197045571a36SOlivier Moysan } 197145571a36SOlivier Moysan 19720e346b2cSOlivier Moysan static int stm32_adc_populate_int_ch(struct iio_dev *indio_dev, const char *ch_name, 19730e346b2cSOlivier Moysan int chan) 19740e346b2cSOlivier Moysan { 19750e346b2cSOlivier Moysan struct stm32_adc *adc = iio_priv(indio_dev); 19760e346b2cSOlivier Moysan u16 vrefint; 19770e346b2cSOlivier Moysan int i, ret; 19780e346b2cSOlivier Moysan 19790e346b2cSOlivier Moysan for (i = 0; i < STM32_ADC_INT_CH_NB; i++) { 19800e346b2cSOlivier Moysan if (!strncmp(stm32_adc_ic[i].name, ch_name, STM32_ADC_CH_SZ)) { 19810e346b2cSOlivier Moysan adc->int_ch[i] = chan; 19820e346b2cSOlivier Moysan 19830e346b2cSOlivier Moysan if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT) 19840e346b2cSOlivier Moysan continue; 19850e346b2cSOlivier Moysan 19860e346b2cSOlivier Moysan /* Get calibration data for vrefint channel */ 19870e346b2cSOlivier Moysan ret = nvmem_cell_read_u16(&indio_dev->dev, "vrefint", &vrefint); 19880e346b2cSOlivier Moysan if (ret && ret != -ENOENT) { 19890e346b2cSOlivier Moysan return dev_err_probe(&indio_dev->dev, ret, 19900e346b2cSOlivier Moysan "nvmem access error\n"); 19910e346b2cSOlivier Moysan } 19920e346b2cSOlivier Moysan if (ret == -ENOENT) 19930e346b2cSOlivier Moysan dev_dbg(&indio_dev->dev, "vrefint calibration not found\n"); 19940e346b2cSOlivier Moysan else 19950e346b2cSOlivier Moysan adc->vrefint.vrefint_cal = vrefint; 19960e346b2cSOlivier Moysan } 19970e346b2cSOlivier Moysan } 19980e346b2cSOlivier Moysan 19990e346b2cSOlivier Moysan return 0; 20000e346b2cSOlivier Moysan } 20010e346b2cSOlivier Moysan 200295bc8184SOlivier Moysan static int stm32_adc_generic_chan_init(struct iio_dev *indio_dev, 200395bc8184SOlivier Moysan struct stm32_adc *adc, 200495bc8184SOlivier Moysan struct iio_chan_spec *channels) 200595bc8184SOlivier Moysan { 200695bc8184SOlivier Moysan struct device_node *node = indio_dev->dev.of_node; 200795bc8184SOlivier Moysan const struct stm32_adc_info *adc_info = adc->cfg->adc_info; 200895bc8184SOlivier Moysan struct device_node *child; 200995bc8184SOlivier Moysan const char *name; 20100e346b2cSOlivier Moysan int val, scan_index = 0, ret; 201195bc8184SOlivier Moysan bool differential; 201295bc8184SOlivier Moysan u32 vin[2]; 201395bc8184SOlivier Moysan 201495bc8184SOlivier Moysan for_each_available_child_of_node(node, child) { 201595bc8184SOlivier Moysan ret = of_property_read_u32(child, "reg", &val); 201695bc8184SOlivier Moysan if (ret) { 201795bc8184SOlivier Moysan dev_err(&indio_dev->dev, "Missing channel index %d\n", ret); 201895bc8184SOlivier Moysan goto err; 201995bc8184SOlivier Moysan } 202095bc8184SOlivier Moysan 202195bc8184SOlivier Moysan ret = of_property_read_string(child, "label", &name); 202295bc8184SOlivier Moysan /* label is optional */ 202395bc8184SOlivier Moysan if (!ret) { 202495bc8184SOlivier Moysan if (strlen(name) >= STM32_ADC_CH_SZ) { 202595bc8184SOlivier Moysan dev_err(&indio_dev->dev, "Label %s exceeds %d characters\n", 202695bc8184SOlivier Moysan name, STM32_ADC_CH_SZ); 202795bc8184SOlivier Moysan return -EINVAL; 202895bc8184SOlivier Moysan } 202995bc8184SOlivier Moysan strncpy(adc->chan_name[val], name, STM32_ADC_CH_SZ); 20300e346b2cSOlivier Moysan ret = stm32_adc_populate_int_ch(indio_dev, name, val); 20310e346b2cSOlivier Moysan if (ret) 20320e346b2cSOlivier Moysan goto err; 203395bc8184SOlivier Moysan } else if (ret != -EINVAL) { 203495bc8184SOlivier Moysan dev_err(&indio_dev->dev, "Invalid label %d\n", ret); 203595bc8184SOlivier Moysan goto err; 203695bc8184SOlivier Moysan } 203795bc8184SOlivier Moysan 203895bc8184SOlivier Moysan if (val >= adc_info->max_channels) { 203995bc8184SOlivier Moysan dev_err(&indio_dev->dev, "Invalid channel %d\n", val); 204095bc8184SOlivier Moysan ret = -EINVAL; 204195bc8184SOlivier Moysan goto err; 204295bc8184SOlivier Moysan } 204395bc8184SOlivier Moysan 204495bc8184SOlivier Moysan differential = false; 204595bc8184SOlivier Moysan ret = of_property_read_u32_array(child, "diff-channels", vin, 2); 204695bc8184SOlivier Moysan /* diff-channels is optional */ 204795bc8184SOlivier Moysan if (!ret) { 204895bc8184SOlivier Moysan differential = true; 204995bc8184SOlivier Moysan if (vin[0] != val || vin[1] >= adc_info->max_channels) { 205095bc8184SOlivier Moysan dev_err(&indio_dev->dev, "Invalid channel in%d-in%d\n", 205195bc8184SOlivier Moysan vin[0], vin[1]); 205295bc8184SOlivier Moysan goto err; 205395bc8184SOlivier Moysan } 205495bc8184SOlivier Moysan } else if (ret != -EINVAL) { 205595bc8184SOlivier Moysan dev_err(&indio_dev->dev, "Invalid diff-channels property %d\n", ret); 205695bc8184SOlivier Moysan goto err; 205795bc8184SOlivier Moysan } 205895bc8184SOlivier Moysan 205995bc8184SOlivier Moysan stm32_adc_chan_init_one(indio_dev, &channels[scan_index], val, 206095bc8184SOlivier Moysan vin[1], scan_index, differential); 2061*796e5d0bSOlivier Moysan 2062*796e5d0bSOlivier Moysan ret = of_property_read_u32(child, "st,min-sample-time-ns", &val); 2063*796e5d0bSOlivier Moysan /* st,min-sample-time-ns is optional */ 2064*796e5d0bSOlivier Moysan if (!ret) { 2065*796e5d0bSOlivier Moysan stm32_adc_smpr_init(adc, channels[scan_index].channel, val); 2066*796e5d0bSOlivier Moysan if (differential) 2067*796e5d0bSOlivier Moysan stm32_adc_smpr_init(adc, vin[1], val); 2068*796e5d0bSOlivier Moysan } else if (ret != -EINVAL) { 2069*796e5d0bSOlivier Moysan dev_err(&indio_dev->dev, "Invalid st,min-sample-time-ns property %d\n", 2070*796e5d0bSOlivier Moysan ret); 2071*796e5d0bSOlivier Moysan goto err; 2072*796e5d0bSOlivier Moysan } 2073*796e5d0bSOlivier Moysan 207495bc8184SOlivier Moysan scan_index++; 207595bc8184SOlivier Moysan } 207695bc8184SOlivier Moysan 207795bc8184SOlivier Moysan return scan_index; 207895bc8184SOlivier Moysan 207995bc8184SOlivier Moysan err: 208095bc8184SOlivier Moysan of_node_put(child); 208195bc8184SOlivier Moysan 208295bc8184SOlivier Moysan return ret; 208395bc8184SOlivier Moysan } 208495bc8184SOlivier Moysan 208545571a36SOlivier Moysan static int stm32_adc_chan_of_init(struct iio_dev *indio_dev, bool timestamping) 208645571a36SOlivier Moysan { 208745571a36SOlivier Moysan struct device_node *node = indio_dev->dev.of_node; 208845571a36SOlivier Moysan struct stm32_adc *adc = iio_priv(indio_dev); 208945571a36SOlivier Moysan const struct stm32_adc_info *adc_info = adc->cfg->adc_info; 209045571a36SOlivier Moysan struct iio_chan_spec *channels; 209145571a36SOlivier Moysan int scan_index = 0, num_channels = 0, ret, i; 209295bc8184SOlivier Moysan bool legacy = false; 209395bc8184SOlivier Moysan 2094aec6e0d8SOlivier Moysan for (i = 0; i < STM32_ADC_INT_CH_NB; i++) 2095aec6e0d8SOlivier Moysan adc->int_ch[i] = STM32_ADC_INT_CH_NONE; 2096aec6e0d8SOlivier Moysan 209795bc8184SOlivier Moysan num_channels = of_get_available_child_count(node); 209895bc8184SOlivier Moysan /* If no channels have been found, fallback to channels legacy properties. */ 209995bc8184SOlivier Moysan if (!num_channels) { 210095bc8184SOlivier Moysan legacy = true; 210145571a36SOlivier Moysan 210245571a36SOlivier Moysan ret = stm32_adc_get_legacy_chan_count(indio_dev, adc); 210395bc8184SOlivier Moysan if (!ret) { 210495bc8184SOlivier Moysan dev_err(indio_dev->dev.parent, "No channel found\n"); 21053fb2e24eSFabrice Gasnier return -ENODATA; 210695bc8184SOlivier Moysan } else if (ret < 0) { 210795bc8184SOlivier Moysan return ret; 210895bc8184SOlivier Moysan } 210995bc8184SOlivier Moysan 211095bc8184SOlivier Moysan num_channels = ret; 21110f883b22SFabrice Gasnier } 21120f883b22SFabrice Gasnier 211345571a36SOlivier Moysan if (num_channels > adc_info->max_channels) { 211445571a36SOlivier Moysan dev_err(&indio_dev->dev, "Channel number [%d] exceeds %d\n", 211545571a36SOlivier Moysan num_channels, adc_info->max_channels); 211645571a36SOlivier Moysan return -EINVAL; 211745571a36SOlivier Moysan } 211845571a36SOlivier Moysan 21198a09054fSAhmad Fatoum if (timestamping) 21208a09054fSAhmad Fatoum num_channels++; 21218a09054fSAhmad Fatoum 21220f883b22SFabrice Gasnier channels = devm_kcalloc(&indio_dev->dev, num_channels, 21230f883b22SFabrice Gasnier sizeof(struct iio_chan_spec), GFP_KERNEL); 21240f883b22SFabrice Gasnier if (!channels) 21250f883b22SFabrice Gasnier return -ENOMEM; 21260f883b22SFabrice Gasnier 212795bc8184SOlivier Moysan if (legacy) 212845571a36SOlivier Moysan ret = stm32_adc_legacy_chan_init(indio_dev, adc, channels); 212995bc8184SOlivier Moysan else 213095bc8184SOlivier Moysan ret = stm32_adc_generic_chan_init(indio_dev, adc, channels); 213145571a36SOlivier Moysan if (ret < 0) 213245571a36SOlivier Moysan return ret; 213345571a36SOlivier Moysan scan_index = ret; 21343fb2e24eSFabrice Gasnier 21358a09054fSAhmad Fatoum if (timestamping) { 21368a09054fSAhmad Fatoum struct iio_chan_spec *timestamp = &channels[scan_index]; 21378a09054fSAhmad Fatoum 21388a09054fSAhmad Fatoum timestamp->type = IIO_TIMESTAMP; 21398a09054fSAhmad Fatoum timestamp->channel = -1; 21408a09054fSAhmad Fatoum timestamp->scan_index = scan_index; 21418a09054fSAhmad Fatoum timestamp->scan_type.sign = 's'; 21428a09054fSAhmad Fatoum timestamp->scan_type.realbits = 64; 21438a09054fSAhmad Fatoum timestamp->scan_type.storagebits = 64; 21448a09054fSAhmad Fatoum 21458a09054fSAhmad Fatoum scan_index++; 21468a09054fSAhmad Fatoum } 21478a09054fSAhmad Fatoum 21480f883b22SFabrice Gasnier indio_dev->num_channels = scan_index; 21490f883b22SFabrice Gasnier indio_dev->channels = channels; 21500f883b22SFabrice Gasnier 21510f883b22SFabrice Gasnier return 0; 21520f883b22SFabrice Gasnier } 21530f883b22SFabrice Gasnier 215452cd91c2SFabrice Gasnier static int stm32_adc_dma_request(struct device *dev, struct iio_dev *indio_dev) 21552763ea05SFabrice Gasnier { 21562763ea05SFabrice Gasnier struct stm32_adc *adc = iio_priv(indio_dev); 21572763ea05SFabrice Gasnier struct dma_slave_config config; 21582763ea05SFabrice Gasnier int ret; 21592763ea05SFabrice Gasnier 216052cd91c2SFabrice Gasnier adc->dma_chan = dma_request_chan(dev, "rx"); 2161735404b8SPeter Ujfalusi if (IS_ERR(adc->dma_chan)) { 2162735404b8SPeter Ujfalusi ret = PTR_ERR(adc->dma_chan); 2163ce30eeb6SKrzysztof Kozlowski if (ret != -ENODEV) 2164ce30eeb6SKrzysztof Kozlowski return dev_err_probe(dev, ret, 2165ce30eeb6SKrzysztof Kozlowski "DMA channel request failed with\n"); 2166735404b8SPeter Ujfalusi 2167735404b8SPeter Ujfalusi /* DMA is optional: fall back to IRQ mode */ 2168735404b8SPeter Ujfalusi adc->dma_chan = NULL; 21692763ea05SFabrice Gasnier return 0; 2170735404b8SPeter Ujfalusi } 21712763ea05SFabrice Gasnier 21722763ea05SFabrice Gasnier adc->rx_buf = dma_alloc_coherent(adc->dma_chan->device->dev, 21732763ea05SFabrice Gasnier STM32_DMA_BUFFER_SIZE, 21742763ea05SFabrice Gasnier &adc->rx_dma_buf, GFP_KERNEL); 21752763ea05SFabrice Gasnier if (!adc->rx_buf) { 21762763ea05SFabrice Gasnier ret = -ENOMEM; 21772763ea05SFabrice Gasnier goto err_release; 21782763ea05SFabrice Gasnier } 21792763ea05SFabrice Gasnier 21802763ea05SFabrice Gasnier /* Configure DMA channel to read data register */ 21812763ea05SFabrice Gasnier memset(&config, 0, sizeof(config)); 21822763ea05SFabrice Gasnier config.src_addr = (dma_addr_t)adc->common->phys_base; 218364ad7f64SFabrice Gasnier config.src_addr += adc->offset + adc->cfg->regs->dr; 21842763ea05SFabrice Gasnier config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 21852763ea05SFabrice Gasnier 21862763ea05SFabrice Gasnier ret = dmaengine_slave_config(adc->dma_chan, &config); 21872763ea05SFabrice Gasnier if (ret) 21882763ea05SFabrice Gasnier goto err_free; 21892763ea05SFabrice Gasnier 21902763ea05SFabrice Gasnier return 0; 21912763ea05SFabrice Gasnier 21922763ea05SFabrice Gasnier err_free: 21932763ea05SFabrice Gasnier dma_free_coherent(adc->dma_chan->device->dev, STM32_DMA_BUFFER_SIZE, 21942763ea05SFabrice Gasnier adc->rx_buf, adc->rx_dma_buf); 21952763ea05SFabrice Gasnier err_release: 21962763ea05SFabrice Gasnier dma_release_channel(adc->dma_chan); 21972763ea05SFabrice Gasnier 21982763ea05SFabrice Gasnier return ret; 21992763ea05SFabrice Gasnier } 22002763ea05SFabrice Gasnier 22010f883b22SFabrice Gasnier static int stm32_adc_probe(struct platform_device *pdev) 22020f883b22SFabrice Gasnier { 22030f883b22SFabrice Gasnier struct iio_dev *indio_dev; 220464ad7f64SFabrice Gasnier struct device *dev = &pdev->dev; 2205e2042d29SOlivier Moysan irqreturn_t (*handler)(int irq, void *p) = NULL; 22060f883b22SFabrice Gasnier struct stm32_adc *adc; 22078a09054fSAhmad Fatoum bool timestamping = false; 22080f883b22SFabrice Gasnier int ret; 22090f883b22SFabrice Gasnier 22100f883b22SFabrice Gasnier if (!pdev->dev.of_node) 22110f883b22SFabrice Gasnier return -ENODEV; 22120f883b22SFabrice Gasnier 22130f883b22SFabrice Gasnier indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc)); 22140f883b22SFabrice Gasnier if (!indio_dev) 22150f883b22SFabrice Gasnier return -ENOMEM; 22160f883b22SFabrice Gasnier 22170f883b22SFabrice Gasnier adc = iio_priv(indio_dev); 22180f883b22SFabrice Gasnier adc->common = dev_get_drvdata(pdev->dev.parent); 22190f883b22SFabrice Gasnier spin_lock_init(&adc->lock); 22200f883b22SFabrice Gasnier init_completion(&adc->completion); 222164ad7f64SFabrice Gasnier adc->cfg = (const struct stm32_adc_cfg *) 222264ad7f64SFabrice Gasnier of_match_device(dev->driver->of_match_table, dev)->data; 22230f883b22SFabrice Gasnier 22240f883b22SFabrice Gasnier indio_dev->name = dev_name(&pdev->dev); 22250f883b22SFabrice Gasnier indio_dev->dev.of_node = pdev->dev.of_node; 22260f883b22SFabrice Gasnier indio_dev->info = &stm32_adc_iio_info; 2227f0b638a7SFabrice Gasnier indio_dev->modes = INDIO_DIRECT_MODE | INDIO_HARDWARE_TRIGGERED; 22280f883b22SFabrice Gasnier 2229cd64d357SAlexandru Ardelean platform_set_drvdata(pdev, indio_dev); 22300f883b22SFabrice Gasnier 22310f883b22SFabrice Gasnier ret = of_property_read_u32(pdev->dev.of_node, "reg", &adc->offset); 22320f883b22SFabrice Gasnier if (ret != 0) { 22330f883b22SFabrice Gasnier dev_err(&pdev->dev, "missing reg property\n"); 22340f883b22SFabrice Gasnier return -EINVAL; 22350f883b22SFabrice Gasnier } 22360f883b22SFabrice Gasnier 22370f883b22SFabrice Gasnier adc->irq = platform_get_irq(pdev, 0); 22387c279229SStephen Boyd if (adc->irq < 0) 22390f883b22SFabrice Gasnier return adc->irq; 22400f883b22SFabrice Gasnier 2241cc06e67dSFabrice Gasnier ret = devm_request_threaded_irq(&pdev->dev, adc->irq, stm32_adc_isr, 2242cc06e67dSFabrice Gasnier stm32_adc_threaded_isr, 2243cd64d357SAlexandru Ardelean 0, pdev->name, indio_dev); 22440f883b22SFabrice Gasnier if (ret) { 22450f883b22SFabrice Gasnier dev_err(&pdev->dev, "failed to request IRQ\n"); 22460f883b22SFabrice Gasnier return ret; 22470f883b22SFabrice Gasnier } 22480f883b22SFabrice Gasnier 22490f883b22SFabrice Gasnier adc->clk = devm_clk_get(&pdev->dev, NULL); 22500f883b22SFabrice Gasnier if (IS_ERR(adc->clk)) { 2251204a6a25SFabrice Gasnier ret = PTR_ERR(adc->clk); 2252204a6a25SFabrice Gasnier if (ret == -ENOENT && !adc->cfg->clk_required) { 2253204a6a25SFabrice Gasnier adc->clk = NULL; 2254204a6a25SFabrice Gasnier } else { 22550f883b22SFabrice Gasnier dev_err(&pdev->dev, "Can't get clock\n"); 2256204a6a25SFabrice Gasnier return ret; 2257204a6a25SFabrice Gasnier } 22580f883b22SFabrice Gasnier } 22590f883b22SFabrice Gasnier 226025a85bedSFabrice Gasnier ret = stm32_adc_of_get_resolution(indio_dev); 226125a85bedSFabrice Gasnier if (ret < 0) 22629bdbb113SFabrice Gasnier return ret; 226325a85bedSFabrice Gasnier 226452cd91c2SFabrice Gasnier ret = stm32_adc_dma_request(dev, indio_dev); 22652763ea05SFabrice Gasnier if (ret < 0) 22669bdbb113SFabrice Gasnier return ret; 22672763ea05SFabrice Gasnier 22688a09054fSAhmad Fatoum if (!adc->dma_chan) { 22698a09054fSAhmad Fatoum /* For PIO mode only, iio_pollfunc_store_time stores a timestamp 22708a09054fSAhmad Fatoum * in the primary trigger IRQ handler and stm32_adc_trigger_handler 22718a09054fSAhmad Fatoum * runs in the IRQ thread to push out buffer along with timestamp. 22728a09054fSAhmad Fatoum */ 2273e2042d29SOlivier Moysan handler = &stm32_adc_trigger_handler; 22748a09054fSAhmad Fatoum timestamping = true; 22758a09054fSAhmad Fatoum } 22768a09054fSAhmad Fatoum 22778a09054fSAhmad Fatoum ret = stm32_adc_chan_of_init(indio_dev, timestamping); 22788a09054fSAhmad Fatoum if (ret < 0) 22798a09054fSAhmad Fatoum goto err_dma_disable; 2280e2042d29SOlivier Moysan 2281da9b9485SFabrice Gasnier ret = iio_triggered_buffer_setup(indio_dev, 2282e2042d29SOlivier Moysan &iio_pollfunc_store_time, handler, 2283da9b9485SFabrice Gasnier &stm32_adc_buffer_setup_ops); 22840f883b22SFabrice Gasnier if (ret) { 2285da9b9485SFabrice Gasnier dev_err(&pdev->dev, "buffer setup failed\n"); 22862763ea05SFabrice Gasnier goto err_dma_disable; 22870f883b22SFabrice Gasnier } 22880f883b22SFabrice Gasnier 22899bdbb113SFabrice Gasnier /* Get stm32-adc-core PM online */ 22909bdbb113SFabrice Gasnier pm_runtime_get_noresume(dev); 22919bdbb113SFabrice Gasnier pm_runtime_set_active(dev); 22929bdbb113SFabrice Gasnier pm_runtime_set_autosuspend_delay(dev, STM32_ADC_HW_STOP_DELAY_MS); 22939bdbb113SFabrice Gasnier pm_runtime_use_autosuspend(dev); 22949bdbb113SFabrice Gasnier pm_runtime_enable(dev); 22959bdbb113SFabrice Gasnier 22969bdbb113SFabrice Gasnier ret = stm32_adc_hw_start(dev); 22979bdbb113SFabrice Gasnier if (ret) 22989bdbb113SFabrice Gasnier goto err_buffer_cleanup; 22999bdbb113SFabrice Gasnier 2300da9b9485SFabrice Gasnier ret = iio_device_register(indio_dev); 2301da9b9485SFabrice Gasnier if (ret) { 2302da9b9485SFabrice Gasnier dev_err(&pdev->dev, "iio dev register failed\n"); 23039bdbb113SFabrice Gasnier goto err_hw_stop; 2304da9b9485SFabrice Gasnier } 2305da9b9485SFabrice Gasnier 23069bdbb113SFabrice Gasnier pm_runtime_mark_last_busy(dev); 23079bdbb113SFabrice Gasnier pm_runtime_put_autosuspend(dev); 23089bdbb113SFabrice Gasnier 23090f883b22SFabrice Gasnier return 0; 23100f883b22SFabrice Gasnier 23119bdbb113SFabrice Gasnier err_hw_stop: 23129bdbb113SFabrice Gasnier stm32_adc_hw_stop(dev); 23139bdbb113SFabrice Gasnier 2314da9b9485SFabrice Gasnier err_buffer_cleanup: 23159bdbb113SFabrice Gasnier pm_runtime_disable(dev); 23169bdbb113SFabrice Gasnier pm_runtime_set_suspended(dev); 23179bdbb113SFabrice Gasnier pm_runtime_put_noidle(dev); 2318da9b9485SFabrice Gasnier iio_triggered_buffer_cleanup(indio_dev); 2319da9b9485SFabrice Gasnier 23202763ea05SFabrice Gasnier err_dma_disable: 23212763ea05SFabrice Gasnier if (adc->dma_chan) { 23222763ea05SFabrice Gasnier dma_free_coherent(adc->dma_chan->device->dev, 23232763ea05SFabrice Gasnier STM32_DMA_BUFFER_SIZE, 23242763ea05SFabrice Gasnier adc->rx_buf, adc->rx_dma_buf); 23252763ea05SFabrice Gasnier dma_release_channel(adc->dma_chan); 23262763ea05SFabrice Gasnier } 23270f883b22SFabrice Gasnier 23280f883b22SFabrice Gasnier return ret; 23290f883b22SFabrice Gasnier } 23300f883b22SFabrice Gasnier 23310f883b22SFabrice Gasnier static int stm32_adc_remove(struct platform_device *pdev) 23320f883b22SFabrice Gasnier { 2333cd64d357SAlexandru Ardelean struct iio_dev *indio_dev = platform_get_drvdata(pdev); 2334cd64d357SAlexandru Ardelean struct stm32_adc *adc = iio_priv(indio_dev); 23350f883b22SFabrice Gasnier 23369bdbb113SFabrice Gasnier pm_runtime_get_sync(&pdev->dev); 23370f883b22SFabrice Gasnier iio_device_unregister(indio_dev); 23389bdbb113SFabrice Gasnier stm32_adc_hw_stop(&pdev->dev); 23399bdbb113SFabrice Gasnier pm_runtime_disable(&pdev->dev); 23409bdbb113SFabrice Gasnier pm_runtime_set_suspended(&pdev->dev); 23419bdbb113SFabrice Gasnier pm_runtime_put_noidle(&pdev->dev); 2342da9b9485SFabrice Gasnier iio_triggered_buffer_cleanup(indio_dev); 23432763ea05SFabrice Gasnier if (adc->dma_chan) { 23442763ea05SFabrice Gasnier dma_free_coherent(adc->dma_chan->device->dev, 23452763ea05SFabrice Gasnier STM32_DMA_BUFFER_SIZE, 23462763ea05SFabrice Gasnier adc->rx_buf, adc->rx_dma_buf); 23472763ea05SFabrice Gasnier dma_release_channel(adc->dma_chan); 23482763ea05SFabrice Gasnier } 23490f883b22SFabrice Gasnier 23500f883b22SFabrice Gasnier return 0; 23510f883b22SFabrice Gasnier } 23520f883b22SFabrice Gasnier 235349ad8d28SFabrice Gasnier #if defined(CONFIG_PM_SLEEP) 235449ad8d28SFabrice Gasnier static int stm32_adc_suspend(struct device *dev) 235549ad8d28SFabrice Gasnier { 2356cd64d357SAlexandru Ardelean struct iio_dev *indio_dev = dev_get_drvdata(dev); 235749ad8d28SFabrice Gasnier 235849ad8d28SFabrice Gasnier if (iio_buffer_enabled(indio_dev)) 2359f11d59d8SLars-Peter Clausen stm32_adc_buffer_predisable(indio_dev); 236049ad8d28SFabrice Gasnier 236149ad8d28SFabrice Gasnier return pm_runtime_force_suspend(dev); 236249ad8d28SFabrice Gasnier } 236349ad8d28SFabrice Gasnier 236449ad8d28SFabrice Gasnier static int stm32_adc_resume(struct device *dev) 236549ad8d28SFabrice Gasnier { 2366cd64d357SAlexandru Ardelean struct iio_dev *indio_dev = dev_get_drvdata(dev); 236749ad8d28SFabrice Gasnier int ret; 236849ad8d28SFabrice Gasnier 236949ad8d28SFabrice Gasnier ret = pm_runtime_force_resume(dev); 237049ad8d28SFabrice Gasnier if (ret < 0) 237149ad8d28SFabrice Gasnier return ret; 237249ad8d28SFabrice Gasnier 237349ad8d28SFabrice Gasnier if (!iio_buffer_enabled(indio_dev)) 237449ad8d28SFabrice Gasnier return 0; 237549ad8d28SFabrice Gasnier 237649ad8d28SFabrice Gasnier ret = stm32_adc_update_scan_mode(indio_dev, 237749ad8d28SFabrice Gasnier indio_dev->active_scan_mask); 237849ad8d28SFabrice Gasnier if (ret < 0) 237949ad8d28SFabrice Gasnier return ret; 238049ad8d28SFabrice Gasnier 2381f11d59d8SLars-Peter Clausen return stm32_adc_buffer_postenable(indio_dev); 238249ad8d28SFabrice Gasnier } 238349ad8d28SFabrice Gasnier #endif 238449ad8d28SFabrice Gasnier 23859bdbb113SFabrice Gasnier #if defined(CONFIG_PM) 23869bdbb113SFabrice Gasnier static int stm32_adc_runtime_suspend(struct device *dev) 23879bdbb113SFabrice Gasnier { 23889bdbb113SFabrice Gasnier return stm32_adc_hw_stop(dev); 23899bdbb113SFabrice Gasnier } 23909bdbb113SFabrice Gasnier 23919bdbb113SFabrice Gasnier static int stm32_adc_runtime_resume(struct device *dev) 23929bdbb113SFabrice Gasnier { 23939bdbb113SFabrice Gasnier return stm32_adc_hw_start(dev); 23949bdbb113SFabrice Gasnier } 23959bdbb113SFabrice Gasnier #endif 23969bdbb113SFabrice Gasnier 23979bdbb113SFabrice Gasnier static const struct dev_pm_ops stm32_adc_pm_ops = { 239849ad8d28SFabrice Gasnier SET_SYSTEM_SLEEP_PM_OPS(stm32_adc_suspend, stm32_adc_resume) 23999bdbb113SFabrice Gasnier SET_RUNTIME_PM_OPS(stm32_adc_runtime_suspend, stm32_adc_runtime_resume, 24009bdbb113SFabrice Gasnier NULL) 24019bdbb113SFabrice Gasnier }; 24029bdbb113SFabrice Gasnier 240364ad7f64SFabrice Gasnier static const struct stm32_adc_cfg stm32f4_adc_cfg = { 240464ad7f64SFabrice Gasnier .regs = &stm32f4_adc_regspec, 240564ad7f64SFabrice Gasnier .adc_info = &stm32f4_adc_info, 240664ad7f64SFabrice Gasnier .trigs = stm32f4_adc_trigs, 2407204a6a25SFabrice Gasnier .clk_required = true, 240864ad7f64SFabrice Gasnier .start_conv = stm32f4_adc_start_conv, 240964ad7f64SFabrice Gasnier .stop_conv = stm32f4_adc_stop_conv, 2410ee2ac1cdSFabrice Gasnier .smp_cycles = stm32f4_adc_smp_cycles, 2411695e2f5cSOlivier Moysan .irq_clear = stm32f4_adc_irq_clear, 241264ad7f64SFabrice Gasnier }; 241364ad7f64SFabrice Gasnier 241495e339b6SFabrice Gasnier static const struct stm32_adc_cfg stm32h7_adc_cfg = { 241595e339b6SFabrice Gasnier .regs = &stm32h7_adc_regspec, 241695e339b6SFabrice Gasnier .adc_info = &stm32h7_adc_info, 241795e339b6SFabrice Gasnier .trigs = stm32h7_adc_trigs, 241895e339b6SFabrice Gasnier .start_conv = stm32h7_adc_start_conv, 241995e339b6SFabrice Gasnier .stop_conv = stm32h7_adc_stop_conv, 242095e339b6SFabrice Gasnier .prepare = stm32h7_adc_prepare, 242195e339b6SFabrice Gasnier .unprepare = stm32h7_adc_unprepare, 2422ee2ac1cdSFabrice Gasnier .smp_cycles = stm32h7_adc_smp_cycles, 2423695e2f5cSOlivier Moysan .irq_clear = stm32h7_adc_irq_clear, 242495e339b6SFabrice Gasnier }; 242595e339b6SFabrice Gasnier 2426d58c67d1SFabrice Gasnier static const struct stm32_adc_cfg stm32mp1_adc_cfg = { 2427aec6e0d8SOlivier Moysan .regs = &stm32mp1_adc_regspec, 2428d58c67d1SFabrice Gasnier .adc_info = &stm32h7_adc_info, 2429d58c67d1SFabrice Gasnier .trigs = stm32h7_adc_trigs, 2430d58c67d1SFabrice Gasnier .has_vregready = true, 2431d58c67d1SFabrice Gasnier .start_conv = stm32h7_adc_start_conv, 2432d58c67d1SFabrice Gasnier .stop_conv = stm32h7_adc_stop_conv, 2433d58c67d1SFabrice Gasnier .prepare = stm32h7_adc_prepare, 2434d58c67d1SFabrice Gasnier .unprepare = stm32h7_adc_unprepare, 2435d58c67d1SFabrice Gasnier .smp_cycles = stm32h7_adc_smp_cycles, 2436695e2f5cSOlivier Moysan .irq_clear = stm32h7_adc_irq_clear, 24370e346b2cSOlivier Moysan .ts_vrefint_ns = 4300, 2438d58c67d1SFabrice Gasnier }; 2439d58c67d1SFabrice Gasnier 24400f883b22SFabrice Gasnier static const struct of_device_id stm32_adc_of_match[] = { 244164ad7f64SFabrice Gasnier { .compatible = "st,stm32f4-adc", .data = (void *)&stm32f4_adc_cfg }, 244295e339b6SFabrice Gasnier { .compatible = "st,stm32h7-adc", .data = (void *)&stm32h7_adc_cfg }, 2443d58c67d1SFabrice Gasnier { .compatible = "st,stm32mp1-adc", .data = (void *)&stm32mp1_adc_cfg }, 24440f883b22SFabrice Gasnier {}, 24450f883b22SFabrice Gasnier }; 24460f883b22SFabrice Gasnier MODULE_DEVICE_TABLE(of, stm32_adc_of_match); 24470f883b22SFabrice Gasnier 24480f883b22SFabrice Gasnier static struct platform_driver stm32_adc_driver = { 24490f883b22SFabrice Gasnier .probe = stm32_adc_probe, 24500f883b22SFabrice Gasnier .remove = stm32_adc_remove, 24510f883b22SFabrice Gasnier .driver = { 24520f883b22SFabrice Gasnier .name = "stm32-adc", 24530f883b22SFabrice Gasnier .of_match_table = stm32_adc_of_match, 24549bdbb113SFabrice Gasnier .pm = &stm32_adc_pm_ops, 24550f883b22SFabrice Gasnier }, 24560f883b22SFabrice Gasnier }; 24570f883b22SFabrice Gasnier module_platform_driver(stm32_adc_driver); 24580f883b22SFabrice Gasnier 24590f883b22SFabrice Gasnier MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>"); 24600f883b22SFabrice Gasnier MODULE_DESCRIPTION("STMicroelectronics STM32 ADC IIO driver"); 24610f883b22SFabrice Gasnier MODULE_LICENSE("GPL v2"); 24620f883b22SFabrice Gasnier MODULE_ALIAS("platform:stm32-adc"); 2463