mfd: tps6594: Add power button functionality

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>
This commit is contained in:
Michael Walle 2025-08-26 15:46:30 +02:00 committed by Lee Jones
parent 170031ff27
commit d766ca01c2
1 changed files with 36 additions and 2 deletions

View 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,