OSDN Git Service

power: qpnp-fg-gen3: Adjust ki_coeff_full_soc dynamically
authorSubbaraman Narayanamurthy <subbaram@codeaurora.org>
Wed, 5 Apr 2017 02:24:20 +0000 (19:24 -0700)
committerSubbaraman Narayanamurthy <subbaram@codeaurora.org>
Wed, 5 Apr 2017 21:23:51 +0000 (14:23 -0700)
When the battery temperature goes below -10 C, SOC may get stuck
to 100%. This is due to the SOC full loop adjusting down with
very high battery impedance. To mitigate this, SOC full loop has
to be frozen. Add support for it by adjusting ki_coeff_full_soc
dynamically based on battery temperature.

Change-Id: I6218568712b025bc4427770bf86d142d50f40c7b
Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
drivers/power/supply/qcom/fg-core.h
drivers/power/supply/qcom/qpnp-fg-gen3.c

index 9ddbd8c..2741e46 100644 (file)
@@ -171,6 +171,7 @@ enum fg_sram_param_id {
        FG_SRAM_RECHARGE_VBATT_THR,
        FG_SRAM_KI_COEFF_MED_DISCHG,
        FG_SRAM_KI_COEFF_HI_DISCHG,
+       FG_SRAM_KI_COEFF_FULL_SOC,
        FG_SRAM_ESR_TIGHT_FILTER,
        FG_SRAM_ESR_BROAD_FILTER,
        FG_SRAM_SLOPE_LIMIT,
@@ -356,6 +357,7 @@ struct fg_chip {
        u32                     rradc_base;
        u32                     wa_flags;
        int                     batt_id_ohms;
+       int                     ki_coeff_full_soc;
        int                     charge_status;
        int                     prev_charge_status;
        int                     charge_done;
index 4252939..b625eb0 100644 (file)
@@ -52,6 +52,8 @@
 #define KI_COEFF_HI_DISCHG_OFFSET      0
 #define KI_COEFF_LOW_DISCHG_WORD       10
 #define KI_COEFF_LOW_DISCHG_OFFSET     2
+#define KI_COEFF_FULL_SOC_WORD         12
+#define KI_COEFF_FULL_SOC_OFFSET       2
 #define DELTA_MSOC_THR_WORD            12
 #define DELTA_MSOC_THR_OFFSET          3
 #define DELTA_BSOC_THR_WORD            13
@@ -226,6 +228,9 @@ static struct fg_sram_param pmi8998_v1_sram_params[] = {
        PARAM(KI_COEFF_HI_DISCHG, KI_COEFF_HI_DISCHG_WORD,
                KI_COEFF_HI_DISCHG_OFFSET, 1, 1000, 244141, 0,
                fg_encode_default, NULL),
+       PARAM(KI_COEFF_FULL_SOC, KI_COEFF_FULL_SOC_WORD,
+               KI_COEFF_FULL_SOC_OFFSET, 1, 1000, 244141, 0,
+               fg_encode_default, NULL),
        PARAM(ESR_TIGHT_FILTER, ESR_FILTER_WORD, ESR_UPD_TIGHT_OFFSET,
                1, 512, 1000000, 0, fg_encode_default, NULL),
        PARAM(ESR_BROAD_FILTER, ESR_FILTER_WORD, ESR_UPD_BROAD_OFFSET,
@@ -298,6 +303,9 @@ static struct fg_sram_param pmi8998_v2_sram_params[] = {
        PARAM(KI_COEFF_HI_DISCHG, KI_COEFF_HI_DISCHG_v2_WORD,
                KI_COEFF_HI_DISCHG_v2_OFFSET, 1, 1000, 244141, 0,
                fg_encode_default, NULL),
+       PARAM(KI_COEFF_FULL_SOC, KI_COEFF_FULL_SOC_WORD,
+               KI_COEFF_FULL_SOC_OFFSET, 1, 1000, 244141, 0,
+               fg_encode_default, NULL),
        PARAM(ESR_TIGHT_FILTER, ESR_FILTER_WORD, ESR_UPD_TIGHT_OFFSET,
                1, 512, 1000000, 0, fg_encode_default, NULL),
        PARAM(ESR_BROAD_FILTER, ESR_FILTER_WORD, ESR_UPD_BROAD_OFFSET,
@@ -1482,6 +1490,37 @@ static int fg_adjust_ki_coeff_dischg(struct fg_chip *chip)
        return 0;
 }
 
+#define KI_COEFF_FULL_SOC_DEFAULT      733
+static int fg_adjust_ki_coeff_full_soc(struct fg_chip *chip, int batt_temp)
+{
+       int rc, ki_coeff_full_soc;
+       u8 val;
+
+       if (batt_temp < 0)
+               ki_coeff_full_soc = 0;
+       else
+               ki_coeff_full_soc = KI_COEFF_FULL_SOC_DEFAULT;
+
+       if (chip->ki_coeff_full_soc == ki_coeff_full_soc)
+               return 0;
+
+       fg_encode(chip->sp, FG_SRAM_KI_COEFF_FULL_SOC, ki_coeff_full_soc, &val);
+       rc = fg_sram_write(chip,
+                       chip->sp[FG_SRAM_KI_COEFF_FULL_SOC].addr_word,
+                       chip->sp[FG_SRAM_KI_COEFF_FULL_SOC].addr_byte, &val,
+                       chip->sp[FG_SRAM_KI_COEFF_FULL_SOC].len,
+                       FG_IMA_DEFAULT);
+       if (rc < 0) {
+               pr_err("Error in writing ki_coeff_full_soc, rc=%d\n", rc);
+               return rc;
+       }
+
+       chip->ki_coeff_full_soc = ki_coeff_full_soc;
+       fg_dbg(chip, FG_STATUS, "Wrote ki_coeff_full_soc %d\n",
+               ki_coeff_full_soc);
+       return 0;
+}
+
 static int fg_set_recharge_voltage(struct fg_chip *chip, int voltage_mv)
 {
        u8 buf;
@@ -2066,6 +2105,11 @@ static void status_change_work(struct work_struct *work)
                if (rc < 0)
                        pr_err("Error in configuring slope limiter rc:%d\n",
                                rc);
+
+               rc = fg_adjust_ki_coeff_full_soc(chip, batt_temp);
+               if (rc < 0)
+                       pr_err("Error in configuring ki_coeff_full_soc rc:%d\n",
+                               rc);
        }
 
        fg_batt_avg_update(chip);
@@ -3409,6 +3453,10 @@ static irqreturn_t fg_delta_batt_temp_irq_handler(int irq, void *data)
        if (rc < 0)
                pr_err("Error in configuring slope limiter rc:%d\n", rc);
 
+       rc = fg_adjust_ki_coeff_full_soc(chip, batt_temp);
+       if (rc < 0)
+               pr_err("Error in configuring ki_coeff_full_soc rc:%d\n", rc);
+
        if (!batt_psy_initialized(chip)) {
                chip->last_batt_temp = batt_temp;
                return IRQ_HANDLED;
@@ -4146,6 +4194,7 @@ static int fg_gen3_probe(struct platform_device *pdev)
        chip->irqs = fg_irqs;
        chip->charge_status = -EINVAL;
        chip->prev_charge_status = -EINVAL;
+       chip->ki_coeff_full_soc = -EINVAL;
        chip->regmap = dev_get_regmap(chip->dev->parent, NULL);
        if (!chip->regmap) {
                dev_err(chip->dev, "Parent regmap is unavailable\n");