From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753511AbdKHVBG (ORCPT ); Wed, 8 Nov 2017 16:01:06 -0500 Received: from omzsmtpe03.verizonbusiness.com ([199.249.25.208]:60249 "EHLO omzsmtpe03.verizonbusiness.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752742AbdKHVBD (ORCPT ); Wed, 8 Nov 2017 16:01:03 -0500 X-Host: mariner.tdc.vzwcorp.com From: "Levin, Alexander (Sasha Levin)" To: "linux-kernel@vger.kernel.org" , "stable@vger.kernel.org" CC: Hans de Goede , Sebastian Reichel , "Levin, Alexander (Sasha Levin)" Subject: [PATCH AUTOSEL for-4.9 29/53] power: supply: axp288_fuel_gauge: Read 12 bit values 2 registers at a time Thread-Topic: [PATCH AUTOSEL for-4.9 29/53] power: supply: axp288_fuel_gauge: Read 12 bit values 2 registers at a time Thread-Index: AQHTWNMlWAckiZcqIEmLW9AmxAWrdA== Date: Wed, 8 Nov 2017 20:50:02 +0000 Message-ID: <20171108204940.27321-29-alexander.levin@verizon.com> References: <20171108204940.27321-1-alexander.levin@verizon.com> In-Reply-To: <20171108204940.27321-1-alexander.levin@verizon.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.144.60.250] Content-Type: text/plain; charset="iso-8859-1" MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by nfs id vA8L1BAx003754 From: Hans de Goede [ Upstream commit 248efcf00602f0282587999bcc221a872bd72530 ] In order for the MSB -> LSB latching to work correctly we must read the 2 8 bit registers of a 12 bit value in one consecutive read. This fixes voltage_ocv reporting inconsistent values on my tablet. Signed-off-by: Hans de Goede Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/power/supply/axp288_fuel_gauge.c | 40 ++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/power/supply/axp288_fuel_gauge.c b/drivers/power/supply/axp288_fuel_gauge.c index 99d6d3030731..089056cb8e73 100644 --- a/drivers/power/supply/axp288_fuel_gauge.c +++ b/drivers/power/supply/axp288_fuel_gauge.c @@ -210,6 +210,22 @@ static int fuel_gauge_read_15bit_word(struct axp288_fg_info *info, int reg) return ret & FG_15BIT_VAL_MASK; } +static int fuel_gauge_read_12bit_word(struct axp288_fg_info *info, int reg) +{ + unsigned char buf[2]; + int ret; + + ret = regmap_bulk_read(info->regmap, reg, buf, 2); + if (ret < 0) { + dev_err(&info->pdev->dev, "Error reading reg 0x%02x err: %d\n", + reg, ret); + return ret; + } + + /* 12-bit data values have upper 8 bits in buf[0], lower 4 in buf[1] */ + return (buf[0] << 4) | ((buf[1] >> 4) & 0x0f); +} + static int pmic_read_adc_val(const char *name, int *raw_val, struct axp288_fg_info *info) { @@ -270,12 +286,9 @@ static int fuel_gauge_debug_show(struct seq_file *s, void *data) seq_printf(s, " FG_RDC0[%02x] : %02x\n", AXP288_FG_RDC0_REG, fuel_gauge_reg_readb(info, AXP288_FG_RDC0_REG)); - seq_printf(s, " FG_OCVH[%02x] : %02x\n", + seq_printf(s, " FG_OCV[%02x] : %04x\n", AXP288_FG_OCVH_REG, - fuel_gauge_reg_readb(info, AXP288_FG_OCVH_REG)); - seq_printf(s, " FG_OCVL[%02x] : %02x\n", - AXP288_FG_OCVL_REG, - fuel_gauge_reg_readb(info, AXP288_FG_OCVL_REG)); + fuel_gauge_read_12bit_word(info, AXP288_FG_OCVH_REG)); seq_printf(s, " FG_DES_CAP[%02x] : %04x\n", AXP288_FG_DES_CAP1_REG, fuel_gauge_read_15bit_word(info, AXP288_FG_DES_CAP1_REG)); @@ -532,21 +545,12 @@ temp_read_fail: static int fuel_gauge_get_vocv(struct axp288_fg_info *info, int *vocv) { - int ret, value; - - /* 12-bit data value, upper 8 in OCVH, lower 4 in OCVL */ - ret = fuel_gauge_reg_readb(info, AXP288_FG_OCVH_REG); - if (ret < 0) - goto vocv_read_fail; - value = ret << 4; + int ret; - ret = fuel_gauge_reg_readb(info, AXP288_FG_OCVL_REG); - if (ret < 0) - goto vocv_read_fail; - value |= (ret & 0xf); + ret = fuel_gauge_read_12bit_word(info, AXP288_FG_OCVH_REG); + if (ret >= 0) + *vocv = VOLTAGE_FROM_ADC(ret); - *vocv = VOLTAGE_FROM_ADC(value); -vocv_read_fail: return ret; } -- 2.11.0