xref: /rk3399_rockchip-uboot/drivers/power/regulator/max77686.c (revision 1757df4693fcde9fb4d4de02a22cc74d6f5caec1)
1*1757df46SPrzemyslaw Marczak /*
2*1757df46SPrzemyslaw Marczak  *  Copyright (C) 2012-2015 Samsung Electronics
3*1757df46SPrzemyslaw Marczak  *
4*1757df46SPrzemyslaw Marczak  *  Rajeshwari Shinde <rajeshwari.s@samsung.com>
5*1757df46SPrzemyslaw Marczak  *  Przemyslaw Marczak <p.marczak@samsung.com>
6*1757df46SPrzemyslaw Marczak  *
7*1757df46SPrzemyslaw Marczak  * SPDX-License-Identifier:	GPL-2.0+
8*1757df46SPrzemyslaw Marczak  */
9*1757df46SPrzemyslaw Marczak 
10*1757df46SPrzemyslaw Marczak #include <common.h>
11*1757df46SPrzemyslaw Marczak #include <fdtdec.h>
12*1757df46SPrzemyslaw Marczak #include <errno.h>
13*1757df46SPrzemyslaw Marczak #include <dm.h>
14*1757df46SPrzemyslaw Marczak #include <i2c.h>
15*1757df46SPrzemyslaw Marczak #include <power/pmic.h>
16*1757df46SPrzemyslaw Marczak #include <power/regulator.h>
17*1757df46SPrzemyslaw Marczak #include <power/max77686_pmic.h>
18*1757df46SPrzemyslaw Marczak 
19*1757df46SPrzemyslaw Marczak DECLARE_GLOBAL_DATA_PTR;
20*1757df46SPrzemyslaw Marczak 
21*1757df46SPrzemyslaw Marczak #define MODE(_id, _val, _name) { \
22*1757df46SPrzemyslaw Marczak 	.id = _id, \
23*1757df46SPrzemyslaw Marczak 	.register_value = _val, \
24*1757df46SPrzemyslaw Marczak 	.name = _name, \
25*1757df46SPrzemyslaw Marczak }
26*1757df46SPrzemyslaw Marczak 
27*1757df46SPrzemyslaw Marczak /* LDO: 1,3,4,5,9,17,18,19,20,21,22,23,24,26,26,27 */
28*1757df46SPrzemyslaw Marczak static struct dm_regulator_mode max77686_ldo_mode_standby1[] = {
29*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_OFF, MAX77686_LDO_MODE_OFF, "OFF"),
30*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_LPM, MAX77686_LDO_MODE_LPM, "LPM"),
31*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_STANDBY_LPM, MAX77686_LDO_MODE_STANDBY_LPM, "ON/LPM"),
32*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_ON, MAX77686_LDO_MODE_ON, "ON"),
33*1757df46SPrzemyslaw Marczak };
34*1757df46SPrzemyslaw Marczak 
35*1757df46SPrzemyslaw Marczak /* LDO: 2,6,7,8,10,11,12,14,15,16 */
36*1757df46SPrzemyslaw Marczak static struct dm_regulator_mode max77686_ldo_mode_standby2[] = {
37*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_OFF, MAX77686_LDO_MODE_OFF, "OFF"),
38*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_STANDBY, MAX77686_LDO_MODE_STANDBY, "ON/OFF"),
39*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_STANDBY_LPM, MAX77686_LDO_MODE_STANDBY_LPM, "ON/LPM"),
40*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_ON, MAX77686_LDO_MODE_ON, "ON"),
41*1757df46SPrzemyslaw Marczak };
42*1757df46SPrzemyslaw Marczak 
43*1757df46SPrzemyslaw Marczak /* Buck: 1 */
44*1757df46SPrzemyslaw Marczak static struct dm_regulator_mode max77686_buck_mode_standby[] = {
45*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
46*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_STANDBY, MAX77686_BUCK_MODE_STANDBY, "ON/OFF"),
47*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
48*1757df46SPrzemyslaw Marczak };
49*1757df46SPrzemyslaw Marczak 
50*1757df46SPrzemyslaw Marczak /* Buck: 2,3,4 */
51*1757df46SPrzemyslaw Marczak static struct dm_regulator_mode max77686_buck_mode_lpm[] = {
52*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
53*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_STANDBY, MAX77686_BUCK_MODE_STANDBY, "ON/OFF"),
54*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_LPM, MAX77686_BUCK_MODE_LPM, "LPM"),
55*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
56*1757df46SPrzemyslaw Marczak };
57*1757df46SPrzemyslaw Marczak 
58*1757df46SPrzemyslaw Marczak /* Buck: 5,6,7,8,9 */
59*1757df46SPrzemyslaw Marczak static struct dm_regulator_mode max77686_buck_mode_onoff[] = {
60*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
61*1757df46SPrzemyslaw Marczak 	MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
62*1757df46SPrzemyslaw Marczak };
63*1757df46SPrzemyslaw Marczak 
64*1757df46SPrzemyslaw Marczak static const char max77686_buck_addr[] = {
65*1757df46SPrzemyslaw Marczak 	0xff, 0x10, 0x12, 0x1c, 0x26, 0x30, 0x32, 0x34, 0x36, 0x38
66*1757df46SPrzemyslaw Marczak };
67*1757df46SPrzemyslaw Marczak 
68*1757df46SPrzemyslaw Marczak static int max77686_buck_volt2hex(int buck, int uV)
69*1757df46SPrzemyslaw Marczak {
70*1757df46SPrzemyslaw Marczak 	unsigned int hex = 0;
71*1757df46SPrzemyslaw Marczak 	unsigned int hex_max = 0;
72*1757df46SPrzemyslaw Marczak 
73*1757df46SPrzemyslaw Marczak 	switch (buck) {
74*1757df46SPrzemyslaw Marczak 	case 2:
75*1757df46SPrzemyslaw Marczak 	case 3:
76*1757df46SPrzemyslaw Marczak 	case 4:
77*1757df46SPrzemyslaw Marczak 		/* hex = (uV - 600000) / 12500; */
78*1757df46SPrzemyslaw Marczak 		hex = (uV - MAX77686_BUCK_UV_LMIN) / MAX77686_BUCK_UV_LSTEP;
79*1757df46SPrzemyslaw Marczak 		hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
80*1757df46SPrzemyslaw Marczak 		/**
81*1757df46SPrzemyslaw Marczak 		 * Those use voltage scaller - temporary not implemented
82*1757df46SPrzemyslaw Marczak 		 * so return just 0
83*1757df46SPrzemyslaw Marczak 		 */
84*1757df46SPrzemyslaw Marczak 		return -ENOSYS;
85*1757df46SPrzemyslaw Marczak 	default:
86*1757df46SPrzemyslaw Marczak 		/* hex = (uV - 750000) / 50000; */
87*1757df46SPrzemyslaw Marczak 		hex = (uV - MAX77686_BUCK_UV_HMIN) / MAX77686_BUCK_UV_HSTEP;
88*1757df46SPrzemyslaw Marczak 		hex_max = MAX77686_BUCK_VOLT_MAX_HEX;
89*1757df46SPrzemyslaw Marczak 		break;
90*1757df46SPrzemyslaw Marczak 	}
91*1757df46SPrzemyslaw Marczak 
92*1757df46SPrzemyslaw Marczak 	if (hex >= 0 && hex <= hex_max)
93*1757df46SPrzemyslaw Marczak 		return hex;
94*1757df46SPrzemyslaw Marczak 
95*1757df46SPrzemyslaw Marczak 	error("Value: %d uV is wrong for BUCK%d", uV, buck);
96*1757df46SPrzemyslaw Marczak 	return -EINVAL;
97*1757df46SPrzemyslaw Marczak }
98*1757df46SPrzemyslaw Marczak 
99*1757df46SPrzemyslaw Marczak static int max77686_buck_hex2volt(int buck, int hex)
100*1757df46SPrzemyslaw Marczak {
101*1757df46SPrzemyslaw Marczak 	unsigned uV = 0;
102*1757df46SPrzemyslaw Marczak 	unsigned int hex_max = 0;
103*1757df46SPrzemyslaw Marczak 
104*1757df46SPrzemyslaw Marczak 	if (hex < 0)
105*1757df46SPrzemyslaw Marczak 		goto bad_hex;
106*1757df46SPrzemyslaw Marczak 
107*1757df46SPrzemyslaw Marczak 	switch (buck) {
108*1757df46SPrzemyslaw Marczak 	case 2:
109*1757df46SPrzemyslaw Marczak 	case 3:
110*1757df46SPrzemyslaw Marczak 	case 4:
111*1757df46SPrzemyslaw Marczak 		hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
112*1757df46SPrzemyslaw Marczak 		if (hex > hex_max)
113*1757df46SPrzemyslaw Marczak 			goto bad_hex;
114*1757df46SPrzemyslaw Marczak 
115*1757df46SPrzemyslaw Marczak 		/* uV = hex * 12500 + 600000; */
116*1757df46SPrzemyslaw Marczak 		uV = hex * MAX77686_BUCK_UV_LSTEP + MAX77686_BUCK_UV_LMIN;
117*1757df46SPrzemyslaw Marczak 		break;
118*1757df46SPrzemyslaw Marczak 	default:
119*1757df46SPrzemyslaw Marczak 		hex_max = MAX77686_BUCK_VOLT_MAX_HEX;
120*1757df46SPrzemyslaw Marczak 		if (hex > hex_max)
121*1757df46SPrzemyslaw Marczak 			goto bad_hex;
122*1757df46SPrzemyslaw Marczak 
123*1757df46SPrzemyslaw Marczak 		/* uV = hex * 50000 + 750000; */
124*1757df46SPrzemyslaw Marczak 		uV = hex * MAX77686_BUCK_UV_HSTEP + MAX77686_BUCK_UV_HMIN;
125*1757df46SPrzemyslaw Marczak 		break;
126*1757df46SPrzemyslaw Marczak 	}
127*1757df46SPrzemyslaw Marczak 
128*1757df46SPrzemyslaw Marczak 	return uV;
129*1757df46SPrzemyslaw Marczak 
130*1757df46SPrzemyslaw Marczak bad_hex:
131*1757df46SPrzemyslaw Marczak 	error("Value: %#x is wrong for BUCK%d", hex, buck);
132*1757df46SPrzemyslaw Marczak 	return -EINVAL;
133*1757df46SPrzemyslaw Marczak }
134*1757df46SPrzemyslaw Marczak 
135*1757df46SPrzemyslaw Marczak static int max77686_ldo_volt2hex(int ldo, int uV)
136*1757df46SPrzemyslaw Marczak {
137*1757df46SPrzemyslaw Marczak 	unsigned int hex = 0;
138*1757df46SPrzemyslaw Marczak 
139*1757df46SPrzemyslaw Marczak 	switch (ldo) {
140*1757df46SPrzemyslaw Marczak 	case 1:
141*1757df46SPrzemyslaw Marczak 	case 2:
142*1757df46SPrzemyslaw Marczak 	case 6:
143*1757df46SPrzemyslaw Marczak 	case 7:
144*1757df46SPrzemyslaw Marczak 	case 8:
145*1757df46SPrzemyslaw Marczak 	case 15:
146*1757df46SPrzemyslaw Marczak 		hex = (uV - MAX77686_LDO_UV_MIN) / MAX77686_LDO_UV_LSTEP;
147*1757df46SPrzemyslaw Marczak 		/* hex = (uV - 800000) / 25000; */
148*1757df46SPrzemyslaw Marczak 		break;
149*1757df46SPrzemyslaw Marczak 	default:
150*1757df46SPrzemyslaw Marczak 		hex = (uV - MAX77686_LDO_UV_MIN) / MAX77686_LDO_UV_HSTEP;
151*1757df46SPrzemyslaw Marczak 		/* hex = (uV - 800000) / 50000; */
152*1757df46SPrzemyslaw Marczak 	}
153*1757df46SPrzemyslaw Marczak 
154*1757df46SPrzemyslaw Marczak 	if (hex >= 0 && hex <= MAX77686_LDO_VOLT_MAX_HEX)
155*1757df46SPrzemyslaw Marczak 		return hex;
156*1757df46SPrzemyslaw Marczak 
157*1757df46SPrzemyslaw Marczak 	error("Value: %d uV is wrong for LDO%d", uV, ldo);
158*1757df46SPrzemyslaw Marczak 	return -EINVAL;
159*1757df46SPrzemyslaw Marczak }
160*1757df46SPrzemyslaw Marczak 
161*1757df46SPrzemyslaw Marczak static int max77686_ldo_hex2volt(int ldo, int hex)
162*1757df46SPrzemyslaw Marczak {
163*1757df46SPrzemyslaw Marczak 	unsigned int uV = 0;
164*1757df46SPrzemyslaw Marczak 
165*1757df46SPrzemyslaw Marczak 	if (hex > MAX77686_LDO_VOLT_MAX_HEX)
166*1757df46SPrzemyslaw Marczak 		goto bad_hex;
167*1757df46SPrzemyslaw Marczak 
168*1757df46SPrzemyslaw Marczak 	switch (ldo) {
169*1757df46SPrzemyslaw Marczak 	case 1:
170*1757df46SPrzemyslaw Marczak 	case 2:
171*1757df46SPrzemyslaw Marczak 	case 6:
172*1757df46SPrzemyslaw Marczak 	case 7:
173*1757df46SPrzemyslaw Marczak 	case 8:
174*1757df46SPrzemyslaw Marczak 	case 15:
175*1757df46SPrzemyslaw Marczak 		/* uV = hex * 25000 + 800000; */
176*1757df46SPrzemyslaw Marczak 		uV = hex * MAX77686_LDO_UV_LSTEP + MAX77686_LDO_UV_MIN;
177*1757df46SPrzemyslaw Marczak 		break;
178*1757df46SPrzemyslaw Marczak 	default:
179*1757df46SPrzemyslaw Marczak 		/* uV = hex * 50000 + 800000; */
180*1757df46SPrzemyslaw Marczak 		uV = hex * MAX77686_LDO_UV_HSTEP + MAX77686_LDO_UV_MIN;
181*1757df46SPrzemyslaw Marczak 	}
182*1757df46SPrzemyslaw Marczak 
183*1757df46SPrzemyslaw Marczak 	return uV;
184*1757df46SPrzemyslaw Marczak 
185*1757df46SPrzemyslaw Marczak bad_hex:
186*1757df46SPrzemyslaw Marczak 	error("Value: %#x is wrong for ldo%d", hex, ldo);
187*1757df46SPrzemyslaw Marczak 	return -EINVAL;
188*1757df46SPrzemyslaw Marczak }
189*1757df46SPrzemyslaw Marczak 
190*1757df46SPrzemyslaw Marczak static int max77686_ldo_hex2mode(int ldo, int hex)
191*1757df46SPrzemyslaw Marczak {
192*1757df46SPrzemyslaw Marczak 	if (hex > MAX77686_LDO_MODE_MASK)
193*1757df46SPrzemyslaw Marczak 		return -EINVAL;
194*1757df46SPrzemyslaw Marczak 
195*1757df46SPrzemyslaw Marczak 	switch (hex) {
196*1757df46SPrzemyslaw Marczak 	case MAX77686_LDO_MODE_OFF:
197*1757df46SPrzemyslaw Marczak 		return OPMODE_OFF;
198*1757df46SPrzemyslaw Marczak 	case MAX77686_LDO_MODE_LPM: /* == MAX77686_LDO_MODE_STANDBY: */
199*1757df46SPrzemyslaw Marczak 		/* The same mode values but different meaning for each ldo */
200*1757df46SPrzemyslaw Marczak 		switch (ldo) {
201*1757df46SPrzemyslaw Marczak 		case 2:
202*1757df46SPrzemyslaw Marczak 		case 6:
203*1757df46SPrzemyslaw Marczak 		case 7:
204*1757df46SPrzemyslaw Marczak 		case 8:
205*1757df46SPrzemyslaw Marczak 		case 10:
206*1757df46SPrzemyslaw Marczak 		case 11:
207*1757df46SPrzemyslaw Marczak 		case 12:
208*1757df46SPrzemyslaw Marczak 		case 14:
209*1757df46SPrzemyslaw Marczak 		case 15:
210*1757df46SPrzemyslaw Marczak 		case 16:
211*1757df46SPrzemyslaw Marczak 			return OPMODE_STANDBY;
212*1757df46SPrzemyslaw Marczak 		default:
213*1757df46SPrzemyslaw Marczak 			return OPMODE_LPM;
214*1757df46SPrzemyslaw Marczak 		}
215*1757df46SPrzemyslaw Marczak 	case MAX77686_LDO_MODE_STANDBY_LPM:
216*1757df46SPrzemyslaw Marczak 		return OPMODE_STANDBY_LPM;
217*1757df46SPrzemyslaw Marczak 	case MAX77686_LDO_MODE_ON:
218*1757df46SPrzemyslaw Marczak 		return OPMODE_ON;
219*1757df46SPrzemyslaw Marczak 	default:
220*1757df46SPrzemyslaw Marczak 		return -EINVAL;
221*1757df46SPrzemyslaw Marczak 	}
222*1757df46SPrzemyslaw Marczak }
223*1757df46SPrzemyslaw Marczak 
224*1757df46SPrzemyslaw Marczak static int max77686_buck_hex2mode(int buck, int hex)
225*1757df46SPrzemyslaw Marczak {
226*1757df46SPrzemyslaw Marczak 	if (hex > MAX77686_BUCK_MODE_MASK)
227*1757df46SPrzemyslaw Marczak 		return -EINVAL;
228*1757df46SPrzemyslaw Marczak 
229*1757df46SPrzemyslaw Marczak 	switch (hex) {
230*1757df46SPrzemyslaw Marczak 	case MAX77686_BUCK_MODE_OFF:
231*1757df46SPrzemyslaw Marczak 		return OPMODE_OFF;
232*1757df46SPrzemyslaw Marczak 	case MAX77686_BUCK_MODE_ON:
233*1757df46SPrzemyslaw Marczak 		return OPMODE_ON;
234*1757df46SPrzemyslaw Marczak 	case MAX77686_BUCK_MODE_STANDBY:
235*1757df46SPrzemyslaw Marczak 		switch (buck) {
236*1757df46SPrzemyslaw Marczak 		case 1:
237*1757df46SPrzemyslaw Marczak 		case 2:
238*1757df46SPrzemyslaw Marczak 		case 3:
239*1757df46SPrzemyslaw Marczak 		case 4:
240*1757df46SPrzemyslaw Marczak 			return OPMODE_STANDBY;
241*1757df46SPrzemyslaw Marczak 		default:
242*1757df46SPrzemyslaw Marczak 			return -EINVAL;
243*1757df46SPrzemyslaw Marczak 		}
244*1757df46SPrzemyslaw Marczak 	case MAX77686_BUCK_MODE_LPM:
245*1757df46SPrzemyslaw Marczak 		switch (buck) {
246*1757df46SPrzemyslaw Marczak 		case 2:
247*1757df46SPrzemyslaw Marczak 		case 3:
248*1757df46SPrzemyslaw Marczak 		case 4:
249*1757df46SPrzemyslaw Marczak 			return OPMODE_LPM;
250*1757df46SPrzemyslaw Marczak 		default:
251*1757df46SPrzemyslaw Marczak 			return -EINVAL;
252*1757df46SPrzemyslaw Marczak 		}
253*1757df46SPrzemyslaw Marczak 	default:
254*1757df46SPrzemyslaw Marczak 		return -EINVAL;
255*1757df46SPrzemyslaw Marczak 	}
256*1757df46SPrzemyslaw Marczak }
257*1757df46SPrzemyslaw Marczak 
258*1757df46SPrzemyslaw Marczak static int max77686_buck_modes(int buck, struct dm_regulator_mode **modesp)
259*1757df46SPrzemyslaw Marczak {
260*1757df46SPrzemyslaw Marczak 	int ret = -EINVAL;
261*1757df46SPrzemyslaw Marczak 
262*1757df46SPrzemyslaw Marczak 	if (buck < 1 || buck > MAX77686_BUCK_NUM)
263*1757df46SPrzemyslaw Marczak 		return ret;
264*1757df46SPrzemyslaw Marczak 
265*1757df46SPrzemyslaw Marczak 	switch (buck) {
266*1757df46SPrzemyslaw Marczak 	case 1:
267*1757df46SPrzemyslaw Marczak 		*modesp = max77686_buck_mode_standby;
268*1757df46SPrzemyslaw Marczak 		ret = ARRAY_SIZE(max77686_buck_mode_standby);
269*1757df46SPrzemyslaw Marczak 		break;
270*1757df46SPrzemyslaw Marczak 	case 2:
271*1757df46SPrzemyslaw Marczak 	case 3:
272*1757df46SPrzemyslaw Marczak 	case 4:
273*1757df46SPrzemyslaw Marczak 		*modesp = max77686_buck_mode_lpm;
274*1757df46SPrzemyslaw Marczak 		ret = ARRAY_SIZE(max77686_buck_mode_lpm);
275*1757df46SPrzemyslaw Marczak 		break;
276*1757df46SPrzemyslaw Marczak 	default:
277*1757df46SPrzemyslaw Marczak 		*modesp = max77686_buck_mode_onoff;
278*1757df46SPrzemyslaw Marczak 		ret = ARRAY_SIZE(max77686_buck_mode_onoff);
279*1757df46SPrzemyslaw Marczak 	}
280*1757df46SPrzemyslaw Marczak 
281*1757df46SPrzemyslaw Marczak 	return ret;
282*1757df46SPrzemyslaw Marczak }
283*1757df46SPrzemyslaw Marczak 
284*1757df46SPrzemyslaw Marczak static int max77686_ldo_modes(int ldo, struct dm_regulator_mode **modesp,
285*1757df46SPrzemyslaw Marczak 				struct udevice *dev)
286*1757df46SPrzemyslaw Marczak {
287*1757df46SPrzemyslaw Marczak 	int ret = -EINVAL;
288*1757df46SPrzemyslaw Marczak 
289*1757df46SPrzemyslaw Marczak 	if (ldo < 1 || ldo > MAX77686_LDO_NUM)
290*1757df46SPrzemyslaw Marczak 		return ret;
291*1757df46SPrzemyslaw Marczak 
292*1757df46SPrzemyslaw Marczak 	switch (ldo) {
293*1757df46SPrzemyslaw Marczak 	case 2:
294*1757df46SPrzemyslaw Marczak 	case 6:
295*1757df46SPrzemyslaw Marczak 	case 7:
296*1757df46SPrzemyslaw Marczak 	case 8:
297*1757df46SPrzemyslaw Marczak 	case 10:
298*1757df46SPrzemyslaw Marczak 	case 11:
299*1757df46SPrzemyslaw Marczak 	case 12:
300*1757df46SPrzemyslaw Marczak 	case 14:
301*1757df46SPrzemyslaw Marczak 	case 15:
302*1757df46SPrzemyslaw Marczak 	case 16:
303*1757df46SPrzemyslaw Marczak 		*modesp = max77686_ldo_mode_standby2;
304*1757df46SPrzemyslaw Marczak 		ret = ARRAY_SIZE(max77686_ldo_mode_standby2);
305*1757df46SPrzemyslaw Marczak 		break;
306*1757df46SPrzemyslaw Marczak 	default:
307*1757df46SPrzemyslaw Marczak 		*modesp = max77686_ldo_mode_standby1;
308*1757df46SPrzemyslaw Marczak 		ret = ARRAY_SIZE(max77686_ldo_mode_standby1);
309*1757df46SPrzemyslaw Marczak 	}
310*1757df46SPrzemyslaw Marczak 
311*1757df46SPrzemyslaw Marczak 	return ret;
312*1757df46SPrzemyslaw Marczak }
313*1757df46SPrzemyslaw Marczak 
314*1757df46SPrzemyslaw Marczak static int max77686_ldo_val(struct udevice *dev, int op, int *uV)
315*1757df46SPrzemyslaw Marczak {
316*1757df46SPrzemyslaw Marczak 	unsigned int ret, hex, adr;
317*1757df46SPrzemyslaw Marczak 	unsigned char val;
318*1757df46SPrzemyslaw Marczak 	int ldo;
319*1757df46SPrzemyslaw Marczak 
320*1757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET)
321*1757df46SPrzemyslaw Marczak 		*uV = 0;
322*1757df46SPrzemyslaw Marczak 
323*1757df46SPrzemyslaw Marczak 	ldo = dev->driver_data;
324*1757df46SPrzemyslaw Marczak 	if (ldo < 1 || ldo > MAX77686_LDO_NUM) {
325*1757df46SPrzemyslaw Marczak 		error("Wrong ldo number: %d", ldo);
326*1757df46SPrzemyslaw Marczak 		return -EINVAL;
327*1757df46SPrzemyslaw Marczak 	}
328*1757df46SPrzemyslaw Marczak 
329*1757df46SPrzemyslaw Marczak 	adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
330*1757df46SPrzemyslaw Marczak 
331*1757df46SPrzemyslaw Marczak 	ret = pmic_read(dev->parent, adr, &val, 1);
332*1757df46SPrzemyslaw Marczak 	if (ret)
333*1757df46SPrzemyslaw Marczak 		return ret;
334*1757df46SPrzemyslaw Marczak 
335*1757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET) {
336*1757df46SPrzemyslaw Marczak 		val &= MAX77686_LDO_VOLT_MASK;
337*1757df46SPrzemyslaw Marczak 		ret = max77686_ldo_hex2volt(ldo, val);
338*1757df46SPrzemyslaw Marczak 		if (ret < 0)
339*1757df46SPrzemyslaw Marczak 			return ret;
340*1757df46SPrzemyslaw Marczak 		*uV = ret;
341*1757df46SPrzemyslaw Marczak 		return 0;
342*1757df46SPrzemyslaw Marczak 	}
343*1757df46SPrzemyslaw Marczak 
344*1757df46SPrzemyslaw Marczak 	hex = max77686_ldo_volt2hex(ldo, *uV);
345*1757df46SPrzemyslaw Marczak 	if (hex < 0)
346*1757df46SPrzemyslaw Marczak 		return hex;
347*1757df46SPrzemyslaw Marczak 
348*1757df46SPrzemyslaw Marczak 	val &= ~MAX77686_LDO_VOLT_MASK;
349*1757df46SPrzemyslaw Marczak 	val |= hex;
350*1757df46SPrzemyslaw Marczak 	ret = pmic_write(dev->parent, adr, &val, 1);
351*1757df46SPrzemyslaw Marczak 
352*1757df46SPrzemyslaw Marczak 	return ret;
353*1757df46SPrzemyslaw Marczak }
354*1757df46SPrzemyslaw Marczak 
355*1757df46SPrzemyslaw Marczak static int max77686_buck_val(struct udevice *dev, int op, int *uV)
356*1757df46SPrzemyslaw Marczak {
357*1757df46SPrzemyslaw Marczak 	unsigned int hex, ret, mask, adr;
358*1757df46SPrzemyslaw Marczak 	unsigned char val;
359*1757df46SPrzemyslaw Marczak 	int buck;
360*1757df46SPrzemyslaw Marczak 
361*1757df46SPrzemyslaw Marczak 	buck = dev->driver_data;
362*1757df46SPrzemyslaw Marczak 	if (buck < 1 || buck > MAX77686_BUCK_NUM) {
363*1757df46SPrzemyslaw Marczak 		error("Wrong buck number: %d", buck);
364*1757df46SPrzemyslaw Marczak 		return -EINVAL;
365*1757df46SPrzemyslaw Marczak 	}
366*1757df46SPrzemyslaw Marczak 
367*1757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET)
368*1757df46SPrzemyslaw Marczak 		*uV = 0;
369*1757df46SPrzemyslaw Marczak 
370*1757df46SPrzemyslaw Marczak 	/* &buck_out = ctrl + 1 */
371*1757df46SPrzemyslaw Marczak 	adr = max77686_buck_addr[buck] + 1;
372*1757df46SPrzemyslaw Marczak 
373*1757df46SPrzemyslaw Marczak 	/* mask */
374*1757df46SPrzemyslaw Marczak 	switch (buck) {
375*1757df46SPrzemyslaw Marczak 	case 2:
376*1757df46SPrzemyslaw Marczak 	case 3:
377*1757df46SPrzemyslaw Marczak 	case 4:
378*1757df46SPrzemyslaw Marczak 		/* Those use voltage scallers - will support in the future */
379*1757df46SPrzemyslaw Marczak 		mask = MAX77686_BUCK234_VOLT_MASK;
380*1757df46SPrzemyslaw Marczak 		return -ENOSYS;
381*1757df46SPrzemyslaw Marczak 	default:
382*1757df46SPrzemyslaw Marczak 		mask = MAX77686_BUCK_VOLT_MASK;
383*1757df46SPrzemyslaw Marczak 	}
384*1757df46SPrzemyslaw Marczak 
385*1757df46SPrzemyslaw Marczak 	ret = pmic_read(dev->parent, adr, &val, 1);
386*1757df46SPrzemyslaw Marczak 	if (ret)
387*1757df46SPrzemyslaw Marczak 		return ret;
388*1757df46SPrzemyslaw Marczak 
389*1757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET) {
390*1757df46SPrzemyslaw Marczak 		val &= mask;
391*1757df46SPrzemyslaw Marczak 		ret = max77686_buck_hex2volt(buck, val);
392*1757df46SPrzemyslaw Marczak 		if (ret < 0)
393*1757df46SPrzemyslaw Marczak 			return ret;
394*1757df46SPrzemyslaw Marczak 		*uV = ret;
395*1757df46SPrzemyslaw Marczak 		return 0;
396*1757df46SPrzemyslaw Marczak 	}
397*1757df46SPrzemyslaw Marczak 
398*1757df46SPrzemyslaw Marczak 	hex = max77686_buck_volt2hex(buck, *uV);
399*1757df46SPrzemyslaw Marczak 	if (hex < 0)
400*1757df46SPrzemyslaw Marczak 		return hex;
401*1757df46SPrzemyslaw Marczak 
402*1757df46SPrzemyslaw Marczak 	val &= ~mask;
403*1757df46SPrzemyslaw Marczak 	val |= hex;
404*1757df46SPrzemyslaw Marczak 	ret = pmic_write(dev->parent, adr, &val, 1);
405*1757df46SPrzemyslaw Marczak 
406*1757df46SPrzemyslaw Marczak 	return ret;
407*1757df46SPrzemyslaw Marczak }
408*1757df46SPrzemyslaw Marczak 
409*1757df46SPrzemyslaw Marczak static int max77686_ldo_mode(struct udevice *dev, int op, int *opmode)
410*1757df46SPrzemyslaw Marczak {
411*1757df46SPrzemyslaw Marczak 	unsigned int ret, adr, mode;
412*1757df46SPrzemyslaw Marczak 	unsigned char val;
413*1757df46SPrzemyslaw Marczak 	int ldo;
414*1757df46SPrzemyslaw Marczak 
415*1757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET)
416*1757df46SPrzemyslaw Marczak 		*opmode = -EINVAL;
417*1757df46SPrzemyslaw Marczak 
418*1757df46SPrzemyslaw Marczak 	ldo = dev->driver_data;
419*1757df46SPrzemyslaw Marczak 	if (ldo < 1 || ldo > MAX77686_LDO_NUM) {
420*1757df46SPrzemyslaw Marczak 		error("Wrong ldo number: %d", ldo);
421*1757df46SPrzemyslaw Marczak 		return -EINVAL;
422*1757df46SPrzemyslaw Marczak 	}
423*1757df46SPrzemyslaw Marczak 
424*1757df46SPrzemyslaw Marczak 	adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
425*1757df46SPrzemyslaw Marczak 
426*1757df46SPrzemyslaw Marczak 	ret = pmic_read(dev->parent, adr, &val, 1);
427*1757df46SPrzemyslaw Marczak 	if (ret)
428*1757df46SPrzemyslaw Marczak 		return ret;
429*1757df46SPrzemyslaw Marczak 
430*1757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET) {
431*1757df46SPrzemyslaw Marczak 		val &= MAX77686_LDO_MODE_MASK;
432*1757df46SPrzemyslaw Marczak 		ret = max77686_ldo_hex2mode(ldo, val);
433*1757df46SPrzemyslaw Marczak 		if (ret < 0)
434*1757df46SPrzemyslaw Marczak 			return ret;
435*1757df46SPrzemyslaw Marczak 		*opmode = ret;
436*1757df46SPrzemyslaw Marczak 		return 0;
437*1757df46SPrzemyslaw Marczak 	}
438*1757df46SPrzemyslaw Marczak 
439*1757df46SPrzemyslaw Marczak 	/* mode */
440*1757df46SPrzemyslaw Marczak 	switch (*opmode) {
441*1757df46SPrzemyslaw Marczak 	case OPMODE_OFF:
442*1757df46SPrzemyslaw Marczak 		mode = MAX77686_LDO_MODE_OFF;
443*1757df46SPrzemyslaw Marczak 		break;
444*1757df46SPrzemyslaw Marczak 	case OPMODE_LPM:
445*1757df46SPrzemyslaw Marczak 		switch (ldo) {
446*1757df46SPrzemyslaw Marczak 		case 2:
447*1757df46SPrzemyslaw Marczak 		case 6:
448*1757df46SPrzemyslaw Marczak 		case 7:
449*1757df46SPrzemyslaw Marczak 		case 8:
450*1757df46SPrzemyslaw Marczak 		case 10:
451*1757df46SPrzemyslaw Marczak 		case 11:
452*1757df46SPrzemyslaw Marczak 		case 12:
453*1757df46SPrzemyslaw Marczak 		case 14:
454*1757df46SPrzemyslaw Marczak 		case 15:
455*1757df46SPrzemyslaw Marczak 		case 16:
456*1757df46SPrzemyslaw Marczak 			return -EINVAL;
457*1757df46SPrzemyslaw Marczak 		default:
458*1757df46SPrzemyslaw Marczak 			mode = MAX77686_LDO_MODE_LPM;
459*1757df46SPrzemyslaw Marczak 		}
460*1757df46SPrzemyslaw Marczak 		break;
461*1757df46SPrzemyslaw Marczak 	case OPMODE_STANDBY:
462*1757df46SPrzemyslaw Marczak 		switch (ldo) {
463*1757df46SPrzemyslaw Marczak 		case 2:
464*1757df46SPrzemyslaw Marczak 		case 6:
465*1757df46SPrzemyslaw Marczak 		case 7:
466*1757df46SPrzemyslaw Marczak 		case 8:
467*1757df46SPrzemyslaw Marczak 		case 10:
468*1757df46SPrzemyslaw Marczak 		case 11:
469*1757df46SPrzemyslaw Marczak 		case 12:
470*1757df46SPrzemyslaw Marczak 		case 14:
471*1757df46SPrzemyslaw Marczak 		case 15:
472*1757df46SPrzemyslaw Marczak 		case 16:
473*1757df46SPrzemyslaw Marczak 			mode = MAX77686_LDO_MODE_STANDBY;
474*1757df46SPrzemyslaw Marczak 			break;
475*1757df46SPrzemyslaw Marczak 		default:
476*1757df46SPrzemyslaw Marczak 			return -EINVAL;
477*1757df46SPrzemyslaw Marczak 		}
478*1757df46SPrzemyslaw Marczak 		break;
479*1757df46SPrzemyslaw Marczak 	case OPMODE_STANDBY_LPM:
480*1757df46SPrzemyslaw Marczak 		mode = MAX77686_LDO_MODE_STANDBY_LPM;
481*1757df46SPrzemyslaw Marczak 		break;
482*1757df46SPrzemyslaw Marczak 	case OPMODE_ON:
483*1757df46SPrzemyslaw Marczak 		mode = MAX77686_LDO_MODE_ON;
484*1757df46SPrzemyslaw Marczak 		break;
485*1757df46SPrzemyslaw Marczak 	default:
486*1757df46SPrzemyslaw Marczak 		mode = 0xff;
487*1757df46SPrzemyslaw Marczak 	}
488*1757df46SPrzemyslaw Marczak 
489*1757df46SPrzemyslaw Marczak 	if (mode == 0xff) {
490*1757df46SPrzemyslaw Marczak 		error("Wrong mode: %d for ldo%d", *opmode, ldo);
491*1757df46SPrzemyslaw Marczak 		return -EINVAL;
492*1757df46SPrzemyslaw Marczak 	}
493*1757df46SPrzemyslaw Marczak 
494*1757df46SPrzemyslaw Marczak 	val &= ~MAX77686_LDO_MODE_MASK;
495*1757df46SPrzemyslaw Marczak 	val |= mode;
496*1757df46SPrzemyslaw Marczak 	ret = pmic_write(dev->parent, adr, &val, 1);
497*1757df46SPrzemyslaw Marczak 
498*1757df46SPrzemyslaw Marczak 	return ret;
499*1757df46SPrzemyslaw Marczak }
500*1757df46SPrzemyslaw Marczak 
501*1757df46SPrzemyslaw Marczak static int max77686_ldo_enable(struct udevice *dev, int op, bool *enable)
502*1757df46SPrzemyslaw Marczak {
503*1757df46SPrzemyslaw Marczak 	int ret, on_off;
504*1757df46SPrzemyslaw Marczak 
505*1757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET) {
506*1757df46SPrzemyslaw Marczak 		ret = max77686_ldo_mode(dev, op, &on_off);
507*1757df46SPrzemyslaw Marczak 		if (ret)
508*1757df46SPrzemyslaw Marczak 			return ret;
509*1757df46SPrzemyslaw Marczak 
510*1757df46SPrzemyslaw Marczak 		switch (on_off) {
511*1757df46SPrzemyslaw Marczak 		case OPMODE_OFF:
512*1757df46SPrzemyslaw Marczak 			*enable = 0;
513*1757df46SPrzemyslaw Marczak 			break;
514*1757df46SPrzemyslaw Marczak 		case OPMODE_ON:
515*1757df46SPrzemyslaw Marczak 			*enable = 1;
516*1757df46SPrzemyslaw Marczak 			break;
517*1757df46SPrzemyslaw Marczak 		default:
518*1757df46SPrzemyslaw Marczak 			return -EINVAL;
519*1757df46SPrzemyslaw Marczak 		}
520*1757df46SPrzemyslaw Marczak 	} else if (op == PMIC_OP_SET) {
521*1757df46SPrzemyslaw Marczak 		switch (*enable) {
522*1757df46SPrzemyslaw Marczak 		case 0:
523*1757df46SPrzemyslaw Marczak 			on_off = OPMODE_OFF;
524*1757df46SPrzemyslaw Marczak 			break;
525*1757df46SPrzemyslaw Marczak 		case 1:
526*1757df46SPrzemyslaw Marczak 			on_off = OPMODE_ON;
527*1757df46SPrzemyslaw Marczak 			break;
528*1757df46SPrzemyslaw Marczak 		default:
529*1757df46SPrzemyslaw Marczak 			return -EINVAL;
530*1757df46SPrzemyslaw Marczak 		}
531*1757df46SPrzemyslaw Marczak 
532*1757df46SPrzemyslaw Marczak 		ret = max77686_ldo_mode(dev, op, &on_off);
533*1757df46SPrzemyslaw Marczak 		if (ret)
534*1757df46SPrzemyslaw Marczak 			return ret;
535*1757df46SPrzemyslaw Marczak 	}
536*1757df46SPrzemyslaw Marczak 
537*1757df46SPrzemyslaw Marczak 	return 0;
538*1757df46SPrzemyslaw Marczak }
539*1757df46SPrzemyslaw Marczak 
540*1757df46SPrzemyslaw Marczak static int max77686_buck_mode(struct udevice *dev, int op, int *opmode)
541*1757df46SPrzemyslaw Marczak {
542*1757df46SPrzemyslaw Marczak 	unsigned int ret, mask, adr, mode, mode_shift;
543*1757df46SPrzemyslaw Marczak 	unsigned char val;
544*1757df46SPrzemyslaw Marczak 	int buck;
545*1757df46SPrzemyslaw Marczak 
546*1757df46SPrzemyslaw Marczak 	buck = dev->driver_data;
547*1757df46SPrzemyslaw Marczak 	if (buck < 1 || buck > MAX77686_BUCK_NUM) {
548*1757df46SPrzemyslaw Marczak 		error("Wrong buck number: %d", buck);
549*1757df46SPrzemyslaw Marczak 		return -EINVAL;
550*1757df46SPrzemyslaw Marczak 	}
551*1757df46SPrzemyslaw Marczak 
552*1757df46SPrzemyslaw Marczak 	adr = max77686_buck_addr[buck];
553*1757df46SPrzemyslaw Marczak 
554*1757df46SPrzemyslaw Marczak 	/* mask */
555*1757df46SPrzemyslaw Marczak 	switch (buck) {
556*1757df46SPrzemyslaw Marczak 	case 2:
557*1757df46SPrzemyslaw Marczak 	case 3:
558*1757df46SPrzemyslaw Marczak 	case 4:
559*1757df46SPrzemyslaw Marczak 		mode_shift = MAX77686_BUCK_MODE_SHIFT_2;
560*1757df46SPrzemyslaw Marczak 		break;
561*1757df46SPrzemyslaw Marczak 	default:
562*1757df46SPrzemyslaw Marczak 		mode_shift = MAX77686_BUCK_MODE_SHIFT_1;
563*1757df46SPrzemyslaw Marczak 	}
564*1757df46SPrzemyslaw Marczak 
565*1757df46SPrzemyslaw Marczak 	mask = MAX77686_BUCK_MODE_MASK << mode_shift;
566*1757df46SPrzemyslaw Marczak 
567*1757df46SPrzemyslaw Marczak 	ret = pmic_read(dev->parent, adr, &val, 1);
568*1757df46SPrzemyslaw Marczak 	if (ret)
569*1757df46SPrzemyslaw Marczak 		return ret;
570*1757df46SPrzemyslaw Marczak 
571*1757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET) {
572*1757df46SPrzemyslaw Marczak 		val &= mask;
573*1757df46SPrzemyslaw Marczak 		val >>= mode_shift;
574*1757df46SPrzemyslaw Marczak 		ret = max77686_buck_hex2mode(buck, val);
575*1757df46SPrzemyslaw Marczak 		if (ret < 0)
576*1757df46SPrzemyslaw Marczak 			return ret;
577*1757df46SPrzemyslaw Marczak 		*opmode = ret;
578*1757df46SPrzemyslaw Marczak 		return 0;
579*1757df46SPrzemyslaw Marczak 	}
580*1757df46SPrzemyslaw Marczak 
581*1757df46SPrzemyslaw Marczak 	/* mode */
582*1757df46SPrzemyslaw Marczak 	switch (*opmode) {
583*1757df46SPrzemyslaw Marczak 	case OPMODE_OFF:
584*1757df46SPrzemyslaw Marczak 		mode = MAX77686_BUCK_MODE_OFF;
585*1757df46SPrzemyslaw Marczak 		break;
586*1757df46SPrzemyslaw Marczak 	case OPMODE_STANDBY:
587*1757df46SPrzemyslaw Marczak 		switch (buck) {
588*1757df46SPrzemyslaw Marczak 		case 1:
589*1757df46SPrzemyslaw Marczak 		case 2:
590*1757df46SPrzemyslaw Marczak 		case 3:
591*1757df46SPrzemyslaw Marczak 		case 4:
592*1757df46SPrzemyslaw Marczak 			mode = MAX77686_BUCK_MODE_STANDBY << mode_shift;
593*1757df46SPrzemyslaw Marczak 			break;
594*1757df46SPrzemyslaw Marczak 		default:
595*1757df46SPrzemyslaw Marczak 			mode = 0xff;
596*1757df46SPrzemyslaw Marczak 		}
597*1757df46SPrzemyslaw Marczak 		break;
598*1757df46SPrzemyslaw Marczak 	case OPMODE_LPM:
599*1757df46SPrzemyslaw Marczak 		switch (buck) {
600*1757df46SPrzemyslaw Marczak 		case 2:
601*1757df46SPrzemyslaw Marczak 		case 3:
602*1757df46SPrzemyslaw Marczak 		case 4:
603*1757df46SPrzemyslaw Marczak 			mode = MAX77686_BUCK_MODE_LPM << mode_shift;
604*1757df46SPrzemyslaw Marczak 			break;
605*1757df46SPrzemyslaw Marczak 		default:
606*1757df46SPrzemyslaw Marczak 			mode = 0xff;
607*1757df46SPrzemyslaw Marczak 		}
608*1757df46SPrzemyslaw Marczak 		break;
609*1757df46SPrzemyslaw Marczak 	case OPMODE_ON:
610*1757df46SPrzemyslaw Marczak 		mode = MAX77686_BUCK_MODE_ON << mode_shift;
611*1757df46SPrzemyslaw Marczak 		break;
612*1757df46SPrzemyslaw Marczak 	default:
613*1757df46SPrzemyslaw Marczak 		mode = 0xff;
614*1757df46SPrzemyslaw Marczak 	}
615*1757df46SPrzemyslaw Marczak 
616*1757df46SPrzemyslaw Marczak 	if (mode == 0xff) {
617*1757df46SPrzemyslaw Marczak 		error("Wrong mode: %d for buck: %d\n", *opmode, buck);
618*1757df46SPrzemyslaw Marczak 		return -EINVAL;
619*1757df46SPrzemyslaw Marczak 	}
620*1757df46SPrzemyslaw Marczak 
621*1757df46SPrzemyslaw Marczak 	val &= ~mask;
622*1757df46SPrzemyslaw Marczak 	val |= mode;
623*1757df46SPrzemyslaw Marczak 	ret = pmic_write(dev->parent, adr, &val, 1);
624*1757df46SPrzemyslaw Marczak 
625*1757df46SPrzemyslaw Marczak 	return ret;
626*1757df46SPrzemyslaw Marczak }
627*1757df46SPrzemyslaw Marczak 
628*1757df46SPrzemyslaw Marczak static int max77686_buck_enable(struct udevice *dev, int op, bool *enable)
629*1757df46SPrzemyslaw Marczak {
630*1757df46SPrzemyslaw Marczak 	int ret, on_off;
631*1757df46SPrzemyslaw Marczak 
632*1757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET) {
633*1757df46SPrzemyslaw Marczak 		ret = max77686_buck_mode(dev, op, &on_off);
634*1757df46SPrzemyslaw Marczak 		if (ret)
635*1757df46SPrzemyslaw Marczak 			return ret;
636*1757df46SPrzemyslaw Marczak 
637*1757df46SPrzemyslaw Marczak 		switch (on_off) {
638*1757df46SPrzemyslaw Marczak 		case OPMODE_OFF:
639*1757df46SPrzemyslaw Marczak 			*enable = false;
640*1757df46SPrzemyslaw Marczak 			break;
641*1757df46SPrzemyslaw Marczak 		case OPMODE_ON:
642*1757df46SPrzemyslaw Marczak 			*enable = true;
643*1757df46SPrzemyslaw Marczak 			break;
644*1757df46SPrzemyslaw Marczak 		default:
645*1757df46SPrzemyslaw Marczak 			return -EINVAL;
646*1757df46SPrzemyslaw Marczak 		}
647*1757df46SPrzemyslaw Marczak 	} else if (op == PMIC_OP_SET) {
648*1757df46SPrzemyslaw Marczak 		switch (*enable) {
649*1757df46SPrzemyslaw Marczak 		case 0:
650*1757df46SPrzemyslaw Marczak 			on_off = OPMODE_OFF;
651*1757df46SPrzemyslaw Marczak 			break;
652*1757df46SPrzemyslaw Marczak 		case 1:
653*1757df46SPrzemyslaw Marczak 			on_off = OPMODE_ON;
654*1757df46SPrzemyslaw Marczak 			break;
655*1757df46SPrzemyslaw Marczak 		default:
656*1757df46SPrzemyslaw Marczak 			return -EINVAL;
657*1757df46SPrzemyslaw Marczak 		}
658*1757df46SPrzemyslaw Marczak 
659*1757df46SPrzemyslaw Marczak 		ret = max77686_buck_mode(dev, op, &on_off);
660*1757df46SPrzemyslaw Marczak 		if (ret)
661*1757df46SPrzemyslaw Marczak 			return ret;
662*1757df46SPrzemyslaw Marczak 	}
663*1757df46SPrzemyslaw Marczak 
664*1757df46SPrzemyslaw Marczak 	return 0;
665*1757df46SPrzemyslaw Marczak }
666*1757df46SPrzemyslaw Marczak 
667*1757df46SPrzemyslaw Marczak static int max77686_ldo_probe(struct udevice *dev)
668*1757df46SPrzemyslaw Marczak {
669*1757df46SPrzemyslaw Marczak 	struct dm_regulator_uclass_platdata *uc_pdata;
670*1757df46SPrzemyslaw Marczak 
671*1757df46SPrzemyslaw Marczak 	uc_pdata = dev_get_uclass_platdata(dev);
672*1757df46SPrzemyslaw Marczak 
673*1757df46SPrzemyslaw Marczak 	uc_pdata->type = REGULATOR_TYPE_LDO;
674*1757df46SPrzemyslaw Marczak 	uc_pdata->mode_count = max77686_ldo_modes(dev->driver_data,
675*1757df46SPrzemyslaw Marczak 						  &uc_pdata->mode, dev);
676*1757df46SPrzemyslaw Marczak 
677*1757df46SPrzemyslaw Marczak 	return 0;
678*1757df46SPrzemyslaw Marczak }
679*1757df46SPrzemyslaw Marczak 
680*1757df46SPrzemyslaw Marczak static int ldo_get_value(struct udevice *dev)
681*1757df46SPrzemyslaw Marczak {
682*1757df46SPrzemyslaw Marczak 	int uV;
683*1757df46SPrzemyslaw Marczak 	int ret;
684*1757df46SPrzemyslaw Marczak 
685*1757df46SPrzemyslaw Marczak 	ret = max77686_ldo_val(dev, PMIC_OP_GET, &uV);
686*1757df46SPrzemyslaw Marczak 	if (ret)
687*1757df46SPrzemyslaw Marczak 		return ret;
688*1757df46SPrzemyslaw Marczak 
689*1757df46SPrzemyslaw Marczak 	return uV;
690*1757df46SPrzemyslaw Marczak }
691*1757df46SPrzemyslaw Marczak 
692*1757df46SPrzemyslaw Marczak static int ldo_set_value(struct udevice *dev, int uV)
693*1757df46SPrzemyslaw Marczak {
694*1757df46SPrzemyslaw Marczak 	return max77686_ldo_val(dev, PMIC_OP_SET, &uV);
695*1757df46SPrzemyslaw Marczak }
696*1757df46SPrzemyslaw Marczak 
697*1757df46SPrzemyslaw Marczak static bool ldo_get_enable(struct udevice *dev)
698*1757df46SPrzemyslaw Marczak {
699*1757df46SPrzemyslaw Marczak 	bool enable = false;
700*1757df46SPrzemyslaw Marczak 	int ret;
701*1757df46SPrzemyslaw Marczak 
702*1757df46SPrzemyslaw Marczak 	ret = max77686_ldo_enable(dev, PMIC_OP_GET, &enable);
703*1757df46SPrzemyslaw Marczak 	if (ret)
704*1757df46SPrzemyslaw Marczak 		return ret;
705*1757df46SPrzemyslaw Marczak 
706*1757df46SPrzemyslaw Marczak 	return enable;
707*1757df46SPrzemyslaw Marczak }
708*1757df46SPrzemyslaw Marczak 
709*1757df46SPrzemyslaw Marczak static int ldo_set_enable(struct udevice *dev, bool enable)
710*1757df46SPrzemyslaw Marczak {
711*1757df46SPrzemyslaw Marczak 	return max77686_ldo_enable(dev, PMIC_OP_SET, &enable);
712*1757df46SPrzemyslaw Marczak }
713*1757df46SPrzemyslaw Marczak 
714*1757df46SPrzemyslaw Marczak static int ldo_get_mode(struct udevice *dev)
715*1757df46SPrzemyslaw Marczak {
716*1757df46SPrzemyslaw Marczak 	int mode;
717*1757df46SPrzemyslaw Marczak 	int ret;
718*1757df46SPrzemyslaw Marczak 
719*1757df46SPrzemyslaw Marczak 	ret = max77686_ldo_mode(dev, PMIC_OP_GET, &mode);
720*1757df46SPrzemyslaw Marczak 	if (ret)
721*1757df46SPrzemyslaw Marczak 		return ret;
722*1757df46SPrzemyslaw Marczak 
723*1757df46SPrzemyslaw Marczak 	return mode;
724*1757df46SPrzemyslaw Marczak }
725*1757df46SPrzemyslaw Marczak 
726*1757df46SPrzemyslaw Marczak static int ldo_set_mode(struct udevice *dev, int mode)
727*1757df46SPrzemyslaw Marczak {
728*1757df46SPrzemyslaw Marczak 	return max77686_ldo_mode(dev, PMIC_OP_SET, &mode);
729*1757df46SPrzemyslaw Marczak }
730*1757df46SPrzemyslaw Marczak 
731*1757df46SPrzemyslaw Marczak static int max77686_buck_probe(struct udevice *dev)
732*1757df46SPrzemyslaw Marczak {
733*1757df46SPrzemyslaw Marczak 	struct dm_regulator_uclass_platdata *uc_pdata;
734*1757df46SPrzemyslaw Marczak 
735*1757df46SPrzemyslaw Marczak 	uc_pdata = dev_get_uclass_platdata(dev);
736*1757df46SPrzemyslaw Marczak 
737*1757df46SPrzemyslaw Marczak 	uc_pdata->type = REGULATOR_TYPE_BUCK;
738*1757df46SPrzemyslaw Marczak 	uc_pdata->mode_count = max77686_buck_modes(dev->driver_data,
739*1757df46SPrzemyslaw Marczak 						   &uc_pdata->mode);
740*1757df46SPrzemyslaw Marczak 
741*1757df46SPrzemyslaw Marczak 	return 0;
742*1757df46SPrzemyslaw Marczak }
743*1757df46SPrzemyslaw Marczak 
744*1757df46SPrzemyslaw Marczak static int buck_get_value(struct udevice *dev)
745*1757df46SPrzemyslaw Marczak {
746*1757df46SPrzemyslaw Marczak 	int uV;
747*1757df46SPrzemyslaw Marczak 	int ret;
748*1757df46SPrzemyslaw Marczak 
749*1757df46SPrzemyslaw Marczak 	ret = max77686_buck_val(dev, PMIC_OP_GET, &uV);
750*1757df46SPrzemyslaw Marczak 	if (ret)
751*1757df46SPrzemyslaw Marczak 		return ret;
752*1757df46SPrzemyslaw Marczak 
753*1757df46SPrzemyslaw Marczak 	return uV;
754*1757df46SPrzemyslaw Marczak }
755*1757df46SPrzemyslaw Marczak 
756*1757df46SPrzemyslaw Marczak static int buck_set_value(struct udevice *dev, int uV)
757*1757df46SPrzemyslaw Marczak {
758*1757df46SPrzemyslaw Marczak 	return max77686_buck_val(dev, PMIC_OP_SET, &uV);
759*1757df46SPrzemyslaw Marczak }
760*1757df46SPrzemyslaw Marczak 
761*1757df46SPrzemyslaw Marczak static bool buck_get_enable(struct udevice *dev)
762*1757df46SPrzemyslaw Marczak {
763*1757df46SPrzemyslaw Marczak 	bool enable = false;
764*1757df46SPrzemyslaw Marczak 	int ret;
765*1757df46SPrzemyslaw Marczak 
766*1757df46SPrzemyslaw Marczak 	ret = max77686_buck_enable(dev, PMIC_OP_GET, &enable);
767*1757df46SPrzemyslaw Marczak 	if (ret)
768*1757df46SPrzemyslaw Marczak 		return ret;
769*1757df46SPrzemyslaw Marczak 
770*1757df46SPrzemyslaw Marczak 	return enable;
771*1757df46SPrzemyslaw Marczak }
772*1757df46SPrzemyslaw Marczak 
773*1757df46SPrzemyslaw Marczak static int buck_set_enable(struct udevice *dev, bool enable)
774*1757df46SPrzemyslaw Marczak {
775*1757df46SPrzemyslaw Marczak 	return max77686_buck_enable(dev, PMIC_OP_SET, &enable);
776*1757df46SPrzemyslaw Marczak }
777*1757df46SPrzemyslaw Marczak 
778*1757df46SPrzemyslaw Marczak static int buck_get_mode(struct udevice *dev)
779*1757df46SPrzemyslaw Marczak {
780*1757df46SPrzemyslaw Marczak 	int mode;
781*1757df46SPrzemyslaw Marczak 	int ret;
782*1757df46SPrzemyslaw Marczak 
783*1757df46SPrzemyslaw Marczak 	ret = max77686_buck_mode(dev, PMIC_OP_GET, &mode);
784*1757df46SPrzemyslaw Marczak 	if (ret)
785*1757df46SPrzemyslaw Marczak 		return ret;
786*1757df46SPrzemyslaw Marczak 
787*1757df46SPrzemyslaw Marczak 	return mode;
788*1757df46SPrzemyslaw Marczak }
789*1757df46SPrzemyslaw Marczak 
790*1757df46SPrzemyslaw Marczak static int buck_set_mode(struct udevice *dev, int mode)
791*1757df46SPrzemyslaw Marczak {
792*1757df46SPrzemyslaw Marczak 	return max77686_buck_mode(dev, PMIC_OP_SET, &mode);
793*1757df46SPrzemyslaw Marczak }
794*1757df46SPrzemyslaw Marczak 
795*1757df46SPrzemyslaw Marczak static const struct dm_regulator_ops max77686_ldo_ops = {
796*1757df46SPrzemyslaw Marczak 	.get_value  = ldo_get_value,
797*1757df46SPrzemyslaw Marczak 	.set_value  = ldo_set_value,
798*1757df46SPrzemyslaw Marczak 	.get_enable = ldo_get_enable,
799*1757df46SPrzemyslaw Marczak 	.set_enable = ldo_set_enable,
800*1757df46SPrzemyslaw Marczak 	.get_mode   = ldo_get_mode,
801*1757df46SPrzemyslaw Marczak 	.set_mode   = ldo_set_mode,
802*1757df46SPrzemyslaw Marczak };
803*1757df46SPrzemyslaw Marczak 
804*1757df46SPrzemyslaw Marczak U_BOOT_DRIVER(max77686_ldo) = {
805*1757df46SPrzemyslaw Marczak 	.name = MAX77686_LDO_DRIVER,
806*1757df46SPrzemyslaw Marczak 	.id = UCLASS_REGULATOR,
807*1757df46SPrzemyslaw Marczak 	.ops = &max77686_ldo_ops,
808*1757df46SPrzemyslaw Marczak 	.probe = max77686_ldo_probe,
809*1757df46SPrzemyslaw Marczak };
810*1757df46SPrzemyslaw Marczak 
811*1757df46SPrzemyslaw Marczak static const struct dm_regulator_ops max77686_buck_ops = {
812*1757df46SPrzemyslaw Marczak 	.get_value  = buck_get_value,
813*1757df46SPrzemyslaw Marczak 	.set_value  = buck_set_value,
814*1757df46SPrzemyslaw Marczak 	.get_enable = buck_get_enable,
815*1757df46SPrzemyslaw Marczak 	.set_enable = buck_set_enable,
816*1757df46SPrzemyslaw Marczak 	.get_mode   = buck_get_mode,
817*1757df46SPrzemyslaw Marczak 	.set_mode   = buck_set_mode,
818*1757df46SPrzemyslaw Marczak };
819*1757df46SPrzemyslaw Marczak 
820*1757df46SPrzemyslaw Marczak U_BOOT_DRIVER(max77686_buck) = {
821*1757df46SPrzemyslaw Marczak 	.name = MAX77686_BUCK_DRIVER,
822*1757df46SPrzemyslaw Marczak 	.id = UCLASS_REGULATOR,
823*1757df46SPrzemyslaw Marczak 	.ops = &max77686_buck_ops,
824*1757df46SPrzemyslaw Marczak 	.probe = max77686_buck_probe,
825*1757df46SPrzemyslaw Marczak };
826