summaryrefslogtreecommitdiff
path: root/class/hid/usb_hid.h
blob: b2bd5713300a62ddcd60b5eff2290a2011da2e3d (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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
/*
 * Copyright (c) 2022, sakumisu
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#ifndef USB_HID_H
#define USB_HID_H

/* Subclass codes (HID 4.2) */
#define HID_SUBCLASS_NONE   0 /* No subclass */
#define HID_SUBCLASS_BOOTIF 1 /* Boot Interface Subclass */

/* HID Protocol Codes (HID 4.3) */
#define HID_PROTOCOL_NONE     0x00
#define HID_PROTOCOL_BOOT     0x00
#define HID_PROTOCOL_KEYBOARD 0x01
#define HID_PROTOCOL_REPORT   0x01
#define HID_PROTOCOL_MOUSE    0x02

/* HID Class Descriptor Types (HID 7.1) */
#define HID_DESCRIPTOR_TYPE_HID          0x21
#define HID_DESCRIPTOR_TYPE_HID_REPORT   0x22
#define HID_DESCRIPTOR_TYPE_HID_PHYSICAL 0x23

/* HID Class Specific Requests (HID 7.2) */
#define HID_REQUEST_GET_REPORT   0x01
#define HID_REQUEST_GET_IDLE     0x02
#define HID_REQUEST_GET_PROTOCOL 0x03
#define HID_REQUEST_SET_REPORT   0x09
#define HID_REQUEST_SET_IDLE     0x0A
#define HID_REQUEST_SET_PROTOCOL 0x0B

/* Report Type (MS byte of wValue for GET_REPORT) (HID 7.2.1) */
#define HID_REPORT_INPUT   0x01
#define HID_REPORT_OUTPUT  0x02
#define HID_REPORT_FEATURE 0x03

/* HID Descriptor */

#define HID_COUNTRY_NONE        0x00 /* Not Supported */
#define HID_COUNTRY_ARABIC      0x01 /* Arabic */
#define HID_COUNTRY_BELGIAN     0x02 /* Belgian */
#define HID_COUNTRY_CANADA      0x03 /* Canadian-Bilingual */
#define HID_COUNTRY_CANADRFR    0x04 /* Canadian-French */
#define HID_COUNTRY_CZECH       0x05 /* Czech Republic */
#define HID_COUNTRY_DANISH      0x06 /* Danish */
#define HID_COUNTRY_FINNISH     0x07 /* Finnish */
#define HID_COUNTRY_FRENCH      0x08 /* French */
#define HID_COUNTRY_GERMAN      0x09 /* German */
#define HID_COUNTRY_GREEK       0x10 /* Greek */
#define HID_COUNTRY_HEBREW      0x11 /* Hebrew */
#define HID_COUNTRY_HUNGARY     0x12 /* Hungary */
#define HID_COUNTRY_ISO         0x13 /* International (ISO) */
#define HID_COUNTRY_ITALIAN     0x14 /* Italian */
#define HID_COUNTRY_JAPAN       0x15 /* Japan (Katakana) */
#define HID_COUNTRY_KOREAN      0x16 /* Korean  */
#define HID_COUNTRY_LATINAM     0x17 /* Latin American */
#define HID_COUNTRY_DUTCH       0x18 /* Netherlands/Dutch */
#define HID_COUNTRY_NORWEGIAN   0x19 /* Norwegian */
#define HID_COUNTRY_PERSIAN     0x20 /* Persian (Farsi) */
#define HID_COUNTRY_POLAND      0x21 /* Poland */
#define HID_COUNTRY_PORTUGUESE  0x22 /* Portuguese */
#define HID_COUNTRY_RUSSIA      0x23 /* Russia */
#define HID_COUNTRY_SLOVAKIA    0x24 /* Slovakia */
#define HID_COUNTRY_SPANISH     0x25 /* Spanish */
#define HID_COUNTRY_SWEDISH     0x26 /* Swedish */
#define HID_COUNTRY_SWISSFR     0x27 /* Swiss/French */
#define HID_COUNTRY_SWISSGR     0x28 /* Swiss/German */
#define HID_COUNTRY_SWITZERLAND 0x29 /* Switzerland */
#define HID_COUNTRY_TAIWAN      0x30 /* Taiwan */
#define HID_COUNTRY_TURKISHQ    0x31 /* Turkish-Q */
#define HID_COUNTRY_UK          0x32 /* UK */
#define HID_COUNTRY_US          0x33 /* US */
#define HID_COUNTRY_YUGOSLAVIA  0x34 /* Yugoslavia */
#define HID_COUNTRY_TURKISHF    0x35 /* Turkish-F */

/* HID report See specification at
 * https://www.usb.org/sites/default/files/hid1_11.pdf
 * https://www.usb.org/sites/default/files/hut1_22.pdf
 */

#define HID_SIZE_MASK (0x3 << 0)
#define HID_TYPE_MASK (0x3 << 2)
#define HID_TAG_MASK  (0xF << 4)

#define HID_ITEMTYPE_MAIN   (0x0 << 2)
#define HID_ITEMTYPE_GLOBAL (0x1 << 2)
#define HID_ITEMTYPE_LOCAL  (0x2 << 2)
#define HID_ITEMTYPE_LONG   (0x3 << 2)

/* Main Items (HID 6.2.2.4) */
#define HID_MAINITEM_TAG_INPUT         (0x08 << 4)
#define HID_MAINITEM_TAG_OUTPUT        (0x09 << 4)
#define HID_MAINITEM_TAG_COLLECTION    (0x0a << 4)
#define HID_MAINITEM_TAG_FEATURE       (0x0b << 4)
#define HID_MAINITEM_TAG_ENDCOLLECTION (0x0c << 4)

#define HID_MAINITEM_CONSTANT      (1 << 0) /* Constant(1) vs Data(0) */
#define HID_MAINITEM_VARIABLE      (1 << 1) /* Variable(1) vs Array(0) */
#define HID_MAINITEM_RELATIVE      (1 << 2) /* Relative(1) vs Absolute(0) */
#define HID_MAINITEM_WRAP          (1 << 3) /* Wrap(1) vs No Wrap(0) */
#define HID_MAINITEM_NONLINEAR     (1 << 4) /* Non Linear(1) vs Linear(0) */
#define HID_MAINITEM_NOPREFERRED   (1 << 5) /* No Preferred (1) vs Preferred State(0) */
#define HID_MAINITEM_NULLSTATE     (1 << 6) /* Null state(1) vs No Null position(0) */
#define HID_MAINITEM_VOLATILE      (1 << 7) /* Volatile(1) vs Non volatile(0) */
#define HID_MAINITEM_BUFFEREDBYTES (1 << 8) /* Buffered Bytes(1) vs Bit Field(0) */

#define HID_MAINITEM_COLLECTION_PHYSICAL 0x00 /* Physical (group of axes) */
#define HID_MAINITEM_COLLECTION_APPL     0x01 /* Application (mouse, keyboard) */
#define HID_MAINITEM_COLLECTION_LOGICAL  0x02 /* Logical (interrelated data) */
#define HID_MAINITEM_COLLECTION_REPORT   0x03 /* Report */
#define HID_MAINITEM_COLLECTION_ARRAY    0x04 /* Named Array */
#define HID_MAINITEM_COLLECTION_SWITCH   0x05 /* Usage Switch */
#define HID_MAINITEM_COLLECTION_MODIFIER 0x06 /* Usage Modifier */

/* Global Items (HID 6.2.2.7) */
#define HID_GLOBALITEM_TAG_USAGE_PAGE   (0x00 << 4)
#define HID_GLOBALITEM_TAG_LOGICAL_MIN  (0x01 << 4)
#define HID_GLOBALITEM_TAG_LOGICAL_MAX  (0x02 << 4)
#define HID_GLOBALITEM_TAG_PHYSICAL_MIN (0x03 << 4)
#define HID_GLOBALITEM_TAG_PHYSICAL_MAX (0x04 << 4)
#define HID_GLOBALITEM_TAG_UNIT_EXP     (0x05 << 4)
#define HID_GLOBALITEM_TAG_UNIT         (0x06 << 4)
#define HID_GLOBALITEM_TAG_REPORT_SIZE  (0x07 << 4)
#define HID_GLOBALITEM_TAG_REPORT_ID    (0x08 << 4)
#define HID_GLOBALITEM_TAG_REPORT_COUNT (0x09 << 4)
#define HID_GLOBALITEM_TAG_PUSH         (0x0a << 4)
#define HID_GLOBALITEM_TAG_POP          (0x0b << 4)

/* Local Items (HID 6.2.2.8) */
#define HID_LOCALITEM_TAG_USAGE       (0x00 << 4)
#define HID_LOCALITEM_TAG_USAGE_MIN   (0x01 << 4)
#define HID_LOCALITEM_TAG_USAGE_MAX   (0x02 << 4)
#define HID_LOCALITEM_TAG_DESIG_INDEX (0x03 << 4)
#define HID_LOCALITEM_TAG_DESIG_MIN   (0x04 << 4)
#define HID_LOCALITEM_TAG_DESIG_MAX   (0x05 << 4)
/* No 6 in spec */
#define HID_LOCALITEM_TAG_STRING_INDEX (0x07 << 4)
#define HID_LOCALITEM_TAG_STRING_MIN   (0x08 << 4)
#define HID_LOCALITEM_TAG_STRING_MAX   (0x09 << 4)
#define HID_LOCALITEM_TAG_DELIMITER    (0x0a << 4) /* Also listed as reserved in spec! */

/* Usage pages (HuT 3) */
#define HID_USAGE_PAGE_UNDEFINED                0x00  /* Undefined */
#define HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS 0x01  /* Generic Desktop Controls */
#define HID_USAGE_PAGE_SIMULATION_CONTROLS      0x02  /* Simulation Controls */
#define HID_USAGE_PAGE_VR_CONTROLS              0x03  /* VR Controls */
#define HID_USAGE_PAGE_SPORT_CONTROLS           0x04  /* Sport Controls */
#define HID_USAGE_PAGE_GAME_CONTROLS            0x05  /* Game Controls */
#define HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS  0x06  /* Generic Device Controls */
#define HID_USAGE_PAGE_KEYBOARD_KEYPAD          0x07  /* Keyboard/Keypad */
#define HID_USAGE_PAGE_LED                      0x08  /* LEDs */
#define HID_USAGE_PAGE_BUTTON                   0x09  /* Button */
#define HID_USAGE_PAGE_ORDINAL                  0x0a  /* Ordinal */
#define HID_USAGE_PAGE_TELEPHONY                0x0b  /* Telephony */
#define HID_USAGE_PAGE_CONSUMER                 0x0c  /* Consumer */
#define HID_USAGE_PAGE_DIGITIZER                0x0d  /* Digitizer */
#define HID_USAGE_PAGE_HAPTICS                        /* 0x0e Reserved */
#define HID_USAGE_PAGE_PID                      0x0f  /* PID Page  Physical Interface Device */
#define HID_USAGE_PAGE_UNICODE                  0x10  /* Unicode */
#define HID_USAGE_PAGE_SOC                      0x11  /* Sensor Orientation Category */
#define HID_USAGE_PAGE_EYE_AND_HEAD_TRACKER     0x12  /* Eye and Head Tracker */
                                                      /* 0x13 Reserved */
#define HID_USAGE_PAGE_ALPHA_DISPLAY 0x14             /* Alphanumeric Display */
                                                      /* 0x15-3f Reserved */
#define HID_USAGE_PAGE_MEDICAL         0x40           /* Medical Instruments */
#define HID_USAGE_PAGE_BRAILLE_DISPLAY 0x41           /* Braille Display */
                                                      /* 0x42-0x58 Reserved */
#define HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION 0x59 /* Lighting and Illumination */
                                                      /* 0x5a-0x7f Reserved */
#define HID_USAGE_PAGE_USB_MONITOR           0x80     /* USB Monitor */
#define HID_USAGE_PAGE_USB_ENUMERATED_VALUES 0x81     /* USB Enumerated Values */
#define HID_USAGE_PAGE_VESA_VIRTUAL_CONTROLS 0x82     /* VESA Virtual Controls */
#define HID_USAGE_PAGE_POWER_DEVICE          0x84     /* Power Device */
#define HID_USAGE_PAGE_BATTERY_SYSTEM        0x85     /* Battery System */
#define HID_USAGE_PAGE_BARCODE_SCANNER       0x8c     /* Bar Code Scanner page */
#define HID_USAGE_PAGE_SCALE                 0x8d     /* Scale page */
#define HID_USAGE_PAGE_MSR                   0x8e     /* Magnetic Stripe Reading (MSR) Devices */
#define HID_USAGE_PAGE_POS                   0x8f     /* Point of Sale devices */
#define HID_USAGE_PAGE_CAMERA_CONTROL        0x90     /* Camera Control Page */
#define HID_USAGE_PAGE_ARCADE                0x91
#define HID_USAGE_PAGE_GAMING_DEVICE         0x92
#define HID_USAGE_PAGE_FIDO_ALLIANCE         0xF1D0
#define HID_USAGE_PAGE_VENDOR_PAGE_HBYTE     0xFF00

/* Modifier Keys (HID 8.3) */
#define HID_MODIFIER_LCTRL  (1 << 0) /* Left Ctrl */
#define HID_MODIFIER_LSHIFT (1 << 1) /* Left Shift */
#define HID_MODIFIER_LALT   (1 << 2) /* Left Alt */
#define HID_MODIFIER_LGUI   (1 << 3) /* Left GUI */
#define HID_MODIFIER_RCTRL  (1 << 4) /* Right Ctrl */
#define HID_MODIFIER_RSHIFT (1 << 5) /* Right Shift */
#define HID_MODIFIER_RALT   (1 << 6) /* Right Alt */
#define HID_MODIFIER_RGUI   (1 << 7) /* Right GUI */

/* Keyboard output report (1 byte) (HID B.1) */
#define HID_KBD_OUTPUT_REPORT_NUMLOCK    (1 << 0)
#define HID_KBD_OUTPUT_REPORT_CAPSLOCK   (1 << 1)
#define HID_KBD_OUTPUT_REPORT_SCROLLLOCK (1 << 2)
#define HID_KBD_OUTPUT_REPORT_COMPOSE    (1 << 3)
#define HID_KBD_OUTPUT_REPORT_KANA       (1 << 4)

/* Mouse input report (HID B.2) */
#define HID_MOUSE_INPUT_REPORT_BUTTON1     (1 << 0)
#define HID_MOUSE_INPUT_REPORT_BUTTON2     (1 << 1)
#define HID_MOUSE_INPUT_REPORT_BUTTON3     (1 << 2)
#define HID_MOUSE_INPUT_REPORT_BUTTON_MASK (7)

#define HID_MOUSE_INPUT_BUTTON_LEFT     (1 << 0)
#define HID_MOUSE_INPUT_BUTTON_RIGHT    (1 << 1)
#define HID_MOUSE_INPUT_BUTTON_MIDDLE   (1 << 2)
#define HID_MOUSE_INPUT_BUTTON_BACKWARD (1 << 3)
#define HID_MOUSE_INPUT_BUTTON_FORWARD  (1 << 4)

/* Joystick input report (4 bytes) (HID D.1) */
#define HID_JS_INPUT_REPORT_HATSWITCH_SHIFT (0)
#define HID_JS_INPUT_REPORT_HATSWITCH_MASK  (15 << HID_JSIN_HATSWITCH_SHIFT)
#define HID_JS_INPUT_REPORT_BUTTON1         (1 << 4)
#define HID_JS_INPUT_REPORT_BUTTON2         (1 << 5)
#define HID_JS_INPUT_REPORT_BUTTON3         (1 << 6)
#define HID_JS_INPUT_REPORT_BUTTON4         (1 << 7)

/* Generic Desktop Page Usage IDs (HuT 4) */
#define HID_DESKTOP_USAGE_UNDEFINED 0x00        /* Undefined */
#define HID_DESKTOP_USAGE_POINTER   0x01        /* Pointer */
#define HID_DESKTOP_USAGE_MOUSE     0x02        /* Mouse */
                                                /* 0x03 Reserved */
#define HID_DESKTOP_USAGE_JOYSTICK  0x04        /* Joystick */
#define HID_DESKTOP_USAGE_GAMEPAD   0x05        /* Game Pad */
#define HID_DESKTOP_USAGE_KEYBOARD  0x06        /* Keyboard */
#define HID_DESKTOP_USAGE_KEYPAD    0x07        /* Keypad */
#define HID_DESKTOP_USAGE_MULTIAXIS 0x08        /* Multi-axis Controller */
#define HID_DESKTOP_USAGE_TABLET    0x09        /* Tablet PC System Controls */
                                                /* 0x0a-2f Reserved */
#define HID_DESKTOP_USAGE_X         0x30        /* X */
#define HID_DESKTOP_USAGE_Y         0x31        /* Y */
#define HID_DESKTOP_USAGE_Z         0x32        /* Z */
#define HID_DESKTOP_USAGE_RX        0x33        /* Rx */
#define HID_DESKTOP_USAGE_RY        0x34        /* Ry */
#define HID_DESKTOP_USAGE_RZ        0x35        /* Rz */
#define HID_DESKTOP_USAGE_SLIDER    0x36        /* Slider */
#define HID_DESKTOP_USAGE_DIAL      0x37        /* Dial */
#define HID_DESKTOP_USAGE_WHEEL     0x38        /* Wheel */
#define HID_DESKTOP_USAGE_HATSWITCH 0x39        /* Hat switch */
#define HID_DESKTOP_USAGE_COUNTED   0x3a        /* Counted Buffer */
#define HID_DESKTOP_USAGE_BYTECOUNT 0x3b        /* Byte Count */
#define HID_DESKTOP_USAGE_MOTION    0x3c        /* Motion Wakeup */
#define HID_DESKTOP_USAGE_START     0x3d        /* Start */
#define HID_DESKTOP_USAGE_SELECT    0x3e        /* Select */
                                                /* 0x3f Reserved */
#define HID_DESKTOP_USAGE_VX         0x40       /* Vx */
#define HID_DESKTOP_USAGE_VY         0x41       /* Vy */
#define HID_DESKTOP_USAGE_VZ         0x42       /* Vz */
#define HID_DESKTOP_USAGE_VBRX       0x43       /* Vbrx */
#define HID_DESKTOP_USAGE_VBRY       0x44       /* Vbry */
#define HID_DESKTOP_USAGE_VBRZ       0x45       /* Vbrz */
#define HID_DESKTOP_USAGE_VNO        0x46       /* Vno */
#define HID_DESKTOP_USAGE_FEATURE    0x47       /* Feature Notification */
#define HID_DESKTOP_USAGE_RESOLUTION 0x48       /* Resolution Multiplier */
                                                /* 0x49-7f Reserved */
#define HID_DESKTOP_USAGE_CONTROL      0x80     /* System Control */
#define HID_DESKTOP_USAGE_POWERDOWN    0x81     /* System Power Down */
#define HID_DESKTOP_USAGE_SLEEP        0x82     /* System Sleep */
#define HID_DESKTOP_USAGE_WAKEUP       0x83     /* System Wake Up */
#define HID_DESKTOP_USAGE_CONTEXT_MENU 0x84     /* System Context Menu */
#define HID_DESKTOP_USAGE_MAIN_MENU    0x85     /* System Main Menu */
#define HID_DESKTOP_USAGE_APP_MENU     0x86     /* System App Menu */
#define HID_DESKTOP_USAGE_MENU_HELP    0x87     /* System Menu Help */
#define HID_DESKTOP_USAGE_MENU_EXIT    0x88     /* System Menu Exit */
#define HID_DESKTOP_USAGE_MENU_SELECT  0x89     /* System Menu Select */
#define HID_DESKTOP_USAGE_MENU_RIGHT   0x8a     /* System Menu Right */
#define HID_DESKTOP_USAGE_MENU_LEFT    0x8b     /* System Menu Left */
#define HID_DESKTOP_USAGE_MENU_UP      0x8c     /* System Menu Up */
#define HID_DESKTOP_USAGE_MENU_DOWN    0x8d     /* System Menu Down */
#define HID_DESKTOP_USAGE_COLD_RESTART 0x8e     /* System Cold Restart */
#define HID_DESKTOP_USAGE_WARM_RESTART 0x8f     /* System Warm Restart */
#define HID_DESKTOP_USAGE_DPAD_UP      0x90     /* D-pad Up */
#define HID_DESKTOP_USAGE_DPAD_DOWN    0x91     /* D-pad Down */
#define HID_DESKTOP_USAGE_DPAD_RIGHT   0x92     /* D-pad Right */
#define HID_DESKTOP_USAGE_DPAD_LEFT    0x93     /* D-pad Left */
                                                /* 0x94-9f Reserved */
#define HID_DESKTOP_USAGE_DOCK            0xa0  /* System Dock */
#define HID_DESKTOP_USAGE_UNDOCK          0xa1  /* System Undock */
#define HID_DESKTOP_USAGE_SETUP           0xa2  /* System Setup */
#define HID_DESKTOP_USAGE_BREAK           0xa3  /* System Break */
#define HID_DESKTOP_USAGE_DEBUG_BREAK     0xa4  /* System Debugger Break */
#define HID_DESKTOP_USAGE_APP_BREAK       0xa5  /* Application Break */
#define HID_DESKTOP_USAGE_APP_DEBUG_BREAK 0xa6  /* Application Debugger Break */
#define HID_DESKTOP_USAGE_MUTE            0xa7  /* System Speaker Mute */
#define HID_DESKTOP_USAGE_HIBERNATE       0xa8  /* System Hibernate */
                                                /* 0xa9-af Reserved */
#define HID_DESKTOP_USAGE_DISPLAY_INVERT   0xb0 /* System Display Invert */
#define HID_DESKTOP_USAGE_DISPALY_INTERNAL 0xb1 /* System Display Internal */
#define HID_DESKTOP_USAGE_DISPLAY_EXTERNAL 0xb2 /* System Display External */
#define HID_DESKTOP_USAGE_DISPLAY_BOTH     0xb3 /* System Display Both */
#define HID_DESKTOP_USAGE_DISPLAY_DUAL     0xb4 /* System Display Dual */
#define HID_DESKTOP_USAGE_DISPLAY_TOGGLE   0xb5 /* System Display Toggle Int/Ext */
#define HID_DESKTOP_USAGE_DISPLAY_SWAP     0xb6 /* System Display Swap */
#define HID_DESKTOP_USAGE_                 0xb7 /* System Display LCD Autoscale */
                                                /* 0xb8-ffff Reserved */

/* Keyboard usage IDs (HuT 10) */
#define HID_KBD_USAGE_NONE            0x00 /* Reserved (no event indicated) */
#define HID_KBD_USAGE_ERRORROLLOVER   0x01 /* Keyboard ErrorRollOver */
#define HID_KBD_USAGE_POSTFAIL        0x02 /* Keyboard POSTFail */
#define HID_KBD_USAGE_ERRUNDEF        0x03 /* Keyboard ErrorUndefined */
#define HID_KBD_USAGE_A               0x04 /* Keyboard a or A (B-Z follow) */
#define HID_KBD_USAGE_1               0x1e /* Keyboard 1 (2-9 follow) */
#define HID_KBD_USAGE_EXCLAM          0x1e /* Keyboard 1 and ! */
#define HID_KBD_USAGE_AT              0x1f /* Keyboard 2 and @ */
#define HID_KBD_USAGE_POUND           0x20 /* Keyboard 3 and # */
#define HID_KBD_USAGE_DOLLAR          0x21 /* Keyboard 4 and $ */
#define HID_KBD_USAGE_PERCENT         0x22 /* Keyboard 5 and % */
#define HID_KBD_USAGE_CARAT           0x23 /* Keyboard 6 and ^ */
#define HID_KBD_USAGE_AMPERSAND       0x24 /* Keyboard 7 and & */
#define HID_KBD_USAGE_ASTERISK        0x25 /* Keyboard 8 and * */
#define HID_KBD_USAGE_LPAREN          0x26 /* Keyboard 9 and ( */
#define HID_KBD_USAGE_0               0x27 /* Keyboard 0 and ) */
#define HID_KBD_USAGE_RPAREN          0x27 /* Keyboard 0 and ) */
#define HID_KBD_USAGE_ENTER           0x28 /* Keyboard Return (ENTER) */
#define HID_KBD_USAGE_ESCAPE          0x29 /* Keyboard ESCAPE */
#define HID_KBD_USAGE_DELETE          0x2a /* Keyboard DELETE (Backspace) */
#define HID_KBD_USAGE_TAB             0x2b /* Keyboard Tab */
#define HID_KBD_USAGE_SPACE           0x2c /* Keyboard Spacebar */
#define HID_KBD_USAGE_HYPHEN          0x2d /* Keyboard - and (underscore) */
#define HID_KBD_USAGE_UNDERSCORE      0x2d /* Keyboard - and (underscore) */
#define HID_KBD_USAGE_EQUAL           0x2e /* Keyboard = and + */
#define HID_KBD_USAGE_PLUS            0x2e /* Keyboard = and + */
#define HID_KBD_USAGE_LBRACKET        0x2f /* Keyboard [ and { */
#define HID_KBD_USAGE_LBRACE          0x2f /* Keyboard [ and { */
#define HID_KBD_USAGE_RBRACKET        0x30 /* Keyboard ] and } */
#define HID_KBD_USAGE_RBRACE          0x30 /* Keyboard ] and } */
#define HID_KBD_USAGE_BSLASH          0x31 /* Keyboard \ and | */
#define HID_KBD_USAGE_VERTBAR         0x31 /* Keyboard \ and | */
#define HID_KBD_USAGE_NONUSPOUND      0x32 /* Keyboard Non-US # and ~ */
#define HID_KBD_USAGE_TILDE           0x32 /* Keyboard Non-US # and ~ */
#define HID_KBD_USAGE_SEMICOLON       0x33 /* Keyboard ; and : */
#define HID_KBD_USAGE_COLON           0x33 /* Keyboard ; and : */
#define HID_KBD_USAGE_SQUOTE          0x34 /* Keyboard ' and " */
#define HID_KBD_USAGE_DQUOUTE         0x34 /* Keyboard ' and " */
#define HID_KBD_USAGE_GACCENT         0x35 /* Keyboard Grave Accent and Tilde */
#define HID_KBD_USAGE_GTILDE          0x35 /* Keyboard Grave Accent and Tilde */
#define HID_KBD_USAGE_COMMON          0x36 /* Keyboard , and < */
#define HID_KBD_USAGE_LT              0x36 /* Keyboard , and < */
#define HID_KBD_USAGE_PERIOD          0x37 /* Keyboard . and > */
#define HID_KBD_USAGE_GT              0x37 /* Keyboard . and > */
#define HID_KBD_USAGE_DIV             0x38 /* Keyboard / and ? */
#define HID_KBD_USAGE_QUESTION        0x38 /* Keyboard / and ? */
#define HID_KBD_USAGE_CAPSLOCK        0x39 /* Keyboard Caps Lock */
#define HID_KBD_USAGE_F1              0x3a /* Keyboard F1 */
#define HID_KBD_USAGE_F2              0x3b /* Keyboard F2 */
#define HID_KBD_USAGE_F3              0x3c /* Keyboard F3 */
#define HID_KBD_USAGE_F4              0x3d /* Keyboard F4 */
#define HID_KBD_USAGE_F5              0x3e /* Keyboard F5 */
#define HID_KBD_USAGE_F6              0x3f /* Keyboard F6 */
#define HID_KBD_USAGE_F7              0x40 /* Keyboard F7 */
#define HID_KBD_USAGE_F8              0x41 /* Keyboard F8 */
#define HID_KBD_USAGE_F9              0x42 /* Keyboard F9 */
#define HID_KBD_USAGE_F10             0x43 /* Keyboard F10 */
#define HID_KBD_USAGE_F11             0x44 /* Keyboard F11 */
#define HID_KBD_USAGE_F12             0x45 /* Keyboard F12 */
#define HID_KBD_USAGE_PRINTSCN        0x46 /* Keyboard PrintScreen */
#define HID_KBD_USAGE_SCROLLLOCK      0x47 /* Keyboard Scroll Lock */
#define HID_KBD_USAGE_PAUSE           0x48 /* Keyboard Pause */
#define HID_KBD_USAGE_INSERT          0x49 /* Keyboard Insert */
#define HID_KBD_USAGE_HOME            0x4a /* Keyboard Home */
#define HID_KBD_USAGE_PAGEUP          0x4b /* Keyboard PageUp */
#define HID_KBD_USAGE_DELFWD          0x4c /* Keyboard Delete Forward */
#define HID_KBD_USAGE_END             0x4d /* Keyboard End */
#define HID_KBD_USAGE_PAGEDOWN        0x4e /* Keyboard PageDown */
#define HID_KBD_USAGE_RIGHT           0x4f /* eyboard RightArrow */
#define HID_KBD_USAGE_LEFT            0x50 /* Keyboard LeftArrow */
#define HID_KBD_USAGE_DOWN            0x51 /* Keyboard DownArrow */
#define HID_KBD_USAGE_UP              0x52 /* Keyboard UpArrow */
#define HID_KBD_USAGE_KPDNUMLOCK      0x53 /* Keypad Num Lock and Clear */
#define HID_KBD_USAGE_KPDNUMLOCKCLEAR 0x53 /* Keypad Num Lock and Clear */
#define HID_KBD_USAGE_KPDDIV          0x54 /* Keypad / */
#define HID_KBD_USAGE_KPDMUL          0x55 /* Keypad * */
#define HID_KBD_USAGE_KPDHMINUS       0x56 /* Keypad - */
#define HID_KBD_USAGE_KPDPLUS         0x57 /* Keypad + */
#define HID_KBD_USAGE_KPDEMTER        0x58 /* Keypad ENTER */
#define HID_KBD_USAGE_KPD1            0x59 /* Keypad 1 (2-9 follow) */
#define HID_KBD_USAGE_KPDEND          0x59 /* Keypad 1 and End */
#define HID_KBD_USAGE_KPDDOWN         0x5a /* Keypad 2 and Down Arrow */
#define HID_KBD_USAGE_KPDPAGEDN       0x5b /* Keypad 3 and PageDn */
#define HID_KBD_USAGE_KPDLEFT         0x5c /* Keypad 4 and Left Arrow */
#define HID_KBD_USAGE_KPDRIGHT        0x5e /* Keypad 6 and Right Arrow */
#define HID_KBD_USAGE_KPDHOME         0x5f /* Keypad 7 and Home */
#define HID_KBD_USAGE_KPDUP           0x60 /* Keypad 8 and Up Arrow */
#define HID_KBD_USAGE_KPDPAGEUP       0x61 /* Keypad 9 and PageUp */
#define HID_KBD_USAGE_KPD0            0x62 /* Keypad 0 and Insert */
#define HID_KBD_USAGE_KPDINSERT       0x62 /* Keypad 0 and Insert */
#define HID_KBD_USAGE_KPDDECIMALPT    0x63 /* Keypad . and Delete */
#define HID_KBD_USAGE_KPDDELETE       0x63 /* Keypad . and Delete */
#define HID_KBD_USAGE_NONSLASH        0x64 /* Keyboard Non-US \ and | */
#define HID_KBD_USAGE_NONUSVERT       0x64 /* Keyboard Non-US \ and | */
#define HID_KBD_USAGE_APPLICATION     0x65 /* Keyboard Application */
#define HID_KBD_USAGE_POWER           0x66 /* Keyboard Power */
#define HID_KBD_USAGE_KPDEQUAL        0x67 /* Keypad = */
#define HID_KBD_USAGE_F13             0x68 /* Keyboard F13 */
#define HID_KBD_USAGE_F14             0x69 /* Keyboard F14 */
#define HID_KBD_USAGE_F15             0x6a /* Keyboard F15 */
#define HID_KBD_USAGE_F16             0x6b /* Keyboard F16 */
#define HID_KBD_USAGE_F17             0x6c /* Keyboard F17 */
#define HID_KBD_USAGE_F18             0x6d /* Keyboard F18 */
#define HID_KBD_USAGE_F19             0x6e /* Keyboard F19 */
#define HID_KBD_USAGE_F20             0x6f /* Keyboard F20 */
#define HID_KBD_USAGE_F21             0x70 /* Keyboard F21 */
#define HID_KBD_USAGE_F22             0x71 /* Keyboard F22 */
#define HID_KBD_USAGE_F23             0x72 /* Keyboard F23 */
#define HID_KBD_USAGE_F24             0x73 /* Keyboard F24 */
#define HID_KBD_USAGE_EXECUTE         0x74 /* Keyboard Execute */
#define HID_KBD_USAGE_HELP            0x75 /* Keyboard Help */
#define HID_KBD_USAGE_MENU            0x76 /* Keyboard Menu */
#define HID_KBD_USAGE_SELECT          0x77 /* Keyboard Select */
#define HID_KBD_USAGE_STOP            0x78 /* Keyboard Stop */
#define HID_KBD_USAGE_AGAIN           0x79 /* Keyboard Again */
#define HID_KBD_USAGE_UNDO            0x7a /* Keyboard Undo */
#define HID_KBD_USAGE_CUT             0x7b /* Keyboard Cut */
#define HID_KBD_USAGE_COPY            0x7c /* Keyboard Copy */
#define HID_KBD_USAGE_PASTE           0x7d /* Keyboard Paste */
#define HID_KBD_USAGE_FIND            0x7e /* Keyboard Find */
#define HID_KBD_USAGE_MUTE            0x7f /* Keyboard Mute */
#define HID_KBD_USAGE_VOLUP           0x80 /* Keyboard Volume Up */
#define HID_KBD_USAGE_VOLDOWN         0x81 /* Keyboard Volume Down */
#define HID_KBD_USAGE_LCAPSLOCK       0x82 /* Keyboard Locking Caps Lock */
#define HID_KBD_USAGE_LNUMLOCK        0x83 /* Keyboard Locking Num Lock */
#define HID_KBD_USAGE_LSCROLLLOCK     0x84 /* Keyboard Locking Scroll Lock */
#define HID_KBD_USAGE_KPDCOMMA        0x85 /* Keypad Comma */
#define HID_KBD_USAGE_KPDEQUALSIGN    0x86 /* Keypad Equal Sign */
#define HID_KBD_USAGE_INTERNATIONAL1  0x87 /* Keyboard International 1 */
#define HID_KBD_USAGE_INTERNATIONAL2  0x88 /* Keyboard International 2 */
#define HID_KBD_USAGE_INTERNATIONAL3  0x89 /* Keyboard International 3 */
#define HID_KBD_USAGE_INTERNATIONAL4  0x8a /* Keyboard International 4 */
#define HID_KBD_USAGE_INTERNATIONAL5  0x8b /* Keyboard International 5 */
#define HID_KBD_USAGE_INTERNATIONAL6  0x8c /* Keyboard International 6 */
#define HID_KBD_USAGE_INTERNATIONAL7  0x8d /* Keyboard International 7 */
#define HID_KBD_USAGE_INTERNATIONAL8  0x8e /* Keyboard International 8 */
#define HID_KBD_USAGE_INTERNATIONAL9  0x8f /* Keyboard International 9 */
#define HID_KBD_USAGE_LANG1           0x90 /* Keyboard LANG1 */
#define HID_KBD_USAGE_LANG2           0x91 /* Keyboard LANG2 */
#define HID_KBD_USAGE_LANG3           0x92 /* Keyboard LANG3 */
#define HID_KBD_USAGE_LANG4           0x93 /* Keyboard LANG4 */
#define HID_KBD_USAGE_LANG5           0x94 /* Keyboard LANG5 */
#define HID_KBD_USAGE_LANG6           0x95 /* Keyboard LANG6 */
#define HID_KBD_USAGE_LANG7           0x96 /* Keyboard LANG7 */
#define HID_KBD_USAGE_LANG8           0x97 /* Keyboard LANG8 */
#define HID_KBD_USAGE_LANG9           0x98 /* Keyboard LANG9 */
#define HID_KBD_USAGE_ALTERASE        0x99 /* Keyboard Alternate Erase */
#define HID_KBD_USAGE_SYSREQ          0x9a /* Keyboard SysReq/Attention */
#define HID_KBD_USAGE_CANCEL          0x9b /* Keyboard Cancel */
#define HID_KBD_USAGE_CLEAR           0x9c /* Keyboard Clear */
#define HID_KBD_USAGE_PRIOR           0x9d /* Keyboard Prior */
#define HID_KBD_USAGE_RETURN          0x9e /* Keyboard Return */
#define HID_KBD_USAGE_SEPARATOR       0x9f /* Keyboard Separator */
#define HID_KBD_USAGE_OUT             0xa0 /* Keyboard Out */
#define HID_KBD_USAGE_OPER            0xa1 /* Keyboard Oper */
#define HID_KBD_USAGE_CLEARAGAIN      0xa2 /* Keyboard Clear/Again */
#define HID_KBD_USAGE_CLRSEL          0xa3 /* Keyboard CrSel/Props */
#define HID_KBD_USAGE_EXSEL           0xa4 /* Keyboard ExSel */
#define HID_KBD_USAGE_KPD00           0xb0 /* Keypad 00 */
#define HID_KBD_USAGE_KPD000          0xb1 /* Keypad 000 */
#define HID_KBD_USAGE_THOUSEPARATOR   0xb2 /* Thousands Separator */
#define HID_KBD_USAGE_DECSEPARATOR    0xb3 /* Decimal Separator */
#define HID_KBD_USAGE_CURRUNIT        0xb4 /* Currency Unit */
#define HID_KBD_USAGE_CURRSUBUNIT     0xb5 /* Currency Sub-unit */
#define HID_KBD_USAGE_KPDLPAREN       0xb6 /* Keypad ( */
#define HID_KBD_USAGE_KPDRPAREN       0xb7 /* Keypad ) */
#define HID_KBD_USAGE_KPDLBRACE       0xb8 /* Keypad { */
#define HID_KBD_USAGE_KPDRBRACE       0xb9 /* Keypad } */
#define HID_KBD_USAGE_KPDTAB          0xba /* Keypad Tab */
#define HID_KBD_USAGE_KPDBACKSPACE    0xbb /* Keypad Backspace */
#define HID_KBD_USAGE_KPDA            0xbc /* Keypad A (B-F follow) */
#define HID_KBD_USAGE_KPDXOR          0xc2 /* Keypad XOR */
#define HID_KBD_USAGE_KPDEXP          0xc3 /* Keypad ^ */
#define HID_KBD_USAGE_KPDPERCENT      0xc4 /* Keypad % */
#define HID_KBD_USAGE_KPDLT           0xc5 /* Keypad < */
#define HID_KBD_USAGE_KPDGT           0xc6 /* Keypad > */
#define HID_KBD_USAGE_KPDAMPERSAND    0xc7 /* Keypad & */
#define HID_KBD_USAGE_KPDAND          0xc8 /* Keypad && */
#define HID_KBD_USAGE_KPDVERT         0xc9 /* Keypad | */
#define HID_KBD_USAGE_KPDOR           0xca /* Keypad || */
#define HID_KBD_USAGE_KPDCOLON        0xcb /* Keypad : */
#define HID_KBD_USAGE_KPDPOUND        0xcc /* Keypad # */
#define HID_KBD_USAGE_KPDSPACE        0xcd /* Keypad Space */
#define HID_KBD_USAGE_KPDAT           0xce /* Keypad @ */
#define HID_KBD_USAGE_KPDEXCLAM       0xcf /* Keypad ! */
#define HID_KBD_USAGE_KPDMEMSTORE     0xd0 /* Keypad Memory Store */
#define HID_KBD_USAGE_KPDMEMRECALL    0xd1 /* Keypad Memory Recall */
#define HID_KBD_USAGE_KPDMEMCLEAR     0xd2 /* Keypad Memory Clear */
#define HID_KBD_USAGE_KPDMEMADD       0xd3 /* Keypad Memory Add */
#define HID_KBD_USAGE_KPDMEMSUB       0xd4 /* Keypad Memory Subtract */
#define HID_KBD_USAGE_KPDMEMMULT      0xd5 /* Keypad Memory Multiply */
#define HID_KBD_USAGE_KPDMEMDIV       0xd6 /* Keypad Memory Divide */
#define HID_KBD_USAGE_KPDPLUSMINUS    0xd7 /* Keypad +/- */
#define HID_KBD_USAGE_KPDCLEAR        0xd8 /* Keypad Clear */
#define HID_KBD_USAGE_KPDCLEARENTRY   0xd9 /* Keypad Clear Entry */
#define HID_KBD_USAGE_KPDBINARY       0xda /* Keypad Binary */
#define HID_KBD_USAGE_KPDOCTAL        0xdb /* Keypad Octal */
#define HID_KBD_USAGE_KPDDECIMAL      0xdc /* Keypad Decimal */
#define HID_KBD_USAGE_KPDHEXADECIMAL  0xdd /* Keypad Hexadecimal */
#define HID_KBD_USAGE_LCTRL           0xe0 /* Keyboard LeftControl */
#define HID_KBD_USAGE_LSHIFT          0xe1 /* Keyboard LeftShift */
#define HID_KBD_USAGE_LALT            0xe2 /* Keyboard LeftAlt */
#define HID_KBD_USAGE_LGUI            0xe3 /* Keyboard Left GUI */
#define HID_KBD_USAGE_RCTRL           0xe4 /* Keyboard RightControl */
#define HID_KBD_USAGE_RSHIFT          0xe5 /* Keyboard RightShift */
#define HID_KBD_USAGE_RALT            0xe6 /* Keyboard RightAlt */
#define HID_KBD_USAGE_RGUI            0xe7 /* Keyboard Right GUI */

#define HID_KBD_USAGE_MAX 0xe7

/* HID Report Definitions */
struct usb_hid_class_subdescriptor {
    uint8_t bDescriptorType;    /* Class descriptor type (See 7.1) */
    uint16_t wDescriptorLength; /* Size of the report descriptor */
} __PACKED;

struct usb_hid_descriptor {
    uint8_t bLength;         /* Size of the HID descriptor */
    uint8_t bDescriptorType; /* HID descriptor type */
    uint16_t bcdHID;         /* HID class specification release */
    uint8_t bCountryCode;    /* Country code */
    uint8_t bNumDescriptors; /* Number of descriptors (>=1) */

    /*
     * Specification says at least one Class Descriptor needs to
     * be present (Report Descriptor).
     */
    struct usb_hid_class_subdescriptor subdesc[1];
} __PACKED;

/* Standard Reports *********************************************************/

/* Keyboard input report (8 bytes) (HID B.1) */
struct usb_hid_kbd_report {
    uint8_t modifier; /* Modifier keys. See HID_MODIFER_* definitions */
    uint8_t reserved;
    uint8_t key[6]; /* Keycode 1-6 */
};

/* Keyboard output report (1 byte) (HID B.1),
 * see HID_KBD_OUTPUT_* definitions
 */

/* Mouse input report (HID B.2) */
struct usb_hid_mouse_report {
    uint8_t buttons; /* See HID_MOUSE_INPUT_BUTTON_* definitions */
    int8_t xdisp;    /* X displacement */
    int8_t ydisp;    /* y displacement */
                     /* Device specific additional bytes may follow */
    uint8_t wdisp;   /* Wheel displacement */
};

/* Joystick input report (1 bytes) (HID D.1) */
struct usb_hid_js_report {
    int8_t xpos;      /* X position */
    int8_t ypos;      /* X position */
    uint8_t buttons;  /* See USBHID_JSIN_* definitions */
    uint8_t throttle; /* Throttle */
};

// clang-format off
#define HID_MOUSE_DESCRIPTOR_LEN (9 + 9 + 7)

#define HID_MOUSE_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, int_ep, wMaxPacketSize, bInterval) \
    0x09,                          /* bLength: Interface Descriptor size */                                         \
    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */                                 \
    bInterfaceNumber,              /* bInterfaceNumber: Number of Interface */                                      \
    0x00,                          /* bAlternateSetting: Alternate setting */                                       \
    0x01,                          /* bNumEndpoints */                                                              \
    0x03,                          /* bInterfaceClass: HID */                                                       \
    bInterfaceSubClass,            /* bInterfaceSubClass : 1=BOOT, 0=no boot */                                     \
    0x02,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */                           \
    0x00,                          /* iInterface: Index of string descriptor */                                     \
    0x09,                          /* bLength: HID Descriptor size */                                               \
    HID_DESCRIPTOR_TYPE_HID,       /* bDescriptorType: HID */                                                       \
    0x11,                          /* bcdHID: HID Class Spec release number */                                      \
    0x01,                                                                                                           \
    0x00,                         /* bCountryCode: Hardware target country */                                       \
    0x01,                         /* bNumDescriptors: Number of HID class descriptors to follow */                  \
    0x22,                         /* bDescriptorType */                                                             \
    WBVAL(wItemLength),           /* wItemLength: Total length of Report descriptor */                              \
    0x07,                         /* bLength: Endpoint Descriptor size */                                           \
    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */                                                            \
    int_ep,                       /* bEndpointAddress: Endpoint Address (IN) */                                     \
    0x03,                         /* bmAttributes: Interrupt endpoint */                                            \
    WBVAL(wMaxPacketSize),        /* wMaxPacketSize: x Byte max */                                                  \
    bInterval                     /* bInterval: Polling Interval */

#define HID_KEYBOARD_DESCRIPTOR_LEN (9 + 9 + 7)

#define HID_KEYBOARD_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, int_ep, wMaxPacketSize, bInterval) \
    0x09,                          /* bLength: Interface Descriptor size */                                         \
    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */                                 \
    bInterfaceNumber,              /* bInterfaceNumber: Number of Interface */                                      \
    0x00,                          /* bAlternateSetting: Alternate setting */                                       \
    0x01,                          /* bNumEndpoints */                                                              \
    0x03,                          /* bInterfaceClass: HID */                                                       \
    bInterfaceSubClass,            /* bInterfaceSubClass : 1=BOOT, 0=no boot */                                     \
    0x01,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */                           \
    0x00,                          /* iInterface: Index of string descriptor */                                     \
    0x09,                          /* bLength: HID Descriptor size */                                               \
    HID_DESCRIPTOR_TYPE_HID,       /* bDescriptorType: HID */                                                       \
    0x11,                          /* bcdHID: HID Class Spec release number */                                      \
    0x01,                                                                                                           \
    0x00,                         /* bCountryCode: Hardware target country */                                       \
    0x01,                         /* bNumDescriptors: Number of HID class descriptors to follow */                  \
    0x22,                         /* bDescriptorType */                                                             \
    WBVAL(wItemLength),           /* wItemLength: Total length of Report descriptor */                              \
    0x07,                         /* bLength: Endpoint Descriptor size */                                           \
    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */                                                            \
    int_ep,                       /* bEndpointAddress: Endpoint Address (IN) */                                     \
    0x03,                         /* bmAttributes: Interrupt endpoint */                                            \
    WBVAL(wMaxPacketSize),        /* wMaxPacketSize: x Byte max */                                                  \
    bInterval                     /* bInterval: Polling Interval */

#define HID_CUSTOM_INOUT_DESCRIPTOR_LEN (9 + 9 + 7 + 7)

#define HID_CUSTOM_INOUT_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, out_ep, in_ep, wMaxPacketSize, bInterval) \
    0x09,                          /* bLength: Interface Descriptor size */                                         \
    USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */                                 \
    bInterfaceNumber,              /* bInterfaceNumber: Number of Interface */                                      \
    0x00,                          /* bAlternateSetting: Alternate setting */                                       \
    0x02,                          /* bNumEndpoints */                                                              \
    0x03,                          /* bInterfaceClass: HID */                                                       \
    bInterfaceSubClass,            /* bInterfaceSubClass : 1=BOOT, 0=no boot */                                     \
    0x00,                          /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */                           \
    0x00,                          /* iInterface: Index of string descriptor */                                     \
    0x09,                          /* bLength: HID Descriptor size */                                               \
    HID_DESCRIPTOR_TYPE_HID,       /* bDescriptorType: HID */                                                       \
    0x11,                          /* bcdHID: HID Class Spec release number */                                      \
    0x01,                                                                                                           \
    0x00,                         /* bCountryCode: Hardware target country */                                       \
    0x01,                         /* bNumDescriptors: Number of HID class descriptors to follow */                  \
    0x22,                         /* bDescriptorType */                                                             \
    WBVAL(wItemLength),           /* wItemLength: Total length of Report descriptor */                              \
    0x07,                         /* bLength: Endpoint Descriptor size */                                           \
    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */                                                            \
    out_ep,                       /* bEndpointAddress: Endpoint Address (OUT) */                                    \
    0x03,                         /* bmAttributes: Interrupt endpoint */                                            \
    WBVAL(wMaxPacketSize),        /* wMaxPacketSize: x Byte max */                                                  \
    bInterval,                    /* bInterval: Polling Interval */                                                 \
    0x07,                         /* bLength: Endpoint Descriptor size */                                           \
    USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */                                                            \
    in_ep,                        /* bEndpointAddress: Endpoint Address (IN) */                                     \
    0x03,                         /* bmAttributes: Interrupt endpoint */                                            \
    WBVAL(wMaxPacketSize),        /* wMaxPacketSize: x Byte max */                                                  \
    bInterval                     /* bInterval: Polling Interval */
// clang-format on

#endif /* USB_HID_H */