diff options
-rw-r--r-- | board/kukui/base_detect_krane.c | 133 | ||||
-rw-r--r-- | board/kukui/board.c | 31 | ||||
-rw-r--r-- | board/kukui/gpio.inc | 8 |
3 files changed, 109 insertions, 63 deletions
diff --git a/board/kukui/base_detect_krane.c b/board/kukui/base_detect_krane.c index b39375860d..2ec9fa7d2e 100644 --- a/board/kukui/base_detect_krane.c +++ b/board/kukui/base_detect_krane.c @@ -5,9 +5,15 @@ #include "adc.h" #include "board.h" +#include "charge_manager.h" +#include "console.h" #include "gpio.h" #include "hooks.h" #include "timer.h" +#include "usb_pd.h" +#include "util.h" + +#define CPRINTS(format, args...) cprints(CC_USB, format, ## args) /* Krane base detection code */ @@ -20,28 +26,73 @@ */ #define BASE_DETECT_RETRY_US (500 * MSEC) -/** - * ADC value to indicate device is attached to a keyboard. - * 3.3V, 10K + 1K ohm => 0.3V, +10% margin. - */ -#define KEYBOARD_DETECT_MIN_MV 270 -#define KEYBOARD_DETECT_MAX_MV 330 - -/** - * Minimum ADC value to indicate device is attached to a dock, or disconnected. - * 3.3V, 10K + 100K ohm => 3V, +10% margin. - */ -#define DOCK_DETECT_MIN_MV 2700 +enum kukui_pogo_device_type { + DEVICE_TYPE_ERROR = -2, + DEVICE_TYPE_UNKNOWN = -1, + DEVICE_TYPE_DETACHED = 0, + DEVICE_TYPE_DOCK = 1, + DEVICE_TYPE_KEYBOARD = 2, + DEVICE_TYPE_COUNT, +}; + +struct { + int mv_low, mv_high; +} static const pogo_detect_table[] = { + [DEVICE_TYPE_DETACHED] = {2700, 3500}, /* 10K, NC, around 3.3V */ + [DEVICE_TYPE_DOCK] = {141, 173}, /* 10K, 0.5K ohm */ + [DEVICE_TYPE_KEYBOARD] = {270, 400}, /* 10K, 1K ohm */ +}; +BUILD_ASSERT(ARRAY_SIZE(pogo_detect_table) == DEVICE_TYPE_COUNT); static uint64_t base_detect_debounce_time; +static enum kukui_pogo_device_type get_device_type(int mv) +{ + int i; + + if (mv == ADC_READ_ERROR) + return DEVICE_TYPE_ERROR; + + for (i = 0; i < DEVICE_TYPE_COUNT; i++) { + if (pogo_detect_table[i].mv_low <= mv && + mv <= pogo_detect_table[i].mv_high) + return i; + } + + return DEVICE_TYPE_UNKNOWN; +} + +static void enable_charge(int enable) +{ + if (enable) { + struct charge_port_info info = { + .voltage = 5000, .current = 1500}; + /* + * Set supplier type to PD to have same priority as type c + * port. + */ + charge_manager_update_charge( + CHARGE_SUPPLIER_DEDICATED, CHARGE_PORT_POGO, &info); + } else { + charge_manager_update_charge( + CHARGE_SUPPLIER_DEDICATED, CHARGE_PORT_POGO, NULL); + } + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +static void enable_power_supply(int enable) +{ + gpio_set_level(GPIO_EN_PP3300_POGO, enable); +} + static void base_detect_deferred(void); DECLARE_DEFERRED(base_detect_deferred); static void base_detect_deferred(void) { uint64_t time_now = get_time().val; - int v; + int mv; + int device_type; if (base_detect_debounce_time > time_now) { hook_call_deferred(&base_detect_deferred_data, @@ -49,22 +100,46 @@ static void base_detect_deferred(void) return; } - v = adc_read_channel(ADC_POGO_ADC_INT_L); - if (v == ADC_READ_ERROR) - return; - - if (v >= KEYBOARD_DETECT_MIN_MV && v <= KEYBOARD_DETECT_MAX_MV) { - gpio_set_level(GPIO_EN_PP3300_POGO, 1); - return; - } - - if (v >= DOCK_DETECT_MIN_MV) { - gpio_set_level(GPIO_EN_PP3300_POGO, 0); - return; + /* + * Disable interrupt first to prevent it triggered by value + * changed from 1 to disabled state(=0). + */ + gpio_disable_interrupt(GPIO_POGO_ADC_INT_L); + gpio_set_flags(GPIO_POGO_ADC_INT_L, GPIO_ANALOG); + mv = adc_read_channel(ADC_POGO_ADC_INT_L); + /* restore the pin function */ + gpio_set_flags(GPIO_POGO_ADC_INT_L, GPIO_INT_BOTH); + gpio_enable_interrupt(GPIO_POGO_ADC_INT_L); + + device_type = get_device_type(mv); + CPRINTS("POGO: adc=%d, device_type=%d", mv, device_type); + + switch (device_type) { + case DEVICE_TYPE_ERROR: + case DEVICE_TYPE_UNKNOWN: + hook_call_deferred(&base_detect_deferred_data, + BASE_DETECT_RETRY_US); + break; + + case DEVICE_TYPE_DETACHED: + enable_power_supply(0); + enable_charge(0); + break; + + case DEVICE_TYPE_DOCK: + enable_power_supply(0); + enable_charge(1); + break; + + case DEVICE_TYPE_KEYBOARD: + enable_charge(0); + enable_power_supply(1); + break; + + case DEVICE_TYPE_COUNT: + /* should not happen */ + break; } - - /* Unclear base status, schedule again in a while. */ - hook_call_deferred(&base_detect_deferred_data, BASE_DETECT_RETRY_US); } void pogo_adc_interrupt(enum gpio_signal signal) @@ -83,4 +158,4 @@ static void base_init(void) { hook_call_deferred(&base_detect_deferred_data, 0); } -DECLARE_HOOK(HOOK_INIT, base_init, HOOK_PRIO_DEFAULT + 1); +DECLARE_HOOK(HOOK_INIT, base_init, HOOK_PRIO_INIT_ADC + 1); diff --git a/board/kukui/board.c b/board/kukui/board.c index 40a18c9729..53bd3f6222 100644 --- a/board/kukui/board.c +++ b/board/kukui/board.c @@ -50,8 +50,6 @@ #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) -#define POGO_VBUS_DETECT_DEBOUNCE_US (20 * MSEC) - static void tcpc_alert_event(enum gpio_signal signal) { schedule_deferred_pd_interrupt(0 /* port */); @@ -62,33 +60,6 @@ static void gauge_interrupt(enum gpio_signal signal) task_wake(TASK_ID_CHARGER); } -static void pogo_vbus_detect_deferred(void); -DECLARE_DEFERRED(pogo_vbus_detect_deferred); - -static void pogo_vbus_detect_deferred(void) -{ - if (gpio_get_level(GPIO_POGO_VBUS_PRESENT)) { - struct charge_port_info info = { - .voltage = 5000, .current = 1500}; - /* - * Set supplier type to PD to have same priority as type c - * port. - */ - charge_manager_update_charge( - CHARGE_SUPPLIER_DEDICATED, CHARGE_PORT_POGO, &info); - } else { - charge_manager_update_charge( - CHARGE_SUPPLIER_DEDICATED, CHARGE_PORT_POGO, NULL); - } - pd_send_host_event(PD_EVENT_POWER_CHANGE); -} - -static void pogo_vbus_present(enum gpio_signal signal) -{ - hook_call_deferred(&pogo_vbus_detect_deferred_data, - POGO_VBUS_DETECT_DEBOUNCE_US); -} - #include "gpio_list.h" /******************************************************************************/ @@ -191,8 +162,6 @@ static void board_pogo_charge_init(void) /* Initialize all charge suppliers to 0 */ for (i = 0; i < CHARGE_SUPPLIER_COUNT; i++) charge_manager_update_charge(i, CHARGE_PORT_POGO, NULL); - - hook_call_deferred(&pogo_vbus_detect_deferred_data, 0); } DECLARE_HOOK(HOOK_INIT, board_pogo_charge_init, HOOK_PRIO_CHARGE_MANAGER_INIT + 1); diff --git a/board/kukui/gpio.inc b/board/kukui/gpio.inc index cba7902172..f9ddacc6ec 100644 --- a/board/kukui/gpio.inc +++ b/board/kukui/gpio.inc @@ -43,10 +43,12 @@ GPIO_INT(HALL_INT_L, PIN(C, 5), GPIO_INT_BOTH, lid_interrupt) GPIO_INT(GAUGE_INT_ODL, PIN(C, 9), GPIO_INT_FALLING | GPIO_PULL_UP, gauge_interrupt) -GPIO_INT(POGO_ADC_INT_L, PIN(A, 6), GPIO_INT_BOTH | GPIO_ANALOG, +GPIO_INT(POGO_ADC_INT_L, PIN(A, 6), GPIO_INT_BOTH, pogo_adc_interrupt) -GPIO_INT(POGO_VBUS_PRESENT, PIN(A, 14), GPIO_INT_BOTH, - pogo_vbus_present) + +/* unused */ +GPIO(POGO_VBUS_PRESENT, PIN(A, 14), GPIO_INPUT) + /* Reset pins */ GPIO(AP_SYS_RST_L, PIN(C, 11), GPIO_OUT_LOW) |