1 /*
2 * Copyright (C) 2014-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/uclass-internal.h>
12 #include <power/pmic.h>
13 #include <power/regulator.h>
14
15 DECLARE_GLOBAL_DATA_PTR;
16
regulator_mode(struct udevice * dev,struct dm_regulator_mode ** modep)17 int regulator_mode(struct udevice *dev, struct dm_regulator_mode **modep)
18 {
19 struct dm_regulator_uclass_platdata *uc_pdata;
20
21 *modep = NULL;
22
23 uc_pdata = dev_get_uclass_platdata(dev);
24 if (!uc_pdata)
25 return -ENXIO;
26
27 *modep = uc_pdata->mode;
28 return uc_pdata->mode_count;
29 }
30
regulator_get_value(struct udevice * dev)31 int regulator_get_value(struct udevice *dev)
32 {
33 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
34
35 if (!ops || !ops->get_value)
36 return -ENOSYS;
37
38 return ops->get_value(dev);
39 }
40
regulator_set_value(struct udevice * dev,int uV)41 int regulator_set_value(struct udevice *dev, int uV)
42 {
43 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
44 struct dm_regulator_uclass_platdata *uc_pdata;
45 u32 old_uV = -ENODATA, us;
46 int ret;
47
48 uc_pdata = dev_get_uclass_platdata(dev);
49 if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV)
50 return -EINVAL;
51 if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
52 return -EINVAL;
53
54 if (!ops || !ops->set_value)
55 return -ENOSYS;
56
57 if (uc_pdata->ramp_delay != -ENODATA) {
58 if (!ops->get_value)
59 return -ENOSYS;
60 old_uV = ops->get_value(dev);
61 if (old_uV < 0)
62 return -EINVAL;
63 }
64
65 ret = ops->set_value(dev, uV);
66
67 if (!ret && (old_uV != -ENODATA) && (old_uV != uV)) {
68 us = DIV_ROUND_UP(abs(uV - old_uV), uc_pdata->ramp_delay);
69 udelay(us);
70 debug("%s: ramp=%d, old_uV=%d, uV=%d, us=%d\n",
71 uc_pdata->name, uc_pdata->ramp_delay, old_uV, uV, us);
72 }
73
74 return ret;
75 }
76
regulator_set_suspend_value(struct udevice * dev,int uV)77 int regulator_set_suspend_value(struct udevice *dev, int uV)
78 {
79 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
80
81 if (!ops || !ops->set_suspend_value)
82 return -ENOSYS;
83
84 return ops->set_suspend_value(dev, uV);
85 }
86
regulator_get_suspend_value(struct udevice * dev)87 int regulator_get_suspend_value(struct udevice *dev)
88 {
89 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
90
91 if (!ops || !ops->get_suspend_value)
92 return -ENOSYS;
93
94 return ops->get_suspend_value(dev);
95 }
96
97 /*
98 * To be called with at most caution as there is no check
99 * before setting the actual voltage value.
100 */
regulator_set_value_force(struct udevice * dev,int uV)101 int regulator_set_value_force(struct udevice *dev, int uV)
102 {
103 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
104
105 if (!ops || !ops->set_value)
106 return -ENOSYS;
107
108 return ops->set_value(dev, uV);
109 }
110
regulator_get_current(struct udevice * dev)111 int regulator_get_current(struct udevice *dev)
112 {
113 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
114
115 if (!ops || !ops->get_current)
116 return -ENOSYS;
117
118 return ops->get_current(dev);
119 }
120
regulator_set_current(struct udevice * dev,int uA)121 int regulator_set_current(struct udevice *dev, int uA)
122 {
123 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
124 struct dm_regulator_uclass_platdata *uc_pdata;
125
126 uc_pdata = dev_get_uclass_platdata(dev);
127 if (uc_pdata->min_uA != -ENODATA && uA < uc_pdata->min_uA)
128 return -EINVAL;
129 if (uc_pdata->max_uA != -ENODATA && uA > uc_pdata->max_uA)
130 return -EINVAL;
131
132 if (!ops || !ops->set_current)
133 return -ENOSYS;
134
135 return ops->set_current(dev, uA);
136 }
137
regulator_get_enable(struct udevice * dev)138 int regulator_get_enable(struct udevice *dev)
139 {
140 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
141
142 if (!ops || !ops->get_enable)
143 return -ENOSYS;
144
145 return ops->get_enable(dev);
146 }
147
regulator_set_enable(struct udevice * dev,bool enable)148 int regulator_set_enable(struct udevice *dev, bool enable)
149 {
150 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
151
152 if (!ops || !ops->set_enable)
153 return -ENOSYS;
154
155 return ops->set_enable(dev, enable);
156 }
157
regulator_set_suspend_enable(struct udevice * dev,bool enable)158 int regulator_set_suspend_enable(struct udevice *dev, bool enable)
159 {
160 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
161
162 if (!ops || !ops->set_suspend_enable)
163 return -ENOSYS;
164
165 return ops->set_suspend_enable(dev, enable);
166 }
167
regulator_get_suspend_enable(struct udevice * dev)168 int regulator_get_suspend_enable(struct udevice *dev)
169 {
170 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
171
172 if (!ops || !ops->get_suspend_enable)
173 return -ENOSYS;
174
175 return ops->get_suspend_enable(dev);
176 }
177
regulator_set_ramp_delay(struct udevice * dev,u32 ramp_delay)178 int regulator_set_ramp_delay(struct udevice *dev, u32 ramp_delay)
179 {
180 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
181
182 if (!ops || !ops->set_ramp_delay)
183 return -ENOSYS;
184
185 return ops->set_ramp_delay(dev, ramp_delay);
186 }
187
regulator_get_mode(struct udevice * dev)188 int regulator_get_mode(struct udevice *dev)
189 {
190 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
191
192 if (!ops || !ops->get_mode)
193 return -ENOSYS;
194
195 return ops->get_mode(dev);
196 }
197
regulator_set_mode(struct udevice * dev,int mode)198 int regulator_set_mode(struct udevice *dev, int mode)
199 {
200 const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
201
202 if (!ops || !ops->set_mode)
203 return -ENOSYS;
204
205 return ops->set_mode(dev, mode);
206 }
207
regulator_get_by_platname(const char * plat_name,struct udevice ** devp)208 int regulator_get_by_platname(const char *plat_name, struct udevice **devp)
209 {
210 struct dm_regulator_uclass_platdata *uc_pdata;
211 struct udevice *dev;
212 int ret;
213
214 *devp = NULL;
215
216 for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
217 ret = uclass_find_next_device(&dev)) {
218 if (ret) {
219 debug("regulator %s, ret=%d\n", dev->name, ret);
220 continue;
221 }
222
223 uc_pdata = dev_get_uclass_platdata(dev);
224 if (!uc_pdata || strcmp(plat_name, uc_pdata->name))
225 continue;
226
227 return uclass_get_device_tail(dev, 0, devp);
228 }
229
230 debug("%s: can't find: %s, ret=%d\n", __func__, plat_name, ret);
231
232 return -ENODEV;
233 }
234
regulator_get_by_devname(const char * devname,struct udevice ** devp)235 int regulator_get_by_devname(const char *devname, struct udevice **devp)
236 {
237 return uclass_get_device_by_name(UCLASS_REGULATOR, devname, devp);
238 }
239
device_get_supply_regulator(struct udevice * dev,const char * supply_name,struct udevice ** devp)240 int device_get_supply_regulator(struct udevice *dev, const char *supply_name,
241 struct udevice **devp)
242 {
243 return uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
244 supply_name, devp);
245 }
246
regulator_init_suspend(struct udevice * dev)247 static int regulator_init_suspend(struct udevice *dev)
248 {
249 struct dm_regulator_uclass_platdata *uc_pdata;
250 int ret;
251
252 uc_pdata = dev_get_uclass_platdata(dev);
253
254 ret = regulator_set_suspend_enable(dev, uc_pdata->suspend_on);
255 if (!ret && uc_pdata->suspend_on)
256 return regulator_set_suspend_value(dev, uc_pdata->suspend_uV);
257
258 return 0;
259 }
260
regulator_autoset(struct udevice * dev)261 int regulator_autoset(struct udevice *dev)
262 {
263 struct dm_regulator_uclass_platdata *uc_pdata;
264 int ret = 0;
265
266 uc_pdata = dev_get_uclass_platdata(dev);
267
268 if (uc_pdata->ignore)
269 return ret;
270
271 if (uc_pdata->ramp_delay != -ENODATA)
272 regulator_set_ramp_delay(dev, uc_pdata->ramp_delay);
273
274 if (!uc_pdata->always_on && !uc_pdata->boot_on)
275 return -EMEDIUMTYPE;
276
277 if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV) {
278 ret = regulator_set_value(dev, uc_pdata->min_uV);
279 } else {
280 if ((uc_pdata->type == REGULATOR_TYPE_BUCK) &&
281 (uc_pdata->min_uV != -ENODATA) &&
282 (uc_pdata->max_uV != -ENODATA) &&
283 (uc_pdata->init_uV <= 0))
284 printf("%s %d uV\n",
285 uc_pdata->name, regulator_get_value(dev));
286 }
287
288 if (uc_pdata->init_uV > 0) {
289 ret = regulator_set_value(dev, uc_pdata->init_uV);
290 if (!ret)
291 printf("%s init %d uV\n",
292 uc_pdata->name, uc_pdata->init_uV);
293 }
294
295 if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA))
296 ret = regulator_set_current(dev, uc_pdata->min_uA);
297
298 if (!ret)
299 ret = regulator_set_enable(dev, true);
300
301 return ret;
302 }
303
regulator_show(struct udevice * dev,int ret)304 static void regulator_show(struct udevice *dev, int ret)
305 {
306 struct dm_regulator_uclass_platdata *uc_pdata;
307 int uV = 0;
308
309 uc_pdata = dev_get_uclass_platdata(dev);
310 uV = regulator_get_value(dev);
311
312 printf("%25s@%15s: ", dev->name, uc_pdata->name);
313 printf("%7duV <-> %7duV, set %7duV, %s",
314 uc_pdata->min_uV, uc_pdata->max_uV, uV,
315 (uc_pdata->always_on || uc_pdata->boot_on) ?
316 "enabling" : "disabled");
317
318 printf(" | supsend %7duV, %s",
319 uc_pdata->suspend_uV,
320 uc_pdata->suspend_on ? "enabling" : "disabled");
321 if (uc_pdata->init_uV != -ENODATA)
322 printf(" ; init %7duV", uc_pdata->init_uV);
323
324 if (ret)
325 printf(" (ret: %d)", ret);
326
327 printf("\n");
328 }
329
regulator_autoset_by_name(const char * platname,struct udevice ** devp)330 int regulator_autoset_by_name(const char *platname, struct udevice **devp)
331 {
332 struct udevice *dev;
333 int ret;
334
335 ret = regulator_get_by_platname(platname, &dev);
336 if (devp)
337 *devp = dev;
338 if (ret) {
339 debug("Can get the regulator: %s (err=%d)\n", platname, ret);
340 return ret;
341 }
342
343 return regulator_autoset(dev);
344 }
345
regulator_list_autoset(const char * list_platname[],struct udevice * list_devp[],bool verbose)346 int regulator_list_autoset(const char *list_platname[],
347 struct udevice *list_devp[],
348 bool verbose)
349 {
350 struct udevice *dev;
351 int error = 0, i = 0, ret;
352
353 while (list_platname[i]) {
354 ret = regulator_autoset_by_name(list_platname[i], &dev);
355 if (ret != -EMEDIUMTYPE && verbose)
356 regulator_show(dev, ret);
357 if (ret & !error)
358 error = ret;
359
360 if (list_devp)
361 list_devp[i] = dev;
362
363 i++;
364 }
365
366 return error;
367 }
368
regulator_name_is_unique(struct udevice * check_dev,const char * check_name)369 static 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)
381 continue;
382
383 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;
390 }
391
392 return true;
393 }
394
regulator_post_bind(struct udevice * dev)395 static int regulator_post_bind(struct udevice *dev)
396 {
397 struct dm_regulator_uclass_platdata *uc_pdata;
398 const char *property = "regulator-name";
399
400 uc_pdata = dev_get_uclass_platdata(dev);
401
402 /* Regulator's mandatory constraint */
403 uc_pdata->name = dev_read_string(dev, property);
404 if (!uc_pdata->name) {
405 debug("%s: dev '%s' has no property '%s'\n",
406 __func__, dev->name, property);
407 uc_pdata->name = dev_read_name(dev);
408 if (!uc_pdata->name)
409 return -EINVAL;
410 }
411
412 if (regulator_name_is_unique(dev, uc_pdata->name))
413 return 0;
414
415 debug("'%s' of dev: '%s', has nonunique value: '%s\n",
416 property, dev->name, uc_pdata->name);
417
418 return -EINVAL;
419 }
420
regulator_pre_probe(struct udevice * dev)421 static int regulator_pre_probe(struct udevice *dev)
422 {
423 struct dm_regulator_uclass_platdata *uc_pdata;
424 ofnode node;
425
426 uc_pdata = dev_get_uclass_platdata(dev);
427 if (!uc_pdata)
428 return -ENXIO;
429
430 /* Regulator's optional constraints */
431 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);
435 uc_pdata->init_uV = dev_read_u32_default(dev, "regulator-init-microvolt",
436 -ENODATA);
437 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");
443 uc_pdata->ignore = dev_read_bool(dev, "regulator-loader-ignore");
444 uc_pdata->ramp_delay = dev_read_u32_default(dev, "regulator-ramp-delay",
445 -ENODATA);
446 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_uA;
451 } else {
452 uc_pdata->suspend_on = true;
453 uc_pdata->suspend_uV = uc_pdata->max_uA;
454 }
455
456 /* 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
468 debug("dev.name=%s: min_uV=%d, max_uV=%d, boot-on=%d, always-on=%d, "
469 "off-in-suspend=%d, suspend_volt=%d\n",
470 dev->name, uc_pdata->min_uV, uc_pdata->max_uV, uc_pdata->boot_on,
471 uc_pdata->always_on, !uc_pdata->suspend_on, uc_pdata->suspend_uV);
472
473 return 0;
474 }
475
regulators_enable_state_mem(bool verbose)476 int regulators_enable_state_mem(bool verbose)
477 {
478 struct udevice *dev;
479 struct uclass *uc;
480 int ret;
481
482 ret = uclass_get(UCLASS_REGULATOR, &uc);
483 if (ret)
484 return ret;
485 for (uclass_first_device(UCLASS_REGULATOR, &dev);
486 dev;
487 uclass_next_device(&dev)) {
488 ret = regulator_init_suspend(dev);
489
490 if (ret == -EMEDIUMTYPE)
491 ret = 0;
492 if (verbose)
493 regulator_show(dev, ret);
494 if (ret == -ENOSYS)
495 ret = 0;
496 }
497
498 return ret;
499 }
500
regulators_enable_boot_on(bool verbose)501 int regulators_enable_boot_on(bool verbose)
502 {
503 struct udevice *dev;
504 struct uclass *uc;
505 int ret;
506
507 ret = uclass_get(UCLASS_REGULATOR, &uc);
508 if (ret)
509 return ret;
510 for (uclass_first_device(UCLASS_REGULATOR, &dev);
511 dev;
512 uclass_next_device(&dev)) {
513 ret = regulator_autoset(dev);
514
515 if (ret == -EMEDIUMTYPE)
516 ret = 0;
517 if (verbose)
518 regulator_show(dev, ret);
519 if (ret == -ENOSYS)
520 ret = 0;
521 }
522
523 return ret;
524 }
525
526 UCLASS_DRIVER(regulator) = {
527 .id = UCLASS_REGULATOR,
528 .name = "regulator",
529 .post_bind = regulator_post_bind,
530 .pre_probe = regulator_pre_probe,
531 .per_device_platdata_auto_alloc_size =
532 sizeof(struct dm_regulator_uclass_platdata),
533 };
534