From a51aee4744ce6921348e93e726fe84a599b06370 Mon Sep 17 00:00:00 2001 From: Jianhong Chen Date: Mon, 19 Jun 2017 20:14:50 +0800 Subject: [PATCH] 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 --- drivers/power/rk818_battery.c | 77 +++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 3 deletions(-) diff --git a/drivers/power/rk818_battery.c b/drivers/power/rk818_battery.c index f2a07fd05841..378fea9e3feb 100644 --- a/drivers/power/rk818_battery.c +++ b/drivers/power/rk818_battery.c @@ -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, -- 2.34.1