summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@google.com>2016-12-02 11:42:11 +0800
committerchrome-bot <chrome-bot@chromium.org>2016-12-14 06:02:54 -0800
commit87e8cd610313fa7fe902c2fd359ade18e6b22ef0 (patch)
tree8c9468648b1347e6c411f9bc3f15008d5a11e6ea
parenta573d17be93b52e6b3cb0ab7bf374199091752f4 (diff)
downloadchrome-ec-87e8cd610313fa7fe902c2fd359ade18e6b22ef0.tar.gz
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>
-rw-r--r--common/usb_pd_policy.c7
-rw-r--r--common/usb_pd_protocol.c12
-rw-r--r--include/usb_pd.h8
3 files changed, 26 insertions, 1 deletions
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
@@ -1515,6 +1515,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
*
* @param port USB-C port number