diff options
author | Bill Richardson <wfrichar@chromium.org> | 2016-04-06 16:35:12 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-04-07 20:13:52 -0700 |
commit | 62cbb5cafe3cb4ec770c7c6ab0f19e86460f2a9c (patch) | |
tree | 0f1dcc28b162e4e52fbedda68635ff9e47bf8554 | |
parent | a5e74e6b45e2484fba2d7dc81ac054497d2576f3 (diff) | |
download | chrome-ec-62cbb5cafe3cb4ec770c7c6ab0f19e86460f2a9c.tar.gz |
Cr50: Add console command "usb" for testing
This adds a command to connect or disconnect, and to switch the
PHY between A or B.
BUG=chrome-os-partner:52055
BRANCH=none
TEST=make buildall; test on Cr50
Using a test board with both PHYs plugged in, try the various
commands:
usb off
usb on
usb a
usb b
The on/off option connects and disconnects, the a/b option
switches between PHYs. You can see the state change on the
console, or by running dmesg on the host.
Change-Id: I4c77e9c586ce197dc99b0b50af7396c253a1a377
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/337706
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r-- | chip/g/registers.h | 10 | ||||
-rw-r--r-- | chip/g/usb.c | 47 |
2 files changed, 44 insertions, 13 deletions
diff --git a/chip/g/registers.h b/chip/g/registers.h index 8841da9ba6..5ecd12fa34 100644 --- a/chip/g/registers.h +++ b/chip/g/registers.h @@ -357,12 +357,12 @@ static inline int x_timehs_addr(unsigned int module, unsigned int timer, * * The GP_OUT bit fields aren't defined elsewhere, so we'll define them here */ -#define GP_OUT(v) ((v << GC_USB_GGPIO_GPO_LSB) & GC_USB_GGPIO_GPO_MASK) -#define GP_IN(v) ((v << GC_USB_GGPIO_GPI_LSB) & GC_USB_GGPIO_GPI_MASK) +#define GP_OUT(v) (GC_USB_GGPIO_GPO_MASK & ((v) << GC_USB_GGPIO_GPO_LSB)) +#define GP_IN(v) (GC_USB_GGPIO_GPI_MASK & ((v) << GC_USB_GGPIO_GPI_LSB)) #define GGPIO_WRITE(reg, val) GP_OUT(((1 << 15) | /* write bit */ \ - ((val & 0xFF) << 4) | /* value */ \ - (reg & 0x0F))) /* register */ -#define GGPIO_READ(reg) (v & 0x0F) + (((val) & 0xFF) << 4) | /* value */ \ + ((reg) & 0x0F))) /* register */ +#define GGPIO_READ(reg) GP_OUT((reg) & 0x0F) /* register */ /* Further, the custom config registers for the USB module are: */ #define USB_CUSTOM_CFG_REG 0 /* register number */ diff --git a/chip/g/usb.c b/chip/g/usb.c index 9963f2dff7..104da0caf3 100644 --- a/chip/g/usb.c +++ b/chip/g/usb.c @@ -137,7 +137,7 @@ static void showbits(uint32_t b) ccprintf("\n"); } -static int command_usb(int argc, char **argv) +static void showregs(void) { ccprintf("GINTSTS: 0x%08x\n", GR_USB_GINTSTS); showbits(GR_USB_GINTSTS); @@ -154,12 +154,7 @@ static int command_usb(int argc, char **argv) ccprintf("DIEPCTL1: 0x%08x\n", GR_USB_DIEPCTL(1)); ccprintf("DOEPCTL2: 0x%08x\n", GR_USB_DOEPCTL(2)); ccprintf("DIEPCTL2: 0x%08x\n", GR_USB_DIEPCTL(2)); - return EC_SUCCESS; } -DECLARE_CONSOLE_COMMAND(usb, command_usb, - "", - "Show some USB regs", - NULL); /* When debugging, print errors as they occur */ #define report_error(val) \ @@ -168,6 +163,7 @@ DECLARE_CONSOLE_COMMAND(usb, command_usb, #else /* Not debugging */ #define print_later(...) +#define showregs(...) /* TODO: Something unexpected happened. Figure out how to report & fix it. */ #define report_error(val) \ @@ -316,6 +312,15 @@ static enum { } device_state; static uint8_t configuration_value; +/* Default PHY to use */ +static uint32_t which_phy = USB_SEL_PHY0; +static inline void select_phy(uint32_t phy) +{ + which_phy = phy; + GR_USB_GGPIO = GGPIO_WRITE(USB_CUSTOM_CFG_REG, + (USB_PHY_ACTIVE | which_phy)); +} + /* Reset all this to a good starting state. */ static void initialize_dma_buffers(void) { @@ -707,6 +712,7 @@ static int handle_setup_with_no_data_stage(enum table_case tc, * doesn't respond to anything. */ GWRITE_FIELD(USB, DCFG, DEVADDR, set_addr); + CPRINTS("SETAD 0x%02x (%d)", set_addr, set_addr); print_later("SETAD 0x%02x (%d)", set_addr, set_addr, 0, 0, 0); device_state = DS_ADDRESS; break; @@ -1048,6 +1054,7 @@ static void usb_init_endpoints(void) static void usb_reset(void) { + CPRINTS("%s", __func__); print_later("usb_reset()", 0, 0, 0, 0, 0); /* Clear our internal state */ @@ -1174,12 +1181,14 @@ static void usb_softreset(void) void usb_connect(void) { + CPRINTS("%s", __func__); print_later("usb_connect()", 0, 0, 0, 0, 0); GR_USB_DCTL &= ~DCTL_SFTDISCON; } void usb_disconnect(void) { + CPRINTS("%s", __func__); print_later("usb_disconnect()", 0, 0, 0, 0, 0); GR_USB_DCTL |= DCTL_SFTDISCON; @@ -1228,8 +1237,7 @@ void usb_init(void) GR_USB_DOEPMSK = 0; /* Select the correct PHY */ - GR_USB_GGPIO = GGPIO_WRITE(USB_CUSTOM_CFG_REG, - (USB_PHY_ACTIVE | USB_SEL_PHY0)); + select_phy(which_phy); /* Full-Speed Serial PHY */ GR_USB_GUSBCFG = GUSBCFG_PHYSEL_FS | GUSBCFG_FSINTF_6PIN @@ -1345,3 +1353,26 @@ void usb_release(void) /* USB is off, so sleep whenever */ enable_sleep(SLEEP_MASK_USB_DEVICE); } + +static int command_usb(int argc, char **argv) +{ + if (argc > 1) { + if (!strcasecmp("on", argv[1])) + usb_init(); + else if (!strcasecmp("off", argv[1])) + usb_release(); + else if (!strcasecmp("a", argv[1])) + select_phy(USB_SEL_PHY0); + else if (!strcasecmp("b", argv[1])) + select_phy(USB_SEL_PHY1); + } + + showregs(); + ccprintf("PHY %c\n", (which_phy == USB_SEL_PHY0 ? 'A' : 'B')); + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(usb, command_usb, + "[on|off|a|b]", + "Get/set the USB connection state and PHY selection", + NULL); |