2929/* ModelGauge m5 */
3030#define MAX172XX_STATUS 0x00 /* Status */
3131#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 */
3237#define MAX172XX_REPCAP 0x05 /* Average capacity */
3338#define MAX172XX_REPSOC 0x06 /* Percentage of charge */
3439#define MAX172XX_TEMP 0x08 /* Temperature */
@@ -250,6 +255,7 @@ static const struct nvmem_cell_info max1720x_nvmem_cells[] = {
250255};
251256
252257static const enum power_supply_property max1720x_battery_props [] = {
258+ POWER_SUPPLY_PROP_HEALTH ,
253259 POWER_SUPPLY_PROP_PRESENT ,
254260 POWER_SUPPLY_PROP_CAPACITY ,
255261 POWER_SUPPLY_PROP_VOLTAGE_NOW ,
@@ -314,6 +320,43 @@ static int max172xx_current_to_voltage(unsigned int reg)
314320 return val * 156252 ;
315321}
316322
323+ static int max172xx_battery_health (struct max1720x_device_info * info ,
324+ unsigned int * health )
325+ {
326+ unsigned int status ;
327+ int ret ;
328+
329+ ret = regmap_read (info -> regmap , MAX172XX_STATUS , & status );
330+ if (ret < 0 )
331+ return ret ;
332+
333+ if (status & MAX172XX_STATUS_VMN )
334+ * health = POWER_SUPPLY_HEALTH_DEAD ;
335+ else if (status & MAX172XX_STATUS_VMX )
336+ * health = POWER_SUPPLY_HEALTH_OVERVOLTAGE ;
337+ else if (status & MAX172XX_STATUS_TMN )
338+ * health = POWER_SUPPLY_HEALTH_COLD ;
339+ else if (status & MAX172XX_STATUS_TMX )
340+ * health = POWER_SUPPLY_HEALTH_OVERHEAT ;
341+ else if (status & MAX172XX_STATUS_IMX )
342+ * health = POWER_SUPPLY_HEALTH_OVERCURRENT ;
343+ else
344+ * health = POWER_SUPPLY_HEALTH_GOOD ;
345+
346+ /* Clear events which are not self-clearing to detect next events */
347+ if (status > 0 && status != MAX172XX_STATUS_IMX ) {
348+ ret = regmap_set_bits (info -> regmap , MAX172XX_STATUS ,
349+ MAX172XX_STATUS_VMN |
350+ MAX172XX_STATUS_VMX |
351+ MAX172XX_STATUS_TMN |
352+ MAX172XX_STATUS_TMX );
353+ if (ret < 0 )
354+ return ret ;
355+ }
356+
357+ return 0 ;
358+ }
359+
317360static int max1720x_battery_get_property (struct power_supply * psy ,
318361 enum power_supply_property psp ,
319362 union power_supply_propval * val )
@@ -323,6 +366,10 @@ static int max1720x_battery_get_property(struct power_supply *psy,
323366 int ret = 0 ;
324367
325368 switch (psp ) {
369+ case POWER_SUPPLY_PROP_HEALTH :
370+ ret = max172xx_battery_health (info , & reg_val );
371+ val -> intval = reg_val ;
372+ break ;
326373 case POWER_SUPPLY_PROP_PRESENT :
327374 /*
328375 * POWER_SUPPLY_PROP_PRESENT will always readable via
0 commit comments