diff options
-rw-r--r-- | common/usbc/usb_pd_host.c | 5 | ||||
-rw-r--r-- | common/usbc/usb_pe_drp_sm.c | 53 | ||||
-rw-r--r-- | include/usb_pd.h | 14 | ||||
-rw-r--r-- | test/usb_pe.h | 1 | ||||
-rw-r--r-- | test/usb_pe_drp_old.c | 9 |
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); |