staticint wm831x_power_read_voltage(struct wm831x *wm831x, enum wm831x_auxadc src, union power_supply_propval *val)
{ int ret;
ret = wm831x_auxadc_read_uv(wm831x, src); if (ret >= 0)
val->intval = ret;
return ret;
}
/********************************************************************* * WALL Power
*********************************************************************/ staticint wm831x_wall_get_prop(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val)
{ struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev.parent); struct wm831x *wm831x = wm831x_power->wm831x; int ret = 0;
switch (psp) { case POWER_SUPPLY_PROP_ONLINE:
ret = wm831x_power_check_online(wm831x, WM831X_PWR_WALL, val); break; case POWER_SUPPLY_PROP_VOLTAGE_NOW:
ret = wm831x_power_read_voltage(wm831x, WM831X_AUX_WALL, val); break; default:
ret = -EINVAL; break;
}
/********************************************************************* * USB Power
*********************************************************************/ staticint wm831x_usb_get_prop(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val)
{ struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev.parent); struct wm831x *wm831x = wm831x_power->wm831x; int ret = 0;
switch (psp) { case POWER_SUPPLY_PROP_ONLINE:
ret = wm831x_power_check_online(wm831x, WM831X_PWR_USB, val); break; case POWER_SUPPLY_PROP_VOLTAGE_NOW:
ret = wm831x_power_read_voltage(wm831x, WM831X_AUX_USB, val); break; default:
ret = -EINVAL; break;
}
/* Find the highest supported limit */
best = 0; for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) { if (limit >= wm831x_usb_limits[i] &&
wm831x_usb_limits[best] < wm831x_usb_limits[i])
best = i;
}
dev_dbg(wm831x_power->wm831x->dev, "Limiting USB current to %umA", wm831x_usb_limits[best]);
staticvoid wm831x_battery_apply_config(struct wm831x *wm831x, conststruct chg_map *map, int count, int val, int *reg, constchar *name, constchar *units)
{ int i;
for (i = 0; i < count; i++) if (val == map[i].val) break; if (i == count) {
dev_err(wm831x->dev, "Invalid %s %d%s\n",
name, val, units);
} else {
*reg |= map[i].reg_val;
dev_dbg(wm831x->dev, "Set %s of %d%s\n", name, val, units);
}
}
ret = wm831x_reg_unlock(wm831x); if (ret != 0) {
dev_err(wm831x->dev, "Failed to unlock registers: %d\n", ret); return;
}
ret = wm831x_set_bits(wm831x, WM831X_CHARGER_CONTROL_1,
WM831X_CHG_ENA_MASK |
WM831X_CHG_FAST_MASK |
WM831X_CHG_ITERM_MASK,
reg1); if (ret != 0)
dev_err(wm831x->dev, "Failed to set charger control 1: %d\n",
ret);
ret = wm831x_set_bits(wm831x, WM831X_CHARGER_CONTROL_2,
WM831X_CHG_OFF_MSK |
WM831X_CHG_TIME_MASK |
WM831X_CHG_FAST_ILIM_MASK |
WM831X_CHG_TRKL_ILIM_MASK |
WM831X_CHG_VSEL_MASK,
reg2); if (ret != 0)
dev_err(wm831x->dev, "Failed to set charger control 2: %d\n",
ret);
wm831x_reg_lock(wm831x);
}
staticint wm831x_bat_check_status(struct wm831x *wm831x, int *status)
{ int ret;
ret = wm831x_reg_read(wm831x, WM831X_SYSTEM_STATUS); if (ret < 0) return ret;
switch (ret & WM831X_CHG_STATE_MASK) { case WM831X_CHG_STATE_TRICKLE_OT: case WM831X_CHG_STATE_FAST_OT:
*health = POWER_SUPPLY_HEALTH_OVERHEAT; break; case WM831X_CHG_STATE_DEFECTIVE:
*health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; break; default:
*health = POWER_SUPPLY_HEALTH_GOOD; break;
}
return 0;
}
staticint wm831x_bat_get_prop(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val)
{ struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev.parent); struct wm831x *wm831x = wm831x_power->wm831x; int ret = 0;
switch (psp) { case POWER_SUPPLY_PROP_STATUS:
ret = wm831x_bat_check_status(wm831x, &val->intval); break; case POWER_SUPPLY_PROP_ONLINE:
ret = wm831x_power_check_online(wm831x, WM831X_PWR_SRC_BATT,
val); break; case POWER_SUPPLY_PROP_VOLTAGE_NOW:
ret = wm831x_power_read_voltage(wm831x, WM831X_AUX_BATT, val); break; case POWER_SUPPLY_PROP_HEALTH:
ret = wm831x_bat_check_health(wm831x, &val->intval); break; case POWER_SUPPLY_PROP_CHARGE_TYPE:
ret = wm831x_bat_check_type(wm831x, &val->intval); break; default:
ret = -EINVAL; break;
}
dev_dbg(wm831x->dev, "Battery status changed: %d\n", irq);
/* The battery charger is autonomous so we don't need to do
* anything except kick user space */ if (wm831x_power->have_battery)
power_supply_changed(wm831x_power->battery);
/* Not much we can actually *do* but tell people for
* posterity, we're probably about to run out of power. */
dev_crit(wm831x->dev, "SYSVDD under voltage\n");
/* Just notify for everything - little harm in overnotifying. */ if (wm831x_power->have_battery)
power_supply_changed(wm831x_power->battery);
power_supply_changed(wm831x_power->usb);
power_supply_changed(wm831x_power->wall);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.