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

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

power: qpnp-fg-gen3: disable parallel charging during battery removal



During battery hotswap, parallel charging is disabled and enabled
by charger driver when battery is removed and inserted. However,
this changes ESR FCC configuration from SW control to HW control
during battery removal. ESR FCC configuration stays in HW control
before the parallel charging is enabled again and notified to FG
driver.

During this period, when an ESR pulse is triggered right after
the battery insertion, FG HW can request for a decrement in FCC
but charger can end up incrementing FCC due to not accounting the
distribution of FCC via the parallel charger. To fix this issue,
vote to disable parallel charging upon battery removal and enable
it 5 seconds after battery insertion.

CRs-Fixed: 2131292
Change-Id: I0cf09033fb3591508089e472e8f1813cf1ab3a8b
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent fc9ce0e0
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -57,6 +57,8 @@
/* Battery missing irq votable reasons */
#define BATT_MISS_IRQ_VOTER	"fg_batt_miss_irq"

#define ESR_FCC_VOTER		"fg_esr_fcc"

#define DEBUG_PRINT_BUFFER_SIZE		64
/* 3 byte address + 1 space character */
#define ADDR_LEN			4
@@ -403,6 +405,7 @@ struct fg_chip {
	struct votable		*awake_votable;
	struct votable		*delta_bsoc_irq_en_votable;
	struct votable		*batt_miss_irq_en_votable;
	struct votable		*pl_disable_votable;
	struct fg_sram_param	*sp;
	struct fg_dma_address	*addr_map;
	struct fg_alg_flag	*alg_flags;
@@ -460,6 +463,7 @@ struct fg_chip {
	struct work_struct	status_change_work;
	struct delayed_work	ttf_work;
	struct delayed_work	sram_dump_work;
	struct delayed_work	pl_enable_work;
};

/* Debugfs data structures are below */
+21 −0
Original line number Diff line number Diff line
@@ -2790,6 +2790,16 @@ static int __fg_restart(struct fg_chip *chip)
	return rc;
}

static void pl_enable_work(struct work_struct *work)
{
	struct fg_chip *chip = container_of(work,
				struct fg_chip,
				pl_enable_work.work);

	vote(chip->pl_disable_votable, ESR_FCC_VOTER, false, 0);
	vote(chip->awake_votable, ESR_FCC_VOTER, false, 0);
}

static void profile_load_work(struct work_struct *work)
{
	struct fg_chip *chip = container_of(work,
@@ -2883,6 +2893,8 @@ static void profile_load_work(struct work_struct *work)
	fg_dbg(chip, FG_STATUS, "profile loaded successfully");
out:
	chip->soc_reporting_ready = true;
	vote(chip->awake_votable, ESR_FCC_VOTER, true, 0);
	schedule_delayed_work(&chip->pl_enable_work, msecs_to_jiffies(5000));
	vote(chip->awake_votable, PROFILE_LOAD, false, 0);
}

@@ -4250,6 +4262,8 @@ static irqreturn_t fg_batt_missing_irq_handler(int irq, void *data)
		chip->profile_loaded = false;
		chip->soc_reporting_ready = false;
		chip->batt_id_ohms = -EINVAL;
		cancel_delayed_work_sync(&chip->pl_enable_work);
		vote(chip->pl_disable_votable, ESR_FCC_VOTER, true, 0);
		return IRQ_HANDLED;
	}

@@ -5105,6 +5119,12 @@ static int fg_gen3_probe(struct platform_device *pdev)
		}
	}

	chip->pl_disable_votable = find_votable("PL_DISABLE");
	if (chip->pl_disable_votable == NULL) {
		rc = -EPROBE_DEFER;
		goto exit;
	}

	chip->awake_votable = create_votable("FG_WS", VOTE_SET_ANY, fg_awake_cb,
					chip);
	if (IS_ERR(chip->awake_votable)) {
@@ -5149,6 +5169,7 @@ static int fg_gen3_probe(struct platform_device *pdev)
	init_completion(&chip->soc_ready);
	init_completion(&chip->mem_grant);
	INIT_DELAYED_WORK(&chip->profile_load_work, profile_load_work);
	INIT_DELAYED_WORK(&chip->pl_enable_work, pl_enable_work);
	INIT_WORK(&chip->status_change_work, status_change_work);
	INIT_DELAYED_WORK(&chip->ttf_work, ttf_work);
	INIT_DELAYED_WORK(&chip->sram_dump_work, sram_dump_work);