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

Commit 0edd2565 authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy
Browse files

qpnp-fg-gen3: add support to restart fuel gauge



Add a module parameter "fg_restart" to restart the fuel gauge
without loading the battery profile. This will be useful in
geting a fresh SOC estimate whenever required.

Change-Id: I0c054ad523a0eab72f777d010807bb3a55f63f7e
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent bd811f3a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -237,9 +237,11 @@ struct fg_chip {
	int			nom_cap_uah;
	int			status;
	int			prev_status;
	int			last_soc;
	bool			profile_available;
	bool			profile_loaded;
	bool			battery_missing;
	bool			fg_restarting;
	struct completion	soc_update;
	struct completion	soc_ready;
	struct delayed_work	profile_load_work;
+95 −24
Original line number Diff line number Diff line
@@ -279,6 +279,7 @@ module_param_named(
	sram_dump, fg_sram_dump, bool, S_IRUSR | S_IWUSR
);

static int fg_restart;

/* All getters HERE */

@@ -999,12 +1000,57 @@ static bool is_profile_load_required(struct fg_chip *chip)
}

#define SOC_READY_WAIT_MS		2000
static int __fg_restart(struct fg_chip *chip)
{
	int rc, msoc;
	bool tried_again = false;

	rc = fg_get_prop_capacity(chip, &msoc);
	if (rc < 0) {
		pr_err("Error in getting capacity, rc=%d\n", rc);
		return rc;
	}

	chip->last_soc = msoc;
	chip->fg_restarting = true;
	reinit_completion(&chip->soc_ready);
	rc = fg_masked_write(chip, BATT_SOC_RESTART(chip), RESTART_GO_BIT,
			RESTART_GO_BIT);
	if (rc < 0) {
		pr_err("Error in writing to %04x, rc=%d\n",
			BATT_SOC_RESTART(chip), rc);
		goto out;
	}

wait:
	rc = wait_for_completion_interruptible_timeout(&chip->soc_ready,
		msecs_to_jiffies(SOC_READY_WAIT_MS));

	/* If we were interrupted wait again one more time. */
	if (rc == -ERESTARTSYS && !tried_again) {
		tried_again = true;
		goto wait;
	} else if (rc <= 0) {
		pr_err("wait for soc_ready timed out rc=%d\n", rc);
		goto out;
	}

	rc = fg_masked_write(chip, BATT_SOC_RESTART(chip), RESTART_GO_BIT, 0);
	if (rc < 0) {
		pr_err("Error in writing to %04x, rc=%d\n",
			BATT_SOC_RESTART(chip), rc);
		goto out;
	}
out:
	chip->fg_restarting = false;
	return rc;
}

static void profile_load_work(struct work_struct *work)
{
	struct fg_chip *chip = container_of(work,
				struct fg_chip,
				profile_load_work.work);
	bool tried_again = false;
	u8 buf[2], val;
	int rc;

@@ -1029,24 +1075,9 @@ static void profile_load_work(struct work_struct *work)
		goto out;
	}

	rc = fg_masked_write(chip, BATT_SOC_RESTART(chip), RESTART_GO_BIT,
			RESTART_GO_BIT);
	rc = __fg_restart(chip);
	if (rc < 0) {
		pr_err("Error in writing to %04x, rc=%d\n",
			BATT_SOC_RESTART(chip), rc);
		goto out;
	}

wait:
	rc = wait_for_completion_interruptible_timeout(&chip->soc_ready,
		msecs_to_jiffies(SOC_READY_WAIT_MS));

	/* If we were interrupted wait again one more time. */
	if (rc == -ERESTARTSYS && !tried_again) {
		tried_again = true;
		goto wait;
	} else if (rc <= 0) {
		pr_err("wait for soc_ready timed out rc=%d\n", rc);
		pr_err("Error in restarting FG, rc=%d\n", rc);
		goto out;
	}

@@ -1061,7 +1092,6 @@ wait:
		goto out;
	}

	fg_dbg(chip, FG_STATUS, "profile loaded successfully");
done:
	rc = fg_sram_read(chip, NOM_CAP_WORD, NOM_CAP_OFFSET, buf, 2,
			FG_IMA_DEFAULT);
@@ -1073,14 +1103,52 @@ done:

	chip->nom_cap_uah = (int)(buf[0] | buf[1] << 8) * 1000;
	chip->profile_loaded = true;
	fg_dbg(chip, FG_STATUS, "profile loaded successfully");
out:
	vote(chip->awake_votable, PROFILE_LOAD, false, 0);
	rc = fg_masked_write(chip, BATT_SOC_RESTART(chip), RESTART_GO_BIT, 0);
	if (rc < 0)
		pr_err("Error in writing to %04x, rc=%d\n",
			BATT_SOC_RESTART(chip), rc);
}

static int fg_restart_sysfs(const char *val, const struct kernel_param *kp)
{
	int rc;
	struct power_supply *bms_psy;
	struct fg_chip *chip;

	rc = param_set_int(val, kp);
	if (rc) {
		pr_err("Unable to set fg_restart: %d\n", rc);
		return rc;
	}

	if (fg_restart != 1) {
		pr_err("Bad value %d\n", fg_restart);
		return -EINVAL;
	}

	bms_psy = power_supply_get_by_name("bms");
	if (!bms_psy) {
		pr_err("bms psy not found\n");
		return 0;
	}

	chip = power_supply_get_drvdata(bms_psy);
	rc = __fg_restart(chip);
	if (rc < 0) {
		pr_err("Error in restarting FG, rc=%d\n", rc);
		return rc;
	}

	pr_info("FG restart done\n");
	return rc;
}

static struct kernel_param_ops fg_restart_ops = {
	.set = fg_restart_sysfs,
	.get = param_get_int,
};

module_param_cb(restart, &fg_restart_ops, &fg_restart, 0644);

/* PSY CALLBACKS STAY HERE */

static int fg_psy_get_property(struct power_supply *psy,
@@ -1092,6 +1160,9 @@ static int fg_psy_get_property(struct power_supply *psy,

	switch (psp) {
	case POWER_SUPPLY_PROP_CAPACITY:
		if (chip->fg_restarting)
			pval->intval = chip->last_soc;
		else
			rc = fg_get_prop_capacity(chip, &pval->intval);
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_NOW: