summaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
authorAndreas Kemnade <andreas@kemnade.info>2024-02-17 09:20:04 +0100
committerLee Jones <lee@kernel.org>2024-02-23 16:11:39 +0000
commitca9414a1d08756c8392f9219caee607e1b7bade1 (patch)
tree95bc6fc005bd9cfdd38dbe7e1ba9f9706d20b147 /drivers/mfd
parent0c7cc7497f6f62a65037e94cf0d885ab0af3c0d3 (diff)
mfd: twl-core: Add power off implementation for twl603x
If the system-power-controller property is there, enable power off. Implementation is based on a Linux v3.0 vendor kernel. Signed-off-by: Andreas Kemnade <andreas@kemnade.info> Link: https://lore.kernel.org/r/20240217082007.3238948-3-andreas@kemnade.info Signed-off-by: Lee Jones <lee@kernel.org>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/twl-core.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 6e384a79e341..c130ffef182f 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -124,6 +124,11 @@
#define TWL6030_BASEADD_RSV 0x0000
#define TWL6030_BASEADD_ZERO 0x0000
+/* Some fields in TWL6030_PHOENIX_DEV_ON */
+#define TWL6030_APP_DEVOFF BIT(0)
+#define TWL6030_CON_DEVOFF BIT(1)
+#define TWL6030_MOD_DEVOFF BIT(2)
+
/* Few power values */
#define R_CFG_BOOT 0x05
@@ -687,6 +692,20 @@ static void twl_remove(struct i2c_client *client)
twl_priv->ready = false;
}
+static void twl6030_power_off(void)
+{
+ int err;
+ u8 val;
+
+ err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val, TWL6030_PHOENIX_DEV_ON);
+ if (err)
+ return;
+
+ val |= TWL6030_APP_DEVOFF | TWL6030_CON_DEVOFF | TWL6030_MOD_DEVOFF;
+ twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val, TWL6030_PHOENIX_DEV_ON);
+}
+
+
static struct of_dev_auxdata twl_auxdata_lookup[] = {
OF_DEV_AUXDATA("ti,twl4030-gpio", 0, "twl4030-gpio", NULL),
{ /* sentinel */ },
@@ -852,6 +871,15 @@ twl_probe(struct i2c_client *client)
goto free;
}
+ if (twl_class_is_6030()) {
+ if (of_device_is_system_power_controller(node)) {
+ if (!pm_power_off)
+ pm_power_off = twl6030_power_off;
+ else
+ dev_warn(&client->dev, "Poweroff callback already assigned\n");
+ }
+ }
+
status = of_platform_populate(node, NULL, twl_auxdata_lookup,
&client->dev);