aboutsummaryrefslogtreecommitdiffhomepage
path: root/app
diff options
context:
space:
mode:
authorPeter Johanson <[email protected]>2023-09-13 20:01:02 +0000
committerPete Johanson <[email protected]>2024-03-27 20:59:26 -0700
commitb19df0cbf053a88a9389bdf463df431e5b7e70a5 (patch)
tree59a23ef32e303c515d322808d1f5792ea6172f59 /app
parent738c3c0e3b3878ddaebafae65becdf5e5f68fe86 (diff)
downloadzmk-b19df0cbf053a88a9389bdf463df431e5b7e70a5.tar.gz
zmk-b19df0cbf053a88a9389bdf463df431e5b7e70a5.zip
feat(behaviors): Add soft off behavior.
* New soft-off behavior that can be used to force the device into soft-off state with only certain configured wakeup devices.
Diffstat (limited to 'app')
-rw-r--r--app/CMakeLists.txt1
-rw-r--r--app/Kconfig.behaviors6
-rw-r--r--app/dts/behaviors/soft_off.dtsi3
-rw-r--r--app/dts/bindings/behaviors/zmk,behavior-soft-off.yaml14
-rw-r--r--app/src/behaviors/behavior_soft_off.c70
5 files changed, 92 insertions, 2 deletions
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index ac83091c5e..bf7cfeefb4 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -42,6 +42,7 @@ target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/events/wpm_state_changed.c)
target_sources_ifdef(CONFIG_USB_DEVICE_STACK app PRIVATE src/events/usb_conn_state_changed.c)
target_sources(app PRIVATE src/behaviors/behavior_reset.c)
target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/behaviors/behavior_ext_power.c)
+target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_SOFT_OFF app PRIVATE src/behaviors/behavior_soft_off.c)
if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
target_sources(app PRIVATE src/hid.c)
target_sources_ifdef(CONFIG_ZMK_MOUSE app PRIVATE src/mouse.c)
diff --git a/app/Kconfig.behaviors b/app/Kconfig.behaviors
index e5e0c4d7a2..7c30f50ec9 100644
--- a/app/Kconfig.behaviors
+++ b/app/Kconfig.behaviors
@@ -22,6 +22,12 @@ config ZMK_BEHAVIOR_MOUSE_KEY_PRESS
depends on DT_HAS_ZMK_BEHAVIOR_MOUSE_KEY_PRESS_ENABLED
imply ZMK_MOUSE
+config ZMK_BEHAVIOR_SOFT_OFF
+ bool
+ default y
+ select ZMK_PM_SOFT_OFF
+ depends on DT_HAS_ZMK_BEHAVIOR_SOFT_OFF_ENABLED
+
config ZMK_BEHAVIOR_SENSOR_ROTATE_COMMON
bool
diff --git a/app/dts/behaviors/soft_off.dtsi b/app/dts/behaviors/soft_off.dtsi
index fa6571a111..c68230f323 100644
--- a/app/dts/behaviors/soft_off.dtsi
+++ b/app/dts/behaviors/soft_off.dtsi
@@ -6,9 +6,8 @@
/ {
behaviors {
- /omit-if-no-ref/ soft_off: behavior_soft_off {
+ soft_off: soft_off {
compatible = "zmk,behavior-soft-off";
- label = "SOFTOFF";
#binding-cells = <0>;
};
};
diff --git a/app/dts/bindings/behaviors/zmk,behavior-soft-off.yaml b/app/dts/bindings/behaviors/zmk,behavior-soft-off.yaml
new file mode 100644
index 0000000000..1467ede477
--- /dev/null
+++ b/app/dts/bindings/behaviors/zmk,behavior-soft-off.yaml
@@ -0,0 +1,14 @@
+# Copyright (c) 2023 The ZMK Contributors
+# SPDX-License-Identifier: MIT
+
+description: Soft-Off Behavior
+
+compatible: "zmk,behavior-soft-off"
+
+include: zero_param.yaml
+
+properties:
+ hold-time-ms:
+ type: int
+ required: false
+ description: Number of milliseconds the behavior must be held before releasing will actually trigger a soft-off.
diff --git a/app/src/behaviors/behavior_soft_off.c b/app/src/behaviors/behavior_soft_off.c
new file mode 100644
index 0000000000..0f24a644d9
--- /dev/null
+++ b/app/src/behaviors/behavior_soft_off.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2020 The ZMK Contributors
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#define DT_DRV_COMPAT zmk_behavior_soft_off
+
+#include <zephyr/device.h>
+#include <drivers/behavior.h>
+#include <zephyr/logging/log.h>
+
+#include <zmk/pm.h>
+#include <zmk/behavior.h>
+
+LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
+
+struct behavior_soft_off_config {
+ uint32_t hold_time_ms;
+};
+
+struct behavior_soft_off_data {
+ uint32_t press_start;
+};
+
+static int behavior_soft_off_init(const struct device *dev) { return 0; };
+
+static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
+ struct zmk_behavior_binding_event event) {
+ const struct device *dev = zmk_behavior_get_binding(binding->behavior_dev);
+ struct behavior_soft_off_data *data = dev->data;
+
+#if IS_ENABLED(CONFIG_ZMK_SPLIT) && !IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
+ zmk_pm_soft_off();
+#else
+ data->press_start = k_uptime_get();
+#endif
+
+ return ZMK_BEHAVIOR_OPAQUE;
+}
+
+static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
+ struct zmk_behavior_binding_event event) {
+ const struct device *dev = zmk_behavior_get_binding(binding->behavior_dev);
+ struct behavior_soft_off_data *data = dev->data;
+ const struct behavior_soft_off_config *config = dev->config;
+
+ if (config->hold_time_ms == 0 || (k_uptime_get() - data->press_start) >= config->hold_time_ms) {
+ zmk_pm_soft_off();
+ }
+
+ return ZMK_BEHAVIOR_OPAQUE;
+}
+
+static const struct behavior_driver_api behavior_soft_off_driver_api = {
+ .binding_pressed = on_keymap_binding_pressed,
+ .binding_released = on_keymap_binding_released,
+ .locality = BEHAVIOR_LOCALITY_GLOBAL,
+};
+
+#define BSO_INST(n) \
+ static const struct behavior_soft_off_config bso_config_##n = { \
+ .hold_time_ms = DT_INST_PROP_OR(n, hold_time_ms, 0), \
+ }; \
+ static struct behavior_soft_off_data bso_data_##n = {}; \
+ BEHAVIOR_DT_INST_DEFINE(0, behavior_soft_off_init, NULL, &bso_data_##n, &bso_config_##n, \
+ APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
+ &behavior_soft_off_driver_api);
+
+DT_INST_FOREACH_STATUS_OKAY(BSO_INST)