diff options
| author | Joseph Chen <chenjh@rock-chips.com> | 2026-01-12 20:43:50 +0800 |
|---|---|---|
| committer | Lee Jones <lee@kernel.org> | 2026-01-20 14:57:41 +0000 |
| commit | 156442eb6e44d545f09559bd70c5b31fba39eb01 (patch) | |
| tree | b04c0c2d66a7bb2e4a9082267d011c58f0cce59f /drivers | |
| parent | a8a2add7b1889f00bc5d2b1f25fad34e89ef85fb (diff) | |
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>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/mfd/Kconfig | 6 | ||||
| -rw-r--r-- | drivers/mfd/rk8xx-core.c | 81 | ||||
| -rw-r--r-- | drivers/mfd/rk8xx-i2c.c | 33 |
3 files changed, 116 insertions, 4 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index aace5766b38a..498d4260b777 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -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. diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c index def4587fdfb8..3dcf6abfda74 100644 --- a/drivers/mfd/rk8xx-core.c +++ b/drivers/mfd/rk8xx-core.c @@ -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, diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c index 37287b06dab0..2951b2911a37 100644 --- a/drivers/mfd/rk8xx-i2c.c +++ b/drivers/mfd/rk8xx-i2c.c @@ -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 }, |
