1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2015 Samsung Electronics
4 * Przemyslaw Marczak <p.marczak@samsung.com>
5 */
6
7#define LOG_CATEGORY UCLASS_ADC
8
9#include <errno.h>
10#include <div64.h>
11#include <dm.h>
12#include <dm/lists.h>
13#include <dm/device-internal.h>
14#include <dm/uclass-internal.h>
15#include <adc.h>
16#include <linux/delay.h>
17#include <linux/printk.h>
18#include <power/regulator.h>
19
20#define ADC_UCLASS_PLATDATA_SIZE	sizeof(struct adc_uclass_plat)
21#define CHECK_NUMBER			true
22#define CHECK_MASK			(!CHECK_NUMBER)
23
24/* TODO: add support for timer uclass (for early calls) */
25#ifdef CONFIG_SANDBOX
26#define sdelay(x)	udelay(x)
27#else
28extern void sdelay(unsigned long loops);
29#endif
30
31static int check_channel(struct udevice *dev, int value, bool number_or_mask,
32			 const char *caller_function)
33{
34	struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
35	unsigned mask = number_or_mask ? (1 << value) : value;
36
37	/* For the real ADC hardware, some ADC channels can be inactive.
38	 * For example if device has 4 analog channels, and only channels
39	 * 1-st and 3-rd are valid, then channel mask is: 0b1010, so request
40	 * with mask 0b1110 should return an error.
41	*/
42	if ((uc_pdata->channel_mask >= mask) && (uc_pdata->channel_mask & mask))
43		return 0;
44
45	printf("Error in %s/%s().\nWrong channel selection for device: %s\n",
46	       __FILE__, caller_function, dev->name);
47
48	return -EINVAL;
49}
50
51static int adc_supply_enable(struct udevice *dev)
52{
53	struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
54	int ret;
55
56	ret = regulator_set_enable_if_allowed(uc_pdata->vdd_supply, true);
57	if (ret && ret != -ENOSYS) {
58		pr_err("%s: can't enable vdd-supply!", dev->name);
59		return ret;
60	}
61
62	ret = regulator_set_enable_if_allowed(uc_pdata->vss_supply, true);
63	if (ret && ret != -ENOSYS) {
64		pr_err("%s: can't enable vss-supply!", dev->name);
65		return ret;
66	}
67
68	return 0;
69}
70
71int adc_data_mask(struct udevice *dev, unsigned int *data_mask)
72{
73	struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
74
75	if (!uc_pdata)
76		return -ENOSYS;
77
78	*data_mask = uc_pdata->data_mask;
79	return 0;
80}
81
82int adc_channel_mask(struct udevice *dev, unsigned int *channel_mask)
83{
84	struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
85
86	if (!uc_pdata)
87		return -ENOSYS;
88
89	*channel_mask = uc_pdata->channel_mask;
90
91	return 0;
92}
93
94int adc_stop(struct udevice *dev)
95{
96	const struct adc_ops *ops = dev_get_driver_ops(dev);
97
98	if (!ops->stop)
99		return -ENOSYS;
100
101	return ops->stop(dev);
102}
103
104int adc_start_channel(struct udevice *dev, int channel)
105{
106	const struct adc_ops *ops = dev_get_driver_ops(dev);
107	int ret;
108
109	if (!ops->start_channel)
110		return -ENOSYS;
111
112	ret = check_channel(dev, channel, CHECK_NUMBER, __func__);
113	if (ret)
114		return ret;
115
116	ret = adc_supply_enable(dev);
117	if (ret)
118		return ret;
119
120	return ops->start_channel(dev, channel);
121}
122
123int adc_start_channels(struct udevice *dev, unsigned int channel_mask)
124{
125	const struct adc_ops *ops = dev_get_driver_ops(dev);
126	int ret;
127
128	if (!ops->start_channels)
129		return -ENOSYS;
130
131	ret = check_channel(dev, channel_mask, CHECK_MASK, __func__);
132	if (ret)
133		return ret;
134
135	ret = adc_supply_enable(dev);
136	if (ret)
137		return ret;
138
139	return ops->start_channels(dev, channel_mask);
140}
141
142int adc_channel_data(struct udevice *dev, int channel, unsigned int *data)
143{
144	struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
145	const struct adc_ops *ops = dev_get_driver_ops(dev);
146	unsigned int timeout_us = uc_pdata->data_timeout_us;
147	int ret;
148
149	if (!ops->channel_data)
150		return -ENOSYS;
151
152	ret = check_channel(dev, channel, CHECK_NUMBER, __func__);
153	if (ret)
154		return ret;
155
156	do {
157		ret = ops->channel_data(dev, channel, data);
158		if (!ret || ret != -EBUSY)
159			break;
160
161		/* TODO: use timer uclass (for early calls). */
162		sdelay(5);
163	} while (timeout_us--);
164
165	return ret;
166}
167
168int adc_channels_data(struct udevice *dev, unsigned int channel_mask,
169		      struct adc_channel *channels)
170{
171	struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
172	unsigned int timeout_us = uc_pdata->multidata_timeout_us;
173	const struct adc_ops *ops = dev_get_driver_ops(dev);
174	int ret;
175
176	if (!ops->channels_data)
177		return -ENOSYS;
178
179	ret = check_channel(dev, channel_mask, CHECK_MASK, __func__);
180	if (ret)
181		return ret;
182
183	do {
184		ret = ops->channels_data(dev, channel_mask, channels);
185		if (!ret || ret != -EBUSY)
186			break;
187
188		/* TODO: use timer uclass (for early calls). */
189		sdelay(5);
190	} while (timeout_us--);
191
192	return ret;
193}
194
195int adc_channel_single_shot(const char *name, int channel, unsigned int *data)
196{
197	struct udevice *dev;
198	int ret;
199
200	ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev);
201	if (ret)
202		return ret;
203
204	ret = adc_start_channel(dev, channel);
205	if (ret)
206		return ret;
207
208	ret = adc_channel_data(dev, channel, data);
209	if (ret)
210		return ret;
211
212	return 0;
213}
214
215static int _adc_channels_single_shot(struct udevice *dev,
216				     unsigned int channel_mask,
217				     struct adc_channel *channels)
218{
219	unsigned int data;
220	int channel, ret;
221
222	for (channel = 0; channel <= ADC_MAX_CHANNEL; channel++) {
223		/* Check channel bit. */
224		if (!((channel_mask >> channel) & 0x1))
225			continue;
226
227		ret = adc_start_channel(dev, channel);
228		if (ret)
229			return ret;
230
231		ret = adc_channel_data(dev, channel, &data);
232		if (ret)
233			return ret;
234
235		channels->id = channel;
236		channels->data = data;
237		channels++;
238	}
239
240	return 0;
241}
242
243int adc_channels_single_shot(const char *name, unsigned int channel_mask,
244			     struct adc_channel *channels)
245{
246	struct udevice *dev;
247	int ret;
248
249	ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev);
250	if (ret)
251		return ret;
252
253	ret = adc_start_channels(dev, channel_mask);
254	if (ret)
255		goto try_manual;
256
257	ret = adc_channels_data(dev, channel_mask, channels);
258	if (ret)
259		return ret;
260
261	return 0;
262
263try_manual:
264	if (ret != -ENOSYS)
265		return ret;
266
267	return _adc_channels_single_shot(dev, channel_mask, channels);
268}
269
270static int adc_vdd_plat_update(struct udevice *dev)
271{
272	struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
273	int ret;
274
275	/* Warning!
276	 * This function can't return supply device before its bind.
277	 * Please pay attention to proper fdt scan sequence. If ADC device
278	 * will bind before its supply regulator device, then the below 'get'
279	 * will return an error.
280	 */
281	if (!uc_pdata->vdd_supply)
282		return 0;
283
284	ret = regulator_get_value(uc_pdata->vdd_supply);
285	if (ret < 0)
286		return ret;
287
288	uc_pdata->vdd_microvolts = ret;
289
290	return 0;
291}
292
293static int adc_vss_plat_update(struct udevice *dev)
294{
295	struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
296	int ret;
297
298	if (!uc_pdata->vss_supply)
299		return 0;
300
301	ret = regulator_get_value(uc_pdata->vss_supply);
302	if (ret < 0)
303		return ret;
304
305	uc_pdata->vss_microvolts = ret;
306
307	return 0;
308}
309
310int adc_vdd_value(struct udevice *dev, int *uV)
311{
312	struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
313	int ret, value_sign = uc_pdata->vdd_polarity_negative ? -1 : 1;
314
315	/* Update the regulator Value. */
316	ret = adc_vdd_plat_update(dev);
317	if (ret)
318		return ret;
319
320	if (uc_pdata->vdd_microvolts == -ENODATA)
321		return -ENODATA;
322
323	*uV = uc_pdata->vdd_microvolts * value_sign;
324
325	return 0;
326}
327
328int adc_vss_value(struct udevice *dev, int *uV)
329{
330	struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
331	int ret, value_sign = uc_pdata->vss_polarity_negative ? -1 : 1;
332
333	/* Update the regulator Value. */
334	ret = adc_vss_plat_update(dev);
335	if (ret)
336		return ret;
337
338	if (uc_pdata->vss_microvolts == -ENODATA)
339		return -ENODATA;
340
341	*uV = uc_pdata->vss_microvolts * value_sign;
342
343	return 0;
344}
345
346int adc_raw_to_uV(struct udevice *dev, unsigned int raw, int *uV)
347{
348	unsigned int data_mask;
349	int ret, val, vref;
350	u64 raw64 = raw;
351
352	ret = adc_vdd_value(dev, &vref);
353	if (ret)
354		return ret;
355
356	if (!adc_vss_value(dev, &val))
357		vref -= val;
358
359	ret = adc_data_mask(dev, &data_mask);
360	if (ret)
361		return ret;
362
363	raw64 *= vref;
364	do_div(raw64, data_mask);
365	*uV = raw64;
366
367	return 0;
368}
369
370static int adc_vdd_plat_set(struct udevice *dev)
371{
372	struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
373	int ret;
374	char *prop;
375
376	prop = "vdd-polarity-negative";
377	uc_pdata->vdd_polarity_negative = dev_read_bool(dev, prop);
378
379	/* Optionally get regulators */
380	ret = device_get_supply_regulator(dev, "vdd-supply",
381					  &uc_pdata->vdd_supply);
382	if (!ret)
383		return adc_vdd_plat_update(dev);
384
385	if (ret != -ENOENT)
386		return ret;
387
388	/* No vdd-supply phandle. */
389	prop  = "vdd-microvolts";
390	uc_pdata->vdd_microvolts = dev_read_u32_default(dev, prop, -ENODATA);
391
392	return 0;
393}
394
395static int adc_vss_plat_set(struct udevice *dev)
396{
397	struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
398	int ret;
399	char *prop;
400
401	prop = "vss-polarity-negative";
402	uc_pdata->vss_polarity_negative = dev_read_bool(dev, prop);
403
404	ret = device_get_supply_regulator(dev, "vss-supply",
405					  &uc_pdata->vss_supply);
406	if (!ret)
407		return adc_vss_plat_update(dev);
408
409	if (ret != -ENOENT)
410		return ret;
411
412	/* No vss-supply phandle. */
413	prop = "vss-microvolts";
414	uc_pdata->vss_microvolts = dev_read_u32_default(dev, prop, -ENODATA);
415
416	return 0;
417}
418
419static int adc_pre_probe(struct udevice *dev)
420{
421	int ret;
422
423	/* Set ADC VDD plat: polarity, uV, regulator (phandle). */
424	ret = adc_vdd_plat_set(dev);
425	if (ret)
426		pr_err("%s: Can't update Vdd. Error: %d", dev->name, ret);
427
428	/* Set ADC VSS plat: polarity, uV, regulator (phandle). */
429	ret = adc_vss_plat_set(dev);
430	if (ret)
431		pr_err("%s: Can't update Vss. Error: %d", dev->name, ret);
432
433	return 0;
434}
435
436UCLASS_DRIVER(adc) = {
437	.id	= UCLASS_ADC,
438	.name	= "adc",
439	.pre_probe =  adc_pre_probe,
440	.per_device_plat_auto	= ADC_UCLASS_PLATDATA_SIZE,
441};
442