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