power: rk818-battery: fix battery charging state report error
authorJianhong Chen <chenjh@rock-chips.com>
Mon, 19 Jun 2017 12:14:50 +0000 (20:14 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 21 Jun 2017 06:07:17 +0000 (14:07 +0800)
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>
drivers/power/rk818_battery.c

index f2a07fd05841b164ed6c2e1063fa911fbb5fbf3e..378fea9e3feb842c3149ccd821d2d4dff42ee899 100644 (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,