1 /*
2  * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <string.h>
8 
9 #include <common/debug.h>
10 #include <drivers/st/stpmic1.h>
11 
12 #define I2C_TIMEOUT_MS		25
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;
22 	uint8_t mask_reset_reg;
23 	uint8_t mask_reset;
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 	500,
349 	0xFFFF, /* VREFDDR */
350 };
351 
352 static const uint16_t ldo5_voltage_table[] = {
353 	1700,
354 	1700,
355 	1700,
356 	1700,
357 	1700,
358 	1700,
359 	1700,
360 	1700,
361 	1700,
362 	1800,
363 	1900,
364 	2000,
365 	2100,
366 	2200,
367 	2300,
368 	2400,
369 	2500,
370 	2600,
371 	2700,
372 	2800,
373 	2900,
374 	3000,
375 	3100,
376 	3200,
377 	3300,
378 	3400,
379 	3500,
380 	3600,
381 	3700,
382 	3800,
383 	3900,
384 };
385 
386 static const uint16_t ldo6_voltage_table[] = {
387 	900,
388 	1000,
389 	1100,
390 	1200,
391 	1300,
392 	1400,
393 	1500,
394 	1600,
395 	1700,
396 	1800,
397 	1900,
398 	2000,
399 	2100,
400 	2200,
401 	2300,
402 	2400,
403 	2500,
404 	2600,
405 	2700,
406 	2800,
407 	2900,
408 	3000,
409 	3100,
410 	3200,
411 	3300,
412 };
413 
414 static const uint16_t ldo4_voltage_table[] = {
415 	3300,
416 };
417 
418 static const uint16_t vref_ddr_voltage_table[] = {
419 	3300,
420 };
421 
422 /* Table of Regulators in PMIC SoC */
423 static const struct regul_struct regulators_table[] = {
424 	{
425 		.dt_node_name	= "buck1",
426 		.voltage_table	= buck1_voltage_table,
427 		.voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
428 		.control_reg	= BUCK1_CONTROL_REG,
429 		.low_power_reg	= BUCK1_PWRCTRL_REG,
430 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
431 		.pull_down	= BUCK1_PULL_DOWN_SHIFT,
432 		.mask_reset_reg	= MASK_RESET_BUCK_REG,
433 		.mask_reset	= BUCK1_MASK_RESET,
434 	},
435 	{
436 		.dt_node_name	= "buck2",
437 		.voltage_table	= buck2_voltage_table,
438 		.voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
439 		.control_reg	= BUCK2_CONTROL_REG,
440 		.low_power_reg	= BUCK2_PWRCTRL_REG,
441 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
442 		.pull_down	= BUCK2_PULL_DOWN_SHIFT,
443 		.mask_reset_reg	= MASK_RESET_BUCK_REG,
444 		.mask_reset	= BUCK2_MASK_RESET,
445 	},
446 	{
447 		.dt_node_name	= "buck3",
448 		.voltage_table	= buck3_voltage_table,
449 		.voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
450 		.control_reg	= BUCK3_CONTROL_REG,
451 		.low_power_reg	= BUCK3_PWRCTRL_REG,
452 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
453 		.pull_down	= BUCK3_PULL_DOWN_SHIFT,
454 		.mask_reset_reg	= MASK_RESET_BUCK_REG,
455 		.mask_reset	= BUCK3_MASK_RESET,
456 	},
457 	{
458 		.dt_node_name	= "buck4",
459 		.voltage_table	= buck4_voltage_table,
460 		.voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
461 		.control_reg	= BUCK4_CONTROL_REG,
462 		.low_power_reg	= BUCK4_PWRCTRL_REG,
463 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
464 		.pull_down	= BUCK4_PULL_DOWN_SHIFT,
465 		.mask_reset_reg	= MASK_RESET_BUCK_REG,
466 		.mask_reset	= BUCK4_MASK_RESET,
467 	},
468 	{
469 		.dt_node_name	= "ldo1",
470 		.voltage_table	= ldo1_voltage_table,
471 		.voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
472 		.control_reg	= LDO1_CONTROL_REG,
473 		.low_power_reg	= LDO1_PWRCTRL_REG,
474 		.mask_reset_reg	= MASK_RESET_LDO_REG,
475 		.mask_reset	= LDO1_MASK_RESET,
476 	},
477 	{
478 		.dt_node_name	= "ldo2",
479 		.voltage_table	= ldo2_voltage_table,
480 		.voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
481 		.control_reg	= LDO2_CONTROL_REG,
482 		.low_power_reg	= LDO2_PWRCTRL_REG,
483 		.mask_reset_reg	= MASK_RESET_LDO_REG,
484 		.mask_reset	= LDO2_MASK_RESET,
485 	},
486 	{
487 		.dt_node_name	= "ldo3",
488 		.voltage_table	= ldo3_voltage_table,
489 		.voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
490 		.control_reg	= LDO3_CONTROL_REG,
491 		.low_power_reg	= LDO3_PWRCTRL_REG,
492 		.mask_reset_reg	= MASK_RESET_LDO_REG,
493 		.mask_reset	= LDO3_MASK_RESET,
494 	},
495 	{
496 		.dt_node_name	= "ldo4",
497 		.voltage_table	= ldo4_voltage_table,
498 		.voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
499 		.control_reg	= LDO4_CONTROL_REG,
500 		.low_power_reg	= LDO4_PWRCTRL_REG,
501 		.mask_reset_reg	= MASK_RESET_LDO_REG,
502 		.mask_reset	= LDO4_MASK_RESET,
503 	},
504 	{
505 		.dt_node_name	= "ldo5",
506 		.voltage_table	= ldo5_voltage_table,
507 		.voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
508 		.control_reg	= LDO5_CONTROL_REG,
509 		.low_power_reg	= LDO5_PWRCTRL_REG,
510 		.mask_reset_reg	= MASK_RESET_LDO_REG,
511 		.mask_reset	= LDO5_MASK_RESET,
512 	},
513 	{
514 		.dt_node_name	= "ldo6",
515 		.voltage_table	= ldo6_voltage_table,
516 		.voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
517 		.control_reg	= LDO6_CONTROL_REG,
518 		.low_power_reg	= LDO6_PWRCTRL_REG,
519 		.mask_reset_reg	= MASK_RESET_LDO_REG,
520 		.mask_reset	= LDO6_MASK_RESET,
521 	},
522 	{
523 		.dt_node_name	= "vref_ddr",
524 		.voltage_table	= vref_ddr_voltage_table,
525 		.voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
526 		.control_reg	= VREF_DDR_CONTROL_REG,
527 		.low_power_reg	= VREF_DDR_PWRCTRL_REG,
528 		.mask_reset_reg	= MASK_RESET_LDO_REG,
529 		.mask_reset	= VREF_DDR_MASK_RESET,
530 	},
531 };
532 
533 #define MAX_REGUL	ARRAY_SIZE(regulators_table)
534 
get_regulator_data(const char * name)535 static const struct regul_struct *get_regulator_data(const char *name)
536 {
537 	uint8_t i;
538 
539 	for (i = 0 ; i < MAX_REGUL ; i++) {
540 		if (strncmp(name, regulators_table[i].dt_node_name,
541 			    strlen(regulators_table[i].dt_node_name)) == 0) {
542 			return &regulators_table[i];
543 		}
544 	}
545 
546 	/* Regulator not found */
547 	panic();
548 	return NULL;
549 }
550 
voltage_to_index(const char * name,uint16_t millivolts)551 static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
552 {
553 	const struct regul_struct *regul = get_regulator_data(name);
554 	uint8_t i;
555 
556 	for (i = 0 ; i < regul->voltage_table_size ; i++) {
557 		if (regul->voltage_table[i] == millivolts) {
558 			return i;
559 		}
560 	}
561 
562 	/* Voltage not found */
563 	panic();
564 
565 	return 0;
566 }
567 
stpmic1_powerctrl_on(void)568 int stpmic1_powerctrl_on(void)
569 {
570 	return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
571 				       PWRCTRL_PIN_VALID);
572 }
573 
stpmic1_switch_off(void)574 int stpmic1_switch_off(void)
575 {
576 	return stpmic1_register_update(MAIN_CONTROL_REG, 1,
577 				       SOFTWARE_SWITCH_OFF_ENABLED);
578 }
579 
stpmic1_regulator_enable(const char * name)580 int stpmic1_regulator_enable(const char *name)
581 {
582 	const struct regul_struct *regul = get_regulator_data(name);
583 
584 	return stpmic1_register_update(regul->control_reg, BIT(0), BIT(0));
585 }
586 
stpmic1_regulator_disable(const char * name)587 int stpmic1_regulator_disable(const char *name)
588 {
589 	const struct regul_struct *regul = get_regulator_data(name);
590 
591 	return stpmic1_register_update(regul->control_reg, 0, BIT(0));
592 }
593 
stpmic1_is_regulator_enabled(const char * name)594 uint8_t stpmic1_is_regulator_enabled(const char *name)
595 {
596 	uint8_t val;
597 	const struct regul_struct *regul = get_regulator_data(name);
598 
599 	if (stpmic1_register_read(regul->control_reg, &val) != 0) {
600 		panic();
601 	}
602 
603 	return (val & 0x1U);
604 }
605 
stpmic1_regulator_voltage_set(const char * name,uint16_t millivolts)606 int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
607 {
608 	uint8_t voltage_index = voltage_to_index(name, millivolts);
609 	const struct regul_struct *regul = get_regulator_data(name);
610 	uint8_t mask;
611 
612 	/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
613 	if (strncmp(name, "buck", 4) == 0) {
614 		mask = BUCK_VOLTAGE_MASK;
615 	} else if ((strncmp(name, "ldo", 3) == 0) &&
616 		   (strncmp(name, "ldo4", 4) != 0)) {
617 		mask = LDO_VOLTAGE_MASK;
618 	} else {
619 		return 0;
620 	}
621 
622 	return stpmic1_register_update(regul->control_reg,
623 				       voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
624 				       mask);
625 }
626 
stpmic1_regulator_pull_down_set(const char * name)627 int stpmic1_regulator_pull_down_set(const char *name)
628 {
629 	const struct regul_struct *regul = get_regulator_data(name);
630 
631 	if (regul->pull_down_reg != 0) {
632 		return stpmic1_register_update(regul->pull_down_reg,
633 					       BIT(regul->pull_down),
634 					       LDO_BUCK_PULL_DOWN_MASK <<
635 					       regul->pull_down);
636 	}
637 
638 	return 0;
639 }
640 
stpmic1_regulator_mask_reset_set(const char * name)641 int stpmic1_regulator_mask_reset_set(const char *name)
642 {
643 	const struct regul_struct *regul = get_regulator_data(name);
644 
645 	return stpmic1_register_update(regul->mask_reset_reg,
646 				       BIT(regul->mask_reset),
647 				       LDO_BUCK_RESET_MASK <<
648 				       regul->mask_reset);
649 }
650 
stpmic1_regulator_voltage_get(const char * name)651 int stpmic1_regulator_voltage_get(const char *name)
652 {
653 	const struct regul_struct *regul = get_regulator_data(name);
654 	uint8_t value;
655 	uint8_t mask;
656 
657 	/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
658 	if (strncmp(name, "buck", 4) == 0) {
659 		mask = BUCK_VOLTAGE_MASK;
660 	} else if ((strncmp(name, "ldo", 3) == 0) &&
661 		   (strncmp(name, "ldo4", 4) != 0)) {
662 		mask = LDO_VOLTAGE_MASK;
663 	} else {
664 		return 0;
665 	}
666 
667 	if (stpmic1_register_read(regul->control_reg, &value))
668 		return -1;
669 
670 	value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
671 
672 	if (value > regul->voltage_table_size)
673 		return -1;
674 
675 	return (int)regul->voltage_table[value];
676 }
677 
stpmic1_register_read(uint8_t register_id,uint8_t * value)678 int stpmic1_register_read(uint8_t register_id,  uint8_t *value)
679 {
680 	return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr,
681 				  (uint16_t)register_id,
682 				  I2C_MEMADD_SIZE_8BIT, value,
683 				  1, I2C_TIMEOUT_MS);
684 }
685 
stpmic1_register_write(uint8_t register_id,uint8_t value)686 int stpmic1_register_write(uint8_t register_id, uint8_t value)
687 {
688 	int status;
689 
690 	status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr,
691 				     (uint16_t)register_id,
692 				     I2C_MEMADD_SIZE_8BIT, &value,
693 				     1, I2C_TIMEOUT_MS);
694 
695 #if ENABLE_ASSERTIONS
696 	if (status != 0) {
697 		return status;
698 	}
699 
700 	if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
701 		uint8_t readval;
702 
703 		status = stpmic1_register_read(register_id, &readval);
704 		if (status != 0) {
705 			return status;
706 		}
707 
708 		if (readval != value) {
709 			return -1;
710 		}
711 	}
712 #endif
713 
714 	return status;
715 }
716 
stpmic1_register_update(uint8_t register_id,uint8_t value,uint8_t mask)717 int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
718 {
719 	int status;
720 	uint8_t val;
721 
722 	status = stpmic1_register_read(register_id, &val);
723 	if (status != 0) {
724 		return status;
725 	}
726 
727 	val = (val & ~mask) | (value & mask);
728 
729 	return stpmic1_register_write(register_id, val);
730 }
731 
stpmic1_bind_i2c(struct i2c_handle_s * i2c_handle,uint16_t i2c_addr)732 void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
733 {
734 	pmic_i2c_handle = i2c_handle;
735 	pmic_i2c_addr = i2c_addr;
736 }
737 
stpmic1_dump_regulators(void)738 void stpmic1_dump_regulators(void)
739 {
740 	uint32_t i;
741 
742 	for (i = 0U; i < MAX_REGUL; i++) {
743 		const char *name __unused = regulators_table[i].dt_node_name;
744 
745 		VERBOSE("PMIC regul %s: %sable, %dmV",
746 			name,
747 			stpmic1_is_regulator_enabled(name) ? "en" : "dis",
748 			stpmic1_regulator_voltage_get(name));
749 	}
750 }
751 
stpmic1_get_version(unsigned long * version)752 int stpmic1_get_version(unsigned long *version)
753 {
754 	int rc;
755 	uint8_t read_val;
756 
757 	rc = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
758 	if (rc) {
759 		return -1;
760 	}
761 
762 	*version = (unsigned long)read_val;
763 
764 	return 0;
765 }
766