misc: tps6594-pfsm: Add TI TPS65224 PMIC PFSM
authorBhargav Raviprakash <bhargav.r@ltts.com>
Tue, 30 Apr 2024 16:35:38 +0000 (16:35 +0000)
committerLee Jones <lee@kernel.org>
Fri, 3 May 2024 09:07:07 +0000 (10:07 +0100)
Add support for TPS65224 PFSM in the TPS6594 PFSM driver as they share
significant functionality.

Signed-off-by: Bhargav Raviprakash <bhargav.r@ltts.com>
Acked-by: Julien Panis <jpanis@baylibre.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://lore.kernel.org/r/0109018f2fdc9dc4-db5a45c0-0148-48cc-8462-d1c5b577a4bd-000000@ap-south-1.amazonses.com
Signed-off-by: Lee Jones <lee@kernel.org>
drivers/misc/tps6594-pfsm.c

index 88dcac8148922c7f5dc8fcf7147f7dc218c26728..9bcca1856bfeea15b4fd9ef92153e6ac79b9eb56 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * PFSM (Pre-configurable Finite State Machine) driver for TI TPS6594/TPS6593/LP8764 PMICs
+ * PFSM (Pre-configurable Finite State Machine) driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
  *
  * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
  */
  *
  * @miscdev: misc device infos
  * @regmap:  regmap for accessing the device registers
+ * @chip_id: chip identifier of the device
  */
 struct tps6594_pfsm {
        struct miscdevice miscdev;
        struct regmap *regmap;
+       unsigned long chip_id;
 };
 
 static ssize_t tps6594_pfsm_read(struct file *f, char __user *buf,
@@ -133,21 +135,29 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
        struct tps6594_pfsm *pfsm = TPS6594_FILE_TO_PFSM(f);
        struct pmic_state_opt state_opt;
        void __user *argp = (void __user *)arg;
+       unsigned int regmap_reg, mask;
        int ret = -ENOIOCTLCMD;
 
        switch (cmd) {
        case PMIC_GOTO_STANDBY:
-               /* Disable LP mode */
-               ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
-                                       TPS6594_BIT_LP_STANDBY_SEL);
-               if (ret)
-                       return ret;
+               /* Disable LP mode on TPS6594 Family PMIC */
+               if (pfsm->chip_id != TPS65224) {
+                       ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
+                                               TPS6594_BIT_LP_STANDBY_SEL);
+
+                       if (ret)
+                               return ret;
+               }
 
                /* Force trigger */
                ret = regmap_write_bits(pfsm->regmap, TPS6594_REG_FSM_I2C_TRIGGERS,
                                        TPS6594_BIT_TRIGGER_I2C(0), TPS6594_BIT_TRIGGER_I2C(0));
                break;
        case PMIC_GOTO_LP_STANDBY:
+               /* TPS65224 does not support LP STANDBY */
+               if (pfsm->chip_id == TPS65224)
+                       return ret;
+
                /* Enable LP mode */
                ret = regmap_set_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
                                      TPS6594_BIT_LP_STANDBY_SEL);
@@ -169,6 +179,10 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
                                      TPS6594_BIT_NSLEEP1B | TPS6594_BIT_NSLEEP2B);
                break;
        case PMIC_SET_MCU_ONLY_STATE:
+               /* TPS65224 does not support MCU_ONLY_STATE */
+               if (pfsm->chip_id == TPS65224)
+                       return ret;
+
                if (copy_from_user(&state_opt, argp, sizeof(state_opt)))
                        return -EFAULT;
 
@@ -192,14 +206,20 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
                        return -EFAULT;
 
                /* Configure wake-up destination */
+               if (pfsm->chip_id == TPS65224) {
+                       regmap_reg = TPS65224_REG_STARTUP_CTRL;
+                       mask = TPS65224_MASK_STARTUP_DEST;
+               } else {
+                       regmap_reg = TPS6594_REG_RTC_CTRL_2;
+                       mask = TPS6594_MASK_STARTUP_DEST;
+               }
+
                if (state_opt.mcu_only_startup_dest)
-                       ret = regmap_write_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
-                                               TPS6594_MASK_STARTUP_DEST,
-                                               TPS6594_STARTUP_DEST_MCU_ONLY);
+                       ret = regmap_write_bits(pfsm->regmap, regmap_reg,
+                                               mask, TPS6594_STARTUP_DEST_MCU_ONLY);
                else
-                       ret = regmap_write_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
-                                               TPS6594_MASK_STARTUP_DEST,
-                                               TPS6594_STARTUP_DEST_ACTIVE);
+                       ret = regmap_write_bits(pfsm->regmap, regmap_reg,
+                                               mask, TPS6594_STARTUP_DEST_ACTIVE);
                if (ret)
                        return ret;
 
@@ -211,7 +231,8 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
 
                /* Modify NSLEEP1-2 bits */
                ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS,
-                                       TPS6594_BIT_NSLEEP2B);
+                                       pfsm->chip_id == TPS65224 ?
+                                       TPS6594_BIT_NSLEEP1B : TPS6594_BIT_NSLEEP2B);
                break;
        }
 
@@ -262,6 +283,7 @@ static int tps6594_pfsm_probe(struct platform_device *pdev)
                                            tps->chip_id, tps->reg);
        pfsm->miscdev.fops = &tps6594_pfsm_fops;
        pfsm->miscdev.parent = dev->parent;
+       pfsm->chip_id = tps->chip_id;
 
        for (i = 0 ; i < pdev->num_resources ; i++) {
                irq = platform_get_irq_byname(pdev, pdev->resource[i].name);