feat(underglow): tie underglow ext_pwr to sleep/idle
This commit is contained in:
parent
58ad5d4e86
commit
f4f0ff501f
6 changed files with 113 additions and 48 deletions
|
@ -22,8 +22,8 @@ extern "C" {
|
||||||
* (Internal use only.)
|
* (Internal use only.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef int (*ext_power_enable_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);
|
typedef int (*ext_power_disable_t)(const struct device *dev, bool);
|
||||||
typedef int (*ext_power_get_t)(const struct device *dev);
|
typedef int (*ext_power_get_t)(const struct device *dev);
|
||||||
|
|
||||||
__subsystem struct ext_power_api {
|
__subsystem struct ext_power_api {
|
||||||
|
@ -42,16 +42,16 @@ __subsystem struct ext_power_api {
|
||||||
* @retval 0 If successful.
|
* @retval 0 If successful.
|
||||||
* @retval Negative errno code if failure.
|
* @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;
|
const struct ext_power_api *api = (const struct ext_power_api *)dev->api;
|
||||||
|
|
||||||
if (api->enable == NULL) {
|
if (api->enable == NULL) {
|
||||||
return -ENOTSUP;
|
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 0 If successful.
|
||||||
* @retval Negative errno code if failure.
|
* @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;
|
const struct ext_power_api *api = (const struct ext_power_api *)dev->api;
|
||||||
|
|
||||||
if (api->disable == NULL) {
|
if (api->disable == NULL) {
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
return api->disable(dev);
|
return api->disable(dev, saveState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
|
|
||||||
#pragma once
|
#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_cycle_effect(int direction);
|
||||||
int zmk_rgb_underglow_change_hue(int direction);
|
int zmk_rgb_underglow_change_hue(int direction);
|
||||||
int zmk_rgb_underglow_change_sat(int direction);
|
int zmk_rgb_underglow_change_sat(int direction);
|
||||||
|
|
|
@ -26,14 +26,14 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||||
|
|
||||||
switch (binding->param1) {
|
switch (binding->param1) {
|
||||||
case EXT_POWER_OFF_CMD:
|
case EXT_POWER_OFF_CMD:
|
||||||
return ext_power_disable(ext_power);
|
return ext_power_disable(ext_power, true);
|
||||||
case EXT_POWER_ON_CMD:
|
case EXT_POWER_ON_CMD:
|
||||||
return ext_power_enable(ext_power);
|
return ext_power_enable(ext_power, true);
|
||||||
case EXT_POWER_TOGGLE_CMD:
|
case EXT_POWER_TOGGLE_CMD:
|
||||||
if (ext_power_get(ext_power) > 0)
|
if (ext_power_get(ext_power) > 0)
|
||||||
return ext_power_disable(ext_power);
|
return ext_power_disable(ext_power, true);
|
||||||
else
|
else
|
||||||
return ext_power_enable(ext_power);
|
return ext_power_enable(ext_power, true);
|
||||||
default:
|
default:
|
||||||
LOG_ERR("Unknown ext_power command: %d", binding->param1);
|
LOG_ERR("Unknown ext_power command: %d", binding->param1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||||
struct zmk_behavior_binding_event event) {
|
struct zmk_behavior_binding_event event) {
|
||||||
switch (binding->param1) {
|
switch (binding->param1) {
|
||||||
case RGB_TOG_CMD:
|
case RGB_TOG_CMD:
|
||||||
return zmk_rgb_underglow_toggle();
|
return zmk_rgb_underglow_toggle(true);
|
||||||
case RGB_HUI_CMD:
|
case RGB_HUI_CMD:
|
||||||
return zmk_rgb_underglow_change_hue(1);
|
return zmk_rgb_underglow_change_hue(1);
|
||||||
case RGB_HUD_CMD:
|
case RGB_HUD_CMD:
|
||||||
|
|
|
@ -58,7 +58,7 @@ int ext_power_save_state() {
|
||||||
#endif
|
#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;
|
struct ext_power_generic_data *data = dev->data;
|
||||||
const struct ext_power_generic_config *config = dev->config;
|
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;
|
return -EIO;
|
||||||
}
|
}
|
||||||
data->status = true;
|
data->status = true;
|
||||||
|
if (saveState) {
|
||||||
return ext_power_save_state();
|
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;
|
struct ext_power_generic_data *data = dev->data;
|
||||||
const struct ext_power_generic_config *config = dev->config;
|
const struct ext_power_generic_config *config = dev->config;
|
||||||
|
|
||||||
|
@ -79,8 +82,11 @@ static int ext_power_generic_disable(const struct device *dev) {
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
data->status = false;
|
data->status = false;
|
||||||
|
if (saveState) {
|
||||||
return ext_power_save_state();
|
return ext_power_save_state();
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ext_power_generic_get(const struct device *dev) {
|
static int ext_power_generic_get(const struct device *dev) {
|
||||||
struct ext_power_generic_data *data = dev->data;
|
struct ext_power_generic_data *data = dev->data;
|
||||||
|
@ -111,9 +117,9 @@ static int ext_power_settings_set(const char *name, size_t len, settings_read_cb
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->status) {
|
if (data->status) {
|
||||||
ext_power_generic_enable(ext_power);
|
ext_power_generic_enable(ext_power, true);
|
||||||
} else {
|
} else {
|
||||||
ext_power_generic_disable(ext_power);
|
ext_power_generic_disable(ext_power, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -164,7 +170,7 @@ static int ext_power_generic_init(const struct device *dev) {
|
||||||
data->status = true;
|
data->status = true;
|
||||||
k_delayed_work_submit(&ext_power_save_work, K_NO_WAIT);
|
k_delayed_work_submit(&ext_power_save_work, K_NO_WAIT);
|
||||||
|
|
||||||
ext_power_enable(dev);
|
ext_power_enable(dev, true);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Default to the ext_power being open when no settings
|
// 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;
|
data->pm_state = DEVICE_PM_ACTIVE_STATE;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
ext_power_generic_disable(dev);
|
ext_power_generic_disable(dev, false);
|
||||||
data->pm_state = DEVICE_PM_LOW_POWER_STATE;
|
data->pm_state = DEVICE_PM_LOW_POWER_STATE;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,17 @@
|
||||||
#include <drivers/led_strip.h>
|
#include <drivers/led_strip.h>
|
||||||
#include <drivers/ext_power.h>
|
#include <drivers/ext_power.h>
|
||||||
|
|
||||||
|
#include <zmk/event_manager.h>
|
||||||
|
#include <zmk/events/activity_state_changed.h>
|
||||||
|
|
||||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
#define STRIP_LABEL DT_LABEL(DT_CHOSEN(zmk_underglow))
|
#define STRIP_LABEL DT_LABEL(DT_CHOSEN(zmk_underglow))
|
||||||
#define STRIP_NUM_PIXELS DT_PROP(DT_CHOSEN(zmk_underglow), chain_length)
|
#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 {
|
enum rgb_underglow_effect {
|
||||||
UNDERGLOW_EFFECT_SOLID,
|
UNDERGLOW_EFFECT_SOLID,
|
||||||
UNDERGLOW_EFFECT_BREATHE,
|
UNDERGLOW_EFFECT_BREATHE,
|
||||||
|
@ -105,14 +111,6 @@ static struct led_rgb hsb_to_rgb(struct led_hsb hsb) {
|
||||||
return rgb;
|
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() {
|
static void zmk_rgb_underglow_effect_solid() {
|
||||||
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
|
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
|
||||||
int hue = state.hue;
|
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) {
|
static void zmk_rgb_underglow_tick_handler(struct k_timer *timer) {
|
||||||
if (!state.on) {
|
if (!state.on) {
|
||||||
zmk_rgb_underglow_off();
|
zmk_rgb_underglow_off(true);
|
||||||
|
|
||||||
k_timer_stop(timer);
|
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,
|
animation_speed : CONFIG_ZMK_RGB_UNDERGLOW_SPD_START,
|
||||||
current_effect : CONFIG_ZMK_RGB_UNDERGLOW_EFF_START,
|
current_effect : CONFIG_ZMK_RGB_UNDERGLOW_EFF_START,
|
||||||
animation_step : 0,
|
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)
|
#if IS_ENABLED(CONFIG_SETTINGS)
|
||||||
|
@ -283,6 +281,31 @@ static int zmk_rgb_underglow_init(const struct device *_arg) {
|
||||||
return 0;
|
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() {
|
int zmk_rgb_underglow_save_state() {
|
||||||
#if IS_ENABLED(CONFIG_SETTINGS)
|
#if IS_ENABLED(CONFIG_SETTINGS)
|
||||||
k_delayed_work_cancel(&underglow_save_work);
|
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();
|
return zmk_rgb_underglow_save_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmk_rgb_underglow_toggle() {
|
int zmk_rgb_underglow_toggle(bool saveState) {
|
||||||
if (!led_strip)
|
if (!led_strip)
|
||||||
return -ENODEV;
|
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 IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_EXT_POWER)
|
||||||
if (ext_power != NULL) {
|
if (ext_power != NULL) {
|
||||||
int rc;
|
int rc = ext_power_disable(ext_power, saveState);
|
||||||
|
|
||||||
if (state.on) {
|
|
||||||
rc = ext_power_enable(ext_power);
|
|
||||||
} else {
|
|
||||||
rc = ext_power_disable(ext_power);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
LOG_ERR("Unable to toggle EXT_POWER: %d", rc);
|
LOG_ERR("Unable to toggle EXT_POWER: %d", rc);
|
||||||
|
@ -334,17 +370,38 @@ int zmk_rgb_underglow_toggle() {
|
||||||
}
|
}
|
||||||
#endif
|
#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 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 zmk_rgb_underglow_save_state();
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int zmk_rgb_underglow_set_hsb(uint16_t hue, uint8_t saturation, uint8_t brightness) {
|
int zmk_rgb_underglow_set_hsb(uint16_t hue, uint8_t saturation, uint8_t brightness) {
|
||||||
if (hue > 360 || saturation > 100 || brightness > 100) {
|
if (hue > 360 || saturation > 100 || brightness > 100) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue