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

Commit 5385079a authored by Ashish Chavan's avatar Ashish Chavan
Browse files

qcom: step-chg-jeita: Add support for jeita fcc scaling



The current design of sw-jeita handling requires some predefined
steps to be added for jeita step charge, These steps need to be
tuned and updated appropriately on every platform to get the best
charge time. Add support for auto jeita fcc scaling which
when enabled auto-scales the FCC depending upon the granularity
of increase in battery temperature.

Change-Id: Ida1c9b62f1a94e32de5e74ecb75c5c0b5d47548d
Signed-off-by: default avatarAshish Chavan <ashichav@codeaurora.org>
parent 464112e0
Loading
Loading
Loading
Loading
+125 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt) "QCOM-STEPCHG: %s: " fmt, __func__
@@ -16,6 +16,7 @@

#define STEP_CHG_VOTER		"STEP_CHG_VOTER"
#define JEITA_VOTER		"JEITA_VOTER"
#define JEITA_FCC_SCALE_VOTER	"JEITA_FCC_SCALE_VOTER"

#define is_between(left, right, value) \
		(((left) >= (right) && (left) >= (value) \
@@ -53,10 +54,15 @@ struct step_chg_info {
	bool			vbat_avg_based_step_chg;
	bool			batt_missing;
	bool			taper_fcc;
	bool			jeita_fcc_scaling;
	int			jeita_fcc_index;
	int			jeita_fv_index;
	int			step_index;
	int			get_config_retry_count;
	int			jeita_last_update_temp;
	int			jeita_fcc_scaling_temp_threshold[2];
	long			jeita_max_fcc_ua;
	long			jeita_fcc_step_size;

	struct step_chg_cfg	*step_chg_config;
	struct jeita_fcc_cfg	*jeita_fcc_config;
@@ -230,6 +236,7 @@ static int get_step_chg_jeita_setting_from_profile(struct step_chg_info *chip)
	const char *batt_type_str;
	const __be32 *handle;
	int batt_id_ohms, rc, hysteresis[2] = {0};
	u32 jeita_scaling_min_fcc_ua = 0;
	union power_supply_propval prop = {0, };

	handle = of_get_property(chip->dev->of_node,
@@ -288,6 +295,7 @@ static int get_step_chg_jeita_setting_from_profile(struct step_chg_info *chip)
		pr_err("max-fastchg-current-ma reading failed, rc=%d\n", rc);
		return rc;
	}
	chip->jeita_max_fcc_ua = max_fcc_ma * 1000;

	chip->taper_fcc = of_property_read_bool(profile_node, "qcom,taper-fcc");

@@ -366,6 +374,48 @@ static int get_step_chg_jeita_setting_from_profile(struct step_chg_info *chip)
		chip->sw_jeita_cfg_valid = false;
	}

	if (of_property_read_bool(profile_node, "qcom,jeita-fcc-scaling")) {

		rc = of_property_read_u32_array(profile_node,
				"qcom,jeita-fcc-scaling-temp-threshold",
				chip->jeita_fcc_scaling_temp_threshold, 2);
		if (rc < 0)
			pr_debug("Read jeita-fcc-scaling-temp-threshold from battery profile, rc=%d\n",
				rc);

		rc = of_property_read_u32(profile_node,
			"qcom,jeita-scaling-min-fcc-ua",
			&jeita_scaling_min_fcc_ua);
		if (rc < 0)
			pr_debug("Read jeita-scaling-min-fcc-ua from battery profile, rc=%d\n",
				rc);

		if ((jeita_scaling_min_fcc_ua &&
			(jeita_scaling_min_fcc_ua < chip->jeita_max_fcc_ua)) &&
			(chip->jeita_fcc_scaling_temp_threshold[0] <
			chip->jeita_fcc_scaling_temp_threshold[1])) {
			/*
			 * Calculate jeita-fcc-step-size =
			 *	(difference-in-fcc) / ( difference-in-temp)
			 */
			chip->jeita_fcc_step_size = div_s64(
			(chip->jeita_max_fcc_ua - jeita_scaling_min_fcc_ua),
			(chip->jeita_fcc_scaling_temp_threshold[1] -
				chip->jeita_fcc_scaling_temp_threshold[0]));

			if (chip->jeita_fcc_step_size > 0)
				chip->jeita_fcc_scaling = true;
		}

		pr_debug("jeita-fcc-scaling: enabled = %d, jeita-fcc-scaling-temp-threshold = [%d, %d], jeita-scaling-min-fcc-ua = %ld, jeita-scaling-max_fcc_ua = %ld,jeita-fcc-step-size = %ld\n",
			chip->jeita_fcc_scaling,
			chip->jeita_fcc_scaling_temp_threshold[0],
			chip->jeita_fcc_scaling_temp_threshold[1],
			jeita_scaling_min_fcc_ua, chip->jeita_max_fcc_ua,
			chip->jeita_fcc_step_size
			);
	}

	return rc;
}

@@ -622,6 +672,76 @@ static int handle_step_chg_config(struct step_chg_info *chip)
	return 0;
}

static void handle_jeita_fcc_scaling(struct step_chg_info *chip)
{
	union power_supply_propval pval = {0, };
	int fcc_ua = 0, temp_diff = 0, rc;
	bool first_time_entry;

	if (chip->jeita_fcc_config->param.use_bms)
		rc = power_supply_get_property(chip->bms_psy,
				chip->jeita_fcc_config->param.psy_prop, &pval);
	else
		rc = power_supply_get_property(chip->batt_psy,
				chip->jeita_fcc_config->param.psy_prop, &pval);

	if (rc < 0) {
		pr_err("Couldn't read %s property rc=%d\n",
				chip->jeita_fcc_config->param.prop_name, rc);
		return;
	}

	/* Skip mitigation if temp is not within min-max thresholds */
	if (!is_between(chip->jeita_fcc_scaling_temp_threshold[0],
		chip->jeita_fcc_scaling_temp_threshold[1], pval.intval)) {
		pr_debug("jeita-fcc-scaling : Skip jeita scaling, temp out of range temp = %d\n",
			pval.intval);
		chip->jeita_last_update_temp = pval.intval;
		vote(chip->fcc_votable, JEITA_FCC_SCALE_VOTER, false, 0);
		return;
	}

	/*
	 * We determine this is the first time entry to jeita-fcc-scaling if
	 * jeita_last_update_temp is not within entry/exist thresholds.
	 */
	first_time_entry = !is_between(chip->jeita_fcc_scaling_temp_threshold[0]
		, chip->jeita_fcc_scaling_temp_threshold[1],
		chip->jeita_last_update_temp);

	/*
	 * VOTE on FCC only when temp is within hys or if this the very first
	 * time we crossed the entry threshold.
	 */
	if (first_time_entry ||
		((pval.intval > (chip->jeita_last_update_temp +
			chip->jeita_fcc_config->param.rise_hys)) ||
		(pval.intval < (chip->jeita_last_update_temp -
			chip->jeita_fcc_config->param.fall_hys)))) {

		/*
		 * New FCC step is calculated as :
		 *	fcc_ua = (max-fcc - ((current_temp - min-temp) *
		 *			jeita-step-size))
		 */
		temp_diff = pval.intval -
				chip->jeita_fcc_scaling_temp_threshold[0];
		fcc_ua = div_s64((chip->jeita_max_fcc_ua -
			(chip->jeita_fcc_step_size * temp_diff)), 100) * 100;

		vote(chip->fcc_votable, JEITA_FCC_SCALE_VOTER, true, fcc_ua);
		pr_debug("jeita-fcc-scaling: first_time_entry = %d, max_fcc_ua = %ld, voted_fcc_ua = %d, temp_diff = %d, prev_temp = %d, current_temp = %d\n",
			first_time_entry, chip->jeita_max_fcc_ua, fcc_ua,
			temp_diff, chip->jeita_last_update_temp, pval.intval);

		chip->jeita_last_update_temp = pval.intval;
	} else {
		pr_debug("jeita-fcc-scaling: Skip jeita mitigation temp within first_time_entry = %d, hys temp = %d, last_updated_temp = %d\n",
			first_time_entry, pval.intval,
			chip->jeita_last_update_temp);
	}
}

#define JEITA_SUSPEND_HYST_UV		50000
static int handle_jeita(struct step_chg_info *chip)
{
@@ -636,6 +756,10 @@ static int handle_jeita(struct step_chg_info *chip)
	else
		chip->sw_jeita_enable = pval.intval;

	/* Handle jeita-fcc-scaling if enabled */
	if (chip->jeita_fcc_scaling)
		handle_jeita_fcc_scaling(chip);

	if (!chip->sw_jeita_enable || !chip->sw_jeita_cfg_valid) {
		if (chip->fcc_votable)
			vote(chip->fcc_votable, JEITA_VOTER, false, 0);