mfd: rk8xx: Add RK801 support

The RK801 is a Power Management IC (PMIC) for multimedia
and handheld devices. It contains the following components:

- 4 BUCK
- 2 LDO
- 1 SWITCH

Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
Link: https://patch.msgid.link/20260112124351.17707-3-chenjh@rock-chips.com
Signed-off-by: Lee Jones <lee@kernel.org>
This commit is contained in:
Joseph Chen
2026-01-12 20:43:50 +08:00
committed by Lee Jones
parent a8a2add7b1
commit 156442eb6e
4 changed files with 234 additions and 4 deletions

View File

@@ -1371,15 +1371,15 @@ config MFD_RK8XX
select MFD_CORE
config MFD_RK8XX_I2C
tristate "Rockchip RK805/RK808/RK809/RK816/RK817/RK818 Power Management Chip"
tristate "Rockchip RK8xx Power Management Chips"
depends on I2C && OF
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
select MFD_RK8XX
help
If you say yes here you get support for the RK805, RK808, RK809,
RK816, RK817 and RK818 Power Management chips.
If you say yes here you get support for the RK801, RK805, RK808,
RK809, RK816, RK817 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

@@ -37,6 +37,11 @@ static const struct resource rk817_rtc_resources[] = {
DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM),
};
static const struct resource rk801_key_resources[] = {
DEFINE_RES_IRQ(RK801_IRQ_PWRON_FALL),
DEFINE_RES_IRQ(RK801_IRQ_PWRON_RISE),
};
static const struct resource rk805_key_resources[] = {
DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE),
DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
@@ -57,6 +62,14 @@ static const struct resource rk817_charger_resources[] = {
DEFINE_RES_IRQ(RK817_IRQ_PLUG_OUT),
};
static const struct mfd_cell rk801s[] = {
{ .name = "rk808-regulator", },
{ .name = "rk805-pwrkey",
.num_resources = ARRAY_SIZE(rk801_key_resources),
.resources = &rk801_key_resources[0],
},
};
static const struct mfd_cell rk805s[] = {
{ .name = "rk808-clkout", },
{ .name = "rk808-regulator", },
@@ -139,6 +152,15 @@ static const struct mfd_cell rk818s[] = {
},
};
static const struct rk808_reg_data rk801_pre_init_reg[] = {
{ RK801_SLEEP_CFG_REG, RK801_SLEEP_FUN_MSK, RK801_NONE_FUN },
{ RK801_SYS_CFG2_REG, RK801_RST_MSK, RK801_RST_RESTART_REG_RESETB },
{ RK801_INT_CONFIG_REG, RK801_INT_POL_MSK, RK801_INT_ACT_L },
{ RK801_POWER_FPWM_EN_REG, RK801_PLDO_HRDEC_EN, RK801_PLDO_HRDEC_EN },
{ RK801_BUCK_DEBUG5_REG, MASK_ALL, 0x54 },
{ RK801_CON_BACK1_REG, MASK_ALL, 0x18 },
};
static const struct rk808_reg_data rk805_pre_init_reg[] = {
{RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
RK805_BUCK1_2_ILMAX_4000MA},
@@ -284,6 +306,37 @@ static const struct rk808_reg_data rk818_pre_init_reg[] = {
VB_LO_SEL_3500MV },
};
static const struct regmap_irq rk801_irqs[] = {
[RK801_IRQ_PWRON_FALL] = {
.mask = RK801_IRQ_PWRON_FALL_MSK,
.reg_offset = 0,
},
[RK801_IRQ_PWRON_RISE] = {
.mask = RK801_IRQ_PWRON_RISE_MSK,
.reg_offset = 0,
},
[RK801_IRQ_PWRON] = {
.mask = RK801_IRQ_PWRON_MSK,
.reg_offset = 0,
},
[RK801_IRQ_PWRON_LP] = {
.mask = RK801_IRQ_PWRON_LP_MSK,
.reg_offset = 0,
},
[RK801_IRQ_HOTDIE] = {
.mask = RK801_IRQ_HOTDIE_MSK,
.reg_offset = 0,
},
[RK801_IRQ_VDC_RISE] = {
.mask = RK801_IRQ_VDC_RISE_MSK,
.reg_offset = 0,
},
[RK801_IRQ_VDC_FALL] = {
.mask = RK801_IRQ_VDC_FALL_MSK,
.reg_offset = 0,
},
};
static const struct regmap_irq rk805_irqs[] = {
[RK805_IRQ_PWRON_RISE] = {
.mask = RK805_IRQ_PWRON_RISE_MSK,
@@ -532,6 +585,17 @@ static const struct regmap_irq rk817_irqs[RK817_IRQ_END] = {
REGMAP_IRQ_REG_LINE(23, 8)
};
static const struct regmap_irq_chip rk801_irq_chip = {
.name = "rk801",
.irqs = rk801_irqs,
.num_irqs = ARRAY_SIZE(rk801_irqs),
.num_regs = 1,
.status_base = RK801_INT_STS0_REG,
.mask_base = RK801_INT_MASK0_REG,
.ack_base = RK801_INT_STS0_REG,
.init_ack_masked = true,
};
static const struct regmap_irq_chip rk805_irq_chip = {
.name = "rk805",
.irqs = rk805_irqs,
@@ -610,6 +674,10 @@ static int rk808_power_off(struct sys_off_data *data)
unsigned int reg, bit;
switch (rk808->variant) {
case RK801_ID:
reg = RK801_SYS_CFG2_REG;
bit = DEV_OFF;
break;
case RK805_ID:
reg = RK805_DEV_CTRL_REG;
bit = DEV_OFF;
@@ -714,6 +782,13 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
dev_set_drvdata(dev, rk808);
switch (rk808->variant) {
case RK801_ID:
rk808->regmap_irq_chip = &rk801_irq_chip;
pre_init_reg = rk801_pre_init_reg;
nr_pre_init_regs = ARRAY_SIZE(rk801_pre_init_reg);
cells = rk801s;
nr_cells = ARRAY_SIZE(rk801s);
break;
case RK805_ID:
rk808->regmap_irq_chip = &rk805_irq_chip;
pre_init_reg = rk805_pre_init_reg;
@@ -831,6 +906,12 @@ int rk8xx_suspend(struct device *dev)
int ret = 0;
switch (rk808->variant) {
case RK801_ID:
ret = regmap_update_bits(rk808->regmap,
RK801_SLEEP_CFG_REG,
RK801_SLEEP_FUN_MSK,
RK801_SLEEP_FUN);
break;
case RK805_ID:
ret = regmap_update_bits(rk808->regmap,
RK805_GPIO_IO_POL_REG,

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Rockchip RK805/RK808/RK816/RK817/RK818 Core (I2C) driver
* Rockchip RK801/RK805/RK808/RK816/RK817/RK818 Core (I2C) driver
*
* Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
* Copyright (C) 2016 PHYTEC Messtechnik GmbH
@@ -21,6 +21,23 @@ struct rk8xx_i2c_platform_data {
int variant;
};
static bool rk801_is_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case RK801_SYS_STS_REG:
case RK801_INT_STS0_REG:
case RK801_SYS_CFG0_REG:
case RK801_SYS_CFG1_REG:
case RK801_SYS_CFG2_REG:
case RK801_SYS_CFG3_REG:
case RK801_SYS_CFG4_REG:
case RK801_SLEEP_CFG_REG:
return true;
}
return false;
}
static bool rk806_is_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
@@ -124,6 +141,14 @@ static const struct regmap_config rk818_regmap_config = {
.volatile_reg = rk808_is_volatile_reg,
};
static const struct regmap_config rk801_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = RK801_SYS_CFG3_OTP_REG,
.cache_type = REGCACHE_RBTREE,
.volatile_reg = rk801_is_volatile_reg,
};
static const struct regmap_config rk805_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@@ -164,6 +189,11 @@ static const struct regmap_config rk817_regmap_config = {
.volatile_reg = rk817_is_volatile_reg,
};
static const struct rk8xx_i2c_platform_data rk801_data = {
.regmap_cfg = &rk801_regmap_config,
.variant = RK801_ID,
};
static const struct rk8xx_i2c_platform_data rk805_data = {
.regmap_cfg = &rk805_regmap_config,
.variant = RK805_ID,
@@ -224,6 +254,7 @@ static void rk8xx_i2c_shutdown(struct i2c_client *client)
static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume);
static const struct of_device_id rk8xx_i2c_of_match[] = {
{ .compatible = "rockchip,rk801", .data = &rk801_data },
{ .compatible = "rockchip,rk805", .data = &rk805_data },
{ .compatible = "rockchip,rk806", .data = &rk806_data },
{ .compatible = "rockchip,rk808", .data = &rk808_data },