1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
4 * Author: Fabrice Gasnier <fabrice.gasnier@st.com>
6 * Originally based on the Linux kernel v4.18 drivers/iio/adc/stm32-adc.c.
13 #include <dm/device_compat.h>
14 #include <linux/bitops.h>
15 #include <linux/delay.h>
16 #include <linux/iopoll.h>
17 #include "stm32-adc-core.h"
19 /* STM32H7 - Registers for each ADC instance */
20 #define STM32H7_ADC_ISR 0x00
21 #define STM32H7_ADC_CR 0x08
22 #define STM32H7_ADC_CFGR 0x0C
23 #define STM32H7_ADC_SMPR1 0x14
24 #define STM32H7_ADC_SMPR2 0x18
25 #define STM32H7_ADC_PCSEL 0x1C
26 #define STM32H7_ADC_SQR1 0x30
27 #define STM32H7_ADC_DR 0x40
28 #define STM32H7_ADC_DIFSEL 0xC0
30 /* STM32H7_ADC_ISR - bit fields */
31 #define STM32MP1_VREGREADY BIT(12)
32 #define STM32H7_EOC BIT(2)
33 #define STM32H7_ADRDY BIT(0)
35 /* STM32H7_ADC_CR - bit fields */
36 #define STM32H7_DEEPPWD BIT(29)
37 #define STM32H7_ADVREGEN BIT(28)
38 #define STM32H7_BOOST BIT(8)
39 #define STM32H7_ADSTART BIT(2)
40 #define STM32H7_ADDIS BIT(1)
41 #define STM32H7_ADEN BIT(0)
43 /* STM32H7_ADC_CFGR bit fields */
44 #define STM32H7_EXTEN GENMASK(11, 10)
45 #define STM32H7_DMNGT GENMASK(1, 0)
47 /* STM32H7_ADC_SQR1 - bit fields */
48 #define STM32H7_SQ1_SHIFT 6
50 /* BOOST bit must be set on STM32H7 when ADC clock is above 20MHz */
51 #define STM32H7_BOOST_CLKRATE 20000000UL
53 #define STM32_ADC_CH_MAX 20 /* max number of channels */
54 #define STM32_ADC_TIMEOUT_US 100000
56 struct stm32_adc_cfg {
57 unsigned int max_channels;
58 unsigned int num_bits;
65 const struct stm32_adc_cfg *cfg;
68 static int stm32_adc_stop(struct udevice *dev)
70 struct stm32_adc *adc = dev_get_priv(dev);
72 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADDIS);
73 clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_BOOST);
74 /* Setting DEEPPWD disables ADC vreg and clears ADVREGEN */
75 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_DEEPPWD);
76 adc->active_channel = -1;
81 static int stm32_adc_start_channel(struct udevice *dev, int channel)
83 struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
84 struct stm32_adc_common *common = dev_get_priv(dev_get_parent(dev));
85 struct stm32_adc *adc = dev_get_priv(dev);
89 /* Exit deep power down, then enable ADC voltage regulator */
90 clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_DEEPPWD);
91 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADVREGEN);
92 if (common->rate > STM32H7_BOOST_CLKRATE)
93 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_BOOST);
95 /* Wait for startup time */
96 if (!adc->cfg->has_vregready) {
99 ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val,
100 val & STM32MP1_VREGREADY,
101 STM32_ADC_TIMEOUT_US);
104 dev_err(dev, "Failed to enable vreg: %d\n", ret);
109 /* Only use single ended channels */
110 writel(0, adc->regs + STM32H7_ADC_DIFSEL);
112 /* Enable ADC, Poll for ADRDY to be set (after adc startup time) */
113 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADEN);
114 ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val,
115 val & STM32H7_ADRDY, STM32_ADC_TIMEOUT_US);
118 dev_err(dev, "Failed to enable ADC: %d\n", ret);
122 /* Preselect channels */
123 writel(uc_pdata->channel_mask, adc->regs + STM32H7_ADC_PCSEL);
125 /* Set sampling time to max value by default */
126 writel(0xffffffff, adc->regs + STM32H7_ADC_SMPR1);
127 writel(0xffffffff, adc->regs + STM32H7_ADC_SMPR2);
129 /* Program regular sequence: chan in SQ1 & len = 0 for one channel */
130 writel(channel << STM32H7_SQ1_SHIFT, adc->regs + STM32H7_ADC_SQR1);
132 /* Trigger detection disabled (conversion can be launched in SW) */
133 clrbits_le32(adc->regs + STM32H7_ADC_CFGR, STM32H7_EXTEN |
135 adc->active_channel = channel;
140 static int stm32_adc_channel_data(struct udevice *dev, int channel,
143 struct stm32_adc *adc = dev_get_priv(dev);
147 if (channel != adc->active_channel) {
148 dev_err(dev, "Requested channel is not active!\n");
152 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADSTART);
153 ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val,
154 val & STM32H7_EOC, STM32_ADC_TIMEOUT_US);
156 dev_err(dev, "conversion timed out: %d\n", ret);
160 *data = readl(adc->regs + STM32H7_ADC_DR);
165 static int stm32_adc_chan_of_init(struct udevice *dev)
167 struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
168 struct stm32_adc *adc = dev_get_priv(dev);
169 u32 chans[STM32_ADC_CH_MAX];
170 unsigned int i, num_channels;
173 /* Retrieve single ended channels listed in device tree */
174 ret = dev_read_size(dev, "st,adc-channels");
176 dev_err(dev, "can't get st,adc-channels: %d\n", ret);
179 num_channels = ret / sizeof(u32);
181 if (num_channels > adc->cfg->max_channels) {
182 dev_err(dev, "too many st,adc-channels: %d\n", num_channels);
186 ret = dev_read_u32_array(dev, "st,adc-channels", chans, num_channels);
188 dev_err(dev, "can't read st,adc-channels: %d\n", ret);
192 for (i = 0; i < num_channels; i++) {
193 if (chans[i] >= adc->cfg->max_channels) {
194 dev_err(dev, "bad channel %u\n", chans[i]);
197 uc_pdata->channel_mask |= 1 << chans[i];
200 uc_pdata->data_mask = (1 << adc->cfg->num_bits) - 1;
201 uc_pdata->data_format = ADC_DATA_FORMAT_BIN;
202 uc_pdata->data_timeout_us = 100000;
207 static int stm32_adc_probe(struct udevice *dev)
209 struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
210 struct stm32_adc_common *common = dev_get_priv(dev_get_parent(dev));
211 struct stm32_adc *adc = dev_get_priv(dev);
214 offset = dev_read_u32_default(dev, "reg", -ENODATA);
216 dev_err(dev, "Can't read reg property\n");
219 adc->regs = common->base + offset;
220 adc->cfg = (const struct stm32_adc_cfg *)dev_get_driver_data(dev);
222 /* VDD supplied by common vref pin */
223 uc_pdata->vdd_supply = common->vref;
224 uc_pdata->vdd_microvolts = common->vref_uv;
225 uc_pdata->vss_microvolts = 0;
227 return stm32_adc_chan_of_init(dev);
230 static const struct adc_ops stm32_adc_ops = {
231 .start_channel = stm32_adc_start_channel,
232 .channel_data = stm32_adc_channel_data,
233 .stop = stm32_adc_stop,
236 static const struct stm32_adc_cfg stm32h7_adc_cfg = {
238 .max_channels = STM32_ADC_CH_MAX,
241 static const struct stm32_adc_cfg stm32mp1_adc_cfg = {
243 .max_channels = STM32_ADC_CH_MAX,
244 .has_vregready = true,
247 static const struct udevice_id stm32_adc_ids[] = {
248 { .compatible = "st,stm32h7-adc",
249 .data = (ulong)&stm32h7_adc_cfg },
250 { .compatible = "st,stm32mp1-adc",
251 .data = (ulong)&stm32mp1_adc_cfg },
255 U_BOOT_DRIVER(stm32_adc) = {
258 .of_match = stm32_adc_ids,
259 .probe = stm32_adc_probe,
260 .ops = &stm32_adc_ops,
261 .priv_auto = sizeof(struct stm32_adc),