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 721757df46SPrzemyslaw Marczak static int max77686_buck_volt2hex(int buck, int uV) 731757df46SPrzemyslaw Marczak { 741757df46SPrzemyslaw Marczak unsigned int hex = 0; 751757df46SPrzemyslaw Marczak unsigned 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 1011757df46SPrzemyslaw Marczak error("Value: %d uV is wrong for BUCK%d", uV, buck); 1021757df46SPrzemyslaw Marczak return -EINVAL; 1031757df46SPrzemyslaw Marczak } 1041757df46SPrzemyslaw Marczak 1051757df46SPrzemyslaw Marczak static int max77686_buck_hex2volt(int buck, int hex) 1061757df46SPrzemyslaw Marczak { 1071757df46SPrzemyslaw Marczak unsigned uV = 0; 1081757df46SPrzemyslaw Marczak unsigned 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: 1371757df46SPrzemyslaw Marczak error("Value: %#x is wrong for BUCK%d", hex, buck); 1381757df46SPrzemyslaw Marczak return -EINVAL; 1391757df46SPrzemyslaw Marczak } 1401757df46SPrzemyslaw Marczak 1411757df46SPrzemyslaw Marczak static int max77686_ldo_volt2hex(int ldo, int uV) 1421757df46SPrzemyslaw Marczak { 1431757df46SPrzemyslaw Marczak unsigned 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 1631757df46SPrzemyslaw Marczak error("Value: %d uV is wrong for LDO%d", uV, ldo); 1641757df46SPrzemyslaw Marczak return -EINVAL; 1651757df46SPrzemyslaw Marczak } 1661757df46SPrzemyslaw Marczak 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: 1921757df46SPrzemyslaw Marczak error("Value: %#x is wrong for ldo%d", hex, ldo); 1931757df46SPrzemyslaw Marczak return -EINVAL; 1941757df46SPrzemyslaw Marczak } 1951757df46SPrzemyslaw Marczak 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 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 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 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 3201757df46SPrzemyslaw Marczak static int max77686_ldo_val(struct udevice *dev, int op, int *uV) 3211757df46SPrzemyslaw Marczak { 3228640522dSPeng Fan unsigned int hex, adr; 3231757df46SPrzemyslaw Marczak unsigned char val; 3248640522dSPeng Fan int 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) { 3311757df46SPrzemyslaw Marczak error("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 3611757df46SPrzemyslaw Marczak static int max77686_buck_val(struct udevice *dev, int op, int *uV) 3621757df46SPrzemyslaw Marczak { 3638640522dSPeng Fan unsigned int hex, mask, adr; 3641757df46SPrzemyslaw Marczak unsigned char val; 3658640522dSPeng Fan int buck, ret; 3661757df46SPrzemyslaw Marczak 3671757df46SPrzemyslaw Marczak buck = dev->driver_data; 3681757df46SPrzemyslaw Marczak if (buck < 1 || buck > MAX77686_BUCK_NUM) { 3691757df46SPrzemyslaw Marczak error("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 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) { 4261757df46SPrzemyslaw Marczak error("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) { 4961757df46SPrzemyslaw Marczak error("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 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: 518*6d6aececSTom Rini *enable = false; 5191757df46SPrzemyslaw Marczak break; 5201757df46SPrzemyslaw Marczak case OPMODE_ON: 521*6d6aececSTom Rini *enable = true; 5221757df46SPrzemyslaw Marczak break; 5231757df46SPrzemyslaw Marczak default: 5241757df46SPrzemyslaw Marczak return -EINVAL; 5251757df46SPrzemyslaw Marczak } 5261757df46SPrzemyslaw Marczak } else if (op == PMIC_OP_SET) { 527*6d6aececSTom Rini if (*enable) 5281757df46SPrzemyslaw Marczak on_off = OPMODE_ON; 529*6d6aececSTom Rini else 530*6d6aececSTom 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 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) { 5481757df46SPrzemyslaw Marczak error("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) { 6171757df46SPrzemyslaw Marczak error("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 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) { 648*6d6aececSTom Rini if (*enable) 6491757df46SPrzemyslaw Marczak on_off = OPMODE_ON; 650*6d6aececSTom Rini else 651*6d6aececSTom 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 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 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 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 6911757df46SPrzemyslaw Marczak static bool 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 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 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 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 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 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 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 7551757df46SPrzemyslaw Marczak static bool 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 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 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 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