summaryrefslogtreecommitdiff
path: root/chip/g/rdd.c
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@chromium.org>2016-04-12 11:46:16 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-04-13 20:10:38 -0700
commitd281308b4897ebd8cee38542bf690e4dee53e650 (patch)
treed86c9db1da9881d4082e40611a15b8386e60837c /chip/g/rdd.c
parent0374c599afdc9c13c22b4842266eade8d1afaf83 (diff)
downloadchrome-ec-d281308b4897ebd8cee38542bf690e4dee53e650.tar.gz
cr50: Detect debug cable and switch the PHY
This adds support for RD Detection on cr50. It can be used to detect a debug device and signal the controller to switch from the AP PHY to the to CCD PHY. When RDCC1 and 2 no longer detect the debug device, then the controller switches back to using the USB to AP PHY. BUG=chrome-os-partner:50700 BRANCH=none TEST=change the value on RDCC1 and RDCC1 and check that the usb controller connects to the right PHY. Change-Id: Ice01a45a31fe1932945f89df2e3b851f4d287a17 Signed-off-by: Mary Ruthven <mruthven@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/338454 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Diffstat (limited to 'chip/g/rdd.c')
-rw-r--r--chip/g/rdd.c75
1 files changed, 75 insertions, 0 deletions
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);