return 0;
}
+/*
+ * Update battery status when cpcap-charger calls power_supply_changed().
+ * This allows us to detect battery full condition before the charger
+ * disconnects.
+ */
+static void cpcap_battery_external_power_changed(struct power_supply *psy)
+{
+ union power_supply_propval prop;
+
+ power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS, &prop);
+}
+
static enum power_supply_property cpcap_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_PRESENT,
psy_desc->get_property = cpcap_battery_get_property;
psy_desc->set_property = cpcap_battery_set_property;
psy_desc->property_is_writeable = cpcap_battery_property_is_writeable;
+ psy_desc->external_power_changed = cpcap_battery_external_power_changed;
psy_cfg.of_node = pdev->dev.of_node;
psy_cfg.drv_data = ddata;
{
int error;
+ /* Update battery state before disconnecting the charger */
+ switch (state) {
+ case POWER_SUPPLY_STATUS_DISCHARGING:
+ case POWER_SUPPLY_STATUS_FULL:
+ power_supply_changed(ddata->usb);
+ break;
+ default:
+ break;
+ }
+
error = cpcap_charger_disable(ddata);
if (error) {
cpcap_charger_update_state(ddata, POWER_SUPPLY_STATUS_UNKNOWN);
{
struct cpcap_charger_ddata *ddata;
struct cpcap_charger_ints_state s;
- int error;
+ int error, new_state;
ddata = container_of(work, struct cpcap_charger_ddata,
detect_work.work);
case POWER_SUPPLY_STATUS_CHARGING:
if (s.chrgcurr2)
break;
+ new_state = POWER_SUPPLY_STATUS_FULL;
+
if (s.chrgcurr1 && s.vbusvld) {
- cpcap_charger_disconnect(ddata,
- POWER_SUPPLY_STATUS_FULL,
- HZ * 5);
+ cpcap_charger_disconnect(ddata, new_state, HZ * 5);
return;
}
break;
case POWER_SUPPLY_STATUS_FULL:
if (!s.chrgcurr2)
break;
- cpcap_charger_disconnect(ddata,
- POWER_SUPPLY_STATUS_NOT_CHARGING,
- HZ * 5);
+ if (s.vbusvld)
+ new_state = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ else
+ new_state = POWER_SUPPLY_STATUS_DISCHARGING;
+
+ cpcap_charger_disconnect(ddata, new_state, HZ * 5);
+
return;
default:
break;
return error;
}
+static char *cpcap_charger_supplied_to[] = {
+ "battery",
+};
+
static const struct power_supply_desc cpcap_charger_usb_desc = {
.name = "usb",
.type = POWER_SUPPLY_TYPE_USB,
psy_cfg.of_node = pdev->dev.of_node;
psy_cfg.drv_data = ddata;
+ psy_cfg.supplied_to = cpcap_charger_supplied_to;
+ psy_cfg.num_supplicants = ARRAY_SIZE(cpcap_charger_supplied_to),
ddata->usb = devm_power_supply_register(ddata->dev,
&cpcap_charger_usb_desc,