]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
power: supply: max1720x: add health property
authorDimitri Fedrau <dimitri.fedrau@liebherr.com>
Tue, 4 Feb 2025 13:10:31 +0000 (14:10 +0100)
committerSebastian Reichel <sebastian.reichel@collabora.com>
Wed, 19 Feb 2025 23:27:50 +0000 (00:27 +0100)
Add health property, which checks that temperature, voltage and current are
within limits for the battery. Limits can be programmed in non-volatile
memory.

Signed-off-by: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
Link: https://lore.kernel.org/r/20250204-max1720x_health-v1-1-97ebbe4a0bc5@liebherr.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
drivers/power/supply/max1720x_battery.c

index 2c9aea4f5d7f4497ae0ce7568e723167bf8a86be..c1eaf3f7a78230d9324a2f4af20c5d5229ae6d88 100644 (file)
 /* ModelGauge m5 */
 #define MAX172XX_STATUS                        0x00    /* Status */
 #define MAX172XX_STATUS_BAT_ABSENT     BIT(3)  /* Battery absent */
+#define MAX172XX_STATUS_IMX            BIT(6)  /* Maximum Current Alert Threshold Exceeded */
+#define MAX172XX_STATUS_VMN            BIT(8)  /* Minimum Voltage Alert Threshold Exceeded */
+#define MAX172XX_STATUS_TMN            BIT(9)  /* Minimum Temperature Alert Threshold Exceeded */
+#define MAX172XX_STATUS_VMX            BIT(12) /* Maximum Voltage Alert Threshold Exceeded */
+#define MAX172XX_STATUS_TMX            BIT(13) /* Maximum Temperature Alert Threshold Exceeded */
 #define MAX172XX_REPCAP                        0x05    /* Average capacity */
 #define MAX172XX_REPSOC                        0x06    /* Percentage of charge */
 #define MAX172XX_TEMP                  0x08    /* Temperature */
@@ -250,6 +255,7 @@ static const struct nvmem_cell_info max1720x_nvmem_cells[] = {
 };
 
 static const enum power_supply_property max1720x_battery_props[] = {
+       POWER_SUPPLY_PROP_HEALTH,
        POWER_SUPPLY_PROP_PRESENT,
        POWER_SUPPLY_PROP_CAPACITY,
        POWER_SUPPLY_PROP_VOLTAGE_NOW,
@@ -314,6 +320,43 @@ static int max172xx_current_to_voltage(unsigned int reg)
        return val * 156252;
 }
 
+static int max172xx_battery_health(struct max1720x_device_info *info,
+                                  unsigned int *health)
+{
+       unsigned int status;
+       int ret;
+
+       ret = regmap_read(info->regmap, MAX172XX_STATUS, &status);
+       if (ret < 0)
+               return ret;
+
+       if (status & MAX172XX_STATUS_VMN)
+               *health = POWER_SUPPLY_HEALTH_DEAD;
+       else if (status & MAX172XX_STATUS_VMX)
+               *health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
+       else if (status & MAX172XX_STATUS_TMN)
+               *health = POWER_SUPPLY_HEALTH_COLD;
+       else if (status & MAX172XX_STATUS_TMX)
+               *health = POWER_SUPPLY_HEALTH_OVERHEAT;
+       else if (status & MAX172XX_STATUS_IMX)
+               *health = POWER_SUPPLY_HEALTH_OVERCURRENT;
+       else
+               *health = POWER_SUPPLY_HEALTH_GOOD;
+
+       /* Clear events which are not self-clearing to detect next events */
+       if (status > 0 && status != MAX172XX_STATUS_IMX) {
+               ret = regmap_set_bits(info->regmap, MAX172XX_STATUS,
+                                     MAX172XX_STATUS_VMN |
+                                     MAX172XX_STATUS_VMX |
+                                     MAX172XX_STATUS_TMN |
+                                     MAX172XX_STATUS_TMX);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
 static int max1720x_battery_get_property(struct power_supply *psy,
                                         enum power_supply_property psp,
                                         union power_supply_propval *val)
@@ -323,6 +366,10 @@ static int max1720x_battery_get_property(struct power_supply *psy,
        int ret = 0;
 
        switch (psp) {
+       case POWER_SUPPLY_PROP_HEALTH:
+               ret = max172xx_battery_health(info, &reg_val);
+               val->intval = reg_val;
+               break;
        case POWER_SUPPLY_PROP_PRESENT:
                /*
                 * POWER_SUPPLY_PROP_PRESENT will always readable via