aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kocialkowski <contact@paulk.fr>2017-04-25 11:09:05 -0400
committerSebastian Reichel <sre@kernel.org>2017-05-01 06:45:43 -0400
commit7f93e1fa032bb5ee19b868b9649bc98c82553003 (patch)
tree8a341c417abf7b2009a4352c5ac1011e17926fb3
parent4df2cce4722d35eb35bb9371e7c9a600a84558f9 (diff)
power: supply: sbs-battery: Correct supply status with current draw
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>
-rw-r--r--drivers/power/supply/sbs-battery.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c
index 7fd0f308189f..171c701a2d49 100644
--- a/drivers/power/supply/sbs-battery.c
+++ b/drivers/power/supply/sbs-battery.c
@@ -295,6 +295,31 @@ static int sbs_write_word_data(struct i2c_client *client, u8 address,
295 return 0; 295 return 0;
296} 296}
297 297
298static int sbs_status_correct(struct i2c_client *client, int *intval)
299{
300 int ret;
301
302 ret = sbs_read_word_data(client, sbs_data[REG_CURRENT].addr);
303 if (ret < 0)
304 return ret;
305
306 ret = (s16)ret;
307
308 /* Not drawing current means full (cannot be not charging) */
309 if (ret == 0)
310 *intval = POWER_SUPPLY_STATUS_FULL;
311
312 if (*intval == POWER_SUPPLY_STATUS_FULL) {
313 /* Drawing or providing current when full */
314 if (ret > 0)
315 *intval = POWER_SUPPLY_STATUS_CHARGING;
316 else if (ret < 0)
317 *intval = POWER_SUPPLY_STATUS_DISCHARGING;
318 }
319
320 return 0;
321}
322
298static int sbs_get_battery_presence_and_health( 323static int sbs_get_battery_presence_and_health(
299 struct i2c_client *client, enum power_supply_property psp, 324 struct i2c_client *client, enum power_supply_property psp,
300 union power_supply_propval *val) 325 union power_supply_propval *val)
@@ -401,6 +426,8 @@ static int sbs_get_battery_property(struct i2c_client *client,
401 else 426 else
402 val->intval = POWER_SUPPLY_STATUS_CHARGING; 427 val->intval = POWER_SUPPLY_STATUS_CHARGING;
403 428
429 sbs_status_correct(client, &val->intval);
430
404 if (chip->poll_time == 0) 431 if (chip->poll_time == 0)
405 chip->last_state = val->intval; 432 chip->last_state = val->intval;
406 else if (chip->last_state != val->intval) { 433 else if (chip->last_state != val->intval) {
@@ -721,6 +748,8 @@ static void sbs_delayed_work(struct work_struct *work)
721 else 748 else
722 ret = POWER_SUPPLY_STATUS_CHARGING; 749 ret = POWER_SUPPLY_STATUS_CHARGING;
723 750
751 sbs_status_correct(chip->client, &ret);
752
724 if (chip->last_state != ret) { 753 if (chip->last_state != ret) {
725 chip->poll_time = 0; 754 chip->poll_time = 0;
726 power_supply_changed(chip->power_supply); 755 power_supply_changed(chip->power_supply);