From patchwork Thu May 11 13:42:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 99653 Delivered-To: patch@linaro.org Received: by 10.140.96.100 with SMTP id j91csp738950qge; Thu, 11 May 2017 06:43:54 -0700 (PDT) X-Received: by 10.99.95.88 with SMTP id t85mr449965pgb.50.1494510234586; Thu, 11 May 2017 06:43:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1494510234; cv=none; d=google.com; s=arc-20160816; b=WfTL0wmeo21M6o7N1evXqCljvTebRveZMedk+qa/8U6KWE6o4norShPu7O+aNgrV4T tRE4A6GKn6ca87GVjYBg/XmYnczO9e5pgzgrHMR3vk78oMRJvpNprBJ5778ClpOaLWlg uvDikAiJ3x/H5sqZYWUPmZQ8mpapBvH39fk9e0a34nTnjFuc//BdDqewvnmHeMr5ACrF Wut7IYgjWdRDJLzVpI6oZ0nPAOKTIw75iattHCUNfYP1cJD8tE2T2nhjiEeOdF2Dn9x/ ADvnNSmIfa4SV/Wo1zmAO86Jj8UHfXTdQwgZQAPLEZny/B1kkunRoEe0O0Xt66uJDpCP G1qQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=PqQ4n0vgqkq4GsQI6Ri89/v8NYeGObdSO5NV1GghTak=; b=0bwokT8gkb3EeXCvIg8lM7DHSlYQ+9zSNl1PFTDgWshOyiCDUhclPvw5/EFDL1Ddd1 99VDVoLt3+A58bFphUgb/WtPiQi0UXNxva0o4r5nYRSR4VNxgH9CQ4ul1O+QwbW3GOBM TjZ3WT3/msf6Q7Y7RkH6cvDz5dFsKgIQaW8emrEkwV0K957zaSPj++jAiqcPCJqQ0O9V Qmpj0+ABSf34/K7qUi2+DJ+NV/bSdsEZc5LXoLWqQA4kB3GWmXSaTg4ROzJ/XknMUKc3 VsXE0KuzcgwkGnpgr0xq/YCglbh/x2tCVg66HXhWUgKo/bjVccqD7C1YC9stcnkKXzGa sNKA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r63si177968plb.129.2017.05.11.06.43.54; Thu, 11 May 2017 06:43:54 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932805AbdEKNnt (ORCPT + 7 others); Thu, 11 May 2017 09:43:49 -0400 Received: from mail.free-electrons.com ([62.4.15.54]:34130 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755908AbdEKNmm (ORCPT ); Thu, 11 May 2017 09:42:42 -0400 Received: by mail.free-electrons.com (Postfix, from userid 110) id 339D3212E7; Thu, 11 May 2017 15:42:41 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id E4CBC20E09; Thu, 11 May 2017 15:42:40 +0200 (CEST) From: Quentin Schulz To: sre@kernel.org, robh+dt@kernel.org, mark.rutland@arm.com, wens@csie.org Cc: Quentin Schulz , linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, liam@networkimprov.net, thomas.petazzoni@free-electrons.com, linux-sunxi@googlegroups.com Subject: [PATCH 4/4] power: supply: axp20x_battery: add DT support for battery max constant charge current Date: Thu, 11 May 2017 15:42:20 +0200 Message-Id: <20170511134221.5569-5-quentin.schulz@free-electrons.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170511134221.5569-1-quentin.schulz@free-electrons.com> References: <20170511134221.5569-1-quentin.schulz@free-electrons.com> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This adds the ability to set the maximum constant charge current, supported by the battery, delivered by this battery power supply to the battery. The maximum constant charge current set in DT will also set the default constant charge current supplied by this supply. The actual user can modify the constant charge current within the range of 0 to maximum constant charge current via sysfs. The user can also modify the maximum constant charge current to widen the range of possible constant charge current. While this seems quite risky, a message is printed on the console to warn the user this might damage the battery. The reason for letting the user change the maximum constant charge current is for letting users change the battery and thus, let them adjust the maximum constant charge current according to what the battery can support. Signed-off-by: Quentin Schulz --- drivers/power/supply/axp20x_battery.c | 78 +++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 8 deletions(-) -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c index 66f530541735..7494f0f0eadb 100644 --- a/drivers/power/supply/axp20x_battery.c +++ b/drivers/power/supply/axp20x_battery.c @@ -60,6 +60,8 @@ struct axp20x_batt_ps { struct iio_channel *batt_chrg_i; struct iio_channel *batt_dischrg_i; struct iio_channel *batt_v; + /* Maximum constant charge current */ + unsigned int max_ccc; u8 axp_id; }; @@ -129,6 +131,14 @@ static void raw_to_constant_charge_current(struct axp20x_batt_ps *axp, int *val) *val = *val * 150000 + 300000; } +static void constant_charge_current_to_raw(struct axp20x_batt_ps *axp, int *val) +{ + if (axp->axp_id == AXP209_ID) + *val = (*val - 300000) / 100000; + else + *val = (*val - 300000) / 150000; +} + static int axp20x_get_constant_charge_current(struct axp20x_batt_ps *axp, int *val) { @@ -221,9 +231,7 @@ static int axp20x_battery_get_prop(struct power_supply *psy, break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: - val->intval = AXP20X_CHRG_CTRL1_TGT_CURR; - raw_to_constant_charge_current(axp20x_batt, &val->intval); - + val->intval = axp20x_batt->max_ccc; break; case POWER_SUPPLY_PROP_CURRENT_NOW: @@ -340,10 +348,10 @@ static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt, static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt, int charge_current) { - if (axp_batt->axp_id == AXP209_ID) - charge_current = (charge_current - 300000) / 100000; - else - charge_current = (charge_current - 300000) / 150000; + if (charge_current > axp_batt->max_ccc) + return -EINVAL; + + constant_charge_current_to_raw(axp_batt, &charge_current); if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0) return -EINVAL; @@ -352,6 +360,36 @@ static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt, AXP20X_CHRG_CTRL1_TGT_CURR, charge_current); } +static int axp20x_set_max_constant_charge_current(struct axp20x_batt_ps *axp, + int charge_current) +{ + bool lower_max = false; + + constant_charge_current_to_raw(axp, &charge_current); + + if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0) + return -EINVAL; + + raw_to_constant_charge_current(axp, &charge_current); + + if (charge_current > axp->max_ccc) + dev_warn(axp->dev, + "Setting max constant charge current higher than previously defined. Note that increasing the constant charge current may damage your battery.\n"); + else + lower_max = true; + + axp->max_ccc = charge_current; + + if (lower_max) { + int current_cc; + + axp20x_get_constant_charge_current(axp, ¤t_cc); + if (current_cc > charge_current) + axp20x_set_constant_charge_current(axp, charge_current); + } + + return 0; +} static int axp20x_set_voltage_min_design(struct axp20x_batt_ps *axp_batt, int min_voltage) { @@ -380,6 +418,9 @@ static int axp20x_battery_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: return axp20x_set_constant_charge_current(axp20x_batt, val->intval); + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: + return axp20x_set_max_constant_charge_current(axp20x_batt, + val->intval); default: return -EINVAL; @@ -405,7 +446,8 @@ static int axp20x_battery_prop_writeable(struct power_supply *psy, { return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN || psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN || - psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT; + psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT || + psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX; } static const struct power_supply_desc axp20x_batt_ps_desc = { @@ -487,13 +529,33 @@ static int axp20x_power_probe(struct platform_device *pdev) if (!power_supply_get_battery_info(axp20x_batt->batt, &info)) { int vmin = info.voltage_min_design_uv; + int ccc = info.constant_charge_current_max_ua; if (vmin > 0 && axp20x_set_voltage_min_design(axp20x_batt, vmin)) dev_err(&pdev->dev, "couldn't set voltage_min_design\n"); + + /* Set max to unverified value to be able to set CCC */ + axp20x_batt->max_ccc = ccc; + + if (ccc <= 0 || axp20x_set_constant_charge_current(axp20x_batt, + ccc)) { + dev_err(&pdev->dev, + "couldn't set constant charge current from DT: fallback to minimum value\n"); + ccc = 300000; + axp20x_batt->max_ccc = ccc; + axp20x_set_constant_charge_current(axp20x_batt, ccc); + } } + /* + * Update max CCC to a valid value if battery info is present or set it + * to current register value by default. + */ + axp20x_get_constant_charge_current(axp20x_batt, + &axp20x_batt->max_ccc); + return 0; }