From 62080646fe4312de930e4c4d766106438eae5efc Mon Sep 17 00:00:00 2001 From: Scott Date: Wed, 22 Apr 2015 14:51:58 -0700 Subject: pd: Allow for setting USB mux when swapping into DFP role - Added config option CONFIG_USBC_SS_MUX_DFP_ONLY - If this options is enabled, then the mux is set to TYPEC_USB_MUX only is data role is DFP. - If this option is not enabled, the mux is set for both UFP and DFP (i.e. RYU) BUG=chrome-os-partner:39059 TEST=Manual samus to plankton, switching between source and sink modes. Forced data role swap via ec console command. BRANCH=Samus Change-Id: Ibc2fb0ad42d0fe415d3338d38da94ad4b041513b Signed-off-by: Scott Collyer Reviewed-on: https://chromium-review.googlesource.com/266916 Reviewed-by: Vincent Palatin Tested-by: Vincent Palatin Reviewed-by: Alec Berg Commit-Queue: Alec Berg --- board/samus_pd/board.c | 22 ++++++++++++++-------- board/samus_pd/board.h | 4 +--- board/samus_pd/usb_pd_policy.c | 3 +-- common/usb_pd_protocol.c | 23 ++++++++++++++++------- include/config.h | 6 ++++++ 5 files changed, 38 insertions(+), 20 deletions(-) diff --git a/board/samus_pd/board.c b/board/samus_pd/board.c index 14c407f8df..13ccc90d37 100644 --- a/board/samus_pd/board.c +++ b/board/samus_pd/board.c @@ -157,14 +157,6 @@ void vbus1_evt(enum gpio_signal signal) task_wake(TASK_ID_PD_C1); } -void set_usb_switches(int port, int open) -{ - mutex_lock(&usb_switch_lock[port]); - usb_switch_state[port] = open; - pi3usb9281_set_switches(port, open); - mutex_unlock(&usb_switch_lock[port]); -} - /* Wait after a charger is detected to debounce pin contact order */ #define USB_CHG_DEBOUNCE_DELAY_MS 1000 /* @@ -558,6 +550,16 @@ const struct usb_port_mux usb_muxes[] = { }; BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == PD_PORT_COUNT); + +static void board_set_usb_switches(int port, int open) +{ + + mutex_lock(&usb_switch_lock[port]); + usb_switch_state[port] = open; + pi3usb9281_set_switches(port, open); + mutex_unlock(&usb_switch_lock[port]); +} + void board_set_usb_mux(int port, enum typec_mux mux, int polarity) { const struct usb_port_mux *usb_mux = usb_muxes + port; @@ -570,6 +572,10 @@ void board_set_usb_mux(int port, enum typec_mux mux, int polarity) gpio_set_level(usb_mux->ss1_dp_mode, 1); gpio_set_level(usb_mux->ss2_dp_mode, 1); + if ((mux == TYPEC_MUX_NONE) || (mux == TYPEC_MUX_USB)) + /* Set D+/D- switch to appropriate level */ + board_set_usb_switches(port, mux == TYPEC_MUX_NONE); + if (mux == TYPEC_MUX_NONE) /* everything is already disabled, we can return */ return; diff --git a/board/samus_pd/board.h b/board/samus_pd/board.h index 877e12798f..ea5a7ef290 100644 --- a/board/samus_pd/board.h +++ b/board/samus_pd/board.h @@ -59,6 +59,7 @@ #define CONFIG_USB_SWITCH_PI3USB9281 #undef CONFIG_USB_SWITCH_PI3USB9281_MUX_GPIO #define CONFIG_USB_SWITCH_PI3USB9281_MUX_GPIO GPIO_USB_C_BC12_SEL +#define CONFIG_USBC_SS_MUX_DFP_ONLY #define CONFIG_USBC_SS_MUX #define CONFIG_USBC_VCONN #define CONFIG_USBC_VCONN_SWAP @@ -138,9 +139,6 @@ int board_get_battery_soc(void); /* Send host event to AP */ void pd_send_host_event(int mask); -/* Update the state of the USB data switches */ -void set_usb_switches(int port, int open); - #endif /* !__ASSEMBLER__ */ #endif /* __BOARD_H */ diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c index 3db584fbe5..431c281b1e 100644 --- a/board/samus_pd/usb_pd_policy.c +++ b/board/samus_pd/usb_pd_policy.c @@ -159,8 +159,7 @@ int pd_check_vconn_swap(int port) void pd_execute_data_swap(int port, int data_role) { - /* Open USB switches when taking UFP role */ - set_usb_switches(port, (data_role == PD_ROLE_UFP)); + } void pd_check_pr_role(int port, int pr_role, int flags) diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 08deda0a06..e98187f669 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -1147,6 +1147,19 @@ static void pd_set_data_role(int port, int role) { pd[port].data_role = role; pd_execute_data_swap(port, role); + +#ifdef CONFIG_USBC_SS_MUX +#ifdef CONFIG_USBC_SS_MUX_DFP_ONLY + /* + * Need to connect SS mux for if new data role is DFP. + * If new data role is UFP, then disconnect the SS mux. + */ + board_set_usb_mux(port, role == PD_ROLE_DFP ? + TYPEC_MUX_USB : TYPEC_MUX_NONE, pd[port].polarity); +#else + board_set_usb_mux(port, TYPEC_MUX_USB, pd[port].polarity); +#endif +#endif } static void pd_dr_swap(int port) @@ -1853,7 +1866,6 @@ void pd_task(void) /* Initialize PD protocol state variables for each port. */ pd[port].power_role = PD_ROLE_DEFAULT; - pd_set_data_role(port, PD_ROLE_DEFAULT); pd[port].vdm_state = VDM_STATE_DONE; pd[port].flags = 0; set_state(port, PD_DEFAULT_STATE); @@ -1998,10 +2010,9 @@ void pd_task(void) pd[port].polarity = DFP_GET_POLARITY(cc1_volt, cc2_volt); pd_select_polarity(port, pd[port].polarity); -#ifdef CONFIG_USBC_SS_MUX - board_set_usb_mux(port, TYPEC_MUX_USB, - pd[port].polarity); -#endif + + /* initial data role for source is DFP */ + pd_set_data_role(port, PD_ROLE_DFP); #ifndef CONFIG_USBC_BACKWARDS_COMPATIBLE_DFP /* Enable VBUS */ if (pd_set_power_supply_ready(port)) { @@ -2012,8 +2023,6 @@ void pd_task(void) break; } #endif - /* initial data role for source is DFP */ - pd_set_data_role(port, PD_ROLE_DFP); #ifdef CONFIG_USBC_VCONN pd_set_vconn(port, pd[port].polarity, 1); diff --git a/include/config.h b/include/config.h index c5bfde79f6..88337a2b29 100644 --- a/include/config.h +++ b/include/config.h @@ -1310,6 +1310,12 @@ /* Support for USB type-c superspeed mux */ #undef CONFIG_USBC_SS_MUX +/* + * Only configure USB type-c superspeed mux when DFP (for chipsets that + * don't support being a UFP) + */ +#undef CONFIG_USBC_SS_MUX_DFP_ONLY + /* Support v1.1 type-C connection state machine */ #undef CONFIG_USBC_BACKWARDS_COMPATIBLE_DFP -- cgit v1.2.1