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
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.
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
On 2025/9/30 13:30, Otto Pflüger wrote: > 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 OK. Thanks. Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
On Tue, Oct 14, 2025 at 09:44:15AM +0800, Baolin Wang wrote: > [...] > > > > 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 > > OK. Thanks. > Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> Please note that due to the feedback about the use of empty device tree nodes, I have switched to a different approach and sent an alternative patch as a follow-up to this one: https://lore.kernel.org/all/20251007-sc27xx-mfd-poweroff-v1-0-89a2f919b731@abscue.de/
© 2016 - 2026 Red Hat, Inc.