diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2015-06-24 15:45:24 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-06-26 18:57:40 +0000 |
commit | 5c1bb2174cb7a92799779f7a273aa63052420c4b (patch) | |
tree | a2626883b51b8d1e084991c2d9bcc86496d8d422 | |
parent | 957638c78cc5aa0ba37ef281e2c6a09215c5d60e (diff) | |
download | chrome-ec-5c1bb2174cb7a92799779f7a273aa63052420c4b.tar.gz |
honeybuns: manage USB and DP hardware
Get the USB hub out of reset only when there is a USB host,
same thing for the DisplayPort hardware.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=none
BUG=chrome-os-partner:37078
TEST=Plug and un-plug Honeybuns to Samus. See both the USB devices
connected and the external display.
Change-Id: Iabbeb0650d18c4c0c3324f47d99f9aaa35601c16
Reviewed-on: https://chromium-review.googlesource.com/281927
Trybot-Ready: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | board/honeybuns/board.c | 17 | ||||
-rw-r--r-- | board/honeybuns/board.h | 3 | ||||
-rw-r--r-- | board/honeybuns/ec.tasklist | 1 | ||||
-rw-r--r-- | board/honeybuns/gpio.inc | 6 | ||||
-rw-r--r-- | board/honeybuns/hx3.c | 63 |
5 files changed, 66 insertions, 24 deletions
diff --git a/board/honeybuns/board.c b/board/honeybuns/board.c index b58ca7e075..d7d504a581 100644 --- a/board/honeybuns/board.c +++ b/board/honeybuns/board.c @@ -85,9 +85,6 @@ const void * const usb_strings[] = { }; BUILD_ASSERT(ARRAY_SIZE(usb_strings) == USB_STR_COUNT); - - - void board_set_usb_mux(int port, enum typec_mux mux, enum usb_switch usb, int polarity) { @@ -95,9 +92,17 @@ void board_set_usb_mux(int port, enum typec_mux mux, if (mux == TYPEC_MUX_NONE) { /* put the mux in the high impedance state */ gpio_set_level(GPIO_SS_MUX_OE_L, 1); + /* Disable display hardware */ + gpio_set_level(GPIO_BRIDGE_RESET_L, 0); + gpio_set_level(GPIO_SPLITTER_RESET_L, 0); + /* Put the USB hub under reset */ + hx3_enable(0); return; } + /* Trigger USB Hub configuration */ + hx3_enable(1); + if ((mux == TYPEC_MUX_DOCK) || (mux == TYPEC_MUX_USB)) { /* Low selects USB Dock */ gpio_set_level(GPIO_SS_MUX_SEL, 0); @@ -108,6 +113,12 @@ void board_set_usb_mux(int port, enum typec_mux mux, /* clear OE line to make mux active */ gpio_set_level(GPIO_SS_MUX_OE_L, 0); + + if (mux != TYPEC_MUX_USB) { + /* Enable display hardware */ + gpio_set_level(GPIO_BRIDGE_RESET_L, 1); + gpio_set_level(GPIO_SPLITTER_RESET_L, 1); + } } int board_get_usb_mux(int port, const char **dp_str, const char **usb_str) diff --git a/board/honeybuns/board.h b/board/honeybuns/board.h index 085c057d91..e527e9f367 100644 --- a/board/honeybuns/board.h +++ b/board/honeybuns/board.h @@ -100,6 +100,9 @@ enum usb_strings { #define PD_MAX_CURRENT_MA 3000 #define PD_MAX_VOLTAGE_MV 20000 +/* Enable/disable USB Hub */ +void hx3_enable(int enable); + #endif /* !__ASSEMBLER__ */ /* USB interface indexes (use define rather than enum to expand them) */ diff --git a/board/honeybuns/ec.tasklist b/board/honeybuns/ec.tasklist index 72649e8217..ad72bfe7bb 100644 --- a/board/honeybuns/ec.tasklist +++ b/board/honeybuns/ec.tasklist @@ -18,5 +18,6 @@ */ #define CONFIG_TASK_LIST \ TASK_ALWAYS(HOOKS, hook_task, NULL, TASK_STACK_SIZE) \ + TASK_ALWAYS(USBCFG, hx3_task, NULL, TASK_STACK_SIZE) \ TASK_ALWAYS(CONSOLE, console_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_ALWAYS(PD, pd_task, NULL, TASK_STACK_SIZE) diff --git a/board/honeybuns/gpio.inc b/board/honeybuns/gpio.inc index e18f30ff11..c6a8ffdf08 100644 --- a/board/honeybuns/gpio.inc +++ b/board/honeybuns/gpio.inc @@ -26,9 +26,9 @@ GPIO(SS_MUX_SEL, PIN(B, 14), GPIO_OUT_LOW) GPIO(PD_SBU_ENABLE, PIN(A, 7), GPIO_OUT_LOW) /* Chip Resets */ -GPIO(BRIDGE_RESET_L, PIN(B, 0), GPIO_OUT_HIGH) -GPIO(SPLITTER_RESET_L, PIN(B, 1), GPIO_OUT_HIGH) -GPIO(HUB_RESET_L, PIN(B, 15), GPIO_OUT_HIGH) +GPIO(BRIDGE_RESET_L, PIN(B, 0), GPIO_OUT_LOW) +GPIO(SPLITTER_RESET_L, PIN(B, 1), GPIO_OUT_LOW) +GPIO(HUB_RESET_L, PIN(B, 15), GPIO_OUT_LOW) /* diff --git a/board/honeybuns/hx3.c b/board/honeybuns/hx3.c index df9bcfe121..7944035bce 100644 --- a/board/honeybuns/hx3.c +++ b/board/honeybuns/hx3.c @@ -10,6 +10,7 @@ #include "gpio.h" #include "hooks.h" #include "i2c.h" +#include "task.h" #include "timer.h" #include "usb.h" #include "util.h" @@ -69,44 +70,70 @@ const uint8_t hx3_settings[5 + HX3_SETTINGS_SIZE] = { /* Free space for more strings */ }; -static void configure_hx3(void) +static int hx3_configured; + +static int configure_hx3(void) { int ret; int remaining, len; uint8_t *data = (uint8_t *)hx3_settings; uint16_t addr = 0x0000; - - /* Reset the bridge to put it back in bootloader mode */ - gpio_set_level(GPIO_HUB_RESET_L, 0); - /* Keep the reset low at least 10ms (same as the RC) */ - msleep(50); - gpio_set_level(GPIO_HUB_RESET_L, 1); - msleep(50); + int success = 1; remaining = sizeof(hx3_settings); - while (remaining) { + while (remaining && gpio_get_level(GPIO_HUB_RESET_L)) { /* do 64-byte Page Write */ len = MIN(remaining, 64); - i2c_lock(0, 1); + i2c_lock(I2C_PORT_MASTER, 1); /* send Page Write address */ - ret = i2c_xfer(0, HX3_I2C_ADDR, (uint8_t *)&addr, 2, - NULL, 0, I2C_XFER_START); + ret = i2c_xfer(I2C_PORT_MASTER, HX3_I2C_ADDR, + (uint8_t *)&addr, 2, NULL, 0, I2C_XFER_START); /* send page data */ - ret |= i2c_xfer(0, HX3_I2C_ADDR, data, len, - NULL, 0, I2C_XFER_STOP); - i2c_lock(0, 0); - if (ret != EC_SUCCESS) + ret |= i2c_xfer(I2C_PORT_MASTER, HX3_I2C_ADDR, + data, len, NULL, 0, I2C_XFER_STOP); + i2c_lock(I2C_PORT_MASTER, 0); + if (ret != EC_SUCCESS) { + success = 0; ccprintf("HX3 transfer failed %d\n", ret); + break; + } remaining -= len; data += len; } + return gpio_get_level(GPIO_HUB_RESET_L) ? success : 0; } -DECLARE_HOOK(HOOK_INIT, configure_hx3, HOOK_PRIO_DEFAULT); +void hx3_task(void) +{ + while (1) { + task_wait_event(-1); + if (!hx3_configured && gpio_get_level(GPIO_HUB_RESET_L)) { + /* wait for the HX3 to come out of reset */ + msleep(5); + hx3_configured = configure_hx3(); + } + } +} + +void hx3_enable(int enable) +{ + /* Release reset when the Hub is enabled */ + gpio_set_level(GPIO_HUB_RESET_L, !!enable); + /* Trigger I2C configuration if needed */ + if (enable) + task_wake(TASK_ID_USBCFG); + else + hx3_configured = 0; +} static int command_hx3(int argc, char **argv) { - configure_hx3(); + /* Reset the bridge to put it back in bootloader mode */ + hx3_enable(0); + /* Keep the reset low at least 10ms (same as the RC) */ + msleep(50); + /* Release reset and wait for the hub to come up */ + hx3_enable(1); return EC_SUCCESS; } |