[PATCH 4/5] power: reset: sc27xx: Add support for SC2730 and OF match table

Otto Pflüger posted 5 patches 5 days, 6 hours ago
[PATCH 4/5] power: reset: sc27xx: Add support for SC2730 and OF match table
Posted by Otto Pflüger 5 days, 6 hours ago
Add register definitions for the SC2730 PMIC. Introduce a new struct
sc27xx_poweroff_data for passing register information to the poweroff
handler. Implement device tree matching to distinguish between SC2730
and SC2731 and to probe the driver automatically.

Signed-off-by: Otto Pflüger <otto.pflueger@abscue.de>
---
 drivers/power/reset/sc27xx-poweroff.c | 67 +++++++++++++++++++++++++++++------
 1 file changed, 57 insertions(+), 10 deletions(-)

diff --git a/drivers/power/reset/sc27xx-poweroff.c b/drivers/power/reset/sc27xx-poweroff.c
index 20eb9f32cb2b99adeb16502172adf9d6257cd05f..5937f40021817ea38453705fcef6485ce79ac14c 100644
--- a/drivers/power/reset/sc27xx-poweroff.c
+++ b/drivers/power/reset/sc27xx-poweroff.c
@@ -7,16 +7,33 @@
 #include <linux/cpu.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/reboot.h>
 #include <linux/regmap.h>
 #include <linux/syscore_ops.h>
 
-#define SC27XX_PWR_PD_HW	0xc2c
+#define SC2730_PWR_PD_HW	0x1820
+#define SC2730_SLP_CTRL		0x1a48
+#define SC2730_LDO_XTL_EN	BIT(2)
+
+#define SC2731_PWR_PD_HW	0xc2c
+#define SC2731_SLP_CTRL		0xdf0
+#define SC2731_LDO_XTL_EN	BIT(3)
+
 #define SC27XX_PWR_OFF_EN	BIT(0)
-#define SC27XX_SLP_CTRL		0xdf0
-#define SC27XX_LDO_XTL_EN	BIT(3)
+
+struct sc27xx_poweroff_reg_info {
+	u32 poweroff_reg;
+	u32 slp_ctrl_reg;
+	u32 ldo_xtl_en;
+};
+
+struct sc27xx_poweroff_data {
+	struct regmap *regmap;
+	const struct sc27xx_poweroff_reg_info *regs;
+};
 
 /*
  * On Spreadtrum platform, we need power off system through external SC27xx
@@ -45,12 +62,14 @@ static struct syscore_ops poweroff_syscore_ops = {
 
 static int sc27xx_poweroff_do_poweroff(struct sys_off_data *off_data)
 {
-	struct regmap *regmap = off_data->cb_data;
+	struct sc27xx_poweroff_data *data = off_data->cb_data;
 
 	/* Disable the external subsys connection's power firstly */
-	regmap_write(regmap, SC27XX_SLP_CTRL, SC27XX_LDO_XTL_EN);
+	regmap_write(data->regmap, data->regs->slp_ctrl_reg,
+		     data->regs->ldo_xtl_en);
 
-	regmap_write(regmap, SC27XX_PWR_PD_HW, SC27XX_PWR_OFF_EN);
+	regmap_write(data->regmap, data->regs->poweroff_reg,
+		     SC27XX_PWR_OFF_EN);
 
 	mdelay(1000);
 
@@ -61,10 +80,18 @@ static int sc27xx_poweroff_do_poweroff(struct sys_off_data *off_data)
 
 static int sc27xx_poweroff_probe(struct platform_device *pdev)
 {
-	struct regmap *regmap;
+	struct sc27xx_poweroff_data *data;
 
-	regmap = dev_get_regmap(pdev->dev.parent, NULL);
-	if (!regmap)
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->regs = of_device_get_match_data(&pdev->dev);
+	if (!data->regs)
+		return -EINVAL;
+
+	data->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!data->regmap)
 		return -ENODEV;
 
 	register_syscore_ops(&poweroff_syscore_ops);
@@ -73,13 +100,33 @@ static int sc27xx_poweroff_probe(struct platform_device *pdev)
 					     SYS_OFF_MODE_POWER_OFF,
 					     SYS_OFF_PRIO_DEFAULT,
 					     sc27xx_poweroff_do_poweroff,
-					     regmap);
+					     data);
 }
 
+static const struct sc27xx_poweroff_reg_info sc2730_pwr_regs = {
+	.poweroff_reg = SC2730_PWR_PD_HW,
+	.slp_ctrl_reg = SC2730_SLP_CTRL,
+	.ldo_xtl_en = SC2730_LDO_XTL_EN,
+};
+
+static const struct sc27xx_poweroff_reg_info sc2731_pwr_regs = {
+	.poweroff_reg = SC2731_PWR_PD_HW,
+	.slp_ctrl_reg = SC2731_SLP_CTRL,
+	.ldo_xtl_en = SC2731_LDO_XTL_EN,
+};
+
+static const struct of_device_id sc27xx_poweroff_of_match[] = {
+	{ .compatible = "sprd,sc2730-poweroff", .data = &sc2730_pwr_regs },
+	{ .compatible = "sprd,sc2731-poweroff", .data = &sc2731_pwr_regs },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sc27xx_poweroff_of_match);
+
 static struct platform_driver sc27xx_poweroff_driver = {
 	.probe = sc27xx_poweroff_probe,
 	.driver = {
 		.name = "sc27xx-poweroff",
+		.of_match_table = sc27xx_poweroff_of_match,
 	},
 };
 module_platform_driver(sc27xx_poweroff_driver);

-- 
2.50.0

Re: [PATCH 4/5] power: reset: sc27xx: Add support for SC2730 and OF match table
Posted by Baolin Wang 1 day, 19 hours ago

On 2025/9/27 00:23, Otto Pflüger wrote:
> Add register definitions for the SC2730 PMIC. Introduce a new struct
> sc27xx_poweroff_data for passing register information to the poweroff
> handler. Implement device tree matching to distinguish between SC2730
> and SC2731 and to probe the driver automatically.
> 
> Signed-off-by: Otto Pflüger <otto.pflueger@abscue.de>
> ---

If I remember correctly, the original driver supported SC2730 and SC2731 
chips. Are you sure the current changes are still needed? Have you 
tested them on the SC2730 chip?


config POWER_RESET_SC27XX
         tristate "Spreadtrum SC27xx PMIC power-off driver"
         depends on MFD_SC27XX_PMIC || COMPILE_TEST
         help
           This driver supports powering off a system through
           Spreadtrum SC27xx series PMICs. The SC27xx series
           PMICs includes the SC2720, SC2721, SC2723, SC2730
           and SC2731 chips.
Re: [PATCH 4/5] power: reset: sc27xx: Add support for SC2730 and OF match table
Posted by Otto Pflüger 1 day, 17 hours ago
On Tue, Sep 30, 2025 at 11:30:16AM +0800, Baolin Wang wrote:
> 
> If I remember correctly, the original driver supported SC2730 and SC2731
> chips. Are you sure the current changes are still needed? Have you tested
> them on the SC2730 chip?
> 
> 
> config POWER_RESET_SC27XX
>         tristate "Spreadtrum SC27xx PMIC power-off driver"
>         depends on MFD_SC27XX_PMIC || COMPILE_TEST
>         help
>           This driver supports powering off a system through
>           Spreadtrum SC27xx series PMICs. The SC27xx series
>           PMICs includes the SC2720, SC2721, SC2723, SC2730
>           and SC2731 chips.

The driver was hard-coded to use registers 0xc2c and 0xdf0. SC2730 has
different registers, which were added to the downstream version of the
driver in [1]. I have tested this with a UMS9230 phone which has an
SC2730 PMIC according to the device tree.

[1]: https://github.com/MotorolaMobilityLLC/kernel-sprd/commit/6165e1afe3eba33089fecc86767d47af9ab176d6