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

Commit e0e3cc62 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "power: battery: cleanup FCC stepper flow to handle override votes"

parents 0c217e71 1ab4b14c
Loading
Loading
Loading
Loading
+125 −68
Original line number Original line Diff line number Diff line
@@ -197,6 +197,34 @@ static int cp_get_parallel_mode(struct pl_data *chip, int mode)
	return pval.intval;
	return pval.intval;
}
}


static int get_hvdcp3_icl_limit(struct pl_data *chip)
{
	int rc, main_icl, target_icl = -EINVAL;
	union power_supply_propval pval = {0, };

	rc = power_supply_get_property(chip->usb_psy,
				POWER_SUPPLY_PROP_REAL_TYPE, &pval);
	if ((rc < 0) || (pval.intval != POWER_SUPPLY_TYPE_USB_HVDCP_3))
		return target_icl;

	/*
	 * For HVDCP3 adapters, limit max. ILIM as follows:
	 * HVDCP3_ICL: Maximum ICL of HVDCP3 adapter(from DT configuration)
	 * For Parallel input configurations:
	 * VBUS: target_icl = HVDCP3_ICL - main_ICL
	 * VMID: target_icl = HVDCP3_ICL
	 */
	target_icl = chip->chg_param->hvdcp3_max_icl_ua;
	if (cp_get_parallel_mode(chip, PARALLEL_INPUT_MODE)
					== POWER_SUPPLY_PL_USBIN_USBIN) {
		main_icl = get_effective_result_locked(chip->usb_icl_votable);
		if ((main_icl >= 0) && (main_icl < target_icl))
			target_icl -= main_icl;
	}

	return target_icl;
}

/*
/*
 * Adapter CC Mode: ILIM over-ridden explicitly, below takes no effect.
 * Adapter CC Mode: ILIM over-ridden explicitly, below takes no effect.
 *
 *
@@ -212,7 +240,7 @@ static int cp_get_parallel_mode(struct pl_data *chip, int mode)
 */
 */
static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim)
static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim)
{
{
	int rc, fcc, main_icl, target_icl = chip->chg_param->hvdcp3_max_icl_ua;
	int rc, fcc, target_icl;
	union power_supply_propval pval = {0, };
	union power_supply_propval pval = {0, };


	if (!is_usb_available(chip))
	if (!is_usb_available(chip))
@@ -225,30 +253,8 @@ static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim)
					== POWER_SUPPLY_PL_OUTPUT_VPH)
					== POWER_SUPPLY_PL_OUTPUT_VPH)
		return;
		return;


	rc = power_supply_get_property(chip->usb_psy,
	target_icl = get_hvdcp3_icl_limit(chip);
				POWER_SUPPLY_PROP_REAL_TYPE, &pval);
	ilim = (target_icl > 0) ? min(ilim, target_icl) : ilim;
	if (rc < 0)
		return;

	/*
	 * For HVDCP3 adapters limit max. ILIM based on DT configuration
	 * of HVDCP3 ICL value.
	 * Input VBUS:
	 * target_icl = HVDCP3_ICL - main_ICL
	 * Input VMID
	 * target_icl = HVDCP3_ICL
	 */
	if (pval.intval == POWER_SUPPLY_TYPE_USB_HVDCP_3) {
		if (((cp_get_parallel_mode(chip, PARALLEL_INPUT_MODE))
					== POWER_SUPPLY_PL_USBIN_USBIN)) {
			main_icl = get_effective_result_locked(
							chip->usb_icl_votable);
			if ((main_icl >= 0) && (main_icl < target_icl))
				target_icl -= main_icl;
		}

		ilim = min(target_icl, ilim);
	}


	rc = power_supply_get_property(chip->cp_master_psy,
	rc = power_supply_get_property(chip->cp_master_psy,
				POWER_SUPPLY_PROP_MIN_ICL, &pval);
				POWER_SUPPLY_PROP_MIN_ICL, &pval);
@@ -671,14 +677,17 @@ static void get_main_fcc_config(struct pl_data *chip, int *total_fcc)
static void get_fcc_stepper_params(struct pl_data *chip, int main_fcc_ua,
static void get_fcc_stepper_params(struct pl_data *chip, int main_fcc_ua,
			int parallel_fcc_ua)
			int parallel_fcc_ua)
{
{
	int main_set_fcc_ua, total_fcc_ua;
	int main_set_fcc_ua, total_fcc_ua, target_icl;
	bool override;


	if (!chip->chg_param->fcc_step_size_ua) {
	if (!chip->chg_param->fcc_step_size_ua) {
		pr_err("Invalid fcc stepper step size, value 0\n");
		pr_err("Invalid fcc stepper step size, value 0\n");
		return;
		return;
	}
	}


	if (is_override_vote_enabled_locked(chip->fcc_main_votable)) {
	total_fcc_ua = main_fcc_ua + parallel_fcc_ua;
	override = is_override_vote_enabled_locked(chip->fcc_main_votable);
	if (override) {
		/*
		/*
		 * FCC stepper params need re-calculation in override mode
		 * FCC stepper params need re-calculation in override mode
		 * only if there is change in Main or total FCC
		 * only if there is change in Main or total FCC
@@ -686,48 +695,99 @@ static void get_fcc_stepper_params(struct pl_data *chip, int main_fcc_ua,


		main_set_fcc_ua = get_effective_result_locked(
		main_set_fcc_ua = get_effective_result_locked(
							chip->fcc_main_votable);
							chip->fcc_main_votable);
		total_fcc_ua = main_fcc_ua + parallel_fcc_ua;

		if ((main_set_fcc_ua != chip->override_main_fcc_ua)
		if ((main_set_fcc_ua != chip->override_main_fcc_ua)
				|| (total_fcc_ua != chip->total_fcc_ua)) {
				|| (total_fcc_ua != chip->total_fcc_ua)) {
			chip->override_main_fcc_ua = main_set_fcc_ua;
			chip->override_main_fcc_ua = main_set_fcc_ua;
			chip->total_fcc_ua = total_fcc_ua;
			chip->total_fcc_ua = total_fcc_ua;
			parallel_fcc_ua = (total_fcc_ua
						- chip->override_main_fcc_ua);
		} else {
		} else {
			goto skip_fcc_step_update;
			goto skip_fcc_step_update;
		}
		}
	}
	}


	/* Read current FCC of main charger */
	/*
	chip->main_fcc_ua = get_effective_result(chip->fcc_main_votable);
	 * If override vote is removed then start main FCC from the
	chip->main_step_fcc_dir = (main_fcc_ua > chip->main_fcc_ua) ?
	 * last overridden value.
				STEP_UP : STEP_DOWN;
	 * Clear slave_fcc if requested parallel current is 0 i.e.
	chip->main_step_fcc_count = abs((main_fcc_ua - chip->main_fcc_ua) /
	 * parallel is disabled.
				chip->chg_param->fcc_step_size_ua);
	 */
	chip->main_step_fcc_residual = abs((main_fcc_ua - chip->main_fcc_ua) %
	if (chip->override_main_fcc_ua && !override) {
				chip->chg_param->fcc_step_size_ua);
		chip->main_fcc_ua = chip->override_main_fcc_ua;
		chip->override_main_fcc_ua = 0;
		if (!parallel_fcc_ua)
			chip->slave_fcc_ua = 0;
	} else {
		chip->main_fcc_ua = get_effective_result_locked(
						chip->fcc_main_votable);
	}


	chip->parallel_step_fcc_dir = (parallel_fcc_ua > chip->slave_fcc_ua) ?
	/* Skip stepping if override vote is applied on main */
	if (override) {
		chip->main_step_fcc_count = 0;
		chip->main_step_fcc_residual = 0;
	} else {
		chip->main_step_fcc_dir =
				(main_fcc_ua > chip->main_fcc_ua) ?
					STEP_UP : STEP_DOWN;
					STEP_UP : STEP_DOWN;
	chip->parallel_step_fcc_count
		chip->main_step_fcc_count =
				= abs((parallel_fcc_ua - chip->slave_fcc_ua) /
				abs(main_fcc_ua - chip->main_fcc_ua) /
					chip->chg_param->fcc_step_size_ua);
					chip->chg_param->fcc_step_size_ua;
	chip->parallel_step_fcc_residual
		chip->main_step_fcc_residual =
				= abs((parallel_fcc_ua - chip->slave_fcc_ua) %
				abs(main_fcc_ua - chip->main_fcc_ua) %
					chip->chg_param->fcc_step_size_ua);
					chip->chg_param->fcc_step_size_ua;
	}

	 /* Calculate CP_ILIM based on adapter limit and max. FCC */
	if (!parallel_fcc_ua && is_cp_available(chip) && override) {
		if (!chip->cp_ilim_votable)
			chip->cp_ilim_votable = find_votable("CP_ILIM");

		target_icl = get_hvdcp3_icl_limit(chip) * 2;
		total_fcc_ua -= chip->main_fcc_ua;

		/*
		 * CP_ILIM = parallel_fcc_ua / 2.
		 * Calculate parallel_fcc_ua as follows:
		 * parallel_fcc_ua is based minimum of total FCC
		 * or adapter's maximum allowed ICL limitation(if adapter
		 * has max. ICL limitations).
		 */
		parallel_fcc_ua = (target_icl > 0) ?
				min(target_icl, total_fcc_ua) : total_fcc_ua;
	}


	/* Skip stepping if override vote is applied on CP */
	if (chip->cp_ilim_votable
		&& is_override_vote_enabled(chip->cp_ilim_votable)) {
		chip->parallel_step_fcc_count = 0;
		chip->parallel_step_fcc_residual = 0;
	} else {
		chip->parallel_step_fcc_dir =
				(parallel_fcc_ua > chip->slave_fcc_ua) ?
					STEP_UP : STEP_DOWN;
		chip->parallel_step_fcc_count =
				abs(parallel_fcc_ua - chip->slave_fcc_ua) /
					chip->chg_param->fcc_step_size_ua;
		chip->parallel_step_fcc_residual =
				abs(parallel_fcc_ua - chip->slave_fcc_ua) %
					chip->chg_param->fcc_step_size_ua;
	}
skip_fcc_step_update:
skip_fcc_step_update:
	if (chip->parallel_step_fcc_count || chip->parallel_step_fcc_residual
	if (chip->parallel_step_fcc_count || chip->parallel_step_fcc_residual
		|| chip->main_step_fcc_count || chip->main_step_fcc_residual)
		|| chip->main_step_fcc_count || chip->main_step_fcc_residual)
		chip->step_fcc = 1;
		chip->step_fcc = 1;


	pr_debug("Main FCC Stepper parameters: main_step_direction: %d, main_step_count: %d, main_residual_fcc: %d\n",
	pl_dbg(chip, PR_PARALLEL,
		chip->main_step_fcc_dir, chip->main_step_fcc_count,
		"Main FCC Stepper parameters: target_main_fcc: %d, current_main_fcc: %d main_step_direction: %d, main_step_count: %d, main_residual_fcc: %d override_main_fcc_ua: %d override: %d\n",
		chip->main_step_fcc_residual);
		main_fcc_ua, chip->main_fcc_ua, chip->main_step_fcc_dir,
	pr_debug("Parallel FCC Stepper parameters: parallel_step_direction: %d, parallel_step_count: %d, parallel_residual_fcc: %d\n",
		chip->main_step_fcc_count, chip->main_step_fcc_residual,
		chip->override_main_fcc_ua, override);
	pl_dbg(chip, PR_PARALLEL,
		"Parallel FCC Stepper parameters: target_pl_fcc: %d current_pl_fcc: %d parallel_step_direction: %d, parallel_step_count: %d, parallel_residual_fcc: %d\n",
		parallel_fcc_ua, chip->slave_fcc_ua,
		chip->parallel_step_fcc_dir, chip->parallel_step_fcc_count,
		chip->parallel_step_fcc_dir, chip->parallel_step_fcc_count,
		chip->parallel_step_fcc_residual);
		chip->parallel_step_fcc_residual);
	pl_dbg(chip, PR_PARALLEL, "FCC Stepper parameters: step_fcc=%d\n",
		chip->step_fcc);
}
}


#define MINIMUM_PARALLEL_FCC_UA		500000
#define MINIMUM_PARALLEL_FCC_UA		500000
@@ -853,7 +913,7 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data,
{
{
	struct pl_data *chip = data;
	struct pl_data *chip = data;
	int master_fcc_ua = total_fcc_ua, slave_fcc_ua = 0;
	int master_fcc_ua = total_fcc_ua, slave_fcc_ua = 0;
	int main_fcc_ua = 0, cp_fcc_ua = 0, fcc_thr_ua = 0, rc;
	int cp_fcc_ua = 0, fcc_thr_ua = 0, rc;
	union power_supply_propval pval = {0, };
	union power_supply_propval pval = {0, };
	bool is_cc_mode = false;
	bool is_cc_mode = false;


@@ -900,14 +960,14 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data,
							(4 * pval.intval);
							(4 * pval.intval);
	}
	}


	if (chip->fcc_main_votable)
	/*
		main_fcc_ua =
	 * CP charger current = Total FCC - Main charger's FCC.
			get_effective_result_locked(chip->fcc_main_votable);
	 * Main charger FCC is userspace's override vote on main.

	 */
	if (main_fcc_ua < 0)
	cp_fcc_ua = total_fcc_ua - chip->chg_param->forced_main_fcc;
		main_fcc_ua = 0;
	pl_dbg(chip, PR_PARALLEL,

		"cp_fcc_ua=%d total_fcc_ua=%d forced_main_fcc=%d\n",
	cp_fcc_ua = total_fcc_ua - main_fcc_ua;
		cp_fcc_ua, total_fcc_ua, chip->chg_param->forced_main_fcc);
	if (cp_fcc_ua > 0) {
	if (cp_fcc_ua > 0) {
		if (chip->cp_slave_psy && chip->cp_slave_disable_votable) {
		if (chip->cp_slave_psy && chip->cp_slave_disable_votable) {
			/*
			/*
@@ -1482,13 +1542,6 @@ static int pl_disable_vote_callback(struct votable *votable,
			if (chip->step_fcc) {
			if (chip->step_fcc) {
				vote(chip->pl_awake_votable, FCC_STEPPER_VOTER,
				vote(chip->pl_awake_votable, FCC_STEPPER_VOTER,
					true, 0);
					true, 0);
				/*
				 * Configure ILIM above min ILIM of CP to
				 * ensure CP is not disabled due to ILIM vote.
				 * Later FCC stepper will take to ILIM to
				 * target value.
				 */
				cp_configure_ilim(chip, FCC_VOTER, 0);
				schedule_delayed_work(&chip->fcc_stepper_work,
				schedule_delayed_work(&chip->fcc_stepper_work,
					0);
					0);
			}
			}
@@ -1781,6 +1834,10 @@ static void handle_usb_change(struct pl_data *chip)
		vote(chip->pl_disable_votable, PL_TAPER_EARLY_BAD_VOTER,
		vote(chip->pl_disable_votable, PL_TAPER_EARLY_BAD_VOTER,
				false, 0);
				false, 0);
		vote(chip->pl_disable_votable, ICL_LIMIT_VOTER, false, 0);
		vote(chip->pl_disable_votable, ICL_LIMIT_VOTER, false, 0);
		chip->override_main_fcc_ua = 0;
		chip->total_fcc_ua = 0;
		chip->slave_fcc_ua = 0;
		chip->main_fcc_ua = 0;
	}
	}
}
}


+1 −0
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ struct charger_param {
	u32 fcc_step_size_ua;
	u32 fcc_step_size_ua;
	u32 smb_version;
	u32 smb_version;
	u32 hvdcp3_max_icl_ua;
	u32 hvdcp3_max_icl_ua;
	u32 forced_main_fcc;
};
};


int qcom_batt_init(struct charger_param *param);
int qcom_batt_init(struct charger_param *param);
+3 −0
Original line number Original line Diff line number Diff line
@@ -1310,6 +1310,9 @@ static int smb5_usb_main_set_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_FORCE_MAIN_FCC:
	case POWER_SUPPLY_PROP_FORCE_MAIN_FCC:
		vote_override(chg->fcc_main_votable, CC_MODE_VOTER,
		vote_override(chg->fcc_main_votable, CC_MODE_VOTER,
				(val->intval < 0) ? false : true, val->intval);
				(val->intval < 0) ? false : true, val->intval);
		if (val->intval >= 0)
			chg->chg_param.forced_main_fcc = val->intval;

		/* Main FCC updated re-calculate FCC */
		/* Main FCC updated re-calculate FCC */
		rerun_election(chg->fcc_votable);
		rerun_election(chg->fcc_votable);
		break;
		break;
+2 −0
Original line number Original line Diff line number Diff line
@@ -1188,6 +1188,7 @@ static void smblib_uusb_removal(struct smb_charger *chg)
	chg->usb_icl_delta_ua = 0;
	chg->usb_icl_delta_ua = 0;
	chg->pulse_cnt = 0;
	chg->pulse_cnt = 0;
	chg->uusb_apsd_rerun_done = false;
	chg->uusb_apsd_rerun_done = false;
	chg->chg_param.forced_main_fcc = 0;


	/* write back the default FLOAT charger configuration */
	/* write back the default FLOAT charger configuration */
	rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
	rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
@@ -5723,6 +5724,7 @@ static void typec_src_removal(struct smb_charger *chg)
	chg->voltage_min_uv = MICRO_5V;
	chg->voltage_min_uv = MICRO_5V;
	chg->voltage_max_uv = MICRO_5V;
	chg->voltage_max_uv = MICRO_5V;
	chg->usbin_forced_max_uv = 0;
	chg->usbin_forced_max_uv = 0;
	chg->chg_param.forced_main_fcc = 0;


	/* Reset CC mode votes */
	/* Reset CC mode votes */
	vote(chg->fcc_main_votable, MAIN_FCC_VOTER, false, 0);
	vote(chg->fcc_main_votable, MAIN_FCC_VOTER, false, 0);