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

Commit 563b7853 authored by Harry Yang's avatar Harry Yang
Browse files

power: smb5-lib: Fix floating cable IRQ storms



A Type-C cable attached to a device with the other end floating
triggers Water detection IRQ storms.

If no moisture is detected, simply disable TYPEC_WATER_DETECTION_INT_EN,
and wait 60s to re-enable it.

Change-Id: I512d197a2542a9c8dca889ac6c1fcc7143e64a86
Signed-off-by: default avatarHarry Yang <harryy@codeaurora.org>
parent 63066f2d
Loading
Loading
Loading
Loading
+43 −17
Original line number Diff line number Diff line
@@ -3672,6 +3672,7 @@ enum alarmtimer_restart smblib_lpd_recheck_timer(struct alarm *alarm,
							lpd_recheck_timer);
	int rc;

	if (chg->lpd_reason == LPD_MOISTURE_DETECTED) {
		pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL;
		rc = smblib_set_prop_typec_power_role(chg, &pval);
		if (rc < 0) {
@@ -3679,8 +3680,19 @@ enum alarmtimer_restart smblib_lpd_recheck_timer(struct alarm *alarm,
				pval.intval, rc);
			return ALARMTIMER_NORESTART;
		}
	} else {
		rc = smblib_masked_write(chg, TYPE_C_INTERRUPT_EN_CFG_2_REG,
					TYPEC_WATER_DETECTION_INT_EN_BIT,
					TYPEC_WATER_DETECTION_INT_EN_BIT);
		if (rc < 0) {
			smblib_err(chg, "Couldn't set TYPE_C_INTERRUPT_EN_CFG_2_REG rc=%d\n",
					rc);
			return ALARMTIMER_NORESTART;
		}
	}

	chg->lpd_stage = LPD_STAGE_NONE;
	chg->lpd_reason = LPD_NONE;

	return ALARMTIMER_NORESTART;
}
@@ -3719,9 +3731,11 @@ static bool smblib_src_lpd(struct smb_charger *chg)
		if (rc < 0)
			smblib_err(chg, "Couldn't write 0x%02x to TYPE_C_INTRPT_ENB_SOFTWARE_CTRL rc=%d\n",
				pval.intval, rc);
		chg->lpd_reason = LPD_MOISTURE_DETECTED;
		alarm_start_relative(&chg->lpd_recheck_timer,
						ms_to_ktime(60000));
	} else {
		chg->lpd_reason = LPD_NONE;
		chg->typec_mode = smblib_get_prop_typec_mode(chg);
	}

@@ -4559,17 +4573,26 @@ static void smblib_lpd_ra_open_work(struct work_struct *work)
	/* Emark cable */
	if ((stat & SRC_RA_OPEN_BIT) &&
			!smblib_rsbux_low(chg, RSBU_K_300K_UV)) {
		/* Floating cable, disable water detection irq temporarily */
		rc = smblib_masked_write(chg, TYPE_C_INTERRUPT_EN_CFG_2_REG,
					TYPEC_WATER_DETECTION_INT_EN_BIT, 0);
		if (rc < 0) {
			smblib_err(chg, "Couldn't set TYPE_C_INTERRUPT_EN_CFG_2_REG rc=%d\n",
					rc);
			goto out;
		}

		/* restore DRP mode */
		pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL;
		rc = smblib_set_prop_typec_power_role(chg, &pval);
		if (rc < 0)
		if (rc < 0) {
			smblib_err(chg, "Couldn't write 0x%02x to TYPE_C_INTRPT_ENB_SOFTWARE_CTRL rc=%d\n",
				pval.intval, rc);

		chg->lpd_stage = LPD_STAGE_NONE;
			goto out;
		}

		chg->lpd_reason = LPD_FLOATING_CABLE;
	} else {
		/* Moisture detected, enable sink only mode */
		pval.intval = POWER_SUPPLY_TYPEC_PR_SINK;
		rc = smblib_set_prop_typec_power_role(chg, &pval);
@@ -4579,6 +4602,9 @@ static void smblib_lpd_ra_open_work(struct work_struct *work)
			goto out;
		}

		chg->lpd_reason = LPD_MOISTURE_DETECTED;
	}

	/* recheck in 60 seconds */
	alarm_start_relative(&chg->lpd_recheck_timer, ms_to_ktime(60000));
out:
+7 −0
Original line number Diff line number Diff line
@@ -197,6 +197,12 @@ static const unsigned int smblib_extcon_cable[] = {
	EXTCON_NONE,
};

enum lpd_reason {
	LPD_NONE,
	LPD_MOISTURE_DETECTED,
	LPD_FLOATING_CABLE,
};

enum lpd_stage {
	LPD_STAGE_NONE,
	LPD_STAGE_FLOAT,
@@ -392,6 +398,7 @@ struct smb_charger {
	int			smb_temp_max;
	u8			typec_try_mode;
	enum lpd_stage		lpd_stage;
	enum lpd_reason		lpd_reason;

	/* workaround flag */
	u32			wa_flags;