usb: typec: tcpm: fix dp altmode negotiation failure

Do DR_SWAP (UFP/Sink swap to DFP/Sink) when received VDM DiscIdentity
NAK or terminated in VDM DiscModes to fix altmode negotiation failure.

This can fix a few odd DP monitor (DFP/Source) can not start DR_SWAP
to UFP/Source role at DP altmode negotiation stage.

Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
Signed-off-by: Zhang Yubing <yubing.zhang@rock-chips.com>
Change-Id: Ieae9489c068064a20e04151f322ac82a71a72aa4
This commit is contained in:
Frank Wang
2023-07-10 15:52:00 +08:00
committed by Tao Huang
parent b181d44259
commit 48a7374baa

View File

@@ -1724,6 +1724,14 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev,
rlen = 1;
} else if (port->data_role == TYPEC_HOST) {
tcpm_register_partner_altmodes(port);
} else {
/* Do dr_swap for ufp if the port supports drd */
if (port->typec_caps.data == TYPEC_PORT_DRD &&
!IS_ERR_OR_NULL(port->port_altmode[0])) {
port->vdm_sm_running = false;
port->upcoming_state = DR_SWAP_SEND;
tcpm_ams_start(port, DATA_ROLE_SWAP);
}
}
break;
case CMD_ENTER_MODE:
@@ -1755,6 +1763,16 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev,
tcpm_ams_finish(port);
switch (cmd) {
case CMD_DISCOVER_IDENT:
/* Do dr_swap for ufp if the port supports drd */
if (port->typec_caps.data == TYPEC_PORT_DRD &&
port->data_role == TYPEC_DEVICE &&
!IS_ERR_OR_NULL(port->port_altmode[0])) {
port->vdm_sm_running = false;
port->upcoming_state = DR_SWAP_SEND;
tcpm_ams_start(port, DATA_ROLE_SWAP);
break;
}
fallthrough;
case CMD_DISCOVER_SVID:
case CMD_DISCOVER_MODES:
case VDO_CMD_VENDOR(0) ... VDO_CMD_VENDOR(15):