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

Commit e697192c authored by Ashay Jaiswal's avatar Ashay Jaiswal Committed by Gerrit - the friendly Code Review server
Browse files

qpnp: smb2: fix ICL recovery mechanism



ICL recovery mechanism is used by user space daemon
to recover from adapter collapse during voltage increment
event by reducing the USB ICL. There could be a situation
where nobody votes on usb_icl_votable and this could lead
to a negative ICL value.
Fix this by reading "HW_CURRENT_MAX" property to get ICL in
situations where usb_icl_votable is not voted by any client,
this ensures ICL reduction will always vote a valid ICL.

CRs-Fixed: 2048330
Change-Id: I8e53a945530c1685aaaba0537d16ac5fb11858df
Signed-off-by: default avatarAshay Jaiswal <ashayj@codeaurora.org>
parent 60be7160
Loading
Loading
Loading
Loading
+30 −2
Original line number Diff line number Diff line
@@ -638,6 +638,7 @@ static void smblib_uusb_removal(struct smb_charger *chg)
	/* reset both usbin current and voltage votes */
	vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, false, 0);
	vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0);
	vote(chg->usb_icl_votable, SW_QC3_VOTER, false, 0);

	cancel_delayed_work_sync(&chg->hvdcp_detect_work);

@@ -1985,6 +1986,7 @@ static int smblib_dm_pulse(struct smb_charger *chg)
int smblib_dp_dm(struct smb_charger *chg, int val)
{
	int target_icl_ua, rc = 0;
	union power_supply_propval pval;

	switch (val) {
	case POWER_SUPPLY_DP_DM_DP_PULSE:
@@ -2002,10 +2004,35 @@ int smblib_dp_dm(struct smb_charger *chg, int val)
				rc, chg->pulse_cnt);
		break;
	case POWER_SUPPLY_DP_DM_ICL_DOWN:
		chg->usb_icl_delta_ua -= 100000;
		target_icl_ua = get_effective_result(chg->usb_icl_votable);
		if (target_icl_ua < 0) {
			/* no client vote, get the ICL from charger */
			rc = power_supply_get_property(chg->usb_psy,
					POWER_SUPPLY_PROP_HW_CURRENT_MAX,
					&pval);
			if (rc < 0) {
				smblib_err(chg,
					"Couldn't get max current rc=%d\n",
					rc);
				return rc;
			}
			target_icl_ua = pval.intval;
		}

		/*
		 * Check if any other voter voted on USB_ICL in case of
		 * voter other than SW_QC3_VOTER reset and restart reduction
		 * again.
		 */
		if (target_icl_ua != get_client_vote(chg->usb_icl_votable,
							SW_QC3_VOTER))
			chg->usb_icl_delta_ua = 0;

		chg->usb_icl_delta_ua += 100000;
		vote(chg->usb_icl_votable, SW_QC3_VOTER, true,
				target_icl_ua + chg->usb_icl_delta_ua);
						target_icl_ua - 100000);
		smblib_dbg(chg, PR_PARALLEL, "ICL DOWN ICL=%d reduction=%d\n",
				target_icl_ua, chg->usb_icl_delta_ua);
		break;
	case POWER_SUPPLY_DP_DM_ICL_UP:
	default:
@@ -3620,6 +3647,7 @@ static void smblib_handle_typec_removal(struct smb_charger *chg)
	vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0);
	vote(chg->usb_icl_votable, DCP_VOTER, false, 0);
	vote(chg->usb_icl_votable, PL_USBIN_USBIN_VOTER, false, 0);
	vote(chg->usb_icl_votable, SW_QC3_VOTER, false, 0);

	/* reset hvdcp voters */
	vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0);