diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c index 9c42f5f5a3..fe204b9301 100644 --- a/common/usb_pd_policy.c +++ b/common/usb_pd_policy.c @@ -271,8 +271,13 @@ static void dfp_consume_identity(int port, int cnt, uint32_t *payload) */ if (!PD_VDO_AMA_VBUS_REQ(payload[VDO_I(AMA)])) pd_power_supply_reset(port); + +#if defined(CONFIG_USB_PD_DUAL_ROLE) && defined(CONFIG_USBC_VCONN_SWAP) + /* Adapter is requesting vconn, try to supply it */ + if (PD_VDO_AMA_VCONN_REQ(payload[VDO_I(AMA)])) + pd_try_vconn_src(port); +#endif break; - /* TODO(crosbug.com/p/30645) provide vconn support here */ default: break; } diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 1e9c4192ae..1055ed61c7 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -844,6 +844,18 @@ static void pd_request_vconn_swap(int port) set_state(port, PD_STATE_VCONN_SWAP_SEND); task_wake(PD_PORT_TO_TASK_ID(port)); } + +void pd_try_vconn_src(int port) +{ + /* + * If we don't currently provide vconn, and we can supply it, send + * a vconn swap request. + */ + if (!(pd[port].flags & PD_FLAGS_VCONN_ON)) { + if (pd_check_vconn_swap(port)) + pd_request_vconn_swap(port); + } +} #endif #endif /* CONFIG_USB_PD_DUAL_ROLE */ diff --git a/include/usb_pd.h b/include/usb_pd.h index e322fed381..4eef319ae2 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -1514,6 +1514,14 @@ int pd_get_partner_data_swap_capable(int port); */ void pd_request_power_swap(int port); +/** + * Try to become the VCONN source, if we are not already the source and the + * other side is willing to accept a VCONN swap. + * + * @param port USB-C port number + */ +void pd_try_vconn_src(int port); + /** * Request data swap command to be issued *