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

Commit af439727 authored by Xiaozhe Shi's avatar Xiaozhe Shi
Browse files

power: qpnp-bms: recalculate SoC faster when vbat is low



Sometimes the BMS accumulates errors through faulty OCVs or small
coulomb counters inaccuracies. These errors can add up when doing high
load discharging, and can make the device go into UVLO without having
the BMS driver report 0% SoC.

Allow the BMS to correct faster if the battery voltage is almost at
cutoff.

Change-Id: Ic19b992d0da954a18cf5357db31dc5c0ffa09812
Signed-off-by: default avatarXiaozhe Shi <xiaozhes@codeaurora.org>
parent 4b2d5f30
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -56,10 +56,14 @@ Parent node required properties:
- qcom,low-voltage-threshold : The battery voltage threshold in micro-volts for
			when the BMS tries to wake up and hold a wakelock to
			ensure a clean shutdown.
- qcom,low-voltage-calculate-soc-ms : The time period between subsequent
			SoC recalculations when the current voltage is below
			qcom,low-voltage threshold. This takes precedence over
			qcom,low-soc-calculate-soc-ms.
- qcom,low-soc-calculate-soc-ms : The time period between subsequent
			SoC recalculations when the current SoC is below
			qcom,low-soc-calculate-soc-threshold or when battery
			voltage is below qcom,low-voltage-threshold.
			qcom,low-soc-calculate-soc-threshold. This takes
			precedence over qcom,calculate-soc-ms.
- qcom,calculate-soc-ms : The time period between subsequent SoC
			recalculations when the current SoC is above or equal
			qcom,low-soc-calculate-soc-threshold.
@@ -160,6 +164,7 @@ pm8941_bms: qcom,bms {
	qcom,adjust-soc-low-threshold = <15>;
	qcom,low-soc-calculate-soc-threshold = <15>;
	qcom,low-voltage-threshold = <3420000>;
	qcom,low-voltage-calculate-soc-ms = <1000>;
	qcom,low-soc-calculate-soc-ms = <5000>;
	qcom,calculate-soc-ms = <20000>;
	qcom,chg-term-ua = <100000>;
+1 −0
Original line number Diff line number Diff line
@@ -326,6 +326,7 @@
			qcom,ocv-voltage-high-threshold-uv = <3750000>;
			qcom,ocv-voltage-low-threshold-uv = <3650000>;
			qcom,low-soc-calculate-soc-threshold = <15>;
			qcom,low-voltage-calculate-soc-ms = <1000>;
			qcom,low-soc-calculate-soc-ms = <5000>;
			qcom,calculate-soc-ms = <20000>;
			qcom,chg-term-ua = <100000>;
+1 −0
Original line number Diff line number Diff line
@@ -199,6 +199,7 @@
			qcom,ocv-voltage-high-threshold-uv = <3750000>;
			qcom,ocv-voltage-low-threshold-uv = <3650000>;
			qcom,low-soc-calculate-soc-threshold = <15>;
			qcom,low-voltage-calculate-soc-ms = <1000>;
			qcom,low-soc-calculate-soc-ms = <5000>;
			qcom,calculate-soc-ms = <20000>;
			qcom,chg-term-ua = <100000>;
+1 −0
Original line number Diff line number Diff line
@@ -125,6 +125,7 @@
		qcom,ocv-voltage-high-threshold-uv = <3750000>;
		qcom,ocv-voltage-low-threshold-uv = <3650000>;
		qcom,low-soc-calculate-soc-threshold = <15>;
		qcom,low-voltage-calculate-soc-ms = <1000>;
		qcom,low-soc-calculate-soc-ms = <5000>;
		qcom,calculate-soc-ms = <20000>;
		qcom,chg-term-ua = <100000>;
+18 −14
Original line number Diff line number Diff line
@@ -204,6 +204,7 @@ struct qpnp_bms_chip {
	int				low_voltage_threshold;
	int				low_soc_calc_threshold;
	int				low_soc_calculate_soc_ms;
	int				low_voltage_calculate_soc_ms;
	int				calculate_soc_ms;
	struct bms_wakeup_source	soc_wake_source;
	struct wake_lock		cv_wake_lock;
@@ -2546,22 +2547,26 @@ static void recalculate_work(struct work_struct *work)
	recalculate_soc(chip);
}

static int get_calculation_delay_ms(struct qpnp_bms_chip *chip)
{
	if (wake_lock_active(&chip->low_voltage_wake_lock))
		return chip->low_voltage_calculate_soc_ms;
	else if (chip->calculated_soc < chip->low_soc_calc_threshold)
		return chip->low_soc_calculate_soc_ms;
	else
		return chip->calculate_soc_ms;
}

static void calculate_soc_work(struct work_struct *work)
{
	struct qpnp_bms_chip *chip = container_of(work,
				struct qpnp_bms_chip,
				calculate_soc_delayed_work.work);
	int soc = recalculate_soc(chip);

	if (soc < chip->low_soc_calc_threshold
			|| wake_lock_active(&chip->low_voltage_wake_lock))
		schedule_delayed_work(&chip->calculate_soc_delayed_work,
			round_jiffies_relative(msecs_to_jiffies
			(chip->low_soc_calculate_soc_ms)));
	else
	recalculate_soc(chip);
	schedule_delayed_work(&chip->calculate_soc_delayed_work,
		round_jiffies_relative(msecs_to_jiffies
			(chip->calculate_soc_ms)));
		(get_calculation_delay_ms(chip))));
}

static void configure_vbat_monitor_low(struct qpnp_bms_chip *chip)
@@ -3711,6 +3716,8 @@ static inline int bms_read_properties(struct qpnp_bms_chip *chip)
			"low-soc-calculate-soc-threshold", rc);
	SPMI_PROP_READ(low_soc_calculate_soc_ms,
			"low-soc-calculate-soc-ms", rc);
	SPMI_PROP_READ(low_voltage_calculate_soc_ms,
			"low-voltage-calculate-soc-ms", rc);
	SPMI_PROP_READ(calculate_soc_ms, "calculate-soc-ms", rc);
	SPMI_PROP_READ(high_ocv_correction_limit_uv,
			"high-ocv-correction-limit-uv", rc);
@@ -4330,10 +4337,7 @@ static int bms_resume(struct device *dev)
	if (rc) {
		pr_err("Could not read current time: %d\n", rc);
	} else {
		if (chip->calculated_soc < chip->low_soc_calc_threshold)
			soc_calc_period = chip->low_soc_calculate_soc_ms;
		else
			soc_calc_period = chip->calculate_soc_ms;
		soc_calc_period = get_calculation_delay_ms(chip);
		time_since_last_recalc = tm_now_sec - chip->last_recalc_time;
		pr_debug("Time since last recalc: %lu\n",
				time_since_last_recalc);