blob: d50f00f1233e07cfdf8f9e2b26137b3bb7b4b408 [file] [log] [blame]
Fabrice Gasnier5a1da382018-07-24 16:31:31 +02001// 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
Fabrice Gasnier5a1da382018-07-24 16:31:31 +02009#include <adc.h>
Simon Glass8237eeb2020-07-19 10:15:52 -060010#include <dm.h>
Fabrice Gasnier5a1da382018-07-24 16:31:31 +020011#include <asm/io.h>
Simon Glass9bc15642020-02-03 07:36:16 -070012#include <dm/device_compat.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060013#include <linux/bitops.h>
Simon Glassdbd79542020-05-10 11:40:11 -060014#include <linux/delay.h>
Fabrice Gasnier5a1da382018-07-24 16:31:31 +020015#include <linux/iopoll.h>
16#include "stm32-adc-core.h"
17
18/* STM32H7 - Registers for each ADC instance */
19#define STM32H7_ADC_ISR 0x00
20#define STM32H7_ADC_CR 0x08
21#define STM32H7_ADC_CFGR 0x0C
22#define STM32H7_ADC_SMPR1 0x14
23#define STM32H7_ADC_SMPR2 0x18
24#define STM32H7_ADC_PCSEL 0x1C
25#define STM32H7_ADC_SQR1 0x30
26#define STM32H7_ADC_DR 0x40
27#define STM32H7_ADC_DIFSEL 0xC0
28
29/* STM32H7_ADC_ISR - bit fields */
30#define STM32MP1_VREGREADY BIT(12)
31#define STM32H7_EOC BIT(2)
32#define STM32H7_ADRDY BIT(0)
33
34/* STM32H7_ADC_CR - bit fields */
Olivier Moysan28dde162022-12-15 13:51:10 +010035#define STM32H7_ADCAL BIT(31)
36#define STM32H7_ADCALDIF BIT(30)
Fabrice Gasnier5a1da382018-07-24 16:31:31 +020037#define STM32H7_DEEPPWD BIT(29)
38#define STM32H7_ADVREGEN BIT(28)
Olivier Moysan28dde162022-12-15 13:51:10 +010039#define STM32H7_ADCALLIN BIT(16)
Fabrice Gasnier5a1da382018-07-24 16:31:31 +020040#define STM32H7_BOOST BIT(8)
41#define STM32H7_ADSTART BIT(2)
42#define STM32H7_ADDIS BIT(1)
43#define STM32H7_ADEN BIT(0)
44
45/* STM32H7_ADC_CFGR bit fields */
46#define STM32H7_EXTEN GENMASK(11, 10)
47#define STM32H7_DMNGT GENMASK(1, 0)
48
49/* STM32H7_ADC_SQR1 - bit fields */
50#define STM32H7_SQ1_SHIFT 6
51
52/* BOOST bit must be set on STM32H7 when ADC clock is above 20MHz */
53#define STM32H7_BOOST_CLKRATE 20000000UL
54
55#define STM32_ADC_CH_MAX 20 /* max number of channels */
56#define STM32_ADC_TIMEOUT_US 100000
57
58struct stm32_adc_cfg {
59 unsigned int max_channels;
60 unsigned int num_bits;
61 bool has_vregready;
62};
63
64struct stm32_adc {
65 void __iomem *regs;
66 int active_channel;
67 const struct stm32_adc_cfg *cfg;
68};
69
Olivier Moysan28dde162022-12-15 13:51:10 +010070static void stm32_adc_enter_pwr_down(struct udevice *dev)
Fabrice Gasnier5a1da382018-07-24 16:31:31 +020071{
72 struct stm32_adc *adc = dev_get_priv(dev);
73
Fabrice Gasnier5a1da382018-07-24 16:31:31 +020074 clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_BOOST);
75 /* Setting DEEPPWD disables ADC vreg and clears ADVREGEN */
76 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_DEEPPWD);
Fabrice Gasnier5a1da382018-07-24 16:31:31 +020077}
78
Olivier Moysan28dde162022-12-15 13:51:10 +010079static int stm32_adc_exit_pwr_down(struct udevice *dev)
Fabrice Gasnier5a1da382018-07-24 16:31:31 +020080{
Fabrice Gasnier5a1da382018-07-24 16:31:31 +020081 struct stm32_adc_common *common = dev_get_priv(dev_get_parent(dev));
82 struct stm32_adc *adc = dev_get_priv(dev);
83 int ret;
84 u32 val;
85
Olivier Moysan28dde162022-12-15 13:51:10 +010086 /* return immediately if ADC is not in deep power down mode */
87 if (!(readl(adc->regs + STM32H7_ADC_CR) & STM32H7_DEEPPWD))
88 return 0;
89
Fabrice Gasnier5a1da382018-07-24 16:31:31 +020090 /* Exit deep power down, then enable ADC voltage regulator */
91 clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_DEEPPWD);
92 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADVREGEN);
Olivier Moysan28dde162022-12-15 13:51:10 +010093
Fabrice Gasnier5a1da382018-07-24 16:31:31 +020094 if (common->rate > STM32H7_BOOST_CLKRATE)
95 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_BOOST);
96
97 /* Wait for startup time */
98 if (!adc->cfg->has_vregready) {
99 udelay(20);
Olivier Moysan28dde162022-12-15 13:51:10 +0100100 return 0;
101 }
102
103 ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val,
104 val & STM32MP1_VREGREADY,
105 STM32_ADC_TIMEOUT_US);
106 if (ret < 0) {
107 stm32_adc_enter_pwr_down(dev);
108 dev_err(dev, "Failed to enable vreg: %d\n", ret);
Fabrice Gasnier5a1da382018-07-24 16:31:31 +0200109 }
110
Olivier Moysan28dde162022-12-15 13:51:10 +0100111 return ret;
112}
113
114static int stm32_adc_stop(struct udevice *dev)
115{
116 struct stm32_adc *adc = dev_get_priv(dev);
117
118 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADDIS);
119 stm32_adc_enter_pwr_down(dev);
120 adc->active_channel = -1;
121
122 return 0;
123}
124
125static int stm32_adc_start_channel(struct udevice *dev, int channel)
126{
127 struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
128 struct stm32_adc *adc = dev_get_priv(dev);
129 int ret;
130 u32 val;
131
132 ret = stm32_adc_exit_pwr_down(dev);
133 if (ret < 0)
134 return ret;
135
Fabrice Gasnier5a1da382018-07-24 16:31:31 +0200136 /* Only use single ended channels */
137 writel(0, adc->regs + STM32H7_ADC_DIFSEL);
138
139 /* Enable ADC, Poll for ADRDY to be set (after adc startup time) */
140 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADEN);
141 ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val,
142 val & STM32H7_ADRDY, STM32_ADC_TIMEOUT_US);
143 if (ret < 0) {
144 stm32_adc_stop(dev);
145 dev_err(dev, "Failed to enable ADC: %d\n", ret);
146 return ret;
147 }
148
149 /* Preselect channels */
150 writel(uc_pdata->channel_mask, adc->regs + STM32H7_ADC_PCSEL);
151
152 /* Set sampling time to max value by default */
153 writel(0xffffffff, adc->regs + STM32H7_ADC_SMPR1);
154 writel(0xffffffff, adc->regs + STM32H7_ADC_SMPR2);
155
156 /* Program regular sequence: chan in SQ1 & len = 0 for one channel */
157 writel(channel << STM32H7_SQ1_SHIFT, adc->regs + STM32H7_ADC_SQR1);
158
159 /* Trigger detection disabled (conversion can be launched in SW) */
160 clrbits_le32(adc->regs + STM32H7_ADC_CFGR, STM32H7_EXTEN |
161 STM32H7_DMNGT);
162 adc->active_channel = channel;
163
164 return 0;
165}
166
167static int stm32_adc_channel_data(struct udevice *dev, int channel,
168 unsigned int *data)
169{
170 struct stm32_adc *adc = dev_get_priv(dev);
171 int ret;
172 u32 val;
173
174 if (channel != adc->active_channel) {
175 dev_err(dev, "Requested channel is not active!\n");
176 return -EINVAL;
177 }
178
179 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADSTART);
180 ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val,
181 val & STM32H7_EOC, STM32_ADC_TIMEOUT_US);
182 if (ret < 0) {
183 dev_err(dev, "conversion timed out: %d\n", ret);
184 return ret;
185 }
186
187 *data = readl(adc->regs + STM32H7_ADC_DR);
188
189 return 0;
190}
191
Olivier Moysan28dde162022-12-15 13:51:10 +0100192/**
193 * Fixed timeout value for ADC calibration.
194 * worst cases:
195 * - low clock frequency (0.12 MHz min)
196 * - maximum prescalers
197 * Calibration requires:
198 * - 16384 ADC clock cycle for the linear calibration
199 * - 20 ADC clock cycle for the offset calibration
200 *
201 * Set to 100ms for now
202 */
203#define STM32H7_ADC_CALIB_TIMEOUT_US 100000
204
205static int stm32_adc_selfcalib(struct udevice *dev)
206{
207 struct stm32_adc *adc = dev_get_priv(dev);
208 int ret;
209 u32 val;
210
211 /*
212 * Select calibration mode:
213 * - Offset calibration for single ended inputs
214 * - No linearity calibration. Done in next step.
215 */
216 clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADCALDIF | STM32H7_ADCALLIN);
217
218 /* Start calibration, then wait for completion */
219 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADCAL);
220 ret = readl_poll_sleep_timeout(adc->regs + STM32H7_ADC_CR, val,
221 !(val & STM32H7_ADCAL), 100,
222 STM32H7_ADC_CALIB_TIMEOUT_US);
223 if (ret) {
224 dev_err(dev, "calibration failed\n");
225 goto out;
226 }
227
228 /*
229 * Select calibration mode, then start calibration:
230 * - Offset calibration for differential input
231 * - Linearity calibration (needs to be done only once for single/diff)
232 * will run simultaneously with offset calibration.
233 */
234 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADCALDIF | STM32H7_ADCALLIN);
235
236 /* Start calibration, then wait for completion */
237 setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADCAL);
238 ret = readl_poll_sleep_timeout(adc->regs + STM32H7_ADC_CR, val,
239 !(val & STM32H7_ADCAL), 100,
240 STM32H7_ADC_CALIB_TIMEOUT_US);
241 if (ret)
242 dev_err(dev, "calibration failed\n");
243
244out:
245 clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADCALDIF | STM32H7_ADCALLIN);
246
247 return ret;
248}
249
Olivier Moysanf3850e92022-11-23 16:20:15 +0100250static int stm32_adc_get_legacy_chan_count(struct udevice *dev)
Fabrice Gasnier5a1da382018-07-24 16:31:31 +0200251{
Patrick Delaunay35fc48d2019-06-21 15:26:44 +0200252 int ret;
Fabrice Gasnier5a1da382018-07-24 16:31:31 +0200253
254 /* Retrieve single ended channels listed in device tree */
Patrick Delaunay35fc48d2019-06-21 15:26:44 +0200255 ret = dev_read_size(dev, "st,adc-channels");
256 if (ret < 0) {
257 dev_err(dev, "can't get st,adc-channels: %d\n", ret);
258 return ret;
Fabrice Gasnier5a1da382018-07-24 16:31:31 +0200259 }
Fabrice Gasnier5a1da382018-07-24 16:31:31 +0200260
Olivier Moysanf3850e92022-11-23 16:20:15 +0100261 return (ret / sizeof(u32));
262}
263
264static int stm32_adc_legacy_chan_init(struct udevice *dev, unsigned int num_channels)
265{
266 struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
267 struct stm32_adc *adc = dev_get_priv(dev);
268 u32 chans[STM32_ADC_CH_MAX];
269 int i, ret;
Fabrice Gasnier5a1da382018-07-24 16:31:31 +0200270
271 ret = dev_read_u32_array(dev, "st,adc-channels", chans, num_channels);
272 if (ret < 0) {
273 dev_err(dev, "can't read st,adc-channels: %d\n", ret);
274 return ret;
275 }
276
277 for (i = 0; i < num_channels; i++) {
278 if (chans[i] >= adc->cfg->max_channels) {
279 dev_err(dev, "bad channel %u\n", chans[i]);
280 return -EINVAL;
281 }
282 uc_pdata->channel_mask |= 1 << chans[i];
283 }
284
Olivier Moysanf3850e92022-11-23 16:20:15 +0100285 return ret;
286}
287
Olivier Moysancd9cf582022-11-23 16:20:16 +0100288static int stm32_adc_generic_chan_init(struct udevice *dev, unsigned int num_channels)
289{
290 struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
291 struct stm32_adc *adc = dev_get_priv(dev);
292 ofnode child;
293 int val, ret;
294
295 ofnode_for_each_subnode(child, dev_ofnode(dev)) {
296 ret = ofnode_read_u32(child, "reg", &val);
297 if (ret) {
298 dev_err(dev, "Missing channel index %d\n", ret);
299 return ret;
300 }
301
302 if (val >= adc->cfg->max_channels) {
303 dev_err(dev, "Invalid channel %d\n", val);
304 return -EINVAL;
305 }
306
307 uc_pdata->channel_mask |= 1 << val;
308 }
309
310 return 0;
311}
312
Olivier Moysanf3850e92022-11-23 16:20:15 +0100313static int stm32_adc_chan_of_init(struct udevice *dev)
314{
315 struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
316 struct stm32_adc *adc = dev_get_priv(dev);
317 unsigned int num_channels;
318 int ret;
Olivier Moysancd9cf582022-11-23 16:20:16 +0100319 bool legacy = false;
Olivier Moysanf3850e92022-11-23 16:20:15 +0100320
Olivier Moysancd9cf582022-11-23 16:20:16 +0100321 num_channels = dev_get_child_count(dev);
322 /* If no channels have been found, fallback to channels legacy properties. */
323 if (!num_channels) {
324 legacy = true;
325
326 ret = stm32_adc_get_legacy_chan_count(dev);
327 if (!ret) {
328 dev_err(dev, "No channel found\n");
329 return -ENODATA;
330 } else if (ret < 0) {
331 return ret;
332 }
333 num_channels = ret;
334 }
Olivier Moysanf3850e92022-11-23 16:20:15 +0100335
336 if (num_channels > adc->cfg->max_channels) {
337 dev_err(dev, "too many st,adc-channels: %d\n", num_channels);
338 return -EINVAL;
339 }
340
Olivier Moysancd9cf582022-11-23 16:20:16 +0100341 if (legacy)
342 ret = stm32_adc_legacy_chan_init(dev, num_channels);
343 else
344 ret = stm32_adc_generic_chan_init(dev, num_channels);
Olivier Moysanf3850e92022-11-23 16:20:15 +0100345 if (ret < 0)
346 return ret;
347
Fabrice Gasnier5a1da382018-07-24 16:31:31 +0200348 uc_pdata->data_mask = (1 << adc->cfg->num_bits) - 1;
349 uc_pdata->data_format = ADC_DATA_FORMAT_BIN;
350 uc_pdata->data_timeout_us = 100000;
351
352 return 0;
353}
354
355static int stm32_adc_probe(struct udevice *dev)
356{
Simon Glass71fa5b42020-12-03 16:55:18 -0700357 struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
Fabrice Gasnier5a1da382018-07-24 16:31:31 +0200358 struct stm32_adc_common *common = dev_get_priv(dev_get_parent(dev));
359 struct stm32_adc *adc = dev_get_priv(dev);
Olivier Moysan28dde162022-12-15 13:51:10 +0100360 int offset, ret;
Fabrice Gasnier5a1da382018-07-24 16:31:31 +0200361
362 offset = dev_read_u32_default(dev, "reg", -ENODATA);
363 if (offset < 0) {
364 dev_err(dev, "Can't read reg property\n");
365 return offset;
366 }
367 adc->regs = common->base + offset;
368 adc->cfg = (const struct stm32_adc_cfg *)dev_get_driver_data(dev);
369
370 /* VDD supplied by common vref pin */
371 uc_pdata->vdd_supply = common->vref;
372 uc_pdata->vdd_microvolts = common->vref_uv;
373 uc_pdata->vss_microvolts = 0;
374
Olivier Moysan28dde162022-12-15 13:51:10 +0100375 ret = stm32_adc_chan_of_init(dev);
376 if (ret < 0)
377 return ret;
378
379 ret = stm32_adc_exit_pwr_down(dev);
380 if (ret < 0)
381 return ret;
382
383 ret = stm32_adc_selfcalib(dev);
384 if (ret)
385 stm32_adc_enter_pwr_down(dev);
386
387 return ret;
Fabrice Gasnier5a1da382018-07-24 16:31:31 +0200388}
389
390static const struct adc_ops stm32_adc_ops = {
391 .start_channel = stm32_adc_start_channel,
392 .channel_data = stm32_adc_channel_data,
393 .stop = stm32_adc_stop,
394};
395
396static const struct stm32_adc_cfg stm32h7_adc_cfg = {
397 .num_bits = 16,
398 .max_channels = STM32_ADC_CH_MAX,
399};
400
401static const struct stm32_adc_cfg stm32mp1_adc_cfg = {
402 .num_bits = 16,
403 .max_channels = STM32_ADC_CH_MAX,
404 .has_vregready = true,
405};
406
407static const struct udevice_id stm32_adc_ids[] = {
408 { .compatible = "st,stm32h7-adc",
409 .data = (ulong)&stm32h7_adc_cfg },
410 { .compatible = "st,stm32mp1-adc",
411 .data = (ulong)&stm32mp1_adc_cfg },
412 {}
413};
414
415U_BOOT_DRIVER(stm32_adc) = {
416 .name = "stm32-adc",
417 .id = UCLASS_ADC,
418 .of_match = stm32_adc_ids,
419 .probe = stm32_adc_probe,
420 .ops = &stm32_adc_ops,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700421 .priv_auto = sizeof(struct stm32_adc),
Fabrice Gasnier5a1da382018-07-24 16:31:31 +0200422};