xref: /rk3399_ARM-atf/drivers/st/pmic/stpmic1.c (revision 13fbfe046e71393961d2c70a4f748a15f9c15f77)
123684d0eSYann Gautier /*
2ed6a8523SYann Gautier  * Copyright (c) 2016-2021, STMicroelectronics - All Rights Reserved
323684d0eSYann Gautier  *
423684d0eSYann Gautier  * SPDX-License-Identifier: BSD-3-Clause
523684d0eSYann Gautier  */
623684d0eSYann Gautier 
7ed6a8523SYann Gautier #include <errno.h>
823684d0eSYann Gautier #include <string.h>
923684d0eSYann Gautier 
1023684d0eSYann Gautier #include <common/debug.h>
1123684d0eSYann Gautier #include <drivers/st/stpmic1.h>
12d82d4ff0SYann Gautier 
13d82d4ff0SYann Gautier #define I2C_TIMEOUT_MS		25
1423684d0eSYann Gautier 
1523684d0eSYann Gautier struct regul_struct {
1623684d0eSYann Gautier 	const char *dt_node_name;
1723684d0eSYann Gautier 	const uint16_t *voltage_table;
1823684d0eSYann Gautier 	uint8_t voltage_table_size;
1923684d0eSYann Gautier 	uint8_t control_reg;
2001619911SPascal Paillet 	uint8_t enable_mask;
2123684d0eSYann Gautier 	uint8_t low_power_reg;
22077f6828SYann Gautier 	uint8_t pull_down_reg;
23077f6828SYann Gautier 	uint8_t pull_down;
24077f6828SYann Gautier 	uint8_t mask_reset_reg;
25077f6828SYann Gautier 	uint8_t mask_reset;
2623684d0eSYann Gautier };
2723684d0eSYann Gautier 
2823684d0eSYann Gautier static struct i2c_handle_s *pmic_i2c_handle;
2923684d0eSYann Gautier static uint16_t pmic_i2c_addr;
3023684d0eSYann Gautier 
3123684d0eSYann Gautier /* Voltage tables in mV */
3223684d0eSYann Gautier static const uint16_t buck1_voltage_table[] = {
33077f6828SYann Gautier 	725,
34077f6828SYann Gautier 	725,
35077f6828SYann Gautier 	725,
36077f6828SYann Gautier 	725,
37077f6828SYann Gautier 	725,
3823684d0eSYann Gautier 	725,
3923684d0eSYann Gautier 	750,
4023684d0eSYann Gautier 	775,
4123684d0eSYann Gautier 	800,
4223684d0eSYann Gautier 	825,
4323684d0eSYann Gautier 	850,
4423684d0eSYann Gautier 	875,
4523684d0eSYann Gautier 	900,
4623684d0eSYann Gautier 	925,
4723684d0eSYann Gautier 	950,
4823684d0eSYann Gautier 	975,
4923684d0eSYann Gautier 	1000,
5023684d0eSYann Gautier 	1025,
5123684d0eSYann Gautier 	1050,
5223684d0eSYann Gautier 	1075,
5323684d0eSYann Gautier 	1100,
5423684d0eSYann Gautier 	1125,
5523684d0eSYann Gautier 	1150,
5623684d0eSYann Gautier 	1175,
5723684d0eSYann Gautier 	1200,
5823684d0eSYann Gautier 	1225,
5923684d0eSYann Gautier 	1250,
6023684d0eSYann Gautier 	1275,
6123684d0eSYann Gautier 	1300,
6223684d0eSYann Gautier 	1325,
6323684d0eSYann Gautier 	1350,
64077f6828SYann Gautier 	1375,
65077f6828SYann Gautier 	1400,
66077f6828SYann Gautier 	1425,
67077f6828SYann Gautier 	1450,
68077f6828SYann Gautier 	1475,
69077f6828SYann Gautier 	1500,
70077f6828SYann Gautier 	1500,
71077f6828SYann Gautier 	1500,
72077f6828SYann Gautier 	1500,
73077f6828SYann Gautier 	1500,
74077f6828SYann Gautier 	1500,
75077f6828SYann Gautier 	1500,
76077f6828SYann Gautier 	1500,
77077f6828SYann Gautier 	1500,
78077f6828SYann Gautier 	1500,
79077f6828SYann Gautier 	1500,
80077f6828SYann Gautier 	1500,
81077f6828SYann Gautier 	1500,
82077f6828SYann Gautier 	1500,
83077f6828SYann Gautier 	1500,
84077f6828SYann Gautier 	1500,
85077f6828SYann Gautier 	1500,
86077f6828SYann Gautier 	1500,
87077f6828SYann Gautier 	1500,
88077f6828SYann Gautier 	1500,
89077f6828SYann Gautier 	1500,
90077f6828SYann Gautier 	1500,
91077f6828SYann Gautier 	1500,
92077f6828SYann Gautier 	1500,
93077f6828SYann Gautier 	1500,
94077f6828SYann Gautier 	1500,
95077f6828SYann Gautier 	1500,
96077f6828SYann Gautier 	1500,
9723684d0eSYann Gautier };
9823684d0eSYann Gautier 
9923684d0eSYann Gautier static const uint16_t buck2_voltage_table[] = {
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 	1000,
11623684d0eSYann Gautier 	1000,
11723684d0eSYann Gautier 	1000,
11823684d0eSYann Gautier 	1050,
11923684d0eSYann Gautier 	1050,
12023684d0eSYann Gautier 	1100,
12123684d0eSYann Gautier 	1100,
12223684d0eSYann Gautier 	1150,
12323684d0eSYann Gautier 	1150,
12423684d0eSYann Gautier 	1200,
12523684d0eSYann Gautier 	1200,
12623684d0eSYann Gautier 	1250,
12723684d0eSYann Gautier 	1250,
12823684d0eSYann Gautier 	1300,
12923684d0eSYann Gautier 	1300,
13023684d0eSYann Gautier 	1350,
13123684d0eSYann Gautier 	1350,
13223684d0eSYann Gautier 	1400,
13323684d0eSYann Gautier 	1400,
13423684d0eSYann Gautier 	1450,
13523684d0eSYann Gautier 	1450,
13623684d0eSYann Gautier 	1500,
13723684d0eSYann Gautier };
13823684d0eSYann Gautier 
13923684d0eSYann Gautier static const uint16_t buck3_voltage_table[] = {
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 	1000,
15823684d0eSYann Gautier 	1000,
15923684d0eSYann Gautier 	1000,
16023684d0eSYann Gautier 	1100,
16123684d0eSYann Gautier 	1100,
16223684d0eSYann Gautier 	1100,
16323684d0eSYann Gautier 	1100,
16423684d0eSYann Gautier 	1200,
16523684d0eSYann Gautier 	1200,
16623684d0eSYann Gautier 	1200,
16723684d0eSYann Gautier 	1200,
16823684d0eSYann Gautier 	1300,
16923684d0eSYann Gautier 	1300,
17023684d0eSYann Gautier 	1300,
17123684d0eSYann Gautier 	1300,
17223684d0eSYann Gautier 	1400,
17323684d0eSYann Gautier 	1400,
17423684d0eSYann Gautier 	1400,
17523684d0eSYann Gautier 	1400,
17623684d0eSYann Gautier 	1500,
17723684d0eSYann Gautier 	1600,
17823684d0eSYann Gautier 	1700,
17923684d0eSYann Gautier 	1800,
18023684d0eSYann Gautier 	1900,
18123684d0eSYann Gautier 	2000,
18223684d0eSYann Gautier 	2100,
18323684d0eSYann Gautier 	2200,
18423684d0eSYann Gautier 	2300,
18523684d0eSYann Gautier 	2400,
18623684d0eSYann Gautier 	2500,
18723684d0eSYann Gautier 	2600,
18823684d0eSYann Gautier 	2700,
18923684d0eSYann Gautier 	2800,
19023684d0eSYann Gautier 	2900,
19123684d0eSYann Gautier 	3000,
19223684d0eSYann Gautier 	3100,
19323684d0eSYann Gautier 	3200,
19423684d0eSYann Gautier 	3300,
19523684d0eSYann Gautier 	3400,
19623684d0eSYann Gautier };
19723684d0eSYann Gautier 
19823684d0eSYann Gautier static const uint16_t buck4_voltage_table[] = {
19923684d0eSYann Gautier 	600,
20023684d0eSYann Gautier 	625,
20123684d0eSYann Gautier 	650,
20223684d0eSYann Gautier 	675,
20323684d0eSYann Gautier 	700,
20423684d0eSYann Gautier 	725,
20523684d0eSYann Gautier 	750,
20623684d0eSYann Gautier 	775,
20723684d0eSYann Gautier 	800,
20823684d0eSYann Gautier 	825,
20923684d0eSYann Gautier 	850,
21023684d0eSYann Gautier 	875,
21123684d0eSYann Gautier 	900,
21223684d0eSYann Gautier 	925,
21323684d0eSYann Gautier 	950,
21423684d0eSYann Gautier 	975,
21523684d0eSYann Gautier 	1000,
21623684d0eSYann Gautier 	1025,
21723684d0eSYann Gautier 	1050,
21823684d0eSYann Gautier 	1075,
21923684d0eSYann Gautier 	1100,
22023684d0eSYann Gautier 	1125,
22123684d0eSYann Gautier 	1150,
22223684d0eSYann Gautier 	1175,
22323684d0eSYann Gautier 	1200,
22423684d0eSYann Gautier 	1225,
22523684d0eSYann Gautier 	1250,
22623684d0eSYann Gautier 	1275,
22723684d0eSYann Gautier 	1300,
22823684d0eSYann Gautier 	1300,
22923684d0eSYann Gautier 	1350,
23023684d0eSYann Gautier 	1350,
23123684d0eSYann Gautier 	1400,
23223684d0eSYann Gautier 	1400,
23323684d0eSYann Gautier 	1450,
23423684d0eSYann Gautier 	1450,
23523684d0eSYann Gautier 	1500,
23623684d0eSYann Gautier 	1600,
23723684d0eSYann Gautier 	1700,
23823684d0eSYann Gautier 	1800,
23923684d0eSYann Gautier 	1900,
24023684d0eSYann Gautier 	2000,
24123684d0eSYann Gautier 	2100,
24223684d0eSYann Gautier 	2200,
24323684d0eSYann Gautier 	2300,
24423684d0eSYann Gautier 	2400,
24523684d0eSYann Gautier 	2500,
24623684d0eSYann Gautier 	2600,
24723684d0eSYann Gautier 	2700,
24823684d0eSYann Gautier 	2800,
24923684d0eSYann Gautier 	2900,
25023684d0eSYann Gautier 	3000,
25123684d0eSYann Gautier 	3100,
25223684d0eSYann Gautier 	3200,
25323684d0eSYann Gautier 	3300,
25423684d0eSYann Gautier 	3400,
25523684d0eSYann Gautier 	3500,
25623684d0eSYann Gautier 	3600,
25723684d0eSYann Gautier 	3700,
25823684d0eSYann Gautier 	3800,
25923684d0eSYann Gautier 	3900,
26023684d0eSYann Gautier };
26123684d0eSYann Gautier 
26223684d0eSYann Gautier static const uint16_t ldo1_voltage_table[] = {
26323684d0eSYann Gautier 	1700,
26423684d0eSYann Gautier 	1700,
26523684d0eSYann Gautier 	1700,
26623684d0eSYann Gautier 	1700,
26723684d0eSYann Gautier 	1700,
26823684d0eSYann Gautier 	1700,
26923684d0eSYann Gautier 	1700,
27023684d0eSYann Gautier 	1700,
27123684d0eSYann Gautier 	1700,
27223684d0eSYann Gautier 	1800,
27323684d0eSYann Gautier 	1900,
27423684d0eSYann Gautier 	2000,
27523684d0eSYann Gautier 	2100,
27623684d0eSYann Gautier 	2200,
27723684d0eSYann Gautier 	2300,
27823684d0eSYann Gautier 	2400,
27923684d0eSYann Gautier 	2500,
28023684d0eSYann Gautier 	2600,
28123684d0eSYann Gautier 	2700,
28223684d0eSYann Gautier 	2800,
28323684d0eSYann Gautier 	2900,
28423684d0eSYann Gautier 	3000,
28523684d0eSYann Gautier 	3100,
28623684d0eSYann Gautier 	3200,
28723684d0eSYann Gautier 	3300,
28823684d0eSYann Gautier };
28923684d0eSYann Gautier 
29023684d0eSYann Gautier static const uint16_t ldo2_voltage_table[] = {
29123684d0eSYann Gautier 	1700,
29223684d0eSYann Gautier 	1700,
29323684d0eSYann Gautier 	1700,
29423684d0eSYann Gautier 	1700,
29523684d0eSYann Gautier 	1700,
29623684d0eSYann Gautier 	1700,
29723684d0eSYann Gautier 	1700,
29823684d0eSYann Gautier 	1700,
29923684d0eSYann Gautier 	1700,
30023684d0eSYann Gautier 	1800,
30123684d0eSYann Gautier 	1900,
30223684d0eSYann Gautier 	2000,
30323684d0eSYann Gautier 	2100,
30423684d0eSYann Gautier 	2200,
30523684d0eSYann Gautier 	2300,
30623684d0eSYann Gautier 	2400,
30723684d0eSYann Gautier 	2500,
30823684d0eSYann Gautier 	2600,
30923684d0eSYann Gautier 	2700,
31023684d0eSYann Gautier 	2800,
31123684d0eSYann Gautier 	2900,
31223684d0eSYann Gautier 	3000,
31323684d0eSYann Gautier 	3100,
31423684d0eSYann Gautier 	3200,
31523684d0eSYann Gautier 	3300,
31623684d0eSYann Gautier };
31723684d0eSYann Gautier 
31823684d0eSYann Gautier static const uint16_t ldo3_voltage_table[] = {
31923684d0eSYann Gautier 	1700,
32023684d0eSYann Gautier 	1700,
32123684d0eSYann Gautier 	1700,
32223684d0eSYann Gautier 	1700,
32323684d0eSYann Gautier 	1700,
32423684d0eSYann Gautier 	1700,
32523684d0eSYann Gautier 	1700,
32623684d0eSYann Gautier 	1700,
32723684d0eSYann Gautier 	1700,
32823684d0eSYann Gautier 	1800,
32923684d0eSYann Gautier 	1900,
33023684d0eSYann Gautier 	2000,
33123684d0eSYann Gautier 	2100,
33223684d0eSYann Gautier 	2200,
33323684d0eSYann Gautier 	2300,
33423684d0eSYann Gautier 	2400,
33523684d0eSYann Gautier 	2500,
33623684d0eSYann Gautier 	2600,
33723684d0eSYann Gautier 	2700,
33823684d0eSYann Gautier 	2800,
33923684d0eSYann Gautier 	2900,
34023684d0eSYann Gautier 	3000,
34123684d0eSYann Gautier 	3100,
34223684d0eSYann Gautier 	3200,
34323684d0eSYann Gautier 	3300,
34423684d0eSYann Gautier 	3300,
34523684d0eSYann Gautier 	3300,
34623684d0eSYann Gautier 	3300,
34723684d0eSYann Gautier 	3300,
34823684d0eSYann Gautier 	3300,
34923684d0eSYann Gautier 	3300,
350077f6828SYann Gautier 	500,
35123684d0eSYann Gautier 	0xFFFF, /* VREFDDR */
35223684d0eSYann Gautier };
35323684d0eSYann Gautier 
35423684d0eSYann Gautier static const uint16_t ldo5_voltage_table[] = {
35523684d0eSYann Gautier 	1700,
35623684d0eSYann Gautier 	1700,
35723684d0eSYann Gautier 	1700,
35823684d0eSYann Gautier 	1700,
35923684d0eSYann Gautier 	1700,
36023684d0eSYann Gautier 	1700,
36123684d0eSYann Gautier 	1700,
36223684d0eSYann Gautier 	1700,
36323684d0eSYann Gautier 	1700,
36423684d0eSYann Gautier 	1800,
36523684d0eSYann Gautier 	1900,
36623684d0eSYann Gautier 	2000,
36723684d0eSYann Gautier 	2100,
36823684d0eSYann Gautier 	2200,
36923684d0eSYann Gautier 	2300,
37023684d0eSYann Gautier 	2400,
37123684d0eSYann Gautier 	2500,
37223684d0eSYann Gautier 	2600,
37323684d0eSYann Gautier 	2700,
37423684d0eSYann Gautier 	2800,
37523684d0eSYann Gautier 	2900,
37623684d0eSYann Gautier 	3000,
37723684d0eSYann Gautier 	3100,
37823684d0eSYann Gautier 	3200,
37923684d0eSYann Gautier 	3300,
38023684d0eSYann Gautier 	3400,
38123684d0eSYann Gautier 	3500,
38223684d0eSYann Gautier 	3600,
38323684d0eSYann Gautier 	3700,
38423684d0eSYann Gautier 	3800,
38523684d0eSYann Gautier 	3900,
38623684d0eSYann Gautier };
38723684d0eSYann Gautier 
38823684d0eSYann Gautier static const uint16_t ldo6_voltage_table[] = {
38923684d0eSYann Gautier 	900,
39023684d0eSYann Gautier 	1000,
39123684d0eSYann Gautier 	1100,
39223684d0eSYann Gautier 	1200,
39323684d0eSYann Gautier 	1300,
39423684d0eSYann Gautier 	1400,
39523684d0eSYann Gautier 	1500,
39623684d0eSYann Gautier 	1600,
39723684d0eSYann Gautier 	1700,
39823684d0eSYann Gautier 	1800,
39923684d0eSYann Gautier 	1900,
40023684d0eSYann Gautier 	2000,
40123684d0eSYann Gautier 	2100,
40223684d0eSYann Gautier 	2200,
40323684d0eSYann Gautier 	2300,
40423684d0eSYann Gautier 	2400,
40523684d0eSYann Gautier 	2500,
40623684d0eSYann Gautier 	2600,
40723684d0eSYann Gautier 	2700,
40823684d0eSYann Gautier 	2800,
40923684d0eSYann Gautier 	2900,
41023684d0eSYann Gautier 	3000,
41123684d0eSYann Gautier 	3100,
41223684d0eSYann Gautier 	3200,
41323684d0eSYann Gautier 	3300,
41423684d0eSYann Gautier };
41523684d0eSYann Gautier 
41623684d0eSYann Gautier static const uint16_t ldo4_voltage_table[] = {
41723684d0eSYann Gautier 	3300,
41823684d0eSYann Gautier };
41923684d0eSYann Gautier 
42023684d0eSYann Gautier static const uint16_t vref_ddr_voltage_table[] = {
42123684d0eSYann Gautier 	3300,
42223684d0eSYann Gautier };
42323684d0eSYann Gautier 
424*13fbfe04SEtienne Carriere static const uint16_t fixed_5v_voltage_table[] = {
425*13fbfe04SEtienne Carriere 	5000,
426*13fbfe04SEtienne Carriere };
427*13fbfe04SEtienne Carriere 
42823684d0eSYann Gautier /* Table of Regulators in PMIC SoC */
42923684d0eSYann Gautier static const struct regul_struct regulators_table[] = {
43023684d0eSYann Gautier 	{
43123684d0eSYann Gautier 		.dt_node_name	= "buck1",
43223684d0eSYann Gautier 		.voltage_table	= buck1_voltage_table,
43323684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
43423684d0eSYann Gautier 		.control_reg	= BUCK1_CONTROL_REG,
43501619911SPascal Paillet 		.enable_mask	= LDO_BUCK_ENABLE_MASK,
43623684d0eSYann Gautier 		.low_power_reg	= BUCK1_PWRCTRL_REG,
437077f6828SYann Gautier 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
438077f6828SYann Gautier 		.pull_down	= BUCK1_PULL_DOWN_SHIFT,
439077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_BUCK_REG,
440077f6828SYann Gautier 		.mask_reset	= BUCK1_MASK_RESET,
44123684d0eSYann Gautier 	},
44223684d0eSYann Gautier 	{
44323684d0eSYann Gautier 		.dt_node_name	= "buck2",
44423684d0eSYann Gautier 		.voltage_table	= buck2_voltage_table,
44523684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
44623684d0eSYann Gautier 		.control_reg	= BUCK2_CONTROL_REG,
44701619911SPascal Paillet 		.enable_mask	= LDO_BUCK_ENABLE_MASK,
44823684d0eSYann Gautier 		.low_power_reg	= BUCK2_PWRCTRL_REG,
449077f6828SYann Gautier 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
450077f6828SYann Gautier 		.pull_down	= BUCK2_PULL_DOWN_SHIFT,
451077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_BUCK_REG,
452077f6828SYann Gautier 		.mask_reset	= BUCK2_MASK_RESET,
45323684d0eSYann Gautier 	},
45423684d0eSYann Gautier 	{
45523684d0eSYann Gautier 		.dt_node_name	= "buck3",
45623684d0eSYann Gautier 		.voltage_table	= buck3_voltage_table,
45723684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
45823684d0eSYann Gautier 		.control_reg	= BUCK3_CONTROL_REG,
45901619911SPascal Paillet 		.enable_mask	= LDO_BUCK_ENABLE_MASK,
46023684d0eSYann Gautier 		.low_power_reg	= BUCK3_PWRCTRL_REG,
461077f6828SYann Gautier 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
462077f6828SYann Gautier 		.pull_down	= BUCK3_PULL_DOWN_SHIFT,
463077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_BUCK_REG,
464077f6828SYann Gautier 		.mask_reset	= BUCK3_MASK_RESET,
46523684d0eSYann Gautier 	},
46623684d0eSYann Gautier 	{
46723684d0eSYann Gautier 		.dt_node_name	= "buck4",
46823684d0eSYann Gautier 		.voltage_table	= buck4_voltage_table,
46923684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
47023684d0eSYann Gautier 		.control_reg	= BUCK4_CONTROL_REG,
47101619911SPascal Paillet 		.enable_mask	= LDO_BUCK_ENABLE_MASK,
47223684d0eSYann Gautier 		.low_power_reg	= BUCK4_PWRCTRL_REG,
473077f6828SYann Gautier 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
474077f6828SYann Gautier 		.pull_down	= BUCK4_PULL_DOWN_SHIFT,
475077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_BUCK_REG,
476077f6828SYann Gautier 		.mask_reset	= BUCK4_MASK_RESET,
47723684d0eSYann Gautier 	},
47823684d0eSYann Gautier 	{
47923684d0eSYann Gautier 		.dt_node_name	= "ldo1",
48023684d0eSYann Gautier 		.voltage_table	= ldo1_voltage_table,
48123684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
48223684d0eSYann Gautier 		.control_reg	= LDO1_CONTROL_REG,
48301619911SPascal Paillet 		.enable_mask	= LDO_BUCK_ENABLE_MASK,
48423684d0eSYann Gautier 		.low_power_reg	= LDO1_PWRCTRL_REG,
485077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_LDO_REG,
486077f6828SYann Gautier 		.mask_reset	= LDO1_MASK_RESET,
48723684d0eSYann Gautier 	},
48823684d0eSYann Gautier 	{
48923684d0eSYann Gautier 		.dt_node_name	= "ldo2",
49023684d0eSYann Gautier 		.voltage_table	= ldo2_voltage_table,
49123684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
49223684d0eSYann Gautier 		.control_reg	= LDO2_CONTROL_REG,
49301619911SPascal Paillet 		.enable_mask	= LDO_BUCK_ENABLE_MASK,
49423684d0eSYann Gautier 		.low_power_reg	= LDO2_PWRCTRL_REG,
495077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_LDO_REG,
496077f6828SYann Gautier 		.mask_reset	= LDO2_MASK_RESET,
49723684d0eSYann Gautier 	},
49823684d0eSYann Gautier 	{
49923684d0eSYann Gautier 		.dt_node_name	= "ldo3",
50023684d0eSYann Gautier 		.voltage_table	= ldo3_voltage_table,
50123684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
50223684d0eSYann Gautier 		.control_reg	= LDO3_CONTROL_REG,
50301619911SPascal Paillet 		.enable_mask	= LDO_BUCK_ENABLE_MASK,
50423684d0eSYann Gautier 		.low_power_reg	= LDO3_PWRCTRL_REG,
505077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_LDO_REG,
506077f6828SYann Gautier 		.mask_reset	= LDO3_MASK_RESET,
50723684d0eSYann Gautier 	},
50823684d0eSYann Gautier 	{
50923684d0eSYann Gautier 		.dt_node_name	= "ldo4",
51023684d0eSYann Gautier 		.voltage_table	= ldo4_voltage_table,
51123684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
51223684d0eSYann Gautier 		.control_reg	= LDO4_CONTROL_REG,
51301619911SPascal Paillet 		.enable_mask	= LDO_BUCK_ENABLE_MASK,
51423684d0eSYann Gautier 		.low_power_reg	= LDO4_PWRCTRL_REG,
515077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_LDO_REG,
516077f6828SYann Gautier 		.mask_reset	= LDO4_MASK_RESET,
51723684d0eSYann Gautier 	},
51823684d0eSYann Gautier 	{
51923684d0eSYann Gautier 		.dt_node_name	= "ldo5",
52023684d0eSYann Gautier 		.voltage_table	= ldo5_voltage_table,
52123684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
52223684d0eSYann Gautier 		.control_reg	= LDO5_CONTROL_REG,
52301619911SPascal Paillet 		.enable_mask	= LDO_BUCK_ENABLE_MASK,
52423684d0eSYann Gautier 		.low_power_reg	= LDO5_PWRCTRL_REG,
525077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_LDO_REG,
526077f6828SYann Gautier 		.mask_reset	= LDO5_MASK_RESET,
52723684d0eSYann Gautier 	},
52823684d0eSYann Gautier 	{
52923684d0eSYann Gautier 		.dt_node_name	= "ldo6",
53023684d0eSYann Gautier 		.voltage_table	= ldo6_voltage_table,
53123684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
53223684d0eSYann Gautier 		.control_reg	= LDO6_CONTROL_REG,
53301619911SPascal Paillet 		.enable_mask	= LDO_BUCK_ENABLE_MASK,
53423684d0eSYann Gautier 		.low_power_reg	= LDO6_PWRCTRL_REG,
535077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_LDO_REG,
536077f6828SYann Gautier 		.mask_reset	= LDO6_MASK_RESET,
53723684d0eSYann Gautier 	},
53823684d0eSYann Gautier 	{
53923684d0eSYann Gautier 		.dt_node_name	= "vref_ddr",
54023684d0eSYann Gautier 		.voltage_table	= vref_ddr_voltage_table,
54123684d0eSYann Gautier 		.voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
54223684d0eSYann Gautier 		.control_reg	= VREF_DDR_CONTROL_REG,
54301619911SPascal Paillet 		.enable_mask	= LDO_BUCK_ENABLE_MASK,
54423684d0eSYann Gautier 		.low_power_reg	= VREF_DDR_PWRCTRL_REG,
545077f6828SYann Gautier 		.mask_reset_reg	= MASK_RESET_LDO_REG,
546077f6828SYann Gautier 		.mask_reset	= VREF_DDR_MASK_RESET,
54723684d0eSYann Gautier 	},
548*13fbfe04SEtienne Carriere 	{
549*13fbfe04SEtienne Carriere 		.dt_node_name	= "boost",
550*13fbfe04SEtienne Carriere 		.voltage_table	= fixed_5v_voltage_table,
551*13fbfe04SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
552*13fbfe04SEtienne Carriere 		.control_reg	= USB_CONTROL_REG,
553*13fbfe04SEtienne Carriere 		.enable_mask	= BOOST_ENABLED,
554*13fbfe04SEtienne Carriere 	},
555*13fbfe04SEtienne Carriere 	{
556*13fbfe04SEtienne Carriere 		.dt_node_name	= "pwr_sw1",
557*13fbfe04SEtienne Carriere 		.voltage_table	= fixed_5v_voltage_table,
558*13fbfe04SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
559*13fbfe04SEtienne Carriere 		.control_reg	= USB_CONTROL_REG,
560*13fbfe04SEtienne Carriere 		.enable_mask	= USBSW_OTG_SWITCH_ENABLED,
561*13fbfe04SEtienne Carriere 	},
562*13fbfe04SEtienne Carriere 	{
563*13fbfe04SEtienne Carriere 		.dt_node_name	= "pwr_sw2",
564*13fbfe04SEtienne Carriere 		.voltage_table	= fixed_5v_voltage_table,
565*13fbfe04SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
566*13fbfe04SEtienne Carriere 		.control_reg	= USB_CONTROL_REG,
567*13fbfe04SEtienne Carriere 		.enable_mask	= SWIN_SWOUT_ENABLED,
568*13fbfe04SEtienne Carriere 	},
56923684d0eSYann Gautier };
57023684d0eSYann Gautier 
57123684d0eSYann Gautier #define MAX_REGUL	ARRAY_SIZE(regulators_table)
57223684d0eSYann Gautier 
57323684d0eSYann Gautier static const struct regul_struct *get_regulator_data(const char *name)
57423684d0eSYann Gautier {
57523684d0eSYann Gautier 	uint8_t i;
57623684d0eSYann Gautier 
57723684d0eSYann Gautier 	for (i = 0 ; i < MAX_REGUL ; i++) {
57823684d0eSYann Gautier 		if (strncmp(name, regulators_table[i].dt_node_name,
57923684d0eSYann Gautier 			    strlen(regulators_table[i].dt_node_name)) == 0) {
58023684d0eSYann Gautier 			return &regulators_table[i];
58123684d0eSYann Gautier 		}
58223684d0eSYann Gautier 	}
58323684d0eSYann Gautier 
58423684d0eSYann Gautier 	/* Regulator not found */
58523684d0eSYann Gautier 	panic();
58623684d0eSYann Gautier 	return NULL;
58723684d0eSYann Gautier }
58823684d0eSYann Gautier 
58923684d0eSYann Gautier static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
59023684d0eSYann Gautier {
59123684d0eSYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
59223684d0eSYann Gautier 	uint8_t i;
59323684d0eSYann Gautier 
59423684d0eSYann Gautier 	for (i = 0 ; i < regul->voltage_table_size ; i++) {
59523684d0eSYann Gautier 		if (regul->voltage_table[i] == millivolts) {
59623684d0eSYann Gautier 			return i;
59723684d0eSYann Gautier 		}
59823684d0eSYann Gautier 	}
59923684d0eSYann Gautier 
60023684d0eSYann Gautier 	/* Voltage not found */
60123684d0eSYann Gautier 	panic();
60223684d0eSYann Gautier 
60323684d0eSYann Gautier 	return 0;
60423684d0eSYann Gautier }
60523684d0eSYann Gautier 
606077f6828SYann Gautier int stpmic1_powerctrl_on(void)
607077f6828SYann Gautier {
608077f6828SYann Gautier 	return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
609077f6828SYann Gautier 				       PWRCTRL_PIN_VALID);
610077f6828SYann Gautier }
611077f6828SYann Gautier 
61223684d0eSYann Gautier int stpmic1_switch_off(void)
61323684d0eSYann Gautier {
61423684d0eSYann Gautier 	return stpmic1_register_update(MAIN_CONTROL_REG, 1,
61523684d0eSYann Gautier 				       SOFTWARE_SWITCH_OFF_ENABLED);
61623684d0eSYann Gautier }
61723684d0eSYann Gautier 
61823684d0eSYann Gautier int stpmic1_regulator_enable(const char *name)
61923684d0eSYann Gautier {
62023684d0eSYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
62123684d0eSYann Gautier 
62201619911SPascal Paillet 	return stpmic1_register_update(regul->control_reg, regul->enable_mask,
62301619911SPascal Paillet 				       regul->enable_mask);
62423684d0eSYann Gautier }
62523684d0eSYann Gautier 
62623684d0eSYann Gautier int stpmic1_regulator_disable(const char *name)
62723684d0eSYann Gautier {
62823684d0eSYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
62923684d0eSYann Gautier 
63001619911SPascal Paillet 	return stpmic1_register_update(regul->control_reg, 0,
63101619911SPascal Paillet 				       regul->enable_mask);
63223684d0eSYann Gautier }
63323684d0eSYann Gautier 
63416e56a75SNicolas Le Bayon bool stpmic1_is_regulator_enabled(const char *name)
63523684d0eSYann Gautier {
63623684d0eSYann Gautier 	uint8_t val;
63723684d0eSYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
63823684d0eSYann Gautier 
63923684d0eSYann Gautier 	if (stpmic1_register_read(regul->control_reg, &val) != 0) {
64023684d0eSYann Gautier 		panic();
64123684d0eSYann Gautier 	}
64223684d0eSYann Gautier 
64316e56a75SNicolas Le Bayon 	return (val & regul->enable_mask) == regul->enable_mask;
64423684d0eSYann Gautier }
64523684d0eSYann Gautier 
64623684d0eSYann Gautier int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
64723684d0eSYann Gautier {
64823684d0eSYann Gautier 	uint8_t voltage_index = voltage_to_index(name, millivolts);
64923684d0eSYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
650077f6828SYann Gautier 	uint8_t mask;
65123684d0eSYann Gautier 
652077f6828SYann Gautier 	/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
653077f6828SYann Gautier 	if (strncmp(name, "buck", 4) == 0) {
654077f6828SYann Gautier 		mask = BUCK_VOLTAGE_MASK;
655077f6828SYann Gautier 	} else if ((strncmp(name, "ldo", 3) == 0) &&
656077f6828SYann Gautier 		   (strncmp(name, "ldo4", 4) != 0)) {
657077f6828SYann Gautier 		mask = LDO_VOLTAGE_MASK;
658077f6828SYann Gautier 	} else {
659077f6828SYann Gautier 		return 0;
660077f6828SYann Gautier 	}
661077f6828SYann Gautier 
662077f6828SYann Gautier 	return stpmic1_register_update(regul->control_reg,
663077f6828SYann Gautier 				       voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
664077f6828SYann Gautier 				       mask);
665077f6828SYann Gautier }
666077f6828SYann Gautier 
667077f6828SYann Gautier int stpmic1_regulator_pull_down_set(const char *name)
668077f6828SYann Gautier {
669077f6828SYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
670077f6828SYann Gautier 
671077f6828SYann Gautier 	if (regul->pull_down_reg != 0) {
672077f6828SYann Gautier 		return stpmic1_register_update(regul->pull_down_reg,
673077f6828SYann Gautier 					       BIT(regul->pull_down),
674077f6828SYann Gautier 					       LDO_BUCK_PULL_DOWN_MASK <<
675077f6828SYann Gautier 					       regul->pull_down);
676077f6828SYann Gautier 	}
677077f6828SYann Gautier 
678077f6828SYann Gautier 	return 0;
679077f6828SYann Gautier }
680077f6828SYann Gautier 
681077f6828SYann Gautier int stpmic1_regulator_mask_reset_set(const char *name)
682077f6828SYann Gautier {
683077f6828SYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
684077f6828SYann Gautier 
685077f6828SYann Gautier 	return stpmic1_register_update(regul->mask_reset_reg,
686077f6828SYann Gautier 				       BIT(regul->mask_reset),
687077f6828SYann Gautier 				       LDO_BUCK_RESET_MASK <<
688077f6828SYann Gautier 				       regul->mask_reset);
689077f6828SYann Gautier }
690077f6828SYann Gautier 
691077f6828SYann Gautier int stpmic1_regulator_voltage_get(const char *name)
692077f6828SYann Gautier {
693077f6828SYann Gautier 	const struct regul_struct *regul = get_regulator_data(name);
694077f6828SYann Gautier 	uint8_t value;
695077f6828SYann Gautier 	uint8_t mask;
696ed6a8523SYann Gautier 	int status;
697077f6828SYann Gautier 
698077f6828SYann Gautier 	/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
699077f6828SYann Gautier 	if (strncmp(name, "buck", 4) == 0) {
700077f6828SYann Gautier 		mask = BUCK_VOLTAGE_MASK;
701077f6828SYann Gautier 	} else if ((strncmp(name, "ldo", 3) == 0) &&
702077f6828SYann Gautier 		   (strncmp(name, "ldo4", 4) != 0)) {
703077f6828SYann Gautier 		mask = LDO_VOLTAGE_MASK;
704077f6828SYann Gautier 	} else {
705077f6828SYann Gautier 		return 0;
706077f6828SYann Gautier 	}
707077f6828SYann Gautier 
708ed6a8523SYann Gautier 	status = stpmic1_register_read(regul->control_reg, &value);
709ed6a8523SYann Gautier 	if (status < 0) {
710ed6a8523SYann Gautier 		return status;
711ed6a8523SYann Gautier 	}
712077f6828SYann Gautier 
713077f6828SYann Gautier 	value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
714077f6828SYann Gautier 
715ed6a8523SYann Gautier 	if (value > regul->voltage_table_size) {
716ed6a8523SYann Gautier 		return -ERANGE;
717ed6a8523SYann Gautier 	}
718077f6828SYann Gautier 
719077f6828SYann Gautier 	return (int)regul->voltage_table[value];
72023684d0eSYann Gautier }
72123684d0eSYann Gautier 
72223684d0eSYann Gautier int stpmic1_register_read(uint8_t register_id,  uint8_t *value)
72323684d0eSYann Gautier {
72423684d0eSYann Gautier 	return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr,
725d82d4ff0SYann Gautier 				  (uint16_t)register_id,
726d82d4ff0SYann Gautier 				  I2C_MEMADD_SIZE_8BIT, value,
727d82d4ff0SYann Gautier 				  1, I2C_TIMEOUT_MS);
72823684d0eSYann Gautier }
72923684d0eSYann Gautier 
73023684d0eSYann Gautier int stpmic1_register_write(uint8_t register_id, uint8_t value)
73123684d0eSYann Gautier {
73223684d0eSYann Gautier 	int status;
73323684d0eSYann Gautier 
73423684d0eSYann Gautier 	status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr,
73523684d0eSYann Gautier 				     (uint16_t)register_id,
736d82d4ff0SYann Gautier 				     I2C_MEMADD_SIZE_8BIT, &value,
737d82d4ff0SYann Gautier 				     1, I2C_TIMEOUT_MS);
73823684d0eSYann Gautier 
739077f6828SYann Gautier #if ENABLE_ASSERTIONS
74023684d0eSYann Gautier 	if (status != 0) {
74123684d0eSYann Gautier 		return status;
74223684d0eSYann Gautier 	}
74323684d0eSYann Gautier 
74423684d0eSYann Gautier 	if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
74523684d0eSYann Gautier 		uint8_t readval;
74623684d0eSYann Gautier 
74723684d0eSYann Gautier 		status = stpmic1_register_read(register_id, &readval);
74823684d0eSYann Gautier 		if (status != 0) {
74923684d0eSYann Gautier 			return status;
75023684d0eSYann Gautier 		}
75123684d0eSYann Gautier 
75223684d0eSYann Gautier 		if (readval != value) {
753ed6a8523SYann Gautier 			return -EIO;
75423684d0eSYann Gautier 		}
75523684d0eSYann Gautier 	}
756077f6828SYann Gautier #endif
75723684d0eSYann Gautier 
758077f6828SYann Gautier 	return status;
75923684d0eSYann Gautier }
76023684d0eSYann Gautier 
76123684d0eSYann Gautier int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
76223684d0eSYann Gautier {
76323684d0eSYann Gautier 	int status;
76423684d0eSYann Gautier 	uint8_t val;
76523684d0eSYann Gautier 
76623684d0eSYann Gautier 	status = stpmic1_register_read(register_id, &val);
76723684d0eSYann Gautier 	if (status != 0) {
76823684d0eSYann Gautier 		return status;
76923684d0eSYann Gautier 	}
77023684d0eSYann Gautier 
771077f6828SYann Gautier 	val = (val & ~mask) | (value & mask);
77223684d0eSYann Gautier 
77323684d0eSYann Gautier 	return stpmic1_register_write(register_id, val);
77423684d0eSYann Gautier }
77523684d0eSYann Gautier 
77623684d0eSYann Gautier void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
77723684d0eSYann Gautier {
77823684d0eSYann Gautier 	pmic_i2c_handle = i2c_handle;
77923684d0eSYann Gautier 	pmic_i2c_addr = i2c_addr;
78023684d0eSYann Gautier }
781077f6828SYann Gautier 
782077f6828SYann Gautier void stpmic1_dump_regulators(void)
783077f6828SYann Gautier {
784077f6828SYann Gautier 	uint32_t i;
785077f6828SYann Gautier 
786077f6828SYann Gautier 	for (i = 0U; i < MAX_REGUL; i++) {
787077f6828SYann Gautier 		const char *name __unused = regulators_table[i].dt_node_name;
788077f6828SYann Gautier 
789077f6828SYann Gautier 		VERBOSE("PMIC regul %s: %sable, %dmV",
790077f6828SYann Gautier 			name,
791077f6828SYann Gautier 			stpmic1_is_regulator_enabled(name) ? "en" : "dis",
792077f6828SYann Gautier 			stpmic1_regulator_voltage_get(name));
793077f6828SYann Gautier 	}
794077f6828SYann Gautier }
795077f6828SYann Gautier 
796077f6828SYann Gautier int stpmic1_get_version(unsigned long *version)
797077f6828SYann Gautier {
798077f6828SYann Gautier 	uint8_t read_val;
799ed6a8523SYann Gautier 	int status;
800077f6828SYann Gautier 
801ed6a8523SYann Gautier 	status = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
802ed6a8523SYann Gautier 	if (status < 0) {
803ed6a8523SYann Gautier 		return status;
804077f6828SYann Gautier 	}
805077f6828SYann Gautier 
806077f6828SYann Gautier 	*version = (unsigned long)read_val;
807077f6828SYann Gautier 
808077f6828SYann Gautier 	return 0;
809077f6828SYann Gautier }
810