]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mfd: tps6594: Add power button functionality
authorMichael Walle <mwalle@kernel.org>
Tue, 26 Aug 2025 13:46:30 +0000 (15:46 +0200)
committerLee Jones <lee@kernel.org>
Wed, 3 Sep 2025 10:28:26 +0000 (11:28 +0100)
The PMIC has a multi-function pin PB/EN/VSENSE. If it is configured as
push-button (PB), add the corresponding device for it.

Co-developed-by: Job Sava <jsava@criticallink.com>
Signed-off-by: Job Sava <jsava@criticallink.com>
Signed-off-by: Michael Walle <mwalle@kernel.org>
Link: https://lore.kernel.org/r/20250826134631.1499936-3-mwalle@kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
drivers/mfd/tps6594-core.c

index c16c37e366178762ae8c32ec26d5d8ef7442facc..9195c90594898f3605831bf85fbac6a7204a4d0a 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/mfd/tps6594.h>
 
 #define TPS6594_CRC_SYNC_TIMEOUT_MS 150
+#define TPS65224_EN_SEL_PB 1
+#define TPS65224_GPIO3_SEL_PB 3
 
 /* Completion to synchronize CRC feature enabling on all PMICs */
 static DECLARE_COMPLETION(tps6594_crc_comp);
@@ -128,6 +130,12 @@ static const struct resource tps6594_rtc_resources[] = {
        DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_POWER_UP, TPS6594_IRQ_NAME_POWERUP),
 };
 
+static const struct resource tps6594_pwrbutton_resources[] = {
+       DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_FALL, TPS65224_IRQ_NAME_PB_FALL),
+       DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_RISE, TPS65224_IRQ_NAME_PB_RISE),
+       DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_SHORT, TPS65224_IRQ_NAME_PB_SHORT),
+};
+
 static const struct mfd_cell tps6594_common_cells[] = {
        MFD_CELL_RES("tps6594-regulator", tps6594_regulator_resources),
        MFD_CELL_RES("tps6594-pinctrl", tps6594_pinctrl_resources),
@@ -318,8 +326,6 @@ static const struct resource tps65224_pfsm_resources[] = {
        DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_REG_UNLOCK, TPS65224_IRQ_NAME_REG_UNLOCK),
        DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_TWARN, TPS65224_IRQ_NAME_TWARN),
        DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_LONG, TPS65224_IRQ_NAME_PB_LONG),
-       DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_FALL, TPS65224_IRQ_NAME_PB_FALL),
-       DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_PB_RISE, TPS65224_IRQ_NAME_PB_RISE),
        DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_TSD_ORD, TPS65224_IRQ_NAME_TSD_ORD),
        DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_BIST_FAIL, TPS65224_IRQ_NAME_BIST_FAIL),
        DEFINE_RES_IRQ_NAMED(TPS65224_IRQ_REG_CRC_ERR, TPS65224_IRQ_NAME_REG_CRC_ERR),
@@ -347,6 +353,12 @@ static const struct mfd_cell tps65224_common_cells[] = {
        MFD_CELL_RES("tps6594-regulator", tps65224_regulator_resources),
 };
 
+static const struct mfd_cell tps6594_pwrbutton_cell = {
+       .name = "tps6594-pwrbutton",
+       .resources = tps6594_pwrbutton_resources,
+       .num_resources = ARRAY_SIZE(tps6594_pwrbutton_resources),
+};
+
 static const struct regmap_irq tps65224_irqs[] = {
        /* INT_BUCK register */
        REGMAP_IRQ_REG(TPS65224_IRQ_BUCK1_UVOV, 0, TPS65224_BIT_BUCK1_UVOV_INT),
@@ -681,6 +693,7 @@ int tps6594_device_init(struct tps6594 *tps, bool enable_crc)
        struct device *dev = tps->dev;
        int ret;
        struct regmap_irq_chip *irq_chip;
+       unsigned int pwr_on, gpio3_cfg;
        const struct mfd_cell *cells;
        int n_cells;
 
@@ -727,6 +740,27 @@ int tps6594_device_init(struct tps6594 *tps, bool enable_crc)
        if (ret)
                return dev_err_probe(dev, ret, "Failed to add common child devices\n");
 
+       /* If either the PB/EN/VSENSE or GPIO3 is configured as PB, register a driver for it */
+       if (tps->chip_id == TPS65224 || tps->chip_id == TPS652G1) {
+               ret = regmap_read(tps->regmap, TPS6594_REG_NPWRON_CONF, &pwr_on);
+               if (ret)
+                       return dev_err_probe(dev, ret, "Failed to read PB/EN/VSENSE config\n");
+
+               ret = regmap_read(tps->regmap, TPS6594_REG_GPIOX_CONF(2), &gpio3_cfg);
+               if (ret)
+                       return dev_err_probe(dev, ret, "Failed to read GPIO3 config\n");
+
+               if (FIELD_GET(TPS65224_MASK_EN_PB_VSENSE_CONFIG, pwr_on) == TPS65224_EN_SEL_PB ||
+                   FIELD_GET(TPS65224_MASK_GPIO_SEL, gpio3_cfg) == TPS65224_GPIO3_SEL_PB) {
+                       ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO,
+                                                  &tps6594_pwrbutton_cell, 1, NULL, 0,
+                                                  regmap_irq_get_domain(tps->irq_data));
+                       if (ret)
+                               return dev_err_probe(dev, ret,
+                                                    "Failed to add power button device.\n");
+               }
+       }
+
        /* No RTC for LP8764, TPS65224 and TPS652G1 */
        if (tps->chip_id != LP8764 && tps->chip_id != TPS65224 && tps->chip_id != TPS652G1) {
                ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, tps6594_rtc_cells,