xref: /openbmc/linux/drivers/iio/adc/ingenic-adc.c (revision f8e17c17)
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>
14 #include <linux/kernel.h>
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
26 #define JZ_ADC_REG_ADCLK		0x28
27 
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
35 
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
46 
47 struct ingenic_adc;
48 
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);
59 };
60 
61 struct ingenic_adc {
62 	void __iomem *base;
63 	struct clk *clk;
64 	struct mutex lock;
65 	struct mutex aux_lock;
66 	const struct ingenic_adc_soc_data *soc_data;
67 	bool low_vref_mode;
68 };
69 
70 static void ingenic_adc_set_config(struct ingenic_adc *adc,
71 				   uint32_t mask,
72 				   uint32_t val)
73 {
74 	uint32_t cfg;
75 
76 	clk_enable(adc->clk);
77 	mutex_lock(&adc->lock);
78 
79 	cfg = readl(adc->base + JZ_ADC_REG_CFG) & ~mask;
80 	cfg |= val;
81 	writel(cfg, adc->base + JZ_ADC_REG_CFG);
82 
83 	mutex_unlock(&adc->lock);
84 	clk_disable(adc->clk);
85 }
86 
87 static void ingenic_adc_enable(struct ingenic_adc *adc,
88 			       int engine,
89 			       bool enabled)
90 {
91 	u8 val;
92 
93 	mutex_lock(&adc->lock);
94 	val = readb(adc->base + JZ_ADC_REG_ENABLE);
95 
96 	if (enabled)
97 		val |= BIT(engine);
98 	else
99 		val &= ~BIT(engine);
100 
101 	writeb(val, adc->base + JZ_ADC_REG_ENABLE);
102 	mutex_unlock(&adc->lock);
103 }
104 
105 static int ingenic_adc_capture(struct ingenic_adc *adc,
106 			       int engine)
107 {
108 	u8 val;
109 	int ret;
110 
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);
114 	if (ret)
115 		ingenic_adc_enable(adc, engine, false);
116 
117 	return ret;
118 }
119 
120 static int ingenic_adc_write_raw(struct iio_dev *iio_dev,
121 				 struct iio_chan_spec const *chan,
122 				 int val,
123 				 int val2,
124 				 long m)
125 {
126 	struct ingenic_adc *adc = iio_priv(iio_dev);
127 
128 	switch (m) {
129 	case IIO_CHAN_INFO_SCALE:
130 		switch (chan->channel) {
131 		case INGENIC_ADC_BATTERY:
132 			if (!adc->soc_data->battery_vref_mode)
133 				return -EINVAL;
134 			if (val > JZ_ADC_BATTERY_LOW_VREF) {
135 				ingenic_adc_set_config(adc,
136 						       JZ_ADC_REG_CFG_BAT_MD,
137 						       0);
138 				adc->low_vref_mode = false;
139 			} else {
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;
144 			}
145 			return 0;
146 		default:
147 			return -EINVAL;
148 		}
149 	default:
150 		return -EINVAL;
151 	}
152 }
153 
154 static const int jz4725b_adc_battery_raw_avail[] = {
155 	0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1,
156 };
157 
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,
161 };
162 
163 static const int jz4740_adc_battery_raw_avail[] = {
164 	0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1,
165 };
166 
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,
170 };
171 
172 static const int jz4770_adc_battery_raw_avail[] = {
173 	0, 1, (1 << JZ4770_ADC_BATTERY_VREF_BITS) - 1,
174 };
175 
176 static const int jz4770_adc_battery_scale_avail[] = {
177 	JZ4770_ADC_BATTERY_VREF, JZ4770_ADC_BATTERY_VREF_BITS,
178 };
179 
180 static int jz4725b_adc_init_clk_div(struct device *dev, struct ingenic_adc *adc)
181 {
182 	struct clk *parent_clk;
183 	unsigned long parent_rate, rate;
184 	unsigned int div_main, div_10us;
185 
186 	parent_clk = clk_get_parent(adc->clk);
187 	if (!parent_clk) {
188 		dev_err(dev, "ADC clock has no parent\n");
189 		return -ENODEV;
190 	}
191 	parent_rate = clk_get_rate(parent_clk);
192 
193 	/*
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.
197 	 */
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");
203 		return -EINVAL;
204 	}
205 
206 	/* We also need a divider that produces a 10us clock. */
207 	div_10us = DIV_ROUND_UP(rate, 100000);
208 
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);
212 
213 	return 0;
214 }
215 
216 static int jz4770_adc_init_clk_div(struct device *dev, struct ingenic_adc *adc)
217 {
218 	struct clk *parent_clk;
219 	unsigned long parent_rate, rate;
220 	unsigned int div_main, div_ms, div_10us;
221 
222 	parent_clk = clk_get_parent(adc->clk);
223 	if (!parent_clk) {
224 		dev_err(dev, "ADC clock has no parent\n");
225 		return -ENODEV;
226 	}
227 	parent_rate = clk_get_rate(parent_clk);
228 
229 	/*
230 	 * The JZ4770 ADC works at 20 kHz to 200 kHz.
231 	 * We pick the highest rate possible.
232 	 */
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");
238 		return -EINVAL;
239 	}
240 
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);
245 
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);
250 
251 	return 0;
252 }
253 
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,
262 	.has_aux2 = false,
263 	.init_clk_div = jz4725b_adc_init_clk_div,
264 };
265 
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,
274 	.has_aux2 = false,
275 	.init_clk_div = NULL, /* no ADCLK register on JZ4740 */
276 };
277 
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,
286 	.has_aux2 = true,
287 	.init_clk_div = jz4770_adc_init_clk_div,
288 };
289 
290 static int ingenic_adc_read_avail(struct iio_dev *iio_dev,
291 				  struct iio_chan_spec const *chan,
292 				  const int **vals,
293 				  int *type,
294 				  int *length,
295 				  long m)
296 {
297 	struct ingenic_adc *adc = iio_priv(iio_dev);
298 
299 	switch (m) {
300 	case IIO_CHAN_INFO_RAW:
301 		*type = IIO_VAL_INT;
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;
310 	default:
311 		return -EINVAL;
312 	};
313 }
314 
315 static int ingenic_adc_read_chan_info_raw(struct ingenic_adc *adc,
316 					  struct iio_chan_spec const *chan,
317 					  int *val)
318 {
319 	int bit, ret, engine = (chan->channel == INGENIC_ADC_BATTERY);
320 
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);
326 	}
327 
328 	clk_enable(adc->clk);
329 	ret = ingenic_adc_capture(adc, engine);
330 	if (ret)
331 		goto out;
332 
333 	switch (chan->channel) {
334 	case INGENIC_ADC_AUX:
335 	case INGENIC_ADC_AUX2:
336 		*val = readw(adc->base + JZ_ADC_REG_ADSDAT);
337 		break;
338 	case INGENIC_ADC_BATTERY:
339 		*val = readw(adc->base + JZ_ADC_REG_ADBDAT);
340 		break;
341 	}
342 
343 	ret = IIO_VAL_INT;
344 out:
345 	clk_disable(adc->clk);
346 	mutex_unlock(&adc->aux_lock);
347 
348 	return ret;
349 }
350 
351 static int ingenic_adc_read_raw(struct iio_dev *iio_dev,
352 				struct iio_chan_spec const *chan,
353 				int *val,
354 				int *val2,
355 				long m)
356 {
357 	struct ingenic_adc *adc = iio_priv(iio_dev);
358 
359 	switch (m) {
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;
368 			break;
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;
373 			} else {
374 				*val = adc->soc_data->battery_high_vref;
375 				*val2 = adc->soc_data->battery_high_vref_bits;
376 			}
377 			break;
378 		}
379 
380 		return IIO_VAL_FRACTIONAL_LOG2;
381 	default:
382 		return -EINVAL;
383 	}
384 }
385 
386 static void ingenic_adc_clk_cleanup(void *data)
387 {
388 	clk_unprepare(data);
389 }
390 
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,
395 };
396 
397 static const struct iio_chan_spec ingenic_channels[] = {
398 	{
399 		.extend_name = "aux",
400 		.type = IIO_VOLTAGE,
401 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
402 				      BIT(IIO_CHAN_INFO_SCALE),
403 		.indexed = 1,
404 		.channel = INGENIC_ADC_AUX,
405 	},
406 	{
407 		.extend_name = "battery",
408 		.type = IIO_VOLTAGE,
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),
413 		.indexed = 1,
414 		.channel = INGENIC_ADC_BATTERY,
415 	},
416 	{ /* Must always be last in the array. */
417 		.extend_name = "aux2",
418 		.type = IIO_VOLTAGE,
419 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
420 				      BIT(IIO_CHAN_INFO_SCALE),
421 		.indexed = 1,
422 		.channel = INGENIC_ADC_AUX2,
423 	},
424 };
425 
426 static int ingenic_adc_probe(struct platform_device *pdev)
427 {
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;
432 	int ret;
433 
434 	soc_data = device_get_match_data(dev);
435 	if (!soc_data)
436 		return -EINVAL;
437 
438 	iio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
439 	if (!iio_dev)
440 		return -ENOMEM;
441 
442 	adc = iio_priv(iio_dev);
443 	mutex_init(&adc->lock);
444 	mutex_init(&adc->aux_lock);
445 	adc->soc_data = soc_data;
446 
447 	adc->base = devm_platform_ioremap_resource(pdev, 0);
448 	if (IS_ERR(adc->base))
449 		return PTR_ERR(adc->base);
450 
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);
455 	}
456 
457 	ret = clk_prepare_enable(adc->clk);
458 	if (ret) {
459 		dev_err(dev, "Failed to enable clock\n");
460 		return ret;
461 	}
462 
463 	/* Set clock dividers. */
464 	if (soc_data->init_clk_div) {
465 		ret = soc_data->init_clk_div(dev, adc);
466 		if (ret) {
467 			clk_disable_unprepare(adc->clk);
468 			return ret;
469 		}
470 	}
471 
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);
477 
478 	ret = devm_add_action_or_reset(dev, ingenic_adc_clk_cleanup, adc->clk);
479 	if (ret) {
480 		dev_err(dev, "Unable to add action\n");
481 		return ret;
482 	}
483 
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;
493 
494 	ret = devm_iio_device_register(dev, iio_dev);
495 	if (ret)
496 		dev_err(dev, "Unable to register IIO device\n");
497 
498 	return ret;
499 }
500 
501 #ifdef CONFIG_OF
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, },
506 	{ },
507 };
508 MODULE_DEVICE_TABLE(of, ingenic_adc_of_match);
509 #endif
510 
511 static struct platform_driver ingenic_adc_driver = {
512 	.driver = {
513 		.name = "ingenic-adc",
514 		.of_match_table = of_match_ptr(ingenic_adc_of_match),
515 	},
516 	.probe = ingenic_adc_probe,
517 };
518 module_platform_driver(ingenic_adc_driver);
519 MODULE_LICENSE("GPL v2");
520