Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Feature: Allow external power on USB only #1184

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ target_sources_ifdef(CONFIG_ZMK_USB app PRIVATE src/usb_hid.c)
target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/hog.c)
target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/rgb_underglow.c)
target_sources_ifdef(CONFIG_ZMK_BACKLIGHT app PRIVATE src/backlight.c)
target_sources_ifdef(CONFIG_ZMK_EXT_POWER_USB_ONLY app PRIVATE src/ext_power_usb_only.c)
target_sources(app PRIVATE src/endpoints.c)
target_sources(app PRIVATE src/hid_listener.c)
target_sources(app PRIVATE src/main.c)
Expand Down
4 changes: 4 additions & 0 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,10 @@ config ZMK_EXT_POWER
bool "Enable support to control external power output"
default y

config ZMK_EXT_POWER_USB_ONLY
bool "Turn off external power when USB is disconnected"
default n

#Power Management
endmenu

Expand Down
67 changes: 67 additions & 0 deletions app/src/ext_power_usb_only.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include <settings/settings.h>
#include <drivers/ext_power.h>
#include <zmk/activity.h>
#include <zmk/usb.h>
#include <zmk/event_manager.h>
#include <zmk/events/usb_conn_state_changed.h>
#include <logging/log.h>

LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);

#if IS_ENABLED(CONFIG_ZMK_EXT_POWER_USB_ONLY)

static bool initialized = false;

void zmk_ext_power_usb_only_toggle() {

// Do not touch external power until properly initialized.
// This prevents cutting external power until displays and other
// components are properly initialized
if (initialized == false) {
LOG_DBG("zmk_ext_power_usb_only not initialized yet. Ignoring.");
return;
}

const struct device *ext_power = device_get_binding("EXT_POWER");
const int ext_power_enabled = ext_power_get(ext_power);

if (zmk_usb_is_powered() == true && ext_power_enabled == false) {
LOG_DBG("USB power was connected. Enabling external power.");
ext_power_enable(ext_power);
} else if (zmk_usb_is_powered() == false && ext_power_enabled == true) {
LOG_DBG("USB power was removed. Disabling external power.");
ext_power_disable(ext_power);
}
}

static int zmk_ext_power_usb_only_event_listener(const zmk_event_t *eh) {
if (as_zmk_usb_conn_state_changed(eh)) {
LOG_DBG("USB conn state changed: %d", zmk_usb_is_powered());

zmk_ext_power_usb_only_toggle();
}

return 0;
}

ZMK_LISTENER(ext_power, zmk_ext_power_usb_only_event_listener);
ZMK_SUBSCRIPTION(ext_power, zmk_usb_conn_state_changed);

static int zmk_ext_power_usb_only_init(const struct device *_arg) {

LOG_DBG("Running zmk_ext_power_usb_only_init");

initialized = true;
zmk_ext_power_usb_only_toggle();

return 0;
}

// Initialized ext power usb only after everything else has been
// initialized.
//
// This avoids interrupting the iniitalization of displays for example.
#define ZMK_EXT_POWER_USB_ONLY_INIT_PRIORITY CONFIG_APPLICATION_INIT_PRIORITY+100
SYS_INIT(zmk_ext_power_usb_only_init, APPLICATION, ZMK_EXT_POWER_USB_ONLY_INIT_PRIORITY);

#endif