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

Commit d98d6971 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "power: qpnp-qg: Update the recharge/hold-SOC logic"

parents 10fe7715 bdf36373
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -134,6 +134,7 @@ struct qpnp_qg {
	u32			esr_last;
	ktime_t			last_user_update_time;
	ktime_t			last_fifo_update_time;
	unsigned long		last_maint_soc_update_time;

	/* soc params */
	int			catch_up_soc;
@@ -145,6 +146,7 @@ struct qpnp_qg {
	int			full_soc;
	int			sys_soc;
	int			last_adj_ssoc;
	int			recharge_soc;
	struct alarm		alarm_timer;
	u32			sdam_data[SDAM_MAX];

+40 −7
Original line number Diff line number Diff line
@@ -41,6 +41,11 @@ module_param_named(
	soc_cold_interval_ms, qg_delta_soc_cold_interval_ms, int, 0600
);

static int qg_maint_soc_update_ms = 120000;
module_param_named(
	maint_soc_update_ms, qg_maint_soc_update_ms, int, 0600
);

int qg_adjust_sys_soc(struct qpnp_qg *chip)
{
	int soc, vbat_uv, rc;
@@ -93,10 +98,11 @@ static void get_next_update_time(struct qpnp_qg *chip)

	/* Lower the delta soc interval by half at cold */
	rc = qg_get_battery_temp(chip, &batt_temp);
	if (rc < 0)
		pr_err("Failed to read battery temperature rc=%d\n", rc);
	else if (batt_temp < chip->dt.cold_temp_threshold)
	if (!rc && batt_temp < chip->dt.cold_temp_threshold)
		min_delta_soc_interval_ms = qg_delta_soc_cold_interval_ms;
	else if (chip->maint_soc > 0 && chip->maint_soc >= chip->recharge_soc)
		/* if in maintenance mode scale slower */
		min_delta_soc_interval_ms = qg_maint_soc_update_ms;

	if (!min_delta_soc_interval_ms)
		min_delta_soc_interval_ms = 1000;	/* 1 second */
@@ -135,9 +141,34 @@ static bool is_scaling_required(struct qpnp_qg *chip)
	return true;
}

static bool maint_soc_timeout(struct qpnp_qg *chip)
{
	unsigned long now;
	int rc;

	if (chip->maint_soc < 0)
		return false;

	rc = get_rtc_time(&now);
	if (rc < 0)
		return true;

	/* Do not scale if we have dropped below recharge-soc */
	if (chip->maint_soc < chip->recharge_soc)
		return true;

	if ((now - chip->last_maint_soc_update_time) >=
			(qg_maint_soc_update_ms / 1000)) {
		chip->last_maint_soc_update_time = now;
		return true;
	}

	return false;
}

static void update_msoc(struct qpnp_qg *chip)
{
	int rc = 0, batt_temp = 0,  batt_soc_32bit = 0;
	int rc = 0, sdam_soc, batt_temp = 0,  batt_soc_32bit = 0;
	bool usb_present = is_usb_present(chip);

	if (chip->catch_up_soc > chip->msoc) {
@@ -150,7 +181,8 @@ static void update_msoc(struct qpnp_qg *chip)
	}
	chip->msoc = CAP(0, 100, chip->msoc);

	if (chip->maint_soc > 0 && chip->msoc < chip->maint_soc) {
	if (chip->maint_soc > 0 && chip->msoc < chip->maint_soc
				&& maint_soc_timeout(chip)) {
		chip->maint_soc -= chip->dt.delta_soc;
		chip->maint_soc = CAP(0, 100, chip->maint_soc);
	}
@@ -165,8 +197,9 @@ static void update_msoc(struct qpnp_qg *chip)
		pr_err("Failed to update MSOC register rc=%d\n", rc);

	/* update SDAM with the new MSOC */
	chip->sdam_data[SDAM_SOC] = chip->msoc;
	rc = qg_sdam_write(SDAM_SOC, chip->msoc);
	sdam_soc = (chip->maint_soc > 0) ? chip->maint_soc : chip->msoc;
	chip->sdam_data[SDAM_SOC] = sdam_soc;
	rc = qg_sdam_write(SDAM_SOC, sdam_soc);
	if (rc < 0)
		pr_err("Failed to update SDAM with MSOC rc=%d\n", rc);

+36 −16
Original line number Diff line number Diff line
@@ -1858,9 +1858,11 @@ static int qg_charge_full_update(struct qpnp_qg *chip)
		recharge_soc = DEFAULT_RECHARGE_SOC;
	}
	recharge_soc = prop.intval;
	chip->recharge_soc = recharge_soc;

	qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d health=%d charge_full=%d\n",
				chip->msoc, health, chip->charge_full);
	qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d health=%d charge_full=%d charge_done=%d\n",
				chip->msoc, health, chip->charge_full,
				chip->charge_done);
	if (chip->charge_done && !chip->charge_full) {
		if (chip->msoc >= 99 && health == POWER_SUPPLY_HEALTH_GOOD) {
			chip->charge_full = true;
@@ -1871,10 +1873,18 @@ static int qg_charge_full_update(struct qpnp_qg *chip)
			qg_dbg(chip, QG_DEBUG_STATUS, "Terminated charging @ msoc=%d\n",
					chip->msoc);
		}
	} else if ((!chip->charge_done || chip->msoc < recharge_soc)
	} else if ((!chip->charge_done || chip->msoc <= recharge_soc)
				&& chip->charge_full) {

		if (chip->wa_flags & QG_RECHARGE_SOC_WA) {
		bool usb_present = is_usb_present(chip);

		/*
		 * force a recharge only if SOC <= recharge SOC and
		 * we have not started charging.
		 */
		if ((chip->wa_flags & QG_RECHARGE_SOC_WA) &&
			usb_present && chip->msoc <= recharge_soc &&
			chip->charge_status != POWER_SUPPLY_STATUS_CHARGING) {
			/* Force recharge */
			prop.intval = 0;
			rc = power_supply_set_property(chip->batt_psy,
@@ -1882,23 +1892,33 @@ static int qg_charge_full_update(struct qpnp_qg *chip)
			if (rc < 0)
				pr_err("Failed to force recharge rc=%d\n", rc);
			else
				qg_dbg(chip, QG_DEBUG_STATUS,
					"Forced recharge\n");
				qg_dbg(chip, QG_DEBUG_STATUS, "Forced recharge\n");
		}


		if (chip->charge_done)
			return 0;	/* wait for recharge */

		/*
		 * If recharge or discharge has started and
		 * if linearize soc dtsi property defined
		 * scale msoc from 100% for better UX.
		 * If SOC has indeed dropped below recharge-SOC or
		 * the USB is removed, if linearize-soc is set scale
		 * msoc from 100% for better UX.
		 */
		if (chip->dt.linearize_soc && chip->msoc < 99) {
		if (chip->msoc < recharge_soc || !usb_present) {
			if (chip->dt.linearize_soc) {
				get_rtc_time(&chip->last_maint_soc_update_time);
				chip->maint_soc = FULL_SOC;
				qg_scale_soc(chip, false);
			}

			chip->charge_full = false;
			qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d recharge_soc=%d charge_full (1->0)\n",
					chip->msoc, recharge_soc);
		chip->charge_full = false;
		} else {
			/* continue with charge_full state */
			qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d recharge_soc=%d charge_full=%d usb_present=%d\n",
					chip->msoc, recharge_soc,
					chip->charge_full, usb_present);
		}
	}
out:
	return 0;