From patchwork Sun Apr 30 18:27:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Kocialkowski X-Patchwork-Id: 9706175 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id AD363601D2 for ; Sun, 30 Apr 2017 18:29:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A530D2621B for ; Sun, 30 Apr 2017 18:29:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 99E002623C; Sun, 30 Apr 2017 18:29:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2959926247 for ; Sun, 30 Apr 2017 18:29:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1163668AbdD3S3M (ORCPT ); Sun, 30 Apr 2017 14:29:12 -0400 Received: from gagarine.paulk.fr ([109.190.93.129]:53854 "EHLO gagarine.paulk.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1162962AbdD3S3G (ORCPT ); Sun, 30 Apr 2017 14:29:06 -0400 Received: by gagarine.paulk.fr (Postfix, from userid 65534) id 278AB2072E; Sun, 30 Apr 2017 20:29:05 +0200 (CEST) Received: from localhost.localdomain (collins [192.168.1.129]) by gagarine.paulk.fr (Postfix) with ESMTP id E2EB320811; Sun, 30 Apr 2017 20:28:32 +0200 (CEST) From: Paul Kocialkowski To: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Pali=20Roh=C3=A1r?= , "Andrew F . Davis" , Sebastian Reichel , Chris Lapa , Matt Ranostay , Paul Kocialkowski Subject: [PATCH 5/5] power: supply: bq27xxx: Correct supply status with current draw Date: Sun, 30 Apr 2017 20:27:27 +0200 Message-Id: <20170430182727.24412-5-contact@paulk.fr> X-Mailer: git-send-email 2.12.2 In-Reply-To: <20170430182727.24412-1-contact@paulk.fr> References: <20170430182727.24412-1-contact@paulk.fr> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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);