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

Commit 75e8aff4 authored by Anirudh Ghayal's avatar Anirudh Ghayal
Browse files

power: qpnp-qg: Use both charge & discharge tables for PON SOC



To avoid a big SOC dump while moving between charge/discharge
profiles, use the average of charge and discharge SOC for PON
and GOOD OCV.

Change-Id: I02d88798cab2e2b5aeb13991586d9026c99dc922
Signed-off-by: default avatarAnirudh Ghayal <aghayal@codeaurora.org>
parent c609639e
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -393,19 +393,33 @@ static int qg_parse_battery_profile(struct qg_battery_data *battery)
	return rc;
}

int lookup_soc_ocv(u32 *soc, u32 ocv_uv, int batt_temp, bool charging)
int lookup_soc_ocv(u32 *soc, u32 ocv_uv, int batt_temp, u8 lookup)
{
	u8 table_index = charging ? TABLE_SOC_OCV1 : TABLE_SOC_OCV2;
	u8 table_index = 0;
	int soc_avg = 0, soc_charge = 0, soc_discharge = 0;

	if (!the_battery || !the_battery->profile) {
		pr_err("Battery profile not loaded\n");
		return -ENODEV;
	}

	*soc = interpolate_soc(&the_battery->profile[table_index],
	if (lookup == SOC_AVERAGE) {
		soc_charge = interpolate_soc(
				&the_battery->profile[TABLE_SOC_OCV1],
				batt_temp, UV_TO_DECIUV(ocv_uv));
		soc_discharge = interpolate_soc(
				&the_battery->profile[TABLE_SOC_OCV2],
				batt_temp, UV_TO_DECIUV(ocv_uv));
		soc_avg = (soc_charge + soc_discharge) / 2;
	} else {
		table_index = (lookup == SOC_CHARGE) ?
				TABLE_SOC_OCV1 : TABLE_SOC_OCV2;
		soc_avg = interpolate_soc(
				&the_battery->profile[table_index],
				batt_temp, UV_TO_DECIUV(ocv_uv));
	}

	*soc = CAP(0, 100, DIV_ROUND_CLOSEST(*soc, 100));
	*soc = CAP(0, 100, DIV_ROUND_CLOSEST(soc_avg, 100));

	return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -14,6 +14,6 @@

int qg_batterydata_init(struct device_node *node);
void qg_batterydata_exit(void);
int lookup_soc_ocv(u32 *soc, u32 ocv_uv, int batt_temp, bool charging);
int lookup_soc_ocv(u32 *soc, u32 ocv_uv, int batt_temp, u8 lookup);

#endif /* __QG_BATTERY_PROFILE_H__ */
+6 −0
Original line number Diff line number Diff line
@@ -45,4 +45,10 @@
#define CAP(min, max, value)			\
		((min > value) ? min : ((value > max) ? max : value))

enum soc_lookup {
	SOC_CHARGE,
	SOC_DISCHARGE,
	SOC_AVERAGE,
};

#endif /* __QG_DEFS_H__ */
+3 −2
Original line number Diff line number Diff line
@@ -1495,7 +1495,8 @@ static int qg_determine_pon_soc(struct qpnp_qg *chip)
			pr_err("Failed to read good_ocv rc=%d\n", rc);
			use_pon_ocv = true;
		} else {
			rc = lookup_soc_ocv(&soc, ocv_uv, batt_temp, false);
			rc = lookup_soc_ocv(&soc, ocv_uv, batt_temp,
							SOC_AVERAGE);
			if (rc < 0) {
				pr_err("Failed to lookup SOC (GOOD_OCV) @ PON rc=%d\n",
					rc);
@@ -1548,7 +1549,7 @@ static int qg_determine_pon_soc(struct qpnp_qg *chip)
			pr_err("Failed to read HW PON ocv rc=%d\n", rc);
			return rc;
		}
		rc = lookup_soc_ocv(&soc, ocv_uv, batt_temp, false);
		rc = lookup_soc_ocv(&soc, ocv_uv, batt_temp, SOC_AVERAGE);
		if (rc < 0) {
			pr_err("Failed to lookup SOC @ PON rc=%d\n", rc);
			soc = 50;