summaryrefslogtreecommitdiff
path: root/board/plankton/board.c
diff options
context:
space:
mode:
authorTodd Broch <tbroch@chromium.org>2014-11-12 16:32:02 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-05-01 01:08:10 +0000
commit7cc3136da56eaea8cfa7f9139ebaf6361707ade2 (patch)
tree9a66caa15bf4a2df6954c592ca6978a1bda1ad11 /board/plankton/board.c
parent56653dec06ede2c62ec35c74f0e133f18dd7ea50 (diff)
downloadchrome-ec-7cc3136da56eaea8cfa7f9139ebaf6361707ade2.tar.gz
plankton: HPD over USB PD.
HPD needs to be transported over USB PD as both SBU lines are consumed for differential AUX signalling. This CL does the following: 1. Enables GPIO DPSRC_HPD as interrupt. 2. Sends debounced HPD across CC via the SVDM DP status message. 3. Adds polling for GPIO_DBG_20V_TO_DUT_L as it shares the same interrupt as DPSRC_HPD. 4. Configures DP redriver in presence of HPD high. Signed-off-by: Todd Broch <tbroch@chromium.org> BRANCH=none BUG=chrome-os-partner:33132,chrome-os-partner:33761 TEST=manual, 1. Connect samus -> plankton via type-C 2. Connect plankton -> DP monitor via displayport See initial SVDM discovery on samus console See EDID information See SVDM status message correct when plug/unplug DP cable from plankton 3. Press 'CHARGING_20V_TO_DUT_L' button and see below on plankton console. Button 8 = 0 Change-Id: Id95567a3bfa073ffa2c699335be8c5bf0327675f Reviewed-on: https://chromium-review.googlesource.com/229429 Reviewed-by: Alec Berg <alecaberg@chromium.org> Commit-Queue: Todd Broch <tbroch@chromium.org> Tested-by: Todd Broch <tbroch@chromium.org>
Diffstat (limited to 'board/plankton/board.c')
-rw-r--r--board/plankton/board.c107
1 files changed, 104 insertions, 3 deletions
diff --git a/board/plankton/board.c b/board/plankton/board.c
index 7140942ab1..bd6fe3637a 100644
--- a/board/plankton/board.c
+++ b/board/plankton/board.c
@@ -21,6 +21,78 @@
#include "usb_pd_config.h"
#include "util.h"
+void button_event(enum gpio_signal signal);
+void hpd_event(enum gpio_signal signal);
+void vbus_event(enum gpio_signal signal);
+#include "gpio_list.h"
+
+static volatile uint64_t hpd_prev_ts;
+static volatile int hpd_prev_level;
+static volatile int hpd_possible_irq;
+
+static int sn75dp130_dpcd_init(void);
+
+/**
+ * Hotplug detect deferred task
+ *
+ * Called after level change on hpd GPIO to evaluate (and debounce) what event
+ * has occurred. There are 3 events that occur on HPD:
+ * 1. low : downstream display sink is deattached
+ * 2. high : downstream display sink is attached
+ * 3. irq : downstream display sink signalling an interrupt.
+ *
+ * The debounce times for these various events are:
+ * 100MSEC : min pulse width of level value.
+ * 2MSEC : min pulse width of IRQ low pulse. Max is level debounce min.
+ *
+ * lvl(n-2) lvl(n-1) lvl prev_delta now_delta event
+ * ----------------------------------------------------
+ * 1 0 1 <2ms n/a low glitch (ignore)
+ * 1 0 1 >2ms <100ms irq
+ * x 0 1 n/a >100ms high
+ * 0 1 0 <100ms n/a high glitch (ignore)
+ * x 1 0 n/a >100ms low
+ */
+
+void hpd_lvl_deferred(void)
+{
+ int level = gpio_get_level(GPIO_DPSRC_HPD);
+
+ if (level != hpd_prev_level) {
+ /* Stable level changed. Send HPD event */
+ hpd_prev_level = level;
+ pd_send_hpd(0, level ? hpd_high : hpd_low);
+ /* Configure redriver's back side */
+ if (level)
+ sn75dp130_dpcd_init();
+
+ }
+
+ /* Send queued IRQ if the cable is attached */
+ if (hpd_possible_irq && level)
+ pd_send_hpd(0, hpd_irq);
+ hpd_possible_irq = 0;
+
+}
+DECLARE_DEFERRED(hpd_lvl_deferred);
+
+void hpd_event(enum gpio_signal signal)
+{
+ timestamp_t now = get_time();
+ int level = gpio_get_level(signal);
+ uint64_t cur_delta = now.val - hpd_prev_ts;
+
+ /* Record low pulse */
+ if (cur_delta >= HPD_DEBOUNCE_IRQ && level)
+ hpd_possible_irq = 1;
+
+ /* store current time */
+ hpd_prev_ts = now.val;
+
+ /* All previous hpd level events need to be re-triggered */
+ hook_call_deferred(hpd_lvl_deferred, HPD_DEBOUNCE_LVL);
+}
+
/* Debounce time for voltage buttons */
#define BUTTON_DEBOUNCE_US (100 * MSEC)
@@ -98,9 +170,24 @@ static void set_usbc_action(enum usbc_action act)
}
}
+/* has Pull-up */
+static int prev_dbg20v = 1;
+static void button_dbg20v_deferred(void);
+static void enable_dbg20v_poll(void)
+{
+ hook_call_deferred(button_dbg20v_deferred, 10 * MSEC);
+}
+
/* Handle debounced button press */
static void button_deferred(void)
{
+ if (button_pressed == GPIO_DBG_20V_TO_DUT_L) {
+ enable_dbg20v_poll();
+ if (gpio_get_level(GPIO_DBG_20V_TO_DUT_L) == prev_dbg20v)
+ return;
+ else
+ prev_dbg20v = !prev_dbg20v;
+ }
/* bounce ? */
if (gpio_get_level(button_pressed) != 0)
return;
@@ -140,14 +227,21 @@ void button_event(enum gpio_signal signal)
hook_call_deferred(button_deferred, BUTTON_DEBOUNCE_US);
}
+static void button_dbg20v_deferred(void)
+{
+ if (gpio_get_level(GPIO_DBG_20V_TO_DUT_L) == 0)
+ button_event(GPIO_DBG_20V_TO_DUT_L);
+ else
+ enable_dbg20v_poll();
+}
+DECLARE_DEFERRED(button_dbg20v_deferred);
+
void vbus_event(enum gpio_signal signal)
{
ccprintf("VBUS! =%d\n", gpio_get_level(signal));
task_wake(TASK_ID_PD);
}
-#include "gpio_list.h"
-
/* ADC channels */
const struct adc_t adc_channels[] = {
/* USB PD CC lines sensing. Converted to mV (3300mV/4096). */
@@ -247,17 +341,24 @@ static int sn75dp130_redriver_init(void)
static void board_init(void)
{
+ timestamp_t now = get_time();
+ hpd_prev_level = gpio_get_level(GPIO_DPSRC_HPD);
+ hpd_prev_ts = now.val;
+ gpio_enable_interrupt(GPIO_DPSRC_HPD);
+
/* Enable interrupts on VBUS transitions. */
gpio_enable_interrupt(GPIO_VBUS_WAKE);
/* Enable button interrupts. */
gpio_enable_interrupt(GPIO_DBG_5V_TO_DUT_L);
gpio_enable_interrupt(GPIO_DBG_12V_TO_DUT_L);
- gpio_enable_interrupt(GPIO_DBG_20V_TO_DUT_L);
gpio_enable_interrupt(GPIO_DBG_CHG_TO_DEV_L);
gpio_enable_interrupt(GPIO_DBG_USB_TOGGLE_L);
gpio_enable_interrupt(GPIO_DBG_MUX_FLIP_L);
+ /* TODO(crosbug.com/33761): poll DBG_20V_TO_DUT_L */
+ enable_dbg20v_poll();
+
ina2xx_init(0, 0x399f, INA2XX_CALIB_1MA(10 /* mOhm */));
sn75dp130_redriver_init();
}