summaryrefslogtreecommitdiff
path: root/src/usb_hid.c
blob: 688b31c5493e8c5a542aeb49e51a139916046414 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <device.h>

#include <usb/usb_device.h>
#include <usb/class/usb_hid.h>

LOG_MODULE_REGISTER(zmk_usb_hid, CONFIG_ZMK_USB_HID_LOG_LEVEL);

static const u8_t hid_report_desc[] = HID_KEYBOARD_REPORT_DESC();
static enum usb_dc_status_code usb_status;

static struct device *hid_dev;
static u8_t report[8] = { 0x00, 0x00 };

#define KEY_OFFSET 0x02
#define MAX_KEYS 6

int zmk_usb_hid_press_key(enum hid_kbd_code code)
{
	if (usb_status == USB_DC_SUSPEND) {
		return usb_wakeup_request();
	}

	for (int idx = 0; idx < MAX_KEYS; idx++) {
		if (report[idx + KEY_OFFSET] != 0U) {
			continue;
		}

		report[idx + KEY_OFFSET] = code;

		return hid_int_ep_write(hid_dev, report, sizeof(report), NULL);
	}

	return -EINVAL;
}

int zmk_usb_hid_release_key(enum hid_kbd_code code)
{
	for (int idx = 0; idx < MAX_KEYS; idx++) {
		if (report[idx + KEY_OFFSET] != code) {
			continue;
		}

		report[idx + KEY_OFFSET] = 0U;

		return hid_int_ep_write(hid_dev, report, sizeof(report), NULL);
	}

	return -EINVAL;
}

void usb_hid_status_cb(enum usb_dc_status_code status, const u8_t *params)
{
	usb_status = status;
};

int zmk_usb_hid_init()
{
	int usb_enable_ret;

	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,
	                        hid_report_desc, sizeof(hid_report_desc),
	                        NULL);

	usb_hid_init(hid_dev);

	usb_enable_ret = usb_enable(usb_hid_status_cb);

	if (usb_enable_ret != 0) {
		LOG_ERR("Unable to enable USB");
		return -EINVAL;
	}

	return 0;
}