xref: /arm-trusted-firmware/drivers/st/pmic/stm32mp_pmic.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu #include <errno.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <common/debug.h>
11*91f16700Schasinglulu #include <drivers/delay_timer.h>
12*91f16700Schasinglulu #include <drivers/st/regulator.h>
13*91f16700Schasinglulu #include <drivers/st/stm32_i2c.h>
14*91f16700Schasinglulu #include <drivers/st/stm32mp_pmic.h>
15*91f16700Schasinglulu #include <drivers/st/stpmic1.h>
16*91f16700Schasinglulu #include <lib/mmio.h>
17*91f16700Schasinglulu #include <lib/utils_def.h>
18*91f16700Schasinglulu #include <libfdt.h>
19*91f16700Schasinglulu 
20*91f16700Schasinglulu #include <platform_def.h>
21*91f16700Schasinglulu 
22*91f16700Schasinglulu #define PMIC_NODE_NOT_FOUND	1
23*91f16700Schasinglulu #define NB_REG			14U
24*91f16700Schasinglulu 
25*91f16700Schasinglulu static struct i2c_handle_s i2c_handle;
26*91f16700Schasinglulu static uint32_t pmic_i2c_addr;
27*91f16700Schasinglulu 
28*91f16700Schasinglulu static int register_pmic(void);
29*91f16700Schasinglulu 
30*91f16700Schasinglulu static int dt_get_pmic_node(void *fdt)
31*91f16700Schasinglulu {
32*91f16700Schasinglulu 	static int node = -FDT_ERR_BADOFFSET;
33*91f16700Schasinglulu 
34*91f16700Schasinglulu 	if (node == -FDT_ERR_BADOFFSET) {
35*91f16700Schasinglulu 		node = fdt_node_offset_by_compatible(fdt, -1, "st,stpmic1");
36*91f16700Schasinglulu 	}
37*91f16700Schasinglulu 
38*91f16700Schasinglulu 	return node;
39*91f16700Schasinglulu }
40*91f16700Schasinglulu 
41*91f16700Schasinglulu int dt_pmic_status(void)
42*91f16700Schasinglulu {
43*91f16700Schasinglulu 	static int status = -FDT_ERR_BADVALUE;
44*91f16700Schasinglulu 	int node;
45*91f16700Schasinglulu 	void *fdt;
46*91f16700Schasinglulu 
47*91f16700Schasinglulu 	if (status != -FDT_ERR_BADVALUE) {
48*91f16700Schasinglulu 		return status;
49*91f16700Schasinglulu 	}
50*91f16700Schasinglulu 
51*91f16700Schasinglulu 	if (fdt_get_address(&fdt) == 0) {
52*91f16700Schasinglulu 		return -ENOENT;
53*91f16700Schasinglulu 	}
54*91f16700Schasinglulu 
55*91f16700Schasinglulu 	node = dt_get_pmic_node(fdt);
56*91f16700Schasinglulu 	if (node <= 0) {
57*91f16700Schasinglulu 		status = -FDT_ERR_NOTFOUND;
58*91f16700Schasinglulu 
59*91f16700Schasinglulu 		return status;
60*91f16700Schasinglulu 	}
61*91f16700Schasinglulu 
62*91f16700Schasinglulu 	status = (int)fdt_get_status(node);
63*91f16700Schasinglulu 
64*91f16700Schasinglulu 	return status;
65*91f16700Schasinglulu }
66*91f16700Schasinglulu 
67*91f16700Schasinglulu static bool dt_pmic_is_secure(void)
68*91f16700Schasinglulu {
69*91f16700Schasinglulu 	int status = dt_pmic_status();
70*91f16700Schasinglulu 
71*91f16700Schasinglulu 	return (status >= 0) &&
72*91f16700Schasinglulu 	       (status == DT_SECURE) &&
73*91f16700Schasinglulu 	       (i2c_handle.dt_status == DT_SECURE);
74*91f16700Schasinglulu }
75*91f16700Schasinglulu 
76*91f16700Schasinglulu /*
77*91f16700Schasinglulu  * Get PMIC and its I2C bus configuration from the device tree.
78*91f16700Schasinglulu  * Return 0 on success, negative on error, 1 if no PMIC node is defined.
79*91f16700Schasinglulu  */
80*91f16700Schasinglulu static int dt_pmic_i2c_config(struct dt_node_info *i2c_info,
81*91f16700Schasinglulu 			      struct stm32_i2c_init_s *init)
82*91f16700Schasinglulu {
83*91f16700Schasinglulu 	static int i2c_node = -FDT_ERR_NOTFOUND;
84*91f16700Schasinglulu 	void *fdt;
85*91f16700Schasinglulu 
86*91f16700Schasinglulu 	if (fdt_get_address(&fdt) == 0) {
87*91f16700Schasinglulu 		return -FDT_ERR_NOTFOUND;
88*91f16700Schasinglulu 	}
89*91f16700Schasinglulu 
90*91f16700Schasinglulu 	if (i2c_node == -FDT_ERR_NOTFOUND) {
91*91f16700Schasinglulu 		int pmic_node;
92*91f16700Schasinglulu 		const fdt32_t *cuint;
93*91f16700Schasinglulu 
94*91f16700Schasinglulu 		pmic_node = dt_get_pmic_node(fdt);
95*91f16700Schasinglulu 		if (pmic_node < 0) {
96*91f16700Schasinglulu 			return PMIC_NODE_NOT_FOUND;
97*91f16700Schasinglulu 		}
98*91f16700Schasinglulu 
99*91f16700Schasinglulu 		cuint = fdt_getprop(fdt, pmic_node, "reg", NULL);
100*91f16700Schasinglulu 		if (cuint == NULL) {
101*91f16700Schasinglulu 			return -FDT_ERR_NOTFOUND;
102*91f16700Schasinglulu 		}
103*91f16700Schasinglulu 
104*91f16700Schasinglulu 		pmic_i2c_addr = fdt32_to_cpu(*cuint) << 1;
105*91f16700Schasinglulu 		if (pmic_i2c_addr > UINT16_MAX) {
106*91f16700Schasinglulu 			return -FDT_ERR_BADVALUE;
107*91f16700Schasinglulu 		}
108*91f16700Schasinglulu 
109*91f16700Schasinglulu 		i2c_node = fdt_parent_offset(fdt, pmic_node);
110*91f16700Schasinglulu 		if (i2c_node < 0) {
111*91f16700Schasinglulu 			return -FDT_ERR_NOTFOUND;
112*91f16700Schasinglulu 		}
113*91f16700Schasinglulu 	}
114*91f16700Schasinglulu 
115*91f16700Schasinglulu 	dt_fill_device_info(i2c_info, i2c_node);
116*91f16700Schasinglulu 	if (i2c_info->base == 0U) {
117*91f16700Schasinglulu 		return -FDT_ERR_NOTFOUND;
118*91f16700Schasinglulu 	}
119*91f16700Schasinglulu 
120*91f16700Schasinglulu 	return stm32_i2c_get_setup_from_fdt(fdt, i2c_node, init);
121*91f16700Schasinglulu }
122*91f16700Schasinglulu 
123*91f16700Schasinglulu bool initialize_pmic_i2c(void)
124*91f16700Schasinglulu {
125*91f16700Schasinglulu 	int ret;
126*91f16700Schasinglulu 	struct dt_node_info i2c_info;
127*91f16700Schasinglulu 	struct i2c_handle_s *i2c = &i2c_handle;
128*91f16700Schasinglulu 	struct stm32_i2c_init_s i2c_init;
129*91f16700Schasinglulu 
130*91f16700Schasinglulu 	ret = dt_pmic_i2c_config(&i2c_info, &i2c_init);
131*91f16700Schasinglulu 	if (ret < 0) {
132*91f16700Schasinglulu 		ERROR("I2C configuration failed %d\n", ret);
133*91f16700Schasinglulu 		panic();
134*91f16700Schasinglulu 	}
135*91f16700Schasinglulu 
136*91f16700Schasinglulu 	if (ret != 0) {
137*91f16700Schasinglulu 		return false;
138*91f16700Schasinglulu 	}
139*91f16700Schasinglulu 
140*91f16700Schasinglulu 	/* Initialize PMIC I2C */
141*91f16700Schasinglulu 	i2c->i2c_base_addr		= i2c_info.base;
142*91f16700Schasinglulu 	i2c->dt_status			= i2c_info.status;
143*91f16700Schasinglulu 	i2c->clock			= i2c_info.clock;
144*91f16700Schasinglulu 	i2c->i2c_state			= I2C_STATE_RESET;
145*91f16700Schasinglulu 	i2c_init.own_address1		= pmic_i2c_addr;
146*91f16700Schasinglulu 	i2c_init.addressing_mode	= I2C_ADDRESSINGMODE_7BIT;
147*91f16700Schasinglulu 	i2c_init.dual_address_mode	= I2C_DUALADDRESS_DISABLE;
148*91f16700Schasinglulu 	i2c_init.own_address2		= 0;
149*91f16700Schasinglulu 	i2c_init.own_address2_masks	= I2C_OAR2_OA2NOMASK;
150*91f16700Schasinglulu 	i2c_init.general_call_mode	= I2C_GENERALCALL_DISABLE;
151*91f16700Schasinglulu 	i2c_init.no_stretch_mode	= I2C_NOSTRETCH_DISABLE;
152*91f16700Schasinglulu 	i2c_init.analog_filter		= 1;
153*91f16700Schasinglulu 	i2c_init.digital_filter_coef	= 0;
154*91f16700Schasinglulu 
155*91f16700Schasinglulu 	ret = stm32_i2c_init(i2c, &i2c_init);
156*91f16700Schasinglulu 	if (ret != 0) {
157*91f16700Schasinglulu 		ERROR("Cannot initialize I2C %x (%d)\n",
158*91f16700Schasinglulu 		      i2c->i2c_base_addr, ret);
159*91f16700Schasinglulu 		panic();
160*91f16700Schasinglulu 	}
161*91f16700Schasinglulu 
162*91f16700Schasinglulu 	if (!stm32_i2c_is_device_ready(i2c, pmic_i2c_addr, 1,
163*91f16700Schasinglulu 				       I2C_TIMEOUT_BUSY_MS)) {
164*91f16700Schasinglulu 		ERROR("I2C device not ready\n");
165*91f16700Schasinglulu 		panic();
166*91f16700Schasinglulu 	}
167*91f16700Schasinglulu 
168*91f16700Schasinglulu 	stpmic1_bind_i2c(i2c, (uint16_t)pmic_i2c_addr);
169*91f16700Schasinglulu 
170*91f16700Schasinglulu 	return true;
171*91f16700Schasinglulu }
172*91f16700Schasinglulu 
173*91f16700Schasinglulu static void register_pmic_shared_peripherals(void)
174*91f16700Schasinglulu {
175*91f16700Schasinglulu 	uintptr_t i2c_base = i2c_handle.i2c_base_addr;
176*91f16700Schasinglulu 
177*91f16700Schasinglulu 	if (dt_pmic_is_secure()) {
178*91f16700Schasinglulu 		stm32mp_register_secure_periph_iomem(i2c_base);
179*91f16700Schasinglulu 	} else {
180*91f16700Schasinglulu 		if (i2c_base != 0U) {
181*91f16700Schasinglulu 			stm32mp_register_non_secure_periph_iomem(i2c_base);
182*91f16700Schasinglulu 		}
183*91f16700Schasinglulu 	}
184*91f16700Schasinglulu }
185*91f16700Schasinglulu 
186*91f16700Schasinglulu void initialize_pmic(void)
187*91f16700Schasinglulu {
188*91f16700Schasinglulu 	if (!initialize_pmic_i2c()) {
189*91f16700Schasinglulu 		VERBOSE("No PMIC\n");
190*91f16700Schasinglulu 		return;
191*91f16700Schasinglulu 	}
192*91f16700Schasinglulu 
193*91f16700Schasinglulu 	register_pmic_shared_peripherals();
194*91f16700Schasinglulu 
195*91f16700Schasinglulu 	if (register_pmic() < 0) {
196*91f16700Schasinglulu 		panic();
197*91f16700Schasinglulu 	}
198*91f16700Schasinglulu 
199*91f16700Schasinglulu 	if (stpmic1_powerctrl_on() < 0) {
200*91f16700Schasinglulu 		panic();
201*91f16700Schasinglulu 	}
202*91f16700Schasinglulu 
203*91f16700Schasinglulu }
204*91f16700Schasinglulu 
205*91f16700Schasinglulu #if DEBUG
206*91f16700Schasinglulu void print_pmic_info_and_debug(void)
207*91f16700Schasinglulu {
208*91f16700Schasinglulu 	unsigned long pmic_version;
209*91f16700Schasinglulu 
210*91f16700Schasinglulu 	if (stpmic1_get_version(&pmic_version) != 0) {
211*91f16700Schasinglulu 		ERROR("Failed to access PMIC\n");
212*91f16700Schasinglulu 		panic();
213*91f16700Schasinglulu 	}
214*91f16700Schasinglulu 
215*91f16700Schasinglulu 	INFO("PMIC version = 0x%02lx\n", pmic_version);
216*91f16700Schasinglulu }
217*91f16700Schasinglulu #endif
218*91f16700Schasinglulu 
219*91f16700Schasinglulu int pmic_ddr_power_init(enum ddr_type ddr_type)
220*91f16700Schasinglulu {
221*91f16700Schasinglulu 	int status;
222*91f16700Schasinglulu 	uint16_t buck3_min_mv;
223*91f16700Schasinglulu 	struct rdev *buck2, *buck3, *vref;
224*91f16700Schasinglulu 	struct rdev *ldo3 __unused;
225*91f16700Schasinglulu 
226*91f16700Schasinglulu 	buck2 = regulator_get_by_name("buck2");
227*91f16700Schasinglulu 	if (buck2 == NULL) {
228*91f16700Schasinglulu 		return -ENOENT;
229*91f16700Schasinglulu 	}
230*91f16700Schasinglulu 
231*91f16700Schasinglulu #if STM32MP15
232*91f16700Schasinglulu 	ldo3 = regulator_get_by_name("ldo3");
233*91f16700Schasinglulu 	if (ldo3 == NULL) {
234*91f16700Schasinglulu 		return -ENOENT;
235*91f16700Schasinglulu 	}
236*91f16700Schasinglulu #endif
237*91f16700Schasinglulu 
238*91f16700Schasinglulu 	vref = regulator_get_by_name("vref_ddr");
239*91f16700Schasinglulu 	if (vref == NULL) {
240*91f16700Schasinglulu 		return -ENOENT;
241*91f16700Schasinglulu 	}
242*91f16700Schasinglulu 
243*91f16700Schasinglulu 	switch (ddr_type) {
244*91f16700Schasinglulu 	case STM32MP_DDR3:
245*91f16700Schasinglulu #if STM32MP15
246*91f16700Schasinglulu 		status = regulator_set_flag(ldo3, REGUL_SINK_SOURCE);
247*91f16700Schasinglulu 		if (status != 0) {
248*91f16700Schasinglulu 			return status;
249*91f16700Schasinglulu 		}
250*91f16700Schasinglulu #endif
251*91f16700Schasinglulu 
252*91f16700Schasinglulu 		status = regulator_set_min_voltage(buck2);
253*91f16700Schasinglulu 		if (status != 0) {
254*91f16700Schasinglulu 			return status;
255*91f16700Schasinglulu 		}
256*91f16700Schasinglulu 
257*91f16700Schasinglulu 		status = regulator_enable(buck2);
258*91f16700Schasinglulu 		if (status != 0) {
259*91f16700Schasinglulu 			return status;
260*91f16700Schasinglulu 		}
261*91f16700Schasinglulu 
262*91f16700Schasinglulu 		status = regulator_enable(vref);
263*91f16700Schasinglulu 		if (status != 0) {
264*91f16700Schasinglulu 			return status;
265*91f16700Schasinglulu 		}
266*91f16700Schasinglulu 
267*91f16700Schasinglulu #if STM32MP15
268*91f16700Schasinglulu 		status = regulator_enable(ldo3);
269*91f16700Schasinglulu 		if (status != 0) {
270*91f16700Schasinglulu 			return status;
271*91f16700Schasinglulu 		}
272*91f16700Schasinglulu #endif
273*91f16700Schasinglulu 		break;
274*91f16700Schasinglulu 
275*91f16700Schasinglulu 	case STM32MP_LPDDR2:
276*91f16700Schasinglulu 	case STM32MP_LPDDR3:
277*91f16700Schasinglulu 		/*
278*91f16700Schasinglulu 		 * Set LDO3 to 1.8V
279*91f16700Schasinglulu 		 * Set LDO3 to bypass mode if BUCK3 = 1.8V
280*91f16700Schasinglulu 		 * Set LDO3 to normal mode if BUCK3 != 1.8V
281*91f16700Schasinglulu 		 */
282*91f16700Schasinglulu 		buck3 = regulator_get_by_name("buck3");
283*91f16700Schasinglulu 		if (buck3 == NULL) {
284*91f16700Schasinglulu 			return -ENOENT;
285*91f16700Schasinglulu 		}
286*91f16700Schasinglulu 
287*91f16700Schasinglulu 		regulator_get_range(buck3, &buck3_min_mv, NULL);
288*91f16700Schasinglulu 
289*91f16700Schasinglulu #if STM32MP15
290*91f16700Schasinglulu 		if (buck3_min_mv != 1800) {
291*91f16700Schasinglulu 			status = regulator_set_min_voltage(ldo3);
292*91f16700Schasinglulu 			if (status != 0) {
293*91f16700Schasinglulu 				return status;
294*91f16700Schasinglulu 			}
295*91f16700Schasinglulu 		} else {
296*91f16700Schasinglulu 			status = regulator_set_flag(ldo3, REGUL_ENABLE_BYPASS);
297*91f16700Schasinglulu 			if (status != 0) {
298*91f16700Schasinglulu 				return status;
299*91f16700Schasinglulu 			}
300*91f16700Schasinglulu 		}
301*91f16700Schasinglulu #endif
302*91f16700Schasinglulu 
303*91f16700Schasinglulu 		status = regulator_set_min_voltage(buck2);
304*91f16700Schasinglulu 		if (status != 0) {
305*91f16700Schasinglulu 			return status;
306*91f16700Schasinglulu 		}
307*91f16700Schasinglulu 
308*91f16700Schasinglulu #if STM32MP15
309*91f16700Schasinglulu 		status = regulator_enable(ldo3);
310*91f16700Schasinglulu 		if (status != 0) {
311*91f16700Schasinglulu 			return status;
312*91f16700Schasinglulu 		}
313*91f16700Schasinglulu #endif
314*91f16700Schasinglulu 
315*91f16700Schasinglulu 		status = regulator_enable(buck2);
316*91f16700Schasinglulu 		if (status != 0) {
317*91f16700Schasinglulu 			return status;
318*91f16700Schasinglulu 		}
319*91f16700Schasinglulu 
320*91f16700Schasinglulu 		status = regulator_enable(vref);
321*91f16700Schasinglulu 		if (status != 0) {
322*91f16700Schasinglulu 			return status;
323*91f16700Schasinglulu 		}
324*91f16700Schasinglulu 		break;
325*91f16700Schasinglulu 
326*91f16700Schasinglulu 	default:
327*91f16700Schasinglulu 		break;
328*91f16700Schasinglulu 	};
329*91f16700Schasinglulu 
330*91f16700Schasinglulu 	return 0;
331*91f16700Schasinglulu }
332*91f16700Schasinglulu 
333*91f16700Schasinglulu int pmic_voltages_init(void)
334*91f16700Schasinglulu {
335*91f16700Schasinglulu #if STM32MP13
336*91f16700Schasinglulu 	struct rdev *buck1, *buck4;
337*91f16700Schasinglulu 	int status;
338*91f16700Schasinglulu 
339*91f16700Schasinglulu 	buck1 = regulator_get_by_name("buck1");
340*91f16700Schasinglulu 	if (buck1 == NULL) {
341*91f16700Schasinglulu 		return -ENOENT;
342*91f16700Schasinglulu 	}
343*91f16700Schasinglulu 
344*91f16700Schasinglulu 	buck4 = regulator_get_by_name("buck4");
345*91f16700Schasinglulu 	if (buck4 == NULL) {
346*91f16700Schasinglulu 		return -ENOENT;
347*91f16700Schasinglulu 	}
348*91f16700Schasinglulu 
349*91f16700Schasinglulu 	status = regulator_set_min_voltage(buck1);
350*91f16700Schasinglulu 	if (status != 0) {
351*91f16700Schasinglulu 		return status;
352*91f16700Schasinglulu 	}
353*91f16700Schasinglulu 
354*91f16700Schasinglulu 	status = regulator_set_min_voltage(buck4);
355*91f16700Schasinglulu 	if (status != 0) {
356*91f16700Schasinglulu 		return status;
357*91f16700Schasinglulu 	}
358*91f16700Schasinglulu #endif
359*91f16700Schasinglulu 
360*91f16700Schasinglulu 	return 0;
361*91f16700Schasinglulu }
362*91f16700Schasinglulu 
363*91f16700Schasinglulu enum {
364*91f16700Schasinglulu 	STPMIC1_BUCK1 = 0,
365*91f16700Schasinglulu 	STPMIC1_BUCK2,
366*91f16700Schasinglulu 	STPMIC1_BUCK3,
367*91f16700Schasinglulu 	STPMIC1_BUCK4,
368*91f16700Schasinglulu 	STPMIC1_LDO1,
369*91f16700Schasinglulu 	STPMIC1_LDO2,
370*91f16700Schasinglulu 	STPMIC1_LDO3,
371*91f16700Schasinglulu 	STPMIC1_LDO4,
372*91f16700Schasinglulu 	STPMIC1_LDO5,
373*91f16700Schasinglulu 	STPMIC1_LDO6,
374*91f16700Schasinglulu 	STPMIC1_VREF_DDR,
375*91f16700Schasinglulu 	STPMIC1_BOOST,
376*91f16700Schasinglulu 	STPMIC1_VBUS_OTG,
377*91f16700Schasinglulu 	STPMIC1_SW_OUT,
378*91f16700Schasinglulu };
379*91f16700Schasinglulu 
380*91f16700Schasinglulu static int pmic_set_state(const struct regul_description *desc, bool enable)
381*91f16700Schasinglulu {
382*91f16700Schasinglulu 	VERBOSE("%s: set state to %d\n", desc->node_name, enable);
383*91f16700Schasinglulu 
384*91f16700Schasinglulu 	if (enable == STATE_ENABLE) {
385*91f16700Schasinglulu 		return stpmic1_regulator_enable(desc->node_name);
386*91f16700Schasinglulu 	} else {
387*91f16700Schasinglulu 		return stpmic1_regulator_disable(desc->node_name);
388*91f16700Schasinglulu 	}
389*91f16700Schasinglulu }
390*91f16700Schasinglulu 
391*91f16700Schasinglulu static int pmic_get_state(const struct regul_description *desc)
392*91f16700Schasinglulu {
393*91f16700Schasinglulu 	VERBOSE("%s: get state\n", desc->node_name);
394*91f16700Schasinglulu 
395*91f16700Schasinglulu 	return stpmic1_is_regulator_enabled(desc->node_name);
396*91f16700Schasinglulu }
397*91f16700Schasinglulu 
398*91f16700Schasinglulu static int pmic_get_voltage(const struct regul_description *desc)
399*91f16700Schasinglulu {
400*91f16700Schasinglulu 	VERBOSE("%s: get volt\n", desc->node_name);
401*91f16700Schasinglulu 
402*91f16700Schasinglulu 	return stpmic1_regulator_voltage_get(desc->node_name);
403*91f16700Schasinglulu }
404*91f16700Schasinglulu 
405*91f16700Schasinglulu static int pmic_set_voltage(const struct regul_description *desc, uint16_t mv)
406*91f16700Schasinglulu {
407*91f16700Schasinglulu 	VERBOSE("%s: get volt\n", desc->node_name);
408*91f16700Schasinglulu 
409*91f16700Schasinglulu 	return stpmic1_regulator_voltage_set(desc->node_name, mv);
410*91f16700Schasinglulu }
411*91f16700Schasinglulu 
412*91f16700Schasinglulu static int pmic_list_voltages(const struct regul_description *desc,
413*91f16700Schasinglulu 			      const uint16_t **levels, size_t *count)
414*91f16700Schasinglulu {
415*91f16700Schasinglulu 	VERBOSE("%s: list volt\n", desc->node_name);
416*91f16700Schasinglulu 
417*91f16700Schasinglulu 	return stpmic1_regulator_levels_mv(desc->node_name, levels, count);
418*91f16700Schasinglulu }
419*91f16700Schasinglulu 
420*91f16700Schasinglulu static int pmic_set_flag(const struct regul_description *desc, uint16_t flag)
421*91f16700Schasinglulu {
422*91f16700Schasinglulu 	VERBOSE("%s: set_flag 0x%x\n", desc->node_name, flag);
423*91f16700Schasinglulu 
424*91f16700Schasinglulu 	switch (flag) {
425*91f16700Schasinglulu 	case REGUL_OCP:
426*91f16700Schasinglulu 		return stpmic1_regulator_icc_set(desc->node_name);
427*91f16700Schasinglulu 
428*91f16700Schasinglulu 	case REGUL_ACTIVE_DISCHARGE:
429*91f16700Schasinglulu 		return stpmic1_active_discharge_mode_set(desc->node_name);
430*91f16700Schasinglulu 
431*91f16700Schasinglulu 	case REGUL_PULL_DOWN:
432*91f16700Schasinglulu 		return stpmic1_regulator_pull_down_set(desc->node_name);
433*91f16700Schasinglulu 
434*91f16700Schasinglulu 	case REGUL_MASK_RESET:
435*91f16700Schasinglulu 		return stpmic1_regulator_mask_reset_set(desc->node_name);
436*91f16700Schasinglulu 
437*91f16700Schasinglulu 	case REGUL_SINK_SOURCE:
438*91f16700Schasinglulu 		return stpmic1_regulator_sink_mode_set(desc->node_name);
439*91f16700Schasinglulu 
440*91f16700Schasinglulu 	case REGUL_ENABLE_BYPASS:
441*91f16700Schasinglulu 		return stpmic1_regulator_bypass_mode_set(desc->node_name);
442*91f16700Schasinglulu 
443*91f16700Schasinglulu 	default:
444*91f16700Schasinglulu 		return -EINVAL;
445*91f16700Schasinglulu 	}
446*91f16700Schasinglulu }
447*91f16700Schasinglulu 
448*91f16700Schasinglulu static const struct regul_ops pmic_ops = {
449*91f16700Schasinglulu 	.set_state = pmic_set_state,
450*91f16700Schasinglulu 	.get_state = pmic_get_state,
451*91f16700Schasinglulu 	.set_voltage = pmic_set_voltage,
452*91f16700Schasinglulu 	.get_voltage = pmic_get_voltage,
453*91f16700Schasinglulu 	.list_voltages = pmic_list_voltages,
454*91f16700Schasinglulu 	.set_flag = pmic_set_flag,
455*91f16700Schasinglulu };
456*91f16700Schasinglulu 
457*91f16700Schasinglulu #define DEFINE_REGU(name) { \
458*91f16700Schasinglulu 	.node_name = (name), \
459*91f16700Schasinglulu 	.ops = &pmic_ops, \
460*91f16700Schasinglulu 	.driver_data = NULL, \
461*91f16700Schasinglulu 	.enable_ramp_delay = 1000, \
462*91f16700Schasinglulu }
463*91f16700Schasinglulu 
464*91f16700Schasinglulu static const struct regul_description pmic_regs[NB_REG] = {
465*91f16700Schasinglulu 	[STPMIC1_BUCK1] = DEFINE_REGU("buck1"),
466*91f16700Schasinglulu 	[STPMIC1_BUCK2] = DEFINE_REGU("buck2"),
467*91f16700Schasinglulu 	[STPMIC1_BUCK3] = DEFINE_REGU("buck3"),
468*91f16700Schasinglulu 	[STPMIC1_BUCK4] = DEFINE_REGU("buck4"),
469*91f16700Schasinglulu 	[STPMIC1_LDO1] = DEFINE_REGU("ldo1"),
470*91f16700Schasinglulu 	[STPMIC1_LDO2] = DEFINE_REGU("ldo2"),
471*91f16700Schasinglulu 	[STPMIC1_LDO3] = DEFINE_REGU("ldo3"),
472*91f16700Schasinglulu 	[STPMIC1_LDO4] = DEFINE_REGU("ldo4"),
473*91f16700Schasinglulu 	[STPMIC1_LDO5] = DEFINE_REGU("ldo5"),
474*91f16700Schasinglulu 	[STPMIC1_LDO6] = DEFINE_REGU("ldo6"),
475*91f16700Schasinglulu 	[STPMIC1_VREF_DDR] = DEFINE_REGU("vref_ddr"),
476*91f16700Schasinglulu 	[STPMIC1_BOOST] = DEFINE_REGU("boost"),
477*91f16700Schasinglulu 	[STPMIC1_VBUS_OTG] = DEFINE_REGU("pwr_sw1"),
478*91f16700Schasinglulu 	[STPMIC1_SW_OUT] = DEFINE_REGU("pwr_sw2"),
479*91f16700Schasinglulu };
480*91f16700Schasinglulu 
481*91f16700Schasinglulu static int register_pmic(void)
482*91f16700Schasinglulu {
483*91f16700Schasinglulu 	void *fdt;
484*91f16700Schasinglulu 	int pmic_node, regulators_node, subnode;
485*91f16700Schasinglulu 
486*91f16700Schasinglulu 	VERBOSE("Register pmic\n");
487*91f16700Schasinglulu 
488*91f16700Schasinglulu 	if (fdt_get_address(&fdt) == 0) {
489*91f16700Schasinglulu 		return -FDT_ERR_NOTFOUND;
490*91f16700Schasinglulu 	}
491*91f16700Schasinglulu 
492*91f16700Schasinglulu 	pmic_node = dt_get_pmic_node(fdt);
493*91f16700Schasinglulu 	if (pmic_node < 0) {
494*91f16700Schasinglulu 		return pmic_node;
495*91f16700Schasinglulu 	}
496*91f16700Schasinglulu 
497*91f16700Schasinglulu 	regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators");
498*91f16700Schasinglulu 	if (regulators_node < 0) {
499*91f16700Schasinglulu 		return -ENOENT;
500*91f16700Schasinglulu 	}
501*91f16700Schasinglulu 
502*91f16700Schasinglulu 	fdt_for_each_subnode(subnode, fdt, regulators_node) {
503*91f16700Schasinglulu 		const char *reg_name = fdt_get_name(fdt, subnode, NULL);
504*91f16700Schasinglulu 		const struct regul_description *desc;
505*91f16700Schasinglulu 		unsigned int i;
506*91f16700Schasinglulu 		int ret;
507*91f16700Schasinglulu 
508*91f16700Schasinglulu 		for (i = 0U; i < NB_REG; i++) {
509*91f16700Schasinglulu 			desc = &pmic_regs[i];
510*91f16700Schasinglulu 			if (strcmp(desc->node_name, reg_name) == 0) {
511*91f16700Schasinglulu 				break;
512*91f16700Schasinglulu 			}
513*91f16700Schasinglulu 		}
514*91f16700Schasinglulu 		assert(i < NB_REG);
515*91f16700Schasinglulu 
516*91f16700Schasinglulu 		ret = regulator_register(desc, subnode);
517*91f16700Schasinglulu 		if (ret != 0) {
518*91f16700Schasinglulu 			WARN("%s:%d failed to register %s\n", __func__,
519*91f16700Schasinglulu 			     __LINE__, reg_name);
520*91f16700Schasinglulu 			return ret;
521*91f16700Schasinglulu 		}
522*91f16700Schasinglulu 	}
523*91f16700Schasinglulu 
524*91f16700Schasinglulu 	return 0;
525*91f16700Schasinglulu }
526