From patchwork Sun Jan 10 19:53:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Lindgren X-Patchwork-Id: 360296 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90FAFC433DB for ; Sun, 10 Jan 2021 19:54:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 61DA1207B3 for ; Sun, 10 Jan 2021 19:54:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726655AbhAJTyw (ORCPT ); Sun, 10 Jan 2021 14:54:52 -0500 Received: from muru.com ([72.249.23.125]:42358 "EHLO muru.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726394AbhAJTyw (ORCPT ); Sun, 10 Jan 2021 14:54:52 -0500 Received: from hillo.muru.com (localhost [127.0.0.1]) by muru.com (Postfix) with ESMTP id 8937C810A; Sun, 10 Jan 2021 19:54:11 +0000 (UTC) From: Tony Lindgren To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, linux-omap@vger.kernel.org, Arthur Demchenkov , Carl Philipp Klemm , Merlijn Wajer , Pavel Machek Subject: [PATCH 02/15] power: supply: cpcap-battery: Fix missing power_supply_put() Date: Sun, 10 Jan 2021 21:53:50 +0200 Message-Id: <20210110195403.13758-3-tony@atomide.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210110195403.13758-1-tony@atomide.com> References: <20210110195403.13758-1-tony@atomide.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org Fix missing power_supply_put(). Cc: Arthur Demchenkov Cc: Carl Philipp Klemm Cc: Merlijn Wajer Cc: Pavel Machek Fixes: b0134cc14b9 ("power: supply: cpcap-battery: Fix handling of lowered charger voltage") Signed-off-by: Tony Lindgren --- drivers/power/supply/cpcap-battery.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c --- a/drivers/power/supply/cpcap-battery.c +++ b/drivers/power/supply/cpcap-battery.c @@ -568,17 +568,21 @@ static int cpcap_battery_update_charger(struct cpcap_battery_ddata *ddata, POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, &prop); if (error) - return error; + goto out_put; /* Allow charger const voltage lower than battery const voltage */ if (const_charge_voltage > prop.intval) - return 0; + goto out_put; val.intval = const_charge_voltage; - return power_supply_set_property(charger, + error = power_supply_set_property(charger, POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, &val); +out_put: + power_supply_put(charger); + + return error; } static int cpcap_battery_set_property(struct power_supply *psy, From patchwork Sun Jan 10 19:53:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Lindgren X-Patchwork-Id: 360295 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CDB04C433E9 for ; Sun, 10 Jan 2021 19:54:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A858722581 for ; Sun, 10 Jan 2021 19:54:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726748AbhAJTy4 (ORCPT ); Sun, 10 Jan 2021 14:54:56 -0500 Received: from muru.com ([72.249.23.125]:42380 "EHLO muru.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726394AbhAJTy4 (ORCPT ); Sun, 10 Jan 2021 14:54:56 -0500 Received: from hillo.muru.com (localhost [127.0.0.1]) by muru.com (Postfix) with ESMTP id 1A41D8140; Sun, 10 Jan 2021 19:54:14 +0000 (UTC) From: Tony Lindgren To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, linux-omap@vger.kernel.org, Arthur Demchenkov , Carl Philipp Klemm , Merlijn Wajer , Pavel Machek Subject: [PATCH 04/15] power: supply: cpcap-charger: Make VBUS already provided debug only Date: Sun, 10 Jan 2021 21:53:52 +0200 Message-Id: <20210110195403.13758-5-tony@atomide.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210110195403.13758-1-tony@atomide.com> References: <20210110195403.13758-1-tony@atomide.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org This should be only shown when debug is enabled. Cc: Arthur Demchenkov Cc: Carl Philipp Klemm Cc: Merlijn Wajer Cc: Pavel Machek Signed-off-by: Tony Lindgren --- drivers/power/supply/cpcap-charger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c --- a/drivers/power/supply/cpcap-charger.c +++ b/drivers/power/supply/cpcap-charger.c @@ -434,7 +434,7 @@ static void cpcap_charger_vbus_work(struct work_struct *work) if (ddata->vbus_enabled) { vbus = cpcap_charger_vbus_valid(ddata); if (vbus) { - dev_info(ddata->dev, "VBUS already provided\n"); + dev_dbg(ddata->dev, "VBUS already provided\n"); return; } From patchwork Sun Jan 10 19:53:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Lindgren X-Patchwork-Id: 360294 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ECF6AC433E9 for ; Sun, 10 Jan 2021 19:55:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C0A6222A84 for ; Sun, 10 Jan 2021 19:55:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726495AbhAJTza (ORCPT ); Sun, 10 Jan 2021 14:55:30 -0500 Received: from muru.com ([72.249.23.125]:42500 "EHLO muru.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726479AbhAJTza (ORCPT ); Sun, 10 Jan 2021 14:55:30 -0500 Received: from hillo.muru.com (localhost [127.0.0.1]) by muru.com (Postfix) with ESMTP id 82DE581D0; Sun, 10 Jan 2021 19:54:18 +0000 (UTC) From: Tony Lindgren To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, linux-omap@vger.kernel.org, Pavel Machek , Arthur Demchenkov , Carl Philipp Klemm , Merlijn Wajer Subject: [PATCH 06/15] power: supply: cpcap-charger: Limiting charge current on Droid 4 Date: Sun, 10 Jan 2021 21:53:54 +0200 Message-Id: <20210110195403.13758-7-tony@atomide.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210110195403.13758-1-tony@atomide.com> References: <20210110195403.13758-1-tony@atomide.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org From: Pavel Machek Droid 4 has same problem as N900: it is often necessary to manually tweak current draw from USB, for example when using thin charging cable. Cc: Arthur Demchenkov Cc: Carl Philipp Klemm Cc: Merlijn Wajer Cc: Pavel Machek Signed-off-by: Pavel Machek [tony@atomide.com: rebased, cleaned up whitespace issues, updated comments] Signed-off-by: Tony Lindgren --- drivers/power/supply/cpcap-charger.c | 49 ++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c --- a/drivers/power/supply/cpcap-charger.c +++ b/drivers/power/supply/cpcap-charger.c @@ -89,6 +89,8 @@ * CPCAP_REG_CRM charge currents. These seem to match MC13783UG.pdf * values in "Table 8-3. Charge Path Regulator Current Limit * Characteristics" for the nominal values. + * + * Except 70mA and 1.596A and unlimited, these are simply 88.7mA / step. */ #define CPCAP_REG_CRM_ICHRG(val) (((val) & 0xf) << 0) #define CPCAP_REG_CRM_ICHRG_0A000 CPCAP_REG_CRM_ICHRG(0x0) @@ -140,6 +142,7 @@ struct cpcap_charger_ddata { int status; int state; int voltage; + int limit_current; }; struct cpcap_interrupt_desc { @@ -166,6 +169,7 @@ static enum power_supply_property cpcap_charger_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_NOW, }; @@ -229,6 +233,9 @@ static int cpcap_charger_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_STATUS: val->intval = ddata->status; break; + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + val->intval = ddata->limit_current; + break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: val->intval = ddata->voltage; break; @@ -300,6 +307,26 @@ cpcap_charger_get_bat_const_charge_voltage(struct cpcap_charger_ddata *ddata) return voltage; } +static int cpcap_charger_current_to_regval(int microamp) +{ + int miliamp = microamp / 1000; + int res; + + if (miliamp < 0) + return -EINVAL; + if (miliamp < 70) + return CPCAP_REG_CRM_ICHRG(0x0); + if (miliamp < 177) + return CPCAP_REG_CRM_ICHRG(0x1); + if (miliamp > 1596) + return CPCAP_REG_CRM_ICHRG(0xe); + + res = microamp / 88666; + if (res > 0xd) + res = 0xd; + return CPCAP_REG_CRM_ICHRG(res); +} + static int cpcap_charger_set_property(struct power_supply *psy, enum power_supply_property psp, const union power_supply_propval *val) @@ -308,6 +335,12 @@ static int cpcap_charger_set_property(struct power_supply *psy, int voltage, batvolt; switch (psp) { + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + if (cpcap_charger_current_to_regval(val->intval) < 0) + return -EINVAL; + ddata->limit_current = val->intval; + schedule_delayed_work(&ddata->detect_work, 0); + break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: voltage = cpcap_charger_match_voltage(val->intval); batvolt = cpcap_charger_get_bat_const_charge_voltage(ddata); @@ -327,6 +360,7 @@ static int cpcap_charger_property_is_writeable(struct power_supply *psy, enum power_supply_property psp) { switch (psp) { + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: return 1; default: @@ -652,18 +686,20 @@ static void cpcap_usb_detect(struct work_struct *work) if (!ddata->feeding_vbus && cpcap_charger_vbus_valid(ddata) && s.chrgcurr1) { - int max_current; - int vchrg; + int max_current = 532000; + int vchrg, ichrg; if (cpcap_charger_battery_found(ddata)) - max_current = CPCAP_REG_CRM_ICHRG_1A596; - else - max_current = CPCAP_REG_CRM_ICHRG_0A532; + max_current = 1596000; + + if (max_current > ddata->limit_current) + max_current = ddata->limit_current; + ichrg = cpcap_charger_current_to_regval(max_current); vchrg = cpcap_charger_voltage_to_regval(ddata->voltage); error = cpcap_charger_set_state(ddata, CPCAP_REG_CRM_VCHRG(vchrg), - max_current, 0); + ichrg, 0); if (error) goto out_err; cpcap_charger_update_state(ddata, @@ -837,6 +873,7 @@ static int cpcap_charger_probe(struct platform_device *pdev) ddata->dev = &pdev->dev; ddata->voltage = 4200000; + ddata->limit_current = 532000; ddata->reg = dev_get_regmap(ddata->dev->parent, NULL); if (!ddata->reg) From patchwork Sun Jan 10 19:53:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Lindgren X-Patchwork-Id: 360293 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 91383C433E0 for ; Sun, 10 Jan 2021 19:55:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5DE1422A84 for ; Sun, 10 Jan 2021 19:55:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726686AbhAJTzc (ORCPT ); Sun, 10 Jan 2021 14:55:32 -0500 Received: from muru.com ([72.249.23.125]:42504 "EHLO muru.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726479AbhAJTzc (ORCPT ); Sun, 10 Jan 2021 14:55:32 -0500 Received: from hillo.muru.com (localhost [127.0.0.1]) by muru.com (Postfix) with ESMTP id 5364388B3; Sun, 10 Jan 2021 19:54:20 +0000 (UTC) From: Tony Lindgren To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, linux-omap@vger.kernel.org, Arthur Demchenkov , Carl Philipp Klemm , Merlijn Wajer , Pavel Machek Subject: [PATCH 07/15] power: supply: cpcap-charger: Drop internal state and use generic stats Date: Sun, 10 Jan 2021 21:53:55 +0200 Message-Id: <20210110195403.13758-8-tony@atomide.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210110195403.13758-1-tony@atomide.com> References: <20210110195403.13758-1-tony@atomide.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org We currently have both state and status, get rid of state and use generic status instead. Cc: Arthur Demchenkov Cc: Carl Philipp Klemm Cc: Merlijn Wajer Cc: Pavel Machek Signed-off-by: Tony Lindgren --- drivers/power/supply/cpcap-charger.c | 81 ++++++++++++++-------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c --- a/drivers/power/supply/cpcap-charger.c +++ b/drivers/power/supply/cpcap-charger.c @@ -140,7 +140,6 @@ struct cpcap_charger_ddata { atomic_t active; int status; - int state; int voltage; int limit_current; }; @@ -386,6 +385,39 @@ static void cpcap_charger_set_inductive_path(struct cpcap_charger_ddata *ddata, gpiod_set_value(ddata->gpio[1], enabled); } +static void cpcap_charger_update_state(struct cpcap_charger_ddata *ddata, + int state) +{ + const char *status; + + if (state > POWER_SUPPLY_STATUS_FULL) { + dev_warn(ddata->dev, "unknown state: %i\n", state); + + return; + } + + ddata->status = state; + + switch (state) { + case POWER_SUPPLY_STATUS_DISCHARGING: + status = "DISCONNECTED"; + break; + case POWER_SUPPLY_STATUS_NOT_CHARGING: + status = "DETECTING"; + break; + case POWER_SUPPLY_STATUS_CHARGING: + status = "CHARGING"; + break; + case POWER_SUPPLY_STATUS_FULL: + status = "DONE"; + break; + default: + return; + } + + dev_dbg(ddata->dev, "state: %s\n", status); +} + static int cpcap_charger_set_state(struct cpcap_charger_ddata *ddata, int max_voltage, int charge_current, int trickle_current) @@ -402,11 +434,13 @@ static int cpcap_charger_set_state(struct cpcap_charger_ddata *ddata, CPCAP_REG_CRM_FET_OVRD | CPCAP_REG_CRM_FET_CTRL); if (error) { - ddata->status = POWER_SUPPLY_STATUS_UNKNOWN; + cpcap_charger_update_state(ddata, + POWER_SUPPLY_STATUS_UNKNOWN); goto out_err; } - ddata->status = POWER_SUPPLY_STATUS_DISCHARGING; + cpcap_charger_update_state(ddata, + POWER_SUPPLY_STATUS_DISCHARGING); return 0; } @@ -419,11 +453,13 @@ static int cpcap_charger_set_state(struct cpcap_charger_ddata *ddata, max_voltage | charge_current); if (error) { - ddata->status = POWER_SUPPLY_STATUS_UNKNOWN; + cpcap_charger_update_state(ddata, + POWER_SUPPLY_STATUS_UNKNOWN); goto out_err; } - ddata->status = POWER_SUPPLY_STATUS_CHARGING; + cpcap_charger_update_state(ddata, + POWER_SUPPLY_STATUS_CHARGING); return 0; @@ -555,39 +591,6 @@ static int cpcap_charger_get_ints_state(struct cpcap_charger_ddata *ddata, return 0; } -static void cpcap_charger_update_state(struct cpcap_charger_ddata *ddata, - int state) -{ - const char *status; - - if (state > POWER_SUPPLY_STATUS_FULL) { - dev_warn(ddata->dev, "unknown state: %i\n", state); - - return; - } - - ddata->state = state; - - switch (state) { - case POWER_SUPPLY_STATUS_DISCHARGING: - status = "DISCONNECTED"; - break; - case POWER_SUPPLY_STATUS_NOT_CHARGING: - status = "DETECTING"; - break; - case POWER_SUPPLY_STATUS_CHARGING: - status = "CHARGING"; - break; - case POWER_SUPPLY_STATUS_FULL: - status = "DONE"; - break; - default: - return; - } - - dev_dbg(ddata->dev, "state: %s\n", status); -} - static int cpcap_charger_voltage_to_regval(int voltage) { int offset; @@ -662,7 +665,7 @@ static void cpcap_usb_detect(struct work_struct *work) } /* Throttle chrgcurr2 interrupt for charger done and retry */ - switch (ddata->state) { + switch (ddata->status) { case POWER_SUPPLY_STATUS_CHARGING: if (s.chrgcurr2) break; From patchwork Sun Jan 10 19:53:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Lindgren X-Patchwork-Id: 360292 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F1D5CC43332 for ; Sun, 10 Jan 2021 19:55:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CB376225A9 for ; Sun, 10 Jan 2021 19:55:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726827AbhAJTze (ORCPT ); Sun, 10 Jan 2021 14:55:34 -0500 Received: from muru.com ([72.249.23.125]:42506 "EHLO muru.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726479AbhAJTzd (ORCPT ); Sun, 10 Jan 2021 14:55:33 -0500 Received: from hillo.muru.com (localhost [127.0.0.1]) by muru.com (Postfix) with ESMTP id F3F0C88C3; Sun, 10 Jan 2021 19:54:23 +0000 (UTC) From: Tony Lindgren To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, linux-omap@vger.kernel.org, Arthur Demchenkov , Carl Philipp Klemm , Merlijn Wajer , Pavel Machek Subject: [PATCH 09/15] power: supply: cpcap-charger: Provide state updates for battery from charger Date: Sun, 10 Jan 2021 21:53:57 +0200 Message-Id: <20210110195403.13758-10-tony@atomide.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210110195403.13758-1-tony@atomide.com> References: <20210110195403.13758-1-tony@atomide.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org We want to have the battery update it's status when the charge is done, and when the charger is disconnected. Otherwise the battery does not know when it's full unless there's a userspace app polling the battery status. To do this, we add supplied_to handling to cpcap-battery, and implement power_supply_changed() for cpcap-charger. When cpcap-charger calls power_supply_changed(), cpcap-battery will update it's status. Let's also use new_state variable for the POWER_SUPPLY_STATUS_CHARGING case to have unified handling for the switch. Cc: Arthur Demchenkov Cc: Carl Philipp Klemm Cc: Merlijn Wajer Cc: Pavel Machek Signed-off-by: Tony Lindgren --- drivers/power/supply/cpcap-battery.c | 13 +++++++++++ drivers/power/supply/cpcap-charger.c | 34 ++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c --- a/drivers/power/supply/cpcap-battery.c +++ b/drivers/power/supply/cpcap-battery.c @@ -416,6 +416,18 @@ static int cpcap_battery_update_status(struct cpcap_battery_ddata *ddata) return 0; } +/* + * Update battery status when cpcap-charger calls power_supply_changed(). + * This allows us to detect battery full condition before the charger + * disconnects. + */ +static void cpcap_battery_external_power_changed(struct power_supply *psy) +{ + union power_supply_propval prop; + + power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS, &prop); +} + static enum power_supply_property cpcap_battery_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, @@ -914,6 +926,7 @@ static int cpcap_battery_probe(struct platform_device *pdev) psy_desc->get_property = cpcap_battery_get_property; psy_desc->set_property = cpcap_battery_set_property; psy_desc->property_is_writeable = cpcap_battery_property_is_writeable; + psy_desc->external_power_changed = cpcap_battery_external_power_changed; psy_cfg.of_node = pdev->dev.of_node; psy_cfg.drv_data = ddata; diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c --- a/drivers/power/supply/cpcap-charger.c +++ b/drivers/power/supply/cpcap-charger.c @@ -613,6 +613,16 @@ static void cpcap_charger_disconnect(struct cpcap_charger_ddata *ddata, { int error; + /* Update battery state before disconnecting the charger */ + switch (state) { + case POWER_SUPPLY_STATUS_DISCHARGING: + case POWER_SUPPLY_STATUS_FULL: + power_supply_changed(ddata->usb); + break; + default: + break; + } + error = cpcap_charger_disable(ddata); if (error) { cpcap_charger_update_state(ddata, POWER_SUPPLY_STATUS_UNKNOWN); @@ -628,7 +638,7 @@ static void cpcap_usb_detect(struct work_struct *work) { struct cpcap_charger_ddata *ddata; struct cpcap_charger_ints_state s; - int error; + int error, new_state; ddata = container_of(work, struct cpcap_charger_ddata, detect_work.work); @@ -662,19 +672,23 @@ static void cpcap_usb_detect(struct work_struct *work) case POWER_SUPPLY_STATUS_CHARGING: if (s.chrgcurr2) break; + new_state = POWER_SUPPLY_STATUS_FULL; + if (s.chrgcurr1 && s.vbusvld) { - cpcap_charger_disconnect(ddata, - POWER_SUPPLY_STATUS_FULL, - HZ * 5); + cpcap_charger_disconnect(ddata, new_state, HZ * 5); return; } break; case POWER_SUPPLY_STATUS_FULL: if (!s.chrgcurr2) break; - cpcap_charger_disconnect(ddata, - POWER_SUPPLY_STATUS_NOT_CHARGING, - HZ * 5); + if (s.vbusvld) + new_state = POWER_SUPPLY_STATUS_NOT_CHARGING; + else + new_state = POWER_SUPPLY_STATUS_DISCHARGING; + + cpcap_charger_disconnect(ddata, new_state, HZ * 5); + return; default: break; @@ -832,6 +846,10 @@ static int cpcap_charger_init_iio(struct cpcap_charger_ddata *ddata) return error; } +static char *cpcap_charger_supplied_to[] = { + "battery", +}; + static const struct power_supply_desc cpcap_charger_usb_desc = { .name = "usb", .type = POWER_SUPPLY_TYPE_USB, @@ -889,6 +907,8 @@ static int cpcap_charger_probe(struct platform_device *pdev) psy_cfg.of_node = pdev->dev.of_node; psy_cfg.drv_data = ddata; + psy_cfg.supplied_to = cpcap_charger_supplied_to; + psy_cfg.num_supplicants = ARRAY_SIZE(cpcap_charger_supplied_to), ddata->usb = devm_power_supply_register(ddata->dev, &cpcap_charger_usb_desc, From patchwork Sun Jan 10 19:54:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Lindgren X-Patchwork-Id: 360291 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 11BB9C433E6 for ; Sun, 10 Jan 2021 19:55:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D978122A84 for ; Sun, 10 Jan 2021 19:55:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726877AbhAJTzg (ORCPT ); Sun, 10 Jan 2021 14:55:36 -0500 Received: from muru.com ([72.249.23.125]:42510 "EHLO muru.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726841AbhAJTzf (ORCPT ); Sun, 10 Jan 2021 14:55:35 -0500 Received: from hillo.muru.com (localhost [127.0.0.1]) by muru.com (Postfix) with ESMTP id 66FE588E0; Sun, 10 Jan 2021 19:54:29 +0000 (UTC) From: Tony Lindgren To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, linux-omap@vger.kernel.org, Arthur Demchenkov , Carl Philipp Klemm , Merlijn Wajer , Pavel Machek Subject: [PATCH 12/15] power: supply: cpcap-battery: Keep track of state for capacity reporting Date: Sun, 10 Jan 2021 21:54:00 +0200 Message-Id: <20210110195403.13758-13-tony@atomide.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210110195403.13758-1-tony@atomide.com> References: <20210110195403.13758-1-tony@atomide.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org From: Arthur Demchenkov Save the battery empty and full states so we can use those to estimate the battery capacity in the following patches. If the user provides us with charge_full value (which it could save in a permanent storage between reboots), initialize low and high counter_uah with calculated values. If we hit battery low once, we should stick on reporting it until the charger is connected. This way low->counter_uah will be updated properly, and that will allow us to get more accurate charge_full value. Based on an earlier patch by Tony Lindgren with charge_full usage and other improvments done by Arthur Demchenkov. Cc: Arthur Demchenkov Cc: Carl Philipp Klemm Cc: Merlijn Wajer Cc: Pavel Machek Co-developed-by: Tony Lindgren Signed-off-by: Arthur Demchenkov [tony@atomide.com: combined earlier patches, updated comments] Signed-off-by: Tony Lindgren --- drivers/power/supply/cpcap-battery.c | 56 +++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c --- a/drivers/power/supply/cpcap-battery.c +++ b/drivers/power/supply/cpcap-battery.c @@ -111,6 +111,8 @@ struct cpcap_coulomb_counter_data { enum cpcap_battery_state { CPCAP_BATTERY_STATE_PREVIOUS, CPCAP_BATTERY_STATE_LATEST, + CPCAP_BATTERY_STATE_EMPTY, + CPCAP_BATTERY_STATE_FULL, CPCAP_BATTERY_STATE_NR, }; @@ -166,6 +168,18 @@ cpcap_battery_previous(struct cpcap_battery_ddata *ddata) return cpcap_battery_get_state(ddata, CPCAP_BATTERY_STATE_PREVIOUS); } +static struct cpcap_battery_state_data * +cpcap_battery_get_empty(struct cpcap_battery_ddata *ddata) +{ + return cpcap_battery_get_state(ddata, CPCAP_BATTERY_STATE_EMPTY); +} + +static struct cpcap_battery_state_data * +cpcap_battery_get_full(struct cpcap_battery_ddata *ddata) +{ + return cpcap_battery_get_state(ddata, CPCAP_BATTERY_STATE_FULL); +} + static int cpcap_charger_battery_temperature(struct cpcap_battery_ddata *ddata, int *value) { @@ -431,9 +445,23 @@ static bool cpcap_battery_full(struct cpcap_battery_ddata *ddata) return ddata->is_full; } +static bool cpcap_battery_low(struct cpcap_battery_ddata *ddata) +{ + struct cpcap_battery_state_data *state = cpcap_battery_latest(ddata); + static bool is_low; + + if (state->current_ua > 0 && (state->voltage <= 3350000 || is_low)) + is_low = true; + else + is_low = false; + + return is_low; +} + static int cpcap_battery_update_status(struct cpcap_battery_ddata *ddata) { - struct cpcap_battery_state_data state, *latest, *previous; + struct cpcap_battery_state_data state, *latest, *previous, + *empty, *full; ktime_t now; int error; @@ -462,6 +490,32 @@ static int cpcap_battery_update_status(struct cpcap_battery_ddata *ddata) memcpy(previous, latest, sizeof(*previous)); memcpy(latest, &state, sizeof(*latest)); + if (cpcap_battery_full(ddata)) { + full = cpcap_battery_get_full(ddata); + memcpy(full, latest, sizeof(*full)); + + empty = cpcap_battery_get_empty(ddata); + if (empty->voltage && empty->voltage != -1) { + empty->voltage = -1; + ddata->charge_full = + empty->counter_uah - full->counter_uah; + } else if (ddata->charge_full) { + empty->voltage = -1; + empty->counter_uah = + full->counter_uah + ddata->charge_full; + } + } else if (cpcap_battery_low(ddata)) { + empty = cpcap_battery_get_empty(ddata); + memcpy(empty, latest, sizeof(*empty)); + + full = cpcap_battery_get_full(ddata); + if (full->voltage) { + full->voltage = 0; + ddata->charge_full = + empty->counter_uah - full->counter_uah; + } + } + return 0; } From patchwork Sun Jan 10 19:54:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Lindgren X-Patchwork-Id: 360290 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 78FD2C432C3 for ; Sun, 10 Jan 2021 19:55:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4688122A84 for ; Sun, 10 Jan 2021 19:55:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726787AbhAJTzh (ORCPT ); Sun, 10 Jan 2021 14:55:37 -0500 Received: from muru.com ([72.249.23.125]:42516 "EHLO muru.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726841AbhAJTzg (ORCPT ); Sun, 10 Jan 2021 14:55:36 -0500 Received: from hillo.muru.com (localhost [127.0.0.1]) by muru.com (Postfix) with ESMTP id 39B608931; Sun, 10 Jan 2021 19:54:31 +0000 (UTC) From: Tony Lindgren To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, linux-omap@vger.kernel.org, Arthur Demchenkov , Carl Philipp Klemm , Merlijn Wajer , Pavel Machek Subject: [PATCH 13/15] power: supply: cpcap-battery: Implement capacity reporting Date: Sun, 10 Jan 2021 21:54:01 +0200 Message-Id: <20210110195403.13758-14-tony@atomide.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210110195403.13758-1-tony@atomide.com> References: <20210110195403.13758-1-tony@atomide.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org From: Arthur Demchenkov Calculate percentage using charge_full value provided. Cc: Arthur Demchenkov Cc: Carl Philipp Klemm Cc: Merlijn Wajer Cc: Pavel Machek Signed-off-by: Arthur Demchenkov [tony@atomide.com: updated to apply after dropping my earlier patch] Signed-off-by: Tony Lindgren --- drivers/power/supply/cpcap-battery.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c --- a/drivers/power/supply/cpcap-battery.c +++ b/drivers/power/supply/cpcap-battery.c @@ -546,6 +546,7 @@ static enum power_supply_property cpcap_battery_props[] = { POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_POWER_NOW, POWER_SUPPLY_PROP_POWER_AVG, + POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_CAPACITY_LEVEL, POWER_SUPPLY_PROP_SCOPE, POWER_SUPPLY_PROP_TEMP, @@ -556,7 +557,7 @@ static int cpcap_battery_get_property(struct power_supply *psy, union power_supply_propval *val) { struct cpcap_battery_ddata *ddata = power_supply_get_drvdata(psy); - struct cpcap_battery_state_data *latest, *previous; + struct cpcap_battery_state_data *latest, *previous, *empty; u32 sample; s32 accumulator; int cached; @@ -636,6 +637,16 @@ static int cpcap_battery_get_property(struct power_supply *psy, tmp *= ((latest->voltage + previous->voltage) / 20000); val->intval = div64_s64(tmp, 100); break; + case POWER_SUPPLY_PROP_CAPACITY: + empty = cpcap_battery_get_empty(ddata); + if (!empty->voltage || !ddata->charge_full) + return -ENODATA; + /* (ddata->charge_full / 200) is needed for rounding */ + val->intval = empty->counter_uah - latest->counter_uah + + ddata->charge_full / 200; + val->intval = clamp(val->intval, 0, ddata->charge_full); + val->intval = val->intval * 100 / ddata->charge_full; + break; case POWER_SUPPLY_PROP_CAPACITY_LEVEL: if (cpcap_battery_full(ddata)) val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;