diff options
author | Nick Winans <nick.win999@gmail.com> | 2020-10-23 00:55:50 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-23 00:55:50 -0500 |
commit | 70ffcca3b42f5dacf5be155a56b11387a7e68b63 (patch) | |
tree | 80954a5afb17978ad897e3dde0385cfee0a902c9 /app/src/usb.c | |
parent | 162c6b77db27c158b05ed65effa8d8ded68ba9b7 (diff) | |
parent | 04b7a759f4c676c96da261a724cef1517614dea1 (diff) |
Merge branch 'main' into bluetooth/battery-reporting
Diffstat (limited to 'app/src/usb.c')
-rw-r--r-- | app/src/usb.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/app/src/usb.c b/app/src/usb.c new file mode 100644 index 0000000..434b3d4 --- /dev/null +++ b/app/src/usb.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include <device.h> +#include <init.h> + +#include <usb/usb_device.h> +#include <usb/class/usb_hid.h> +#include <dt-bindings/zmk/keys.h> + +#include <zmk/hid.h> +#include <zmk/keymap.h> + +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); + +static void in_ready_cb(void) { k_sem_give(&hid_sem); } + +static const struct hid_ops ops = { + .int_in_ready = in_ready_cb, +}; + +int zmk_usb_hid_send_report(const u8_t *report, size_t len) { + switch (usb_status) { + case USB_DC_SUSPEND: + return usb_wakeup_request(); + case USB_DC_ERROR: + case USB_DC_RESET: + case USB_DC_DISCONNECTED: + case USB_DC_UNKNOWN: + return -ENODEV; + default: + k_sem_take(&hid_sem, K_MSEC(30)); + int err = hid_int_ep_write(hid_dev, report, len, NULL); + + if (err) { + k_sem_give(&hid_sem); + } + + return err; + } +} + +#endif /* CONFIG_ZMK_USB */ + +enum usb_dc_status_code zmk_usb_get_status() { return usb_status; } + +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"); + return -EINVAL; + } + + usb_hid_register_device(hid_dev, zmk_hid_report_desc, sizeof(zmk_hid_report_desc), &ops); + + usb_hid_init(hid_dev); + +#endif /* CONFIG_ZMK_USB */ + + usb_enable_ret = usb_enable(usb_status_cb); + + if (usb_enable_ret != 0) { + LOG_ERR("Unable to enable USB"); + return -EINVAL; + } + + return 0; +} + +SYS_INIT(zmk_usb_init, APPLICATION, CONFIG_ZMK_USB_INIT_PRIORITY); |