in supply/max17042_battery.c [229:436]
static int max17042_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct max17042_chip *chip = power_supply_get_drvdata(psy);
struct regmap *map = chip->regmap;
int ret;
u32 data;
u64 data64;
if (!chip->init_complete)
return -EAGAIN;
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
ret = max17042_get_status(chip, &val->intval);
if (ret < 0)
return ret;
break;
case POWER_SUPPLY_PROP_PRESENT:
ret = regmap_read(map, MAX17042_STATUS, &data);
if (ret < 0)
return ret;
if (data & MAX17042_STATUS_BattAbsent)
val->intval = 0;
else
val->intval = 1;
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
break;
case POWER_SUPPLY_PROP_CYCLE_COUNT:
ret = regmap_read(map, MAX17042_Cycles, &data);
if (ret < 0)
return ret;
val->intval = data;
break;
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
ret = regmap_read(map, MAX17042_MinMaxVolt, &data);
if (ret < 0)
return ret;
val->intval = data >> 8;
val->intval *= 20000; /* Units of LSB = 20mV */
break;
case POWER_SUPPLY_PROP_VOLTAGE_MIN:
ret = regmap_read(map, MAX17042_MinMaxVolt, &data);
if (ret < 0)
return ret;
val->intval = (data & 0xff) * 20000; /* Units of 20mV */
break;
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042)
ret = regmap_read(map, MAX17042_V_empty, &data);
else
ret = regmap_read(map, MAX17047_V_empty, &data);
if (ret < 0)
return ret;
val->intval = data >> 7;
val->intval *= 10000; /* Units of LSB = 10mV */
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
ret = regmap_read(map, MAX17042_VCELL, &data);
if (ret < 0)
return ret;
val->intval = data * 625 / 8;
break;
case POWER_SUPPLY_PROP_VOLTAGE_AVG:
ret = regmap_read(map, MAX17042_AvgVCELL, &data);
if (ret < 0)
return ret;
val->intval = data * 625 / 8;
break;
case POWER_SUPPLY_PROP_VOLTAGE_OCV:
ret = regmap_read(map, MAX17042_OCVInternal, &data);
if (ret < 0)
return ret;
val->intval = data * 625 / 8;
break;
case POWER_SUPPLY_PROP_CAPACITY:
if (chip->pdata->enable_current_sense)
ret = regmap_read(map, MAX17042_RepSOC, &data);
else
ret = regmap_read(map, MAX17042_VFSOC, &data);
if (ret < 0)
return ret;
val->intval = data >> 8;
break;
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
ret = regmap_read(map, MAX17042_DesignCap, &data);
if (ret < 0)
return ret;
data64 = data * 5000000ll;
do_div(data64, chip->pdata->r_sns);
val->intval = data64;
break;
case POWER_SUPPLY_PROP_CHARGE_FULL:
ret = regmap_read(map, MAX17042_FullCAP, &data);
if (ret < 0)
return ret;
data64 = data * 5000000ll;
do_div(data64, chip->pdata->r_sns);
val->intval = data64;
break;
case POWER_SUPPLY_PROP_CHARGE_NOW:
ret = regmap_read(map, MAX17042_RepCap, &data);
if (ret < 0)
return ret;
data64 = data * 5000000ll;
do_div(data64, chip->pdata->r_sns);
val->intval = data64;
break;
case POWER_SUPPLY_PROP_CHARGE_COUNTER:
ret = regmap_read(map, MAX17042_QH, &data);
if (ret < 0)
return ret;
data64 = sign_extend64(data, 15) * 5000000ll;
val->intval = div_s64(data64, chip->pdata->r_sns);
break;
case POWER_SUPPLY_PROP_TEMP:
ret = max17042_get_temperature(chip, &val->intval);
if (ret < 0)
return ret;
break;
case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
ret = regmap_read(map, MAX17042_TALRT_Th, &data);
if (ret < 0)
return ret;
/* LSB is Alert Minimum. In deci-centigrade */
val->intval = sign_extend32(data & 0xff, 7) * 10;
break;
case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
ret = regmap_read(map, MAX17042_TALRT_Th, &data);
if (ret < 0)
return ret;
/* MSB is Alert Maximum. In deci-centigrade */
val->intval = sign_extend32(data >> 8, 7) * 10;
break;
case POWER_SUPPLY_PROP_TEMP_MIN:
val->intval = chip->pdata->temp_min;
break;
case POWER_SUPPLY_PROP_TEMP_MAX:
val->intval = chip->pdata->temp_max;
break;
case POWER_SUPPLY_PROP_HEALTH:
ret = max17042_get_battery_health(chip, &val->intval);
if (ret < 0)
return ret;
break;
case POWER_SUPPLY_PROP_SCOPE:
val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
if (chip->pdata->enable_current_sense) {
ret = regmap_read(map, MAX17042_Current, &data);
if (ret < 0)
return ret;
data64 = sign_extend64(data, 15) * 1562500ll;
val->intval = div_s64(data64, chip->pdata->r_sns);
} else {
return -EINVAL;
}
break;
case POWER_SUPPLY_PROP_CURRENT_AVG:
if (chip->pdata->enable_current_sense) {
ret = regmap_read(map, MAX17042_AvgCurrent, &data);
if (ret < 0)
return ret;
data64 = sign_extend64(data, 15) * 1562500ll;
val->intval = div_s64(data64, chip->pdata->r_sns);
} else {
return -EINVAL;
}
break;
case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
ret = regmap_read(map, MAX17042_ICHGTerm, &data);
if (ret < 0)
return ret;
data64 = data * 1562500ll;
val->intval = div_s64(data64, chip->pdata->r_sns);
break;
case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
ret = regmap_read(map, MAX17042_TTE, &data);
if (ret < 0)
return ret;
val->intval = data * 5625 / 1000;
break;
default:
return -EINVAL;
}
return 0;
}