blob: 21db55831d8dc5b52aef3d1dd36620cf14aa80a5 [file] [log] [blame]
Neil Armstrong4c76ddc2018-04-23 16:19:23 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
4 * Copyright (C) 2018 BayLibre, SAS
5 * Author: Neil Armstrong <narmstrong@baylibre.com>
6 *
7 * Amlogic Meson Successive Approximation Register (SAR) A/D Converter
8 */
9
10#include <common.h>
11#include <adc.h>
12#include <clk.h>
13#include <dm.h>
14#include <regmap.h>
15#include <errno.h>
16#include <asm/io.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060017#include <linux/bitops.h>
Simon Glassdbd79542020-05-10 11:40:11 -060018#include <linux/delay.h>
Neil Armstrong4c76ddc2018-04-23 16:19:23 +020019#include <linux/math64.h>
20#include <linux/bitfield.h>
21
22#define MESON_SAR_ADC_REG0 0x00
23 #define MESON_SAR_ADC_REG0_PANEL_DETECT BIT(31)
24 #define MESON_SAR_ADC_REG0_BUSY_MASK GENMASK(30, 28)
25 #define MESON_SAR_ADC_REG0_DELTA_BUSY BIT(30)
26 #define MESON_SAR_ADC_REG0_AVG_BUSY BIT(29)
27 #define MESON_SAR_ADC_REG0_SAMPLE_BUSY BIT(28)
28 #define MESON_SAR_ADC_REG0_FIFO_FULL BIT(27)
29 #define MESON_SAR_ADC_REG0_FIFO_EMPTY BIT(26)
30 #define MESON_SAR_ADC_REG0_FIFO_COUNT_MASK GENMASK(25, 21)
31 #define MESON_SAR_ADC_REG0_ADC_BIAS_CTRL_MASK GENMASK(20, 19)
32 #define MESON_SAR_ADC_REG0_CURR_CHAN_ID_MASK GENMASK(18, 16)
33 #define MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL BIT(15)
34 #define MESON_SAR_ADC_REG0_SAMPLING_STOP BIT(14)
35 #define MESON_SAR_ADC_REG0_CHAN_DELTA_EN_MASK GENMASK(13, 12)
36 #define MESON_SAR_ADC_REG0_DETECT_IRQ_POL BIT(10)
37 #define MESON_SAR_ADC_REG0_DETECT_IRQ_EN BIT(9)
38 #define MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK GENMASK(8, 4)
39 #define MESON_SAR_ADC_REG0_FIFO_IRQ_EN BIT(3)
40 #define MESON_SAR_ADC_REG0_SAMPLING_START BIT(2)
41 #define MESON_SAR_ADC_REG0_CONTINUOUS_EN BIT(1)
42 #define MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE BIT(0)
43
44#define MESON_SAR_ADC_CHAN_LIST 0x04
45 #define MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK GENMASK(26, 24)
46 #define MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(_chan) \
47 (GENMASK(2, 0) << ((_chan) * 3))
48
49#define MESON_SAR_ADC_AVG_CNTL 0x08
50 #define MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(_chan) \
51 (16 + ((_chan) * 2))
52 #define MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(_chan) \
53 (GENMASK(17, 16) << ((_chan) * 2))
54 #define MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(_chan) \
55 (0 + ((_chan) * 2))
56 #define MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(_chan) \
57 (GENMASK(1, 0) << ((_chan) * 2))
58
59#define MESON_SAR_ADC_REG3 0x0c
60 #define MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY BIT(31)
61 #define MESON_SAR_ADC_REG3_CLK_EN BIT(30)
62 #define MESON_SAR_ADC_REG3_BL30_INITIALIZED BIT(28)
63 #define MESON_SAR_ADC_REG3_CTRL_CONT_RING_COUNTER_EN BIT(27)
64 #define MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE BIT(26)
65 #define MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK GENMASK(25, 23)
66 #define MESON_SAR_ADC_REG3_DETECT_EN BIT(22)
67 #define MESON_SAR_ADC_REG3_ADC_EN BIT(21)
68 #define MESON_SAR_ADC_REG3_PANEL_DETECT_COUNT_MASK GENMASK(20, 18)
69 #define MESON_SAR_ADC_REG3_PANEL_DETECT_FILTER_TB_MASK GENMASK(17, 16)
70 #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT 10
71 #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH 5
72 #define MESON_SAR_ADC_REG3_BLOCK_DLY_SEL_MASK GENMASK(9, 8)
73 #define MESON_SAR_ADC_REG3_BLOCK_DLY_MASK GENMASK(7, 0)
74
75#define MESON_SAR_ADC_DELAY 0x10
76 #define MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK GENMASK(25, 24)
77 #define MESON_SAR_ADC_DELAY_BL30_BUSY BIT(15)
78 #define MESON_SAR_ADC_DELAY_KERNEL_BUSY BIT(14)
79 #define MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK GENMASK(23, 16)
80 #define MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK GENMASK(9, 8)
81 #define MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK GENMASK(7, 0)
82
83#define MESON_SAR_ADC_LAST_RD 0x14
84 #define MESON_SAR_ADC_LAST_RD_LAST_CHANNEL1_MASK GENMASK(23, 16)
85 #define MESON_SAR_ADC_LAST_RD_LAST_CHANNEL0_MASK GENMASK(9, 0)
86
87#define MESON_SAR_ADC_FIFO_RD 0x18
88 #define MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK GENMASK(14, 12)
89 #define MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK GENMASK(11, 0)
90
91#define MESON_SAR_ADC_AUX_SW 0x1c
92 #define MESON_SAR_ADC_AUX_SW_MUX_SEL_CHAN_SHIFT(_chan) \
93 (8 + (((_chan) - 2) * 3))
94 #define MESON_SAR_ADC_AUX_SW_VREF_P_MUX BIT(6)
95 #define MESON_SAR_ADC_AUX_SW_VREF_N_MUX BIT(5)
96 #define MESON_SAR_ADC_AUX_SW_MODE_SEL BIT(4)
97 #define MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW BIT(3)
98 #define MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW BIT(2)
99 #define MESON_SAR_ADC_AUX_SW_YM_DRIVE_SW BIT(1)
100 #define MESON_SAR_ADC_AUX_SW_XM_DRIVE_SW BIT(0)
101
102#define MESON_SAR_ADC_CHAN_10_SW 0x20
103 #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK GENMASK(25, 23)
104 #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_VREF_P_MUX BIT(22)
105 #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_VREF_N_MUX BIT(21)
106 #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_MODE_SEL BIT(20)
107 #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_YP_DRIVE_SW BIT(19)
108 #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_XP_DRIVE_SW BIT(18)
109 #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_YM_DRIVE_SW BIT(17)
110 #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_XM_DRIVE_SW BIT(16)
111 #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK GENMASK(9, 7)
112 #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_VREF_P_MUX BIT(6)
113 #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_VREF_N_MUX BIT(5)
114 #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_MODE_SEL BIT(4)
115 #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_YP_DRIVE_SW BIT(3)
116 #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_XP_DRIVE_SW BIT(2)
117 #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_YM_DRIVE_SW BIT(1)
118 #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_XM_DRIVE_SW BIT(0)
119
120#define MESON_SAR_ADC_DETECT_IDLE_SW 0x24
121 #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_SW_EN BIT(26)
122 #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK GENMASK(25, 23)
123 #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_VREF_P_MUX BIT(22)
124 #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_VREF_N_MUX BIT(21)
125 #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MODE_SEL BIT(20)
126 #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_YP_DRIVE_SW BIT(19)
127 #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_XP_DRIVE_SW BIT(18)
128 #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_YM_DRIVE_SW BIT(17)
129 #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_XM_DRIVE_SW BIT(16)
130 #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK GENMASK(9, 7)
131 #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_VREF_P_MUX BIT(6)
132 #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_VREF_N_MUX BIT(5)
133 #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MODE_SEL BIT(4)
134 #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_YP_DRIVE_SW BIT(3)
135 #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_XP_DRIVE_SW BIT(2)
136 #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_YM_DRIVE_SW BIT(1)
137 #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_XM_DRIVE_SW BIT(0)
138
139#define MESON_SAR_ADC_DELTA_10 0x28
140 #define MESON_SAR_ADC_DELTA_10_TEMP_SEL BIT(27)
141 #define MESON_SAR_ADC_DELTA_10_TS_REVE1 BIT(26)
142 #define MESON_SAR_ADC_DELTA_10_CHAN1_DELTA_VALUE_MASK GENMASK(25, 16)
143 #define MESON_SAR_ADC_DELTA_10_TS_REVE0 BIT(15)
144 #define MESON_SAR_ADC_DELTA_10_TS_C_SHIFT 11
145 #define MESON_SAR_ADC_DELTA_10_TS_C_MASK GENMASK(14, 11)
146 #define MESON_SAR_ADC_DELTA_10_TS_VBG_EN BIT(10)
147 #define MESON_SAR_ADC_DELTA_10_CHAN0_DELTA_VALUE_MASK GENMASK(9, 0)
148
149/*
150 * NOTE: registers from here are undocumented (the vendor Linux kernel driver
151 * and u-boot source served as reference). These only seem to be relevant on
152 * GXBB and newer.
153 */
154#define MESON_SAR_ADC_REG11 0x2c
155 #define MESON_SAR_ADC_REG11_BANDGAP_EN BIT(13)
156
157#define MESON_SAR_ADC_REG13 0x34
158 #define MESON_SAR_ADC_REG13_12BIT_CALIBRATION_MASK GENMASK(13, 8)
159
160#define MESON_SAR_ADC_MAX_FIFO_SIZE 32
161#define MESON_SAR_ADC_TIMEOUT 100 /* ms */
162
163#define NUM_CHANNELS 8
164
165#define MILLION 1000000
166
167struct meson_saradc_data {
168 int num_bits;
169};
170
171struct meson_saradc_priv {
172 const struct meson_saradc_data *data;
173 struct regmap *regmap;
174 struct clk core_clk;
175 struct clk adc_clk;
176 bool initialized;
177 int active_channel;
178 int calibbias;
179 int calibscale;
180};
181
182static unsigned int
183meson_saradc_get_fifo_count(struct meson_saradc_priv *priv)
184{
185 u32 regval;
186
187 regmap_read(priv->regmap, MESON_SAR_ADC_REG0, &regval);
188
189 return FIELD_GET(MESON_SAR_ADC_REG0_FIFO_COUNT_MASK, regval);
190}
191
192static int meson_saradc_lock(struct meson_saradc_priv *priv)
193{
194 uint val, timeout = 10000;
195
196 /* prevent BL30 from using the SAR ADC while we are using it */
197 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
198 MESON_SAR_ADC_DELAY_KERNEL_BUSY,
199 MESON_SAR_ADC_DELAY_KERNEL_BUSY);
200
201 /*
202 * wait until BL30 releases it's lock (so we can use the SAR ADC)
203 */
204 do {
205 udelay(1);
206 regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val);
207 } while (val & MESON_SAR_ADC_DELAY_BL30_BUSY && timeout--);
208
209 if (timeout < 0) {
210 printf("Timeout while waiting for BL30 unlock\n");
211 return -ETIMEDOUT;
212 }
213
214 return 0;
215}
216
217static void meson_saradc_unlock(struct meson_saradc_priv *priv)
218{
219 /* allow BL30 to use the SAR ADC again */
220 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
221 MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0);
222}
223
224static void meson_saradc_clear_fifo(struct meson_saradc_priv *priv)
225{
226 unsigned int count, tmp;
227
228 for (count = 0; count < MESON_SAR_ADC_MAX_FIFO_SIZE; count++) {
229 if (!meson_saradc_get_fifo_count(priv))
230 break;
231
232 regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &tmp);
233 }
234}
235
236static int meson_saradc_calib_val(struct meson_saradc_priv *priv, int val)
237{
238 int tmp;
239
240 /* use val_calib = scale * val_raw + offset calibration function */
241 tmp = div_s64((s64)val * priv->calibscale, MILLION) + priv->calibbias;
242
243 return clamp(tmp, 0, (1 << priv->data->num_bits) - 1);
244}
245
246static int meson_saradc_wait_busy_clear(struct meson_saradc_priv *priv)
247{
248 uint regval, timeout = 10000;
249
250 /*
251 * NOTE: we need a small delay before reading the status, otherwise
252 * the sample engine may not have started internally (which would
253 * seem to us that sampling is already finished).
254 */
255 do {
256 udelay(1);
257 regmap_read(priv->regmap, MESON_SAR_ADC_REG0, &regval);
258 } while (FIELD_GET(MESON_SAR_ADC_REG0_BUSY_MASK, regval) && timeout--);
259
260 if (timeout < 0)
261 return -ETIMEDOUT;
262
263 return 0;
264}
265
266static int meson_saradc_read_raw_sample(struct meson_saradc_priv *priv,
267 unsigned int channel, uint *val)
268{
269 uint regval, fifo_chan, fifo_val, count;
270 int ret;
271
272 ret = meson_saradc_wait_busy_clear(priv);
273 if (ret)
274 return ret;
275
276 count = meson_saradc_get_fifo_count(priv);
277 if (count != 1) {
278 printf("ADC FIFO has %d element(s) instead of one\n", count);
279 return -EINVAL;
280 }
281
282 regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &regval);
283 fifo_chan = FIELD_GET(MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK, regval);
284 if (fifo_chan != channel) {
Heinrich Schuchardt400ea522020-12-27 09:46:46 +0100285 printf("ADC FIFO entry belongs to channel %u instead of %u\n",
Neil Armstrong4c76ddc2018-04-23 16:19:23 +0200286 fifo_chan, channel);
287 return -EINVAL;
288 }
289
290 fifo_val = FIELD_GET(MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK, regval);
291 fifo_val &= GENMASK(priv->data->num_bits - 1, 0);
292 *val = meson_saradc_calib_val(priv, fifo_val);
293
294 return 0;
295}
296
297static void meson_saradc_start_sample_engine(struct meson_saradc_priv *priv)
298{
299 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
300 MESON_SAR_ADC_REG0_FIFO_IRQ_EN,
301 MESON_SAR_ADC_REG0_FIFO_IRQ_EN);
302
303 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
304 MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE,
305 MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE);
306
307 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
308 MESON_SAR_ADC_REG0_SAMPLING_START,
309 MESON_SAR_ADC_REG0_SAMPLING_START);
310}
311
312static void meson_saradc_stop_sample_engine(struct meson_saradc_priv *priv)
313{
314 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
315 MESON_SAR_ADC_REG0_FIFO_IRQ_EN, 0);
316
317 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
318 MESON_SAR_ADC_REG0_SAMPLING_STOP,
319 MESON_SAR_ADC_REG0_SAMPLING_STOP);
320
321 /* wait until all modules are stopped */
322 meson_saradc_wait_busy_clear(priv);
323
324 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
325 MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE, 0);
326}
327
328enum meson_saradc_avg_mode {
329 NO_AVERAGING = 0x0,
330 MEAN_AVERAGING = 0x1,
331 MEDIAN_AVERAGING = 0x2,
332};
333
334enum meson_saradc_num_samples {
335 ONE_SAMPLE = 0x0,
336 TWO_SAMPLES = 0x1,
337 FOUR_SAMPLES = 0x2,
338 EIGHT_SAMPLES = 0x3,
339};
340
341static void meson_saradc_set_averaging(struct meson_saradc_priv *priv,
342 unsigned int channel,
343 enum meson_saradc_avg_mode mode,
344 enum meson_saradc_num_samples samples)
345{
346 int val;
347
348 val = samples << MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(channel);
349 regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL,
350 MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(channel),
351 val);
352
353 val = mode << MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(channel);
354 regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL,
355 MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(channel), val);
356}
357
358static void meson_saradc_enable_channel(struct meson_saradc_priv *priv,
359 unsigned int channel)
360{
361 uint regval;
362
363 /*
364 * the SAR ADC engine allows sampling multiple channels at the same
365 * time. to keep it simple we're only working with one *internal*
366 * channel, which starts counting at index 0 (which means: count = 1).
367 */
368 regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, 0);
369 regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST,
370 MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, regval);
371
372 /* map channel index 0 to the channel which we want to read */
373 regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0), channel);
374 regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST,
375 MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0), regval);
376
377 regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK,
378 channel);
379 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW,
380 MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK,
381 regval);
382
383 regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK,
384 channel);
385 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW,
386 MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK,
387 regval);
388
389 if (channel == 6)
390 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10,
391 MESON_SAR_ADC_DELTA_10_TEMP_SEL, 0);
392}
393
394static int meson_saradc_get_sample(struct meson_saradc_priv *priv,
395 int chan, uint *val)
396{
397 int ret;
398
399 ret = meson_saradc_lock(priv);
400 if (ret)
401 return ret;
402
403 /* clear the FIFO to make sure we're not reading old values */
404 meson_saradc_clear_fifo(priv);
405
406 meson_saradc_set_averaging(priv, chan, MEAN_AVERAGING, EIGHT_SAMPLES);
407
408 meson_saradc_enable_channel(priv, chan);
409
410 meson_saradc_start_sample_engine(priv);
411 ret = meson_saradc_read_raw_sample(priv, chan, val);
412 meson_saradc_stop_sample_engine(priv);
413
414 meson_saradc_unlock(priv);
415
416 if (ret) {
417 printf("failed to read sample for channel %d: %d\n",
418 chan, ret);
419 return ret;
420 }
421
422 return 0;
423}
424
425static int meson_saradc_channel_data(struct udevice *dev, int channel,
426 unsigned int *data)
427{
428 struct meson_saradc_priv *priv = dev_get_priv(dev);
429
430 if (channel != priv->active_channel) {
431 pr_err("Requested channel is not active!");
432 return -EINVAL;
433 }
434
435 return meson_saradc_get_sample(priv, channel, data);
436}
437
438enum meson_saradc_chan7_mux_sel {
439 CHAN7_MUX_VSS = 0x0,
440 CHAN7_MUX_VDD_DIV4 = 0x1,
441 CHAN7_MUX_VDD_DIV2 = 0x2,
442 CHAN7_MUX_VDD_MUL3_DIV4 = 0x3,
443 CHAN7_MUX_VDD = 0x4,
444 CHAN7_MUX_CH7_INPUT = 0x7,
445};
446
447static void meson_saradc_set_chan7_mux(struct meson_saradc_priv *priv,
448 enum meson_saradc_chan7_mux_sel sel)
449{
450 u32 regval;
451
452 regval = FIELD_PREP(MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, sel);
453 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
454 MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, regval);
455
456 udelay(20);
457}
458
459static int meson_saradc_calib(struct meson_saradc_priv *priv)
460{
461 uint nominal0, nominal1, value0, value1;
462 int ret;
463
464 /* use points 25% and 75% for calibration */
465 nominal0 = (1 << priv->data->num_bits) / 4;
466 nominal1 = (1 << priv->data->num_bits) * 3 / 4;
467
468 meson_saradc_set_chan7_mux(priv, CHAN7_MUX_VDD_DIV4);
469 udelay(20);
470 ret = meson_saradc_get_sample(priv, 7, &value0);
471 if (ret < 0)
472 goto out;
473
474 meson_saradc_set_chan7_mux(priv, CHAN7_MUX_VDD_MUL3_DIV4);
475 udelay(20);
476 ret = meson_saradc_get_sample(priv, 7, &value1);
477 if (ret < 0)
478 goto out;
479
480 if (value1 <= value0) {
481 ret = -EINVAL;
482 goto out;
483 }
484
485 priv->calibscale = div_s64((nominal1 - nominal0) * (s64)MILLION,
486 value1 - value0);
487 priv->calibbias = nominal0 - div_s64((s64)value0 * priv->calibscale,
488 MILLION);
489 ret = 0;
490out:
491 meson_saradc_set_chan7_mux(priv, CHAN7_MUX_CH7_INPUT);
492
493 return ret;
494}
495
496static int meson_saradc_init(struct meson_saradc_priv *priv)
497{
498 uint regval;
499 int ret, i;
500
501 priv->calibscale = MILLION;
502
503 /*
504 * make sure we start at CH7 input since the other muxes are only used
505 * for internal calibration.
506 */
507 meson_saradc_set_chan7_mux(priv, CHAN7_MUX_CH7_INPUT);
508
509 /*
510 * leave sampling delay and the input clocks as configured by
511 * BL30 to make sure BL30 gets the values it expects when
512 * reading the temperature sensor.
513 */
514 regmap_read(priv->regmap, MESON_SAR_ADC_REG3, &regval);
Marek Szyprowski6bcd0662020-12-16 08:51:55 +0100515 if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED) {
516 regmap_read(priv->regmap, MESON_SAR_ADC_REG3, &regval);
517 if (regval & MESON_SAR_ADC_REG3_ADC_EN)
518 return 0;
519 }
Neil Armstrong4c76ddc2018-04-23 16:19:23 +0200520
521 meson_saradc_stop_sample_engine(priv);
522
523 /* update the channel 6 MUX to select the temperature sensor */
524 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
525 MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL,
526 MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL);
527
528 /* disable all channels by default */
529 regmap_write(priv->regmap, MESON_SAR_ADC_CHAN_LIST, 0x0);
530
531 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
532 MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE, 0);
533 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
534 MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY,
535 MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY);
536
537 /* delay between two samples = (10+1) * 1uS */
538 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
539 MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
540 FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK,
541 10));
542 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
543 MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK,
544 FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK,
545 0));
546
547 /* delay between two samples = (10+1) * 1uS */
548 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
549 MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
550 FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
551 10));
552 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
553 MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK,
554 FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK,
555 1));
556
557 /*
558 * set up the input channel muxes in MESON_SAR_ADC_CHAN_10_SW
559 * (0 = SAR_ADC_CH0, 1 = SAR_ADC_CH1)
560 */
561 regval = FIELD_PREP(MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK, 0);
562 regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW,
563 MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK,
564 regval);
565 regval = FIELD_PREP(MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK, 1);
566 regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW,
567 MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK,
568 regval);
569
570 /*
571 * set up the input channel muxes in MESON_SAR_ADC_AUX_SW
572 * (2 = SAR_ADC_CH2, 3 = SAR_ADC_CH3, ...) and enable
573 * MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW and
574 * MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW like the vendor driver.
575 */
576 regval = 0;
577 for (i = 2; i <= 7; i++)
578 regval |= i << MESON_SAR_ADC_AUX_SW_MUX_SEL_CHAN_SHIFT(i);
579 regval |= MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW;
580 regval |= MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW;
581 regmap_write(priv->regmap, MESON_SAR_ADC_AUX_SW, regval);
582
583 ret = meson_saradc_lock(priv);
584 if (ret)
585 return ret;
586
587#if CONFIG_IS_ENABLED(CLK)
588 ret = clk_enable(&priv->core_clk);
589 if (ret)
590 return ret;
591#endif
592
593 regval = FIELD_PREP(MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, 1);
594 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
595 MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, regval);
596
597 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
598 MESON_SAR_ADC_REG11_BANDGAP_EN,
599 MESON_SAR_ADC_REG11_BANDGAP_EN);
600
601 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
602 MESON_SAR_ADC_REG3_ADC_EN,
603 MESON_SAR_ADC_REG3_ADC_EN);
604
605 udelay(5);
606
607#if CONFIG_IS_ENABLED(CLK)
608 ret = clk_enable(&priv->adc_clk);
609 if (ret)
610 return ret;
611#endif
612
613 meson_saradc_unlock(priv);
614
615 ret = meson_saradc_calib(priv);
616 if (ret) {
617 printf("calibration failed\n");
618 return -EIO;
619 }
620
621 return 0;
622}
623
624static int meson_saradc_start_channel(struct udevice *dev, int channel)
625{
626 struct meson_saradc_priv *priv = dev_get_priv(dev);
627
628 if (channel < 0 || channel >= NUM_CHANNELS) {
629 printf("Requested channel is invalid!");
630 return -EINVAL;
631 }
632
633 if (!priv->initialized) {
634 int ret;
635
636 ret = meson_saradc_init(priv);
637 if (ret)
638 return ret;
639
640 priv->initialized = true;
641 }
642
643 priv->active_channel = channel;
644
645 return 0;
646}
647
648static int meson_saradc_stop(struct udevice *dev)
649{
650 struct meson_saradc_priv *priv = dev_get_priv(dev);
651
652 priv->active_channel = -1;
653
654 return 0;
655}
656
657static int meson_saradc_probe(struct udevice *dev)
658{
659 struct meson_saradc_priv *priv = dev_get_priv(dev);
660 int ret;
661
Neil Armstrong934f5822018-06-14 13:43:37 +0200662 ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
Neil Armstrong4c76ddc2018-04-23 16:19:23 +0200663 if (ret)
664 return ret;
665
666#if CONFIG_IS_ENABLED(CLK)
667 ret = clk_get_by_name(dev, "core", &priv->core_clk);
668 if (ret)
669 return ret;
670
671 ret = clk_get_by_name(dev, "adc_clk", &priv->adc_clk);
672 if (ret)
673 return ret;
674#endif
675
676 priv->active_channel = -1;
677
678 return 0;
679}
680
Simon Glassaad29ae2020-12-03 16:55:21 -0700681int meson_saradc_of_to_plat(struct udevice *dev)
Neil Armstrong4c76ddc2018-04-23 16:19:23 +0200682{
Simon Glass71fa5b42020-12-03 16:55:18 -0700683 struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
Neil Armstrong4c76ddc2018-04-23 16:19:23 +0200684 struct meson_saradc_priv *priv = dev_get_priv(dev);
685
686 priv->data = (struct meson_saradc_data *)dev_get_driver_data(dev);
687
688 uc_pdata->data_mask = GENMASK(priv->data->num_bits - 1, 0);
689 uc_pdata->data_format = ADC_DATA_FORMAT_BIN;
690 uc_pdata->data_timeout_us = MESON_SAR_ADC_TIMEOUT * 1000;
691 uc_pdata->channel_mask = GENMASK(NUM_CHANNELS - 1, 0);
692
693 return 0;
694}
695
696static const struct adc_ops meson_saradc_ops = {
697 .start_channel = meson_saradc_start_channel,
698 .channel_data = meson_saradc_channel_data,
699 .stop = meson_saradc_stop,
700};
701
702static const struct meson_saradc_data gxbb_saradc_data = {
703 .num_bits = 10,
704};
705
706static const struct meson_saradc_data gxl_saradc_data = {
707 .num_bits = 12,
708};
709
710static const struct udevice_id meson_saradc_ids[] = {
711 { .compatible = "amlogic,meson-gxbb-saradc",
712 .data = (ulong)&gxbb_saradc_data },
713 { .compatible = "amlogic,meson-gxl-saradc",
714 .data = (ulong)&gxl_saradc_data },
715 { .compatible = "amlogic,meson-gxm-saradc",
716 .data = (ulong)&gxl_saradc_data },
Marek Szyprowski4f56e542020-12-16 08:51:54 +0100717 { .compatible = "amlogic,meson-g12a-saradc",
718 .data = (ulong)&gxl_saradc_data },
Neil Armstrong4c76ddc2018-04-23 16:19:23 +0200719 { }
720};
721
722U_BOOT_DRIVER(meson_saradc) = {
723 .name = "meson_saradc",
724 .id = UCLASS_ADC,
725 .of_match = meson_saradc_ids,
726 .ops = &meson_saradc_ops,
727 .probe = meson_saradc_probe,
Simon Glassaad29ae2020-12-03 16:55:21 -0700728 .of_to_plat = meson_saradc_of_to_plat,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700729 .priv_auto = sizeof(struct meson_saradc_priv),
Neil Armstrong4c76ddc2018-04-23 16:19:23 +0200730};