/* * Helper function for mapping values of STATUS2/CHGTYP register on max14577 * and max77836 chipsets to enum maxim_muic_charger_type.
*/ staticenum max14577_muic_charger_type maxim_get_charger_type( enum maxim_device_type dev_type, u8 val) { switch (val) { case MAX14577_CHARGER_TYPE_NONE: case MAX14577_CHARGER_TYPE_USB: case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT: case MAX14577_CHARGER_TYPE_DEDICATED_CHG: case MAX14577_CHARGER_TYPE_SPECIAL_500MA: case MAX14577_CHARGER_TYPE_SPECIAL_1A: return val; case MAX14577_CHARGER_TYPE_DEAD_BATTERY: case MAX14577_CHARGER_TYPE_RESERVED: if (dev_type == MAXIM_DEVICE_TYPE_MAX77836)
val |= 0x8; return val; default:
WARN_ONCE(1, "max14577: Unsupported chgtyp register value 0x%02x", val); return val;
}
}
staticint max14577_get_charger_state(struct max14577_charger *chg, int *val)
{ struct regmap *rmap = chg->max14577->regmap; int ret;
u8 reg_data;
/* * Charging occurs only if: * - CHGCTRL2/MBCHOSTEN == 1 * - STATUS2/CGMBC == 1 * * TODO: * - handle FULL after Top-off timer (EOC register may be off * and the charger won't be charging although MBCHOSTEN is on) * - handle properly dead-battery charging (respect timer) * - handle timers (fast-charge and prequal) /MBCCHGERR/
*/
ret = max14577_read_reg(rmap, MAX14577_CHG_REG_CHG_CTRL2, ®_data); if (ret < 0) goto out;
/* * TODO: CHARGE_TYPE_TRICKLE (VCHGR_RC or EOC)? * As spec says: * [after reaching EOC interrupt] * "When the battery is fully charged, the 30-minute (typ) * top-off timer starts. The device continues to trickle * charge the battery until the top-off timer runs out."
*/
ret = max14577_get_charger_state(chg, &charging); if (ret < 0) return ret;
staticint max14577_get_online(struct max14577_charger *chg, int *val)
{ struct regmap *rmap = chg->max14577->regmap;
u8 reg_data; int ret; enum max14577_muic_charger_type chg_type;
ret = max14577_read_reg(rmap, MAX14577_MUIC_REG_STATUS2, ®_data); if (ret < 0) return ret;
reg_data = ((reg_data & STATUS2_CHGTYP_MASK) >> STATUS2_CHGTYP_SHIFT);
chg_type = maxim_get_charger_type(chg->max14577->dev_type, reg_data); switch (chg_type) { case MAX14577_CHARGER_TYPE_USB: case MAX14577_CHARGER_TYPE_DEDICATED_CHG: case MAX14577_CHARGER_TYPE_SPECIAL_500MA: case MAX14577_CHARGER_TYPE_SPECIAL_1A: case MAX14577_CHARGER_TYPE_DEAD_BATTERY: case MAX77836_CHARGER_TYPE_SPECIAL_BIAS:
*val = 1; break; case MAX14577_CHARGER_TYPE_NONE: case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT: case MAX14577_CHARGER_TYPE_RESERVED: case MAX77836_CHARGER_TYPE_RESERVED: default:
*val = 0;
}
/* Not dead, not overvoltage */
*val = POWER_SUPPLY_HEALTH_GOOD;
out: return ret;
}
/* * Always returns 1. * The max14577 chip doesn't report any status of battery presence. * Lets assume that it will always be used with some battery.
*/ staticint max14577_get_present(struct max14577_charger *chg, int *val)
{
*val = 1;
val -= MAXIM_CHARGER_CONSTANT_VOLTAGE_MIN;
val /= MAXIM_CHARGER_CONSTANT_VOLTAGE_STEP; if (uvolt <= 4180000)
reg_data = 0x1 + val; else
reg_data = val; /* Fix for gap between 4.18V and 4.22V */
} else return -EINVAL;
ret = maxim_charger_calc_reg_current(limits, uamp, uamp, ®_data); if (ret) {
dev_err(chg->dev, "Wrong value for fast charge: %u\n", uamp); return ret;
}
/* * Sets charger registers to proper and safe default values. * Some of these values are equal to defaults in MAX14577E * data sheet but there are minor differences.
*/ staticint max14577_charger_reg_init(struct max14577_charger *chg)
{ struct regmap *rmap = chg->max14577->regmap;
u8 reg_data; int ret;
/* * Charger-Type Manual Detection, default off (set CHGTYPMAN to 0) * Charger-Detection Enable, default on (set CHGDETEN to 1) * Combined mask of CHGDETEN and CHGTYPMAN will zero the CHGTYPMAN bit
*/
reg_data = 0x1 << CDETCTRL1_CHGDETEN_SHIFT;
max14577_update_reg(rmap, MAX14577_REG_CDETCTRL1,
CDETCTRL1_CHGDETEN_MASK | CDETCTRL1_CHGTYPMAN_MASK,
reg_data);
staticint max14577_charger_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val)
{ struct max14577_charger *chg = power_supply_get_drvdata(psy); int ret = 0;
switch (psp) { case POWER_SUPPLY_PROP_STATUS:
ret = max14577_get_charger_state(chg, &val->intval); break; case POWER_SUPPLY_PROP_CHARGE_TYPE:
ret = max14577_get_charge_type(chg, &val->intval); break; case POWER_SUPPLY_PROP_HEALTH:
ret = max14577_get_battery_health(chg, &val->intval); break; case POWER_SUPPLY_PROP_PRESENT:
ret = max14577_get_present(chg, &val->intval); break; case POWER_SUPPLY_PROP_ONLINE:
ret = max14577_get_online(chg, &val->intval); break; case POWER_SUPPLY_PROP_MODEL_NAME:
BUILD_BUG_ON(ARRAY_SIZE(model_names) != MAXIM_DEVICE_TYPE_NUM);
val->strval = model_names[chg->max14577->dev_type]; break; case POWER_SUPPLY_PROP_MANUFACTURER:
val->strval = manufacturer; break; default: return -EINVAL;
}
if (!np) {
dev_err(&pdev->dev, "No charger OF node\n"); return ERR_PTR(-EINVAL);
}
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return ERR_PTR(-ENOMEM);
ret = of_property_read_u32(np, "maxim,constant-uvolt",
&pdata->constant_uvolt); if (ret) {
dev_err(&pdev->dev, "Cannot parse maxim,constant-uvolt field from DT\n"); return ERR_PTR(ret);
}
ret = of_property_read_u32(np, "maxim,fast-charge-uamp",
&pdata->fast_charge_uamp); if (ret) {
dev_err(&pdev->dev, "Cannot parse maxim,fast-charge-uamp field from DT\n"); return ERR_PTR(ret);
}
ret = of_property_read_u32(np, "maxim,eoc-uamp", &pdata->eoc_uamp); if (ret) {
dev_err(&pdev->dev, "Cannot parse maxim,eoc-uamp field from DT\n"); return ERR_PTR(ret);
}
ret = of_property_read_u32(np, "maxim,ovp-uvolt", &pdata->ovp_uvolt); if (ret) {
dev_err(&pdev->dev, "Cannot parse maxim,ovp-uvolt field from DT\n"); return ERR_PTR(ret);
}
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.