usb_pd_policy: Automatically swap vconn if adapter requests it

During discovery, if adapter requests vconn power in the AMA flags,
make sure that we provide vconn.

This, for example, is necessary for the Apple HDMI adapter to work
on boot, when connected in S5. In that case, adapter does request
vconn swap, but we reject that as the system is off, and, therefore
5V supply is off. On boot, we send another discovery request, which
will detect this case and swap the power.

BRANCH=none
BUG=chromium:644663
TEST=On elm, S5. Plug adapter with power+HDMI. Switch on elm,
     type "pd 0 vdm ident" in console, display works.

Change-Id: I55b6658c2bc0574b8427ae086f61daf03730a725
Reviewed-on: https://chromium-review.googlesource.com/415697
Commit-Ready: Nicolas Boichat <drinkcat@chromium.org>
Tested-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
Nicolas Boichat
2016-12-02 11:42:11 +08:00
committed by chrome-bot
parent a573d17be9
commit 87e8cd6103
3 changed files with 26 additions and 1 deletions

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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
*