pmic: add RK817 support
include sub modules: pmic, regulator, pwrkey Change-Id: I3a1cbaa3c4d069cbac17124f9c0fe3b01184697c Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
This commit is contained in:
parent
2f22a22f29
commit
7f18d96c70
|
|
@ -14,6 +14,17 @@
|
|||
#include <asm/arch/periph.h>
|
||||
#include <dm/pinctrl.h>
|
||||
|
||||
#define RK817_GPIO_INT_CFG 0xfe
|
||||
#define RK817_INT_STS_REG0 0xf8
|
||||
#define RK817_INT_MSK_REG0 0xf9
|
||||
#define RK817_INT_STS_REG1 0xfa
|
||||
#define RK817_INT_MSK_REG1 0xfb
|
||||
#define RK817_INT_STS_REG2 0xfc
|
||||
#define RK817_INT_MSK_REG2 0xfd
|
||||
#define RK817_PWRON_RISE_INT (1 << 1)
|
||||
#define RK817_PWRON_FALL_INT (1 << 0)
|
||||
#define RK817_INT_POL_MSK BIT(1)
|
||||
|
||||
#define RK816_INT_STS_REG1 0x49
|
||||
#define RK816_INT_MSK_REG1 0x4a
|
||||
#define RK816_INT_STS_REG2 0x4c
|
||||
|
|
@ -44,6 +55,26 @@ struct rk8xx_key_priv {
|
|||
u32 irq_reg_num;
|
||||
};
|
||||
|
||||
static struct reg_data rk817_init_reg[] = {
|
||||
/* only enable rise/fall interrupt */
|
||||
{ RK817_INT_MSK_REG0, 0xfc },
|
||||
{ RK817_INT_MSK_REG1, 0xff },
|
||||
{ RK817_INT_MSK_REG2, 0xff },
|
||||
/* clear all interrupt states */
|
||||
{ RK817_INT_STS_REG0, 0xff },
|
||||
{ RK817_INT_STS_REG1, 0xff },
|
||||
{ RK817_INT_STS_REG2, 0xff },
|
||||
/* pmic_int active low */
|
||||
{ RK817_GPIO_INT_CFG, 0x20 },
|
||||
};
|
||||
|
||||
static struct reg_data rk817_irq_reg[] = {
|
||||
/* clear all interrupt states */
|
||||
{ RK817_INT_STS_REG0, 0xff },
|
||||
{ RK817_INT_STS_REG1, 0xff },
|
||||
{ RK817_INT_STS_REG2, 0xff },
|
||||
};
|
||||
|
||||
static struct reg_data rk816_init_reg[] = {
|
||||
/* only enable rise/fall interrupt */
|
||||
{ RK816_INT_MSK_REG1, 0x9f },
|
||||
|
|
@ -118,6 +149,8 @@ static void pwrkey_irq_handler(int irq, void *data)
|
|||
struct input_key *key = dev_get_platdata(dev);
|
||||
int ret, val, i;
|
||||
|
||||
debug("%s: irq = %d\n", __func__, irq);
|
||||
|
||||
/* read status */
|
||||
val = pmic_reg_read(dev->parent, priv->int_sts_reg);
|
||||
if (val < 0) {
|
||||
|
|
@ -146,6 +179,9 @@ static void pwrkey_irq_handler(int irq, void *data)
|
|||
printf("%s: i2c write reg 0x%x failed, ret=%d\n",
|
||||
__func__, priv->irq_reg[i].reg, ret);
|
||||
}
|
||||
|
||||
debug("%s: reg[0x%x] = 0x%x\n", __func__, priv->irq_reg[i].reg,
|
||||
pmic_reg_read(dev->parent, priv->irq_reg[i].reg));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -210,7 +246,16 @@ static int rk8xx_pwrkey_probe(struct udevice *dev)
|
|||
priv->irq_reg = rk816_irq_reg;
|
||||
priv->irq_reg_num = ARRAY_SIZE(rk816_irq_reg);
|
||||
break;
|
||||
|
||||
case RK817_ID:
|
||||
priv->int_sts_reg = RK817_INT_STS_REG0;
|
||||
priv->int_msk_reg = RK817_INT_MSK_REG0;
|
||||
priv->pwron_rise_int = RK817_PWRON_RISE_INT;
|
||||
priv->pwron_fall_int = RK817_PWRON_FALL_INT;
|
||||
priv->init_reg = rk817_init_reg;
|
||||
priv->init_reg_num = ARRAY_SIZE(rk817_init_reg);
|
||||
priv->irq_reg = rk817_irq_reg;
|
||||
priv->irq_reg_num = ARRAY_SIZE(rk817_irq_reg);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -225,6 +270,9 @@ static int rk8xx_pwrkey_probe(struct udevice *dev)
|
|||
__func__, priv->init_reg[i].reg, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
debug("%s: reg[%x] = 0x%x\n", __func__, priv->init_reg[i].reg,
|
||||
pmic_reg_read(dev->parent, priv->init_reg[i].reg));
|
||||
}
|
||||
|
||||
return pwrkey_interrupt_init(dev);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ static const struct pmic_child_info power_key_info[] = {
|
|||
|
||||
static const struct pmic_child_info fuel_gauge_info[] = {
|
||||
{ .prefix = "battery", .driver = "rk818_fg"},
|
||||
{ .prefix = "battery", .driver = "rk817_fg"},
|
||||
{ .prefix = "battery", .driver = "rk816_fg"},
|
||||
{ },
|
||||
};
|
||||
|
|
@ -66,16 +67,22 @@ static int rk8xx_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
|||
static int rk8xx_shutdown(struct udevice *dev)
|
||||
{
|
||||
struct rk8xx_priv *priv = dev_get_priv(dev);
|
||||
u8 val, dev_off;
|
||||
u8 val, dev_off, devctrl_reg;
|
||||
int ret = 0;
|
||||
|
||||
switch (priv->variant) {
|
||||
case RK808_ID:
|
||||
devctrl_reg = REG_DEVCTRL;
|
||||
dev_off = BIT(3);
|
||||
break;
|
||||
case RK805_ID:
|
||||
case RK816_ID:
|
||||
case RK818_ID:
|
||||
devctrl_reg = REG_DEVCTRL;
|
||||
dev_off = BIT(0);
|
||||
break;
|
||||
case RK817_ID:
|
||||
devctrl_reg = RK817_REG_SYS_CFG3;
|
||||
dev_off = BIT(0);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -83,18 +90,18 @@ static int rk8xx_shutdown(struct udevice *dev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = dm_i2c_read(dev, REG_DEVCTRL, &val, 1);
|
||||
ret = dm_i2c_read(dev, devctrl_reg, &val, 1);
|
||||
if (ret) {
|
||||
printf("read error from device: %p register: %#x!",
|
||||
dev, REG_DEVCTRL);
|
||||
dev, devctrl_reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
val |= dev_off;
|
||||
ret = dm_i2c_write(dev, REG_DEVCTRL, &val, 1);
|
||||
ret = dm_i2c_write(dev, devctrl_reg, &val, 1);
|
||||
if (ret) {
|
||||
printf("write error to device: %p register: %#x!",
|
||||
dev, REG_DEVCTRL);
|
||||
dev, devctrl_reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -136,14 +143,24 @@ static int rk8xx_bind(struct udevice *dev)
|
|||
static int rk8xx_probe(struct udevice *dev)
|
||||
{
|
||||
struct rk8xx_priv *priv = dev_get_priv(dev);
|
||||
uint8_t msb, lsb;
|
||||
uint8_t msb, lsb, id_msb, id_lsb;
|
||||
|
||||
/* read Chip variant */
|
||||
rk8xx_read(dev, ID_MSB, &msb, 1);
|
||||
rk8xx_read(dev, ID_LSB, &lsb, 1);
|
||||
if (device_is_compatible(dev, "rockchip,rk817")) {
|
||||
id_msb = RK817_ID_MSB;
|
||||
id_lsb = RK817_ID_LSB;
|
||||
} else {
|
||||
id_msb = ID_MSB;
|
||||
id_lsb = ID_LSB;
|
||||
}
|
||||
|
||||
rk8xx_read(dev, id_msb, &msb, 1);
|
||||
rk8xx_read(dev, id_lsb, &lsb, 1);
|
||||
|
||||
priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
|
||||
|
||||
printf("PMIC: RK%x\n", priv->variant);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -158,6 +175,7 @@ static const struct udevice_id rk8xx_ids[] = {
|
|||
{ .compatible = "rockchip,rk805" },
|
||||
{ .compatible = "rockchip,rk808" },
|
||||
{ .compatible = "rockchip,rk816" },
|
||||
{ .compatible = "rockchip,rk817" },
|
||||
{ .compatible = "rockchip,rk818" },
|
||||
{ }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -33,12 +33,27 @@
|
|||
#define RK818_USB_ILIM_SEL_MASK 0x0f
|
||||
#define RK818_USB_CHG_SD_VSEL_MASK 0x70
|
||||
|
||||
/* RK817 BUCK */
|
||||
#define RK817_BUCK_ON_VSEL(n) (0xbb + 3 * (n - 1))
|
||||
#define RK817_BUCK_SLP_VSEL(n) (0xbc + 3 * (n - 1))
|
||||
#define RK817_BUCK_VSEL_MASK 0x7f
|
||||
|
||||
/* RK817 LDO */
|
||||
#define RK817_LDO_ON_VSEL(n) (0xcc + 2 * (n - 1))
|
||||
#define RK817_LDO_SLP_VSEL(n) (0xcd + 2 * (n - 1))
|
||||
#define RK817_LDO_VSEL_MASK 0x7f
|
||||
|
||||
/* RK817 ENABLE */
|
||||
#define RK817_POWER_EN(n) (0xb1 + (n))
|
||||
#define RK817_POWER_SLP_EN(n) (0xb5 + (n))
|
||||
|
||||
struct rk8xx_reg_info {
|
||||
uint min_uv;
|
||||
uint step_uv;
|
||||
s8 vsel_reg;
|
||||
s8 vsel_sleep_reg;
|
||||
u8 vsel_reg;
|
||||
u8 vsel_sleep_reg;
|
||||
u8 vsel_mask;
|
||||
u8 min_sel;
|
||||
};
|
||||
|
||||
static const struct rk8xx_reg_info rk808_buck[] = {
|
||||
|
|
@ -63,6 +78,25 @@ static const struct rk8xx_reg_info rk816_buck[] = {
|
|||
{ 800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, RK818_BUCK4_VSEL_MASK, },
|
||||
};
|
||||
|
||||
static const struct rk8xx_reg_info rk817_buck[] = {
|
||||
/* buck 1 */
|
||||
{ 500000, 12500, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_VSEL_MASK, 0x00, },
|
||||
{ 1500000, 100000, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_VSEL_MASK, 0x50, },
|
||||
{ 2400000, 0, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_VSEL_MASK, 0x59, },
|
||||
/* buck 2 */
|
||||
{ 500000, 12500, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_VSEL_MASK, 0x00, },
|
||||
{ 1500000, 100000, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_VSEL_MASK, 0x50, },
|
||||
{ 2400000, 0, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_VSEL_MASK, 0x59, },
|
||||
/* buck 3 */
|
||||
{ 500000, 12500, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_VSEL_MASK, 0x00, },
|
||||
{ 1500000, 100000, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_VSEL_MASK, 0x50, },
|
||||
{ 2400000, 0, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_VSEL_MASK, 0x59, },
|
||||
/* buck 4 */
|
||||
{ 500000, 12500, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_VSEL_MASK, 0x00, },
|
||||
{ 1500000, 100000, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_VSEL_MASK, 0x50, },
|
||||
{ 3400000, 0, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_VSEL_MASK, 0x63, },
|
||||
};
|
||||
|
||||
static const struct rk8xx_reg_info rk818_buck[] = {
|
||||
{ 712500, 12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, RK818_BUCK_VSEL_MASK, },
|
||||
{ 712500, 12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, RK818_BUCK_VSEL_MASK, },
|
||||
|
|
@ -91,6 +125,36 @@ static const struct rk8xx_reg_info rk816_ldo[] = {
|
|||
{ 800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, RK818_LDO_VSEL_MASK, },
|
||||
};
|
||||
|
||||
static const struct rk8xx_reg_info rk817_ldo[] = {
|
||||
/* ldo1 */
|
||||
{ 600000, 25000, RK817_LDO_ON_VSEL(1), RK817_LDO_SLP_VSEL(1), RK817_LDO_VSEL_MASK, 0x00, },
|
||||
{ 3400000, 0, RK817_LDO_ON_VSEL(1), RK817_LDO_SLP_VSEL(1), RK817_LDO_VSEL_MASK, 0x70, },
|
||||
/* ldo2 */
|
||||
{ 600000, 25000, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), RK817_LDO_VSEL_MASK, 0x00, },
|
||||
{ 3400000, 0, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), RK817_LDO_VSEL_MASK, 0x70, },
|
||||
/* ldo3 */
|
||||
{ 600000, 25000, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), RK817_LDO_VSEL_MASK, 0x00, },
|
||||
{ 3400000, 0, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), RK817_LDO_VSEL_MASK, 0x70, },
|
||||
/* ldo4 */
|
||||
{ 600000, 25000, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), RK817_LDO_VSEL_MASK, 0x00, },
|
||||
{ 3400000, 0, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), RK817_LDO_VSEL_MASK, 0x70, },
|
||||
/* ldo5 */
|
||||
{ 600000, 25000, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), RK817_LDO_VSEL_MASK, 0x00, },
|
||||
{ 3400000, 0, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), RK817_LDO_VSEL_MASK, 0x70, },
|
||||
/* ldo6 */
|
||||
{ 600000, 25000, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), RK817_LDO_VSEL_MASK, 0x00, },
|
||||
{ 3400000, 0, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), RK817_LDO_VSEL_MASK, 0x70, },
|
||||
/* ldo7 */
|
||||
{ 600000, 25000, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), RK817_LDO_VSEL_MASK, 0x00, },
|
||||
{ 3400000, 0, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), RK817_LDO_VSEL_MASK, 0x70, },
|
||||
/* ldo8 */
|
||||
{ 600000, 25000, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), RK817_LDO_VSEL_MASK, 0x00, },
|
||||
{ 3400000, 0, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), RK817_LDO_VSEL_MASK, 0x70, },
|
||||
/* ldo9 */
|
||||
{ 600000, 25000, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), RK817_LDO_VSEL_MASK, 0x00, },
|
||||
{ 3400000, 0, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), RK817_LDO_VSEL_MASK, 0x70, },
|
||||
};
|
||||
|
||||
static const struct rk8xx_reg_info rk818_ldo[] = {
|
||||
{ 1800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, RK818_LDO_VSEL_MASK, },
|
||||
{ 1800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, RK818_LDO_VSEL_MASK, },
|
||||
|
|
@ -131,6 +195,24 @@ static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
|
|||
default:
|
||||
return &rk816_buck[num + 4];
|
||||
}
|
||||
|
||||
case RK817_ID:
|
||||
switch (num) {
|
||||
case 0 ... 2:
|
||||
if (uvolt < 1500000)
|
||||
return &rk817_buck[num * 3 + 0];
|
||||
else if (uvolt < 2400000)
|
||||
return &rk817_buck[num * 3 + 1];
|
||||
else
|
||||
return &rk817_buck[num * 3 + 2];
|
||||
default:
|
||||
if (uvolt < 1500000)
|
||||
return &rk817_buck[num * 3 + 0];
|
||||
else if (uvolt < 3400000)
|
||||
return &rk817_buck[num * 3 + 1];
|
||||
else
|
||||
return &rk817_buck[num * 3 + 2];
|
||||
}
|
||||
case RK818_ID:
|
||||
return &rk818_buck[num];
|
||||
default:
|
||||
|
|
@ -146,9 +228,14 @@ static int _buck_set_value(struct udevice *pmic, int buck, int uvolt)
|
|||
|
||||
if (info->vsel_reg == -1)
|
||||
return -ENOSYS;
|
||||
val = (uvolt - info->min_uv) / info->step_uv;
|
||||
debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask,
|
||||
val);
|
||||
|
||||
if (info->step_uv == 0) /* Fixed voltage */
|
||||
val = info->min_sel;
|
||||
else
|
||||
val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
|
||||
|
||||
debug("%s: volt=%d, buck=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
|
||||
__func__, uvolt, buck+1, info->vsel_reg, mask, val);
|
||||
|
||||
return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
|
||||
}
|
||||
|
|
@ -191,6 +278,13 @@ static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
|
|||
ret = pmic_clrsetbits(pmic, REG_DCDC_EN, mask,
|
||||
enable ? mask : 0);
|
||||
break;
|
||||
case RK817_ID:
|
||||
if (enable)
|
||||
value = ((1 << buck) | (1 << (buck + 4)));
|
||||
else
|
||||
value = ((0 << buck) | (1 << (buck + 4)));
|
||||
ret = pmic_reg_write(pmic, RK817_POWER_EN(0), value);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
|
@ -207,9 +301,14 @@ static int _buck_set_suspend_value(struct udevice *pmic, int buck, int uvolt)
|
|||
|
||||
if (info->vsel_sleep_reg == -1)
|
||||
return -ENOSYS;
|
||||
val = (uvolt - info->min_uv) / info->step_uv;
|
||||
debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_sleep_reg, mask,
|
||||
val);
|
||||
|
||||
if (info->step_uv == 0)
|
||||
val = info->min_sel;
|
||||
else
|
||||
val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
|
||||
|
||||
debug("%s: volt=%d, buck=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
|
||||
__func__, uvolt, buck+1, info->vsel_sleep_reg, mask, val);
|
||||
|
||||
return pmic_clrsetbits(pmic, info->vsel_sleep_reg, mask, val);
|
||||
}
|
||||
|
|
@ -238,6 +337,11 @@ static int _buck_get_enable(struct udevice *pmic, int buck)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
break;
|
||||
case RK817_ID:
|
||||
mask = 1 << buck;
|
||||
ret = pmic_reg_read(pmic, RK817_POWER_EN(0));
|
||||
debug("%s: %s, buck=%d, en=%x\n", __func__, pmic->name, buck, ret);
|
||||
break;
|
||||
}
|
||||
return ret & mask ? true : false;
|
||||
}
|
||||
|
|
@ -262,6 +366,11 @@ static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable)
|
|||
ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF1, mask,
|
||||
enable ? 0 : mask);
|
||||
break;
|
||||
case RK817_ID:
|
||||
mask = 1 << buck;
|
||||
ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
|
||||
enable ? mask : 0);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
|
@ -270,7 +379,7 @@ static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable)
|
|||
}
|
||||
|
||||
static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
|
||||
int num)
|
||||
int num, int uvolt)
|
||||
{
|
||||
struct rk8xx_priv *priv = dev_get_priv(pmic);
|
||||
|
||||
|
|
@ -278,6 +387,11 @@ static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
|
|||
case RK805_ID:
|
||||
case RK816_ID:
|
||||
return &rk816_ldo[num];
|
||||
case RK817_ID:
|
||||
if (uvolt < 3400000)
|
||||
return &rk817_ldo[num * 2 + 0];
|
||||
else
|
||||
return &rk817_ldo[num * 2 + 1];
|
||||
case RK818_ID:
|
||||
return &rk818_ldo[num];
|
||||
default:
|
||||
|
|
@ -309,6 +423,20 @@ static int _ldo_get_enable(struct udevice *pmic, int ldo)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
break;
|
||||
case RK817_ID:
|
||||
if (ldo < 4) {
|
||||
mask = 1 << ldo;
|
||||
ret = pmic_reg_read(pmic, RK817_POWER_EN(1));
|
||||
} else if (ldo < 8) {
|
||||
mask = 1 << (ldo - 4);
|
||||
ret = pmic_reg_read(pmic, RK817_POWER_EN(2));
|
||||
} else if (ldo == 8) {
|
||||
mask = 1 << 0;
|
||||
ret = pmic_reg_read(pmic, RK817_POWER_EN(3));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret & mask ? true : false;
|
||||
}
|
||||
|
|
@ -341,6 +469,24 @@ static int _ldo_set_enable(struct udevice *pmic, int ldo, bool enable)
|
|||
ret = pmic_clrsetbits(pmic, REG_LDO_EN, mask,
|
||||
enable ? mask : 0);
|
||||
break;
|
||||
case RK817_ID:
|
||||
if (ldo < 4) {
|
||||
en_reg = RK817_POWER_EN(1);
|
||||
} else if (ldo < 8) {
|
||||
ldo -= 4;
|
||||
en_reg = RK817_POWER_EN(2);
|
||||
} else if (ldo == 8) {
|
||||
ldo = 0; /* BIT 0 */
|
||||
en_reg = RK817_POWER_EN(3);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (enable)
|
||||
value = ((1 << ldo) | (1 << (ldo + 4)));
|
||||
else
|
||||
value = ((0 << ldo) | (1 << (ldo + 4)));
|
||||
ret = pmic_reg_write(pmic, en_reg, value);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -365,6 +511,17 @@ static int _ldo_set_suspend_enable(struct udevice *pmic, int ldo, bool enable)
|
|||
ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF2, mask,
|
||||
enable ? 0 : mask);
|
||||
break;
|
||||
case RK817_ID:
|
||||
if (ldo == 8) {
|
||||
mask = 1 << 4; /* LDO9 */
|
||||
ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
|
||||
enable ? mask : 0);
|
||||
} else {
|
||||
mask = 1 << ldo;
|
||||
ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(1), mask,
|
||||
enable ? mask : 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -373,12 +530,14 @@ static int _ldo_set_suspend_enable(struct udevice *pmic, int ldo, bool enable)
|
|||
static int buck_get_value(struct udevice *dev)
|
||||
{
|
||||
int buck = dev->driver_data - 1;
|
||||
/* We assume level-1 voltage is enough for usage in U-Boot */
|
||||
const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
|
||||
int mask = info->vsel_mask;
|
||||
int ret, val;
|
||||
|
||||
if (info->vsel_reg == -1)
|
||||
return -ENOSYS;
|
||||
|
||||
ret = pmic_reg_read(dev->parent, info->vsel_reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
|
@ -425,7 +584,7 @@ static int buck_get_enable(struct udevice *dev)
|
|||
static int ldo_get_value(struct udevice *dev)
|
||||
{
|
||||
int ldo = dev->driver_data - 1;
|
||||
const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
|
||||
const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, 0);
|
||||
int mask = info->vsel_mask;
|
||||
int ret, val;
|
||||
|
||||
|
|
@ -442,15 +601,20 @@ static int ldo_get_value(struct udevice *dev)
|
|||
static int ldo_set_value(struct udevice *dev, int uvolt)
|
||||
{
|
||||
int ldo = dev->driver_data - 1;
|
||||
const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
|
||||
const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
|
||||
int mask = info->vsel_mask;
|
||||
int val;
|
||||
|
||||
if (info->vsel_reg == -1)
|
||||
return -ENOSYS;
|
||||
val = (uvolt - info->min_uv) / info->step_uv;
|
||||
debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask,
|
||||
val);
|
||||
|
||||
if (info->step_uv == 0)
|
||||
val = info->min_sel;
|
||||
else
|
||||
val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
|
||||
|
||||
debug("%s: volt=%d, ldo=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
|
||||
__func__, uvolt, ldo+1, info->vsel_reg, mask, val);
|
||||
|
||||
return pmic_clrsetbits(dev->parent, info->vsel_reg, mask, val);
|
||||
}
|
||||
|
|
@ -458,15 +622,20 @@ static int ldo_set_value(struct udevice *dev, int uvolt)
|
|||
static int ldo_set_suspend_value(struct udevice *dev, int uvolt)
|
||||
{
|
||||
int ldo = dev->driver_data - 1;
|
||||
const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
|
||||
const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
|
||||
int mask = info->vsel_mask;
|
||||
int val;
|
||||
|
||||
if (info->vsel_sleep_reg == -1)
|
||||
return -ENOSYS;
|
||||
val = (uvolt - info->min_uv) / info->step_uv;
|
||||
debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_sleep_reg, mask,
|
||||
val);
|
||||
|
||||
if (info->step_uv == 0)
|
||||
val = info->min_sel;
|
||||
else
|
||||
val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
|
||||
|
||||
debug("%s: volt=%d, ldo=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
|
||||
__func__, uvolt, ldo+1, info->vsel_sleep_reg, mask, val);
|
||||
|
||||
return pmic_clrsetbits(dev->parent, info->vsel_sleep_reg, mask, val);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,6 +170,10 @@ enum {
|
|||
RK808_NUM_OF_REGS,
|
||||
};
|
||||
|
||||
enum {
|
||||
RK817_REG_SYS_CFG3 = 0xf4,
|
||||
};
|
||||
|
||||
enum {
|
||||
RK816_REG_DCDC_EN1 = 0x23,
|
||||
RK816_REG_DCDC_EN2,
|
||||
|
|
@ -183,9 +187,12 @@ enum {
|
|||
RK805_ID = 0x8050,
|
||||
RK808_ID = 0x0000,
|
||||
RK816_ID = 0x8160,
|
||||
RK817_ID = 0x8170,
|
||||
RK818_ID = 0x8180,
|
||||
};
|
||||
|
||||
#define RK817_ID_MSB 0xed
|
||||
#define RK817_ID_LSB 0xee
|
||||
#define RK8XX_ID_MSK 0xfff0
|
||||
|
||||
struct rk8xx_reg_table {
|
||||
|
|
|
|||
Loading…
Reference in New Issue