nvmem: rockchip-efuse: add support for rk3288 secure efuse
[firefly-linux-kernel-4.4.55.git] / drivers / regulator / rk808-regulator.c
index d86a3dcd61e243a806724e16da6be4db44097a45..fb44d5215e30c8573b8eef9ad751367ef4e23e81 100644 (file)
@@ -1,11 +1,15 @@
 /*
- * Regulator driver for Rockchip RK808
+ * Regulator driver for Rockchip RK808/RK818
  *
  * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
  *
  * Author: Chris Zhong <zyw@rock-chips.com>
  * Author: Zhang Qing <zhangqing@rock-chips.com>
  *
+ * Copyright (C) 2016 PHYTEC Messtechnik GmbH
+ *
+ * Author: Wadim Egorov <w.egorov@phytec.de>
+ *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
  * version 2, as published by the Free Software Foundation.
 #define RK808_BUCK4_VSEL_MASK  0xf
 #define RK808_LDO_VSEL_MASK    0x1f
 
+#define RK818_BUCK_VSEL_MASK           0x3f
+#define RK818_BUCK4_VSEL_MASK          0x1f
+#define RK818_LDO_VSEL_MASK            0x1f
+#define RK818_LDO3_ON_VSEL_MASK                0xf
+#define RK818_BOOST_ON_VSEL_MASK       0xe0
+
 /* Ramp rate definitions for buck1 / buck2 only */
 #define RK808_RAMP_RATE_OFFSET         3
 #define RK808_RAMP_RATE_MASK           (3 << RK808_RAMP_RATE_OFFSET)
 /* max steps for increase voltage of Buck1/2, equal 100mv*/
 #define MAX_STEPS_ONE_TIME 8
 
+#define RK8XX_DESC(_id, _match, _supply, _min, _max, _step, _vreg,     \
+       _vmask, _ereg, _emask, _etime)                                  \
+       [_id] = {                                                       \
+               .name           = (_match),                             \
+               .supply_name    = (_supply),                            \
+               .of_match       = of_match_ptr(_match),                 \
+               .regulators_node = of_match_ptr("regulators"),          \
+               .type           = REGULATOR_VOLTAGE,                    \
+               .id             = (_id),                                \
+               .n_voltages     = (((_max) - (_min)) / (_step) + 1),    \
+               .owner          = THIS_MODULE,                          \
+               .min_uV         = (_min) * 1000,                        \
+               .uV_step        = (_step) * 1000,                       \
+               .vsel_reg       = (_vreg),                              \
+               .vsel_mask      = (_vmask),                             \
+               .enable_reg     = (_ereg),                              \
+               .enable_mask    = (_emask),                             \
+               .enable_time    = (_etime),                             \
+               .ops            = &rk808_reg_ops,                       \
+       }
+
+#define RK8XX_DESC_SWITCH(_id, _match, _supply, _ereg, _emask)         \
+       [_id] = {                                                       \
+               .name           = (_match),                             \
+               .supply_name    = (_supply),                            \
+               .of_match       = of_match_ptr(_match),                 \
+               .regulators_node = of_match_ptr("regulators"),          \
+               .type           = REGULATOR_VOLTAGE,                    \
+               .id             = (_id),                                \
+               .enable_reg     = (_ereg),                              \
+               .enable_mask    = (_emask),                             \
+               .owner          = THIS_MODULE,                          \
+               .ops            = &rk808_switch_ops                     \
+       }
+
+
 struct rk808_regulator_data {
        struct gpio_desc *dvs_gpio[2];
 };
@@ -66,31 +112,15 @@ static const int rk808_buck_config_regs[] = {
        RK808_BUCK4_CONFIG_REG,
 };
 
-static const struct regulator_linear_range rk808_buck_voltage_ranges[] = {
-       REGULATOR_LINEAR_RANGE(712500, 0, 63, 12500),
-};
-
-static const struct regulator_linear_range rk808_buck4_voltage_ranges[] = {
-       REGULATOR_LINEAR_RANGE(1800000, 0, 15, 100000),
-};
-
-static const struct regulator_linear_range rk808_ldo_voltage_ranges[] = {
-       REGULATOR_LINEAR_RANGE(1800000, 0, 16, 100000),
-};
-
 static const struct regulator_linear_range rk808_ldo3_voltage_ranges[] = {
        REGULATOR_LINEAR_RANGE(800000, 0, 13, 100000),
        REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0),
 };
 
-static const struct regulator_linear_range rk808_ldo6_voltage_ranges[] = {
-       REGULATOR_LINEAR_RANGE(800000, 0, 17, 100000),
-};
-
 static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev)
 {
        struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
-       int id = rdev->desc->id - RK808_ID_DCDC1;
+       int id = rdev_get_id(rdev);
        struct gpio_desc *gpio = pdata->dvs_gpio[id];
        unsigned int val;
        int ret;
@@ -163,7 +193,7 @@ static int rk808_buck1_2_set_voltage_sel(struct regulator_dev *rdev,
                                         unsigned sel)
 {
        struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
-       int id = rdev->desc->id - RK808_ID_DCDC1;
+       int id = rdev_get_id(rdev);
        struct gpio_desc *gpio = pdata->dvs_gpio[id];
        unsigned int reg = rdev->desc->vsel_reg;
        unsigned old_sel;
@@ -202,7 +232,7 @@ static int rk808_buck1_2_set_voltage_time_sel(struct regulator_dev *rdev,
                                       unsigned int new_selector)
 {
        struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
-       int id = rdev->desc->id - RK808_ID_DCDC1;
+       int id = rdev_get_id(rdev);
        struct gpio_desc *gpio = pdata->dvs_gpio[id];
 
        /* if there is no dvs1/2 pin, we don't need wait extra time here. */
@@ -215,8 +245,7 @@ static int rk808_buck1_2_set_voltage_time_sel(struct regulator_dev *rdev,
 static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
 {
        unsigned int ramp_value = RK808_RAMP_RATE_10MV_PER_US;
-       unsigned int reg = rk808_buck_config_regs[rdev->desc->id -
-                                                 RK808_ID_DCDC1];
+       unsigned int reg = rk808_buck_config_regs[rdev_get_id(rdev)];
 
        switch (ramp_delay) {
        case 1 ... 2000:
@@ -240,6 +269,21 @@ static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
 }
 
 static int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
+{
+       unsigned int reg;
+       int sel = regulator_map_voltage_linear(rdev, uv, uv);
+
+       if (sel < 0)
+               return -EINVAL;
+
+       reg = rdev->desc->vsel_reg + RK808_SLP_REG_OFFSET;
+
+       return regmap_update_bits(rdev->regmap, reg,
+                                 rdev->desc->vsel_mask,
+                                 sel);
+}
+
+static int rk808_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
 {
        unsigned int reg;
        int sel = regulator_map_voltage_linear_range(rdev, uv, uv);
@@ -277,8 +321,8 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
 }
 
 static struct regulator_ops rk808_buck1_2_ops = {
-       .list_voltage           = regulator_list_voltage_linear_range,
-       .map_voltage            = regulator_map_voltage_linear_range,
+       .list_voltage           = regulator_list_voltage_linear,
+       .map_voltage            = regulator_map_voltage_linear,
        .get_voltage_sel        = rk808_buck1_2_get_voltage_sel_regmap,
        .set_voltage_sel        = rk808_buck1_2_set_voltage_sel,
        .set_voltage_time_sel   = rk808_buck1_2_set_voltage_time_sel,
@@ -292,6 +336,19 @@ static struct regulator_ops rk808_buck1_2_ops = {
 };
 
 static struct regulator_ops rk808_reg_ops = {
+       .list_voltage           = regulator_list_voltage_linear,
+       .map_voltage            = regulator_map_voltage_linear,
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .is_enabled             = regulator_is_enabled_regmap,
+       .set_suspend_voltage    = rk808_set_suspend_voltage,
+       .set_suspend_enable     = rk808_set_suspend_enable,
+       .set_suspend_disable    = rk808_set_suspend_disable,
+};
+
+static struct regulator_ops rk808_reg_ops_ranges = {
        .list_voltage           = regulator_list_voltage_linear_range,
        .map_voltage            = regulator_map_voltage_linear_range,
        .get_voltage_sel        = regulator_get_voltage_sel_regmap,
@@ -299,7 +356,7 @@ static struct regulator_ops rk808_reg_ops = {
        .enable                 = regulator_enable_regmap,
        .disable                = regulator_disable_regmap,
        .is_enabled             = regulator_is_enabled_regmap,
-       .set_suspend_voltage    = rk808_set_suspend_voltage,
+       .set_suspend_voltage    = rk808_set_suspend_voltage_range,
        .set_suspend_enable     = rk808_set_suspend_enable,
        .set_suspend_disable    = rk808_set_suspend_disable,
 };
@@ -316,12 +373,14 @@ static const struct regulator_desc rk808_reg[] = {
        {
                .name = "DCDC_REG1",
                .supply_name = "vcc1",
+               .of_match = of_match_ptr("DCDC_REG1"),
+               .regulators_node = of_match_ptr("regulators"),
                .id = RK808_ID_DCDC1,
                .ops = &rk808_buck1_2_ops,
                .type = REGULATOR_VOLTAGE,
+               .min_uV = 712500,
+               .uV_step = 12500,
                .n_voltages = 64,
-               .linear_ranges = rk808_buck_voltage_ranges,
-               .n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges),
                .vsel_reg = RK808_BUCK1_ON_VSEL_REG,
                .vsel_mask = RK808_BUCK_VSEL_MASK,
                .enable_reg = RK808_DCDC_EN_REG,
@@ -330,12 +389,14 @@ static const struct regulator_desc rk808_reg[] = {
        }, {
                .name = "DCDC_REG2",
                .supply_name = "vcc2",
+               .of_match = of_match_ptr("DCDC_REG2"),
+               .regulators_node = of_match_ptr("regulators"),
                .id = RK808_ID_DCDC2,
                .ops = &rk808_buck1_2_ops,
                .type = REGULATOR_VOLTAGE,
+               .min_uV = 712500,
+               .uV_step = 12500,
                .n_voltages = 64,
-               .linear_ranges = rk808_buck_voltage_ranges,
-               .n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges),
                .vsel_reg = RK808_BUCK2_ON_VSEL_REG,
                .vsel_mask = RK808_BUCK_VSEL_MASK,
                .enable_reg = RK808_DCDC_EN_REG,
@@ -344,6 +405,8 @@ static const struct regulator_desc rk808_reg[] = {
        }, {
                .name = "DCDC_REG3",
                .supply_name = "vcc3",
+               .of_match = of_match_ptr("DCDC_REG3"),
+               .regulators_node = of_match_ptr("regulators"),
                .id = RK808_ID_DCDC3,
                .ops = &rk808_switch_ops,
                .type = REGULATOR_VOLTAGE,
@@ -351,55 +414,23 @@ static const struct regulator_desc rk808_reg[] = {
                .enable_reg = RK808_DCDC_EN_REG,
                .enable_mask = BIT(2),
                .owner = THIS_MODULE,
-       }, {
-               .name = "DCDC_REG4",
-               .supply_name = "vcc4",
-               .id = RK808_ID_DCDC4,
-               .ops = &rk808_reg_ops,
-               .type = REGULATOR_VOLTAGE,
-               .n_voltages = 16,
-               .linear_ranges = rk808_buck4_voltage_ranges,
-               .n_linear_ranges = ARRAY_SIZE(rk808_buck4_voltage_ranges),
-               .vsel_reg = RK808_BUCK4_ON_VSEL_REG,
-               .vsel_mask = RK808_BUCK4_VSEL_MASK,
-               .enable_reg = RK808_DCDC_EN_REG,
-               .enable_mask = BIT(3),
-               .owner = THIS_MODULE,
-       }, {
-               .name = "LDO_REG1",
-               .supply_name = "vcc6",
-               .id = RK808_ID_LDO1,
-               .ops = &rk808_reg_ops,
-               .type = REGULATOR_VOLTAGE,
-               .n_voltages = 17,
-               .linear_ranges = rk808_ldo_voltage_ranges,
-               .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
-               .vsel_reg = RK808_LDO1_ON_VSEL_REG,
-               .vsel_mask = RK808_LDO_VSEL_MASK,
-               .enable_reg = RK808_LDO_EN_REG,
-               .enable_mask = BIT(0),
-               .enable_time = 400,
-               .owner = THIS_MODULE,
-       }, {
-               .name = "LDO_REG2",
-               .supply_name = "vcc6",
-               .id = RK808_ID_LDO2,
-               .ops = &rk808_reg_ops,
-               .type = REGULATOR_VOLTAGE,
-               .n_voltages = 17,
-               .linear_ranges = rk808_ldo_voltage_ranges,
-               .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
-               .vsel_reg = RK808_LDO2_ON_VSEL_REG,
-               .vsel_mask = RK808_LDO_VSEL_MASK,
-               .enable_reg = RK808_LDO_EN_REG,
-               .enable_mask = BIT(1),
-               .enable_time = 400,
-               .owner = THIS_MODULE,
-       }, {
+       },
+       RK8XX_DESC(RK808_ID_DCDC4, "DCDC_REG4", "vcc4", 1800, 3300, 100,
+               RK808_BUCK4_ON_VSEL_REG, RK808_BUCK4_VSEL_MASK,
+               RK808_DCDC_EN_REG, BIT(3), 0),
+       RK8XX_DESC(RK808_ID_LDO1, "LDO_REG1", "vcc6", 1800, 3400, 100,
+               RK808_LDO1_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
+               BIT(0), 400),
+       RK8XX_DESC(RK808_ID_LDO2, "LDO_REG2", "vcc6", 1800, 3400, 100,
+               RK808_LDO2_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
+               BIT(1), 400),
+       {
                .name = "LDO_REG3",
                .supply_name = "vcc7",
+               .of_match = of_match_ptr("LDO_REG3"),
+               .regulators_node = of_match_ptr("regulators"),
                .id = RK808_ID_LDO3,
-               .ops = &rk808_reg_ops,
+               .ops = &rk808_reg_ops_ranges,
                .type = REGULATOR_VOLTAGE,
                .n_voltages = 16,
                .linear_ranges = rk808_ldo3_voltage_ranges,
@@ -410,117 +441,128 @@ static const struct regulator_desc rk808_reg[] = {
                .enable_mask = BIT(2),
                .enable_time = 400,
                .owner = THIS_MODULE,
-       }, {
-               .name = "LDO_REG4",
-               .supply_name = "vcc9",
-               .id = RK808_ID_LDO4,
+       },
+       RK8XX_DESC(RK808_ID_LDO4, "LDO_REG4", "vcc9", 1800, 3400, 100,
+               RK808_LDO4_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
+               BIT(3), 400),
+       RK8XX_DESC(RK808_ID_LDO5, "LDO_REG5", "vcc9", 1800, 3400, 100,
+               RK808_LDO5_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
+               BIT(4), 400),
+       RK8XX_DESC(RK808_ID_LDO6, "LDO_REG6", "vcc10", 800, 2500, 100,
+               RK808_LDO6_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
+               BIT(5), 400),
+       RK8XX_DESC(RK808_ID_LDO7, "LDO_REG7", "vcc7", 800, 2500, 100,
+               RK808_LDO7_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
+               BIT(6), 400),
+       RK8XX_DESC(RK808_ID_LDO8, "LDO_REG8", "vcc11", 1800, 3400, 100,
+               RK808_LDO8_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
+               BIT(7), 400),
+       RK8XX_DESC_SWITCH(RK808_ID_SWITCH1, "SWITCH_REG1", "vcc8",
+               RK808_DCDC_EN_REG, BIT(5)),
+       RK8XX_DESC_SWITCH(RK808_ID_SWITCH2, "SWITCH_REG2", "vcc12",
+               RK808_DCDC_EN_REG, BIT(6)),
+};
+
+static const struct regulator_desc rk818_reg[] = {
+       {
+               .name = "DCDC_REG1",
+               .supply_name = "vcc1",
+               .of_match = of_match_ptr("DCDC_REG1"),
+               .regulators_node = of_match_ptr("regulators"),
+               .id = RK818_ID_DCDC1,
                .ops = &rk808_reg_ops,
                .type = REGULATOR_VOLTAGE,
-               .n_voltages = 17,
-               .linear_ranges = rk808_ldo_voltage_ranges,
-               .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
-               .vsel_reg = RK808_LDO4_ON_VSEL_REG,
-               .vsel_mask = RK808_LDO_VSEL_MASK,
-               .enable_reg = RK808_LDO_EN_REG,
-               .enable_mask = BIT(3),
-               .enable_time = 400,
+               .min_uV = 712500,
+               .uV_step = 12500,
+               .n_voltages = 64,
+               .vsel_reg = RK818_BUCK1_ON_VSEL_REG,
+               .vsel_mask = RK818_BUCK_VSEL_MASK,
+               .enable_reg = RK818_DCDC_EN_REG,
+               .enable_mask = BIT(0),
                .owner = THIS_MODULE,
        }, {
-               .name = "LDO_REG5",
-               .supply_name = "vcc9",
-               .id = RK808_ID_LDO5,
+               .name = "DCDC_REG2",
+               .supply_name = "vcc2",
+               .of_match = of_match_ptr("DCDC_REG2"),
+               .regulators_node = of_match_ptr("regulators"),
+               .id = RK818_ID_DCDC2,
                .ops = &rk808_reg_ops,
                .type = REGULATOR_VOLTAGE,
-               .n_voltages = 17,
-               .linear_ranges = rk808_ldo_voltage_ranges,
-               .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
-               .vsel_reg = RK808_LDO5_ON_VSEL_REG,
-               .vsel_mask = RK808_LDO_VSEL_MASK,
-               .enable_reg = RK808_LDO_EN_REG,
-               .enable_mask = BIT(4),
-               .enable_time = 400,
+               .min_uV = 712500,
+               .uV_step = 12500,
+               .n_voltages = 64,
+               .vsel_reg = RK818_BUCK2_ON_VSEL_REG,
+               .vsel_mask = RK818_BUCK_VSEL_MASK,
+               .enable_reg = RK818_DCDC_EN_REG,
+               .enable_mask = BIT(1),
                .owner = THIS_MODULE,
        }, {
-               .name = "LDO_REG6",
-               .supply_name = "vcc10",
-               .id = RK808_ID_LDO6,
-               .ops = &rk808_reg_ops,
+               .name = "DCDC_REG3",
+               .supply_name = "vcc3",
+               .of_match = of_match_ptr("DCDC_REG3"),
+               .regulators_node = of_match_ptr("regulators"),
+               .id = RK818_ID_DCDC3,
+               .ops = &rk808_switch_ops,
                .type = REGULATOR_VOLTAGE,
-               .n_voltages = 18,
-               .linear_ranges = rk808_ldo6_voltage_ranges,
-               .n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges),
-               .vsel_reg = RK808_LDO6_ON_VSEL_REG,
-               .vsel_mask = RK808_LDO_VSEL_MASK,
-               .enable_reg = RK808_LDO_EN_REG,
-               .enable_mask = BIT(5),
-               .enable_time = 400,
+               .n_voltages = 1,
+               .enable_reg = RK818_DCDC_EN_REG,
+               .enable_mask = BIT(2),
                .owner = THIS_MODULE,
-       }, {
-               .name = "LDO_REG7",
+       },
+       RK8XX_DESC(RK818_ID_DCDC4, "DCDC_REG4", "vcc4", 1800, 3600, 100,
+               RK818_BUCK4_ON_VSEL_REG, RK818_BUCK4_VSEL_MASK,
+               RK818_DCDC_EN_REG, BIT(3), 0),
+       RK8XX_DESC(RK818_ID_BOOST, "DCDC_BOOST", "boost", 4700, 5400, 100,
+               RK818_BOOST_LDO9_ON_VSEL_REG, RK818_BOOST_ON_VSEL_MASK,
+               RK818_DCDC_EN_REG, BIT(4), 0),
+       RK8XX_DESC(RK818_ID_LDO1, "LDO_REG1", "vcc6", 1800, 3400, 100,
+               RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
+               BIT(0), 400),
+       RK8XX_DESC(RK818_ID_LDO2, "LDO_REG2", "vcc6", 1800, 3400, 100,
+               RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
+               BIT(1), 400),
+       {
+               .name = "LDO_REG3",
                .supply_name = "vcc7",
-               .id = RK808_ID_LDO7,
-               .ops = &rk808_reg_ops,
+               .of_match = of_match_ptr("LDO_REG3"),
+               .regulators_node = of_match_ptr("regulators"),
+               .id = RK818_ID_LDO3,
+               .ops = &rk808_reg_ops_ranges,
                .type = REGULATOR_VOLTAGE,
-               .n_voltages = 18,
-               .linear_ranges = rk808_ldo6_voltage_ranges,
-               .n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges),
-               .vsel_reg = RK808_LDO7_ON_VSEL_REG,
-               .vsel_mask = RK808_LDO_VSEL_MASK,
-               .enable_reg = RK808_LDO_EN_REG,
-               .enable_mask = BIT(6),
-               .enable_time = 400,
-               .owner = THIS_MODULE,
-       }, {
-               .name = "LDO_REG8",
-               .supply_name = "vcc11",
-               .id = RK808_ID_LDO8,
-               .ops = &rk808_reg_ops,
-               .type = REGULATOR_VOLTAGE,
-               .n_voltages = 17,
-               .linear_ranges = rk808_ldo_voltage_ranges,
-               .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
-               .vsel_reg = RK808_LDO8_ON_VSEL_REG,
-               .vsel_mask = RK808_LDO_VSEL_MASK,
-               .enable_reg = RK808_LDO_EN_REG,
-               .enable_mask = BIT(7),
+               .n_voltages = 16,
+               .linear_ranges = rk808_ldo3_voltage_ranges,
+               .n_linear_ranges = ARRAY_SIZE(rk808_ldo3_voltage_ranges),
+               .vsel_reg = RK818_LDO3_ON_VSEL_REG,
+               .vsel_mask = RK818_LDO3_ON_VSEL_MASK,
+               .enable_reg = RK818_LDO_EN_REG,
+               .enable_mask = BIT(2),
                .enable_time = 400,
                .owner = THIS_MODULE,
-       }, {
-               .name = "SWITCH_REG1",
-               .supply_name = "vcc8",
-               .id = RK808_ID_SWITCH1,
-               .ops = &rk808_switch_ops,
-               .type = REGULATOR_VOLTAGE,
-               .enable_reg = RK808_DCDC_EN_REG,
-               .enable_mask = BIT(5),
-               .owner = THIS_MODULE,
-       }, {
-               .name = "SWITCH_REG2",
-               .supply_name = "vcc12",
-               .id = RK808_ID_SWITCH2,
-               .ops = &rk808_switch_ops,
-               .type = REGULATOR_VOLTAGE,
-               .enable_reg = RK808_DCDC_EN_REG,
-               .enable_mask = BIT(6),
-               .owner = THIS_MODULE,
        },
-};
-
-static struct of_regulator_match rk808_reg_matches[] = {
-       [RK808_ID_DCDC1]        = { .name = "DCDC_REG1" },
-       [RK808_ID_DCDC2]        = { .name = "DCDC_REG2" },
-       [RK808_ID_DCDC3]        = { .name = "DCDC_REG3" },
-       [RK808_ID_DCDC4]        = { .name = "DCDC_REG4" },
-       [RK808_ID_LDO1]         = { .name = "LDO_REG1" },
-       [RK808_ID_LDO2]         = { .name = "LDO_REG2" },
-       [RK808_ID_LDO3]         = { .name = "LDO_REG3" },
-       [RK808_ID_LDO4]         = { .name = "LDO_REG4" },
-       [RK808_ID_LDO5]         = { .name = "LDO_REG5" },
-       [RK808_ID_LDO6]         = { .name = "LDO_REG6" },
-       [RK808_ID_LDO7]         = { .name = "LDO_REG7" },
-       [RK808_ID_LDO8]         = { .name = "LDO_REG8" },
-       [RK808_ID_SWITCH1]      = { .name = "SWITCH_REG1" },
-       [RK808_ID_SWITCH2]      = { .name = "SWITCH_REG2" },
+       RK8XX_DESC(RK818_ID_LDO4, "LDO_REG4", "vcc8", 1800, 3400, 100,
+               RK818_LDO4_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
+               BIT(3), 400),
+       RK8XX_DESC(RK818_ID_LDO5, "LDO_REG5", "vcc7", 1800, 3400, 100,
+               RK818_LDO5_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
+               BIT(4), 400),
+       RK8XX_DESC(RK818_ID_LDO6, "LDO_REG6", "vcc8", 800, 2500, 100,
+               RK818_LDO6_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
+               BIT(5), 400),
+       RK8XX_DESC(RK818_ID_LDO7, "LDO_REG7", "vcc7", 800, 2500, 100,
+               RK818_LDO7_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
+               BIT(6), 400),
+       RK8XX_DESC(RK818_ID_LDO8, "LDO_REG8", "vcc8", 1800, 3400, 100,
+               RK818_LDO8_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
+               BIT(7), 400),
+       RK8XX_DESC(RK818_ID_LDO9, "LDO_REG9", "vcc9", 1800, 3400, 100,
+               RK818_BOOST_LDO9_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+               RK818_DCDC_EN_REG, BIT(5), 400),
+       RK8XX_DESC_SWITCH(RK818_ID_SWITCH, "SWITCH_REG", "vcc9",
+               RK818_DCDC_EN_REG, BIT(6)),
+       RK8XX_DESC_SWITCH(RK818_ID_HDMI_SWITCH, "HDMI_SWITCH", "h_5v",
+               RK818_H5V_EN_REG, BIT(0)),
+       RK8XX_DESC_SWITCH(RK818_ID_OTG_SWITCH, "OTG_SWITCH", "usb",
+               RK818_DCDC_EN_REG, BIT(7)),
 };
 
 static int rk808_regulator_dt_parse_pdata(struct device *dev,
@@ -529,17 +571,12 @@ static int rk808_regulator_dt_parse_pdata(struct device *dev,
                                   struct rk808_regulator_data *pdata)
 {
        struct device_node *np;
-       int tmp, ret, i;
+       int tmp, ret = 0, i;
 
        np = of_get_child_by_name(client_dev->of_node, "regulators");
        if (!np)
                return -ENXIO;
 
-       ret = of_regulator_match(dev, np, rk808_reg_matches,
-                                RK808_NUM_REGULATORS);
-       if (ret < 0)
-               goto dt_parse_end;
-
        for (i = 0; i < ARRAY_SIZE(pdata->dvs_gpio); i++) {
                pdata->dvs_gpio[i] =
                        devm_gpiod_get_index_optional(client_dev, "dvs", i,
@@ -573,7 +610,8 @@ static int rk808_regulator_probe(struct platform_device *pdev)
        struct regulator_config config = {};
        struct regulator_dev *rk808_rdev;
        struct rk808_regulator_data *pdata;
-       int ret, i;
+       const struct regulator_desc *regulators;
+       int ret, i, nregulators;
 
        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
@@ -586,20 +624,29 @@ static int rk808_regulator_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, pdata);
 
-       /* Instantiate the regulators */
-       for (i = 0; i < RK808_NUM_REGULATORS; i++) {
-               if (!rk808_reg_matches[i].init_data ||
-                   !rk808_reg_matches[i].of_node)
-                       continue;
+       switch (rk808->variant) {
+       case RK808_ID:
+               regulators = rk808_reg;
+               nregulators = RK808_NUM_REGULATORS;
+               break;
+       case RK818_ID:
+               regulators = rk818_reg;
+               nregulators = RK818_NUM_REGULATORS;
+               break;
+       default:
+               dev_err(&client->dev, "unsupported RK8XX ID %lu\n",
+                       rk808->variant);
+               return -EINVAL;
+       }
 
-               config.dev = &client->dev;
-               config.driver_data = pdata;
-               config.regmap = rk808->regmap;
-               config.of_node = rk808_reg_matches[i].of_node;
-               config.init_data = rk808_reg_matches[i].init_data;
+       config.dev = &client->dev;
+       config.driver_data = pdata;
+       config.regmap = rk808->regmap;
 
+       /* Instantiate the regulators */
+       for (i = 0; i < nregulators; i++) {
                rk808_rdev = devm_regulator_register(&pdev->dev,
-                                                    &rk808_reg[i], &config);
+                                                    &regulators[i], &config);
                if (IS_ERR(rk808_rdev)) {
                        dev_err(&client->dev,
                                "failed to register %d regulator\n", i);
@@ -613,15 +660,15 @@ static int rk808_regulator_probe(struct platform_device *pdev)
 static struct platform_driver rk808_regulator_driver = {
        .probe = rk808_regulator_probe,
        .driver = {
-               .name = "rk808-regulator",
-               .owner = THIS_MODULE,
+               .name = "rk808-regulator"
        },
 };
 
 module_platform_driver(rk808_regulator_driver);
 
-MODULE_DESCRIPTION("regulator driver for the rk808 series PMICs");
-MODULE_AUTHOR("Chris Zhong<zyw@rock-chips.com>");
-MODULE_AUTHOR("Zhang Qing<zhangqing@rock-chips.com>");
+MODULE_DESCRIPTION("regulator driver for the RK808/RK818 series PMICs");
+MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
+MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
+MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:rk808-regulator");