From: Joseph Chen <che...@rock-chips.com>

include sub modules: pmic, regulator

Signed-off-by: Joseph Chen <che...@rock-chips.com>
Signed-off-by: Elaine Zhang <zhangq...@rock-chips.com>
---
 drivers/power/pmic/rk8xx.c      | 109 ++++++++++++++++++++--
 drivers/power/regulator/rk8xx.c | 198 +++++++++++++++++++++++++++++++++++++++-
 include/power/rk8xx_pmic.h      |  31 +++++++
 3 files changed, 329 insertions(+), 9 deletions(-)

diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index df2056913ced..b7ce87d0eff5 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -10,6 +10,22 @@
 #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},
+/*
+ * Only when system suspend while U-Boot charge needs this config support
+ */
+#ifdef CONFIG_DM_CHARGE_DISPLAY
+       /* Set pmic_sleep as sleep function */
+       { RK817_PMIC_SYS_CFG3, 0x08, 0x18 },
+       /* Set pmic_int active low */
+       { RK817_GPIO_INT_CFG,  0x00, 0x02 },
+#endif
+};
+
 static const struct pmic_child_info pmic_children_info[] = {
        { .prefix = "DCDC_REG", .driver = "rk8xx_buck"},
        { .prefix = "LDO_REG", .driver = "rk8xx_ldo"},
@@ -52,16 +68,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 +91,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 +136,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 +228,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 2416477f5c06..0d95e54220b0 100644
--- a/drivers/power/regulator/rk8xx.c
+++ b/drivers/power/regulator/rk8xx.c
@@ -28,6 +28,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
@@ -46,13 +61,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;
@@ -85,6 +106,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, },
@@ -113,6 +153,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, },
@@ -153,6 +223,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:
@@ -221,6 +309,22 @@ 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);
+               /* BUCK5 for RK809 */
+               } else {
+                       if (enable)
+                               value = ((1 << 1) | (1 << 5));
+                       else
+                               value = ((0 << 1) | (1 << 5));
+                       ret = pmic_reg_write(pmic, RK817_POWER_EN(3), value);
+               }
+               break;
        default:
                ret = -EINVAL;
        }
@@ -273,6 +377,16 @@ 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));
+               /* BUCK5 for RK809 */
+               } else {
+                       mask = 1 << 1;
+                       ret = pmic_reg_read(pmic, RK817_POWER_EN(3));
+               }
+               break;
        }
 
        if (ret < 0)
@@ -300,6 +414,14 @@ 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;
+               else
+                       mask = 1 << 5;  /* BUCK5 for RK809 */
+               ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
+                                     enable ? mask : 0);
+               break;
        default:
                ret = -EINVAL;
        }
@@ -330,6 +452,17 @@ 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;
+               else
+                       mask = 1 << 5;  /* BUCK5 for RK809 */
+
+               val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0));
+               if (val < 0)
+                       return val;
+               ret = val & mask ? 1 : 0;
+               break;
        default:
                ret = -EINVAL;
        }
@@ -346,6 +479,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:
@@ -377,6 +515,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)
@@ -414,6 +566,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;
@@ -438,6 +608,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;
@@ -466,6 +647,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;
-- 
1.9.1



_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to