mfd: rk808: add rk816 support
authorshengfei Xu <xsf@rock-chips.com>
Fri, 7 Jul 2017 09:18:10 +0000 (17:18 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 19 Jul 2017 06:33:51 +0000 (14:33 +0800)
include sub modules: regulator, rtc, gpio, pwrkey

Change-Id: I59cc4b943403f1e0b1210a314cfcbf61fc193bdf
Signed-off-by: shengfei Xu <xsf@rock-chips.com>
Documentation/devicetree/bindings/mfd/rk816.txt [new file with mode: 0644]
drivers/clk/Kconfig
drivers/gpio/gpio-rk8xx.c
drivers/mfd/rk808.c
drivers/regulator/Kconfig
drivers/regulator/rk808-regulator.c
drivers/rtc/Kconfig
include/linux/mfd/rk808.h

diff --git a/Documentation/devicetree/bindings/mfd/rk816.txt b/Documentation/devicetree/bindings/mfd/rk816.txt
new file mode 100644 (file)
index 0000000..75b1ecf
--- /dev/null
@@ -0,0 +1,217 @@
+RK816 Power Management Integrated Circuit
+
+Required properties:
+- compatible: "rockchip,rk816"
+- reg: I2C slave address
+- interrupt-parent: The parent interrupt controller.
+- interrupts: the interrupt outputs of the controller.
+- #clock-cells: from common clock binding; shall be set to 1 (multiple clock
+  outputs).
+
+Optional properties:
+- clock-output-names: From common clock binding to override the
+  default output clock name
+- rockchip,system-power-controller: Telling whether or not this pmic is controlling
+  the system power.
+- gpio-controller: Specifies that the node is a gpio controller when you attempt to
+  use the TS pin of RK816 by GPIO general interface.
+- #gpio-cells: Should be two. The first cell is the GPIO number and the second cell
+  is used to specify the GPIO polarity.
+- wakeup-source: Flag to indicate this device can wake system (suspend/resume)
+- vcc1-supply:  The input supply for DCDC_REG1
+- vcc2-supply:  The input supply for DCDC_REG2
+- vcc3-supply:  The input supply for DCDC_REG3
+- vcc4-supply:  The input supply for DCDC_REG4
+- vcc5-supply:  The input supply for LDO_REG1, LDO_REG2, LDO_REG3
+- vcc6-supply:  The input supply for LDO_REG4, LDO_REG5, LDO_REG6
+
+Regulators: All the regulators of RK816 to be instantiated shall be
+listed in a child node named 'regulators'. Each regulator is represented
+by a child node of the 'regulators' node.
+
+       regulator-name {
+               /* standard regulator bindings here */
+       };
+
+Following regulators of the RK816 PMIC block are supported. Note that
+the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
+number as described in RK816 datasheet.
+
+       - DCDC_REGn
+               - valid values for n are 1 to 4.
+       - LDO_REGn
+               - valid values for n are 1 to 6.
+
+Standard regulator bindings are used inside regulator subnodes. Check
+  Documentation/devicetree/bindings/regulator/regulator.txt
+for more details
+
+Gpio, Rtc, Pwrkey: the node are represented like below. When you attempt to enable
+  the module, setting the "status" to be "okay", otherwise "disabled".
+
+               rtc {
+                       status = "okay";
+               };
+
+               pwrkey {
+                       status = "okay";
+               };
+
+               gpio {
+                       status = "okay";
+               };
+
+Example:
+       rk816: pmic@1a {
+               compatible = "rockchip,rk816";
+               status = "disabled";
+               reg = <0x1a>;
+               clock-output-names = "xin32k", "wifibt_32kin";
+               interrupt-parent = <&gpio0>;
+               interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_int>;
+               rockchip,system-power-controller;
+               wakeup-source;
+               #clock-cells = <1>;
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               vcc1-supply = <&vcc_sys>;
+               vcc2-supply = <&vcc_sys>;
+               vcc3-supply = <&vcc_sys>;
+               vcc4-supply = <&vcc_sys>;
+               vcc5-supply = <&vcc_sys>;
+               vcc6-supply = <&vcc_sys>;
+
+               rtc {
+                       status = "okay";
+               };
+
+               pwrkey {
+                       status = "okay";
+               };
+
+               gpio {
+                       status = "okay";
+               };
+
+               regulators {
+                       vdd_cpu: DCDC_REG1 {
+                               regulator-name = "vdd_logic";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <1450000>;
+                               regulator-ramp-delay = <6001>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+                       vdd_gpu: DCDC_REG2 {
+                               regulator-name = "vdd_gpu";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1250000>;
+                               regulator-ramp-delay = <6001>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1000000>;
+                               };
+                       };
+
+                       vcc_ddr: DCDC_REG3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-name = "vcc_ddr";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc33_io: DCDC_REG4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc33_io";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vccio_pmu: LDO_REG1 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vccio_pmu";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vcc_tp: LDO_REG2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc_tp";
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_10: LDO_REG3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-name = "vdd_10";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1000000>;
+                               };
+                       };
+
+                       vcc18_lcd: LDO_REG4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc18_lcd";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vccio_sd: LDO_REG5 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vccio_sd";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vdd10_lcd: LDO_REG6 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-name = "vdd10_lcd";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1000000>;
+                               };
+                       };
+
+               };
+       };
index c3e3a02f7f1f9b288ac93a524db3615f6abb72ae..56698bd7cf772770689e38a25333ab52df980f92 100644 (file)
@@ -52,10 +52,10 @@ config COMMON_CLK_MAX77802
          This driver supports Maxim 77802 crystal oscillator clock.
 
 config COMMON_CLK_RK808
-       tristate "Clock driver for RK808"
+       tristate "Clock driver for RK808/RK816"
        depends on MFD_RK808
        ---help---
-         This driver supports RK808 crystal oscillator clock. These
+         This driver supports RK808/RK816 crystal oscillator clock. These
          multi-function devices have two fixed-rate oscillators,
          clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
          by control register.
index 6adc8d408c4a0a65cfd17eeebfd22709a97aa637..67577d21baab7922cd91207c7846f09f0647dddb 100644 (file)
 #define RK805_OUT0_VALMASK     BIT(0)
 #define RK805_OUT1_VALMASK     BIT(1)
 
+#define RK816_FUN_MASK         BIT(2)
+#define RK816_OUT_VALMASK      BIT(3)
+#define RK816_DIR_MASK         BIT(4)
+
 struct rk8xx_gpio_reg {
        u8 reg;
        u8 dir_msk;
@@ -174,6 +178,15 @@ static struct rk8xx_gpio_reg rk805_gpio_reg[] = {
        },
 };
 
+static struct rk8xx_gpio_reg rk816_gpio_reg[] = {
+       {
+               .reg = RK816_GPIO_IO_POL_REG,
+               .dir_msk = RK816_DIR_MASK,
+               .val_msk = RK816_OUT_VALMASK,
+               .fun_msk = RK816_FUN_MASK,
+       },
+};
+
 static int rk8xx_gpio_probe(struct platform_device *pdev)
 {
        struct rk808 *rk8xx = dev_get_drvdata(pdev->dev.parent);
@@ -198,6 +211,10 @@ static int rk8xx_gpio_probe(struct platform_device *pdev)
                gi->gpio_reg = rk805_gpio_reg;
                gi->gpio_nr = ARRAY_SIZE(rk805_gpio_reg);
                break;
+       case RK816_ID:
+               gi->gpio_reg = rk816_gpio_reg;
+               gi->gpio_nr = ARRAY_SIZE(rk816_gpio_reg);
+               break;
        default:
                dev_err(&pdev->dev, "unsupported RK8XX ID %lu\n",
                        rk8xx->variant);
index 4905291724f71a5ae411ddd6cf24a1273fe09bd2..dadecc76e48e5c700a455fd388eefd3eb1c809d9 100644 (file)
@@ -69,6 +69,16 @@ static int rk808_shutdown(struct regmap *regmap)
        return ret;
 }
 
+static int rk816_shutdown(struct regmap *regmap)
+{
+       int ret;
+
+       ret = regmap_update_bits(regmap,
+                                RK816_DEV_CTRL_REG,
+                                DEV_OFF, DEV_OFF);
+       return ret;
+}
+
 static int rk818_shutdown(struct regmap *regmap)
 {
        int ret;
@@ -146,6 +156,22 @@ static const struct regmap_config rk805_regmap_config = {
        .volatile_reg = rk808_is_volatile_reg,
 };
 
+static const struct regmap_config rk816_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = RK816_DATA18_REG,
+       .cache_type = REGCACHE_RBTREE,
+       .volatile_reg = rk818_is_volatile_reg,
+};
+
+static const struct regmap_config rk818_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = RK818_SAVE_DATA19,
+       .cache_type = REGCACHE_RBTREE,
+       .volatile_reg = rk818_is_volatile_reg,
+};
+
 static struct resource rtc_resources[] = {
        {
                .start  = RK808_IRQ_RTC_ALARM,
@@ -167,6 +193,19 @@ static struct resource pwrkey_resources[] = {
        },
 };
 
+static struct resource rk816_pwrkey_resources[] = {
+       {
+               .start  = RK816_IRQ_PWRON_RISE,
+               .end    = RK816_IRQ_PWRON_RISE,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = RK816_IRQ_PWRON_FALL,
+               .end    = RK816_IRQ_PWRON_FALL,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
 static const struct mfd_cell rk808s[] = {
        { .name = "rk808-clkout", },
        { .name = "rk808-regulator", },
@@ -243,12 +282,96 @@ static struct regmap_irq_chip rk808_irq_chip = {
        .init_ack_masked = true,
 };
 
-static const struct regmap_config rk818_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-       .max_register = RK818_SAVE_DATA19,
-       .cache_type = REGCACHE_RBTREE,
-       .volatile_reg = rk818_is_volatile_reg,
+static const struct mfd_cell rk816s[] = {
+       { .name = "rk808-clkout", },
+       { .name = "rk808-regulator", },
+       { .name = "rk8xx-gpio", },
+       {
+               .name = "rk8xx-pwrkey",
+               .num_resources = ARRAY_SIZE(rk816_pwrkey_resources),
+               .resources = &rk816_pwrkey_resources[0],
+       },
+       {
+               .name = "rk808-rtc",
+               .num_resources = ARRAY_SIZE(rtc_resources),
+               .resources = &rtc_resources[0],
+       },
+};
+
+static const struct rk808_reg_data rk816_pre_init_reg[] = {
+       /* buck4 Max ILMIT*/
+       {RK816_BUCK4_CONFIG_REG, BUCK4_MAX_ILIMIT, REG_WRITE_MSK},
+       /* hotdie temperature: 105c*/
+       {RK816_THERMAL_REG, TEMP105C, REG_WRITE_MSK},
+       /* set buck 12.5mv/us */
+       {RK816_BUCK1_CONFIG_REG, BUCK_RATE_12_5MV_US, BUCK_RATE_MSK},
+       {RK816_BUCK2_CONFIG_REG, BUCK_RATE_12_5MV_US, BUCK_RATE_MSK},
+       /* enable RTC_PERIOD & RTC_ALARM int */
+       {RK816_INT_STS_MSK_REG2, RTC_PERIOD_ALARM_INT_EN, REG_WRITE_MSK},
+       /* set bat 3.0 low and act shutdown */
+       {RK816_VB_MON_REG, RK816_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN,
+       VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK},
+       /* enable PWRON rising/faling int */
+       {RK816_INT_STS_MSK_REG1, RK816_PWRON_FALL_RISE_INT_EN, REG_WRITE_MSK},
+       /* enable PLUG IN/OUT int */
+       {RK816_INT_STS_MSK_REG3, PLUGIN_OUT_INT_EN, REG_WRITE_MSK},
+       /* clear int flags */
+       {RK816_INT_STS_REG1, ALL_INT_FLAGS_ST, REG_WRITE_MSK},
+       {RK816_INT_STS_REG2, ALL_INT_FLAGS_ST, REG_WRITE_MSK},
+       {RK816_INT_STS_REG3, ALL_INT_FLAGS_ST, REG_WRITE_MSK},
+       {RK816_DCDC_EN_REG2, BOOST_DISABLE, BOOST_EN_MASK},
+};
+
+static const struct regmap_irq rk816_irqs[] = {
+       /* INT_STS */
+       [RK816_IRQ_PWRON_FALL] = {
+               .mask = RK816_IRQ_PWRON_FALL_MSK,
+               .reg_offset = 0,
+       },
+       [RK816_IRQ_PWRON_RISE] = {
+               .mask = RK816_IRQ_PWRON_RISE_MSK,
+               .reg_offset = 0,
+       },
+       [RK816_IRQ_VB_LOW] = {
+               .mask = RK816_IRQ_VB_LOW_MSK,
+               .reg_offset = 1,
+       },
+       [RK816_IRQ_PWRON] = {
+               .mask = RK816_IRQ_PWRON_MSK,
+               .reg_offset = 1,
+       },
+       [RK816_IRQ_PWRON_LP] = {
+               .mask = RK816_IRQ_PWRON_LP_MSK,
+               .reg_offset = 1,
+       },
+       [RK816_IRQ_HOTDIE] = {
+               .mask = RK816_IRQ_HOTDIE_MSK,
+               .reg_offset = 1,
+       },
+       [RK816_IRQ_RTC_ALARM] = {
+               .mask = RK816_IRQ_RTC_ALARM_MSK,
+               .reg_offset = 1,
+       },
+       [RK816_IRQ_RTC_PERIOD] = {
+               .mask = RK816_IRQ_RTC_PERIOD_MSK,
+               .reg_offset = 1,
+       },
+       [RK816_IRQ_USB_OV] = {
+               .mask = RK816_IRQ_USB_OV_MSK,
+               .reg_offset = 1,
+       },
+};
+
+static struct regmap_irq_chip rk816_irq_chip = {
+       .name = "rk816",
+       .irqs = rk816_irqs,
+       .num_irqs = ARRAY_SIZE(rk816_irqs),
+       .num_regs = 2,
+       .irq_reg_stride = 3,
+       .status_base = RK816_INT_STS_REG1,
+       .mask_base = RK816_INT_STS_MSK_REG1,
+       .ack_base = RK816_INT_STS_REG1,
+       .init_ack_masked = true,
 };
 
 static const struct mfd_cell rk818s[] = {
@@ -522,6 +645,7 @@ static struct device_attribute rk8xx_attrs =
 static const struct of_device_id rk808_of_match[] = {
        { .compatible = "rockchip,rk805" },
        { .compatible = "rockchip,rk808" },
+       { .compatible = "rockchip,rk816" },
        { .compatible = "rockchip,rk818" },
        { },
 };
@@ -584,6 +708,17 @@ static int rk808_probe(struct i2c_client *client,
                on_source = RK818_ON_SOURCE_REG;
                off_source = RK818_OFF_SOURCE_REG;
                break;
+       case RK816_ID:
+               cell = rk816s;
+               cell_num = ARRAY_SIZE(rk816s);
+               pre_init_reg = rk816_pre_init_reg;
+               reg_num = ARRAY_SIZE(rk816_pre_init_reg);
+               regmap_config = &rk816_regmap_config;
+               irq_chip = &rk816_irq_chip;
+               pm_shutdown_fn = rk816_shutdown;
+               on_source = RK816_ON_SOURCE_REG;
+               off_source = RK816_OFF_SOURCE_REG;
+               break;
        case RK808_ID:
                cell = rk808s;
                cell_num = ARRAY_SIZE(rk808s);
@@ -711,6 +846,7 @@ static int rk808_remove(struct i2c_client *client)
 static const struct i2c_device_id rk808_ids[] = {
        { "rk805" },
        { "rk808" },
+       { "rk816" },
        { "rk818" },
        { },
 };
index f9dde4d26ea234a298c7728bbb7c38b38dbb1e01..bc24890f718487439660bacba3fa02e66acdb727 100644 (file)
@@ -574,11 +574,11 @@ config REGULATOR_RC5T583
          outputs which can be controlled by i2c communication.
 
 config REGULATOR_RK808
-       tristate "Rockchip RK808/RK818 Power regulators"
+       tristate "Rockchip RK808/RK816/RK818 Power regulators"
        depends on MFD_RK808
        help
          Select this option to enable the power regulator of ROCKCHIP
-         PMIC RK808 and RK818.
+         PMIC RK808/RK816/RK818.
          This driver supports the control of different power rails of device
          through regulator interface. The device supports multiple DCDC/LDO
          outputs which can be controlled by i2c communication.
index a16d81420612e485e2a96e1fe679d3c3b13d7d31..92c274217a1d9aadcae38d126f5945f70e7b0988 100644 (file)
 #define RK808_BUCK4_VSEL_MASK  0xf
 #define RK808_LDO_VSEL_MASK    0x1f
 
+#define RK816_DCDC_SLP_EN_REG_OFFSET   2
+#define RK816_SWITCH_SLP_EN_REG_OFFSET 1
+#define RK816_LDO1_4_SLP_EN_REG_OFFSET 1
+#define RK816_LDO5_6_SLP_EN_REG_OFFSET 2
+
 #define RK818_BUCK_VSEL_MASK           0x3f
 #define RK818_BUCK4_VSEL_MASK          0x1f
 #define RK818_LDO_VSEL_MASK            0x1f
                .ops            = &rk808_reg_ops,                       \
        }
 
+#define RK816_DESC(_id, _match, _supply, _min, _max, _step, _vreg,     \
+       _vmask, _ereg, _emask, _disval, _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),                             \
+               .disable_val     = (_disval),                           \
+               .enable_time    = (_etime),                             \
+               .ops            = &rk808_reg_ops,                       \
+       }
+
 #define RK8XX_DESC_SWITCH(_id, _match, _supply, _ereg, _emask)         \
        [_id] = {                                                       \
                .name           = (_match),                             \
@@ -117,6 +144,17 @@ static const struct regulator_linear_range rk808_ldo3_voltage_ranges[] = {
        REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0),
 };
 
+static const struct regulator_linear_range rk816_buck_voltage_ranges[] = {
+       REGULATOR_LINEAR_RANGE(712500, 0, 59, 12500),   /* 0.7125v - 1.45v */
+       REGULATOR_LINEAR_RANGE(1800000, 60, 62, 200000),/* 1.8v - 2.2v */
+       REGULATOR_LINEAR_RANGE(2300000, 63, 63, 0),     /* 2.3v - 2.3v */
+};
+
+static const struct regulator_linear_range rk816_buck4_voltage_ranges[] = {
+       REGULATOR_LINEAR_RANGE(800000, 0, 26, 100000),  /* 0.8v - 3.4 */
+       REGULATOR_LINEAR_RANGE(3500000, 27, 31, 0),     /* 3.5v */
+};
+
 static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev)
 {
        struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
@@ -298,9 +336,72 @@ static int rk808_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
                                  sel);
 }
 
+static int rk816_set_suspend_enable(struct regulator_dev *rdev)
+{
+       unsigned int reg, val;
+
+       if (rdev->desc->id <= RK816_ID_DCDC4)
+               reg = rdev->desc->enable_reg +
+                       RK816_DCDC_SLP_EN_REG_OFFSET;
+
+       if ((rdev->desc->id > RK816_ID_DCDC4) &&
+           (rdev->desc->id <= RK816_ID_OTG_SWITCH))
+               reg = rdev->desc->enable_reg +
+                       RK816_SWITCH_SLP_EN_REG_OFFSET;
+
+       if ((rdev->desc->id > RK816_ID_OTG_SWITCH) &&
+           (rdev->desc->id <= RK816_ID_LDO4))
+               reg = rdev->desc->enable_reg -
+                       RK816_LDO1_4_SLP_EN_REG_OFFSET;
+
+       if ((rdev->desc->id > RK816_ID_LDO4) &&
+           (rdev->desc->id <= RK816_ID_LDO6))
+               reg = rdev->desc->enable_reg -
+                       RK816_LDO5_6_SLP_EN_REG_OFFSET;
+
+       val = 1 << (rdev->desc->id % 8);
+       return regmap_update_bits(rdev->regmap, reg,
+                                 val,
+                                 0);
+}
+
+static int rk816_set_suspend_disable(struct regulator_dev *rdev)
+{
+       unsigned int reg, val;
+
+       if (rdev->desc->id <= RK816_ID_DCDC4)
+               reg = rdev->desc->enable_reg +
+                       RK816_DCDC_SLP_EN_REG_OFFSET;
+
+       if ((rdev->desc->id > RK816_ID_DCDC4) &&
+           (rdev->desc->id <= RK816_ID_OTG_SWITCH))
+               reg = rdev->desc->enable_reg +
+                       RK816_SWITCH_SLP_EN_REG_OFFSET;
+
+       if ((rdev->desc->id > RK816_ID_OTG_SWITCH) &&
+           (rdev->desc->id <= RK816_ID_LDO4))
+               reg = rdev->desc->enable_reg -
+                       RK816_LDO1_4_SLP_EN_REG_OFFSET;
+
+       if ((rdev->desc->id > RK816_ID_LDO4) &&
+           (rdev->desc->id <= RK816_ID_LDO6))
+               reg = rdev->desc->enable_reg -
+                       RK816_LDO5_6_SLP_EN_REG_OFFSET;
+
+       val = 1 << (rdev->desc->id % 8);
+
+       return regmap_update_bits(rdev->regmap, reg,
+                                 val,
+                                 val);
+}
+
 static int rk808_set_suspend_enable(struct regulator_dev *rdev)
 {
        unsigned int reg;
+       struct rk808 *rk808 = dev_get_drvdata(rdev->dev.parent);
+
+       if (rk808->variant == RK816_ID)
+               return rk816_set_suspend_enable(rdev);
 
        reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
 
@@ -312,6 +413,10 @@ static int rk808_set_suspend_enable(struct regulator_dev *rdev)
 static int rk808_set_suspend_disable(struct regulator_dev *rdev)
 {
        unsigned int reg;
+       struct rk808 *rk808 = dev_get_drvdata(rdev->dev.parent);
+
+       if (rk808->variant == RK816_ID)
+               return rk816_set_suspend_disable(rdev);
 
        reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
 
@@ -463,6 +568,109 @@ static const struct regulator_desc rk808_reg[] = {
                RK808_DCDC_EN_REG, BIT(6)),
 };
 
+static const struct regulator_desc rk816_reg[] = {
+       {
+               .name = "DCDC_REG1",
+               .supply_name = "vcc1",
+               .of_match = of_match_ptr("DCDC_REG1"),
+               .regulators_node = of_match_ptr("regulators"),
+               .id = RK816_ID_DCDC1,
+               .ops = &rk808_reg_ops,
+               .type = REGULATOR_VOLTAGE,
+               .n_voltages = 64,
+               .linear_ranges = rk816_buck_voltage_ranges,
+               .n_linear_ranges = ARRAY_SIZE(rk816_buck_voltage_ranges),
+               .vsel_reg = RK816_BUCK1_ON_VSEL_REG,
+               .vsel_mask = RK818_BUCK_VSEL_MASK,
+               .enable_reg = RK816_DCDC_EN_REG1,
+               .enable_mask = BIT(4) | BIT(0),
+               .disable_val = BIT(4),
+               .owner = THIS_MODULE,
+       }, {
+               .name = "DCDC_REG2",
+               .supply_name = "vcc2",
+               .of_match = of_match_ptr("DCDC_REG2"),
+               .regulators_node = of_match_ptr("regulators"),
+               .id = RK816_ID_DCDC2,
+               .ops = &rk808_reg_ops,
+               .type = REGULATOR_VOLTAGE,
+               .n_voltages = 64,
+               .linear_ranges = rk816_buck_voltage_ranges,
+               .n_linear_ranges = ARRAY_SIZE(rk816_buck_voltage_ranges),
+               .vsel_reg = RK816_BUCK2_ON_VSEL_REG,
+               .vsel_mask = RK818_BUCK_VSEL_MASK,
+               .enable_reg = RK816_DCDC_EN_REG1,
+               .enable_mask = BIT(5) | BIT(1),
+               .disable_val = BIT(5),
+               .owner = THIS_MODULE,
+       }, {
+               .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 = 1,
+               .enable_reg = RK816_DCDC_EN_REG1,
+               .enable_mask = BIT(6) | BIT(2),
+               .disable_val = BIT(6),
+               .owner = THIS_MODULE,
+       }, {
+               .name = "DCDC_REG4",
+               .supply_name = "vcc4",
+               .of_match = of_match_ptr("DCDC_REG4"),
+               .regulators_node = of_match_ptr("regulators"),
+               .id = RK816_ID_DCDC4,
+               .ops = &rk808_reg_ops,
+               .type = REGULATOR_VOLTAGE,
+               .n_voltages = 32,
+               .linear_ranges = rk816_buck4_voltage_ranges,
+               .n_linear_ranges = ARRAY_SIZE(rk816_buck4_voltage_ranges),
+               .vsel_reg = RK816_BUCK4_ON_VSEL_REG,
+               .vsel_mask = RK818_BUCK4_VSEL_MASK,
+               .enable_reg = RK816_DCDC_EN_REG1,
+               .enable_mask = BIT(7) | BIT(3),
+               .disable_val = BIT(7),
+               .owner = THIS_MODULE,
+       },
+       RK816_DESC(RK816_ID_BOOST, "DCDC_BOOST", "boost", 4700, 5400, 100,
+                  RK816_BOOST_ON_VESL_REG, RK818_BOOST_ON_VSEL_MASK,
+                  RK816_DCDC_EN_REG2, BIT(4) | BIT(0), BIT(4), 0),
+       {
+               .name = "OTG_SWITCH",
+               .supply_name = "usb",
+               .of_match = of_match_ptr("OTG_SWITCH"),
+               .regulators_node = of_match_ptr("regulators"),
+               .id = RK816_ID_OTG_SWITCH,
+               .ops = &rk808_switch_ops,
+               .type = REGULATOR_VOLTAGE,
+               .n_voltages = 1,
+               .enable_reg = RK816_DCDC_EN_REG2,
+               .enable_mask = BIT(6) | BIT(2),
+               .disable_val = BIT(6),
+               .owner = THIS_MODULE,
+       },
+       RK816_DESC(RK816_ID_LDO1, "LDO_REG1", "vcc5", 800, 3400, 100,
+                  RK816_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+                  RK816_LDO_EN_REG1, BIT(4) | BIT(0), BIT(4), 400),
+       RK816_DESC(RK816_ID_LDO2, "LDO_REG2", "vcc5", 800, 3400, 100,
+                  RK816_LDO2_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+                  RK816_LDO_EN_REG1, BIT(5) | BIT(1), BIT(5), 400),
+       RK816_DESC(RK816_ID_LDO3, "LDO_REG2", "vcc5", 800, 3400, 100,
+                  RK816_LDO3_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+                  RK816_LDO_EN_REG1, BIT(6) | BIT(2), BIT(6), 400),
+       RK816_DESC(RK816_ID_LDO4, "LDO_REG4", "vcc6", 800, 3400, 100,
+                  RK816_LDO4_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+                  RK816_LDO_EN_REG1, BIT(7) | BIT(3), BIT(7), 400),
+       RK816_DESC(RK816_ID_LDO5, "LDO_REG5", "vcc6", 800, 3400, 100,
+                  RK816_LDO5_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+                  RK816_LDO_EN_REG2, BIT(4) | BIT(0), BIT(4), 400),
+       RK816_DESC(RK816_ID_LDO6, "LDO_REG6", "vcc6", 800, 3400, 100,
+                  RK816_LDO6_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+                  RK816_LDO_EN_REG2, BIT(5) | BIT(1), BIT(5), 400),
+};
+
 static const struct regulator_desc rk818_reg[] = {
        {
                .name = "DCDC_REG1",
@@ -633,6 +841,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
                regulators = rk818_reg;
                nregulators = RK818_NUM_REGULATORS;
                break;
+       case RK816_ID:
+               regulators = rk816_reg;
+               nregulators = RK816_NUM_REGULATORS;
+               break;
        default:
                dev_err(&client->dev, "unsupported RK8XX ID %lu\n",
                        rk808->variant);
@@ -666,7 +878,7 @@ static struct platform_driver rk808_regulator_driver = {
 
 module_platform_driver(rk808_regulator_driver);
 
-MODULE_DESCRIPTION("regulator driver for the RK808/RK818 series PMICs");
+MODULE_DESCRIPTION("regulator driver for the RK808/RK816/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>");
index 2a524244afec1d563f18cb8ccfb1b694c5ceb52e..87e06adce2b926ea411a1b12c2a0a385bee37ce3 100644 (file)
@@ -326,11 +326,11 @@ config RTC_DRV_MAX77686
          will be called rtc-max77686.
 
 config RTC_DRV_RK808
-       tristate "Rockchip RK808 RTC"
+       tristate "Rockchip RK808/RK816 RTC"
        depends on MFD_RK808
        help
          If you say yes here you will get support for the
-         RTC of RK808 PMIC.
+         RTC of RK808/RK816 PMIC.
 
          This driver can also be built as a module. If so, the module
          will be called rk808-rtc.
index d8f766135867b3c73e7dc5a5b149c48dcf5b702e..20d24c07996126bdbaa6e10a00fb796baee19245 100644 (file)
@@ -47,6 +47,21 @@ enum rk808_reg {
        RK808_ID_SWITCH2,
 };
 
+enum rk816_reg {
+       RK816_ID_DCDC1,
+       RK816_ID_DCDC2,
+       RK816_ID_DCDC3,
+       RK816_ID_DCDC4,
+       RK816_ID_BOOST = 5,
+       RK816_ID_OTG_SWITCH,
+       RK816_ID_LDO1 = 8,
+       RK816_ID_LDO2,
+       RK816_ID_LDO3,
+       RK816_ID_LDO4,
+       RK816_ID_LDO5,
+       RK816_ID_LDO6,
+};
+
 enum rk818_reg {
        RK818_ID_DCDC1,
        RK818_ID_DCDC2,
@@ -530,6 +545,145 @@ enum rk805_reg {
 #define RK805_PWRON_FALL_RISE_INT_EN   0x0
 #define RK805_PWRON_FALL_RISE_INT_MSK  0x81
 
+/*VERSION REGISTER*/
+#define RK816_CHIP_NAME_REG                    0x17
+#define RK816_CHIP_VER_REG                     0x18
+#define RK816_OTP_VER_REG                      0x19
+#define RK816_NUM_REGULATORS                   12
+
+/*POWER ON/OFF REGISTER*/
+#define RK816_VB_MON_REG                       0x21
+#define RK816_THERMAL_REG                      0x22
+#define RK816_PWRON_LP_INT_TIME_REG            0x47
+#define RK816_PWRON_DB_REG                     0x48
+#define RK816_DEV_CTRL_REG                     0x4B
+#define RK816_ON_SOURCE_REG                    0xAE
+#define RK816_OFF_SOURCE_REG                   0xAF
+
+/*POWER CHANNELS ENABLE REGISTER*/
+#define RK816_DCDC_EN_REG1                     0x23
+#define RK816_DCDC_EN_REG2                     0x24
+#define RK816_SLP_DCDC_EN_REG                  0x25
+#define RK816_SLP_LDO_EN_REG                   0x26
+#define RK816_LDO_EN_REG1                      0x27
+#define RK816_LDO_EN_REG2                      0x28
+
+/*BUCK AND LDO CONFIG REGISTER*/
+#define RK816_BUCK1_CONFIG_REG                 0x2E
+#define RK816_BUCK1_ON_VSEL_REG                        0x2F
+#define RK816_BUCK1_SLP_VSEL_REG               0x30
+#define RK816_BUCK2_CONFIG_REG                 0x32
+#define RK816_BUCK2_ON_VSEL_REG                        0x33
+#define RK816_BUCK2_SLP_VSEL_REG               0x34
+#define RK816_BUCK3_CONFIG_REG                 0x36
+#define RK816_BUCK4_CONFIG_REG                 0x37
+#define RK816_BUCK4_ON_VSEL_REG                        0x38
+#define RK816_BUCK4_SLP_VSEL_REG               0x39
+#define RK816_LDO1_ON_VSEL_REG                 0x3B
+#define RK816_LDO1_SLP_VSEL_REG                        0x3C
+#define RK816_LDO2_ON_VSEL_REG                 0x3D
+#define RK816_LDO2_SLP_VSEL_REG                        0x3E
+#define RK816_LDO3_ON_VSEL_REG                 0x3F
+#define RK816_LDO3_SLP_VSEL_REG                        0x40
+#define RK816_LDO4_ON_VSEL_REG                 0x41
+#define RK816_LDO4_SLP_VSEL_REG                        0x42
+#define RK816_LDO5_ON_VSEL_REG                 0x43
+#define RK816_LDO5_SLP_VSEL_REG                        0x44
+#define RK816_LDO6_ON_VSEL_REG                 0x45
+#define RK816_LDO6_SLP_VSEL_REG                        0x46
+
+/*CHARGER BOOST AND OTG REGISTER*/
+#define RK816_OTG_BUCK_LDO_CONFIG_REG           0x2A
+#define RK816_CHRG_CONFIG_REG                   0x2B
+#define RK816_BOOST_ON_VESL_REG                 0x54
+#define RK816_BOOST_SLP_VSEL_REG                0x55
+#define RK816_CHRG_BOOST_CONFIG_REG             0x9A
+#define RK816_SUP_STS_REG                       0xA0
+#define RK816_USB_CTRL_REG                      0xA1
+#define RK816_CHRG_CTRL_REG1                    0xA3
+#define RK816_CHRG_CTRL_REG2                    0xA4
+#define RK816_CHRG_CTRL_REG3                    0xA5
+#define RK816_BAT_CTRL_REG                      0xA6
+#define RK816_BAT_HTS_TS_REG                    0xA8
+#define RK816_BAT_LTS_TS_REG                    0xA9
+
+/*INTERRUPT REGISTER*/
+#define RK816_INT_STS_REG1                     0x49
+#define RK816_INT_STS_MSK_REG1                 0x4A
+#define RK816_INT_STS_REG2                     0x4C
+#define RK816_INT_STS_MSK_REG2                 0x4D
+#define RK816_INT_STS_REG3                     0x4E
+#define RK816_INT_STS_MSK_REG3                 0x4F
+#define RK816_GPIO_IO_POL_REG                  0x50
+
+#define RK816_DATA18_REG                       0xF2
+
+/* IRQ Definitions */
+#define RK816_IRQ_PWRON_FALL                   0
+#define RK816_IRQ_PWRON_RISE                   1
+#define RK816_IRQ_VB_LOW                       2
+#define RK816_IRQ_PWRON                                3
+#define RK816_IRQ_PWRON_LP                     4
+#define RK816_IRQ_HOTDIE                       5
+#define RK816_IRQ_RTC_ALARM                    6
+#define RK816_IRQ_RTC_PERIOD                   7
+#define RK816_IRQ_USB_OV                       8
+#define RK816_IRQ_PLUG_IN                      9
+#define RK816_IRQ_PLUG_OUT                     10
+#define RK816_IRQ_CHG_OK                       11
+#define RK816_IRQ_CHG_TE                       12
+#define RK816_IRQ_CHG_TS                       13
+#define RK816_IRQ_CHG_CVTLIM                   14
+#define RK816_IRQ_DISCHG_ILIM                  15
+
+#define RK816_IRQ_PWRON_FALL_MSK               BIT(5)
+#define RK816_IRQ_PWRON_RISE_MSK               BIT(6)
+#define RK816_IRQ_VB_LOW_MSK                   BIT(1)
+#define RK816_IRQ_PWRON_MSK                    BIT(2)
+#define RK816_IRQ_PWRON_LP_MSK                 BIT(3)
+#define RK816_IRQ_HOTDIE_MSK                   BIT(4)
+#define RK816_IRQ_RTC_ALARM_MSK                        BIT(5)
+#define RK816_IRQ_RTC_PERIOD_MSK               BIT(6)
+#define RK816_IRQ_USB_OV_MSK                   BIT(7)
+#define RK816_IRQ_PLUG_IN_MSK                  BIT(0)
+#define RK816_IRQ_PLUG_OUT_MSK                 BIT(1)
+#define RK816_IRQ_CHG_OK_MSK                   BIT(2)
+#define RK816_IRQ_CHG_TE_MSK                   BIT(3)
+#define RK816_IRQ_CHG_TS_MSK                   BIT(4)
+#define RK816_IRQ_CHG_CVTLIM_MSK               BIT(6)
+#define RK816_IRQ_DISCHG_ILIM_MSK              BIT(7)
+
+#define RK816_VBAT_LOW_2V8                     0x00
+#define RK816_VBAT_LOW_2V9                     0x01
+#define RK816_VBAT_LOW_3V0                     0x02
+#define RK816_VBAT_LOW_3V1                     0x03
+#define RK816_VBAT_LOW_3V2                     0x04
+#define RK816_VBAT_LOW_3V3                     0x05
+#define RK816_VBAT_LOW_3V4                     0x06
+#define RK816_VBAT_LOW_3V5                     0x07
+#define RK816_PWR_FALL_INT_STATUS              (0x1 << 5)
+#define RK816_PWR_RISE_INT_STATUS              (0x1 << 6)
+#define RK816_ALARM_INT_STATUS                 (0x1 << 5)
+#define EN_VBAT_LOW_IRQ                                (0x1 << 4)
+#define VBAT_LOW_ACT_MASK                      (0x1 << 4)
+#define RTC_TIMER_ALARM_INT_MSK                        (0x3 << 2)
+#define RTC_TIMER_ALARM_INT_DIS                        (0x0 << 2)
+#define RTC_PERIOD_ALARM_INT_MSK               (0x3 << 5)
+#define RTC_PERIOD_ALARM_INT_ST                        (0x3 << 5)
+#define RTC_PERIOD_ALARM_INT_DIS               (0x3 << 5)
+#define RTC_PERIOD_ALARM_INT_EN                        (0x9f)
+#define REG_WRITE_MSK                          0xff
+#define BUCK4_MAX_ILIMIT                       0x2c
+#define BUCK_RATE_MSK                          (0x3 << 3)
+#define BUCK_RATE_12_5MV_US                    (0x2 << 3)
+#define ALL_INT_FLAGS_ST                       0xff
+#define PLUGIN_OUT_INT_EN                      0xfc
+#define RK816_PWRON_FALL_RISE_INT_EN           0x9f
+#define BUCK1_2_IMAX_MAX                       (0x3 << 6)
+#define BUCK3_4_IMAX_MAX                       (0x3 << 3)
+#define BOOST_DISABLE                          ((0x1 << 5) | (0x0 << 1))
+
+#define TEMP105C                       0x08
 #define TEMP115C                       0x0c
 #define TEMP_HOTDIE_MSK                        0x0c
 #define SLP_SD_MSK                     (0x3 << 2)
@@ -570,6 +724,7 @@ struct rk808 {
 enum {
        RK805_ID = 0x8050,
        RK808_ID = 0x0000,
+       RK816_ID = 0x8160,
        RK818_ID = 0x8180,
 };