summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/usb_pd_protocol.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 1de3a4a696..79f66aa57b 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -2054,6 +2054,22 @@ void pd_set_dual_role(int port, enum pd_dual_role_states state)
PD_EVENT_UPDATE_DUAL_ROLE, 0);
}
+static void exit_dp_mode(int port)
+{
+#ifdef CONFIG_USB_PD_ALT_MODE_DFP
+ int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT);
+ if (opos <= 0)
+ return;
+ CPRINTS("C%d Exiting DP mode", port);
+ if (!pd_dfp_exit_mode(port, USB_SID_DISPLAYPORT, opos))
+ return;
+ pd_send_vdm(port, USB_SID_DISPLAYPORT,
+ CMD_EXIT_MODE | VDO_OPOS(opos), NULL, 0);
+ pd_vdm_send_state_machine(port);
+ /* Have to wait for ACK */
+#endif
+}
+
void pd_update_dual_role_config(int port)
{
/*
@@ -2508,6 +2524,8 @@ void pd_task(void *u)
#endif
#ifdef CONFIG_USB_PD_DUAL_ROLE
+ if (evt & PD_EVENT_DP_DISCONNECT)
+ exit_dp_mode(port);
if (evt & PD_EVENT_UPDATE_DUAL_ROLE)
pd_update_dual_role_config(port);
#endif
@@ -3873,8 +3891,11 @@ static void pd_chipset_shutdown(void)
{
int i;
- for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++)
+ for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++) {
+ task_set_event(PD_PORT_TO_TASK_ID(i),
+ PD_EVENT_DP_DISCONNECT, 0);
pd_set_dual_role(i, PD_DRP_FORCE_SINK);
+ }
CPRINTS("PD:S3->S5");
}
DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, pd_chipset_shutdown, HOOK_PRIO_DEFAULT);