xref: /rk3399_rockchip-uboot/drivers/power/regulator/max77686.c (revision 90aa625c9a9e1fb7a2f001fd8e50099bacaf92b8)
11757df46SPrzemyslaw Marczak /*
21757df46SPrzemyslaw Marczak  *  Copyright (C) 2012-2015 Samsung Electronics
31757df46SPrzemyslaw Marczak  *
41757df46SPrzemyslaw Marczak  *  Rajeshwari Shinde <rajeshwari.s@samsung.com>
51757df46SPrzemyslaw Marczak  *  Przemyslaw Marczak <p.marczak@samsung.com>
61757df46SPrzemyslaw Marczak  *
71757df46SPrzemyslaw Marczak  * SPDX-License-Identifier:	GPL-2.0+
81757df46SPrzemyslaw Marczak  */
91757df46SPrzemyslaw Marczak 
101757df46SPrzemyslaw Marczak #include <common.h>
111757df46SPrzemyslaw Marczak #include <fdtdec.h>
121757df46SPrzemyslaw Marczak #include <errno.h>
131757df46SPrzemyslaw Marczak #include <dm.h>
141757df46SPrzemyslaw Marczak #include <i2c.h>
151757df46SPrzemyslaw Marczak #include <power/pmic.h>
161757df46SPrzemyslaw Marczak #include <power/regulator.h>
171757df46SPrzemyslaw Marczak #include <power/max77686_pmic.h>
181757df46SPrzemyslaw Marczak 
191757df46SPrzemyslaw Marczak DECLARE_GLOBAL_DATA_PTR;
201757df46SPrzemyslaw Marczak 
211757df46SPrzemyslaw Marczak #define MODE(_id, _val, _name) { \
221757df46SPrzemyslaw Marczak 	.id = _id, \
231757df46SPrzemyslaw Marczak 	.register_value = _val, \
241757df46SPrzemyslaw Marczak 	.name = _name, \
251757df46SPrzemyslaw Marczak }
261757df46SPrzemyslaw Marczak 
271757df46SPrzemyslaw Marczak /* LDO: 1,3,4,5,9,17,18,19,20,21,22,23,24,26,26,27 */
281757df46SPrzemyslaw Marczak static struct dm_regulator_mode max77686_ldo_mode_standby1[] = {
291757df46SPrzemyslaw Marczak 	MODE(OPMODE_OFF, MAX77686_LDO_MODE_OFF, "OFF"),
301757df46SPrzemyslaw Marczak 	MODE(OPMODE_LPM, MAX77686_LDO_MODE_LPM, "LPM"),
311757df46SPrzemyslaw Marczak 	MODE(OPMODE_STANDBY_LPM, MAX77686_LDO_MODE_STANDBY_LPM, "ON/LPM"),
321757df46SPrzemyslaw Marczak 	MODE(OPMODE_ON, MAX77686_LDO_MODE_ON, "ON"),
331757df46SPrzemyslaw Marczak };
341757df46SPrzemyslaw Marczak 
351757df46SPrzemyslaw Marczak /* LDO: 2,6,7,8,10,11,12,14,15,16 */
361757df46SPrzemyslaw Marczak static struct dm_regulator_mode max77686_ldo_mode_standby2[] = {
371757df46SPrzemyslaw Marczak 	MODE(OPMODE_OFF, MAX77686_LDO_MODE_OFF, "OFF"),
381757df46SPrzemyslaw Marczak 	MODE(OPMODE_STANDBY, MAX77686_LDO_MODE_STANDBY, "ON/OFF"),
391757df46SPrzemyslaw Marczak 	MODE(OPMODE_STANDBY_LPM, MAX77686_LDO_MODE_STANDBY_LPM, "ON/LPM"),
401757df46SPrzemyslaw Marczak 	MODE(OPMODE_ON, MAX77686_LDO_MODE_ON, "ON"),
411757df46SPrzemyslaw Marczak };
421757df46SPrzemyslaw Marczak 
431757df46SPrzemyslaw Marczak /* Buck: 1 */
441757df46SPrzemyslaw Marczak static struct dm_regulator_mode max77686_buck_mode_standby[] = {
451757df46SPrzemyslaw Marczak 	MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
461757df46SPrzemyslaw Marczak 	MODE(OPMODE_STANDBY, MAX77686_BUCK_MODE_STANDBY, "ON/OFF"),
471757df46SPrzemyslaw Marczak 	MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
481757df46SPrzemyslaw Marczak };
491757df46SPrzemyslaw Marczak 
501757df46SPrzemyslaw Marczak /* Buck: 2,3,4 */
511757df46SPrzemyslaw Marczak static struct dm_regulator_mode max77686_buck_mode_lpm[] = {
521757df46SPrzemyslaw Marczak 	MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
531757df46SPrzemyslaw Marczak 	MODE(OPMODE_STANDBY, MAX77686_BUCK_MODE_STANDBY, "ON/OFF"),
541757df46SPrzemyslaw Marczak 	MODE(OPMODE_LPM, MAX77686_BUCK_MODE_LPM, "LPM"),
551757df46SPrzemyslaw Marczak 	MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
561757df46SPrzemyslaw Marczak };
571757df46SPrzemyslaw Marczak 
581757df46SPrzemyslaw Marczak /* Buck: 5,6,7,8,9 */
591757df46SPrzemyslaw Marczak static struct dm_regulator_mode max77686_buck_mode_onoff[] = {
601757df46SPrzemyslaw Marczak 	MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
611757df46SPrzemyslaw Marczak 	MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
621757df46SPrzemyslaw Marczak };
631757df46SPrzemyslaw Marczak 
648c428709SSimon Glass static const char max77686_buck_ctrl[] = {
651757df46SPrzemyslaw Marczak 	0xff, 0x10, 0x12, 0x1c, 0x26, 0x30, 0x32, 0x34, 0x36, 0x38
661757df46SPrzemyslaw Marczak };
671757df46SPrzemyslaw Marczak 
688c428709SSimon Glass static const char max77686_buck_out[] = {
698c428709SSimon Glass 	0xff, 0x11, 0x14, 0x1e, 0x28, 0x31, 0x33, 0x35, 0x37, 0x39
708c428709SSimon Glass };
718c428709SSimon Glass 
max77686_buck_volt2hex(int buck,int uV)721757df46SPrzemyslaw Marczak static int max77686_buck_volt2hex(int buck, int uV)
731757df46SPrzemyslaw Marczak {
74aae78fa7STom Rini 	int hex = 0;
75aae78fa7STom Rini 	int hex_max = 0;
761757df46SPrzemyslaw Marczak 
771757df46SPrzemyslaw Marczak 	switch (buck) {
781757df46SPrzemyslaw Marczak 	case 2:
791757df46SPrzemyslaw Marczak 	case 3:
801757df46SPrzemyslaw Marczak 	case 4:
811757df46SPrzemyslaw Marczak 		/* hex = (uV - 600000) / 12500; */
821757df46SPrzemyslaw Marczak 		hex = (uV - MAX77686_BUCK_UV_LMIN) / MAX77686_BUCK_UV_LSTEP;
831757df46SPrzemyslaw Marczak 		hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
8475a429f1SSimon Glass 		break;
851757df46SPrzemyslaw Marczak 	default:
8675a429f1SSimon Glass 		/*
8775a429f1SSimon Glass 		 * hex = (uV - 750000) / 50000. We assume that dynamic voltage
8875a429f1SSimon Glass 		 * scaling via GPIOs is not enabled and don't support that.
8975a429f1SSimon Glass 		 * If this is enabled then the driver will need to take that
90e6b606d6SSimon Glass 		 * into account and check different registers depending on
91e6b606d6SSimon Glass 		 * the current setting. See the datasheet for details.
9275a429f1SSimon Glass 		 */
931757df46SPrzemyslaw Marczak 		hex = (uV - MAX77686_BUCK_UV_HMIN) / MAX77686_BUCK_UV_HSTEP;
941757df46SPrzemyslaw Marczak 		hex_max = MAX77686_BUCK_VOLT_MAX_HEX;
951757df46SPrzemyslaw Marczak 		break;
961757df46SPrzemyslaw Marczak 	}
971757df46SPrzemyslaw Marczak 
981757df46SPrzemyslaw Marczak 	if (hex >= 0 && hex <= hex_max)
991757df46SPrzemyslaw Marczak 		return hex;
1001757df46SPrzemyslaw Marczak 
101*90aa625cSMasahiro Yamada 	pr_err("Value: %d uV is wrong for BUCK%d", uV, buck);
1021757df46SPrzemyslaw Marczak 	return -EINVAL;
1031757df46SPrzemyslaw Marczak }
1041757df46SPrzemyslaw Marczak 
max77686_buck_hex2volt(int buck,int hex)1051757df46SPrzemyslaw Marczak static int max77686_buck_hex2volt(int buck, int hex)
1061757df46SPrzemyslaw Marczak {
1071757df46SPrzemyslaw Marczak 	unsigned uV = 0;
108aae78fa7STom Rini 	int hex_max = 0;
1091757df46SPrzemyslaw Marczak 
1101757df46SPrzemyslaw Marczak 	if (hex < 0)
1111757df46SPrzemyslaw Marczak 		goto bad_hex;
1121757df46SPrzemyslaw Marczak 
1131757df46SPrzemyslaw Marczak 	switch (buck) {
1141757df46SPrzemyslaw Marczak 	case 2:
1151757df46SPrzemyslaw Marczak 	case 3:
1161757df46SPrzemyslaw Marczak 	case 4:
1171757df46SPrzemyslaw Marczak 		hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
1181757df46SPrzemyslaw Marczak 		if (hex > hex_max)
1191757df46SPrzemyslaw Marczak 			goto bad_hex;
1201757df46SPrzemyslaw Marczak 
1211757df46SPrzemyslaw Marczak 		/* uV = hex * 12500 + 600000; */
1221757df46SPrzemyslaw Marczak 		uV = hex * MAX77686_BUCK_UV_LSTEP + MAX77686_BUCK_UV_LMIN;
1231757df46SPrzemyslaw Marczak 		break;
1241757df46SPrzemyslaw Marczak 	default:
1251757df46SPrzemyslaw Marczak 		hex_max = MAX77686_BUCK_VOLT_MAX_HEX;
1261757df46SPrzemyslaw Marczak 		if (hex > hex_max)
1271757df46SPrzemyslaw Marczak 			goto bad_hex;
1281757df46SPrzemyslaw Marczak 
1291757df46SPrzemyslaw Marczak 		/* uV = hex * 50000 + 750000; */
1301757df46SPrzemyslaw Marczak 		uV = hex * MAX77686_BUCK_UV_HSTEP + MAX77686_BUCK_UV_HMIN;
1311757df46SPrzemyslaw Marczak 		break;
1321757df46SPrzemyslaw Marczak 	}
1331757df46SPrzemyslaw Marczak 
1341757df46SPrzemyslaw Marczak 	return uV;
1351757df46SPrzemyslaw Marczak 
1361757df46SPrzemyslaw Marczak bad_hex:
137*90aa625cSMasahiro Yamada 	pr_err("Value: %#x is wrong for BUCK%d", hex, buck);
1381757df46SPrzemyslaw Marczak 	return -EINVAL;
1391757df46SPrzemyslaw Marczak }
1401757df46SPrzemyslaw Marczak 
max77686_ldo_volt2hex(int ldo,int uV)1411757df46SPrzemyslaw Marczak static int max77686_ldo_volt2hex(int ldo, int uV)
1421757df46SPrzemyslaw Marczak {
143aae78fa7STom Rini 	int hex = 0;
1441757df46SPrzemyslaw Marczak 
1451757df46SPrzemyslaw Marczak 	switch (ldo) {
1461757df46SPrzemyslaw Marczak 	case 1:
1471757df46SPrzemyslaw Marczak 	case 2:
1481757df46SPrzemyslaw Marczak 	case 6:
1491757df46SPrzemyslaw Marczak 	case 7:
1501757df46SPrzemyslaw Marczak 	case 8:
1511757df46SPrzemyslaw Marczak 	case 15:
1521757df46SPrzemyslaw Marczak 		hex = (uV - MAX77686_LDO_UV_MIN) / MAX77686_LDO_UV_LSTEP;
1531757df46SPrzemyslaw Marczak 		/* hex = (uV - 800000) / 25000; */
1541757df46SPrzemyslaw Marczak 		break;
1551757df46SPrzemyslaw Marczak 	default:
1561757df46SPrzemyslaw Marczak 		hex = (uV - MAX77686_LDO_UV_MIN) / MAX77686_LDO_UV_HSTEP;
1571757df46SPrzemyslaw Marczak 		/* hex = (uV - 800000) / 50000; */
1581757df46SPrzemyslaw Marczak 	}
1591757df46SPrzemyslaw Marczak 
1601757df46SPrzemyslaw Marczak 	if (hex >= 0 && hex <= MAX77686_LDO_VOLT_MAX_HEX)
1611757df46SPrzemyslaw Marczak 		return hex;
1621757df46SPrzemyslaw Marczak 
163*90aa625cSMasahiro Yamada 	pr_err("Value: %d uV is wrong for LDO%d", uV, ldo);
1641757df46SPrzemyslaw Marczak 	return -EINVAL;
1651757df46SPrzemyslaw Marczak }
1661757df46SPrzemyslaw Marczak 
max77686_ldo_hex2volt(int ldo,int hex)1671757df46SPrzemyslaw Marczak static int max77686_ldo_hex2volt(int ldo, int hex)
1681757df46SPrzemyslaw Marczak {
1691757df46SPrzemyslaw Marczak 	unsigned int uV = 0;
1701757df46SPrzemyslaw Marczak 
1711757df46SPrzemyslaw Marczak 	if (hex > MAX77686_LDO_VOLT_MAX_HEX)
1721757df46SPrzemyslaw Marczak 		goto bad_hex;
1731757df46SPrzemyslaw Marczak 
1741757df46SPrzemyslaw Marczak 	switch (ldo) {
1751757df46SPrzemyslaw Marczak 	case 1:
1761757df46SPrzemyslaw Marczak 	case 2:
1771757df46SPrzemyslaw Marczak 	case 6:
1781757df46SPrzemyslaw Marczak 	case 7:
1791757df46SPrzemyslaw Marczak 	case 8:
1801757df46SPrzemyslaw Marczak 	case 15:
1811757df46SPrzemyslaw Marczak 		/* uV = hex * 25000 + 800000; */
1821757df46SPrzemyslaw Marczak 		uV = hex * MAX77686_LDO_UV_LSTEP + MAX77686_LDO_UV_MIN;
1831757df46SPrzemyslaw Marczak 		break;
1841757df46SPrzemyslaw Marczak 	default:
1851757df46SPrzemyslaw Marczak 		/* uV = hex * 50000 + 800000; */
1861757df46SPrzemyslaw Marczak 		uV = hex * MAX77686_LDO_UV_HSTEP + MAX77686_LDO_UV_MIN;
1871757df46SPrzemyslaw Marczak 	}
1881757df46SPrzemyslaw Marczak 
1891757df46SPrzemyslaw Marczak 	return uV;
1901757df46SPrzemyslaw Marczak 
1911757df46SPrzemyslaw Marczak bad_hex:
192*90aa625cSMasahiro Yamada 	pr_err("Value: %#x is wrong for ldo%d", hex, ldo);
1931757df46SPrzemyslaw Marczak 	return -EINVAL;
1941757df46SPrzemyslaw Marczak }
1951757df46SPrzemyslaw Marczak 
max77686_ldo_hex2mode(int ldo,int hex)1961757df46SPrzemyslaw Marczak static int max77686_ldo_hex2mode(int ldo, int hex)
1971757df46SPrzemyslaw Marczak {
1981757df46SPrzemyslaw Marczak 	if (hex > MAX77686_LDO_MODE_MASK)
1991757df46SPrzemyslaw Marczak 		return -EINVAL;
2001757df46SPrzemyslaw Marczak 
2011757df46SPrzemyslaw Marczak 	switch (hex) {
2021757df46SPrzemyslaw Marczak 	case MAX77686_LDO_MODE_OFF:
2031757df46SPrzemyslaw Marczak 		return OPMODE_OFF;
2041757df46SPrzemyslaw Marczak 	case MAX77686_LDO_MODE_LPM: /* == MAX77686_LDO_MODE_STANDBY: */
2051757df46SPrzemyslaw Marczak 		/* The same mode values but different meaning for each ldo */
2061757df46SPrzemyslaw Marczak 		switch (ldo) {
2071757df46SPrzemyslaw Marczak 		case 2:
2081757df46SPrzemyslaw Marczak 		case 6:
2091757df46SPrzemyslaw Marczak 		case 7:
2101757df46SPrzemyslaw Marczak 		case 8:
2111757df46SPrzemyslaw Marczak 		case 10:
2121757df46SPrzemyslaw Marczak 		case 11:
2131757df46SPrzemyslaw Marczak 		case 12:
2141757df46SPrzemyslaw Marczak 		case 14:
2151757df46SPrzemyslaw Marczak 		case 15:
2161757df46SPrzemyslaw Marczak 		case 16:
2171757df46SPrzemyslaw Marczak 			return OPMODE_STANDBY;
2181757df46SPrzemyslaw Marczak 		default:
2191757df46SPrzemyslaw Marczak 			return OPMODE_LPM;
2201757df46SPrzemyslaw Marczak 		}
2211757df46SPrzemyslaw Marczak 	case MAX77686_LDO_MODE_STANDBY_LPM:
2221757df46SPrzemyslaw Marczak 		return OPMODE_STANDBY_LPM;
2231757df46SPrzemyslaw Marczak 	case MAX77686_LDO_MODE_ON:
2241757df46SPrzemyslaw Marczak 		return OPMODE_ON;
2251757df46SPrzemyslaw Marczak 	default:
2261757df46SPrzemyslaw Marczak 		return -EINVAL;
2271757df46SPrzemyslaw Marczak 	}
2281757df46SPrzemyslaw Marczak }
2291757df46SPrzemyslaw Marczak 
max77686_buck_hex2mode(int buck,int hex)2301757df46SPrzemyslaw Marczak static int max77686_buck_hex2mode(int buck, int hex)
2311757df46SPrzemyslaw Marczak {
2321757df46SPrzemyslaw Marczak 	if (hex > MAX77686_BUCK_MODE_MASK)
2331757df46SPrzemyslaw Marczak 		return -EINVAL;
2341757df46SPrzemyslaw Marczak 
2351757df46SPrzemyslaw Marczak 	switch (hex) {
2361757df46SPrzemyslaw Marczak 	case MAX77686_BUCK_MODE_OFF:
2371757df46SPrzemyslaw Marczak 		return OPMODE_OFF;
2381757df46SPrzemyslaw Marczak 	case MAX77686_BUCK_MODE_ON:
2391757df46SPrzemyslaw Marczak 		return OPMODE_ON;
2401757df46SPrzemyslaw Marczak 	case MAX77686_BUCK_MODE_STANDBY:
2411757df46SPrzemyslaw Marczak 		switch (buck) {
2421757df46SPrzemyslaw Marczak 		case 1:
2431757df46SPrzemyslaw Marczak 		case 2:
2441757df46SPrzemyslaw Marczak 		case 3:
2451757df46SPrzemyslaw Marczak 		case 4:
2461757df46SPrzemyslaw Marczak 			return OPMODE_STANDBY;
2471757df46SPrzemyslaw Marczak 		default:
2481757df46SPrzemyslaw Marczak 			return -EINVAL;
2491757df46SPrzemyslaw Marczak 		}
2501757df46SPrzemyslaw Marczak 	case MAX77686_BUCK_MODE_LPM:
2511757df46SPrzemyslaw Marczak 		switch (buck) {
2521757df46SPrzemyslaw Marczak 		case 2:
2531757df46SPrzemyslaw Marczak 		case 3:
2541757df46SPrzemyslaw Marczak 		case 4:
2551757df46SPrzemyslaw Marczak 			return OPMODE_LPM;
2561757df46SPrzemyslaw Marczak 		default:
2571757df46SPrzemyslaw Marczak 			return -EINVAL;
2581757df46SPrzemyslaw Marczak 		}
2591757df46SPrzemyslaw Marczak 	default:
2601757df46SPrzemyslaw Marczak 		return -EINVAL;
2611757df46SPrzemyslaw Marczak 	}
2621757df46SPrzemyslaw Marczak }
2631757df46SPrzemyslaw Marczak 
max77686_buck_modes(int buck,struct dm_regulator_mode ** modesp)2641757df46SPrzemyslaw Marczak static int max77686_buck_modes(int buck, struct dm_regulator_mode **modesp)
2651757df46SPrzemyslaw Marczak {
2661757df46SPrzemyslaw Marczak 	int ret = -EINVAL;
2671757df46SPrzemyslaw Marczak 
2681757df46SPrzemyslaw Marczak 	if (buck < 1 || buck > MAX77686_BUCK_NUM)
2691757df46SPrzemyslaw Marczak 		return ret;
2701757df46SPrzemyslaw Marczak 
2711757df46SPrzemyslaw Marczak 	switch (buck) {
2721757df46SPrzemyslaw Marczak 	case 1:
2731757df46SPrzemyslaw Marczak 		*modesp = max77686_buck_mode_standby;
2741757df46SPrzemyslaw Marczak 		ret = ARRAY_SIZE(max77686_buck_mode_standby);
2751757df46SPrzemyslaw Marczak 		break;
2761757df46SPrzemyslaw Marczak 	case 2:
2771757df46SPrzemyslaw Marczak 	case 3:
2781757df46SPrzemyslaw Marczak 	case 4:
2791757df46SPrzemyslaw Marczak 		*modesp = max77686_buck_mode_lpm;
2801757df46SPrzemyslaw Marczak 		ret = ARRAY_SIZE(max77686_buck_mode_lpm);
2811757df46SPrzemyslaw Marczak 		break;
2821757df46SPrzemyslaw Marczak 	default:
2831757df46SPrzemyslaw Marczak 		*modesp = max77686_buck_mode_onoff;
2841757df46SPrzemyslaw Marczak 		ret = ARRAY_SIZE(max77686_buck_mode_onoff);
2851757df46SPrzemyslaw Marczak 	}
2861757df46SPrzemyslaw Marczak 
2871757df46SPrzemyslaw Marczak 	return ret;
2881757df46SPrzemyslaw Marczak }
2891757df46SPrzemyslaw Marczak 
max77686_ldo_modes(int ldo,struct dm_regulator_mode ** modesp,struct udevice * dev)2901757df46SPrzemyslaw Marczak static int max77686_ldo_modes(int ldo, struct dm_regulator_mode **modesp,
2911757df46SPrzemyslaw Marczak 				struct udevice *dev)
2921757df46SPrzemyslaw Marczak {
2931757df46SPrzemyslaw Marczak 	int ret = -EINVAL;
2941757df46SPrzemyslaw Marczak 
2951757df46SPrzemyslaw Marczak 	if (ldo < 1 || ldo > MAX77686_LDO_NUM)
2961757df46SPrzemyslaw Marczak 		return ret;
2971757df46SPrzemyslaw Marczak 
2981757df46SPrzemyslaw Marczak 	switch (ldo) {
2991757df46SPrzemyslaw Marczak 	case 2:
3001757df46SPrzemyslaw Marczak 	case 6:
3011757df46SPrzemyslaw Marczak 	case 7:
3021757df46SPrzemyslaw Marczak 	case 8:
3031757df46SPrzemyslaw Marczak 	case 10:
3041757df46SPrzemyslaw Marczak 	case 11:
3051757df46SPrzemyslaw Marczak 	case 12:
3061757df46SPrzemyslaw Marczak 	case 14:
3071757df46SPrzemyslaw Marczak 	case 15:
3081757df46SPrzemyslaw Marczak 	case 16:
3091757df46SPrzemyslaw Marczak 		*modesp = max77686_ldo_mode_standby2;
3101757df46SPrzemyslaw Marczak 		ret = ARRAY_SIZE(max77686_ldo_mode_standby2);
3111757df46SPrzemyslaw Marczak 		break;
3121757df46SPrzemyslaw Marczak 	default:
3131757df46SPrzemyslaw Marczak 		*modesp = max77686_ldo_mode_standby1;
3141757df46SPrzemyslaw Marczak 		ret = ARRAY_SIZE(max77686_ldo_mode_standby1);
3151757df46SPrzemyslaw Marczak 	}
3161757df46SPrzemyslaw Marczak 
3171757df46SPrzemyslaw Marczak 	return ret;
3181757df46SPrzemyslaw Marczak }
3191757df46SPrzemyslaw Marczak 
max77686_ldo_val(struct udevice * dev,int op,int * uV)3201757df46SPrzemyslaw Marczak static int max77686_ldo_val(struct udevice *dev, int op, int *uV)
3211757df46SPrzemyslaw Marczak {
322aae78fa7STom Rini 	unsigned int adr;
3231757df46SPrzemyslaw Marczak 	unsigned char val;
324aae78fa7STom Rini 	int hex, ldo, ret;
3251757df46SPrzemyslaw Marczak 
3261757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET)
3271757df46SPrzemyslaw Marczak 		*uV = 0;
3281757df46SPrzemyslaw Marczak 
3291757df46SPrzemyslaw Marczak 	ldo = dev->driver_data;
3301757df46SPrzemyslaw Marczak 	if (ldo < 1 || ldo > MAX77686_LDO_NUM) {
331*90aa625cSMasahiro Yamada 		pr_err("Wrong ldo number: %d", ldo);
3321757df46SPrzemyslaw Marczak 		return -EINVAL;
3331757df46SPrzemyslaw Marczak 	}
3341757df46SPrzemyslaw Marczak 
3351757df46SPrzemyslaw Marczak 	adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
3361757df46SPrzemyslaw Marczak 
3371757df46SPrzemyslaw Marczak 	ret = pmic_read(dev->parent, adr, &val, 1);
3381757df46SPrzemyslaw Marczak 	if (ret)
3391757df46SPrzemyslaw Marczak 		return ret;
3401757df46SPrzemyslaw Marczak 
3411757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET) {
3421757df46SPrzemyslaw Marczak 		val &= MAX77686_LDO_VOLT_MASK;
3431757df46SPrzemyslaw Marczak 		ret = max77686_ldo_hex2volt(ldo, val);
3441757df46SPrzemyslaw Marczak 		if (ret < 0)
3451757df46SPrzemyslaw Marczak 			return ret;
3461757df46SPrzemyslaw Marczak 		*uV = ret;
3471757df46SPrzemyslaw Marczak 		return 0;
3481757df46SPrzemyslaw Marczak 	}
3491757df46SPrzemyslaw Marczak 
3501757df46SPrzemyslaw Marczak 	hex = max77686_ldo_volt2hex(ldo, *uV);
3511757df46SPrzemyslaw Marczak 	if (hex < 0)
3521757df46SPrzemyslaw Marczak 		return hex;
3531757df46SPrzemyslaw Marczak 
3541757df46SPrzemyslaw Marczak 	val &= ~MAX77686_LDO_VOLT_MASK;
3551757df46SPrzemyslaw Marczak 	val |= hex;
3561757df46SPrzemyslaw Marczak 	ret = pmic_write(dev->parent, adr, &val, 1);
3571757df46SPrzemyslaw Marczak 
3581757df46SPrzemyslaw Marczak 	return ret;
3591757df46SPrzemyslaw Marczak }
3601757df46SPrzemyslaw Marczak 
max77686_buck_val(struct udevice * dev,int op,int * uV)3611757df46SPrzemyslaw Marczak static int max77686_buck_val(struct udevice *dev, int op, int *uV)
3621757df46SPrzemyslaw Marczak {
363aae78fa7STom Rini 	unsigned int mask, adr;
3641757df46SPrzemyslaw Marczak 	unsigned char val;
365aae78fa7STom Rini 	int hex, buck, ret;
3661757df46SPrzemyslaw Marczak 
3671757df46SPrzemyslaw Marczak 	buck = dev->driver_data;
3681757df46SPrzemyslaw Marczak 	if (buck < 1 || buck > MAX77686_BUCK_NUM) {
369*90aa625cSMasahiro Yamada 		pr_err("Wrong buck number: %d", buck);
3701757df46SPrzemyslaw Marczak 		return -EINVAL;
3711757df46SPrzemyslaw Marczak 	}
3721757df46SPrzemyslaw Marczak 
3731757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET)
3741757df46SPrzemyslaw Marczak 		*uV = 0;
3751757df46SPrzemyslaw Marczak 
3761757df46SPrzemyslaw Marczak 	/* &buck_out = ctrl + 1 */
3778c428709SSimon Glass 	adr = max77686_buck_out[buck];
3781757df46SPrzemyslaw Marczak 
3791757df46SPrzemyslaw Marczak 	/* mask */
3801757df46SPrzemyslaw Marczak 	switch (buck) {
3811757df46SPrzemyslaw Marczak 	case 2:
3821757df46SPrzemyslaw Marczak 	case 3:
3831757df46SPrzemyslaw Marczak 	case 4:
3841757df46SPrzemyslaw Marczak 		mask = MAX77686_BUCK234_VOLT_MASK;
38575a429f1SSimon Glass 		break;
3861757df46SPrzemyslaw Marczak 	default:
3871757df46SPrzemyslaw Marczak 		mask = MAX77686_BUCK_VOLT_MASK;
38875a429f1SSimon Glass 		break;
3891757df46SPrzemyslaw Marczak 	}
3901757df46SPrzemyslaw Marczak 
3911757df46SPrzemyslaw Marczak 	ret = pmic_read(dev->parent, adr, &val, 1);
3921757df46SPrzemyslaw Marczak 	if (ret)
3931757df46SPrzemyslaw Marczak 		return ret;
3941757df46SPrzemyslaw Marczak 
3951757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET) {
3961757df46SPrzemyslaw Marczak 		val &= mask;
3971757df46SPrzemyslaw Marczak 		ret = max77686_buck_hex2volt(buck, val);
3981757df46SPrzemyslaw Marczak 		if (ret < 0)
3991757df46SPrzemyslaw Marczak 			return ret;
4001757df46SPrzemyslaw Marczak 		*uV = ret;
4011757df46SPrzemyslaw Marczak 		return 0;
4021757df46SPrzemyslaw Marczak 	}
4031757df46SPrzemyslaw Marczak 
4041757df46SPrzemyslaw Marczak 	hex = max77686_buck_volt2hex(buck, *uV);
4051757df46SPrzemyslaw Marczak 	if (hex < 0)
4061757df46SPrzemyslaw Marczak 		return hex;
4071757df46SPrzemyslaw Marczak 
4081757df46SPrzemyslaw Marczak 	val &= ~mask;
4091757df46SPrzemyslaw Marczak 	val |= hex;
4101757df46SPrzemyslaw Marczak 	ret = pmic_write(dev->parent, adr, &val, 1);
4111757df46SPrzemyslaw Marczak 
4121757df46SPrzemyslaw Marczak 	return ret;
4131757df46SPrzemyslaw Marczak }
4141757df46SPrzemyslaw Marczak 
max77686_ldo_mode(struct udevice * dev,int op,int * opmode)4151757df46SPrzemyslaw Marczak static int max77686_ldo_mode(struct udevice *dev, int op, int *opmode)
4161757df46SPrzemyslaw Marczak {
4178640522dSPeng Fan 	unsigned int adr, mode;
4181757df46SPrzemyslaw Marczak 	unsigned char val;
4198640522dSPeng Fan 	int ldo, ret;
4201757df46SPrzemyslaw Marczak 
4211757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET)
4221757df46SPrzemyslaw Marczak 		*opmode = -EINVAL;
4231757df46SPrzemyslaw Marczak 
4241757df46SPrzemyslaw Marczak 	ldo = dev->driver_data;
4251757df46SPrzemyslaw Marczak 	if (ldo < 1 || ldo > MAX77686_LDO_NUM) {
426*90aa625cSMasahiro Yamada 		pr_err("Wrong ldo number: %d", ldo);
4271757df46SPrzemyslaw Marczak 		return -EINVAL;
4281757df46SPrzemyslaw Marczak 	}
4291757df46SPrzemyslaw Marczak 
4301757df46SPrzemyslaw Marczak 	adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
4311757df46SPrzemyslaw Marczak 
4321757df46SPrzemyslaw Marczak 	ret = pmic_read(dev->parent, adr, &val, 1);
4331757df46SPrzemyslaw Marczak 	if (ret)
4341757df46SPrzemyslaw Marczak 		return ret;
4351757df46SPrzemyslaw Marczak 
4361757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET) {
4371757df46SPrzemyslaw Marczak 		val &= MAX77686_LDO_MODE_MASK;
4381757df46SPrzemyslaw Marczak 		ret = max77686_ldo_hex2mode(ldo, val);
4391757df46SPrzemyslaw Marczak 		if (ret < 0)
4401757df46SPrzemyslaw Marczak 			return ret;
4411757df46SPrzemyslaw Marczak 		*opmode = ret;
4421757df46SPrzemyslaw Marczak 		return 0;
4431757df46SPrzemyslaw Marczak 	}
4441757df46SPrzemyslaw Marczak 
4451757df46SPrzemyslaw Marczak 	/* mode */
4461757df46SPrzemyslaw Marczak 	switch (*opmode) {
4471757df46SPrzemyslaw Marczak 	case OPMODE_OFF:
4481757df46SPrzemyslaw Marczak 		mode = MAX77686_LDO_MODE_OFF;
4491757df46SPrzemyslaw Marczak 		break;
4501757df46SPrzemyslaw Marczak 	case OPMODE_LPM:
4511757df46SPrzemyslaw Marczak 		switch (ldo) {
4521757df46SPrzemyslaw Marczak 		case 2:
4531757df46SPrzemyslaw Marczak 		case 6:
4541757df46SPrzemyslaw Marczak 		case 7:
4551757df46SPrzemyslaw Marczak 		case 8:
4561757df46SPrzemyslaw Marczak 		case 10:
4571757df46SPrzemyslaw Marczak 		case 11:
4581757df46SPrzemyslaw Marczak 		case 12:
4591757df46SPrzemyslaw Marczak 		case 14:
4601757df46SPrzemyslaw Marczak 		case 15:
4611757df46SPrzemyslaw Marczak 		case 16:
4621757df46SPrzemyslaw Marczak 			return -EINVAL;
4631757df46SPrzemyslaw Marczak 		default:
4641757df46SPrzemyslaw Marczak 			mode = MAX77686_LDO_MODE_LPM;
4651757df46SPrzemyslaw Marczak 		}
4661757df46SPrzemyslaw Marczak 		break;
4671757df46SPrzemyslaw Marczak 	case OPMODE_STANDBY:
4681757df46SPrzemyslaw Marczak 		switch (ldo) {
4691757df46SPrzemyslaw Marczak 		case 2:
4701757df46SPrzemyslaw Marczak 		case 6:
4711757df46SPrzemyslaw Marczak 		case 7:
4721757df46SPrzemyslaw Marczak 		case 8:
4731757df46SPrzemyslaw Marczak 		case 10:
4741757df46SPrzemyslaw Marczak 		case 11:
4751757df46SPrzemyslaw Marczak 		case 12:
4761757df46SPrzemyslaw Marczak 		case 14:
4771757df46SPrzemyslaw Marczak 		case 15:
4781757df46SPrzemyslaw Marczak 		case 16:
4791757df46SPrzemyslaw Marczak 			mode = MAX77686_LDO_MODE_STANDBY;
4801757df46SPrzemyslaw Marczak 			break;
4811757df46SPrzemyslaw Marczak 		default:
4821757df46SPrzemyslaw Marczak 			return -EINVAL;
4831757df46SPrzemyslaw Marczak 		}
4841757df46SPrzemyslaw Marczak 		break;
4851757df46SPrzemyslaw Marczak 	case OPMODE_STANDBY_LPM:
4861757df46SPrzemyslaw Marczak 		mode = MAX77686_LDO_MODE_STANDBY_LPM;
4871757df46SPrzemyslaw Marczak 		break;
4881757df46SPrzemyslaw Marczak 	case OPMODE_ON:
4891757df46SPrzemyslaw Marczak 		mode = MAX77686_LDO_MODE_ON;
4901757df46SPrzemyslaw Marczak 		break;
4911757df46SPrzemyslaw Marczak 	default:
4921757df46SPrzemyslaw Marczak 		mode = 0xff;
4931757df46SPrzemyslaw Marczak 	}
4941757df46SPrzemyslaw Marczak 
4951757df46SPrzemyslaw Marczak 	if (mode == 0xff) {
496*90aa625cSMasahiro Yamada 		pr_err("Wrong mode: %d for ldo%d", *opmode, ldo);
4971757df46SPrzemyslaw Marczak 		return -EINVAL;
4981757df46SPrzemyslaw Marczak 	}
4991757df46SPrzemyslaw Marczak 
5001757df46SPrzemyslaw Marczak 	val &= ~MAX77686_LDO_MODE_MASK;
5011757df46SPrzemyslaw Marczak 	val |= mode;
5021757df46SPrzemyslaw Marczak 	ret = pmic_write(dev->parent, adr, &val, 1);
5031757df46SPrzemyslaw Marczak 
5041757df46SPrzemyslaw Marczak 	return ret;
5051757df46SPrzemyslaw Marczak }
5061757df46SPrzemyslaw Marczak 
max77686_ldo_enable(struct udevice * dev,int op,bool * enable)5071757df46SPrzemyslaw Marczak static int max77686_ldo_enable(struct udevice *dev, int op, bool *enable)
5081757df46SPrzemyslaw Marczak {
5091757df46SPrzemyslaw Marczak 	int ret, on_off;
5101757df46SPrzemyslaw Marczak 
5111757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET) {
5121757df46SPrzemyslaw Marczak 		ret = max77686_ldo_mode(dev, op, &on_off);
5131757df46SPrzemyslaw Marczak 		if (ret)
5141757df46SPrzemyslaw Marczak 			return ret;
5151757df46SPrzemyslaw Marczak 
5161757df46SPrzemyslaw Marczak 		switch (on_off) {
5171757df46SPrzemyslaw Marczak 		case OPMODE_OFF:
5186d6aececSTom Rini 			*enable = false;
5191757df46SPrzemyslaw Marczak 			break;
5201757df46SPrzemyslaw Marczak 		case OPMODE_ON:
5216d6aececSTom Rini 			*enable = true;
5221757df46SPrzemyslaw Marczak 			break;
5231757df46SPrzemyslaw Marczak 		default:
5241757df46SPrzemyslaw Marczak 			return -EINVAL;
5251757df46SPrzemyslaw Marczak 		}
5261757df46SPrzemyslaw Marczak 	} else if (op == PMIC_OP_SET) {
5276d6aececSTom Rini 		if (*enable)
5281757df46SPrzemyslaw Marczak 			on_off = OPMODE_ON;
5296d6aececSTom Rini 		else
5306d6aececSTom Rini 			on_off = OPMODE_OFF;
5311757df46SPrzemyslaw Marczak 
5321757df46SPrzemyslaw Marczak 		ret = max77686_ldo_mode(dev, op, &on_off);
5331757df46SPrzemyslaw Marczak 		if (ret)
5341757df46SPrzemyslaw Marczak 			return ret;
5351757df46SPrzemyslaw Marczak 	}
5361757df46SPrzemyslaw Marczak 
5371757df46SPrzemyslaw Marczak 	return 0;
5381757df46SPrzemyslaw Marczak }
5391757df46SPrzemyslaw Marczak 
max77686_buck_mode(struct udevice * dev,int op,int * opmode)5401757df46SPrzemyslaw Marczak static int max77686_buck_mode(struct udevice *dev, int op, int *opmode)
5411757df46SPrzemyslaw Marczak {
5428640522dSPeng Fan 	unsigned int mask, adr, mode, mode_shift;
5431757df46SPrzemyslaw Marczak 	unsigned char val;
5448640522dSPeng Fan 	int buck, ret;
5451757df46SPrzemyslaw Marczak 
5461757df46SPrzemyslaw Marczak 	buck = dev->driver_data;
5471757df46SPrzemyslaw Marczak 	if (buck < 1 || buck > MAX77686_BUCK_NUM) {
548*90aa625cSMasahiro Yamada 		pr_err("Wrong buck number: %d", buck);
5491757df46SPrzemyslaw Marczak 		return -EINVAL;
5501757df46SPrzemyslaw Marczak 	}
5511757df46SPrzemyslaw Marczak 
5528c428709SSimon Glass 	adr = max77686_buck_ctrl[buck];
5531757df46SPrzemyslaw Marczak 
5541757df46SPrzemyslaw Marczak 	/* mask */
5551757df46SPrzemyslaw Marczak 	switch (buck) {
5561757df46SPrzemyslaw Marczak 	case 2:
5571757df46SPrzemyslaw Marczak 	case 3:
5581757df46SPrzemyslaw Marczak 	case 4:
5591757df46SPrzemyslaw Marczak 		mode_shift = MAX77686_BUCK_MODE_SHIFT_2;
5601757df46SPrzemyslaw Marczak 		break;
5611757df46SPrzemyslaw Marczak 	default:
5621757df46SPrzemyslaw Marczak 		mode_shift = MAX77686_BUCK_MODE_SHIFT_1;
5631757df46SPrzemyslaw Marczak 	}
5641757df46SPrzemyslaw Marczak 
5651757df46SPrzemyslaw Marczak 	mask = MAX77686_BUCK_MODE_MASK << mode_shift;
5661757df46SPrzemyslaw Marczak 
5671757df46SPrzemyslaw Marczak 	ret = pmic_read(dev->parent, adr, &val, 1);
5681757df46SPrzemyslaw Marczak 	if (ret)
5691757df46SPrzemyslaw Marczak 		return ret;
5701757df46SPrzemyslaw Marczak 
5711757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET) {
5721757df46SPrzemyslaw Marczak 		val &= mask;
5731757df46SPrzemyslaw Marczak 		val >>= mode_shift;
5741757df46SPrzemyslaw Marczak 		ret = max77686_buck_hex2mode(buck, val);
5751757df46SPrzemyslaw Marczak 		if (ret < 0)
5761757df46SPrzemyslaw Marczak 			return ret;
5771757df46SPrzemyslaw Marczak 		*opmode = ret;
5781757df46SPrzemyslaw Marczak 		return 0;
5791757df46SPrzemyslaw Marczak 	}
5801757df46SPrzemyslaw Marczak 
5811757df46SPrzemyslaw Marczak 	/* mode */
5821757df46SPrzemyslaw Marczak 	switch (*opmode) {
5831757df46SPrzemyslaw Marczak 	case OPMODE_OFF:
5841757df46SPrzemyslaw Marczak 		mode = MAX77686_BUCK_MODE_OFF;
5851757df46SPrzemyslaw Marczak 		break;
5861757df46SPrzemyslaw Marczak 	case OPMODE_STANDBY:
5871757df46SPrzemyslaw Marczak 		switch (buck) {
5881757df46SPrzemyslaw Marczak 		case 1:
5891757df46SPrzemyslaw Marczak 		case 2:
5901757df46SPrzemyslaw Marczak 		case 3:
5911757df46SPrzemyslaw Marczak 		case 4:
5921757df46SPrzemyslaw Marczak 			mode = MAX77686_BUCK_MODE_STANDBY << mode_shift;
5931757df46SPrzemyslaw Marczak 			break;
5941757df46SPrzemyslaw Marczak 		default:
5951757df46SPrzemyslaw Marczak 			mode = 0xff;
5961757df46SPrzemyslaw Marczak 		}
5971757df46SPrzemyslaw Marczak 		break;
5981757df46SPrzemyslaw Marczak 	case OPMODE_LPM:
5991757df46SPrzemyslaw Marczak 		switch (buck) {
6001757df46SPrzemyslaw Marczak 		case 2:
6011757df46SPrzemyslaw Marczak 		case 3:
6021757df46SPrzemyslaw Marczak 		case 4:
6031757df46SPrzemyslaw Marczak 			mode = MAX77686_BUCK_MODE_LPM << mode_shift;
6041757df46SPrzemyslaw Marczak 			break;
6051757df46SPrzemyslaw Marczak 		default:
6061757df46SPrzemyslaw Marczak 			mode = 0xff;
6071757df46SPrzemyslaw Marczak 		}
6081757df46SPrzemyslaw Marczak 		break;
6091757df46SPrzemyslaw Marczak 	case OPMODE_ON:
6101757df46SPrzemyslaw Marczak 		mode = MAX77686_BUCK_MODE_ON << mode_shift;
6111757df46SPrzemyslaw Marczak 		break;
6121757df46SPrzemyslaw Marczak 	default:
6131757df46SPrzemyslaw Marczak 		mode = 0xff;
6141757df46SPrzemyslaw Marczak 	}
6151757df46SPrzemyslaw Marczak 
6161757df46SPrzemyslaw Marczak 	if (mode == 0xff) {
617*90aa625cSMasahiro Yamada 		pr_err("Wrong mode: %d for buck: %d\n", *opmode, buck);
6181757df46SPrzemyslaw Marczak 		return -EINVAL;
6191757df46SPrzemyslaw Marczak 	}
6201757df46SPrzemyslaw Marczak 
6211757df46SPrzemyslaw Marczak 	val &= ~mask;
6221757df46SPrzemyslaw Marczak 	val |= mode;
6231757df46SPrzemyslaw Marczak 	ret = pmic_write(dev->parent, adr, &val, 1);
6241757df46SPrzemyslaw Marczak 
6251757df46SPrzemyslaw Marczak 	return ret;
6261757df46SPrzemyslaw Marczak }
6271757df46SPrzemyslaw Marczak 
max77686_buck_enable(struct udevice * dev,int op,bool * enable)6281757df46SPrzemyslaw Marczak static int max77686_buck_enable(struct udevice *dev, int op, bool *enable)
6291757df46SPrzemyslaw Marczak {
6301757df46SPrzemyslaw Marczak 	int ret, on_off;
6311757df46SPrzemyslaw Marczak 
6321757df46SPrzemyslaw Marczak 	if (op == PMIC_OP_GET) {
6331757df46SPrzemyslaw Marczak 		ret = max77686_buck_mode(dev, op, &on_off);
6341757df46SPrzemyslaw Marczak 		if (ret)
6351757df46SPrzemyslaw Marczak 			return ret;
6361757df46SPrzemyslaw Marczak 
6371757df46SPrzemyslaw Marczak 		switch (on_off) {
6381757df46SPrzemyslaw Marczak 		case OPMODE_OFF:
6391757df46SPrzemyslaw Marczak 			*enable = false;
6401757df46SPrzemyslaw Marczak 			break;
6411757df46SPrzemyslaw Marczak 		case OPMODE_ON:
6421757df46SPrzemyslaw Marczak 			*enable = true;
6431757df46SPrzemyslaw Marczak 			break;
6441757df46SPrzemyslaw Marczak 		default:
6451757df46SPrzemyslaw Marczak 			return -EINVAL;
6461757df46SPrzemyslaw Marczak 		}
6471757df46SPrzemyslaw Marczak 	} else if (op == PMIC_OP_SET) {
6486d6aececSTom Rini 		if (*enable)
6491757df46SPrzemyslaw Marczak 			on_off = OPMODE_ON;
6506d6aececSTom Rini 		else
6516d6aececSTom Rini 			on_off = OPMODE_OFF;
6521757df46SPrzemyslaw Marczak 
6531757df46SPrzemyslaw Marczak 		ret = max77686_buck_mode(dev, op, &on_off);
6541757df46SPrzemyslaw Marczak 		if (ret)
6551757df46SPrzemyslaw Marczak 			return ret;
6561757df46SPrzemyslaw Marczak 	}
6571757df46SPrzemyslaw Marczak 
6581757df46SPrzemyslaw Marczak 	return 0;
6591757df46SPrzemyslaw Marczak }
6601757df46SPrzemyslaw Marczak 
max77686_ldo_probe(struct udevice * dev)6611757df46SPrzemyslaw Marczak static int max77686_ldo_probe(struct udevice *dev)
6621757df46SPrzemyslaw Marczak {
6631757df46SPrzemyslaw Marczak 	struct dm_regulator_uclass_platdata *uc_pdata;
6641757df46SPrzemyslaw Marczak 
6651757df46SPrzemyslaw Marczak 	uc_pdata = dev_get_uclass_platdata(dev);
6661757df46SPrzemyslaw Marczak 
6671757df46SPrzemyslaw Marczak 	uc_pdata->type = REGULATOR_TYPE_LDO;
6681757df46SPrzemyslaw Marczak 	uc_pdata->mode_count = max77686_ldo_modes(dev->driver_data,
6691757df46SPrzemyslaw Marczak 						  &uc_pdata->mode, dev);
6701757df46SPrzemyslaw Marczak 
6711757df46SPrzemyslaw Marczak 	return 0;
6721757df46SPrzemyslaw Marczak }
6731757df46SPrzemyslaw Marczak 
ldo_get_value(struct udevice * dev)6741757df46SPrzemyslaw Marczak static int ldo_get_value(struct udevice *dev)
6751757df46SPrzemyslaw Marczak {
6761757df46SPrzemyslaw Marczak 	int uV;
6771757df46SPrzemyslaw Marczak 	int ret;
6781757df46SPrzemyslaw Marczak 
6791757df46SPrzemyslaw Marczak 	ret = max77686_ldo_val(dev, PMIC_OP_GET, &uV);
6801757df46SPrzemyslaw Marczak 	if (ret)
6811757df46SPrzemyslaw Marczak 		return ret;
6821757df46SPrzemyslaw Marczak 
6831757df46SPrzemyslaw Marczak 	return uV;
6841757df46SPrzemyslaw Marczak }
6851757df46SPrzemyslaw Marczak 
ldo_set_value(struct udevice * dev,int uV)6861757df46SPrzemyslaw Marczak static int ldo_set_value(struct udevice *dev, int uV)
6871757df46SPrzemyslaw Marczak {
6881757df46SPrzemyslaw Marczak 	return max77686_ldo_val(dev, PMIC_OP_SET, &uV);
6891757df46SPrzemyslaw Marczak }
6901757df46SPrzemyslaw Marczak 
ldo_get_enable(struct udevice * dev)691b616835dSKeerthy static int ldo_get_enable(struct udevice *dev)
6921757df46SPrzemyslaw Marczak {
6931757df46SPrzemyslaw Marczak 	bool enable = false;
6941757df46SPrzemyslaw Marczak 	int ret;
6951757df46SPrzemyslaw Marczak 
6961757df46SPrzemyslaw Marczak 	ret = max77686_ldo_enable(dev, PMIC_OP_GET, &enable);
6971757df46SPrzemyslaw Marczak 	if (ret)
6981757df46SPrzemyslaw Marczak 		return ret;
6991757df46SPrzemyslaw Marczak 
7001757df46SPrzemyslaw Marczak 	return enable;
7011757df46SPrzemyslaw Marczak }
7021757df46SPrzemyslaw Marczak 
ldo_set_enable(struct udevice * dev,bool enable)7031757df46SPrzemyslaw Marczak static int ldo_set_enable(struct udevice *dev, bool enable)
7041757df46SPrzemyslaw Marczak {
7051757df46SPrzemyslaw Marczak 	return max77686_ldo_enable(dev, PMIC_OP_SET, &enable);
7061757df46SPrzemyslaw Marczak }
7071757df46SPrzemyslaw Marczak 
ldo_get_mode(struct udevice * dev)7081757df46SPrzemyslaw Marczak static int ldo_get_mode(struct udevice *dev)
7091757df46SPrzemyslaw Marczak {
7101757df46SPrzemyslaw Marczak 	int mode;
7111757df46SPrzemyslaw Marczak 	int ret;
7121757df46SPrzemyslaw Marczak 
7131757df46SPrzemyslaw Marczak 	ret = max77686_ldo_mode(dev, PMIC_OP_GET, &mode);
7141757df46SPrzemyslaw Marczak 	if (ret)
7151757df46SPrzemyslaw Marczak 		return ret;
7161757df46SPrzemyslaw Marczak 
7171757df46SPrzemyslaw Marczak 	return mode;
7181757df46SPrzemyslaw Marczak }
7191757df46SPrzemyslaw Marczak 
ldo_set_mode(struct udevice * dev,int mode)7201757df46SPrzemyslaw Marczak static int ldo_set_mode(struct udevice *dev, int mode)
7211757df46SPrzemyslaw Marczak {
7221757df46SPrzemyslaw Marczak 	return max77686_ldo_mode(dev, PMIC_OP_SET, &mode);
7231757df46SPrzemyslaw Marczak }
7241757df46SPrzemyslaw Marczak 
max77686_buck_probe(struct udevice * dev)7251757df46SPrzemyslaw Marczak static int max77686_buck_probe(struct udevice *dev)
7261757df46SPrzemyslaw Marczak {
7271757df46SPrzemyslaw Marczak 	struct dm_regulator_uclass_platdata *uc_pdata;
7281757df46SPrzemyslaw Marczak 
7291757df46SPrzemyslaw Marczak 	uc_pdata = dev_get_uclass_platdata(dev);
7301757df46SPrzemyslaw Marczak 
7311757df46SPrzemyslaw Marczak 	uc_pdata->type = REGULATOR_TYPE_BUCK;
7321757df46SPrzemyslaw Marczak 	uc_pdata->mode_count = max77686_buck_modes(dev->driver_data,
7331757df46SPrzemyslaw Marczak 						   &uc_pdata->mode);
7341757df46SPrzemyslaw Marczak 
7351757df46SPrzemyslaw Marczak 	return 0;
7361757df46SPrzemyslaw Marczak }
7371757df46SPrzemyslaw Marczak 
buck_get_value(struct udevice * dev)7381757df46SPrzemyslaw Marczak static int buck_get_value(struct udevice *dev)
7391757df46SPrzemyslaw Marczak {
7401757df46SPrzemyslaw Marczak 	int uV;
7411757df46SPrzemyslaw Marczak 	int ret;
7421757df46SPrzemyslaw Marczak 
7431757df46SPrzemyslaw Marczak 	ret = max77686_buck_val(dev, PMIC_OP_GET, &uV);
7441757df46SPrzemyslaw Marczak 	if (ret)
7451757df46SPrzemyslaw Marczak 		return ret;
7461757df46SPrzemyslaw Marczak 
7471757df46SPrzemyslaw Marczak 	return uV;
7481757df46SPrzemyslaw Marczak }
7491757df46SPrzemyslaw Marczak 
buck_set_value(struct udevice * dev,int uV)7501757df46SPrzemyslaw Marczak static int buck_set_value(struct udevice *dev, int uV)
7511757df46SPrzemyslaw Marczak {
7521757df46SPrzemyslaw Marczak 	return max77686_buck_val(dev, PMIC_OP_SET, &uV);
7531757df46SPrzemyslaw Marczak }
7541757df46SPrzemyslaw Marczak 
buck_get_enable(struct udevice * dev)755b616835dSKeerthy static int buck_get_enable(struct udevice *dev)
7561757df46SPrzemyslaw Marczak {
7571757df46SPrzemyslaw Marczak 	bool enable = false;
7581757df46SPrzemyslaw Marczak 	int ret;
7591757df46SPrzemyslaw Marczak 
7601757df46SPrzemyslaw Marczak 	ret = max77686_buck_enable(dev, PMIC_OP_GET, &enable);
7611757df46SPrzemyslaw Marczak 	if (ret)
7621757df46SPrzemyslaw Marczak 		return ret;
7631757df46SPrzemyslaw Marczak 
7641757df46SPrzemyslaw Marczak 	return enable;
7651757df46SPrzemyslaw Marczak }
7661757df46SPrzemyslaw Marczak 
buck_set_enable(struct udevice * dev,bool enable)7671757df46SPrzemyslaw Marczak static int buck_set_enable(struct udevice *dev, bool enable)
7681757df46SPrzemyslaw Marczak {
7691757df46SPrzemyslaw Marczak 	return max77686_buck_enable(dev, PMIC_OP_SET, &enable);
7701757df46SPrzemyslaw Marczak }
7711757df46SPrzemyslaw Marczak 
buck_get_mode(struct udevice * dev)7721757df46SPrzemyslaw Marczak static int buck_get_mode(struct udevice *dev)
7731757df46SPrzemyslaw Marczak {
7741757df46SPrzemyslaw Marczak 	int mode;
7751757df46SPrzemyslaw Marczak 	int ret;
7761757df46SPrzemyslaw Marczak 
7771757df46SPrzemyslaw Marczak 	ret = max77686_buck_mode(dev, PMIC_OP_GET, &mode);
7781757df46SPrzemyslaw Marczak 	if (ret)
7791757df46SPrzemyslaw Marczak 		return ret;
7801757df46SPrzemyslaw Marczak 
7811757df46SPrzemyslaw Marczak 	return mode;
7821757df46SPrzemyslaw Marczak }
7831757df46SPrzemyslaw Marczak 
buck_set_mode(struct udevice * dev,int mode)7841757df46SPrzemyslaw Marczak static int buck_set_mode(struct udevice *dev, int mode)
7851757df46SPrzemyslaw Marczak {
7861757df46SPrzemyslaw Marczak 	return max77686_buck_mode(dev, PMIC_OP_SET, &mode);
7871757df46SPrzemyslaw Marczak }
7881757df46SPrzemyslaw Marczak 
7891757df46SPrzemyslaw Marczak static const struct dm_regulator_ops max77686_ldo_ops = {
7901757df46SPrzemyslaw Marczak 	.get_value  = ldo_get_value,
7911757df46SPrzemyslaw Marczak 	.set_value  = ldo_set_value,
7921757df46SPrzemyslaw Marczak 	.get_enable = ldo_get_enable,
7931757df46SPrzemyslaw Marczak 	.set_enable = ldo_set_enable,
7941757df46SPrzemyslaw Marczak 	.get_mode   = ldo_get_mode,
7951757df46SPrzemyslaw Marczak 	.set_mode   = ldo_set_mode,
7961757df46SPrzemyslaw Marczak };
7971757df46SPrzemyslaw Marczak 
7981757df46SPrzemyslaw Marczak U_BOOT_DRIVER(max77686_ldo) = {
7991757df46SPrzemyslaw Marczak 	.name = MAX77686_LDO_DRIVER,
8001757df46SPrzemyslaw Marczak 	.id = UCLASS_REGULATOR,
8011757df46SPrzemyslaw Marczak 	.ops = &max77686_ldo_ops,
8021757df46SPrzemyslaw Marczak 	.probe = max77686_ldo_probe,
8031757df46SPrzemyslaw Marczak };
8041757df46SPrzemyslaw Marczak 
8051757df46SPrzemyslaw Marczak static const struct dm_regulator_ops max77686_buck_ops = {
8061757df46SPrzemyslaw Marczak 	.get_value  = buck_get_value,
8071757df46SPrzemyslaw Marczak 	.set_value  = buck_set_value,
8081757df46SPrzemyslaw Marczak 	.get_enable = buck_get_enable,
8091757df46SPrzemyslaw Marczak 	.set_enable = buck_set_enable,
8101757df46SPrzemyslaw Marczak 	.get_mode   = buck_get_mode,
8111757df46SPrzemyslaw Marczak 	.set_mode   = buck_set_mode,
8121757df46SPrzemyslaw Marczak };
8131757df46SPrzemyslaw Marczak 
8141757df46SPrzemyslaw Marczak U_BOOT_DRIVER(max77686_buck) = {
8151757df46SPrzemyslaw Marczak 	.name = MAX77686_BUCK_DRIVER,
8161757df46SPrzemyslaw Marczak 	.id = UCLASS_REGULATOR,
8171757df46SPrzemyslaw Marczak 	.ops = &max77686_buck_ops,
8181757df46SPrzemyslaw Marczak 	.probe = max77686_buck_probe,
8191757df46SPrzemyslaw Marczak };
820