mfd: rk808: add rk816 support

include sub modules: regulator, rtc, gpio, pwrkey

Change-Id: I59cc4b943403f1e0b1210a314cfcbf61fc193bdf
Signed-off-by: shengfei Xu <xsf@rock-chips.com>
This commit is contained in:
shengfei Xu 2017-07-07 17:18:10 +08:00 committed by Huang, Tao
parent 9d1525c6d7
commit ce4e02a88b
8 changed files with 750 additions and 13 deletions

View File

@ -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>;
};
};
};
};

View 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.

View File

@ -29,6 +29,10 @@
#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);

View 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" },
{ },
};

View 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.

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
@ -86,6 +91,28 @@
.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>");

View 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.

View 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,
};