Skip to content

Commit 64dce3e

Browse files
committed
power: supply: ln8411: Adds health reporting
Adds power supply health reporting. Change-Id: I396420f34b0f7ca5f7db94526a103222c274e328 Signed-off-by: Ricardo Rivera-Matos <[email protected]>
1 parent eb52430 commit 64dce3e

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

drivers/power/supply/ln8411_charger.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
109220
static 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

13701486
static 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,
14101528
static 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

14151534
static 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

15151637
static 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

15281651
static void ln8411_charger_external_power_changed(struct power_supply *psy)

drivers/power/supply/ln8411_charger.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,40 @@
295295
#define LN8411_STANDBY_STS BIT(1)
296296
#define LN8411_SHUTDOWN_STS BIT(0)
297297

298+
#define LN8411_SAFETY_STS 0x99
299+
#define LN8411_TEMP_FAULT_DETECTED BIT(7)
300+
#define LN8411_TEMP_MAX_STS BIT(6)
301+
#define LN8411_TSBAT_ALARM_STS BIT(5)
302+
#define LN8411_TSBAT_SHUTDOWN_STS BIT(3)
303+
#define LN8411_REV_IBUS_STS BIT(1)
304+
#define LN8411_REV_IBUS_LATCHED BIT(0)
305+
306+
#define LN8411_FAULT1_STS 0x9a
307+
#define LN8411_WATCHDOG_TIMER_STS BIT(7)
308+
#define LN8411_VOLT_FAULT_DETECTED BIT(6)
309+
#define LN8411_V_SHORT_STS BIT(5)
310+
#define LN8411_VBUS_OV_FIXED_STS BIT(4)
311+
#define LN8411_PMID2OUT_OV_STS BIT(3)
312+
#define LN8411_PMID2OUT_UV_STS BIT(2)
313+
#define LN8411_SYS_LPM_STS BIT(1)
314+
#define LN8411_INFET_OFF_DET_STS BIT(0)
315+
316+
#define LN8411_FAULT2_STS 0x9b
317+
#define LN8411_VOUT_OV_STS BIT(4)
318+
#define LN8411_VWPC_OV_STS BIT(3)
319+
#define LN8411_VWPC_UV_STS BIT(2)
320+
#define LN8411_VUSB_OV_STS BIT(1)
321+
#define LN8411_VUSB_UV_STS BIT(0)
322+
298323
#define LN8411_FAULT3_STS 0x9c
324+
#define LN8411_IBUS_OC_DETECTED BIT(7)
325+
#define LN8411_IBAT_OC_DETECTED BIT(6)
326+
#define LN8411_VBAT_OV_STS BIT(5)
327+
#define LN8411_IBUS_ALARM_STS BIT(4)
328+
#define LN8411_IBAT_ALARM_STS BIT(3)
329+
#define LN8411_VBAT_ALARM_STS BIT(2)
330+
#define LN8411_CFLY_SHORT_DETECTED BIT(1)
331+
#define LN8411_SC_OUT_SHORT_DETECTED BIT(0)
299332

300333
enum ln8411_roles {
301334
LN8411_USB = 0,

0 commit comments

Comments
 (0)