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

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

power: qpnp-charger: disable ibat_loop when temperature is out of range



When the charger is in the chg_pause state, the ibat regulation loop can
cause the batfet to oscillate due to VCP. This occurs because of an
hardware issue with the IBAT_MAX stepper when the charger is paused.
When charging is paused, the buck accuracy degrades and can cause VPH to
dip below vbat, triggering VCP. The batfet toggling causes faulty IBAT
readings by the BMS.

Fix this by disabling the ibat regulation loop when the battery goes
into the hot or cold state. This will fix the batfet toggling issue as
well as the faulty ibat readings.

Change-Id: I74bab3e6fd0c1be0e83100672262fc504eee3396
Signed-off-by: default avatarXiaozhe Shi <xiaozhes@codeaurora.org>
parent d2056c0d
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -1519,15 +1519,35 @@ qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip)
	return IRQ_HANDLED;
}

#define TEST_EN_SMBC_LOOP		0xE5
#define IBAT_REGULATION_DISABLE		BIT(2)
static irqreturn_t
qpnp_chg_bat_if_batt_temp_irq_handler(int irq, void *_chip)
{
	struct qpnp_chg_chip *chip = _chip;
	int batt_temp_good;
	int batt_temp_good, rc;

	batt_temp_good = qpnp_chg_is_batt_temp_ok(chip);
	pr_debug("batt-temp triggered: %d\n", batt_temp_good);

	rc = qpnp_chg_masked_write(chip,
		chip->buck_base + SEC_ACCESS,
		0xFF,
		0xA5, 1);
	if (rc) {
		pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
		return rc;
	}

	rc = qpnp_chg_masked_write(chip,
		chip->buck_base + TEST_EN_SMBC_LOOP,
		IBAT_REGULATION_DISABLE,
		batt_temp_good ? 0 : IBAT_REGULATION_DISABLE, 1);
	if (rc) {
		pr_err("failed to write COMP_OVR1 rc=%d\n", rc);
		return rc;
	}

	pr_debug("psy changed batt_psy\n");
	power_supply_changed(&chip->batt_psy);
	return IRQ_HANDLED;
@@ -3864,6 +3884,7 @@ qpnp_chg_request_irqs(struct qpnp_chg_chip *chip)
						chip->batt_temp_ok.irq, rc);
				return rc;
			}
			qpnp_chg_bat_if_batt_temp_irq_handler(0, chip);

			enable_irq_wake(chip->batt_temp_ok.irq);