Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1bf973e5 authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy
Browse files

power: qpnp-fg-gen3: Adjust ki_coeff_full_soc dynamically



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: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent e4e90297
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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;
+49 −0
Original line number Diff line number Diff line
@@ -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;
@@ -4147,6 +4195,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");