diff options
author | wangganxiang <wangganxiang@huaqin.corp-partner.google.com> | 2023-05-09 18:35:20 +0800 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-05-12 02:39:10 +0000 |
commit | 9615337c2d27357fa7672837f1088fd1356e6d45 (patch) | |
tree | 8d7375964111230f97723fd25638333e8298c7c7 | |
parent | cf0bb2883ee6c9419b5431e47e80ec9f104ceb42 (diff) | |
download | chrome-ec-9615337c2d27357fa7672837f1088fd1356e6d45.tar.gz |
starmie: implement base detection
Change the judgment mode to interrupt.
BUG=b:281643319
TEST=`ectool mkbpget switches`
Change-Id: I974cd46ed187fefc3989a0072bc93fe556fd425b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4516960
Reviewed-by: Sung-Chi Li <lschyi@chromium.org>
Reviewed-by: Mike Lee <mike5@huaqin.corp-partner.google.com>
Tested-by: Ganxiang Wang <wangganxiang@huaqin.corp-partner.google.com>
Commit-Queue: Ganxiang Wang <wangganxiang@huaqin.corp-partner.google.com>
-rw-r--r-- | zephyr/program/corsola/starmie/CMakeLists.txt | 5 | ||||
-rw-r--r-- | zephyr/program/corsola/starmie/project.conf | 4 | ||||
-rw-r--r-- | zephyr/program/corsola/starmie/project.overlay | 13 | ||||
-rw-r--r-- | zephyr/program/corsola/starmie/src/base_detect.c | 151 |
4 files changed, 168 insertions, 5 deletions
diff --git a/zephyr/program/corsola/starmie/CMakeLists.txt b/zephyr/program/corsola/starmie/CMakeLists.txt index f401c5dd43..dd669ab82c 100644 --- a/zephyr/program/corsola/starmie/CMakeLists.txt +++ b/zephyr/program/corsola/starmie/CMakeLists.txt @@ -9,4 +9,7 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_I2C "../src/ite_i2c.c") zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_USBC "../src/ite_usb_pd_policy.c" "../src/ite_usbc.c") -zephyr_library_sources("src/ppc.c")
\ No newline at end of file +zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_DETACHABLE_BASE + "src/base_detect.c") + +zephyr_library_sources("src/ppc.c") diff --git a/zephyr/program/corsola/starmie/project.conf b/zephyr/program/corsola/starmie/project.conf index 70bd94520f..72d18b8e9f 100644 --- a/zephyr/program/corsola/starmie/project.conf +++ b/zephyr/program/corsola/starmie/project.conf @@ -40,3 +40,7 @@ CONFIG_PLATFORM_EC_BODY_DETECTION=y CONFIG_PLATFORM_EC_BODY_DETECTION_ALWAYS_ENABLE_IN_S0=y CONFIG_PLATFORM_EC_GESTURE_DETECTION=y CONFIG_PLATFORM_EC_GESTURE_HOST_DETECTION=y + +# Detachable +CONFIG_PLATFORM_EC_DETACHABLE_BASE=y +CONFIG_PLATFORM_EC_BASE_ATTACHED_SWITCH=y diff --git a/zephyr/program/corsola/starmie/project.overlay b/zephyr/program/corsola/starmie/project.overlay index 2358026e2d..a4d69867a5 100644 --- a/zephyr/program/corsola/starmie/project.overlay +++ b/zephyr/program/corsola/starmie/project.overlay @@ -43,6 +43,11 @@ handler = "power_signal_interrupt"; }; + pogo_prsnt_int: pogo-prsnt-int { + irq-pin = <&pogo_prsnt_int_l>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "base_detect_interrupt"; + }; /delete-node/ lid_imu; }; @@ -71,8 +76,8 @@ }; // POGO_PRSNT_INT_L GPI5 - pogo_prsnt_int_l: pogo_prsnt_int_l{ - gpios = <&gpioi 5 GPIO_INPUT_PULL_DOWN>; + pogo_prsnt_int_l: pogo_prsnt_int_l { + gpios = <&gpioi 5 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; }; pg_pp4200_s5_od: pg-pp4200-s5-od { @@ -131,8 +136,8 @@ motionsense-rotation-ref { compatible = "cros-ec,motionsense-rotation-ref"; lid_rot_ref_bmi: lid-rotation-ref-bmi { - mat33 = <1 0 0 - 0 1 0 + mat33 = <(-1) 0 0 + 0 (-1) 0 0 0 1>; }; }; diff --git a/zephyr/program/corsola/starmie/src/base_detect.c b/zephyr/program/corsola/starmie/src/base_detect.c new file mode 100644 index 0000000000..144b26e3be --- /dev/null +++ b/zephyr/program/corsola/starmie/src/base_detect.c @@ -0,0 +1,151 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "ap_power/ap_power.h" +#include "base_state.h" +#include "chipset.h" +#include "console.h" +#include "gpio/gpio_int.h" +#include "hooks.h" +#include "host_command.h" +#include "tablet_mode.h" + +#include <zephyr/drivers/gpio.h> +#include <zephyr/kernel.h> + +#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ##args) +#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ##args) + +/* Base detection debouncing */ +#define BASE_DETECT_EN_DEBOUNCE_US (350 * MSEC) +#define BASE_DETECT_DIS_DEBOUNCE_US (20 * MSEC) + +K_MUTEX_DEFINE(modify_base_detection_mutex); +static bool detect_base_enabled; + +static void base_detect_deferred(void); +DECLARE_DEFERRED(base_detect_deferred); + +enum base_status { + BASE_UNKNOWN = 0, + BASE_DISCONNECTED = 1, + BASE_CONNECTED = 2, +}; + +static enum base_status current_base_status; + +static void base_update(enum base_status specified_status) +{ + int connected = (specified_status != BASE_CONNECTED) ? false : true; + + if (current_base_status == specified_status) + return; + + current_base_status = specified_status; + + base_set_state(connected); + tablet_set_mode(!connected, TABLET_TRIGGER_BASE); + gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(en_pp3300_base_x), connected); +} + +void base_detect_interrupt(enum gpio_signal signal) +{ + gpio_disable_dt_interrupt(GPIO_INT_FROM_NODELABEL(pogo_prsnt_int)); + hook_call_deferred(&base_detect_deferred_data, + (current_base_status == BASE_CONNECTED) ? + BASE_DETECT_DIS_DEBOUNCE_US : + BASE_DETECT_EN_DEBOUNCE_US); +} + +static inline void detect_and_update_base_status(void) +{ + if (gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(pogo_prsnt_int_l))) { + base_update(BASE_CONNECTED); + } else { + base_update(BASE_DISCONNECTED); + } +} + +static void base_detect_deferred(void) +{ + k_mutex_lock(&modify_base_detection_mutex, K_FOREVER); + /* + * If a disable base detection is issued after an ISR, and is before + * executing the deferred hook, then we need to check whether the + * detection is enabled. If disabled, there is no need to re-enable the + * interrupt. + */ + if (detect_base_enabled) { + detect_and_update_base_status(); + gpio_enable_dt_interrupt( + GPIO_INT_FROM_NODELABEL(pogo_prsnt_int)); + } + k_mutex_unlock(&modify_base_detection_mutex); +} + +static void base_detect_enable(bool enable) +{ + detect_base_enabled = enable; + if (enable) { + gpio_enable_dt_interrupt( + GPIO_INT_FROM_NODELABEL(pogo_prsnt_int)); + detect_and_update_base_status(); + } else { + gpio_disable_dt_interrupt( + GPIO_INT_FROM_NODELABEL(pogo_prsnt_int)); + base_update(BASE_UNKNOWN); + } +} + +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(void) +{ + static struct ap_power_ev_callback cb; + + detect_base_enabled = false; + 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; +} +SYS_INIT(base_init, APPLICATION, 1); + +void base_force_state(enum ec_set_base_state_cmd state) +{ + k_mutex_lock(&modify_base_detection_mutex, K_FOREVER); + switch (state) { + case EC_SET_BASE_STATE_ATTACH: + base_detect_enable(false); + base_update(BASE_CONNECTED); + break; + case EC_SET_BASE_STATE_DETACH: + base_detect_enable(false); + base_update(BASE_DISCONNECTED); + break; + case EC_SET_BASE_STATE_RESET: + base_detect_enable(true); + break; + } + k_mutex_unlock(&modify_base_detection_mutex); +} |