From patchwork Wed Sep 20 15:18:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Icenowy Zheng X-Patchwork-Id: 9961643 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 59A7860208 for ; Wed, 20 Sep 2017 15:19:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4B799287E0 for ; Wed, 20 Sep 2017 15:19:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 400AF2880F; Wed, 20 Sep 2017 15:19:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D566A287E0 for ; Wed, 20 Sep 2017 15:19:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751925AbdITPTK (ORCPT ); Wed, 20 Sep 2017 11:19:10 -0400 Received: from hermes.aosc.io ([199.195.250.187]:41696 "EHLO hermes.aosc.io" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751921AbdITPTI (ORCPT ); Wed, 20 Sep 2017 11:19:08 -0400 Received: from localhost (localhost [127.0.0.1]) (Authenticated sender: icenowy@aosc.io) by hermes.aosc.io (Postfix) with ESMTPSA id DF76247941; Wed, 20 Sep 2017 15:19:03 +0000 (UTC) From: Icenowy Zheng To: Chen-Yu Tsai , Maxime Ripard , Jonathan Cameron , Lee Jones , Quentin Schulz Cc: linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-iio@vger.kernel.org, linux-sunxi@googlegroups.com, Icenowy Zheng Subject: [RFC PATCH 4/7] power: supply: axp20x-battery: support AXP803 Date: Wed, 20 Sep 2017 23:18:11 +0800 Message-Id: <20170920151814.22461-5-icenowy@aosc.io> In-Reply-To: <20170920151814.22461-1-icenowy@aosc.io> References: <20170920151814.22461-1-icenowy@aosc.io> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The AXP803 PMIC has battery support like other AXP PMICs, but with different definition of max target charging voltage and constant charging current. Add support for AXP803 battery in axp20x-battery driver. Signed-off-by: Icenowy Zheng --- drivers/power/supply/axp20x_battery.c | 88 +++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 10 deletions(-) diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c index 7494f0f0eadb..c9a9fb320c92 100644 --- a/drivers/power/supply/axp20x_battery.c +++ b/drivers/power/supply/axp20x_battery.c @@ -49,6 +49,8 @@ #define AXP22X_CHRG_CTRL1_TGT_4_22V (1 << 5) #define AXP22X_CHRG_CTRL1_TGT_4_24V (3 << 5) +#define AXP803_CHRG_CTRL1_TGT_4_35V (3 << 5) + #define AXP20X_CHRG_CTRL1_TGT_CURR GENMASK(3, 0) #define AXP20X_V_OFF_MASK GENMASK(2, 0) @@ -123,20 +125,71 @@ static int axp22x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt, return 0; } +static int axp803_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt, + int *val) +{ + int ret, reg; + + ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, ®); + if (ret) + return ret; + + switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) { + case AXP20X_CHRG_CTRL1_TGT_4_1V: + *val = 4100000; + break; + case AXP20X_CHRG_CTRL1_TGT_4_15V: + *val = 4150000; + break; + case AXP20X_CHRG_CTRL1_TGT_4_2V: + *val = 4200000; + break; + case AXP803_CHRG_CTRL1_TGT_4_35V: + *val = 4350000; + break; + default: + return -EINVAL; + } + + return 0; +} + static void raw_to_constant_charge_current(struct axp20x_batt_ps *axp, int *val) { - if (axp->axp_id == AXP209_ID) + switch (axp->axp_id) { + case AXP209_ID: *val = *val * 100000 + 300000; - else + break; + case AXP221_ID: *val = *val * 150000 + 300000; + break; + case AXP803_ID: + *val = *val * 200000 + 200000; + break; + } } static void constant_charge_current_to_raw(struct axp20x_batt_ps *axp, int *val) { - if (axp->axp_id == AXP209_ID) + switch (axp->axp_id) { + case AXP209_ID: *val = (*val - 300000) / 100000; - else + break; + case AXP221_ID: *val = (*val - 300000) / 150000; + break; + case AXP803_ID: + *val = (*val - 200000) / 200000; + /* + * The maximum charge current on AXP803 is 2.8A, and the + * datasheet says "1110-1111 reserved" in this part. + * So we return an invalid value -1 in this situation, + * which will be dealed by the caller of this function, + */ + if (*val > 13) + *val = -1; + break; + } } static int axp20x_get_constant_charge_current(struct axp20x_batt_ps *axp, @@ -269,9 +322,13 @@ static int axp20x_battery_get_prop(struct power_supply *psy, if (ret) return ret; - if (axp20x_batt->axp_id == AXP221_ID && - !(reg & AXP22X_FG_VALID)) - return -EINVAL; + switch (axp20x_batt->axp_id) { + case AXP221_ID: + case AXP803_ID: + if (!(reg & AXP22X_FG_VALID)) + return -EINVAL; + break; + }; /* * Fuel Gauge data takes 7 bits but the stored value seems to be @@ -281,11 +338,19 @@ static int axp20x_battery_get_prop(struct power_supply *psy, break; case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: - if (axp20x_batt->axp_id == AXP209_ID) + switch (axp20x_batt->axp_id) { + case AXP209_ID: return axp20x_battery_get_max_voltage(axp20x_batt, &val->intval); - return axp22x_battery_get_max_voltage(axp20x_batt, - &val->intval); + case AXP221_ID: + return axp22x_battery_get_max_voltage(axp20x_batt, + &val->intval); + case AXP803_ID: + return axp803_battery_get_max_voltage(axp20x_batt, + &val->intval); + default: + return -EINVAL; + } case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, ®); @@ -467,6 +532,9 @@ static const struct of_device_id axp20x_battery_ps_id[] = { }, { .compatible = "x-powers,axp221-battery-power-supply", .data = (void *)AXP221_ID, + }, { + .compatible = "x-powers,axp803-battery-power-supply", + .data = (void *)AXP803_ID, }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, axp20x_battery_ps_id);