usb: typec: husb311: fix non-standard cable that cc double pull-up

For the non-standard cables that double Rp connected to VBUS, when
husb311 detects one of CC is Rp, let do clear the another CC status
in anyway to dodge being stuck in the SNK_ATTACH_WAIT state.

[   59.366185] VBUS on
[   59.403488] CC1: 0 -> 3, CC2: 0 -> 3 [state TOGGLING, polarity 0, connected]

Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
Change-Id: Ief2f01c97d1a7be81bca7dd26ecd975d35ea9877
This commit is contained in:
Frank Wang
2024-04-17 16:26:40 +08:00
committed by Tao Huang
parent 2e7e4970dc
commit f549f20ac4

View File

@@ -172,6 +172,39 @@ done:
static irqreturn_t husb311_irq(int irq, void *dev_id)
{
struct husb311_chip *chip = dev_id;
enum typec_cc_status cc1, cc2;
u8 reg, role_ctrl;
u8 status;
husb311_read8(chip, TCPC_ALERT, &status);
dev_dbg(chip->dev, "status 0x%02x", status);
/*
* If husb311 detects one of CC is Rp, let do clear the another CC
* status in anyway to dodge the non-standard cables that double Rp
* connected to VBUS which produced by Huawei and etc.
*/
if (status & TCPC_ALERT_CC_STATUS) {
husb311_read8(chip, TCPC_ROLE_CTRL, &role_ctrl);
husb311_read8(chip, TCPC_CC_STATUS, &reg);
cc1 = tcpci_to_typec_cc((reg >> TCPC_CC_STATUS_CC1_SHIFT) &
TCPC_CC_STATUS_CC1_MASK,
reg & TCPC_CC_STATUS_TERM ||
tcpc_presenting_rd(role_ctrl, CC1));
cc2 = tcpci_to_typec_cc((reg >> TCPC_CC_STATUS_CC2_SHIFT) &
TCPC_CC_STATUS_CC2_MASK,
reg & TCPC_CC_STATUS_TERM ||
tcpc_presenting_rd(role_ctrl, CC2));
dev_dbg(chip->dev, "CC1 %u, CC2 %u", cc1, cc2);
if (cc1 == TYPEC_CC_RP_DEF) {
role_ctrl |= TCPC_ROLE_CTRL_CC_OPEN << TCPC_ROLE_CTRL_CC2_SHIFT;
husb311_write8(chip, TCPC_ROLE_CTRL, role_ctrl);
} else if (cc2 == TYPEC_CC_RP_DEF) {
role_ctrl |= TCPC_ROLE_CTRL_CC_OPEN << TCPC_ROLE_CTRL_CC1_SHIFT;
husb311_write8(chip, TCPC_ROLE_CTRL, role_ctrl);
}
}
return tcpci_irq(chip->tcpci);
}