diff options
author | Peter Johanson <[email protected]> | 2023-09-13 20:01:02 +0000 |
---|---|---|
committer | Pete Johanson <[email protected]> | 2024-03-27 20:59:26 -0700 |
commit | b19df0cbf053a88a9389bdf463df431e5b7e70a5 (patch) | |
tree | 59a23ef32e303c515d322808d1f5792ea6172f59 | |
parent | 738c3c0e3b3878ddaebafae65becdf5e5f68fe86 (diff) | |
download | zmk-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.
-rw-r--r-- | app/CMakeLists.txt | 1 | ||||
-rw-r--r-- | app/Kconfig.behaviors | 6 | ||||
-rw-r--r-- | app/dts/behaviors/soft_off.dtsi | 3 | ||||
-rw-r--r-- | app/dts/bindings/behaviors/zmk,behavior-soft-off.yaml | 14 | ||||
-rw-r--r-- | app/src/behaviors/behavior_soft_off.c | 70 |
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) |