Messages in this thread Patch in this message |  | | From | Paul Kocialkowski <> | Subject | [PATCH 5/5] power: supply: bq27xxx: Correct supply status with current draw | Date | Sun, 30 Apr 2017 20:27:27 +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 when retrieving the supply status.
Signed-off-by: Paul Kocialkowski <contact@paulk.fr> --- drivers/power/supply/bq27xxx_battery.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c index cade00df6162..f7694e775e68 100644 --- a/drivers/power/supply/bq27xxx_battery.c +++ b/drivers/power/supply/bq27xxx_battery.c @@ -1171,8 +1171,22 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di, union power_supply_propval *val) { int status; + int curr; + int flags; + + curr = bq27xxx_read(di, BQ27XXX_REG_AI, false); + if (curr < 0) { + dev_err(di->dev, "error reading current\n"); + return curr; + } if (di->chip == BQ27000 || di->chip == BQ27010) { + flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true); + if (flags & BQ27000_FLAG_CHGS) { + dev_dbg(di->dev, "negative current!\n"); + curr = -curr; + } + if (di->cache.flags & BQ27000_FLAG_FC) status = POWER_SUPPLY_STATUS_FULL; else if (di->cache.flags & BQ27000_FLAG_CHGS) @@ -1182,6 +1196,8 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di, else status = POWER_SUPPLY_STATUS_DISCHARGING; } else { + curr = (int)((s16)curr) * 1000; + if (di->cache.flags & BQ27XXX_FLAG_FC) status = POWER_SUPPLY_STATUS_FULL; else if (di->cache.flags & BQ27XXX_FLAG_DSC) @@ -1190,6 +1206,18 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di, status = POWER_SUPPLY_STATUS_CHARGING; } + + if (curr == 0 && status != POWER_SUPPLY_STATUS_NOT_CHARGING) + status = POWER_SUPPLY_STATUS_FULL; + + if (status == POWER_SUPPLY_STATUS_FULL) { + /* Drawing or providing current when full */ + if (curr > 0) + status = POWER_SUPPLY_STATUS_CHARGING; + else if (curr < 0) + status = POWER_SUPPLY_STATUS_DISCHARGING; + } + if (di->status_retry == 0 && di->status_change_reference != status) { di->status_change_reference = status; power_supply_changed(di->bat); -- 2.12.2
|  |