blob: b959c469ec6ce52a31d40c4613bcd0847d06b085 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Przemyslaw Marczak08edd002015-04-20 20:07:42 +02002/*
3 * Copyright (C) 2014-2015 Samsung Electronics
4 * Przemyslaw Marczak <p.marczak@samsung.com>
Przemyslaw Marczak08edd002015-04-20 20:07:42 +02005 */
Simon Glasseeb99de2017-05-18 20:09:34 -06006
Przemyslaw Marczak08edd002015-04-20 20:07:42 +02007#include <common.h>
Przemyslaw Marczak08edd002015-04-20 20:07:42 +02008#include <errno.h>
9#include <dm.h>
Simon Glass0f2af882020-05-10 11:40:05 -060010#include <log.h>
Przemyslaw Marczak08edd002015-04-20 20:07:42 +020011#include <dm/uclass-internal.h>
12#include <power/pmic.h>
13#include <power/regulator.h>
14
Przemyslaw Marczak08edd002015-04-20 20:07:42 +020015int regulator_mode(struct udevice *dev, struct dm_regulator_mode **modep)
16{
17 struct dm_regulator_uclass_platdata *uc_pdata;
18
19 *modep = NULL;
20
21 uc_pdata = dev_get_uclass_platdata(dev);
22 if (!uc_pdata)
23 return -ENXIO;
24
25 *modep = uc_pdata->mode;
26 return uc_pdata->mode_count;
27}
28
29int regulator_get_value(struct udevice *dev)
30{
31 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
32
33 if (!ops || !ops->get_value)
34 return -ENOSYS;
35
36 return ops->get_value(dev);
37}
38
Krzysztof Kozlowskie2fa3972019-03-06 19:37:54 +010039static void regulator_set_value_ramp_delay(struct udevice *dev, int old_uV,
40 int new_uV, unsigned int ramp_delay)
41{
42 int delay = DIV_ROUND_UP(abs(new_uV - old_uV), ramp_delay);
43
44 debug("regulator %s: delay %u us (%d uV -> %d uV)\n", dev->name, delay,
45 old_uV, new_uV);
46
47 udelay(delay);
48}
49
Przemyslaw Marczak08edd002015-04-20 20:07:42 +020050int regulator_set_value(struct udevice *dev, int uV)
51{
52 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
Keerthyc6e66692016-10-26 13:42:31 +053053 struct dm_regulator_uclass_platdata *uc_pdata;
Krzysztof Kozlowskie2fa3972019-03-06 19:37:54 +010054 int ret, old_uV = uV, is_enabled = 0;
Keerthyc6e66692016-10-26 13:42:31 +053055
56 uc_pdata = dev_get_uclass_platdata(dev);
57 if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV)
58 return -EINVAL;
59 if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
60 return -EINVAL;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +020061
62 if (!ops || !ops->set_value)
63 return -ENOSYS;
64
Krzysztof Kozlowskie2fa3972019-03-06 19:37:54 +010065 if (uc_pdata->ramp_delay) {
66 is_enabled = regulator_get_enable(dev);
67 old_uV = regulator_get_value(dev);
68 }
69
70 ret = ops->set_value(dev, uV);
71
72 if (!ret) {
73 if (uc_pdata->ramp_delay && old_uV > 0 && is_enabled)
74 regulator_set_value_ramp_delay(dev, old_uV, uV,
75 uc_pdata->ramp_delay);
76 }
77
78 return ret;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +020079}
80
Joseph Chenbb511322019-09-26 15:43:52 +080081int regulator_set_suspend_value(struct udevice *dev, int uV)
82{
83 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
84 struct dm_regulator_uclass_platdata *uc_pdata;
85
86 uc_pdata = dev_get_uclass_platdata(dev);
87 if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV)
88 return -EINVAL;
89 if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
90 return -EINVAL;
91
92 if (!ops->set_suspend_value)
93 return -ENOSYS;
94
95 return ops->set_suspend_value(dev, uV);
96}
97
98int regulator_get_suspend_value(struct udevice *dev)
99{
100 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
101
102 if (!ops->get_suspend_value)
103 return -ENOSYS;
104
105 return ops->get_suspend_value(dev);
106}
107
Keerthy162c02e2016-10-26 13:42:30 +0530108/*
109 * To be called with at most caution as there is no check
110 * before setting the actual voltage value.
111 */
112int regulator_set_value_force(struct udevice *dev, int uV)
113{
114 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
115
116 if (!ops || !ops->set_value)
117 return -ENOSYS;
118
119 return ops->set_value(dev, uV);
120}
121
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200122int regulator_get_current(struct udevice *dev)
123{
124 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
125
126 if (!ops || !ops->get_current)
127 return -ENOSYS;
128
129 return ops->get_current(dev);
130}
131
132int regulator_set_current(struct udevice *dev, int uA)
133{
134 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
Keerthyce152be2016-10-26 13:42:32 +0530135 struct dm_regulator_uclass_platdata *uc_pdata;
136
137 uc_pdata = dev_get_uclass_platdata(dev);
138 if (uc_pdata->min_uA != -ENODATA && uA < uc_pdata->min_uA)
139 return -EINVAL;
140 if (uc_pdata->max_uA != -ENODATA && uA > uc_pdata->max_uA)
141 return -EINVAL;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200142
143 if (!ops || !ops->set_current)
144 return -ENOSYS;
145
146 return ops->set_current(dev, uA);
147}
148
Keerthy23be7fb2017-06-13 09:53:45 +0530149int regulator_get_enable(struct udevice *dev)
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200150{
151 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
152
153 if (!ops || !ops->get_enable)
154 return -ENOSYS;
155
156 return ops->get_enable(dev);
157}
158
159int regulator_set_enable(struct udevice *dev, bool enable)
160{
161 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
Patrick Delaunayd7585f22018-11-15 13:45:31 +0100162 struct dm_regulator_uclass_platdata *uc_pdata;
Krzysztof Kozlowskie2fa3972019-03-06 19:37:54 +0100163 int ret, old_enable = 0;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200164
165 if (!ops || !ops->set_enable)
166 return -ENOSYS;
167
Patrick Delaunayd7585f22018-11-15 13:45:31 +0100168 uc_pdata = dev_get_uclass_platdata(dev);
169 if (!enable && uc_pdata->always_on)
Lokesh Vutlaf870da22019-01-11 15:15:50 +0530170 return -EACCES;
Patrick Delaunayd7585f22018-11-15 13:45:31 +0100171
Krzysztof Kozlowskie2fa3972019-03-06 19:37:54 +0100172 if (uc_pdata->ramp_delay)
173 old_enable = regulator_get_enable(dev);
174
175 ret = ops->set_enable(dev, enable);
176 if (!ret) {
177 if (uc_pdata->ramp_delay && !old_enable && enable) {
178 int uV = regulator_get_value(dev);
179
180 if (uV > 0) {
181 regulator_set_value_ramp_delay(dev, 0, uV,
182 uc_pdata->ramp_delay);
183 }
184 }
185 }
186
187 return ret;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200188}
189
Lokesh Vutla7106b782019-01-11 15:15:51 +0530190int regulator_set_enable_if_allowed(struct udevice *dev, bool enable)
191{
192 int ret;
193
194 ret = regulator_set_enable(dev, enable);
195 if (ret == -ENOSYS || ret == -EACCES)
196 return 0;
197
198 return ret;
199}
200
Joseph Chenbb511322019-09-26 15:43:52 +0800201int regulator_set_suspend_enable(struct udevice *dev, bool enable)
202{
203 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
204
205 if (!ops->set_suspend_enable)
206 return -ENOSYS;
207
208 return ops->set_suspend_enable(dev, enable);
209}
210
211int regulator_get_suspend_enable(struct udevice *dev)
212{
213 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
214
215 if (!ops->get_suspend_enable)
216 return -ENOSYS;
217
218 return ops->get_suspend_enable(dev);
219}
220
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200221int regulator_get_mode(struct udevice *dev)
222{
223 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
224
225 if (!ops || !ops->get_mode)
226 return -ENOSYS;
227
228 return ops->get_mode(dev);
229}
230
231int regulator_set_mode(struct udevice *dev, int mode)
232{
233 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
234
235 if (!ops || !ops->set_mode)
236 return -ENOSYS;
237
238 return ops->set_mode(dev, mode);
239}
240
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200241int regulator_get_by_platname(const char *plat_name, struct udevice **devp)
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200242{
243 struct dm_regulator_uclass_platdata *uc_pdata;
244 struct udevice *dev;
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200245 int ret;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200246
247 *devp = NULL;
248
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200249 for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
250 ret = uclass_find_next_device(&dev)) {
Simon Glassfc3ebf12017-05-31 17:57:15 -0600251 if (ret) {
252 debug("regulator %s, ret=%d\n", dev->name, ret);
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200253 continue;
Simon Glassfc3ebf12017-05-31 17:57:15 -0600254 }
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200255
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200256 uc_pdata = dev_get_uclass_platdata(dev);
257 if (!uc_pdata || strcmp(plat_name, uc_pdata->name))
258 continue;
259
260 return uclass_get_device_tail(dev, 0, devp);
261 }
262
Simon Glassfc3ebf12017-05-31 17:57:15 -0600263 debug("%s: can't find: %s, ret=%d\n", __func__, plat_name, ret);
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200264
265 return -ENODEV;
266}
267
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200268int regulator_get_by_devname(const char *devname, struct udevice **devp)
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200269{
270 return uclass_get_device_by_name(UCLASS_REGULATOR, devname, devp);
271}
272
Przemyslaw Marczakc9001032015-10-27 13:07:59 +0100273int device_get_supply_regulator(struct udevice *dev, const char *supply_name,
274 struct udevice **devp)
275{
276 return uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
277 supply_name, devp);
278}
279
Simon Glass46cb8242015-06-23 15:38:58 -0600280int regulator_autoset(struct udevice *dev)
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200281{
Simon Glass46cb8242015-06-23 15:38:58 -0600282 struct dm_regulator_uclass_platdata *uc_pdata;
283 int ret = 0;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200284
Simon Glass46cb8242015-06-23 15:38:58 -0600285 uc_pdata = dev_get_uclass_platdata(dev);
Joseph Chenbb511322019-09-26 15:43:52 +0800286
287 ret = regulator_set_suspend_enable(dev, uc_pdata->suspend_on);
288 if (!ret && uc_pdata->suspend_on) {
289 ret = regulator_set_suspend_value(dev, uc_pdata->suspend_uV);
290 if (!ret)
291 return ret;
292 }
293
Simon Glass46cb8242015-06-23 15:38:58 -0600294 if (!uc_pdata->always_on && !uc_pdata->boot_on)
295 return -EMEDIUMTYPE;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200296
Sven Schwermerd033cbf2019-06-12 08:32:38 +0200297 if (uc_pdata->type == REGULATOR_TYPE_FIXED)
298 return regulator_set_enable(dev, true);
299
Simon Glass46cb8242015-06-23 15:38:58 -0600300 if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
301 ret = regulator_set_value(dev, uc_pdata->min_uV);
Joseph Chenbb511322019-09-26 15:43:52 +0800302 if (uc_pdata->init_uV > 0)
303 ret = regulator_set_value(dev, uc_pdata->init_uV);
Simon Glass46cb8242015-06-23 15:38:58 -0600304 if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA))
305 ret = regulator_set_current(dev, uc_pdata->min_uA);
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200306
307 if (!ret)
Simon Glass46cb8242015-06-23 15:38:58 -0600308 ret = regulator_set_enable(dev, true);
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200309
310 return ret;
311}
312
Simon Glass46cb8242015-06-23 15:38:58 -0600313static void regulator_show(struct udevice *dev, int ret)
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200314{
315 struct dm_regulator_uclass_platdata *uc_pdata;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200316
317 uc_pdata = dev_get_uclass_platdata(dev);
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200318
Simon Glass46cb8242015-06-23 15:38:58 -0600319 printf("%s@%s: ", dev->name, uc_pdata->name);
320 if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
321 printf("set %d uV", uc_pdata->min_uV);
322 if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA)
323 printf("; set %d uA", uc_pdata->min_uA);
324 printf("; enabling");
325 if (ret)
Simon Glass46ad8cb2016-01-21 19:43:58 -0700326 printf(" (ret: %d)", ret);
Simon Glass46cb8242015-06-23 15:38:58 -0600327 printf("\n");
328}
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200329
Simon Glass46cb8242015-06-23 15:38:58 -0600330int regulator_autoset_by_name(const char *platname, struct udevice **devp)
331{
332 struct udevice *dev;
333 int ret;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200334
Simon Glass46cb8242015-06-23 15:38:58 -0600335 ret = regulator_get_by_platname(platname, &dev);
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200336 if (devp)
337 *devp = dev;
Simon Glass46cb8242015-06-23 15:38:58 -0600338 if (ret) {
Simon Glassfc3ebf12017-05-31 17:57:15 -0600339 debug("Can get the regulator: %s (err=%d)\n", platname, ret);
Simon Glass46cb8242015-06-23 15:38:58 -0600340 return ret;
341 }
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200342
Simon Glass46cb8242015-06-23 15:38:58 -0600343 return regulator_autoset(dev);
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200344}
345
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200346int regulator_list_autoset(const char *list_platname[],
347 struct udevice *list_devp[],
348 bool verbose)
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200349{
350 struct udevice *dev;
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200351 int error = 0, i = 0, ret;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200352
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200353 while (list_platname[i]) {
Simon Glass46cb8242015-06-23 15:38:58 -0600354 ret = regulator_autoset_by_name(list_platname[i], &dev);
355 if (ret != -EMEDIUMTYPE && verbose)
356 regulator_show(dev, ret);
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200357 if (ret & !error)
358 error = ret;
359
360 if (list_devp)
361 list_devp[i] = dev;
362
363 i++;
364 }
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200365
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200366 return error;
367}
368
369static bool regulator_name_is_unique(struct udevice *check_dev,
370 const char *check_name)
371{
372 struct dm_regulator_uclass_platdata *uc_pdata;
373 struct udevice *dev;
374 int check_len = strlen(check_name);
375 int ret;
376 int len;
377
378 for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
379 ret = uclass_find_next_device(&dev)) {
380 if (ret || dev == check_dev)
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200381 continue;
382
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200383 uc_pdata = dev_get_uclass_platdata(dev);
384 len = strlen(uc_pdata->name);
385 if (len != check_len)
386 continue;
387
388 if (!strcmp(uc_pdata->name, check_name))
389 return false;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200390 }
391
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200392 return true;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200393}
394
395static int regulator_post_bind(struct udevice *dev)
396{
397 struct dm_regulator_uclass_platdata *uc_pdata;
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200398 const char *property = "regulator-name";
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200399
400 uc_pdata = dev_get_uclass_platdata(dev);
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200401
402 /* Regulator's mandatory constraint */
Simon Glasseeb99de2017-05-18 20:09:34 -0600403 uc_pdata->name = dev_read_string(dev, property);
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200404 if (!uc_pdata->name) {
Simon Glasseeb99de2017-05-18 20:09:34 -0600405 debug("%s: dev '%s' has no property '%s'\n",
406 __func__, dev->name, property);
407 uc_pdata->name = dev_read_name(dev);
Peng Fancd672d42015-08-07 16:43:42 +0800408 if (!uc_pdata->name)
409 return -EINVAL;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200410 }
411
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200412 if (regulator_name_is_unique(dev, uc_pdata->name))
413 return 0;
414
Simon Glasseeb99de2017-05-18 20:09:34 -0600415 debug("'%s' of dev: '%s', has nonunique value: '%s\n",
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200416 property, dev->name, uc_pdata->name);
417
418 return -EINVAL;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200419}
420
421static int regulator_pre_probe(struct udevice *dev)
422{
423 struct dm_regulator_uclass_platdata *uc_pdata;
Joseph Chenbb511322019-09-26 15:43:52 +0800424 ofnode node;
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200425
426 uc_pdata = dev_get_uclass_platdata(dev);
427 if (!uc_pdata)
428 return -ENXIO;
429
430 /* Regulator's optional constraints */
Simon Glasseeb99de2017-05-18 20:09:34 -0600431 uc_pdata->min_uV = dev_read_u32_default(dev, "regulator-min-microvolt",
432 -ENODATA);
433 uc_pdata->max_uV = dev_read_u32_default(dev, "regulator-max-microvolt",
434 -ENODATA);
Joseph Chenbb511322019-09-26 15:43:52 +0800435 uc_pdata->init_uV = dev_read_u32_default(dev, "regulator-init-microvolt",
436 -ENODATA);
Simon Glasseeb99de2017-05-18 20:09:34 -0600437 uc_pdata->min_uA = dev_read_u32_default(dev, "regulator-min-microamp",
438 -ENODATA);
439 uc_pdata->max_uA = dev_read_u32_default(dev, "regulator-max-microamp",
440 -ENODATA);
441 uc_pdata->always_on = dev_read_bool(dev, "regulator-always-on");
442 uc_pdata->boot_on = dev_read_bool(dev, "regulator-boot-on");
Krzysztof Kozlowskie2fa3972019-03-06 19:37:54 +0100443 uc_pdata->ramp_delay = dev_read_u32_default(dev, "regulator-ramp-delay",
444 0);
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200445
Joseph Chenbb511322019-09-26 15:43:52 +0800446 node = dev_read_subnode(dev, "regulator-state-mem");
447 if (ofnode_valid(node)) {
448 uc_pdata->suspend_on = !ofnode_read_bool(node, "regulator-off-in-suspend");
449 if (ofnode_read_u32(node, "regulator-suspend-microvolt", &uc_pdata->suspend_uV))
450 uc_pdata->suspend_uV = uc_pdata->max_uV;
451 } else {
452 uc_pdata->suspend_on = true;
453 uc_pdata->suspend_uV = uc_pdata->max_uV;
454 }
455
Simon Glass991f9bc2015-06-23 15:38:57 -0600456 /* Those values are optional (-ENODATA if unset) */
457 if ((uc_pdata->min_uV != -ENODATA) &&
458 (uc_pdata->max_uV != -ENODATA) &&
459 (uc_pdata->min_uV == uc_pdata->max_uV))
460 uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UV;
461
462 /* Those values are optional (-ENODATA if unset) */
463 if ((uc_pdata->min_uA != -ENODATA) &&
464 (uc_pdata->max_uA != -ENODATA) &&
465 (uc_pdata->min_uA == uc_pdata->max_uA))
466 uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UA;
467
Lukasz Majewski8460a6b2020-01-25 09:00:58 +0100468 if (uc_pdata->boot_on)
469 regulator_set_enable(dev, uc_pdata->boot_on);
470
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200471 return 0;
472}
473
Simon Glassefeeb2c2015-06-23 15:38:59 -0600474int regulators_enable_boot_on(bool verbose)
475{
476 struct udevice *dev;
477 struct uclass *uc;
478 int ret;
479
480 ret = uclass_get(UCLASS_REGULATOR, &uc);
481 if (ret)
482 return ret;
483 for (uclass_first_device(UCLASS_REGULATOR, &dev);
Simon Glassc7298e72016-02-11 13:23:26 -0700484 dev;
Simon Glassefeeb2c2015-06-23 15:38:59 -0600485 uclass_next_device(&dev)) {
486 ret = regulator_autoset(dev);
Simon Glassf55c9512015-07-02 18:16:06 -0600487 if (ret == -EMEDIUMTYPE) {
488 ret = 0;
Simon Glassefeeb2c2015-06-23 15:38:59 -0600489 continue;
Simon Glassf55c9512015-07-02 18:16:06 -0600490 }
Simon Glassefeeb2c2015-06-23 15:38:59 -0600491 if (verbose)
492 regulator_show(dev, ret);
Simon Glassd6eddad2016-01-21 19:43:59 -0700493 if (ret == -ENOSYS)
494 ret = 0;
Simon Glassefeeb2c2015-06-23 15:38:59 -0600495 }
496
497 return ret;
498}
499
Przemyslaw Marczak08edd002015-04-20 20:07:42 +0200500UCLASS_DRIVER(regulator) = {
501 .id = UCLASS_REGULATOR,
502 .name = "regulator",
503 .post_bind = regulator_post_bind,
504 .pre_probe = regulator_pre_probe,
505 .per_device_platdata_auto_alloc_size =
506 sizeof(struct dm_regulator_uclass_platdata),
507};