staticint max77693_get_charger_state(struct regmap *regmap, int *val)
{ int ret; unsignedint data;
ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data); if (ret < 0) return ret;
data &= CHG_DETAILS_01_CHG_MASK;
data >>= CHG_DETAILS_01_CHG_SHIFT;
switch (data) { case MAX77693_CHARGING_PREQUALIFICATION: case MAX77693_CHARGING_FAST_CONST_CURRENT: case MAX77693_CHARGING_FAST_CONST_VOLTAGE: case MAX77693_CHARGING_TOP_OFF: /* In high temp the charging current is reduced, but still charging */ case MAX77693_CHARGING_HIGH_TEMP:
*val = POWER_SUPPLY_STATUS_CHARGING; break; case MAX77693_CHARGING_DONE:
*val = POWER_SUPPLY_STATUS_FULL; break; case MAX77693_CHARGING_TIMER_EXPIRED: case MAX77693_CHARGING_THERMISTOR_SUSPEND:
*val = POWER_SUPPLY_STATUS_NOT_CHARGING; break; case MAX77693_CHARGING_OFF: case MAX77693_CHARGING_OVER_TEMP: case MAX77693_CHARGING_WATCHDOG_EXPIRED:
*val = POWER_SUPPLY_STATUS_DISCHARGING; break; case MAX77693_CHARGING_RESERVED: default:
*val = POWER_SUPPLY_STATUS_UNKNOWN;
}
return 0;
}
staticint max77693_get_charge_type(struct regmap *regmap, int *val)
{ int ret; unsignedint data;
ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data); if (ret < 0) return ret;
data &= CHG_DETAILS_01_CHG_MASK;
data >>= CHG_DETAILS_01_CHG_SHIFT;
switch (data) { case MAX77693_CHARGING_PREQUALIFICATION: /* * Top-off: trickle or fast? In top-off the current varies between * 100 and 250 mA. It is higher than prequalification current.
*/ case MAX77693_CHARGING_TOP_OFF:
*val = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; break; case MAX77693_CHARGING_FAST_CONST_CURRENT: case MAX77693_CHARGING_FAST_CONST_VOLTAGE: /* In high temp the charging current is reduced, but still charging */ case MAX77693_CHARGING_HIGH_TEMP:
*val = POWER_SUPPLY_CHARGE_TYPE_FAST; break; case MAX77693_CHARGING_DONE: case MAX77693_CHARGING_TIMER_EXPIRED: case MAX77693_CHARGING_THERMISTOR_SUSPEND: case MAX77693_CHARGING_OFF: case MAX77693_CHARGING_OVER_TEMP: case MAX77693_CHARGING_WATCHDOG_EXPIRED:
*val = POWER_SUPPLY_CHARGE_TYPE_NONE; break; case MAX77693_CHARGING_RESERVED: default:
*val = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
}
ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data); if (ret < 0) return ret;
data &= CHG_DETAILS_01_BAT_MASK;
data >>= CHG_DETAILS_01_BAT_SHIFT;
switch (data) { case MAX77693_BATTERY_NOBAT:
*val = POWER_SUPPLY_HEALTH_DEAD; break; case MAX77693_BATTERY_PREQUALIFICATION: case MAX77693_BATTERY_GOOD: case MAX77693_BATTERY_LOWVOLTAGE:
*val = POWER_SUPPLY_HEALTH_GOOD; break; case MAX77693_BATTERY_TIMER_EXPIRED: /* * Took longer to charge than expected, charging suspended. * Damaged battery?
*/
*val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; break; case MAX77693_BATTERY_OVERVOLTAGE:
*val = POWER_SUPPLY_HEALTH_OVERVOLTAGE; break; case MAX77693_BATTERY_OVERCURRENT:
*val = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; break; case MAX77693_BATTERY_RESERVED: default:
*val = POWER_SUPPLY_HEALTH_UNKNOWN; break;
}
return 0;
}
staticint max77693_get_present(struct regmap *regmap, int *val)
{ unsignedint data; int ret;
/* * Read CHG_INT_OK register. High DETBAT bit here should be * equal to value 0x0 in CHG_DETAILS_01/BAT field.
*/
ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_INT_OK, &data); if (ret < 0) return ret;
*val = (data & CHG_INT_OK_DETBAT_MASK) ? 0 : 1;
return 0;
}
staticint max77693_get_online(struct regmap *regmap, int *val)
{ unsignedint data; int ret;
ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_INT_OK, &data); if (ret < 0) return ret;
*val = (data & CHG_INT_OK_CHGIN_MASK) ? 1 : 0;
return 0;
}
/* * There are *two* current limit registers: * - CHGIN limit, which limits the input current from the external charger; * - Fast charge current limit, which limits the current going to the battery.
*/
staticint max77693_get_input_current_limit(struct regmap *regmap, int *val)
{ unsignedint data; int ret;
ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_CNFG_09, &data); if (ret < 0) return ret;
data &= CHG_CNFG_09_CHGIN_ILIM_MASK;
data >>= CHG_CNFG_09_CHGIN_ILIM_SHIFT;
if (data <= 0x03) /* The first four values (0x00..0x03) are 60mA */
*val = 60000; else
*val = data * 20000; /* 20mA steps */
return 0;
}
staticint max77693_get_fast_charge_current(struct regmap *regmap, int *val)
{ unsignedint data; int ret;
ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_CNFG_02, &data); if (ret < 0) return ret;
data &= CHG_CNFG_02_CC_MASK;
data >>= CHG_CNFG_02_CC_SHIFT;
staticint max77693_charger_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val)
{ struct max77693_charger *chg = power_supply_get_drvdata(psy); struct regmap *regmap = chg->max77693->regmap; int ret = 0;
switch (psp) { case POWER_SUPPLY_PROP_STATUS:
ret = max77693_get_charger_state(regmap, &val->intval); break; case POWER_SUPPLY_PROP_CHARGE_TYPE:
ret = max77693_get_charge_type(regmap, &val->intval); break; case POWER_SUPPLY_PROP_HEALTH:
ret = max77693_get_battery_health(regmap, &val->intval); break; case POWER_SUPPLY_PROP_PRESENT:
ret = max77693_get_present(regmap, &val->intval); break; case POWER_SUPPLY_PROP_ONLINE:
ret = max77693_get_online(regmap, &val->intval); break; case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
ret = max77693_get_input_current_limit(regmap, &val->intval); break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
ret = max77693_get_fast_charge_current(regmap, &val->intval); break; case POWER_SUPPLY_PROP_MODEL_NAME:
val->strval = max77693_charger_model; break; case POWER_SUPPLY_PROP_MANUFACTURER:
val->strval = max77693_charger_manufacturer; break; default: return -EINVAL;
}
switch (cels) { case 70: case 85: case 100: case 115:
data = (cels - 70) / 15; break; default:
dev_err(chg->dev, "Wrong value for thermal regulation loop temperature\n"); return -EINVAL;
}
switch (uvolt) { case 4300000:
data = 0x0; break; case 4700000: case 4800000: case 4900000:
data = ((uvolt - 4700000) / 100000) + 1; break; default:
dev_err(chg->dev, "Wrong value for charge input voltage regulation threshold\n"); return -EINVAL;
}
data <<= CHG_CNFG_12_VCHGINREG_SHIFT;
dev_dbg(chg->dev, "Charge input voltage regulation threshold: %u (0x%x)\n",
uvolt, data);
ret = max77693_dt_init(&pdev->dev, chg); if (ret) return ret;
ret = max77693_reg_init(chg); if (ret) return ret;
psy_cfg.drv_data = chg;
ret = device_create_file(&pdev->dev, &dev_attr_fast_charge_timer); if (ret) {
dev_err(&pdev->dev, "failed: create fast charge timer sysfs entry\n"); goto err;
}
ret = device_create_file(&pdev->dev,
&dev_attr_top_off_threshold_current); if (ret) {
dev_err(&pdev->dev, "failed: create top off current sysfs entry\n"); goto err;
}
ret = device_create_file(&pdev->dev, &dev_attr_top_off_timer); if (ret) {
dev_err(&pdev->dev, "failed: create top off timer sysfs entry\n"); goto err;
}
chg->charger = devm_power_supply_register(&pdev->dev,
&max77693_charger_desc,
&psy_cfg); if (IS_ERR(chg->charger)) {
dev_err(&pdev->dev, "failed: power supply register\n");
ret = PTR_ERR(chg->charger); goto err;
}
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.