xref: /rk3399_ARM-atf/drivers/st/pmic/stpmic1.c (revision 077f6828539b5f9ac24c6f272dfffeaae5a30bba)
123684d0eSYann Gautier /*
223684d0eSYann Gautier  * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
323684d0eSYann Gautier  *
423684d0eSYann Gautier  * SPDX-License-Identifier: BSD-3-Clause
523684d0eSYann Gautier  */
623684d0eSYann Gautier 
723684d0eSYann Gautier #include <string.h>
823684d0eSYann Gautier 
923684d0eSYann Gautier #include <common/debug.h>
1023684d0eSYann Gautier #include <drivers/st/stpmic1.h>
1123684d0eSYann Gautier #include <plat/common/platform.h>
1223684d0eSYann Gautier 
1323684d0eSYann Gautier struct regul_struct {
1423684d0eSYann Gautier 	const char *dt_node_name;
1523684d0eSYann Gautier 	const uint16_t *voltage_table;
1623684d0eSYann Gautier 	uint8_t voltage_table_size;
1723684d0eSYann Gautier 	uint8_t control_reg;
1823684d0eSYann Gautier 	uint8_t low_power_reg;
19*077f6828SYann Gautier 	uint8_t pull_down_reg;
20*077f6828SYann Gautier 	uint8_t pull_down;
21*077f6828SYann Gautier 	uint8_t mask_reset_reg;
22*077f6828SYann Gautier 	uint8_t mask_reset;
2323684d0eSYann Gautier };
2423684d0eSYann Gautier 
2523684d0eSYann Gautier static struct i2c_handle_s *pmic_i2c_handle;
2623684d0eSYann Gautier static uint16_t pmic_i2c_addr;
2723684d0eSYann Gautier 
2823684d0eSYann Gautier /* Voltage tables in mV */
2923684d0eSYann Gautier static const uint16_t buck1_voltage_table[] = {
30*077f6828SYann Gautier 	725,
31*077f6828SYann Gautier 	725,
32*077f6828SYann Gautier 	725,
33*077f6828SYann Gautier 	725,
34*077f6828SYann Gautier 	725,
3523684d0eSYann Gautier 	725,
3623684d0eSYann Gautier 	750,
3723684d0eSYann Gautier 	775,
3823684d0eSYann Gautier 	800,
3923684d0eSYann Gautier 	825,
4023684d0eSYann Gautier 	850,
4123684d0eSYann Gautier 	875,
4223684d0eSYann Gautier 	900,
4323684d0eSYann Gautier 	925,
4423684d0eSYann Gautier 	950,
4523684d0eSYann Gautier 	975,
4623684d0eSYann Gautier 	1000,
4723684d0eSYann Gautier 	1025,
4823684d0eSYann Gautier 	1050,
4923684d0eSYann Gautier 	1075,
5023684d0eSYann Gautier 	1100,
5123684d0eSYann Gautier 	1125,
5223684d0eSYann Gautier 	1150,
5323684d0eSYann Gautier 	1175,
5423684d0eSYann Gautier 	1200,
5523684d0eSYann Gautier 	1225,
5623684d0eSYann Gautier 	1250,
5723684d0eSYann Gautier 	1275,
5823684d0eSYann Gautier 	1300,
5923684d0eSYann Gautier 	1325,
6023684d0eSYann Gautier 	1350,
61*077f6828SYann Gautier 	1375,
62*077f6828SYann Gautier 	1400,
63*077f6828SYann Gautier 	1425,
64*077f6828SYann Gautier 	1450,
65*077f6828SYann Gautier 	1475,
66*077f6828SYann Gautier 	1500,
67*077f6828SYann Gautier 	1500,
68*077f6828SYann Gautier 	1500,
69*077f6828SYann Gautier 	1500,
70*077f6828SYann Gautier 	1500,
71*077f6828SYann Gautier 	1500,
72*077f6828SYann Gautier 	1500,
73*077f6828SYann Gautier 	1500,
74*077f6828SYann Gautier 	1500,
75*077f6828SYann Gautier 	1500,
76*077f6828SYann Gautier 	1500,
77*077f6828SYann Gautier 	1500,
78*077f6828SYann Gautier 	1500,
79*077f6828SYann Gautier 	1500,
80*077f6828SYann Gautier 	1500,
81*077f6828SYann Gautier 	1500,
82*077f6828SYann Gautier 	1500,
83*077f6828SYann Gautier 	1500,
84*077f6828SYann Gautier 	1500,
85*077f6828SYann Gautier 	1500,
86*077f6828SYann Gautier 	1500,
87*077f6828SYann Gautier 	1500,
88*077f6828SYann Gautier 	1500,
89*077f6828SYann Gautier 	1500,
90*077f6828SYann Gautier 	1500,
91*077f6828SYann Gautier 	1500,
92*077f6828SYann Gautier 	1500,
93*077f6828SYann Gautier 	1500,
9423684d0eSYann Gautier };
9523684d0eSYann Gautier 
9623684d0eSYann Gautier static const uint16_t buck2_voltage_table[] = {
9723684d0eSYann Gautier 	1000,
9823684d0eSYann Gautier 	1000,
9923684d0eSYann Gautier 	1000,
10023684d0eSYann Gautier 	1000,
10123684d0eSYann Gautier 	1000,
10223684d0eSYann Gautier 	1000,
10323684d0eSYann Gautier 	1000,
10423684d0eSYann Gautier 	1000,
10523684d0eSYann Gautier 	1000,
10623684d0eSYann Gautier 	1000,
10723684d0eSYann Gautier 	1000,
10823684d0eSYann Gautier 	1000,
10923684d0eSYann Gautier 	1000,
11023684d0eSYann Gautier 	1000,
11123684d0eSYann Gautier 	1000,
11223684d0eSYann Gautier 	1000,
11323684d0eSYann Gautier 	1000,
11423684d0eSYann Gautier 	1000,
11523684d0eSYann Gautier 	1050,
11623684d0eSYann Gautier 	1050,
11723684d0eSYann Gautier 	1100,
11823684d0eSYann Gautier 	1100,
11923684d0eSYann Gautier 	1150,
12023684d0eSYann Gautier 	1150,
12123684d0eSYann Gautier 	1200,
12223684d0eSYann Gautier 	1200,
12323684d0eSYann Gautier 	1250,
12423684d0eSYann Gautier 	1250,
12523684d0eSYann Gautier 	1300,
12623684d0eSYann Gautier 	1300,
12723684d0eSYann Gautier 	1350,
12823684d0eSYann Gautier 	1350,
12923684d0eSYann Gautier 	1400,
13023684d0eSYann Gautier 	1400,
13123684d0eSYann Gautier 	1450,
13223684d0eSYann Gautier 	1450,
13323684d0eSYann Gautier 	1500,
13423684d0eSYann Gautier };
13523684d0eSYann Gautier 
13623684d0eSYann Gautier static const uint16_t buck3_voltage_table[] = {
13723684d0eSYann Gautier 	1000,
13823684d0eSYann Gautier 	1000,
13923684d0eSYann Gautier 	1000,
14023684d0eSYann Gautier 	1000,
14123684d0eSYann Gautier 	1000,
14223684d0eSYann Gautier 	1000,
14323684d0eSYann Gautier 	1000,
14423684d0eSYann Gautier 	1000,
14523684d0eSYann Gautier 	1000,
14623684d0eSYann Gautier 	1000,
14723684d0eSYann Gautier 	1000,
14823684d0eSYann Gautier 	1000,
14923684d0eSYann Gautier 	1000,
15023684d0eSYann Gautier 	1000,
15123684d0eSYann Gautier 	1000,
15223684d0eSYann Gautier 	1000,
15323684d0eSYann Gautier 	1000,
15423684d0eSYann Gautier 	1000,
15523684d0eSYann Gautier 	1000,
15623684d0eSYann Gautier 	1000,
15723684d0eSYann Gautier 	1100,
15823684d0eSYann Gautier 	1100,
15923684d0eSYann Gautier 	1100,
16023684d0eSYann Gautier 	1100,
16123684d0eSYann Gautier 	1200,
16223684d0eSYann Gautier 	1200,
16323684d0eSYann Gautier 	1200,
16423684d0eSYann Gautier 	1200,
16523684d0eSYann Gautier 	1300,
16623684d0eSYann Gautier 	1300,
16723684d0eSYann Gautier 	1300,
16823684d0eSYann Gautier 	1300,
16923684d0eSYann Gautier 	1400,
17023684d0eSYann Gautier 	1400,
17123684d0eSYann Gautier 	1400,
17223684d0eSYann Gautier 	1400,
17323684d0eSYann Gautier 	1500,
17423684d0eSYann Gautier 	1600,
17523684d0eSYann Gautier 	1700,
17623684d0eSYann Gautier 	1800,
17723684d0eSYann Gautier 	1900,
17823684d0eSYann Gautier 	2000,
17923684d0eSYann Gautier 	2100,
18023684d0eSYann Gautier 	2200,
18123684d0eSYann Gautier 	2300,
18223684d0eSYann Gautier 	2400,
18323684d0eSYann Gautier 	2500,
18423684d0eSYann Gautier 	2600,
18523684d0eSYann Gautier 	2700,
18623684d0eSYann Gautier 	2800,
18723684d0eSYann Gautier 	2900,
18823684d0eSYann Gautier 	3000,
18923684d0eSYann Gautier 	3100,
19023684d0eSYann Gautier 	3200,
19123684d0eSYann Gautier 	3300,
19223684d0eSYann Gautier 	3400,
19323684d0eSYann Gautier };
19423684d0eSYann Gautier 
19523684d0eSYann Gautier static const uint16_t buck4_voltage_table[] = {
19623684d0eSYann Gautier 	600,
19723684d0eSYann Gautier 	625,
19823684d0eSYann Gautier 	650,
19923684d0eSYann Gautier 	675,
20023684d0eSYann Gautier 	700,
20123684d0eSYann Gautier 	725,
20223684d0eSYann Gautier 	750,
20323684d0eSYann Gautier 	775,
20423684d0eSYann Gautier 	800,
20523684d0eSYann Gautier 	825,
20623684d0eSYann Gautier 	850,
20723684d0eSYann Gautier 	875,
20823684d0eSYann Gautier 	900,
20923684d0eSYann Gautier 	925,
21023684d0eSYann Gautier 	950,
21123684d0eSYann Gautier 	975,
21223684d0eSYann Gautier 	1000,
21323684d0eSYann Gautier 	1025,
21423684d0eSYann Gautier 	1050,
21523684d0eSYann Gautier 	1075,
21623684d0eSYann Gautier 	1100,
21723684d0eSYann Gautier 	1125,
21823684d0eSYann Gautier 	1150,
21923684d0eSYann Gautier 	1175,
22023684d0eSYann Gautier 	1200,
22123684d0eSYann Gautier 	1225,
22223684d0eSYann Gautier 	1250,
22323684d0eSYann Gautier 	1275,
22423684d0eSYann Gautier 	1300,
22523684d0eSYann Gautier 	1300,
22623684d0eSYann Gautier 	1350,
22723684d0eSYann Gautier 	1350,
22823684d0eSYann Gautier 	1400,
22923684d0eSYann Gautier 	1400,
23023684d0eSYann Gautier 	1450,
23123684d0eSYann Gautier 	1450,
23223684d0eSYann Gautier 	1500,
23323684d0eSYann Gautier 	1600,
23423684d0eSYann Gautier 	1700,
23523684d0eSYann Gautier 	1800,
23623684d0eSYann Gautier 	1900,
23723684d0eSYann Gautier 	2000,
23823684d0eSYann Gautier 	2100,
23923684d0eSYann Gautier 	2200,
24023684d0eSYann Gautier 	2300,
24123684d0eSYann Gautier 	2400,
24223684d0eSYann Gautier 	2500,
24323684d0eSYann Gautier 	2600,
24423684d0eSYann Gautier 	2700,
24523684d0eSYann Gautier 	2800,
24623684d0eSYann Gautier 	2900,
24723684d0eSYann Gautier 	3000,
24823684d0eSYann Gautier 	3100,
24923684d0eSYann Gautier 	3200,
25023684d0eSYann Gautier 	3300,
25123684d0eSYann Gautier 	3400,
25223684d0eSYann Gautier 	3500,
25323684d0eSYann Gautier 	3600,
25423684d0eSYann Gautier 	3700,
25523684d0eSYann Gautier 	3800,
25623684d0eSYann Gautier 	3900,
25723684d0eSYann Gautier };
25823684d0eSYann Gautier 
25923684d0eSYann Gautier static const uint16_t ldo1_voltage_table[] = {
26023684d0eSYann Gautier 	1700,
26123684d0eSYann Gautier 	1700,
26223684d0eSYann Gautier 	1700,
26323684d0eSYann Gautier 	1700,
26423684d0eSYann Gautier 	1700,
26523684d0eSYann Gautier 	1700,
26623684d0eSYann Gautier 	1700,
26723684d0eSYann Gautier 	1700,
26823684d0eSYann Gautier 	1700,
26923684d0eSYann Gautier 	1800,
27023684d0eSYann Gautier 	1900,
27123684d0eSYann Gautier 	2000,
27223684d0eSYann Gautier 	2100,
27323684d0eSYann Gautier 	2200,
27423684d0eSYann Gautier 	2300,
27523684d0eSYann Gautier 	2400,
27623684d0eSYann Gautier 	2500,
27723684d0eSYann Gautier 	2600,
27823684d0eSYann Gautier 	2700,
27923684d0eSYann Gautier 	2800,
28023684d0eSYann Gautier 	2900,
28123684d0eSYann Gautier 	3000,
28223684d0eSYann Gautier 	3100,
28323684d0eSYann Gautier 	3200,
28423684d0eSYann Gautier 	3300,
28523684d0eSYann Gautier };
28623684d0eSYann Gautier 
28723684d0eSYann Gautier static const uint16_t ldo2_voltage_table[] = {
28823684d0eSYann Gautier 	1700,
28923684d0eSYann Gautier 	1700,
29023684d0eSYann Gautier 	1700,
29123684d0eSYann Gautier 	1700,
29223684d0eSYann Gautier 	1700,
29323684d0eSYann Gautier 	1700,
29423684d0eSYann Gautier 	1700,
29523684d0eSYann Gautier 	1700,
29623684d0eSYann Gautier 	1700,
29723684d0eSYann Gautier 	1800,
29823684d0eSYann Gautier 	1900,
29923684d0eSYann Gautier 	2000,
30023684d0eSYann Gautier 	2100,
30123684d0eSYann Gautier 	2200,
30223684d0eSYann Gautier 	2300,
30323684d0eSYann Gautier 	2400,
30423684d0eSYann Gautier 	2500,
30523684d0eSYann Gautier 	2600,
30623684d0eSYann Gautier 	2700,
30723684d0eSYann Gautier 	2800,
30823684d0eSYann Gautier 	2900,
30923684d0eSYann Gautier 	3000,
31023684d0eSYann Gautier 	3100,
31123684d0eSYann Gautier 	3200,
31223684d0eSYann Gautier 	3300,
31323684d0eSYann Gautier };
31423684d0eSYann Gautier 
31523684d0eSYann Gautier static const uint16_t ldo3_voltage_table[] = {
31623684d0eSYann Gautier 	1700,
31723684d0eSYann Gautier 	1700,
31823684d0eSYann Gautier 	1700,
31923684d0eSYann Gautier 	1700,
32023684d0eSYann Gautier 	1700,
32123684d0eSYann Gautier 	1700,
32223684d0eSYann Gautier 	1700,
32323684d0eSYann Gautier 	1700,
32423684d0eSYann Gautier 	1700,
32523684d0eSYann Gautier 	1800,
32623684d0eSYann Gautier 	1900,
32723684d0eSYann Gautier 	2000,
32823684d0eSYann Gautier 	2100,
32923684d0eSYann Gautier 	2200,
33023684d0eSYann Gautier 	2300,
33123684d0eSYann Gautier 	2400,
33223684d0eSYann Gautier 	2500,
33323684d0eSYann Gautier 	2600,
33423684d0eSYann Gautier 	2700,
33523684d0eSYann Gautier 	2800,
33623684d0eSYann Gautier 	2900,
33723684d0eSYann Gautier 	3000,
33823684d0eSYann Gautier 	3100,
33923684d0eSYann Gautier 	3200,
34023684d0eSYann Gautier 	3300,
34123684d0eSYann Gautier 	3300,
34223684d0eSYann Gautier 	3300,
34323684d0eSYann Gautier 	3300,
34423684d0eSYann Gautier 	3300,
34523684d0eSYann Gautier 	3300,
34623684d0eSYann Gautier 	3300,
347*077f6828SYann Gautier 	500,
34823684d0eSYann Gautier 	0xFFFF, /* VREFDDR */
34923684d0eSYann Gautier };
35023684d0eSYann Gautier 
35123684d0eSYann Gautier static const uint16_t ldo5_voltage_table[] = {
35223684d0eSYann Gautier 	1700,
35323684d0eSYann Gautier 	1700,
35423684d0eSYann Gautier 	1700,
35523684d0eSYann Gautier 	1700,
35623684d0eSYann Gautier 	1700,
35723684d0eSYann Gautier 	1700,
35823684d0eSYann Gautier 	1700,
35923684d0eSYann Gautier 	1700,
36023684d0eSYann Gautier 	1700,
36123684d0eSYann Gautier 	1800,
36223684d0eSYann Gautier 	1900,
36323684d0eSYann Gautier 	2000,
36423684d0eSYann Gautier 	2100,
36523684d0eSYann Gautier 	2200,
36623684d0eSYann Gautier 	2300,
36723684d0eSYann Gautier 	2400,
36823684d0eSYann Gautier 	2500,
36923684d0eSYann Gautier 	2600,
37023684d0eSYann Gautier 	2700,
37123684d0eSYann Gautier 	2800,
37223684d0eSYann Gautier 	2900,
37323684d0eSYann Gautier 	3000,
37423684d0eSYann Gautier 	3100,
37523684d0eSYann Gautier 	3200,
37623684d0eSYann Gautier 	3300,
37723684d0eSYann Gautier 	3400,
37823684d0eSYann Gautier 	3500,
37923684d0eSYann Gautier 	3600,
38023684d0eSYann Gautier 	3700,
38123684d0eSYann Gautier 	3800,
38223684d0eSYann Gautier 	3900,
38323684d0eSYann Gautier };
38423684d0eSYann Gautier 
38523684d0eSYann Gautier static const uint16_t ldo6_voltage_table[] = {
38623684d0eSYann Gautier 	900,
38723684d0eSYann Gautier 	1000,
38823684d0eSYann Gautier 	1100,
38923684d0eSYann Gautier 	1200,
39023684d0eSYann Gautier 	1300,
39123684d0eSYann Gautier 	1400,
39223684d0eSYann Gautier 	1500,
39323684d0eSYann Gautier 	1600,
39423684d0eSYann Gautier 	1700,
39523684d0eSYann Gautier 	1800,
39623684d0eSYann Gautier 	1900,
39723684d0eSYann Gautier 	2000,
39823684d0eSYann Gautier 	2100,
39923684d0eSYann Gautier 	2200,
40023684d0eSYann Gautier 	2300,
40123684d0eSYann Gautier 	2400,
40223684d0eSYann Gautier 	2500,
40323684d0eSYann Gautier 	2600,
40423684d0eSYann Gautier 	2700,
40523684d0eSYann Gautier 	2800,
40623684d0eSYann Gautier 	2900,
40723684d0eSYann Gautier 	3000,
40823684d0eSYann Gautier 	3100,
40923684d0eSYann Gautier 	3200,
41023684d0eSYann Gautier 	3300,
41123684d0eSYann Gautier };
41223684d0eSYann Gautier 
41323684d0eSYann Gautier static const uint16_t ldo4_voltage_table[] = {
41423684d0eSYann Gautier 	3300,
41523684d0eSYann Gautier };
41623684d0eSYann Gautier 
41723684d0eSYann Gautier static const uint16_t vref_ddr_voltage_table[] = {
41823684d0eSYann Gautier 	3300,
41923684d0eSYann Gautier };
42023684d0eSYann Gautier 
42123684d0eSYann Gautier /* Table of Regulators in PMIC SoC */
42223684d0eSYann Gautier static const struct regul_struct regulators_table[] = {
42323684d0eSYann Gautier 	{
42423684d0eSYann Gautier 		.dt_node_name	= "buck1",
42523684d0eSYann Gautier 		.voltage_table	= buck1_voltage_table,
42623684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
42723684d0eSYann Gautier 		.control_reg	= BUCK1_CONTROL_REG,
42823684d0eSYann Gautier 		.low_power_reg	= BUCK1_PWRCTRL_REG,
429*077f6828SYann Gautier 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
430*077f6828SYann Gautier 		.pull_down	= BUCK1_PULL_DOWN_SHIFT,
431*077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_BUCK_REG,
432*077f6828SYann Gautier 		.mask_reset	= BUCK1_MASK_RESET,
43323684d0eSYann Gautier 	},
43423684d0eSYann Gautier 	{
43523684d0eSYann Gautier 		.dt_node_name	= "buck2",
43623684d0eSYann Gautier 		.voltage_table	= buck2_voltage_table,
43723684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
43823684d0eSYann Gautier 		.control_reg	= BUCK2_CONTROL_REG,
43923684d0eSYann Gautier 		.low_power_reg	= BUCK2_PWRCTRL_REG,
440*077f6828SYann Gautier 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
441*077f6828SYann Gautier 		.pull_down	= BUCK2_PULL_DOWN_SHIFT,
442*077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_BUCK_REG,
443*077f6828SYann Gautier 		.mask_reset	= BUCK2_MASK_RESET,
44423684d0eSYann Gautier 	},
44523684d0eSYann Gautier 	{
44623684d0eSYann Gautier 		.dt_node_name	= "buck3",
44723684d0eSYann Gautier 		.voltage_table	= buck3_voltage_table,
44823684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
44923684d0eSYann Gautier 		.control_reg	= BUCK3_CONTROL_REG,
45023684d0eSYann Gautier 		.low_power_reg	= BUCK3_PWRCTRL_REG,
451*077f6828SYann Gautier 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
452*077f6828SYann Gautier 		.pull_down	= BUCK3_PULL_DOWN_SHIFT,
453*077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_BUCK_REG,
454*077f6828SYann Gautier 		.mask_reset	= BUCK3_MASK_RESET,
45523684d0eSYann Gautier 	},
45623684d0eSYann Gautier 	{
45723684d0eSYann Gautier 		.dt_node_name	= "buck4",
45823684d0eSYann Gautier 		.voltage_table	= buck4_voltage_table,
45923684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
46023684d0eSYann Gautier 		.control_reg	= BUCK4_CONTROL_REG,
46123684d0eSYann Gautier 		.low_power_reg	= BUCK4_PWRCTRL_REG,
462*077f6828SYann Gautier 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
463*077f6828SYann Gautier 		.pull_down	= BUCK4_PULL_DOWN_SHIFT,
464*077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_BUCK_REG,
465*077f6828SYann Gautier 		.mask_reset	= BUCK4_MASK_RESET,
46623684d0eSYann Gautier 	},
46723684d0eSYann Gautier 	{
46823684d0eSYann Gautier 		.dt_node_name	= "ldo1",
46923684d0eSYann Gautier 		.voltage_table	= ldo1_voltage_table,
47023684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
47123684d0eSYann Gautier 		.control_reg	= LDO1_CONTROL_REG,
47223684d0eSYann Gautier 		.low_power_reg	= LDO1_PWRCTRL_REG,
473*077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_LDO_REG,
474*077f6828SYann Gautier 		.mask_reset	= LDO1_MASK_RESET,
47523684d0eSYann Gautier 	},
47623684d0eSYann Gautier 	{
47723684d0eSYann Gautier 		.dt_node_name	= "ldo2",
47823684d0eSYann Gautier 		.voltage_table	= ldo2_voltage_table,
47923684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
48023684d0eSYann Gautier 		.control_reg	= LDO2_CONTROL_REG,
48123684d0eSYann Gautier 		.low_power_reg	= LDO2_PWRCTRL_REG,
482*077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_LDO_REG,
483*077f6828SYann Gautier 		.mask_reset	= LDO2_MASK_RESET,
48423684d0eSYann Gautier 	},
48523684d0eSYann Gautier 	{
48623684d0eSYann Gautier 		.dt_node_name	= "ldo3",
48723684d0eSYann Gautier 		.voltage_table	= ldo3_voltage_table,
48823684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
48923684d0eSYann Gautier 		.control_reg	= LDO3_CONTROL_REG,
49023684d0eSYann Gautier 		.low_power_reg	= LDO3_PWRCTRL_REG,
491*077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_LDO_REG,
492*077f6828SYann Gautier 		.mask_reset	= LDO3_MASK_RESET,
49323684d0eSYann Gautier 	},
49423684d0eSYann Gautier 	{
49523684d0eSYann Gautier 		.dt_node_name	= "ldo4",
49623684d0eSYann Gautier 		.voltage_table	= ldo4_voltage_table,
49723684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
49823684d0eSYann Gautier 		.control_reg	= LDO4_CONTROL_REG,
49923684d0eSYann Gautier 		.low_power_reg	= LDO4_PWRCTRL_REG,
500*077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_LDO_REG,
501*077f6828SYann Gautier 		.mask_reset	= LDO4_MASK_RESET,
50223684d0eSYann Gautier 	},
50323684d0eSYann Gautier 	{
50423684d0eSYann Gautier 		.dt_node_name	= "ldo5",
50523684d0eSYann Gautier 		.voltage_table	= ldo5_voltage_table,
50623684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
50723684d0eSYann Gautier 		.control_reg	= LDO5_CONTROL_REG,
50823684d0eSYann Gautier 		.low_power_reg	= LDO5_PWRCTRL_REG,
509*077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_LDO_REG,
510*077f6828SYann Gautier 		.mask_reset	= LDO5_MASK_RESET,
51123684d0eSYann Gautier 	},
51223684d0eSYann Gautier 	{
51323684d0eSYann Gautier 		.dt_node_name	= "ldo6",
51423684d0eSYann Gautier 		.voltage_table	= ldo6_voltage_table,
51523684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
51623684d0eSYann Gautier 		.control_reg	= LDO6_CONTROL_REG,
51723684d0eSYann Gautier 		.low_power_reg	= LDO6_PWRCTRL_REG,
518*077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_LDO_REG,
519*077f6828SYann Gautier 		.mask_reset	= LDO6_MASK_RESET,
52023684d0eSYann Gautier 	},
52123684d0eSYann Gautier 	{
52223684d0eSYann Gautier 		.dt_node_name	= "vref_ddr",
52323684d0eSYann Gautier 		.voltage_table	= vref_ddr_voltage_table,
52423684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
52523684d0eSYann Gautier 		.control_reg	= VREF_DDR_CONTROL_REG,
52623684d0eSYann Gautier 		.low_power_reg	= VREF_DDR_PWRCTRL_REG,
527*077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_LDO_REG,
528*077f6828SYann Gautier 		.mask_reset	= VREF_DDR_MASK_RESET,
52923684d0eSYann Gautier 	},
53023684d0eSYann Gautier };
53123684d0eSYann Gautier 
53223684d0eSYann Gautier #define MAX_REGUL	ARRAY_SIZE(regulators_table)
53323684d0eSYann Gautier 
53423684d0eSYann Gautier static const struct regul_struct *get_regulator_data(const char *name)
53523684d0eSYann Gautier {
53623684d0eSYann Gautier 	uint8_t i;
53723684d0eSYann Gautier 
53823684d0eSYann Gautier 	for (i = 0 ; i < MAX_REGUL ; i++) {
53923684d0eSYann Gautier 		if (strncmp(name, regulators_table[i].dt_node_name,
54023684d0eSYann Gautier 			    strlen(regulators_table[i].dt_node_name)) == 0) {
54123684d0eSYann Gautier 			return &regulators_table[i];
54223684d0eSYann Gautier 		}
54323684d0eSYann Gautier 	}
54423684d0eSYann Gautier 
54523684d0eSYann Gautier 	/* Regulator not found */
54623684d0eSYann Gautier 	panic();
54723684d0eSYann Gautier 	return NULL;
54823684d0eSYann Gautier }
54923684d0eSYann Gautier 
55023684d0eSYann Gautier static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
55123684d0eSYann Gautier {
55223684d0eSYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
55323684d0eSYann Gautier 	uint8_t i;
55423684d0eSYann Gautier 
55523684d0eSYann Gautier 	for (i = 0 ; i < regul->voltage_table_size ; i++) {
55623684d0eSYann Gautier 		if (regul->voltage_table[i] == millivolts) {
55723684d0eSYann Gautier 			return i;
55823684d0eSYann Gautier 		}
55923684d0eSYann Gautier 	}
56023684d0eSYann Gautier 
56123684d0eSYann Gautier 	/* Voltage not found */
56223684d0eSYann Gautier 	panic();
56323684d0eSYann Gautier 
56423684d0eSYann Gautier 	return 0;
56523684d0eSYann Gautier }
56623684d0eSYann Gautier 
567*077f6828SYann Gautier int stpmic1_powerctrl_on(void)
568*077f6828SYann Gautier {
569*077f6828SYann Gautier 	return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
570*077f6828SYann Gautier 				       PWRCTRL_PIN_VALID);
571*077f6828SYann Gautier }
572*077f6828SYann Gautier 
57323684d0eSYann Gautier int stpmic1_switch_off(void)
57423684d0eSYann Gautier {
57523684d0eSYann Gautier 	return stpmic1_register_update(MAIN_CONTROL_REG, 1,
57623684d0eSYann Gautier 				       SOFTWARE_SWITCH_OFF_ENABLED);
57723684d0eSYann Gautier }
57823684d0eSYann Gautier 
57923684d0eSYann Gautier int stpmic1_regulator_enable(const char *name)
58023684d0eSYann Gautier {
58123684d0eSYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
58223684d0eSYann Gautier 
58323684d0eSYann Gautier 	return stpmic1_register_update(regul->control_reg, BIT(0), BIT(0));
58423684d0eSYann Gautier }
58523684d0eSYann Gautier 
58623684d0eSYann Gautier int stpmic1_regulator_disable(const char *name)
58723684d0eSYann Gautier {
58823684d0eSYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
58923684d0eSYann Gautier 
59023684d0eSYann Gautier 	return stpmic1_register_update(regul->control_reg, 0, BIT(0));
59123684d0eSYann Gautier }
59223684d0eSYann Gautier 
59323684d0eSYann Gautier uint8_t stpmic1_is_regulator_enabled(const char *name)
59423684d0eSYann Gautier {
59523684d0eSYann Gautier 	uint8_t val;
59623684d0eSYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
59723684d0eSYann Gautier 
59823684d0eSYann Gautier 	if (stpmic1_register_read(regul->control_reg, &val) != 0) {
59923684d0eSYann Gautier 		panic();
60023684d0eSYann Gautier 	}
60123684d0eSYann Gautier 
60223684d0eSYann Gautier 	return (val & 0x1U);
60323684d0eSYann Gautier }
60423684d0eSYann Gautier 
60523684d0eSYann Gautier int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
60623684d0eSYann Gautier {
60723684d0eSYann Gautier 	uint8_t voltage_index = voltage_to_index(name, millivolts);
60823684d0eSYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
609*077f6828SYann Gautier 	uint8_t mask;
61023684d0eSYann Gautier 
611*077f6828SYann Gautier 	/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
612*077f6828SYann Gautier 	if (strncmp(name, "buck", 4) == 0) {
613*077f6828SYann Gautier 		mask = BUCK_VOLTAGE_MASK;
614*077f6828SYann Gautier 	} else if ((strncmp(name, "ldo", 3) == 0) &&
615*077f6828SYann Gautier 		   (strncmp(name, "ldo4", 4) != 0)) {
616*077f6828SYann Gautier 		mask = LDO_VOLTAGE_MASK;
617*077f6828SYann Gautier 	} else {
618*077f6828SYann Gautier 		return 0;
619*077f6828SYann Gautier 	}
620*077f6828SYann Gautier 
621*077f6828SYann Gautier 	return stpmic1_register_update(regul->control_reg,
622*077f6828SYann Gautier 				       voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
623*077f6828SYann Gautier 				       mask);
624*077f6828SYann Gautier }
625*077f6828SYann Gautier 
626*077f6828SYann Gautier int stpmic1_regulator_pull_down_set(const char *name)
627*077f6828SYann Gautier {
628*077f6828SYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
629*077f6828SYann Gautier 
630*077f6828SYann Gautier 	if (regul->pull_down_reg != 0) {
631*077f6828SYann Gautier 		return stpmic1_register_update(regul->pull_down_reg,
632*077f6828SYann Gautier 					       BIT(regul->pull_down),
633*077f6828SYann Gautier 					       LDO_BUCK_PULL_DOWN_MASK <<
634*077f6828SYann Gautier 					       regul->pull_down);
635*077f6828SYann Gautier 	}
636*077f6828SYann Gautier 
637*077f6828SYann Gautier 	return 0;
638*077f6828SYann Gautier }
639*077f6828SYann Gautier 
640*077f6828SYann Gautier int stpmic1_regulator_mask_reset_set(const char *name)
641*077f6828SYann Gautier {
642*077f6828SYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
643*077f6828SYann Gautier 
644*077f6828SYann Gautier 	return stpmic1_register_update(regul->mask_reset_reg,
645*077f6828SYann Gautier 				       BIT(regul->mask_reset),
646*077f6828SYann Gautier 				       LDO_BUCK_RESET_MASK <<
647*077f6828SYann Gautier 				       regul->mask_reset);
648*077f6828SYann Gautier }
649*077f6828SYann Gautier 
650*077f6828SYann Gautier int stpmic1_regulator_voltage_get(const char *name)
651*077f6828SYann Gautier {
652*077f6828SYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
653*077f6828SYann Gautier 	uint8_t value;
654*077f6828SYann Gautier 	uint8_t mask;
655*077f6828SYann Gautier 
656*077f6828SYann Gautier 	/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
657*077f6828SYann Gautier 	if (strncmp(name, "buck", 4) == 0) {
658*077f6828SYann Gautier 		mask = BUCK_VOLTAGE_MASK;
659*077f6828SYann Gautier 	} else if ((strncmp(name, "ldo", 3) == 0) &&
660*077f6828SYann Gautier 		   (strncmp(name, "ldo4", 4) != 0)) {
661*077f6828SYann Gautier 		mask = LDO_VOLTAGE_MASK;
662*077f6828SYann Gautier 	} else {
663*077f6828SYann Gautier 		return 0;
664*077f6828SYann Gautier 	}
665*077f6828SYann Gautier 
666*077f6828SYann Gautier 	if (stpmic1_register_read(regul->control_reg, &value))
667*077f6828SYann Gautier 		return -1;
668*077f6828SYann Gautier 
669*077f6828SYann Gautier 	value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
670*077f6828SYann Gautier 
671*077f6828SYann Gautier 	if (value > regul->voltage_table_size)
672*077f6828SYann Gautier 		return -1;
673*077f6828SYann Gautier 
674*077f6828SYann Gautier 	return (int)regul->voltage_table[value];
67523684d0eSYann Gautier }
67623684d0eSYann Gautier 
67723684d0eSYann Gautier int stpmic1_register_read(uint8_t register_id,  uint8_t *value)
67823684d0eSYann Gautier {
67923684d0eSYann Gautier 	return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr,
68023684d0eSYann Gautier 				  (uint16_t)register_id, I2C_MEMADD_SIZE_8BIT,
68123684d0eSYann Gautier 				  value, 1, 100000);
68223684d0eSYann Gautier }
68323684d0eSYann Gautier 
68423684d0eSYann Gautier int stpmic1_register_write(uint8_t register_id, uint8_t value)
68523684d0eSYann Gautier {
68623684d0eSYann Gautier 	int status;
68723684d0eSYann Gautier 
68823684d0eSYann Gautier 	status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr,
68923684d0eSYann Gautier 				     (uint16_t)register_id,
69023684d0eSYann Gautier 				     I2C_MEMADD_SIZE_8BIT, &value, 1, 100000);
69123684d0eSYann Gautier 
692*077f6828SYann Gautier #if ENABLE_ASSERTIONS
69323684d0eSYann Gautier 	if (status != 0) {
69423684d0eSYann Gautier 		return status;
69523684d0eSYann Gautier 	}
69623684d0eSYann Gautier 
69723684d0eSYann Gautier 	if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
69823684d0eSYann Gautier 		uint8_t readval;
69923684d0eSYann Gautier 
70023684d0eSYann Gautier 		status = stpmic1_register_read(register_id, &readval);
70123684d0eSYann Gautier 		if (status != 0) {
70223684d0eSYann Gautier 			return status;
70323684d0eSYann Gautier 		}
70423684d0eSYann Gautier 
70523684d0eSYann Gautier 		if (readval != value) {
70623684d0eSYann Gautier 			return -1;
70723684d0eSYann Gautier 		}
70823684d0eSYann Gautier 	}
709*077f6828SYann Gautier #endif
71023684d0eSYann Gautier 
711*077f6828SYann Gautier 	return status;
71223684d0eSYann Gautier }
71323684d0eSYann Gautier 
71423684d0eSYann Gautier int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
71523684d0eSYann Gautier {
71623684d0eSYann Gautier 	int status;
71723684d0eSYann Gautier 	uint8_t val;
71823684d0eSYann Gautier 
71923684d0eSYann Gautier 	status = stpmic1_register_read(register_id, &val);
72023684d0eSYann Gautier 	if (status != 0) {
72123684d0eSYann Gautier 		return status;
72223684d0eSYann Gautier 	}
72323684d0eSYann Gautier 
724*077f6828SYann Gautier 	val = (val & ~mask) | (value & mask);
72523684d0eSYann Gautier 
72623684d0eSYann Gautier 	return stpmic1_register_write(register_id, val);
72723684d0eSYann Gautier }
72823684d0eSYann Gautier 
72923684d0eSYann Gautier void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
73023684d0eSYann Gautier {
73123684d0eSYann Gautier 	pmic_i2c_handle = i2c_handle;
73223684d0eSYann Gautier 	pmic_i2c_addr = i2c_addr;
73323684d0eSYann Gautier }
734*077f6828SYann Gautier 
735*077f6828SYann Gautier void stpmic1_dump_regulators(void)
736*077f6828SYann Gautier {
737*077f6828SYann Gautier 	uint32_t i;
738*077f6828SYann Gautier 
739*077f6828SYann Gautier 	for (i = 0U; i < MAX_REGUL; i++) {
740*077f6828SYann Gautier 		const char *name __unused = regulators_table[i].dt_node_name;
741*077f6828SYann Gautier 
742*077f6828SYann Gautier 		VERBOSE("PMIC regul %s: %sable, %dmV",
743*077f6828SYann Gautier 			name,
744*077f6828SYann Gautier 			stpmic1_is_regulator_enabled(name) ? "en" : "dis",
745*077f6828SYann Gautier 			stpmic1_regulator_voltage_get(name));
746*077f6828SYann Gautier 	}
747*077f6828SYann Gautier }
748*077f6828SYann Gautier 
749*077f6828SYann Gautier int stpmic1_get_version(unsigned long *version)
750*077f6828SYann Gautier {
751*077f6828SYann Gautier 	int rc;
752*077f6828SYann Gautier 	uint8_t read_val;
753*077f6828SYann Gautier 
754*077f6828SYann Gautier 	rc = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
755*077f6828SYann Gautier 	if (rc) {
756*077f6828SYann Gautier 		return -1;
757*077f6828SYann Gautier 	}
758*077f6828SYann Gautier 
759*077f6828SYann Gautier 	*version = (unsigned long)read_val;
760*077f6828SYann Gautier 
761*077f6828SYann Gautier 	return 0;
762*077f6828SYann Gautier }
763