1// SPDX-License-Identifier: GPL-2.0
2/*
3 * ADC driver for the Ingenic JZ47xx SoCs
4 * Copyright (c) 2019 Artur Rojek <contact@artur-rojek.eu>
5 *
6 * based on drivers/mfd/jz4740-adc.c
7 */
8
9#include <dt-bindings/iio/adc/ingenic,adc.h>
10#include <linux/clk.h>
11#include <linux/iio/buffer.h>
12#include <linux/iio/iio.h>
13#include <linux/interrupt.h>
14#include <linux/io.h>
15#include <linux/iopoll.h>
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/mod_devicetable.h>
19#include <linux/mutex.h>
20#include <linux/of.h>
21#include <linux/platform_device.h>
22#include <linux/property.h>
23
24#define JZ_ADC_REG_ENABLE 0x00
25#define JZ_ADC_REG_CFG 0x04
26#define JZ_ADC_REG_CTRL 0x08
27#define JZ_ADC_REG_STATUS 0x0c
28#define JZ_ADC_REG_ADSAME 0x10
29#define JZ_ADC_REG_ADWAIT 0x14
30#define JZ_ADC_REG_ADTCH 0x18
31#define JZ_ADC_REG_ADBDAT 0x1c
32#define JZ_ADC_REG_ADSDAT 0x20
33#define JZ_ADC_REG_ADCMD 0x24
34#define JZ_ADC_REG_ADCLK 0x28
35
36#define JZ_ADC_REG_ENABLE_PD BIT(7)
37#define JZ_ADC_REG_CFG_AUX_MD (BIT(0) | BIT(1))
38#define JZ_ADC_REG_CFG_BAT_MD BIT(4)
39#define JZ_ADC_REG_CFG_SAMPLE_NUM(n) ((n) << 10)
40#define JZ_ADC_REG_CFG_PULL_UP(n) ((n) << 16)
41#define JZ_ADC_REG_CFG_CMD_SEL BIT(22)
42#define JZ_ADC_REG_CFG_VBAT_SEL BIT(30)
43#define JZ_ADC_REG_CFG_TOUCH_OPS_MASK (BIT(31) | GENMASK(23, 10))
44#define JZ_ADC_REG_ADCLK_CLKDIV_LSB 0
45#define JZ4725B_ADC_REG_ADCLK_CLKDIV10US_LSB 16
46#define JZ4770_ADC_REG_ADCLK_CLKDIV10US_LSB 8
47#define JZ4770_ADC_REG_ADCLK_CLKDIVMS_LSB 16
48
49#define JZ_ADC_REG_ADCMD_YNADC BIT(7)
50#define JZ_ADC_REG_ADCMD_YPADC BIT(8)
51#define JZ_ADC_REG_ADCMD_XNADC BIT(9)
52#define JZ_ADC_REG_ADCMD_XPADC BIT(10)
53#define JZ_ADC_REG_ADCMD_VREFPYP BIT(11)
54#define JZ_ADC_REG_ADCMD_VREFPXP BIT(12)
55#define JZ_ADC_REG_ADCMD_VREFPXN BIT(13)
56#define JZ_ADC_REG_ADCMD_VREFPAUX BIT(14)
57#define JZ_ADC_REG_ADCMD_VREFPVDD33 BIT(15)
58#define JZ_ADC_REG_ADCMD_VREFNYN BIT(16)
59#define JZ_ADC_REG_ADCMD_VREFNXP BIT(17)
60#define JZ_ADC_REG_ADCMD_VREFNXN BIT(18)
61#define JZ_ADC_REG_ADCMD_VREFAUX BIT(19)
62#define JZ_ADC_REG_ADCMD_YNGRU BIT(20)
63#define JZ_ADC_REG_ADCMD_XNGRU BIT(21)
64#define JZ_ADC_REG_ADCMD_XPGRU BIT(22)
65#define JZ_ADC_REG_ADCMD_YPSUP BIT(23)
66#define JZ_ADC_REG_ADCMD_XNSUP BIT(24)
67#define JZ_ADC_REG_ADCMD_XPSUP BIT(25)
68
69#define JZ_ADC_AUX_VREF 3300
70#define JZ_ADC_AUX_VREF_BITS 12
71#define JZ_ADC_BATTERY_LOW_VREF 2500
72#define JZ_ADC_BATTERY_LOW_VREF_BITS 12
73#define JZ4725B_ADC_BATTERY_HIGH_VREF 7500
74#define JZ4725B_ADC_BATTERY_HIGH_VREF_BITS 10
75#define JZ4740_ADC_BATTERY_HIGH_VREF (7500 * 0.986)
76#define JZ4740_ADC_BATTERY_HIGH_VREF_BITS 12
77#define JZ4760_ADC_BATTERY_VREF 2500
78#define JZ4770_ADC_BATTERY_VREF 1200
79#define JZ4770_ADC_BATTERY_VREF_BITS 12
80
81#define JZ_ADC_IRQ_AUX BIT(0)
82#define JZ_ADC_IRQ_BATTERY BIT(1)
83#define JZ_ADC_IRQ_TOUCH BIT(2)
84#define JZ_ADC_IRQ_PEN_DOWN BIT(3)
85#define JZ_ADC_IRQ_PEN_UP BIT(4)
86#define JZ_ADC_IRQ_PEN_DOWN_SLEEP BIT(5)
87#define JZ_ADC_IRQ_SLEEP BIT(7)
88
89struct ingenic_adc;
90
91struct ingenic_adc_soc_data {
92 unsigned int battery_high_vref;
93 unsigned int battery_high_vref_bits;
94 const int *battery_raw_avail;
95 size_t battery_raw_avail_size;
96 const int *battery_scale_avail;
97 size_t battery_scale_avail_size;
98 unsigned int battery_vref_mode: 1;
99 unsigned int has_aux_md: 1;
100 const struct iio_chan_spec *channels;
101 unsigned int num_channels;
102 int (*init_clk_div)(struct device *dev, struct ingenic_adc *adc);
103};
104
105struct ingenic_adc {
106 void __iomem *base;
107 struct clk *clk;
108 struct mutex lock;
109 struct mutex aux_lock;
110 const struct ingenic_adc_soc_data *soc_data;
111 bool low_vref_mode;
112};
113
114static void ingenic_adc_set_adcmd(struct iio_dev *iio_dev, unsigned long mask)
115{
116 struct ingenic_adc *adc = iio_priv(indio_dev: iio_dev);
117
118 mutex_lock(&adc->lock);
119
120 /* Init ADCMD */
121 readl(addr: adc->base + JZ_ADC_REG_ADCMD);
122
123 if (mask & 0x3) {
124 /* Second channel (INGENIC_ADC_TOUCH_YP): sample YP vs. GND */
125 writel(JZ_ADC_REG_ADCMD_XNGRU
126 | JZ_ADC_REG_ADCMD_VREFNXN | JZ_ADC_REG_ADCMD_VREFPVDD33
127 | JZ_ADC_REG_ADCMD_YPADC,
128 addr: adc->base + JZ_ADC_REG_ADCMD);
129
130 /* First channel (INGENIC_ADC_TOUCH_XP): sample XP vs. GND */
131 writel(JZ_ADC_REG_ADCMD_YNGRU
132 | JZ_ADC_REG_ADCMD_VREFNYN | JZ_ADC_REG_ADCMD_VREFPVDD33
133 | JZ_ADC_REG_ADCMD_XPADC,
134 addr: adc->base + JZ_ADC_REG_ADCMD);
135 }
136
137 if (mask & 0xc) {
138 /* Fourth channel (INGENIC_ADC_TOUCH_YN): sample YN vs. GND */
139 writel(JZ_ADC_REG_ADCMD_XNGRU
140 | JZ_ADC_REG_ADCMD_VREFNXN | JZ_ADC_REG_ADCMD_VREFPVDD33
141 | JZ_ADC_REG_ADCMD_YNADC,
142 addr: adc->base + JZ_ADC_REG_ADCMD);
143
144 /* Third channel (INGENIC_ADC_TOUCH_XN): sample XN vs. GND */
145 writel(JZ_ADC_REG_ADCMD_YNGRU
146 | JZ_ADC_REG_ADCMD_VREFNYN | JZ_ADC_REG_ADCMD_VREFPVDD33
147 | JZ_ADC_REG_ADCMD_XNADC,
148 addr: adc->base + JZ_ADC_REG_ADCMD);
149 }
150
151 if (mask & 0x30) {
152 /* Sixth channel (INGENIC_ADC_TOUCH_YD): sample YP vs. YN */
153 writel(JZ_ADC_REG_ADCMD_VREFNYN | JZ_ADC_REG_ADCMD_VREFPVDD33
154 | JZ_ADC_REG_ADCMD_YPADC,
155 addr: adc->base + JZ_ADC_REG_ADCMD);
156
157 /* Fifth channel (INGENIC_ADC_TOUCH_XD): sample XP vs. XN */
158 writel(JZ_ADC_REG_ADCMD_VREFNXN | JZ_ADC_REG_ADCMD_VREFPVDD33
159 | JZ_ADC_REG_ADCMD_XPADC,
160 addr: adc->base + JZ_ADC_REG_ADCMD);
161 }
162
163 /* We're done */
164 writel(val: 0, addr: adc->base + JZ_ADC_REG_ADCMD);
165
166 mutex_unlock(lock: &adc->lock);
167}
168
169static void ingenic_adc_set_config(struct ingenic_adc *adc,
170 uint32_t mask,
171 uint32_t val)
172{
173 uint32_t cfg;
174
175 mutex_lock(&adc->lock);
176
177 cfg = readl(addr: adc->base + JZ_ADC_REG_CFG) & ~mask;
178 cfg |= val;
179 writel(val: cfg, addr: adc->base + JZ_ADC_REG_CFG);
180
181 mutex_unlock(lock: &adc->lock);
182}
183
184static void ingenic_adc_enable_unlocked(struct ingenic_adc *adc,
185 int engine,
186 bool enabled)
187{
188 u8 val;
189
190 val = readb(addr: adc->base + JZ_ADC_REG_ENABLE);
191
192 if (enabled)
193 val |= BIT(engine);
194 else
195 val &= ~BIT(engine);
196
197 writeb(val, addr: adc->base + JZ_ADC_REG_ENABLE);
198}
199
200static void ingenic_adc_enable(struct ingenic_adc *adc,
201 int engine,
202 bool enabled)
203{
204 mutex_lock(&adc->lock);
205 ingenic_adc_enable_unlocked(adc, engine, enabled);
206 mutex_unlock(lock: &adc->lock);
207}
208
209static int ingenic_adc_capture(struct ingenic_adc *adc,
210 int engine)
211{
212 u32 cfg;
213 u8 val;
214 int ret;
215
216 /*
217 * Disable CMD_SEL temporarily, because it causes wrong VBAT readings,
218 * probably due to the switch of VREF. We must keep the lock here to
219 * avoid races with the buffer enable/disable functions.
220 */
221 mutex_lock(&adc->lock);
222 cfg = readl(addr: adc->base + JZ_ADC_REG_CFG);
223 writel(val: cfg & ~JZ_ADC_REG_CFG_CMD_SEL, addr: adc->base + JZ_ADC_REG_CFG);
224
225 ingenic_adc_enable_unlocked(adc, engine, enabled: true);
226 ret = readb_poll_timeout(adc->base + JZ_ADC_REG_ENABLE, val,
227 !(val & BIT(engine)), 250, 1000);
228 if (ret)
229 ingenic_adc_enable_unlocked(adc, engine, enabled: false);
230
231 writel(val: cfg, addr: adc->base + JZ_ADC_REG_CFG);
232 mutex_unlock(lock: &adc->lock);
233
234 return ret;
235}
236
237static int ingenic_adc_write_raw(struct iio_dev *iio_dev,
238 struct iio_chan_spec const *chan,
239 int val,
240 int val2,
241 long m)
242{
243 struct ingenic_adc *adc = iio_priv(indio_dev: iio_dev);
244 struct device *dev = iio_dev->dev.parent;
245 int ret;
246
247 switch (m) {
248 case IIO_CHAN_INFO_SCALE:
249 switch (chan->channel) {
250 case INGENIC_ADC_BATTERY:
251 if (!adc->soc_data->battery_vref_mode)
252 return -EINVAL;
253
254 ret = clk_enable(clk: adc->clk);
255 if (ret) {
256 dev_err(dev, "Failed to enable clock: %d\n",
257 ret);
258 return ret;
259 }
260
261 if (val > JZ_ADC_BATTERY_LOW_VREF) {
262 ingenic_adc_set_config(adc,
263 JZ_ADC_REG_CFG_BAT_MD,
264 val: 0);
265 adc->low_vref_mode = false;
266 } else {
267 ingenic_adc_set_config(adc,
268 JZ_ADC_REG_CFG_BAT_MD,
269 JZ_ADC_REG_CFG_BAT_MD);
270 adc->low_vref_mode = true;
271 }
272
273 clk_disable(clk: adc->clk);
274
275 return 0;
276 default:
277 return -EINVAL;
278 }
279 default:
280 return -EINVAL;
281 }
282}
283
284static const int jz4725b_adc_battery_raw_avail[] = {
285 0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1,
286};
287
288static const int jz4725b_adc_battery_scale_avail[] = {
289 JZ4725B_ADC_BATTERY_HIGH_VREF, JZ4725B_ADC_BATTERY_HIGH_VREF_BITS,
290 JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS,
291};
292
293static const int jz4740_adc_battery_raw_avail[] = {
294 0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1,
295};
296
297static const int jz4740_adc_battery_scale_avail[] = {
298 JZ4740_ADC_BATTERY_HIGH_VREF, JZ4740_ADC_BATTERY_HIGH_VREF_BITS,
299 JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS,
300};
301
302static const int jz4760_adc_battery_scale_avail[] = {
303 JZ4760_ADC_BATTERY_VREF, JZ4770_ADC_BATTERY_VREF_BITS,
304};
305
306static const int jz4770_adc_battery_raw_avail[] = {
307 0, 1, (1 << JZ4770_ADC_BATTERY_VREF_BITS) - 1,
308};
309
310static const int jz4770_adc_battery_scale_avail[] = {
311 JZ4770_ADC_BATTERY_VREF, JZ4770_ADC_BATTERY_VREF_BITS,
312};
313
314static int jz4725b_adc_init_clk_div(struct device *dev, struct ingenic_adc *adc)
315{
316 struct clk *parent_clk;
317 unsigned long parent_rate, rate;
318 unsigned int div_main, div_10us;
319
320 parent_clk = clk_get_parent(clk: adc->clk);
321 if (!parent_clk) {
322 dev_err(dev, "ADC clock has no parent\n");
323 return -ENODEV;
324 }
325 parent_rate = clk_get_rate(clk: parent_clk);
326
327 /*
328 * The JZ4725B ADC works at 500 kHz to 8 MHz.
329 * We pick the highest rate possible.
330 * In practice we typically get 6 MHz, half of the 12 MHz EXT clock.
331 */
332 div_main = DIV_ROUND_UP(parent_rate, 8000000);
333 div_main = clamp(div_main, 1u, 64u);
334 rate = parent_rate / div_main;
335 if (rate < 500000 || rate > 8000000) {
336 dev_err(dev, "No valid divider for ADC main clock\n");
337 return -EINVAL;
338 }
339
340 /* We also need a divider that produces a 10us clock. */
341 div_10us = DIV_ROUND_UP(rate, 100000);
342
343 writel(val: ((div_10us - 1) << JZ4725B_ADC_REG_ADCLK_CLKDIV10US_LSB) |
344 (div_main - 1) << JZ_ADC_REG_ADCLK_CLKDIV_LSB,
345 addr: adc->base + JZ_ADC_REG_ADCLK);
346
347 return 0;
348}
349
350static int jz4770_adc_init_clk_div(struct device *dev, struct ingenic_adc *adc)
351{
352 struct clk *parent_clk;
353 unsigned long parent_rate, rate;
354 unsigned int div_main, div_ms, div_10us;
355
356 parent_clk = clk_get_parent(clk: adc->clk);
357 if (!parent_clk) {
358 dev_err(dev, "ADC clock has no parent\n");
359 return -ENODEV;
360 }
361 parent_rate = clk_get_rate(clk: parent_clk);
362
363 /*
364 * The JZ4770 ADC works at 20 kHz to 200 kHz.
365 * We pick the highest rate possible.
366 */
367 div_main = DIV_ROUND_UP(parent_rate, 200000);
368 div_main = clamp(div_main, 1u, 256u);
369 rate = parent_rate / div_main;
370 if (rate < 20000 || rate > 200000) {
371 dev_err(dev, "No valid divider for ADC main clock\n");
372 return -EINVAL;
373 }
374
375 /* We also need a divider that produces a 10us clock. */
376 div_10us = DIV_ROUND_UP(rate, 10000);
377 /* And another, which produces a 1ms clock. */
378 div_ms = DIV_ROUND_UP(rate, 1000);
379
380 writel(val: ((div_ms - 1) << JZ4770_ADC_REG_ADCLK_CLKDIVMS_LSB) |
381 ((div_10us - 1) << JZ4770_ADC_REG_ADCLK_CLKDIV10US_LSB) |
382 (div_main - 1) << JZ_ADC_REG_ADCLK_CLKDIV_LSB,
383 addr: adc->base + JZ_ADC_REG_ADCLK);
384
385 return 0;
386}
387
388static const struct iio_chan_spec jz4740_channels[] = {
389 {
390 .extend_name = "aux",
391 .type = IIO_VOLTAGE,
392 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
393 BIT(IIO_CHAN_INFO_SCALE),
394 .indexed = 1,
395 .channel = INGENIC_ADC_AUX,
396 .scan_index = -1,
397 },
398 {
399 .extend_name = "battery",
400 .type = IIO_VOLTAGE,
401 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
402 BIT(IIO_CHAN_INFO_SCALE),
403 .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
404 BIT(IIO_CHAN_INFO_SCALE),
405 .indexed = 1,
406 .channel = INGENIC_ADC_BATTERY,
407 .scan_index = -1,
408 },
409};
410
411static const struct iio_chan_spec jz4760_channels[] = {
412 {
413 .extend_name = "aux",
414 .type = IIO_VOLTAGE,
415 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
416 BIT(IIO_CHAN_INFO_SCALE),
417 .indexed = 1,
418 .channel = INGENIC_ADC_AUX0,
419 .scan_index = -1,
420 },
421 {
422 .extend_name = "aux1",
423 .type = IIO_VOLTAGE,
424 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
425 BIT(IIO_CHAN_INFO_SCALE),
426 .indexed = 1,
427 .channel = INGENIC_ADC_AUX,
428 .scan_index = -1,
429 },
430 {
431 .extend_name = "aux2",
432 .type = IIO_VOLTAGE,
433 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
434 BIT(IIO_CHAN_INFO_SCALE),
435 .indexed = 1,
436 .channel = INGENIC_ADC_AUX2,
437 .scan_index = -1,
438 },
439 {
440 .extend_name = "battery",
441 .type = IIO_VOLTAGE,
442 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
443 BIT(IIO_CHAN_INFO_SCALE),
444 .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
445 BIT(IIO_CHAN_INFO_SCALE),
446 .indexed = 1,
447 .channel = INGENIC_ADC_BATTERY,
448 .scan_index = -1,
449 },
450};
451
452static const struct iio_chan_spec jz4770_channels[] = {
453 {
454 .type = IIO_VOLTAGE,
455 .indexed = 1,
456 .channel = INGENIC_ADC_TOUCH_XP,
457 .scan_index = 0,
458 .scan_type = {
459 .sign = 'u',
460 .realbits = 12,
461 .storagebits = 16,
462 },
463 },
464 {
465 .type = IIO_VOLTAGE,
466 .indexed = 1,
467 .channel = INGENIC_ADC_TOUCH_YP,
468 .scan_index = 1,
469 .scan_type = {
470 .sign = 'u',
471 .realbits = 12,
472 .storagebits = 16,
473 },
474 },
475 {
476 .type = IIO_VOLTAGE,
477 .indexed = 1,
478 .channel = INGENIC_ADC_TOUCH_XN,
479 .scan_index = 2,
480 .scan_type = {
481 .sign = 'u',
482 .realbits = 12,
483 .storagebits = 16,
484 },
485 },
486 {
487 .type = IIO_VOLTAGE,
488 .indexed = 1,
489 .channel = INGENIC_ADC_TOUCH_YN,
490 .scan_index = 3,
491 .scan_type = {
492 .sign = 'u',
493 .realbits = 12,
494 .storagebits = 16,
495 },
496 },
497 {
498 .type = IIO_VOLTAGE,
499 .indexed = 1,
500 .channel = INGENIC_ADC_TOUCH_XD,
501 .scan_index = 4,
502 .scan_type = {
503 .sign = 'u',
504 .realbits = 12,
505 .storagebits = 16,
506 },
507 },
508 {
509 .type = IIO_VOLTAGE,
510 .indexed = 1,
511 .channel = INGENIC_ADC_TOUCH_YD,
512 .scan_index = 5,
513 .scan_type = {
514 .sign = 'u',
515 .realbits = 12,
516 .storagebits = 16,
517 },
518 },
519 {
520 .extend_name = "aux",
521 .type = IIO_VOLTAGE,
522 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
523 BIT(IIO_CHAN_INFO_SCALE),
524 .indexed = 1,
525 .channel = INGENIC_ADC_AUX,
526 .scan_index = -1,
527 },
528 {
529 .extend_name = "battery",
530 .type = IIO_VOLTAGE,
531 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
532 BIT(IIO_CHAN_INFO_SCALE),
533 .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
534 BIT(IIO_CHAN_INFO_SCALE),
535 .indexed = 1,
536 .channel = INGENIC_ADC_BATTERY,
537 .scan_index = -1,
538 },
539 {
540 .extend_name = "aux2",
541 .type = IIO_VOLTAGE,
542 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
543 BIT(IIO_CHAN_INFO_SCALE),
544 .indexed = 1,
545 .channel = INGENIC_ADC_AUX2,
546 .scan_index = -1,
547 },
548};
549
550static const struct ingenic_adc_soc_data jz4725b_adc_soc_data = {
551 .battery_high_vref = JZ4725B_ADC_BATTERY_HIGH_VREF,
552 .battery_high_vref_bits = JZ4725B_ADC_BATTERY_HIGH_VREF_BITS,
553 .battery_raw_avail = jz4725b_adc_battery_raw_avail,
554 .battery_raw_avail_size = ARRAY_SIZE(jz4725b_adc_battery_raw_avail),
555 .battery_scale_avail = jz4725b_adc_battery_scale_avail,
556 .battery_scale_avail_size = ARRAY_SIZE(jz4725b_adc_battery_scale_avail),
557 .battery_vref_mode = true,
558 .has_aux_md = false,
559 .channels = jz4740_channels,
560 .num_channels = ARRAY_SIZE(jz4740_channels),
561 .init_clk_div = jz4725b_adc_init_clk_div,
562};
563
564static const struct ingenic_adc_soc_data jz4740_adc_soc_data = {
565 .battery_high_vref = JZ4740_ADC_BATTERY_HIGH_VREF,
566 .battery_high_vref_bits = JZ4740_ADC_BATTERY_HIGH_VREF_BITS,
567 .battery_raw_avail = jz4740_adc_battery_raw_avail,
568 .battery_raw_avail_size = ARRAY_SIZE(jz4740_adc_battery_raw_avail),
569 .battery_scale_avail = jz4740_adc_battery_scale_avail,
570 .battery_scale_avail_size = ARRAY_SIZE(jz4740_adc_battery_scale_avail),
571 .battery_vref_mode = true,
572 .has_aux_md = false,
573 .channels = jz4740_channels,
574 .num_channels = ARRAY_SIZE(jz4740_channels),
575 .init_clk_div = NULL, /* no ADCLK register on JZ4740 */
576};
577
578static const struct ingenic_adc_soc_data jz4760_adc_soc_data = {
579 .battery_high_vref = JZ4760_ADC_BATTERY_VREF,
580 .battery_high_vref_bits = JZ4770_ADC_BATTERY_VREF_BITS,
581 .battery_raw_avail = jz4770_adc_battery_raw_avail,
582 .battery_raw_avail_size = ARRAY_SIZE(jz4770_adc_battery_raw_avail),
583 .battery_scale_avail = jz4760_adc_battery_scale_avail,
584 .battery_scale_avail_size = ARRAY_SIZE(jz4760_adc_battery_scale_avail),
585 .battery_vref_mode = false,
586 .has_aux_md = true,
587 .channels = jz4760_channels,
588 .num_channels = ARRAY_SIZE(jz4760_channels),
589 .init_clk_div = jz4770_adc_init_clk_div,
590};
591
592static const struct ingenic_adc_soc_data jz4770_adc_soc_data = {
593 .battery_high_vref = JZ4770_ADC_BATTERY_VREF,
594 .battery_high_vref_bits = JZ4770_ADC_BATTERY_VREF_BITS,
595 .battery_raw_avail = jz4770_adc_battery_raw_avail,
596 .battery_raw_avail_size = ARRAY_SIZE(jz4770_adc_battery_raw_avail),
597 .battery_scale_avail = jz4770_adc_battery_scale_avail,
598 .battery_scale_avail_size = ARRAY_SIZE(jz4770_adc_battery_scale_avail),
599 .battery_vref_mode = false,
600 .has_aux_md = true,
601 .channels = jz4770_channels,
602 .num_channels = ARRAY_SIZE(jz4770_channels),
603 .init_clk_div = jz4770_adc_init_clk_div,
604};
605
606static int ingenic_adc_read_avail(struct iio_dev *iio_dev,
607 struct iio_chan_spec const *chan,
608 const int **vals,
609 int *type,
610 int *length,
611 long m)
612{
613 struct ingenic_adc *adc = iio_priv(indio_dev: iio_dev);
614
615 switch (m) {
616 case IIO_CHAN_INFO_RAW:
617 *type = IIO_VAL_INT;
618 *length = adc->soc_data->battery_raw_avail_size;
619 *vals = adc->soc_data->battery_raw_avail;
620 return IIO_AVAIL_RANGE;
621 case IIO_CHAN_INFO_SCALE:
622 *type = IIO_VAL_FRACTIONAL_LOG2;
623 *length = adc->soc_data->battery_scale_avail_size;
624 *vals = adc->soc_data->battery_scale_avail;
625 return IIO_AVAIL_LIST;
626 default:
627 return -EINVAL;
628 }
629}
630
631static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
632 struct iio_chan_spec const *chan,
633 int *val)
634{
635 int cmd, ret, engine = (chan->channel == INGENIC_ADC_BATTERY);
636 struct ingenic_adc *adc = iio_priv(indio_dev: iio_dev);
637
638 ret = clk_enable(clk: adc->clk);
639 if (ret) {
640 dev_err(iio_dev->dev.parent, "Failed to enable clock: %d\n",
641 ret);
642 return ret;
643 }
644
645 /* We cannot sample the aux channels in parallel. */
646 mutex_lock(&adc->aux_lock);
647 if (adc->soc_data->has_aux_md && engine == 0) {
648 switch (chan->channel) {
649 case INGENIC_ADC_AUX0:
650 cmd = 0;
651 break;
652 case INGENIC_ADC_AUX:
653 cmd = 1;
654 break;
655 case INGENIC_ADC_AUX2:
656 cmd = 2;
657 break;
658 }
659
660 ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_AUX_MD, val: cmd);
661 }
662
663 ret = ingenic_adc_capture(adc, engine);
664 if (ret)
665 goto out;
666
667 switch (chan->channel) {
668 case INGENIC_ADC_AUX0:
669 case INGENIC_ADC_AUX:
670 case INGENIC_ADC_AUX2:
671 *val = readw(addr: adc->base + JZ_ADC_REG_ADSDAT);
672 break;
673 case INGENIC_ADC_BATTERY:
674 *val = readw(addr: adc->base + JZ_ADC_REG_ADBDAT);
675 break;
676 }
677
678 ret = IIO_VAL_INT;
679out:
680 mutex_unlock(lock: &adc->aux_lock);
681 clk_disable(clk: adc->clk);
682
683 return ret;
684}
685
686static int ingenic_adc_read_raw(struct iio_dev *iio_dev,
687 struct iio_chan_spec const *chan,
688 int *val,
689 int *val2,
690 long m)
691{
692 struct ingenic_adc *adc = iio_priv(indio_dev: iio_dev);
693
694 switch (m) {
695 case IIO_CHAN_INFO_RAW:
696 return ingenic_adc_read_chan_info_raw(iio_dev, chan, val);
697 case IIO_CHAN_INFO_SCALE:
698 switch (chan->channel) {
699 case INGENIC_ADC_AUX0:
700 case INGENIC_ADC_AUX:
701 case INGENIC_ADC_AUX2:
702 *val = JZ_ADC_AUX_VREF;
703 *val2 = JZ_ADC_AUX_VREF_BITS;
704 break;
705 case INGENIC_ADC_BATTERY:
706 if (adc->low_vref_mode) {
707 *val = JZ_ADC_BATTERY_LOW_VREF;
708 *val2 = JZ_ADC_BATTERY_LOW_VREF_BITS;
709 } else {
710 *val = adc->soc_data->battery_high_vref;
711 *val2 = adc->soc_data->battery_high_vref_bits;
712 }
713 break;
714 }
715
716 return IIO_VAL_FRACTIONAL_LOG2;
717 default:
718 return -EINVAL;
719 }
720}
721
722static int ingenic_adc_fwnode_xlate(struct iio_dev *iio_dev,
723 const struct fwnode_reference_args *iiospec)
724{
725 int i;
726
727 if (!iiospec->nargs)
728 return -EINVAL;
729
730 for (i = 0; i < iio_dev->num_channels; ++i)
731 if (iio_dev->channels[i].channel == iiospec->args[0])
732 return i;
733
734 return -EINVAL;
735}
736
737static const struct iio_info ingenic_adc_info = {
738 .write_raw = ingenic_adc_write_raw,
739 .read_raw = ingenic_adc_read_raw,
740 .read_avail = ingenic_adc_read_avail,
741 .fwnode_xlate = ingenic_adc_fwnode_xlate,
742};
743
744static int ingenic_adc_buffer_enable(struct iio_dev *iio_dev)
745{
746 struct ingenic_adc *adc = iio_priv(indio_dev: iio_dev);
747 int ret;
748
749 ret = clk_enable(clk: adc->clk);
750 if (ret) {
751 dev_err(iio_dev->dev.parent, "Failed to enable clock: %d\n",
752 ret);
753 return ret;
754 }
755
756 /* It takes significant time for the touchscreen hw to stabilize. */
757 msleep(msecs: 50);
758 ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_TOUCH_OPS_MASK,
759 JZ_ADC_REG_CFG_SAMPLE_NUM(4) |
760 JZ_ADC_REG_CFG_PULL_UP(4));
761
762 writew(val: 80, addr: adc->base + JZ_ADC_REG_ADWAIT);
763 writew(val: 2, addr: adc->base + JZ_ADC_REG_ADSAME);
764 writeb(val: (u8)~JZ_ADC_IRQ_TOUCH, addr: adc->base + JZ_ADC_REG_CTRL);
765 writel(val: 0, addr: adc->base + JZ_ADC_REG_ADTCH);
766
767 ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_CMD_SEL,
768 JZ_ADC_REG_CFG_CMD_SEL);
769 ingenic_adc_set_adcmd(iio_dev, mask: iio_dev->active_scan_mask[0]);
770
771 ingenic_adc_enable(adc, engine: 2, enabled: true);
772
773 return 0;
774}
775
776static int ingenic_adc_buffer_disable(struct iio_dev *iio_dev)
777{
778 struct ingenic_adc *adc = iio_priv(indio_dev: iio_dev);
779
780 ingenic_adc_enable(adc, engine: 2, enabled: false);
781
782 ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_CMD_SEL, val: 0);
783
784 writeb(val: 0xff, addr: adc->base + JZ_ADC_REG_CTRL);
785 writeb(val: 0xff, addr: adc->base + JZ_ADC_REG_STATUS);
786 ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_TOUCH_OPS_MASK, val: 0);
787 writew(val: 0, addr: adc->base + JZ_ADC_REG_ADSAME);
788 writew(val: 0, addr: adc->base + JZ_ADC_REG_ADWAIT);
789 clk_disable(clk: adc->clk);
790
791 return 0;
792}
793
794static const struct iio_buffer_setup_ops ingenic_buffer_setup_ops = {
795 .postenable = &ingenic_adc_buffer_enable,
796 .predisable = &ingenic_adc_buffer_disable
797};
798
799static irqreturn_t ingenic_adc_irq(int irq, void *data)
800{
801 struct iio_dev *iio_dev = data;
802 struct ingenic_adc *adc = iio_priv(indio_dev: iio_dev);
803 unsigned long mask = iio_dev->active_scan_mask[0];
804 unsigned int i;
805 u32 tdat[3];
806
807 for (i = 0; i < ARRAY_SIZE(tdat); mask >>= 2, i++) {
808 if (mask & 0x3)
809 tdat[i] = readl(addr: adc->base + JZ_ADC_REG_ADTCH);
810 else
811 tdat[i] = 0;
812 }
813
814 iio_push_to_buffers(indio_dev: iio_dev, data: tdat);
815 writeb(JZ_ADC_IRQ_TOUCH, addr: adc->base + JZ_ADC_REG_STATUS);
816
817 return IRQ_HANDLED;
818}
819
820static int ingenic_adc_probe(struct platform_device *pdev)
821{
822 struct device *dev = &pdev->dev;
823 struct iio_dev *iio_dev;
824 struct ingenic_adc *adc;
825 const struct ingenic_adc_soc_data *soc_data;
826 int irq, ret;
827
828 soc_data = device_get_match_data(dev);
829 if (!soc_data)
830 return -EINVAL;
831
832 iio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*adc));
833 if (!iio_dev)
834 return -ENOMEM;
835
836 adc = iio_priv(indio_dev: iio_dev);
837 mutex_init(&adc->lock);
838 mutex_init(&adc->aux_lock);
839 adc->soc_data = soc_data;
840
841 irq = platform_get_irq(pdev, 0);
842 if (irq < 0)
843 return irq;
844
845 ret = devm_request_irq(dev, irq, handler: ingenic_adc_irq, irqflags: 0,
846 devname: dev_name(dev), dev_id: iio_dev);
847 if (ret < 0) {
848 dev_err(dev, "Failed to request irq: %d\n", ret);
849 return ret;
850 }
851
852 adc->base = devm_platform_ioremap_resource(pdev, index: 0);
853 if (IS_ERR(ptr: adc->base))
854 return PTR_ERR(ptr: adc->base);
855
856 adc->clk = devm_clk_get_prepared(dev, id: "adc");
857 if (IS_ERR(ptr: adc->clk)) {
858 dev_err(dev, "Unable to get clock\n");
859 return PTR_ERR(ptr: adc->clk);
860 }
861
862 ret = clk_enable(clk: adc->clk);
863 if (ret) {
864 dev_err(dev, "Failed to enable clock\n");
865 return ret;
866 }
867
868 /* Set clock dividers. */
869 if (soc_data->init_clk_div) {
870 ret = soc_data->init_clk_div(dev, adc);
871 if (ret) {
872 clk_disable_unprepare(clk: adc->clk);
873 return ret;
874 }
875 }
876
877 /* Put hardware in a known passive state. */
878 writeb(val: 0x00, addr: adc->base + JZ_ADC_REG_ENABLE);
879 writeb(val: 0xff, addr: adc->base + JZ_ADC_REG_CTRL);
880
881 /* JZ4760B specific */
882 if (device_property_present(dev, propname: "ingenic,use-internal-divider"))
883 ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_VBAT_SEL,
884 JZ_ADC_REG_CFG_VBAT_SEL);
885 else
886 ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_VBAT_SEL, val: 0);
887
888 usleep_range(min: 2000, max: 3000); /* Must wait at least 2ms. */
889 clk_disable(clk: adc->clk);
890
891 iio_dev->name = "jz-adc";
892 iio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
893 iio_dev->setup_ops = &ingenic_buffer_setup_ops;
894 iio_dev->channels = soc_data->channels;
895 iio_dev->num_channels = soc_data->num_channels;
896 iio_dev->info = &ingenic_adc_info;
897
898 ret = devm_iio_device_register(dev, iio_dev);
899 if (ret)
900 dev_err(dev, "Unable to register IIO device\n");
901
902 return ret;
903}
904
905static const struct of_device_id ingenic_adc_of_match[] = {
906 { .compatible = "ingenic,jz4725b-adc", .data = &jz4725b_adc_soc_data, },
907 { .compatible = "ingenic,jz4740-adc", .data = &jz4740_adc_soc_data, },
908 { .compatible = "ingenic,jz4760-adc", .data = &jz4760_adc_soc_data, },
909 { .compatible = "ingenic,jz4760b-adc", .data = &jz4760_adc_soc_data, },
910 { .compatible = "ingenic,jz4770-adc", .data = &jz4770_adc_soc_data, },
911 { },
912};
913MODULE_DEVICE_TABLE(of, ingenic_adc_of_match);
914
915static struct platform_driver ingenic_adc_driver = {
916 .driver = {
917 .name = "ingenic-adc",
918 .of_match_table = ingenic_adc_of_match,
919 },
920 .probe = ingenic_adc_probe,
921};
922module_platform_driver(ingenic_adc_driver);
923MODULE_LICENSE("GPL v2");
924

source code of linux/drivers/iio/adc/ingenic-adc.c