summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/cr50/board.h1
-rw-r--r--chip/g/build.mk1
-rw-r--r--chip/g/clock.c3
-rw-r--r--chip/g/rdd.c75
-rw-r--r--chip/g/usb.c14
-rw-r--r--include/config.h6
-rw-r--r--include/module_id.h13
-rw-r--r--include/usb_api.h7
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 */