Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

power: supply: max1720x: add health property

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>

authored by

Dimitri Fedrau and committed by
Sebastian Reichel
4ad5c726 252e6671

+47
+47
drivers/power/supply/max1720x_battery.c
··· 29 29 /* ModelGauge m5 */ 30 30 #define MAX172XX_STATUS 0x00 /* Status */ 31 31 #define MAX172XX_STATUS_BAT_ABSENT BIT(3) /* Battery absent */ 32 + #define MAX172XX_STATUS_IMX BIT(6) /* Maximum Current Alert Threshold Exceeded */ 33 + #define MAX172XX_STATUS_VMN BIT(8) /* Minimum Voltage Alert Threshold Exceeded */ 34 + #define MAX172XX_STATUS_TMN BIT(9) /* Minimum Temperature Alert Threshold Exceeded */ 35 + #define MAX172XX_STATUS_VMX BIT(12) /* Maximum Voltage Alert Threshold Exceeded */ 36 + #define MAX172XX_STATUS_TMX BIT(13) /* Maximum Temperature Alert Threshold Exceeded */ 32 37 #define MAX172XX_REPCAP 0x05 /* Average capacity */ 33 38 #define MAX172XX_REPSOC 0x06 /* Percentage of charge */ 34 39 #define MAX172XX_TEMP 0x08 /* Temperature */ ··· 255 250 }; 256 251 257 252 static const enum power_supply_property max1720x_battery_props[] = { 253 + POWER_SUPPLY_PROP_HEALTH, 258 254 POWER_SUPPLY_PROP_PRESENT, 259 255 POWER_SUPPLY_PROP_CAPACITY, 260 256 POWER_SUPPLY_PROP_VOLTAGE_NOW, ··· 320 314 return val * 156252; 321 315 } 322 316 317 + static int max172xx_battery_health(struct max1720x_device_info *info, 318 + unsigned int *health) 319 + { 320 + unsigned int status; 321 + int ret; 322 + 323 + ret = regmap_read(info->regmap, MAX172XX_STATUS, &status); 324 + if (ret < 0) 325 + return ret; 326 + 327 + if (status & MAX172XX_STATUS_VMN) 328 + *health = POWER_SUPPLY_HEALTH_DEAD; 329 + else if (status & MAX172XX_STATUS_VMX) 330 + *health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 331 + else if (status & MAX172XX_STATUS_TMN) 332 + *health = POWER_SUPPLY_HEALTH_COLD; 333 + else if (status & MAX172XX_STATUS_TMX) 334 + *health = POWER_SUPPLY_HEALTH_OVERHEAT; 335 + else if (status & MAX172XX_STATUS_IMX) 336 + *health = POWER_SUPPLY_HEALTH_OVERCURRENT; 337 + else 338 + *health = POWER_SUPPLY_HEALTH_GOOD; 339 + 340 + /* Clear events which are not self-clearing to detect next events */ 341 + if (status > 0 && status != MAX172XX_STATUS_IMX) { 342 + ret = regmap_set_bits(info->regmap, MAX172XX_STATUS, 343 + MAX172XX_STATUS_VMN | 344 + MAX172XX_STATUS_VMX | 345 + MAX172XX_STATUS_TMN | 346 + MAX172XX_STATUS_TMX); 347 + if (ret < 0) 348 + return ret; 349 + } 350 + 351 + return 0; 352 + } 353 + 323 354 static int max1720x_battery_get_property(struct power_supply *psy, 324 355 enum power_supply_property psp, 325 356 union power_supply_propval *val) ··· 366 323 int ret = 0; 367 324 368 325 switch (psp) { 326 + case POWER_SUPPLY_PROP_HEALTH: 327 + ret = max172xx_battery_health(info, &reg_val); 328 + val->intval = reg_val; 329 + break; 369 330 case POWER_SUPPLY_PROP_PRESENT: 370 331 /* 371 332 * POWER_SUPPLY_PROP_PRESENT will always readable via