power: rk818-battery: fix battery charging state report error

RK818_VB_MON_REG register needs at least 100ms to be correct
status for checking whether charger is online or offline.
So We search power_supply_class to get usb and ac psy for
charging state.

Change-Id: Ic332c055100309481d0dcd6d4bf030cc8db77d2d
Signed-off-by: Jianhong Chen <chenjh@rock-chips.com>
This commit is contained in:
Jianhong Chen 2017-06-19 20:14:50 +08:00 committed by Huang, Tao
parent a427c42979
commit a51aee4744

View File

@ -143,6 +143,8 @@ struct rk818_battery {
struct regmap *regmap;
struct device *dev;
struct power_supply *bat;
struct power_supply *usb_psy;
struct power_supply *ac_psy;
struct battery_platform_data *pdata;
struct workqueue_struct *bat_monitor_wq;
struct delayed_work bat_delay_work;
@ -230,6 +232,8 @@ struct rk818_battery {
int dbg_meet_soc;
int dbg_calc_dsoc;
int dbg_calc_rsoc;
u8 ac_in;
u8 usb_in;
};
#define DIV(x) ((x) ? (x) : 1)
@ -859,6 +863,72 @@ static enum power_supply_property rk818_bat_props[] = {
POWER_SUPPLY_PROP_STATUS,
};
static int rk818_bat_get_usb_psy(struct device *dev, void *data)
{
struct rk818_battery *di = data;
struct power_supply *psy = dev_get_drvdata(dev);
if (psy->desc->type == POWER_SUPPLY_TYPE_USB) {
di->usb_psy = psy;
return 1;
}
return 0;
}
static int rk818_bat_get_ac_psy(struct device *dev, void *data)
{
struct rk818_battery *di = data;
struct power_supply *psy = dev_get_drvdata(dev);
if (psy->desc->type == POWER_SUPPLY_TYPE_MAINS) {
di->ac_psy = psy;
return 1;
}
return 0;
}
static void rk818_bat_get_chrg_psy(struct rk818_battery *di)
{
if (!di->usb_psy)
class_for_each_device(power_supply_class, NULL, (void *)di,
rk818_bat_get_usb_psy);
if (!di->ac_psy)
class_for_each_device(power_supply_class, NULL, (void *)di,
rk818_bat_get_ac_psy);
}
static int rk818_bat_get_charge_state(struct rk818_battery *di)
{
union power_supply_propval val;
int ret;
if (!di->usb_psy || !di->ac_psy)
rk818_bat_get_chrg_psy(di);
if (di->usb_psy) {
ret = di->usb_psy->desc->get_property(di->usb_psy,
POWER_SUPPLY_PROP_ONLINE,
&val);
if (!ret)
di->usb_in = val.intval;
}
if (di->ac_psy) {
ret = di->ac_psy->desc->get_property(di->ac_psy,
POWER_SUPPLY_PROP_ONLINE,
&val);
if (!ret)
di->ac_in = val.intval;
}
DBG("%s: ac_online=%d, usb_online=%d\n",
__func__, di->ac_in, di->usb_in);
return (di->usb_in || di->ac_in);
}
static int rk818_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@ -900,7 +970,7 @@ static int rk818_battery_get_property(struct power_supply *psy,
val->intval = VIRTUAL_STATUS;
else if (di->dsoc == 100)
val->intval = POWER_SUPPLY_STATUS_FULL;
else if (rk818_bat_chrg_online(di))
else if (rk818_bat_get_charge_state(di))
val->intval = POWER_SUPPLY_STATUS_CHARGING;
else
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
@ -1832,7 +1902,7 @@ static void rk818_bat_debug_info(struct rk818_battery *di)
DBG("###############################################################\n"
"Dsoc=%d, Rsoc=%d, Vavg=%d, Iavg=%d, Cap=%d, Fcc=%d, d=%d\n"
"K=%d, Mode=%s, Oldcap=%d, Is=%d, Ip=%d, Vs=%d\n"
"fb_temp=%d, bat_temp=%d, sample_res=%d\n"
"fb_temp=%d, bat_temp=%d, sample_res=%d, USB=%d, DC=%d\n"
"off:i=0x%x, c=0x%x, p=%d, Rbat=%d, age_ocv_cap=%d, fb=%d\n"
"adp:finish=%lu, boot_min=%lu, sleep_min=%lu, adc=%d, Vsys=%d\n"
"bat:%s, meet: soc=%d, calc: dsoc=%d, rsoc=%d, Vocv=%d\n"
@ -1847,7 +1917,8 @@ static void rk818_bat_debug_info(struct rk818_battery *di)
chrg_cur_input_array[usb_ctrl & 0x0f],
chrg_vol_sel_array[(chrg_ctrl1 & 0x70) >> 4],
feedback_temp_array[(thermal & 0x0c) >> 2], di->temperature,
di->pdata->sample_res, rk818_bat_get_ioffset(di),
di->pdata->sample_res, di->usb_in, di->ac_in,
rk818_bat_get_ioffset(di),
rk818_bat_get_coffset(di), di->poffset, di->bat_res,
di->age_adjust_cap, di->fb_blank, base2min(di->finish_base),
base2min(di->boot_base), di->sleep_sum_sec / 60,