[PATCH 4/4] power: supply: sc27xx: Fix capacity saving function

From: Baolin Wang
Date: Tue Jan 15 2019 - 05:33:36 EST


From: Yuanjiang Yu <yuanjiang.yu@xxxxxxxxxx>

We found sometimes we can not get the saving capacity to initialize the
battery capacity, the reason is the user area registers are put on power
always-on region, so we need delay some time to wait until values are
updated successfully.

Moreover we also should clear the USER_AREA_CLEAR register after setting
the USER_AREA_SET register, otherwise we can not save the values in the
USER_AREA_SET register.

Signed-off-by: Yuanjiang Yu <yuanjiang.yu@xxxxxxxxxx>
Signed-off-by: Baolin Wang <baolin.wang@xxxxxxxxxx>
---
drivers/power/supply/sc27xx_fuel_gauge.c | 64 +++++++++++++++++++++++++++---
1 file changed, 59 insertions(+), 5 deletions(-)

diff --git a/drivers/power/supply/sc27xx_fuel_gauge.c b/drivers/power/supply/sc27xx_fuel_gauge.c
index ea1349f..24895cc 100644
--- a/drivers/power/supply/sc27xx_fuel_gauge.c
+++ b/drivers/power/supply/sc27xx_fuel_gauge.c
@@ -171,10 +171,37 @@ static int sc27xx_fgu_save_boot_mode(struct sc27xx_fgu_data *data,
if (ret)
return ret;

+ /*
+ * Since the user area registers are put on power always-on region,
+ * then these registers changing time will be a little long. Thus
+ * here we should delay 200us to wait until values are updated
+ * successfully according to the datasheet.
+ */
+ udelay(200);
+
+ ret = regmap_update_bits(data->regmap,
+ data->base + SC27XX_FGU_USER_AREA_SET,
+ SC27XX_FGU_MODE_AREA_MASK,
+ boot_mode << SC27XX_FGU_MODE_AREA_SHIFT);
+ if (ret)
+ return ret;
+
+ /*
+ * Since the user area registers are put on power always-on region,
+ * then these registers changing time will be a little long. Thus
+ * here we should delay 200us to wait until values are updated
+ * successfully according to the datasheet.
+ */
+ udelay(200);
+
+ /*
+ * According to the datasheet, we should set the USER_AREA_CLEAR to 0 to
+ * make the user area data available, otherwise we can not save the user
+ * area data.
+ */
return regmap_update_bits(data->regmap,
- data->base + SC27XX_FGU_USER_AREA_SET,
- SC27XX_FGU_MODE_AREA_MASK,
- boot_mode << SC27XX_FGU_MODE_AREA_SHIFT);
+ data->base + SC27XX_FGU_USER_AREA_CLEAR,
+ SC27XX_FGU_MODE_AREA_MASK, 0);
}

static int sc27xx_fgu_save_last_cap(struct sc27xx_fgu_data *data, int cap)
@@ -188,9 +215,36 @@ static int sc27xx_fgu_save_last_cap(struct sc27xx_fgu_data *data, int cap)
if (ret)
return ret;

+ /*
+ * Since the user area registers are put on power always-on region,
+ * then these registers changing time will be a little long. Thus
+ * here we should delay 200us to wait until values are updated
+ * successfully according to the datasheet.
+ */
+ udelay(200);
+
+ ret = regmap_update_bits(data->regmap,
+ data->base + SC27XX_FGU_USER_AREA_SET,
+ SC27XX_FGU_CAP_AREA_MASK, cap);
+ if (ret)
+ return ret;
+
+ /*
+ * Since the user area registers are put on power always-on region,
+ * then these registers changing time will be a little long. Thus
+ * here we should delay 200us to wait until values are updated
+ * successfully according to the datasheet.
+ */
+ udelay(200);
+
+ /*
+ * According to the datasheet, we should set the USER_AREA_CLEAR to 0 to
+ * make the user area data available, otherwise we can not save the user
+ * area data.
+ */
return regmap_update_bits(data->regmap,
- data->base + SC27XX_FGU_USER_AREA_SET,
- SC27XX_FGU_CAP_AREA_MASK, cap);
+ data->base + SC27XX_FGU_USER_AREA_CLEAR,
+ SC27XX_FGU_CAP_AREA_MASK, 0);
}

static int sc27xx_fgu_read_last_cap(struct sc27xx_fgu_data *data, int *cap)
--
1.7.9.5