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