mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-16 09:48:16 +00:00
aae78fa774
Inside of max77686_buck_volt2hex/max77686_buck_hex2volt/max77686_ldo_volt2hex we check that the value we calculate is >= 0 however we declare 'hex' as unsigned int making these always true. Mark these as 'int' instead. We also move hex_max to int as they are constants that are 0x3f/0xff. Given that the above functions are marked as returning an int, make the variables we assign their return value to also be int to be able to catch the error condition now. Reported by clang-3.8. Cc: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Tom Rini <trini@konsulko.com>
819 lines
15 KiB
C
819 lines
15 KiB
C
/*
|
|
* Copyright (C) 2012-2015 Samsung Electronics
|
|
*
|
|
* Rajeshwari Shinde <rajeshwari.s@samsung.com>
|
|
* Przemyslaw Marczak <p.marczak@samsung.com>
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <fdtdec.h>
|
|
#include <errno.h>
|
|
#include <dm.h>
|
|
#include <i2c.h>
|
|
#include <power/pmic.h>
|
|
#include <power/regulator.h>
|
|
#include <power/max77686_pmic.h>
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
#define MODE(_id, _val, _name) { \
|
|
.id = _id, \
|
|
.register_value = _val, \
|
|
.name = _name, \
|
|
}
|
|
|
|
/* LDO: 1,3,4,5,9,17,18,19,20,21,22,23,24,26,26,27 */
|
|
static struct dm_regulator_mode max77686_ldo_mode_standby1[] = {
|
|
MODE(OPMODE_OFF, MAX77686_LDO_MODE_OFF, "OFF"),
|
|
MODE(OPMODE_LPM, MAX77686_LDO_MODE_LPM, "LPM"),
|
|
MODE(OPMODE_STANDBY_LPM, MAX77686_LDO_MODE_STANDBY_LPM, "ON/LPM"),
|
|
MODE(OPMODE_ON, MAX77686_LDO_MODE_ON, "ON"),
|
|
};
|
|
|
|
/* LDO: 2,6,7,8,10,11,12,14,15,16 */
|
|
static struct dm_regulator_mode max77686_ldo_mode_standby2[] = {
|
|
MODE(OPMODE_OFF, MAX77686_LDO_MODE_OFF, "OFF"),
|
|
MODE(OPMODE_STANDBY, MAX77686_LDO_MODE_STANDBY, "ON/OFF"),
|
|
MODE(OPMODE_STANDBY_LPM, MAX77686_LDO_MODE_STANDBY_LPM, "ON/LPM"),
|
|
MODE(OPMODE_ON, MAX77686_LDO_MODE_ON, "ON"),
|
|
};
|
|
|
|
/* Buck: 1 */
|
|
static struct dm_regulator_mode max77686_buck_mode_standby[] = {
|
|
MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
|
|
MODE(OPMODE_STANDBY, MAX77686_BUCK_MODE_STANDBY, "ON/OFF"),
|
|
MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
|
|
};
|
|
|
|
/* Buck: 2,3,4 */
|
|
static struct dm_regulator_mode max77686_buck_mode_lpm[] = {
|
|
MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
|
|
MODE(OPMODE_STANDBY, MAX77686_BUCK_MODE_STANDBY, "ON/OFF"),
|
|
MODE(OPMODE_LPM, MAX77686_BUCK_MODE_LPM, "LPM"),
|
|
MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
|
|
};
|
|
|
|
/* Buck: 5,6,7,8,9 */
|
|
static struct dm_regulator_mode max77686_buck_mode_onoff[] = {
|
|
MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
|
|
MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
|
|
};
|
|
|
|
static const char max77686_buck_ctrl[] = {
|
|
0xff, 0x10, 0x12, 0x1c, 0x26, 0x30, 0x32, 0x34, 0x36, 0x38
|
|
};
|
|
|
|
static const char max77686_buck_out[] = {
|
|
0xff, 0x11, 0x14, 0x1e, 0x28, 0x31, 0x33, 0x35, 0x37, 0x39
|
|
};
|
|
|
|
static int max77686_buck_volt2hex(int buck, int uV)
|
|
{
|
|
int hex = 0;
|
|
int hex_max = 0;
|
|
|
|
switch (buck) {
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
/* hex = (uV - 600000) / 12500; */
|
|
hex = (uV - MAX77686_BUCK_UV_LMIN) / MAX77686_BUCK_UV_LSTEP;
|
|
hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
|
|
break;
|
|
default:
|
|
/*
|
|
* hex = (uV - 750000) / 50000. We assume that dynamic voltage
|
|
* scaling via GPIOs is not enabled and don't support that.
|
|
* If this is enabled then the driver will need to take that
|
|
* into account and check different registers depending on
|
|
* the current setting. See the datasheet for details.
|
|
*/
|
|
hex = (uV - MAX77686_BUCK_UV_HMIN) / MAX77686_BUCK_UV_HSTEP;
|
|
hex_max = MAX77686_BUCK_VOLT_MAX_HEX;
|
|
break;
|
|
}
|
|
|
|
if (hex >= 0 && hex <= hex_max)
|
|
return hex;
|
|
|
|
error("Value: %d uV is wrong for BUCK%d", uV, buck);
|
|
return -EINVAL;
|
|
}
|
|
|
|
static int max77686_buck_hex2volt(int buck, int hex)
|
|
{
|
|
unsigned uV = 0;
|
|
int hex_max = 0;
|
|
|
|
if (hex < 0)
|
|
goto bad_hex;
|
|
|
|
switch (buck) {
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
|
|
if (hex > hex_max)
|
|
goto bad_hex;
|
|
|
|
/* uV = hex * 12500 + 600000; */
|
|
uV = hex * MAX77686_BUCK_UV_LSTEP + MAX77686_BUCK_UV_LMIN;
|
|
break;
|
|
default:
|
|
hex_max = MAX77686_BUCK_VOLT_MAX_HEX;
|
|
if (hex > hex_max)
|
|
goto bad_hex;
|
|
|
|
/* uV = hex * 50000 + 750000; */
|
|
uV = hex * MAX77686_BUCK_UV_HSTEP + MAX77686_BUCK_UV_HMIN;
|
|
break;
|
|
}
|
|
|
|
return uV;
|
|
|
|
bad_hex:
|
|
error("Value: %#x is wrong for BUCK%d", hex, buck);
|
|
return -EINVAL;
|
|
}
|
|
|
|
static int max77686_ldo_volt2hex(int ldo, int uV)
|
|
{
|
|
int hex = 0;
|
|
|
|
switch (ldo) {
|
|
case 1:
|
|
case 2:
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
case 15:
|
|
hex = (uV - MAX77686_LDO_UV_MIN) / MAX77686_LDO_UV_LSTEP;
|
|
/* hex = (uV - 800000) / 25000; */
|
|
break;
|
|
default:
|
|
hex = (uV - MAX77686_LDO_UV_MIN) / MAX77686_LDO_UV_HSTEP;
|
|
/* hex = (uV - 800000) / 50000; */
|
|
}
|
|
|
|
if (hex >= 0 && hex <= MAX77686_LDO_VOLT_MAX_HEX)
|
|
return hex;
|
|
|
|
error("Value: %d uV is wrong for LDO%d", uV, ldo);
|
|
return -EINVAL;
|
|
}
|
|
|
|
static int max77686_ldo_hex2volt(int ldo, int hex)
|
|
{
|
|
unsigned int uV = 0;
|
|
|
|
if (hex > MAX77686_LDO_VOLT_MAX_HEX)
|
|
goto bad_hex;
|
|
|
|
switch (ldo) {
|
|
case 1:
|
|
case 2:
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
case 15:
|
|
/* uV = hex * 25000 + 800000; */
|
|
uV = hex * MAX77686_LDO_UV_LSTEP + MAX77686_LDO_UV_MIN;
|
|
break;
|
|
default:
|
|
/* uV = hex * 50000 + 800000; */
|
|
uV = hex * MAX77686_LDO_UV_HSTEP + MAX77686_LDO_UV_MIN;
|
|
}
|
|
|
|
return uV;
|
|
|
|
bad_hex:
|
|
error("Value: %#x is wrong for ldo%d", hex, ldo);
|
|
return -EINVAL;
|
|
}
|
|
|
|
static int max77686_ldo_hex2mode(int ldo, int hex)
|
|
{
|
|
if (hex > MAX77686_LDO_MODE_MASK)
|
|
return -EINVAL;
|
|
|
|
switch (hex) {
|
|
case MAX77686_LDO_MODE_OFF:
|
|
return OPMODE_OFF;
|
|
case MAX77686_LDO_MODE_LPM: /* == MAX77686_LDO_MODE_STANDBY: */
|
|
/* The same mode values but different meaning for each ldo */
|
|
switch (ldo) {
|
|
case 2:
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
case 10:
|
|
case 11:
|
|
case 12:
|
|
case 14:
|
|
case 15:
|
|
case 16:
|
|
return OPMODE_STANDBY;
|
|
default:
|
|
return OPMODE_LPM;
|
|
}
|
|
case MAX77686_LDO_MODE_STANDBY_LPM:
|
|
return OPMODE_STANDBY_LPM;
|
|
case MAX77686_LDO_MODE_ON:
|
|
return OPMODE_ON;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
static int max77686_buck_hex2mode(int buck, int hex)
|
|
{
|
|
if (hex > MAX77686_BUCK_MODE_MASK)
|
|
return -EINVAL;
|
|
|
|
switch (hex) {
|
|
case MAX77686_BUCK_MODE_OFF:
|
|
return OPMODE_OFF;
|
|
case MAX77686_BUCK_MODE_ON:
|
|
return OPMODE_ON;
|
|
case MAX77686_BUCK_MODE_STANDBY:
|
|
switch (buck) {
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
return OPMODE_STANDBY;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
case MAX77686_BUCK_MODE_LPM:
|
|
switch (buck) {
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
return OPMODE_LPM;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
static int max77686_buck_modes(int buck, struct dm_regulator_mode **modesp)
|
|
{
|
|
int ret = -EINVAL;
|
|
|
|
if (buck < 1 || buck > MAX77686_BUCK_NUM)
|
|
return ret;
|
|
|
|
switch (buck) {
|
|
case 1:
|
|
*modesp = max77686_buck_mode_standby;
|
|
ret = ARRAY_SIZE(max77686_buck_mode_standby);
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
*modesp = max77686_buck_mode_lpm;
|
|
ret = ARRAY_SIZE(max77686_buck_mode_lpm);
|
|
break;
|
|
default:
|
|
*modesp = max77686_buck_mode_onoff;
|
|
ret = ARRAY_SIZE(max77686_buck_mode_onoff);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int max77686_ldo_modes(int ldo, struct dm_regulator_mode **modesp,
|
|
struct udevice *dev)
|
|
{
|
|
int ret = -EINVAL;
|
|
|
|
if (ldo < 1 || ldo > MAX77686_LDO_NUM)
|
|
return ret;
|
|
|
|
switch (ldo) {
|
|
case 2:
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
case 10:
|
|
case 11:
|
|
case 12:
|
|
case 14:
|
|
case 15:
|
|
case 16:
|
|
*modesp = max77686_ldo_mode_standby2;
|
|
ret = ARRAY_SIZE(max77686_ldo_mode_standby2);
|
|
break;
|
|
default:
|
|
*modesp = max77686_ldo_mode_standby1;
|
|
ret = ARRAY_SIZE(max77686_ldo_mode_standby1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int max77686_ldo_val(struct udevice *dev, int op, int *uV)
|
|
{
|
|
unsigned int adr;
|
|
unsigned char val;
|
|
int hex, ldo, ret;
|
|
|
|
if (op == PMIC_OP_GET)
|
|
*uV = 0;
|
|
|
|
ldo = dev->driver_data;
|
|
if (ldo < 1 || ldo > MAX77686_LDO_NUM) {
|
|
error("Wrong ldo number: %d", ldo);
|
|
return -EINVAL;
|
|
}
|
|
|
|
adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
|
|
|
|
ret = pmic_read(dev->parent, adr, &val, 1);
|
|
if (ret)
|
|
return ret;
|
|
|
|
if (op == PMIC_OP_GET) {
|
|
val &= MAX77686_LDO_VOLT_MASK;
|
|
ret = max77686_ldo_hex2volt(ldo, val);
|
|
if (ret < 0)
|
|
return ret;
|
|
*uV = ret;
|
|
return 0;
|
|
}
|
|
|
|
hex = max77686_ldo_volt2hex(ldo, *uV);
|
|
if (hex < 0)
|
|
return hex;
|
|
|
|
val &= ~MAX77686_LDO_VOLT_MASK;
|
|
val |= hex;
|
|
ret = pmic_write(dev->parent, adr, &val, 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int max77686_buck_val(struct udevice *dev, int op, int *uV)
|
|
{
|
|
unsigned int mask, adr;
|
|
unsigned char val;
|
|
int hex, buck, ret;
|
|
|
|
buck = dev->driver_data;
|
|
if (buck < 1 || buck > MAX77686_BUCK_NUM) {
|
|
error("Wrong buck number: %d", buck);
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (op == PMIC_OP_GET)
|
|
*uV = 0;
|
|
|
|
/* &buck_out = ctrl + 1 */
|
|
adr = max77686_buck_out[buck];
|
|
|
|
/* mask */
|
|
switch (buck) {
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
mask = MAX77686_BUCK234_VOLT_MASK;
|
|
break;
|
|
default:
|
|
mask = MAX77686_BUCK_VOLT_MASK;
|
|
break;
|
|
}
|
|
|
|
ret = pmic_read(dev->parent, adr, &val, 1);
|
|
if (ret)
|
|
return ret;
|
|
|
|
if (op == PMIC_OP_GET) {
|
|
val &= mask;
|
|
ret = max77686_buck_hex2volt(buck, val);
|
|
if (ret < 0)
|
|
return ret;
|
|
*uV = ret;
|
|
return 0;
|
|
}
|
|
|
|
hex = max77686_buck_volt2hex(buck, *uV);
|
|
if (hex < 0)
|
|
return hex;
|
|
|
|
val &= ~mask;
|
|
val |= hex;
|
|
ret = pmic_write(dev->parent, adr, &val, 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int max77686_ldo_mode(struct udevice *dev, int op, int *opmode)
|
|
{
|
|
unsigned int adr, mode;
|
|
unsigned char val;
|
|
int ldo, ret;
|
|
|
|
if (op == PMIC_OP_GET)
|
|
*opmode = -EINVAL;
|
|
|
|
ldo = dev->driver_data;
|
|
if (ldo < 1 || ldo > MAX77686_LDO_NUM) {
|
|
error("Wrong ldo number: %d", ldo);
|
|
return -EINVAL;
|
|
}
|
|
|
|
adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
|
|
|
|
ret = pmic_read(dev->parent, adr, &val, 1);
|
|
if (ret)
|
|
return ret;
|
|
|
|
if (op == PMIC_OP_GET) {
|
|
val &= MAX77686_LDO_MODE_MASK;
|
|
ret = max77686_ldo_hex2mode(ldo, val);
|
|
if (ret < 0)
|
|
return ret;
|
|
*opmode = ret;
|
|
return 0;
|
|
}
|
|
|
|
/* mode */
|
|
switch (*opmode) {
|
|
case OPMODE_OFF:
|
|
mode = MAX77686_LDO_MODE_OFF;
|
|
break;
|
|
case OPMODE_LPM:
|
|
switch (ldo) {
|
|
case 2:
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
case 10:
|
|
case 11:
|
|
case 12:
|
|
case 14:
|
|
case 15:
|
|
case 16:
|
|
return -EINVAL;
|
|
default:
|
|
mode = MAX77686_LDO_MODE_LPM;
|
|
}
|
|
break;
|
|
case OPMODE_STANDBY:
|
|
switch (ldo) {
|
|
case 2:
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
case 10:
|
|
case 11:
|
|
case 12:
|
|
case 14:
|
|
case 15:
|
|
case 16:
|
|
mode = MAX77686_LDO_MODE_STANDBY;
|
|
break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
break;
|
|
case OPMODE_STANDBY_LPM:
|
|
mode = MAX77686_LDO_MODE_STANDBY_LPM;
|
|
break;
|
|
case OPMODE_ON:
|
|
mode = MAX77686_LDO_MODE_ON;
|
|
break;
|
|
default:
|
|
mode = 0xff;
|
|
}
|
|
|
|
if (mode == 0xff) {
|
|
error("Wrong mode: %d for ldo%d", *opmode, ldo);
|
|
return -EINVAL;
|
|
}
|
|
|
|
val &= ~MAX77686_LDO_MODE_MASK;
|
|
val |= mode;
|
|
ret = pmic_write(dev->parent, adr, &val, 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int max77686_ldo_enable(struct udevice *dev, int op, bool *enable)
|
|
{
|
|
int ret, on_off;
|
|
|
|
if (op == PMIC_OP_GET) {
|
|
ret = max77686_ldo_mode(dev, op, &on_off);
|
|
if (ret)
|
|
return ret;
|
|
|
|
switch (on_off) {
|
|
case OPMODE_OFF:
|
|
*enable = false;
|
|
break;
|
|
case OPMODE_ON:
|
|
*enable = true;
|
|
break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
} else if (op == PMIC_OP_SET) {
|
|
if (*enable)
|
|
on_off = OPMODE_ON;
|
|
else
|
|
on_off = OPMODE_OFF;
|
|
|
|
ret = max77686_ldo_mode(dev, op, &on_off);
|
|
if (ret)
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int max77686_buck_mode(struct udevice *dev, int op, int *opmode)
|
|
{
|
|
unsigned int mask, adr, mode, mode_shift;
|
|
unsigned char val;
|
|
int buck, ret;
|
|
|
|
buck = dev->driver_data;
|
|
if (buck < 1 || buck > MAX77686_BUCK_NUM) {
|
|
error("Wrong buck number: %d", buck);
|
|
return -EINVAL;
|
|
}
|
|
|
|
adr = max77686_buck_ctrl[buck];
|
|
|
|
/* mask */
|
|
switch (buck) {
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
mode_shift = MAX77686_BUCK_MODE_SHIFT_2;
|
|
break;
|
|
default:
|
|
mode_shift = MAX77686_BUCK_MODE_SHIFT_1;
|
|
}
|
|
|
|
mask = MAX77686_BUCK_MODE_MASK << mode_shift;
|
|
|
|
ret = pmic_read(dev->parent, adr, &val, 1);
|
|
if (ret)
|
|
return ret;
|
|
|
|
if (op == PMIC_OP_GET) {
|
|
val &= mask;
|
|
val >>= mode_shift;
|
|
ret = max77686_buck_hex2mode(buck, val);
|
|
if (ret < 0)
|
|
return ret;
|
|
*opmode = ret;
|
|
return 0;
|
|
}
|
|
|
|
/* mode */
|
|
switch (*opmode) {
|
|
case OPMODE_OFF:
|
|
mode = MAX77686_BUCK_MODE_OFF;
|
|
break;
|
|
case OPMODE_STANDBY:
|
|
switch (buck) {
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
mode = MAX77686_BUCK_MODE_STANDBY << mode_shift;
|
|
break;
|
|
default:
|
|
mode = 0xff;
|
|
}
|
|
break;
|
|
case OPMODE_LPM:
|
|
switch (buck) {
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
mode = MAX77686_BUCK_MODE_LPM << mode_shift;
|
|
break;
|
|
default:
|
|
mode = 0xff;
|
|
}
|
|
break;
|
|
case OPMODE_ON:
|
|
mode = MAX77686_BUCK_MODE_ON << mode_shift;
|
|
break;
|
|
default:
|
|
mode = 0xff;
|
|
}
|
|
|
|
if (mode == 0xff) {
|
|
error("Wrong mode: %d for buck: %d\n", *opmode, buck);
|
|
return -EINVAL;
|
|
}
|
|
|
|
val &= ~mask;
|
|
val |= mode;
|
|
ret = pmic_write(dev->parent, adr, &val, 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int max77686_buck_enable(struct udevice *dev, int op, bool *enable)
|
|
{
|
|
int ret, on_off;
|
|
|
|
if (op == PMIC_OP_GET) {
|
|
ret = max77686_buck_mode(dev, op, &on_off);
|
|
if (ret)
|
|
return ret;
|
|
|
|
switch (on_off) {
|
|
case OPMODE_OFF:
|
|
*enable = false;
|
|
break;
|
|
case OPMODE_ON:
|
|
*enable = true;
|
|
break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
} else if (op == PMIC_OP_SET) {
|
|
if (*enable)
|
|
on_off = OPMODE_ON;
|
|
else
|
|
on_off = OPMODE_OFF;
|
|
|
|
ret = max77686_buck_mode(dev, op, &on_off);
|
|
if (ret)
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int max77686_ldo_probe(struct udevice *dev)
|
|
{
|
|
struct dm_regulator_uclass_platdata *uc_pdata;
|
|
|
|
uc_pdata = dev_get_uclass_platdata(dev);
|
|
|
|
uc_pdata->type = REGULATOR_TYPE_LDO;
|
|
uc_pdata->mode_count = max77686_ldo_modes(dev->driver_data,
|
|
&uc_pdata->mode, dev);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int ldo_get_value(struct udevice *dev)
|
|
{
|
|
int uV;
|
|
int ret;
|
|
|
|
ret = max77686_ldo_val(dev, PMIC_OP_GET, &uV);
|
|
if (ret)
|
|
return ret;
|
|
|
|
return uV;
|
|
}
|
|
|
|
static int ldo_set_value(struct udevice *dev, int uV)
|
|
{
|
|
return max77686_ldo_val(dev, PMIC_OP_SET, &uV);
|
|
}
|
|
|
|
static bool ldo_get_enable(struct udevice *dev)
|
|
{
|
|
bool enable = false;
|
|
int ret;
|
|
|
|
ret = max77686_ldo_enable(dev, PMIC_OP_GET, &enable);
|
|
if (ret)
|
|
return ret;
|
|
|
|
return enable;
|
|
}
|
|
|
|
static int ldo_set_enable(struct udevice *dev, bool enable)
|
|
{
|
|
return max77686_ldo_enable(dev, PMIC_OP_SET, &enable);
|
|
}
|
|
|
|
static int ldo_get_mode(struct udevice *dev)
|
|
{
|
|
int mode;
|
|
int ret;
|
|
|
|
ret = max77686_ldo_mode(dev, PMIC_OP_GET, &mode);
|
|
if (ret)
|
|
return ret;
|
|
|
|
return mode;
|
|
}
|
|
|
|
static int ldo_set_mode(struct udevice *dev, int mode)
|
|
{
|
|
return max77686_ldo_mode(dev, PMIC_OP_SET, &mode);
|
|
}
|
|
|
|
static int max77686_buck_probe(struct udevice *dev)
|
|
{
|
|
struct dm_regulator_uclass_platdata *uc_pdata;
|
|
|
|
uc_pdata = dev_get_uclass_platdata(dev);
|
|
|
|
uc_pdata->type = REGULATOR_TYPE_BUCK;
|
|
uc_pdata->mode_count = max77686_buck_modes(dev->driver_data,
|
|
&uc_pdata->mode);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int buck_get_value(struct udevice *dev)
|
|
{
|
|
int uV;
|
|
int ret;
|
|
|
|
ret = max77686_buck_val(dev, PMIC_OP_GET, &uV);
|
|
if (ret)
|
|
return ret;
|
|
|
|
return uV;
|
|
}
|
|
|
|
static int buck_set_value(struct udevice *dev, int uV)
|
|
{
|
|
return max77686_buck_val(dev, PMIC_OP_SET, &uV);
|
|
}
|
|
|
|
static bool buck_get_enable(struct udevice *dev)
|
|
{
|
|
bool enable = false;
|
|
int ret;
|
|
|
|
ret = max77686_buck_enable(dev, PMIC_OP_GET, &enable);
|
|
if (ret)
|
|
return ret;
|
|
|
|
return enable;
|
|
}
|
|
|
|
static int buck_set_enable(struct udevice *dev, bool enable)
|
|
{
|
|
return max77686_buck_enable(dev, PMIC_OP_SET, &enable);
|
|
}
|
|
|
|
static int buck_get_mode(struct udevice *dev)
|
|
{
|
|
int mode;
|
|
int ret;
|
|
|
|
ret = max77686_buck_mode(dev, PMIC_OP_GET, &mode);
|
|
if (ret)
|
|
return ret;
|
|
|
|
return mode;
|
|
}
|
|
|
|
static int buck_set_mode(struct udevice *dev, int mode)
|
|
{
|
|
return max77686_buck_mode(dev, PMIC_OP_SET, &mode);
|
|
}
|
|
|
|
static const struct dm_regulator_ops max77686_ldo_ops = {
|
|
.get_value = ldo_get_value,
|
|
.set_value = ldo_set_value,
|
|
.get_enable = ldo_get_enable,
|
|
.set_enable = ldo_set_enable,
|
|
.get_mode = ldo_get_mode,
|
|
.set_mode = ldo_set_mode,
|
|
};
|
|
|
|
U_BOOT_DRIVER(max77686_ldo) = {
|
|
.name = MAX77686_LDO_DRIVER,
|
|
.id = UCLASS_REGULATOR,
|
|
.ops = &max77686_ldo_ops,
|
|
.probe = max77686_ldo_probe,
|
|
};
|
|
|
|
static const struct dm_regulator_ops max77686_buck_ops = {
|
|
.get_value = buck_get_value,
|
|
.set_value = buck_set_value,
|
|
.get_enable = buck_get_enable,
|
|
.set_enable = buck_set_enable,
|
|
.get_mode = buck_get_mode,
|
|
.set_mode = buck_set_mode,
|
|
};
|
|
|
|
U_BOOT_DRIVER(max77686_buck) = {
|
|
.name = MAX77686_BUCK_DRIVER,
|
|
.id = UCLASS_REGULATOR,
|
|
.ops = &max77686_buck_ops,
|
|
.probe = max77686_buck_probe,
|
|
};
|