diff options
author | Abe Levkoy <alevkoy@chromium.org> | 2020-06-03 11:06:53 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-06-11 19:44:59 +0000 |
commit | b9203fa3b2b032c3aa7b2e3ccfb01dce7eea8f22 (patch) | |
tree | 7969549ba4fdc71e0d4427765543330f8f40df11 | |
parent | 7b2203f0e45e6dc653aec4bc4c5cd4b72e844b9f (diff) | |
download | chrome-ec-b9203fa3b2b032c3aa7b2e3ccfb01dce7eea8f22.tar.gz |
TCPMv2: Support mode entry for SOP' and SOP''
Add a transmit type parameter to functions involved in mode entry; also
add such a parameter to various functions calling those functions. For
DisplayPort-specific definitions or calls, specify SOP; we do not
currently support DisplayPort mode for cable plugs. For TCPMv1-specific
code, specify SOP. TCPMv1 generally assumes that the discovery/mode
structures are 1-dimensional, as they were previously, and changing that
is outside the scope of this CL.
BUG=b:155890173
TEST=Enter DP mode on Volteer with TCPMv2
TEST=Enter DP mode on Volteer with TCPMv1
TEST=Enter TBT mode on Volteer with TCPMV1
BRANCH=none
Change-Id: I8afc75b3f3be8939c4645058ac4a31f24c88fb9e
Signed-off-by: Abe Levkoy <alevkoy@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2229279
Reviewed-by: Diana Z <dzigterman@chromium.org>
Commit-Queue: Diana Z <dzigterman@chromium.org>
-rw-r--r-- | baseboard/grunt/usb_pd_policy.c | 2 | ||||
-rw-r--r-- | baseboard/kukui/usb_pd_policy.c | 2 | ||||
-rw-r--r-- | baseboard/trogdor/usb_pd_policy.c | 2 | ||||
-rw-r--r-- | baseboard/zork/usb_pd_policy.c | 2 | ||||
-rw-r--r-- | board/chell/usb_pd_policy.c | 4 | ||||
-rw-r--r-- | board/coffeecake/usb_pd_policy.c | 5 | ||||
-rw-r--r-- | board/dingdong/usb_pd_policy.c | 5 | ||||
-rw-r--r-- | board/hoho/usb_pd_policy.c | 5 | ||||
-rw-r--r-- | board/pdeval-stm32f072/usb_pd_policy.c | 2 | ||||
-rw-r--r-- | board/plankton/usb_pd_policy.c | 2 | ||||
-rw-r--r-- | board/servo_v4/board.c | 4 | ||||
-rw-r--r-- | board/servo_v4/usb_pd_policy.c | 4 | ||||
-rw-r--r-- | common/usb_common.c | 2 | ||||
-rw-r--r-- | common/usb_pd_alt_mode_dfp.c | 94 | ||||
-rw-r--r-- | common/usb_pd_console_cmd.c | 3 | ||||
-rw-r--r-- | common/usb_pd_host_cmd.c | 8 | ||||
-rw-r--r-- | common/usb_pd_policy.c | 18 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 21 | ||||
-rw-r--r-- | common/usbc/dp_alt_mode.c | 10 | ||||
-rw-r--r-- | common/usbc/usb_pd_dpm.c | 2 | ||||
-rw-r--r-- | common/usbc/usb_pe_drp_sm.c | 72 | ||||
-rw-r--r-- | common/usbc/usb_tc_drp_acc_trysrc_sm.c | 38 | ||||
-rw-r--r-- | include/usb_pd.h | 46 |
23 files changed, 228 insertions, 125 deletions
diff --git a/baseboard/grunt/usb_pd_policy.c b/baseboard/grunt/usb_pd_policy.c index 0d2e41b64a..4b28081785 100644 --- a/baseboard/grunt/usb_pd_policy.c +++ b/baseboard/grunt/usb_pd_policy.c @@ -96,7 +96,7 @@ mux_state_t svdm_dp_mux_mode(int port) __override int svdm_dp_config(int port, uint32_t *payload) { - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT); int mf_pref = PD_VDO_DPSTS_MF_PREF(dp_status[port]); int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); mux_state_t mux_mode = svdm_dp_mux_mode(port); diff --git a/baseboard/kukui/usb_pd_policy.c b/baseboard/kukui/usb_pd_policy.c index feca48a8e7..1b28975fa1 100644 --- a/baseboard/kukui/usb_pd_policy.c +++ b/baseboard/kukui/usb_pd_policy.c @@ -158,7 +158,7 @@ __override int svdm_enter_dp_mode(int port, uint32_t mode_caps) __override int svdm_dp_config(int port, uint32_t *payload) { - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT); int status = dp_status[port]; int mf_pref = PD_VDO_DPSTS_MF_PREF(dp_status[port]); int pin_mode; diff --git a/baseboard/trogdor/usb_pd_policy.c b/baseboard/trogdor/usb_pd_policy.c index 40cfd91319..dc4733d20d 100644 --- a/baseboard/trogdor/usb_pd_policy.c +++ b/baseboard/trogdor/usb_pd_policy.c @@ -96,7 +96,7 @@ int pd_snk_is_vbus_provided(int port) #ifdef CONFIG_USB_PD_ALT_MODE_DFP __override int svdm_dp_config(int port, uint32_t *payload) { - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT); uint8_t pin_mode = get_dp_pin_mode(port); if (!pin_mode) diff --git a/baseboard/zork/usb_pd_policy.c b/baseboard/zork/usb_pd_policy.c index 4650682ed8..e83172880b 100644 --- a/baseboard/zork/usb_pd_policy.c +++ b/baseboard/zork/usb_pd_policy.c @@ -105,7 +105,7 @@ mux_state_t svdm_dp_mux_mode(int port) __override int svdm_dp_config(int port, uint32_t *payload) { - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT); int mf_pref = PD_VDO_DPSTS_MF_PREF(dp_status[port]); int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); mux_state_t mux_mode = svdm_dp_mux_mode(port); diff --git a/board/chell/usb_pd_policy.c b/board/chell/usb_pd_policy.c index 478f656de2..2123c45d86 100644 --- a/board/chell/usb_pd_policy.c +++ b/board/chell/usb_pd_policy.c @@ -228,7 +228,7 @@ static int svdm_enter_dp_mode(int port, uint32_t mode_caps) static int svdm_dp_status(int port, uint32_t *payload) { - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT); payload[0] = VDO(USB_SID_DISPLAYPORT, 1, CMD_DP_STATUS | VDO_OPOS(opos)); @@ -245,7 +245,7 @@ static int svdm_dp_status(int port, uint32_t *payload) static int svdm_dp_config(int port, uint32_t *payload) { - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT); int mf_pref = PD_VDO_DPSTS_MF_PREF(dp_status[port]); int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); diff --git a/board/coffeecake/usb_pd_policy.c b/board/coffeecake/usb_pd_policy.c index 99a0faec83..6da20a5b37 100644 --- a/board/coffeecake/usb_pd_policy.c +++ b/board/coffeecake/usb_pd_policy.c @@ -266,8 +266,11 @@ static int svdm_enter_mode(int port, uint32_t *payload) return rv; } -int pd_alt_mode(int port, uint16_t svid) +int pd_alt_mode(int port, enum tcpm_transmit_type type, uint16_t svid) { + if (type != TCPC_TX_SOP) + return 0; + if (svid == USB_SID_DISPLAYPORT) return alt_mode[PD_AMODE_DISPLAYPORT]; else if (svid == USB_VID_GOOGLE) diff --git a/board/dingdong/usb_pd_policy.c b/board/dingdong/usb_pd_policy.c index a4bfec541d..f17802c82a 100644 --- a/board/dingdong/usb_pd_policy.c +++ b/board/dingdong/usb_pd_policy.c @@ -219,8 +219,11 @@ static int svdm_enter_mode(int port, uint32_t *payload) return rv; } -int pd_alt_mode(int port, uint16_t svid) +int pd_alt_mode(int port, enum tcpm_transmit_type type, uint16_t svid) { + if (type != TCPC_TX_SOP) + return 0; + if (svid == USB_SID_DISPLAYPORT) return alt_mode[PD_AMODE_DISPLAYPORT]; else if (svid == USB_VID_GOOGLE) diff --git a/board/hoho/usb_pd_policy.c b/board/hoho/usb_pd_policy.c index 9bc8d3aa2f..4fe82320e8 100644 --- a/board/hoho/usb_pd_policy.c +++ b/board/hoho/usb_pd_policy.c @@ -194,8 +194,11 @@ static int svdm_enter_mode(int port, uint32_t *payload) return rv; } -int pd_alt_mode(int port, uint16_t svid) +int pd_alt_mode(int port, enum tcpm_transmit_type type, uint16_t svid) { + if (type != TCPC_TX_SOP) + return 0; + if (svid == USB_SID_DISPLAYPORT) return alt_mode[PD_AMODE_DISPLAYPORT]; else if (svid == USB_VID_GOOGLE) diff --git a/board/pdeval-stm32f072/usb_pd_policy.c b/board/pdeval-stm32f072/usb_pd_policy.c index 775f8b8876..78026c9e7b 100644 --- a/board/pdeval-stm32f072/usb_pd_policy.c +++ b/board/pdeval-stm32f072/usb_pd_policy.c @@ -199,7 +199,7 @@ __override void svdm_safe_dp_mode(int port) __override int svdm_dp_config(int port, uint32_t *payload) { - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT); int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); #if defined(CONFIG_USB_PD_TCPM_MUX) && defined(CONFIG_USB_PD_TCPM_ANX7447) const struct usb_mux *mux = &usb_muxes[port]; diff --git a/board/plankton/usb_pd_policy.c b/board/plankton/usb_pd_policy.c index 87718648f1..f6701ab65e 100644 --- a/board/plankton/usb_pd_policy.c +++ b/board/plankton/usb_pd_policy.c @@ -236,7 +236,7 @@ int svdm_enter_mode(int port, uint32_t *payload) return 1; } -int pd_alt_mode(int port, uint16_t svid) +int pd_alt_mode(int port, enum tcpm_transmit_type type, uint16_t svid) { return alt_mode; } diff --git a/board/servo_v4/board.c b/board/servo_v4/board.c index 559b9bb5b0..fc6735e19c 100644 --- a/board/servo_v4/board.c +++ b/board/servo_v4/board.c @@ -78,7 +78,7 @@ static volatile int hpd_prev_level; void hpd_irq_deferred(void) { - int dp_mode = pd_alt_mode(1, USB_SID_DISPLAYPORT); + int dp_mode = pd_alt_mode(1, TCPC_TX_SOP, USB_SID_DISPLAYPORT); if (dp_mode) { pd_send_hpd(DUT, hpd_irq); @@ -90,7 +90,7 @@ DECLARE_DEFERRED(hpd_irq_deferred); void hpd_lvl_deferred(void) { int level = gpio_get_level(GPIO_DP_HPD); - int dp_mode = pd_alt_mode(1, USB_SID_DISPLAYPORT); + int dp_mode = pd_alt_mode(1, TCPC_TX_SOP, USB_SID_DISPLAYPORT); if (level != hpd_prev_level) { /* It's a glitch while in deferred or canceled action */ diff --git a/board/servo_v4/usb_pd_policy.c b/board/servo_v4/usb_pd_policy.c index a8a6b8ee1f..b87130fbc8 100644 --- a/board/servo_v4/usb_pd_policy.c +++ b/board/servo_v4/usb_pd_policy.c @@ -950,9 +950,9 @@ static int svdm_enter_mode(int port, uint32_t *payload) return 1; } -int pd_alt_mode(int port, uint16_t svid) +int pd_alt_mode(int port, enum tcpm_transmit_type type, uint16_t svid) { - if (svid == USB_SID_DISPLAYPORT) + if (type == TCPC_TX_SOP && svid == USB_SID_DISPLAYPORT) return alt_mode; return 0; diff --git a/common/usb_common.c b/common/usb_common.c index 156dc816cb..974e136a7b 100644 --- a/common/usb_common.c +++ b/common/usb_common.c @@ -645,7 +645,7 @@ static void pd_usb_billboard_deferred(void) * 1. Will we have multiple type-C port UFPs * 2. Will there be other modes applicable to DFPs besides DP */ - if (!pd_alt_mode(0, USB_SID_DISPLAYPORT)) + if (!pd_alt_mode(0, TCPC_TX_SOP, USB_SID_DISPLAYPORT)) usb_connect(); } } diff --git a/common/usb_pd_alt_mode_dfp.c b/common/usb_pd_alt_mode_dfp.c index a5d7120669..421ae72024 100644 --- a/common/usb_pd_alt_mode_dfp.c +++ b/common/usb_pd_alt_mode_dfp.c @@ -50,33 +50,37 @@ __overridable const struct svdm_response svdm_rsp = { .modes = NULL, }; -static int pd_get_mode_idx(int port, uint16_t svid) +static int pd_get_mode_idx(int port, enum tcpm_transmit_type type, + uint16_t svid) { - int i; - /* TODO(b/150611251): Support SOP' */ - struct pd_discovery *disc = pd_get_am_discovery(port, TCPC_TX_SOP); + int amode_idx; + struct partner_active_modes *active = + pd_get_partner_active_modes(port, type); - for (i = 0; i < PD_AMODE_COUNT; i++) { - if (disc->amodes[i].fx && - (disc->amodes[i].fx->svid == svid)) - return i; + for (amode_idx = 0; amode_idx < PD_AMODE_COUNT; amode_idx++) { + if (active->amodes[amode_idx].fx && + (active->amodes[amode_idx].fx->svid == svid)) + return amode_idx; } return -1; } -static int pd_allocate_mode(int port, uint16_t svid) +static int pd_allocate_mode(int port, enum tcpm_transmit_type type, + uint16_t svid) { int i, j; struct svdm_amode_data *modep; - int mode_idx = pd_get_mode_idx(port, svid); - /* TODO(b/150611251): Support SOP' and SOP'' */ - struct pd_discovery *disc = pd_get_am_discovery(port, TCPC_TX_SOP); + int mode_idx = pd_get_mode_idx(port, type, svid); + struct pd_discovery *disc = pd_get_am_discovery(port, type); + struct partner_active_modes *active = + pd_get_partner_active_modes(port, type); + assert(active); if (mode_idx != -1) return mode_idx; /* There's no space to enter another mode */ - if (disc->amode_idx == PD_AMODE_COUNT) { + if (active->amode_idx == PD_AMODE_COUNT) { CPRINTF("ERR:NO AMODE SPACE\n"); return -1; } @@ -91,16 +95,18 @@ static int pd_allocate_mode(int port, uint16_t svid) * discovered SVIDs; must also match the passed-in SVID * if that was non-zero. Otherwise, go to the next * discovered SVID. + * TODO(b/155890173): Support AP-directed mode entry + * where the mode is unknown to the TCPM. */ if ((svidp->svid != supported_modes[i].svid) || (svid && (svidp->svid != svid))) continue; - modep = &disc->amodes[disc->amode_idx]; + modep = &active->amodes[active->amode_idx]; modep->fx = &supported_modes[i]; modep->data = &disc->svids[j]; - disc->amode_idx++; - return disc->amode_idx - 1; + active->amode_idx++; + return active->amode_idx - 1; } } return -1; @@ -169,7 +175,7 @@ void pd_prepare_sysjump(void) int pd_dfp_dp_get_pin_mode(int port, uint32_t status) { struct svdm_amode_data *modep = - pd_get_amode_data(port, USB_SID_DISPLAYPORT); + pd_get_amode_data(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT); uint32_t mode_caps; uint32_t pin_caps; @@ -199,30 +205,31 @@ int pd_dfp_dp_get_pin_mode(int port, uint32_t status) return 1 << get_next_bit(&pin_caps); } -struct svdm_amode_data *pd_get_amode_data(int port, uint16_t svid) +struct svdm_amode_data *pd_get_amode_data(int port, + enum tcpm_transmit_type type, uint16_t svid) { - int idx = pd_get_mode_idx(port, svid); - /* TODO(b/150611251): Support SOP' */ - struct pd_discovery *disc = pd_get_am_discovery(port, TCPC_TX_SOP); + int idx = pd_get_mode_idx(port, type, svid); + struct partner_active_modes *active = + pd_get_partner_active_modes(port, type); + assert(active); - return (idx == -1) ? NULL : &disc->amodes[idx]; + return (idx == -1) ? NULL : &active->amodes[idx]; } /* * Enter default mode ( payload[0] == 0 ) or attempt to enter mode via svid & * opos */ -uint32_t pd_dfp_enter_mode(int port, uint16_t svid, int opos) +uint32_t pd_dfp_enter_mode(int port, enum tcpm_transmit_type type, + uint16_t svid, int opos) { - int mode_idx = pd_allocate_mode(port, svid); - /* TODO(b/150611251): Support SOP' */ - struct pd_discovery *disc = pd_get_am_discovery(port, TCPC_TX_SOP); + int mode_idx = pd_allocate_mode(port, type, svid); struct svdm_amode_data *modep; uint32_t mode_caps; if (mode_idx == -1) return 0; - modep = &disc->amodes[mode_idx]; + modep = &pd_get_partner_active_modes(port, type)->amodes[mode_idx]; if (!opos) { /* choose the lowest as default */ @@ -230,7 +237,7 @@ uint32_t pd_dfp_enter_mode(int port, uint16_t svid, int opos) } else if (opos <= modep->data->mode_cnt) { modep->opos = opos; } else { - CPRINTF("opos error\n"); + CPRINTS("C%d: Invalid opos %d for SVID %x", port, opos, svid); return 0; } @@ -244,11 +251,12 @@ uint32_t pd_dfp_enter_mode(int port, uint16_t svid, int opos) return VDO(modep->fx->svid, 1, CMD_ENTER_MODE | VDO_OPOS(modep->opos)); } -int pd_dfp_exit_mode(int port, uint16_t svid, int opos) +int pd_dfp_exit_mode(int port, enum tcpm_transmit_type type, uint16_t svid, + int opos) { struct svdm_amode_data *modep; - /* TODO(b/150611251): Support SOP' */ - struct pd_discovery *disc = pd_get_am_discovery(port, TCPC_TX_SOP); + struct partner_active_modes *active = + pd_get_partner_active_modes(port, type); int idx; /* @@ -258,8 +266,8 @@ int pd_dfp_exit_mode(int port, uint16_t svid, int opos) */ if (!svid) { for (idx = 0; idx < PD_AMODE_COUNT; idx++) - if (disc->amodes[idx].fx) - disc->amodes[idx].fx->exit(port); + if (active->amodes[idx].fx) + active->amodes[idx].fx->exit(port); pd_dfp_discovery_init(port); return 0; @@ -271,7 +279,7 @@ int pd_dfp_exit_mode(int port, uint16_t svid, int opos) * to exit all modes. We currently don't have any UFPs that support * multiple modes on one SVID. */ - modep = pd_get_amode_data(port, svid); + modep = pd_get_amode_data(port, type, svid); if (!modep || !validate_mode_request(modep, svid, opos)) return 0; @@ -289,7 +297,8 @@ void dfp_consume_attention(int port, uint32_t *payload) { uint16_t svid = PD_VDO_VID(payload[0]); int opos = PD_VDO_OPOS(payload[0]); - struct svdm_amode_data *modep = pd_get_amode_data(port, svid); + struct svdm_amode_data *modep = + pd_get_amode_data(port, TCPC_TX_SOP, svid); if (!modep || !validate_mode_request(modep, svid, opos)) return; @@ -434,9 +443,9 @@ int dfp_discover_modes(int port, uint32_t *payload) return 1; } -int pd_alt_mode(int port, uint16_t svid) +int pd_alt_mode(int port, enum tcpm_transmit_type type, uint16_t svid) { - struct svdm_amode_data *modep = pd_get_amode_data(port, svid); + struct svdm_amode_data *modep = pd_get_amode_data(port, type, svid); return (modep) ? modep->opos : -1; } @@ -846,7 +855,12 @@ int enter_tbt_compat_mode(int port, enum tcpm_transmit_type sop, struct pd_cable *cable = pd_get_cable_attributes(port); /* Table F-12 TBT3 Cable Enter Mode Command */ - payload[0] = pd_dfp_enter_mode(port, USB_VID_INTEL, 0) | + /* + * Although TCPMv2 contemplates separate mode storage for each SOP + * type, TCPMv1 stores everything in the array for SOP. + */ + /* TODO(b/148528713): Make this function generic to TCPM version. */ + payload[0] = pd_dfp_enter_mode(port, TCPC_TX_SOP, USB_VID_INTEL, 0) | VDO_SVDM_VERS(VDM_VER20); /* For TBT3 Cable Enter Mode Command, number of Objects is 1 */ @@ -1061,7 +1075,7 @@ __overridable int svdm_enter_dp_mode(int port, uint32_t mode_caps) __overridable int svdm_dp_status(int port, uint32_t *payload) { - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT); payload[0] = VDO(USB_SID_DISPLAYPORT, 1, CMD_DP_STATUS | VDO_OPOS(opos)); @@ -1083,7 +1097,7 @@ __overridable uint8_t get_dp_pin_mode(int port) __overridable int svdm_dp_config(int port, uint32_t *payload) { - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT); int mf_pref = PD_VDO_DPSTS_MF_PREF(dp_status[port]); uint8_t pin_mode = get_dp_pin_mode(port); mux_state_t mux_mode; diff --git a/common/usb_pd_console_cmd.c b/common/usb_pd_console_cmd.c index 22039eddc3..3fc6a6f35f 100644 --- a/common/usb_pd_console_cmd.c +++ b/common/usb_pd_console_cmd.c @@ -64,7 +64,8 @@ static void dump_pe(int port) disc->svids[i].mode_vdo[j]); ccprintf("\n"); - modep = pd_get_amode_data(port, disc->svids[i].svid); + modep = pd_get_amode_data(port, TCPC_TX_SOP, + disc->svids[i].svid); if (modep) { mode_caps = modep->data->mode_vdo[modep->opos - 1]; ccprintf("MODE[%d]: svid:%04x caps:%08x\n", modep->opos, diff --git a/common/usb_pd_host_cmd.c b/common/usb_pd_host_cmd.c index 8bd9f16aea..6e8afe761e 100644 --- a/common/usb_pd_host_cmd.c +++ b/common/usb_pd_host_cmd.c @@ -125,7 +125,7 @@ static enum ec_status hc_remote_pd_set_amode(struct host_cmd_handler_args *args) switch (p->cmd) { case PD_EXIT_MODE: - if (pd_dfp_exit_mode(p->port, p->svid, p->opos)) + if (pd_dfp_exit_mode(p->port, TCPC_TX_SOP, p->svid, p->opos)) pd_send_vdm(p->port, p->svid, CMD_EXIT_MODE | VDO_OPOS(p->opos), NULL, 0); else { @@ -134,7 +134,7 @@ static enum ec_status hc_remote_pd_set_amode(struct host_cmd_handler_args *args) } break; case PD_ENTER_MODE: - if (pd_dfp_enter_mode(p->port, p->svid, p->opos)) + if (pd_dfp_enter_mode(p->port, TCPC_TX_SOP, p->svid, p->opos)) pd_send_vdm(p->port, p->svid, CMD_ENTER_MODE | VDO_OPOS(p->opos), NULL, 0); break; @@ -190,10 +190,10 @@ static enum ec_status hc_remote_pd_get_amode(struct host_cmd_handler_args *args) r->opos = 0; memcpy(r->vdo, pd_get_mode_vdo(p->port, p->svid_idx, TCPC_TX_SOP), sizeof(uint32_t) * PDO_MODES); - modep = pd_get_amode_data(p->port, r->svid); + modep = pd_get_amode_data(p->port, TCPC_TX_SOP, r->svid); if (modep) - r->opos = pd_alt_mode(p->port, r->svid); + r->opos = pd_alt_mode(p->port, TCPC_TX_SOP, r->svid); args->response_size = sizeof(*r); return EC_RES_SUCCESS; diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c index 0d468b0ce8..b10b9cb8c7 100644 --- a/common/usb_pd_policy.c +++ b/common/usb_pd_policy.c @@ -206,6 +206,7 @@ void disable_enter_usb4_mode(int port) #ifdef CONFIG_USB_PD_ALT_MODE_DFP static struct pd_discovery discovery[CONFIG_USB_PD_PORT_MAX_COUNT]; +static struct partner_active_modes partner_amodes[CONFIG_USB_PD_PORT_MAX_COUNT]; static bool is_tbt_compat_enabled(int port) { @@ -331,6 +332,7 @@ static bool is_cable_ready_to_enter_usb4(int port, int cnt) void pd_dfp_discovery_init(int port) { memset(&discovery[port], 0, sizeof(struct pd_discovery)); + memset(&partner_amodes[port], 0, sizeof(partner_amodes[0])); } static int dfp_discover_ident(uint32_t *payload) @@ -354,6 +356,13 @@ struct pd_discovery *pd_get_am_discovery(int port, enum tcpm_transmit_type type) return &discovery[port]; } +struct partner_active_modes *pd_get_partner_active_modes(int port, + enum tcpm_transmit_type type) +{ + assert(type < AMODE_TYPE_COUNT); + return &partner_amodes[port]; +} + /* Note: Enter mode flag is not needed by TCPMv1 */ void pd_set_dfp_enter_mode_flag(int port, bool set) { @@ -656,7 +665,8 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, #ifdef CONFIG_USB_PD_ALT_MODE_DFP struct svdm_amode_data *modep; - modep = pd_get_amode_data(port, PD_VDO_VID(payload[0])); + modep = pd_get_amode_data(port, TCPC_TX_SOP, + PD_VDO_VID(payload[0])); #endif switch (cmd) { #ifdef CONFIG_USB_PD_ALT_MODE_DFP @@ -705,7 +715,8 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, * SVID. */ disable_tbt_compat_mode(port); - payload[0] = pd_dfp_enter_mode(port, 0, 0); + payload[0] = pd_dfp_enter_mode(port, + TCPC_TX_SOP, 0, 0); if (payload[0]) rsize = 1; } @@ -722,7 +733,8 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload, rsize = 0; } else { if (!modep->opos) - pd_dfp_enter_mode(port, 0, 0); + pd_dfp_enter_mode(port, TCPC_TX_SOP, 0, + 0); if (modep->opos) { rsize = modep->fx->status(port, diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 442432890e..b8cd5d7340 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -791,7 +791,7 @@ static inline void set_state(int port, enum pd_states next_state) charge_manager_update_dualrole(port, CAP_UNKNOWN); #endif #ifdef CONFIG_USB_PD_ALT_MODE_DFP - pd_dfp_exit_mode(port, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP, 0, 0); #endif /* * Indicate that the port is disconnected by setting role to @@ -1325,7 +1325,7 @@ void pd_execute_hard_reset(int port) pd[port].msg_id = 0; invalidate_last_message_id(port); #ifdef CONFIG_USB_PD_ALT_MODE_DFP - pd_dfp_exit_mode(port, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP, 0, 0); #endif #ifdef CONFIG_USB_PD_REV30 @@ -2131,12 +2131,17 @@ static void exit_tbt_mode_sop_prime(int port) if (!IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE)) return; - opos = pd_alt_mode(port, USB_VID_INTEL); + opos = pd_alt_mode(port, TCPC_TX_SOP, USB_VID_INTEL); if (opos <= 0) return; CPRINTS("C%d Cable exiting TBT Compat mode", port); - if (!pd_dfp_exit_mode(port, USB_VID_INTEL, opos)) + /* + * Note: TCPMv2 contemplates separate discovery structures for each SOP + * type. TCPMv1 only uses one discovery structure, so all accesses + * specify TCPC_TX_SOP. + */ + if (!pd_dfp_exit_mode(port, TCPC_TX_SOP, USB_VID_INTEL, opos)) return; header = PD_HEADER(PD_DATA_VENDOR_DEF, pd[port].power_role, @@ -2333,10 +2338,12 @@ __maybe_unused static void exit_supported_alt_mode(int port) return; for (i = 0; i < supported_modes_cnt; i++) { - int opos = pd_alt_mode(port, supported_modes[i].svid); + int opos = pd_alt_mode(port, TCPC_TX_SOP, + supported_modes[i].svid); if (opos > 0 && - pd_dfp_exit_mode(port, supported_modes[i].svid, opos)) { + pd_dfp_exit_mode( + port, TCPC_TX_SOP, supported_modes[i].svid, opos)) { CPRINTS("C%d Exiting ALT mode with SVID = 0x%x", port, supported_modes[i].svid); pd_send_vdm(port, supported_modes[i].svid, @@ -4969,7 +4976,7 @@ int pd_is_port_enabled(int port) void pd_send_hpd(int port, enum hpd_event hpd) { uint32_t data[1]; - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT); if (!opos) return; diff --git a/common/usbc/dp_alt_mode.c b/common/usbc/dp_alt_mode.c index ba0b35550b..ff8909bbd6 100644 --- a/common/usbc/dp_alt_mode.c +++ b/common/usbc/dp_alt_mode.c @@ -58,11 +58,12 @@ void dp_vdm_acked(int port, enum tcpm_transmit_type type, int vdo_count, uint32_t *vdm) { const struct svdm_amode_data *modep = - pd_get_amode_data(port, USB_SID_DISPLAYPORT); + pd_get_amode_data(port, type, USB_SID_DISPLAYPORT); const uint8_t vdm_cmd = PD_VDO_CMD(vdm[0]); if (type != TCPC_TX_SOP || next_vdm_cmd[port] != vdm_cmd) { print_unexpected_response(port, type, CMDT_RSP_ACK, vdm_cmd); + dpm_set_mode_entry_done(port); return; } @@ -105,8 +106,8 @@ void dp_reset_next_command(int port) int dp_setup_next_vdm(int port, int vdo_count, uint32_t *vdm) { - const struct svdm_amode_data *modep = - pd_get_amode_data(port, USB_SID_DISPLAYPORT); + const struct svdm_amode_data *modep = pd_get_amode_data(port, + TCPC_TX_SOP, USB_SID_DISPLAYPORT); int vdo_count_ret; if (vdo_count < VDO_MAX_SIZE) @@ -115,7 +116,8 @@ int dp_setup_next_vdm(int port, int vdo_count, uint32_t *vdm) switch (next_vdm_cmd[port]) { case CMD_ENTER_MODE: /* Enter the first supported mode for DisplayPort. */ - vdm[0] = pd_dfp_enter_mode(port, USB_SID_DISPLAYPORT, 0); + vdm[0] = pd_dfp_enter_mode(port, TCPC_TX_SOP, + USB_SID_DISPLAYPORT, 0); if (vdm[0] == 0) return -1; /* CMDT_INIT is 0, so this is a no-op */ diff --git a/common/usbc/usb_pd_dpm.c b/common/usbc/usb_pd_dpm.c index 44ec46e588..adfb64d8fd 100644 --- a/common/usbc/usb_pd_dpm.c +++ b/common/usbc/usb_pd_dpm.c @@ -101,7 +101,7 @@ void dpm_attempt_mode_entry(int port) * TODO(b/155890173): Provide a host command to request that the PE send * an arbitrary VDM via this mechanism. */ - if (!pd_setup_vdm_request(port, vdm, vdo_count)) { + if (!pd_setup_vdm_request(port, TCPC_TX_SOP, vdm, vdo_count)) { dpm_set_mode_entry_done(port); return; } diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index 0db15df6ee..7c6d8a9f98 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -466,6 +466,8 @@ static struct policy_engine { int32_t vpd_vdo; /* Alternate mode discovery results */ struct pd_discovery discovery[DISCOVERY_TYPE_COUNT]; + /* Active alternate modes */ + struct partner_active_modes partner_amodes[AMODE_TYPE_COUNT]; /* Alternate mode object position */ int8_t alt_opos; @@ -1063,7 +1065,7 @@ void pd_send_vdm(int port, uint32_t vid, int cmd, const uint32_t *data, void pe_exit_dp_mode(int port) { if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT); if (opos <= 0) return; @@ -1075,7 +1077,8 @@ void pe_exit_dp_mode(int port) * the mode to be cleaned up before return. */ CPRINTS("C%d Exiting DP mode", port); - if (!pd_dfp_exit_mode(port, USB_SID_DISPLAYPORT, opos)) + if (!pd_dfp_exit_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT, + opos)) return; /* @@ -1439,13 +1442,13 @@ static bool pe_attempt_port_discovery(int port) } #endif -bool pd_setup_vdm_request(int port, uint32_t *vdm, uint32_t vdo_cnt) +bool pd_setup_vdm_request(int port, enum tcpm_transmit_type tx_type, + uint32_t *vdm, uint32_t vdo_cnt) { if (vdo_cnt < VDO_HDR_SIZE || vdo_cnt > VDO_MAX_SIZE) return false; - /* TODO(b/155890173): Support cable plug */ - pe[port].partner_type = PORT; + pe[port].tx_type = tx_type; memcpy(pe[port].vdm_data, vdm, vdo_cnt * sizeof(*vdm)); pe[port].vdm_cnt = vdo_cnt; @@ -4183,7 +4186,7 @@ static void pe_do_port_discovery_run(int port) #ifdef CONFIG_USB_PD_ALT_MODE_DFP uint32_t *payload = (uint32_t *)rx_emsg[port].buf; struct svdm_amode_data *modep = - pd_get_amode_data(port, PD_VDO_VID(payload[0])); + pd_get_amode_data(port, TCPC_TX_SOP, PD_VDO_VID(payload[0])); int ret = 0; if (!PE_CHK_FLAG(port, @@ -4205,7 +4208,8 @@ static void pe_do_port_discovery_run(int port) break; case CMD_DISCOVER_MODES: pe[port].vdm_cmd = CMD_ENTER_MODE; - pe[port].vdm_data[0] = pd_dfp_enter_mode(port, 0, 0); + pe[port].vdm_data[0] = + pd_dfp_enter_mode(port, TCPC_TX_SOP, 0, 0); if (pe[port].vdm_data[0]) ret = 1; break; @@ -4860,6 +4864,12 @@ static void pe_vdm_request_entry(int port) { print_current_state(port); + if (pe[port].tx_type == TCPC_TX_INVALID) { + CPRINTS("C%d: TX type expected to be set, returning", port); + set_state_pe(port, get_last_state_pe(port)); + return; + } + /* All VDM sequences are Interruptible */ PE_SET_FLAG(port, PE_FLAGS_INTERRUPTIBLE_AMS); @@ -4873,8 +4883,7 @@ static void pe_vdm_request_entry(int port) tx_emsg[port].len = pe[port].vdm_cnt * 4; } - /* TODO(b/155890173): Support cable plug */ - send_data_msg(port, TCPC_TX_SOP, PD_DATA_VENDOR_DEF); + send_data_msg(port, pe[port].tx_type, PD_DATA_VENDOR_DEF); pe[port].vdm_response_timer = TIMER_DISABLED; } @@ -4909,9 +4918,8 @@ static void pe_vdm_request_run(int port) cnt = PD_HEADER_CNT(rx_emsg[port].header); ext = PD_HEADER_EXT(rx_emsg[port].header); - if ((sop == TCPC_TX_SOP || sop == TCPC_TX_SOP_PRIME) && - type == PD_DATA_VENDOR_DEF && cnt > 0 && - ext == 0) { + if (sop == pe[port].tx_type && type == PD_DATA_VENDOR_DEF && + cnt > 0 && ext == 0) { if (PD_VDO_CMDT(payload[0]) == CMDT_RSP_ACK) { set_state_pe(port, PE_VDM_ACKED); return; @@ -4925,7 +4933,7 @@ static void pe_vdm_request_run(int port) PE_FLAGS_VDM_REQUEST_BUSY); } } else { - if ((sop == TCPC_TX_SOP || sop == TCPC_TX_SOP_PRIME) && + if (sop == pe[port].tx_type && type == PD_CTRL_NOT_SUPPORTED && cnt == 0 && ext == 0) { /* Equivalent meaning to a NAK */ @@ -4962,7 +4970,8 @@ static void pe_vdm_request_run(int port) PE_SET_FLAG(port, PE_FLAGS_VDM_REQUEST_BUSY); } else if (get_time().val > pe[port].vdm_response_timer) { CPRINTF("C%d: VDM %s Response Timeout\n", port, - pe[port].partner_type ? "Cable" : "Port"); + pe[port].tx_type == TCPC_TX_SOP + ? "Port" : "Cable"); PE_SET_FLAG(port, PE_FLAGS_VDM_REQUEST_NAKED); } @@ -4990,6 +4999,9 @@ static void pe_vdm_request_run(int port) static void pe_vdm_request_exit(int port) { + /* Invalidate TX type so that it must be set before next call */ + pe[port].tx_type = TCPC_TX_INVALID; + PE_CLR_FLAG(port, PE_FLAGS_INTERRUPTIBLE_AMS); } @@ -5012,24 +5024,18 @@ static void pe_vdm_acked_entry(int port) payload = (uint32_t *)rx_emsg[port].buf; svid = PD_VDO_VID(payload[0]); vdo_cmd = PD_VDO_CMD(payload[0]); - sop = PD_HEADER_GET_SOP(rx_emsg[port].header); - /* TODO(b/155890173): Support cable plug */ - if (sop == TCPC_TX_SOP) { - /* - * Handle Message From Port Partner - */ - /* vdo_count must have been >= 1 to get into this state. */ - dpm_vdm_acked(port, sop, vdo_count, payload); + /* vdo_count must have been >= 1 to get into this state. */ + dpm_vdm_acked(port, sop, vdo_count, payload); - /* - * TODO(b/155890173): Respect distinction between discovery and - * mode entry in flags. - */ - if (svid == USB_SID_DISPLAYPORT && vdo_cmd == CMD_DP_CONFIG) - PE_SET_FLAG(port, PE_FLAGS_DISCOVER_PORT_IDENTITY_DONE); - } + /* + * TODO(b/155890173): Respect distinction between discovery and mode + * entry in flags. + */ + if (sop == TCPC_TX_SOP && svid == USB_SID_DISPLAYPORT && + vdo_cmd == CMD_DP_CONFIG) + PE_SET_FLAG(port, PE_FLAGS_DISCOVER_PORT_IDENTITY_DONE); if (pe[port].power_role == PD_ROLE_SOURCE) { set_state_pe(port, PE_SRC_READY); @@ -5659,6 +5665,7 @@ uint8_t pd_get_src_cap_cnt(int port) void pd_dfp_discovery_init(int port) { memset(&pe[port].discovery, 0, sizeof(pe[port].discovery)); + memset(pe[port].partner_amodes, 0, sizeof(pe[port].partner_amodes)); /* Reset the DPM and DP modules to enable alternate mode entry. */ dpm_init(port); @@ -5671,6 +5678,13 @@ struct pd_discovery *pd_get_am_discovery(int port, enum tcpm_transmit_type type) return &pe[port].discovery[type]; } +struct partner_active_modes *pd_get_partner_active_modes(int port, + enum tcpm_transmit_type type) +{ + assert(type < AMODE_TYPE_COUNT); + return &pe[port].partner_amodes[type]; +} + struct pd_cable *pd_get_cable_attributes(int port) { return &pe[port].cable; diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index 8258f9666f..b39ea83ca6 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -1475,7 +1475,7 @@ static void handle_new_power_state(int port) void pd_send_hpd(int port, enum hpd_event hpd) { uint32_t data[1]; - int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT); if (!opos) return; @@ -1907,7 +1907,9 @@ static void tc_attach_wait_snk_run(const int port) get_time().val > tc[port].pd_debounce) { if (IS_ENABLED(CONFIG_USB_PE_SM) && IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { - pd_dfp_exit_mode(port, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME_PRIME, 0, 0); } /* We are detached */ @@ -2054,8 +2056,12 @@ static void tc_attached_snk_run(const int port) !TC_CHK_FLAG(port, TC_FLAGS_PR_SWAP_IN_PROGRESS)) { /* Detach detection */ if (!pd_is_vbus_present(port)) { - if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) - pd_dfp_exit_mode(port, 0, 0); + if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { + pd_dfp_exit_mode(port, TCPC_TX_SOP, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME_PRIME, + 0, 0); + } set_state_tc(port, TC_UNATTACHED_SNK); return; @@ -2444,8 +2450,12 @@ static void tc_dbg_acc_snk_run(const int port) !TC_CHK_FLAG(port, TC_FLAGS_PR_SWAP_IN_PROGRESS)) { /* Detach detection */ if (!pd_is_vbus_present(port)) { - if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) - pd_dfp_exit_mode(port, 0, 0); + if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { + pd_dfp_exit_mode(port, TCPC_TX_SOP, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME_PRIME, + 0, 0); + } set_state_tc(port, TC_UNATTACHED_SNK); return; @@ -2862,8 +2872,12 @@ static void tc_attached_src_run(const int port) !TC_CHK_FLAG(port, TC_FLAGS_DISC_IDENT_IN_PROGRESS)) { if (IS_ENABLED(CONFIG_USB_PE_SM)) - if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) - pd_dfp_exit_mode(port, 0, 0); + if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { + pd_dfp_exit_mode(port, TCPC_TX_SOP, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME_PRIME, + 0, 0); + } set_state_tc(port, IS_ENABLED(CONFIG_USB_PD_TRY_SRC) ? TC_TRY_WAIT_SNK : TC_UNATTACHED_SNK); @@ -3303,8 +3317,12 @@ static void tc_ct_unattached_snk_run(int port) if (get_time().val > tc[port].cc_debounce) { if (new_cc_state == PD_CC_NONE && pd_check_vbus_level(port, VBUS_SAFE0V)) { - if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) - pd_dfp_exit_mode(port, 0, 0); + if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { + pd_dfp_exit_mode(port, TCPC_TX_SOP, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME, 0, 0); + pd_dfp_exit_mode(port, TCPC_TX_SOP_PRIME_PRIME, + 0, 0); + } set_state_tc(port, TC_UNATTACHED_SNK); return; diff --git a/include/usb_pd.h b/include/usb_pd.h index 4b63eed869..34fe964966 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -371,11 +371,13 @@ enum pd_alternate_modes { PD_AMODE_COUNT, }; -/* Discover all SOP* communications when enabled */ +/* Discover and possibly enter modes for all SOP* communications when enabled */ #ifdef CONFIG_USB_PD_DECODE_SOP #define DISCOVERY_TYPE_COUNT (TCPC_TX_SOP_PRIME + 1) +#define AMODE_TYPE_COUNT (TCPC_TX_SOP_PRIME_PRIME + 1) #else #define DISCOVERY_TYPE_COUNT (TCPC_TX_SOP + 1) +#define AMODE_TYPE_COUNT (TCPC_TX_SOP + 1) #endif /* Discovery results for a port partner (SOP) or cable plug (SOP') */ @@ -384,20 +386,24 @@ struct pd_discovery { union disc_ident_ack identity; /* Supported SVIDs and corresponding mode VDOs */ struct svid_mode_data svids[SVID_DISCOVERY_MAX]; - /* active modes */ - struct svdm_amode_data amodes[PD_AMODE_COUNT]; /* index of SVID currently being operated on */ int svid_idx; /* Count of SVIDs discovered */ int svid_cnt; - /* Next index to insert DFP alternate mode into amodes */ - int amode_idx; /* Identity discovery state */ enum pd_discovery_state identity_discovery; /* SVID discovery state */ enum pd_discovery_state svids_discovery; }; +/* Active modes for a partner (SOP, SOP', or SOP'') */ +struct partner_active_modes { + /* Active modes */ + struct svdm_amode_data amodes[PD_AMODE_COUNT]; + /* Next index to insert DFP alternate mode into amodes */ + int amode_idx; +}; + /* * VDO : Vendor Defined Message Object * VDM object is minimum of VDM header + 6 additional data objects. @@ -1594,11 +1600,13 @@ int pd_custom_flash_vdm(int port, int cnt, uint32_t *payload); * Enter alternate mode on DFP * * @param port USB-C port number + * @param type Transmit type (SOP, SOP') for which to enter mode * @param svid USB standard or vendor id to exit or zero for DFP amode reset. * @param opos object position of mode to exit. * @return vdm for UFP to be sent to enter mode or zero if not. */ -uint32_t pd_dfp_enter_mode(int port, uint16_t svid, int opos); +uint32_t pd_dfp_enter_mode(int port, enum tcpm_transmit_type type, + uint16_t svid, int opos); /** * Get DisplayPort pin mode for DFP to request from UFP's capabilities. @@ -1613,11 +1621,13 @@ int pd_dfp_dp_get_pin_mode(int port, uint32_t status); * Exit alternate mode on DFP * * @param port USB-C port number + * @param type Transmit type (SOP, SOP') for which to exit mode * @param svid USB standard or vendor id to exit or zero for DFP amode reset. * @param opos object position of mode to exit. * @return 1 if UFP should be sent exit mode VDM. */ -int pd_dfp_exit_mode(int port, uint16_t svid, int opos); +int pd_dfp_exit_mode(int port, enum tcpm_transmit_type type, uint16_t svid, + int opos); /** * Consume the SVDM attention data @@ -1833,10 +1843,12 @@ bool pd_is_mode_discovered_for_svid(int port, enum tcpm_transmit_type type, * Return the alternate mode entry and exit data * * @param port USB-C port number + * @param type Transmit type (SOP, SOP', SOP'') for mode data * @param svid SVID * @return pointer to SVDM mode data */ -struct svdm_amode_data *pd_get_amode_data(int port, uint16_t svid); +struct svdm_amode_data *pd_get_amode_data(int port, + enum tcpm_transmit_type type, uint16_t svid); /** * Returns false if previous SOP' messageId count is different from received @@ -1874,6 +1886,17 @@ struct pd_discovery *pd_get_am_discovery(int port, enum tcpm_transmit_type type); /* + * Returns the pointer to PD active alternate modes. + * Note: Caller function can mutate the data in this structure. + * + * @param port USB-C port number + * @param type Transmit type (SOP, SOP', SOP'') for active modes + * @return Pointer to PD active alternate modes. + */ +struct partner_active_modes *pd_get_partner_active_modes(int port, + enum tcpm_transmit_type type); + +/* * Return the pointer to PD cable attributes * Note: Caller function can mutate the data in this structure. * @@ -2228,13 +2251,15 @@ void pd_send_vdm(int port, uint32_t vid, int cmd, const uint32_t *data, /* Prepares the PE to send an VDM. * * @param port USB-C port number + * @param type Transmit type (SOP, SOP', SOP'') for VDM * @param vdm Buffer containing the message body to send, including the VDM * Header but not the Message Header. * @param vdo_cnt The number of 32-bit VDOs in vdm, including the VDM Header; * must be 1 - 7 inclusive. * @return True if the setup was successful */ -bool pd_setup_vdm_request(int port, uint32_t *vdm, uint32_t vdo_cnt); +bool pd_setup_vdm_request(int port, enum tcpm_transmit_type tx_type, + uint32_t *vdm, uint32_t vdo_cnt); /* Power Data Objects for the source and the sink */ __override_proto extern const uint32_t pd_src_pdo[]; @@ -2259,10 +2284,11 @@ static inline void pd_send_host_event(int mask) { } * Determine if in alternate mode or not. * * @param port port number. + * @param type Transmit type (SOP, SOP', SOP'') for alt mode status * @param svid USB standard or vendor id * @return object position of mode chosen in alternate mode otherwise zero. */ -int pd_alt_mode(int port, uint16_t svid); +int pd_alt_mode(int port, enum tcpm_transmit_type type, uint16_t svid); /** * Send hpd over USB PD. |