xref: /openbmc/u-boot/drivers/adc/stm32-adc.c (revision 8a23fc9c)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
4  * Author: Fabrice Gasnier <fabrice.gasnier@st.com>
5  *
6  * Originally based on the Linux kernel v4.18 drivers/iio/adc/stm32-adc.c.
7  */
8 
9 #include <common.h>
10 #include <adc.h>
11 #include <asm/io.h>
12 #include <linux/iopoll.h>
13 #include "stm32-adc-core.h"
14 
15 /* STM32H7 - Registers for each ADC instance */
16 #define STM32H7_ADC_ISR			0x00
17 #define STM32H7_ADC_CR			0x08
18 #define STM32H7_ADC_CFGR		0x0C
19 #define STM32H7_ADC_SMPR1		0x14
20 #define STM32H7_ADC_SMPR2		0x18
21 #define STM32H7_ADC_PCSEL		0x1C
22 #define STM32H7_ADC_SQR1		0x30
23 #define STM32H7_ADC_DR			0x40
24 #define STM32H7_ADC_DIFSEL		0xC0
25 
26 /* STM32H7_ADC_ISR - bit fields */
27 #define STM32MP1_VREGREADY		BIT(12)
28 #define STM32H7_EOC			BIT(2)
29 #define STM32H7_ADRDY			BIT(0)
30 
31 /* STM32H7_ADC_CR - bit fields */
32 #define STM32H7_DEEPPWD			BIT(29)
33 #define STM32H7_ADVREGEN		BIT(28)
34 #define STM32H7_BOOST			BIT(8)
35 #define STM32H7_ADSTART			BIT(2)
36 #define STM32H7_ADDIS			BIT(1)
37 #define STM32H7_ADEN			BIT(0)
38 
39 /* STM32H7_ADC_CFGR bit fields */
40 #define STM32H7_EXTEN			GENMASK(11, 10)
41 #define STM32H7_DMNGT			GENMASK(1, 0)
42 
43 /* STM32H7_ADC_SQR1 - bit fields */
44 #define STM32H7_SQ1_SHIFT		6
45 
46 /* BOOST bit must be set on STM32H7 when ADC clock is above 20MHz */
47 #define STM32H7_BOOST_CLKRATE		20000000UL
48 
49 #define STM32_ADC_CH_MAX		20	/* max number of channels */
50 #define STM32_ADC_TIMEOUT_US		100000
51 
52 struct stm32_adc_cfg {
53 	unsigned int max_channels;
54 	unsigned int num_bits;
55 	bool has_vregready;
56 };
57 
58 struct stm32_adc {
59 	void __iomem *regs;
60 	int active_channel;
61 	const struct stm32_adc_cfg *cfg;
62 };
63 
64 static int stm32_adc_stop(struct udevice *dev)
65 {
66 	struct stm32_adc *adc = dev_get_priv(dev);
67 
68 	setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADDIS);
69 	clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_BOOST);
70 	/* Setting DEEPPWD disables ADC vreg and clears ADVREGEN */
71 	setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_DEEPPWD);
72 	adc->active_channel = -1;
73 
74 	return 0;
75 }
76 
77 static int stm32_adc_start_channel(struct udevice *dev, int channel)
78 {
79 	struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
80 	struct stm32_adc_common *common = dev_get_priv(dev_get_parent(dev));
81 	struct stm32_adc *adc = dev_get_priv(dev);
82 	int ret;
83 	u32 val;
84 
85 	/* Exit deep power down, then enable ADC voltage regulator */
86 	clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_DEEPPWD);
87 	setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADVREGEN);
88 	if (common->rate > STM32H7_BOOST_CLKRATE)
89 		setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_BOOST);
90 
91 	/* Wait for startup time */
92 	if (!adc->cfg->has_vregready) {
93 		udelay(20);
94 	} else {
95 		ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val,
96 					 val & STM32MP1_VREGREADY,
97 					 STM32_ADC_TIMEOUT_US);
98 		if (ret < 0) {
99 			stm32_adc_stop(dev);
100 			dev_err(dev, "Failed to enable vreg: %d\n", ret);
101 			return ret;
102 		}
103 	}
104 
105 	/* Only use single ended channels */
106 	writel(0, adc->regs + STM32H7_ADC_DIFSEL);
107 
108 	/* Enable ADC, Poll for ADRDY to be set (after adc startup time) */
109 	setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADEN);
110 	ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val,
111 				 val & STM32H7_ADRDY, STM32_ADC_TIMEOUT_US);
112 	if (ret < 0) {
113 		stm32_adc_stop(dev);
114 		dev_err(dev, "Failed to enable ADC: %d\n", ret);
115 		return ret;
116 	}
117 
118 	/* Preselect channels */
119 	writel(uc_pdata->channel_mask, adc->regs + STM32H7_ADC_PCSEL);
120 
121 	/* Set sampling time to max value by default */
122 	writel(0xffffffff, adc->regs + STM32H7_ADC_SMPR1);
123 	writel(0xffffffff, adc->regs + STM32H7_ADC_SMPR2);
124 
125 	/* Program regular sequence: chan in SQ1 & len = 0 for one channel */
126 	writel(channel << STM32H7_SQ1_SHIFT, adc->regs + STM32H7_ADC_SQR1);
127 
128 	/* Trigger detection disabled (conversion can be launched in SW) */
129 	clrbits_le32(adc->regs + STM32H7_ADC_CFGR, STM32H7_EXTEN |
130 		     STM32H7_DMNGT);
131 	adc->active_channel = channel;
132 
133 	return 0;
134 }
135 
136 static int stm32_adc_channel_data(struct udevice *dev, int channel,
137 				  unsigned int *data)
138 {
139 	struct stm32_adc *adc = dev_get_priv(dev);
140 	int ret;
141 	u32 val;
142 
143 	if (channel != adc->active_channel) {
144 		dev_err(dev, "Requested channel is not active!\n");
145 		return -EINVAL;
146 	}
147 
148 	setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADSTART);
149 	ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val,
150 				 val & STM32H7_EOC, STM32_ADC_TIMEOUT_US);
151 	if (ret < 0) {
152 		dev_err(dev, "conversion timed out: %d\n", ret);
153 		return ret;
154 	}
155 
156 	*data = readl(adc->regs + STM32H7_ADC_DR);
157 
158 	return 0;
159 }
160 
161 static int stm32_adc_chan_of_init(struct udevice *dev)
162 {
163 	struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
164 	struct stm32_adc *adc = dev_get_priv(dev);
165 	u32 chans[STM32_ADC_CH_MAX];
166 	int i, num_channels, ret;
167 
168 	/* Retrieve single ended channels listed in device tree */
169 	num_channels = dev_read_size(dev, "st,adc-channels");
170 	if (num_channels < 0) {
171 		dev_err(dev, "can't get st,adc-channels: %d\n", num_channels);
172 		return num_channels;
173 	}
174 	num_channels /= sizeof(u32);
175 
176 	if (num_channels > adc->cfg->max_channels) {
177 		dev_err(dev, "too many st,adc-channels: %d\n", num_channels);
178 		return -EINVAL;
179 	}
180 
181 	ret = dev_read_u32_array(dev, "st,adc-channels", chans, num_channels);
182 	if (ret < 0) {
183 		dev_err(dev, "can't read st,adc-channels: %d\n", ret);
184 		return ret;
185 	}
186 
187 	for (i = 0; i < num_channels; i++) {
188 		if (chans[i] >= adc->cfg->max_channels) {
189 			dev_err(dev, "bad channel %u\n", chans[i]);
190 			return -EINVAL;
191 		}
192 		uc_pdata->channel_mask |= 1 << chans[i];
193 	}
194 
195 	uc_pdata->data_mask = (1 << adc->cfg->num_bits) - 1;
196 	uc_pdata->data_format = ADC_DATA_FORMAT_BIN;
197 	uc_pdata->data_timeout_us = 100000;
198 
199 	return 0;
200 }
201 
202 static int stm32_adc_probe(struct udevice *dev)
203 {
204 	struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
205 	struct stm32_adc_common *common = dev_get_priv(dev_get_parent(dev));
206 	struct stm32_adc *adc = dev_get_priv(dev);
207 	int offset;
208 
209 	offset = dev_read_u32_default(dev, "reg", -ENODATA);
210 	if (offset < 0) {
211 		dev_err(dev, "Can't read reg property\n");
212 		return offset;
213 	}
214 	adc->regs = common->base + offset;
215 	adc->cfg = (const struct stm32_adc_cfg *)dev_get_driver_data(dev);
216 
217 	/* VDD supplied by common vref pin */
218 	uc_pdata->vdd_supply = common->vref;
219 	uc_pdata->vdd_microvolts = common->vref_uv;
220 	uc_pdata->vss_microvolts = 0;
221 
222 	return stm32_adc_chan_of_init(dev);
223 }
224 
225 static const struct adc_ops stm32_adc_ops = {
226 	.start_channel = stm32_adc_start_channel,
227 	.channel_data = stm32_adc_channel_data,
228 	.stop = stm32_adc_stop,
229 };
230 
231 static const struct stm32_adc_cfg stm32h7_adc_cfg = {
232 	.num_bits = 16,
233 	.max_channels = STM32_ADC_CH_MAX,
234 };
235 
236 static const struct stm32_adc_cfg stm32mp1_adc_cfg = {
237 	.num_bits = 16,
238 	.max_channels = STM32_ADC_CH_MAX,
239 	.has_vregready = true,
240 };
241 
242 static const struct udevice_id stm32_adc_ids[] = {
243 	{ .compatible = "st,stm32h7-adc",
244 	  .data = (ulong)&stm32h7_adc_cfg },
245 	{ .compatible = "st,stm32mp1-adc",
246 	  .data = (ulong)&stm32mp1_adc_cfg },
247 	{}
248 };
249 
250 U_BOOT_DRIVER(stm32_adc) = {
251 	.name  = "stm32-adc",
252 	.id = UCLASS_ADC,
253 	.of_match = stm32_adc_ids,
254 	.probe = stm32_adc_probe,
255 	.ops = &stm32_adc_ops,
256 	.priv_auto_alloc_size = sizeof(struct stm32_adc),
257 };
258