Message ID | 1568880581-23147-1-git-send-email-zhangqing@rock-chips.com |
---|---|
State | Superseded |
Delegated to: | Philipp Tomsich |
Headers | show |
Series | power: pmic: support more PMIC | expand |
On 2019/9/19 下午4:09, Elaine Zhang wrote: > From: Joseph Chen <chenjh@rock-chips.com> > > The RK817 is a Power Management IC (PMIC) for multimedia > and handheld devices. They contains the following components: > - Regulators(4*BUCKs, 1* BOOST, 9*LDOs, 1*SWITCH) > - RTC > - Clocking > > Signed-off-by: Joseph Chen <chenjh@rock-chips.com> > Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com> Reviewed-by: Kever Yang<kever.yang@rock-chips.com> Thanks, - Kever > --- > drivers/power/pmic/rk8xx.c | 100 +++++++++++++++++++-- > drivers/power/regulator/rk8xx.c | 189 +++++++++++++++++++++++++++++++++++++++- > include/power/rk8xx_pmic.h | 31 +++++++ > 3 files changed, 308 insertions(+), 12 deletions(-) > > diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c > index df2056913ced..0ec6cb31d706 100644 > --- a/drivers/power/pmic/rk8xx.c > +++ b/drivers/power/pmic/rk8xx.c > @@ -10,6 +10,13 @@ > #include <power/rk8xx_pmic.h> > #include <power/pmic.h> > > +static struct reg_data rk817_init_reg[] = { > +/* enable the under-voltage protection, > + * the under-voltage protection will shutdown the LDO3 and reset the PMIC > + */ > + { RK817_BUCK4_CMIN, 0x60, 0x60}, > +}; > + > static const struct pmic_child_info pmic_children_info[] = { > { .prefix = "DCDC_REG", .driver = "rk8xx_buck"}, > { .prefix = "LDO_REG", .driver = "rk8xx_ldo"}, > @@ -52,16 +59,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: > @@ -69,18 +82,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; > } > > @@ -114,13 +127,83 @@ 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; > + struct reg_data *init_data = NULL; > + int init_data_num = 0; > + int ret = 0, i, show_variant; > + u8 msb, lsb, id_msb, id_lsb; > + u8 on_source = 0, off_source = 0; > + u8 power_en0, power_en1, power_en2, power_en3; > + u8 value; > > /* 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; > + } > + > + ret = rk8xx_read(dev, id_msb, &msb, 1); > + if (ret) > + return ret; > + ret = rk8xx_read(dev, id_lsb, &lsb, 1); > + if (ret) > + return ret; > > priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK; > + show_variant = priv->variant; > + switch (priv->variant) { > + case RK808_ID: > + show_variant = 0x808; /* RK808 hardware ID is 0 */ > + break; > + case RK805_ID: > + case RK816_ID: > + case RK818_ID: > + on_source = RK8XX_ON_SOURCE; > + off_source = RK8XX_OFF_SOURCE; > + break; > + case RK817_ID: > + on_source = RK817_ON_SOURCE; > + off_source = RK817_OFF_SOURCE; > + init_data = rk817_init_reg; > + init_data_num = ARRAY_SIZE(rk817_init_reg); > + power_en0 = pmic_reg_read(dev, RK817_POWER_EN0); > + power_en1 = pmic_reg_read(dev, RK817_POWER_EN1); > + power_en2 = pmic_reg_read(dev, RK817_POWER_EN2); > + power_en3 = pmic_reg_read(dev, RK817_POWER_EN3); > + > + value = (power_en0 & 0x0f) | ((power_en1 & 0x0f) << 4); > + pmic_reg_write(dev, RK817_POWER_EN_SAVE0, value); > + value = (power_en2 & 0x0f) | ((power_en3 & 0x0f) << 4); > + pmic_reg_write(dev, RK817_POWER_EN_SAVE1, value); > + break; > + default: > + printf("Unknown PMIC: RK%x!!\n", priv->variant); > + return -EINVAL; > + } > + > + for (i = 0; i < init_data_num; i++) { > + ret = pmic_clrsetbits(dev, > + init_data[i].reg, > + init_data[i].mask, > + init_data[i].val); > + if (ret < 0) { > + printf("%s: i2c set reg 0x%x failed, ret=%d\n", > + __func__, init_data[i].reg, ret); > + } > + > + debug("%s: reg[0x%x] = 0x%x\n", __func__, init_data[i].reg, > + pmic_reg_read(dev, init_data[i].reg)); > + } > + > + printf("PMIC: RK%x ", show_variant); > + > + if (on_source && off_source) > + printf("(on=0x%02x, off=0x%02x)", > + pmic_reg_read(dev, on_source), > + pmic_reg_read(dev, off_source)); > + printf("\n"); > > return 0; > } > @@ -136,6 +219,7 @@ static const struct udevice_id rk8xx_ids[] = { > { .compatible = "rockchip,rk805" }, > { .compatible = "rockchip,rk808" }, > { .compatible = "rockchip,rk816" }, > + { .compatible = "rockchip,rk817" }, > { .compatible = "rockchip,rk818" }, > { } > }; > diff --git a/drivers/power/regulator/rk8xx.c b/drivers/power/regulator/rk8xx.c > index e9d83635988b..3c4a18b0f0c7 100644 > --- a/drivers/power/regulator/rk8xx.c > +++ b/drivers/power/regulator/rk8xx.c > @@ -27,6 +27,21 @@ > #define RK808_BUCK4_VSEL_MASK 0xf > #define RK808_LDO_VSEL_MASK 0x1f > > +/* 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 > +#define RK817_BUCK_CONFIG(i) (0xba + (i) * 3) > + > +/* 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)) > + > #define RK818_BUCK_VSEL_MASK 0x3f > #define RK818_BUCK4_VSEL_MASK 0x1f > #define RK818_LDO_VSEL_MASK 0x1f > @@ -45,13 +60,19 @@ > #define RK805_RAMP_RATE_12_5MV_PER_US (2 << RK805_RAMP_RATE_OFFSET) > #define RK805_RAMP_RATE_25MV_PER_US (3 << RK805_RAMP_RATE_OFFSET) > #define RK808_RAMP_RATE_OFFSET 3 > - > #define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET) > #define RK808_RAMP_RATE_2MV_PER_US (0 << RK808_RAMP_RATE_OFFSET) > #define RK808_RAMP_RATE_4MV_PER_US (1 << RK808_RAMP_RATE_OFFSET) > #define RK808_RAMP_RATE_6MV_PER_US (2 << RK808_RAMP_RATE_OFFSET) > #define RK808_RAMP_RATE_10MV_PER_US (3 << RK808_RAMP_RATE_OFFSET) > > +#define RK817_RAMP_RATE_OFFSET 6 > +#define RK817_RAMP_RATE_MASK (0x3 << RK817_RAMP_RATE_OFFSET) > +#define RK817_RAMP_RATE_3MV_PER_US (0x0 << RK817_RAMP_RATE_OFFSET) > +#define RK817_RAMP_RATE_6_3MV_PER_US (0x1 << RK817_RAMP_RATE_OFFSET) > +#define RK817_RAMP_RATE_12_5MV_PER_US (0x2 << RK817_RAMP_RATE_OFFSET) > +#define RK817_RAMP_RATE_25MV_PER_US (0x3 << RK817_RAMP_RATE_OFFSET) > + > struct rk8xx_reg_info { > uint min_uv; > uint step_uv; > @@ -84,6 +105,25 @@ static const struct rk8xx_reg_info rk816_buck[] = { > { 800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, REG_BUCK4_CONFIG, 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_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x00, }, > + { 1500000, 100000, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x50, }, > + { 2400000, 0, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x59, }, > + /* buck 2 */ > + { 500000, 12500, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x00, }, > + { 1500000, 100000, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x50, }, > + { 2400000, 0, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x59, }, > + /* buck 3 */ > + { 500000, 12500, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x00, }, > + { 1500000, 100000, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x50, }, > + { 2400000, 0, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x59, }, > + /* buck 4 */ > + { 500000, 12500, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x00, }, > + { 1500000, 100000, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x50, }, > + { 3400000, 0, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x63, }, > +}; > + > static const struct rk8xx_reg_info rk818_buck[] = { > { 712500, 12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, REG_BUCK1_CONFIG, RK818_BUCK_VSEL_MASK, }, > { 712500, 12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, REG_BUCK2_CONFIG, RK818_BUCK_VSEL_MASK, }, > @@ -112,6 +152,36 @@ static const struct rk8xx_reg_info rk816_ldo[] = { > { 800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, NA, 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), NA, RK817_LDO_VSEL_MASK, 0x00, }, > + { 3400000, 0, RK817_LDO_ON_VSEL(1), RK817_LDO_SLP_VSEL(1), NA, RK817_LDO_VSEL_MASK, 0x70, }, > + /* ldo2 */ > + { 600000, 25000, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), NA, RK817_LDO_VSEL_MASK, 0x00, }, > + { 3400000, 0, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), NA, RK817_LDO_VSEL_MASK, 0x70, }, > + /* ldo3 */ > + { 600000, 25000, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), NA, RK817_LDO_VSEL_MASK, 0x00, }, > + { 3400000, 0, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), NA, RK817_LDO_VSEL_MASK, 0x70, }, > + /* ldo4 */ > + { 600000, 25000, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), NA, RK817_LDO_VSEL_MASK, 0x00, }, > + { 3400000, 0, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), NA, RK817_LDO_VSEL_MASK, 0x70, }, > + /* ldo5 */ > + { 600000, 25000, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), NA, RK817_LDO_VSEL_MASK, 0x00, }, > + { 3400000, 0, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), NA, RK817_LDO_VSEL_MASK, 0x70, }, > + /* ldo6 */ > + { 600000, 25000, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), NA, RK817_LDO_VSEL_MASK, 0x00, }, > + { 3400000, 0, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), NA, RK817_LDO_VSEL_MASK, 0x70, }, > + /* ldo7 */ > + { 600000, 25000, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), NA, RK817_LDO_VSEL_MASK, 0x00, }, > + { 3400000, 0, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), NA, RK817_LDO_VSEL_MASK, 0x70, }, > + /* ldo8 */ > + { 600000, 25000, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), NA, RK817_LDO_VSEL_MASK, 0x00, }, > + { 3400000, 0, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), NA, RK817_LDO_VSEL_MASK, 0x70, }, > + /* ldo9 */ > + { 600000, 25000, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), NA, RK817_LDO_VSEL_MASK, 0x00, }, > + { 3400000, 0, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), NA, RK817_LDO_VSEL_MASK, 0x70, }, > +}; > + > static const struct rk8xx_reg_info rk818_ldo[] = { > { 1800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, }, > { 1800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, }, > @@ -152,6 +222,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]; > + case 3: > + 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: > @@ -189,7 +277,7 @@ static int _buck_set_value(struct udevice *pmic, int buck, int uvolt) > static int _buck_set_enable(struct udevice *pmic, int buck, bool enable) > { > uint mask, value, en_reg; > - int ret; > + int ret = 0; > struct rk8xx_priv *priv = dev_get_priv(pmic); > > switch (priv->variant) { > @@ -220,6 +308,15 @@ 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 (buck < 4) { > + 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; > } > @@ -272,6 +369,12 @@ static int _buck_get_enable(struct udevice *pmic, int buck) > if (ret < 0) > return ret; > break; > + case RK817_ID: > + if (buck < 4) { > + mask = 1 << buck; > + ret = pmic_reg_read(pmic, RK817_POWER_EN(0)); > + } > + break; > } > > if (ret < 0) > @@ -282,7 +385,7 @@ static int _buck_get_enable(struct udevice *pmic, int buck) > > static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable) > { > - uint mask; > + uint mask = 0; > int ret; > struct rk8xx_priv *priv = dev_get_priv(pmic); > > @@ -299,6 +402,12 @@ 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: > + if (buck < 4) > + mask = 1 << buck; > + ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask, > + enable ? mask : 0); > + break; > default: > ret = -EINVAL; > } > @@ -310,7 +419,7 @@ static int _buck_get_suspend_enable(struct udevice *pmic, int buck) > { > struct rk8xx_priv *priv = dev_get_priv(pmic); > int ret, val; > - uint mask; > + uint mask = 0; > > switch (priv->variant) { > case RK805_ID: > @@ -329,6 +438,15 @@ static int _buck_get_suspend_enable(struct udevice *pmic, int buck) > return val; > ret = val & mask ? 0 : 1; > break; > + case RK817_ID: > + if (buck < 4) > + mask = 1 << buck; > + > + val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0)); > + if (val < 0) > + return val; > + ret = val & mask ? 1 : 0; > + break; > default: > ret = -EINVAL; > } > @@ -345,6 +463,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: > @@ -376,6 +499,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; > } > > if (ret < 0) > @@ -413,6 +550,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; > @@ -437,6 +592,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; > @@ -465,6 +631,21 @@ static int _ldo_get_suspend_enable(struct udevice *pmic, int ldo) > return val; > ret = val & mask ? 0 : 1; > break; > + case RK817_ID: > + if (ldo == 8) { > + mask = 1 << 4; /* LDO9 */ > + val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0)); > + if (val < 0) > + return val; > + ret = val & mask ? 1 : 0; > + } else { > + mask = 1 << ldo; > + val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(1)); > + if (val < 0) > + return val; > + ret = val & mask ? 1 : 0; > + } > + break; > } > > return ret; > diff --git a/include/power/rk8xx_pmic.h b/include/power/rk8xx_pmic.h > index 7784c2a5e473..d93cecedddf7 100644 > --- a/include/power/rk8xx_pmic.h > +++ b/include/power/rk8xx_pmic.h > @@ -170,6 +170,10 @@ enum { > }; > > enum { > + RK817_REG_SYS_CFG3 = 0xf4, > +}; > + > +enum { > RK816_REG_DCDC_EN1 = 0x23, > RK816_REG_DCDC_EN2, > RK816_REG_DCDC_SLP_EN, > @@ -182,11 +186,38 @@ enum { > RK805_ID = 0x8050, > RK808_ID = 0x0000, > RK816_ID = 0x8160, > + RK817_ID = 0x8170, > RK818_ID = 0x8180, > }; > > +enum { > + RK817_POWER_EN0 = 0xb1, > + RK817_POWER_EN1, > + RK817_POWER_EN2, > + RK817_POWER_EN3, > +}; > + > +#define RK817_POWER_EN_SAVE0 0x99 > +#define RK817_POWER_EN_SAVE1 0xa4 > + > +#define RK817_ID_MSB 0xed > +#define RK817_ID_LSB 0xee > #define RK8XX_ID_MSK 0xfff0 > > +#define RK817_PMIC_SYS_CFG3 0xf4 > +#define RK817_GPIO_INT_CFG 0xfe > + > +#define RK8XX_ON_SOURCE 0xae > +#define RK8XX_OFF_SOURCE 0xaf > +#define RK817_BUCK4_CMIN 0xc6 > +#define RK817_ON_SOURCE 0xf5 > +#define RK817_OFF_SOURCE 0xf6 > + > +struct reg_data { > + u8 reg; > + u8 val; > + u8 mask; > +}; > struct rk8xx_reg_table { > char *name; > u8 reg_ctl;
diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c index df2056913ced..0ec6cb31d706 100644 --- a/drivers/power/pmic/rk8xx.c +++ b/drivers/power/pmic/rk8xx.c @@ -10,6 +10,13 @@ #include <power/rk8xx_pmic.h> #include <power/pmic.h> +static struct reg_data rk817_init_reg[] = { +/* enable the under-voltage protection, + * the under-voltage protection will shutdown the LDO3 and reset the PMIC + */ + { RK817_BUCK4_CMIN, 0x60, 0x60}, +}; + static const struct pmic_child_info pmic_children_info[] = { { .prefix = "DCDC_REG", .driver = "rk8xx_buck"}, { .prefix = "LDO_REG", .driver = "rk8xx_ldo"}, @@ -52,16 +59,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: @@ -69,18 +82,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; } @@ -114,13 +127,83 @@ 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; + struct reg_data *init_data = NULL; + int init_data_num = 0; + int ret = 0, i, show_variant; + u8 msb, lsb, id_msb, id_lsb; + u8 on_source = 0, off_source = 0; + u8 power_en0, power_en1, power_en2, power_en3; + u8 value; /* 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; + } + + ret = rk8xx_read(dev, id_msb, &msb, 1); + if (ret) + return ret; + ret = rk8xx_read(dev, id_lsb, &lsb, 1); + if (ret) + return ret; priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK; + show_variant = priv->variant; + switch (priv->variant) { + case RK808_ID: + show_variant = 0x808; /* RK808 hardware ID is 0 */ + break; + case RK805_ID: + case RK816_ID: + case RK818_ID: + on_source = RK8XX_ON_SOURCE; + off_source = RK8XX_OFF_SOURCE; + break; + case RK817_ID: + on_source = RK817_ON_SOURCE; + off_source = RK817_OFF_SOURCE; + init_data = rk817_init_reg; + init_data_num = ARRAY_SIZE(rk817_init_reg); + power_en0 = pmic_reg_read(dev, RK817_POWER_EN0); + power_en1 = pmic_reg_read(dev, RK817_POWER_EN1); + power_en2 = pmic_reg_read(dev, RK817_POWER_EN2); + power_en3 = pmic_reg_read(dev, RK817_POWER_EN3); + + value = (power_en0 & 0x0f) | ((power_en1 & 0x0f) << 4); + pmic_reg_write(dev, RK817_POWER_EN_SAVE0, value); + value = (power_en2 & 0x0f) | ((power_en3 & 0x0f) << 4); + pmic_reg_write(dev, RK817_POWER_EN_SAVE1, value); + break; + default: + printf("Unknown PMIC: RK%x!!\n", priv->variant); + return -EINVAL; + } + + for (i = 0; i < init_data_num; i++) { + ret = pmic_clrsetbits(dev, + init_data[i].reg, + init_data[i].mask, + init_data[i].val); + if (ret < 0) { + printf("%s: i2c set reg 0x%x failed, ret=%d\n", + __func__, init_data[i].reg, ret); + } + + debug("%s: reg[0x%x] = 0x%x\n", __func__, init_data[i].reg, + pmic_reg_read(dev, init_data[i].reg)); + } + + printf("PMIC: RK%x ", show_variant); + + if (on_source && off_source) + printf("(on=0x%02x, off=0x%02x)", + pmic_reg_read(dev, on_source), + pmic_reg_read(dev, off_source)); + printf("\n"); return 0; } @@ -136,6 +219,7 @@ static const struct udevice_id rk8xx_ids[] = { { .compatible = "rockchip,rk805" }, { .compatible = "rockchip,rk808" }, { .compatible = "rockchip,rk816" }, + { .compatible = "rockchip,rk817" }, { .compatible = "rockchip,rk818" }, { } }; diff --git a/drivers/power/regulator/rk8xx.c b/drivers/power/regulator/rk8xx.c index e9d83635988b..3c4a18b0f0c7 100644 --- a/drivers/power/regulator/rk8xx.c +++ b/drivers/power/regulator/rk8xx.c @@ -27,6 +27,21 @@ #define RK808_BUCK4_VSEL_MASK 0xf #define RK808_LDO_VSEL_MASK 0x1f +/* 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 +#define RK817_BUCK_CONFIG(i) (0xba + (i) * 3) + +/* 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)) + #define RK818_BUCK_VSEL_MASK 0x3f #define RK818_BUCK4_VSEL_MASK 0x1f #define RK818_LDO_VSEL_MASK 0x1f @@ -45,13 +60,19 @@ #define RK805_RAMP_RATE_12_5MV_PER_US (2 << RK805_RAMP_RATE_OFFSET) #define RK805_RAMP_RATE_25MV_PER_US (3 << RK805_RAMP_RATE_OFFSET) #define RK808_RAMP_RATE_OFFSET 3 - #define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET) #define RK808_RAMP_RATE_2MV_PER_US (0 << RK808_RAMP_RATE_OFFSET) #define RK808_RAMP_RATE_4MV_PER_US (1 << RK808_RAMP_RATE_OFFSET) #define RK808_RAMP_RATE_6MV_PER_US (2 << RK808_RAMP_RATE_OFFSET) #define RK808_RAMP_RATE_10MV_PER_US (3 << RK808_RAMP_RATE_OFFSET) +#define RK817_RAMP_RATE_OFFSET 6 +#define RK817_RAMP_RATE_MASK (0x3 << RK817_RAMP_RATE_OFFSET) +#define RK817_RAMP_RATE_3MV_PER_US (0x0 << RK817_RAMP_RATE_OFFSET) +#define RK817_RAMP_RATE_6_3MV_PER_US (0x1 << RK817_RAMP_RATE_OFFSET) +#define RK817_RAMP_RATE_12_5MV_PER_US (0x2 << RK817_RAMP_RATE_OFFSET) +#define RK817_RAMP_RATE_25MV_PER_US (0x3 << RK817_RAMP_RATE_OFFSET) + struct rk8xx_reg_info { uint min_uv; uint step_uv; @@ -84,6 +105,25 @@ static const struct rk8xx_reg_info rk816_buck[] = { { 800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, REG_BUCK4_CONFIG, 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_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x00, }, + { 1500000, 100000, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x50, }, + { 2400000, 0, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x59, }, + /* buck 2 */ + { 500000, 12500, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x00, }, + { 1500000, 100000, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x50, }, + { 2400000, 0, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x59, }, + /* buck 3 */ + { 500000, 12500, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x00, }, + { 1500000, 100000, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x50, }, + { 2400000, 0, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x59, }, + /* buck 4 */ + { 500000, 12500, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x00, }, + { 1500000, 100000, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x50, }, + { 3400000, 0, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x63, }, +}; + static const struct rk8xx_reg_info rk818_buck[] = { { 712500, 12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, REG_BUCK1_CONFIG, RK818_BUCK_VSEL_MASK, }, { 712500, 12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, REG_BUCK2_CONFIG, RK818_BUCK_VSEL_MASK, }, @@ -112,6 +152,36 @@ static const struct rk8xx_reg_info rk816_ldo[] = { { 800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, NA, 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), NA, RK817_LDO_VSEL_MASK, 0x00, }, + { 3400000, 0, RK817_LDO_ON_VSEL(1), RK817_LDO_SLP_VSEL(1), NA, RK817_LDO_VSEL_MASK, 0x70, }, + /* ldo2 */ + { 600000, 25000, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), NA, RK817_LDO_VSEL_MASK, 0x00, }, + { 3400000, 0, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), NA, RK817_LDO_VSEL_MASK, 0x70, }, + /* ldo3 */ + { 600000, 25000, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), NA, RK817_LDO_VSEL_MASK, 0x00, }, + { 3400000, 0, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), NA, RK817_LDO_VSEL_MASK, 0x70, }, + /* ldo4 */ + { 600000, 25000, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), NA, RK817_LDO_VSEL_MASK, 0x00, }, + { 3400000, 0, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), NA, RK817_LDO_VSEL_MASK, 0x70, }, + /* ldo5 */ + { 600000, 25000, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), NA, RK817_LDO_VSEL_MASK, 0x00, }, + { 3400000, 0, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), NA, RK817_LDO_VSEL_MASK, 0x70, }, + /* ldo6 */ + { 600000, 25000, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), NA, RK817_LDO_VSEL_MASK, 0x00, }, + { 3400000, 0, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), NA, RK817_LDO_VSEL_MASK, 0x70, }, + /* ldo7 */ + { 600000, 25000, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), NA, RK817_LDO_VSEL_MASK, 0x00, }, + { 3400000, 0, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), NA, RK817_LDO_VSEL_MASK, 0x70, }, + /* ldo8 */ + { 600000, 25000, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), NA, RK817_LDO_VSEL_MASK, 0x00, }, + { 3400000, 0, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), NA, RK817_LDO_VSEL_MASK, 0x70, }, + /* ldo9 */ + { 600000, 25000, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), NA, RK817_LDO_VSEL_MASK, 0x00, }, + { 3400000, 0, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), NA, RK817_LDO_VSEL_MASK, 0x70, }, +}; + static const struct rk8xx_reg_info rk818_ldo[] = { { 1800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, }, { 1800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, }, @@ -152,6 +222,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]; + case 3: + 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: @@ -189,7 +277,7 @@ static int _buck_set_value(struct udevice *pmic, int buck, int uvolt) static int _buck_set_enable(struct udevice *pmic, int buck, bool enable) { uint mask, value, en_reg; - int ret; + int ret = 0; struct rk8xx_priv *priv = dev_get_priv(pmic); switch (priv->variant) { @@ -220,6 +308,15 @@ 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 (buck < 4) { + 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; } @@ -272,6 +369,12 @@ static int _buck_get_enable(struct udevice *pmic, int buck) if (ret < 0) return ret; break; + case RK817_ID: + if (buck < 4) { + mask = 1 << buck; + ret = pmic_reg_read(pmic, RK817_POWER_EN(0)); + } + break; } if (ret < 0) @@ -282,7 +385,7 @@ static int _buck_get_enable(struct udevice *pmic, int buck) static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable) { - uint mask; + uint mask = 0; int ret; struct rk8xx_priv *priv = dev_get_priv(pmic); @@ -299,6 +402,12 @@ 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: + if (buck < 4) + mask = 1 << buck; + ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask, + enable ? mask : 0); + break; default: ret = -EINVAL; } @@ -310,7 +419,7 @@ static int _buck_get_suspend_enable(struct udevice *pmic, int buck) { struct rk8xx_priv *priv = dev_get_priv(pmic); int ret, val; - uint mask; + uint mask = 0; switch (priv->variant) { case RK805_ID: @@ -329,6 +438,15 @@ static int _buck_get_suspend_enable(struct udevice *pmic, int buck) return val; ret = val & mask ? 0 : 1; break; + case RK817_ID: + if (buck < 4) + mask = 1 << buck; + + val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0)); + if (val < 0) + return val; + ret = val & mask ? 1 : 0; + break; default: ret = -EINVAL; } @@ -345,6 +463,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: @@ -376,6 +499,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; } if (ret < 0) @@ -413,6 +550,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; @@ -437,6 +592,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; @@ -465,6 +631,21 @@ static int _ldo_get_suspend_enable(struct udevice *pmic, int ldo) return val; ret = val & mask ? 0 : 1; break; + case RK817_ID: + if (ldo == 8) { + mask = 1 << 4; /* LDO9 */ + val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0)); + if (val < 0) + return val; + ret = val & mask ? 1 : 0; + } else { + mask = 1 << ldo; + val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(1)); + if (val < 0) + return val; + ret = val & mask ? 1 : 0; + } + break; } return ret; diff --git a/include/power/rk8xx_pmic.h b/include/power/rk8xx_pmic.h index 7784c2a5e473..d93cecedddf7 100644 --- a/include/power/rk8xx_pmic.h +++ b/include/power/rk8xx_pmic.h @@ -170,6 +170,10 @@ enum { }; enum { + RK817_REG_SYS_CFG3 = 0xf4, +}; + +enum { RK816_REG_DCDC_EN1 = 0x23, RK816_REG_DCDC_EN2, RK816_REG_DCDC_SLP_EN, @@ -182,11 +186,38 @@ enum { RK805_ID = 0x8050, RK808_ID = 0x0000, RK816_ID = 0x8160, + RK817_ID = 0x8170, RK818_ID = 0x8180, }; +enum { + RK817_POWER_EN0 = 0xb1, + RK817_POWER_EN1, + RK817_POWER_EN2, + RK817_POWER_EN3, +}; + +#define RK817_POWER_EN_SAVE0 0x99 +#define RK817_POWER_EN_SAVE1 0xa4 + +#define RK817_ID_MSB 0xed +#define RK817_ID_LSB 0xee #define RK8XX_ID_MSK 0xfff0 +#define RK817_PMIC_SYS_CFG3 0xf4 +#define RK817_GPIO_INT_CFG 0xfe + +#define RK8XX_ON_SOURCE 0xae +#define RK8XX_OFF_SOURCE 0xaf +#define RK817_BUCK4_CMIN 0xc6 +#define RK817_ON_SOURCE 0xf5 +#define RK817_OFF_SOURCE 0xf6 + +struct reg_data { + u8 reg; + u8 val; + u8 mask; +}; struct rk8xx_reg_table { char *name; u8 reg_ctl;