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

Commit d5098d6b authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy
Browse files

power: qpnp-fg: add support to configure Rconn



On some platforms, battery connector resistance (Rconn) needs to
be taken into account when Rslow (capacitive reactance) values
are used from battery profile. Without this, battery resistance
observed by FG algorithm will be wrong ending up in wrong SOC
estimate. When Rconn is specified, Rslow values for charge and
discharge will be updated. Add support to configure Rconn through
a device tree parameter "qcom,fg-rconn-mohms".

While at it, fix a bug in reading rs_to_rslow_chg from a wrong
offset 0 instead of 2.

CRs-Fixed: 980218
Change-Id: Ibd93e5013197a91098e3936b1b13f1193789215c
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent 683a5c23
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -109,6 +109,10 @@ Parent node optional properties:
					this. If this property is not specified,
					low battery voltage threshold will be
					configured to 4200 mV.
- qcom,fg-rconn-mohm:			Battery connector resistance (Rconn) in
					milliohms. If Rconn is specified, then
					Rslow values will be updated to account
					it for an accurate ESR.
- qcom,cycle-counter-en:		Boolean property which enables the cycle
					counter feature. If this property is
					present, then the following properties
+90 −19
Original line number Diff line number Diff line
@@ -504,6 +504,7 @@ struct fg_chip {
	struct fg_cc_soc_data	sw_cc_soc_data;
	/* rslow compensation */
	struct fg_rslow_data	rslow_comp;
	int			rconn_mohm;
	/* cycle counter */
	struct fg_cyc_ctr_data	cyc_ctr;
	/* iadc compensation */
@@ -2568,6 +2569,7 @@ static int lookup_soc_for_ocv(struct fg_chip *chip, int ocv)
#define ESR_ACTUAL_REG		0x554
#define BATTERY_ESR_REG		0x4F4
#define TEMP_RS_TO_RSLOW_REG	0x514
#define ESR_OFFSET		2
static int estimate_battery_age(struct fg_chip *chip, int *actual_capacity)
{
	int64_t ocv_cutoff_new, ocv_cutoff_aged, temp_rs_to_rslow;
@@ -2608,7 +2610,7 @@ static int estimate_battery_age(struct fg_chip *chip, int *actual_capacity)

	rc = fg_mem_read(chip, buffer, ESR_ACTUAL_REG, 2, 2, 0);
	esr_actual = half_float(buffer);
	rc |= fg_mem_read(chip, buffer, BATTERY_ESR_REG, 2, 2, 0);
	rc |= fg_mem_read(chip, buffer, BATTERY_ESR_REG, 2, ESR_OFFSET, 0);
	battery_esr = half_float(buffer);

	if (rc) {
@@ -4268,7 +4270,6 @@ done:
	fg_relax(&chip->resume_soc_wakeup_source);
}


#define OCV_COEFFS_START_REG		0x4C0
#define OCV_JUNCTION_REG		0x4D8
#define NOM_CAP_REG			0x4F4
@@ -4277,7 +4278,8 @@ done:
#define RSLOW_CFG_OFFSET		2
#define RSLOW_THRESH_REG		0x52C
#define RSLOW_THRESH_OFFSET		0
#define TEMP_RS_TO_RSLOW_OFFSET		2
#define RS_TO_RSLOW_CHG_OFFSET		2
#define RS_TO_RSLOW_DISCHG_OFFSET	0
#define RSLOW_COMP_REG			0x528
#define RSLOW_COMP_C1_OFFSET		0
#define RSLOW_COMP_C2_OFFSET		2
@@ -4380,9 +4382,9 @@ static int populate_system_data(struct fg_chip *chip)
	}
	chip->rslow_comp.rslow_thr = buffer[0];
	rc = fg_mem_read(chip, buffer, TEMP_RS_TO_RSLOW_REG, 2,
			RSLOW_THRESH_OFFSET, 0);
			RS_TO_RSLOW_CHG_OFFSET, 0);
	if (rc) {
		pr_err("unable to read rs to rslow: %d\n", rc);
		pr_err("unable to read rs to rslow_chg: %d\n", rc);
		goto done;
	}
	memcpy(chip->rslow_comp.rs_to_rslow, buffer, 2);
@@ -4399,6 +4401,68 @@ done:
	return rc;
}

static int fg_update_batt_rslow_settings(struct fg_chip *chip)
{
	int64_t rs_to_rslow_chg, rs_to_rslow_dischg, batt_esr, rconn_uohm;
	u8 buffer[2];
	int rc;

	rc = fg_mem_read(chip, buffer, BATTERY_ESR_REG, 2, ESR_OFFSET, 0);
	if (rc) {
		pr_err("unable to read battery_esr: %d\n", rc);
		goto done;
	}
	batt_esr = half_float(buffer);

	rc = fg_mem_read(chip, buffer, TEMP_RS_TO_RSLOW_REG, 2,
			RS_TO_RSLOW_DISCHG_OFFSET, 0);
	if (rc) {
		pr_err("unable to read rs to rslow dischg: %d\n", rc);
		goto done;
	}
	rs_to_rslow_dischg = half_float(buffer);

	rc = fg_mem_read(chip, buffer, TEMP_RS_TO_RSLOW_REG, 2,
			RS_TO_RSLOW_CHG_OFFSET, 0);
	if (rc) {
		pr_err("unable to read rs to rslow chg: %d\n", rc);
		goto done;
	}
	rs_to_rslow_chg = half_float(buffer);

	if (fg_debug_mask & FG_STATUS)
		pr_info("rs_rslow_chg: %lld, rs_rslow_dischg: %lld, esr: %lld\n",
			rs_to_rslow_chg, rs_to_rslow_dischg, batt_esr);

	rconn_uohm = chip->rconn_mohm * 1000;
	rs_to_rslow_dischg = div64_s64(rs_to_rslow_dischg * batt_esr,
					batt_esr + rconn_uohm);
	rs_to_rslow_chg = div64_s64(rs_to_rslow_chg * batt_esr,
					batt_esr + rconn_uohm);

	half_float_to_buffer(rs_to_rslow_chg, buffer);
	rc = fg_mem_write(chip, buffer, TEMP_RS_TO_RSLOW_REG, 2,
			RS_TO_RSLOW_CHG_OFFSET, 0);
	if (rc) {
		pr_err("unable to write rs_to_rslow_chg: %d\n", rc);
		goto done;
	}

	half_float_to_buffer(rs_to_rslow_dischg, buffer);
	rc = fg_mem_write(chip, buffer, TEMP_RS_TO_RSLOW_REG, 2,
			RS_TO_RSLOW_DISCHG_OFFSET, 0);
	if (rc) {
		pr_err("unable to write rs_to_rslow_dischg: %d\n", rc);
		goto done;
	}

	if (fg_debug_mask & FG_STATUS)
		pr_info("Modified rs_rslow_chg: %lld, rs_rslow_dischg: %lld\n",
			rs_to_rslow_chg, rs_to_rslow_dischg);
done:
	return rc;
}

#define RSLOW_CFG_MASK		(BIT(2) | BIT(3) | BIT(4) | BIT(5))
#define RSLOW_CFG_ON_VAL	(BIT(2) | BIT(3))
#define RSLOW_THRESH_FULL_VAL	0xFF
@@ -4425,7 +4489,7 @@ static int fg_rslow_charge_comp_set(struct fg_chip *chip)

	half_float_to_buffer(chip->rslow_comp.chg_rs_to_rslow, buffer);
	rc = fg_mem_write(chip, buffer,
			TEMP_RS_TO_RSLOW_REG, 2, TEMP_RS_TO_RSLOW_OFFSET, 0);
			TEMP_RS_TO_RSLOW_REG, 2, RS_TO_RSLOW_CHG_OFFSET, 0);
	if (rc) {
		pr_err("unable to write rs to rslow: %d\n", rc);
		goto done;
@@ -4478,7 +4542,7 @@ static int fg_rslow_charge_comp_clear(struct fg_chip *chip)
	}

	rc = fg_mem_write(chip, chip->rslow_comp.rs_to_rslow,
			TEMP_RS_TO_RSLOW_REG, 2, TEMP_RS_TO_RSLOW_OFFSET, 0);
			TEMP_RS_TO_RSLOW_REG, 2, RS_TO_RSLOW_CHG_OFFSET, 0);
	if (rc) {
		pr_err("unable to write rs to rslow: %d\n", rc);
		goto done;
@@ -5186,6 +5250,11 @@ wait:
		}
	}

	if (chip->rconn_mohm > 0) {
		rc = fg_update_batt_rslow_settings(chip);
		if (rc)
			pr_err("Error in updating ESR, rc=%d\n", rc);
	}
done:
	if (chip->charging_disabled) {
		rc = set_prop_enable_charging(chip, true);
@@ -5683,6 +5752,8 @@ static int fg_of_init(struct fg_chip *chip)
				chip->slope_limit_coeffs[HIGH_TEMP_DISCHARGE]);
	}

	OF_READ_PROPERTY(chip->rconn_mohm, "fg-rconn-mohm", rc, 0);

	return rc;
}

@@ -6480,6 +6551,7 @@ static int fg_common_hw_init(struct fg_chip *chip)
		if (fg_debug_mask & FG_STATUS)
			pr_info("imptr_pulse_slow is %sabled\n",
				chip->imptr_pulse_slow_en ? "en" : "dis");
	}

	rc = fg_mem_read(chip, &val, RSLOW_CFG_REG, 1, RSLOW_CFG_OFFSET,
			0);
@@ -6494,7 +6566,6 @@ static int fg_common_hw_init(struct fg_chip *chip)
	if (fg_debug_mask & FG_STATUS)
		pr_info("rslow_comp active is %sabled\n",
			chip->rslow_comp.active ? "en" : "dis");
	}

	return 0;
}