]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
power: supply: axp288_fuel_gauge: Read 12 bit values 2 registers at a time
authorHans de Goede <hdegoede@redhat.com>
Wed, 14 Dec 2016 16:38:52 +0000 (17:38 +0100)
committerSebastian Reichel <sre@kernel.org>
Wed, 4 Jan 2017 20:59:17 +0000 (21:59 +0100)
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 <hdegoede@redhat.com>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
drivers/power/supply/axp288_fuel_gauge.c

index efb2da253029b5f7e6d2ebb680edde7a9f587a6d..b0325a108431af581633bb0107b64bf335e2dc1e 100644 (file)
@@ -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;
 }