if (limit <= SC2731_CURRENT_LIMIT_100)
val = 0; elseif (limit <= SC2731_CURRENT_LIMIT_500)
val = 3; elseif (limit <= SC2731_CURRENT_LIMIT_900)
val = 2; else
val = 1;
return regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG5,
SC2731_CUR_LIMIT_MASK,
val << SC2731_CUR_LIMIT_SHIFT);
}
if (cur > SC2731_CURRENT_LIMIT_2000)
cur = SC2731_CURRENT_LIMIT_2000; elseif (cur < SC2731_CURRENT_PRECHG)
cur = SC2731_CURRENT_PRECHG;
/* Calculate the step value, each step is 50 mA */
val = (cur - SC2731_CURRENT_PRECHG) / SC2731_CURRENT_STEP;
/* Set pre-charge current as 450 mA */
ret = regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG0,
SC2731_PRECHG_RNG_MASK,
0x3 << SC2731_PRECHG_RNG_SHIFT); if (ret) return ret;
if (!info->charging) {
mutex_unlock(&info->lock); return -ENODEV;
}
switch (psp) { case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
ret = sc2731_charger_set_current(info, val->intval / 1000); if (ret < 0)
dev_err(info->dev, "set charge current failed\n"); break;
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
ret = sc2731_charger_set_current_limit(info,
val->intval / 1000); if (ret < 0)
dev_err(info->dev, "set input current limit failed\n"); break;
default:
ret = -EINVAL;
}
mutex_unlock(&info->lock); return ret;
}
staticint sc2731_charger_usb_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val)
{ struct sc2731_charger_info *info = power_supply_get_drvdata(psy); int ret = 0;
u32 cur;
mutex_lock(&info->lock);
switch (psp) { case POWER_SUPPLY_PROP_STATUS: if (info->charging)
val->intval = sc2731_charger_get_status(info); else
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: if (!info->charging) {
val->intval = 0;
} else {
ret = sc2731_charger_get_current(info, &cur); if (ret) goto out;
val->intval = cur * 1000;
} break;
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: if (!info->charging) {
val->intval = 0;
} else {
ret = sc2731_charger_get_current_limit(info, &cur); if (ret) goto out;
val->intval = cur * 1000;
} break;
default:
ret = -EINVAL;
}
out:
mutex_unlock(&info->lock); return ret;
}
staticint sc2731_charger_property_is_writeable(struct power_supply *psy, enum power_supply_property psp)
{ int ret;
switch (psp) { case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
ret = 1; break;
if (info->limit > 0 && !info->charging) { /* set current limitation and start to charge */
ret = sc2731_charger_set_current_limit(info, info->limit); if (ret) goto out;
ret = sc2731_charger_set_current(info, info->limit); if (ret) goto out;
ret = sc2731_charger_start_charge(info); if (ret) goto out;
/* Enable charger module */
ret = regmap_update_bits(info->regmap, SC2731_MODULE_EN1,
SC2731_CHARGE_EN, SC2731_CHARGE_EN); if (ret) return ret;
ret = power_supply_get_battery_info(info->psy_usb, &bat_info); if (ret) {
dev_warn(info->dev, "no battery information is supplied\n");
/* * If no battery information is supplied, we should set * default charge termination current to 120 mA, and default * charge termination voltage to 4.35V.
*/
cur_val = 0x2;
vol_val = 0x1;
} else {
term_currrent = bat_info->charge_term_current_ua / 1000;
/* Set charge termination current */
ret = regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG2,
SC2731_TERMINATION_CUR_MASK, cur_val); if (ret) goto error;
/* Set charge termination voltage */
ret = regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG0,
SC2731_TERMINATION_VOL_MASK |
SC2731_TERMINATION_VOL_CAL_MASK,
(vol_val << SC2731_TERMINATION_VOL_SHIFT) |
(0x6 << SC2731_TERMINATION_VOL_CAL_SHIFT)); if (ret) goto error;
/* * If the USB charger status has been USB_CHARGER_PRESENT before * registering the notifier, we should start to charge with getting * the charge current.
*/ if (info->usb_phy->chg_state != USB_CHARGER_PRESENT) return;
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.