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

Commit 437db308 authored by Nicholas Troast's avatar Nicholas Troast
Browse files

power: smb-lib: always assume legacy cable and limit ICL



While in DRP the legacy cable detection may fail. When a legacy cable is
detected the legacy input current limits are enforced by hardware.

Always assume a legacy cable since the legacy cable detection will
fail in some cases. Manually enforce the legacy input current limits to
ensure USB stability and compliance. As a side effect, non-legacy 22k
ohm and 10k ohm Rp adapters will be current limited to legacy standards.

To realize this:
- Set a limit of 100mA as soon as type-c is connected and remove that
  limit once PD is confirmed.
- If PD is not confirmed:
  - SDP:   Use 100mA vote until USB PHY updates it to 500/900mA
  - CDP:   Use 1.5A vote
  - DCP:   Use 1.5A vote
  - HVDCP: Use 3A vote

Change-Id: I049a7ee2099acd9e58df1b9417847daec4854af5
Signed-off-by: default avatarNicholas Troast <ntroast@codeaurora.org>
parent 11a54fcf
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
@@ -2505,6 +2505,9 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,
			return rc;
		}

		/* since PD was found the cable must be non-legacy */
		vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, false, 0);

		/* clear USB ICL vote for DCP_VOTER */
		rc = vote(chg->usb_icl_votable, DCP_VOTER, false, 0);
		if (rc < 0)
@@ -3337,6 +3340,37 @@ static void smblib_handle_hvdcp_detect_done(struct smb_charger *chg,
		   rising ? "rising" : "falling");
}

static void smblib_force_legacy_icl(struct smb_charger *chg, int pst)
{
	switch (pst) {
	case POWER_SUPPLY_TYPE_USB:
		/*
		 * USB_PSY will vote to increase the current to 500/900mA once
		 * enumeration is done. Ensure that USB_PSY has at least voted
		 * for 100mA before releasing the LEGACY_UNKNOWN vote
		 */
		if (!is_client_vote_enabled(chg->usb_icl_votable,
								USB_PSY_VOTER))
			vote(chg->usb_icl_votable, USB_PSY_VOTER, true, 100000);
		vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, false, 0);
		break;
	case POWER_SUPPLY_TYPE_USB_CDP:
		vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, true, 1500000);
		break;
	case POWER_SUPPLY_TYPE_USB_DCP:
		vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, true, 1500000);
		break;
	case POWER_SUPPLY_TYPE_USB_HVDCP:
	case POWER_SUPPLY_TYPE_USB_HVDCP_3:
		vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, true, 3000000);
		break;
	default:
		smblib_err(chg, "Unknown APSD %d; forcing 500mA\n", pst);
		vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, true, 500000);
		break;
	}
}

#define HVDCP_DET_MS 2500
static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising)
{
@@ -3346,6 +3380,10 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising)
		return;

	apsd_result = smblib_update_usb_type(chg);

	if (!chg->pd_active)
		smblib_force_legacy_icl(chg, apsd_result->pst);

	switch (apsd_result->bit) {
	case SDP_CHARGER_BIT:
	case CDP_CHARGER_BIT:
@@ -3426,6 +3464,9 @@ static void typec_source_removal(struct smb_charger *chg)
{
	int rc;

	/* reset legacy unknown vote */
	vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, false, 0);

	/* 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);
@@ -3479,6 +3520,15 @@ static void typec_source_removal(struct smb_charger *chg)

static void typec_source_insertion(struct smb_charger *chg)
{
	/*
	 * at any time we want LEGACY_UNKNOWN, PD, or USB_PSY to be voting for
	 * ICL, so vote LEGACY_UNKNOWN here if none of the above three have
	 * casted their votes
	 */
	if (!is_client_vote_enabled(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER)
		&& !is_client_vote_enabled(chg->usb_icl_votable, PD_VOTER)
		&& !is_client_vote_enabled(chg->usb_icl_votable, USB_PSY_VOTER))
		vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, true, 100000);
}

static void typec_sink_insertion(struct smb_charger *chg)
+1 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ enum print_reason {
#define CTM_VOTER			"CTM_VOTER"
#define SW_QC3_VOTER			"SW_QC3_VOTER"
#define AICL_RERUN_VOTER		"AICL_RERUN_VOTER"
#define LEGACY_UNKNOWN_VOTER		"LEGACY_UNKNOWN_VOTER"

#define VCONN_MAX_ATTEMPTS	3
#define OTG_MAX_ATTEMPTS	3