]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
power: supply: sbs-battery: Correct supply status with current draw
authorPaul Kocialkowski <contact@paulk.fr>
Tue, 25 Apr 2017 15:09:05 +0000 (17:09 +0200)
committerSebastian Reichel <sre@kernel.org>
Mon, 1 May 2017 10:45:43 +0000 (12:45 +0200)
The status reported directly by the battery controller is not always
reliable and should be corrected based on the current draw information.

This implements such a correction with a dedicated function, called
where the supply status is retrieved.

Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
drivers/power/supply/sbs-battery.c

index 7fd0f308189f8cf754d0737377547c07f90a5191..171c701a2d492988c0a68401a5a2c42e4853f5fc 100644 (file)
@@ -295,6 +295,31 @@ static int sbs_write_word_data(struct i2c_client *client, u8 address,
        return 0;
 }
 
+static int sbs_status_correct(struct i2c_client *client, int *intval)
+{
+       int ret;
+
+       ret = sbs_read_word_data(client, sbs_data[REG_CURRENT].addr);
+       if (ret < 0)
+               return ret;
+
+       ret = (s16)ret;
+
+       /* Not drawing current means full (cannot be not charging) */
+       if (ret == 0)
+               *intval = POWER_SUPPLY_STATUS_FULL;
+
+       if (*intval == POWER_SUPPLY_STATUS_FULL) {
+               /* Drawing or providing current when full */
+               if (ret > 0)
+                       *intval = POWER_SUPPLY_STATUS_CHARGING;
+               else if (ret < 0)
+                       *intval = POWER_SUPPLY_STATUS_DISCHARGING;
+       }
+
+       return 0;
+}
+
 static int sbs_get_battery_presence_and_health(
        struct i2c_client *client, enum power_supply_property psp,
        union power_supply_propval *val)
@@ -401,6 +426,8 @@ static int sbs_get_battery_property(struct i2c_client *client,
                else
                        val->intval = POWER_SUPPLY_STATUS_CHARGING;
 
+               sbs_status_correct(client, &val->intval);
+
                if (chip->poll_time == 0)
                        chip->last_state = val->intval;
                else if (chip->last_state != val->intval) {
@@ -721,6 +748,8 @@ static void sbs_delayed_work(struct work_struct *work)
        else
                ret = POWER_SUPPLY_STATUS_CHARGING;
 
+       sbs_status_correct(chip->client, &ret);
+
        if (chip->last_state != ret) {
                chip->poll_time = 0;
                power_supply_changed(chip->power_supply);