Merge branch 'for-5.4/apple' into for-linus
[linux-2.6-block.git] / drivers / iio / adc / ingenic-adc.c
CommitLineData
1a78daea
AR
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/iio.h>
12#include <linux/io.h>
13#include <linux/iopoll.h>
5a304e1a 14#include <linux/kernel.h>
1a78daea
AR
15#include <linux/module.h>
16#include <linux/mutex.h>
17#include <linux/platform_device.h>
18
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
5a304e1a 26#define JZ_ADC_REG_ADCLK 0x28
1a78daea
AR
27
28#define JZ_ADC_REG_CFG_BAT_MD BIT(4)
5a304e1a
MH
29#define JZ_ADC_REG_ADCLK_CLKDIV_LSB 0
30#define JZ_ADC_REG_ADCLK_CLKDIV10US_LSB 16
1a78daea
AR
31
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
40
5a304e1a
MH
41struct ingenic_adc;
42
1a78daea
AR
43struct 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;
5a304e1a 50 int (*init_clk_div)(struct device *dev, struct ingenic_adc *adc);
1a78daea
AR
51};
52
53struct ingenic_adc {
54 void __iomem *base;
55 struct clk *clk;
56 struct mutex lock;
57 const struct ingenic_adc_soc_data *soc_data;
58 bool low_vref_mode;
59};
60
61static void ingenic_adc_set_config(struct ingenic_adc *adc,
62 uint32_t mask,
63 uint32_t val)
64{
65 uint32_t cfg;
66
67 clk_enable(adc->clk);
68 mutex_lock(&adc->lock);
69
70 cfg = readl(adc->base + JZ_ADC_REG_CFG) & ~mask;
71 cfg |= val;
72 writel(cfg, adc->base + JZ_ADC_REG_CFG);
73
74 mutex_unlock(&adc->lock);
75 clk_disable(adc->clk);
76}
77
78static void ingenic_adc_enable(struct ingenic_adc *adc,
79 int engine,
80 bool enabled)
81{
82 u8 val;
83
84 mutex_lock(&adc->lock);
85 val = readb(adc->base + JZ_ADC_REG_ENABLE);
86
87 if (enabled)
88 val |= BIT(engine);
89 else
90 val &= ~BIT(engine);
91
92 writeb(val, adc->base + JZ_ADC_REG_ENABLE);
93 mutex_unlock(&adc->lock);
94}
95
96static int ingenic_adc_capture(struct ingenic_adc *adc,
97 int engine)
98{
99 u8 val;
100 int ret;
101
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);
105 if (ret)
106 ingenic_adc_enable(adc, engine, false);
107
108 return ret;
109}
110
111static int ingenic_adc_write_raw(struct iio_dev *iio_dev,
112 struct iio_chan_spec const *chan,
113 int val,
114 int val2,
115 long m)
116{
117 struct ingenic_adc *adc = iio_priv(iio_dev);
118
119 switch (m) {
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,
126 0);
127 adc->low_vref_mode = false;
128 } else {
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;
133 }
134 return 0;
135 default:
136 return -EINVAL;
137 }
138 default:
139 return -EINVAL;
140 }
141}
142
143static const int jz4725b_adc_battery_raw_avail[] = {
144 0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1,
145};
146
147static 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,
150};
151
152static const int jz4740_adc_battery_raw_avail[] = {
153 0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1,
154};
155
156static 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,
159};
160
5a304e1a
MH
161static int jz4725b_adc_init_clk_div(struct device *dev, struct ingenic_adc *adc)
162{
163 struct clk *parent_clk;
164 unsigned long parent_rate, rate;
165 unsigned int div_main, div_10us;
166
167 parent_clk = clk_get_parent(adc->clk);
168 if (!parent_clk) {
169 dev_err(dev, "ADC clock has no parent\n");
170 return -ENODEV;
171 }
172 parent_rate = clk_get_rate(parent_clk);
173
174 /*
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.
178 */
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");
184 return -EINVAL;
185 }
186
187 /* We also need a divider that produces a 10us clock. */
188 div_10us = DIV_ROUND_UP(rate, 100000);
189
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);
193
194 return 0;
195}
196
1a78daea
AR
197static 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),
5a304e1a 204 .init_clk_div = jz4725b_adc_init_clk_div,
1a78daea
AR
205};
206
207static 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),
5a304e1a 214 .init_clk_div = NULL, /* no ADCLK register on JZ4740 */
1a78daea
AR
215};
216
217static int ingenic_adc_read_avail(struct iio_dev *iio_dev,
218 struct iio_chan_spec const *chan,
219 const int **vals,
220 int *type,
221 int *length,
222 long m)
223{
224 struct ingenic_adc *adc = iio_priv(iio_dev);
225
226 switch (m) {
227 case IIO_CHAN_INFO_RAW:
228 *type = IIO_VAL_INT;
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;
237 default:
238 return -EINVAL;
239 };
240}
241
242static int ingenic_adc_read_raw(struct iio_dev *iio_dev,
243 struct iio_chan_spec const *chan,
244 int *val,
245 int *val2,
246 long m)
247{
248 struct ingenic_adc *adc = iio_priv(iio_dev);
249 int ret;
250
251 switch (m) {
252 case IIO_CHAN_INFO_RAW:
253 clk_enable(adc->clk);
254 ret = ingenic_adc_capture(adc, chan->channel);
255 if (ret) {
256 clk_disable(adc->clk);
257 return ret;
258 }
259
260 switch (chan->channel) {
261 case INGENIC_ADC_AUX:
262 *val = readw(adc->base + JZ_ADC_REG_ADSDAT);
263 break;
264 case INGENIC_ADC_BATTERY:
265 *val = readw(adc->base + JZ_ADC_REG_ADBDAT);
266 break;
267 }
268
269 clk_disable(adc->clk);
270
271 return IIO_VAL_INT;
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;
277 break;
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;
282 } else {
283 *val = adc->soc_data->battery_high_vref;
284 *val2 = adc->soc_data->battery_high_vref_bits;
285 }
286 break;
287 }
288
289 return IIO_VAL_FRACTIONAL_LOG2;
290 default:
291 return -EINVAL;
292 }
293}
294
295static void ingenic_adc_clk_cleanup(void *data)
296{
297 clk_unprepare(data);
298}
299
300static 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,
304};
305
306static const struct iio_chan_spec ingenic_channels[] = {
307 {
308 .extend_name = "aux",
309 .type = IIO_VOLTAGE,
310 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
311 BIT(IIO_CHAN_INFO_SCALE),
312 .indexed = 1,
313 .channel = INGENIC_ADC_AUX,
314 },
315 {
316 .extend_name = "battery",
317 .type = IIO_VOLTAGE,
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),
322 .indexed = 1,
323 .channel = INGENIC_ADC_BATTERY,
324 },
325};
326
327static int ingenic_adc_probe(struct platform_device *pdev)
328{
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;
334 int ret;
335
336 soc_data = device_get_match_data(dev);
337 if (!soc_data)
338 return -EINVAL;
339
340 iio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
341 if (!iio_dev)
342 return -ENOMEM;
343
344 adc = iio_priv(iio_dev);
345 mutex_init(&adc->lock);
346 adc->soc_data = soc_data;
347
348 mem_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
349 adc->base = devm_ioremap_resource(dev, mem_base);
76838a8f 350 if (IS_ERR(adc->base))
1a78daea 351 return PTR_ERR(adc->base);
1a78daea
AR
352
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);
357 }
358
359 ret = clk_prepare_enable(adc->clk);
360 if (ret) {
361 dev_err(dev, "Failed to enable clock\n");
362 return ret;
363 }
364
5a304e1a
MH
365 /* Set clock dividers. */
366 if (soc_data->init_clk_div) {
367 ret = soc_data->init_clk_div(dev, adc);
368 if (ret) {
369 clk_disable_unprepare(adc->clk);
370 return ret;
371 }
372 }
373
1a78daea
AR
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);
378
379 ret = devm_add_action_or_reset(dev, ingenic_adc_clk_cleanup, adc->clk);
380 if (ret) {
381 dev_err(dev, "Unable to add action\n");
382 return ret;
383 }
384
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;
391
392 ret = devm_iio_device_register(dev, iio_dev);
393 if (ret)
394 dev_err(dev, "Unable to register IIO device\n");
395
396 return ret;
397}
398
399#ifdef CONFIG_OF
400static 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, },
403 { },
404};
405MODULE_DEVICE_TABLE(of, ingenic_adc_of_match);
406#endif
407
408static struct platform_driver ingenic_adc_driver = {
409 .driver = {
410 .name = "ingenic-adc",
411 .of_match_table = of_match_ptr(ingenic_adc_of_match),
412 },
413 .probe = ingenic_adc_probe,
414};
415module_platform_driver(ingenic_adc_driver);
416MODULE_LICENSE("GPL v2");