1 /*
2  * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <errno.h>
9 #include <limits.h>
10 #include <stdint.h>
11 #include <string.h>
12 
13 #include <common/debug.h>
14 #include <drivers/delay_timer.h>
15 #include <drivers/st/regulator.h>
16 #include <libfdt.h>
17 
18 #define MAX_PROPERTY_LEN 64
19 
20 static struct rdev rdev_array[PLAT_NB_RDEVS];
21 
22 #define for_each_rdev(rdev) \
23 	for (rdev = rdev_array; rdev < (rdev_array + PLAT_NB_RDEVS); rdev++)
24 
25 #define for_each_registered_rdev(rdev) \
26 	for (rdev = rdev_array; \
27 	     (rdev < (rdev_array + PLAT_NB_RDEVS)) && (rdev->desc != NULL); rdev++)
28 
lock_driver(const struct rdev * rdev)29 static void lock_driver(const struct rdev *rdev)
30 {
31 	if (rdev->desc->ops->lock != NULL) {
32 		rdev->desc->ops->lock(rdev->desc);
33 	}
34 }
35 
unlock_driver(const struct rdev * rdev)36 static void unlock_driver(const struct rdev *rdev)
37 {
38 	if (rdev->desc->ops->unlock != NULL) {
39 		rdev->desc->ops->unlock(rdev->desc);
40 	}
41 }
42 
regulator_get_by_phandle(int32_t phandle)43 static struct rdev *regulator_get_by_phandle(int32_t phandle)
44 {
45 	struct rdev *rdev;
46 
47 	for_each_registered_rdev(rdev) {
48 		if (rdev->phandle == phandle) {
49 			return rdev;
50 		}
51 	}
52 
53 	WARN("%s: phandle %d not found\n", __func__, phandle);
54 	return NULL;
55 }
56 
57 /*
58  * Get a regulator from its node name
59  *
60  * @fdt - pointer to device tree memory
61  * @node_name - name of the node "ldo1"
62  * Return pointer to rdev if succeed, NULL else.
63  */
regulator_get_by_name(const char * node_name)64 struct rdev *regulator_get_by_name(const char *node_name)
65 {
66 	struct rdev *rdev;
67 
68 	assert(node_name != NULL);
69 	VERBOSE("get %s\n", node_name);
70 
71 	for_each_registered_rdev(rdev) {
72 		if (strcmp(rdev->desc->node_name, node_name) == 0) {
73 			return rdev;
74 		}
75 	}
76 
77 	WARN("%s: %s not found\n", __func__, node_name);
78 	return NULL;
79 }
80 
get_supply_phandle(const void * fdt,int node,const char * name)81 static int32_t get_supply_phandle(const void *fdt, int node, const char *name)
82 {
83 	const fdt32_t *cuint;
84 	int len __unused;
85 	int supply_phandle = -FDT_ERR_NOTFOUND;
86 	char prop_name[MAX_PROPERTY_LEN];
87 
88 	len = snprintf(prop_name, MAX_PROPERTY_LEN - 1, "%s-supply", name);
89 	assert((len >= 0) && (len < MAX_PROPERTY_LEN - 1));
90 
91 	cuint = fdt_getprop(fdt, node, prop_name, NULL);
92 	if (cuint != NULL) {
93 		supply_phandle = fdt32_to_cpu(*cuint);
94 		VERBOSE("%s: supplied by %d\n", name, supply_phandle);
95 	}
96 
97 	return supply_phandle;
98 }
99 
100 /*
101  * Get a regulator from a supply name
102  *
103  * @fdt - pointer to device tree memory
104  * @node - offset of the node that contains the supply description
105  * @name - name of the supply "vdd" for "vdd-supply'
106  * Return pointer to rdev if succeed, NULL else.
107  */
regulator_get_by_supply_name(const void * fdt,int node,const char * name)108 struct rdev *regulator_get_by_supply_name(const void *fdt, int node, const char *name)
109 {
110 	const int p = get_supply_phandle(fdt, node, name);
111 
112 	if (p < 0) {
113 		return NULL;
114 	}
115 
116 	return regulator_get_by_phandle(p);
117 }
118 
__regulator_set_state(struct rdev * rdev,bool state)119 static int __regulator_set_state(struct rdev *rdev, bool state)
120 {
121 	if (rdev->desc->ops->set_state == NULL) {
122 		return -ENODEV;
123 	}
124 
125 	return rdev->desc->ops->set_state(rdev->desc, state);
126 }
127 
128 /*
129  * Enable regulator
130  *
131  * @rdev - pointer to rdev struct
132  * Return 0 if succeed, non 0 else.
133  */
regulator_enable(struct rdev * rdev)134 int regulator_enable(struct rdev *rdev)
135 {
136 	int ret;
137 
138 	assert(rdev != NULL);
139 
140 	ret = __regulator_set_state(rdev, STATE_ENABLE);
141 
142 	udelay(rdev->enable_ramp_delay);
143 
144 	return ret;
145 }
146 
147 /*
148  * Disable regulator
149  *
150  * @rdev - pointer to rdev struct
151  * Return 0 if succeed, non 0 else.
152  */
regulator_disable(struct rdev * rdev)153 int regulator_disable(struct rdev *rdev)
154 {
155 	int ret;
156 
157 	assert(rdev != NULL);
158 
159 	if (rdev->flags & REGUL_ALWAYS_ON) {
160 		return 0;
161 	}
162 
163 	ret = __regulator_set_state(rdev, STATE_DISABLE);
164 
165 	udelay(rdev->enable_ramp_delay);
166 
167 	return ret;
168 }
169 
170 /*
171  * Regulator enabled query
172  *
173  * @rdev - pointer to rdev struct
174  * Return 0 if disabled, 1 if enabled, <0 else.
175  */
regulator_is_enabled(const struct rdev * rdev)176 int regulator_is_enabled(const struct rdev *rdev)
177 {
178 	int ret;
179 
180 	assert(rdev != NULL);
181 
182 	VERBOSE("%s: is en\n", rdev->desc->node_name);
183 
184 	if (rdev->desc->ops->get_state == NULL) {
185 		return -ENODEV;
186 	}
187 
188 	lock_driver(rdev);
189 
190 	ret = rdev->desc->ops->get_state(rdev->desc);
191 	if (ret < 0) {
192 		ERROR("regul %s get state failed: err:%d\n",
193 		      rdev->desc->node_name, ret);
194 	}
195 
196 	unlock_driver(rdev);
197 
198 	return ret;
199 }
200 
201 /*
202  * Set regulator voltage
203  *
204  * @rdev - pointer to rdev struct
205  * @mvolt - Target voltage level in millivolt
206  * Return 0 if succeed, non 0 else.
207  */
regulator_set_voltage(struct rdev * rdev,uint16_t mvolt)208 int regulator_set_voltage(struct rdev *rdev, uint16_t mvolt)
209 {
210 	int ret;
211 
212 	assert(rdev != NULL);
213 
214 	VERBOSE("%s: set mvolt\n", rdev->desc->node_name);
215 
216 	if (rdev->desc->ops->set_voltage == NULL) {
217 		return -ENODEV;
218 	}
219 
220 	if ((mvolt < rdev->min_mv) || (mvolt > rdev->max_mv)) {
221 		return -EPERM;
222 	}
223 
224 	lock_driver(rdev);
225 
226 	ret = rdev->desc->ops->set_voltage(rdev->desc, mvolt);
227 	if (ret < 0) {
228 		ERROR("regul %s set volt failed: err:%d\n",
229 		      rdev->desc->node_name, ret);
230 	}
231 
232 	unlock_driver(rdev);
233 
234 	return ret;
235 }
236 
237 /*
238  * Set regulator min voltage
239  *
240  * @rdev - pointer to rdev struct
241  * Return 0 if succeed, non 0 else.
242  */
regulator_set_min_voltage(struct rdev * rdev)243 int regulator_set_min_voltage(struct rdev *rdev)
244 {
245 	return regulator_set_voltage(rdev, rdev->min_mv);
246 }
247 
248 /*
249  * Get regulator voltage
250  *
251  * @rdev - pointer to rdev struct
252  * Return milli volts if succeed, <0 else.
253  */
regulator_get_voltage(const struct rdev * rdev)254 int regulator_get_voltage(const struct rdev *rdev)
255 {
256 	int ret;
257 
258 	assert(rdev != NULL);
259 
260 	VERBOSE("%s: get volt\n", rdev->desc->node_name);
261 
262 	if (rdev->desc->ops->get_voltage == NULL) {
263 		return rdev->min_mv;
264 	}
265 
266 	lock_driver(rdev);
267 
268 	ret = rdev->desc->ops->get_voltage(rdev->desc);
269 	if (ret < 0) {
270 		ERROR("regul %s get voltage failed: err:%d\n",
271 		      rdev->desc->node_name, ret);
272 	}
273 
274 	unlock_driver(rdev);
275 
276 	return ret;
277 }
278 
279 /*
280  * List regulator voltages
281  *
282  * @rdev - pointer to rdev struct
283  * @levels - out: array of supported millitvolt levels from min to max value
284  * @count - out: number of possible millivolt values
285  * Return 0 if succeed, non 0 else.
286  */
regulator_list_voltages(const struct rdev * rdev,const uint16_t ** levels,size_t * count)287 int regulator_list_voltages(const struct rdev *rdev, const uint16_t **levels, size_t *count)
288 {
289 	int ret;
290 	size_t n;
291 
292 	assert(rdev != NULL);
293 	assert(levels != NULL);
294 	assert(count != NULL);
295 
296 	VERBOSE("%s: list volt\n", rdev->desc->node_name);
297 
298 	if (rdev->desc->ops->list_voltages == NULL) {
299 		return -ENODEV;
300 	}
301 
302 	lock_driver(rdev);
303 
304 	ret = rdev->desc->ops->list_voltages(rdev->desc, levels, count);
305 
306 	unlock_driver(rdev);
307 
308 	if (ret < 0) {
309 		ERROR("regul %s list_voltages failed: err: %d\n",
310 		      rdev->desc->node_name, ret);
311 		return ret;
312 	}
313 
314 	/*
315 	 * Reduce the possible values depending on min and max from device-tree
316 	 */
317 	n = *count;
318 	while ((n > 1U) && ((*levels)[n - 1U] > rdev->max_mv)) {
319 		n--;
320 	}
321 
322 	/* Verify that max val is a valid value */
323 	if (rdev->max_mv != (*levels)[n - 1]) {
324 		ERROR("regul %s: max value %u is invalid\n",
325 		      rdev->desc->node_name, rdev->max_mv);
326 		return -EINVAL;
327 	}
328 
329 	while ((n > 1U) && ((*levels[0U]) < rdev->min_mv)) {
330 		(*levels)++;
331 		n--;
332 	}
333 
334 	/* Verify that min is not too high */
335 	if (n == 0U) {
336 		ERROR("regul %s set min voltage is too high\n",
337 		      rdev->desc->node_name);
338 		return -EINVAL;
339 	}
340 
341 	/* Verify that min val is a valid vlue */
342 	if (rdev->min_mv != (*levels)[0U]) {
343 		ERROR("regul %s: min value %u is invalid\n",
344 		      rdev->desc->node_name, rdev->min_mv);
345 		return -EINVAL;
346 	}
347 
348 	*count = n;
349 
350 	VERBOSE("rdev->min_mv=%u rdev->max_mv=%u\n", rdev->min_mv, rdev->max_mv);
351 
352 	return 0;
353 }
354 
355 /*
356  * Get regulator voltages range
357  *
358  * @rdev - pointer to rdev struct
359  * @min_mv - out: min possible millivolt value
360  * @max_mv - out: max possible millivolt value
361  * Return 0 if succeed, non 0 else.
362  */
regulator_get_range(const struct rdev * rdev,uint16_t * min_mv,uint16_t * max_mv)363 void regulator_get_range(const struct rdev *rdev, uint16_t *min_mv, uint16_t *max_mv)
364 {
365 	assert(rdev != NULL);
366 
367 	if (min_mv != NULL) {
368 		*min_mv = rdev->min_mv;
369 	}
370 	if (max_mv != NULL) {
371 		*max_mv = rdev->max_mv;
372 	}
373 }
374 
375 /*
376  * Set regulator flag
377  *
378  * @rdev - pointer to rdev struct
379  * @flag - flag value to set (eg: REGUL_OCP)
380  * Return 0 if succeed, non 0 else.
381  */
regulator_set_flag(struct rdev * rdev,uint16_t flag)382 int regulator_set_flag(struct rdev *rdev, uint16_t flag)
383 {
384 	int ret;
385 
386 	/* check that only one bit is set on flag */
387 	if (__builtin_popcount(flag) != 1) {
388 		return -EINVAL;
389 	}
390 
391 	/* REGUL_ALWAYS_ON and REGUL_BOOT_ON are internal properties of the core */
392 	if ((flag == REGUL_ALWAYS_ON) || (flag == REGUL_BOOT_ON)) {
393 		rdev->flags |= flag;
394 		return 0;
395 	}
396 
397 	if (rdev->desc->ops->set_flag == NULL) {
398 		ERROR("%s can not set any flag\n", rdev->desc->node_name);
399 		return -ENODEV;
400 	}
401 
402 	lock_driver(rdev);
403 
404 	ret = rdev->desc->ops->set_flag(rdev->desc, flag);
405 
406 	unlock_driver(rdev);
407 
408 	if (ret != 0) {
409 		ERROR("%s: could not set flag %d ret=%d\n",
410 		      rdev->desc->node_name, flag, ret);
411 		return ret;
412 	}
413 
414 	rdev->flags |= flag;
415 
416 	return 0;
417 }
418 
parse_properties(const void * fdt,struct rdev * rdev,int node)419 static int parse_properties(const void *fdt, struct rdev *rdev, int node)
420 {
421 	int ret;
422 
423 	if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL) {
424 		VERBOSE("%s: set regulator-always-on\n", rdev->desc->node_name);
425 		ret = regulator_set_flag(rdev, REGUL_ALWAYS_ON);
426 		if (ret != 0) {
427 			return ret;
428 		}
429 	}
430 
431 	return 0;
432 }
433 
434 /*
435  * Parse the device-tree for a regulator
436  *
437  * Read min/max voltage from dt and check its validity
438  * Read the properties, and call the driver to set flags
439  * Read power supply phandle
440  * Read and store low power mode states
441  *
442  * @rdev - pointer to rdev struct
443  * @node - device-tree node offset of the regulator
444  * Return 0 if disabled, 1 if enabled, <0 else.
445  */
parse_dt(struct rdev * rdev,int node)446 static int parse_dt(struct rdev *rdev, int node)
447 {
448 	void *fdt;
449 	const fdt32_t *cuint;
450 	const uint16_t *levels;
451 	size_t size;
452 	int ret;
453 
454 	VERBOSE("%s: parse dt\n", rdev->desc->node_name);
455 
456 	if (fdt_get_address(&fdt) == 0) {
457 		return -ENOENT;
458 	}
459 
460 	rdev->phandle = fdt_get_phandle(fdt, node);
461 
462 	cuint = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL);
463 	if (cuint != NULL) {
464 		uint16_t min_mv;
465 
466 		min_mv = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
467 		VERBOSE("%s: min_mv=%d\n", rdev->desc->node_name, (int)min_mv);
468 		if (min_mv <= rdev->max_mv) {
469 			rdev->min_mv = min_mv;
470 		} else {
471 			ERROR("%s: min_mv=%d is too high\n",
472 			      rdev->desc->node_name, (int)min_mv);
473 			return -EINVAL;
474 		}
475 	}
476 
477 	cuint = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL);
478 	if (cuint != NULL) {
479 		uint16_t max_mv;
480 
481 		max_mv = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
482 		VERBOSE("%s: max_mv=%d\n", rdev->desc->node_name, (int)max_mv);
483 		if (max_mv >= rdev->min_mv) {
484 			rdev->max_mv = max_mv;
485 		} else {
486 			ERROR("%s: max_mv=%d is too low\n",
487 			      rdev->desc->node_name, (int)max_mv);
488 			return -EINVAL;
489 		}
490 	}
491 
492 	/* validate that min and max values can be used */
493 	ret = regulator_list_voltages(rdev, &levels, &size);
494 	if ((ret != 0) && (ret != -ENODEV)) {
495 		return ret;
496 	}
497 
498 	ret = parse_properties(fdt, rdev, node);
499 	if (ret != 0) {
500 		return ret;
501 	}
502 
503 	return 0;
504 }
505 
506 /*
507  * Register a regulator driver in regulator framework.
508  * Initialize voltage range from driver description
509  *
510  * @desc - pointer to the regulator description
511  * @node - device-tree node offset of the regulator
512  * Return 0 if succeed, non 0 else.
513  */
regulator_register(const struct regul_description * desc,int node)514 int regulator_register(const struct regul_description *desc, int node)
515 {
516 	struct rdev *rdev;
517 
518 	assert(desc != NULL);
519 
520 	VERBOSE("register %s\n", desc->node_name);
521 
522 	for_each_rdev(rdev) {
523 		if (rdev->desc == NULL) {
524 			break;
525 		}
526 	}
527 
528 	if (rdev == rdev_array + PLAT_NB_RDEVS) {
529 		WARN("Not enough place for regulators, PLAT_NB_RDEVS should be increased.\n");
530 		return -ENOMEM;
531 	}
532 
533 	rdev->desc = desc;
534 	rdev->enable_ramp_delay = rdev->desc->enable_ramp_delay;
535 
536 	if (rdev->desc->ops->list_voltages != NULL) {
537 		int ret;
538 		const uint16_t *levels;
539 		size_t count;
540 
541 		lock_driver(rdev);
542 
543 		ret = rdev->desc->ops->list_voltages(rdev->desc, &levels, &count);
544 
545 		unlock_driver(rdev);
546 
547 		if (ret < 0) {
548 			ERROR("regul %s set state failed: err:%d\n",
549 			      rdev->desc->node_name, ret);
550 			return ret;
551 		}
552 
553 		rdev->min_mv = levels[0];
554 		rdev->max_mv = levels[count - 1U];
555 	} else {
556 		rdev->max_mv = UINT16_MAX;
557 	}
558 
559 	return parse_dt(rdev, node);
560 }
561