From 1ff9fbe4866dca901c018f789fda0cd5efae7d64 Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Fri, 10 Nov 2017 15:37:29 -0800 Subject: [PATCH] power: qpnp-fg-gen3: update battery profile based on Rconn configuration Currently, Rconn is configured once in fg_hw_init() if it is not configured already. However, if the driver loads the profile later, it will overwrite the Rconn value configured during fg_hw_init. To fix this problem, configure Rconn after handling battery profile loading. Usually the Rconn configuration is setup differently from what the profile has for it. We check if the profile in SRAM is bit to bit matching with the profile in device tree. We may come across a mismatch for Rconn configuration and conclude that the profile isn't matching. Fix this by initializing the Rconn configuration in the profile read from device tree to the value read from SRAM. CRs-Fixed: 2142441 Change-Id: I2b7ac8cd6efe811527c29bc5cd0fa43b77da7b15 Signed-off-by: Subbaraman Narayanamurthy --- drivers/power/supply/qcom/qpnp-fg-gen3.c | 55 +++++++++++++++++++++--- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c index 491dda6ff7e8..b1a57d8853e8 100644 --- a/drivers/power/supply/qcom/qpnp-fg-gen3.c +++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c @@ -2733,6 +2733,49 @@ static bool is_profile_load_required(struct fg_chip *chip) return true; } +static void fg_update_batt_profile(struct fg_chip *chip) +{ + int rc, offset; + u8 val; + + rc = fg_sram_read(chip, PROFILE_INTEGRITY_WORD, + SW_CONFIG_OFFSET, &val, 1, FG_IMA_DEFAULT); + if (rc < 0) { + pr_err("Error in reading SW_CONFIG_OFFSET, rc=%d\n", rc); + return; + } + + /* + * If the RCONN had not been updated, no need to update battery + * profile. Else, update the battery profile so that the profile + * modified by bootloader or HLOS matches with the profile read + * from device tree. + */ + + if (!(val & RCONN_CONFIG_BIT)) + return; + + rc = fg_sram_read(chip, ESR_RSLOW_CHG_WORD, + ESR_RSLOW_CHG_OFFSET, &val, 1, FG_IMA_DEFAULT); + if (rc < 0) { + pr_err("Error in reading ESR_RSLOW_CHG_OFFSET, rc=%d\n", rc); + return; + } + offset = (ESR_RSLOW_CHG_WORD - PROFILE_LOAD_WORD) * 4 + + ESR_RSLOW_CHG_OFFSET; + chip->batt_profile[offset] = val; + + rc = fg_sram_read(chip, ESR_RSLOW_DISCHG_WORD, + ESR_RSLOW_DISCHG_OFFSET, &val, 1, FG_IMA_DEFAULT); + if (rc < 0) { + pr_err("Error in reading ESR_RSLOW_DISCHG_OFFSET, rc=%d\n", rc); + return; + } + offset = (ESR_RSLOW_DISCHG_WORD - PROFILE_LOAD_WORD) * 4 + + ESR_RSLOW_DISCHG_OFFSET; + chip->batt_profile[offset] = val; +} + static void clear_battery_profile(struct fg_chip *chip) { u8 val = 0; @@ -2816,6 +2859,8 @@ static void profile_load_work(struct work_struct *work) if (!chip->profile_available) goto out; + fg_update_batt_profile(chip); + if (!is_profile_load_required(chip)) goto done; @@ -2877,6 +2922,10 @@ done: rc); } + rc = fg_rconn_config(chip); + if (rc < 0) + pr_err("Error in configuring Rconn, rc=%d\n", rc); + batt_psy_initialized(chip); fg_notify_charger(chip); chip->profile_loaded = true; @@ -4076,12 +4125,6 @@ static int fg_hw_init(struct fg_chip *chip) return rc; } - rc = fg_rconn_config(chip); - if (rc < 0) { - pr_err("Error in configuring Rconn, rc=%d\n", rc); - return rc; - } - fg_encode(chip->sp, FG_SRAM_ESR_TIGHT_FILTER, chip->dt.esr_tight_flt_upct, buf); rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR_TIGHT_FILTER].addr_word,