summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/kukui/base_detect_krane.c133
-rw-r--r--board/kukui/board.c31
-rw-r--r--board/kukui/gpio.inc8
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)