mfd: rk808: add rk816 support

include sub modules: regulator, rtc, gpio, pwrkey

Change-Id: I5efedb2abe2be5335c467aaa91955cb7b9f56cfb
Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
This commit is contained in:
Elaine Zhang 2019-03-15 09:38:20 +08:00 committed by Tao Huang
parent bf09920b43
commit 7b1c59d2b1
6 changed files with 741 additions and 8 deletions

View File

@ -997,14 +997,14 @@ config MFD_RC5T583
different functionality of the device.
config MFD_RK808
tristate "Rockchip RK805/RK808/RK818 Power Management Chip"
tristate "Rockchip RK805/RK808/RK816/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 RK805, RK808 and RK818
Power Management chips.
If you say yes here you get support for the RK805, RK808 , RK816
and RK818 Power Management chips.
This driver provides common support for accessing the device
through I2C interface. The device supports multiple sub-devices
including interrupts, RTC, LDO & DCDC regulators, and onkey.

View File

@ -62,6 +62,40 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
return false;
}
static bool rk818_is_volatile_reg(struct device *dev, unsigned int reg)
{
/*
* Notes:
* - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
* we don't use that feature. It's better to cache.
* - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
* bits are cleared in case when we shutoff anyway, but better safe.
*/
switch (reg) {
case RK808_SECONDS_REG ... RK808_WEEKS_REG:
case RK808_RTC_STATUS_REG:
case RK808_VB_MON_REG:
case RK808_THERMAL_REG:
case RK808_DCDC_EN_REG:
case RK808_LDO_EN_REG:
case RK808_DCDC_UV_STS_REG:
case RK808_LDO_UV_STS_REG:
case RK808_DCDC_PG_REG:
case RK808_LDO_PG_REG:
case RK808_DEVCTRL_REG:
case RK808_INT_STS_REG1:
case RK808_INT_STS_REG2:
case RK808_INT_STS_MSK_REG1:
case RK808_INT_STS_MSK_REG2:
case RK816_INT_STS_REG1:
case RK816_INT_STS_MSK_REG1:
return true;
}
return false;
}
static const struct regmap_config rk818_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@ -86,6 +120,14 @@ static const struct regmap_config rk808_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 struct resource rtc_resources[] = {
{
.start = RK808_IRQ_RTC_ALARM,
@ -94,6 +136,14 @@ static struct resource rtc_resources[] = {
}
};
static struct resource rk816_rtc_resources[] = {
{
.start = RK816_IRQ_RTC_ALARM,
.end = RK816_IRQ_RTC_ALARM,
.flags = IORESOURCE_IRQ,
}
};
static struct resource rk805_key_resources[] = {
{
.start = RK805_IRQ_PWRON_FALL,
@ -107,6 +157,19 @@ static struct resource rk805_key_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 rk805s[] = {
{ .name = "rk808-clkout", },
{ .name = "rk808-regulator", },
@ -132,6 +195,23 @@ static const struct mfd_cell rk808s[] = {
},
};
static const struct mfd_cell rk816s[] = {
{ .name = "rk808-clkout", },
{ .name = "rk808-regulator", },
{ .name = "rk8xx-gpio", },
{ .name = "rk816-battery", .of_compatible = "rk816-battery", },
{
.name = "rk8xx-pwrkey",
.num_resources = ARRAY_SIZE(rk816_pwrkey_resources),
.resources = &rk816_pwrkey_resources[0],
},
{
.name = "rk808-rtc",
.num_resources = ARRAY_SIZE(rk816_rtc_resources),
.resources = &rk816_rtc_resources[0],
},
};
static const struct mfd_cell rk818s[] = {
{ .name = "rk808-clkout", },
{ .name = "rk808-regulator", },
@ -169,6 +249,33 @@ static const struct rk808_reg_data rk808_pre_init_reg[] = {
VB_LO_SEL_3500MV },
};
static const struct rk808_reg_data rk816_pre_init_reg[] = {
/* buck4 Max ILMIT*/
{ RK816_BUCK4_CONFIG_REG, REG_WRITE_MSK, BUCK4_MAX_ILIMIT },
/* hotdie temperature: 105c*/
{ RK816_THERMAL_REG, REG_WRITE_MSK, TEMP105C },
/* set buck 12.5mv/us */
{ RK816_BUCK1_CONFIG_REG, BUCK_RATE_MSK, BUCK_RATE_12_5MV_US },
{ RK816_BUCK2_CONFIG_REG, BUCK_RATE_MSK, BUCK_RATE_12_5MV_US },
/* enable RTC_PERIOD & RTC_ALARM int */
{ RK816_INT_STS_MSK_REG2, REG_WRITE_MSK, RTC_PERIOD_ALARM_INT_EN },
/* set bat 3.0 low and act shutdown */
{ RK816_VB_MON_REG, VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK,
RK816_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN },
/* enable PWRON rising/faling int */
{ RK816_INT_STS_MSK_REG1, REG_WRITE_MSK, RK816_PWRON_FALL_RISE_INT_EN },
/* enable PLUG IN/OUT int */
{ RK816_INT_STS_MSK_REG3, REG_WRITE_MSK, PLUGIN_OUT_INT_EN },
/* clear int flags */
{ RK816_INT_STS_REG1, REG_WRITE_MSK, ALL_INT_FLAGS_ST },
{ RK816_INT_STS_REG2, REG_WRITE_MSK, ALL_INT_FLAGS_ST },
{ RK816_INT_STS_REG3, REG_WRITE_MSK, ALL_INT_FLAGS_ST },
{ RK816_DCDC_EN_REG2, BOOST_EN_MASK, BOOST_DISABLE },
/* set write mask bit 1, otherwise 'is_enabled()' get wrong status */
{ RK816_LDO_EN_REG1, REGS_WMSK, REGS_WMSK },
{ RK816_LDO_EN_REG2, REGS_WMSK, REGS_WMSK },
};
static const struct rk808_reg_data rk818_pre_init_reg[] = {
/* improve efficiency */
{ RK818_BUCK2_CONFIG_REG, BUCK2_RATE_MASK, BUCK_ILMIN_250MA },
@ -265,6 +372,46 @@ static const struct regmap_irq rk808_irqs[] = {
},
};
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 const struct regmap_irq rk818_irqs[] = {
/* INT_STS */
[RK818_IRQ_VOUT_LO] = {
@ -358,6 +505,18 @@ static const struct regmap_irq_chip rk808_irq_chip = {
.init_ack_masked = true,
};
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 regmap_irq_chip rk818_irq_chip = {
.name = "rk818",
.irqs = rk818_irqs,
@ -408,6 +567,24 @@ static void rk808_device_shutdown(void)
dev_err(&rk808_i2c_client->dev, "power off error!\n");
}
static void rk816_device_shutdown(void)
{
int ret;
struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
if (!rk808) {
dev_warn(&rk808_i2c_client->dev,
"have no rk805, so do nothing here\n");
return;
}
ret = regmap_update_bits(rk808->regmap,
RK816_DEV_CTRL_REG,
DEV_OFF, DEV_OFF);
if (ret)
dev_err(&rk808_i2c_client->dev, "power off error!\n");
}
static void rk818_device_shutdown(void)
{
int ret;
@ -429,6 +606,7 @@ static void rk818_device_shutdown(void)
static const struct of_device_id rk808_of_match[] = {
{ .compatible = "rockchip,rk805" },
{ .compatible = "rockchip,rk808" },
{ .compatible = "rockchip,rk816" },
{ .compatible = "rockchip,rk818" },
{ },
};
@ -489,6 +667,15 @@ static int rk808_probe(struct i2c_client *client,
nr_cells = ARRAY_SIZE(rk808s);
pm_pwroff_fn = rk808_device_shutdown;
break;
case RK816_ID:
rk808->regmap_cfg = &rk816_regmap_config;
rk808->regmap_irq_chip = &rk816_irq_chip;
pre_init_reg = rk816_pre_init_reg;
nr_pre_init_regs = ARRAY_SIZE(rk816_pre_init_reg);
cells = rk816s;
nr_cells = ARRAY_SIZE(rk816s);
pm_pwroff_fn = rk816_device_shutdown;
break;
case RK818_ID:
rk808->regmap_cfg = &rk818_regmap_config;
rk808->regmap_irq_chip = &rk818_irq_chip;
@ -574,6 +761,7 @@ static int rk808_remove(struct i2c_client *client)
static const struct i2c_device_id rk808_ids[] = {
{ "rk805" },
{ "rk808" },
{ "rk816" },
{ "rk818" },
{ },
};

View File

@ -741,11 +741,11 @@ config REGULATOR_RC5T583
outputs which can be controlled by i2c communication.
config REGULATOR_RK808
tristate "Rockchip RK805/RK808/RK818 Power regulators"
tristate "Rockchip RK805/RK808/RK816/RK818 Power regulators"
depends on MFD_RK808
help
Select this option to enable the power regulator of ROCKCHIP
PMIC RK805,RK808 and RK818.
PMIC RK805,RK808 , RK816 and 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.

View File

@ -36,6 +36,11 @@
#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
@ -107,6 +112,28 @@
.ops = &rk808_reg_ops, \
}
#define RK816_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \
_vmask, _ereg, _emask, _enval, _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), \
.enable_val = (_enval), \
.disable_val = (_disval), \
.enable_time = (_etime), \
.ops = &rk808_reg_ops, \
}
#define RK8XX_DESC_SWITCH(_id, _match, _supply, _ereg, _emask) \
[_id] = { \
.name = (_match), \
@ -138,6 +165,27 @@ 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 unsigned int rk8xx_regulator_of_map_mode(unsigned int mode)
{
if (mode == 1)
return REGULATOR_MODE_FAST;
if (mode == 2)
return REGULATOR_MODE_NORMAL;
return -EINVAL;
}
static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev)
{
struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
@ -210,6 +258,58 @@ static int rk808_buck1_2_i2c_set_voltage_sel(struct regulator_dev *rdev,
return ret;
}
#ifdef CONFIG_CPU_RK312X
extern void rkclk_cpuclk_div_setting(int div);
#else
static inline void rkclk_cpuclk_div_setting(int div) {}
#endif
static int rk816_regulator_set_voltage_sel_regmap(struct regulator_dev *rdev,
unsigned int sel)
{
int ret, real_sel, delay = 100;
int rk816_type;
int id = rdev_get_id(rdev);
regmap_read(rdev->regmap, RK816_CHIP_VER_REG, &rk816_type);
rk816_type &= RK816_CHIP_VERSION_MASK;
sel <<= ffs(rdev->desc->vsel_mask) - 1;
if ((rk816_type != RK816_TYPE_ES2) && (id == 0)) {
if (sel > 23)
rkclk_cpuclk_div_setting(4);
else
rkclk_cpuclk_div_setting(2);
}
do {
ret = regmap_update_bits(rdev->regmap,
rdev->desc->vsel_reg,
rdev->desc->vsel_mask, sel);
if (ret)
return ret;
if (rk816_type == RK816_TYPE_ES2) {
ret = regmap_update_bits(rdev->regmap,
RK816_DCDC_EN_REG2,
RK816_BUCK_DVS_CONFIRM,
RK816_BUCK_DVS_CONFIRM);
if (ret)
return ret;
}
regmap_read(rdev->regmap,
rdev->desc->vsel_reg, &real_sel);
real_sel &= rdev->desc->vsel_mask;
delay--;
} while ((sel != real_sel) && (delay > 0));
if ((rk816_type != RK816_TYPE_ES2) && (id == 0))
rkclk_cpuclk_div_setting(1);
return ret;
}
static int rk808_buck1_2_set_voltage_sel(struct regulator_dev *rdev,
unsigned sel)
{
@ -363,6 +463,59 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
rdev->desc->enable_mask);
}
static int rk8xx_set_suspend_mode(struct regulator_dev *rdev, unsigned int mode)
{
unsigned int reg;
reg = rdev->desc->vsel_reg + RK808_SLP_REG_OFFSET;
switch (mode) {
case REGULATOR_MODE_FAST:
return regmap_update_bits(rdev->regmap, reg,
PWM_MODE_MSK, FPWM_MODE);
case REGULATOR_MODE_NORMAL:
return regmap_update_bits(rdev->regmap, reg,
PWM_MODE_MSK, AUTO_PWM_MODE);
default:
pr_err("do not support this mode\n");
return -EINVAL;
}
return 0;
}
static int rk8xx_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
switch (mode) {
case REGULATOR_MODE_FAST:
return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
PWM_MODE_MSK, FPWM_MODE);
case REGULATOR_MODE_NORMAL:
return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
PWM_MODE_MSK, AUTO_PWM_MODE);
default:
pr_err("do not support this mode\n");
return -EINVAL;
}
return 0;
}
static unsigned int rk8xx_get_mode(struct regulator_dev *rdev)
{
unsigned int val;
int err;
err = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
if (err)
return err;
if (val & FPWM_MODE)
return REGULATOR_MODE_FAST;
else
return REGULATOR_MODE_NORMAL;
}
static struct regulator_ops rk805_reg_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
@ -433,6 +586,42 @@ static struct regulator_ops rk808_switch_ops = {
.set_suspend_disable = rk808_set_suspend_disable,
};
static struct regulator_ops rk8xx_buck_ops_range = {
.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 = regulator_set_voltage_time_sel,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_mode = rk8xx_set_mode,
.get_mode = rk8xx_get_mode,
.set_suspend_mode = rk8xx_set_suspend_mode,
.set_ramp_delay = rk808_set_ramp_delay,
.set_suspend_voltage = rk808_set_suspend_voltage_range,
.set_suspend_enable = rk808_set_suspend_enable,
.set_suspend_disable = rk808_set_suspend_disable,
};
static struct regulator_ops rk816_buck_ops_range = {
.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 = rk816_regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_mode = rk8xx_set_mode,
.get_mode = rk8xx_get_mode,
.set_suspend_mode = rk8xx_set_suspend_mode,
.set_ramp_delay = rk808_set_ramp_delay,
.set_suspend_voltage = rk808_set_suspend_voltage_range,
.set_suspend_enable = rk808_set_suspend_enable,
.set_suspend_disable = rk808_set_suspend_disable,
};
static const struct regulator_desc rk805_reg[] = {
{
.name = "DCDC_REG1",
@ -589,6 +778,106 @@ 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 = &rk816_buck_ops_range,
.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),
.enable_val = BIT(4) | BIT(0),
.disable_val = BIT(4),
.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 = RK816_ID_DCDC2,
.ops = &rk816_buck_ops_range,
.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),
.enable_val = BIT(5) | BIT(1),
.disable_val = BIT(5),
.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 = 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),
.enable_val = BIT(6) | BIT(2),
.disable_val = BIT(6),
.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 = RK816_ID_DCDC4,
.ops = &rk8xx_buck_ops_range,
.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),
.enable_val = BIT(7) | BIT(3),
.disable_val = BIT(7),
.of_map_mode = rk8xx_regulator_of_map_mode,
.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) | 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) | BIT(1),
BIT(5), 400),
RK816_DESC(RK816_ID_LDO3, "LDO_REG3", "vcc5", 800, 3400, 100,
RK816_LDO3_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
RK816_LDO_EN_REG1, BIT(6) | BIT(2), 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) | 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) | 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) | BIT(1),
BIT(5), 400),
};
static const struct regulator_desc rk818_reg[] = {
{
.name = "DCDC_REG1",
@ -759,6 +1048,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
regulators = rk808_reg;
nregulators = RK808_NUM_REGULATORS;
break;
case RK816_ID:
regulators = rk816_reg;
nregulators = RK816_NUM_REGULATORS;
break;
case RK818_ID:
regulators = rk818_reg;
nregulators = RK818_NUM_REGULATORS;
@ -796,7 +1089,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>");

View File

@ -362,11 +362,11 @@ config RTC_DRV_MAX77686
will be called rtc-max77686.
config RTC_DRV_RK808
tristate "Rockchip RK805/RK808/RK818 RTC"
tristate "Rockchip RK805/RK808/RK816/RK818 RTC"
depends on MFD_RK808
help
If you say yes here you will get support for the
RTC of RK805, RK808 and RK818 PMIC.
RTC of RK805, RK808 , RK816 and RK818 PMIC.
This driver can also be built as a module. If so, the module
will be called rk808-rtc.

View File

@ -121,6 +121,234 @@ enum rk808_reg {
#define RK808_INT_STS_MSK_REG2 0x4f
#define RK808_IO_POL_REG 0x50
/* RK816 */
enum rk816_reg {
RK816_ID_DCDC1,
RK816_ID_DCDC2,
RK816_ID_DCDC3,
RK816_ID_DCDC4,
RK816_ID_LDO1,
RK816_ID_LDO2,
RK816_ID_LDO3,
RK816_ID_LDO4,
RK816_ID_LDO5,
RK816_ID_LDO6,
};
/*VERSION REGISTER*/
#define RK816_CHIP_NAME_REG 0x17
#define RK816_CHIP_VER_REG 0x18
#define RK816_OTP_VER_REG 0x19
#define RK816_NUM_REGULATORS 10
/*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
#define RK816_TS_CTRL_REG 0xAC
#define RK816_ADC_CTRL_REG 0xAD
#define RK816_GGCON_REG 0xB0
#define RK816_GGSTS_REG 0xB1
#define RK816_ZERO_CUR_ADC_REGH 0xB2
#define RK816_ZERO_CUR_ADC_REGL 0xB3
#define RK816_GASCNT_CAL_REG3 0xB4
#define RK816_GASCNT_CAL_REG2 0xB5
#define RK816_GASCNT_CAL_REG1 0xB6
#define RK816_GASCNT_CAL_REG0 0xB7
#define RK816_GASCNT_REG3 0xB8
#define RK816_GASCNT_REG2 0xB9
#define RK816_GASCNT_REG1 0xBA
#define RK816_GASCNT_REG0 0xBB
#define RK816_BAT_CUR_AVG_REGH 0xBC
#define RK816_BAT_CUR_AVG_REGL 0xBD
#define RK816_TS_ADC_REGH 0xBE
#define RK816_TS_ADC_REGL 0xBF
#define RK816_USB_ADC_REGH 0xC0
#define RK816_USB_ADC_REGL 0xC1
#define RK816_BAT_OCV_REGH 0xC2
#define RK816_BAT_OCV_REGL 0xC3
#define RK816_BAT_VOL_REGH 0xC4
#define RK816_BAT_VOL_REGL 0xC5
#define RK816_RELAX_ENTRY_THRES_REGH 0xC6
#define RK816_RELAX_ENTRY_THRES_REGL 0xC7
#define RK816_RELAX_EXIT_THRES_REGH 0xC8
#define RK816_RELAX_EXIT_THRES_REGL 0xC9
#define RK816_RELAX_VOL1_REGH 0xCA
#define RK816_RELAX_VOL1_REGL 0xCB
#define RK816_RELAX_VOL2_REGH 0xCC
#define RK816_RELAX_VOL2_REGL 0xCD
#define RK816_RELAX_CUR1_REGH 0xCE
#define RK816_RELAX_CUR1_REGL 0xCF
#define RK816_RELAX_CUR2_REGH 0xD0
#define RK816_RELAX_CUR2_REGL 0xD1
#define RK816_CAL_OFFSET_REGH 0xD2
#define RK816_CAL_OFFSET_REGL 0xD3
#define RK816_NON_ACT_TIMER_CNT_REG 0xD4
#define RK816_VCALIB0_REGH 0xD5
#define RK816_VCALIB0_REGL 0xD6
#define RK816_VCALIB1_REGH 0xD7
#define RK816_VCALIB1_REGL 0xD8
#define RK816_FCC_GASCNT_REG3 0xD9
#define RK816_FCC_GASCNT_REG2 0xDA
#define RK816_FCC_GASCNT_REG1 0xDB
#define RK816_FCC_GASCNT_REG0 0xDC
#define RK816_IOFFSET_REGH 0xDD
#define RK816_IOFFSET_REGL 0xDE
#define RK816_SLEEP_CON_SAMP_CUR_REG 0xDF
/*DATA REGISTER*/
#define RK816_SOC_REG 0xE0
#define RK816_REMAIN_CAP_REG3 0xE1
#define RK816_REMAIN_CAP_REG2 0xE2
#define RK816_REMAIN_CAP_REG1 0xE3
#define RK816_REMAIN_CAP_REG0 0xE4
#define RK816_UPDATE_LEVE_REG 0xE5
#define RK816_NEW_FCC_REG3 0xE6
#define RK816_NEW_FCC_REG2 0xE7
#define RK816_NEW_FCC_REG1 0xE8
#define RK816_NEW_FCC_REG0 0xE9
#define RK816_NON_ACT_TIMER_CNT_REG_SAVE 0xEA
#define RK816_OCV_VOL_VALID_REG 0xEB
#define RK816_REBOOT_CNT_REG 0xEC
#define RK816_PCB_IOFFSET_REG 0xED
#define RK816_MISC_MARK_REG 0xEE
#define RK816_HALT_CNT_REG 0xEF
#define RK816_CALC_REST_REGH 0xF0
#define RK816_CALC_REST_REGL 0xF1
#define DATA18_REG 0xF2
/*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 BUCK4_VRP_3PERCENT 0xc0
#define RK816_BUCK_DVS_CONFIRM (0x1 << 7)
#define RK816_TYPE_ES2 0x05
#define RK816_CHIP_VERSION_MASK 0x0f
/* RK818 */
#define RK818_DCDC1 0
#define RK818_LDO1 4
@ -356,6 +584,25 @@ enum rk805_reg {
#define RK818_NUM_IRQ 16
/*RK818_DCDC_EN_REG*/
#define BUCK1_EN_MASK BIT(0)
#define BUCK2_EN_MASK BIT(1)
#define BUCK3_EN_MASK BIT(2)
#define BUCK4_EN_MASK BIT(3)
#define BOOST_EN_MASK BIT(4)
#define LDO9_EN_MASK BIT(5)
#define SWITCH_EN_MASK BIT(6)
#define OTG_EN_MASK BIT(7)
#define BUCK1_EN_ENABLE BIT(0)
#define BUCK2_EN_ENABLE BIT(1)
#define BUCK3_EN_ENABLE BIT(2)
#define BUCK4_EN_ENABLE BIT(3)
#define BOOST_EN_ENABLE BIT(4)
#define LDO9_EN_ENABLE BIT(5)
#define SWITCH_EN_ENABLE BIT(6)
#define OTG_EN_ENABLE BIT(7)
#define RK808_VBAT_LOW_2V8 0x00
#define RK808_VBAT_LOW_2V9 0x01
#define RK808_VBAT_LOW_3V0 0x02
@ -390,13 +637,17 @@ enum rk805_reg {
#define VOUT_LO_INT BIT(0)
#define CLK32KOUT2_EN BIT(0)
#define TEMP105C 0x08
#define TEMP115C 0x0c
#define TEMP_HOTDIE_MSK 0x0c
#define SLP_SD_MSK (0x3 << 2)
#define SHUTDOWN_FUN (0x2 << 2)
#define SLEEP_FUN (0x1 << 2)
#define RK8XX_ID_MSK 0xfff0
#define PWM_MODE_MSK BIT(7)
#define FPWM_MODE BIT(7)
#define AUTO_PWM_MODE 0
#define REGS_WMSK 0xf0
enum {
BUCK_ILMIN_50MA,
@ -444,6 +695,7 @@ enum {
enum {
RK805_ID = 0x8050,
RK808_ID = 0x0000,
RK816_ID = 0x8160,
RK818_ID = 0x8181,
};