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

Commit 3fbcbe95 authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy Committed by Harry Yang
Browse files

power: qpnp-fg-gen3: synchronize ESR extraction control configuration



Currently, ESR extraction control is configured from two paths.
First is invoked when Qnovo is enabled or disabled. Second is
invoked when the pulse train is done and ESR measurement is
requested. When the latter is run, there is a sleep time of 1.5
seconds that is essential for allowing FG to do ESR measurement.
However in that time window, if Qnovo is disabled for some reason
then ESR extraction control will be kept disabled unexpectedly.

Fix this by protecting both the paths using a mutex lock as well
as checking for qnovo enable status before disabling ESR
extraction control after measuring ESR.

Change-Id: Ib93539071724a1ce59d198074854a8a9c5fd3ab3
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent 7b429571
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -417,6 +417,7 @@ struct fg_chip {
	struct mutex		bus_lock;
	struct mutex		sram_rw_lock;
	struct mutex		charge_full_lock;
	struct mutex		qnovo_esr_ctrl_lock;
	u32			batt_soc_base;
	u32			batt_info_base;
	u32			mem_if_base;
@@ -450,6 +451,7 @@ struct fg_chip {
	bool			slope_limit_en;
	bool			use_ima_single_mode;
	bool			use_dma;
	bool			qnovo_enable;
	struct completion	soc_update;
	struct completion	soc_ready;
	struct completion	mem_grant;
+36 −12
Original line number Diff line number Diff line
@@ -3301,20 +3301,21 @@ static int fg_force_esr_meas(struct fg_chip *chip)
	int rc;
	int esr_uohms;

	mutex_lock(&chip->qnovo_esr_ctrl_lock);
	/* force esr extraction enable */
	rc = fg_sram_masked_write(chip, ESR_EXTRACTION_ENABLE_WORD,
			ESR_EXTRACTION_ENABLE_OFFSET, BIT(0), BIT(0),
			FG_IMA_DEFAULT);
	if (rc < 0) {
		pr_err("failed to enable esr extn rc=%d\n", rc);
		return rc;
		goto out;
	}

	rc = fg_masked_write(chip, BATT_INFO_QNOVO_CFG(chip),
			LD_REG_CTRL_BIT, 0);
	if (rc < 0) {
		pr_err("Error in configuring qnovo_cfg rc=%d\n", rc);
		return rc;
		goto out;
	}

	rc = fg_masked_write(chip, BATT_INFO_TM_MISC1(chip),
@@ -3322,24 +3323,36 @@ static int fg_force_esr_meas(struct fg_chip *chip)
			ESR_REQ_CTL_BIT | ESR_REQ_CTL_EN_BIT);
	if (rc < 0) {
		pr_err("Error in configuring force ESR rc=%d\n", rc);
		return rc;
		goto out;
	}

	/*
	 * Release and grab the lock again after 1.5 seconds so that prepare
	 * callback can succeed if the request comes in between.
	 */
	mutex_unlock(&chip->qnovo_esr_ctrl_lock);

	/* wait 1.5 seconds for hw to measure ESR */
	msleep(1500);

	mutex_lock(&chip->qnovo_esr_ctrl_lock);
	rc = fg_masked_write(chip, BATT_INFO_TM_MISC1(chip),
			ESR_REQ_CTL_BIT | ESR_REQ_CTL_EN_BIT,
			0);
	if (rc < 0) {
		pr_err("Error in restoring force ESR rc=%d\n", rc);
		return rc;
		goto out;
	}

	/* If qnovo is disabled, then leave ESR extraction enabled */
	if (!chip->qnovo_enable)
		goto done;

	rc = fg_masked_write(chip, BATT_INFO_QNOVO_CFG(chip),
			LD_REG_CTRL_BIT, LD_REG_CTRL_BIT);
	if (rc < 0) {
		pr_err("Error in restoring qnovo_cfg rc=%d\n", rc);
		return rc;
		goto out;
	}

	/* force esr extraction disable */
@@ -3348,36 +3361,46 @@ static int fg_force_esr_meas(struct fg_chip *chip)
			FG_IMA_DEFAULT);
	if (rc < 0) {
		pr_err("failed to disable esr extn rc=%d\n", rc);
		return rc;
		goto out;
	}

done:
	fg_get_battery_resistance(chip, &esr_uohms);
	fg_dbg(chip, FG_STATUS, "ESR uohms = %d\n", esr_uohms);

out:
	mutex_unlock(&chip->qnovo_esr_ctrl_lock);
	return rc;
}

static int fg_prepare_for_qnovo(struct fg_chip *chip, int qnovo_enable)
{
	int rc;
	int rc = 0;

	mutex_lock(&chip->qnovo_esr_ctrl_lock);
	/* force esr extraction disable when qnovo enables */
	rc = fg_sram_masked_write(chip, ESR_EXTRACTION_ENABLE_WORD,
			ESR_EXTRACTION_ENABLE_OFFSET,
			BIT(0), qnovo_enable ? 0 : BIT(0),
			FG_IMA_DEFAULT);
	if (rc < 0)
	if (rc < 0) {
		pr_err("Error in configuring esr extraction rc=%d\n", rc);
		goto out;
	}

	rc = fg_masked_write(chip, BATT_INFO_QNOVO_CFG(chip),
			LD_REG_CTRL_BIT,
			qnovo_enable ? LD_REG_CTRL_BIT : 0);
	if (rc < 0) {
		pr_err("Error in configuring qnovo_cfg rc=%d\n", rc);
		return rc;
		goto out;
	}
	fg_dbg(chip, FG_STATUS, "Prepared for Qnovo\n");
	return 0;

	fg_dbg(chip, FG_STATUS, "%s for Qnovo\n",
		qnovo_enable ? "Prepared" : "Unprepared");
	chip->qnovo_enable = qnovo_enable;
out:
	mutex_unlock(&chip->qnovo_esr_ctrl_lock);
	return rc;
}

static void ttf_work(struct work_struct *work)
@@ -5049,6 +5072,7 @@ static int fg_gen3_probe(struct platform_device *pdev)
	mutex_init(&chip->cl.lock);
	mutex_init(&chip->ttf.lock);
	mutex_init(&chip->charge_full_lock);
	mutex_init(&chip->qnovo_esr_ctrl_lock);
	init_completion(&chip->soc_update);
	init_completion(&chip->soc_ready);
	init_completion(&chip->mem_grant);