[acpi] Expose system MAC address via ${sysmac} setting
[ipxe.git] / src / drivers / usb / usbkbd.h
1 #ifndef _USBKBD_H
2 #define _USBKBD_H
3
4 /** @file
5 *
6 * USB keyboard driver
7 *
8 */
9
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
12 #include <assert.h>
13 #include <ipxe/usb.h>
14 #include <ipxe/usbhid.h>
15
16 /** Keyboard protocol */
17 #define USBKBD_PROTOCOL 1
18
19 /** A USB keyboard report */
20 struct usb_keyboard_report {
21 /** Modifier keys */
22 uint8_t modifiers;
23 /** Reserved */
24 uint8_t reserved;
25 /** Keycodes */
26 uint8_t keycode[6];
27 } __attribute__ (( packed ));
28
29 /** USB modifier keys */
30 enum usb_keyboard_modifier {
31 /** Left Ctrl key */
32 USBKBD_CTRL_LEFT = 0x01,
33 /** Left Shift key */
34 USBKBD_SHIFT_LEFT = 0x02,
35 /** Left Alt key */
36 USBKBD_ALT_LEFT = 0x04,
37 /** Left GUI key */
38 USBKBD_GUI_LEFT = 0x08,
39 /** Right Ctrl key */
40 USBKBD_CTRL_RIGHT = 0x10,
41 /** Right Shift key */
42 USBKBD_SHIFT_RIGHT = 0x20,
43 /** Right Alt key */
44 USBKBD_ALT_RIGHT = 0x40,
45 /** Right GUI key */
46 USBKBD_GUI_RIGHT = 0x80,
47 };
48
49 /** Either Ctrl key */
50 #define USBKBD_CTRL ( USBKBD_CTRL_LEFT | USBKBD_CTRL_RIGHT )
51
52 /** Either Shift key */
53 #define USBKBD_SHIFT ( USBKBD_SHIFT_LEFT | USBKBD_SHIFT_RIGHT )
54
55 /** Either Alt key */
56 #define USBKBD_ALT ( USBKBD_ALT_LEFT | USBKBD_ALT_RIGHT )
57
58 /** Either GUI key */
59 #define USBKBD_GUI ( USBKBD_GUI_LEFT | USBKBD_GUI_RIGHT )
60
61 /** USB keycodes */
62 enum usb_keycode {
63 USBKBD_KEY_A = 0x04,
64 USBKBD_KEY_Z = 0x1d,
65 USBKBD_KEY_1 = 0x1e,
66 USBKBD_KEY_0 = 0x27,
67 USBKBD_KEY_ENTER = 0x28,
68 USBKBD_KEY_SPACE = 0x2c,
69 USBKBD_KEY_MINUS = 0x2d,
70 USBKBD_KEY_SLASH = 0x38,
71 USBKBD_KEY_CAPS_LOCK = 0x39,
72 USBKBD_KEY_F1 = 0x3a,
73 USBKBD_KEY_UP = 0x52,
74 USBKBD_KEY_NUM_LOCK = 0x53,
75 USBKBD_KEY_PAD_ENTER = 0x58,
76 USBKBD_KEY_PAD_1 = 0x59,
77 USBKBD_KEY_PAD_DOT = 0x63,
78 USBKBD_KEY_NON_US = 0x64,
79 };
80
81 /** USB keyboard LEDs */
82 enum usb_keyboard_led {
83 USBKBD_LED_NUM_LOCK = 0x01,
84 USBKBD_LED_CAPS_LOCK = 0x02,
85 USBKBD_LED_SCROLL_LOCK = 0x04,
86 };
87
88 /** Keyboard idle duration (in 4ms units)
89 *
90 * This is a policy decision. We choose to use an autorepeat rate of
91 * approximately 40ms.
92 */
93 #define USBKBD_IDLE_DURATION 10 /* 10 x 4ms = 40ms */
94
95 /** Keyboard auto-repeat hold-off (in units of USBKBD_IDLE_DURATION)
96 *
97 * This is a policy decision. We choose to use an autorepeat delay of
98 * approximately 500ms.
99 */
100 #define USBKBD_HOLDOFF 12 /* 12 x 40ms = 480ms */
101
102 /** Interrupt endpoint maximum fill level
103 *
104 * When idling, we are likely to poll the USB endpoint at only the
105 * 18.2Hz system timer tick rate. With a typical observed bInterval
106 * of 10ms (which will be rounded down to 8ms by the HCI drivers),
107 * this gives approximately 7 completions per poll.
108 */
109 #define USBKBD_INTR_MAX_FILL 8
110
111 /** Keyboard buffer size
112 *
113 * Must be a power of two.
114 */
115 #define USBKBD_BUFSIZE 8
116
117 /** A USB keyboard device */
118 struct usb_keyboard {
119 /** Name */
120 const char *name;
121 /** List of all USB keyboards */
122 struct list_head list;
123
124 /** USB bus */
125 struct usb_bus *bus;
126 /** USB human interface device */
127 struct usb_hid hid;
128
129 /** Most recent keyboard report */
130 struct usb_keyboard_report report;
131 /** Most recently pressed non-modifier key (if any) */
132 unsigned int keycode;
133 /** Autorepeat hold-off time (in number of completions reported) */
134 unsigned int holdoff;
135
136 /** Keyboard LED state */
137 uint8_t leds;
138 /** Keyboard LEDs changed */
139 uint8_t leds_changed;
140
141 /** Keyboard buffer
142 *
143 * This stores iPXE key values.
144 */
145 unsigned int key[USBKBD_BUFSIZE];
146 /** Keyboard buffer producer counter */
147 unsigned int prod;
148 /** Keyboard buffer consumer counter */
149 unsigned int cons;
150 /** Keyboard buffer sub-consumer counter
151 *
152 * This represents the index within the ANSI escape sequence
153 * corresponding to an iPXE key value.
154 */
155 unsigned int subcons;
156 };
157
158 /**
159 * Calculate keyboard buffer fill level
160 *
161 * @v kbd USB keyboard
162 * @ret fill Keyboard buffer fill level
163 */
164 static inline __attribute__ (( always_inline )) unsigned int
165 usbkbd_fill ( struct usb_keyboard *kbd ) {
166 unsigned int fill = ( kbd->prod - kbd->cons );
167
168 assert ( fill <= USBKBD_BUFSIZE );
169 return fill;
170 }
171
172 #endif /* _USBKBD_H */