From nobody Sat Feb 7 06:21:54 2026 Received: from mail-m3282.qiye.163.com (mail-m3282.qiye.163.com [220.197.32.82]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 86FD61ADC97 for ; Wed, 31 Dec 2025 03:15:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.32.82 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767150947; cv=none; b=dJUI63ynhkbzafT0rPr1fMpcINjoZQ++cKIzGEGfPaG435BOGGxvlPpEY3Pb9dfm1dmK5nzbcmNJ7H/ji0ozbTFBA4Vd7FWlQM/fKoCgP71Qj5CbUJWhUAgh1yJ2b/Yc6XOZ+mXXNPKNrzwrw9R4nnUIO3cjK4Z/2p5F3TK8VS4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767150947; c=relaxed/simple; bh=+E0efjuKp2EnS1ByJlL6mMPxEHLTmle7JevD0gmLOI0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NOsn5LP9u6Ad/VV8uzrVKPOy9uJSo9E/2BCmgnmdz7L63w3Zm7BN7vAd/Fh2KHtQF8G1fnzRoNjCReWwK/LCrBSSukcx42SqR84860/vsHcWG/hBSUD4gFTHEVPoCdEhT9fll6AcxXsYX5lELq6Jf1kY3y3EJkWnpENtH9QjPVI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rock-chips.com; spf=pass smtp.mailfrom=rock-chips.com; dkim=pass (1024-bit key) header.d=rock-chips.com header.i=@rock-chips.com header.b=UMOeFQRd; arc=none smtp.client-ip=220.197.32.82 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rock-chips.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rock-chips.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=rock-chips.com header.i=@rock-chips.com header.b="UMOeFQRd" Received: from localhost.localdomain (unknown [58.22.7.114]) by smtp.qiye.163.com (Hmail) with ESMTP id 2f185eb3c; Wed, 31 Dec 2025 11:10:26 +0800 (GMT+08:00) From: Joseph Chen To: lee@kernel.org, lgirdwood@gmail.com, broonie@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org Cc: linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, Joseph Chen Subject: [PATCH v1 1/2] dt-bindings: mfd: Add rk801 binding Date: Wed, 31 Dec 2025 11:09:50 +0800 Message-Id: <20251231030951.818-2-chenjh@rock-chips.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20251231030951.818-1-chenjh@rock-chips.com> References: <20251231030951.818-1-chenjh@rock-chips.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-HM-Tid: 0a9b7262a7ba09d2kunm5c2c20206ab0f2 X-HM-MType: 1 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFDSUNOT01LS0k3V1ktWUFJV1kPCRoVCBIfWUFZGhkYTVZIHhpMHkoZTkJDSU5WFRQJFh oXVRMBExYaEhckFA4PWVdZGBILWUFZTkNVSUlVTFVKSk9ZV1kWGg8SFR0UWUFZT0tIVUpLSU9PT0 hVSktLVUpCS0tZBg++ DKIM-Signature: a=rsa-sha256; b=UMOeFQRd10Fts8bJe7uVAy1cu9eSjddpM7UJ0vfd2LDXloqDjuyyRdGCzQHodLXbSQq6zbs3Ou8ORYQdojrjrogD3LVUvmw5eo3Sa6qWmP9kRYjNADtg3NHIl4yCsXQK5n9iMF9Muj8UkB0602IrBNTL9DxmuOovXskP7VXaLvI=; c=relaxed/relaxed; s=default; d=rock-chips.com; v=1; bh=pJDyZVU8UBhoZL2Hk2oZGuZv9aeWaJrXTMLpCjzYgDw=; h=date:mime-version:subject:message-id:from; Content-Type: text/plain; charset="utf-8" Add DT binding document for Rockchip's RK801 PMIC Signed-off-by: Joseph Chen --- .../bindings/mfd/rockchip,rk801.yaml | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/rockchip,rk801.ya= ml diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk801.yaml b/Do= cumentation/devicetree/bindings/mfd/rockchip,rk801.yaml new file mode 100644 index 00000000000..d591125dfe8 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/rockchip,rk801.yaml @@ -0,0 +1,199 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/rockchip,rk801.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: RK801 Power Management Integrated Circuit + +maintainers: + - Joseph Chen + +description: | + Rockchip RK801 series PMIC. This device consists of an i2c controlled MFD + that includes multiple switchable regulators. + +properties: + compatible: + enum: + - rockchip,rk801 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + rockchip,system-power-controller: + type: boolean + description: + Telling whether or not this PMIC is controlling the system power. + + system-power-controller: true + + wakeup-source: + type: boolean + description: + Device can be used as a wakeup source. + + vcc1-supply: + description: + The input supply for DCDC_REG1. + + vcc2-supply: + description: + The input supply for DCDC_REG2. + + vcc3-supply: + description: + The input supply for DCDC_REG3. + + vcc4-supply: + description: + The input supply for DCDC_REG4. + + vcc5-supply: + description: + The input supply for LDO_REG1. + + vcc6-supply: + description: + The input supply for LDO_REG2. + + vcc7-supply: + description: + The input supply for SWITCH_REG. + + regulators: + type: object + patternProperties: + "^(DCDC_REG[1-4]|LDO_REG[1-2]|SWITCH_REG)$": + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + #include + #include + i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + + rk801: rk801@27 { + compatible =3D "rockchip,rk801"; + reg =3D <0x27>; + interrupt-parent =3D <&gpio0>; + interrupts =3D ; + pwrctrl-gpios =3D <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; + pinctrl-names =3D "default"; + pinctrl-0 =3D <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply =3D <&vcc12v_dcin>; + vcc2-supply =3D <&vcc12v_dcin>; + vcc3-supply =3D <&vcc5v0_sys>; + vcc4-supply =3D <&vcc5v0_sys>; + vcc5-supply =3D <&vcc3v3_sys>; + vcc6-supply =3D <&vcc3v3_sys>; + vcc7-supply =3D <&vcc3v3_sys>; + + regulators { + vdd_cpu: DCDC_REG1 { + regulator-name =3D "vdd_cpu"; + regulator-min-microvolt =3D <500000>; + regulator-max-microvolt =3D <1500000>; + regulator-initial-mode =3D <0x1>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-mode =3D <0x2>; + regulator-off-in-suspend; + regulator-suspend-microvolt =3D <950000>; + }; + }; + + vcc3v3_sys: DCDC_REG2 { + regulator-name =3D "vcc3v3_sys"; + regulator-min-microvolt =3D <3300000>; + regulator-max-microvolt =3D <3300000>; + regulator-initial-mode =3D <0x1>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-mode =3D <0x2>; + regulator-on-in-suspend; + regulator-suspend-microvolt =3D <3300000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name =3D "vcc_ddr"; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-mode =3D <0x2>; + regulator-on-in-suspend; + }; + }; + + vdd_logic: DCDC_REG4 { + regulator-name =3D "vdd_logic"; + regulator-min-microvolt =3D <500000>; + regulator-max-microvolt =3D <1500000>; + regulator-initial-mode =3D <0x1>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-mode =3D <0x2>; + regulator-off-in-suspend; + regulator-suspend-microvolt =3D <900000>; + }; + }; + + vdd0v9_sys: LDO_REG1 { + regulator-name =3D "vdd0v9_sys"; + regulator-min-microvolt =3D <900000>; + regulator-max-microvolt =3D <900000>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt =3D <900000>; + }; + }; + + vcc_1v8: LDO_REG2 { + regulator-name =3D "vcc_1v8"; + regulator-min-microvolt =3D <1800000>; + regulator-max-microvolt =3D <1800000>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt =3D <1800000>; + }; + }; + + vcc_3v3: SWITCH_REG { + regulator-name =3D "vcc_3v3"; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt =3D <3300000>; + }; + }; + }; + }; + }; --=20 2.25.1 From nobody Sat Feb 7 06:21:54 2026 Received: from mail-m155106.qiye.163.com (mail-m155106.qiye.163.com [101.71.155.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4AA6745C0B for ; Wed, 31 Dec 2025 05:33:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=101.71.155.106 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767159186; cv=none; b=ahTcyEyzDWwem7mRoFJ2YB3k/dl+n6yIwprApl48SUoT3NnqeNC5k8zeceR/Q0R6MKZcF9DX2WhmM3Cheo9kN+rkMcelAmROxpzMHlPGNFnd/rKQ5MSbBTCt6Eh7Jeagl2ExP4kvkUE+hLqGYQs3mfdAtjbJNu8B420/xRFoIH4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767159186; c=relaxed/simple; bh=RZPTTJeeTdvTgs3jyh4J20ULs/PttCi7oUw8ZCy8QG4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=adoaGp3GoAADJms2w5td6BzTA1sp5hUYXFprwvkgcpdeaU4hLID1OcXKOgu7FGaQt8Ta8tlge/whcQMHrlUC4xniQvPKTke5KoqHFRuXGuIahzml5J010ieU4nDhUI0B65nVLEIqGujFlXejvDR7huPZ31HVmiSbYuq3WZYgyDQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rock-chips.com; spf=pass smtp.mailfrom=rock-chips.com; dkim=pass (1024-bit key) header.d=rock-chips.com header.i=@rock-chips.com header.b=ZNdUVkCh; arc=none smtp.client-ip=101.71.155.106 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rock-chips.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rock-chips.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=rock-chips.com header.i=@rock-chips.com header.b="ZNdUVkCh" Received: from localhost.localdomain (unknown [58.22.7.114]) by smtp.qiye.163.com (Hmail) with ESMTP id 2f185eb54; Wed, 31 Dec 2025 11:10:29 +0800 (GMT+08:00) From: Joseph Chen To: lee@kernel.org, lgirdwood@gmail.com, broonie@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org Cc: linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, Joseph Chen Subject: [PATCH v1 2/2] mfd: rk808: Add RK801 support Date: Wed, 31 Dec 2025 11:09:51 +0800 Message-Id: <20251231030951.818-3-chenjh@rock-chips.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20251231030951.818-1-chenjh@rock-chips.com> References: <20251231030951.818-1-chenjh@rock-chips.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-HM-Tid: 0a9b7262b08809d2kunm5c2c20206ab137 X-HM-MType: 1 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFDSUNOT01LS0k3V1ktWUFJV1kPCRoVCBIfWUFZGU0eGlYeGU0ZHklKQ0kYGkhWFRQJFh oXVRMBExYaEhckFA4PWVdZGBILWUFZTkNVSUlVTFVKSk9ZV1kWGg8SFR0UWUFZT0tIVUpLSU9PT0 hVSktLVUpCS0tZBg++ DKIM-Signature: a=rsa-sha256; b=ZNdUVkChKYyFYvX94T/Ik02mBVndsE/nMS7Fy+0v2JHw6HelXhGk3dtVaqll5qTLhNffl3yWHpMy3X4BV102gjUE0G1PHbrXy6GsAHu7CuogzUFBCXFEUOxlWdONmds/rWhANs/Bne5K6jt2RzGunHK1LTMiU4iSGy8RqXzFk9A=; c=relaxed/relaxed; s=default; d=rock-chips.com; v=1; bh=3XiVce+pMvxcoZyi9xCODzohl8+z/vuE1MvCHUBl+zo=; h=date:mime-version:subject:message-id:from; Content-Type: text/plain; charset="utf-8" The RK801 are a Power Management IC (PMIC) for multimedia and handheld devices. They contains the following components: - 4 BUCK - 2 LDO - 1 SWITCH Signed-off-by: Joseph Chen --- drivers/mfd/Kconfig | 6 +- drivers/mfd/rk8xx-core.c | 81 ++++++++++ drivers/mfd/rk8xx-i2c.c | 33 +++- drivers/regulator/rk808-regulator.c | 243 ++++++++++++++++++++++++++++ include/linux/mfd/rk808.h | 118 ++++++++++++++ 5 files changed, 477 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 6cec1858947..5405e8633aa 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1355,15 +1355,15 @@ config MFD_RK8XX select MFD_CORE =20 config MFD_RK8XX_I2C - tristate "Rockchip RK805/RK808/RK809/RK816/RK817/RK818 Power Management C= hip" + tristate "Rockchip RK801/RK805/RK808/RK809/RK816/RK817/RK818 Power Manage= ment Chip" 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 def4587fdfb..3dcf6abfda7 100644 --- a/drivers/mfd/rk8xx-core.c +++ b/drivers/mfd/rk8xx-core.c @@ -37,6 +37,11 @@ static const struct resource rk817_rtc_resources[] =3D { DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM), }; =20 +static const struct resource rk801_key_resources[] =3D { + DEFINE_RES_IRQ(RK801_IRQ_PWRON_FALL), + DEFINE_RES_IRQ(RK801_IRQ_PWRON_RISE), +}; + static const struct resource rk805_key_resources[] =3D { 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[] = =3D { DEFINE_RES_IRQ(RK817_IRQ_PLUG_OUT), }; =20 +static const struct mfd_cell rk801s[] =3D { + { .name =3D "rk808-regulator", }, + { .name =3D "rk805-pwrkey", + .num_resources =3D ARRAY_SIZE(rk801_key_resources), + .resources =3D &rk801_key_resources[0], + }, +}; + static const struct mfd_cell rk805s[] =3D { { .name =3D "rk808-clkout", }, { .name =3D "rk808-regulator", }, @@ -139,6 +152,15 @@ static const struct mfd_cell rk818s[] =3D { }, }; =20 +static const struct rk808_reg_data rk801_pre_init_reg[] =3D { + { 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[] =3D { {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[= ] =3D { VB_LO_SEL_3500MV }, }; =20 +static const struct regmap_irq rk801_irqs[] =3D { + [RK801_IRQ_PWRON_FALL] =3D { + .mask =3D RK801_IRQ_PWRON_FALL_MSK, + .reg_offset =3D 0, + }, + [RK801_IRQ_PWRON_RISE] =3D { + .mask =3D RK801_IRQ_PWRON_RISE_MSK, + .reg_offset =3D 0, + }, + [RK801_IRQ_PWRON] =3D { + .mask =3D RK801_IRQ_PWRON_MSK, + .reg_offset =3D 0, + }, + [RK801_IRQ_PWRON_LP] =3D { + .mask =3D RK801_IRQ_PWRON_LP_MSK, + .reg_offset =3D 0, + }, + [RK801_IRQ_HOTDIE] =3D { + .mask =3D RK801_IRQ_HOTDIE_MSK, + .reg_offset =3D 0, + }, + [RK801_IRQ_VDC_RISE] =3D { + .mask =3D RK801_IRQ_VDC_RISE_MSK, + .reg_offset =3D 0, + }, + [RK801_IRQ_VDC_FALL] =3D { + .mask =3D RK801_IRQ_VDC_FALL_MSK, + .reg_offset =3D 0, + }, +}; + static const struct regmap_irq rk805_irqs[] =3D { [RK805_IRQ_PWRON_RISE] =3D { .mask =3D RK805_IRQ_PWRON_RISE_MSK, @@ -532,6 +585,17 @@ static const struct regmap_irq rk817_irqs[RK817_IRQ_EN= D] =3D { REGMAP_IRQ_REG_LINE(23, 8) }; =20 +static const struct regmap_irq_chip rk801_irq_chip =3D { + .name =3D "rk801", + .irqs =3D rk801_irqs, + .num_irqs =3D ARRAY_SIZE(rk801_irqs), + .num_regs =3D 1, + .status_base =3D RK801_INT_STS0_REG, + .mask_base =3D RK801_INT_MASK0_REG, + .ack_base =3D RK801_INT_STS0_REG, + .init_ack_masked =3D true, +}; + static const struct regmap_irq_chip rk805_irq_chip =3D { .name =3D "rk805", .irqs =3D rk805_irqs, @@ -610,6 +674,10 @@ static int rk808_power_off(struct sys_off_data *data) unsigned int reg, bit; =20 switch (rk808->variant) { + case RK801_ID: + reg =3D RK801_SYS_CFG2_REG; + bit =3D DEV_OFF; + break; case RK805_ID: reg =3D RK805_DEV_CTRL_REG; bit =3D DEV_OFF; @@ -714,6 +782,13 @@ int rk8xx_probe(struct device *dev, int variant, unsig= ned int irq, struct regmap dev_set_drvdata(dev, rk808); =20 switch (rk808->variant) { + case RK801_ID: + rk808->regmap_irq_chip =3D &rk801_irq_chip; + pre_init_reg =3D rk801_pre_init_reg; + nr_pre_init_regs =3D ARRAY_SIZE(rk801_pre_init_reg); + cells =3D rk801s; + nr_cells =3D ARRAY_SIZE(rk801s); + break; case RK805_ID: rk808->regmap_irq_chip =3D &rk805_irq_chip; pre_init_reg =3D rk805_pre_init_reg; @@ -831,6 +906,12 @@ int rk8xx_suspend(struct device *dev) int ret =3D 0; =20 switch (rk808->variant) { + case RK801_ID: + ret =3D regmap_update_bits(rk808->regmap, + RK801_SLEEP_CFG_REG, + RK801_SLEEP_FUN_MSK, + RK801_SLEEP_FUN); + break; case RK805_ID: ret =3D 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 37287b06dab..2951b2911a3 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; }; =20 +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 = =3D { .volatile_reg =3D rk808_is_volatile_reg, }; =20 +static const struct regmap_config rk801_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + .max_register =3D RK801_SYS_CFG3_OTP_REG, + .cache_type =3D REGCACHE_RBTREE, + .volatile_reg =3D rk801_is_volatile_reg, +}; + static const struct regmap_config rk805_regmap_config =3D { .reg_bits =3D 8, .val_bits =3D 8, @@ -164,6 +189,11 @@ static const struct regmap_config rk817_regmap_config = =3D { .volatile_reg =3D rk817_is_volatile_reg, }; =20 +static const struct rk8xx_i2c_platform_data rk801_data =3D { + .regmap_cfg =3D &rk801_regmap_config, + .variant =3D RK801_ID, +}; + static const struct rk8xx_i2c_platform_data rk805_data =3D { .regmap_cfg =3D &rk805_regmap_config, .variant =3D RK805_ID, @@ -224,6 +254,7 @@ static void rk8xx_i2c_shutdown(struct i2c_client *clien= t) static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume); =20 static const struct of_device_id rk8xx_i2c_of_match[] =3D { + { .compatible =3D "rockchip,rk801", .data =3D &rk801_data }, { .compatible =3D "rockchip,rk805", .data =3D &rk805_data }, { .compatible =3D "rockchip,rk806", .data =3D &rk806_data }, { .compatible =3D "rockchip,rk808", .data =3D &rk808_data }, diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-= regulator.c index 1e814247965..5f87a070e72 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c @@ -24,6 +24,9 @@ #include =20 /* Field definitions */ +#define RK801_BUCK_VSEL_MASK 0x7f +#define RK801_LDO_VSEL_MASK 0x3f + #define RK808_BUCK_VSEL_MASK 0x3f #define RK808_BUCK4_VSEL_MASK 0xf #define RK808_LDO_VSEL_MASK 0x1f @@ -158,6 +161,11 @@ RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \ _vmask, _ereg, _emask, 0, 0, _etime, &rk808_reg_ops) =20 +#define RK801_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \ + _vmask, _ereg, _emask, _disval, _etime) \ + RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \ + _vmask, _ereg, _emask, _emask, _disval, _etime, &rk801_reg_ops) + #define RK816_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \ _vmask, _ereg, _emask, _disval, _etime) \ RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \ @@ -185,6 +193,11 @@ .ops =3D _ops \ } =20 +#define RK801_DESC_SWITCH(_id, _match, _supply, _ereg, _emask, \ + _disval) \ + RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask, \ + _emask, _disval, &rk801_switch_ops) + #define RK817_DESC_SWITCH(_id, _match, _supply, _ereg, _emask, \ _disval) \ RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask, \ @@ -802,6 +815,115 @@ static unsigned int rk8xx_regulator_of_map_mode(unsig= ned int mode) } } =20 +static unsigned int rk801_get_mode(struct regulator_dev *rdev) +{ + unsigned int val; + int err; + + err =3D regmap_read(rdev->regmap, RK801_POWER_FPWM_EN_REG, &val); + if (err) + return err; + + if (val & BIT(rdev->desc->id)) + return REGULATOR_MODE_FAST; + else + return REGULATOR_MODE_NORMAL; +} + +static int rk801_set_mode(struct regulator_dev *rdev, unsigned int mode) +{ + unsigned int offset =3D rdev->desc->id; + + switch (mode) { + case REGULATOR_MODE_FAST: + return regmap_update_bits(rdev->regmap, RK801_POWER_FPWM_EN_REG, + BIT(offset), RK801_FPWM_MODE << offset); + case REGULATOR_MODE_NORMAL: + return regmap_update_bits(rdev->regmap, RK801_POWER_FPWM_EN_REG, + BIT(offset), RK801_AUTO_PWM_MODE << offset); + default: + dev_err(&rdev->dev, "do not support this mode\n"); + return -EINVAL; + } + + return 0; +} + +static int rk801_set_suspend_voltage(struct regulator_dev *rdev, int uv) +{ + unsigned int reg; + int sel; + + if (rdev->desc->id < RK801_ID_LDO1) + sel =3D regulator_map_voltage_linear_range(rdev, uv, uv); + else + sel =3D regulator_map_voltage_linear(rdev, uv, uv); + if (sel < 0) + return -EINVAL; + + reg =3D rdev->desc->vsel_reg + RK801_SLP_REG_OFFSET; + + return regmap_update_bits(rdev->regmap, reg, + rdev->desc->vsel_mask, sel); +} + +static int rk801_set_suspend_enable(struct regulator_dev *rdev) +{ + return regmap_update_bits(rdev->regmap, RK801_POWER_SLP_EN_REG, + BIT(rdev->desc->id), BIT(rdev->desc->id)); +} + +static int rk801_set_suspend_disable(struct regulator_dev *rdev) +{ + return regmap_update_bits(rdev->regmap, RK801_POWER_SLP_EN_REG, + BIT(rdev->desc->id), 0); +} + +static int rk801_set_voltage_time_sel(struct regulator_dev *rdev, + unsigned int old_selector, + unsigned int new_selector) +{ + return regulator_set_voltage_time_sel(rdev, old_selector, + new_selector) + RK801_HW_SYNC_US; +} + +static const struct regulator_ops rk801_buck_ops =3D { + .list_voltage =3D regulator_list_voltage_linear_range, + .map_voltage =3D regulator_map_voltage_linear_range, + .get_voltage_sel =3D regulator_get_voltage_sel_regmap, + .set_voltage_sel =3D regulator_set_voltage_sel_regmap, + .set_voltage_time_sel =3D rk801_set_voltage_time_sel, + .enable =3D regulator_enable_regmap, + .disable =3D regulator_disable_regmap, + .is_enabled =3D regulator_is_enabled_regmap, + .set_mode =3D rk801_set_mode, + .get_mode =3D rk801_get_mode, + .set_suspend_voltage =3D rk801_set_suspend_voltage, + .set_suspend_enable =3D rk801_set_suspend_enable, + .set_suspend_disable =3D rk801_set_suspend_disable, +}; + +static const struct regulator_ops rk801_reg_ops =3D { + .list_voltage =3D regulator_list_voltage_linear, + .map_voltage =3D regulator_map_voltage_linear, + .get_voltage_sel =3D regulator_get_voltage_sel_regmap, + .set_voltage_sel =3D regulator_set_voltage_sel_regmap, + .enable =3D regulator_enable_regmap, + .disable =3D regulator_disable_regmap, + .is_enabled =3D regulator_is_enabled_regmap, + .set_suspend_voltage =3D rk801_set_suspend_voltage, + .set_suspend_enable =3D rk801_set_suspend_enable, + .set_suspend_disable =3D rk801_set_suspend_disable, +}; + +static const struct regulator_ops rk801_switch_ops =3D { + .enable =3D regulator_enable_regmap, + .disable =3D regulator_disable_regmap, + .is_enabled =3D regulator_is_enabled_regmap, + .set_suspend_enable =3D rk801_set_suspend_enable, + .set_suspend_disable =3D rk801_set_suspend_disable, +}; + static const struct regulator_ops rk805_reg_ops =3D { .list_voltage =3D regulator_list_voltage_linear, .map_voltage =3D regulator_map_voltage_linear, @@ -1049,6 +1171,123 @@ static const struct regulator_ops rk817_switch_ops = =3D { .set_suspend_disable =3D rk817_set_suspend_disable, }; =20 +static const struct linear_range rk801_buck1_voltage_ranges[] =3D { + REGULATOR_LINEAR_RANGE(500000, 0, 80, 12500), /* 0.5v - 1.5v */ + REGULATOR_LINEAR_RANGE(1800000, 81, 82, 400000),/* 1.8v - 2.2v */ + REGULATOR_LINEAR_RANGE(3300000, 83, 83, 0), /* 3.3v */ + REGULATOR_LINEAR_RANGE(5000000, 84, 84, 0), /* 5.0v */ + REGULATOR_LINEAR_RANGE(5250000, 85, 85, 0), /* 5.25v */ +}; + +static const struct linear_range rk801_buck2_voltage_ranges[] =3D { + REGULATOR_LINEAR_RANGE(800000, 0, 2, 50000), /* 0.8v - 0.9v */ + REGULATOR_LINEAR_RANGE(1800000, 3, 4, 400000), /* 1.8v - 2.2v */ + REGULATOR_LINEAR_RANGE(3300000, 5, 5, 0), /* 3.3v */ + REGULATOR_LINEAR_RANGE(5000000, 6, 6, 0), /* 5.0v */ + REGULATOR_LINEAR_RANGE(5250000, 7, 7, 0), /* 5.25v */ +}; + +static const struct linear_range rk801_buck4_voltage_ranges[] =3D { + REGULATOR_LINEAR_RANGE(500000, 0, 80, 12500), /* 0.5v - 1.5v */ + REGULATOR_LINEAR_RANGE(1800000, 81, 82, 400000),/* 1.8v - 2.2v */ + REGULATOR_LINEAR_RANGE(2500000, 83, 83, 0), /* 2.5v */ + REGULATOR_LINEAR_RANGE(2800000, 84, 84, 0), /* 2.8v */ + REGULATOR_LINEAR_RANGE(3000000, 85, 85, 0), /* 3.0v */ + REGULATOR_LINEAR_RANGE(3300000, 86, 86, 0), /* 3.3v */ +}; + +static const struct regulator_desc rk801_reg[] =3D { + { + .name =3D "DCDC_REG1", + .supply_name =3D "vcc1", + .of_match =3D of_match_ptr("DCDC_REG1"), + .regulators_node =3D of_match_ptr("regulators"), + .id =3D RK801_ID_DCDC1, + .ops =3D &rk801_buck_ops, + .type =3D REGULATOR_VOLTAGE, + .n_voltages =3D 86, + .linear_ranges =3D rk801_buck1_voltage_ranges, + .n_linear_ranges =3D ARRAY_SIZE(rk801_buck1_voltage_ranges), + .vsel_reg =3D RK801_BUCK1_ON_VSEL_REG, + .vsel_mask =3D RK801_BUCK_VSEL_MASK, + .enable_reg =3D RK801_POWER_EN0_REG, + .enable_mask =3D ENABLE_MASK(RK801_ID_DCDC1), + .enable_val =3D ENABLE_MASK(RK801_ID_DCDC1), + .disable_val =3D DISABLE_VAL(RK801_ID_DCDC1), + .ramp_delay =3D 1000, + .of_map_mode =3D rk8xx_regulator_of_map_mode, + .enable_time =3D 400, + .owner =3D THIS_MODULE, + }, { + .name =3D "DCDC_REG2", + .supply_name =3D "vcc2", + .of_match =3D of_match_ptr("DCDC_REG2"), + .regulators_node =3D of_match_ptr("regulators"), + .id =3D RK801_ID_DCDC2, + .ops =3D &rk801_buck_ops, + .type =3D REGULATOR_VOLTAGE, + .n_voltages =3D 8, + .linear_ranges =3D rk801_buck2_voltage_ranges, + .n_linear_ranges =3D ARRAY_SIZE(rk801_buck2_voltage_ranges), + .vsel_reg =3D RK801_BUCK2_ON_VSEL_REG, + .vsel_mask =3D RK801_BUCK_VSEL_MASK, + .enable_reg =3D RK801_POWER_EN0_REG, + .enable_mask =3D ENABLE_MASK(RK801_ID_DCDC2), + .enable_val =3D ENABLE_MASK(RK801_ID_DCDC2), + .disable_val =3D DISABLE_VAL(RK801_ID_DCDC2), + .ramp_delay =3D 1000, + .of_map_mode =3D rk8xx_regulator_of_map_mode, + .enable_time =3D 400, + .owner =3D THIS_MODULE, + }, { + .name =3D "DCDC_REG3", + .supply_name =3D "vcc3", + .of_match =3D of_match_ptr("DCDC_REG3"), + .regulators_node =3D of_match_ptr("regulators"), + .id =3D RK801_ID_DCDC3, + .ops =3D &rk801_switch_ops, + .type =3D REGULATOR_VOLTAGE, + .n_voltages =3D 1, + .enable_reg =3D RK801_POWER_EN0_REG, + .enable_mask =3D ENABLE_MASK(RK801_ID_DCDC3), + .enable_val =3D ENABLE_MASK(RK801_ID_DCDC3), + .disable_val =3D DISABLE_VAL(RK801_ID_DCDC3), + .of_map_mode =3D rk8xx_regulator_of_map_mode, + .enable_time =3D 400, + .owner =3D THIS_MODULE, + }, { + .name =3D "DCDC_REG4", + .supply_name =3D "vcc4", + .of_match =3D of_match_ptr("DCDC_REG4"), + .regulators_node =3D of_match_ptr("regulators"), + .id =3D RK801_ID_DCDC4, + .ops =3D &rk801_buck_ops, + .type =3D REGULATOR_VOLTAGE, + .n_voltages =3D 87, + .linear_ranges =3D rk801_buck4_voltage_ranges, + .n_linear_ranges =3D ARRAY_SIZE(rk801_buck4_voltage_ranges), + .vsel_reg =3D RK801_BUCK4_ON_VSEL_REG, + .vsel_mask =3D RK801_BUCK_VSEL_MASK, + .enable_reg =3D RK801_POWER_EN0_REG, + .enable_mask =3D ENABLE_MASK(RK801_ID_DCDC4), + .enable_val =3D ENABLE_MASK(RK801_ID_DCDC4), + .disable_val =3D DISABLE_VAL(RK801_ID_DCDC4), + .ramp_delay =3D 1000, + .of_map_mode =3D rk8xx_regulator_of_map_mode, + .enable_time =3D 400, + .owner =3D THIS_MODULE, + }, + + RK801_DESC(RK801_ID_LDO1, "LDO_REG1", "vcc5", 500, 3400, 50, + RK801_LDO1_ON_VSEL_REG, RK801_LDO_VSEL_MASK, RK801_POWER_EN1_REG, + ENABLE_MASK(0), DISABLE_VAL(0), 400), + RK801_DESC(RK801_ID_LDO2, "LDO_REG2", "vcc6", 500, 3400, 50, + RK801_LDO2_ON_VSEL_REG, RK801_LDO_VSEL_MASK, RK801_POWER_EN1_REG, + ENABLE_MASK(1), DISABLE_VAL(1), 400), + RK801_DESC_SWITCH(RK801_ID_SWITCH, "SWITCH_REG", "vcc7", RK801_POWER_EN1_= REG, + ENABLE_MASK(2), DISABLE_VAL(2)), +}; + static const struct regulator_desc rk805_reg[] =3D { { .name =3D "DCDC_REG1", @@ -1887,6 +2126,10 @@ static int rk808_regulator_probe(struct platform_dev= ice *pdev) return -ENOMEM; =20 switch (rk808->variant) { + case RK801_ID: + regulators =3D rk801_reg; + nregulators =3D RK801_NUM_REGULATORS; + break; case RK805_ID: regulators =3D rk805_reg; nregulators =3D RK805_NUM_REGULATORS; diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h index 28170ee0889..7ffc904c864 100644 --- a/include/linux/mfd/rk808.h +++ b/include/linux/mfd/rk808.h @@ -340,6 +340,123 @@ enum rk818_reg { #define RK818_USB_ILMIN_2000MA 0x7 #define RK818_USB_CHG_SD_VSEL_MASK 0x70 =20 +/* RK801 */ +enum rk801_reg { + RK801_ID_DCDC1, + RK801_ID_DCDC2, + RK801_ID_DCDC4, + RK801_ID_DCDC3, + RK801_ID_LDO1, + RK801_ID_LDO2, + RK801_ID_SWITCH, + RK801_ID_MAX, +}; + +#define RK801_SLP_REG_OFFSET 5 +#define RK801_NUM_REGULATORS 7 + +#define RK801_HW_SYNC_US 32 + +/* RK801 Register Definitions */ +#define RK801_ID_MSB 0x00 +#define RK801_ID_LSB 0x01 +#define RK801_OTP_VER_REG 0x02 +#define RK801_POWER_EN0_REG 0x03 +#define RK801_POWER_EN1_REG 0x04 +#define RK801_POWER_SLP_EN_REG 0x05 +#define RK801_POWER_FPWM_EN_REG 0x06 +#define RK801_SLP_LP_CONFIG_REG 0x07 +#define RK801_BUCK_CONFIG_REG 0x08 +#define RK801_BUCK1_ON_VSEL_REG 0x09 +#define RK801_BUCK2_ON_VSEL_REG 0x0a +#define RK801_BUCK4_ON_VSEL_REG 0x0b +#define RK801_LDO1_ON_VSEL_REG 0x0c +#define RK801_LDO2_ON_VSEL_REG 0x0d +#define RK801_BUCK1_SLP_VSEL_REG 0x0e +#define RK801_BUCK2_SLP_VSEL_REG 0x0f +#define RK801_BUCK4_SLP_VSEL_REG 0x10 +#define RK801_LDO1_SLP_VSEL_REG 0x11 +#define RK801_LDO2_SLP_VSEL_REG 0x12 +#define RK801_LDO_SW_IMAX_REG 0x13 +#define RK801_SYS_STS_REG 0x14 +#define RK801_SYS_CFG0_REG 0x15 +#define RK801_SYS_CFG1_REG 0x16 +#define RK801_SYS_CFG2_REG 0x17 +#define RK801_SYS_CFG3_REG 0x18 +#define RK801_SYS_CFG4_REG 0x19 +#define RK801_SLEEP_CFG_REG 0x1a +#define RK801_ON_SOURCE_REG 0x1b +#define RK801_OFF_SOURCE_REG 0x1c +#define RK801_PWRON_KEY_REG 0x1d +#define RK801_INT_STS0_REG 0x1e +#define RK801_INT_MASK0_REG 0x1f +#define RK801_INT_CONFIG_REG 0x20 +#define RK801_CON_BACK1_REG 0x21 +#define RK801_CON_BACK2_REG 0x22 +#define RK801_DATA_CON0_REG 0x23 +#define RK801_DATA_CON1_REG 0x24 +#define RK801_DATA_CON2_REG 0x25 +#define RK801_DATA_CON3_REG 0x26 +#define RK801_POWER_EXIT_SLP_SEQ0_REG 0x27 +#define RK801_POWER_EXIT_SLP_SEQ1_REG 0x28 +#define RK801_POWER_EXIT_SLP_SEQ2_REG 0x29 +#define RK801_POWER_EXIT_SLP_SEQ3_REG 0x2a +#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ0_REG 0x2b +#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ1_REG 0x2c +#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ2_REG 0x2d +#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ3_REG 0x2e +#define RK801_BUCK_DEBUG1_REG 0x2f +#define RK801_BUCK_DEBUG2_REG 0x30 +#define RK801_BUCK_DEBUG3_REG 0x31 +#define RK801_BUCK_DEBUG4_REG 0x32 +#define RK801_BUCK_DEBUG5_REG 0x33 +#define RK801_BUCK_DEBUG7_REG 0x34 +#define RK801_OTP_EN_CON_REG 0x35 +#define RK801_TEST_CON_REG 0x36 +#define RK801_EFUSE_CONTROL_REG 0x37 +#define RK801_SYS_CFG3_OTP_REG 0x38 + +/* RK801 IRQ Definitions */ +#define RK801_IRQ_PWRON_FALL 0 +#define RK801_IRQ_PWRON_RISE 1 +#define RK801_IRQ_PWRON 2 +#define RK801_IRQ_PWRON_LP 3 +#define RK801_IRQ_HOTDIE 4 +#define RK801_IRQ_VDC_RISE 5 +#define RK801_IRQ_VDC_FALL 6 +#define RK801_IRQ_PWRON_FALL_MSK BIT(0) +#define RK801_IRQ_PWRON_RISE_MSK BIT(1) +#define RK801_IRQ_PWRON_MSK BIT(2) +#define RK801_IRQ_PWRON_LP_MSK BIT(3) +#define RK801_IRQ_HOTDIE_MSK BIT(4) +#define RK801_IRQ_VDC_RISE_MSK BIT(5) +#define RK801_IRQ_VDC_FALL_MSK BIT(6) +/* RK801_SLP_LP_CONFIG_REG */ +#define RK801_BUCK_SLP_LP_EN BIT(3) +#define RK801_PLDO_SLP_LP_EN BIT(1) +#define RK801_SLP_LP_MASK (RK801_PLDO_SLP_LP_EN | RK801_BUCK_SLP_LP_EN) +/* RK801_SLEEP_CFG_REG */ +#define RK801_SLEEP_FUN_MSK 0x3 +#define RK801_NONE_FUN 0x0 +#define RK801_SLEEP_FUN 0x1 +#define RK801_SHUTDOWN_FUN 0x2 +#define RK801_RESET_FUN 0x3 +/* RK801_SYS_CFG2_REG */ +#define RK801_SLEEP_POL_MSK BIT(1) +#define RK801_SLEEP_ACT_H BIT(1) +#define RK801_SLEEP_ACT_L 0 +#define RK801_RST_MSK (0x3 << 4) +#define RK801_RST_RESTART_PMU (0x0 << 4) +#define RK801_RST_RESTART_REG (0x1 << 4) +#define RK801_RST_RESTART_REG_RESETB (0x2 << 4) +/* RK801_INT_CONFIG_REG */ +#define RK801_INT_POL_MSK BIT(1) +#define RK801_INT_ACT_H BIT(1) +#define RK801_INT_ACT_L 0 +#define RK801_FPWM_MODE 1 +#define RK801_AUTO_PWM_MODE 0 +#define RK801_PLDO_HRDEC_EN BIT(6) + /* RK805 */ enum rk805_reg { RK805_ID_DCDC1, @@ -1332,6 +1449,7 @@ enum { }; =20 enum { + RK801_ID =3D 0x8010, RK805_ID =3D 0x8050, RK806_ID =3D 0x8060, RK808_ID =3D 0x0000, --=20 2.25.1