From c2276c74bf43f1502e2126db0ee93eeca5b93750 Mon Sep 17 00:00:00 2001 From: Ting Shen Date: Fri, 10 Mar 2023 16:27:07 +0800 Subject: geralt: implement base state detection BUG=b:272439221 TEST=`ectool mkbpget switches` verify the base switch reflects the actual hardware status BRANCH=none Change-Id: Ic2f968766b0119c2f89e0d191ec8d7d58d25ace8 Signed-off-by: Ting Shen Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4351433 Reviewed-by: Eric Yilun Lin Commit-Queue: Ting Shen Tested-by: Ting Shen --- zephyr/program/geralt/src/base_detect.c | 101 ++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 5 deletions(-) diff --git a/zephyr/program/geralt/src/base_detect.c b/zephyr/program/geralt/src/base_detect.c index b3f078486d..074c2db5f9 100644 --- a/zephyr/program/geralt/src/base_detect.c +++ b/zephyr/program/geralt/src/base_detect.c @@ -3,21 +3,101 @@ * found in the LICENSE file. */ +#include "adc.h" +#include "ap_power/ap_power.h" #include "base_state.h" +#include "chipset.h" +#include "console.h" +#include "hooks.h" #include "tablet_mode.h" -#include +#include + +#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ##args) +#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ##args) + +#define BASE_DETECT_INTERVAL (200 * MSEC) +#define ATTACH_MAX_THRESHOLD_MV 300 +#define DETACH_MIN_THRESHOLD_MV 3000 static void base_update(bool attached) { + const struct gpio_dt_spec *en_cc_lid_base_pu = + GPIO_DT_FROM_NODELABEL(en_cc_lid_base_pu); + base_set_state(attached); tablet_set_mode(!attached, TABLET_TRIGGER_BASE); + + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(en_ppvar_base_x), attached); + gpio_pin_configure(en_cc_lid_base_pu->port, en_cc_lid_base_pu->pin, + attached ? GPIO_OUTPUT_HIGH : GPIO_INPUT); +} + +static void base_detect_tick(void); +DECLARE_DEFERRED(base_detect_tick); + +static void base_detect_tick(void) +{ + static bool debouncing; + int mv = adc_read_channel(ADC_BASE_DET); + + if (mv >= DETACH_MIN_THRESHOLD_MV && base_get_state()) { + if (!debouncing) { + debouncing = true; + } else { + debouncing = false; + base_update(false); + } + } else if (mv <= ATTACH_MAX_THRESHOLD_MV && !base_get_state()) { + if (!debouncing) { + debouncing = true; + } else { + debouncing = false; + base_update(true); + } + } else { + debouncing = false; + } + hook_call_deferred(&base_detect_tick_data, BASE_DETECT_INTERVAL); +} + +static void base_detect_enable(bool enable) +{ + if (enable) { + hook_call_deferred(&base_detect_tick_data, + BASE_DETECT_INTERVAL); + } else { + hook_call_deferred(&base_detect_tick_data, -1); + base_update(false); + } +} + +static void base_startup_hook(struct ap_power_ev_callback *cb, + struct ap_power_ev_data data) +{ + switch (data.event) { + case AP_POWER_STARTUP: + base_detect_enable(true); + break; + case AP_POWER_SHUTDOWN: + base_detect_enable(false); + break; + default: + return; + } } static int base_init(const struct device *unused) { - /* TODO: this is a temporary fix to force tablet mode for developers. */ - base_update(false); + static struct ap_power_ev_callback cb; + + ap_power_ev_init_callback(&cb, base_startup_hook, + AP_POWER_STARTUP | AP_POWER_SHUTDOWN); + ap_power_ev_add_callback(&cb); + + if (!chipset_in_state(CHIPSET_STATE_ANY_OFF)) { + base_detect_enable(true); + } return 0; } @@ -26,6 +106,17 @@ SYS_INIT(base_init, APPLICATION, 1); void base_force_state(enum ec_set_base_state_cmd state) { - /* TODO: not implemented yet */ - base_update(state == EC_SET_BASE_STATE_ATTACH); + switch (state) { + case EC_SET_BASE_STATE_ATTACH: + base_update(true); + base_detect_enable(false); + break; + case EC_SET_BASE_STATE_DETACH: + base_update(false); + base_detect_enable(false); + break; + case EC_SET_BASE_STATE_RESET: + base_detect_enable(true); + break; + } } -- cgit v1.2.1