summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/usbc/usb_pd_host.c5
-rw-r--r--common/usbc/usb_pe_drp_sm.c53
-rw-r--r--include/usb_pd.h14
-rw-r--r--test/usb_pe.h1
-rw-r--r--test/usb_pe_drp_old.c9
5 files changed, 67 insertions, 15 deletions
diff --git a/common/usbc/usb_pd_host.c b/common/usbc/usb_pd_host.c
index 7fa49874dc..c72e16afe9 100644
--- a/common/usbc/usb_pd_host.c
+++ b/common/usbc/usb_pd_host.c
@@ -165,8 +165,9 @@ static enum ec_status hc_typec_status(struct host_cmd_handler_args *args)
memcpy(r->source_cap_pdos, pd_get_src_caps(p->port),
r->source_cap_count * sizeof(uint32_t));
- /* TODO(b/160009733): Populate sink cap PDOs */
- r->sink_cap_count = 0;
+ r->sink_cap_count = pd_get_snk_cap_cnt(p->port);
+ memcpy(r->sink_cap_pdos, pd_get_snk_caps(p->port),
+ r->sink_cap_count * sizeof(uint32_t));
return EC_RES_SUCCESS;
}
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index c893f225db..86563efc59 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -749,6 +749,10 @@ static struct policy_engine {
uint32_t src_caps[PDO_MAX_OBJECTS];
int src_cap_cnt;
+ /* Last received sink cap */
+ uint32_t snk_caps[PDO_MAX_OBJECTS];
+ int snk_cap_cnt;
+
/* Attached ChromeOS device id, RW hash, and current RO / RW image */
uint16_t dev_id;
uint32_t dev_rw_hash[PD_RW_HASH_SIZE/4];
@@ -1028,6 +1032,23 @@ uint32_t pd_get_events(int port)
return pe[port].events;
}
+void pe_set_snk_caps(int port, int cnt, uint32_t *snk_caps)
+{
+ pe[port].snk_cap_cnt = cnt;
+
+ memcpy(pe[port].snk_caps, snk_caps, sizeof(uint32_t) * cnt);
+}
+
+const uint32_t * const pd_get_snk_caps(int port)
+{
+ return pe[port].snk_caps;
+}
+
+uint8_t pd_get_snk_cap_cnt(int port)
+{
+ return pe[port].snk_cap_cnt;
+}
+
/*
* Determine if this port may communicate with the cable plug.
*
@@ -1249,9 +1270,10 @@ static void pe_handle_detach(void)
pe_invalidate_explicit_contract(port);
/*
- * Saved SRC_Capabilities are no longer valid on disconnect
+ * Saved Source and Sink Capabilities are no longer valid on disconnect
*/
pd_set_src_caps(port, 0, NULL);
+ pe_set_snk_caps(port, 0, NULL);
}
DECLARE_HOOK(HOOK_USB_PD_DISCONNECT, pe_handle_detach, HOOK_PRIO_DEFAULT);
@@ -2681,6 +2703,12 @@ static void pe_snk_startup_entry(int port)
*/
PE_SET_FLAG(port, PE_FLAGS_DR_SWAP_TO_DFP);
PE_SET_FLAG(port, PE_FLAGS_VCONN_SWAP_TO_ON);
+
+ /*
+ * Set up to get Device Policy Manager to
+ * request Sink Capabilities
+ */
+ pd_dpm_request(port, DPM_REQUEST_GET_SNK_CAPS);
}
}
@@ -2873,11 +2901,6 @@ static void pe_snk_select_capability_run(int port)
set_state_pe(port, PE_SNK_TRANSITION_SINK);
- /*
- * Setup to get Device Policy Manager to
- * request Sink Capabilities for possible FRS
- */
- pd_dpm_request(port, DPM_REQUEST_GET_SNK_CAPS);
return;
}
/*
@@ -6121,8 +6144,12 @@ static void pe_dr_get_sink_cap_run(int port)
if (ext == 0 && sop == TCPC_TX_SOP) {
if ((cnt > 0) && (type == PD_DATA_SINK_CAP)) {
- uint32_t payload =
- *(uint32_t *)rx_emsg[port].buf;
+ uint32_t *payload =
+ (uint32_t *)rx_emsg[port].buf;
+ uint8_t cap_cnt = rx_emsg[port].len /
+ sizeof(uint32_t);
+
+ pe_set_snk_caps(port, cap_cnt, payload);
/*
* Check message to see if we can handle
@@ -6136,8 +6163,8 @@ static void pe_dr_get_sink_cap_run(int port)
*/
if (IS_ENABLED(CONFIG_USB_PD_REV30) &&
(rev > PD_REV20) &&
- (payload & PDO_FIXED_DUAL_ROLE)) {
- switch (payload &
+ (payload[0] & PDO_FIXED_DUAL_ROLE)) {
+ switch (payload[0] &
PDO_FIXED_FRS_CURR_MASK) {
case PDO_FIXED_FRS_CURR_NOT_SUPPORTED:
break;
@@ -6300,7 +6327,6 @@ uint8_t pd_get_src_cap_cnt(int port)
return pe[port].src_cap_cnt;
}
-
/* Track access to the PD discovery structures during HC execution */
uint32_t task_access[CONFIG_USB_PD_PORT_MAX_COUNT][DISCOVERY_TYPE_COUNT];
@@ -6711,6 +6737,7 @@ static const struct usb_state pe_states[] = {
};
#ifdef TEST_BUILD
+/* TODO(b/173791979): Unit tests shouldn't need to access internal states */
const struct test_sm_data test_pe_sm_data[] = {
{
.base = pe_states,
@@ -6742,4 +6769,8 @@ void pe_set_all_flags(int port, int flags)
{
pe[port].flags = flags;
}
+void pe_clr_dpm_requests(int port)
+{
+ pe[port].dpm_request = 0;
+}
#endif
diff --git a/include/usb_pd.h b/include/usb_pd.h
index 640cbba7ed..6a8e084ff3 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -2759,6 +2759,20 @@ uint8_t pd_get_src_cap_cnt(int port);
void pd_set_src_caps(int port, int cnt, uint32_t *src_caps);
/**
+ * Returns the sink caps list
+ *
+ * @param port USB-C port number
+ */
+const uint32_t * const pd_get_snk_caps(int port);
+
+/**
+ * Returns the number of sink caps
+ *
+ * @param port USB-C port number
+ */
+uint8_t pd_get_snk_cap_cnt(int port);
+
+/**
* Return true if partner port is capable of communication over USB data
* lines.
*
diff --git a/test/usb_pe.h b/test/usb_pe.h
index fb5ac10f88..8c1177f1f3 100644
--- a/test/usb_pe.h
+++ b/test/usb_pe.h
@@ -152,5 +152,6 @@ void pe_clr_flag(int port, int flag);
int pe_chk_flag(int port, int flag);
int pe_get_all_flags(int port);
void pe_set_all_flags(int port, int flags);
+void pe_clr_dpm_requests(int port);
#endif /* __CROS_TEST_USB_PE_H */
diff --git a/test/usb_pe_drp_old.c b/test/usb_pe_drp_old.c
index c9815b4726..c6e55f47ca 100644
--- a/test/usb_pe_drp_old.c
+++ b/test/usb_pe_drp_old.c
@@ -79,6 +79,8 @@ test_static void setup_source(void)
task_wait_event(10 * MSEC);
pe_set_flag(PORT0, PE_FLAGS_VDM_SETUP_DONE);
pe_set_flag(PORT0, PE_FLAGS_EXPLICIT_CONTRACT);
+ /* As long as we're hacking our way to ready, clear any DPM requests */
+ pe_clr_dpm_requests(PORT0);
set_state_pe(PORT0, PE_SRC_READY);
task_wait_event(10 * MSEC);
/* At this point, the PE should be running in PE_SRC_Ready. */
@@ -93,6 +95,8 @@ test_static void setup_sink(void)
task_wait_event(10 * MSEC);
pe_set_flag(PORT0, PE_FLAGS_VDM_SETUP_DONE);
pe_set_flag(PORT0, PE_FLAGS_EXPLICIT_CONTRACT);
+ /* As long as we're hacking our way to ready, clear any DPM requests */
+ pe_clr_dpm_requests(PORT0);
set_state_pe(PORT0, PE_SNK_READY);
task_wait_event(10 * MSEC);
/* At this point, the PE should be running in PE_SNK_Ready. */
@@ -104,8 +108,8 @@ test_static void setup_sink(void)
static int test_pe_frs(void)
{
/*
- * TODO: This test should validate PE boundary API differences -- not
- * internal state changes.
+ * TODO(b/173791979): This test should validate PE boundary API
+ * differences -- not internal state changes.
*/
task_wait_event(10 * MSEC);
@@ -119,6 +123,7 @@ static int test_pe_frs(void)
tc_prs_src_snk_assert_rd(PORT0);
pe_set_flag(PORT0, PE_FLAGS_VDM_SETUP_DONE);
pe_set_flag(PORT0, PE_FLAGS_EXPLICIT_CONTRACT);
+ pe_clr_dpm_requests(PORT0);
set_state_pe(PORT0, PE_SNK_READY);
task_wait_event(10 * MSEC);
TEST_ASSERT(get_state_pe(PORT0) == PE_SNK_READY);