summaryrefslogtreecommitdiff
path: root/app/src
diff options
context:
space:
mode:
Diffstat (limited to 'app/src')
-rw-r--r--app/src/endpoints.c2
-rw-r--r--app/src/ext_power_generic.c91
-rw-r--r--app/src/kscan_composite.c12
-rw-r--r--app/src/main.c9
-rw-r--r--app/src/power.c69
-rw-r--r--app/src/usb.c (renamed from app/src/usb_hid.c)17
6 files changed, 187 insertions, 13 deletions
diff --git a/app/src/endpoints.c b/app/src/endpoints.c
index ae78587..79d294e 100644
--- a/app/src/endpoints.c
+++ b/app/src/endpoints.c
@@ -6,7 +6,7 @@
#include <zmk/endpoints.h>
#include <zmk/hid.h>
-#include <zmk/usb_hid.h>
+#include <zmk/usb.h>
#include <zmk/hog.h>
#include <logging/log.h>
diff --git a/app/src/ext_power_generic.c b/app/src/ext_power_generic.c
new file mode 100644
index 0000000..4817030
--- /dev/null
+++ b/app/src/ext_power_generic.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2020 The ZMK Contributors
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#define DT_DRV_COMPAT zmk_ext_power_generic
+
+#include <device.h>
+#include <init.h>
+#include <drivers/gpio.h>
+#include <drivers/ext_power.h>
+
+#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
+
+#include <logging/log.h>
+LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
+
+struct ext_power_generic_config {
+ const char *label;
+ const u8_t pin;
+ const u8_t flags;
+};
+
+struct ext_power_generic_data {
+ struct device *gpio;
+ bool status;
+};
+
+static int ext_power_generic_enable(struct device *dev) {
+ struct ext_power_generic_data *data = dev->driver_data;
+ const struct ext_power_generic_config *config = dev->config_info;
+
+ if (gpio_pin_set(data->gpio, config->pin, 1)) {
+ LOG_WRN("Failed to set ext-power control pin");
+ return -EIO;
+ }
+ data->status = true;
+ return 0;
+}
+
+static int ext_power_generic_disable(struct device *dev) {
+ struct ext_power_generic_data *data = dev->driver_data;
+ const struct ext_power_generic_config *config = dev->config_info;
+
+ if (gpio_pin_set(data->gpio, config->pin, 0)) {
+ LOG_WRN("Failed to clear ext-power control pin");
+ return -EIO;
+ }
+ data->status = false;
+ return 0;
+}
+
+static int ext_power_generic_get(struct device *dev) {
+ struct ext_power_generic_data *data = dev->driver_data;
+ return data->status;
+}
+
+static int ext_power_generic_init(struct device *dev) {
+ struct ext_power_generic_data *data = dev->driver_data;
+ const struct ext_power_generic_config *config = dev->config_info;
+
+ data->gpio = device_get_binding(config->label);
+ if (data->gpio == NULL) {
+ LOG_ERR("Failed to get ext-power control device");
+ return -EINVAL;
+ }
+
+ if (gpio_pin_configure(data->gpio, config->pin, config->flags | GPIO_OUTPUT)) {
+ LOG_ERR("Failed to configure ext-power control pin");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static const struct ext_power_generic_config config = {
+ .label = DT_INST_GPIO_LABEL(0, control_gpios),
+ .pin = DT_INST_GPIO_PIN(0, control_gpios),
+ .flags = DT_INST_GPIO_FLAGS(0, control_gpios)};
+
+static struct ext_power_generic_data data = {.status = false};
+
+static const struct ext_power_api api = {.enable = ext_power_generic_enable,
+ .disable = ext_power_generic_disable,
+ .get = ext_power_generic_get};
+
+DEVICE_AND_API_INIT(ext_power_generic, DT_INST_LABEL(0), ext_power_generic_init, &data, &config,
+ APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &api);
+
+#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
diff --git a/app/src/kscan_composite.c b/app/src/kscan_composite.c
index 0249140..f8e8d60 100644
--- a/app/src/kscan_composite.c
+++ b/app/src/kscan_composite.c
@@ -38,8 +38,7 @@ struct kscan_composite_data {
};
static int kscan_composite_enable_callback(struct device *dev) {
- for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]);
- i++) {
+ for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) {
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
kscan_enable_callback(device_get_binding(cfg->label));
@@ -48,8 +47,7 @@ static int kscan_composite_enable_callback(struct device *dev) {
}
static int kscan_composite_disable_callback(struct device *dev) {
- for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]);
- i++) {
+ for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) {
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
kscan_disable_callback(device_get_binding(cfg->label));
@@ -63,8 +61,7 @@ static void kscan_composite_child_callback(struct device *child_dev, u32_t row,
struct device *dev = device_get_binding(DT_INST_LABEL(0));
struct kscan_composite_data *data = dev->driver_data;
- for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]);
- i++) {
+ for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) {
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
if (device_get_binding(cfg->label) != child_dev) {
@@ -82,8 +79,7 @@ static int kscan_composite_configure(struct device *dev, kscan_callback_t callba
return -EINVAL;
}
- for (int i = 0; i < sizeof(kscan_composite_children) / sizeof(kscan_composite_children[0]);
- i++) {
+ for (int i = 0; i < ARRAY_SIZE(kscan_composite_children); i++) {
const struct kscan_composite_child_config *cfg = &kscan_composite_children[i];
kscan_config(device_get_binding(cfg->label), &kscan_composite_child_callback);
diff --git a/app/src/main.c b/app/src/main.c
index dca923e..0551356 100644
--- a/app/src/main.c
+++ b/app/src/main.c
@@ -15,16 +15,25 @@ LOG_MODULE_REGISTER(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/matrix.h>
#include <zmk/kscan.h>
#include <zmk/display.h>
+#include <drivers/ext_power.h>
#define ZMK_KSCAN_DEV DT_LABEL(ZMK_MATRIX_NODE_ID)
void main(void) {
+ struct device *ext_power;
LOG_INF("Welcome to ZMK!\n");
if (zmk_kscan_init(ZMK_KSCAN_DEV) != 0) {
return;
}
+ // Enable the external VCC output
+ ext_power = device_get_binding("EXT_POWER");
+ if (ext_power != NULL) {
+ const struct ext_power_api *ext_power_api = ext_power->driver_api;
+ ext_power_api->enable(ext_power);
+ }
+
#ifdef CONFIG_ZMK_DISPLAY
zmk_display_init();
diff --git a/app/src/power.c b/app/src/power.c
new file mode 100644
index 0000000..73b3f12
--- /dev/null
+++ b/app/src/power.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2020 The ZMK Contributors
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <zephyr.h>
+#include <kernel.h>
+#include <power/power.h>
+
+#include <logging/log.h>
+
+LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
+
+#include <zmk/usb.h>
+#include <zmk/event-manager.h>
+#include <zmk/events/position-state-changed.h>
+#include <zmk/events/sensor-event.h>
+
+static u32_t power_last_uptime;
+
+#define MAX_IDLE_MS CONFIG_ZMK_IDLE_SLEEP_TIMEOUT
+
+bool is_usb_power_present() {
+#ifdef CONFIG_USB
+ enum usb_dc_status_code usb_status = zmk_usb_get_status();
+ switch (usb_status) {
+ case USB_DC_DISCONNECTED:
+ case USB_DC_UNKNOWN:
+ return false;
+ default:
+ return true;
+ }
+#else
+ return false;
+#endif /* CONFIG_USB */
+}
+
+enum power_states sys_pm_policy_next_state(s32_t ticks) {
+#ifdef CONFIG_SYS_POWER_DEEP_SLEEP_STATES
+#ifdef CONFIG_HAS_SYS_POWER_STATE_DEEP_SLEEP_1
+ s32_t current = k_uptime_get();
+ if (power_last_uptime > 0 && !is_usb_power_present() &&
+ current - power_last_uptime > MAX_IDLE_MS) {
+ return SYS_POWER_STATE_DEEP_SLEEP_1;
+ }
+#endif /* CONFIG_HAS_SYS_POWER_STATE_DEEP_SLEEP_1 */
+#endif /* CONFIG_SYS_POWER_DEEP_SLEEP_STATES */
+
+ return SYS_POWER_STATE_ACTIVE;
+}
+
+int power_event_listener(const struct zmk_event_header *eh) {
+ power_last_uptime = k_uptime_get();
+
+ return 0;
+}
+
+int power_init() {
+ power_last_uptime = k_uptime_get();
+
+ return 0;
+}
+
+ZMK_LISTENER(power, power_event_listener);
+ZMK_SUBSCRIPTION(power, position_state_changed);
+ZMK_SUBSCRIPTION(power, sensor_event);
+
+SYS_INIT(power_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); \ No newline at end of file
diff --git a/app/src/usb_hid.c b/app/src/usb.c
index 530ffea..434b3d4 100644
--- a/app/src/usb_hid.c
+++ b/app/src/usb.c
@@ -18,6 +18,8 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
static enum usb_dc_status_code usb_status = USB_DC_UNKNOWN;
+#ifdef CONFIG_ZMK_USB
+
static struct device *hid_dev;
static K_SEM_DEFINE(hid_sem, 1, 1);
@@ -49,11 +51,16 @@ int zmk_usb_hid_send_report(const u8_t *report, size_t len) {
}
}
-void usb_hid_status_cb(enum usb_dc_status_code status, const u8_t *params) { usb_status = status; };
+#endif /* CONFIG_ZMK_USB */
+
+enum usb_dc_status_code zmk_usb_get_status() { return usb_status; }
-static int zmk_usb_hid_init(struct device *_arg) {
+void usb_status_cb(enum usb_dc_status_code status, const u8_t *params) { usb_status = status; };
+
+static int zmk_usb_init(struct device *_arg) {
int usb_enable_ret;
+#ifdef CONFIG_ZMK_USB
hid_dev = device_get_binding("HID_0");
if (hid_dev == NULL) {
LOG_ERR("Unable to locate HID device");
@@ -64,7 +71,9 @@ static int zmk_usb_hid_init(struct device *_arg) {
usb_hid_init(hid_dev);
- usb_enable_ret = usb_enable(usb_hid_status_cb);
+#endif /* CONFIG_ZMK_USB */
+
+ usb_enable_ret = usb_enable(usb_status_cb);
if (usb_enable_ret != 0) {
LOG_ERR("Unable to enable USB");
@@ -74,4 +83,4 @@ static int zmk_usb_hid_init(struct device *_arg) {
return 0;
}
-SYS_INIT(zmk_usb_hid_init, APPLICATION, CONFIG_ZMK_USB_INIT_PRIORITY);
+SYS_INIT(zmk_usb_init, APPLICATION, CONFIG_ZMK_USB_INIT_PRIORITY);