diff --git a/app/include/drivers/ext_power.h b/app/include/drivers/ext_power.h index b422750c..8782c9fc 100644 --- a/app/include/drivers/ext_power.h +++ b/app/include/drivers/ext_power.h @@ -22,8 +22,8 @@ extern "C" { * (Internal use only.) */ -typedef int (*ext_power_enable_t)(const struct device *dev); -typedef int (*ext_power_disable_t)(const struct device *dev); +typedef int (*ext_power_enable_t)(const struct device *dev, bool); +typedef int (*ext_power_disable_t)(const struct device *dev, bool); typedef int (*ext_power_get_t)(const struct device *dev); __subsystem struct ext_power_api { @@ -42,16 +42,16 @@ __subsystem struct ext_power_api { * @retval 0 If successful. * @retval Negative errno code if failure. */ -__syscall int ext_power_enable(const struct device *dev); +__syscall int ext_power_enable(const struct device *dev, bool saveState); -static inline int z_impl_ext_power_enable(const struct device *dev) { +static inline int z_impl_ext_power_enable(const struct device *dev, bool saveState) { const struct ext_power_api *api = (const struct ext_power_api *)dev->api; if (api->enable == NULL) { return -ENOTSUP; } - return api->enable(dev); + return api->enable(dev, saveState); } /** @@ -61,16 +61,16 @@ static inline int z_impl_ext_power_enable(const struct device *dev) { * @retval 0 If successful. * @retval Negative errno code if failure. */ -__syscall int ext_power_disable(const struct device *dev); +__syscall int ext_power_disable(const struct device *dev, bool saveState); -static inline int z_impl_ext_power_disable(const struct device *dev) { +static inline int z_impl_ext_power_disable(const struct device *dev, bool saveState) { const struct ext_power_api *api = (const struct ext_power_api *)dev->api; if (api->disable == NULL) { return -ENOTSUP; } - return api->disable(dev); + return api->disable(dev, saveState); } /** diff --git a/app/include/zmk/rgb_underglow.h b/app/include/zmk/rgb_underglow.h index 7fcd42dd..db16275a 100644 --- a/app/include/zmk/rgb_underglow.h +++ b/app/include/zmk/rgb_underglow.h @@ -6,7 +6,9 @@ #pragma once -int zmk_rgb_underglow_toggle(); +int zmk_rgb_underglow_toggle(bool saveState); +int zmk_rgb_underglow_on(bool saveState); +int zmk_rgb_underglow_off(bool saveState); int zmk_rgb_underglow_cycle_effect(int direction); int zmk_rgb_underglow_change_hue(int direction); int zmk_rgb_underglow_change_sat(int direction); diff --git a/app/src/behaviors/behavior_ext_power.c b/app/src/behaviors/behavior_ext_power.c index 18520f7d..a98fdf2b 100644 --- a/app/src/behaviors/behavior_ext_power.c +++ b/app/src/behaviors/behavior_ext_power.c @@ -26,14 +26,14 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, switch (binding->param1) { case EXT_POWER_OFF_CMD: - return ext_power_disable(ext_power); + return ext_power_disable(ext_power, true); case EXT_POWER_ON_CMD: - return ext_power_enable(ext_power); + return ext_power_enable(ext_power, true); case EXT_POWER_TOGGLE_CMD: if (ext_power_get(ext_power) > 0) - return ext_power_disable(ext_power); + return ext_power_disable(ext_power, true); else - return ext_power_enable(ext_power); + return ext_power_enable(ext_power, true); default: LOG_ERR("Unknown ext_power command: %d", binding->param1); } diff --git a/app/src/behaviors/behavior_rgb_underglow.c b/app/src/behaviors/behavior_rgb_underglow.c index 07f24940..40345b7f 100644 --- a/app/src/behaviors/behavior_rgb_underglow.c +++ b/app/src/behaviors/behavior_rgb_underglow.c @@ -22,7 +22,7 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) { switch (binding->param1) { case RGB_TOG_CMD: - return zmk_rgb_underglow_toggle(); + return zmk_rgb_underglow_toggle(true); case RGB_HUI_CMD: return zmk_rgb_underglow_change_hue(1); case RGB_HUD_CMD: diff --git a/app/src/ext_power_generic.c b/app/src/ext_power_generic.c index d8e7844e..8dddc48d 100644 --- a/app/src/ext_power_generic.c +++ b/app/src/ext_power_generic.c @@ -58,7 +58,7 @@ int ext_power_save_state() { #endif } -static int ext_power_generic_enable(const struct device *dev) { +static int ext_power_generic_enable(const struct device *dev, bool saveState) { struct ext_power_generic_data *data = dev->data; const struct ext_power_generic_config *config = dev->config; @@ -67,10 +67,13 @@ static int ext_power_generic_enable(const struct device *dev) { return -EIO; } data->status = true; - return ext_power_save_state(); + if (saveState) { + return ext_power_save_state(); + } + return 0; } -static int ext_power_generic_disable(const struct device *dev) { +static int ext_power_generic_disable(const struct device *dev, bool saveState) { struct ext_power_generic_data *data = dev->data; const struct ext_power_generic_config *config = dev->config; @@ -79,7 +82,10 @@ static int ext_power_generic_disable(const struct device *dev) { return -EIO; } data->status = false; - return ext_power_save_state(); + if (saveState) { + return ext_power_save_state(); + } + return 0; } static int ext_power_generic_get(const struct device *dev) { @@ -111,9 +117,9 @@ static int ext_power_settings_set(const char *name, size_t len, settings_read_cb } if (data->status) { - ext_power_generic_enable(ext_power); + ext_power_generic_enable(ext_power, true); } else { - ext_power_generic_disable(ext_power); + ext_power_generic_disable(ext_power, true); } return 0; @@ -164,7 +170,7 @@ static int ext_power_generic_init(const struct device *dev) { data->status = true; k_delayed_work_submit(&ext_power_save_work, K_NO_WAIT); - ext_power_enable(dev); + ext_power_enable(dev, true); } #else // Default to the ext_power being open when no settings @@ -186,7 +192,7 @@ static int ext_power_generic_pm_control(const struct device *dev, uint32_t ctrl_ data->pm_state = DEVICE_PM_ACTIVE_STATE; rc = 0; } else { - ext_power_generic_disable(dev); + ext_power_generic_disable(dev, false); data->pm_state = DEVICE_PM_LOW_POWER_STATE; rc = 0; } diff --git a/app/src/rgb_underglow.c b/app/src/rgb_underglow.c index f3bd7a9d..b3ccbadc 100644 --- a/app/src/rgb_underglow.c +++ b/app/src/rgb_underglow.c @@ -17,11 +17,17 @@ #include #include +#include +#include + LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #define STRIP_LABEL DT_LABEL(DT_CHOSEN(zmk_underglow)) #define STRIP_NUM_PIXELS DT_PROP(DT_CHOSEN(zmk_underglow), chain_length) +int zmk_rgb_underglow_off(bool saveState); +int zmk_rgb_underglow_on(bool saveState); + enum rgb_underglow_effect { UNDERGLOW_EFFECT_SOLID, UNDERGLOW_EFFECT_BREATHE, @@ -105,14 +111,6 @@ static struct led_rgb hsb_to_rgb(struct led_hsb hsb) { return rgb; } -static void zmk_rgb_underglow_off() { - for (int i = 0; i < STRIP_NUM_PIXELS; i++) { - pixels[i] = (struct led_rgb){r : 0, g : 0, b : 0}; - } - - led_strip_update_rgb(led_strip, pixels, STRIP_NUM_PIXELS); -} - static void zmk_rgb_underglow_effect_solid() { for (int i = 0; i < STRIP_NUM_PIXELS; i++) { int hue = state.hue; @@ -196,7 +194,7 @@ K_WORK_DEFINE(underglow_work, zmk_rgb_underglow_tick); static void zmk_rgb_underglow_tick_handler(struct k_timer *timer) { if (!state.on) { - zmk_rgb_underglow_off(); + zmk_rgb_underglow_off(true); k_timer_stop(timer); @@ -261,7 +259,7 @@ static int zmk_rgb_underglow_init(const struct device *_arg) { animation_speed : CONFIG_ZMK_RGB_UNDERGLOW_SPD_START, current_effect : CONFIG_ZMK_RGB_UNDERGLOW_EFF_START, animation_step : 0, - on : IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_ON_START) + on : IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_ON_START), }; #if IS_ENABLED(CONFIG_SETTINGS) @@ -283,6 +281,31 @@ static int zmk_rgb_underglow_init(const struct device *_arg) { return 0; } +int underglow_event_handler(const zmk_event_t *eh) { + struct zmk_activity_state_changed *ev = as_zmk_activity_state_changed(eh); + switch (ev->state) { + case ZMK_ACTIVITY_ACTIVE: + // Reload settings to get state prior to idle/sleep + settings_load_subtree("rgb/underglow"); + // Don't auto on underglow unless it was on before the board went to sleep + if (state.on) { + zmk_rgb_underglow_on(false); + } + break; + case ZMK_ACTIVITY_IDLE: + case ZMK_ACTIVITY_SLEEP: + zmk_rgb_underglow_off(false); + break; + default: + LOG_WRN("Unhandled activity state: %d", ev->state); + return -EINVAL; + } + return 0; +} + +ZMK_LISTENER(led_strip, underglow_event_handler); +ZMK_SUBSCRIPTION(led_strip, zmk_activity_state_changed); + int zmk_rgb_underglow_save_state() { #if IS_ENABLED(CONFIG_SETTINGS) k_delayed_work_cancel(&underglow_save_work); @@ -312,21 +335,34 @@ int zmk_rgb_underglow_cycle_effect(int direction) { return zmk_rgb_underglow_save_state(); } -int zmk_rgb_underglow_toggle() { +int zmk_rgb_underglow_toggle(bool saveState) { if (!led_strip) return -ENODEV; - state.on = !state.on; + if (state.on) { + return zmk_rgb_underglow_off(saveState); + } else { + return zmk_rgb_underglow_on(saveState); + } + + return -ENOENT; +} + +int zmk_rgb_underglow_off(bool saveState) { + if (!led_strip) + return -ENODEV; + + state.on = false; + + for (int i = 0; i < STRIP_NUM_PIXELS; i++) { + pixels[i] = (struct led_rgb){r : 0, g : 0, b : 0}; + } + + led_strip_update_rgb(led_strip, pixels, STRIP_NUM_PIXELS); #if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_EXT_POWER) if (ext_power != NULL) { - int rc; - - if (state.on) { - rc = ext_power_enable(ext_power); - } else { - rc = ext_power_disable(ext_power); - } + int rc = ext_power_disable(ext_power, saveState); if (rc != 0) { LOG_ERR("Unable to toggle EXT_POWER: %d", rc); @@ -334,16 +370,37 @@ int zmk_rgb_underglow_toggle() { } #endif - if (state.on) { - state.animation_step = 0; - k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50)); - } else { - zmk_rgb_underglow_off(); + k_timer_stop(&underglow_tick); - k_timer_stop(&underglow_tick); + if (saveState) { + return zmk_rgb_underglow_save_state(); } - return zmk_rgb_underglow_save_state(); + return 0; +} + +int zmk_rgb_underglow_on(bool saveState) { + if (!led_strip) + return -ENODEV; + + state.on = true; + +#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_EXT_POWER) + if (ext_power != NULL) { + int rc = ext_power_enable(ext_power, saveState); + if (rc != 0) { + LOG_ERR("Unable to toggle EXT_POWER: %d", rc); + } + } +#endif + + state.animation_step = 0; + k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50)); + + if (saveState) { + return zmk_rgb_underglow_save_state(); + } + return 0; } int zmk_rgb_underglow_set_hsb(uint16_t hue, uint8_t saturation, uint8_t brightness) {