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_CFG_BAT_MD BIT(4)
29 #define JZ_ADC_REG_ADCLK_CLKDIV_LSB 0
30 #define JZ_ADC_REG_ADCLK_CLKDIV10US_LSB 16
32 #define JZ_ADC_AUX_VREF 3300
33 #define JZ_ADC_AUX_VREF_BITS 12
34 #define JZ_ADC_BATTERY_LOW_VREF 2500
35 #define JZ_ADC_BATTERY_LOW_VREF_BITS 12
36 #define JZ4725B_ADC_BATTERY_HIGH_VREF 7500
37 #define JZ4725B_ADC_BATTERY_HIGH_VREF_BITS 10
38 #define JZ4740_ADC_BATTERY_HIGH_VREF (7500 * 0.986)
39 #define JZ4740_ADC_BATTERY_HIGH_VREF_BITS 12
43 struct ingenic_adc_soc_data {
44 unsigned int battery_high_vref;
45 unsigned int battery_high_vref_bits;
46 const int *battery_raw_avail;
47 size_t battery_raw_avail_size;
48 const int *battery_scale_avail;
49 size_t battery_scale_avail_size;
50 int (*init_clk_div)(struct device *dev, struct ingenic_adc *adc);
57 const struct ingenic_adc_soc_data *soc_data;
61 static void ingenic_adc_set_config(struct ingenic_adc *adc,
68 mutex_lock(&adc->lock);
70 cfg = readl(adc->base + JZ_ADC_REG_CFG) & ~mask;
72 writel(cfg, adc->base + JZ_ADC_REG_CFG);
74 mutex_unlock(&adc->lock);
75 clk_disable(adc->clk);
78 static void ingenic_adc_enable(struct ingenic_adc *adc,
84 mutex_lock(&adc->lock);
85 val = readb(adc->base + JZ_ADC_REG_ENABLE);
92 writeb(val, adc->base + JZ_ADC_REG_ENABLE);
93 mutex_unlock(&adc->lock);
96 static int ingenic_adc_capture(struct ingenic_adc *adc,
102 ingenic_adc_enable(adc, engine, true);
103 ret = readb_poll_timeout(adc->base + JZ_ADC_REG_ENABLE, val,
104 !(val & BIT(engine)), 250, 1000);
106 ingenic_adc_enable(adc, engine, false);
111 static int ingenic_adc_write_raw(struct iio_dev *iio_dev,
112 struct iio_chan_spec const *chan,
117 struct ingenic_adc *adc = iio_priv(iio_dev);
120 case IIO_CHAN_INFO_SCALE:
121 switch (chan->channel) {
122 case INGENIC_ADC_BATTERY:
123 if (val > JZ_ADC_BATTERY_LOW_VREF) {
124 ingenic_adc_set_config(adc,
125 JZ_ADC_REG_CFG_BAT_MD,
127 adc->low_vref_mode = false;
129 ingenic_adc_set_config(adc,
130 JZ_ADC_REG_CFG_BAT_MD,
131 JZ_ADC_REG_CFG_BAT_MD);
132 adc->low_vref_mode = true;
143 static const int jz4725b_adc_battery_raw_avail[] = {
144 0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1,
147 static const int jz4725b_adc_battery_scale_avail[] = {
148 JZ4725B_ADC_BATTERY_HIGH_VREF, JZ4725B_ADC_BATTERY_HIGH_VREF_BITS,
149 JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS,
152 static const int jz4740_adc_battery_raw_avail[] = {
153 0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1,
156 static const int jz4740_adc_battery_scale_avail[] = {
157 JZ4740_ADC_BATTERY_HIGH_VREF, JZ4740_ADC_BATTERY_HIGH_VREF_BITS,
158 JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS,
161 static int jz4725b_adc_init_clk_div(struct device *dev, struct ingenic_adc *adc)
163 struct clk *parent_clk;
164 unsigned long parent_rate, rate;
165 unsigned int div_main, div_10us;
167 parent_clk = clk_get_parent(adc->clk);
169 dev_err(dev, "ADC clock has no parent\n");
172 parent_rate = clk_get_rate(parent_clk);
175 * The JZ4725B ADC works at 500 kHz to 8 MHz.
176 * We pick the highest rate possible.
177 * In practice we typically get 6 MHz, half of the 12 MHz EXT clock.
179 div_main = DIV_ROUND_UP(parent_rate, 8000000);
180 div_main = clamp(div_main, 1u, 64u);
181 rate = parent_rate / div_main;
182 if (rate < 500000 || rate > 8000000) {
183 dev_err(dev, "No valid divider for ADC main clock\n");
187 /* We also need a divider that produces a 10us clock. */
188 div_10us = DIV_ROUND_UP(rate, 100000);
190 writel(((div_10us - 1) << JZ_ADC_REG_ADCLK_CLKDIV10US_LSB) |
191 (div_main - 1) << JZ_ADC_REG_ADCLK_CLKDIV_LSB,
192 adc->base + JZ_ADC_REG_ADCLK);
197 static const struct ingenic_adc_soc_data jz4725b_adc_soc_data = {
198 .battery_high_vref = JZ4725B_ADC_BATTERY_HIGH_VREF,
199 .battery_high_vref_bits = JZ4725B_ADC_BATTERY_HIGH_VREF_BITS,
200 .battery_raw_avail = jz4725b_adc_battery_raw_avail,
201 .battery_raw_avail_size = ARRAY_SIZE(jz4725b_adc_battery_raw_avail),
202 .battery_scale_avail = jz4725b_adc_battery_scale_avail,
203 .battery_scale_avail_size = ARRAY_SIZE(jz4725b_adc_battery_scale_avail),
204 .init_clk_div = jz4725b_adc_init_clk_div,
207 static const struct ingenic_adc_soc_data jz4740_adc_soc_data = {
208 .battery_high_vref = JZ4740_ADC_BATTERY_HIGH_VREF,
209 .battery_high_vref_bits = JZ4740_ADC_BATTERY_HIGH_VREF_BITS,
210 .battery_raw_avail = jz4740_adc_battery_raw_avail,
211 .battery_raw_avail_size = ARRAY_SIZE(jz4740_adc_battery_raw_avail),
212 .battery_scale_avail = jz4740_adc_battery_scale_avail,
213 .battery_scale_avail_size = ARRAY_SIZE(jz4740_adc_battery_scale_avail),
214 .init_clk_div = NULL, /* no ADCLK register on JZ4740 */
217 static int ingenic_adc_read_avail(struct iio_dev *iio_dev,
218 struct iio_chan_spec const *chan,
224 struct ingenic_adc *adc = iio_priv(iio_dev);
227 case IIO_CHAN_INFO_RAW:
229 *length = adc->soc_data->battery_raw_avail_size;
230 *vals = adc->soc_data->battery_raw_avail;
231 return IIO_AVAIL_RANGE;
232 case IIO_CHAN_INFO_SCALE:
233 *type = IIO_VAL_FRACTIONAL_LOG2;
234 *length = adc->soc_data->battery_scale_avail_size;
235 *vals = adc->soc_data->battery_scale_avail;
236 return IIO_AVAIL_LIST;
242 static int ingenic_adc_read_raw(struct iio_dev *iio_dev,
243 struct iio_chan_spec const *chan,
248 struct ingenic_adc *adc = iio_priv(iio_dev);
252 case IIO_CHAN_INFO_RAW:
253 clk_enable(adc->clk);
254 ret = ingenic_adc_capture(adc, chan->channel);
256 clk_disable(adc->clk);
260 switch (chan->channel) {
261 case INGENIC_ADC_AUX:
262 *val = readw(adc->base + JZ_ADC_REG_ADSDAT);
264 case INGENIC_ADC_BATTERY:
265 *val = readw(adc->base + JZ_ADC_REG_ADBDAT);
269 clk_disable(adc->clk);
272 case IIO_CHAN_INFO_SCALE:
273 switch (chan->channel) {
274 case INGENIC_ADC_AUX:
275 *val = JZ_ADC_AUX_VREF;
276 *val2 = JZ_ADC_AUX_VREF_BITS;
278 case INGENIC_ADC_BATTERY:
279 if (adc->low_vref_mode) {
280 *val = JZ_ADC_BATTERY_LOW_VREF;
281 *val2 = JZ_ADC_BATTERY_LOW_VREF_BITS;
283 *val = adc->soc_data->battery_high_vref;
284 *val2 = adc->soc_data->battery_high_vref_bits;
289 return IIO_VAL_FRACTIONAL_LOG2;
295 static void ingenic_adc_clk_cleanup(void *data)
300 static const struct iio_info ingenic_adc_info = {
301 .write_raw = ingenic_adc_write_raw,
302 .read_raw = ingenic_adc_read_raw,
303 .read_avail = ingenic_adc_read_avail,
306 static const struct iio_chan_spec ingenic_channels[] = {
308 .extend_name = "aux",
310 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
311 BIT(IIO_CHAN_INFO_SCALE),
313 .channel = INGENIC_ADC_AUX,
316 .extend_name = "battery",
318 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
319 BIT(IIO_CHAN_INFO_SCALE),
320 .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
321 BIT(IIO_CHAN_INFO_SCALE),
323 .channel = INGENIC_ADC_BATTERY,
327 static int ingenic_adc_probe(struct platform_device *pdev)
329 struct device *dev = &pdev->dev;
330 struct iio_dev *iio_dev;
331 struct ingenic_adc *adc;
332 struct resource *mem_base;
333 const struct ingenic_adc_soc_data *soc_data;
336 soc_data = device_get_match_data(dev);
340 iio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
344 adc = iio_priv(iio_dev);
345 mutex_init(&adc->lock);
346 adc->soc_data = soc_data;
348 mem_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
349 adc->base = devm_ioremap_resource(dev, mem_base);
350 if (IS_ERR(adc->base))
351 return PTR_ERR(adc->base);
353 adc->clk = devm_clk_get(dev, "adc");
354 if (IS_ERR(adc->clk)) {
355 dev_err(dev, "Unable to get clock\n");
356 return PTR_ERR(adc->clk);
359 ret = clk_prepare_enable(adc->clk);
361 dev_err(dev, "Failed to enable clock\n");
365 /* Set clock dividers. */
366 if (soc_data->init_clk_div) {
367 ret = soc_data->init_clk_div(dev, adc);
369 clk_disable_unprepare(adc->clk);
374 /* Put hardware in a known passive state. */
375 writeb(0x00, adc->base + JZ_ADC_REG_ENABLE);
376 writeb(0xff, adc->base + JZ_ADC_REG_CTRL);
377 clk_disable(adc->clk);
379 ret = devm_add_action_or_reset(dev, ingenic_adc_clk_cleanup, adc->clk);
381 dev_err(dev, "Unable to add action\n");
385 iio_dev->dev.parent = dev;
386 iio_dev->name = "jz-adc";
387 iio_dev->modes = INDIO_DIRECT_MODE;
388 iio_dev->channels = ingenic_channels;
389 iio_dev->num_channels = ARRAY_SIZE(ingenic_channels);
390 iio_dev->info = &ingenic_adc_info;
392 ret = devm_iio_device_register(dev, iio_dev);
394 dev_err(dev, "Unable to register IIO device\n");
400 static const struct of_device_id ingenic_adc_of_match[] = {
401 { .compatible = "ingenic,jz4725b-adc", .data = &jz4725b_adc_soc_data, },
402 { .compatible = "ingenic,jz4740-adc", .data = &jz4740_adc_soc_data, },
405 MODULE_DEVICE_TABLE(of, ingenic_adc_of_match);
408 static struct platform_driver ingenic_adc_driver = {
410 .name = "ingenic-adc",
411 .of_match_table = of_match_ptr(ingenic_adc_of_match),
413 .probe = ingenic_adc_probe,
415 module_platform_driver(ingenic_adc_driver);
416 MODULE_LICENSE("GPL v2");