diff options
author | Alec Berg <alecaberg@chromium.org> | 2015-05-04 10:44:52 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-05-05 03:36:24 +0000 |
commit | 828086e961c0107bbdd65fa1086c082e95c912fc (patch) | |
tree | 63dd7a3750d5f1bc13ad0f0787d5822dd422d253 | |
parent | 1abcdf9145eaa4508546190f76577289dcd04803 (diff) | |
download | chrome-ec-828086e961c0107bbdd65fa1086c082e95c912fc.tar.gz |
pd: add explicit setting of D+/D- switch when setting type-C muxes
Add explicit setting of USB D+/D- switch when setting the type-C
muxes. This fixes a bug in which we would open D+/D- switch when
entering DP mode and lose USB2.0 connection.
BUG=chrome-os-partner:39766
BRANCH=samus
TEST=add printf to board_set_usb_switches() on samus and make sure
we don't open the D+/D- switch when entering DP mode.
Change-Id: I2b5bb2185298794ddb4cc457f3695ce6adabd9f8
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/268993
Reviewed-by: Todd Broch <tbroch@chromium.org>
Tested-by: Todd Broch <tbroch@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Scott Collyer <scollyer@chromium.org>
-rw-r--r-- | board/fruitpie/board.c | 3 | ||||
-rw-r--r-- | board/fruitpie/usb_pd_config.h | 2 | ||||
-rw-r--r-- | board/fruitpie/usb_pd_policy.c | 3 | ||||
-rw-r--r-- | board/honeybuns/board.c | 3 | ||||
-rw-r--r-- | board/honeybuns/usb_pd_policy.c | 3 | ||||
-rw-r--r-- | board/ryu/board.c | 3 | ||||
-rw-r--r-- | board/ryu/usb_pd_config.h | 2 | ||||
-rw-r--r-- | board/ryu_p4p5/board.c | 3 | ||||
-rw-r--r-- | board/ryu_p4p5/usb_pd_config.h | 2 | ||||
-rw-r--r-- | board/samus_pd/board.c | 11 | ||||
-rw-r--r-- | board/samus_pd/usb_pd_config.h | 2 | ||||
-rw-r--r-- | board/samus_pd/usb_pd_policy.c | 4 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 23 | ||||
-rw-r--r-- | include/usb_pd.h | 8 |
14 files changed, 50 insertions, 22 deletions
diff --git a/board/fruitpie/board.c b/board/fruitpie/board.c index f03d8546db..ab6289b5b2 100644 --- a/board/fruitpie/board.c +++ b/board/fruitpie/board.c @@ -183,7 +183,8 @@ static int command_debug(int argc, char **argv) } DECLARE_CONSOLE_COMMAND(debugset, command_debug, NULL, "Set debug mode", NULL); -void board_set_usb_mux(int port, enum typec_mux mux, int polarity) +void board_set_usb_mux(int port, enum typec_mux mux, + enum usb_switch usb, int polarity) { /* reset everything */ gpio_set_level(GPIO_SS1_EN_L, 1); diff --git a/board/fruitpie/usb_pd_config.h b/board/fruitpie/usb_pd_config.h index e2f184f9d9..c3e11ec7e1 100644 --- a/board/fruitpie/usb_pd_config.h +++ b/board/fruitpie/usb_pd_config.h @@ -155,7 +155,7 @@ static inline void pd_config_init(int port, uint8_t power_role) pd_tx_init(); /* Reset mux ... for NONE polarity doesn't matter */ - board_set_usb_mux(port, TYPEC_MUX_NONE, 0); + board_set_usb_mux(port, TYPEC_MUX_NONE, USB_SWITCH_DISCONNECT, 0); gpio_set_level(GPIO_VCONN1_EN, 0); gpio_set_level(GPIO_VCONN2_EN, 0); diff --git a/board/fruitpie/usb_pd_policy.c b/board/fruitpie/usb_pd_policy.c index bf49a0ce64..4c6eb7d798 100644 --- a/board/fruitpie/usb_pd_policy.c +++ b/board/fruitpie/usb_pd_policy.c @@ -198,7 +198,8 @@ static int svdm_dp_status(int port, uint32_t *payload) static int svdm_dp_config(int port, uint32_t *payload) { - board_set_usb_mux(port, TYPEC_MUX_DP, pd_get_polarity(port)); + board_set_usb_mux(port, TYPEC_MUX_DP, USB_SWITCH_CONNECT, + pd_get_polarity(port)); dp_on = 1; payload[0] = VDO(USB_SID_DISPLAYPORT, 1, CMD_DP_CONFIG); payload[1] = VDO_DP_CFG(MODE_DP_PIN_E, /* sink pins */ diff --git a/board/honeybuns/board.c b/board/honeybuns/board.c index 396e98b08e..b58ca7e075 100644 --- a/board/honeybuns/board.c +++ b/board/honeybuns/board.c @@ -88,7 +88,8 @@ BUILD_ASSERT(ARRAY_SIZE(usb_strings) == USB_STR_COUNT); -void board_set_usb_mux(int port, enum typec_mux mux, int polarity) +void board_set_usb_mux(int port, enum typec_mux mux, + enum usb_switch usb, int polarity) { if (mux == TYPEC_MUX_NONE) { diff --git a/board/honeybuns/usb_pd_policy.c b/board/honeybuns/usb_pd_policy.c index 67d39cbf68..22433b318a 100644 --- a/board/honeybuns/usb_pd_policy.c +++ b/board/honeybuns/usb_pd_policy.c @@ -209,7 +209,8 @@ static int svdm_dp_status(int port, uint32_t *payload) static int svdm_dp_config(int port, uint32_t *payload) { - board_set_usb_mux(port, TYPEC_MUX_DP, pd_get_polarity(port)); + board_set_usb_mux(port, TYPEC_MUX_DP, USB_SWITCH_CONNECT, + pd_get_polarity(port)); dp_on = 1; payload[0] = VDO(USB_SID_DISPLAYPORT, 1, CMD_DP_CONFIG); payload[1] = VDO_DP_CFG(MODE_DP_PIN_E, /* sink pins */ diff --git a/board/ryu/board.c b/board/ryu/board.c index bee0c931b5..3ee91889d7 100644 --- a/board/ryu/board.c +++ b/board/ryu/board.c @@ -372,7 +372,8 @@ const struct i2c_port_t i2c_ports[] = { }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); -void board_set_usb_mux(int port, enum typec_mux mux, int polarity) +void board_set_usb_mux(int port, enum typec_mux mux, + enum usb_switch usb, int polarity) { /* reset everything */ gpio_set_level(GPIO_USBC_MUX_CONF0, 0); diff --git a/board/ryu/usb_pd_config.h b/board/ryu/usb_pd_config.h index 95828a5c46..032611c34a 100644 --- a/board/ryu/usb_pd_config.h +++ b/board/ryu/usb_pd_config.h @@ -173,7 +173,7 @@ static inline void pd_config_init(int port, uint8_t power_role) pd_tx_init(); /* Reset mux ... for NONE polarity doesn't matter */ - board_set_usb_mux(port, TYPEC_MUX_NONE, 0); + board_set_usb_mux(port, TYPEC_MUX_NONE, USB_SWITCH_DISCONNECT, 0); gpio_set_level(GPIO_USBC_VCONN1_EN_L, 1); gpio_set_level(GPIO_USBC_VCONN2_EN_L, 1); diff --git a/board/ryu_p4p5/board.c b/board/ryu_p4p5/board.c index 976c546de2..19daf6c587 100644 --- a/board/ryu_p4p5/board.c +++ b/board/ryu_p4p5/board.c @@ -405,7 +405,8 @@ void p4_board_set_usb_mux(int port, enum typec_mux mux, int polarity) gpio_set_level(GPIO_USBC_SS_EN_L, 0); } -void board_set_usb_mux(int port, enum typec_mux mux, int polarity) +void board_set_usb_mux(int port, enum typec_mux mux, + enum usb_switch usb, int polarity) { if (board_get_version() < 5) { /* P4/EVT or older boards */ diff --git a/board/ryu_p4p5/usb_pd_config.h b/board/ryu_p4p5/usb_pd_config.h index 8ab1017e3f..a100ddb2ac 100644 --- a/board/ryu_p4p5/usb_pd_config.h +++ b/board/ryu_p4p5/usb_pd_config.h @@ -176,7 +176,7 @@ static inline void pd_config_init(int port, uint8_t power_role) pd_tx_init(); /* Reset mux ... for NONE polarity doesn't matter */ - board_set_usb_mux(port, TYPEC_MUX_NONE, 0); + board_set_usb_mux(port, TYPEC_MUX_NONE, USB_SWITCH_DISCONNECT, 0); gpio_set_level(GPIO_USBC_VCONN1_EN_L, 1); gpio_set_level(GPIO_USBC_VCONN2_EN_L, 1); diff --git a/board/samus_pd/board.c b/board/samus_pd/board.c index 13ccc90d37..165c8ebe4f 100644 --- a/board/samus_pd/board.c +++ b/board/samus_pd/board.c @@ -553,6 +553,9 @@ BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == PD_PORT_COUNT); static void board_set_usb_switches(int port, int open) { + /* If switch is not changing, then return */ + if (open == usb_switch_state[port]) + return; mutex_lock(&usb_switch_lock[port]); usb_switch_state[port] = open; @@ -560,7 +563,8 @@ static void board_set_usb_switches(int port, int open) mutex_unlock(&usb_switch_lock[port]); } -void board_set_usb_mux(int port, enum typec_mux mux, int polarity) +void board_set_usb_mux(int port, enum typec_mux mux, + enum usb_switch usb, int polarity) { const struct usb_port_mux *usb_mux = usb_muxes + port; @@ -572,9 +576,8 @@ 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); + /* Set D+/D- switch to appropriate level */ + board_set_usb_switches(port, usb); if (mux == TYPEC_MUX_NONE) /* everything is already disabled, we can return */ diff --git a/board/samus_pd/usb_pd_config.h b/board/samus_pd/usb_pd_config.h index a7df33e499..b655c8e914 100644 --- a/board/samus_pd/usb_pd_config.h +++ b/board/samus_pd/usb_pd_config.h @@ -247,7 +247,7 @@ static inline void pd_config_init(int port, uint8_t power_role) pd_tx_init(); /* Reset mux ... for NONE polarity doesn't matter */ - board_set_usb_mux(port, TYPEC_MUX_NONE, 0); + board_set_usb_mux(port, TYPEC_MUX_NONE, USB_SWITCH_DISCONNECT, 0); if (port == 0) { gpio_set_level(GPIO_USB_C0_CC1_VCONN1_EN_L, 1); diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c index 431c281b1e..05df870be9 100644 --- a/board/samus_pd/usb_pd_policy.c +++ b/board/samus_pd/usb_pd_policy.c @@ -264,7 +264,7 @@ static uint32_t dp_status[PD_PORT_COUNT]; static void svdm_safe_dp_mode(int port) { /* make DP interface safe until configure */ - board_set_usb_mux(port, TYPEC_MUX_NONE, pd_get_polarity(port)); + board_set_usb_mux(port, TYPEC_MUX_NONE, USB_SWITCH_CONNECT, 0); dp_flags[port] = 0; dp_status[port] = 0; } @@ -306,7 +306,7 @@ static int svdm_dp_config(int port, uint32_t *payload) return 0; board_set_usb_mux(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - pd_get_polarity(port)); + USB_SWITCH_CONNECT, pd_get_polarity(port)); payload[0] = VDO(USB_SID_DISPLAYPORT, 1, CMD_DP_CONFIG | VDO_OPOS(opos)); diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index e98187f669..26a9f99803 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -397,7 +397,7 @@ static inline void set_state(int port, enum pd_states next_state) pd_dfp_exit_mode(port, 0, 0); #endif #ifdef CONFIG_USBC_SS_MUX - board_set_usb_mux(port, TYPEC_MUX_NONE, + board_set_usb_mux(port, TYPEC_MUX_NONE, USB_SWITCH_DISCONNECT, pd[port].polarity); #endif #ifdef CONFIG_USBC_VCONN @@ -1154,10 +1154,15 @@ static void pd_set_data_role(int port, int role) * 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); + if (role == PD_ROLE_DFP) + board_set_usb_mux(port, TYPEC_MUX_USB, USB_SWITCH_CONNECT, + pd[port].polarity); + else + board_set_usb_mux(port, TYPEC_MUX_NONE, USB_SWITCH_DISCONNECT, + pd[port].polarity); #else - board_set_usb_mux(port, TYPEC_MUX_USB, pd[port].polarity); + board_set_usb_mux(port, TYPEC_MUX_USB, USB_SWITCH_CONNECT, + pd[port].polarity); #endif #endif } @@ -2018,6 +2023,7 @@ void pd_task(void) if (pd_set_power_supply_ready(port)) { #ifdef CONFIG_USBC_SS_MUX board_set_usb_mux(port, TYPEC_MUX_NONE, + USB_SWITCH_DISCONNECT, pd[port].polarity); #endif break; @@ -2045,6 +2051,7 @@ void pd_task(void) #ifdef CONFIG_USBC_SS_MUX board_set_usb_mux(port, TYPEC_MUX_USB, + USB_SWITCH_CONNECT, pd[port].polarity); #endif @@ -3369,7 +3376,10 @@ static int command_typec(int argc, char **argv) for (i = 0; i < ARRAY_SIZE(mux_name); i++) if (!strcasecmp(argv[2], mux_name[i])) mux = i; - board_set_usb_mux(port, mux, pd_get_polarity(port)); + board_set_usb_mux(port, mux, mux == TYPEC_MUX_NONE ? + USB_SWITCH_DISCONNECT : + USB_SWITCH_CONNECT, + pd_get_polarity(port)); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(typec, command_typec, @@ -3429,6 +3439,9 @@ static int hc_usb_pd_control(struct host_cmd_handler_args *args) #ifdef CONFIG_USBC_SS_MUX if (p->mux != USB_PD_CTRL_MUX_NO_CHANGE) board_set_usb_mux(p->port, typec_mux_map[p->mux], + typec_mux_map[p->mux] == TYPEC_MUX_NONE ? + USB_SWITCH_DISCONNECT : + USB_SWITCH_CONNECT, pd_get_polarity(p->port)); #endif /* CONFIG_USBC_SS_MUX */ diff --git a/include/usb_pd.h b/include/usb_pd.h index 30e25d949a..d957761ac5 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -1135,6 +1135,11 @@ enum typec_mux { TYPEC_MUX_DOCK, }; +enum usb_switch { + USB_SWITCH_CONNECT, + USB_SWITCH_DISCONNECT, +}; + /** * Configure superspeed muxes on type-C port. * @@ -1142,7 +1147,8 @@ enum typec_mux { * @param mux selected function. * @param polarity plug polarity (0=CC1, 1=CC2). */ -void board_set_usb_mux(int port, enum typec_mux mux, int polarity); +void board_set_usb_mux(int port, enum typec_mux mux, + enum usb_switch usb, int polarity); /** * Query superspeed mux status on type-C port. |