diff options
author | Todd Broch <tbroch@chromium.org> | 2014-11-12 16:32:02 -0800 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-05-01 01:08:10 +0000 |
commit | 7cc3136da56eaea8cfa7f9139ebaf6361707ade2 (patch) | |
tree | 9a66caa15bf4a2df6954c592ca6978a1bda1ad11 /board/plankton/board.c | |
parent | 56653dec06ede2c62ec35c74f0e133f18dd7ea50 (diff) | |
download | chrome-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.c | 107 |
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(); } |