diff options
-rw-r--r-- | board/cr50/board.h | 1 | ||||
-rw-r--r-- | chip/g/build.mk | 1 | ||||
-rw-r--r-- | chip/g/clock.c | 3 | ||||
-rw-r--r-- | chip/g/rdd.c | 75 | ||||
-rw-r--r-- | chip/g/usb.c | 14 | ||||
-rw-r--r-- | include/config.h | 6 | ||||
-rw-r--r-- | include/module_id.h | 13 | ||||
-rw-r--r-- | include/usb_api.h | 7 |
8 files changed, 110 insertions, 10 deletions
diff --git a/board/cr50/board.h b/board/cr50/board.h index 3857515714..86942a068a 100644 --- a/board/cr50/board.h +++ b/board/cr50/board.h @@ -28,6 +28,7 @@ #define CONFIG_USB #define CONFIG_USB_HID #define CONFIG_USB_CONSOLE +#define CONFIG_USB_SELECT_PHY #define CONFIG_STREAM_USART #define CONFIG_STREAM_USB diff --git a/chip/g/build.mk b/chip/g/build.mk index 9ba32a9964..6a279417a8 100644 --- a/chip/g/build.mk +++ b/chip/g/build.mk @@ -50,6 +50,7 @@ chip-$(CONFIG_USB)+=usb.o usb_endpoints.o chip-$(CONFIG_USB_CONSOLE)+=usb_console.o chip-$(CONFIG_USB_HID)+=usb_hid.o chip-$(CONFIG_USB_BLOB)+=blob.o +chip-$(CONFIG_RDD)+=rdd.o chip-$(CONFIG_STREAM_USB)+=usb-stream.o chip-$(CONFIG_STREAM_USART)+=usart.o diff --git a/chip/g/clock.c b/chip/g/clock.c index 8903b9b5b0..25e93b0367 100644 --- a/chip/g/clock.c +++ b/chip/g/clock.c @@ -30,6 +30,9 @@ void clock_enable_module(enum module_id module, int enable) clock_func(PERIPH_I2C0); clock_func(PERIPH_I2C1); break; + case MODULE_RDD: + clock_func(PERIPH_RDD0); + break; case MODULE_SPI_FLASH: case MODULE_SPI_MASTER: clock_func(PERIPH_SPI); diff --git a/chip/g/rdd.c b/chip/g/rdd.c new file mode 100644 index 0000000000..63df750484 --- /dev/null +++ b/chip/g/rdd.c @@ -0,0 +1,75 @@ +/* Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "clock.h" +#include "console.h" +#include "gpio.h" +#include "hooks.h" +#include "registers.h" +#include "task.h" +#include "usb_api.h" + +#define CCD_PHY USB_SEL_PHY1 +#define AP_PHY USB_SEL_PHY0 + +uint16_t ccd_detect; + +static int debug_cable_is_detected(void) +{ + uint8_t cc1 = GREAD_FIELD(RDD, INPUT_PIN_VALUES, CC1); + uint8_t cc2 = GREAD_FIELD(RDD, INPUT_PIN_VALUES, CC2); + + return (cc1 == cc2 && (cc1 == 3 || cc1 == 1)); +} + +void rdd_interrupt(void) +{ + if (debug_cable_is_detected()) { + ccprintf("Debug Accessory connected\n"); + /* Detect when debug cable is disconnected */ + GWRITE(RDD, PROG_DEBUG_STATE_MAP, ~ccd_detect); + + /* Select the CCD PHY */ + usb_select_phy(CCD_PHY); + } else { + ccprintf("Debug Accessory disconnected\n"); + /* Detect when debug cable is connected */ + GWRITE(RDD, PROG_DEBUG_STATE_MAP, ccd_detect); + + /* Select the AP PHY */ + usb_select_phy(AP_PHY); + } + + /* Connect to selected phy */ + usb_init(); + + /* Clear interrupt */ + GWRITE_FIELD(RDD, INT_STATE, INTR_DEBUG_STATE_DETECTED, 1); +} +DECLARE_IRQ(GC_IRQNUM_RDD0_INTR_DEBUG_STATE_DETECTED_INT, rdd_interrupt, 1); + +void rdd_init(void) +{ + /* Enable RDD */ + clock_enable_module(MODULE_RDD, 1); + GWRITE(RDD, POWER_DOWN_B, 1); + + ccd_detect = GREAD(RDD, PROG_DEBUG_STATE_MAP); + /* Detect cable disconnect if CCD is enabled */ + if (usb_get_phy() == CCD_PHY) + GWRITE(RDD, PROG_DEBUG_STATE_MAP, ~ccd_detect); + + /* Enable RDD interrupts */ + task_enable_irq(GC_IRQNUM_RDD0_INTR_DEBUG_STATE_DETECTED_INT); + GWRITE_FIELD(RDD, INT_ENABLE, INTR_DEBUG_STATE_DETECTED, 1); +} +DECLARE_HOOK(HOOK_INIT, rdd_init, HOOK_PRIO_DEFAULT); + +static int command_test_rdd(int argc, char **argv) +{ + GWRITE_FIELD(RDD, INT_TEST, INTR_DEBUG_STATE_DETECTED, 1); + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(test_rdd, command_test_rdd, "", "", NULL); diff --git a/chip/g/usb.c b/chip/g/usb.c index eeebd18470..4501aa6496 100644 --- a/chip/g/usb.c +++ b/chip/g/usb.c @@ -314,13 +314,19 @@ static uint8_t configuration_value; /* Default PHY to use */ static uint32_t which_phy = USB_SEL_PHY1; -static inline void select_phy(uint32_t phy) + +void usb_select_phy(uint32_t phy) { which_phy = phy; GR_USB_GGPIO = GGPIO_WRITE(USB_CUSTOM_CFG_REG, (USB_PHY_ACTIVE | which_phy)); } +uint32_t usb_get_phy(void) +{ + return which_phy; +} + /* Reset all this to a good starting state. */ static void initialize_dma_buffers(void) { @@ -1237,7 +1243,7 @@ void usb_init(void) GR_USB_DOEPMSK = 0; /* Select the correct PHY */ - select_phy(which_phy); + usb_select_phy(which_phy); gpio_set_level(GPIO_CCD_MODE_L, !(which_phy == USB_SEL_PHY1)); /* Full-Speed Serial PHY */ @@ -1363,9 +1369,9 @@ static int command_usb(int argc, char **argv) else if (!strcasecmp("off", argv[1])) usb_release(); else if (!strcasecmp("a", argv[1])) - select_phy(USB_SEL_PHY0); + usb_select_phy(USB_SEL_PHY0); else if (!strcasecmp("b", argv[1])) - select_phy(USB_SEL_PHY1); + usb_select_phy(USB_SEL_PHY1); } showregs(); diff --git a/include/config.h b/include/config.h index 3b61e679f0..213ae6ee11 100644 --- a/include/config.h +++ b/include/config.h @@ -1480,6 +1480,9 @@ /* Size of RAM available on the chip, in bytes */ #undef CONFIG_RAM_SIZE +/* Enable RDD peripheral */ +#undef CONFIG_RDD + /* Support IR357x Link voltage regulator debugging / reprogramming */ #undef CONFIG_REGULATOR_IR357X @@ -1945,6 +1948,9 @@ /* Disable automatic initialization of USB peripheral */ #undef CONFIG_USB_INHIBIT_INIT +/* Support control of multiple PHY */ +#undef CONFIG_USB_SELECT_PHY + /* Support simple control of power to the device's USB ports */ #undef CONFIG_USB_PORT_POWER_DUMB diff --git a/include/module_id.h b/include/module_id.h index b4c1191a68..8697cbdd85 100644 --- a/include/module_id.h +++ b/include/module_id.h @@ -32,21 +32,22 @@ enum module_id { MODULE_PORT80, MODULE_POWER_LED, MODULE_PWM, /* 20 */ + MODULE_RDD, MODULE_SPI, MODULE_SPI_FLASH, MODULE_SPI_MASTER, - MODULE_SWITCH, - MODULE_SYSTEM, /* 25 */ + MODULE_SWITCH, /* 25 */ + MODULE_SYSTEM, MODULE_TASK, MODULE_THERMAL, MODULE_UART, - MODULE_USART, - MODULE_USB, /* 30 */ + MODULE_USART, /* 30 */ + MODULE_USB, MODULE_USB_DEBUG, MODULE_USB_PD, MODULE_USB_PORT_POWER, - MODULE_USB_SWITCH, - MODULE_VBOOT, /* 35 */ + MODULE_USB_SWITCH, /* 35 */ + MODULE_VBOOT, /* Module count; not an actual module */ MODULE_COUNT diff --git a/include/usb_api.h b/include/usb_api.h index c73360fce0..c2e365cf28 100644 --- a/include/usb_api.h +++ b/include/usb_api.h @@ -42,4 +42,11 @@ void usb_disconnect(void); */ void usb_release(void); +#ifdef CONFIG_USB_SELECT_PHY +/* Select which PHY to use. */ +void usb_select_phy(uint32_t phy); + +/* Get the current PHY */ +uint32_t usb_get_phy(void); +#endif #endif /* __CROS_EC_USB_API_H */ |