mfd: RK817 & RK809: Add new mfd driver for RK817 & RK809

The RK817 & RK809 chip is a power management IC for multimedia and handheld
devices. It contains the following components:

- Regulators
- RTC
- Clkout
- Pinctrl
- Powerkey

The RK817 & RK809 core driver is registered as a platform driver and provides
communication through I2C with the host device for the different
components.

The following is the different between the RK817 and the RK809.
1、The dcdc-buck5 is a boost dcdc for RK817 and is a buck for RK809.
2、The RK817 have one switch but The Rk809 have two.
3、The RK817 have a charger and powerpatch function but RK809 not.

Change-Id: I132029c5b28978db7ae06e13c327a1edf70f5b69
Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
This commit is contained in:
tony.xie 2018-01-29 15:32:32 +08:00 committed by Tao Huang
parent 1cb8aa091d
commit 4a56c8edc7
7 changed files with 1611 additions and 28 deletions

View File

@ -0,0 +1,293 @@
RK809 Power Management Integrated Circuit
Required properties:
- compatible: "rockchip,rk809"
- 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). See <dt-bindings/clock/rockchip,rk808.h> for clock IDs.
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.
- 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
- vcc7-supply: The input supply for LDO_REG7, LDO_REG8, LDO_REG9
- vcc8-supply: The input supply for SWITCH_REG1
- vcc9-supply: The input supply for DCDC_REG5, SWITCH_REG2
Regulators: All the regulators of RK809 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 RK809 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 RK808 datasheet.
- DCDC_REGn
- valid values for n are 1 to 5.
- LDO_REGn
- valid values for n are 1 to 9.
- SWITCH_REGn
- valid values for n are 1 to 2.
Standard regulator bindings are used inside regulator subnodes. Check
Documentation/devicetree/bindings/regulator/regulator.txt
for more details
Example:
rk809: pmic@20 {
compatible = "rockchip,rk809";
reg = <0x20>;
interrupt-parent = <&gpio0>;
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&pmic_int>;
rockchip,system-power-controller;
wakeup-source;
#clock-cells = <1>;
clock-output-names = "xin32k", "rk808-clkout2";
vcc1-supply = <&vcc5v0_sys>;
vcc2-supply = <&vcc5v0_sys>;
vcc3-supply = <&vcc5v0_sys>;
vcc4-supply = <&vcc5v0_sys>;
vcc5-supply = <&vcc3v3_sys>;
vcc6-supply = <&vcc3v3_sys>;
vcc7-supply = <&vcc3v3_sys>;
vcc8-supply = <&vcc3v3_sys>;
vcc9-supply = <&vcc5v0_sys>;
vcc5v0_sys: vccsys{
compatible = "regulator-fixed";
regulator-name = "vcc5v0_sys";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
};
rk817_pin0_ts: rk817_pin0_ts {
pins = "gpio0";
function = "pin_fun0";
};
rk817_pin0_gpio: rk817_pin0_gpio {
pins = "gpio0";
function = "gpio";
};
rk817_pin1_gt: rk817_pin1_gt {
pins = "gpio1";
function = "pin_fun0";
};
rk817_pin1_gpio: rk817_pin1_gpio {
pins = "gpio1";
function = "gpio";
};
regulators {
vdd_arm: DCDC_REG1 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-ramp-delay = <6001>;
regulator-name = "vdd_arm";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <700000>;
};
};
vdd_logic: DCDC_REG2 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-ramp-delay = <6001>;
regulator-name = "vdd_logic";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <800000>;
};
};
vcc_ddr: DCDC_REG3 {
regulator-always-on;
regulator-boot-on;
regulator-name = "vcc_ddr";
regulator-state-mem {
regulator-on-in-suspend;
};
};
vcc_3v0: DCDC_REG4 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-name = "vcc_3v0";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <3000000>;
};
};
vcc2v5_ddr: LDO_REG1 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <2500000>;
regulator-name = "vcc2v5_ddr";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <2500000>;
};
};
vcc1v8_soc: LDO_REG2 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc1v8_soc";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
vdd1v0_soc: LDO_REG3 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-name = "vcc1v0_soc";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <1000000>;
};
};
vcc3v0_pmu: LDO_REG4 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-name = "vcc3v0_pmu";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <3000000>;
};
};
vccio_sd: LDO_REG5 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vccio_sd";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <3300000>;
};
};
vcc_sd: LDO_REG6 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc_sd";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <3300000>;
};
};
vcc2v8_dvp: LDO_REG7 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-name = "vcc2v8_dvp";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <2800000>;
};
};
vcc1v8_dvp: LDO_REG8 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc1v8_dvp";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
vdd1v5_dvp: LDO_REG9 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
regulator-name = "vdd1v5_dvp";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <1500000>;
};
};
vcc3v3_sys: DCDC_REG5 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc3v3_sys";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <3300000>;
};
};
vcc3v3_lcd: SWITCH_REG1 {
regulator-always-on;
regulator-boot-on;
regulator-name = "vcc3v3_lcd";
};
vcc5v0_host: SWITCH_REG2 {
regulator-always-on;
regulator-boot-on;
regulator-name = "vcc5v0_host";
};
};
};

View File

@ -0,0 +1,288 @@
RK817 Power Management Integrated Circuit
Required properties:
- compatible: "rockchip,rk817"
- 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). See <dt-bindings/clock/rockchip,rk808.h> for clock IDs.
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.
- 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
- vcc7-supply: The input supply for LDO_REG7, LDO_REG8, LDO_REG9
- vcc8-supply: The input supply for BOOST
- vcc9-supply: The input supply for OTG_SWITCH
Regulators: All the regulators of RK817 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 RK817 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 RK808 datasheet.
- DCDC_REGn
- valid values for n are 1 to 4.
- LDO_REGn
- valid values for n are 1 to 9.
Standard regulator bindings are used inside regulator subnodes. Check
Documentation/devicetree/bindings/regulator/regulator.txt
for more details
Example:
rk817: pmic@20 {
compatible = "rockchip,rk817";
reg = <0x20>;
interrupt-parent = <&gpio0>;
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&pmic_int>;
rockchip,system-power-controller;
wakeup-source;
#clock-cells = <1>;
clock-output-names = "xin32k", "rk808-clkout2";
vcc1-supply = <&vccsys>;
vcc2-supply = <&vccsys>;
vcc3-supply = <&vccsys>;
vcc4-supply = <&vccsys>;
vcc5-supply = <&vccsys>;
vcc6-supply = <&vccsys>;
vcc7-supply = <&vccsys>;
vcc8-supply = <&vccsys>;
vcc9-supply = <&vccsys>;
vcc10-supply = <&vccsys>;
vcc11-supply = <&vcc_3v0>;
vcc12-supply = <&vcc_3v0>;
vcc13-supply = <&vcc_3v0>;
vcc14-supply = <&vccsys>;
vcc15-supply = <&rk817_boost>;
vccsys: vccsys{
compatible = "regulator-fixed";
regulator-name = "vcc3v8_sys";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3800000>;
regulator-max-microvolt = <3800000>;
};
rk817_pin0_ts: rk817_pin0_ts {
pins = "gpio0";
function = "pin_fun0";
};
rk817_pin0_gpio: rk817_pin0_gpio {
pins = "gpio0";
function = "gpio";
};
rk817_pin1_gt: rk817_pin1_gt {
pins = "gpio1";
function = "pin_fun0";
};
rk817_pin1_gpio: rk817_pin1_gpio {
pins = "gpio1";
function = "gpio";
};
regulators {
vdd_arm: DCDC_REG1 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-ramp-delay = <6001>;
regulator-name = "vdd_arm";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <700000>;
};
};
vdd_logic: DCDC_REG2 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-ramp-delay = <6001>;
regulator-name = "vdd_logic";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <800000>;
};
};
vcc_ddr: DCDC_REG3 {
regulator-always-on;
regulator-boot-on;
regulator-name = "vcc_ddr";
regulator-state-mem {
regulator-on-in-suspend;
};
};
vcc_3v0: DCDC_REG4 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-name = "vcc_3v0";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <3000000>;
};
};
vcc2v5_ddr: LDO_REG1 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <2500000>;
regulator-name = "vcc2v5_ddr";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <2500000>;
};
};
vcc1v8_soc: LDO_REG2 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc1v8_soc";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
vcc1v0_soc: LDO_REG3 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-name = "vcc1v0_soc";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <1000000>;
};
};
vcc3v0_pmu: LDO_REG4 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-name = "vcc3v0_pmu";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <3000000>;
};
};
vccio_sd: LDO_REG5 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vccio_sd";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <3300000>;
};
};
vcc_sd: LDO_REG6 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>; //??
regulator-max-microvolt = <3300000>;
regulator-name = "vcc_sd";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <3300000>;
};
};
vcc2v8_cif: LDO_REG7 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-name = "vcc2v8_cif";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <2800000>;
};
};
vcc1v8_cif: LDO_REG8 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc1v8_cif";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
vcc1v5_dvp: LDO_REG9 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
regulator-name = "vcc1v5_dvp";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <1500000>;
};
};
boost: BOOST {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <4700000>;
regulator-max-microvolt = <5400000>;
regulator-name = "boost";
};
otg_switch: OTG_SWITCH {
regulator-always-on;
regulator-boot-on;
regulator-name = "otg_switch";
};
};
};

View File

@ -85,6 +85,67 @@ static const struct clk_ops rk808_clkout2_ops = {
.recalc_rate = rk808_clkout_recalc_rate,
};
static int rk817_clkout2_enable(struct clk_hw *hw, bool enable)
{
struct rk808_clkout *rk808_clkout = container_of(hw,
struct rk808_clkout,
clkout2_hw);
struct rk808 *rk808 = rk808_clkout->rk808;
return regmap_update_bits(rk808->regmap, RK817_SYS_CFG(1),
RK817_CLK32KOUT2_EN,
enable ? RK817_CLK32KOUT2_EN : 0);
}
static int rk817_clkout2_prepare(struct clk_hw *hw)
{
return rk817_clkout2_enable(hw, true);
}
static void rk817_clkout2_unprepare(struct clk_hw *hw)
{
rk817_clkout2_enable(hw, false);
}
static int rk817_clkout2_is_prepared(struct clk_hw *hw)
{
struct rk808_clkout *rk808_clkout = container_of(hw,
struct rk808_clkout,
clkout2_hw);
struct rk808 *rk808 = rk808_clkout->rk808;
unsigned int val;
int ret = regmap_read(rk808->regmap, RK817_SYS_CFG(1), &val);
if (ret < 0)
return ret;
return (val & RK817_CLK32KOUT2_EN) ? 1 : 0;
}
static const struct clk_ops rk817_clkout2_ops = {
.prepare = rk817_clkout2_prepare,
.unprepare = rk817_clkout2_unprepare,
.is_prepared = rk817_clkout2_is_prepared,
.recalc_rate = rk808_clkout_recalc_rate,
};
static const struct clk_ops *rkpmic_get_ops(long variant)
{
switch (variant) {
case RK809_ID:
case RK817_ID:
return &rk817_clkout2_ops;
case RK805_ID:
case RK808_ID:
case RK816_ID:
case RK818_ID:
return &rk808_clkout2_ops;
}
return &rk808_clkout2_ops;
}
static int rk808_clkout_probe(struct platform_device *pdev)
{
struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
@ -123,7 +184,7 @@ static int rk808_clkout_probe(struct platform_device *pdev)
return PTR_ERR(clk_table[0]);
init.name = "rk808-clkout2";
init.ops = &rk808_clkout2_ops;
init.ops = rkpmic_get_ops(rk808->variant);
rk808_clkout->clkout2_hw.init = &init;
/* optional override of the clockname */

View File

@ -61,6 +61,29 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
return false;
}
static bool rk817_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 RK817_SECONDS_REG ... RK817_WEEKS_REG:
case RK817_RTC_STATUS_REG:
case RK817_INT_STS_REG0:
case RK817_INT_STS_REG1:
case RK817_INT_STS_REG2:
case RK817_SYS_STS:
return true;
}
return true;
}
static int rk808_shutdown(struct regmap *regmap)
{
int ret;
@ -110,6 +133,25 @@ static int rk805_shutdown_prepare(struct regmap *regmap)
return ret;
}
static int rk817_shutdown_prepare(struct regmap *regmap)
{
int ret;
/* close rtc int when power off */
regmap_update_bits(regmap,
RK817_INT_STS_MSK_REG1,
(0x3 << 5), (0x3 << 5));
regmap_update_bits(regmap,
RK817_RTC_INT_REG,
(0x3 << 2), (0x0 << 2));
/* pmic sleep shutdown function */
ret = regmap_update_bits(regmap,
RK817_SYS_CFG(3),
RK817_SLPPIN_FUNC_MSK, SHUTDOWN_FUN);
return ret;
}
static bool rk818_is_volatile_reg(struct device *dev, unsigned int reg)
{
/*
@ -176,6 +218,14 @@ static const struct regmap_config rk818_regmap_config = {
.volatile_reg = rk818_is_volatile_reg,
};
static const struct regmap_config rk817_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = RK817_GPIO_INT_CFG,
.cache_type = REGCACHE_NONE,
.volatile_reg = rk817_is_volatile_reg,
};
static struct resource rtc_resources[] = {
{
.start = RK808_IRQ_RTC_ALARM,
@ -184,6 +234,14 @@ static struct resource rtc_resources[] = {
}
};
static struct resource rk817_rtc_resources[] = {
{
.start = RK817_IRQ_RTC_ALARM,
.end = RK817_IRQ_RTC_ALARM,
.flags = IORESOURCE_IRQ,
}
};
static struct resource rk816_rtc_resources[] = {
{
.start = RK816_IRQ_RTC_ALARM,
@ -192,7 +250,7 @@ static struct resource rk816_rtc_resources[] = {
}
};
static struct resource pwrkey_resources[] = {
static struct resource rk805_pwrkey_resources[] = {
{
.start = RK805_IRQ_PWRON_RISE,
.end = RK805_IRQ_PWRON_RISE,
@ -205,6 +263,19 @@ static struct resource pwrkey_resources[] = {
},
};
static struct resource rk817_pwrkey_resources[] = {
{
.start = RK817_IRQ_PWRON_RISE,
.end = RK817_IRQ_PWRON_RISE,
.flags = IORESOURCE_IRQ,
},
{
.start = RK817_IRQ_PWRON_FALL,
.end = RK817_IRQ_PWRON_FALL,
.flags = IORESOURCE_IRQ,
},
};
static struct resource rk816_pwrkey_resources[] = {
{
.start = RK816_IRQ_PWRON_RISE,
@ -609,8 +680,8 @@ static const struct mfd_cell rk805s[] = {
{ .name = "rk8xx-gpio", },
{
.name = "rk8xx-pwrkey",
.num_resources = ARRAY_SIZE(pwrkey_resources),
.resources = &pwrkey_resources[0],
.num_resources = ARRAY_SIZE(rk805_pwrkey_resources),
.resources = &rk805_pwrkey_resources[0],
},
{
.name = "rk808-rtc",
@ -635,6 +706,83 @@ static struct rk808_reg_data rk805_resume_reg[] = {
{RK805_BUCK3_CONFIG_REG, PWM_MODE_MSK, FPWM_MODE},
};
#define REGMAP_IRQ_M(_id) \
[_id] = { \
.mask = BIT(((_id) % 8)), \
.reg_offset = ((_id) / 8), \
}
static const struct regmap_irq rk817_irqs[RK817_IRQ_END] = {
REGMAP_IRQ_M(0),
REGMAP_IRQ_M(1),
REGMAP_IRQ_M(2),
REGMAP_IRQ_M(3),
REGMAP_IRQ_M(4),
REGMAP_IRQ_M(5),
REGMAP_IRQ_M(6),
REGMAP_IRQ_M(7),
REGMAP_IRQ_M(8),
REGMAP_IRQ_M(9),
REGMAP_IRQ_M(10),
REGMAP_IRQ_M(11),
REGMAP_IRQ_M(12),
REGMAP_IRQ_M(13),
REGMAP_IRQ_M(14),
REGMAP_IRQ_M(15),
REGMAP_IRQ_M(16),
REGMAP_IRQ_M(17),
REGMAP_IRQ_M(18),
REGMAP_IRQ_M(19),
REGMAP_IRQ_M(20),
REGMAP_IRQ_M(21),
REGMAP_IRQ_M(22),
REGMAP_IRQ_M(23)
};
static struct regmap_irq_chip rk817_irq_chip = {
.name = "rk817",
.irqs = rk817_irqs,
.num_irqs = ARRAY_SIZE(rk817_irqs),
.num_regs = 3,
.irq_reg_stride = 2,
.status_base = RK817_INT_STS_REG0,
.mask_base = RK817_INT_STS_MSK_REG0,
.ack_base = RK817_INT_STS_REG0,
.init_ack_masked = true,
};
static const struct mfd_cell rk817s[] = {
{ .name = "rk808-clkout",},
{ .name = "rk808-regulator",},
{ .name = "rk805-pinctrl", },
{
.name = "rk8xx-pwrkey",
.num_resources = ARRAY_SIZE(rk817_pwrkey_resources),
.resources = &rk817_pwrkey_resources[0],
},
{
.name = "rk808-rtc",
.num_resources = ARRAY_SIZE(rk817_rtc_resources),
.resources = &rk817_rtc_resources[0],
},
};
static const struct rk808_reg_data rk817_pre_init_reg[] = {
{RK817_SYS_CFG(3), RK817_SLPPIN_FUNC_MSK, SLPPIN_SLP_FUN},
{RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
{RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_L},
{RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK,
RK817_HOTDIE_105 | RK817_TSD_140},
};
static struct rk808_reg_data rk817_suspend_reg[] = {
{RK817_BUCK3_ON_VSEL_REG, PWM_MODE_MSK, AUTO_PWM_MODE},
};
static struct rk808_reg_data rk817_resume_reg[] = {
{RK817_BUCK3_ON_VSEL_REG, PWM_MODE_MSK, FPWM_MODE},
};
static int (*pm_shutdown)(struct regmap *regmap);
static int (*pm_shutdown_prepare)(struct regmap *regmap);
static struct i2c_client *rk808_i2c_client;
@ -758,7 +906,9 @@ static struct device_attribute rk8xx_attrs =
static const struct of_device_id rk808_of_match[] = {
{ .compatible = "rockchip,rk805" },
{ .compatible = "rockchip,rk808" },
{ .compatible = "rockchip,rk809" },
{ .compatible = "rockchip,rk816" },
{ .compatible = "rockchip,rk817" },
{ .compatible = "rockchip,rk818" },
{ },
};
@ -780,6 +930,7 @@ static int rk808_probe(struct i2c_client *client,
int msb, lsb, reg_num, cell_num;
int ret, i, pm_off = 0;
unsigned int on, off;
u8 pmic_id_msb = RK808_ID_MSB, pmic_id_lsb = RK808_ID_LSB;
if (!client->irq) {
dev_err(&client->dev, "No interrupt support, no core IRQ\n");
@ -790,15 +941,19 @@ static int rk808_probe(struct i2c_client *client,
if (!rk808)
return -ENOMEM;
if (of_device_is_compatible(np, "rockchip,rk817")) {
pmic_id_msb = RK817_ID_MSB;
pmic_id_lsb = RK817_ID_LSB;
}
/* read Chip variant */
msb = i2c_smbus_read_byte_data(client, RK808_ID_MSB);
msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
if (msb < 0) {
dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
RK808_ID_MSB);
return msb;
}
lsb = i2c_smbus_read_byte_data(client, RK808_ID_LSB);
lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
if (lsb < 0) {
dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
RK808_ID_LSB);
@ -865,6 +1020,22 @@ static int rk808_probe(struct i2c_client *client,
resume_reg = rk805_resume_reg;
resume_reg_num = ARRAY_SIZE(rk805_resume_reg);
break;
case RK809_ID:
case RK817_ID:
cell = rk817s;
cell_num = ARRAY_SIZE(rk817s);
pre_init_reg = rk817_pre_init_reg;
reg_num = ARRAY_SIZE(rk817_pre_init_reg);
regmap_config = &rk817_regmap_config;
irq_chip = &rk817_irq_chip;
pm_shutdown_prepare_fn = rk817_shutdown_prepare;
on_source = RK817_ON_SOURCE_REG;
off_source = RK817_OFF_SOURCE_REG;
suspend_reg = rk817_suspend_reg;
suspend_reg_num = ARRAY_SIZE(rk817_suspend_reg);
resume_reg = rk817_resume_reg;
resume_reg_num = ARRAY_SIZE(rk817_resume_reg);
break;
default:
dev_err(&client->dev, "unsupported RK8XX ID 0x%lx\n",
rk808->variant);
@ -942,7 +1113,7 @@ static int rk808_probe(struct i2c_client *client,
}
pm_off = of_property_read_bool(np,
"rockchip,system-power-controller");
"rockchip,system-power-controller");
if (pm_off) {
if (pm_shutdown_prepare_fn) {
pm_shutdown_prepare = pm_shutdown_prepare_fn;
@ -1033,7 +1204,9 @@ static const struct dev_pm_ops rk808_pm_ops = {
static const struct i2c_device_id rk808_ids[] = {
{ "rk805" },
{ "rk808" },
{ "rk809" },
{ "rk816" },
{ "rk817" },
{ "rk818" },
{ },
};

View File

@ -114,6 +114,53 @@
.ops = &rk808_reg_ops, \
}
#define RK817_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 = &rk817_reg_ops, \
}
#define RK817_BOOST_DESC(_id, _match, _supply, _min, _max, _step, _vreg,\
_vmask, _ereg, _emask, _enval, _disval, _etime, m_drop) \
[_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), \
.min_dropout_uV = (m_drop) * 1000, \
.ops = &rk817_boost_ops, \
}
#define RK8XX_DESC_SWITCH(_id, _match, _supply, _ereg, _emask) \
[_id] = { \
.name = (_match), \
@ -128,6 +175,22 @@
.ops = &rk808_switch_ops \
}
#define RK817_DESC_SWITCH(_id, _match, _supply, _ereg, _emask,\
_enval, _disval) \
[_id] = { \
.name = (_match), \
.supply_name = (_supply), \
.of_match = of_match_ptr(_match), \
.regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \
.id = (_id), \
.enable_reg = (_ereg), \
.enable_mask = (_emask), \
.enable_val = (_enval), \
.disable_val = (_disval), \
.owner = THIS_MODULE, \
.ops = &rk817_switch_ops \
}
struct rk808_regulator_data {
struct gpio_desc *dvs_gpio[2];
@ -156,6 +219,51 @@ static const struct regulator_linear_range rk816_buck4_voltage_ranges[] = {
REGULATOR_LINEAR_RANGE(3500000, 27, 31, 0), /* 3.5v */
};
#define RK817_BUCK1_MIN0 500000
#define RK817_BUCK1_MAX0 1500000
#define RK817_BUCK1_MIN1 1600000
#define RK817_BUCK1_MAX1 2400000
#define RK817_BUCK3_MAX1 3400000
#define RK817_BUCK1_STP0 12500
#define RK817_BUCK1_STP1 100000
#define RK817_BUCK1_SEL0 ((RK817_BUCK1_MAX0 - RK817_BUCK1_MIN0) /\
RK817_BUCK1_STP0)
#define RK817_BUCK1_SEL1 ((RK817_BUCK1_MAX1 - RK817_BUCK1_MIN1) /\
RK817_BUCK1_STP1)
#define RK817_BUCK3_SEL1 ((RK817_BUCK3_MAX1 - RK817_BUCK1_MIN1) /\
RK817_BUCK1_STP1)
#define RK817_BUCK1_SEL_CNT (RK817_BUCK1_SEL0 + RK817_BUCK1_SEL1 + 1)
#define RK817_BUCK3_SEL_CNT (RK817_BUCK1_SEL0 + RK817_BUCK3_SEL1 + 1)
static const struct regulator_linear_range rk817_buck1_voltage_ranges[] = {
REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN0, 0,
RK817_BUCK1_SEL0, RK817_BUCK1_STP0),
REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN1, RK817_BUCK1_SEL0 + 1,
RK817_BUCK1_SEL_CNT, RK817_BUCK1_STP1),
};
static const struct regulator_linear_range rk817_buck3_voltage_ranges[] = {
REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN0, 0,
RK817_BUCK1_SEL0, RK817_BUCK1_STP0),
REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN1, RK817_BUCK1_SEL0 + 1,
RK817_BUCK3_SEL_CNT, RK817_BUCK1_STP1),
};
#define RK809_BUCK5_SEL_CNT (8)
static const struct regulator_linear_range rk809_buck5_voltage_ranges[] = {
REGULATOR_LINEAR_RANGE(1500000, 0, 0, 0),
REGULATOR_LINEAR_RANGE(1800000, 1, 3, 200000),
REGULATOR_LINEAR_RANGE(2800000, 4, 5, 200000),
REGULATOR_LINEAR_RANGE(3300000, 6, 7, 300000),
};
static unsigned int rk8xx_regulator_of_map_mode(unsigned int mode)
{
if (mode == 1)
@ -309,8 +417,8 @@ static int rk808_buck1_2_set_voltage_sel(struct regulator_dev *rdev,
}
static int rk808_buck1_2_set_voltage_time_sel(struct regulator_dev *rdev,
unsigned int old_selector,
unsigned int new_selector)
unsigned int old_selector,
unsigned int new_selector)
{
struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
@ -349,6 +457,35 @@ static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
RK808_RAMP_RATE_MASK, ramp_value);
}
/*
* RK817 RK809
*/
static int rk817_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
unsigned int ramp_value = RK817_RAMP_RATE_25MV_PER_US;
unsigned int reg = RK817_BUCK_CONFIG_REG(rdev_get_id(rdev));
switch (ramp_delay) {
case 0 ... 3000:
ramp_value = RK817_RAMP_RATE_3MV_PER_US;
break;
case 3001 ... 6300:
ramp_value = RK817_RAMP_RATE_6_3MV_PER_US;
break;
case 6301 ... 12500:
ramp_value = RK817_RAMP_RATE_12_5MV_PER_US;
break;
case 12501 ... 25000:
break;
default:
pr_warn("%s ramp_delay: %d not supported, setting 10000\n",
rdev->desc->name, ramp_delay);
}
return regmap_update_bits(rdev->regmap, reg,
RK817_RAMP_RATE_MASK, ramp_value);
}
static int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
{
unsigned int reg;
@ -364,6 +501,29 @@ static int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
sel);
}
static int rk817_check_suspend_voltage(int id)
{
if (id >= RK817_ID_DCDC1 && id <= RK817_ID_LDO9)
return 0;
return -1;
}
static int rk817_set_suspend_voltage(struct regulator_dev *rdev, int uv)
{
unsigned int reg;
int id = rdev_get_id(rdev);
int sel = regulator_map_voltage_linear(rdev, uv, uv);
/* only ldo1~ldo9 */
if (sel < 0 || rk817_check_suspend_voltage(id))
return -EINVAL;
reg = rdev->desc->vsel_reg + RK808_SLP_REG_OFFSET;
return regmap_update_bits(rdev->regmap, reg,
rdev->desc->vsel_mask,
sel);
}
static int rk808_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
{
unsigned int reg;
@ -457,6 +617,43 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
rdev->desc->enable_mask);
}
static int rk817_set_suspend_enable_ctrl(struct regulator_dev *rdev,
unsigned int en)
{
unsigned int reg;
int id = rdev_get_id(rdev);
unsigned int id_slp, msk, val;
if (id >= RK817_ID_DCDC1 && id <= RK817_ID_DCDC4)
id_slp = id;
else if (id >= RK817_ID_LDO1 && id <= RK817_ID_LDO8)
id_slp = 8 + (id - RK817_ID_LDO1);
else if (id >= RK817_ID_LDO9 && id <= RK809_ID_SW2)
id_slp = 4 + (id - RK817_ID_LDO9);
else
return -EINVAL;
reg = RK817_POWER_SLP_EN_REG(id_slp / 8);
msk = BIT(id_slp % 8);
if (en)
val = msk;
else
val = 0;
return regmap_update_bits(rdev->regmap, reg, msk, val);
}
static int rk817_set_suspend_enable(struct regulator_dev *rdev)
{
return rk817_set_suspend_enable_ctrl(rdev, 1);
}
static int rk817_set_suspend_disable(struct regulator_dev *rdev)
{
return rk817_set_suspend_enable_ctrl(rdev, 0);
}
static int rk8xx_set_suspend_mode(struct regulator_dev *rdev, unsigned int mode)
{
unsigned int reg;
@ -510,6 +707,29 @@ static unsigned int rk8xx_get_mode(struct regulator_dev *rdev)
return REGULATOR_MODE_NORMAL;
}
int rk8xx_is_enabled_wmsk_regmap(struct regulator_dev *rdev)
{
unsigned int val;
int ret;
ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
if (ret != 0)
return ret;
/* add write mask bit */
val |= (rdev->desc->enable_mask & 0xf0);
val &= rdev->desc->enable_mask;
if (rdev->desc->enable_is_inverted) {
if (rdev->desc->enable_val)
return val != rdev->desc->enable_val;
return (val == 0);
}
if (rdev->desc->enable_val)
return val == rdev->desc->enable_val;
return val != 0;
}
static struct regulator_ops rk808_buck1_2_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
@ -546,6 +766,38 @@ static struct regulator_ops rk8xx_buck_ops_range = {
.set_suspend_disable = rk808_set_suspend_disable,
};
static struct regulator_ops rk817_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 = rk8xx_is_enabled_wmsk_regmap,
.set_mode = rk8xx_set_mode,
.get_mode = rk8xx_get_mode,
.set_suspend_mode = rk8xx_set_suspend_mode,
.set_ramp_delay = rk817_set_ramp_delay,
.set_suspend_voltage = rk808_set_suspend_voltage_range,
.set_suspend_enable = rk817_set_suspend_enable,
.set_suspend_disable = rk817_set_suspend_disable,
};
static struct regulator_ops rk809_buck5_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 = rk8xx_is_enabled_wmsk_regmap,
.set_suspend_voltage = rk808_set_suspend_voltage_range,
.set_suspend_enable = rk817_set_suspend_enable,
.set_suspend_disable = rk817_set_suspend_disable,
};
static struct regulator_ops rk808_reg_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
@ -562,6 +814,31 @@ static struct regulator_ops rk808_reg_ops = {
.set_suspend_disable = rk808_set_suspend_disable,
};
static struct regulator_ops rk817_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 = rk8xx_is_enabled_wmsk_regmap,
.set_suspend_voltage = rk817_set_suspend_voltage,
.set_suspend_enable = rk817_set_suspend_enable,
.set_suspend_disable = rk817_set_suspend_disable,
};
static struct regulator_ops rk817_boost_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 = rk8xx_is_enabled_wmsk_regmap,
.set_suspend_enable = rk817_set_suspend_enable,
.set_suspend_disable = rk817_set_suspend_disable,
};
static struct regulator_ops rk808_reg_ops_ranges = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
@ -589,6 +866,14 @@ static struct regulator_ops rk808_switch_ops = {
.set_suspend_mode = rk8xx_set_suspend_mode,
};
static struct regulator_ops rk817_switch_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_suspend_enable = rk817_set_suspend_enable,
.set_suspend_disable = rk817_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,
@ -903,10 +1188,284 @@ static const struct regulator_desc rk818_reg[] = {
RK818_DCDC_EN_REG, BIT(7)),
};
#define RK817_LDO_VSEL_MASK 0x7f
#define RK817_BOOST_VSEL_MASK 0x7
#define RK817_BUCK_VSEL_MASK 0x7f
#define RK809_BUCK5_VSEL_MASK 0x7
#define ENABLE_MASK(id) (BIT(id) | BIT(4 + (id)))
#define DISABLE_VAL(id) (BIT(4 + (id)))
static const struct regulator_desc rk817_reg[] = {
{
.name = "DCDC_REG1",
.supply_name = "vcc1",
.of_match = of_match_ptr("DCDC_REG1"),
.regulators_node = of_match_ptr("regulators"),
.id = RK817_ID_DCDC1,
.ops = &rk817_buck_ops_range,
.type = REGULATOR_VOLTAGE,
.n_voltages = RK817_BUCK1_SEL_CNT + 1,
.linear_ranges = rk817_buck1_voltage_ranges,
.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
.vsel_reg = RK817_BUCK1_ON_VSEL_REG,
.vsel_mask = RK817_BUCK_VSEL_MASK,
.enable_reg = RK817_POWER_EN_REG(0),
.enable_mask = ENABLE_MASK(RK817_ID_DCDC1),
.enable_val = ENABLE_MASK(RK817_ID_DCDC1),
.disable_val = DISABLE_VAL(RK817_ID_DCDC1),
.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 = RK817_ID_DCDC2,
.ops = &rk817_buck_ops_range,
.type = REGULATOR_VOLTAGE,
.n_voltages = RK817_BUCK1_SEL_CNT + 1,
.linear_ranges = rk817_buck1_voltage_ranges,
.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
.vsel_reg = RK817_BUCK2_ON_VSEL_REG,
.vsel_mask = RK817_BUCK_VSEL_MASK,
.enable_reg = RK817_POWER_EN_REG(0),
.enable_mask = ENABLE_MASK(RK817_ID_DCDC2),
.enable_val = ENABLE_MASK(RK817_ID_DCDC2),
.disable_val = DISABLE_VAL(RK817_ID_DCDC2),
.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 = RK817_ID_DCDC3,
.ops = &rk817_buck_ops_range,
.type = REGULATOR_VOLTAGE,
.n_voltages = RK817_BUCK1_SEL_CNT + 1,
.linear_ranges = rk817_buck1_voltage_ranges,
.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
.vsel_reg = RK817_BUCK3_ON_VSEL_REG,
.vsel_mask = RK817_BUCK_VSEL_MASK,
.enable_reg = RK817_POWER_EN_REG(0),
.enable_mask = ENABLE_MASK(RK817_ID_DCDC3),
.enable_val = ENABLE_MASK(RK817_ID_DCDC3),
.disable_val = DISABLE_VAL(RK817_ID_DCDC3),
.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 = RK817_ID_DCDC4,
.ops = &rk817_buck_ops_range,
.type = REGULATOR_VOLTAGE,
.n_voltages = RK817_BUCK3_SEL_CNT + 1,
.linear_ranges = rk817_buck3_voltage_ranges,
.n_linear_ranges = ARRAY_SIZE(rk817_buck3_voltage_ranges),
.vsel_reg = RK817_BUCK4_ON_VSEL_REG,
.vsel_mask = RK817_BUCK_VSEL_MASK,
.enable_reg = RK817_POWER_EN_REG(0),
.enable_mask = ENABLE_MASK(RK817_ID_DCDC4),
.enable_val = ENABLE_MASK(RK817_ID_DCDC4),
.disable_val = DISABLE_VAL(RK817_ID_DCDC4),
.of_map_mode = rk8xx_regulator_of_map_mode,
.owner = THIS_MODULE,
},
RK817_DESC(RK817_ID_LDO1, "LDO_REG1", "vcc5", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(0), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(1), ENABLE_MASK(0), ENABLE_MASK(0),
DISABLE_VAL(0), 400),
RK817_DESC(RK817_ID_LDO2, "LDO_REG2", "vcc5", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(1), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(1), ENABLE_MASK(1), ENABLE_MASK(1),
DISABLE_VAL(1), 400),
RK817_DESC(RK817_ID_LDO3, "LDO_REG3", "vcc5", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(2), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(1), ENABLE_MASK(2), ENABLE_MASK(2),
DISABLE_VAL(2), 400),
RK817_DESC(RK817_ID_LDO4, "LDO_REG4", "vcc6", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(3), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(1), ENABLE_MASK(3), ENABLE_MASK(3),
DISABLE_VAL(3), 400),
RK817_DESC(RK817_ID_LDO5, "LDO_REG5", "vcc6", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(4), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(2), ENABLE_MASK(0), ENABLE_MASK(0),
DISABLE_VAL(0), 400),
RK817_DESC(RK817_ID_LDO6, "LDO_REG6", "vcc6", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(5), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(2), ENABLE_MASK(1), ENABLE_MASK(1),
DISABLE_VAL(1), 400),
RK817_DESC(RK817_ID_LDO7, "LDO_REG7", "vcc7", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(6), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(2), ENABLE_MASK(2), ENABLE_MASK(2),
DISABLE_VAL(2), 400),
RK817_DESC(RK817_ID_LDO8, "LDO_REG8", "vcc7", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(7), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(2), ENABLE_MASK(3), ENABLE_MASK(3),
DISABLE_VAL(3), 400),
RK817_DESC(RK817_ID_LDO9, "LDO_REG9", "vcc7", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(8), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(3), ENABLE_MASK(0), ENABLE_MASK(0),
DISABLE_VAL(0), 400),
RK817_BOOST_DESC(RK817_ID_BOOST, "BOOST", "vcc8", 4700, 5400, 100,
RK817_BOOST_OTG_CFG, RK817_BOOST_VSEL_MASK,
RK817_POWER_EN_REG(3), ENABLE_MASK(1), ENABLE_MASK(1),
DISABLE_VAL(1), 400, 3500 - 5400),
RK817_DESC_SWITCH(RK817_ID_BOOST_OTG_SW, "OTG_SWITCH", "vcc9",
RK817_POWER_EN_REG(3), ENABLE_MASK(2),
ENABLE_MASK(2), DISABLE_VAL(2)),
};
static const struct regulator_desc rk809_reg[] = {
{
.name = "DCDC_REG1",
.supply_name = "vcc1",
.of_match = of_match_ptr("DCDC_REG1"),
.regulators_node = of_match_ptr("regulators"),
.id = RK817_ID_DCDC1,
.ops = &rk817_buck_ops_range,
.type = REGULATOR_VOLTAGE,
.n_voltages = RK817_BUCK1_SEL_CNT + 1,
.linear_ranges = rk817_buck1_voltage_ranges,
.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
.vsel_reg = RK817_BUCK1_ON_VSEL_REG,
.vsel_mask = RK817_BUCK_VSEL_MASK,
.enable_reg = RK817_POWER_EN_REG(0),
.enable_mask = ENABLE_MASK(RK817_ID_DCDC1),
.enable_val = ENABLE_MASK(RK817_ID_DCDC1),
.disable_val = DISABLE_VAL(RK817_ID_DCDC1),
.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 = RK817_ID_DCDC2,
.ops = &rk817_buck_ops_range,
.type = REGULATOR_VOLTAGE,
.n_voltages = RK817_BUCK1_SEL_CNT + 1,
.linear_ranges = rk817_buck1_voltage_ranges,
.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
.vsel_reg = RK817_BUCK2_ON_VSEL_REG,
.vsel_mask = RK817_BUCK_VSEL_MASK,
.enable_reg = RK817_POWER_EN_REG(0),
.enable_mask = ENABLE_MASK(RK817_ID_DCDC2),
.enable_val = ENABLE_MASK(RK817_ID_DCDC2),
.disable_val = DISABLE_VAL(RK817_ID_DCDC2),
.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 = RK817_ID_DCDC3,
.ops = &rk817_buck_ops_range,
.type = REGULATOR_VOLTAGE,
.n_voltages = RK817_BUCK1_SEL_CNT + 1,
.linear_ranges = rk817_buck1_voltage_ranges,
.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
.vsel_reg = RK817_BUCK3_ON_VSEL_REG,
.vsel_mask = RK817_BUCK_VSEL_MASK,
.enable_reg = RK817_POWER_EN_REG(0),
.enable_mask = ENABLE_MASK(RK817_ID_DCDC3),
.enable_val = ENABLE_MASK(RK817_ID_DCDC3),
.disable_val = DISABLE_VAL(RK817_ID_DCDC3),
.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 = RK817_ID_DCDC4,
.ops = &rk817_buck_ops_range,
.type = REGULATOR_VOLTAGE,
.n_voltages = RK817_BUCK3_SEL_CNT + 1,
.linear_ranges = rk817_buck3_voltage_ranges,
.n_linear_ranges = ARRAY_SIZE(rk817_buck3_voltage_ranges),
.vsel_reg = RK817_BUCK4_ON_VSEL_REG,
.vsel_mask = RK817_BUCK_VSEL_MASK,
.enable_reg = RK817_POWER_EN_REG(0),
.enable_mask = ENABLE_MASK(RK817_ID_DCDC4),
.enable_val = ENABLE_MASK(RK817_ID_DCDC4),
.disable_val = DISABLE_VAL(RK817_ID_DCDC4),
.of_map_mode = rk8xx_regulator_of_map_mode,
.owner = THIS_MODULE,
},
RK817_DESC(RK817_ID_LDO1, "LDO_REG1", "vcc5", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(0), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(1), ENABLE_MASK(0), ENABLE_MASK(0),
DISABLE_VAL(0), 400),
RK817_DESC(RK817_ID_LDO2, "LDO_REG2", "vcc5", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(1), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(1), ENABLE_MASK(1), ENABLE_MASK(1),
DISABLE_VAL(1), 400),
RK817_DESC(RK817_ID_LDO3, "LDO_REG3", "vcc5", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(2), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(1), ENABLE_MASK(2), ENABLE_MASK(2),
DISABLE_VAL(2), 400),
RK817_DESC(RK817_ID_LDO4, "LDO_REG4", "vcc6", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(3), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(1), ENABLE_MASK(3), ENABLE_MASK(3),
DISABLE_VAL(3), 400),
RK817_DESC(RK817_ID_LDO5, "LDO_REG5", "vcc6", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(4), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(2), ENABLE_MASK(0), ENABLE_MASK(0),
DISABLE_VAL(0), 400),
RK817_DESC(RK817_ID_LDO6, "LDO_REG6", "vcc6", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(5), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(2), ENABLE_MASK(1), ENABLE_MASK(1),
DISABLE_VAL(1), 400),
RK817_DESC(RK817_ID_LDO7, "LDO_REG7", "vcc7", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(6), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(2), ENABLE_MASK(2), ENABLE_MASK(2),
DISABLE_VAL(2), 400),
RK817_DESC(RK817_ID_LDO8, "LDO_REG8", "vcc7", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(7), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(2), ENABLE_MASK(3), ENABLE_MASK(3),
DISABLE_VAL(3), 400),
RK817_DESC(RK817_ID_LDO9, "LDO_REG9", "vcc7", 600, 3400, 25,
RK817_LDO_ON_VSEL_REG(8), RK817_LDO_VSEL_MASK,
RK817_POWER_EN_REG(3), ENABLE_MASK(0), ENABLE_MASK(0),
DISABLE_VAL(0), 400),
{
.name = "DCDC_REG5",
.supply_name = "vcc9",
.of_match = of_match_ptr("DCDC_REG5"),
.regulators_node = of_match_ptr("regulators"),
.id = RK809_ID_DCDC5,
.ops = &rk809_buck5_ops_range,
.type = REGULATOR_VOLTAGE,
.n_voltages = RK809_BUCK5_SEL_CNT,
.linear_ranges = rk809_buck5_voltage_ranges,
.n_linear_ranges = ARRAY_SIZE(rk809_buck5_voltage_ranges),
.vsel_reg = RK809_BUCK5_CONFIG(0),
.vsel_mask = RK809_BUCK5_VSEL_MASK,
.enable_reg = RK817_POWER_EN_REG(3),
.enable_mask = ENABLE_MASK(1),
.enable_val = ENABLE_MASK(1),
.disable_val = DISABLE_VAL(1),
.of_map_mode = rk8xx_regulator_of_map_mode,
.owner = THIS_MODULE,
},
RK817_DESC_SWITCH(RK809_ID_SW1, "SWITCH_REG1", "vcc8",
RK817_POWER_EN_REG(3), ENABLE_MASK(2),
ENABLE_MASK(2), DISABLE_VAL(2)),
RK817_DESC_SWITCH(RK809_ID_SW2, "SWITCH_REG2", "vcc9",
RK817_POWER_EN_REG(3), ENABLE_MASK(3),
ENABLE_MASK(3), DISABLE_VAL(3)),
};
static int rk808_regulator_dt_parse_pdata(struct device *dev,
struct device *client_dev,
struct regmap *map,
struct rk808_regulator_data *pdata)
struct device *client_dev,
struct regmap *map,
struct rk808_regulator_data *pdata)
{
struct device_node *np;
int tmp, ret = 0, i;
@ -967,6 +1526,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
regulators = rk808_reg;
nregulators = RK808_NUM_REGULATORS;
break;
case RK809_ID:
regulators = rk809_reg;
nregulators = RK809_NUM_REGULATORS;
break;
case RK818_ID:
regulators = rk818_reg;
nregulators = RK818_NUM_REGULATORS;
@ -975,6 +1538,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
regulators = rk816_reg;
nregulators = RK816_NUM_REGULATORS;
break;
case RK817_ID:
regulators = rk817_reg;
nregulators = RK817_NUM_REGULATORS;
break;
default:
dev_err(&client->dev, "unsupported RK8XX ID %lu\n",
rk808->variant);

View File

@ -50,9 +50,18 @@
#define NUM_TIME_REGS (RK808_WEEKS_REG - RK808_SECONDS_REG + 1)
#define NUM_ALARM_REGS (RK808_ALARM_YEARS_REG - RK808_ALARM_SECONDS_REG + 1)
struct rk_rtc_compat_reg {
unsigned int ctrl_reg;
unsigned int status_reg;
unsigned int alarm_seconds_reg;
unsigned int int_reg;
unsigned int seconds_reg;
};
struct rk808_rtc {
struct rk808 *rk808;
struct rtc_device *rtc;
struct rk_rtc_compat_reg *creg;
int irq;
};
@ -81,6 +90,7 @@ static void gregorian_to_rockchip(struct rtc_time *tm)
{
time64_t extra_days = nov2dec_transitions(tm);
time64_t time = rtc_tm_to_time64(tm);
rtc_time64_to_tm(time - extra_days * 86400, tm);
/* Compensate if we went back over Nov 31st (will work up to 2381) */
@ -101,7 +111,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
int ret;
/* Force an update of the shadowed registers right now */
ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
BIT_RTC_CTRL_REG_RTC_GET_TIME,
BIT_RTC_CTRL_REG_RTC_GET_TIME);
if (ret) {
@ -115,7 +125,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
* 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
* certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
*/
ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
BIT_RTC_CTRL_REG_RTC_GET_TIME,
0);
if (ret) {
@ -123,7 +133,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
return ret;
}
ret = regmap_bulk_read(rk808->regmap, RK808_SECONDS_REG,
ret = regmap_bulk_read(rk808->regmap, rk808_rtc->creg->seconds_reg,
rtc_data, NUM_TIME_REGS);
if (ret) {
dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret);
@ -166,7 +176,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
rtc_data[6] = bin2bcd(tm->tm_wday);
/* Stop RTC while updating the RTC registers */
ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
BIT_RTC_CTRL_REG_STOP_RTC_M,
BIT_RTC_CTRL_REG_STOP_RTC_M);
if (ret) {
@ -174,14 +184,14 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
return ret;
}
ret = regmap_bulk_write(rk808->regmap, RK808_SECONDS_REG,
ret = regmap_bulk_write(rk808->regmap, rk808_rtc->creg->seconds_reg,
rtc_data, NUM_TIME_REGS);
if (ret) {
dev_err(dev, "Failed to bull write rtc_data: %d\n", ret);
return ret;
}
/* Start RTC again */
ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
if (ret) {
dev_err(dev, "Failed to update RTC control: %d\n", ret);
@ -199,8 +209,13 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
uint32_t int_reg;
int ret;
ret = regmap_bulk_read(rk808->regmap, RK808_ALARM_SECONDS_REG,
ret = regmap_bulk_read(rk808->regmap,
rk808_rtc->creg->alarm_seconds_reg,
alrm_data, NUM_ALARM_REGS);
if (ret) {
dev_err(dev, "Failed to read RTC alarm date REG: %d\n", ret);
return ret;
}
alrm->time.tm_sec = bcd2bin(alrm_data[0] & SECONDS_REG_MSK);
alrm->time.tm_min = bcd2bin(alrm_data[1] & MINUTES_REG_MAK);
@ -210,7 +225,7 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100;
rockchip_to_gregorian(&alrm->time);
ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg);
ret = regmap_read(rk808->regmap, rk808_rtc->creg->int_reg, &int_reg);
if (ret) {
dev_err(dev, "Failed to read RTC INT REG: %d\n", ret);
return ret;
@ -231,7 +246,7 @@ static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc)
struct rk808 *rk808 = rk808_rtc->rk808;
int ret;
ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0);
return ret;
@ -242,7 +257,7 @@ static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc)
struct rk808 *rk808 = rk808_rtc->rk808;
int ret;
ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
BIT_RTC_INTERRUPTS_REG_IT_ALARM_M,
BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
@ -274,7 +289,8 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1);
alrm_data[5] = bin2bcd(alrm->time.tm_year - 100);
ret = regmap_bulk_write(rk808->regmap, RK808_ALARM_SECONDS_REG,
ret = regmap_bulk_write(rk808->regmap,
rk808_rtc->creg->alarm_seconds_reg,
alrm_data, NUM_ALARM_REGS);
if (ret) {
dev_err(dev, "Failed to bulk write: %d\n", ret);
@ -318,7 +334,7 @@ static irqreturn_t rk808_alarm_irq(int irq, void *data)
struct i2c_client *client = rk808->i2c;
int ret;
ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
RTC_STATUS_MASK);
if (ret) {
dev_err(&client->dev,
@ -328,7 +344,7 @@ static irqreturn_t rk808_alarm_irq(int irq, void *data)
rtc_update_irq(rk808_rtc->rtc, 1, RTC_IRQF | RTC_AF);
dev_dbg(&client->dev,
"%s:irq=%d\n", __func__, irq);
"%s:irq=%d\n", __func__, irq);
return IRQ_HANDLED;
}
@ -371,6 +387,22 @@ static int rk808_rtc_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(rk808_rtc_pm_ops,
rk808_rtc_suspend, rk808_rtc_resume);
static struct rk_rtc_compat_reg rk808_creg = {
.ctrl_reg = RK808_RTC_CTRL_REG,
.status_reg = RK808_RTC_STATUS_REG,
.alarm_seconds_reg = RK808_ALARM_SECONDS_REG,
.int_reg = RK808_RTC_INT_REG,
.seconds_reg = RK808_SECONDS_REG,
};
static struct rk_rtc_compat_reg rk817_creg = {
.ctrl_reg = RK817_RTC_CTRL_REG,
.status_reg = RK817_RTC_STATUS_REG,
.alarm_seconds_reg = RK817_ALARM_SECONDS_REG,
.int_reg = RK817_RTC_INT_REG,
.seconds_reg = RK817_SECONDS_REG,
};
static int rk808_rtc_probe(struct platform_device *pdev)
{
struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
@ -382,8 +414,10 @@ static int rk808_rtc_probe(struct platform_device *pdev)
switch (rk808->variant) {
case RK805_ID:
case RK808_ID:
case RK809_ID:
case RK816_ID:
case RK818_ID:
case RK817_ID:
np = of_get_child_by_name(pdev->dev.parent->of_node, "rtc");
if (np && !of_device_is_available(np)) {
dev_info(&pdev->dev, "device is disabled\n");
@ -395,14 +429,23 @@ static int rk808_rtc_probe(struct platform_device *pdev)
}
rk808_rtc = devm_kzalloc(&pdev->dev, sizeof(*rk808_rtc), GFP_KERNEL);
if (rk808_rtc == NULL)
if (!rk808_rtc)
return -ENOMEM;
switch (rk808->variant) {
case RK809_ID:
case RK817_ID:
rk808_rtc->creg = &rk817_creg;
break;
default:
rk808_rtc->creg = &rk808_creg;
break;
}
platform_set_drvdata(pdev, rk808_rtc);
rk808_rtc->rk808 = rk808;
/* start rtc running by default, and use shadowed timer. */
ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
BIT_RTC_CTRL_REG_STOP_RTC_M |
BIT_RTC_CTRL_REG_RTC_READSEL_M,
BIT_RTC_CTRL_REG_RTC_READSEL_M);
@ -412,7 +455,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
return ret;
}
ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
RTC_STATUS_MASK);
if (ret) {
dev_err(&pdev->dev,

View File

@ -766,6 +766,162 @@ enum rk805_reg {
#define FPWM_MODE BIT(7)
#define AUTO_PWM_MODE 0
enum rk817_reg_id {
RK817_ID_DCDC1 = 0,
RK817_ID_DCDC2,
RK817_ID_DCDC3,
RK817_ID_DCDC4,
RK817_ID_LDO1,
RK817_ID_LDO2,
RK817_ID_LDO3,
RK817_ID_LDO4,
RK817_ID_LDO5,
RK817_ID_LDO6,
RK817_ID_LDO7,
RK817_ID_LDO8,
RK817_ID_LDO9,
RK817_ID_BOOST,
RK817_ID_BOOST_OTG_SW,
RK817_NUM_REGULATORS
};
enum rk809_reg_id {
RK809_ID_DCDC5 = RK817_ID_BOOST,
RK809_ID_SW1,
RK809_ID_SW2,
RK809_NUM_REGULATORS
};
#define RK817_SECONDS_REG 0x00
#define RK817_MINUTES_REG 0x01
#define RK817_HOURS_REG 0x02
#define RK817_DAYS_REG 0x03
#define RK817_MONTHS_REG 0x04
#define RK817_YEARS_REG 0x05
#define RK817_WEEKS_REG 0x06
#define RK817_ALARM_SECONDS_REG 0x07
#define RK817_ALARM_MINUTES_REG 0x08
#define RK817_ALARM_HOURS_REG 0x09
#define RK817_ALARM_DAYS_REG 0x0a
#define RK817_ALARM_MONTHS_REG 0x0b
#define RK817_ALARM_YEARS_REG 0x0c
#define RK817_RTC_CTRL_REG 0xd
#define RK817_RTC_STATUS_REG 0xe
#define RK817_RTC_INT_REG 0xf
#define RK817_RTC_COMP_LSB_REG 0x10
#define RK817_RTC_COMP_MSB_REG 0x11
#define RK817_POWER_EN_REG(i) (0xb1 + (i))
#define RK817_POWER_SLP_EN_REG(i) (0xb5 + (i))
#define RK817_BUCK_CONFIG_REG(i) (0xba + (i) * 3)
#define RK817_BUCK1_ON_VSEL_REG 0xBB
#define RK817_BUCK1_SLP_VSEL_REG 0xBC
#define RK817_BUCK2_CONFIG_REG 0xBD
#define RK817_BUCK2_ON_VSEL_REG 0xBE
#define RK817_BUCK2_SLP_VSEL_REG 0xBF
#define RK817_BUCK3_CONFIG_REG 0xC0
#define RK817_BUCK3_ON_VSEL_REG 0xC1
#define RK817_BUCK3_SLP_VSEL_REG 0xC2
#define RK817_BUCK4_CONFIG_REG 0xC3
#define RK817_BUCK4_ON_VSEL_REG 0xC4
#define RK817_BUCK4_SLP_VSEL_REG 0xC5
#define RK817_LDO_ON_VSEL_REG(idx) (0xcc + (idx) * 2)
#define RK817_BOOST_OTG_CFG (0xde)
#define RK817_ID_MSB 0xed
#define RK817_ID_LSB 0xee
#define RK817_SYS_STS 0xf0
#define RK817_SYS_CFG(i) (0xf1 + (i))
#define RK817_ON_SOURCE_REG 0xf5
#define RK817_OFF_SOURCE_REG 0xf6
/* INTERRUPT REGISTER */
#define RK817_INT_STS_REG0 0xf8
#define RK817_INT_STS_MSK_REG0 0xf9
#define RK817_INT_STS_REG1 0xfa
#define RK817_INT_STS_MSK_REG1 0xfb
#define RK817_INT_STS_REG2 0xfc
#define RK817_INT_STS_MSK_REG2 0xfd
#define RK817_GPIO_INT_CFG 0xfe
/* IRQ Definitions */
#define RK817_IRQ_PWRON_FALL 0
#define RK817_IRQ_PWRON_RISE 1
#define RK817_IRQ_PWRON 2
#define RK817_IRQ_PWMON_LP 3
#define RK817_IRQ_HOTDIE 4
#define RK817_IRQ_RTC_ALARM 5
#define RK817_IRQ_RTC_PERIOD 6
#define RK817_IRQ_VB_LO 7
#define RK817_IRQ_PLUG_IN (8 + 0)
#define RK817_IRQ_PLUG_OUT (8 + 1)
#define RK817_IRQ_CHRG_TERM (8 + 2)
#define RK817_IRQ_CHRG_TIME (8 + 3)
#define RK817_IRQ_CHRG_TS (8 + 4)
#define RK817_IRQ_USB_OV (8 + 5)
#define RK817_IRQ_CHRG_IN_CLMP (8 + 6)
#define RK817_IRQ_BAT_DIS_ILIM (8 + 7)
#define RK817_IRQ_GATE_GPIO (16 + 0)
#define RK817_IRQ_TS_GPIO (16 + 1)
#define RK817_IRQ_CODEC_PD (16 + 2)
#define RK817_IRQ_CODEC_PO (16 + 3)
#define RK817_IRQ_CLASSD_MUTE_DONE (16 + 4)
#define RK817_IRQ_CLASSD_OCP (16 + 5)
#define RK817_IRQ_BAT_OVP (16 + 6)
#define RK817_IRQ_CHRG_BAT_HI (16 + 7)
#define RK817_IRQ_END (RK817_IRQ_CHRG_BAT_HI + 1)
/*
* rtc_ctrl 0xd
* same as 808, except bit4
*/
#define RK817_RTC_CTRL_RSV4 BIT(4)
/* buck config 0xba */
#define RK817_RAMP_RATE_OFFSET 6
#define RK817_RAMP_RATE_MASK (0x3 << RK817_RAMP_RATE_OFFSET)
#define RK817_RAMP_RATE_3MV_PER_US (0x0 << RK817_RAMP_RATE_OFFSET)
#define RK817_RAMP_RATE_6_3MV_PER_US (0x1 << RK817_RAMP_RATE_OFFSET)
#define RK817_RAMP_RATE_12_5MV_PER_US (0x2 << RK817_RAMP_RATE_OFFSET)
#define RK817_RAMP_RATE_25MV_PER_US (0x3 << RK817_RAMP_RATE_OFFSET)
/* sys_cfg1 0xf2 */
#define RK817_HOTDIE_TEMP_MSK (0x3 << 4)
#define RK817_HOTDIE_85 (0x0 << 4)
#define RK817_HOTDIE_95 (0x1 << 4)
#define RK817_HOTDIE_105 (0x2 << 4)
#define RK817_HOTDIE_115 (0x3 << 4)
#define RK817_TSD_TEMP_MSK BIT(6)
#define RK817_TSD_140 0
#define RK817_TSD_160 BIT(6)
#define RK817_CLK32KOUT2_EN BIT(7)
/* sys_cfg3 0xf4 */
#define RK817_SLPPIN_FUNC_MSK (0x3 << 3)
#define SLPPIN_NULL_FUN (0x0 << 3)
#define SLPPIN_SLP_FUN (0x1 << 3)
#define SLPPIN_DN_FUN (0x2 << 3)
#define SLPPIN_RST_FUN (0x3 << 3)
#define RK817_SLPPOL_MSK BIT(5)
#define RK817_SLPPOL_H BIT(5)
/* gpio&int 0xfe */
#define RK817_INT_POL_MSK BIT(1)
#define RK817_INT_POL_H BIT(1)
#define RK817_INT_POL_L 0
#define RK809_BUCK5_CONFIG(i) (RK817_BOOST_OTG_CFG + (i) * 1)
enum {
BUCK_ILMIN_50MA,
BUCK_ILMIN_100MA,
@ -799,7 +955,9 @@ struct rk808 {
enum {
RK805_ID = 0x8050,
RK808_ID = 0x0000,
RK809_ID = 0x8090,
RK816_ID = 0x8160,
RK817_ID = 0x8170,
RK818_ID = 0x8180,
};