1 // SPDX-License-Identifier: GPL-2.0
3 * ADC driver for the Ingenic JZ47xx SoCs
4 * Copyright (c) 2019 Artur Rojek <contact@artur-rojek.eu>
6 * based on drivers/mfd/jz4740-adc.c
9 #include <dt-bindings/iio/adc/ingenic,adc.h>
10 #include <linux/clk.h>
11 #include <linux/iio/iio.h>
13 #include <linux/iopoll.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/mutex.h>
17 #include <linux/platform_device.h>
19 #define JZ_ADC_REG_ENABLE 0x00
20 #define JZ_ADC_REG_CFG 0x04
21 #define JZ_ADC_REG_CTRL 0x08
22 #define JZ_ADC_REG_STATUS 0x0c
23 #define JZ_ADC_REG_ADTCH 0x18
24 #define JZ_ADC_REG_ADBDAT 0x1c
25 #define JZ_ADC_REG_ADSDAT 0x20
26 #define JZ_ADC_REG_ADCLK 0x28
28 #define JZ_ADC_REG_ENABLE_PD BIT(7)
29 #define JZ_ADC_REG_CFG_AUX_MD (BIT(0) | BIT(1))
30 #define JZ_ADC_REG_CFG_BAT_MD BIT(4)
31 #define JZ_ADC_REG_ADCLK_CLKDIV_LSB 0
32 #define JZ4725B_ADC_REG_ADCLK_CLKDIV10US_LSB 16
33 #define JZ4770_ADC_REG_ADCLK_CLKDIV10US_LSB 8
34 #define JZ4770_ADC_REG_ADCLK_CLKDIVMS_LSB 16
36 #define JZ_ADC_AUX_VREF 3300
37 #define JZ_ADC_AUX_VREF_BITS 12
38 #define JZ_ADC_BATTERY_LOW_VREF 2500
39 #define JZ_ADC_BATTERY_LOW_VREF_BITS 12
40 #define JZ4725B_ADC_BATTERY_HIGH_VREF 7500
41 #define JZ4725B_ADC_BATTERY_HIGH_VREF_BITS 10
42 #define JZ4740_ADC_BATTERY_HIGH_VREF (7500 * 0.986)
43 #define JZ4740_ADC_BATTERY_HIGH_VREF_BITS 12
44 #define JZ4770_ADC_BATTERY_VREF 6600
45 #define JZ4770_ADC_BATTERY_VREF_BITS 12
49 struct ingenic_adc_soc_data
{
50 unsigned int battery_high_vref
;
51 unsigned int battery_high_vref_bits
;
52 const int *battery_raw_avail
;
53 size_t battery_raw_avail_size
;
54 const int *battery_scale_avail
;
55 size_t battery_scale_avail_size
;
56 unsigned int battery_vref_mode
: 1;
57 unsigned int has_aux2
: 1;
58 int (*init_clk_div
)(struct device
*dev
, struct ingenic_adc
*adc
);
65 struct mutex aux_lock
;
66 const struct ingenic_adc_soc_data
*soc_data
;
70 static void ingenic_adc_set_config(struct ingenic_adc
*adc
,
77 mutex_lock(&adc
->lock
);
79 cfg
= readl(adc
->base
+ JZ_ADC_REG_CFG
) & ~mask
;
81 writel(cfg
, adc
->base
+ JZ_ADC_REG_CFG
);
83 mutex_unlock(&adc
->lock
);
84 clk_disable(adc
->clk
);
87 static void ingenic_adc_enable(struct ingenic_adc
*adc
,
93 mutex_lock(&adc
->lock
);
94 val
= readb(adc
->base
+ JZ_ADC_REG_ENABLE
);
101 writeb(val
, adc
->base
+ JZ_ADC_REG_ENABLE
);
102 mutex_unlock(&adc
->lock
);
105 static int ingenic_adc_capture(struct ingenic_adc
*adc
,
111 ingenic_adc_enable(adc
, engine
, true);
112 ret
= readb_poll_timeout(adc
->base
+ JZ_ADC_REG_ENABLE
, val
,
113 !(val
& BIT(engine
)), 250, 1000);
115 ingenic_adc_enable(adc
, engine
, false);
120 static int ingenic_adc_write_raw(struct iio_dev
*iio_dev
,
121 struct iio_chan_spec
const *chan
,
126 struct ingenic_adc
*adc
= iio_priv(iio_dev
);
129 case IIO_CHAN_INFO_SCALE
:
130 switch (chan
->channel
) {
131 case INGENIC_ADC_BATTERY
:
132 if (!adc
->soc_data
->battery_vref_mode
)
134 if (val
> JZ_ADC_BATTERY_LOW_VREF
) {
135 ingenic_adc_set_config(adc
,
136 JZ_ADC_REG_CFG_BAT_MD
,
138 adc
->low_vref_mode
= false;
140 ingenic_adc_set_config(adc
,
141 JZ_ADC_REG_CFG_BAT_MD
,
142 JZ_ADC_REG_CFG_BAT_MD
);
143 adc
->low_vref_mode
= true;
154 static const int jz4725b_adc_battery_raw_avail
[] = {
155 0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS
) - 1,
158 static const int jz4725b_adc_battery_scale_avail
[] = {
159 JZ4725B_ADC_BATTERY_HIGH_VREF
, JZ4725B_ADC_BATTERY_HIGH_VREF_BITS
,
160 JZ_ADC_BATTERY_LOW_VREF
, JZ_ADC_BATTERY_LOW_VREF_BITS
,
163 static const int jz4740_adc_battery_raw_avail
[] = {
164 0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS
) - 1,
167 static const int jz4740_adc_battery_scale_avail
[] = {
168 JZ4740_ADC_BATTERY_HIGH_VREF
, JZ4740_ADC_BATTERY_HIGH_VREF_BITS
,
169 JZ_ADC_BATTERY_LOW_VREF
, JZ_ADC_BATTERY_LOW_VREF_BITS
,
172 static const int jz4770_adc_battery_raw_avail
[] = {
173 0, 1, (1 << JZ4770_ADC_BATTERY_VREF_BITS
) - 1,
176 static const int jz4770_adc_battery_scale_avail
[] = {
177 JZ4770_ADC_BATTERY_VREF
, JZ4770_ADC_BATTERY_VREF_BITS
,
180 static int jz4725b_adc_init_clk_div(struct device
*dev
, struct ingenic_adc
*adc
)
182 struct clk
*parent_clk
;
183 unsigned long parent_rate
, rate
;
184 unsigned int div_main
, div_10us
;
186 parent_clk
= clk_get_parent(adc
->clk
);
188 dev_err(dev
, "ADC clock has no parent\n");
191 parent_rate
= clk_get_rate(parent_clk
);
194 * The JZ4725B ADC works at 500 kHz to 8 MHz.
195 * We pick the highest rate possible.
196 * In practice we typically get 6 MHz, half of the 12 MHz EXT clock.
198 div_main
= DIV_ROUND_UP(parent_rate
, 8000000);
199 div_main
= clamp(div_main
, 1u, 64u);
200 rate
= parent_rate
/ div_main
;
201 if (rate
< 500000 || rate
> 8000000) {
202 dev_err(dev
, "No valid divider for ADC main clock\n");
206 /* We also need a divider that produces a 10us clock. */
207 div_10us
= DIV_ROUND_UP(rate
, 100000);
209 writel(((div_10us
- 1) << JZ4725B_ADC_REG_ADCLK_CLKDIV10US_LSB
) |
210 (div_main
- 1) << JZ_ADC_REG_ADCLK_CLKDIV_LSB
,
211 adc
->base
+ JZ_ADC_REG_ADCLK
);
216 static int jz4770_adc_init_clk_div(struct device
*dev
, struct ingenic_adc
*adc
)
218 struct clk
*parent_clk
;
219 unsigned long parent_rate
, rate
;
220 unsigned int div_main
, div_ms
, div_10us
;
222 parent_clk
= clk_get_parent(adc
->clk
);
224 dev_err(dev
, "ADC clock has no parent\n");
227 parent_rate
= clk_get_rate(parent_clk
);
230 * The JZ4770 ADC works at 20 kHz to 200 kHz.
231 * We pick the highest rate possible.
233 div_main
= DIV_ROUND_UP(parent_rate
, 200000);
234 div_main
= clamp(div_main
, 1u, 256u);
235 rate
= parent_rate
/ div_main
;
236 if (rate
< 20000 || rate
> 200000) {
237 dev_err(dev
, "No valid divider for ADC main clock\n");
241 /* We also need a divider that produces a 10us clock. */
242 div_10us
= DIV_ROUND_UP(rate
, 10000);
243 /* And another, which produces a 1ms clock. */
244 div_ms
= DIV_ROUND_UP(rate
, 1000);
246 writel(((div_ms
- 1) << JZ4770_ADC_REG_ADCLK_CLKDIVMS_LSB
) |
247 ((div_10us
- 1) << JZ4770_ADC_REG_ADCLK_CLKDIV10US_LSB
) |
248 (div_main
- 1) << JZ_ADC_REG_ADCLK_CLKDIV_LSB
,
249 adc
->base
+ JZ_ADC_REG_ADCLK
);
254 static const struct ingenic_adc_soc_data jz4725b_adc_soc_data
= {
255 .battery_high_vref
= JZ4725B_ADC_BATTERY_HIGH_VREF
,
256 .battery_high_vref_bits
= JZ4725B_ADC_BATTERY_HIGH_VREF_BITS
,
257 .battery_raw_avail
= jz4725b_adc_battery_raw_avail
,
258 .battery_raw_avail_size
= ARRAY_SIZE(jz4725b_adc_battery_raw_avail
),
259 .battery_scale_avail
= jz4725b_adc_battery_scale_avail
,
260 .battery_scale_avail_size
= ARRAY_SIZE(jz4725b_adc_battery_scale_avail
),
261 .battery_vref_mode
= true,
263 .init_clk_div
= jz4725b_adc_init_clk_div
,
266 static const struct ingenic_adc_soc_data jz4740_adc_soc_data
= {
267 .battery_high_vref
= JZ4740_ADC_BATTERY_HIGH_VREF
,
268 .battery_high_vref_bits
= JZ4740_ADC_BATTERY_HIGH_VREF_BITS
,
269 .battery_raw_avail
= jz4740_adc_battery_raw_avail
,
270 .battery_raw_avail_size
= ARRAY_SIZE(jz4740_adc_battery_raw_avail
),
271 .battery_scale_avail
= jz4740_adc_battery_scale_avail
,
272 .battery_scale_avail_size
= ARRAY_SIZE(jz4740_adc_battery_scale_avail
),
273 .battery_vref_mode
= true,
275 .init_clk_div
= NULL
, /* no ADCLK register on JZ4740 */
278 static const struct ingenic_adc_soc_data jz4770_adc_soc_data
= {
279 .battery_high_vref
= JZ4770_ADC_BATTERY_VREF
,
280 .battery_high_vref_bits
= JZ4770_ADC_BATTERY_VREF_BITS
,
281 .battery_raw_avail
= jz4770_adc_battery_raw_avail
,
282 .battery_raw_avail_size
= ARRAY_SIZE(jz4770_adc_battery_raw_avail
),
283 .battery_scale_avail
= jz4770_adc_battery_scale_avail
,
284 .battery_scale_avail_size
= ARRAY_SIZE(jz4770_adc_battery_scale_avail
),
285 .battery_vref_mode
= false,
287 .init_clk_div
= jz4770_adc_init_clk_div
,
290 static int ingenic_adc_read_avail(struct iio_dev
*iio_dev
,
291 struct iio_chan_spec
const *chan
,
297 struct ingenic_adc
*adc
= iio_priv(iio_dev
);
300 case IIO_CHAN_INFO_RAW
:
302 *length
= adc
->soc_data
->battery_raw_avail_size
;
303 *vals
= adc
->soc_data
->battery_raw_avail
;
304 return IIO_AVAIL_RANGE
;
305 case IIO_CHAN_INFO_SCALE
:
306 *type
= IIO_VAL_FRACTIONAL_LOG2
;
307 *length
= adc
->soc_data
->battery_scale_avail_size
;
308 *vals
= adc
->soc_data
->battery_scale_avail
;
309 return IIO_AVAIL_LIST
;
315 static int ingenic_adc_read_chan_info_raw(struct ingenic_adc
*adc
,
316 struct iio_chan_spec
const *chan
,
319 int bit
, ret
, engine
= (chan
->channel
== INGENIC_ADC_BATTERY
);
321 /* We cannot sample AUX/AUX2 in parallel. */
322 mutex_lock(&adc
->aux_lock
);
323 if (adc
->soc_data
->has_aux2
&& engine
== 0) {
324 bit
= BIT(chan
->channel
== INGENIC_ADC_AUX2
);
325 ingenic_adc_set_config(adc
, JZ_ADC_REG_CFG_AUX_MD
, bit
);
328 clk_enable(adc
->clk
);
329 ret
= ingenic_adc_capture(adc
, engine
);
333 switch (chan
->channel
) {
334 case INGENIC_ADC_AUX
:
335 case INGENIC_ADC_AUX2
:
336 *val
= readw(adc
->base
+ JZ_ADC_REG_ADSDAT
);
338 case INGENIC_ADC_BATTERY
:
339 *val
= readw(adc
->base
+ JZ_ADC_REG_ADBDAT
);
345 clk_disable(adc
->clk
);
346 mutex_unlock(&adc
->aux_lock
);
351 static int ingenic_adc_read_raw(struct iio_dev
*iio_dev
,
352 struct iio_chan_spec
const *chan
,
357 struct ingenic_adc
*adc
= iio_priv(iio_dev
);
360 case IIO_CHAN_INFO_RAW
:
361 return ingenic_adc_read_chan_info_raw(adc
, chan
, val
);
362 case IIO_CHAN_INFO_SCALE
:
363 switch (chan
->channel
) {
364 case INGENIC_ADC_AUX
:
365 case INGENIC_ADC_AUX2
:
366 *val
= JZ_ADC_AUX_VREF
;
367 *val2
= JZ_ADC_AUX_VREF_BITS
;
369 case INGENIC_ADC_BATTERY
:
370 if (adc
->low_vref_mode
) {
371 *val
= JZ_ADC_BATTERY_LOW_VREF
;
372 *val2
= JZ_ADC_BATTERY_LOW_VREF_BITS
;
374 *val
= adc
->soc_data
->battery_high_vref
;
375 *val2
= adc
->soc_data
->battery_high_vref_bits
;
380 return IIO_VAL_FRACTIONAL_LOG2
;
386 static void ingenic_adc_clk_cleanup(void *data
)
391 static const struct iio_info ingenic_adc_info
= {
392 .write_raw
= ingenic_adc_write_raw
,
393 .read_raw
= ingenic_adc_read_raw
,
394 .read_avail
= ingenic_adc_read_avail
,
397 static const struct iio_chan_spec ingenic_channels
[] = {
399 .extend_name
= "aux",
401 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
402 BIT(IIO_CHAN_INFO_SCALE
),
404 .channel
= INGENIC_ADC_AUX
,
407 .extend_name
= "battery",
409 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
410 BIT(IIO_CHAN_INFO_SCALE
),
411 .info_mask_separate_available
= BIT(IIO_CHAN_INFO_RAW
) |
412 BIT(IIO_CHAN_INFO_SCALE
),
414 .channel
= INGENIC_ADC_BATTERY
,
416 { /* Must always be last in the array. */
417 .extend_name
= "aux2",
419 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
420 BIT(IIO_CHAN_INFO_SCALE
),
422 .channel
= INGENIC_ADC_AUX2
,
426 static int ingenic_adc_probe(struct platform_device
*pdev
)
428 struct device
*dev
= &pdev
->dev
;
429 struct iio_dev
*iio_dev
;
430 struct ingenic_adc
*adc
;
431 const struct ingenic_adc_soc_data
*soc_data
;
434 soc_data
= device_get_match_data(dev
);
438 iio_dev
= devm_iio_device_alloc(dev
, sizeof(*adc
));
442 adc
= iio_priv(iio_dev
);
443 mutex_init(&adc
->lock
);
444 mutex_init(&adc
->aux_lock
);
445 adc
->soc_data
= soc_data
;
447 adc
->base
= devm_platform_ioremap_resource(pdev
, 0);
448 if (IS_ERR(adc
->base
))
449 return PTR_ERR(adc
->base
);
451 adc
->clk
= devm_clk_get(dev
, "adc");
452 if (IS_ERR(adc
->clk
)) {
453 dev_err(dev
, "Unable to get clock\n");
454 return PTR_ERR(adc
->clk
);
457 ret
= clk_prepare_enable(adc
->clk
);
459 dev_err(dev
, "Failed to enable clock\n");
463 /* Set clock dividers. */
464 if (soc_data
->init_clk_div
) {
465 ret
= soc_data
->init_clk_div(dev
, adc
);
467 clk_disable_unprepare(adc
->clk
);
472 /* Put hardware in a known passive state. */
473 writeb(0x00, adc
->base
+ JZ_ADC_REG_ENABLE
);
474 writeb(0xff, adc
->base
+ JZ_ADC_REG_CTRL
);
475 usleep_range(2000, 3000); /* Must wait at least 2ms. */
476 clk_disable(adc
->clk
);
478 ret
= devm_add_action_or_reset(dev
, ingenic_adc_clk_cleanup
, adc
->clk
);
480 dev_err(dev
, "Unable to add action\n");
484 iio_dev
->dev
.parent
= dev
;
485 iio_dev
->name
= "jz-adc";
486 iio_dev
->modes
= INDIO_DIRECT_MODE
;
487 iio_dev
->channels
= ingenic_channels
;
488 iio_dev
->num_channels
= ARRAY_SIZE(ingenic_channels
);
489 /* Remove AUX2 from the list of supported channels. */
490 if (!adc
->soc_data
->has_aux2
)
491 iio_dev
->num_channels
-= 1;
492 iio_dev
->info
= &ingenic_adc_info
;
494 ret
= devm_iio_device_register(dev
, iio_dev
);
496 dev_err(dev
, "Unable to register IIO device\n");
502 static const struct of_device_id ingenic_adc_of_match
[] = {
503 { .compatible
= "ingenic,jz4725b-adc", .data
= &jz4725b_adc_soc_data
, },
504 { .compatible
= "ingenic,jz4740-adc", .data
= &jz4740_adc_soc_data
, },
505 { .compatible
= "ingenic,jz4770-adc", .data
= &jz4770_adc_soc_data
, },
508 MODULE_DEVICE_TABLE(of
, ingenic_adc_of_match
);
511 static struct platform_driver ingenic_adc_driver
= {
513 .name
= "ingenic-adc",
514 .of_match_table
= of_match_ptr(ingenic_adc_of_match
),
516 .probe
= ingenic_adc_probe
,
518 module_platform_driver(ingenic_adc_driver
);
519 MODULE_LICENSE("GPL v2");