diff --git a/app/Kconfig b/app/Kconfig index d1b6682f..d937ea09 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -305,6 +305,10 @@ endmenu menu "Power Management" +config ZMK_USB_EXT_POWER_ONLY + bool "Turn off external power when USB is disconnected" + default n + config ZMK_IDLE_TIMEOUT int "Milliseconds of inactivity before entering idle state (OLED shutoff, etc)" default 30000 diff --git a/app/src/ext_power_generic.c b/app/src/ext_power_generic.c index e35714da..42e4ca91 100644 --- a/app/src/ext_power_generic.c +++ b/app/src/ext_power_generic.c @@ -16,6 +16,11 @@ #include +#include +#include +#include +#include + #if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) #include @@ -125,6 +130,33 @@ struct settings_handler ext_power_conf = {.name = "ext_power/state", .h_set = ext_power_settings_set}; #endif +#if IS_ENABLED(CONFIG_ZMK_USB_EXT_POWER_ONLY) +static int ext_power_toggle(const struct device *dev, bool enable) { + // If our new state matches the power state, do nothing + if (!enable == (ext_power_get(dev) > 0)) { + return 0; + } + if (enable) { + return ext_power_enable(dev); + } else { + return ext_power_disable(dev); + } +} + +static int ext_power_event_listener(const zmk_event_t *eh) { + if (as_zmk_usb_conn_state_changed(eh)) { + const struct device *ext_power = device_get_binding("EXT_POWER"); + return ext_power_toggle(ext_power, zmk_usb_is_powered()); + } + + return -ENOTSUP; +} + +ZMK_LISTENER(ext_power, ext_power_event_listener); + +ZMK_SUBSCRIPTION(ext_power, zmk_usb_conn_state_changed); +#endif + static int ext_power_generic_init(const struct device *dev) { struct ext_power_generic_data *data = dev->data; const struct ext_power_generic_config *config = dev->config; @@ -154,6 +186,8 @@ static int ext_power_generic_init(const struct device *dev) { ext_power_enable(dev); } +#elif IS_ENABLED(CONFIG_ZMK_USB_EXT_POWER_ONLY) + ext_power_toggle(dev, zmk_usb_is_powered()); #else // Default to the ext_power being open when no settings ext_power_enable(dev);