Patch "power: supply: axp288_fuel_gauge: Read 15 bit values 2 registers at a time" has been added to the 4.9-stable tree
Subsystems (4)
This is a note to let you know that I've just added the patch titled
power: supply: axp288_fuel_gauge: Read 15 bit values 2 registers at a time
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
power-supply-axp288_fuel_gauge-read-15-bit-values-2-registers-at-a-time.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Sun Nov 19 11:32:28 CET 2017
From: Hans de Goede <[email protected]>
Date: Wed, 14 Dec 2016 17:38:51 +0100
Subject: power: supply: axp288_fuel_gauge: Read 15 bit values 2 registers at a time
From: Hans de Goede <[email protected]>
[ Upstream commit 4949fc5e071f8e8d8122e0b16cf6a2ec1ca36258 ]
In order for the MSB -> LSB latching to work correctly we must read the 2 8 bit registers of a 15 bit value in one consecutive read.
This fixes charge_full reporting 3498768 on some reads and 3354624 one other reads on my tablet (for the 3354624 value the raw LSB is 0x00).
--- drivers/power/supply/axp288_fuel_gauge.c | 63 ++++++++++++++++--------------- 1 file changed, 34 insertions(+), 29 deletions(-)
drivers/power/supply/axp288_fuel_gauge.c +34 -29
@@ -29,6 +29,7 @@#include <linux/iio/consumer.h> #include <linux/debugfs.h> #include <linux/seq_file.h> +#include <asm/unaligned.h> #define CHRG_STAT_BAT_SAFE_MODE (1 << 3)#define CHRG_STAT_BAT_VALID (1 << 4)
@@ -73,17 +74,15 @@#define FG_CNTL_CC_EN (1 << 6)#define FG_CNTL_GAUGE_EN (1 << 7) +#define FG_15BIT_WORD_VALID (1 << 15) +#define FG_15BIT_VAL_MASK 0x7fff +#define FG_REP_CAP_VALID (1 << 7)#define FG_REP_CAP_VAL_MASK 0x7F#define FG_DES_CAP1_VALID (1 << 7) -#define FG_DES_CAP1_VAL_MASK 0x7F -#define FG_DES_CAP0_VAL_MASK 0xFF#define FG_DES_CAP_RES_LSB 1456/* 1.456mAhr */ -#define FG_CC_MTR1_VALID (1 << 7) -#define FG_CC_MTR1_VAL_MASK 0x7F -#define FG_CC_MTR0_VAL_MASK 0xFF#define FG_DES_CC_RES_LSB 1456/* 1.456mAhr */ #define FG_OCV_CAP_VALID (1 << 7)
@@ -189,6 +188,28 @@ static int fuel_gauge_reg_writeb(structreturn ret; } +static int fuel_gauge_read_15bit_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; + } + + ret =get_unaligned_be16 (buf); +if (!(ret &FG_15BIT_WORD_VALID )) { +dev_err (&info->pdev->dev,"Error reg 0x%02x contents not valid\n" , + reg); +return -ENXIO ; + } + +return ret &FG_15BIT_VAL_MASK ; +} +static int pmic_read_adc_val (const char *name,int *raw_val,struct axp288_fg_info *info) {
@@ -255,18 +276,12 @@ static int fuel_gauge_debug_show(structseq_printf (s," FG_OCVL[%02x] : %02x\n" ,AXP288_FG_OCVL_REG ,fuel_gauge_reg_readb (info,AXP288_FG_OCVL_REG )); -seq_printf (s,"FG_DES_CAP1[%02x] : %02x\n" , +seq_printf (s," FG_DES_CAP[%02x] : %04x\n" ,AXP288_FG_DES_CAP1_REG , -fuel_gauge_reg_readb (info,AXP288_FG_DES_CAP1_REG )); -seq_printf (s,"FG_DES_CAP0[%02x] : %02x\n" , -AXP288_FG_DES_CAP0_REG , -fuel_gauge_reg_readb (info,AXP288_FG_DES_CAP0_REG )); -seq_printf (s," FG_CC_MTR1[%02x] : %02x\n" , +fuel_gauge_read_15bit_word (info,AXP288_FG_DES_CAP1_REG )); +seq_printf (s," FG_CC_MTR[%02x] : %04x\n" ,AXP288_FG_CC_MTR1_REG , -fuel_gauge_reg_readb (info,AXP288_FG_CC_MTR1_REG )); -seq_printf (s," FG_CC_MTR0[%02x] : %02x\n" , -AXP288_FG_CC_MTR0_REG , -fuel_gauge_reg_readb (info,AXP288_FG_CC_MTR0_REG )); +fuel_gauge_read_15bit_word (info,AXP288_FG_CC_MTR1_REG ));seq_printf (s," FG_OCV_CAP[%02x] : %02x\n" ,AXP288_FG_OCV_CAP_REG ,fuel_gauge_reg_readb (info,AXP288_FG_OCV_CAP_REG ));
@@ -663,28 +678,18 @@ static int fuel_gauge_get_property(struc val->intval =POWER_SUPPLY_TECHNOLOGY_LION ;break ;case POWER_SUPPLY_PROP_CHARGE_NOW : - ret =fuel_gauge_reg_readb (info,AXP288_FG_CC_MTR1_REG ); + ret =fuel_gauge_read_15bit_word (info,AXP288_FG_CC_MTR1_REG );if (ret <0 ) goto fuel_gauge_read_err; - value = (ret &FG_CC_MTR1_VAL_MASK ) <<8 ; - ret =fuel_gauge_reg_readb (info,AXP288_FG_CC_MTR0_REG ); -if (ret <0 ) - goto fuel_gauge_read_err; - value |= (ret &FG_CC_MTR0_VAL_MASK ); - val->intval = value *FG_DES_CAP_RES_LSB ; + val->intval = ret *FG_DES_CAP_RES_LSB ;break ;case POWER_SUPPLY_PROP_CHARGE_FULL : - ret =fuel_gauge_reg_readb (info,AXP288_FG_DES_CAP1_REG ); + ret =fuel_gauge_read_15bit_word (info,AXP288_FG_DES_CAP1_REG );if (ret <0 ) goto fuel_gauge_read_err; - value = (ret &FG_DES_CAP1_VAL_MASK ) <<8 ; - ret =fuel_gauge_reg_readb (info,AXP288_FG_DES_CAP0_REG ); -if (ret <0 ) - goto fuel_gauge_read_err; - value |= (ret &FG_DES_CAP0_VAL_MASK ); - val->intval = value *FG_DES_CAP_RES_LSB ; + val->intval = ret *FG_DES_CAP_RES_LSB ;break ;case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN : val->intval =PROP_CURR (info->pdata->design_cap);
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/power-supply-axp288_fuel_gauge-read-15-bit-values-2-registers-at-a-time.patch queue-4.9/power-supply-axp288_fuel_gauge-read-12-bit-values-2-registers-at-a-time.patch