summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAl Semjonovs <asemjonovs@google.com>2023-01-05 15:19:38 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-01-17 18:50:43 +0000
commitd132fda9205d814f9c0c2a1b11786e0fb48ae35d (patch)
treebf9c6c0f7a16273108b277033ac5584208bfb694
parentacd1253a35b9c35c7c3c139e31014bf1c5d696bf (diff)
downloadchrome-ec-d132fda9205d814f9c0c2a1b11786e0fb48ae35d.tar.gz
zephyr:drivers: power button driver
Add power button driver using Zephyr gpio-keys APIs BUG=b:234728861 BRANCH=NONE TEST=./twister -T zephyr/test Change-Id: I8399f7f0689657b6444a300021161cb8a89c50db Signed-off-by: Al Semjonovs <asemjonovs@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4139709 Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com> Reviewed-by: Keith Short <keithshort@chromium.org>
-rw-r--r--zephyr/Kconfig2
-rw-r--r--zephyr/include/dt-bindings/buttons.h14
-rw-r--r--zephyr/shim/src/CMakeLists.txt1
-rw-r--r--zephyr/shim/src/buttons/CMakeLists.txt6
-rw-r--r--zephyr/shim/src/buttons/buttons.c45
-rw-r--r--zephyr/shim/src/buttons/power_button.c121
-rw-r--r--zephyr/shim/src/buttons/power_button.h13
-rw-r--r--zephyr/test/qcom_power/boards/native_posix.overlay2
-rw-r--r--zephyr/test/qcom_power/boards/power_button.dtsi24
-rw-r--r--zephyr/test/qcom_power/testcase.yaml4
10 files changed, 230 insertions, 2 deletions
diff --git a/zephyr/Kconfig b/zephyr/Kconfig
index c5a7e7fa38..597e6ee250 100644
--- a/zephyr/Kconfig
+++ b/zephyr/Kconfig
@@ -534,7 +534,7 @@ config PLATFORM_EC_PORT80
config PLATFORM_EC_POWER_BUTTON
bool "Power-button support"
- depends on PLATFORM_EC_HOSTCMD
+ depends on PLATFORM_EC_HOSTCMD && !GPIO_KEYS_ZEPHYR
help
Enable shimming the power button implementation and related
commands in platform/ec. This is used to implement the Chromium OS
diff --git a/zephyr/include/dt-bindings/buttons.h b/zephyr/include/dt-bindings/buttons.h
new file mode 100644
index 0000000000..47756d2284
--- /dev/null
+++ b/zephyr/include/dt-bindings/buttons.h
@@ -0,0 +1,14 @@
+/* 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.
+ */
+
+#ifndef DT_BINDINGS_BUTTON_H_
+#define DT_BINDINGS_BUTTON_H_
+
+#define BUTTON_POWER 1
+#define BUTTON_VOLUME_DOWN 2
+#define BUTTON_VOLUME_UP 3
+#define BUTTON_RECOVERY 4
+
+#endif /* DT_BINDINGS_BUTTON_H_ */
diff --git a/zephyr/shim/src/CMakeLists.txt b/zephyr/shim/src/CMakeLists.txt
index f7bdb8fe85..5c77156ef5 100644
--- a/zephyr/shim/src/CMakeLists.txt
+++ b/zephyr/shim/src/CMakeLists.txt
@@ -7,6 +7,7 @@ zephyr_library_sources(crc.c)
zephyr_library_sources(gpio.c)
zephyr_library_sources(gpio_int.c)
+add_subdirectory("buttons")
add_subdirectory("cbi")
add_subdirectory("led_driver")
diff --git a/zephyr/shim/src/buttons/CMakeLists.txt b/zephyr/shim/src/buttons/CMakeLists.txt
new file mode 100644
index 0000000000..28b0926023
--- /dev/null
+++ b/zephyr/shim/src/buttons/CMakeLists.txt
@@ -0,0 +1,6 @@
+# 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.
+
+zephyr_library_sources_ifdef(CONFIG_GPIO_KEYS_ZEPHYR buttons.c)
+zephyr_library_sources_ifdef(CONFIG_GPIO_KEYS_ZEPHYR power_button.c)
diff --git a/zephyr/shim/src/buttons/buttons.c b/zephyr/shim/src/buttons/buttons.c
new file mode 100644
index 0000000000..01aba6c822
--- /dev/null
+++ b/zephyr/shim/src/buttons/buttons.c
@@ -0,0 +1,45 @@
+/* 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 "power_button.h"
+
+#include <zephyr/device.h>
+#include <zephyr/drivers/gpio_keys.h>
+#include <zephyr/logging/log.h>
+
+#include <dt-bindings/buttons.h>
+
+LOG_MODULE_REGISTER(button, CONFIG_GPIO_LOG_LEVEL);
+
+#define DT_DRV_COMPAT zephyr_gpio_keys
+
+static void buttons_cb_handler(const struct device *dev,
+ struct gpio_keys_callback *cbdata, uint32_t pins)
+{
+ LOG_DBG("Button %s, pins=0x%x, zephyr_code=%u, pin_state=%d", dev->name,
+ pins, cbdata->zephyr_code, cbdata->pin_state);
+
+ switch (cbdata->zephyr_code) {
+ case BUTTON_POWER:
+ handle_power_button(cbdata->pin_state);
+ break;
+ default:
+ LOG_ERR("Unknown button code=%u", cbdata->zephyr_code);
+ break;
+ }
+}
+
+#define BUTTONS_ENABLE_INT(node_id) \
+ gpio_keys_enable_interrupt(DEVICE_DT_GET(DT_DRV_INST(node_id)), \
+ buttons_cb_handler)
+
+static int buttons_init(const struct device *device)
+{
+ DT_INST_FOREACH_STATUS_OKAY(BUTTONS_ENABLE_INT);
+
+ return 0;
+}
+
+SYS_INIT(buttons_init, POST_KERNEL, 51);
diff --git a/zephyr/shim/src/buttons/power_button.c b/zephyr/shim/src/buttons/power_button.c
new file mode 100644
index 0000000000..fdb684376c
--- /dev/null
+++ b/zephyr/shim/src/buttons/power_button.c
@@ -0,0 +1,121 @@
+/* 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 "hooks.h"
+#include "host_command.h"
+#include "power_button.h"
+#include "task.h"
+#include "util.h"
+
+#include <zephyr/drivers/gpio_keys.h>
+#include <zephyr/logging/log.h>
+#include <zephyr/shell/shell.h>
+
+LOG_MODULE_REGISTER(power_button, CONFIG_GPIO_LOG_LEVEL);
+
+#define POWER_BUTTON_LBL DT_NODELABEL(power_button)
+#define POWER_BUTTON_IDX DT_NODE_CHILD_IDX(POWER_BUTTON_LBL)
+#define GPIOKEYS_DEV DEVICE_DT_GET(DT_PARENT(POWER_BUTTON_LBL))
+
+static struct power_button_data_s {
+ int8_t state;
+} power_button_data;
+
+int power_button_is_pressed(void)
+{
+ return power_button_data.state;
+}
+
+int power_button_signal_asserted(void)
+{
+ return gpio_keys_get_pin(GPIOKEYS_DEV, POWER_BUTTON_IDX);
+}
+
+int power_button_wait_for_release(int timeout_us)
+{
+ int check_interval_us = 30000;
+ bool released;
+
+ released =
+ WAIT_FOR(!(power_button_data.state), timeout_us,
+ task_wait_event(MIN(timeout_us, check_interval_us)));
+
+ return released ? 0 : -ETIMEDOUT;
+}
+
+void handle_power_button(int8_t new_pin_state)
+{
+ LOG_DBG("Handling power button state=%d", new_pin_state);
+
+ power_button_data.state = new_pin_state;
+
+ hook_notify(HOOK_POWER_BUTTON_CHANGE);
+ host_set_single_event(EC_HOST_EVENT_POWER_BUTTON);
+}
+
+void power_button_simulate_press(unsigned int duration)
+{
+ int8_t temp = power_button_data.state;
+
+ LOG_INF("Simulating %d ms power button press.", duration);
+ handle_power_button(1);
+
+ if (duration > 0)
+ k_sleep(K_MSEC(duration));
+
+ LOG_INF("Simulating power button release.");
+ handle_power_button(0);
+
+ power_button_data.state = temp;
+}
+
+/* LCOV_EXCL_START */
+/* Stubbed to be overridden by specific x86 board */
+__overridable void power_button_pch_press(void)
+{
+}
+
+/* Stubbed to be overridden by specific x86 board */
+__overridable void power_button_pch_release(void)
+{
+}
+
+/* Stubbed to be overridden by specific x86 board */
+__overridable void power_button_pch_pulse(void)
+{
+}
+
+/* Stubbed to be overridden by specific board */
+__overridable int64_t get_time_dsw_pwrok(void)
+{
+ return 0;
+}
+
+/* Stubbed to be overridden by specific board */
+__overridable void board_pwrbtn_to_pch(int level)
+{
+}
+/* LCOV_EXCL_STOP */
+
+/*****************************************************************************/
+/* Console commands */
+static int command_powerbtn(const struct shell *shell, size_t argc, char **argv)
+{
+ int ms = 200; /* Press duration in ms */
+ char *e;
+
+ if (argc > 1) {
+ ms = strtoi(argv[1], &e, 0);
+ if (*e || ms < 0)
+ return EC_ERROR_PARAM1;
+ }
+
+ power_button_simulate_press(ms);
+ return EC_SUCCESS;
+}
+
+SHELL_CMD_ARG_REGISTER(powerbtn, NULL,
+ "Simulate power button press for \'n\' msec",
+ command_powerbtn, 1, 1);
diff --git a/zephyr/shim/src/buttons/power_button.h b/zephyr/shim/src/buttons/power_button.h
new file mode 100644
index 0000000000..7c220f99ca
--- /dev/null
+++ b/zephyr/shim/src/buttons/power_button.h
@@ -0,0 +1,13 @@
+/* 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.
+ */
+
+#ifndef BUTTONS_POWER_BUTTON_H_
+#define BUTTONS_POWER_BUTTON_H_
+
+#include <stdint.h>
+
+void handle_power_button(int8_t new_pin_state);
+
+#endif /* BUTTONS_POWER_BUTTON_H_ */
diff --git a/zephyr/test/qcom_power/boards/native_posix.overlay b/zephyr/test/qcom_power/boards/native_posix.overlay
index 9af8f4cd13..c1ad516b79 100644
--- a/zephyr/test/qcom_power/boards/native_posix.overlay
+++ b/zephyr/test/qcom_power/boards/native_posix.overlay
@@ -87,7 +87,7 @@
/* GPIO_PULL_UP will cause this start asserted,
* i.e. not pressed.
*/
- gpios = <&gpio0 25 (GPIO_INPUT | GPIO_PULL_UP)>;
+ gpios = <&gpio0 25 (GPIO_INPUT | GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
enum-name = "GPIO_POWER_BUTTON_L";
};
gpio_switchcap_pg: src_vph_pwr_pg {
diff --git a/zephyr/test/qcom_power/boards/power_button.dtsi b/zephyr/test/qcom_power/boards/power_button.dtsi
new file mode 100644
index 0000000000..5a91a799cb
--- /dev/null
+++ b/zephyr/test/qcom_power/boards/power_button.dtsi
@@ -0,0 +1,24 @@
+/* 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 <dt-bindings/buttons.h>
+
+/ {
+ gpio_keys0: gpio-keys {
+ compatible = "zephyr,gpio-keys";
+ debounce-interval-ms = <30>;
+ power_button: power_button {
+ gpios = <&gpio0 25 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
+ zephyr,code = <BUTTON_POWER>;
+ };
+ };
+
+};
+
+/* interrupt overrides */
+/{
+ gpio-interrupts {
+ /delete-node/ power_button;
+ };
+};
diff --git a/zephyr/test/qcom_power/testcase.yaml b/zephyr/test/qcom_power/testcase.yaml
index fe580b27e8..fba474392b 100644
--- a/zephyr/test/qcom_power/testcase.yaml
+++ b/zephyr/test/qcom_power/testcase.yaml
@@ -2,3 +2,7 @@ common:
platform_allow: native_posix
tests:
qcom_power.default: {}
+ qcom_power.power_gpio_keys:
+ extra_args: DTC_OVERLAY_FILE="./boards/native_posix.overlay;./boards/power_button.dtsi"
+ extra_configs:
+ - CONFIG_PLATFORM_EC_POWER_BUTTON=n