xref: /rk3399_rockchip-uboot/drivers/power/regulator/regulator-uclass.c (revision e7b5bb3cc9527752c2c01acb4325fc0721fb75aa)
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 
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 
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 
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 
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 
87 /*
88  * To be called with at most caution as there is no check
89  * before setting the actual voltage value.
90  */
91 int regulator_set_value_force(struct udevice *dev, int uV)
92 {
93 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
94 
95 	if (!ops || !ops->set_value)
96 		return -ENOSYS;
97 
98 	return ops->set_value(dev, uV);
99 }
100 
101 int regulator_get_current(struct udevice *dev)
102 {
103 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
104 
105 	if (!ops || !ops->get_current)
106 		return -ENOSYS;
107 
108 	return ops->get_current(dev);
109 }
110 
111 int regulator_set_current(struct udevice *dev, int uA)
112 {
113 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
114 	struct dm_regulator_uclass_platdata *uc_pdata;
115 
116 	uc_pdata = dev_get_uclass_platdata(dev);
117 	if (uc_pdata->min_uA != -ENODATA && uA < uc_pdata->min_uA)
118 		return -EINVAL;
119 	if (uc_pdata->max_uA != -ENODATA && uA > uc_pdata->max_uA)
120 		return -EINVAL;
121 
122 	if (!ops || !ops->set_current)
123 		return -ENOSYS;
124 
125 	return ops->set_current(dev, uA);
126 }
127 
128 int regulator_get_enable(struct udevice *dev)
129 {
130 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
131 
132 	if (!ops || !ops->get_enable)
133 		return -ENOSYS;
134 
135 	return ops->get_enable(dev);
136 }
137 
138 int regulator_set_enable(struct udevice *dev, bool enable)
139 {
140 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
141 
142 	if (!ops || !ops->set_enable)
143 		return -ENOSYS;
144 
145 	return ops->set_enable(dev, enable);
146 }
147 
148 int regulator_set_suspend_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_suspend_enable)
153 		return -ENOSYS;
154 
155 	return ops->set_suspend_enable(dev, enable);
156 }
157 
158 int regulator_set_ramp_delay(struct udevice *dev, u32 ramp_delay)
159 {
160 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
161 
162 	if (!ops || !ops->set_ramp_delay)
163 		return -ENOSYS;
164 
165 	return ops->set_ramp_delay(dev, ramp_delay);
166 }
167 
168 int regulator_get_mode(struct udevice *dev)
169 {
170 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
171 
172 	if (!ops || !ops->get_mode)
173 		return -ENOSYS;
174 
175 	return ops->get_mode(dev);
176 }
177 
178 int regulator_set_mode(struct udevice *dev, int mode)
179 {
180 	const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
181 
182 	if (!ops || !ops->set_mode)
183 		return -ENOSYS;
184 
185 	return ops->set_mode(dev, mode);
186 }
187 
188 int regulator_get_by_platname(const char *plat_name, struct udevice **devp)
189 {
190 	struct dm_regulator_uclass_platdata *uc_pdata;
191 	struct udevice *dev;
192 	int ret;
193 
194 	*devp = NULL;
195 
196 	for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
197 	     ret = uclass_find_next_device(&dev)) {
198 		if (ret) {
199 			debug("regulator %s, ret=%d\n", dev->name, ret);
200 			continue;
201 		}
202 
203 		uc_pdata = dev_get_uclass_platdata(dev);
204 		if (!uc_pdata || strcmp(plat_name, uc_pdata->name))
205 			continue;
206 
207 		return uclass_get_device_tail(dev, 0, devp);
208 	}
209 
210 	debug("%s: can't find: %s, ret=%d\n", __func__, plat_name, ret);
211 
212 	return -ENODEV;
213 }
214 
215 int regulator_get_by_devname(const char *devname, struct udevice **devp)
216 {
217 	return uclass_get_device_by_name(UCLASS_REGULATOR, devname, devp);
218 }
219 
220 int device_get_supply_regulator(struct udevice *dev, const char *supply_name,
221 				struct udevice **devp)
222 {
223 	return uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
224 					    supply_name, devp);
225 }
226 
227 int regulator_autoset(struct udevice *dev)
228 {
229 	struct dm_regulator_uclass_platdata *uc_pdata;
230 	int ret = 0;
231 
232 	uc_pdata = dev_get_uclass_platdata(dev);
233 
234 	if (uc_pdata->ramp_delay != -ENODATA)
235 		regulator_set_ramp_delay(dev, uc_pdata->ramp_delay);
236 
237 	/*
238 	 * Suspend configure is not necessary and should not influence normal
239 	 * configure, so that we set "ret=0" even failed here.
240 	 */
241 	ret = regulator_set_suspend_enable(dev, uc_pdata->suspend_on);
242 	if (!ret && uc_pdata->suspend_on)
243 		regulator_set_suspend_value(dev, uc_pdata->suspend_uV);
244 	else
245 		ret = 0;
246 
247 	if (!uc_pdata->always_on && !uc_pdata->boot_on)
248 		return -EMEDIUMTYPE;
249 
250 	if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
251 		ret = regulator_set_value(dev, uc_pdata->min_uV);
252 	if (uc_pdata->init_uV > 0) {
253 		ret = regulator_set_value(dev, uc_pdata->init_uV);
254 		if (!ret)
255 			printf("regulator(%s) init %d uV\n",
256 			       dev->name, uc_pdata->init_uV);
257 	}
258 
259 	if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA))
260 		ret = regulator_set_current(dev, uc_pdata->min_uA);
261 
262 	if (!ret)
263 		ret = regulator_set_enable(dev, true);
264 
265 	return ret;
266 }
267 
268 static void regulator_show(struct udevice *dev, int ret)
269 {
270 	struct dm_regulator_uclass_platdata *uc_pdata;
271 
272 	uc_pdata = dev_get_uclass_platdata(dev);
273 
274 	printf("%s@%s: ", dev->name, uc_pdata->name);
275 	printf("%duV <-> %duV, set %duV, %s",
276 	       uc_pdata->min_uV, uc_pdata->max_uV, uc_pdata->min_uV,
277 	       (uc_pdata->always_on || uc_pdata->boot_on) ?
278 	       "enabling" : "not enabling");
279 	if (ret)
280 		printf(" (ret: %d)", ret);
281 
282 	printf("; supsend %duV, %s",
283 	       uc_pdata->suspend_uV,
284 	       uc_pdata->suspend_on ? "enabling" : "not enabling");
285 	if (uc_pdata->init_uV != -ENODATA)
286 		printf("; init %duV", uc_pdata->init_uV);
287 
288 	printf("\n");
289 }
290 
291 int regulator_autoset_by_name(const char *platname, struct udevice **devp)
292 {
293 	struct udevice *dev;
294 	int ret;
295 
296 	ret = regulator_get_by_platname(platname, &dev);
297 	if (devp)
298 		*devp = dev;
299 	if (ret) {
300 		debug("Can get the regulator: %s (err=%d)\n", platname, ret);
301 		return ret;
302 	}
303 
304 	return regulator_autoset(dev);
305 }
306 
307 int regulator_list_autoset(const char *list_platname[],
308 			   struct udevice *list_devp[],
309 			   bool verbose)
310 {
311 	struct udevice *dev;
312 	int error = 0, i = 0, ret;
313 
314 	while (list_platname[i]) {
315 		ret = regulator_autoset_by_name(list_platname[i], &dev);
316 		if (ret != -EMEDIUMTYPE && verbose)
317 			regulator_show(dev, ret);
318 		if (ret & !error)
319 			error = ret;
320 
321 		if (list_devp)
322 			list_devp[i] = dev;
323 
324 		i++;
325 	}
326 
327 	return error;
328 }
329 
330 static bool regulator_name_is_unique(struct udevice *check_dev,
331 				     const char *check_name)
332 {
333 	struct dm_regulator_uclass_platdata *uc_pdata;
334 	struct udevice *dev;
335 	int check_len = strlen(check_name);
336 	int ret;
337 	int len;
338 
339 	for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
340 	     ret = uclass_find_next_device(&dev)) {
341 		if (ret || dev == check_dev)
342 			continue;
343 
344 		uc_pdata = dev_get_uclass_platdata(dev);
345 		len = strlen(uc_pdata->name);
346 		if (len != check_len)
347 			continue;
348 
349 		if (!strcmp(uc_pdata->name, check_name))
350 			return false;
351 	}
352 
353 	return true;
354 }
355 
356 static int regulator_post_bind(struct udevice *dev)
357 {
358 	struct dm_regulator_uclass_platdata *uc_pdata;
359 	const char *property = "regulator-name";
360 
361 	uc_pdata = dev_get_uclass_platdata(dev);
362 
363 	/* Regulator's mandatory constraint */
364 	uc_pdata->name = dev_read_string(dev, property);
365 	if (!uc_pdata->name) {
366 		debug("%s: dev '%s' has no property '%s'\n",
367 		      __func__, dev->name, property);
368 		uc_pdata->name = dev_read_name(dev);
369 		if (!uc_pdata->name)
370 			return -EINVAL;
371 	}
372 
373 	if (regulator_name_is_unique(dev, uc_pdata->name))
374 		return 0;
375 
376 	debug("'%s' of dev: '%s', has nonunique value: '%s\n",
377 	      property, dev->name, uc_pdata->name);
378 
379 	return -EINVAL;
380 }
381 
382 static int regulator_pre_probe(struct udevice *dev)
383 {
384 	struct dm_regulator_uclass_platdata *uc_pdata;
385 	ofnode node;
386 
387 	uc_pdata = dev_get_uclass_platdata(dev);
388 	if (!uc_pdata)
389 		return -ENXIO;
390 
391 	/* Regulator's optional constraints */
392 	uc_pdata->min_uV = dev_read_u32_default(dev, "regulator-min-microvolt",
393 						-ENODATA);
394 	uc_pdata->max_uV = dev_read_u32_default(dev, "regulator-max-microvolt",
395 						-ENODATA);
396 	uc_pdata->init_uV = dev_read_u32_default(dev, "regulator-init-microvolt",
397 						-ENODATA);
398 	uc_pdata->min_uA = dev_read_u32_default(dev, "regulator-min-microamp",
399 						-ENODATA);
400 	uc_pdata->max_uA = dev_read_u32_default(dev, "regulator-max-microamp",
401 						-ENODATA);
402 	uc_pdata->always_on = dev_read_bool(dev, "regulator-always-on");
403 	uc_pdata->boot_on = dev_read_bool(dev, "regulator-boot-on");
404 	uc_pdata->ramp_delay = dev_read_u32_default(dev, "regulator-ramp-delay",
405 						    -ENODATA);
406 	node = dev_read_subnode(dev, "regulator-state-mem");
407 	if (ofnode_valid(node)) {
408 		uc_pdata->suspend_on = !ofnode_read_bool(node, "regulator-off-in-suspend");
409 		if (ofnode_read_u32(node, "regulator-suspend-microvolt", &uc_pdata->suspend_uV))
410 			uc_pdata->suspend_uV = uc_pdata->max_uA;
411 	} else {
412 		uc_pdata->suspend_on = true;
413 		uc_pdata->suspend_uV = uc_pdata->max_uA;
414 	}
415 
416 	/* Those values are optional (-ENODATA if unset) */
417 	if ((uc_pdata->min_uV != -ENODATA) &&
418 	    (uc_pdata->max_uV != -ENODATA) &&
419 	    (uc_pdata->min_uV == uc_pdata->max_uV))
420 		uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UV;
421 
422 	/* Those values are optional (-ENODATA if unset) */
423 	if ((uc_pdata->min_uA != -ENODATA) &&
424 	    (uc_pdata->max_uA != -ENODATA) &&
425 	    (uc_pdata->min_uA == uc_pdata->max_uA))
426 		uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UA;
427 
428 	debug("dev.name=%s: min_uV=%d, max_uV=%d, boot-on=%d, always-on=%d, "
429 	      "off-in-suspend=%d, suspend_volt=%d\n",
430 	      dev->name, uc_pdata->min_uV, uc_pdata->max_uV, uc_pdata->boot_on,
431 	      uc_pdata->always_on, !uc_pdata->suspend_on, uc_pdata->suspend_uV);
432 
433 	return 0;
434 }
435 
436 int regulators_enable_boot_on(bool verbose)
437 {
438 	struct udevice *dev;
439 	struct uclass *uc;
440 	int ret;
441 
442 	ret = uclass_get(UCLASS_REGULATOR, &uc);
443 	if (ret)
444 		return ret;
445 	for (uclass_first_device(UCLASS_REGULATOR, &dev);
446 	     dev;
447 	     uclass_next_device(&dev)) {
448 		ret = regulator_autoset(dev);
449 		if (ret == -EMEDIUMTYPE)
450 			ret = 0;
451 		if (verbose)
452 			regulator_show(dev, ret);
453 		if (ret == -ENOSYS)
454 			ret = 0;
455 	}
456 
457 	return ret;
458 }
459 
460 UCLASS_DRIVER(regulator) = {
461 	.id		= UCLASS_REGULATOR,
462 	.name		= "regulator",
463 	.post_bind	= regulator_post_bind,
464 	.pre_probe	= regulator_pre_probe,
465 	.per_device_platdata_auto_alloc_size =
466 				sizeof(struct dm_regulator_uclass_platdata),
467 };
468