From patchwork Thu Nov 18 02:17:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625861 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3ED2DC433F5 for ; Thu, 18 Nov 2021 02:20:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1758861AD0 for ; Thu, 18 Nov 2021 02:20:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241540AbhKRCXA (ORCPT ); Wed, 17 Nov 2021 21:23:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49188 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239811AbhKRCXA (ORCPT ); Wed, 17 Nov 2021 21:23:00 -0500 Received: from mail-lf1-x132.google.com (mail-lf1-x132.google.com [IPv6:2a00:1450:4864:20::132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 96DEFC061570 for ; Wed, 17 Nov 2021 18:20:00 -0800 (PST) Received: by mail-lf1-x132.google.com with SMTP id l22so17861426lfg.7 for ; Wed, 17 Nov 2021 18:20:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=zda0K2UMyoMlsVgagYC4KRWRpPt+lh6+DFsbQjoyUtM=; b=xcDsjqVo6QNiYtkTRQZIfe758goQeOhLyFQvNYVkbwMwgKpEk5823KabCJIsVxZDbi 5yLioWl3WwGt23NJfS1BXfGhJwCrmFqtAs8R0puhL8gR+q9Nh6UnNyeaXeY4cMWzkIzG dTBGzVv4LxtZFCGN1DgcG9kTjzJBzt6t0tCPvgZXIksu/dEy/Y2Zf4+rplNZCHFEsqnJ UM/GX4yTw2SmQLMSky2bihuEQqE5P3vuG+/UNNNd8KBHm9w5rkw6381J4aWgBtlB5MuQ qsM/NFfCjmKRiulKMBrHfa3MyOzjjvkwGPCemhmxxE8XyMsEQGwU6Jyd0RwZVATHarVw qdmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zda0K2UMyoMlsVgagYC4KRWRpPt+lh6+DFsbQjoyUtM=; b=3/Kl6U2VMfW1SYYRXV+7mZV22FZ/+/fzfzsRFrYT5GYGZwVs9vMGoWFB5ev1jd/xX0 m88D08mIU1ggRNmig5aZOIqBAvx9XWNFbQiXXFA6zdCWE0OoabJvqazU8voK7PKODaI5 O8uyM0kl6Jnqa+ODG807UoAGMh3xbVyfEEtnVhnhFAQb+UmNjR0XmPAHfA7ggranBPOU sYyOJIdc6Pdag7rmM000NDnYQ6A9ONOkezegighqe4PGM2oD492clU4H9xjMgFjjPwoW NIKaMEfntflOuN91/Wo0GsoK8YXhfv6k5RB/nS4F9rYytTaMorDQyQpbQJsgtB8waupF 1iTQ== X-Gm-Message-State: AOAM531LS3IZ3Y/qtwD4eSoyi9+/VVAkVu6wyo2SDDLAPo416V3D7TxH tt76UWB4Yk3cOU9hl3VerKj0VQ== X-Google-Smtp-Source: ABdhPJxPtYmRbQtgLTWtI68ukaAd4+oTNouLt+7cCLmzHIER+47E3PpJ5QJjC2UgozJSkO0/HoFixg== X-Received: by 2002:a05:651c:179d:: with SMTP id bn29mr13303339ljb.525.1637201998900; Wed, 17 Nov 2021 18:19:58 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.19.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:19:57 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 01/16] power: supply: ab8500: Use core battery parser Date: Thu, 18 Nov 2021 03:17:37 +0100 Message-Id: <20211118021752.2262818-2-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org This deploys the core battery DT parser to read the basic properties of the battery. We only use very little of it as we start out, but we will improve as we go along. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500-bm.h | 3 +-- drivers/power/supply/ab8500_bmdata.c | 31 ++++++++++----------------- drivers/power/supply/ab8500_charger.c | 17 ++++++++++----- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index d11405b7ee1a..33c7e15f5d96 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -570,8 +570,7 @@ int ab8500_fg_inst_curr_start(struct ab8500_fg *di); int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res); int ab8500_fg_inst_curr_started(struct ab8500_fg *di); int ab8500_fg_inst_curr_done(struct ab8500_fg *di); -int ab8500_bm_of_probe(struct device *dev, - struct device_node *np, +int ab8500_bm_of_probe(struct power_supply *psy, struct ab8500_bm_data *bm); extern struct platform_driver ab8500_fg_driver; diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index bfc1245d7912..d2a9e890c64c 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -488,29 +488,22 @@ struct ab8500_bm_data ab8500_bm_data = { .n_chg_in_curr = ARRAY_SIZE(ab8500_charge_input_curr_map), }; -int ab8500_bm_of_probe(struct device *dev, - struct device_node *np, +int ab8500_bm_of_probe(struct power_supply *psy, struct ab8500_bm_data *bm) { const struct batres_vs_temp *tmp_batres_tbl; - struct device_node *battery_node; - const char *btech; + struct power_supply_battery_info info; + struct device *dev = &psy->dev; + int ret; int i; - battery_node = of_parse_phandle(np, "monitored-battery", 0); - if (!battery_node) { - dev_err(dev, "battery node or reference missing\n"); - return -EINVAL; + ret = power_supply_get_battery_info(psy, &info); + if (ret) { + dev_err(dev, "cannot retrieve battery info\n"); + return ret; } - btech = of_get_property(battery_node, "stericsson,battery-type", NULL); - if (!btech) { - dev_warn(dev, "missing property battery-name/type\n"); - of_node_put(battery_node); - return -EINVAL; - } - - if (strncmp(btech, "LION", 4) == 0) { + if (info.technology == POWER_SUPPLY_TECHNOLOGY_LION) { bm->no_maintenance = true; bm->chg_unknown_bat = true; bm->bat_type[BATTERY_UNKNOWN].charge_full_design = 2600; @@ -520,8 +513,8 @@ int ab8500_bm_of_probe(struct device *dev, bm->bat_type[BATTERY_UNKNOWN].normal_vol_lvl = 4200; } - if (of_property_read_bool(battery_node, "thermistor-on-batctrl")) { - if (strncmp(btech, "LION", 4) == 0) + if (of_property_read_bool(psy->of_node, "thermistor-on-batctrl")) { + if (info.technology == POWER_SUPPLY_TECHNOLOGY_LION) tmp_batres_tbl = temp_to_batres_tbl_9100; else tmp_batres_tbl = temp_to_batres_tbl_thermistor; @@ -536,7 +529,5 @@ int ab8500_bm_of_probe(struct device *dev, for (i = 0; i < bm->n_btypes; ++i) bm->bat_type[i].batres_tbl = tmp_batres_tbl; - of_node_put(battery_node); - return 0; } diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c index 15eadaf46f14..dd25bb5c498c 100644 --- a/drivers/power/supply/ab8500_charger.c +++ b/drivers/power/supply/ab8500_charger.c @@ -3413,11 +3413,6 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->bm = &ab8500_bm_data; - ret = ab8500_bm_of_probe(dev, np, di->bm); - if (ret) { - dev_err(dev, "failed to get battery information\n"); - return ret; - } di->autopower_cfg = of_property_read_bool(np, "autopower_cfg"); /* get parent data */ @@ -3490,9 +3485,11 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->invalid_charger_detect_state = 0; /* AC and USB supply config */ + ac_psy_cfg.of_node = np; ac_psy_cfg.supplied_to = supply_interface; ac_psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface); ac_psy_cfg.drv_data = &di->ac_chg; + usb_psy_cfg.of_node = np; usb_psy_cfg.supplied_to = supply_interface; usb_psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface); usb_psy_cfg.drv_data = &di->usb_chg; @@ -3610,6 +3607,16 @@ static int ab8500_charger_probe(struct platform_device *pdev) return PTR_ERR(di->usb_chg.psy); } + /* + * Check what battery we have, since we always have the USB + * psy, use that as a handle. + */ + ret = ab8500_bm_of_probe(di->usb_chg.psy, di->bm); + if (ret) { + dev_err(dev, "failed to get battery information\n"); + return ret; + } + /* Identify the connected charger types during startup */ charger_status = ab8500_charger_detect_chargers(di, true); if (charger_status & AC_PW_CONN) { From patchwork Thu Nov 18 02:17:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625863 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 795DEC433EF for ; Thu, 18 Nov 2021 02:20:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5F83261ABF for ; Thu, 18 Nov 2021 02:20:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241549AbhKRCXC (ORCPT ); Wed, 17 Nov 2021 21:23:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49200 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239811AbhKRCXC (ORCPT ); Wed, 17 Nov 2021 21:23:02 -0500 Received: from mail-lf1-x130.google.com (mail-lf1-x130.google.com [IPv6:2a00:1450:4864:20::130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DB843C061570 for ; Wed, 17 Nov 2021 18:20:02 -0800 (PST) Received: by mail-lf1-x130.google.com with SMTP id t26so17984606lfk.9 for ; Wed, 17 Nov 2021 18:20:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=zg8k9jCM2vR617ygR1YWlkDPKM5+fi6g2DTBUXSpl+E=; b=e9r/TLsBFOOE1RZAdy5pmMVIxh9mhCr3J34N7gkxIKzAUezxmfSKNeo6wjQ2eJZyZ6 iJeONOkHVtui0HVkCr5yjLFiH7G4cA0X8XlpUMuH+fCa8ejRi7Wv1gxaQ601cNu47wKk p4X7HqiiGRIGFJA92sC6UA/zByR6IR92+ksehDgSL771f1uZeh9qjhH1wuFlFTQKWoAm 2a1AtawzUTFl+7unAkllhK5nEQK2clIVeVHq5TjkhGc0OYfNAELKUlTDHhnj2gTb3D2g 1BhY+sBPsDrMfJIBceBKfSzb1c64ICK5YP6OevE1+13kQeTHiGAYI0z/1OcLm1tNOhmj iRvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zg8k9jCM2vR617ygR1YWlkDPKM5+fi6g2DTBUXSpl+E=; b=Q2qlANqFACIKMIJjxs/e1heLiFdSzJiwzA7TJZ1ED0iDVUB8Mg2fGbjdQqz+6Y5IGy 7gEAsZLx+bud4FdfCyzwxneirli0EKBHVwj0J3wk44nDcgkm3mqdVqe+33HV9FOLuWnm wsfcd134GNmnlq8yVNmeS0AtX19vTqc7ZA1P9wLHX3hhQvu27l7gmuKr/y4N5W25QSN5 pB7cBypQYmJi63aOXmNbazK04S8m9TdqkQET44Zy1jqmCwyKnm7qRpDGaelVmyuyNPPK mZtXkNWLha5YtMqX0QmreDTiL/wmlARiJoiCe66BlLZ/5F9dzBc30qt6HLXct1g18FUJ Y0gQ== X-Gm-Message-State: AOAM532ssicvkAtfDhhvGqS+82dSiE253fZTu9weqJsDATXsQEfOks9+ Bp0kw1WeFp3Rz/16f8ByTQBhow== X-Google-Smtp-Source: ABdhPJzla/uX0m2nilgyf5oVrS8EleDsvVIvvogLoO45F658L10cdlPMC4GxkfhOlYcTF5Fe1J/wAA== X-Received: by 2002:a2e:9654:: with SMTP id z20mr12933906ljh.254.1637202001140; Wed, 17 Nov 2021 18:20:01 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.19.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:00 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 02/16] power: supply: ab8500: Sink current tables into charger code Date: Thu, 18 Nov 2021 03:17:38 +0100 Message-Id: <20211118021752.2262818-3-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The two tables for input and output current translation from register values does not need to be passed around from the battery manager data. Just push it down into the charger code where it is used, like other tables in that code. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500-bm.h | 8 ------ drivers/power/supply/ab8500_bmdata.c | 22 ---------------- drivers/power/supply/ab8500_charger.c | 38 ++++++++++++++++++--------- 3 files changed, 25 insertions(+), 43 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index 33c7e15f5d96..bcb054810290 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -484,10 +484,6 @@ struct ab8500_bm_charger_parameters { * @interval_not_charging charge alg cycle period time when not charging (sec) * @temp_hysteresis temperature hysteresis * @gnd_lift_resistance Battery ground to phone ground resistance (mOhm) - * @n_chg_out_curr number of elements in array chg_output_curr - * @n_chg_in_curr number of elements in array chg_input_curr - * @chg_output_curr charger output current level map - * @chg_input_curr charger input current level map * @maxi maximization parameters * @cap_levels capacity in percent for the different capacity levels * @bat_type table of supported battery types @@ -519,10 +515,6 @@ struct ab8500_bm_data { int interval_not_charging; int temp_hysteresis; int gnd_lift_resistance; - int n_chg_out_curr; - int n_chg_in_curr; - int *chg_output_curr; - int *chg_input_curr; const struct ab8500_maxim_parameters *maxi; const struct ab8500_bm_capacity_levels *cap_levels; struct ab8500_battery_type *bat_type; diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index d2a9e890c64c..b86a88f4f4d2 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -436,24 +436,6 @@ static const struct ab8500_bm_charger_parameters chg = { .ac_curr_max = 1500, }; -/* - * This array maps the raw hex value to charger output current used by the - * AB8500 values - */ -static int ab8500_charge_output_curr_map[] = { - 100, 200, 300, 400, 500, 600, 700, 800, - 900, 1000, 1100, 1200, 1300, 1400, 1500, 1500, -}; - -/* - * This array maps the raw hex value to charger input current used by the - * AB8500 values - */ -static int ab8500_charge_input_curr_map[] = { - 50, 98, 193, 290, 380, 450, 500, 600, - 700, 800, 900, 1000, 1100, 1300, 1400, 1500, -}; - struct ab8500_bm_data ab8500_bm_data = { .temp_under = 3, .temp_low = 8, @@ -479,13 +461,9 @@ struct ab8500_bm_data ab8500_bm_data = { .interval_not_charging = 120, .temp_hysteresis = 3, .gnd_lift_resistance = 34, - .chg_output_curr = ab8500_charge_output_curr_map, - .n_chg_out_curr = ARRAY_SIZE(ab8500_charge_output_curr_map), .maxi = &ab8500_maxi_params, .chg_params = &chg, .fg_params = &fg, - .chg_input_curr = ab8500_charge_input_curr_map, - .n_chg_in_curr = ARRAY_SIZE(ab8500_charge_input_curr_map), }; int ab8500_bm_of_probe(struct power_supply *psy, diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c index dd25bb5c498c..86f237dea44d 100644 --- a/drivers/power/supply/ab8500_charger.c +++ b/drivers/power/supply/ab8500_charger.c @@ -1025,21 +1025,33 @@ static int ab8500_voltage_to_regval(int voltage) return -1; } +/* This array maps the raw register value to charger input current */ +static int ab8500_charge_input_curr_map[] = { + 50, 98, 193, 290, 380, 450, 500, 600, + 700, 800, 900, 1000, 1100, 1300, 1400, 1500, +}; + +/* This array maps the raw register value to charger output current */ +static int ab8500_charge_output_curr_map[] = { + 100, 200, 300, 400, 500, 600, 700, 800, + 900, 1000, 1100, 1200, 1300, 1400, 1500, 1500, +}; + static int ab8500_current_to_regval(struct ab8500_charger *di, int curr) { int i; - if (curr < di->bm->chg_output_curr[0]) + if (curr < ab8500_charge_output_curr_map[0]) return 0; - for (i = 0; i < di->bm->n_chg_out_curr; i++) { - if (curr < di->bm->chg_output_curr[i]) + for (i = 0; i < ARRAY_SIZE(ab8500_charge_output_curr_map); i++) { + if (curr < ab8500_charge_output_curr_map[i]) return i - 1; } /* If not last element, return error */ - i = di->bm->n_chg_out_curr - 1; - if (curr == di->bm->chg_output_curr[i]) + i = ARRAY_SIZE(ab8500_charge_output_curr_map) - 1; + if (curr == ab8500_charge_output_curr_map[i]) return i; else return -1; @@ -1049,17 +1061,17 @@ static int ab8500_vbus_in_curr_to_regval(struct ab8500_charger *di, int curr) { int i; - if (curr < di->bm->chg_input_curr[0]) + if (curr < ab8500_charge_input_curr_map[0]) return 0; - for (i = 0; i < di->bm->n_chg_in_curr; i++) { - if (curr < di->bm->chg_input_curr[i]) + for (i = 0; i < ARRAY_SIZE(ab8500_charge_input_curr_map); i++) { + if (curr < ab8500_charge_input_curr_map[i]) return i - 1; } /* If not last element, return error */ - i = di->bm->n_chg_in_curr - 1; - if (curr == di->bm->chg_input_curr[i]) + i = ARRAY_SIZE(ab8500_charge_input_curr_map) - 1; + if (curr == ab8500_charge_input_curr_map[i]) return i; else return -1; @@ -2673,7 +2685,7 @@ static void ab8500_charger_vbus_drop_end_work(struct work_struct *work) return; } - curr = di->bm->chg_input_curr[ + curr = ab8500_charge_input_curr_map[ reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT]; if (di->max_usb_in_curr.calculated_max != curr) { @@ -3503,7 +3515,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->ac_chg.max_out_volt = ab8500_charger_voltage_map[ ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; di->ac_chg.max_out_curr = - di->bm->chg_output_curr[di->bm->n_chg_out_curr - 1]; + ab8500_charge_output_curr_map[ARRAY_SIZE(ab8500_charge_output_curr_map) - 1]; di->ac_chg.wdt_refresh = CHG_WD_INTERVAL; /* * The AB8505 only supports USB charging. If we are not the @@ -3524,7 +3536,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->usb_chg.max_out_volt = ab8500_charger_voltage_map[ ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; di->usb_chg.max_out_curr = - di->bm->chg_output_curr[di->bm->n_chg_out_curr - 1]; + ab8500_charge_output_curr_map[ARRAY_SIZE(ab8500_charge_output_curr_map) - 1]; di->usb_chg.wdt_refresh = CHG_WD_INTERVAL; di->usb_chg.external = false; di->usb_state.usb_current = -1; From patchwork Thu Nov 18 02:17:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625865 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE607C433EF for ; Thu, 18 Nov 2021 02:20:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C6D31610D0 for ; Thu, 18 Nov 2021 02:20:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242450AbhKRCXH (ORCPT ); Wed, 17 Nov 2021 21:23:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49208 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239811AbhKRCXE (ORCPT ); Wed, 17 Nov 2021 21:23:04 -0500 Received: from mail-lf1-x136.google.com (mail-lf1-x136.google.com [IPv6:2a00:1450:4864:20::136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2F09FC061570 for ; Wed, 17 Nov 2021 18:20:05 -0800 (PST) Received: by mail-lf1-x136.google.com with SMTP id b1so17820407lfs.13 for ; Wed, 17 Nov 2021 18:20:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=W5jAcQ6nyZV6u4Lu1u9FXPSWCE9PAnr97jNCaPUqlNk=; b=lX+l+kAM9fLP95Z+6ZXFlF24jT/bu+15RScSZ01YbLXqLk3Aj7KDXib0B8Kzd9fbIW hJic4myXnbnjNsDHaS0ctKIn2dZmp1iTxvWM2d2w4eDMeegIKOjUXDdx+UyulLQba2Wq 0l7cfewrbBvLkmFXsQpDuv8jvsPwsjJURrQr0RpNZ8ql6JaxxFkefNhj/TsnNii+1mKB U/XkTqajrq97qQXq2wDbvtjMQvIV6nsse+QN9q4tfKRN5uoNVLWUR4c/Bwm1c/nSTl93 TkkiVaovTJCD4dliIqXAwczWug1DqV/+t+HB1te3C9bmktmGqth52kGKw2Z9Afr0i98l lvpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=W5jAcQ6nyZV6u4Lu1u9FXPSWCE9PAnr97jNCaPUqlNk=; b=ZwK6lhuhYlcKQfhhM3WzyU3hRIsmV5jj2jBC1t+xKsPQLXK4UTSjnNCbMSuTK1laVT iP/cRwx/UChl4e8GeoTgMuk0/pX4B1uPE9MOufqlAmfar39mNxNEEp5XzKp9BO5rcjDL bEiiOFqCAWMRA8pFEIl2RWyYvlj7dtMdiF2Uin2t3bvZhyfew8wDKIpK8P1oaO5v0car K5tDfPyxuIM952XNJ5At9Sq1f5Wyqu6eM+PylXrlIGtI6RHs6+jQvNFkL5vKrdYxNjH+ UYTY+l5OlNTBtYqYGzSfyLGU9ABV6eBsD84bmu0f+VOQmLsoJ7iusUyn+YvXq/qJd1O6 Rw5g== X-Gm-Message-State: AOAM533Wj6wuswdUNJlLMRjhzj9GI1E2WQgnKvLqnV0Wg/IjUqGF/Eka 2G2BtZIYn6pz6YOfEvs+X/CGFw== X-Google-Smtp-Source: ABdhPJy7kvJj4xjCvqqqOoXLRpzARhH0kzqwT6rWuolonIVKYMA6mnozJFaeLpIpvEbUsdLejGZF3w== X-Received: by 2002:a2e:b8cc:: with SMTP id s12mr12987255ljp.489.1637202003209; Wed, 17 Nov 2021 18:20:03 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.20.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:02 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 03/16] power: supply: ab8500: Standardize operating temperature Date: Thu, 18 Nov 2021 03:17:39 +0100 Message-Id: <20211118021752.2262818-4-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Instead of storing the temperature limits in our custom struct struct ab8500_bm_data, make struct power_supply_battery_info a member of this and store the min and max temperatures inside that struct as the temp_min/temp_max and temp_alert_min/temp_alert_max respectively. The values can be assigned from the device tree, but if not present will be set to the same defaults as are currently in the code. This way we start to move over to using struct power_supply_battery_info and make it possible to move the data over to the device tree and we will move piece by piece toward using the standard info struct. Temperature hysteresis is currently not supported by the standard struct but we move the assignment here as well so that we have all parameterization in one spot. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500-bm.h | 10 ++------ drivers/power/supply/ab8500_bmdata.c | 35 +++++++++++++++++++------- drivers/power/supply/ab8500_chargalg.c | 20 ++++++++------- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index bcb054810290..36bc28f1604f 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -460,10 +460,7 @@ struct ab8500_bm_charger_parameters { /** * struct ab8500_bm_data - ab8500 battery management data - * @temp_under under this temp, charging is stopped - * @temp_low between this temp and temp_under charging is reduced - * @temp_high between this temp and temp_over charging is reduced - * @temp_over over this temp, charging is stopped + * @bi battery info from device tree * @temp_now present battery temperature * @temp_interval_chg temperature measurement interval in s when charging * @temp_interval_nochg temperature measurement interval in s when not charging @@ -491,10 +488,7 @@ struct ab8500_bm_charger_parameters { * @fg_params fuel gauge parameters */ struct ab8500_bm_data { - int temp_under; - int temp_low; - int temp_high; - int temp_over; + struct power_supply_battery_info bi; int temp_now; int temp_interval_chg; int temp_interval_nochg; diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index b86a88f4f4d2..4ad4a66e7e37 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -5,6 +5,17 @@ #include "ab8500-bm.h" +/* Default: under this temperature, charging is stopped */ +#define AB8500_TEMP_UNDER 3 +/* Default: between this temp and AB8500_TEMP_UNDER charging is reduced */ +#define AB8500_TEMP_LOW 8 +/* Default: between this temp and AB8500_TEMP_OVER charging is reduced */ +#define AB8500_TEMP_HIGH 43 +/* Default: over this temp, charging is stopped */ +#define AB8500_TEMP_OVER 48 +/* Default: temperature hysteresis */ +#define AB8500_TEMP_HYSTERESIS 3 + /* * These are the defined batteries that uses a NTC and ID resistor placed * inside of the battery pack. @@ -437,10 +448,6 @@ static const struct ab8500_bm_charger_parameters chg = { }; struct ab8500_bm_data ab8500_bm_data = { - .temp_under = 3, - .temp_low = 8, - .temp_high = 43, - .temp_over = 48, .main_safety_tmr_h = 4, .temp_interval_chg = 20, .temp_interval_nochg = 120, @@ -459,7 +466,6 @@ struct ab8500_bm_data ab8500_bm_data = { .batt_id = 0, .interval_charging = 5, .interval_not_charging = 120, - .temp_hysteresis = 3, .gnd_lift_resistance = 34, .maxi = &ab8500_maxi_params, .chg_params = &chg, @@ -470,18 +476,29 @@ int ab8500_bm_of_probe(struct power_supply *psy, struct ab8500_bm_data *bm) { const struct batres_vs_temp *tmp_batres_tbl; - struct power_supply_battery_info info; + struct power_supply_battery_info *bi = &bm->bi; struct device *dev = &psy->dev; int ret; int i; - ret = power_supply_get_battery_info(psy, &info); + ret = power_supply_get_battery_info(psy, bi); if (ret) { dev_err(dev, "cannot retrieve battery info\n"); return ret; } - if (info.technology == POWER_SUPPLY_TECHNOLOGY_LION) { + if (bi->temp_min == INT_MIN) + bi->temp_min = AB8500_TEMP_UNDER; + if (bi->temp_max == INT_MAX) + bi->temp_max = AB8500_TEMP_OVER; + if (bi->temp_alert_min == INT_MIN) + bi->temp_alert_min = AB8500_TEMP_LOW; + if (bi->temp_alert_max == INT_MAX) + bi->temp_alert_max = AB8500_TEMP_HIGH; + bm->temp_hysteresis = AB8500_TEMP_HYSTERESIS; + + + if (bi->technology == POWER_SUPPLY_TECHNOLOGY_LION) { bm->no_maintenance = true; bm->chg_unknown_bat = true; bm->bat_type[BATTERY_UNKNOWN].charge_full_design = 2600; @@ -492,7 +509,7 @@ int ab8500_bm_of_probe(struct power_supply *psy, } if (of_property_read_bool(psy->of_node, "thermistor-on-batctrl")) { - if (info.technology == POWER_SUPPLY_TECHNOLOGY_LION) + if (bi->technology == POWER_SUPPLY_TECHNOLOGY_LION) tmp_batres_tbl = temp_to_batres_tbl_9100; else tmp_batres_tbl = temp_to_batres_tbl_thermistor; diff --git a/drivers/power/supply/ab8500_chargalg.c b/drivers/power/supply/ab8500_chargalg.c index ff4b26b1ceca..9196434393e8 100644 --- a/drivers/power/supply/ab8500_chargalg.c +++ b/drivers/power/supply/ab8500_chargalg.c @@ -722,27 +722,29 @@ static void ab8500_chargalg_start_charging(struct ab8500_chargalg *di, */ static void ab8500_chargalg_check_temp(struct ab8500_chargalg *di) { - if (di->batt_data.temp > (di->bm->temp_low + di->t_hyst_norm) && - di->batt_data.temp < (di->bm->temp_high - di->t_hyst_norm)) { + struct power_supply_battery_info *bi = &di->bm->bi; + + if (di->batt_data.temp > (bi->temp_alert_min + di->t_hyst_norm) && + di->batt_data.temp < (bi->temp_alert_max - di->t_hyst_norm)) { /* Temp OK! */ di->events.btemp_underover = false; di->events.btemp_lowhigh = false; di->t_hyst_norm = 0; di->t_hyst_lowhigh = 0; } else { - if (((di->batt_data.temp >= di->bm->temp_high) && + if (((di->batt_data.temp >= bi->temp_alert_max) && (di->batt_data.temp < - (di->bm->temp_over - di->t_hyst_lowhigh))) || + (bi->temp_max - di->t_hyst_lowhigh))) || ((di->batt_data.temp > - (di->bm->temp_under + di->t_hyst_lowhigh)) && - (di->batt_data.temp <= di->bm->temp_low))) { + (bi->temp_min + di->t_hyst_lowhigh)) && + (di->batt_data.temp <= bi->temp_alert_min))) { /* TEMP minor!!!!! */ di->events.btemp_underover = false; di->events.btemp_lowhigh = true; di->t_hyst_norm = di->bm->temp_hysteresis; di->t_hyst_lowhigh = 0; - } else if (di->batt_data.temp <= di->bm->temp_under || - di->batt_data.temp >= di->bm->temp_over) { + } else if (di->batt_data.temp <= bi->temp_min || + di->batt_data.temp >= bi->temp_max) { /* TEMP major!!!!! */ di->events.btemp_underover = true; di->events.btemp_lowhigh = false; @@ -1722,7 +1724,7 @@ static int ab8500_chargalg_get_property(struct power_supply *psy, if (di->events.batt_ovv) { val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; } else if (di->events.btemp_underover) { - if (di->batt_data.temp <= di->bm->temp_under) + if (di->batt_data.temp <= di->bm->bi.temp_min) val->intval = POWER_SUPPLY_HEALTH_COLD; else val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; From patchwork Thu Nov 18 02:17:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625867 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1B993C433FE for ; Thu, 18 Nov 2021 02:20:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 031F061AEC for ; Thu, 18 Nov 2021 02:20:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241556AbhKRCXI (ORCPT ); Wed, 17 Nov 2021 21:23:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49220 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241558AbhKRCXH (ORCPT ); Wed, 17 Nov 2021 21:23:07 -0500 Received: from mail-lf1-x133.google.com (mail-lf1-x133.google.com [IPv6:2a00:1450:4864:20::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1A68DC061764 for ; Wed, 17 Nov 2021 18:20:07 -0800 (PST) Received: by mail-lf1-x133.google.com with SMTP id c32so18130563lfv.4 for ; Wed, 17 Nov 2021 18:20:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=FGx8RfWOWMLiXdarIPjZSVIU9njZPRI9c50EcXVxfDM=; b=jt63639f+95GS0teYCAm+CZV6NHOciOqbSoTDJDSZGEMSzqZph0538wJQtMvQHd+Y4 Gk0j54TL7agiEZV+urwZALwbEvCOjEzNOp9F2OqpG9hf7By8QPoPdNxoEkFOQdll+A1h 7hVeopHynYdODTtHGrrNWS70P/WMjsKf3z4URiFdQcmqufeJLkT3xyz1IdE5HSaY/stM C0t7QIC3h9L4bgeRBFqqBzjP07abrEsGVUtSECN9Cu9cK4o+t+sCHVpwoadv8GBrFhci RmR0MHdmUlIKU3gD9zMO5WiXBIk9C93+G3bs+/swjrjgkqGAg9rmQlWs8jmualPs8xEC ygaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FGx8RfWOWMLiXdarIPjZSVIU9njZPRI9c50EcXVxfDM=; b=vVrHlTNo1ruOJdEuo+YoCiJZe4ltXO/QHV93J149Ek43zOwfdExuhR9zHldKMWeTXx x/WCSPaJ+y9ezCRctftv/u2nB8omc6vu9K3unuuPyUpNfhGFUPmqvkQAC7/UwEuiwFtx xx9Rlswybtyllgbr/Z/xI7IhztdrcUL2Yo9P4VlI6a1R47B6rLf6grjBcHI2TyBe9f4W fDDB0CzoNNvkXvVwU4UMzUUGVZojogV9mXIEaSrxPUZgHPtcWOgJHMKfR99doydkThFc yUIcX9IEi0SdMmbKwA+GZEYL78zJ9kbBWYM/z37ofPJ6A/qYt0IqPKJEMY4fk7QQFYzk GxOw== X-Gm-Message-State: AOAM531AjOkc7QgpvjEtcUN5JgPNEcQHvl/px0gLaeTHNoSg5Y30S7QB 1jBDOHUnUrkhQ1NfZM2vCMy4AQdnS9v5hA== X-Google-Smtp-Source: ABdhPJyoGrzgj0eKVZwj6c+bBEJNIQUFGVCjBg3kUbecUbnieekq4NhMy3/7eRmrFEGtneye8Ri1VQ== X-Received: by 2002:a2e:b5b7:: with SMTP id f23mr12324211ljn.244.1637202005425; Wed, 17 Nov 2021 18:20:05 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.20.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:04 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 04/16] power: supply: ab8500: Drop unused battery types Date: Thu, 18 Nov 2021 03:17:40 +0100 Message-Id: <20211118021752.2262818-5-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The code tries to detect a lot of battery variants on the reference designs, but we are not using the reference designs in practice, we are using real products such as Samsung Phones. The reference design with no battery plugged in will be detected as a LIPO battery with a thermistor on the batctrl pin so we will assume this and later on we can support other types through the device tree if we want, just like the products do. Drop the tables for external thermistor, only keep the internal thermistor tables that we will use as default. We can delete the assignment of the temperature to resistance table since the default will be the only and correct option. Also get rid of some unused variables and unused exports. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500_bmdata.c | 180 +-------------------------- 1 file changed, 1 insertion(+), 179 deletions(-) diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index 4ad4a66e7e37..bd651602fd69 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -39,10 +39,6 @@ const struct ab8500_res_to_temp ab8500_temp_tbl_a_thermistor[] = { {60, 13437}, {65, 12500}, }; -EXPORT_SYMBOL(ab8500_temp_tbl_a_thermistor); - -const int ab8500_temp_tbl_a_size = ARRAY_SIZE(ab8500_temp_tbl_a_thermistor); -EXPORT_SYMBOL(ab8500_temp_tbl_a_size); const struct ab8500_res_to_temp ab8500_temp_tbl_b_thermistor[] = { {-5, 200000}, @@ -61,10 +57,6 @@ const struct ab8500_res_to_temp ab8500_temp_tbl_b_thermistor[] = { {60, 85461}, {65, 82869}, }; -EXPORT_SYMBOL(ab8500_temp_tbl_b_thermistor); - -const int ab8500_temp_tbl_b_size = ARRAY_SIZE(ab8500_temp_tbl_b_thermistor); -EXPORT_SYMBOL(ab8500_temp_tbl_b_size); static const struct ab8500_v_to_cap cap_tbl_a_thermistor[] = { {4171, 100}, @@ -175,31 +167,6 @@ static const struct batres_vs_temp temp_to_batres_tbl_thermistor[] = { {-20, 595}, }; -/* - * Note that the batres_vs_temp table must be strictly sorted by falling - * temperature values to work. - */ -static const struct batres_vs_temp temp_to_batres_tbl_ext_thermistor[] = { - { 60, 300}, - { 30, 300}, - { 20, 300}, - { 10, 300}, - { 00, 300}, - {-10, 300}, - {-20, 300}, -}; - -/* battery resistance table for LI ION 9100 battery */ -static const struct batres_vs_temp temp_to_batres_tbl_9100[] = { - { 60, 180}, - { 30, 180}, - { 20, 180}, - { 10, 180}, - { 00, 180}, - {-10, 180}, - {-20, 180}, -}; - static struct ab8500_battery_type bat_type_thermistor[] = { [BATTERY_UNKNOWN] = { /* First element always represent the UNKNOWN battery */ @@ -286,123 +253,6 @@ static struct ab8500_battery_type bat_type_thermistor[] = { }, }; -static struct ab8500_battery_type bat_type_ext_thermistor[] = { - [BATTERY_UNKNOWN] = { - /* First element always represent the UNKNOWN battery */ - .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN, - .resis_high = 0, - .resis_low = 0, - .battery_resistance = 300, - .charge_full_design = 612, - .nominal_voltage = 3700, - .termination_vol = 4050, - .termination_curr = 200, - .recharge_cap = 95, - .normal_cur_lvl = 400, - .normal_vol_lvl = 4100, - .maint_a_cur_lvl = 400, - .maint_a_vol_lvl = 4050, - .maint_a_chg_timer_h = 60, - .maint_b_cur_lvl = 400, - .maint_b_vol_lvl = 4000, - .maint_b_chg_timer_h = 200, - .low_high_cur_lvl = 300, - .low_high_vol_lvl = 4000, - .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), - .r_to_t_tbl = temp_tbl, - .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), - .v_to_cap_tbl = cap_tbl, - .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), - .batres_tbl = temp_to_batres_tbl_thermistor, - }, -/* - * These are the batteries that doesn't have an internal NTC resistor to measure - * its temperature. The temperature in this case is measure with a NTC placed - * near the battery but on the PCB. - */ - { - .name = POWER_SUPPLY_TECHNOLOGY_LIPO, - .resis_high = 76000, - .resis_low = 53000, - .battery_resistance = 300, - .charge_full_design = 900, - .nominal_voltage = 3700, - .termination_vol = 4150, - .termination_curr = 100, - .recharge_cap = 95, - .normal_cur_lvl = 700, - .normal_vol_lvl = 4200, - .maint_a_cur_lvl = 600, - .maint_a_vol_lvl = 4150, - .maint_a_chg_timer_h = 60, - .maint_b_cur_lvl = 600, - .maint_b_vol_lvl = 4100, - .maint_b_chg_timer_h = 200, - .low_high_cur_lvl = 300, - .low_high_vol_lvl = 4000, - .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), - .r_to_t_tbl = temp_tbl, - .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), - .v_to_cap_tbl = cap_tbl, - .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), - .batres_tbl = temp_to_batres_tbl_thermistor, - }, - { - .name = POWER_SUPPLY_TECHNOLOGY_LION, - .resis_high = 30000, - .resis_low = 10000, - .battery_resistance = 300, - .charge_full_design = 950, - .nominal_voltage = 3700, - .termination_vol = 4150, - .termination_curr = 100, - .recharge_cap = 95, - .normal_cur_lvl = 700, - .normal_vol_lvl = 4200, - .maint_a_cur_lvl = 600, - .maint_a_vol_lvl = 4150, - .maint_a_chg_timer_h = 60, - .maint_b_cur_lvl = 600, - .maint_b_vol_lvl = 4100, - .maint_b_chg_timer_h = 200, - .low_high_cur_lvl = 300, - .low_high_vol_lvl = 4000, - .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), - .r_to_t_tbl = temp_tbl, - .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), - .v_to_cap_tbl = cap_tbl, - .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), - .batres_tbl = temp_to_batres_tbl_thermistor, - }, - { - .name = POWER_SUPPLY_TECHNOLOGY_LION, - .resis_high = 95000, - .resis_low = 76001, - .battery_resistance = 300, - .charge_full_design = 950, - .nominal_voltage = 3700, - .termination_vol = 4150, - .termination_curr = 100, - .recharge_cap = 95, - .normal_cur_lvl = 700, - .normal_vol_lvl = 4200, - .maint_a_cur_lvl = 600, - .maint_a_vol_lvl = 4150, - .maint_a_chg_timer_h = 60, - .maint_b_cur_lvl = 600, - .maint_b_vol_lvl = 4100, - .maint_b_chg_timer_h = 200, - .low_high_cur_lvl = 300, - .low_high_vol_lvl = 4000, - .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), - .r_to_t_tbl = temp_tbl, - .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), - .v_to_cap_tbl = cap_tbl, - .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), - .batres_tbl = temp_to_batres_tbl_thermistor, - }, -}; - static const struct ab8500_bm_capacity_levels cap_levels = { .critical = 2, .low = 10, @@ -447,6 +297,7 @@ static const struct ab8500_bm_charger_parameters chg = { .ac_curr_max = 1500, }; +/* This is referenced directly in the charger code */ struct ab8500_bm_data ab8500_bm_data = { .main_safety_tmr_h = 4, .temp_interval_chg = 20, @@ -475,11 +326,9 @@ struct ab8500_bm_data ab8500_bm_data = { int ab8500_bm_of_probe(struct power_supply *psy, struct ab8500_bm_data *bm) { - const struct batres_vs_temp *tmp_batres_tbl; struct power_supply_battery_info *bi = &bm->bi; struct device *dev = &psy->dev; int ret; - int i; ret = power_supply_get_battery_info(psy, bi); if (ret) { @@ -497,32 +346,5 @@ int ab8500_bm_of_probe(struct power_supply *psy, bi->temp_alert_max = AB8500_TEMP_HIGH; bm->temp_hysteresis = AB8500_TEMP_HYSTERESIS; - - if (bi->technology == POWER_SUPPLY_TECHNOLOGY_LION) { - bm->no_maintenance = true; - bm->chg_unknown_bat = true; - bm->bat_type[BATTERY_UNKNOWN].charge_full_design = 2600; - bm->bat_type[BATTERY_UNKNOWN].termination_vol = 4150; - bm->bat_type[BATTERY_UNKNOWN].recharge_cap = 95; - bm->bat_type[BATTERY_UNKNOWN].normal_cur_lvl = 520; - bm->bat_type[BATTERY_UNKNOWN].normal_vol_lvl = 4200; - } - - if (of_property_read_bool(psy->of_node, "thermistor-on-batctrl")) { - if (bi->technology == POWER_SUPPLY_TECHNOLOGY_LION) - tmp_batres_tbl = temp_to_batres_tbl_9100; - else - tmp_batres_tbl = temp_to_batres_tbl_thermistor; - } else { - bm->n_btypes = 4; - bm->bat_type = bat_type_ext_thermistor; - bm->adc_therm = AB8500_ADC_THERM_BATTEMP; - tmp_batres_tbl = temp_to_batres_tbl_ext_thermistor; - } - - /* select the battery resolution table */ - for (i = 0; i < bm->n_btypes; ++i) - bm->bat_type[i].batres_tbl = tmp_batres_tbl; - return 0; } From patchwork Thu Nov 18 02:17:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625869 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 519D0C433F5 for ; Thu, 18 Nov 2021 02:20:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3699761ABF for ; Thu, 18 Nov 2021 02:20:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241558AbhKRCXM (ORCPT ); Wed, 17 Nov 2021 21:23:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49232 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242492AbhKRCXJ (ORCPT ); Wed, 17 Nov 2021 21:23:09 -0500 Received: from mail-lf1-x12b.google.com (mail-lf1-x12b.google.com [IPv6:2a00:1450:4864:20::12b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C3D89C061570 for ; Wed, 17 Nov 2021 18:20:09 -0800 (PST) Received: by mail-lf1-x12b.google.com with SMTP id bu18so18297442lfb.0 for ; Wed, 17 Nov 2021 18:20:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RTCwYoReSIxdfChw8M+tf14CrRHRRZkyAoA8XAE749E=; b=uou9ALJJgDypTwJx+3lLWehttK8A4g3dB+wGd2dC2Q7qfuUpdGqhqShwBjT4u6tG1C TjNge4l1f1jVfFpgI3VhdGiHDdkBUh/pkqGExMl8yE80O9QUCAWarlR0psEF0lZZnNQ2 zdaB+wclTZsyXXNJ0Yayqqkj4Mus1NIQgAAktuhDGKQH8tiu9ju70fiR/3nQhFwVs5u8 ONZXdSMAP8WZYVtCBQ7O2+Tn+s/4mU/l28CnNxgbpDa6JIf2W2AtT6WKKDQCWOlML5Np MlC++ULv2SlQ7DiP7jf3OVqee3nSug703+bcr0hmHEOhnM+nItFf7xGe2gRcvo2mSufI kw8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RTCwYoReSIxdfChw8M+tf14CrRHRRZkyAoA8XAE749E=; b=71H/rfwkS4oWKPehTbuKlRlTZ0kuTNYLVYlaO043otoUoGVU6dc36YRvpq6zBsSZ/p p0BK9EObXKd0k1l+4AR7dMpRGH/ASqQRZVB8cWRTbBc7cYBJCR7IsfWqQjsx6+tCFGH0 Db+D2flRgk1mgtExoZlEEuu7l708UY+P2gy1Vs/SoLRclu+aP1Sp7zb2GgKXxijTTJ5b R0kelFtywMcFX1dOBIHNO14Ss5QgUCoqYnOQ3GDhozKbnGC+1uTdkcFN6Zpo01PtJFLS GlpACrZRFgsC9BJdYy8Avj2o78baaSRQA+xIxskuHGJvsAvcs1KPAItPm9N2HYSIXiz6 2JWg== X-Gm-Message-State: AOAM530qhHa5JWUZ+F6i3a90nWok1DMzllj/SM3mrjXd5NUYgjI7Nr2S B8wn77qIk4JzDMgxC5w8/ZPYXw== X-Google-Smtp-Source: ABdhPJwb0ff86QKToEZgw8Yi50GgFqrKTDh2iO1Xjb+tLzfqdtZvUTJyFKQhqeppeXtgf9scgnt+Ng== X-Received: by 2002:a2e:b4a6:: with SMTP id q6mr12665814ljm.7.1637202007984; Wed, 17 Nov 2021 18:20:07 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.20.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:07 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 05/16] power: supply: ab8500: Use only one battery type Date: Thu, 18 Nov 2021 03:17:41 +0100 Message-Id: <20211118021752.2262818-6-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The code was going through hoops and loops to detect what battery is connected and check the resistance for this battery etc. Skip this trouble: we will support one battery (currently "unknown") then we will find the connected battery in the device tree using a compatible string. The battery resistance may be used to double-check that the right battery is connected. Convert the array of battery types into one battery type so we can next move over the properties of this one type into the standard struct power_supply_battery_info. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500-bm.h | 4 - drivers/power/supply/ab8500_bmdata.c | 203 ++++--------------------- drivers/power/supply/ab8500_btemp.c | 61 ++++---- drivers/power/supply/ab8500_chargalg.c | 51 +++---- drivers/power/supply/ab8500_fg.c | 17 ++- 5 files changed, 85 insertions(+), 251 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index 36bc28f1604f..9c96722f33d6 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -475,8 +475,6 @@ struct ab8500_bm_charger_parameters { * @enable_overshoot flag to enable VBAT overshoot control * @auto_trig flag to enable auto adc trigger * @fg_res resistance of FG resistor in 0.1mOhm - * @n_btypes number of elements in array bat_type - * @batt_id index of the identified battery in array bat_type * @interval_charging charge alg cycle period time when charging (sec) * @interval_not_charging charge alg cycle period time when not charging (sec) * @temp_hysteresis temperature hysteresis @@ -503,8 +501,6 @@ struct ab8500_bm_data { bool auto_trig; enum ab8500_adc_therm adc_therm; int fg_res; - int n_btypes; - int batt_id; int interval_charging; int interval_not_charging; int temp_hysteresis; diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index bd651602fd69..17c9b8700883 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -16,94 +16,6 @@ /* Default: temperature hysteresis */ #define AB8500_TEMP_HYSTERESIS 3 -/* - * These are the defined batteries that uses a NTC and ID resistor placed - * inside of the battery pack. - * Note that the res_to_temp table must be strictly sorted by falling resistance - * values to work. - */ -const struct ab8500_res_to_temp ab8500_temp_tbl_a_thermistor[] = { - {-5, 53407}, - { 0, 48594}, - { 5, 43804}, - {10, 39188}, - {15, 34870}, - {20, 30933}, - {25, 27422}, - {30, 24347}, - {35, 21694}, - {40, 19431}, - {45, 17517}, - {50, 15908}, - {55, 14561}, - {60, 13437}, - {65, 12500}, -}; - -const struct ab8500_res_to_temp ab8500_temp_tbl_b_thermistor[] = { - {-5, 200000}, - { 0, 159024}, - { 5, 151921}, - {10, 144300}, - {15, 136424}, - {20, 128565}, - {25, 120978}, - {30, 113875}, - {35, 107397}, - {40, 101629}, - {45, 96592}, - {50, 92253}, - {55, 88569}, - {60, 85461}, - {65, 82869}, -}; - -static const struct ab8500_v_to_cap cap_tbl_a_thermistor[] = { - {4171, 100}, - {4114, 95}, - {4009, 83}, - {3947, 74}, - {3907, 67}, - {3863, 59}, - {3830, 56}, - {3813, 53}, - {3791, 46}, - {3771, 33}, - {3754, 25}, - {3735, 20}, - {3717, 17}, - {3681, 13}, - {3664, 8}, - {3651, 6}, - {3635, 5}, - {3560, 3}, - {3408, 1}, - {3247, 0}, -}; - -static const struct ab8500_v_to_cap cap_tbl_b_thermistor[] = { - {4161, 100}, - {4124, 98}, - {4044, 90}, - {4003, 85}, - {3966, 80}, - {3933, 75}, - {3888, 67}, - {3849, 60}, - {3813, 55}, - {3787, 47}, - {3772, 30}, - {3751, 25}, - {3718, 20}, - {3681, 16}, - {3660, 14}, - {3589, 10}, - {3546, 7}, - {3495, 4}, - {3404, 2}, - {3250, 0}, -}; - static const struct ab8500_v_to_cap cap_tbl[] = { {4186, 100}, {4163, 99}, @@ -167,90 +79,33 @@ static const struct batres_vs_temp temp_to_batres_tbl_thermistor[] = { {-20, 595}, }; -static struct ab8500_battery_type bat_type_thermistor[] = { - [BATTERY_UNKNOWN] = { - /* First element always represent the UNKNOWN battery */ - .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN, - .resis_high = 0, - .resis_low = 0, - .battery_resistance = 300, - .charge_full_design = 612, - .nominal_voltage = 3700, - .termination_vol = 4050, - .termination_curr = 200, - .recharge_cap = 95, - .normal_cur_lvl = 400, - .normal_vol_lvl = 4100, - .maint_a_cur_lvl = 400, - .maint_a_vol_lvl = 4050, - .maint_a_chg_timer_h = 60, - .maint_b_cur_lvl = 400, - .maint_b_vol_lvl = 4000, - .maint_b_chg_timer_h = 200, - .low_high_cur_lvl = 300, - .low_high_vol_lvl = 4000, - .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), - .r_to_t_tbl = temp_tbl, - .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), - .v_to_cap_tbl = cap_tbl, - .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), - .batres_tbl = temp_to_batres_tbl_thermistor, - }, - { - .name = POWER_SUPPLY_TECHNOLOGY_LIPO, - .resis_high = 53407, - .resis_low = 12500, - .battery_resistance = 300, - .charge_full_design = 900, - .nominal_voltage = 3600, - .termination_vol = 4150, - .termination_curr = 80, - .recharge_cap = 95, - .normal_cur_lvl = 700, - .normal_vol_lvl = 4200, - .maint_a_cur_lvl = 600, - .maint_a_vol_lvl = 4150, - .maint_a_chg_timer_h = 60, - .maint_b_cur_lvl = 600, - .maint_b_vol_lvl = 4100, - .maint_b_chg_timer_h = 200, - .low_high_cur_lvl = 300, - .low_high_vol_lvl = 4000, - .n_temp_tbl_elements = ARRAY_SIZE(ab8500_temp_tbl_a_thermistor), - .r_to_t_tbl = ab8500_temp_tbl_a_thermistor, - .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_a_thermistor), - .v_to_cap_tbl = cap_tbl_a_thermistor, - .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), - .batres_tbl = temp_to_batres_tbl_thermistor, - - }, - { - .name = POWER_SUPPLY_TECHNOLOGY_LIPO, - .resis_high = 200000, - .resis_low = 82869, - .battery_resistance = 300, - .charge_full_design = 900, - .nominal_voltage = 3600, - .termination_vol = 4150, - .termination_curr = 80, - .recharge_cap = 95, - .normal_cur_lvl = 700, - .normal_vol_lvl = 4200, - .maint_a_cur_lvl = 600, - .maint_a_vol_lvl = 4150, - .maint_a_chg_timer_h = 60, - .maint_b_cur_lvl = 600, - .maint_b_vol_lvl = 4100, - .maint_b_chg_timer_h = 200, - .low_high_cur_lvl = 300, - .low_high_vol_lvl = 4000, - .n_temp_tbl_elements = ARRAY_SIZE(ab8500_temp_tbl_b_thermistor), - .r_to_t_tbl = ab8500_temp_tbl_b_thermistor, - .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_b_thermistor), - .v_to_cap_tbl = cap_tbl_b_thermistor, - .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), - .batres_tbl = temp_to_batres_tbl_thermistor, - }, +/* Default battery type for reference designs is the unknown type */ +static struct ab8500_battery_type bat_type_thermistor_unknown = { + .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN, + .resis_high = 0, + .resis_low = 0, + .battery_resistance = 300, + .charge_full_design = 612, + .nominal_voltage = 3700, + .termination_vol = 4050, + .termination_curr = 200, + .recharge_cap = 95, + .normal_cur_lvl = 400, + .normal_vol_lvl = 4100, + .maint_a_cur_lvl = 400, + .maint_a_vol_lvl = 4050, + .maint_a_chg_timer_h = 60, + .maint_b_cur_lvl = 400, + .maint_b_vol_lvl = 4000, + .maint_b_chg_timer_h = 200, + .low_high_cur_lvl = 300, + .low_high_vol_lvl = 4000, + .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), + .r_to_t_tbl = temp_tbl, + .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), + .v_to_cap_tbl = cap_tbl, + .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), + .batres_tbl = temp_to_batres_tbl_thermistor, }; static const struct ab8500_bm_capacity_levels cap_levels = { @@ -312,9 +167,7 @@ struct ab8500_bm_data ab8500_bm_data = { .enable_overshoot = false, .fg_res = 100, .cap_levels = &cap_levels, - .bat_type = bat_type_thermistor, - .n_btypes = ARRAY_SIZE(bat_type_thermistor), - .batt_id = 0, + .bat_type = &bat_type_thermistor_unknown, .interval_charging = 5, .interval_not_charging = 120, .gnd_lift_resistance = 34, diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c index b6c9111d77d7..fbb58074efab 100644 --- a/drivers/power/supply/ab8500_btemp.c +++ b/drivers/power/supply/ab8500_btemp.c @@ -454,12 +454,9 @@ static int ab8500_btemp_measure_temp(struct ab8500_btemp *di) int temp, ret; static int prev; int rbat, rntc, vntc; - u8 id; - id = di->bm->batt_id; - - if (di->bm->adc_therm == AB8500_ADC_THERM_BATCTRL && - id != BATTERY_UNKNOWN) { + if ((di->bm->adc_therm == AB8500_ADC_THERM_BATCTRL) && + (di->bm->bat_type->name == POWER_SUPPLY_TECHNOLOGY_UNKNOWN)) { rbat = ab8500_btemp_get_batctrl_res(di); if (rbat < 0) { @@ -473,8 +470,8 @@ static int ab8500_btemp_measure_temp(struct ab8500_btemp *di) } temp = ab8500_btemp_res_to_temp(di, - di->bm->bat_type[id].r_to_t_tbl, - di->bm->bat_type[id].n_temp_tbl_elements, rbat); + di->bm->bat_type->r_to_t_tbl, + di->bm->bat_type->n_temp_tbl_elements, rbat); } else { ret = iio_read_channel_processed(di->btemp_ball, &vntc); if (ret < 0) { @@ -490,8 +487,8 @@ static int ab8500_btemp_measure_temp(struct ab8500_btemp *di) rntc = 230000 * vntc / (VTVOUT_V - vntc); temp = ab8500_btemp_res_to_temp(di, - di->bm->bat_type[id].r_to_t_tbl, - di->bm->bat_type[id].n_temp_tbl_elements, rntc); + di->bm->bat_type->r_to_t_tbl, + di->bm->bat_type->n_temp_tbl_elements, rntc); prev = temp; } dev_dbg(di->dev, "Battery temperature is %d\n", temp); @@ -512,7 +509,6 @@ static int ab8500_btemp_id(struct ab8500_btemp *di) u8 i; di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA; - di->bm->batt_id = BATTERY_UNKNOWN; res = ab8500_btemp_get_batctrl_res(di); if (res < 0) { @@ -520,40 +516,37 @@ static int ab8500_btemp_id(struct ab8500_btemp *di) return -ENXIO; } - /* BATTERY_UNKNOWN is defined on position 0, skip it! */ - for (i = BATTERY_UNKNOWN + 1; i < di->bm->n_btypes; i++) { - if ((res <= di->bm->bat_type[i].resis_high) && - (res >= di->bm->bat_type[i].resis_low)) { - dev_dbg(di->dev, "Battery detected on %s" - " low %d < res %d < high: %d" - " index: %d\n", - di->bm->adc_therm == AB8500_ADC_THERM_BATCTRL ? - "BATCTRL" : "BATTEMP", - di->bm->bat_type[i].resis_low, res, - di->bm->bat_type[i].resis_high, i); - - di->bm->batt_id = i; - break; - } - } - - if (di->bm->batt_id == BATTERY_UNKNOWN) { + if ((res <= di->bm->bat_type->resis_high) && + (res >= di->bm->bat_type->resis_low)) { + dev_info(di->dev, "Battery detected on %s" + " low %d < res %d < high: %d" + " index: %d\n", + di->bm->adc_therm == AB8500_ADC_THERM_BATCTRL ? + "BATCTRL" : "BATTEMP", + di->bm->bat_type->resis_low, res, + di->bm->bat_type->resis_high, i); + } else { dev_warn(di->dev, "Battery identified as unknown" - ", resistance %d Ohm\n", res); + ", resistance %d Ohm\n", res); return -ENXIO; } /* * We only have to change current source if the - * detected type is Type 1. + * detected type is Type 1 (LIPO) resis_high = 53407, resis_low = 12500 + * if someone hacks this in. + * + * FIXME: make sure this is done automatically for the batteries + * that need it. */ - if (di->bm->adc_therm == AB8500_ADC_THERM_BATCTRL && - di->bm->batt_id == 1) { + if ((di->bm->adc_therm == AB8500_ADC_THERM_BATCTRL) && + (di->bm->bat_type->name == POWER_SUPPLY_TECHNOLOGY_LIPO) && + (res <= 53407) && (res >= 12500)) { dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n"); di->curr_source = BTEMP_BATCTRL_CURR_SRC_20UA; } - return di->bm->batt_id; + return 0; } /** @@ -814,7 +807,7 @@ static int ab8500_btemp_get_property(struct power_supply *psy, val->intval = 1; break; case POWER_SUPPLY_PROP_TECHNOLOGY: - val->intval = di->bm->bat_type[di->bm->batt_id].name; + val->intval = di->bm->bat_type->name; break; case POWER_SUPPLY_PROP_TEMP: val->intval = ab8500_btemp_get_temp(di); diff --git a/drivers/power/supply/ab8500_chargalg.c b/drivers/power/supply/ab8500_chargalg.c index 9196434393e8..a5ccfb0aa9f4 100644 --- a/drivers/power/supply/ab8500_chargalg.c +++ b/drivers/power/supply/ab8500_chargalg.c @@ -356,13 +356,13 @@ static int ab8500_chargalg_check_charger_enable(struct ab8500_chargalg *di) if (di->chg_info.charger_type & USB_CHG) { return di->usb_chg->ops.check_enable(di->usb_chg, - di->bm->bat_type[di->bm->batt_id].normal_vol_lvl, - di->bm->bat_type[di->bm->batt_id].normal_cur_lvl); + di->bm->bat_type->normal_vol_lvl, + di->bm->bat_type->normal_cur_lvl); } else if ((di->chg_info.charger_type & AC_CHG) && !(di->ac_chg->external)) { return di->ac_chg->ops.check_enable(di->ac_chg, - di->bm->bat_type[di->bm->batt_id].normal_vol_lvl, - di->bm->bat_type[di->bm->batt_id].normal_cur_lvl); + di->bm->bat_type->normal_vol_lvl, + di->bm->bat_type->normal_cur_lvl); } return 0; } @@ -793,10 +793,10 @@ static void ab8500_chargalg_end_of_charge(struct ab8500_chargalg *di) if (di->charge_status == POWER_SUPPLY_STATUS_CHARGING && di->charge_state == STATE_NORMAL && !di->maintenance_chg && (di->batt_data.volt >= - di->bm->bat_type[di->bm->batt_id].termination_vol || + di->bm->bat_type->termination_vol || di->events.usb_cv_active || di->events.ac_cv_active) && di->batt_data.avg_curr < - di->bm->bat_type[di->bm->batt_id].termination_curr && + di->bm->bat_type->termination_curr && di->batt_data.avg_curr > 0) { if (++di->eoc_cnt >= EOC_COND_CNT) { di->eoc_cnt = 0; @@ -819,9 +819,9 @@ static void ab8500_chargalg_end_of_charge(struct ab8500_chargalg *di) static void init_maxim_chg_curr(struct ab8500_chargalg *di) { di->ccm.original_iset = - di->bm->bat_type[di->bm->batt_id].normal_cur_lvl; + di->bm->bat_type->normal_cur_lvl; di->ccm.current_iset = - di->bm->bat_type[di->bm->batt_id].normal_cur_lvl; + di->bm->bat_type->normal_cur_lvl; di->ccm.test_delta_i = di->bm->maxi->charger_curr_step; di->ccm.max_current = di->bm->maxi->chg_curr; di->ccm.condition_cnt = di->bm->maxi->wait_cycles; @@ -924,7 +924,7 @@ static void handle_maxim_chg_curr(struct ab8500_chargalg *di) break; case MAXIM_RET_IBAT_TOO_HIGH: result = ab8500_chargalg_update_chg_curr(di, - di->bm->bat_type[di->bm->batt_id].normal_cur_lvl); + di->bm->bat_type->normal_cur_lvl); if (result) dev_err(di->dev, "failed to set chg curr\n"); break; @@ -1505,13 +1505,12 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) if (di->curr_status.curr_step == CHARGALG_CURR_STEP_LOW) ab8500_chargalg_stop_charging(di); else { - curr_step_lvl = di->bm->bat_type[ - di->bm->batt_id].normal_cur_lvl + curr_step_lvl = di->bm->bat_type->normal_cur_lvl * di->curr_status.curr_step / CHARGALG_CURR_STEP_HIGH; ab8500_chargalg_start_charging(di, - di->bm->bat_type[di->bm->batt_id] - .normal_vol_lvl, curr_step_lvl); + di->bm->bat_type->normal_vol_lvl, + curr_step_lvl); } ab8500_chargalg_state_to(di, STATE_NORMAL); @@ -1546,20 +1545,17 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) case STATE_WAIT_FOR_RECHARGE: if (di->batt_data.percent <= - di->bm->bat_type[di->bm->batt_id].recharge_cap) + di->bm->bat_type->recharge_cap) ab8500_chargalg_state_to(di, STATE_NORMAL_INIT); break; case STATE_MAINTENANCE_A_INIT: ab8500_chargalg_stop_safety_timer(di); ab8500_chargalg_start_maintenance_timer(di, - di->bm->bat_type[ - di->bm->batt_id].maint_a_chg_timer_h); + di->bm->bat_type->maint_a_chg_timer_h); ab8500_chargalg_start_charging(di, - di->bm->bat_type[ - di->bm->batt_id].maint_a_vol_lvl, - di->bm->bat_type[ - di->bm->batt_id].maint_a_cur_lvl); + di->bm->bat_type->maint_a_vol_lvl, + di->bm->bat_type->maint_a_cur_lvl); ab8500_chargalg_state_to(di, STATE_MAINTENANCE_A); power_supply_changed(di->chargalg_psy); fallthrough; @@ -1573,13 +1569,10 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) case STATE_MAINTENANCE_B_INIT: ab8500_chargalg_start_maintenance_timer(di, - di->bm->bat_type[ - di->bm->batt_id].maint_b_chg_timer_h); + di->bm->bat_type->maint_b_chg_timer_h); ab8500_chargalg_start_charging(di, - di->bm->bat_type[ - di->bm->batt_id].maint_b_vol_lvl, - di->bm->bat_type[ - di->bm->batt_id].maint_b_cur_lvl); + di->bm->bat_type->maint_b_vol_lvl, + di->bm->bat_type->maint_b_cur_lvl); ab8500_chargalg_state_to(di, STATE_MAINTENANCE_B); power_supply_changed(di->chargalg_psy); fallthrough; @@ -1593,10 +1586,8 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) case STATE_TEMP_LOWHIGH_INIT: ab8500_chargalg_start_charging(di, - di->bm->bat_type[ - di->bm->batt_id].low_high_vol_lvl, - di->bm->bat_type[ - di->bm->batt_id].low_high_cur_lvl); + di->bm->bat_type->low_high_vol_lvl, + di->bm->bat_type->low_high_cur_lvl); ab8500_chargalg_stop_maintenance_timer(di); di->charge_status = POWER_SUPPLY_STATUS_CHARGING; ab8500_chargalg_state_to(di, STATE_TEMP_LOWHIGH); diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c index 05fe9724ba50..2013db0118ee 100644 --- a/drivers/power/supply/ab8500_fg.c +++ b/drivers/power/supply/ab8500_fg.c @@ -857,8 +857,8 @@ static int ab8500_fg_volt_to_capacity(struct ab8500_fg *di, int voltage) const struct ab8500_v_to_cap *tbl; int cap = 0; - tbl = di->bm->bat_type[di->bm->batt_id].v_to_cap_tbl; - tbl_size = di->bm->bat_type[di->bm->batt_id].n_v_cap_tbl_elements; + tbl = di->bm->bat_type->v_to_cap_tbl; + tbl_size = di->bm->bat_type->n_v_cap_tbl_elements; for (i = 0; i < tbl_size; ++i) { if (voltage > tbl[i].voltage) @@ -910,8 +910,8 @@ static int ab8500_fg_battery_resistance(struct ab8500_fg *di) const struct batres_vs_temp *tbl; int resist = 0; - tbl = di->bm->bat_type[di->bm->batt_id].batres_tbl; - tbl_size = di->bm->bat_type[di->bm->batt_id].n_batres_tbl_elements; + tbl = di->bm->bat_type->batres_tbl; + tbl_size = di->bm->bat_type->n_batres_tbl_elements; for (i = 0; i < tbl_size; ++i) { if (di->bat_temp / 10 > tbl[i].temp) @@ -2234,10 +2234,11 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data) switch (ext->desc->type) { case POWER_SUPPLY_TYPE_BATTERY: if (!di->flags.batt_id_received && - di->bm->batt_id != BATTERY_UNKNOWN) { + (di->bm->bat_type->name != + POWER_SUPPLY_TECHNOLOGY_UNKNOWN)) { const struct ab8500_battery_type *b; - b = &(di->bm->bat_type[di->bm->batt_id]); + b = di->bm->bat_type; di->flags.batt_id_received = true; @@ -3078,11 +3079,11 @@ static int ab8500_fg_probe(struct platform_device *pdev) psy_cfg.drv_data = di; di->bat_cap.max_mah_design = MILLI_TO_MICRO * - di->bm->bat_type[di->bm->batt_id].charge_full_design; + di->bm->bat_type->charge_full_design; di->bat_cap.max_mah = di->bat_cap.max_mah_design; - di->vbat_nom = di->bm->bat_type[di->bm->batt_id].nominal_voltage; + di->vbat_nom = di->bm->bat_type->nominal_voltage; di->init_capacity = true; From patchwork Thu Nov 18 02:17:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625871 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CE101C433F5 for ; Thu, 18 Nov 2021 02:20:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B35BE61AD0 for ; Thu, 18 Nov 2021 02:20:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242491AbhKRCXT (ORCPT ); Wed, 17 Nov 2021 21:23:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49240 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242493AbhKRCXL (ORCPT ); Wed, 17 Nov 2021 21:23:11 -0500 Received: from mail-lf1-x131.google.com (mail-lf1-x131.google.com [IPv6:2a00:1450:4864:20::131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 15CD2C061570 for ; Wed, 17 Nov 2021 18:20:12 -0800 (PST) Received: by mail-lf1-x131.google.com with SMTP id l22so17864092lfg.7 for ; Wed, 17 Nov 2021 18:20:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9j/+9vNRUOuE2OUGHIWjiFJX54aRqGsYS2DHbcFsR74=; b=bOu49EpG1z6ALVV4/cXJHXcvwA+h6l2/XujvF1+xwf7lfxqKheAdiseTR0c85ecnjh 1QAAg5jIHYC7mJacGY6DbUr/djnKrwcaqwjqdMyAZ1Ldh7KUE231PcVC4/4CFYdzuw0d NLKTt/ZylmGR8e56X9sobV3O5xra0QY/BhDL7l6B/6k7dWgkOrU5t20TxboxKKFOiWAk 2sVRILXMQYn3Y41rVjh435GxlWlwbczEpSxjj17PqUevh31YN3UvGEPYRYgn7LkI9GTs uaLy56cr29CpZ/DAIewud+U3oN1RPaZzFh0sU3IWvQTjjzMWt+4V3zuw8W5xPsGOSzZi xbIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9j/+9vNRUOuE2OUGHIWjiFJX54aRqGsYS2DHbcFsR74=; b=jLcRHMzPdJhTCLt1+KST2sBRhnpCkLYPxJ6w3IkwNTmwZoosXIIme4dwSOMnuw4Z9o FlWwEXjvZ9Mq8S/SwpjXVpA3b+SiY4bBv+itzT5ihICd0SlqtuEz4uN2+QKzf/U3pumD E/p2P7H4F6abyBdJ/5e6Dkp3itKs/+LbXv/8oGdS1vIM5AU8rstvG4AQ0bU14RA7Shfa Y2lyk0BdPmWSCpQbivzCVfKkUV/R2TWcYJNVHUvPeKdCutQMdNk7U0dNbx9cSMoo81gF tyK1ceyKegKp+CfiaXdXTknY15rnbnM2q7G89I1wJXDxooC6HS4qvZdG+oBIEYP8A21N FcJQ== X-Gm-Message-State: AOAM532e3MRyLIXEO6fAtNbIexM3eS2BL+uHXPkfjMaK8z2qY3LtoMlc HVr2CyJJpJNzqKmU+t7DXKTDyw== X-Google-Smtp-Source: ABdhPJwWBe3Q+je0o/XZ3VD9hHvBEeY9DxkK2sCrD5JWBRFFobrBD3Nq/ag/t0uBNuuVxmmTCcxgvA== X-Received: by 2002:a2e:a696:: with SMTP id q22mr12656342lje.423.1637202010412; Wed, 17 Nov 2021 18:20:10 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.20.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:09 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 06/16] power: supply: ab8500: Standardize design capacity Date: Thu, 18 Nov 2021 03:17:42 +0100 Message-Id: <20211118021752.2262818-7-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Now that we know that we have only one battery type to deal with we can proceed to transfer properties to struct power_supply_battery_info. The designed capacity for the battery was in a custom field of the custom battery type in mAh, transfer this to the standard charge_full_design_uah property in struct power_supply_battery_info and augment the code accordingly. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500-bm.h | 2 -- drivers/power/supply/ab8500_bmdata.c | 5 ++++- drivers/power/supply/ab8500_fg.c | 8 ++------ 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index 9c96722f33d6..79c00808a372 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -375,7 +375,6 @@ struct ab8500_maxim_parameters { * @name: battery technology * @resis_high: battery upper resistance limit * @resis_low: battery lower resistance limit - * @charge_full_design: Maximum battery capacity in mAh * @nominal_voltage: Nominal voltage of the battery in mV * @termination_vol: max voltage upto which battery can be charged * @termination_curr battery charging termination current in mA @@ -404,7 +403,6 @@ struct ab8500_battery_type { int name; int resis_high; int resis_low; - int charge_full_design; int nominal_voltage; int termination_vol; int termination_curr; diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index 17c9b8700883..6e876ba03956 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -85,7 +85,6 @@ static struct ab8500_battery_type bat_type_thermistor_unknown = { .resis_high = 0, .resis_low = 0, .battery_resistance = 300, - .charge_full_design = 612, .nominal_voltage = 3700, .termination_vol = 4050, .termination_curr = 200, @@ -189,6 +188,10 @@ int ab8500_bm_of_probe(struct power_supply *psy, return ret; } + /* Fill in defaults for any data missing from the device tree */ + if (bi->charge_full_design_uah < 0) + /* The default capacity is 612 mAh for unknown batteries */ + bi->charge_full_design_uah = 612000; if (bi->temp_min == INT_MIN) bi->temp_min = AB8500_TEMP_UNDER; if (bi->temp_max == INT_MAX) diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c index 2013db0118ee..4f8b3a76c565 100644 --- a/drivers/power/supply/ab8500_fg.c +++ b/drivers/power/supply/ab8500_fg.c @@ -38,7 +38,6 @@ #include "ab8500-bm.h" -#define MILLI_TO_MICRO 1000 #define FG_LSB_IN_MA 1627 #define QLSB_NANO_AMP_HOURS_X10 1071 #define INS_CURR_TIMEOUT (3 * HZ) @@ -2243,8 +2242,7 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data) di->flags.batt_id_received = true; di->bat_cap.max_mah_design = - MILLI_TO_MICRO * - b->charge_full_design; + di->bm->bi.charge_full_design_uah; di->bat_cap.max_mah = di->bat_cap.max_mah_design; @@ -3078,9 +3076,7 @@ static int ab8500_fg_probe(struct platform_device *pdev) psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface); psy_cfg.drv_data = di; - di->bat_cap.max_mah_design = MILLI_TO_MICRO * - di->bm->bat_type->charge_full_design; - + di->bat_cap.max_mah_design = di->bm->bi.charge_full_design_uah; di->bat_cap.max_mah = di->bat_cap.max_mah_design; di->vbat_nom = di->bm->bat_type->nominal_voltage; From patchwork Thu Nov 18 02:17:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625873 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E9416C433FE for ; Thu, 18 Nov 2021 02:20:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CBBFE61B42 for ; Thu, 18 Nov 2021 02:20:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242495AbhKRCXV (ORCPT ); Wed, 17 Nov 2021 21:23:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242500AbhKRCXN (ORCPT ); Wed, 17 Nov 2021 21:23:13 -0500 Received: from mail-lf1-x132.google.com (mail-lf1-x132.google.com [IPv6:2a00:1450:4864:20::132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 54DE1C061570 for ; Wed, 17 Nov 2021 18:20:14 -0800 (PST) Received: by mail-lf1-x132.google.com with SMTP id bi37so18050222lfb.5 for ; Wed, 17 Nov 2021 18:20:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tYK5uoy8GHHO0OljX1X+VuD+Rv00GwqfTZX0VCYWrrQ=; b=qg3y3xPH9unsP7I15/V2JYXcZo7bwZyjcpCchpkkbPr+LeXgG5n/9oZbiRjPpQ9lys dZOax1IHBtnAeIcozwZFkGinAKUD0crpgC+WP7bEECqpt8fqZj4jbChTfX6yBV+MOIM2 BgpyTF+a+qQGvmogPTbKL5dInnHsODQxdItmSoq4Nu1FuSG0Wwc0+q1M9ZDEDyejrvl7 O81rRWxGkbnITFlXsoknh6cNmWerddSYwCgO56apP4XVQnzRhonth9KUzx2oHoLTvbU3 9w/jW+DtFDT6m3ZOG33LgQSPutirDXfWSHS37N3sEzOwM/JChW4DOs37vECzqxDWIUO8 miJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tYK5uoy8GHHO0OljX1X+VuD+Rv00GwqfTZX0VCYWrrQ=; b=n0s/pJhPLCVKKPNr4Qf1tiLBHHDdyiV4ymwD2EoGc4DiNHDLoN1rru31gnykQwKjcO Ll9jY5stXlCdWvzwkkg9d3PI0ftumMBgpLKJfQBw4z43tDUQF24qe0xY5TLNTQvoGBCv jRCxnsBs1nN6olZF+ZtPlfbCKzpZ5T9sbnAnlqfKgd252qf19ZcKhYlxiV5akgfKeXvM wU7iPeTaXrGlP3xsSUoEXwbZdxUJhd0UJG9vAIyPY5S0iwTl/qu0ApVeb/ik/AbrTIiH vxYfC54ECUNuv4tZV9py6/sPuWHHYIGnGw48hukGsVdX/AaHLG/NN7l6XfOplYE5g+4h PMgw== X-Gm-Message-State: AOAM5310sFVd7MmavO/GkzlNOsi6HT7DwnUAL9OIYCcSS9j2ZR5s5dRg TqY0RYfI8FV+gRtHDzhlRfNVcA== X-Google-Smtp-Source: ABdhPJxEh7XaC53Z34G3ER4omfS9DihjBWGSAi6zjpOzM/mcVOxPKS8VfGl/XoWGN5FsK9H4nEIgEQ== X-Received: by 2002:a05:6512:3763:: with SMTP id z3mr19705228lft.315.1637202012689; Wed, 17 Nov 2021 18:20:12 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.20.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:11 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 07/16] power: supply: ab8500: Standardize technology Date: Thu, 18 Nov 2021 03:17:43 +0100 Message-Id: <20211118021752.2262818-8-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The AB8500 custom battery type can be replaced by the corresponding struct power_supply_battery_info field. Remove the struct member and amend the code to use the standard property. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500-bm.h | 2 -- drivers/power/supply/ab8500_bmdata.c | 1 - drivers/power/supply/ab8500_btemp.c | 6 +++--- drivers/power/supply/ab8500_fg.c | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index 79c00808a372..66fd6568942c 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -372,7 +372,6 @@ struct ab8500_maxim_parameters { /** * struct ab8500_battery_type - different batteries supported - * @name: battery technology * @resis_high: battery upper resistance limit * @resis_low: battery lower resistance limit * @nominal_voltage: Nominal voltage of the battery in mV @@ -400,7 +399,6 @@ struct ab8500_maxim_parameters { * @batres_tbl battery internal resistance vs temperature table */ struct ab8500_battery_type { - int name; int resis_high; int resis_low; int nominal_voltage; diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index 6e876ba03956..a5e655d0761a 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -81,7 +81,6 @@ static const struct batres_vs_temp temp_to_batres_tbl_thermistor[] = { /* Default battery type for reference designs is the unknown type */ static struct ab8500_battery_type bat_type_thermistor_unknown = { - .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN, .resis_high = 0, .resis_low = 0, .battery_resistance = 300, diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c index fbb58074efab..20253b8a7fe9 100644 --- a/drivers/power/supply/ab8500_btemp.c +++ b/drivers/power/supply/ab8500_btemp.c @@ -456,7 +456,7 @@ static int ab8500_btemp_measure_temp(struct ab8500_btemp *di) int rbat, rntc, vntc; if ((di->bm->adc_therm == AB8500_ADC_THERM_BATCTRL) && - (di->bm->bat_type->name == POWER_SUPPLY_TECHNOLOGY_UNKNOWN)) { + (di->bm->bi.technology == POWER_SUPPLY_TECHNOLOGY_UNKNOWN)) { rbat = ab8500_btemp_get_batctrl_res(di); if (rbat < 0) { @@ -540,7 +540,7 @@ static int ab8500_btemp_id(struct ab8500_btemp *di) * that need it. */ if ((di->bm->adc_therm == AB8500_ADC_THERM_BATCTRL) && - (di->bm->bat_type->name == POWER_SUPPLY_TECHNOLOGY_LIPO) && + (di->bm->bi.technology == POWER_SUPPLY_TECHNOLOGY_LIPO) && (res <= 53407) && (res >= 12500)) { dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n"); di->curr_source = BTEMP_BATCTRL_CURR_SRC_20UA; @@ -807,7 +807,7 @@ static int ab8500_btemp_get_property(struct power_supply *psy, val->intval = 1; break; case POWER_SUPPLY_PROP_TECHNOLOGY: - val->intval = di->bm->bat_type->name; + val->intval = di->bm->bi.technology; break; case POWER_SUPPLY_PROP_TEMP: val->intval = ab8500_btemp_get_temp(di); diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c index 4f8b3a76c565..c6237c4f4721 100644 --- a/drivers/power/supply/ab8500_fg.c +++ b/drivers/power/supply/ab8500_fg.c @@ -2233,7 +2233,7 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data) switch (ext->desc->type) { case POWER_SUPPLY_TYPE_BATTERY: if (!di->flags.batt_id_received && - (di->bm->bat_type->name != + (di->bm->bi.technology != POWER_SUPPLY_TECHNOLOGY_UNKNOWN)) { const struct ab8500_battery_type *b; From patchwork Thu Nov 18 02:17:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625881 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F2EEFC433EF for ; Thu, 18 Nov 2021 02:20:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D86B4610D0 for ; Thu, 18 Nov 2021 02:20:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242533AbhKRCXX (ORCPT ); Wed, 17 Nov 2021 21:23:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49262 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242509AbhKRCXQ (ORCPT ); Wed, 17 Nov 2021 21:23:16 -0500 Received: from mail-lf1-x12e.google.com (mail-lf1-x12e.google.com [IPv6:2a00:1450:4864:20::12e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 734CDC061570 for ; Wed, 17 Nov 2021 18:20:16 -0800 (PST) Received: by mail-lf1-x12e.google.com with SMTP id y26so17979843lfa.11 for ; Wed, 17 Nov 2021 18:20:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=+4vZ1TRJjmkdD5N7MxsfN+lyXT9NBEi/c6RfzKXpo24=; b=JeQppe+3qFh9A4rj0y3/3GD557D9pZvGi6t9fL6QndJlnGxRkiZKiplxlmR1aCKDet f1cuz2UEJfm2toouULBk2juOuL29ON8xo7Q8gl+rIulsrWv7i5TRu/vmLZVSffHVXnKU nlz6YhPsUr5N/AavcBV/yDUERmZiB3H818Tkqja309Q3CwpAVJUEr5dPqHf/CovzrjcJ a2YsbPIpWbFX++c/C4J6sjqMNWQ6aNCIAZUjrxTOukjMG+e+cEXaVm/DChWzHF2OlGqp ylbwb/Je8zCA+/tZnrPFU8ffkzNEy/ZMeFmAo1aQ7KC9xh/Scdt1XW9ty8SQMDcrbwVe /utw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+4vZ1TRJjmkdD5N7MxsfN+lyXT9NBEi/c6RfzKXpo24=; b=I5MBALvVihiEnP3Voz2NTlsstgPCskA0cfgYTeeTekxWPnI8Rnbcc5WSGS6EnlHThZ C2Kcd6QqPpvGP0wKQG/A26RWjpAxEpGKYIVaMNDfrcxPqKvdgooxImz/JMrqOlW2vePb xJKxkZlVdF0PrsczbKvC+kcDiPbGHPapKdDIoDs1k7deGngC0HaooPUYNfkunhF2SAnL zmr7WUVc7NLxwyzA0dAvIaWL55qXNDBnbekATF6GR/OKmToy38fcA6OedQWb+5BGLDyE xW61R3g1htfgKK7/9UMe3z3rl2IT9KZ4j3Qk9M10lmsGr9UtvSsC2edRVr53BOfIRNxt acdw== X-Gm-Message-State: AOAM533WHvM6y7mSD8Tmpyw0wlB+akW5rKjoTXQFqgozS+gDM8QywAw0 s5yCVYXUgelzq/DFOpC/Ru/81w== X-Google-Smtp-Source: ABdhPJz3m9bSXjP1i3uoIN6SssTFRxSFYLR0FRnEV6lCmBSZQEWgsW785RaRIV8LFiV/nCnEcNv7Hg== X-Received: by 2002:a05:6512:a91:: with SMTP id m17mr19989320lfu.690.1637202014597; Wed, 17 Nov 2021 18:20:14 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.20.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:13 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 08/16] power: supply: ab8500: Standardize voltages Date: Thu, 18 Nov 2021 03:17:44 +0100 Message-Id: <20211118021752.2262818-9-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The nominal voltage in this charge driver corresponds to both the voltage_min_design_uv and voltage_max_design_uv of struct power_supply_battery_info so assign both if this is undefined. The overcharge max voltage (when the charger should cut off) is migrated at the same time so we move both voltages to struct power_supply_battery_info. Adjust the code to deal directly with the microvolt values instead of converting them to millivolts. Add *_uv suffixes for clarity and to make sure we have changed all code sites using this member. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500-bm.h | 4 ---- drivers/power/supply/ab8500_bmdata.c | 17 +++++++++++++++-- drivers/power/supply/ab8500_chargalg.c | 10 +++++----- drivers/power/supply/ab8500_fg.c | 21 +++++++++++++-------- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index 66fd6568942c..233fa86f9b2f 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -374,8 +374,6 @@ struct ab8500_maxim_parameters { * struct ab8500_battery_type - different batteries supported * @resis_high: battery upper resistance limit * @resis_low: battery lower resistance limit - * @nominal_voltage: Nominal voltage of the battery in mV - * @termination_vol: max voltage upto which battery can be charged * @termination_curr battery charging termination current in mA * @recharge_cap battery capacity limit that will trigger a new * full charging cycle in the case where maintenan- @@ -401,8 +399,6 @@ struct ab8500_maxim_parameters { struct ab8500_battery_type { int resis_high; int resis_low; - int nominal_voltage; - int termination_vol; int termination_curr; int recharge_cap; int normal_cur_lvl; diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index a5e655d0761a..17df619cdf36 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -84,8 +84,6 @@ static struct ab8500_battery_type bat_type_thermistor_unknown = { .resis_high = 0, .resis_low = 0, .battery_resistance = 300, - .nominal_voltage = 3700, - .termination_vol = 4050, .termination_curr = 200, .recharge_cap = 95, .normal_cur_lvl = 400, @@ -191,6 +189,21 @@ int ab8500_bm_of_probe(struct power_supply *psy, if (bi->charge_full_design_uah < 0) /* The default capacity is 612 mAh for unknown batteries */ bi->charge_full_design_uah = 612000; + + /* + * All of these voltages need to be specified or we will simply + * fall back to safe defaults. + */ + if ((bi->voltage_min_design_uv < 0) || + (bi->voltage_max_design_uv < 0) || + (bi->overvoltage_limit_uv < 0)) { + /* Nominal voltage is 3.7V for unknown batteries */ + bi->voltage_min_design_uv = 3700000; + bi->voltage_max_design_uv = 3700000; + /* Termination voltage (overcharge limit) 4.05V */ + bi->overvoltage_limit_uv = 4050000; + } + if (bi->temp_min == INT_MIN) bi->temp_min = AB8500_TEMP_UNDER; if (bi->temp_max == INT_MAX) diff --git a/drivers/power/supply/ab8500_chargalg.c b/drivers/power/supply/ab8500_chargalg.c index a5ccfb0aa9f4..dd9cad63e37e 100644 --- a/drivers/power/supply/ab8500_chargalg.c +++ b/drivers/power/supply/ab8500_chargalg.c @@ -86,7 +86,7 @@ struct ab8500_chargalg_current_step_status { struct ab8500_chargalg_battery_data { int temp; - int volt; + int volt_uv; int avg_curr; int inst_curr; int percent; @@ -792,8 +792,8 @@ static void ab8500_chargalg_end_of_charge(struct ab8500_chargalg *di) { if (di->charge_status == POWER_SUPPLY_STATUS_CHARGING && di->charge_state == STATE_NORMAL && - !di->maintenance_chg && (di->batt_data.volt >= - di->bm->bat_type->termination_vol || + !di->maintenance_chg && (di->batt_data.volt_uv >= + di->bm->bi.overvoltage_limit_uv || di->events.usb_cv_active || di->events.ac_cv_active) && di->batt_data.avg_curr < di->bm->bat_type->termination_curr && @@ -1160,7 +1160,7 @@ static int ab8500_chargalg_get_ext_psy_data(struct device *dev, void *data) case POWER_SUPPLY_PROP_VOLTAGE_NOW: switch (ext->desc->type) { case POWER_SUPPLY_TYPE_BATTERY: - di->batt_data.volt = ret.intval / 1000; + di->batt_data.volt_uv = ret.intval; break; case POWER_SUPPLY_TYPE_MAINS: di->chg_info.ac_volt = ret.intval / 1000; @@ -1397,7 +1397,7 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) "State %s Active_chg %d Chg_status %d AC %d USB %d " "AC_online %d USB_online %d AC_CV %d USB_CV %d AC_I %d " "USB_I %d AC_Vset %d AC_Iset %d USB_Vset %d USB_Iset %d\n", - di->batt_data.volt, + di->batt_data.volt_uv, di->batt_data.avg_curr, di->batt_data.inst_curr, di->batt_data.temp, diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c index c6237c4f4721..ab6141faa798 100644 --- a/drivers/power/supply/ab8500_fg.c +++ b/drivers/power/supply/ab8500_fg.c @@ -157,7 +157,7 @@ struct inst_curr_result_list { * @node: a list of AB8500 FGs, hence prepared for reentrance * @irq holds the CCEOC interrupt number * @vbat: Battery voltage in mV - * @vbat_nom: Nominal battery voltage in mV + * @vbat_nom_uv: Nominal battery voltage in uV * @inst_curr: Instantenous battery current in mA * @avg_curr: Average battery current in mA * @bat_temp battery temperature @@ -199,7 +199,7 @@ struct ab8500_fg { struct list_head node; int irq; int vbat; - int vbat_nom; + int vbat_nom_uv; int inst_curr; int avg_curr; int bat_temp; @@ -1013,11 +1013,16 @@ static int ab8500_fg_convert_mah_to_uwh(struct ab8500_fg *di, int cap_mah) u64 div_res; u32 div_rem; - div_res = ((u64) cap_mah) * ((u64) di->vbat_nom); - div_rem = do_div(div_res, 1000); + /* + * Capacity is in milli ampere hours (10^-3)Ah + * Nominal voltage is in microvolts (10^-6)V + * divide by 1000000 after multiplication to get to mWh + */ + div_res = ((u64) cap_mah) * ((u64) di->vbat_nom_uv); + div_rem = do_div(div_res, 1000000); /* Make sure to round upwards if necessary */ - if (div_rem >= 1000 / 2) + if (div_rem >= 1000000 / 2) div_res++; return (int) div_res; @@ -2247,7 +2252,8 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data) di->bat_cap.max_mah = di->bat_cap.max_mah_design; - di->vbat_nom = b->nominal_voltage; + di->vbat_nom_uv = + di->bm->bi.voltage_max_design_uv; } if (ret.intval) @@ -3078,8 +3084,7 @@ static int ab8500_fg_probe(struct platform_device *pdev) di->bat_cap.max_mah_design = di->bm->bi.charge_full_design_uah; di->bat_cap.max_mah = di->bat_cap.max_mah_design; - - di->vbat_nom = di->bm->bat_type->nominal_voltage; + di->vbat_nom_uv = di->bm->bi.voltage_max_design_uv; di->init_capacity = true; From patchwork Thu Nov 18 02:17:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625875 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 560E2C4332F for ; Thu, 18 Nov 2021 02:20:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3FA5461B31 for ; Thu, 18 Nov 2021 02:20:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242537AbhKRCXX (ORCPT ); Wed, 17 Nov 2021 21:23:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49272 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242530AbhKRCXS (ORCPT ); Wed, 17 Nov 2021 21:23:18 -0500 Received: from mail-lf1-x12b.google.com (mail-lf1-x12b.google.com [IPv6:2a00:1450:4864:20::12b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9463DC061570 for ; Wed, 17 Nov 2021 18:20:18 -0800 (PST) Received: by mail-lf1-x12b.google.com with SMTP id t26so17987961lfk.9 for ; Wed, 17 Nov 2021 18:20:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OxNCjc7MAwItE0Quq7/jM51++0N9X+9SGKjcFevR0vs=; b=NtJ3GsxjG6ca6VT0dZBFLYg2rZ/TLg3SgtIp/ZiA6DZNKQVkwNEA2C/7T6n9aGPYhX s4yzZUAhbbd6XwuSuMyLP8AgGfeezuXcOMaQGXnRNI0/g4FRtctjPFcn+yn7pGo1gdFq VCE7KC4JzPonJC2vf7LAPYrg+gyKa76YevK0ZSou/wGUfdXx75DQ+Knyc5sLbeEDGjb+ mjggsnbhzWr1xccr6FaifHau4DHDFIHTVtYlr9lfB4jBWW/TrS/ikrREvEB0brUzmrrX uRvysnzpt01AOV93SudkJbBx5lZPMBThDO4ENsSZ2XK8h6NGPl8fuihwIyER3qxiGIYN 3a/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OxNCjc7MAwItE0Quq7/jM51++0N9X+9SGKjcFevR0vs=; b=LluLuoF2DljmYaU/1NoDd4AuDhIOvTUfb+pw0v30LDZ51FJ6Oo1lVx68Wz3DpQHLZ7 4wzz4qLDqDsoXrJL6G2P5AhTQAqrbXFzq5rFAH32W600tc0v4z8DMr2Z4CJ3cDe4Y63v mQvjK530jThfYktod4ITvrt5GDo9u7tu5AUjx4GKB8pmJq9v96BynMrWAIGlkg/FscOE wy+zvc4RQ684lALT/1o94OJrxmpyGk0hkUpBI9N171TFhYGRnVHqeLzlB5x1LHeEXRXT CChtMDpTj4m9En19zugNc20KzwbXkpC36UwGeu+dnei5FA5LGlmL2BQuSeXr1NisfQer PPqA== X-Gm-Message-State: AOAM531G7HihoH/Duwm5CF74G2njThwah1PV3Cw9OxtOGOYFoh1olM50 qPucnv/QYXRU7vzd36lWXW5XZg== X-Google-Smtp-Source: ABdhPJzxEs2+20rCekhCR2yvTq85HsNgYBf3/3jiosawMSQ1RkrWh7mo4rIjX3izYtk1Ua7vzT0Nzw== X-Received: by 2002:a05:6512:2304:: with SMTP id o4mr20392488lfu.543.1637202016994; Wed, 17 Nov 2021 18:20:16 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.20.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:15 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 09/16] power: supply: ab8500_fg: Init battery data in bind() Date: Thu, 18 Nov 2021 03:17:45 +0100 Message-Id: <20211118021752.2262818-10-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org We were assigning some battery data state in probe() but this is insecure as it depends on the proper probe order between the components: the charger must probe first so that the battery data is populated. Move the init to the bind() call which is certain to happen after the probe of the master and all components has happened. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500_fg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c index ab6141faa798..daa008138b05 100644 --- a/drivers/power/supply/ab8500_fg.c +++ b/drivers/power/supply/ab8500_fg.c @@ -3023,6 +3023,10 @@ static int ab8500_fg_bind(struct device *dev, struct device *master, return -ENOMEM; } + di->bat_cap.max_mah_design = di->bm->bi.charge_full_design_uah; + di->bat_cap.max_mah = di->bat_cap.max_mah_design; + di->vbat_nom_uv = di->bm->bi.voltage_max_design_uv; + /* Start the coulomb counter */ ab8500_fg_coulomb_counter(di, true); /* Run the FG algorithm */ @@ -3082,10 +3086,6 @@ static int ab8500_fg_probe(struct platform_device *pdev) psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface); psy_cfg.drv_data = di; - di->bat_cap.max_mah_design = di->bm->bi.charge_full_design_uah; - di->bat_cap.max_mah = di->bat_cap.max_mah_design; - di->vbat_nom_uv = di->bm->bi.voltage_max_design_uv; - di->init_capacity = true; ab8500_fg_charge_state_to(di, AB8500_FG_CHARGE_INIT); From patchwork Thu Nov 18 02:17:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625879 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70433C43217 for ; Thu, 18 Nov 2021 02:20:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5C91C61B5F for ; Thu, 18 Nov 2021 02:20:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242496AbhKRCXX (ORCPT ); Wed, 17 Nov 2021 21:23:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49284 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242492AbhKRCXU (ORCPT ); Wed, 17 Nov 2021 21:23:20 -0500 Received: from mail-lf1-x132.google.com (mail-lf1-x132.google.com [IPv6:2a00:1450:4864:20::132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B4AD5C061764 for ; Wed, 17 Nov 2021 18:20:20 -0800 (PST) Received: by mail-lf1-x132.google.com with SMTP id b40so18100539lfv.10 for ; Wed, 17 Nov 2021 18:20:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Z2SmpuYl2ABnUfey0UDONLQlUHk1m7GyEzeYLIiNTVc=; b=Ye8/5x3879+HgQH6LM5rL2wntnqZQYdiCesoY39KeRHqi5R9tF3sxjZqi4kYa4hB1A X/2dlNue3QATkm0myDYOqX6/MRzP6pFPMmqaRuFtGGpCSpJSuNuCO+wSm58g8lyHZInY YDbdIAIV8SkJ+ulJqjCNPqIGQw5FAdFdMrIHCR6hDSkR8IXXv0EzJOmQjpZzhkEn+gRf 6XDjHIsfKzGRYYTqB4lrwYvLVVMuWMwff3jUOBOnrS1HkfNxNWnNilZD5gv3s23oZPQU ut08/tBX4BEu0cZSWX3xFzu6gcvv34RSf6fHWhDEcPnJG/B7opZ1e3K68rLp0gA+5jAP iYRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Z2SmpuYl2ABnUfey0UDONLQlUHk1m7GyEzeYLIiNTVc=; b=f4SmZeqoWif5Qik2UqE7N8zOnV8f3BGO4I93NDcUIxxTL6UlSp9hARTbGVhYPuE/fk x29o2mv3IQvWFsj5/62qHXXvLmQuctnFnJMil1KZqK5Yz72Zgy34pBQWwLkAXwqoXwU/ mNNsQrelKvoprR6uOv5viWDRxeUulshjCOvI2sm/+IxRLnWsMXxjEE24zMi4dYVZnNK2 iYuT6bjD/x3fFaRofYBYcKGiUtNCzgSiBsdSXh8t1KnDYJwW3h+2SHhiBGbpSXYJZKM4 AKXpD1fLwKOeaz1OEPDhr5EtilelFRq07NRL5dzMDzpJ7k7fzcYNlQ0FJH9I9EfbmBBl uE3w== X-Gm-Message-State: AOAM532eYBCO5dt6oXsTZqto04LPzRvi1e8cm2kJYI5jHVy5EObrOWLl taF0W+1aqcwNu6ZgOhC+y3DjCATCAwYLgg== X-Google-Smtp-Source: ABdhPJy0BtM9uM+piO8Hy74LjFy5Ass8s4CDaPpiCYp9v/cT29/7xzZCMuwnDqEyTI+9lskHIxrRZQ== X-Received: by 2002:a2e:9b47:: with SMTP id o7mr8519729ljj.346.1637202019118; Wed, 17 Nov 2021 18:20:19 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.20.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:18 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 10/16] power: supply: ab8500: Standardize internal resistance Date: Thu, 18 Nov 2021 03:17:46 +0100 Message-Id: <20211118021752.2262818-11-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The nominal internal resistance isn't used by the AB8500 charging code, instead this resistance is measured continuously, but we anyways migrate this to the standard property in struct power_supply_battery_info. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500-bm.h | 2 -- drivers/power/supply/ab8500_bmdata.c | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index 233fa86f9b2f..e6c5c9f5d4c5 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -388,7 +388,6 @@ struct ab8500_maxim_parameters { * @maint_b_chg_timer_h: charge time in maintenance B state * @low_high_cur_lvl: charger current in temp low/high state in mA * @low_high_vol_lvl: charger voltage in temp low/high state in mV' - * @battery_resistance: battery inner resistance in mOhm. * @n_r_t_tbl_elements: number of elements in r_to_t_tbl * @r_to_t_tbl: table containing resistance to temp points * @n_v_cap_tbl_elements: number of elements in v_to_cap_tbl @@ -411,7 +410,6 @@ struct ab8500_battery_type { int maint_b_chg_timer_h; int low_high_cur_lvl; int low_high_vol_lvl; - int battery_resistance; int n_temp_tbl_elements; const struct ab8500_res_to_temp *r_to_t_tbl; int n_v_cap_tbl_elements; diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index 17df619cdf36..2532499afe5f 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -83,7 +83,6 @@ static const struct batres_vs_temp temp_to_batres_tbl_thermistor[] = { static struct ab8500_battery_type bat_type_thermistor_unknown = { .resis_high = 0, .resis_low = 0, - .battery_resistance = 300, .termination_curr = 200, .recharge_cap = 95, .normal_cur_lvl = 400, @@ -204,6 +203,9 @@ int ab8500_bm_of_probe(struct power_supply *psy, bi->overvoltage_limit_uv = 4050000; } + if (bi->factory_internal_resistance_uohm < 0) + bi->factory_internal_resistance_uohm = 300000; + if (bi->temp_min == INT_MIN) bi->temp_min = AB8500_TEMP_UNDER; if (bi->temp_max == INT_MAX) From patchwork Thu Nov 18 02:17:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625877 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49566C43219 for ; Thu, 18 Nov 2021 02:20:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 30AB061AD2 for ; Thu, 18 Nov 2021 02:20:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242530AbhKRCXY (ORCPT ); Wed, 17 Nov 2021 21:23:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49294 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242531AbhKRCXW (ORCPT ); Wed, 17 Nov 2021 21:23:22 -0500 Received: from mail-lf1-x130.google.com (mail-lf1-x130.google.com [IPv6:2a00:1450:4864:20::130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 001C6C061570 for ; Wed, 17 Nov 2021 18:20:22 -0800 (PST) Received: by mail-lf1-x130.google.com with SMTP id l22so17866529lfg.7 for ; Wed, 17 Nov 2021 18:20:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=iZkBzt3OCa2/wdkm1AutmV7G/2eh4Kgn3EYGOFGI8+E=; b=nqtnNMPMvRy+WA0ZueVWJywl4Y4uoU/s/bhG0BX7CZaijrnXgtvJ2H8z5TgIik18cX c0GWQyS7LWoyGGeoNbDIxcPWWAYaP63ICHBCAs6DX8qQzHzImGo1ziU461F2ZoYw6DZi WqJD/qTlYhETGCYPgpOt4AYZwHmIeCUzwEj+WlR8KykFodOeV/ODy+Edmvu+7jr8B1pL SCvqrR2qCtzTdMs+CGJS+454NKrZsoiOMGMYgO7rKNwy1OdbIJmODymxQ5P9AjvzEylg z17y1TLQBhT7qMaDlzDIXhsyscEHzjtG5ezae/JsZZqRVqKgIKdO0ZMRLVMNtpDw/CYO zIXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=iZkBzt3OCa2/wdkm1AutmV7G/2eh4Kgn3EYGOFGI8+E=; b=DY2j/7TTwK7D2ALX4rGDAseOdEcahdrk98P2AQn9K5FWpulnPlEeiP9sM/SWxnt09h umhjjxqeuMCVUI6+oWCSDNuV2EEgj8mEjh67/dXi11ZQYuDDQwnwd5vce+Ke2Ku7PWnQ WVoc1Ziqsiua1EqgmQt8No6XSLKD6qowEn1kUIvoLBi67Bg0hio3RDSC8+p7rSn1AzrI QmBH6IGYlF2CmJdFKyuOV32wV2CYdrWSeBZi65tBxtrBNfn+2z0uonunAGmjSDbqlmac ERtYga0cSEFhjEk7LC3rHcsbbfDh9fgl9FynNp8TToRmUTXvNzxv61dmHr6rhwjGM57R oaqA== X-Gm-Message-State: AOAM530wrlKUNpYAXB3HetgCeDcERCZkwBeq5df8WELbbLXUtiu2gfS0 wijvgbgfqDe1VSLeSzjPx+z2rdcT/O14kw== X-Google-Smtp-Source: ABdhPJxzBrxmoUP2dM6xgjU8PqbkJpWMR3jrwsU5H89NelGce3lNePthziKdc3rlyDchyrdyNMfeZQ== X-Received: by 2002:ac2:46c8:: with SMTP id p8mr20144850lfo.174.1637202021376; Wed, 17 Nov 2021 18:20:21 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.20.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:20 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 11/16] power: supply: ab8500: Standardize termination current Date: Thu, 18 Nov 2021 03:17:47 +0100 Message-Id: <20211118021752.2262818-12-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The AB8500 custom termination current can be replaced by the corresponding struct power_supply_battery_info field. Remove the struct member and amend the code to use the standard property. Add *_ua suffix for clarity and to make sure we have changed all code sites using this member. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500-bm.h | 2 -- drivers/power/supply/ab8500_bmdata.c | 5 ++++- drivers/power/supply/ab8500_chargalg.c | 12 ++++++------ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index e6c5c9f5d4c5..949e6d9f13c7 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -374,7 +374,6 @@ struct ab8500_maxim_parameters { * struct ab8500_battery_type - different batteries supported * @resis_high: battery upper resistance limit * @resis_low: battery lower resistance limit - * @termination_curr battery charging termination current in mA * @recharge_cap battery capacity limit that will trigger a new * full charging cycle in the case where maintenan- * -ce charging has been disabled @@ -398,7 +397,6 @@ struct ab8500_maxim_parameters { struct ab8500_battery_type { int resis_high; int resis_low; - int termination_curr; int recharge_cap; int normal_cur_lvl; int normal_vol_lvl; diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index 2532499afe5f..1e43c9f751e1 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -83,7 +83,6 @@ static const struct batres_vs_temp temp_to_batres_tbl_thermistor[] = { static struct ab8500_battery_type bat_type_thermistor_unknown = { .resis_high = 0, .resis_low = 0, - .termination_curr = 200, .recharge_cap = 95, .normal_cur_lvl = 400, .normal_vol_lvl = 4100, @@ -203,6 +202,10 @@ int ab8500_bm_of_probe(struct power_supply *psy, bi->overvoltage_limit_uv = 4050000; } + if (bi->charge_term_current_ua) + /* Charging stops when we drop below this current */ + bi->charge_term_current_ua = 200000; + if (bi->factory_internal_resistance_uohm < 0) bi->factory_internal_resistance_uohm = 300000; diff --git a/drivers/power/supply/ab8500_chargalg.c b/drivers/power/supply/ab8500_chargalg.c index dd9cad63e37e..49e7167d0362 100644 --- a/drivers/power/supply/ab8500_chargalg.c +++ b/drivers/power/supply/ab8500_chargalg.c @@ -87,7 +87,7 @@ struct ab8500_chargalg_current_step_status { struct ab8500_chargalg_battery_data { int temp; int volt_uv; - int avg_curr; + int avg_curr_ua; int inst_curr; int percent; }; @@ -795,9 +795,9 @@ static void ab8500_chargalg_end_of_charge(struct ab8500_chargalg *di) !di->maintenance_chg && (di->batt_data.volt_uv >= di->bm->bi.overvoltage_limit_uv || di->events.usb_cv_active || di->events.ac_cv_active) && - di->batt_data.avg_curr < - di->bm->bat_type->termination_curr && - di->batt_data.avg_curr > 0) { + di->batt_data.avg_curr_ua < + di->bm->bi.charge_term_current_ua && + di->batt_data.avg_curr_ua > 0) { if (++di->eoc_cnt >= EOC_COND_CNT) { di->eoc_cnt = 0; di->charge_status = POWER_SUPPLY_STATUS_FULL; @@ -1237,7 +1237,7 @@ static int ab8500_chargalg_get_ext_psy_data(struct device *dev, void *data) case POWER_SUPPLY_PROP_CURRENT_AVG: switch (ext->desc->type) { case POWER_SUPPLY_TYPE_BATTERY: - di->batt_data.avg_curr = ret.intval / 1000; + di->batt_data.avg_curr_ua = ret.intval; break; case POWER_SUPPLY_TYPE_USB: if (ret.intval) @@ -1398,7 +1398,7 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) "AC_online %d USB_online %d AC_CV %d USB_CV %d AC_I %d " "USB_I %d AC_Vset %d AC_Iset %d USB_Vset %d USB_Iset %d\n", di->batt_data.volt_uv, - di->batt_data.avg_curr, + di->batt_data.avg_curr_ua, di->batt_data.inst_curr, di->batt_data.temp, di->batt_data.percent, From patchwork Thu Nov 18 02:17:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625883 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 66A4CC433F5 for ; Thu, 18 Nov 2021 02:20:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4CDE861AF0 for ; Thu, 18 Nov 2021 02:20:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242497AbhKRCXZ (ORCPT ); Wed, 17 Nov 2021 21:23:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49302 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242494AbhKRCXY (ORCPT ); Wed, 17 Nov 2021 21:23:24 -0500 Received: from mail-lf1-x136.google.com (mail-lf1-x136.google.com [IPv6:2a00:1450:4864:20::136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4A03BC061570 for ; Wed, 17 Nov 2021 18:20:25 -0800 (PST) Received: by mail-lf1-x136.google.com with SMTP id n12so18191164lfe.1 for ; Wed, 17 Nov 2021 18:20:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=bkJmaZyXa0qnJQKIEoPV8/w271B2CRpKLAwKWy8RIwE=; b=xMlTqLprZbVHcF1CWqhxPnqDmx/x10f29Irh3BDV1LE+cLqwGMH9btMWbDEVpWkCjQ 84mCDyxYDA+w1SBfrJLqblqLnjVf5VHpGGdj71c6Sr+uiUSs/K98LfQd8ImygN/q88RT XFA8PxeCoRj+42sMlSrxrBGrmO36g/ZOeEcQbWOncbsf5QaVtKy+Q0Rm2azO8hymMitz l8UFk3n6F5nc5y8CQNzcsZUSC7nWZPaEJIgBc+1tMZ18+vKggdedsexCHKXgPHRc9DJW 6GX1WeSCZH0DJoHNzum8NFuppqiW3IqBVBrk2fgqxs7/vV4YKtFJADa85sMPYqVO3yWC ZNrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=bkJmaZyXa0qnJQKIEoPV8/w271B2CRpKLAwKWy8RIwE=; b=QFVBwfJcb5ndGMV1ywIn8AIeKPNr8R8XD+rlzvYLw2XJmhChg0LnlrCQUcQLMTiTmO 0ivOkCK6ufjQALbXEFUk/EwusC1vthoo6LfjN1QtPugz5lZ5fcYTMNisLocWasKvv/ra 2BgcndaxgWG2rrpeCmhKDmBPW6FPdNCuxBWeBzp3xO3gcI7Ri5puyKRNVDJ5FuOTyuup FsrcNPzDG+Y9EK9dJW4WzioBPcybCRPb5tgvDgEUGMgUCtQGh4ZdSq2lPnljwnqeZdBq fvzLFdXCG3C3J+YWQMjnn/3DdAM0VpVgpSKn0lJ7yRT7BYwtKG4mRBAzQIapICXgdMda JP6w== X-Gm-Message-State: AOAM530w+csuOaDkuBNPkaWXm8E5YKOBD1Y4fN4jdy26W5ziomYt9zLf Z8paGWF19AU8EZ4x2jeTE/8ksPvItDCBwg== X-Google-Smtp-Source: ABdhPJwe4K98YcmCQetAJiRqjf8DtF/oX9XfxdCuOTp2RuNSL8JAQ03vIVwwHEGH5PzKfB8k/YAN9Q== X-Received: by 2002:a19:c3d5:: with SMTP id t204mr20125107lff.303.1637202023686; Wed, 17 Nov 2021 18:20:23 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.20.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:22 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 12/16] power: supply: ab8500: Make recharge capacity a constant Date: Thu, 18 Nov 2021 03:17:48 +0100 Message-Id: <20211118021752.2262818-13-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The recharge capacity is the hysteresis level for a charger to restart when a battery does not support maintenance charging. All products using the AB8500 have batteries supporting maintenace charging and all code has always set this to 95%. Turn it into a constant. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500-bm.h | 4 ---- drivers/power/supply/ab8500_bmdata.c | 1 - drivers/power/supply/ab8500_chargalg.c | 10 ++++++++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index 949e6d9f13c7..5f515d2a2260 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -374,9 +374,6 @@ struct ab8500_maxim_parameters { * struct ab8500_battery_type - different batteries supported * @resis_high: battery upper resistance limit * @resis_low: battery lower resistance limit - * @recharge_cap battery capacity limit that will trigger a new - * full charging cycle in the case where maintenan- - * -ce charging has been disabled * @normal_cur_lvl: charger current in normal state in mA * @normal_vol_lvl: charger voltage in normal state in mV * @maint_a_cur_lvl: charger current in maintenance A state in mA @@ -397,7 +394,6 @@ struct ab8500_maxim_parameters { struct ab8500_battery_type { int resis_high; int resis_low; - int recharge_cap; int normal_cur_lvl; int normal_vol_lvl; int maint_a_cur_lvl; diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index 1e43c9f751e1..18d83a0e5a7d 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -83,7 +83,6 @@ static const struct batres_vs_temp temp_to_batres_tbl_thermistor[] = { static struct ab8500_battery_type bat_type_thermistor_unknown = { .resis_high = 0, .resis_low = 0, - .recharge_cap = 95, .normal_cur_lvl = 400, .normal_vol_lvl = 4100, .maint_a_cur_lvl = 400, diff --git a/drivers/power/supply/ab8500_chargalg.c b/drivers/power/supply/ab8500_chargalg.c index 49e7167d0362..90974a8887cd 100644 --- a/drivers/power/supply/ab8500_chargalg.c +++ b/drivers/power/supply/ab8500_chargalg.c @@ -49,6 +49,13 @@ #define CHARGALG_CURR_STEP_LOW 0 #define CHARGALG_CURR_STEP_HIGH 100 +/* + * This is the battery capacity limit that will trigger a new + * full charging cycle in the case where maintenance charging + * has been disabled + */ +#define AB8500_RECHARGE_CAP 95 + enum ab8500_chargers { NO_CHG, AC_CHG, @@ -1544,8 +1551,7 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) fallthrough; case STATE_WAIT_FOR_RECHARGE: - if (di->batt_data.percent <= - di->bm->bat_type->recharge_cap) + if (di->batt_data.percent <= AB8500_RECHARGE_CAP) ab8500_chargalg_state_to(di, STATE_NORMAL_INIT); break; From patchwork Thu Nov 18 02:17:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625885 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3836DC433F5 for ; Thu, 18 Nov 2021 02:20:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1CE6F61AD0 for ; Thu, 18 Nov 2021 02:20:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242492AbhKRCX2 (ORCPT ); Wed, 17 Nov 2021 21:23:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49318 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241550AbhKRCX1 (ORCPT ); Wed, 17 Nov 2021 21:23:27 -0500 Received: from mail-lf1-x134.google.com (mail-lf1-x134.google.com [IPv6:2a00:1450:4864:20::134]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 08A34C061764 for ; Wed, 17 Nov 2021 18:20:28 -0800 (PST) Received: by mail-lf1-x134.google.com with SMTP id k37so18187204lfv.3 for ; Wed, 17 Nov 2021 18:20:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=laseDBS2IGIUV3COgCz0VIMY2aMcVPIjjni2hHzcWtQ=; b=hEIY6EwRmqECckyn3UF+vPAW6VfoDNta73qeT2KzeHFDSIUxBlNF4GnjGYImJyQhyE VB9TIvuHZURbej5OjTCL5mxwxj1O0m07GjCwRYNWmyKdgKsUqa0lYYciSjSyD1z/lHdy i8+0qaWL0faC9aoJl1V5IUeJx0PAQk7fC8MCa4ilj0mszR7ePG5KI4sTLGZznw6r/IV1 Hu0YmzS90fc5IQ9LtkB+x9oQgKoXiQ7CPtkFX1fZrQT9qf8TqvX7+jekFuz29kvlQAO0 7KNc0yu/vt16anXbN4kqEof4lj5RLcv7cKXHBm6UEsezGipRcE9J7IyH4ez7BnT0oBoO 5jUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=laseDBS2IGIUV3COgCz0VIMY2aMcVPIjjni2hHzcWtQ=; b=SLCrHQFrdRTR6DkrEEMPFKVgtEDccecvj9h49t/AItUhMIuZPYM9J6QXMW6bhrytxh bSKghelhRLx0sobrE+d1Qmw7j8+5NG859uQjqQrx8yu6mcF0QZAUWNpbv6sMnCGc1kqM Hi3Q5k5R+7byKAVFIagWoVQ0+Ua5/a5ezZNP9YM9yF2klUl4fIgjoGuSS5oBJ8hxJidi okAMDtrW+ujLVAKDme0S+o63COsaelSk5YYnWQT3RqKDNPZ9obqizisMBCPJc3u66kxr T8Tha4hUKnvWwPHE22pIhYE0OFATI/64ep1F2Svv/lwoYjLJYSXiaDa3K4jOzRvNTa8S hZjA== X-Gm-Message-State: AOAM531KryG8kFTPQ+rCdQXTuunSWYeyzFhnBPX6txLB/2z1zjYzpou9 iVWQESRVGT5HBbtVT3da6aoU1lVOsobYqA== X-Google-Smtp-Source: ABdhPJyDYPFYPhoeabN3hOqQs5iG559ivFGd0xRYpGwSTECBC+TpxcJX5gTaa1iMsPjUVcsoyz+DPA== X-Received: by 2002:a19:c352:: with SMTP id t79mr20574599lff.251.1637202025912; Wed, 17 Nov 2021 18:20:25 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.20.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:25 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 13/16] power: supply: ab8500: Standardize CC current Date: Thu, 18 Nov 2021 03:17:49 +0100 Message-Id: <20211118021752.2262818-14-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The current used in the constant current phase of the charging exist in struct power_supply_battery_info as constant_charge_current_max_ua. Switch the custom property max_out_curr to this and consequentally change everything that relates to this value over to using microamperes rather than milliamperes so we align internal representation of current with the power core. Prefix every variable we change with *_ua to indicate the unit everywhere but also to make sure we do not miss any outlier. Drop some duplicate unused defines in a header. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500-bm.h | 25 +- drivers/power/supply/ab8500-chargalg.h | 4 +- drivers/power/supply/ab8500_bmdata.c | 12 +- drivers/power/supply/ab8500_chargalg.c | 194 ++++++++-------- drivers/power/supply/ab8500_charger.c | 301 +++++++++++++------------ 5 files changed, 270 insertions(+), 266 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index 5f515d2a2260..e015bb6e7684 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -160,13 +160,6 @@ #define BTEMP_HIGH_TH_57_1 0x02 #define BTEMP_HIGH_TH_62 0x03 -/* current is mA */ -#define USB_0P1A 100 -#define USB_0P2A 200 -#define USB_0P3A 300 -#define USB_0P4A 400 -#define USB_0P5A 500 - #define LOW_BAT_3P1V 0x20 #define LOW_BAT_2P3V 0x00 #define LOW_BAT_RESET 0x01 @@ -359,22 +352,21 @@ struct ab8500_fg_parameters { /** * struct ab8500_charger_maximization - struct used by the board config. * @use_maxi: Enable maximization for this battery type - * @maxi_chg_curr: Maximum charger current allowed + * @maxi_chg_curr_ua: Maximum charger current allowed in microampere * @maxi_wait_cycles: cycles to wait before setting charger current - * @charger_curr_step delta between two charger current settings (mA) + * @charger_curr_step_ua: delta between two charger current settings (uA) */ struct ab8500_maxim_parameters { bool ena_maxi; - int chg_curr; + int chg_curr_ua; int wait_cycles; - int charger_curr_step; + int charger_curr_step_ua; }; /** * struct ab8500_battery_type - different batteries supported * @resis_high: battery upper resistance limit * @resis_low: battery lower resistance limit - * @normal_cur_lvl: charger current in normal state in mA * @normal_vol_lvl: charger voltage in normal state in mV * @maint_a_cur_lvl: charger current in maintenance A state in mA * @maint_a_vol_lvl: charger voltage in maintenance A state in mV @@ -394,7 +386,6 @@ struct ab8500_maxim_parameters { struct ab8500_battery_type { int resis_high; int resis_low; - int normal_cur_lvl; int normal_vol_lvl; int maint_a_cur_lvl; int maint_a_vol_lvl; @@ -431,15 +422,15 @@ struct ab8500_bm_capacity_levels { /** * struct ab8500_bm_charger_parameters - Charger specific parameters * @usb_volt_max: maximum allowed USB charger voltage in mV - * @usb_curr_max: maximum allowed USB charger current in mA + * @usb_curr_max_ua: maximum allowed USB charger current in uA * @ac_volt_max: maximum allowed AC charger voltage in mV - * @ac_curr_max: maximum allowed AC charger current in mA + * @ac_curr_max_ua: maximum allowed AC charger current in uA */ struct ab8500_bm_charger_parameters { int usb_volt_max; - int usb_curr_max; + int usb_curr_max_ua; int ac_volt_max; - int ac_curr_max; + int ac_curr_max_ua; }; /** diff --git a/drivers/power/supply/ab8500-chargalg.h b/drivers/power/supply/ab8500-chargalg.h index 07e6ff50084f..8094a3c2bd3a 100644 --- a/drivers/power/supply/ab8500-chargalg.h +++ b/drivers/power/supply/ab8500-chargalg.h @@ -32,7 +32,7 @@ struct ux500_charger_ops { * @psy power supply base class * @ops ux500 charger operations * @max_out_volt maximum output charger voltage in mV - * @max_out_curr maximum output charger current in mA + * @max_out_curr_ua maximum output charger current in uA * @enabled indicates if this charger is used or not * @external external charger unit (pm2xxx) */ @@ -40,7 +40,7 @@ struct ux500_charger { struct power_supply *psy; struct ux500_charger_ops ops; int max_out_volt; - int max_out_curr; + int max_out_curr_ua; int wdt_refresh; bool enabled; bool external; diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index 18d83a0e5a7d..ff17fc4593cc 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -83,7 +83,6 @@ static const struct batres_vs_temp temp_to_batres_tbl_thermistor[] = { static struct ab8500_battery_type bat_type_thermistor_unknown = { .resis_high = 0, .resis_low = 0, - .normal_cur_lvl = 400, .normal_vol_lvl = 4100, .maint_a_cur_lvl = 400, .maint_a_vol_lvl = 4050, @@ -133,16 +132,16 @@ static const struct ab8500_fg_parameters fg = { static const struct ab8500_maxim_parameters ab8500_maxi_params = { .ena_maxi = true, - .chg_curr = 910, + .chg_curr_ua = 910000, .wait_cycles = 10, - .charger_curr_step = 100, + .charger_curr_step_ua = 100000, }; static const struct ab8500_bm_charger_parameters chg = { .usb_volt_max = 5500, - .usb_curr_max = 1500, + .usb_curr_max_ua = 1500000, .ac_volt_max = 7500, - .ac_curr_max = 1500, + .ac_curr_max_ua = 1500000, }; /* This is referenced directly in the charger code */ @@ -201,6 +200,9 @@ int ab8500_bm_of_probe(struct power_supply *psy, bi->overvoltage_limit_uv = 4050000; } + if (bi->constant_charge_current_max_ua < 0) + bi->constant_charge_current_max_ua = 400000; + if (bi->charge_term_current_ua) /* Charging stops when we drop below this current */ bi->charge_term_current_ua = 200000; diff --git a/drivers/power/supply/ab8500_chargalg.c b/drivers/power/supply/ab8500_chargalg.c index 90974a8887cd..8ad3924ee496 100644 --- a/drivers/power/supply/ab8500_chargalg.c +++ b/drivers/power/supply/ab8500_chargalg.c @@ -46,8 +46,8 @@ /* Five minutes expressed in seconds */ #define FIVE_MINUTES_IN_SECONDS 300 -#define CHARGALG_CURR_STEP_LOW 0 -#define CHARGALG_CURR_STEP_HIGH 100 +#define CHARGALG_CURR_STEP_LOW_UA 0 +#define CHARGALG_CURR_STEP_HIGH_UA 100000 /* * This is the battery capacity limit that will trigger a new @@ -71,13 +71,13 @@ struct ab8500_chargalg_charger_info { bool usb_chg_ok; bool ac_chg_ok; int usb_volt; - int usb_curr; + int usb_curr_ua; int ac_volt; - int ac_curr; + int ac_curr_ua; int usb_vset; - int usb_iset; + int usb_iset_ua; int ac_vset; - int ac_iset; + int ac_iset_ua; }; struct ab8500_chargalg_suspension_status { @@ -88,14 +88,14 @@ struct ab8500_chargalg_suspension_status { struct ab8500_chargalg_current_step_status { bool curr_step_change; - int curr_step; + int curr_step_ua; }; struct ab8500_chargalg_battery_data { int temp; int volt_uv; int avg_curr_ua; - int inst_curr; + int inst_curr_ua; int percent; }; @@ -184,13 +184,13 @@ struct ab8500_chargalg_events { /** * struct ab8500_charge_curr_maximization - Charger maximization parameters - * @original_iset: the non optimized/maximised charger current - * @current_iset: the charging current used at this moment - * @test_delta_i: the delta between the current we want to charge and the + * @original_iset_ua: the non optimized/maximised charger current + * @current_iset_ua: the charging current used at this moment + * @test_delta_i_ua: the delta between the current we want to charge and the current that is really going into the battery * @condition_cnt: number of iterations needed before a new charger current is set - * @max_current: maximum charger current + * @max_current_ua: maximum charger current * @wait_cnt: to avoid too fast current step down in case of charger * voltage collapse, we insert this delay between step * down @@ -198,11 +198,11 @@ struct ab8500_chargalg_events { increased */ struct ab8500_charge_curr_maximization { - int original_iset; - int current_iset; - int test_delta_i; + int original_iset_ua; + int current_iset_ua; + int test_delta_i_ua; int condition_cnt; - int max_current; + int max_current_ua; int wait_cnt; u8 level; }; @@ -352,6 +352,8 @@ static void ab8500_chargalg_state_to(struct ab8500_chargalg *di, static int ab8500_chargalg_check_charger_enable(struct ab8500_chargalg *di) { + struct power_supply_battery_info *bi = &di->bm->bi; + switch (di->charge_state) { case STATE_NORMAL: case STATE_MAINTENANCE_A: @@ -364,12 +366,12 @@ static int ab8500_chargalg_check_charger_enable(struct ab8500_chargalg *di) if (di->chg_info.charger_type & USB_CHG) { return di->usb_chg->ops.check_enable(di->usb_chg, di->bm->bat_type->normal_vol_lvl, - di->bm->bat_type->normal_cur_lvl); + bi->constant_charge_current_max_ua); } else if ((di->chg_info.charger_type & AC_CHG) && !(di->ac_chg->external)) { return di->ac_chg->ops.check_enable(di->ac_chg, di->bm->bat_type->normal_vol_lvl, - di->bm->bat_type->normal_cur_lvl); + bi->constant_charge_current_max_ua); } return 0; } @@ -545,13 +547,13 @@ static int ab8500_chargalg_kick_watchdog(struct ab8500_chargalg *di) * @di: pointer to the ab8500_chargalg structure * @enable: charger on/off * @vset: requested charger output voltage - * @iset: requested charger output current + * @iset_ua: requested charger output current in microampere * * The AC charger will be turned on/off with the requested charge voltage and * current */ static int ab8500_chargalg_ac_en(struct ab8500_chargalg *di, int enable, - int vset, int iset) + int vset, int iset_ua) { static int ab8500_chargalg_ex_ac_enable_toggle; @@ -561,10 +563,10 @@ static int ab8500_chargalg_ac_en(struct ab8500_chargalg *di, int enable, /* Select maximum of what both the charger and the battery supports */ if (di->ac_chg->max_out_volt) vset = min(vset, di->ac_chg->max_out_volt); - if (di->ac_chg->max_out_curr) - iset = min(iset, di->ac_chg->max_out_curr); + if (di->ac_chg->max_out_curr_ua) + iset_ua = min(iset_ua, di->ac_chg->max_out_curr_ua); - di->chg_info.ac_iset = iset; + di->chg_info.ac_iset_ua = iset_ua; di->chg_info.ac_vset = vset; /* Enable external charger */ @@ -575,7 +577,7 @@ static int ab8500_chargalg_ac_en(struct ab8500_chargalg *di, int enable, ab8500_chargalg_ex_ac_enable_toggle++; } - return di->ac_chg->ops.enable(di->ac_chg, enable, vset, iset); + return di->ac_chg->ops.enable(di->ac_chg, enable, vset, iset_ua); } /** @@ -583,13 +585,13 @@ static int ab8500_chargalg_ac_en(struct ab8500_chargalg *di, int enable, * @di: pointer to the ab8500_chargalg structure * @enable: charger on/off * @vset: requested charger output voltage - * @iset: requested charger output current + * @iset_ua: requested charger output current in microampere * * The USB charger will be turned on/off with the requested charge voltage and * current */ static int ab8500_chargalg_usb_en(struct ab8500_chargalg *di, int enable, - int vset, int iset) + int vset, int iset_ua) { if (!di->usb_chg || !di->usb_chg->ops.enable) return -ENXIO; @@ -597,25 +599,25 @@ static int ab8500_chargalg_usb_en(struct ab8500_chargalg *di, int enable, /* Select maximum of what both the charger and the battery supports */ if (di->usb_chg->max_out_volt) vset = min(vset, di->usb_chg->max_out_volt); - if (di->usb_chg->max_out_curr) - iset = min(iset, di->usb_chg->max_out_curr); + if (di->usb_chg->max_out_curr_ua) + iset_ua = min(iset_ua, di->usb_chg->max_out_curr_ua); - di->chg_info.usb_iset = iset; + di->chg_info.usb_iset_ua = iset_ua; di->chg_info.usb_vset = vset; - return di->usb_chg->ops.enable(di->usb_chg, enable, vset, iset); + return di->usb_chg->ops.enable(di->usb_chg, enable, vset, iset_ua); } /** * ab8500_chargalg_update_chg_curr() - Update charger current * @di: pointer to the ab8500_chargalg structure - * @iset: requested charger output current + * @iset_ua: requested charger output current in microampere * * The charger output current will be updated for the charger * that is currently in use */ static int ab8500_chargalg_update_chg_curr(struct ab8500_chargalg *di, - int iset) + int iset_ua) { /* Check if charger exists and update current if charging */ if (di->ac_chg && di->ac_chg->ops.update_curr && @@ -624,24 +626,24 @@ static int ab8500_chargalg_update_chg_curr(struct ab8500_chargalg *di, * Select maximum of what both the charger * and the battery supports */ - if (di->ac_chg->max_out_curr) - iset = min(iset, di->ac_chg->max_out_curr); + if (di->ac_chg->max_out_curr_ua) + iset_ua = min(iset_ua, di->ac_chg->max_out_curr_ua); - di->chg_info.ac_iset = iset; + di->chg_info.ac_iset_ua = iset_ua; - return di->ac_chg->ops.update_curr(di->ac_chg, iset); + return di->ac_chg->ops.update_curr(di->ac_chg, iset_ua); } else if (di->usb_chg && di->usb_chg->ops.update_curr && di->chg_info.charger_type & USB_CHG) { /* * Select maximum of what both the charger * and the battery supports */ - if (di->usb_chg->max_out_curr) - iset = min(iset, di->usb_chg->max_out_curr); + if (di->usb_chg->max_out_curr_ua) + iset_ua = min(iset_ua, di->usb_chg->max_out_curr_ua); - di->chg_info.usb_iset = iset; + di->chg_info.usb_iset_ua = iset_ua; - return di->usb_chg->ops.update_curr(di->usb_chg, iset); + return di->usb_chg->ops.update_curr(di->usb_chg, iset_ua); } return -ENXIO; @@ -691,27 +693,27 @@ static void ab8500_chargalg_hold_charging(struct ab8500_chargalg *di) * ab8500_chargalg_start_charging() - Start the charger * @di: pointer to the ab8500_chargalg structure * @vset: requested charger output voltage - * @iset: requested charger output current + * @iset_ua: requested charger output current in microampere * * A charger will be enabled depending on the requested charger type that was * detected previously. */ static void ab8500_chargalg_start_charging(struct ab8500_chargalg *di, - int vset, int iset) + int vset, int iset_ua) { switch (di->chg_info.charger_type) { case AC_CHG: dev_dbg(di->dev, - "AC parameters: Vset %d, Ich %d\n", vset, iset); + "AC parameters: Vset %d, Ich %d\n", vset, iset_ua); ab8500_chargalg_usb_en(di, false, 0, 0); - ab8500_chargalg_ac_en(di, true, vset, iset); + ab8500_chargalg_ac_en(di, true, vset, iset_ua); break; case USB_CHG: dev_dbg(di->dev, - "USB parameters: Vset %d, Ich %d\n", vset, iset); + "USB parameters: Vset %d, Ich %d\n", vset, iset_ua); ab8500_chargalg_ac_en(di, false, 0, 0); - ab8500_chargalg_usb_en(di, true, vset, iset); + ab8500_chargalg_usb_en(di, true, vset, iset_ua); break; default: @@ -825,12 +827,12 @@ static void ab8500_chargalg_end_of_charge(struct ab8500_chargalg *di) static void init_maxim_chg_curr(struct ab8500_chargalg *di) { - di->ccm.original_iset = - di->bm->bat_type->normal_cur_lvl; - di->ccm.current_iset = - di->bm->bat_type->normal_cur_lvl; - di->ccm.test_delta_i = di->bm->maxi->charger_curr_step; - di->ccm.max_current = di->bm->maxi->chg_curr; + struct power_supply_battery_info *bi = &di->bm->bi; + + di->ccm.original_iset_ua = bi->constant_charge_current_max_ua; + di->ccm.current_iset_ua = bi->constant_charge_current_max_ua; + di->ccm.test_delta_i_ua = di->bm->maxi->charger_curr_step_ua; + di->ccm.max_current_ua = di->bm->maxi->chg_curr_ua; di->ccm.condition_cnt = di->bm->maxi->wait_cycles; di->ccm.level = 0; } @@ -846,12 +848,12 @@ static void init_maxim_chg_curr(struct ab8500_chargalg *di) */ static enum maxim_ret ab8500_chargalg_chg_curr_maxim(struct ab8500_chargalg *di) { - int delta_i; + int delta_i_ua; if (!di->bm->maxi->ena_maxi) return MAXIM_RET_NOACTION; - delta_i = di->ccm.original_iset - di->batt_data.inst_curr; + delta_i_ua = di->ccm.original_iset_ua - di->batt_data.inst_curr_ua; if (di->events.vbus_collapsed) { dev_dbg(di->dev, "Charger voltage has collapsed %d\n", @@ -860,9 +862,9 @@ static enum maxim_ret ab8500_chargalg_chg_curr_maxim(struct ab8500_chargalg *di) dev_dbg(di->dev, "lowering current\n"); di->ccm.wait_cnt++; di->ccm.condition_cnt = di->bm->maxi->wait_cycles; - di->ccm.max_current = - di->ccm.current_iset - di->ccm.test_delta_i; - di->ccm.current_iset = di->ccm.max_current; + di->ccm.max_current_ua = + di->ccm.current_iset_ua - di->ccm.test_delta_i_ua; + di->ccm.current_iset_ua = di->ccm.max_current_ua; di->ccm.level--; return MAXIM_RET_CHANGE; } else { @@ -875,36 +877,36 @@ static enum maxim_ret ab8500_chargalg_chg_curr_maxim(struct ab8500_chargalg *di) di->ccm.wait_cnt = 0; - if (di->batt_data.inst_curr > di->ccm.original_iset) { - dev_dbg(di->dev, " Maximization Ibat (%dmA) too high" - " (limit %dmA) (current iset: %dmA)!\n", - di->batt_data.inst_curr, di->ccm.original_iset, - di->ccm.current_iset); + if (di->batt_data.inst_curr_ua > di->ccm.original_iset_ua) { + dev_dbg(di->dev, " Maximization Ibat (%duA) too high" + " (limit %duA) (current iset: %duA)!\n", + di->batt_data.inst_curr_ua, di->ccm.original_iset_ua, + di->ccm.current_iset_ua); - if (di->ccm.current_iset == di->ccm.original_iset) + if (di->ccm.current_iset_ua == di->ccm.original_iset_ua) return MAXIM_RET_NOACTION; di->ccm.condition_cnt = di->bm->maxi->wait_cycles; - di->ccm.current_iset = di->ccm.original_iset; + di->ccm.current_iset_ua = di->ccm.original_iset_ua; di->ccm.level = 0; return MAXIM_RET_IBAT_TOO_HIGH; } - if (delta_i > di->ccm.test_delta_i && - (di->ccm.current_iset + di->ccm.test_delta_i) < - di->ccm.max_current) { + if (delta_i_ua > di->ccm.test_delta_i_ua && + (di->ccm.current_iset_ua + di->ccm.test_delta_i_ua) < + di->ccm.max_current_ua) { if (di->ccm.condition_cnt-- == 0) { /* Increse the iset with cco.test_delta_i */ di->ccm.condition_cnt = di->bm->maxi->wait_cycles; - di->ccm.current_iset += di->ccm.test_delta_i; + di->ccm.current_iset_ua += di->ccm.test_delta_i_ua; di->ccm.level++; dev_dbg(di->dev, " Maximization needed, increase" - " with %d mA to %dmA (Optimal ibat: %d)" + " with %d uA to %duA (Optimal ibat: %d uA)" " Level %d\n", - di->ccm.test_delta_i, - di->ccm.current_iset, - di->ccm.original_iset, + di->ccm.test_delta_i_ua, + di->ccm.current_iset_ua, + di->ccm.original_iset_ua, di->ccm.level); return MAXIM_RET_CHANGE; } else { @@ -918,6 +920,7 @@ static enum maxim_ret ab8500_chargalg_chg_curr_maxim(struct ab8500_chargalg *di) static void handle_maxim_chg_curr(struct ab8500_chargalg *di) { + struct power_supply_battery_info *bi = &di->bm->bi; enum maxim_ret ret; int result; @@ -925,13 +928,13 @@ static void handle_maxim_chg_curr(struct ab8500_chargalg *di) switch (ret) { case MAXIM_RET_CHANGE: result = ab8500_chargalg_update_chg_curr(di, - di->ccm.current_iset); + di->ccm.current_iset_ua); if (result) dev_err(di->dev, "failed to set chg curr\n"); break; case MAXIM_RET_IBAT_TOO_HIGH: result = ab8500_chargalg_update_chg_curr(di, - di->bm->bat_type->normal_cur_lvl); + bi->constant_charge_current_max_ua); if (result) dev_err(di->dev, "failed to set chg curr\n"); break; @@ -1226,15 +1229,13 @@ static int ab8500_chargalg_get_ext_psy_data(struct device *dev, void *data) case POWER_SUPPLY_PROP_CURRENT_NOW: switch (ext->desc->type) { case POWER_SUPPLY_TYPE_MAINS: - di->chg_info.ac_curr = - ret.intval / 1000; - break; + di->chg_info.ac_curr_ua = ret.intval; + break; case POWER_SUPPLY_TYPE_USB: - di->chg_info.usb_curr = - ret.intval / 1000; + di->chg_info.usb_curr_ua = ret.intval; break; case POWER_SUPPLY_TYPE_BATTERY: - di->batt_data.inst_curr = ret.intval / 1000; + di->batt_data.inst_curr_ua = ret.intval; break; default: break; @@ -1298,9 +1299,10 @@ static void ab8500_chargalg_external_power_changed(struct power_supply *psy) */ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) { + struct power_supply_battery_info *bi = &di->bm->bi; int charger_status; int ret; - int curr_step_lvl; + int curr_step_lvl_ua; /* Collect data from all power_supply class devices */ class_for_each_device(power_supply_class, NULL, @@ -1406,7 +1408,7 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) "USB_I %d AC_Vset %d AC_Iset %d USB_Vset %d USB_Iset %d\n", di->batt_data.volt_uv, di->batt_data.avg_curr_ua, - di->batt_data.inst_curr, + di->batt_data.inst_curr_ua, di->batt_data.temp, di->batt_data.percent, di->maintenance_chg, @@ -1419,12 +1421,12 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) di->chg_info.online_chg & USB_CHG, di->events.ac_cv_active, di->events.usb_cv_active, - di->chg_info.ac_curr, - di->chg_info.usb_curr, + di->chg_info.ac_curr_ua, + di->chg_info.usb_curr_ua, di->chg_info.ac_vset, - di->chg_info.ac_iset, + di->chg_info.ac_iset_ua, di->chg_info.usb_vset, - di->chg_info.usb_iset); + di->chg_info.usb_iset_ua); switch (di->charge_state) { case STATE_HANDHELD_INIT: @@ -1509,15 +1511,15 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) break; case STATE_NORMAL_INIT: - if (di->curr_status.curr_step == CHARGALG_CURR_STEP_LOW) + if (di->curr_status.curr_step_ua == CHARGALG_CURR_STEP_LOW_UA) ab8500_chargalg_stop_charging(di); else { - curr_step_lvl = di->bm->bat_type->normal_cur_lvl - * di->curr_status.curr_step - / CHARGALG_CURR_STEP_HIGH; + curr_step_lvl_ua = bi->constant_charge_current_max_ua + * di->curr_status.curr_step_ua + / CHARGALG_CURR_STEP_HIGH_UA; ab8500_chargalg_start_charging(di, di->bm->bat_type->normal_vol_lvl, - curr_step_lvl); + curr_step_lvl_ua); } ab8500_chargalg_state_to(di, STATE_NORMAL); @@ -1743,7 +1745,7 @@ static int ab8500_chargalg_get_property(struct power_supply *psy, static ssize_t ab8500_chargalg_curr_step_show(struct ab8500_chargalg *di, char *buf) { - return sprintf(buf, "%d\n", di->curr_status.curr_step); + return sprintf(buf, "%d\n", di->curr_status.curr_step_ua); } static ssize_t ab8500_chargalg_curr_step_store(struct ab8500_chargalg *di, @@ -1756,9 +1758,9 @@ static ssize_t ab8500_chargalg_curr_step_store(struct ab8500_chargalg *di, if (ret < 0) return ret; - di->curr_status.curr_step = param; - if (di->curr_status.curr_step >= CHARGALG_CURR_STEP_LOW && - di->curr_status.curr_step <= CHARGALG_CURR_STEP_HIGH) { + di->curr_status.curr_step_ua = param; + if (di->curr_status.curr_step_ua >= CHARGALG_CURR_STEP_LOW_UA && + di->curr_status.curr_step_ua <= CHARGALG_CURR_STEP_HIGH_UA) { di->curr_status.curr_step_change = true; queue_work(di->chargalg_wq, &di->chargalg_work); } else @@ -2055,7 +2057,7 @@ static int ab8500_chargalg_probe(struct platform_device *pdev) dev_err(di->dev, "failed to create sysfs entry\n"); return ret; } - di->curr_status.curr_step = CHARGALG_CURR_STEP_HIGH; + di->curr_status.curr_step_ua = CHARGALG_CURR_STEP_HIGH_UA; dev_info(di->dev, "probe success\n"); return component_add(dev, &ab8500_chargalg_component_ops); diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c index 86f237dea44d..a2b1c991b570 100644 --- a/drivers/power/supply/ab8500_charger.c +++ b/drivers/power/supply/ab8500_charger.c @@ -145,23 +145,23 @@ enum ab8500_usb_state { AB8500_BM_USB_STATE_MAX, }; -/* VBUS input current limits supported in AB8500 in mA */ -#define USB_CH_IP_CUR_LVL_0P05 50 -#define USB_CH_IP_CUR_LVL_0P09 98 -#define USB_CH_IP_CUR_LVL_0P19 193 -#define USB_CH_IP_CUR_LVL_0P29 290 -#define USB_CH_IP_CUR_LVL_0P38 380 -#define USB_CH_IP_CUR_LVL_0P45 450 -#define USB_CH_IP_CUR_LVL_0P5 500 -#define USB_CH_IP_CUR_LVL_0P6 600 -#define USB_CH_IP_CUR_LVL_0P7 700 -#define USB_CH_IP_CUR_LVL_0P8 800 -#define USB_CH_IP_CUR_LVL_0P9 900 -#define USB_CH_IP_CUR_LVL_1P0 1000 -#define USB_CH_IP_CUR_LVL_1P1 1100 -#define USB_CH_IP_CUR_LVL_1P3 1300 -#define USB_CH_IP_CUR_LVL_1P4 1400 -#define USB_CH_IP_CUR_LVL_1P5 1500 +/* VBUS input current limits supported in AB8500 in uA */ +#define USB_CH_IP_CUR_LVL_0P05 50000 +#define USB_CH_IP_CUR_LVL_0P09 98000 +#define USB_CH_IP_CUR_LVL_0P19 193000 +#define USB_CH_IP_CUR_LVL_0P29 290000 +#define USB_CH_IP_CUR_LVL_0P38 380000 +#define USB_CH_IP_CUR_LVL_0P45 450000 +#define USB_CH_IP_CUR_LVL_0P5 500000 +#define USB_CH_IP_CUR_LVL_0P6 600000 +#define USB_CH_IP_CUR_LVL_0P7 700000 +#define USB_CH_IP_CUR_LVL_0P8 800000 +#define USB_CH_IP_CUR_LVL_0P9 900000 +#define USB_CH_IP_CUR_LVL_1P0 1000000 +#define USB_CH_IP_CUR_LVL_1P1 1100000 +#define USB_CH_IP_CUR_LVL_1P3 1300000 +#define USB_CH_IP_CUR_LVL_1P4 1400000 +#define USB_CH_IP_CUR_LVL_1P5 1500000 #define VBAT_TRESH_IP_CUR_RED 3800 @@ -186,7 +186,7 @@ struct ab8500_charger_info { int charger_voltage; int cv_active; bool wd_expired; - int charger_current; + int charger_current_ua; }; struct ab8500_charger_event_flags { @@ -201,17 +201,17 @@ struct ab8500_charger_event_flags { }; struct ab8500_charger_usb_state { - int usb_current; - int usb_current_tmp; + int usb_current_ua; + int usb_current_tmp_ua; enum ab8500_usb_state state; enum ab8500_usb_state state_tmp; spinlock_t usb_lock; }; struct ab8500_charger_max_usb_in_curr { - int usb_type_max; - int set_max; - int calculated_max; + int usb_type_max_ua; + int set_max_ua; + int calculated_max_ua; }; /** @@ -552,7 +552,7 @@ static int ab8500_charger_get_vbus_voltage(struct ab8500_charger *di) * @di: pointer to the ab8500_charger structure * * This function returns the usb charger current. - * Returns usb current (on success) and error code on failure + * Returns usb current in microamperes (on success) and error code on failure */ static int ab8500_charger_get_usb_current(struct ab8500_charger *di) { @@ -566,7 +566,8 @@ static int ab8500_charger_get_usb_current(struct ab8500_charger *di) } else { ich = 0; } - return ich; + /* Return microamperes */ + return ich * 1000; } /** @@ -574,7 +575,7 @@ static int ab8500_charger_get_usb_current(struct ab8500_charger *di) * @di: pointer to the ab8500_charger structure * * This function returns the ac charger current. - * Returns ac current (on success) and error code on failure. + * Returns ac current in microamperes (on success) and error code on failure. */ static int ab8500_charger_get_ac_current(struct ab8500_charger *di) { @@ -588,7 +589,8 @@ static int ab8500_charger_get_ac_current(struct ab8500_charger *di) } else { ich = 0; } - return ich; + /* Return microamperes */ + return ich * 1000; } /** @@ -711,19 +713,19 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, case USB_STAT_STD_HOST_C_S: dev_dbg(di->dev, "USB Type - Standard host is " "detected through USB driver\n"); - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P5; di->is_aca_rid = 0; break; case USB_STAT_HOST_CHG_HS_CHIRP: - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P5; di->is_aca_rid = 0; break; case USB_STAT_HOST_CHG_HS: - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P5; di->is_aca_rid = 0; break; case USB_STAT_ACA_RID_C_HS: - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P9; + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P9; di->is_aca_rid = 0; break; case USB_STAT_ACA_RID_A: @@ -732,7 +734,7 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, * can consume (900mA). Closest level is 500mA */ dev_dbg(di->dev, "USB_STAT_ACA_RID_A detected\n"); - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P5; di->is_aca_rid = 1; break; case USB_STAT_ACA_RID_B: @@ -740,36 +742,36 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, * Dedicated charger level minus 120mA (20mA for ACA and * 100mA for potential accessory). Closest level is 1300mA */ - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P3; + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_1P3; dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, - di->max_usb_in_curr.usb_type_max); + di->max_usb_in_curr.usb_type_max_ua); di->is_aca_rid = 1; break; case USB_STAT_HOST_CHG_NM: - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P5; di->is_aca_rid = 0; break; case USB_STAT_DEDICATED_CHG: - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P5; + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_1P5; di->is_aca_rid = 0; break; case USB_STAT_ACA_RID_C_HS_CHIRP: case USB_STAT_ACA_RID_C_NM: - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_1P5; + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_1P5; di->is_aca_rid = 1; break; case USB_STAT_NOT_CONFIGURED: if (di->vbus_detected) { di->usb_device_is_unrecognised = true; dev_dbg(di->dev, "USB Type - Legacy charger.\n"); - di->max_usb_in_curr.usb_type_max = + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_1P5; break; } fallthrough; case USB_STAT_HM_IDGND: dev_err(di->dev, "USB Type - Charging not allowed\n"); - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P05; ret = -ENXIO; break; case USB_STAT_RESERVED: @@ -781,11 +783,11 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, break; } else { dev_dbg(di->dev, "USB Type - Charging not allowed\n"); - di->max_usb_in_curr.usb_type_max = + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P05; dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, - di->max_usb_in_curr.usb_type_max); + di->max_usb_in_curr.usb_type_max_ua); ret = -ENXIO; break; } @@ -793,25 +795,25 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, case USB_STAT_CARKIT_2: case USB_STAT_ACA_DOCK_CHARGER: case USB_STAT_CHARGER_LINE_1: - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P5; dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, - di->max_usb_in_curr.usb_type_max); + di->max_usb_in_curr.usb_type_max_ua); break; case USB_STAT_NOT_VALID_LINK: dev_err(di->dev, "USB Type invalid - try charging anyway\n"); - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P5; break; default: dev_err(di->dev, "USB Type - Unknown\n"); - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P05; ret = -ENXIO; break; } - di->max_usb_in_curr.set_max = di->max_usb_in_curr.usb_type_max; + di->max_usb_in_curr.set_max_ua = di->max_usb_in_curr.usb_type_max_ua; dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", - link_status, di->max_usb_in_curr.set_max); + link_status, di->max_usb_in_curr.set_max_ua); return ret; } @@ -1027,51 +1029,51 @@ static int ab8500_voltage_to_regval(int voltage) /* This array maps the raw register value to charger input current */ static int ab8500_charge_input_curr_map[] = { - 50, 98, 193, 290, 380, 450, 500, 600, - 700, 800, 900, 1000, 1100, 1300, 1400, 1500, + 50000, 98000, 193000, 290000, 380000, 450000, 500000, 600000, + 700000, 800000, 900000, 1000000, 1100000, 1300000, 1400000, 1500000, }; /* This array maps the raw register value to charger output current */ static int ab8500_charge_output_curr_map[] = { - 100, 200, 300, 400, 500, 600, 700, 800, - 900, 1000, 1100, 1200, 1300, 1400, 1500, 1500, + 100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, + 900000, 1000000, 1100000, 1200000, 1300000, 1400000, 1500000, 1500000, }; -static int ab8500_current_to_regval(struct ab8500_charger *di, int curr) +static int ab8500_current_to_regval(struct ab8500_charger *di, int curr_ua) { int i; - if (curr < ab8500_charge_output_curr_map[0]) + if (curr_ua < ab8500_charge_output_curr_map[0]) return 0; for (i = 0; i < ARRAY_SIZE(ab8500_charge_output_curr_map); i++) { - if (curr < ab8500_charge_output_curr_map[i]) + if (curr_ua < ab8500_charge_output_curr_map[i]) return i - 1; } /* If not last element, return error */ i = ARRAY_SIZE(ab8500_charge_output_curr_map) - 1; - if (curr == ab8500_charge_output_curr_map[i]) + if (curr_ua == ab8500_charge_output_curr_map[i]) return i; else return -1; } -static int ab8500_vbus_in_curr_to_regval(struct ab8500_charger *di, int curr) +static int ab8500_vbus_in_curr_to_regval(struct ab8500_charger *di, int curr_ua) { int i; - if (curr < ab8500_charge_input_curr_map[0]) + if (curr_ua < ab8500_charge_input_curr_map[0]) return 0; for (i = 0; i < ARRAY_SIZE(ab8500_charge_input_curr_map); i++) { - if (curr < ab8500_charge_input_curr_map[i]) + if (curr_ua < ab8500_charge_input_curr_map[i]) return i - 1; } /* If not last element, return error */ i = ARRAY_SIZE(ab8500_charge_input_curr_map) - 1; - if (curr == ab8500_charge_input_curr_map[i]) + if (curr_ua == ab8500_charge_input_curr_map[i]) return i; else return -1; @@ -1082,35 +1084,35 @@ static int ab8500_vbus_in_curr_to_regval(struct ab8500_charger *di, int curr) * @di: pointer to the ab8500_charger structre * * The usb stack provides the maximum current that can be drawn from - * the standard usb host. This will be in mA. - * This function converts current in mA to a value that can be written + * the standard usb host. This will be in uA. + * This function converts current in uA to a value that can be written * to the register. Returns -1 if charging is not allowed */ static int ab8500_charger_get_usb_cur(struct ab8500_charger *di) { int ret = 0; - switch (di->usb_state.usb_current) { - case 100: - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P09; + switch (di->usb_state.usb_current_ua) { + case 100000: + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P09; break; - case 200: - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P19; + case 200000: + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P19; break; - case 300: - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P29; + case 300000: + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P29; break; - case 400: - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P38; + case 400000: + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P38; break; - case 500: - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5; + case 500000: + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P5; break; default: - di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; + di->max_usb_in_curr.usb_type_max_ua = USB_CH_IP_CUR_LVL_0P05; ret = -EPERM; break; } - di->max_usb_in_curr.set_max = di->max_usb_in_curr.usb_type_max; + di->max_usb_in_curr.set_max_ua = di->max_usb_in_curr.usb_type_max_ua; return ret; } @@ -1135,7 +1137,7 @@ static bool ab8500_charger_check_continue_stepping(struct ab8500_charger *di, /** * ab8500_charger_set_current() - set charger current * @di: pointer to the ab8500_charger structure - * @ich: charger current, in mA + * @ich_ua: charger current, in uA * @reg: select what charger register to set * * Set charger current. @@ -1146,7 +1148,7 @@ static bool ab8500_charger_check_continue_stepping(struct ab8500_charger *di, * Returns error code in case of failure else 0(on success) */ static int ab8500_charger_set_current(struct ab8500_charger *di, - int ich, int reg) + int ich_ua, int reg) { int ret = 0; int curr_index, prev_curr_index, shift_value, i; @@ -1167,7 +1169,7 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, case AB8500_MCH_IPT_CURLVL_REG: shift_value = MAIN_CH_INPUT_CURR_SHIFT; prev_curr_index = (reg_value >> shift_value); - curr_index = ab8500_current_to_regval(di, ich); + curr_index = ab8500_current_to_regval(di, ich_ua); step_udelay = STEP_UDELAY; if (!di->ac.charger_connected) no_stepping = true; @@ -1175,7 +1177,7 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, case AB8500_USBCH_IPT_CRNTLVL_REG: shift_value = VBUS_IN_CURR_LIM_SHIFT; prev_curr_index = (reg_value >> shift_value); - curr_index = ab8500_vbus_in_curr_to_regval(di, ich); + curr_index = ab8500_vbus_in_curr_to_regval(di, ich_ua); step_udelay = STEP_UDELAY * 100; if (!di->usb.charger_connected) @@ -1184,7 +1186,7 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, case AB8500_CH_OPT_CRNTLVL_REG: shift_value = 0; prev_curr_index = (reg_value >> shift_value); - curr_index = ab8500_current_to_regval(di, ich); + curr_index = ab8500_current_to_regval(di, ich_ua); step_udelay = STEP_UDELAY; if (curr_index && (curr_index - prev_curr_index) > 1) step_udelay *= 100; @@ -1213,8 +1215,8 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, goto exit_set_current; } - dev_dbg(di->dev, "%s set charger current: %d mA for reg: 0x%02x\n", - __func__, ich, reg); + dev_dbg(di->dev, "%s set charger current: %d uA for reg: 0x%02x\n", + __func__, ich_ua, reg); if (no_stepping) { ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, @@ -1261,31 +1263,31 @@ static int ab8500_charger_set_current(struct ab8500_charger *di, /** * ab8500_charger_set_vbus_in_curr() - set VBUS input current limit * @di: pointer to the ab8500_charger structure - * @ich_in: charger input current limit + * @ich_in_ua: charger input current limit in microampere * * Sets the current that can be drawn from the USB host * Returns error code in case of failure else 0(on success) */ static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di, - int ich_in) + int ich_in_ua) { int min_value; int ret; /* We should always use to lowest current limit */ - min_value = min(di->bm->chg_params->usb_curr_max, ich_in); - if (di->max_usb_in_curr.set_max > 0) - min_value = min(di->max_usb_in_curr.set_max, min_value); + min_value = min(di->bm->chg_params->usb_curr_max_ua, ich_in_ua); + if (di->max_usb_in_curr.set_max_ua > 0) + min_value = min(di->max_usb_in_curr.set_max_ua, min_value); - if (di->usb_state.usb_current >= 0) - min_value = min(di->usb_state.usb_current, min_value); + if (di->usb_state.usb_current_ua >= 0) + min_value = min(di->usb_state.usb_current_ua, min_value); switch (min_value) { - case 100: + case 100000: if (di->vbat < VBAT_TRESH_IP_CUR_RED) min_value = USB_CH_IP_CUR_LVL_0P05; break; - case 500: + case 500000: if (di->vbat < VBAT_TRESH_IP_CUR_RED) min_value = USB_CH_IP_CUR_LVL_0P45; break; @@ -1293,7 +1295,7 @@ static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di, break; } - dev_info(di->dev, "VBUS input current limit set to %d mA\n", min_value); + dev_info(di->dev, "VBUS input current limit set to %d uA\n", min_value); mutex_lock(&di->usb_ipt_crnt_lock); ret = ab8500_charger_set_current(di, min_value, @@ -1306,30 +1308,30 @@ static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di, /** * ab8500_charger_set_main_in_curr() - set main charger input current * @di: pointer to the ab8500_charger structure - * @ich_in: input charger current, in mA + * @ich_in_ua: input charger current, in uA * * Set main charger input current. * Returns error code in case of failure else 0(on success) */ static int ab8500_charger_set_main_in_curr(struct ab8500_charger *di, - int ich_in) + int ich_in_ua) { - return ab8500_charger_set_current(di, ich_in, + return ab8500_charger_set_current(di, ich_in_ua, AB8500_MCH_IPT_CURLVL_REG); } /** * ab8500_charger_set_output_curr() - set charger output current * @di: pointer to the ab8500_charger structure - * @ich_out: output charger current, in mA + * @ich_out_ua: output charger current, in uA * * Set charger output current. * Returns error code in case of failure else 0(on success) */ static int ab8500_charger_set_output_curr(struct ab8500_charger *di, - int ich_out) + int ich_out_ua) { - return ab8500_charger_set_current(di, ich_out, + return ab8500_charger_set_current(di, ich_out_ua, AB8500_CH_OPT_CRNTLVL_REG); } @@ -1381,13 +1383,13 @@ static int ab8500_charger_led_en(struct ab8500_charger *di, int on) * @di: pointer to the ab8500_charger structure * @enable: enable/disable flag * @vset: charging voltage - * @iset: charging current + * @iset_ua: charging current in microampere * * Enable/Disable AC/Mains charging and turns on/off the charging led * respectively. **/ static int ab8500_charger_ac_en(struct ux500_charger *charger, - int enable, int vset, int iset) + int enable, int vset, int iset_ua) { int ret; int volt_index; @@ -1405,7 +1407,7 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger, } /* Enable AC charging */ - dev_dbg(di->dev, "Enable AC: %dmV %dmA\n", vset, iset); + dev_dbg(di->dev, "Enable AC: %dmV %duA\n", vset, iset_ua); /* * Due to a bug in AB8500, BTEMP_HIGH/LOW interrupts @@ -1428,9 +1430,9 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger, /* Check if the requested voltage or current is valid */ volt_index = ab8500_voltage_to_regval(vset); - curr_index = ab8500_current_to_regval(di, iset); + curr_index = ab8500_current_to_regval(di, iset_ua); input_curr_index = ab8500_current_to_regval(di, - di->bm->chg_params->ac_curr_max); + di->bm->chg_params->ac_curr_max_ua); if (volt_index < 0 || curr_index < 0 || input_curr_index < 0) { dev_err(di->dev, "Charger voltage or current too high, " @@ -1447,14 +1449,14 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger, } /* MainChInputCurr: current that can be drawn from the charger*/ ret = ab8500_charger_set_main_in_curr(di, - di->bm->chg_params->ac_curr_max); + di->bm->chg_params->ac_curr_max_ua); if (ret) { dev_err(di->dev, "%s Failed to set MainChInputCurr\n", __func__); return ret; } /* ChOutputCurentLevel: protected output current */ - ret = ab8500_charger_set_output_curr(di, iset); + ret = ab8500_charger_set_output_curr(di, iset_ua); if (ret) { dev_err(di->dev, "%s " "Failed to set ChOutputCurentLevel\n", @@ -1558,13 +1560,13 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger, * @di: pointer to the ab8500_charger structure * @enable: enable/disable flag * @vset: charging voltage - * @ich_out: charger output current + * @ich_out_ua: charger output current in microampere * * Enable/Disable USB charging and turns on/off the charging led respectively. * Returns error code in case of failure else 0(on success) */ static int ab8500_charger_usb_en(struct ux500_charger *charger, - int enable, int vset, int ich_out) + int enable, int vset, int ich_out_ua) { int ret; int volt_index; @@ -1600,11 +1602,11 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, } /* Enable USB charging */ - dev_dbg(di->dev, "Enable USB: %dmV %dmA\n", vset, ich_out); + dev_dbg(di->dev, "Enable USB: %d mV %d uA\n", vset, ich_out_ua); /* Check if the requested voltage or current is valid */ volt_index = ab8500_voltage_to_regval(vset); - curr_index = ab8500_current_to_regval(di, ich_out); + curr_index = ab8500_current_to_regval(di, ich_out_ua); if (volt_index < 0 || curr_index < 0) { dev_err(di->dev, "Charger voltage or current too high, " @@ -1645,14 +1647,14 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, /* USBChInputCurr: current that can be drawn from the usb */ ret = ab8500_charger_set_vbus_in_curr(di, - di->max_usb_in_curr.usb_type_max); + di->max_usb_in_curr.usb_type_max_ua); if (ret) { dev_err(di->dev, "setting USBChInputCurr failed\n"); return ret; } /* ChOutputCurentLevel: protected output current */ - ret = ab8500_charger_set_output_curr(di, ich_out); + ret = ab8500_charger_set_output_curr(di, ich_out_ua); if (ret) { dev_err(di->dev, "%s " "Failed to set ChOutputCurentLevel\n", @@ -1739,13 +1741,13 @@ static int ab8500_external_charger_prepare(struct notifier_block *charger_nb, * ab8500_charger_usb_check_enable() - enable usb charging * @charger: pointer to the ux500_charger structure * @vset: charging voltage - * @iset: charger output current + * @iset_ua: charger output current in microampere * * Check if the VBUS charger has been disconnected and reconnected without * AB8500 rising an interrupt. Returns 0 on success. */ static int ab8500_charger_usb_check_enable(struct ux500_charger *charger, - int vset, int iset) + int vset, int iset_ua) { u8 usbch_ctrl1 = 0; int ret = 0; @@ -1774,7 +1776,7 @@ static int ab8500_charger_usb_check_enable(struct ux500_charger *charger, return ret; } - ret = ab8500_charger_usb_en(&di->usb_chg, true, vset, iset); + ret = ab8500_charger_usb_en(&di->usb_chg, true, vset, iset_ua); if (ret < 0) { dev_err(di->dev, "Failed to enable VBUS charger %d\n", __LINE__); @@ -1788,13 +1790,13 @@ static int ab8500_charger_usb_check_enable(struct ux500_charger *charger, * ab8500_charger_ac_check_enable() - enable usb charging * @charger: pointer to the ux500_charger structure * @vset: charging voltage - * @iset: charger output current + * @iset_ua: charger output current in micrompere * * Check if the AC charger has been disconnected and reconnected without * AB8500 rising an interrupt. Returns 0 on success. */ static int ab8500_charger_ac_check_enable(struct ux500_charger *charger, - int vset, int iset) + int vset, int iset_ua) { u8 mainch_ctrl1 = 0; int ret = 0; @@ -1824,7 +1826,7 @@ static int ab8500_charger_ac_check_enable(struct ux500_charger *charger, return ret; } - ret = ab8500_charger_ac_en(&di->usb_chg, true, vset, iset); + ret = ab8500_charger_ac_en(&di->usb_chg, true, vset, iset_ua); if (ret < 0) { dev_err(di->dev, "failed to enable AC charger %d\n", __LINE__); @@ -1863,13 +1865,14 @@ static int ab8500_charger_watchdog_kick(struct ux500_charger *charger) /** * ab8500_charger_update_charger_current() - update charger current - * @di: pointer to the ab8500_charger structure + * @charger: pointer to the ab8500_charger structure + * @ich_out_ua: desired output current in microampere * * Update the charger output current for the specified charger * Returns error code in case of failure else 0(on success) */ static int ab8500_charger_update_charger_current(struct ux500_charger *charger, - int ich_out) + int ich_out_ua) { int ret; struct ab8500_charger *di; @@ -1881,7 +1884,7 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger, else return -ENXIO; - ret = ab8500_charger_set_output_curr(di, ich_out); + ret = ab8500_charger_set_output_curr(di, ich_out_ua); if (ret) { dev_err(di->dev, "%s " "Failed to set ChOutputCurentLevel\n", @@ -1973,10 +1976,10 @@ static void ab8500_charger_check_vbat_work(struct work_struct *work) di->vbat > VBAT_TRESH_IP_CUR_RED))) { dev_dbg(di->dev, "Vbat did cross threshold, curr: %d, new: %d," - " old: %d\n", di->max_usb_in_curr.usb_type_max, + " old: %d\n", di->max_usb_in_curr.usb_type_max_ua, di->vbat, di->old_vbat); ab8500_charger_set_vbus_in_curr(di, - di->max_usb_in_curr.usb_type_max); + di->max_usb_in_curr.usb_type_max_ua); power_supply_changed(di->usb_chg.psy); } @@ -2257,7 +2260,7 @@ static void ab8500_charger_usb_link_attach_work(struct work_struct *work) /* Update maximum input current if USB enumeration is not detected */ if (!di->usb.charger_online) { ret = ab8500_charger_set_vbus_in_curr(di, - di->max_usb_in_curr.usb_type_max); + di->max_usb_in_curr.usb_type_max_ua); if (ret) return; } @@ -2419,11 +2422,11 @@ static void ab8500_charger_usb_state_changed_work(struct work_struct *work) spin_lock_irqsave(&di->usb_state.usb_lock, flags); di->usb_state.state = di->usb_state.state_tmp; - di->usb_state.usb_current = di->usb_state.usb_current_tmp; + di->usb_state.usb_current_ua = di->usb_state.usb_current_tmp_ua; spin_unlock_irqrestore(&di->usb_state.usb_lock, flags); - dev_dbg(di->dev, "%s USB state: 0x%02x mA: %d\n", - __func__, di->usb_state.state, di->usb_state.usb_current); + dev_dbg(di->dev, "%s USB state: 0x%02x uA: %d\n", + __func__, di->usb_state.state, di->usb_state.usb_current_ua); switch (di->usb_state.state) { case AB8500_BM_USB_STATE_RESET_HS: @@ -2449,7 +2452,7 @@ static void ab8500_charger_usb_state_changed_work(struct work_struct *work) if (!ab8500_charger_get_usb_cur(di)) { /* Update maximum input current */ ret = ab8500_charger_set_vbus_in_curr(di, - di->max_usb_in_curr.usb_type_max); + di->max_usb_in_curr.usb_type_max_ua); if (ret) return; @@ -2669,7 +2672,7 @@ static void ab8500_charger_vbus_drop_end_work(struct work_struct *work) { struct ab8500_charger *di = container_of(work, struct ab8500_charger, vbus_drop_end_work.work); - int ret, curr; + int ret, curr_ua; u8 reg_value; di->flags.vbus_drop_end = false; @@ -2685,30 +2688,30 @@ static void ab8500_charger_vbus_drop_end_work(struct work_struct *work) return; } - curr = ab8500_charge_input_curr_map[ + curr_ua = ab8500_charge_input_curr_map[ reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT]; - if (di->max_usb_in_curr.calculated_max != curr) { + if (di->max_usb_in_curr.calculated_max_ua != curr_ua) { /* USB source is collapsing */ - di->max_usb_in_curr.calculated_max = curr; + di->max_usb_in_curr.calculated_max_ua = curr_ua; dev_dbg(di->dev, - "VBUS input current limiting to %d mA\n", - di->max_usb_in_curr.calculated_max); + "VBUS input current limiting to %d uA\n", + di->max_usb_in_curr.calculated_max_ua); } else { /* * USB source can not give more than this amount. * Taking more will collapse the source. */ - di->max_usb_in_curr.set_max = - di->max_usb_in_curr.calculated_max; + di->max_usb_in_curr.set_max_ua = + di->max_usb_in_curr.calculated_max_ua; dev_dbg(di->dev, - "VBUS input current limited to %d mA\n", - di->max_usb_in_curr.set_max); + "VBUS input current limited to %d uA\n", + di->max_usb_in_curr.set_max_ua); } if (di->usb.charger_connected) ab8500_charger_set_vbus_in_curr(di, - di->max_usb_in_curr.usb_type_max); + di->max_usb_in_curr.usb_type_max_ua); } /** @@ -2953,8 +2956,8 @@ static int ab8500_charger_ac_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CURRENT_NOW: ret = ab8500_charger_get_ac_current(di); if (ret >= 0) - di->ac.charger_current = ret; - val->intval = di->ac.charger_current * 1000; + di->ac.charger_current_ua = ret; + val->intval = di->ac.charger_current_ua; break; default: return -EINVAL; @@ -3021,8 +3024,8 @@ static int ab8500_charger_usb_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CURRENT_NOW: ret = ab8500_charger_get_usb_current(di); if (ret >= 0) - di->usb.charger_current = ret; - val->intval = di->usb.charger_current * 1000; + di->usb.charger_current_ua = ret; + val->intval = di->usb.charger_current_ua; break; case POWER_SUPPLY_PROP_CURRENT_AVG: /* @@ -3198,6 +3201,11 @@ static int ab8500_charger_usb_notifier_call(struct notifier_block *nb, struct ab8500_charger *di = container_of(nb, struct ab8500_charger, nb); enum ab8500_usb_state bm_usb_state; + /* + * FIXME: it appears the AB8500 PHY never sends what it should here. + * Fix the PHY driver to properly notify the desired current. + * Also broadcast microampere and not milliampere. + */ unsigned mA = *((unsigned *)power); if (event != USB_EVENT_VBUS) { @@ -3208,7 +3216,7 @@ static int ab8500_charger_usb_notifier_call(struct notifier_block *nb, /* TODO: State is fabricate here. See if charger really needs USB * state or if mA is enough */ - if ((di->usb_state.usb_current == 2) && (mA > 2)) + if ((di->usb_state.usb_current_ua == 2000) && (mA > 2)) bm_usb_state = AB8500_BM_USB_STATE_RESUME; else if (mA == 0) bm_usb_state = AB8500_BM_USB_STATE_RESET_HS; @@ -3224,7 +3232,8 @@ static int ab8500_charger_usb_notifier_call(struct notifier_block *nb, spin_lock(&di->usb_state.usb_lock); di->usb_state.state_tmp = bm_usb_state; - di->usb_state.usb_current_tmp = mA; + /* FIXME: broadcast ua instead, see above */ + di->usb_state.usb_current_tmp_ua = mA * 1000; spin_unlock(&di->usb_state.usb_lock); /* @@ -3514,7 +3523,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->ac_chg.ops.update_curr = &ab8500_charger_update_charger_current; di->ac_chg.max_out_volt = ab8500_charger_voltage_map[ ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; - di->ac_chg.max_out_curr = + di->ac_chg.max_out_curr_ua = ab8500_charge_output_curr_map[ARRAY_SIZE(ab8500_charge_output_curr_map) - 1]; di->ac_chg.wdt_refresh = CHG_WD_INTERVAL; /* @@ -3535,11 +3544,11 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->usb_chg.ops.update_curr = &ab8500_charger_update_charger_current; di->usb_chg.max_out_volt = ab8500_charger_voltage_map[ ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; - di->usb_chg.max_out_curr = + di->usb_chg.max_out_curr_ua = ab8500_charge_output_curr_map[ARRAY_SIZE(ab8500_charge_output_curr_map) - 1]; di->usb_chg.wdt_refresh = CHG_WD_INTERVAL; di->usb_chg.external = false; - di->usb_state.usb_current = -1; + di->usb_state.usb_current_ua = -1; mutex_init(&di->charger_attached_mutex); From patchwork Thu Nov 18 02:17:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625887 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 342ECC433EF for ; Thu, 18 Nov 2021 02:20:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1B1C561ABF for ; Thu, 18 Nov 2021 02:20:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242504AbhKRCXf (ORCPT ); Wed, 17 Nov 2021 21:23:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241550AbhKRCXa (ORCPT ); Wed, 17 Nov 2021 21:23:30 -0500 Received: from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com [IPv6:2a00:1450:4864:20::12a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 63127C061570 for ; Wed, 17 Nov 2021 18:20:30 -0800 (PST) Received: by mail-lf1-x12a.google.com with SMTP id f18so18125303lfv.6 for ; Wed, 17 Nov 2021 18:20:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=oOi1S1KUH1kwJOUO7h21Qu8x4jnt3a9YWtvOp51eSVk=; b=Ni0x02GnQHrrwiAZg4bwVRZm8Co3EYdpMhPn5vKEXRWtTI5/SSe4KklRSUtR1AvioM e/Fp6LIGj4VNIW9y4tlQDi+AH2enLZc1q9/wVmhVmzbQimCVIbM1webl5sveVtfrukJb 2l6CN5RRqLm6F4hdPLbgC7dFJSZbQwaaX8sQ0OQZ+8R2mn1iTX52Pz+SazJ9FD3t7cZ2 iqr1i0HDWbth8b0PNhQEdXMMqkEo9u4CDpm2ABh9xgLDV46SUSgk0Gk34SZ/zczCiUUb W5ojadRkzEoL0kG7mZoJzA4qZ5y9hBGk278FUEJq/diLf1lh9Kv8BYDOxyuri9N+gv/b a1ww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oOi1S1KUH1kwJOUO7h21Qu8x4jnt3a9YWtvOp51eSVk=; b=uNMJRcXRQtgjY4XQUHfZ3NN1tux05ajwULgH/NLCxMCNpRSFx83c2lbVLrXbzX8K5d WhqcHCAvwz9yKuP8wyL4CLQvWmUNBCT4rOT3YFKEXDUhBIAIZlfso3Kz052WAVdYErQp VILky24sVmWyR4NZ2Bu87hK2gOOTJ+FA5DDK9LEXhwebyc6HfJmce9irXwOy6iFYLkul Wwgr/ducPq9pC0yk8VJwkDCJ3Yrfj6+AUd+nv3Cueom73HKpkLfP0REZhAydgDG8P5nF cAK/EsnqqACzKZXAmTeQLYB/k43qxGDX+fAwLnFHMyxiPkX9RDSxUz9mYOSn5cRYLFpZ W8sg== X-Gm-Message-State: AOAM533eNVbZzOg2Wx+dBX88aN+pmD8oN00RnHIGQ1y1x6Exz4YIb/Vk i34juyRANCK6bOLsxZuY4tozDm1hkrbCiQ== X-Google-Smtp-Source: ABdhPJxtLTVygJz3paxe86abp/62NUjIvd5jqXZ3eQ2vYbxAF3izM0BThgyNxlmqmovnqs+vKGWfXQ== X-Received: by 2002:a2e:8e2d:: with SMTP id r13mr12493997ljk.222.1637202028659; Wed, 17 Nov 2021 18:20:28 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.20.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:27 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 14/16] power: supply: ab8500: Standardize CV voltage Date: Thu, 18 Nov 2021 03:17:50 +0100 Message-Id: <20211118021752.2262818-15-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The voltage used in the constant voltage phase of the charging exist in struct power_supply_battery_info as constant_charge_voltage_max_uv. Switch the custom property normal_vol_lvl to this and consequentially change everything that relates to this value over to using microvolts rather than millivolts so we align internal representation of current with the power core. Prefix every variable we change with *_uv to indicate the unit everywhere but also to make sure we do not miss any outlier. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500-bm.h | 10 +- drivers/power/supply/ab8500-chargalg.h | 4 +- drivers/power/supply/ab8500_bmdata.c | 8 +- drivers/power/supply/ab8500_chargalg.c | 62 +++---- drivers/power/supply/ab8500_charger.c | 218 +++++++++++++------------ 5 files changed, 152 insertions(+), 150 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index e015bb6e7684..56bf70bc673a 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -367,7 +367,6 @@ struct ab8500_maxim_parameters { * struct ab8500_battery_type - different batteries supported * @resis_high: battery upper resistance limit * @resis_low: battery lower resistance limit - * @normal_vol_lvl: charger voltage in normal state in mV * @maint_a_cur_lvl: charger current in maintenance A state in mA * @maint_a_vol_lvl: charger voltage in maintenance A state in mV * @maint_a_chg_timer_h: charge time in maintenance A state @@ -386,7 +385,6 @@ struct ab8500_maxim_parameters { struct ab8500_battery_type { int resis_high; int resis_low; - int normal_vol_lvl; int maint_a_cur_lvl; int maint_a_vol_lvl; int maint_a_chg_timer_h; @@ -421,15 +419,15 @@ struct ab8500_bm_capacity_levels { /** * struct ab8500_bm_charger_parameters - Charger specific parameters - * @usb_volt_max: maximum allowed USB charger voltage in mV + * @usb_volt_max_uv: maximum allowed USB charger voltage in uV * @usb_curr_max_ua: maximum allowed USB charger current in uA - * @ac_volt_max: maximum allowed AC charger voltage in mV + * @ac_volt_max_uv: maximum allowed AC charger voltage in uV * @ac_curr_max_ua: maximum allowed AC charger current in uA */ struct ab8500_bm_charger_parameters { - int usb_volt_max; + int usb_volt_max_uv; int usb_curr_max_ua; - int ac_volt_max; + int ac_volt_max_uv; int ac_curr_max_ua; }; diff --git a/drivers/power/supply/ab8500-chargalg.h b/drivers/power/supply/ab8500-chargalg.h index 8094a3c2bd3a..f47a0061c36a 100644 --- a/drivers/power/supply/ab8500-chargalg.h +++ b/drivers/power/supply/ab8500-chargalg.h @@ -31,7 +31,7 @@ struct ux500_charger_ops { * struct ux500_charger - power supply ux500 charger sub class * @psy power supply base class * @ops ux500 charger operations - * @max_out_volt maximum output charger voltage in mV + * @max_out_volt_uv maximum output charger voltage in uV * @max_out_curr_ua maximum output charger current in uA * @enabled indicates if this charger is used or not * @external external charger unit (pm2xxx) @@ -39,7 +39,7 @@ struct ux500_charger_ops { struct ux500_charger { struct power_supply *psy; struct ux500_charger_ops ops; - int max_out_volt; + int max_out_volt_uv; int max_out_curr_ua; int wdt_refresh; bool enabled; diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index ff17fc4593cc..a41b9f3a88cb 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -83,7 +83,6 @@ static const struct batres_vs_temp temp_to_batres_tbl_thermistor[] = { static struct ab8500_battery_type bat_type_thermistor_unknown = { .resis_high = 0, .resis_low = 0, - .normal_vol_lvl = 4100, .maint_a_cur_lvl = 400, .maint_a_vol_lvl = 4050, .maint_a_chg_timer_h = 60, @@ -138,9 +137,9 @@ static const struct ab8500_maxim_parameters ab8500_maxi_params = { }; static const struct ab8500_bm_charger_parameters chg = { - .usb_volt_max = 5500, + .usb_volt_max_uv = 5500000, .usb_curr_max_ua = 1500000, - .ac_volt_max = 7500, + .ac_volt_max_uv = 7500000, .ac_curr_max_ua = 1500000, }; @@ -203,6 +202,9 @@ int ab8500_bm_of_probe(struct power_supply *psy, if (bi->constant_charge_current_max_ua < 0) bi->constant_charge_current_max_ua = 400000; + if (bi->constant_charge_voltage_max_uv < 0) + bi->constant_charge_voltage_max_uv = 4100000; + if (bi->charge_term_current_ua) /* Charging stops when we drop below this current */ bi->charge_term_current_ua = 200000; diff --git a/drivers/power/supply/ab8500_chargalg.c b/drivers/power/supply/ab8500_chargalg.c index 8ad3924ee496..86d740ce3a63 100644 --- a/drivers/power/supply/ab8500_chargalg.c +++ b/drivers/power/supply/ab8500_chargalg.c @@ -70,13 +70,13 @@ struct ab8500_chargalg_charger_info { enum ab8500_chargers charger_type; bool usb_chg_ok; bool ac_chg_ok; - int usb_volt; + int usb_volt_uv; int usb_curr_ua; - int ac_volt; + int ac_volt_uv; int ac_curr_ua; - int usb_vset; + int usb_vset_uv; int usb_iset_ua; - int ac_vset; + int ac_vset_uv; int ac_iset_ua; }; @@ -365,12 +365,12 @@ static int ab8500_chargalg_check_charger_enable(struct ab8500_chargalg *di) if (di->chg_info.charger_type & USB_CHG) { return di->usb_chg->ops.check_enable(di->usb_chg, - di->bm->bat_type->normal_vol_lvl, + bi->constant_charge_voltage_max_uv, bi->constant_charge_current_max_ua); } else if ((di->chg_info.charger_type & AC_CHG) && !(di->ac_chg->external)) { return di->ac_chg->ops.check_enable(di->ac_chg, - di->bm->bat_type->normal_vol_lvl, + bi->constant_charge_voltage_max_uv, bi->constant_charge_current_max_ua); } return 0; @@ -546,14 +546,14 @@ static int ab8500_chargalg_kick_watchdog(struct ab8500_chargalg *di) * ab8500_chargalg_ac_en() - Turn on/off the AC charger * @di: pointer to the ab8500_chargalg structure * @enable: charger on/off - * @vset: requested charger output voltage + * @vset_uv: requested charger output voltage in microvolt * @iset_ua: requested charger output current in microampere * * The AC charger will be turned on/off with the requested charge voltage and * current */ static int ab8500_chargalg_ac_en(struct ab8500_chargalg *di, int enable, - int vset, int iset_ua) + int vset_uv, int iset_ua) { static int ab8500_chargalg_ex_ac_enable_toggle; @@ -561,13 +561,13 @@ static int ab8500_chargalg_ac_en(struct ab8500_chargalg *di, int enable, return -ENXIO; /* Select maximum of what both the charger and the battery supports */ - if (di->ac_chg->max_out_volt) - vset = min(vset, di->ac_chg->max_out_volt); + if (di->ac_chg->max_out_volt_uv) + vset_uv = min(vset_uv, di->ac_chg->max_out_volt_uv); if (di->ac_chg->max_out_curr_ua) iset_ua = min(iset_ua, di->ac_chg->max_out_curr_ua); di->chg_info.ac_iset_ua = iset_ua; - di->chg_info.ac_vset = vset; + di->chg_info.ac_vset_uv = vset_uv; /* Enable external charger */ if (enable && di->ac_chg->external && @@ -577,35 +577,35 @@ static int ab8500_chargalg_ac_en(struct ab8500_chargalg *di, int enable, ab8500_chargalg_ex_ac_enable_toggle++; } - return di->ac_chg->ops.enable(di->ac_chg, enable, vset, iset_ua); + return di->ac_chg->ops.enable(di->ac_chg, enable, vset_uv, iset_ua); } /** * ab8500_chargalg_usb_en() - Turn on/off the USB charger * @di: pointer to the ab8500_chargalg structure * @enable: charger on/off - * @vset: requested charger output voltage + * @vset_uv: requested charger output voltage in microvolt * @iset_ua: requested charger output current in microampere * * The USB charger will be turned on/off with the requested charge voltage and * current */ static int ab8500_chargalg_usb_en(struct ab8500_chargalg *di, int enable, - int vset, int iset_ua) + int vset_uv, int iset_ua) { if (!di->usb_chg || !di->usb_chg->ops.enable) return -ENXIO; /* Select maximum of what both the charger and the battery supports */ - if (di->usb_chg->max_out_volt) - vset = min(vset, di->usb_chg->max_out_volt); + if (di->usb_chg->max_out_volt_uv) + vset_uv = min(vset_uv, di->usb_chg->max_out_volt_uv); if (di->usb_chg->max_out_curr_ua) iset_ua = min(iset_ua, di->usb_chg->max_out_curr_ua); di->chg_info.usb_iset_ua = iset_ua; - di->chg_info.usb_vset = vset; + di->chg_info.usb_vset_uv = vset_uv; - return di->usb_chg->ops.enable(di->usb_chg, enable, vset, iset_ua); + return di->usb_chg->ops.enable(di->usb_chg, enable, vset_uv, iset_ua); } /** @@ -692,28 +692,28 @@ static void ab8500_chargalg_hold_charging(struct ab8500_chargalg *di) /** * ab8500_chargalg_start_charging() - Start the charger * @di: pointer to the ab8500_chargalg structure - * @vset: requested charger output voltage + * @vset_uv: requested charger output voltage in microvolt * @iset_ua: requested charger output current in microampere * * A charger will be enabled depending on the requested charger type that was * detected previously. */ static void ab8500_chargalg_start_charging(struct ab8500_chargalg *di, - int vset, int iset_ua) + int vset_uv, int iset_ua) { switch (di->chg_info.charger_type) { case AC_CHG: dev_dbg(di->dev, - "AC parameters: Vset %d, Ich %d\n", vset, iset_ua); + "AC parameters: Vset %d, Ich %d\n", vset_uv, iset_ua); ab8500_chargalg_usb_en(di, false, 0, 0); - ab8500_chargalg_ac_en(di, true, vset, iset_ua); + ab8500_chargalg_ac_en(di, true, vset_uv, iset_ua); break; case USB_CHG: dev_dbg(di->dev, - "USB parameters: Vset %d, Ich %d\n", vset, iset_ua); + "USB parameters: Vset %d, Ich %d\n", vset_uv, iset_ua); ab8500_chargalg_ac_en(di, false, 0, 0); - ab8500_chargalg_usb_en(di, true, vset, iset_ua); + ab8500_chargalg_usb_en(di, true, vset_uv, iset_ua); break; default: @@ -777,12 +777,12 @@ static void ab8500_chargalg_check_temp(struct ab8500_chargalg *di) */ static void ab8500_chargalg_check_charger_voltage(struct ab8500_chargalg *di) { - if (di->chg_info.usb_volt > di->bm->chg_params->usb_volt_max) + if (di->chg_info.usb_volt_uv > di->bm->chg_params->usb_volt_max_uv) di->chg_info.usb_chg_ok = false; else di->chg_info.usb_chg_ok = true; - if (di->chg_info.ac_volt > di->bm->chg_params->ac_volt_max) + if (di->chg_info.ac_volt_uv > di->bm->chg_params->ac_volt_max_uv) di->chg_info.ac_chg_ok = false; else di->chg_info.ac_chg_ok = true; @@ -1173,10 +1173,10 @@ static int ab8500_chargalg_get_ext_psy_data(struct device *dev, void *data) di->batt_data.volt_uv = ret.intval; break; case POWER_SUPPLY_TYPE_MAINS: - di->chg_info.ac_volt = ret.intval / 1000; + di->chg_info.ac_volt_uv = ret.intval; break; case POWER_SUPPLY_TYPE_USB: - di->chg_info.usb_volt = ret.intval / 1000; + di->chg_info.usb_volt_uv = ret.intval; break; default: break; @@ -1423,9 +1423,9 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) di->events.usb_cv_active, di->chg_info.ac_curr_ua, di->chg_info.usb_curr_ua, - di->chg_info.ac_vset, + di->chg_info.ac_vset_uv, di->chg_info.ac_iset_ua, - di->chg_info.usb_vset, + di->chg_info.usb_vset_uv, di->chg_info.usb_iset_ua); switch (di->charge_state) { @@ -1518,7 +1518,7 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) * di->curr_status.curr_step_ua / CHARGALG_CURR_STEP_HIGH_UA; ab8500_chargalg_start_charging(di, - di->bm->bat_type->normal_vol_lvl, + bi->constant_charge_voltage_max_uv, curr_step_lvl_ua); } diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c index a2b1c991b570..067d66af24f1 100644 --- a/drivers/power/supply/ab8500_charger.c +++ b/drivers/power/supply/ab8500_charger.c @@ -183,7 +183,7 @@ struct ab8500_charger_interrupts { struct ab8500_charger_info { int charger_connected; int charger_online; - int charger_voltage; + int charger_voltage_uv; int cv_active; bool wd_expired; int charger_current_ua; @@ -479,7 +479,7 @@ static void ab8500_charger_set_usb_connected(struct ab8500_charger *di, * ab8500_charger_get_ac_voltage() - get ac charger voltage * @di: pointer to the ab8500_charger structure * - * Returns ac charger voltage (on success) + * Returns ac charger voltage in microvolt (on success) */ static int ab8500_charger_get_ac_voltage(struct ab8500_charger *di) { @@ -493,7 +493,8 @@ static int ab8500_charger_get_ac_voltage(struct ab8500_charger *di) } else { vch = 0; } - return vch; + /* Convert to microvolt, IIO returns millivolt */ + return vch * 1000; } /** @@ -530,7 +531,7 @@ static int ab8500_charger_ac_cv(struct ab8500_charger *di) * @di: pointer to the ab8500_charger structure * * This function returns the vbus voltage. - * Returns vbus voltage (on success) + * Returns vbus voltage in microvolt (on success) */ static int ab8500_charger_get_vbus_voltage(struct ab8500_charger *di) { @@ -544,7 +545,8 @@ static int ab8500_charger_get_vbus_voltage(struct ab8500_charger *di) } else { vch = 0; } - return vch; + /* Convert to microvolt, IIO returns millivolt */ + return vch * 1000; } /** @@ -923,105 +925,105 @@ static int ab8500_charger_detect_usb_type(struct ab8500_charger *di) /* * This array maps the raw hex value to charger voltage used by the AB8500 - * Values taken from the UM0836 + * Values taken from the UM0836, in microvolt. */ static int ab8500_charger_voltage_map[] = { - 3500 , - 3525 , - 3550 , - 3575 , - 3600 , - 3625 , - 3650 , - 3675 , - 3700 , - 3725 , - 3750 , - 3775 , - 3800 , - 3825 , - 3850 , - 3875 , - 3900 , - 3925 , - 3950 , - 3975 , - 4000 , - 4025 , - 4050 , - 4060 , - 4070 , - 4080 , - 4090 , - 4100 , - 4110 , - 4120 , - 4130 , - 4140 , - 4150 , - 4160 , - 4170 , - 4180 , - 4190 , - 4200 , - 4210 , - 4220 , - 4230 , - 4240 , - 4250 , - 4260 , - 4270 , - 4280 , - 4290 , - 4300 , - 4310 , - 4320 , - 4330 , - 4340 , - 4350 , - 4360 , - 4370 , - 4380 , - 4390 , - 4400 , - 4410 , - 4420 , - 4430 , - 4440 , - 4450 , - 4460 , - 4470 , - 4480 , - 4490 , - 4500 , - 4510 , - 4520 , - 4530 , - 4540 , - 4550 , - 4560 , - 4570 , - 4580 , - 4590 , - 4600 , + 3500000, + 3525000, + 3550000, + 3575000, + 3600000, + 3625000, + 3650000, + 3675000, + 3700000, + 3725000, + 3750000, + 3775000, + 3800000, + 3825000, + 3850000, + 3875000, + 3900000, + 3925000, + 3950000, + 3975000, + 4000000, + 4025000, + 4050000, + 4060000, + 4070000, + 4080000, + 4090000, + 4100000, + 4110000, + 4120000, + 4130000, + 4140000, + 4150000, + 4160000, + 4170000, + 4180000, + 4190000, + 4200000, + 4210000, + 4220000, + 4230000, + 4240000, + 4250000, + 4260000, + 4270000, + 4280000, + 4290000, + 4300000, + 4310000, + 4320000, + 4330000, + 4340000, + 4350000, + 4360000, + 4370000, + 4380000, + 4390000, + 4400000, + 4410000, + 4420000, + 4430000, + 4440000, + 4450000, + 4460000, + 4470000, + 4480000, + 4490000, + 4500000, + 4510000, + 4520000, + 4530000, + 4540000, + 4550000, + 4560000, + 4570000, + 4580000, + 4590000, + 4600000, }; -static int ab8500_voltage_to_regval(int voltage) +static int ab8500_voltage_to_regval(int voltage_uv) { int i; /* Special case for voltage below 3.5V */ - if (voltage < ab8500_charger_voltage_map[0]) + if (voltage_uv < ab8500_charger_voltage_map[0]) return LOW_VOLT_REG; for (i = 1; i < ARRAY_SIZE(ab8500_charger_voltage_map); i++) { - if (voltage < ab8500_charger_voltage_map[i]) + if (voltage_uv < ab8500_charger_voltage_map[i]) return i - 1; } /* If not last element, return error */ i = ARRAY_SIZE(ab8500_charger_voltage_map) - 1; - if (voltage == ab8500_charger_voltage_map[i]) + if (voltage_uv == ab8500_charger_voltage_map[i]) return i; else return -1; @@ -1382,14 +1384,14 @@ static int ab8500_charger_led_en(struct ab8500_charger *di, int on) * ab8500_charger_ac_en() - enable or disable ac charging * @di: pointer to the ab8500_charger structure * @enable: enable/disable flag - * @vset: charging voltage + * @vset_uv: charging voltage in microvolt * @iset_ua: charging current in microampere * * Enable/Disable AC/Mains charging and turns on/off the charging led * respectively. **/ static int ab8500_charger_ac_en(struct ux500_charger *charger, - int enable, int vset, int iset_ua) + int enable, int vset_uv, int iset_ua) { int ret; int volt_index; @@ -1407,7 +1409,7 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger, } /* Enable AC charging */ - dev_dbg(di->dev, "Enable AC: %dmV %duA\n", vset, iset_ua); + dev_dbg(di->dev, "Enable AC: %duV %duA\n", vset_uv, iset_ua); /* * Due to a bug in AB8500, BTEMP_HIGH/LOW interrupts @@ -1429,7 +1431,7 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger, } /* Check if the requested voltage or current is valid */ - volt_index = ab8500_voltage_to_regval(vset); + volt_index = ab8500_voltage_to_regval(vset_uv); curr_index = ab8500_current_to_regval(di, iset_ua); input_curr_index = ab8500_current_to_regval(di, di->bm->chg_params->ac_curr_max_ua); @@ -1559,14 +1561,14 @@ static int ab8500_charger_ac_en(struct ux500_charger *charger, * ab8500_charger_usb_en() - enable usb charging * @di: pointer to the ab8500_charger structure * @enable: enable/disable flag - * @vset: charging voltage + * @vset_uv: charging voltage in microvolt * @ich_out_ua: charger output current in microampere * * Enable/Disable USB charging and turns on/off the charging led respectively. * Returns error code in case of failure else 0(on success) */ static int ab8500_charger_usb_en(struct ux500_charger *charger, - int enable, int vset, int ich_out_ua) + int enable, int vset_uv, int ich_out_ua) { int ret; int volt_index; @@ -1602,10 +1604,10 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, } /* Enable USB charging */ - dev_dbg(di->dev, "Enable USB: %d mV %d uA\n", vset, ich_out_ua); + dev_dbg(di->dev, "Enable USB: %d uV %d uA\n", vset_uv, ich_out_ua); /* Check if the requested voltage or current is valid */ - volt_index = ab8500_voltage_to_regval(vset); + volt_index = ab8500_voltage_to_regval(vset_uv); curr_index = ab8500_current_to_regval(di, ich_out_ua); if (volt_index < 0 || curr_index < 0) { dev_err(di->dev, @@ -1740,14 +1742,14 @@ static int ab8500_external_charger_prepare(struct notifier_block *charger_nb, /** * ab8500_charger_usb_check_enable() - enable usb charging * @charger: pointer to the ux500_charger structure - * @vset: charging voltage + * @vset_uv: charging voltage in microvolt * @iset_ua: charger output current in microampere * * Check if the VBUS charger has been disconnected and reconnected without * AB8500 rising an interrupt. Returns 0 on success. */ static int ab8500_charger_usb_check_enable(struct ux500_charger *charger, - int vset, int iset_ua) + int vset_uv, int iset_ua) { u8 usbch_ctrl1 = 0; int ret = 0; @@ -1776,7 +1778,7 @@ static int ab8500_charger_usb_check_enable(struct ux500_charger *charger, return ret; } - ret = ab8500_charger_usb_en(&di->usb_chg, true, vset, iset_ua); + ret = ab8500_charger_usb_en(&di->usb_chg, true, vset_uv, iset_ua); if (ret < 0) { dev_err(di->dev, "Failed to enable VBUS charger %d\n", __LINE__); @@ -1789,14 +1791,14 @@ static int ab8500_charger_usb_check_enable(struct ux500_charger *charger, /** * ab8500_charger_ac_check_enable() - enable usb charging * @charger: pointer to the ux500_charger structure - * @vset: charging voltage + * @vset_uv: charging voltage in microvolt * @iset_ua: charger output current in micrompere * * Check if the AC charger has been disconnected and reconnected without * AB8500 rising an interrupt. Returns 0 on success. */ static int ab8500_charger_ac_check_enable(struct ux500_charger *charger, - int vset, int iset_ua) + int vset_uv, int iset_ua) { u8 mainch_ctrl1 = 0; int ret = 0; @@ -1826,7 +1828,7 @@ static int ab8500_charger_ac_check_enable(struct ux500_charger *charger, return ret; } - ret = ab8500_charger_ac_en(&di->usb_chg, true, vset, iset_ua); + ret = ab8500_charger_ac_en(&di->usb_chg, true, vset_uv, iset_ua); if (ret < 0) { dev_err(di->dev, "failed to enable AC charger %d\n", __LINE__); @@ -2941,9 +2943,9 @@ static int ab8500_charger_ac_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_NOW: ret = ab8500_charger_get_ac_voltage(di); if (ret >= 0) - di->ac.charger_voltage = ret; + di->ac.charger_voltage_uv = ret; /* On error, use previous value */ - val->intval = di->ac.charger_voltage * 1000; + val->intval = di->ac.charger_voltage_uv; break; case POWER_SUPPLY_PROP_VOLTAGE_AVG: /* @@ -3010,8 +3012,8 @@ static int ab8500_charger_usb_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_NOW: ret = ab8500_charger_get_vbus_voltage(di); if (ret >= 0) - di->usb.charger_voltage = ret; - val->intval = di->usb.charger_voltage * 1000; + di->usb.charger_voltage_uv = ret; + val->intval = di->usb.charger_voltage_uv; break; case POWER_SUPPLY_PROP_VOLTAGE_AVG: /* @@ -3521,7 +3523,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->ac_chg.ops.check_enable = &ab8500_charger_ac_check_enable; di->ac_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; di->ac_chg.ops.update_curr = &ab8500_charger_update_charger_current; - di->ac_chg.max_out_volt = ab8500_charger_voltage_map[ + di->ac_chg.max_out_volt_uv = ab8500_charger_voltage_map[ ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; di->ac_chg.max_out_curr_ua = ab8500_charge_output_curr_map[ARRAY_SIZE(ab8500_charge_output_curr_map) - 1]; @@ -3542,7 +3544,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->usb_chg.ops.check_enable = &ab8500_charger_usb_check_enable; di->usb_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; di->usb_chg.ops.update_curr = &ab8500_charger_update_charger_current; - di->usb_chg.max_out_volt = ab8500_charger_voltage_map[ + di->usb_chg.max_out_volt_uv = ab8500_charger_voltage_map[ ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; di->usb_chg.max_out_curr_ua = ab8500_charge_output_curr_map[ARRAY_SIZE(ab8500_charge_output_curr_map) - 1]; From patchwork Thu Nov 18 02:17:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625889 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9FFC4C433F5 for ; Thu, 18 Nov 2021 02:20:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 85D1861AD0 for ; Thu, 18 Nov 2021 02:20:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241589AbhKRCXh (ORCPT ); Wed, 17 Nov 2021 21:23:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49336 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242501AbhKRCXd (ORCPT ); Wed, 17 Nov 2021 21:23:33 -0500 Received: from mail-lf1-x12c.google.com (mail-lf1-x12c.google.com [IPv6:2a00:1450:4864:20::12c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 825A5C061764 for ; Wed, 17 Nov 2021 18:20:32 -0800 (PST) Received: by mail-lf1-x12c.google.com with SMTP id b1so17825633lfs.13 for ; Wed, 17 Nov 2021 18:20:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xBgzA3ht73l6japkeYYBDH9TpjheShCwlXX6OzJoFMM=; b=AIjI0bQIWRb97nmX3ZWmvIRk/gU8fmCj6HsajEa8F92V5qKceOvKEZmliK70ADO9se hWHwNlfg7/xhIDpDrglC1jqtPHHOA9w7sriZb4O+VIQLyClhiRhGM7p2/AgpAtEx1ZXK W2Rq5njKYtKLWoYpEDy39k/8IvFfpUozKuAgu++T1RQypQO3Ku1VyLu6NqhO5SZ7g4XT dMqPwR8m81RJ702LPhEuZb8bGTUmtyztLNvs50YXQsuVfvshIiS+MCmxRfpSbg3kSGTM vsipP9P98DI6aqIXWrwOIMZVkwkTHk2wPP8MOGsD2RX6MXyijTTq8g5z6tD2bKmpG3eA ofLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xBgzA3ht73l6japkeYYBDH9TpjheShCwlXX6OzJoFMM=; b=HYSth0CDZ59PKyTzNZGf9uXJO5W08ASdhcq8zm9Qvd7xXdTHPZvuiOsHneRhgrT27l v2mVMCZgbtvUPyD0qmHSU50J3H/ycZTHMjEazkx+qsm66knOfaMM9Hmzj+rpGcx267OM ZoBPNvqRVIt48+5dDV1SS4oSWw5By8ittrT/qrBx1E+JhvIz1b5WCOrkn0CuNquv2IpL xj2GphpRJuFxW9+sdj0+BMZv74RiwbH2pUw67zWfmtp82cTq+lnvNH0ItJAvajablN67 lWykHA1SIzCCo6e3eaKA/FcgF8N2rDTCfppefL9Hq6nuG7+1AUfkg+szmSeHuKBFL/C6 bkmQ== X-Gm-Message-State: AOAM5310xMwpLH3JbZHvLx+Ennn09GkvTylOXa2+x6wrx7Sx0MXJPyLL ZUqAzhh4HPydQKJ9kP/IHAxEtQ== X-Google-Smtp-Source: ABdhPJyPCmefvWaH8hsX/BEvUaJz0jhPIb9evDw/SfW5JqdjIUJmqpboFUoY0VgEKElQtgt1Fv48Mg== X-Received: by 2002:a05:6512:15a7:: with SMTP id bp39mr20486163lfb.145.1637202030879; Wed, 17 Nov 2021 18:20:30 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.20.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:29 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 15/16] power: supply: ab8500: Standardize temp res lookup Date: Thu, 18 Nov 2021 03:17:51 +0100 Message-Id: <20211118021752.2262818-16-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The lookup from battery temperature to internal resistance was using its own format. Rewrite this to use the table inside struct power_supply_battery_info:s resist_table. The supplied resistance table has to be rewritten to express the resistance in percent of the factory resistance as a side effect. We can then rely on the library function power_supply_temp2resist_simple() to interpolate the internal resistance percent from the temperature. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500-bm.h | 15 --------- drivers/power/supply/ab8500_bmdata.c | 31 +++++++++++------- drivers/power/supply/ab8500_fg.c | 47 +++++++++++----------------- 3 files changed, 38 insertions(+), 55 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index 56bf70bc673a..fd85b54d5ec5 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -379,8 +379,6 @@ struct ab8500_maxim_parameters { * @r_to_t_tbl: table containing resistance to temp points * @n_v_cap_tbl_elements: number of elements in v_to_cap_tbl * @v_to_cap_tbl: Voltage to capacity (in %) table - * @n_batres_tbl_elements number of elements in the batres_tbl - * @batres_tbl battery internal resistance vs temperature table */ struct ab8500_battery_type { int resis_high; @@ -397,8 +395,6 @@ struct ab8500_battery_type { const struct ab8500_res_to_temp *r_to_t_tbl; int n_v_cap_tbl_elements; const struct ab8500_v_to_cap *v_to_cap_tbl; - int n_batres_tbl_elements; - const struct batres_vs_temp *batres_tbl; }; /** @@ -502,17 +498,6 @@ struct res_to_temp { int resist; }; -/** - * struct batres_vs_temp - defines one point in a temp vs battery internal - * resistance curve. - * @temp: battery pack temperature in Celsius - * @resist: battery internal reistance in mOhm - */ -struct batres_vs_temp { - int temp; - int resist; -}; - /* Forward declaration */ struct ab8500_fg; diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index a41b9f3a88cb..8d85fcf4abe7 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -67,16 +67,17 @@ static const struct ab8500_res_to_temp temp_tbl[] = { /* * Note that the batres_vs_temp table must be strictly sorted by falling - * temperature values to work. + * temperature values to work. Factory resistance is 300 mOhm and the + * resistance values to the right are percentages of 300 mOhm. */ -static const struct batres_vs_temp temp_to_batres_tbl_thermistor[] = { - { 40, 120}, - { 30, 135}, - { 20, 165}, - { 10, 230}, - { 00, 325}, - {-10, 445}, - {-20, 595}, +static struct power_supply_resistance_temp_table temp_to_batres_tbl_thermistor[] = { + { .temp = 40, .resistance = 40 /* 120 mOhm */ }, + { .temp = 30, .resistance = 45 /* 135 mOhm */ }, + { .temp = 20, .resistance = 55 /* 165 mOhm */ }, + { .temp = 10, .resistance = 77 /* 230 mOhm */ }, + { .temp = 00, .resistance = 108 /* 325 mOhm */ }, + { .temp = -10, .resistance = 158 /* 445 mOhm */ }, + { .temp = -20, .resistance = 198 /* 595 mOhm */ }, }; /* Default battery type for reference designs is the unknown type */ @@ -95,8 +96,6 @@ static struct ab8500_battery_type bat_type_thermistor_unknown = { .r_to_t_tbl = temp_tbl, .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), .v_to_cap_tbl = cap_tbl, - .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor), - .batres_tbl = temp_to_batres_tbl_thermistor, }; static const struct ab8500_bm_capacity_levels cap_levels = { @@ -209,8 +208,16 @@ int ab8500_bm_of_probe(struct power_supply *psy, /* Charging stops when we drop below this current */ bi->charge_term_current_ua = 200000; - if (bi->factory_internal_resistance_uohm < 0) + /* + * Internal resistance and factory resistance are tightly coupled + * so both MUST be defined or we fall back to defaults. + */ + if ((bi->factory_internal_resistance_uohm < 0) || + !bi->resist_table) { bi->factory_internal_resistance_uohm = 300000; + bi->resist_table = temp_to_batres_tbl_thermistor; + bi->resist_table_size = ARRAY_SIZE(temp_to_batres_tbl_thermistor); + } if (bi->temp_min == INT_MIN) bi->temp_min = AB8500_TEMP_UNDER; diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c index daa008138b05..96bb81e539f0 100644 --- a/drivers/power/supply/ab8500_fg.c +++ b/drivers/power/supply/ab8500_fg.c @@ -901,44 +901,35 @@ static int ab8500_fg_uncomp_volt_to_capacity(struct ab8500_fg *di) * @di: pointer to the ab8500_fg structure * * Returns battery inner resistance added with the fuel gauge resistor value - * to get the total resistance in the whole link from gnd to bat+ node. + * to get the total resistance in the whole link from gnd to bat+ node + * in milliohm. */ static int ab8500_fg_battery_resistance(struct ab8500_fg *di) { - int i, tbl_size; - const struct batres_vs_temp *tbl; - int resist = 0; - - tbl = di->bm->bat_type->batres_tbl; - tbl_size = di->bm->bat_type->n_batres_tbl_elements; - - for (i = 0; i < tbl_size; ++i) { - if (di->bat_temp / 10 > tbl[i].temp) - break; - } + struct power_supply_battery_info *bi = &di->bm->bi; + int resistance_percent = 0; + int resistance; - if ((i > 0) && (i < tbl_size)) { - resist = fixp_linear_interpolate( - tbl[i].temp, - tbl[i].resist, - tbl[i-1].temp, - tbl[i-1].resist, - di->bat_temp / 10); - } else if (i == 0) { - resist = tbl[0].resist; - } else { - resist = tbl[tbl_size - 1].resist; - } + resistance_percent = power_supply_temp2resist_simple(bi->resist_table, + bi->resist_table_size, + di->bat_temp / 10); + /* + * We get a percentage of factory resistance here so first get + * the factory resistance in milliohms then calculate how much + * resistance we have at this temperature. + */ + resistance = (bi->factory_internal_resistance_uohm / 1000); + resistance = resistance * resistance_percent / 100; dev_dbg(di->dev, "%s Temp: %d battery internal resistance: %d" " fg resistance %d, total: %d (mOhm)\n", - __func__, di->bat_temp, resist, di->bm->fg_res / 10, - (di->bm->fg_res / 10) + resist); + __func__, di->bat_temp, resistance, di->bm->fg_res / 10, + (di->bm->fg_res / 10) + resistance); /* fg_res variable is in 0.1mOhm */ - resist += di->bm->fg_res / 10; + resistance += di->bm->fg_res / 10; - return resist; + return resistance; } /** From patchwork Thu Nov 18 02:17:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12625891 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3B50C433F5 for ; Thu, 18 Nov 2021 02:20:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CAC5D61ABF for ; Thu, 18 Nov 2021 02:20:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242494AbhKRCXk (ORCPT ); Wed, 17 Nov 2021 21:23:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49348 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242503AbhKRCXe (ORCPT ); Wed, 17 Nov 2021 21:23:34 -0500 Received: from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com [IPv6:2a00:1450:4864:20::12a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D7399C061570 for ; Wed, 17 Nov 2021 18:20:34 -0800 (PST) Received: by mail-lf1-x12a.google.com with SMTP id y26so17982917lfa.11 for ; Wed, 17 Nov 2021 18:20:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0Famoh5iK69cg4/Y7eCq1AA1UA/L3y9Gage6izqzad4=; b=aUh5qaoa6HI0YTwXVeQCfpCH1kOmBJCMaLKsIyRv7sj7gq9BaD9ld6p2d1Ges/0BJQ YpzVKRumpfVs4B5yrpq6MQztS9lqh7TuvSnzKNnteOFYud2UBn+Oz43D33on00Zt3CuB 9aISaHWsBgMTxm96ZOLFslS7gkLitoFxKZvPgJUJqaBXL/BBT6epaDZXajgHrlC0wzr0 ta/ReFqyxYj0JlqPeFybeTv0wDL0zKo4+etpif0Jwq+595fwyzaOYFr4u+g+8Pb7DOXA 8hgpu8dBhJfqtL6l1t3XFGyohIgsUZJNnpr9MtvFJXk72a0YTUZk9UlZ8Vnbz5Z53oZM sh8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0Famoh5iK69cg4/Y7eCq1AA1UA/L3y9Gage6izqzad4=; b=4VjhVIaCdAsOcv15iSWA0zSaMoGsCKiPNywh+mKDQsUFaYnG7K7HqLReCp8a5fLZaN VBbJJX7sMtf0gcpYqIIjwqnXKve5EQKBRjljajD/JfbB42Gp1zyJnYhYsyIMfp+dtQ52 QUXp7EwZWHsDezgJ4ncGNdYozBwAqET8rTCoNBcujY8ARBKCkBM4Slft5KXTpv/CCEZp u9J6Jj0r4qmPC9i5Q1tOPkWh+B5WRiBqI69MlYJO1iNYYqJRdBnsi7w9kuriu/IuP4hM 33B3LXH4xPAM6Z0BR2G2Fv8dHZN3L2QkFoKAznBP6aEWroJuv/V0Uo5wjCrcMVhzrM1n tUqQ== X-Gm-Message-State: AOAM531YsBSoS1SMTO6X+IlVgVr8Zgni6xXWGir3wfWKeveV2x9SoraN MShHYLoMiteum9KIWNOComeYNg== X-Google-Smtp-Source: ABdhPJzp0/Gdi+e1edj+h6RUNrbYclH63T7gJYybKILmSvJqujB86VuWuiIQhEv/R3wglBvrOQjN/Q== X-Received: by 2002:a05:6512:104c:: with SMTP id c12mr19632147lfb.470.1637202033151; Wed, 17 Nov 2021 18:20:33 -0800 (PST) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id j19sm165321lfe.120.2021.11.17.18.20.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 18:20:32 -0800 (PST) From: Linus Walleij To: Sebastian Reichel Cc: linux-pm@vger.kernel.org, Linus Walleij Subject: [PATCH 16/16] power: supply: ab8500: Standardize capacity lookup Date: Thu, 18 Nov 2021 03:17:52 +0100 Message-Id: <20211118021752.2262818-17-linus.walleij@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211118021752.2262818-1-linus.walleij@linaro.org> References: <20211118021752.2262818-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The AB8500 charger only has one capacity table with unspecified temperature, so we assume this capacity is given for 20 degrees Celsius. Convert this table to use the OCV (open circuit voltage) tables in struct power_supply_battery_ocv_table. In the process, convert the fuel gauge driver to use microvolts and microamperes so we can use the same internals as the power supply subsystem without having to multiply and divide with 1000 in a few places. Also convert high_curr_threshold and lowbat_threshold to use microamperes and microvolts as these are closely related to these changes. Drop the unused overbat_threshold member in the custom struct ab8500_fg_parameters. Signed-off-by: Linus Walleij --- drivers/power/supply/ab8500-bm.h | 30 +-- drivers/power/supply/ab8500_bmdata.c | 63 +++--- drivers/power/supply/ab8500_fg.c | 286 +++++++++++++-------------- 3 files changed, 173 insertions(+), 206 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index fd85b54d5ec5..573f7a428f1f 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -196,8 +196,8 @@ enum bup_vch_sel { #define BATT_OVV_TH_3P7 0x00 #define BATT_OVV_TH_4P75 0x01 -/* A value to indicate over voltage */ -#define BATT_OVV_VALUE 4750 +/* A value to indicate over voltage (microvolts) */ +#define BATT_OVV_VALUE 4750000 /* VBUS OVV constants */ #define VBUS_OVV_SELECT_MASK 0x78 @@ -284,16 +284,6 @@ struct ab8500_res_to_temp { int resist; }; -/** - * struct ab8500_v_to_cap - Table for translating voltage to capacity - * @voltage: Voltage in mV - * @capacity: Capacity in percent - */ -struct ab8500_v_to_cap { - int voltage; - int capacity; -}; - /* Forward declaration */ struct ab8500_fg; @@ -307,10 +297,9 @@ struct ab8500_fg; * @init_total_time: Total init time during startup * @high_curr_time: Time current has to be high to go to recovery * @accu_charging: FG accumulation time while charging - * @accu_high_curr: FG accumulation time in high current mode - * @high_curr_threshold: High current threshold, in mA - * @lowbat_threshold: Low battery threshold, in mV - * @overbat_threshold: Over battery threshold, in mV + * @accu_high_curr_ua: FG accumulation time in high current mode + * @high_curr_threshold_ua: High current threshold, in uA + * @lowbat_threshold_uv: Low battery threshold, in uV * @battok_falling_th_sel0 Threshold in mV for battOk signal sel0 * Resolution in 50 mV step. * @battok_raising_th_sel1 Threshold in mV for battOk signal sel1 @@ -335,9 +324,8 @@ struct ab8500_fg_parameters { int high_curr_time; int accu_charging; int accu_high_curr; - int high_curr_threshold; - int lowbat_threshold; - int overbat_threshold; + int high_curr_threshold_ua; + int lowbat_threshold_uv; int battok_falling_th_sel0; int battok_raising_th_sel1; int user_cap_limit; @@ -377,8 +365,6 @@ struct ab8500_maxim_parameters { * @low_high_vol_lvl: charger voltage in temp low/high state in mV' * @n_r_t_tbl_elements: number of elements in r_to_t_tbl * @r_to_t_tbl: table containing resistance to temp points - * @n_v_cap_tbl_elements: number of elements in v_to_cap_tbl - * @v_to_cap_tbl: Voltage to capacity (in %) table */ struct ab8500_battery_type { int resis_high; @@ -393,8 +379,6 @@ struct ab8500_battery_type { int low_high_vol_lvl; int n_temp_tbl_elements; const struct ab8500_res_to_temp *r_to_t_tbl; - int n_v_cap_tbl_elements; - const struct ab8500_v_to_cap *v_to_cap_tbl; }; /** diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c index 8d85fcf4abe7..890e6fd63f68 100644 --- a/drivers/power/supply/ab8500_bmdata.c +++ b/drivers/power/supply/ab8500_bmdata.c @@ -16,31 +16,31 @@ /* Default: temperature hysteresis */ #define AB8500_TEMP_HYSTERESIS 3 -static const struct ab8500_v_to_cap cap_tbl[] = { - {4186, 100}, - {4163, 99}, - {4114, 95}, - {4068, 90}, - {3990, 80}, - {3926, 70}, - {3898, 65}, - {3866, 60}, - {3833, 55}, - {3812, 50}, - {3787, 40}, - {3768, 30}, - {3747, 25}, - {3730, 20}, - {3705, 15}, - {3699, 14}, - {3684, 12}, - {3672, 9}, - {3657, 7}, - {3638, 6}, - {3556, 4}, - {3424, 2}, - {3317, 1}, - {3094, 0}, +static struct power_supply_battery_ocv_table ocv_cap_tbl[] = { + { .ocv = 4186000, .capacity = 100}, + { .ocv = 4163000, .capacity = 99}, + { .ocv = 4114000, .capacity = 95}, + { .ocv = 4068000, .capacity = 90}, + { .ocv = 3990000, .capacity = 80}, + { .ocv = 3926000, .capacity = 70}, + { .ocv = 3898000, .capacity = 65}, + { .ocv = 3866000, .capacity = 60}, + { .ocv = 3833000, .capacity = 55}, + { .ocv = 3812000, .capacity = 50}, + { .ocv = 3787000, .capacity = 40}, + { .ocv = 3768000, .capacity = 30}, + { .ocv = 3747000, .capacity = 25}, + { .ocv = 3730000, .capacity = 20}, + { .ocv = 3705000, .capacity = 15}, + { .ocv = 3699000, .capacity = 14}, + { .ocv = 3684000, .capacity = 12}, + { .ocv = 3672000, .capacity = 9}, + { .ocv = 3657000, .capacity = 7}, + { .ocv = 3638000, .capacity = 6}, + { .ocv = 3556000, .capacity = 4}, + { .ocv = 3424000, .capacity = 2}, + { .ocv = 3317000, .capacity = 1}, + { .ocv = 3094000, .capacity = 0}, }; /* @@ -94,8 +94,6 @@ static struct ab8500_battery_type bat_type_thermistor_unknown = { .low_high_vol_lvl = 4000, .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl), .r_to_t_tbl = temp_tbl, - .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl), - .v_to_cap_tbl = cap_tbl, }; static const struct ab8500_bm_capacity_levels cap_levels = { @@ -115,8 +113,8 @@ static const struct ab8500_fg_parameters fg = { .high_curr_time = 60, .accu_charging = 30, .accu_high_curr = 30, - .high_curr_threshold = 50, - .lowbat_threshold = 3100, + .high_curr_threshold_ua = 50000, + .lowbat_threshold_uv = 3100000, .battok_falling_th_sel0 = 2860, .battok_raising_th_sel1 = 2860, .maint_thres = 95, @@ -219,6 +217,13 @@ int ab8500_bm_of_probe(struct power_supply *psy, bi->resist_table_size = ARRAY_SIZE(temp_to_batres_tbl_thermistor); } + if (!bi->ocv_table[0]) { + /* Default capacity table at say 25 degrees Celsius */ + bi->ocv_temp[0] = 25; + bi->ocv_table[0] = ocv_cap_tbl; + bi->ocv_table_size[0] = ARRAY_SIZE(ocv_cap_tbl); + } + if (bi->temp_min == INT_MIN) bi->temp_min = AB8500_TEMP_UNDER; if (bi->temp_max == INT_MAX) diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c index 96bb81e539f0..eb3e5c4ca44f 100644 --- a/drivers/power/supply/ab8500_fg.c +++ b/drivers/power/supply/ab8500_fg.c @@ -156,10 +156,10 @@ struct inst_curr_result_list { * @dev: Pointer to the structure device * @node: a list of AB8500 FGs, hence prepared for reentrance * @irq holds the CCEOC interrupt number - * @vbat: Battery voltage in mV + * @vbat_uv: Battery voltage in uV * @vbat_nom_uv: Nominal battery voltage in uV - * @inst_curr: Instantenous battery current in mA - * @avg_curr: Average battery current in mA + * @inst_curr_ua: Instantenous battery current in uA + * @avg_curr_ua: Average battery current in uA * @bat_temp battery temperature * @fg_samples: Number of samples used in the FG accumulation * @accu_charge: Accumulated charge from the last conversion @@ -198,10 +198,10 @@ struct ab8500_fg { struct device *dev; struct list_head node; int irq; - int vbat; + int vbat_uv; int vbat_nom_uv; - int inst_curr; - int avg_curr; + int inst_curr_ua; + int avg_curr_ua; int bat_temp; int fg_samples; int accu_charge; @@ -265,84 +265,84 @@ static enum power_supply_property ab8500_fg_props[] = { /* * This array maps the raw hex value to lowbat voltage used by the AB8500 - * Values taken from the UM0836 + * Values taken from the UM0836, in microvolts. */ static int ab8500_fg_lowbat_voltage_map[] = { - 2300 , - 2325 , - 2350 , - 2375 , - 2400 , - 2425 , - 2450 , - 2475 , - 2500 , - 2525 , - 2550 , - 2575 , - 2600 , - 2625 , - 2650 , - 2675 , - 2700 , - 2725 , - 2750 , - 2775 , - 2800 , - 2825 , - 2850 , - 2875 , - 2900 , - 2925 , - 2950 , - 2975 , - 3000 , - 3025 , - 3050 , - 3075 , - 3100 , - 3125 , - 3150 , - 3175 , - 3200 , - 3225 , - 3250 , - 3275 , - 3300 , - 3325 , - 3350 , - 3375 , - 3400 , - 3425 , - 3450 , - 3475 , - 3500 , - 3525 , - 3550 , - 3575 , - 3600 , - 3625 , - 3650 , - 3675 , - 3700 , - 3725 , - 3750 , - 3775 , - 3800 , - 3825 , - 3850 , - 3850 , + 2300000, + 2325000, + 2350000, + 2375000, + 2400000, + 2425000, + 2450000, + 2475000, + 2500000, + 2525000, + 2550000, + 2575000, + 2600000, + 2625000, + 2650000, + 2675000, + 2700000, + 2725000, + 2750000, + 2775000, + 2800000, + 2825000, + 2850000, + 2875000, + 2900000, + 2925000, + 2950000, + 2975000, + 3000000, + 3025000, + 3050000, + 3075000, + 3100000, + 3125000, + 3150000, + 3175000, + 3200000, + 3225000, + 3250000, + 3275000, + 3300000, + 3325000, + 3350000, + 3375000, + 3400000, + 3425000, + 3450000, + 3475000, + 3500000, + 3525000, + 3550000, + 3575000, + 3600000, + 3625000, + 3650000, + 3675000, + 3700000, + 3725000, + 3750000, + 3775000, + 3800000, + 3825000, + 3850000, + 3850000, }; -static u8 ab8500_volt_to_regval(int voltage) +static u8 ab8500_volt_to_regval(int voltage_uv) { int i; - if (voltage < ab8500_fg_lowbat_voltage_map[0]) + if (voltage_uv < ab8500_fg_lowbat_voltage_map[0]) return 0; for (i = 0; i < ARRAY_SIZE(ab8500_fg_lowbat_voltage_map); i++) { - if (voltage < ab8500_fg_lowbat_voltage_map[i]) + if (voltage_uv < ab8500_fg_lowbat_voltage_map[i]) return (u8) i - 1; } @@ -353,16 +353,16 @@ static u8 ab8500_volt_to_regval(int voltage) /** * ab8500_fg_is_low_curr() - Low or high current mode * @di: pointer to the ab8500_fg structure - * @curr: the current to base or our decision on + * @curr_ua: the current to base or our decision on in microampere * * Low current mode if the current consumption is below a certain threshold */ -static int ab8500_fg_is_low_curr(struct ab8500_fg *di, int curr) +static int ab8500_fg_is_low_curr(struct ab8500_fg *di, int curr_ua) { /* * We want to know if we're in low current mode */ - if (curr > -di->bm->fg_params->high_curr_threshold) + if (curr_ua > -di->bm->fg_params->high_curr_threshold_ua) return true; else return false; @@ -600,13 +600,13 @@ int ab8500_fg_inst_curr_done(struct ab8500_fg *di) /** * ab8500_fg_inst_curr_finalize() - battery instantaneous current * @di: pointer to the ab8500_fg structure - * @res: battery instantenous current(on success) + * @curr_ua: battery instantenous current in microampere (on success) * * Returns 0 or an error code * Note: This is part "two" and has to be called at earliest 250 ms * after ab8500_fg_inst_curr_start() */ -int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res) +int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *curr_ua) { u8 low, high; int val; @@ -662,14 +662,13 @@ int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res) /* * Convert to unit value in mA * Full scale input voltage is - * 63.160mV => LSB = 63.160mV/(4096*res) = 1.542mA + * 63.160mV => LSB = 63.160mV/(4096*res) = 1.542.000 uA * Given a 250ms conversion cycle time the LSB corresponds * to 107.1 nAh. Convert to current by dividing by the conversion * time in hours (250ms = 1 / (3600 * 4)h) * 107.1nAh assumes 10mOhm, but fg_res is in 0.1mOhm */ - val = (val * QLSB_NANO_AMP_HOURS_X10 * 36 * 4) / - (1000 * di->bm->fg_res); + val = (val * QLSB_NANO_AMP_HOURS_X10 * 36 * 4) / di->bm->fg_res; if (di->turn_off_fg) { dev_dbg(di->dev, "%s Disable FG\n", __func__); @@ -687,7 +686,7 @@ int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res) goto fail; } mutex_unlock(&di->cc_lock); - (*res) = val; + *curr_ua = val; return 0; fail: @@ -698,15 +697,15 @@ int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res) /** * ab8500_fg_inst_curr_blocking() - battery instantaneous current * @di: pointer to the ab8500_fg structure - * @res: battery instantenous current(on success) * - * Returns 0 else error code + * Returns battery instantenous current in microampere (on success) + * else error code */ int ab8500_fg_inst_curr_blocking(struct ab8500_fg *di) { int ret; unsigned long timeout; - int res = 0; + int curr_ua = 0; ret = ab8500_fg_inst_curr_start(di); if (ret) { @@ -729,14 +728,14 @@ int ab8500_fg_inst_curr_blocking(struct ab8500_fg *di) } } - ret = ab8500_fg_inst_curr_finalize(di, &res); + ret = ab8500_fg_inst_curr_finalize(di, &curr_ua); if (ret) { dev_err(di->dev, "Failed to finalize fg_inst\n"); return 0; } - dev_dbg(di->dev, "%s instant current: %d", __func__, res); - return res; + dev_dbg(di->dev, "%s instant current: %d uA", __func__, curr_ua); + return curr_ua; fail: disable_irq(di->irq); mutex_unlock(&di->cc_lock); @@ -796,13 +795,12 @@ static void ab8500_fg_acc_cur_work(struct work_struct *work) (100 * di->bm->fg_res); /* - * Convert to unit value in mA + * Convert to unit value in uA * by dividing by the conversion * time in hours (= samples / (3600 * 4)h) - * and multiply with 1000 */ - di->avg_curr = (val * QLSB_NANO_AMP_HOURS_X10 * 36) / - (1000 * di->bm->fg_res * (di->fg_samples / 4)); + di->avg_curr_ua = (val * QLSB_NANO_AMP_HOURS_X10 * 36) / + (di->bm->fg_res * (di->fg_samples / 4)); di->flags.conv_done = true; @@ -824,7 +822,7 @@ static void ab8500_fg_acc_cur_work(struct work_struct *work) * ab8500_fg_bat_voltage() - get battery voltage * @di: pointer to the ab8500_fg structure * - * Returns battery voltage(on success) else error code + * Returns battery voltage in microvolts (on success) else error code */ static int ab8500_fg_bat_voltage(struct ab8500_fg *di) { @@ -839,6 +837,8 @@ static int ab8500_fg_bat_voltage(struct ab8500_fg *di) return prev; } + /* IIO returns millivolts but we want microvolts */ + vbat *= 1000; prev = vbat; return vbat; } @@ -846,41 +846,16 @@ static int ab8500_fg_bat_voltage(struct ab8500_fg *di) /** * ab8500_fg_volt_to_capacity() - Voltage based capacity * @di: pointer to the ab8500_fg structure - * @voltage: The voltage to convert to a capacity + * @voltage_uv: The voltage to convert to a capacity in microvolt * * Returns battery capacity in per mille based on voltage */ -static int ab8500_fg_volt_to_capacity(struct ab8500_fg *di, int voltage) +static int ab8500_fg_volt_to_capacity(struct ab8500_fg *di, int voltage_uv) { - int i, tbl_size; - const struct ab8500_v_to_cap *tbl; - int cap = 0; - - tbl = di->bm->bat_type->v_to_cap_tbl; - tbl_size = di->bm->bat_type->n_v_cap_tbl_elements; - - for (i = 0; i < tbl_size; ++i) { - if (voltage > tbl[i].voltage) - break; - } - - if ((i > 0) && (i < tbl_size)) { - cap = fixp_linear_interpolate( - tbl[i].voltage, - tbl[i].capacity * 10, - tbl[i-1].voltage, - tbl[i-1].capacity * 10, - voltage); - } else if (i == 0) { - cap = 1000; - } else { - cap = 0; - } - - dev_dbg(di->dev, "%s Vbat: %d, Cap: %d per mille", - __func__, voltage, cap); + struct power_supply_battery_info *bi = &di->bm->bi; - return cap; + /* Multiply by 10 because the capacity is tracked in per mille */ + return power_supply_batinfo_ocv2cap(bi, voltage_uv, di->bat_temp) * 10; } /** @@ -892,8 +867,8 @@ static int ab8500_fg_volt_to_capacity(struct ab8500_fg *di, int voltage) */ static int ab8500_fg_uncomp_volt_to_capacity(struct ab8500_fg *di) { - di->vbat = ab8500_fg_bat_voltage(di); - return ab8500_fg_volt_to_capacity(di, di->vbat); + di->vbat_uv = ab8500_fg_bat_voltage(di); + return ab8500_fg_volt_to_capacity(di, di->vbat_uv); } /** @@ -941,31 +916,34 @@ static int ab8500_fg_battery_resistance(struct ab8500_fg *di) */ static int ab8500_fg_load_comp_volt_to_capacity(struct ab8500_fg *di) { - int vbat_comp, res; + int vbat_comp_uv, res; int i = 0; - int vbat = 0; + int vbat_uv = 0; ab8500_fg_inst_curr_start(di); do { - vbat += ab8500_fg_bat_voltage(di); + vbat_uv += ab8500_fg_bat_voltage(di); i++; usleep_range(5000, 6000); } while (!ab8500_fg_inst_curr_done(di)); - ab8500_fg_inst_curr_finalize(di, &di->inst_curr); + ab8500_fg_inst_curr_finalize(di, &di->inst_curr_ua); - di->vbat = vbat / i; + di->vbat_uv = vbat_uv / i; res = ab8500_fg_battery_resistance(di); - /* Use Ohms law to get the load compensated voltage */ - vbat_comp = di->vbat - (di->inst_curr * res) / 1000; + /* + * Use Ohms law to get the load compensated voltage. + * Divide by 1000 to get from milliohms to ohms. + */ + vbat_comp_uv = di->vbat_uv - (di->inst_curr_ua * res) / 1000; - dev_dbg(di->dev, "%s Measured Vbat: %dmV,Compensated Vbat %dmV, " - "R: %dmOhm, Current: %dmA Vbat Samples: %d\n", - __func__, di->vbat, vbat_comp, res, di->inst_curr, i); + dev_dbg(di->dev, "%s Measured Vbat: %d uV,Compensated Vbat %d uV, " + "R: %d mOhm, Current: %d uA Vbat Samples: %d\n", + __func__, di->vbat_uv, vbat_comp_uv, res, di->inst_curr_ua, i); - return ab8500_fg_volt_to_capacity(di, vbat_comp); + return ab8500_fg_volt_to_capacity(di, vbat_comp_uv); } /** @@ -1052,8 +1030,8 @@ static int ab8500_fg_calc_cap_charging(struct ab8500_fg *di) ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); /* We need to update battery voltage and inst current when charging */ - di->vbat = ab8500_fg_bat_voltage(di); - di->inst_curr = ab8500_fg_inst_curr_blocking(di); + di->vbat_uv = ab8500_fg_bat_voltage(di); + di->inst_curr_ua = ab8500_fg_inst_curr_blocking(di); return di->bat_cap.mah; } @@ -1580,9 +1558,9 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di) * RECOVERY_SLEEP if time left. * If high, go to READOUT */ - di->inst_curr = ab8500_fg_inst_curr_blocking(di); + di->inst_curr_ua = ab8500_fg_inst_curr_blocking(di); - if (ab8500_fg_is_low_curr(di, di->inst_curr)) { + if (ab8500_fg_is_low_curr(di, di->inst_curr_ua)) { if (di->recovery_cnt > di->bm->fg_params->recovery_total_time) { di->fg_samples = SEC_TO_SAMPLE( @@ -1615,9 +1593,9 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di) break; case AB8500_FG_DISCHARGE_READOUT: - di->inst_curr = ab8500_fg_inst_curr_blocking(di); + di->inst_curr_ua = ab8500_fg_inst_curr_blocking(di); - if (ab8500_fg_is_low_curr(di, di->inst_curr)) { + if (ab8500_fg_is_low_curr(di, di->inst_curr_ua)) { /* Detect mode change */ if (di->high_curr_mode) { di->high_curr_mode = false; @@ -1763,9 +1741,9 @@ static void ab8500_fg_algorithm(struct ab8500_fg *di) di->bat_cap.prev_mah, di->bat_cap.prev_percent, di->bat_cap.prev_level, - di->vbat, - di->inst_curr, - di->avg_curr, + di->vbat_uv, + di->inst_curr_ua, + di->avg_curr_ua, di->accu_charge, di->flags.charging, di->charge_state, @@ -1858,15 +1836,15 @@ static void ab8500_fg_check_hw_failure_work(struct work_struct *work) */ static void ab8500_fg_low_bat_work(struct work_struct *work) { - int vbat; + int vbat_uv; struct ab8500_fg *di = container_of(work, struct ab8500_fg, fg_low_bat_work.work); - vbat = ab8500_fg_bat_voltage(di); + vbat_uv = ab8500_fg_bat_voltage(di); /* Check if LOW_BAT still fulfilled */ - if (vbat < di->bm->fg_params->lowbat_threshold) { + if (vbat_uv < di->bm->fg_params->lowbat_threshold_uv) { /* Is it time to shut down? */ if (di->low_bat_cnt < 1) { di->flags.low_bat = true; @@ -2096,15 +2074,15 @@ static int ab8500_fg_get_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_VOLTAGE_NOW: if (di->flags.bat_ovv) - val->intval = BATT_OVV_VALUE * 1000; + val->intval = BATT_OVV_VALUE; else - val->intval = di->vbat * 1000; + val->intval = di->vbat_uv; break; case POWER_SUPPLY_PROP_CURRENT_NOW: - val->intval = di->inst_curr * 1000; + val->intval = di->inst_curr_ua; break; case POWER_SUPPLY_PROP_CURRENT_AVG: - val->intval = di->avg_curr * 1000; + val->intval = di->avg_curr_ua; break; case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: val->intval = ab8500_fg_convert_mah_to_uwh(di, @@ -2310,7 +2288,7 @@ static int ab8500_fg_init_hw_registers(struct ab8500_fg *di) AB8500_SYS_CTRL2_BLOCK, AB8500_LOW_BAT_REG, ab8500_volt_to_regval( - di->bm->fg_params->lowbat_threshold) << 1 | + di->bm->fg_params->lowbat_threshold_uv) << 1 | LOW_BAT_ENABLE); if (ret) { dev_err(di->dev, "%s write failed\n", __func__);