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

Commit f4a7b2e5 authored by Harry Yang's avatar Harry Yang
Browse files

power: smb5-lib: Fix QC charger detecion on cold boot



QC chargers are mis-detected as DCP on cold boot. This is caused by
HVDCP_EN_BIT being flipped on and off in early probe, which
interrupts further QC detection after DCP is discovered by APSD.

Fix it by not enabling it by default.

Change-Id: Id424c8477243b52678f782a7b52dc7d405f75167
Signed-off-by: default avatarHarry Yang <harryy@codeaurora.org>
parent 3d91e789
Loading
Loading
Loading
Loading
+6 −19
Original line number Diff line number Diff line
@@ -1822,7 +1822,6 @@ static int smb5_configure_typec(struct smb_charger *chg)
	}

	smblib_apsd_enable(chg, true);
	smblib_hvdcp_detect_enable(chg, false);

	rc = smblib_masked_write(chg, TYPE_C_CFG_REG,
				BC1P2_START_ON_CC_BIT, 0);
@@ -2340,24 +2339,12 @@ static int smb5_init_hw(struct smb5 *chip)
		}
	}

	/*
	 * Disable HVDCP autonomous mode operation by default, providing a DT
	 * knob to turn it on if required. Additionally, if specified in DT,
	 * disable HVDCP and HVDCP authentication algorithm.
	 */
	val = (chg->hvdcp_disable) ? 0 :
		(HVDCP_AUTH_ALG_EN_CFG_BIT | HVDCP_EN_BIT);
	if (chip->dt.hvdcp_autonomous)
		val |= HVDCP_AUTONOMOUS_MODE_EN_CFG_BIT;

	rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG,
			(HVDCP_AUTH_ALG_EN_CFG_BIT | HVDCP_EN_BIT |
			 HVDCP_AUTONOMOUS_MODE_EN_CFG_BIT),
			val);
	if (rc < 0) {
		dev_err(chg->dev, "Couldn't configure HVDCP rc=%d\n", rc);
		return rc;
	}
	/* Set HVDCP autonomous mode per DT option */
	smblib_hvdcp_hw_inov_enable(chg, chip->dt.hvdcp_autonomous);

	/* Disable HVDCP and authentication algorithm if specified in DT */
	if (chg->hvdcp_disable)
		smblib_hvdcp_detect_enable(chg, false);

	rc = smb5_init_connector_type(chg);
	if (rc < 0) {
+21 −7
Original line number Diff line number Diff line
@@ -904,17 +904,31 @@ void smblib_hvdcp_detect_enable(struct smb_charger *chg, bool enable)
	int rc;
	u8 mask;

	if (chg->hvdcp_disable || chg->pd_not_supported)
		return;

	mask = HVDCP_AUTH_ALG_EN_CFG_BIT | HVDCP_EN_BIT;
	rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, mask,
						enable ? mask : 0);
	if (rc < 0)
		smblib_err(chg, "failed to write USBIN_OPTIONS_1_CFG rc=%d\n",
				rc);
}

static void smblib_hvdcp_detect_try_enable(struct smb_charger *chg, bool enable)
{
	if (chg->hvdcp_disable || chg->pd_not_supported)
		return;
	smblib_hvdcp_detect_enable(chg, enable);
}

void smblib_hvdcp_hw_inov_enable(struct smb_charger *chg, bool enable)
{
	int rc;

	rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG,
				HVDCP_AUTONOMOUS_MODE_EN_CFG_BIT,
				enable ? HVDCP_AUTONOMOUS_MODE_EN_CFG_BIT : 0);
	if (rc < 0)
		smblib_err(chg, "failed to write USBIN_OPTIONS_1_CFG rc=%d\n",
				rc);
}

void smblib_hvdcp_exit_config(struct smb_charger *chg)
@@ -3992,7 +4006,7 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,
		/* PD hard resets failed, proceed to detect QC2/3 */
		if (chg->ok_to_pd) {
			chg->ok_to_pd = false;
			smblib_hvdcp_detect_enable(chg, true);
			smblib_hvdcp_detect_try_enable(chg, true);
		}
	}

@@ -5123,7 +5137,7 @@ static void typec_src_insertion(struct smb_charger *chg)

	/* allow apsd proceed to detect QC2/3 */
	if (!chg->ok_to_pd)
		smblib_hvdcp_detect_enable(chg, true);
		smblib_hvdcp_detect_try_enable(chg, true);
}

static void typec_sink_removal(struct smb_charger *chg)
@@ -5160,7 +5174,7 @@ static void typec_src_removal(struct smb_charger *chg)
			"Couldn't disable secondary charger rc=%d\n", rc);

	typec_src_fault_condition_cfg(chg, false);
	smblib_hvdcp_detect_enable(chg, false);
	smblib_hvdcp_detect_try_enable(chg, false);
	smblib_update_usb_type(chg);

	if (chg->wa_flags & BOOST_BACK_WA) {
+1 −0
Original line number Diff line number Diff line
@@ -719,6 +719,7 @@ enum alarmtimer_restart smblib_lpd_recheck_timer(struct alarm *alarm,
				ktime_t time);
int smblib_toggle_smb_en(struct smb_charger *chg, int toggle);
void smblib_hvdcp_detect_enable(struct smb_charger *chg, bool enable);
void smblib_hvdcp_hw_inov_enable(struct smb_charger *chg, bool enable);
void smblib_hvdcp_exit_config(struct smb_charger *chg);
void smblib_apsd_enable(struct smb_charger *chg, bool enable);
int smblib_force_vbus_voltage(struct smb_charger *chg, u8 val);