The RK805 chip is a Power Management IC (PMIC) for multimedia and handheld
devices. It contains the following components:
- Regulators
- RTC
- Clocking
Both RK808 and RK805 chips are using a similar register map,
so we can reuse the RTC and Clocking functionality.
Signed-off-by: Elaine Zhang <zhangqing@xxxxxxxxxxxxxx>
---
drivers/mfd/Kconfig | 4 +-
drivers/mfd/rk808.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 124 insertions(+), 2 deletions(-)
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 55ecdfb74d31..b410a348b756 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -892,13 +892,13 @@ config MFD_RC5T583
different functionality of the device.
config MFD_RK808
- tristate "Rockchip RK808/RK818 Power Management Chip"
+ tristate "Rockchip RK805/RK808/RK818 Power Management Chip"
depends on I2C && OF
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
help
- If you say yes here you get support for the RK808 and RK818
+ If you say yes here you get support for the RK805, RK808 and RK818
Power Management chips.
This driver provides common support for accessing the device
through I2C interface. The device supports multiple sub-devices
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 3334a2a7f3fb..fdd4449b14b0 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -70,6 +70,14 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
.volatile_reg = rk808_is_volatile_reg,
};
+static const struct regmap_config rk805_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = RK805_OFF_SOURCE_REG,
+ .cache_type = REGCACHE_RBTREE,
+ .volatile_reg = rk808_is_volatile_reg,
+};
+
static const struct regmap_config rk808_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@@ -86,6 +94,16 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
}
};
+static const struct mfd_cell rk805s[] = {
+ { .name = "rk808-clkout", },
+ { .name = "rk808-regulator", },
+ {
+ .name = "rk808-rtc",
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resources = &rtc_resources[0],
+ },
+};
+
static const struct mfd_cell rk808s[] = {
{ .name = "rk808-clkout", },
{ .name = "rk808-regulator", },
@@ -106,6 +124,20 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
},
};
+static const struct rk808_reg_data rk805_pre_init_reg[] = {
+ {RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
+ RK805_BUCK1_2_ILMAX_4000MA},
+ {RK805_BUCK2_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
+ RK805_BUCK1_2_ILMAX_4000MA},
+ {RK805_BUCK3_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
+ RK805_BUCK3_ILMAX_3000MA},
+ {RK805_BUCK4_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
+ RK805_BUCK4_ILMAX_3500MA},
+ {RK805_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_400MA},
+ {RK805_GPIO_IO_POL_REG, SLP_SD_MSK, SLEEP_FUN},
+ {RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
+};
+
static const struct rk808_reg_data rk808_pre_init_reg[] = {
{ RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_150MA },
{ RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_200MA },
@@ -135,6 +167,41 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
VB_LO_SEL_3500MV },
};
+static const struct regmap_irq rk805_irqs[] = {
+ [RK805_IRQ_PWRON_RISE] = {
+ .mask = RK805_IRQ_PWRON_RISE_MSK,
+ .reg_offset = 0,
+ },
+ [RK805_IRQ_VB_LOW] = {
+ .mask = RK805_IRQ_VB_LOW_MSK,
+ .reg_offset = 0,
+ },
+ [RK805_IRQ_PWRON] = {
+ .mask = RK805_IRQ_PWRON_MSK,
+ .reg_offset = 0,
+ },
+ [RK805_IRQ_PWRON_LP] = {
+ .mask = RK805_IRQ_PWRON_LP_MSK,
+ .reg_offset = 0,
+ },
+ [RK805_IRQ_HOTDIE] = {
+ .mask = RK805_IRQ_HOTDIE_MSK,
+ .reg_offset = 0,
+ },
+ [RK805_IRQ_RTC_ALARM] = {
+ .mask = RK805_IRQ_RTC_ALARM_MSK,
+ .reg_offset = 0,
+ },
+ [RK805_IRQ_RTC_PERIOD] = {
+ .mask = RK805_IRQ_RTC_PERIOD_MSK,
+ .reg_offset = 0,
+ },
+ [RK805_IRQ_PWRON_FALL] = {
+ .mask = RK805_IRQ_PWRON_FALL_MSK,
+ .reg_offset = 0,
+ },
+};
+
static const struct regmap_irq rk808_irqs[] = {
/* INT_STS */
[RK808_IRQ_VOUT_LO] = {
@@ -247,6 +314,17 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
},
};
+static struct regmap_irq_chip rk805_irq_chip = {
+ .name = "rk805",
+ .irqs = rk805_irqs,
+ .num_irqs = ARRAY_SIZE(rk805_irqs),
+ .num_regs = 1,
+ .status_base = RK805_INT_STS_REG,
+ .mask_base = RK805_INT_STS_MSK_REG,
+ .ack_base = RK805_INT_STS_REG,
+ .init_ack_masked = true,
+};
+
static const struct regmap_irq_chip rk808_irq_chip = {
.name = "rk808",
.irqs = rk808_irqs,
@@ -272,6 +350,38 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
};
static struct i2c_client *rk808_i2c_client;
+
+static void rk805_shutdown_prepare(void)
+{
+ int ret;
+ struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);