@@ -106,6 +106,117 @@ static int ln8411_get_adc(struct ln8411_device *ln8411,
106106 return ret ;
107107}
108108
109+ static int ln8411_get_wpc_health (struct ln8411_device * ln8411 , union power_supply_propval * val )
110+ {
111+ unsigned int reg_code ;
112+ int ret ;
113+
114+ val -> intval = POWER_SUPPLY_HEALTH_UNKNOWN ;
115+
116+ ret = regmap_read (ln8411 -> regmap , LN8411_FAULT2_STS , & reg_code );
117+ if (ret )
118+ return ret ;
119+
120+ if (reg_code & LN8411_VWPC_OV_STS ) {
121+ val -> intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE ;
122+ dev_dbg (ln8411 -> dev , "VWPC overvoltage condition detected!\n" );
123+ return ret ;
124+ }
125+
126+ val -> intval = POWER_SUPPLY_HEALTH_GOOD ;
127+
128+ return ret ;
129+ }
130+
131+ static int ln8411_get_usb_health (struct ln8411_device * ln8411 , union power_supply_propval * val )
132+ {
133+ unsigned int reg_code ;
134+ int ret ;
135+
136+ val -> intval = POWER_SUPPLY_HEALTH_UNKNOWN ;
137+
138+ ret = regmap_read (ln8411 -> regmap , LN8411_FAULT2_STS , & reg_code );
139+ if (ret )
140+ return ret ;
141+
142+ if (reg_code & LN8411_VUSB_OV_STS ) {
143+ val -> intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE ;
144+ dev_dbg (ln8411 -> dev , "VUSB overvoltage condition detected!\n" );
145+ return ret ;
146+ }
147+
148+ val -> intval = POWER_SUPPLY_HEALTH_GOOD ;
149+
150+ return ret ;
151+ }
152+
153+ static int ln8411_get_batt_health (struct ln8411_device * ln8411 , union power_supply_propval * val )
154+ {
155+ unsigned int reg_code ;
156+ int ret ;
157+
158+ val -> intval = POWER_SUPPLY_HEALTH_UNKNOWN ;
159+
160+ ret = regmap_read (ln8411 -> regmap , LN8411_FAULT3_STS , & reg_code );
161+ if (ret )
162+ return ret ;
163+
164+ if (reg_code & LN8411_IBAT_OC_DETECTED ) {
165+ val -> intval = POWER_SUPPLY_HEALTH_OVERCURRENT ;
166+ dev_dbg (ln8411 -> dev , "IBAT overcurrent detected!\n" );
167+ return ret ;
168+ }
169+
170+ if (reg_code & LN8411_VBAT_OV_STS ) {
171+ val -> intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE ;
172+ dev_dbg (ln8411 -> dev , "VBAT overvoltage detected!\n" );
173+ return ret ;
174+ }
175+
176+ ret = regmap_read (ln8411 -> regmap , LN8411_SAFETY_STS , & reg_code );
177+ if (ret )
178+ return ret ;
179+
180+ if (reg_code & (LN8411_TSBAT_ALARM_STS | LN8411_TSBAT_SHUTDOWN_STS )) {
181+ val -> intval = POWER_SUPPLY_HEALTH_OVERHEAT ;
182+ dev_dbg (ln8411 -> dev , "TSBAT condition detected!\n" );
183+ return ret ;
184+ }
185+
186+ val -> intval = POWER_SUPPLY_HEALTH_GOOD ;
187+
188+ return ret ;
189+ }
190+
191+ static int ln8411_get_charger_health (struct ln8411_device * ln8411 , union power_supply_propval * val )
192+ {
193+ u8 buf [3 ];
194+ int ret ;
195+
196+ val -> intval = POWER_SUPPLY_HEALTH_UNKNOWN ;
197+
198+ ret = regmap_bulk_read (ln8411 -> regmap , LN8411_FAULT1_STS , buf , 3 );
199+ if (ret )
200+ return ret ;
201+
202+ if (buf [0 ] & LN8411_WATCHDOG_TIMER_STS ) {
203+ val -> intval = POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE ;
204+ } else if (buf [0 ] & LN8411_PMID2OUT_OV_STS ) {
205+ val -> intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE ;
206+ dev_dbg (ln8411 -> dev , "PMID2OUT overvoltage condition detected!\n" );
207+ } else if (buf [2 ] & LN8411_IBUS_OC_DETECTED ) {
208+ val -> intval = POWER_SUPPLY_HEALTH_OVERCURRENT ;
209+ dev_dbg (ln8411 -> dev , "IBUS overcurrent condition detected!\n" );
210+ } else if (buf [0 ] & LN8411_VOLT_FAULT_DETECTED ) {
211+ val -> intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE ;
212+ dev_dbg (ln8411 -> dev , "Voltage fault condition detected! FAULT1_STS:0x%x, FAULT2_STS:0x%x, FAULT3_STS:0x%x\n" , buf [0 ], buf [1 ], buf [2 ]);
213+ } else {
214+ val -> intval = POWER_SUPPLY_HEALTH_GOOD ;
215+ }
216+
217+ return ret ;
218+ }
219+
109220static int ln8411_set_present (struct ln8411_device * ln8411 , const union power_supply_propval * val )
110221{
111222 int ret ;
@@ -1252,6 +1363,8 @@ static int ln8411_get_wpc_property(struct power_supply *psy,
12521363 break ;
12531364 case POWER_SUPPLY_PROP_VOLTAGE_NOW :
12541365 return ln8411_get_adc (ln8411 , LN8411_ADC_CHAN_VWPC , & val -> intval );
1366+ case POWER_SUPPLY_PROP_HEALTH :
1367+ return ln8411_get_wpc_health (ln8411 , val );
12551368 default :
12561369 return - EINVAL ;
12571370 }
@@ -1332,6 +1445,8 @@ static int ln8411_get_usb_property(struct power_supply *psy,
13321445 break ;
13331446 case POWER_SUPPLY_PROP_VOLTAGE_NOW :
13341447 return ln8411_get_adc (ln8411 , LN8411_ADC_CHAN_VUSB , & val -> intval );
1448+ case POWER_SUPPLY_PROP_HEALTH :
1449+ return ln8411_get_usb_health (ln8411 , val );
13351450 default :
13361451 return - EINVAL ;
13371452 }
@@ -1365,6 +1480,7 @@ static enum power_supply_property ln8411_input_props[] = {
13651480 POWER_SUPPLY_PROP_CURRENT_MAX ,
13661481 POWER_SUPPLY_PROP_ONLINE ,
13671482 POWER_SUPPLY_PROP_VOLTAGE_NOW ,
1483+ POWER_SUPPLY_PROP_HEALTH ,
13681484};
13691485
13701486static struct power_supply_desc ln8411_wpc_desc = {
@@ -1400,6 +1516,8 @@ static int ln8411_get_battery_property(struct power_supply *psy,
14001516 return ln8411_get_adc (ln8411 , LN8411_ADC_CHAN_VBAT , & val -> intval );
14011517 case POWER_SUPPLY_PROP_CURRENT_NOW :
14021518 return ln8411_get_adc (ln8411 , LN8411_ADC_CHAN_IBAT , & val -> intval );
1519+ case POWER_SUPPLY_PROP_HEALTH :
1520+ return ln8411_get_batt_health (ln8411 , val );
14031521 default :
14041522 return - EINVAL ;
14051523 }
@@ -1410,6 +1528,7 @@ static int ln8411_get_battery_property(struct power_supply *psy,
14101528static enum power_supply_property ln8411_battery_props [] = {
14111529 POWER_SUPPLY_PROP_VOLTAGE_NOW ,
14121530 POWER_SUPPLY_PROP_CURRENT_NOW ,
1531+ POWER_SUPPLY_PROP_HEALTH ,
14131532};
14141533
14151534static struct power_supply_desc ln8411_battery_desc = {
@@ -1496,6 +1615,8 @@ static int ln8411_get_charger_property(struct power_supply *psy,
14961615 case POWER_SUPPLY_PROP_PRESENT :
14971616 val -> intval = true;
14981617 break ;
1618+ case POWER_SUPPLY_PROP_HEALTH :
1619+ return ln8411_get_charger_health (ln8411 , val );
14991620 default :
15001621 return - EINVAL ;
15011622 }
@@ -1510,6 +1631,7 @@ static enum power_supply_property ln8411_2nd_charger_props[] = {
15101631 POWER_SUPPLY_PROP_VOLTAGE_NOW ,
15111632 POWER_SUPPLY_PROP_CHARGE_TYPE ,
15121633 POWER_SUPPLY_PROP_STATUS ,
1634+ POWER_SUPPLY_PROP_HEALTH ,
15131635};
15141636
15151637static enum power_supply_property ln8411_charger_props [] = {
@@ -1523,6 +1645,7 @@ static enum power_supply_property ln8411_charger_props[] = {
15231645 POWER_SUPPLY_PROP_CHARGE_TYPE ,
15241646 POWER_SUPPLY_PROP_STATUS ,
15251647 POWER_SUPPLY_PROP_PRESENT ,
1648+ POWER_SUPPLY_PROP_HEALTH ,
15261649};
15271650
15281651static void ln8411_charger_external_power_changed (struct power_supply * psy )
0 commit comments