in supply/bq25890_charger.c [425:570]
static int bq25890_power_supply_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
struct bq25890_device *bq = power_supply_get_drvdata(psy);
struct bq25890_state state;
bool do_adc_conv;
int ret;
mutex_lock(&bq->lock);
/* update state in case we lost an interrupt */
__bq25890_handle_irq(bq);
state = bq->state;
do_adc_conv = !state.online && bq25890_is_adc_property(psp);
if (do_adc_conv)
bq25890_field_write(bq, F_CONV_START, 1);
mutex_unlock(&bq->lock);
if (do_adc_conv)
regmap_field_read_poll_timeout(bq->rmap_fields[F_CONV_START],
ret, !ret, 25000, 1000000);
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
if (!state.online)
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
else if (state.chrg_status == STATUS_NOT_CHARGING)
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
else if (state.chrg_status == STATUS_PRE_CHARGING ||
state.chrg_status == STATUS_FAST_CHARGING)
val->intval = POWER_SUPPLY_STATUS_CHARGING;
else if (state.chrg_status == STATUS_TERMINATION_DONE)
val->intval = POWER_SUPPLY_STATUS_FULL;
else
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
break;
case POWER_SUPPLY_PROP_CHARGE_TYPE:
if (!state.online || state.chrg_status == STATUS_NOT_CHARGING ||
state.chrg_status == STATUS_TERMINATION_DONE)
val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
else if (state.chrg_status == STATUS_PRE_CHARGING)
val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD;
else if (state.chrg_status == STATUS_FAST_CHARGING)
val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
else /* unreachable */
val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
break;
case POWER_SUPPLY_PROP_MANUFACTURER:
val->strval = BQ25890_MANUFACTURER;
break;
case POWER_SUPPLY_PROP_MODEL_NAME:
val->strval = bq25890_chip_name[bq->chip_version];
break;
case POWER_SUPPLY_PROP_ONLINE:
val->intval = state.online;
break;
case POWER_SUPPLY_PROP_HEALTH:
if (!state.chrg_fault && !state.bat_fault && !state.boost_fault)
val->intval = POWER_SUPPLY_HEALTH_GOOD;
else if (state.bat_fault)
val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
else if (state.chrg_fault == CHRG_FAULT_TIMER_EXPIRED)
val->intval = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
else if (state.chrg_fault == CHRG_FAULT_THERMAL_SHUTDOWN)
val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
else
val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
val->intval = bq25890_find_val(bq->init_data.ichg, TBL_ICHG);
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
if (!state.online) {
val->intval = 0;
break;
}
ret = bq25890_field_read(bq, F_BATV); /* read measured value */
if (ret < 0)
return ret;
/* converted_val = 2.304V + ADC_val * 20mV (table 10.3.15) */
val->intval = 2304000 + ret * 20000;
break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
val->intval = bq25890_find_val(bq->init_data.vreg, TBL_VREG);
break;
case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
val->intval = bq25890_find_val(bq->init_data.iprechg, TBL_ITERM);
break;
case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
val->intval = bq25890_find_val(bq->init_data.iterm, TBL_ITERM);
break;
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
ret = bq25890_field_read(bq, F_IILIM);
if (ret < 0)
return ret;
val->intval = bq25890_find_val(ret, TBL_IILIM);
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
ret = bq25890_field_read(bq, F_SYSV); /* read measured value */
if (ret < 0)
return ret;
/* converted_val = 2.304V + ADC_val * 20mV (table 10.3.15) */
val->intval = 2304000 + ret * 20000;
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
ret = bq25890_field_read(bq, F_ICHGR); /* read measured value */
if (ret < 0)
return ret;
/* converted_val = ADC_val * 50mA (table 10.3.19) */
val->intval = ret * -50000;
break;
case POWER_SUPPLY_PROP_TEMP:
ret = bq25890_field_read(bq, F_TSPCT);
if (ret < 0)
return ret;
/* convert TS percentage into rough temperature */
val->intval = bq25890_find_val(ret, TBL_TSPCT);
break;
default:
return -EINVAL;
}
return 0;
}