diff options
author | Mary Ruthven <mruthven@chromium.org> | 2016-04-12 11:46:16 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-04-13 20:10:38 -0700 |
commit | d281308b4897ebd8cee38542bf690e4dee53e650 (patch) | |
tree | d86c9db1da9881d4082e40611a15b8386e60837c /chip/g/rdd.c | |
parent | 0374c599afdc9c13c22b4842266eade8d1afaf83 (diff) | |
download | chrome-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.c | 75 |
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); |