From 14ce427bb0816943410500d88efae2c5c7567e24 Mon Sep 17 00:00:00 2001 From: Joseph Chen Date: Sun, 28 Jul 2024 16:56:01 +0800 Subject: [PATCH] mfd: rk808: Add rk801 PMIC support PMIC RK801 consists of: - 4 x BUCK - 2 x LDO - 1 x SWITCH - 1 x Pwrkey Signed-off-by: Joseph Chen Change-Id: If65c2c3ac41cd6c6199e22c65c54e8600c113148 --- drivers/mfd/rk808.c | 164 ++++++++++++++++- drivers/regulator/rk808-regulator.c | 268 ++++++++++++++++++++++++++++ include/linux/mfd/rk808.h | 111 ++++++++++++ 3 files changed, 536 insertions(+), 7 deletions(-) diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c index 863069480eb1..9fb002b130ea 100644 --- a/drivers/mfd/rk808.c +++ b/drivers/mfd/rk808.c @@ -30,6 +30,23 @@ struct rk808_reg_data { int value; }; +static bool rk801_is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case RK801_SYS_STS_REG: + case RK801_INT_STS0_REG: + case RK801_SYS_CFG0_REG: + case RK801_SYS_CFG1_REG: + case RK801_SYS_CFG2_REG: + case RK801_SYS_CFG3_REG: + case RK801_SYS_CFG4_REG: + case RK801_SLEEP_CFG_REG: + return true; + } + + return false; +} + static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg) { /* @@ -126,6 +143,14 @@ static const struct regmap_config rk818_regmap_config = { .volatile_reg = rk818_is_volatile_reg, }; +static const struct regmap_config rk801_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = RK801_SYS_CFG3_OTP_REG, + .cache_type = REGCACHE_RBTREE, + .volatile_reg = rk801_is_volatile_reg, +}; + static const struct regmap_config rk805_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -171,6 +196,11 @@ static const struct resource rk817_rtc_resources[] = { DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM), }; +static const struct resource rk801_key_resources[] = { + DEFINE_RES_IRQ(RK801_IRQ_PWRON_FALL), + DEFINE_RES_IRQ(RK801_IRQ_PWRON_RISE), +}; + static const struct resource rk805_key_resources[] = { DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL), DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE), @@ -186,6 +216,15 @@ static const struct resource rk817_pwrkey_resources[] = { DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE), }; +static const struct mfd_cell rk801s[] = { + { .name = "rk808-regulator", }, + { + .name = "rk805-pwrkey", + .num_resources = ARRAY_SIZE(rk801_key_resources), + .resources = &rk801_key_resources[0], + }, +}; + static const struct mfd_cell rk805s[] = { { .name = "rk808-clkout", }, { .name = "rk808-regulator", }, @@ -258,6 +297,15 @@ static const struct mfd_cell rk818s[] = { }, }; +static const struct rk808_reg_data rk801_pre_init_reg[] = { + { RK801_SLEEP_CFG_REG, RK801_SLEEP_FUN_MSK, RK801_NONE_FUN }, + { RK801_SYS_CFG2_REG, RK801_SLEEP_POL_MSK, RK801_SLEEP_ACT_H }, + { RK801_INT_CONFIG_REG, RK801_INT_POL_MSK, RK801_INT_ACT_L }, + { RK801_POWER_FPWM_EN_REG, RK801_PLDO_HRDEC_EN, RK801_PLDO_HRDEC_EN }, + { RK801_BUCK_DEBUG5_REG, 0xff, 0x54 }, + { RK801_CON_BACK1_REG, 0xff, 0x18 }, +}; + static const struct rk808_reg_data rk805_pre_init_reg[] = { {RK805_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_400MA}, {RK805_GPIO_IO_POL_REG, SLP_SD_MSK, SLEEP_FUN}, @@ -415,6 +463,37 @@ static const struct rk808_reg_data rk818_pre_init_reg[] = { {RK808_CLK32OUT_REG, CLK32KOUT2_FUNC_MASK, CLK32KOUT2_FUNC}, }; +static const struct regmap_irq rk801_irqs[] = { + [RK801_IRQ_PWRON_FALL] = { + .mask = RK801_IRQ_PWRON_FALL_MSK, + .reg_offset = 0, + }, + [RK801_IRQ_PWRON_RISE] = { + .mask = RK801_IRQ_PWRON_RISE_MSK, + .reg_offset = 0, + }, + [RK801_IRQ_PWRON] = { + .mask = RK801_IRQ_PWRON_MSK, + .reg_offset = 0, + }, + [RK801_IRQ_PWRON_LP] = { + .mask = RK801_IRQ_PWRON_LP_MSK, + .reg_offset = 0, + }, + [RK801_IRQ_HOTDIE] = { + .mask = RK801_IRQ_HOTDIE_MSK, + .reg_offset = 0, + }, + [RK801_IRQ_VDC_RISE] = { + .mask = RK801_IRQ_VDC_RISE_MSK, + .reg_offset = 0, + }, + [RK801_IRQ_VDC_FALL] = { + .mask = RK801_IRQ_VDC_FALL_MSK, + .reg_offset = 0, + }, +}; + static const struct regmap_irq rk805_irqs[] = { [RK805_IRQ_PWRON_RISE] = { .mask = RK805_IRQ_PWRON_RISE_MSK, @@ -653,6 +732,17 @@ static const struct regmap_irq rk817_irqs[RK817_IRQ_END] = { REGMAP_IRQ_REG_LINE(23, 8) }; +static const struct regmap_irq_chip rk801_irq_chip = { + .name = "rk801", + .irqs = rk801_irqs, + .num_irqs = ARRAY_SIZE(rk801_irqs), + .num_regs = 1, + .status_base = RK801_INT_STS0_REG, + .mask_base = RK801_INT_MASK0_REG, + .ack_base = RK801_INT_STS0_REG, + .init_ack_masked = true, +}; + static const struct regmap_irq_chip rk805_irq_chip = { .name = "rk805", .irqs = rk805_irqs, @@ -759,6 +849,23 @@ static struct i2c_client *rk808_i2c_client; static struct rk808_reg_data *suspend_reg, *resume_reg; static int suspend_reg_num, resume_reg_num; +static int rk801_device_shutdown_prepare(struct sys_off_data *data) +{ + int ret = 0; + struct rk808 *rk808 = data->cb_data; + + if (!rk808) + return -1; + + ret = regmap_update_bits(rk808->regmap, RK801_SYS_CFG2_REG, + RK801_SLEEP_POL_MSK, RK801_SLEEP_ACT_H); + if (ret < 0) + return ret; + + return regmap_update_bits(rk808->regmap, RK801_SLEEP_CFG_REG, + RK801_SLEEP_FUN_MSK, RK801_SHUTDOWN_FUN); +} + static int rk805_device_shutdown_prepare(struct sys_off_data *data) { int ret = 0; @@ -828,6 +935,10 @@ static void rk8xx_device_shutdown(void) struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); switch (rk808->variant) { + case RK801_ID: + reg = RK801_SYS_CFG2_REG; + bit = DEV_OFF; + break; case RK805_ID: reg = RK805_DEV_CTRL_REG; bit = DEV_OFF; @@ -866,13 +977,16 @@ static void rk8xx_syscore_shutdown(void) return; } - /* close rtc int when power off */ - regmap_update_bits(rk808->regmap, - RK808_INT_STS_MSK_REG1, - (0x3 << 5), (0x3 << 5)); - regmap_update_bits(rk808->regmap, - RK808_RTC_INT_REG, - (0x3 << 2), (0x0 << 2)); + if (rk808->variant != RK801_ID) { + /* close rtc int when power off */ + regmap_update_bits(rk808->regmap, + RK808_INT_STS_MSK_REG1, + (0x3 << 5), (0x3 << 5)); + regmap_update_bits(rk808->regmap, + RK808_RTC_INT_REG, + (0x3 << 2), (0x0 << 2)); + } + /* * For PMIC that power off supplies by write register via i2c bus, * it's better to do power off at syscore shutdown here. @@ -1181,6 +1295,7 @@ static struct device_attribute rk8xx_attrs = __ATTR(rk8xx_dbg, 0200, NULL, rk8xx_dbg_store); static const struct of_device_id rk808_of_match[] = { + { .compatible = "rockchip,rk801" }, { .compatible = "rockchip,rk805" }, { .compatible = "rockchip,rk808" }, { .compatible = "rockchip,rk809" }, @@ -1220,6 +1335,9 @@ static int rk808_probe(struct i2c_client *client, of_device_is_compatible(np, "rockchip,rk809")) { pmic_id_msb = RK817_ID_MSB; pmic_id_lsb = RK817_ID_LSB; + } else if (of_device_is_compatible(np, "rockchip,rk801")) { + pmic_id_msb = RK801_ID_MSB; + pmic_id_lsb = RK801_ID_LSB; } else { pmic_id_msb = RK808_ID_MSB; pmic_id_lsb = RK808_ID_LSB; @@ -1244,6 +1362,17 @@ static int rk808_probe(struct i2c_client *client, dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant); switch (rk808->variant) { + case RK801_ID: + rk808->regmap_cfg = &rk801_regmap_config; + rk808->regmap_irq_chip = &rk801_irq_chip; + pre_init_reg = rk801_pre_init_reg; + nr_pre_init_regs = ARRAY_SIZE(rk801_pre_init_reg); + cells = rk801s; + nr_cells = ARRAY_SIZE(rk801s); + on_source = RK801_ON_SOURCE_REG; + off_source = RK801_OFF_SOURCE_REG; + device_shutdown_fn = rk8xx_device_shutdown; + break; case RK805_ID: rk808->regmap_cfg = &rk805_regmap_config; rk808->regmap_irq_chip = &rk805_irq_chip; @@ -1403,6 +1532,18 @@ static int rk808_probe(struct i2c_client *client, if (of_property_read_bool(np, "rockchip,system-power-controller")) { switch (rk808->variant) { + case RK801_ID: + ret = devm_register_sys_off_handler(&client->dev, + SYS_OFF_MODE_POWER_OFF_PREPARE, + SYS_OFF_PRIO_DEFAULT, + rk801_device_shutdown_prepare, + rk808); + if (ret) { + dev_err(&client->dev, "failed to register sys-off handler: %d\n", + ret); + return ret; + } + break; case RK805_ID: ret = devm_register_sys_off_handler(&client->dev, SYS_OFF_MODE_POWER_OFF_PREPARE, @@ -1493,6 +1634,15 @@ static int __maybe_unused rk8xx_suspend(struct device *dev) } switch (rk808->variant) { + case RK801_ID: + ret = regmap_update_bits(rk808->regmap, RK801_SYS_CFG2_REG, + RK801_SLEEP_POL_MSK, RK801_SLEEP_ACT_H); + if (ret < 0) + return ret; + + ret = regmap_update_bits(rk808->regmap, RK801_SLEEP_CFG_REG, + RK801_SLEEP_FUN_MSK, RK801_SLEEP_FUN); + break; case RK805_ID: ret = regmap_update_bits(rk808->regmap, RK805_GPIO_IO_POL_REG, diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index 784d9244f7c1..a190bc4c7d66 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c @@ -24,6 +24,9 @@ #include /* Field Definitions */ +#define RK801_BUCK_VSEL_MASK 0x7f +#define RK801_LDO_VSEL_MASK 0x3f + #define RK808_BUCK_VSEL_MASK 0x3f #define RK808_BUCK4_VSEL_MASK 0xf #define RK808_LDO_VSEL_MASK 0x1f @@ -118,6 +121,11 @@ .ops = _ops, \ } +#define RK801_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \ + _vmask, _ereg, _emask, _disval, _etime) \ + RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \ + _vmask, _ereg, _emask, _emask, _disval, _etime, &rk801_reg_ops) + #define RK816_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \ _vmask, _ereg, _emask, _disval, _etime) \ RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \ @@ -155,6 +163,10 @@ .ops = _ops \ } +#define RK801_DESC_SWITCH(_id, _match, _supply, _ereg, _emask, _disval) \ + RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask, \ + _emask, _disval, &rk801_switch_ops) + #define RK817_DESC_SWITCH(_id, _match, _supply, _ereg, _emask, _enval, \ _disval) \ RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask, \ @@ -175,6 +187,31 @@ static const int rk808_buck_config_regs[] = { RK808_BUCK4_CONFIG_REG, }; +static const struct linear_range rk801_buck1_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(500000, 0, 80, 12500), /* 0.5v - 1.5v */ + REGULATOR_LINEAR_RANGE(1800000, 81, 82, 400000),/* 1.8v - 2.2v */ + REGULATOR_LINEAR_RANGE(3300000, 83, 83, 0), /* 3.3v */ + REGULATOR_LINEAR_RANGE(5000000, 84, 84, 0), /* 5.0v */ + REGULATOR_LINEAR_RANGE(5250000, 85, 85, 0), /* 5.25v */ +}; + +static const struct linear_range rk801_buck2_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(800000, 0, 2, 50000), /* 0.8v - 0.9v */ + REGULATOR_LINEAR_RANGE(1800000, 3, 4, 400000), /* 1.8v - 2.2v */ + REGULATOR_LINEAR_RANGE(3300000, 5, 5, 0), /* 3.3v */ + REGULATOR_LINEAR_RANGE(5000000, 6, 6, 0), /* 5.0v */ + REGULATOR_LINEAR_RANGE(5250000, 7, 7, 0), /* 5.25v */ +}; + +static const struct linear_range rk801_buck4_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(500000, 0, 80, 12500), /* 0.5v - 1.5v */ + REGULATOR_LINEAR_RANGE(1800000, 81, 82, 400000),/* 1.8v - 2.2v */ + REGULATOR_LINEAR_RANGE(2500000, 83, 83, 0), /* 2.5v */ + REGULATOR_LINEAR_RANGE(2800000, 84, 84, 0), /* 2.8v */ + REGULATOR_LINEAR_RANGE(3000000, 85, 85, 0), /* 3.0v */ + REGULATOR_LINEAR_RANGE(3300000, 86, 86, 0), /* 3.3v */ +}; + static const struct linear_range rk805_buck_1_2_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(712500, 0, 59, 12500), /* 0.7125v - 1.45v */ REGULATOR_LINEAR_RANGE(1800000, 60, 62, 200000),/* 1.8v - 2.2v */ @@ -709,6 +746,145 @@ static unsigned int rk8xx_regulator_of_map_mode(unsigned int mode) } } +static unsigned int rk801_get_mode(struct regulator_dev *rdev) +{ + unsigned int pmw_mode_msk; + unsigned int val; + int err; + + if (rdev->desc->id == RK801_ID_DCDC3) + pmw_mode_msk = BIT(RK801_ID_DCDC3 + 1); + else if (rdev->desc->id == RK801_ID_DCDC4) + pmw_mode_msk = BIT(RK801_ID_DCDC4 - 1); + else + pmw_mode_msk = BIT(rdev->desc->id); + + err = regmap_read(rdev->regmap, RK801_POWER_FPWM_EN_REG, &val); + if (err) + return err; + + if ((val & pmw_mode_msk) == RK801_FPWM_MODE) + return REGULATOR_MODE_FAST; + else + return REGULATOR_MODE_NORMAL; +} + +static int rk801_set_mode(struct regulator_dev *rdev, unsigned int mode) +{ + unsigned int offset; + + if (rdev->desc->id == RK801_ID_DCDC3) + offset = RK801_ID_DCDC3 + 1; + else if (rdev->desc->id == RK801_ID_DCDC4) + offset = RK801_ID_DCDC4 - 1; + else + offset = rdev->desc->id; + + switch (mode) { + case REGULATOR_MODE_FAST: + return regmap_update_bits(rdev->regmap, RK801_POWER_FPWM_EN_REG, + BIT(offset), RK801_FPWM_MODE << offset); + case REGULATOR_MODE_NORMAL: + return regmap_update_bits(rdev->regmap, RK801_POWER_FPWM_EN_REG, + BIT(offset), RK801_AUTO_PWM_MODE << offset); + default: + dev_err(&rdev->dev, "do not support this mode\n"); + return -EINVAL; + } + + return 0; +} + +static int rk801_set_suspend_voltage(struct regulator_dev *rdev, int uv) +{ + unsigned int reg; + int sel; + + sel = regulator_map_voltage_linear(rdev, uv, uv); + if (sel < 0) + return -EINVAL; + + reg = rdev->desc->vsel_reg + RK801_SLP_REG_OFFSET; + + return regmap_update_bits(rdev->regmap, reg, + rdev->desc->vsel_mask, + sel); +} + +static int rk801_set_suspend_voltage_range(struct regulator_dev *rdev, int uv) +{ + unsigned int reg; + int sel; + + sel = regulator_map_voltage_linear_range(rdev, uv, uv); + if (sel < 0) + return -EINVAL; + + reg = rdev->desc->vsel_reg + RK801_SLP_REG_OFFSET; + + return regmap_update_bits(rdev->regmap, reg, + rdev->desc->vsel_mask, + sel); +} + +static int rk801_set_suspend_enable(struct regulator_dev *rdev) +{ + return regmap_update_bits(rdev->regmap, RK801_POWER_SLP_EN_REG, + rdev->desc->enable_mask, + rdev->desc->enable_val); +} + +static int rk801_set_suspend_disable(struct regulator_dev *rdev) +{ + return regmap_update_bits(rdev->regmap, RK801_POWER_SLP_EN_REG, + rdev->desc->enable_mask, + rdev->desc->disable_val); +} + +static int rk801_set_voltage_time_sel(struct regulator_dev *rdev, + unsigned int old_selector, + unsigned int new_selector) +{ + return regulator_set_voltage_time_sel(rdev, old_selector, new_selector) + 32; +} + +static const struct regulator_ops rk801_buck_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage_time_sel = rk801_set_voltage_time_sel, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_mode = rk801_set_mode, + .get_mode = rk801_get_mode, + .set_suspend_voltage = rk801_set_suspend_voltage_range, + .set_suspend_enable = rk801_set_suspend_enable, + .set_suspend_disable = rk801_set_suspend_disable, +}; + +static const struct regulator_ops rk801_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 = rk801_set_suspend_voltage, + .set_suspend_enable = rk801_set_suspend_enable, + .set_suspend_disable = rk801_set_suspend_disable, +}; + +static const struct regulator_ops rk801_switch_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_suspend_enable = rk801_set_suspend_enable, + .set_suspend_disable = rk801_set_suspend_disable, +}; + static const struct regulator_ops rk808_buck1_2_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, @@ -850,6 +1026,94 @@ static const struct regulator_ops rk817_switch_ops = { .set_suspend_disable = rk817_set_suspend_disable, }; +static const struct regulator_desc rk801_reg[] = { + { + .name = "DCDC_REG1", + .supply_name = "vcc1", + .of_match = of_match_ptr("DCDC_REG1"), + .regulators_node = of_match_ptr("regulators"), + .id = RK801_ID_DCDC1, + .ops = &rk801_buck_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 86, + .linear_ranges = rk801_buck1_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk801_buck1_voltage_ranges), + .vsel_reg = RK801_BUCK1_ON_VSEL_REG, + .vsel_mask = RK801_BUCK_VSEL_MASK, + .enable_reg = RK801_POWER_EN0_REG, + .enable_mask = ENABLE_MASK(RK801_ID_DCDC1), + .enable_val = ENABLE_MASK(RK801_ID_DCDC1), + .disable_val = DISABLE_VAL(RK801_ID_DCDC1), + .ramp_delay = 1, + .of_map_mode = rk8xx_regulator_of_map_mode, + .owner = THIS_MODULE, + }, { + .name = "DCDC_REG2", + .supply_name = "vcc2", + .of_match = of_match_ptr("DCDC_REG2"), + .regulators_node = of_match_ptr("regulators"), + .id = RK801_ID_DCDC2, + .ops = &rk801_buck_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 8, + .linear_ranges = rk801_buck2_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk801_buck2_voltage_ranges), + .vsel_reg = RK801_BUCK2_ON_VSEL_REG, + .vsel_mask = RK801_BUCK_VSEL_MASK, + .enable_reg = RK801_POWER_EN0_REG, + .enable_mask = ENABLE_MASK(RK801_ID_DCDC2), + .enable_val = ENABLE_MASK(RK801_ID_DCDC2), + .disable_val = DISABLE_VAL(RK801_ID_DCDC2), + .ramp_delay = 1, + .of_map_mode = rk8xx_regulator_of_map_mode, + .owner = THIS_MODULE, + }, { + .name = "DCDC_REG3", + .supply_name = "vcc3", + .of_match = of_match_ptr("DCDC_REG3"), + .regulators_node = of_match_ptr("regulators"), + .id = RK801_ID_DCDC3, + .ops = &rk801_switch_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 1, + .enable_reg = RK801_POWER_EN0_REG, + .enable_mask = ENABLE_MASK(RK801_ID_DCDC3 + 1), + .enable_val = ENABLE_MASK(RK801_ID_DCDC3 + 1), + .disable_val = DISABLE_VAL(RK801_ID_DCDC3 + 1), + .of_map_mode = rk8xx_regulator_of_map_mode, + .owner = THIS_MODULE, + }, { + .name = "DCDC_REG4", + .supply_name = "vcc4", + .of_match = of_match_ptr("DCDC_REG4"), + .regulators_node = of_match_ptr("regulators"), + .id = RK801_ID_DCDC4, + .ops = &rk801_buck_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 87, + .linear_ranges = rk801_buck4_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk801_buck4_voltage_ranges), + .vsel_reg = RK801_BUCK4_ON_VSEL_REG, + .vsel_mask = RK801_BUCK_VSEL_MASK, + .enable_reg = RK801_POWER_EN0_REG, + .enable_mask = ENABLE_MASK(RK801_ID_DCDC4 - 1), + .enable_val = ENABLE_MASK(RK801_ID_DCDC4 - 1), + .disable_val = DISABLE_VAL(RK801_ID_DCDC4 - 1), + .ramp_delay = 1, + .of_map_mode = rk8xx_regulator_of_map_mode, + .owner = THIS_MODULE, + }, + + RK801_DESC(RK801_ID_LDO1, "LDO_REG1", "vcc5", 500, 3400, 50, + RK801_LDO1_ON_VSEL_REG, RK801_LDO_VSEL_MASK, RK801_POWER_EN1_REG, + ENABLE_MASK(0), DISABLE_VAL(0), 400), + RK801_DESC(RK801_ID_LDO2, "LDO_REG2", "vcc6", 500, 3400, 50, + RK801_LDO2_ON_VSEL_REG, RK801_LDO_VSEL_MASK, RK801_POWER_EN1_REG, + ENABLE_MASK(1), DISABLE_VAL(1), 400), + RK801_DESC_SWITCH(RK801_ID_SWITCH, "SWITCH_REG", "vcc7", RK801_POWER_EN1_REG, + ENABLE_MASK(2), DISABLE_VAL(2)), +}; + static const struct regulator_desc rk805_reg[] = { { .name = "DCDC_REG1", @@ -1616,6 +1880,10 @@ static int rk808_regulator_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pdata); switch (rk808->variant) { + case RK801_ID: + regulators = rk801_reg; + nregulators = RK801_NUM_REGULATORS; + break; case RK805_ID: regulators = rk805_reg; nregulators = RK805_NUM_REGULATORS; diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h index 48d7957ee4e5..ad2287268bc7 100644 --- a/include/linux/mfd/rk808.h +++ b/include/linux/mfd/rk808.h @@ -18,6 +18,116 @@ #include #include +/* RK801 */ +enum rk801_reg { + RK801_ID_DCDC1, + RK801_ID_DCDC2, + RK801_ID_DCDC3, + RK801_ID_DCDC4, + RK801_ID_LDO1, + RK801_ID_LDO2, + RK801_ID_SWITCH, +}; + +#define RK801_SLP_REG_OFFSET 5 +#define RK801_NUM_REGULATORS 7 + +/* RK801 Register Definitions */ +#define RK801_ID_MSB 0x00 +#define RK801_ID_LSB 0x01 +#define RK801_OTP_VER_REG 0x02 +#define RK801_POWER_EN0_REG 0x03 +#define RK801_POWER_EN1_REG 0x04 +#define RK801_POWER_SLP_EN_REG 0x05 +#define RK801_POWER_FPWM_EN_REG 0x06 +#define RK801_SLP_LP_CONFIG_REG 0x07 +#define RK801_BUCK_CONFIG_REG 0x08 +#define RK801_BUCK1_ON_VSEL_REG 0x09 +#define RK801_BUCK2_ON_VSEL_REG 0x0a +#define RK801_BUCK4_ON_VSEL_REG 0x0b +#define RK801_LDO1_ON_VSEL_REG 0x0c +#define RK801_LDO2_ON_VSEL_REG 0x0d +#define RK801_BUCK1_SLP_VSEL_REG 0x0e +#define RK801_BUCK2_SLP_VSEL_REG 0x0f +#define RK801_BUCK4_SLP_VSEL_REG 0x10 +#define RK801_LDO1_SLP_VSEL_REG 0x11 +#define RK801_LDO2_SLP_VSEL_REG 0x12 +#define RK801_LDO_SW_IMAX_REG 0x13 +#define RK801_SYS_STS_REG 0x14 +#define RK801_SYS_CFG0_REG 0x15 +#define RK801_SYS_CFG1_REG 0x16 +#define RK801_SYS_CFG2_REG 0x17 +#define RK801_SYS_CFG3_REG 0x18 +#define RK801_SYS_CFG4_REG 0x19 +#define RK801_SLEEP_CFG_REG 0x1a +#define RK801_ON_SOURCE_REG 0x1b +#define RK801_OFF_SOURCE_REG 0x1c +#define RK801_PWRON_KEY_REG 0x1d +#define RK801_INT_STS0_REG 0x1e +#define RK801_INT_MASK0_REG 0x1f +#define RK801_INT_CONFIG_REG 0x20 +#define RK801_CON_BACK1_REG 0x21 +#define RK801_CON_BACK2_REG 0x22 +#define RK801_DATA_CON0_REG 0x23 +#define RK801_DATA_CON1_REG 0x24 +#define RK801_DATA_CON2_REG 0x25 +#define RK801_DATA_CON3_REG 0x26 +#define RK801_POWER_EXIT_SLP_SEQ0_REG 0x27 +#define RK801_POWER_EXIT_SLP_SEQ1_REG 0x28 +#define RK801_POWER_EXIT_SLP_SEQ2_REG 0x29 +#define RK801_POWER_EXIT_SLP_SEQ3_REG 0x2a +#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ0_REG 0x2b +#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ1_REG 0x2c +#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ2_REG 0x2d +#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ3_REG 0x2e +#define RK801_BUCK_DEBUG1_REG 0x2f +#define RK801_BUCK_DEBUG2_REG 0x30 +#define RK801_BUCK_DEBUG3_REG 0x31 +#define RK801_BUCK_DEBUG4_REG 0x32 +#define RK801_BUCK_DEBUG5_REG 0x33 +#define RK801_BUCK_DEBUG7_REG 0x34 +#define RK801_OTP_EN_CON_REG 0x35 +#define RK801_TEST_CON_REG 0x36 +#define RK801_EFUSE_CONTROL_REG 0x37 +#define RK801_SYS_CFG3_OTP_REG 0x38 + +/* RK801 IRQ Definitions */ +#define RK801_IRQ_PWRON_FALL 0 +#define RK801_IRQ_PWRON_RISE 1 +#define RK801_IRQ_PWRON 2 +#define RK801_IRQ_PWRON_LP 3 +#define RK801_IRQ_HOTDIE 4 +#define RK801_IRQ_VDC_RISE 5 +#define RK801_IRQ_VDC_FALL 6 +#define RK801_IRQ_PWRON_FALL_MSK BIT(0) +#define RK801_IRQ_PWRON_RISE_MSK BIT(1) +#define RK801_IRQ_PWRON_MSK BIT(2) +#define RK801_IRQ_PWRON_LP_MSK BIT(3) +#define RK801_IRQ_HOTDIE_MSK BIT(4) +#define RK801_IRQ_VDC_RISE_MSK BIT(5) +#define RK801_IRQ_VDC_FALL_MSK BIT(6) + +/* RK801_SLEEP_CFG_REG */ +#define RK801_SLEEP_FUN_MSK 0x3 +#define RK801_NONE_FUN 0x0 +#define RK801_SLEEP_FUN 0x1 +#define RK801_SHUTDOWN_FUN 0x2 +#define RK801_RESET_FUN 0x3 + +/* RK801_SYS_CFG2_REG */ +#define RK801_SLEEP_POL_MSK BIT(1) +#define RK801_SLEEP_ACT_H BIT(1) +#define RK801_SLEEP_ACT_L 0 + +/* RK801_INT_CONFIG_REG */ +#define RK801_INT_POL_MSK BIT(1) +#define RK801_INT_ACT_H BIT(1) +#define RK801_INT_ACT_L 0 + +#define RK801_FPWM_MODE 1 +#define RK801_AUTO_PWM_MODE 0 +#define RK801_PLDO_HRDEC_EN BIT(6) + /* * rk808 Global Register Map. */ @@ -1214,6 +1324,7 @@ enum { }; enum { + RK801_ID = 0x8010, RK805_ID = 0x8050, RK808_ID = 0x0000, RK809_ID = 0x8090,