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