From 0ba4dcb7dd492e319b22f8f82c94adbf4796010a Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Mon, 17 Oct 2016 14:01:34 -0700 Subject: [PATCH] qpnp-fg-gen3: Backup the learned capacity during capacity learning When the capacity learning algorithm completes, we store the learned capacity to BattCapActual word in FG SRAM. Though this is correct and needed for coulomb counter to operate, value is not retained across reboot. Backup the learned capacity to a scratchpad SRAM word (address 74) to overcome this. Change-Id: I39c257876776a9e9c872add1366569394c49ef01 Signed-off-by: Subbaraman Narayanamurthy --- drivers/power/qcom-charger/fg-core.h | 9 +++++- drivers/power/qcom-charger/qpnp-fg-gen3.c | 34 +++++++++++++++-------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/drivers/power/qcom-charger/fg-core.h b/drivers/power/qcom-charger/fg-core.h index adc640c7afe1..a703b208f6e4 100644 --- a/drivers/power/qcom-charger/fg-core.h +++ b/drivers/power/qcom-charger/fg-core.h @@ -118,7 +118,14 @@ enum { DELTA_SOC_IRQ_WA = BIT(0), }; -/* SRAM parameters */ +/* + * List of FG_SRAM parameters. Please add a parameter only if it is an entry + * that will be used either to configure an entity (e.g. termination current) + * which might need some encoding (or) it is an entry that will be read from + * SRAM and decoded (e.g. CC_SOC_SW) for SW to use at various places. For + * generic read/writes to SRAM registers, please use fg_sram_read/write APIs + * directly without adding an entry here. + */ enum fg_sram_param_id { FG_SRAM_BATT_SOC = 0, FG_SRAM_VOLTAGE_PRED, diff --git a/drivers/power/qcom-charger/qpnp-fg-gen3.c b/drivers/power/qcom-charger/qpnp-fg-gen3.c index 30408218b7e7..3429c2a06403 100644 --- a/drivers/power/qcom-charger/qpnp-fg-gen3.c +++ b/drivers/power/qcom-charger/qpnp-fg-gen3.c @@ -64,6 +64,8 @@ #define PROFILE_LOAD_OFFSET 0 #define NOM_CAP_WORD 58 #define NOM_CAP_OFFSET 0 +#define ACT_BATT_CAP_BKUP_WORD 74 +#define ACT_BATT_CAP_BKUP_OFFSET 0 #define CYCLE_COUNT_WORD 75 #define CYCLE_COUNT_OFFSET 0 #define PROFILE_INTEGRITY_WORD 79 @@ -156,8 +158,8 @@ static struct fg_sram_param pmicobalt_v1_sram_params[] = { fg_decode_cc_soc), PARAM(CC_SOC_SW, CC_SOC_SW_WORD, CC_SOC_SW_OFFSET, 4, 1, 1, 0, NULL, fg_decode_cc_soc), - PARAM(ACT_BATT_CAP, ACT_BATT_CAP_WORD, ACT_BATT_CAP_OFFSET, 2, 1, 1, 0, - NULL, fg_decode_default), + PARAM(ACT_BATT_CAP, ACT_BATT_CAP_BKUP_WORD, ACT_BATT_CAP_BKUP_OFFSET, 2, + 1, 1, 0, NULL, fg_decode_default), /* Entries below here are configurable during initialization */ PARAM(CUTOFF_VOLT, CUTOFF_VOLT_WORD, CUTOFF_VOLT_OFFSET, 2, 1000000, 244141, 0, fg_encode_voltage, NULL), @@ -208,8 +210,8 @@ static struct fg_sram_param pmicobalt_v2_sram_params[] = { fg_decode_cc_soc), PARAM(CC_SOC_SW, CC_SOC_SW_WORD, CC_SOC_SW_OFFSET, 4, 1, 1, 0, NULL, fg_decode_cc_soc), - PARAM(ACT_BATT_CAP, ACT_BATT_CAP_WORD, ACT_BATT_CAP_OFFSET, 2, 1, 1, 0, - NULL, fg_decode_default), + PARAM(ACT_BATT_CAP, ACT_BATT_CAP_BKUP_WORD, ACT_BATT_CAP_BKUP_OFFSET, 2, + 1, 1, 0, NULL, fg_decode_default), /* Entries below here are configurable during initialization */ PARAM(CUTOFF_VOLT, CUTOFF_VOLT_WORD, CUTOFF_VOLT_OFFSET, 2, 1000000, 244141, 0, fg_encode_voltage, NULL), @@ -887,9 +889,19 @@ static int fg_save_learned_cap_to_sram(struct fg_chip *chip) return -EPERM; cc_mah = div64_s64(chip->cl.learned_cc_uah, 1000); + /* Write to a backup register to use across reboot */ rc = fg_sram_write(chip, chip->sp[FG_SRAM_ACT_BATT_CAP].addr_word, chip->sp[FG_SRAM_ACT_BATT_CAP].addr_byte, (u8 *)&cc_mah, chip->sp[FG_SRAM_ACT_BATT_CAP].len, FG_IMA_DEFAULT); + if (rc < 0) { + pr_err("Error in writing act_batt_cap_bkup, rc=%d\n", rc); + return rc; + } + + /* Write to actual capacity register for coulomb counter operation */ + rc = fg_sram_write(chip, ACT_BATT_CAP_WORD, ACT_BATT_CAP_OFFSET, + (u8 *)&cc_mah, chip->sp[FG_SRAM_ACT_BATT_CAP].len, + FG_IMA_DEFAULT); if (rc < 0) { pr_err("Error in writing act_batt_cap, rc=%d\n", rc); return rc; @@ -927,16 +939,14 @@ static int fg_load_learned_cap_from_sram(struct fg_chip *chip) * the nominal capacity. */ if (chip->cl.nom_cap_uah && delta_cc_uah > pct_nom_cap_uah) { - fg_dbg(chip, FG_CAP_LEARN, "learned_cc_uah: %lld is higher than expected\n", - chip->cl.learned_cc_uah); - fg_dbg(chip, FG_CAP_LEARN, "Capping it to nominal:%lld\n", - chip->cl.nom_cap_uah); + fg_dbg(chip, FG_CAP_LEARN, "learned_cc_uah: %lld is higher than expected, capping it to nominal: %lld\n", + chip->cl.learned_cc_uah, chip->cl.nom_cap_uah); chip->cl.learned_cc_uah = chip->cl.nom_cap_uah; - rc = fg_save_learned_cap_to_sram(chip); - if (rc < 0) - pr_err("Error in saving learned_cc_uah, rc=%d\n", - rc); } + + rc = fg_save_learned_cap_to_sram(chip); + if (rc < 0) + pr_err("Error in saving learned_cc_uah, rc=%d\n", rc); } fg_dbg(chip, FG_CAP_LEARN, "learned_cc_uah:%lld nom_cap_uah: %lld\n",