xref: /optee_os/core/drivers/stpmic1.c (revision c52a7c2e23f1afb784c01720eeb039485106daf6)
1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved
4  */
5 
6 #include <assert.h>
7 #include <drivers/stpmic1.h>
8 #include <kernel/panic.h>
9 #include <platform_config.h>
10 #include <stdint.h>
11 #include <string.h>
12 #include <trace.h>
13 #include <util.h>
14 
15 #define VOLTAGE_INDEX_INVALID		((unsigned int)~0)
16 
17 struct regul_struct {
18 	const char *dt_node_name;
19 	const uint16_t *voltage_table;
20 	uint8_t voltage_table_size;
21 	uint8_t control_reg;
22 	uint8_t low_power_reg;
23 	uint8_t enable_pos;
24 	uint8_t pull_down_reg;
25 	uint8_t pull_down_pos;
26 	uint8_t mask_reset_reg;
27 	uint8_t mask_reset_pos;
28 };
29 
30 static struct i2c_handle_s *pmic_i2c_handle;
31 static uint16_t pmic_i2c_addr;
32 
33 /* Voltage tables in mV */
34 static const uint16_t buck1_voltage_table[] = {
35 	725,
36 	725,
37 	725,
38 	725,
39 	725,
40 	725,
41 	750,
42 	775,
43 	800,
44 	825,
45 	850,
46 	875,
47 	900,
48 	925,
49 	950,
50 	975,
51 	1000,
52 	1025,
53 	1050,
54 	1075,
55 	1100,
56 	1125,
57 	1150,
58 	1175,
59 	1200,
60 	1225,
61 	1250,
62 	1275,
63 	1300,
64 	1325,
65 	1350,
66 	1375,
67 	1400,
68 	1425,
69 	1450,
70 	1475,
71 	1500,
72 	1500,
73 	1500,
74 	1500,
75 	1500,
76 	1500,
77 	1500,
78 	1500,
79 	1500,
80 	1500,
81 	1500,
82 	1500,
83 	1500,
84 	1500,
85 	1500,
86 	1500,
87 	1500,
88 	1500,
89 	1500,
90 	1500,
91 	1500,
92 	1500,
93 	1500,
94 	1500,
95 	1500,
96 	1500,
97 	1500,
98 	1500,
99 };
100 
101 static const uint16_t buck2_voltage_table[] = {
102 	1000,
103 	1000,
104 	1000,
105 	1000,
106 	1000,
107 	1000,
108 	1000,
109 	1000,
110 	1000,
111 	1000,
112 	1000,
113 	1000,
114 	1000,
115 	1000,
116 	1000,
117 	1000,
118 	1000,
119 	1000,
120 	1050,
121 	1050,
122 	1100,
123 	1100,
124 	1150,
125 	1150,
126 	1200,
127 	1200,
128 	1250,
129 	1250,
130 	1300,
131 	1300,
132 	1350,
133 	1350,
134 	1400,
135 	1400,
136 	1450,
137 	1450,
138 	1500,
139 };
140 
141 static const uint16_t buck3_voltage_table[] = {
142 	1000,
143 	1000,
144 	1000,
145 	1000,
146 	1000,
147 	1000,
148 	1000,
149 	1000,
150 	1000,
151 	1000,
152 	1000,
153 	1000,
154 	1000,
155 	1000,
156 	1000,
157 	1000,
158 	1000,
159 	1000,
160 	1000,
161 	1000,
162 	1100,
163 	1100,
164 	1100,
165 	1100,
166 	1200,
167 	1200,
168 	1200,
169 	1200,
170 	1300,
171 	1300,
172 	1300,
173 	1300,
174 	1400,
175 	1400,
176 	1400,
177 	1400,
178 	1500,
179 	1600,
180 	1700,
181 	1800,
182 	1900,
183 	2000,
184 	2100,
185 	2200,
186 	2300,
187 	2400,
188 	2500,
189 	2600,
190 	2700,
191 	2800,
192 	2900,
193 	3000,
194 	3100,
195 	3200,
196 	3300,
197 	3400,
198 };
199 
200 static const uint16_t buck4_voltage_table[] = {
201 	600,
202 	625,
203 	650,
204 	675,
205 	700,
206 	725,
207 	750,
208 	775,
209 	800,
210 	825,
211 	850,
212 	875,
213 	900,
214 	925,
215 	950,
216 	975,
217 	1000,
218 	1025,
219 	1050,
220 	1075,
221 	1100,
222 	1125,
223 	1150,
224 	1175,
225 	1200,
226 	1225,
227 	1250,
228 	1275,
229 	1300,
230 	1300,
231 	1350,
232 	1350,
233 	1400,
234 	1400,
235 	1450,
236 	1450,
237 	1500,
238 	1600,
239 	1700,
240 	1800,
241 	1900,
242 	2000,
243 	2100,
244 	2200,
245 	2300,
246 	2400,
247 	2500,
248 	2600,
249 	2700,
250 	2800,
251 	2900,
252 	3000,
253 	3100,
254 	3200,
255 	3300,
256 	3400,
257 	3500,
258 	3600,
259 	3700,
260 	3800,
261 	3900,
262 };
263 
264 static const uint16_t ldo1_voltage_table[] = {
265 	1700,
266 	1700,
267 	1700,
268 	1700,
269 	1700,
270 	1700,
271 	1700,
272 	1700,
273 	1700,
274 	1800,
275 	1900,
276 	2000,
277 	2100,
278 	2200,
279 	2300,
280 	2400,
281 	2500,
282 	2600,
283 	2700,
284 	2800,
285 	2900,
286 	3000,
287 	3100,
288 	3200,
289 	3300,
290 };
291 
292 static const uint16_t ldo2_voltage_table[] = {
293 	1700,
294 	1700,
295 	1700,
296 	1700,
297 	1700,
298 	1700,
299 	1700,
300 	1700,
301 	1700,
302 	1800,
303 	1900,
304 	2000,
305 	2100,
306 	2200,
307 	2300,
308 	2400,
309 	2500,
310 	2600,
311 	2700,
312 	2800,
313 	2900,
314 	3000,
315 	3100,
316 	3200,
317 	3300,
318 };
319 
320 static const uint16_t ldo3_voltage_table[] = {
321 	1700,
322 	1700,
323 	1700,
324 	1700,
325 	1700,
326 	1700,
327 	1700,
328 	1700,
329 	1700,
330 	1800,
331 	1900,
332 	2000,
333 	2100,
334 	2200,
335 	2300,
336 	2400,
337 	2500,
338 	2600,
339 	2700,
340 	2800,
341 	2900,
342 	3000,
343 	3100,
344 	3200,
345 	3300,
346 	3300,
347 	3300,
348 	3300,
349 	3300,
350 	3300,
351 	3300,
352 	500,	/* VOUT2/2 (Sink/source mode) */
353 	0xFFFF, /* VREFDDR */
354 };
355 
356 static const uint16_t ldo5_voltage_table[] = {
357 	1700,
358 	1700,
359 	1700,
360 	1700,
361 	1700,
362 	1700,
363 	1700,
364 	1700,
365 	1700,
366 	1800,
367 	1900,
368 	2000,
369 	2100,
370 	2200,
371 	2300,
372 	2400,
373 	2500,
374 	2600,
375 	2700,
376 	2800,
377 	2900,
378 	3000,
379 	3100,
380 	3200,
381 	3300,
382 	3400,
383 	3500,
384 	3600,
385 	3700,
386 	3800,
387 	3900,
388 };
389 
390 static const uint16_t ldo6_voltage_table[] = {
391 	900,
392 	1000,
393 	1100,
394 	1200,
395 	1300,
396 	1400,
397 	1500,
398 	1600,
399 	1700,
400 	1800,
401 	1900,
402 	2000,
403 	2100,
404 	2200,
405 	2300,
406 	2400,
407 	2500,
408 	2600,
409 	2700,
410 	2800,
411 	2900,
412 	3000,
413 	3100,
414 	3200,
415 	3300,
416 };
417 
418 static const uint16_t ldo4_voltage_table[] = {
419 	3300,
420 };
421 
422 static const uint16_t vref_ddr_voltage_table[] = {
423 	3300,
424 };
425 
426 static const uint16_t fixed_5v_voltage_table[] = {
427 	5000,
428 };
429 
430 /* Table of Regulators in PMIC SoC */
431 static const struct regul_struct regulators_table[] = {
432 	{
433 		.dt_node_name	= "buck1",
434 		.voltage_table	= buck1_voltage_table,
435 		.voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
436 		.control_reg	= BUCK1_CONTROL_REG,
437 		.low_power_reg	= BUCK1_PWRCTRL_REG,
438 		.enable_pos	= LDO_BUCK_ENABLE_POS,
439 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
440 		.pull_down_pos	= BUCK1_PULL_DOWN_SHIFT,
441 		.mask_reset_reg = MASK_RESET_BUCK_REG,
442 		.mask_reset_pos = BUCK1_MASK_RESET_SHIFT,
443 	},
444 	{
445 		.dt_node_name	= "buck2",
446 		.voltage_table	= buck2_voltage_table,
447 		.voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
448 		.control_reg	= BUCK2_CONTROL_REG,
449 		.low_power_reg	= BUCK2_PWRCTRL_REG,
450 		.enable_pos	= LDO_BUCK_ENABLE_POS,
451 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
452 		.pull_down_pos	= BUCK2_PULL_DOWN_SHIFT,
453 		.mask_reset_reg = MASK_RESET_BUCK_REG,
454 		.mask_reset_pos = BUCK2_MASK_RESET_SHIFT,
455 	},
456 	{
457 		.dt_node_name	= "buck3",
458 		.voltage_table	= buck3_voltage_table,
459 		.voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
460 		.control_reg	= BUCK3_CONTROL_REG,
461 		.low_power_reg	= BUCK3_PWRCTRL_REG,
462 		.enable_pos	= LDO_BUCK_ENABLE_POS,
463 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
464 		.pull_down_pos	= BUCK3_PULL_DOWN_SHIFT,
465 		.mask_reset_reg = MASK_RESET_BUCK_REG,
466 		.mask_reset_pos = BUCK3_MASK_RESET_SHIFT,
467 	},
468 	{
469 		.dt_node_name	= "buck4",
470 		.voltage_table	= buck4_voltage_table,
471 		.voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
472 		.control_reg	= BUCK4_CONTROL_REG,
473 		.low_power_reg	= BUCK4_PWRCTRL_REG,
474 		.enable_pos	= LDO_BUCK_ENABLE_POS,
475 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
476 		.pull_down_pos	= BUCK4_PULL_DOWN_SHIFT,
477 		.mask_reset_reg = MASK_RESET_BUCK_REG,
478 		.mask_reset_pos = BUCK4_MASK_RESET_SHIFT,
479 	},
480 	{
481 		.dt_node_name	= "ldo1",
482 		.voltage_table	= ldo1_voltage_table,
483 		.voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
484 		.control_reg	= LDO1_CONTROL_REG,
485 		.low_power_reg	= LDO1_PWRCTRL_REG,
486 		.enable_pos	= LDO_BUCK_ENABLE_POS,
487 		.mask_reset_reg = MASK_RESET_LDO_REG,
488 		.mask_reset_pos = LDO1_MASK_RESET_SHIFT,
489 	},
490 	{
491 		.dt_node_name	= "ldo2",
492 		.voltage_table	= ldo2_voltage_table,
493 		.voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
494 		.control_reg	= LDO2_CONTROL_REG,
495 		.low_power_reg	= LDO2_PWRCTRL_REG,
496 		.enable_pos	= LDO_BUCK_ENABLE_POS,
497 		.mask_reset_reg = MASK_RESET_LDO_REG,
498 		.mask_reset_pos = LDO2_MASK_RESET_SHIFT,
499 	},
500 	{
501 		.dt_node_name	= "ldo3",
502 		.voltage_table	= ldo3_voltage_table,
503 		.voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
504 		.control_reg	= LDO3_CONTROL_REG,
505 		.low_power_reg	= LDO3_PWRCTRL_REG,
506 		.enable_pos	= LDO_BUCK_ENABLE_POS,
507 		.mask_reset_reg = MASK_RESET_LDO_REG,
508 		.mask_reset_pos = LDO3_MASK_RESET_SHIFT,
509 	},
510 	{
511 		.dt_node_name	= "ldo4",
512 		.voltage_table	= ldo4_voltage_table,
513 		.voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
514 		.control_reg	= LDO4_CONTROL_REG,
515 		.low_power_reg	= LDO4_PWRCTRL_REG,
516 		.enable_pos	= LDO_BUCK_ENABLE_POS,
517 		.mask_reset_reg = MASK_RESET_LDO_REG,
518 		.mask_reset_pos = LDO4_MASK_RESET_SHIFT,
519 	},
520 	{
521 		.dt_node_name	= "ldo5",
522 		.voltage_table	= ldo5_voltage_table,
523 		.voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
524 		.control_reg	= LDO5_CONTROL_REG,
525 		.low_power_reg	= LDO5_PWRCTRL_REG,
526 		.enable_pos	= LDO_BUCK_ENABLE_POS,
527 		.mask_reset_reg = MASK_RESET_LDO_REG,
528 		.mask_reset_pos = LDO5_MASK_RESET_SHIFT,
529 	},
530 	{
531 		.dt_node_name	= "ldo6",
532 		.voltage_table	= ldo6_voltage_table,
533 		.voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
534 		.control_reg	= LDO6_CONTROL_REG,
535 		.low_power_reg	= LDO6_PWRCTRL_REG,
536 		.enable_pos	= LDO_BUCK_ENABLE_POS,
537 		.mask_reset_reg = MASK_RESET_LDO_REG,
538 		.mask_reset_pos = LDO6_MASK_RESET_SHIFT,
539 	},
540 	{
541 		.dt_node_name	= "vref_ddr",
542 		.voltage_table	= vref_ddr_voltage_table,
543 		.voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
544 		.control_reg	= VREF_DDR_CONTROL_REG,
545 		.low_power_reg	= VREF_DDR_PWRCTRL_REG,
546 		.enable_pos	= LDO_BUCK_ENABLE_POS,
547 		.mask_reset_reg = MASK_RESET_LDO_REG,
548 		.mask_reset_pos = VREF_DDR_MASK_RESET_SHIFT,
549 	},
550 	{
551 		.dt_node_name = "boost",
552 		.voltage_table	= fixed_5v_voltage_table,
553 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
554 		.control_reg	= USB_CONTROL_REG,
555 		.enable_pos	= BOOST_ENABLED_POS,
556 	},
557 	{
558 		.dt_node_name	= "pwr_sw1",
559 		.voltage_table	= fixed_5v_voltage_table,
560 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
561 		.control_reg	= USB_CONTROL_REG,
562 		.enable_pos	= USBSW_OTG_SWITCH_ENABLED_POS,
563 	},
564 	{
565 		.dt_node_name	= "pwr_sw2",
566 		.voltage_table	= fixed_5v_voltage_table,
567 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
568 		.control_reg	= USB_CONTROL_REG,
569 		.enable_pos	= SWIN_SWOUT_ENABLED_POS,
570 	},
571 };
572 
573 static const struct regul_struct *get_regulator_data(const char *name)
574 {
575 	unsigned int i = 0;
576 
577 	for (i = 0; i < ARRAY_SIZE(regulators_table); i++)
578 		if (strcmp(name, regulators_table[i].dt_node_name) == 0)
579 			return &regulators_table[i];
580 
581 	DMSG("Regulator %s not found", name);
582 	return NULL;
583 }
584 
585 TEE_Result stpmic1_regulator_levels_mv(const char *name,
586 				       const uint16_t **levels,
587 				       size_t *levels_count)
588 {
589 	const struct regul_struct *regul = get_regulator_data(name);
590 
591 	if (!regul)
592 		return TEE_ERROR_BAD_PARAMETERS;
593 
594 	if (levels_count)
595 		*levels_count = regul->voltage_table_size;
596 
597 	if (levels)
598 		*levels = regul->voltage_table;
599 
600 	return TEE_SUCCESS;
601 }
602 
603 static size_t voltage_to_index(const char *name, uint16_t millivolts)
604 {
605 	const struct regul_struct *regul = get_regulator_data(name);
606 	unsigned int i = 0;
607 
608 	assert(regul->voltage_table);
609 	for (i = 0; i < regul->voltage_table_size; i++)
610 		if (regul->voltage_table[i] == millivolts)
611 			return i;
612 
613 	return VOLTAGE_INDEX_INVALID;
614 }
615 
616 int stpmic1_powerctrl_on(void)
617 {
618 	return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
619 				       PWRCTRL_PIN_VALID);
620 }
621 
622 int stpmic1_switch_off(void)
623 {
624 	return stpmic1_register_update(MAIN_CONTROL_REG, 1,
625 				       SOFTWARE_SWITCH_OFF_ENABLED);
626 }
627 
628 int stpmic1_regulator_enable(const char *name)
629 {
630 	const struct regul_struct *regul = get_regulator_data(name);
631 
632 	return stpmic1_register_update(regul->control_reg,
633 				       BIT(regul->enable_pos),
634 				       BIT(regul->enable_pos));
635 }
636 
637 int stpmic1_regulator_disable(const char *name)
638 {
639 	const struct regul_struct *regul = get_regulator_data(name);
640 
641 	return stpmic1_register_update(regul->control_reg, 0,
642 				       BIT(regul->enable_pos));
643 }
644 
645 bool stpmic1_is_regulator_enabled(const char *name)
646 {
647 	const struct regul_struct *regul = get_regulator_data(name);
648 	uint8_t val = 0;
649 
650 	if (stpmic1_register_read(regul->control_reg, &val))
651 		panic();
652 
653 	return val & BIT(regul->enable_pos);
654 }
655 
656 /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
657 static uint8_t find_plat_mask(const char *name)
658 {
659 	if (!strncmp(name, "buck", 4))
660 		return BUCK_VOLTAGE_MASK;
661 
662 	if (!strncmp(name, "ldo", 3) && strcmp(name, "ldo4"))
663 		return LDO_VOLTAGE_MASK;
664 
665 	return 0;
666 }
667 
668 int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
669 {
670 	size_t voltage_index = voltage_to_index(name, millivolts);
671 	const struct regul_struct *regul = get_regulator_data(name);
672 	uint8_t mask = 0;
673 
674 	if (voltage_index == VOLTAGE_INDEX_INVALID)
675 		return -1;
676 
677 	mask = find_plat_mask(name);
678 	if (!mask)
679 		return 0;
680 
681 	return stpmic1_register_update(regul->control_reg,
682 				       voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
683 				       mask);
684 }
685 
686 int stpmic1_regulator_mask_reset_set(const char *name)
687 {
688 	const struct regul_struct *regul = get_regulator_data(name);
689 
690 	if (regul->control_reg == USB_CONTROL_REG) {
691 		DMSG("No reset for USB control");
692 		return -1;
693 	}
694 
695 	return stpmic1_register_update(regul->mask_reset_reg,
696 				       BIT(regul->mask_reset_pos),
697 				       LDO_BUCK_RESET_MASK <<
698 				       regul->mask_reset_pos);
699 }
700 
701 int stpmic1_bo_enable_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
702 {
703 	const struct regul_struct *regul = get_regulator_data(name);
704 
705 	cfg->ctrl_reg = regul->control_reg;
706 	cfg->enable_pos = regul->enable_pos;
707 
708 	return 0;
709 }
710 
711 int stpmic1_bo_enable_unpg(struct stpmic1_bo_cfg *cfg)
712 {
713 	return stpmic1_register_update(cfg->ctrl_reg,
714 				       BIT(cfg->enable_pos),
715 				       BIT(cfg->enable_pos));
716 }
717 
718 /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */
719 int stpmic1_bo_voltage_cfg(const char *name, uint16_t min_millivolt,
720 			   struct stpmic1_bo_cfg *cfg)
721 {
722 	size_t min_index = voltage_to_index(name, min_millivolt);
723 	const struct regul_struct *regul = get_regulator_data(name);
724 	uint8_t mask = 0;
725 
726 	if (min_index == VOLTAGE_INDEX_INVALID)
727 		panic();
728 
729 	mask = find_plat_mask(name);
730 	if (!mask)
731 		return 1;
732 
733 	cfg->ctrl_reg = regul->control_reg;
734 	cfg->min_value = min_index << LDO_BUCK_VOLTAGE_SHIFT;
735 	cfg->mask = mask;
736 
737 	return 0;
738 }
739 
740 int stpmic1_bo_voltage_unpg(struct stpmic1_bo_cfg *cfg)
741 {
742 	uint8_t value = 0;
743 
744 	assert(cfg->ctrl_reg);
745 
746 	if (stpmic1_register_read(cfg->ctrl_reg, &value))
747 		return -1;
748 
749 	if ((value & cfg->mask) >= cfg->min_value)
750 		return 0;
751 
752 	return stpmic1_register_update(cfg->ctrl_reg, cfg->min_value,
753 				       cfg->mask);
754 }
755 
756 int stpmic1_bo_pull_down_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
757 {
758 	const struct regul_struct *regul = get_regulator_data(name);
759 
760 	if (!regul->pull_down_reg) {
761 		DMSG("No pull down for regu %s", name);
762 		panic();
763 	}
764 
765 	cfg->pd_reg = regul->pull_down_reg;
766 	cfg->pd_value = BIT(regul->pull_down_pos);
767 	cfg->pd_mask = LDO_BUCK_PULL_DOWN_MASK << regul->pull_down_pos;
768 
769 	return 0;
770 }
771 
772 int stpmic1_bo_pull_down_unpg(struct stpmic1_bo_cfg *cfg)
773 {
774 	assert(cfg->pd_reg);
775 
776 	return stpmic1_register_update(cfg->pd_reg, cfg->pd_value,
777 				       cfg->pd_mask);
778 }
779 
780 int stpmic1_bo_mask_reset_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
781 {
782 	const struct regul_struct *regul = get_regulator_data(name);
783 
784 	if (!regul->mask_reset_reg) {
785 		DMSG("No reset mask for regu %s", name);
786 		panic();
787 	}
788 
789 	cfg->mrst_reg = regul->mask_reset_reg;
790 	cfg->mrst_value = BIT(regul->mask_reset_pos);
791 	cfg->mrst_mask = LDO_BUCK_RESET_MASK << regul->mask_reset_pos;
792 
793 	return 0;
794 }
795 
796 int stpmic1_bo_mask_reset_unpg(struct stpmic1_bo_cfg *cfg)
797 {
798 	assert(cfg->mrst_reg);
799 
800 	return stpmic1_register_update(cfg->mrst_reg, cfg->mrst_value,
801 				       cfg->mrst_mask);
802 }
803 
804 int stpmic1_regulator_voltage_get(const char *name)
805 {
806 	const struct regul_struct *regul = get_regulator_data(name);
807 	uint8_t value = 0;
808 	uint8_t mask = 0;
809 
810 	mask = find_plat_mask(name);
811 	if (!mask)
812 		return 0;
813 
814 	if (stpmic1_register_read(regul->control_reg, &value))
815 		return -1;
816 
817 	value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
818 
819 	if (value > regul->voltage_table_size)
820 		return -1;
821 
822 	return regul->voltage_table[value];
823 }
824 
825 int stpmic1_lp_copy_reg(const char *name)
826 {
827 	const struct regul_struct *regul = get_regulator_data(name);
828 	uint8_t val = 0;
829 	int status = 0;
830 
831 	if (!regul->low_power_reg)
832 		return -1;
833 
834 	status = stpmic1_register_read(regul->control_reg, &val);
835 	if (status)
836 		return status;
837 
838 	return stpmic1_register_write(regul->low_power_reg, val);
839 }
840 
841 bool stpmic1_regu_has_lp_cfg(const char *name)
842 {
843 	return get_regulator_data(name)->low_power_reg;
844 }
845 
846 int stpmic1_lp_cfg(const char *name, struct stpmic1_lp_cfg *cfg)
847 {
848 	const struct regul_struct *regul = get_regulator_data(name);
849 
850 	if (!regul->low_power_reg)
851 		return -1;
852 
853 	cfg->ctrl_reg = regul->control_reg;
854 	cfg->lp_reg = regul->low_power_reg;
855 
856 	return 0;
857 }
858 
859 int stpmic1_lp_load_unpg(struct stpmic1_lp_cfg *cfg)
860 {
861 	uint8_t val = 0;
862 	int status = 0;
863 
864 	assert(cfg->lp_reg);
865 
866 	status = stpmic1_register_read(cfg->ctrl_reg, &val);
867 	if (!status)
868 		status = stpmic1_register_write(cfg->lp_reg, val);
869 
870 	return status;
871 }
872 
873 int stpmic1_lp_reg_on_off(const char *name, uint8_t enable)
874 {
875 	const struct regul_struct *regul = get_regulator_data(name);
876 
877 	if (!regul->low_power_reg)
878 		return -1;
879 
880 	return stpmic1_register_update(regul->low_power_reg, enable,
881 				       LDO_BUCK_ENABLE_MASK);
882 }
883 
884 int stpmic1_lp_on_off_unpg(struct stpmic1_lp_cfg *cfg, int enable)
885 {
886 	assert(cfg->lp_reg && (enable == 0 || enable == 1));
887 
888 	return stpmic1_register_update(cfg->lp_reg, enable,
889 				       LDO_BUCK_ENABLE_MASK);
890 }
891 
892 int stpmic1_lp_set_mode(const char *name, uint8_t hplp)
893 {
894 	const struct regul_struct *regul = get_regulator_data(name);
895 
896 	assert(regul->low_power_reg && (hplp == 0 || hplp == 1));
897 
898 	return stpmic1_register_update(regul->low_power_reg,
899 				       hplp << LDO_BUCK_HPLP_POS,
900 				       BIT(LDO_BUCK_HPLP_POS));
901 }
902 
903 int stpmic1_lp_mode_unpg(struct stpmic1_lp_cfg *cfg, unsigned int mode)
904 {
905 	assert(cfg->lp_reg && (mode == 0 || mode == 1));
906 	return stpmic1_register_update(cfg->lp_reg,
907 				       mode << LDO_BUCK_HPLP_POS,
908 				       BIT(LDO_BUCK_HPLP_POS));
909 }
910 
911 int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts)
912 {
913 	size_t voltage_index = voltage_to_index(name, millivolts);
914 	const struct regul_struct *regul = get_regulator_data(name);
915 	uint8_t mask = 0;
916 
917 	assert(voltage_index != VOLTAGE_INDEX_INVALID);
918 
919 	mask = find_plat_mask(name);
920 	if (!mask)
921 		return 0;
922 
923 	return stpmic1_register_update(regul->low_power_reg, voltage_index << 2,
924 				       mask);
925 }
926 
927 /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */
928 int stpmic1_lp_voltage_cfg(const char *name, uint16_t millivolts,
929 			   struct stpmic1_lp_cfg *cfg)
930 
931 {
932 	size_t voltage_index = voltage_to_index(name, millivolts);
933 	uint8_t mask = 0;
934 
935 	mask = find_plat_mask(name);
936 	if (!mask)
937 		return 1;
938 
939 	assert(voltage_index != VOLTAGE_INDEX_INVALID &&
940 	       cfg->lp_reg == get_regulator_data(name)->low_power_reg);
941 
942 	cfg->value = voltage_index << 2;
943 	cfg->mask = mask;
944 
945 	return 0;
946 }
947 
948 int stpmic1_lp_voltage_unpg(struct stpmic1_lp_cfg *cfg)
949 {
950 	assert(cfg->lp_reg);
951 
952 	return stpmic1_register_update(cfg->lp_reg, cfg->value,	cfg->mask);
953 }
954 
955 int stpmic1_register_read(uint8_t register_id,  uint8_t *value)
956 {
957 	struct i2c_handle_s *i2c = pmic_i2c_handle;
958 
959 	return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
960 					    register_id, value,
961 					    false /* !write */);
962 }
963 
964 int stpmic1_register_write(uint8_t register_id, uint8_t value)
965 {
966 	struct i2c_handle_s *i2c = pmic_i2c_handle;
967 	uint8_t val = value;
968 
969 	return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
970 					    register_id, &val,
971 					    true /* write */);
972 }
973 
974 int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
975 {
976 	int status = 0;
977 	uint8_t val = 0;
978 
979 	status = stpmic1_register_read(register_id, &val);
980 	if (status)
981 		return status;
982 
983 	val = (val & ~mask) | (value & mask);
984 
985 	return stpmic1_register_write(register_id, val);
986 }
987 
988 void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
989 {
990 	pmic_i2c_handle = i2c_handle;
991 	pmic_i2c_addr = i2c_addr;
992 }
993 
994 void stpmic1_dump_regulators(void)
995 {
996 	size_t i = 0;
997 	char __maybe_unused const *name = NULL;
998 
999 	for (i = 0; i < ARRAY_SIZE(regulators_table); i++) {
1000 		if (!regulators_table[i].control_reg)
1001 			continue;
1002 
1003 		name = regulators_table[i].dt_node_name;
1004 		DMSG("PMIC regul %s: %sable, %dmV",
1005 		     name, stpmic1_is_regulator_enabled(name) ? "en" : "dis",
1006 		     stpmic1_regulator_voltage_get(name));
1007 	}
1008 }
1009 
1010 int stpmic1_get_version(unsigned long *version)
1011 {
1012 	uint8_t read_val = 0;
1013 
1014 	if (stpmic1_register_read(VERSION_STATUS_REG, &read_val))
1015 		return -1;
1016 
1017 	*version = read_val;
1018 	return 0;
1019 }
1020