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 };
79 
80 /** USB keyboard LEDs */
81 enum usb_keyboard_led {
82 	USBKBD_LED_NUM_LOCK = 0x01,
83 	USBKBD_LED_CAPS_LOCK = 0x02,
84 	USBKBD_LED_SCROLL_LOCK = 0x04,
85 };
86 
87 /** Keyboard idle duration (in 4ms units)
88  *
89  * This is a policy decision.  We choose to use an autorepeat rate of
90  * approximately 40ms.
91  */
92 #define USBKBD_IDLE_DURATION 10 /* 10 x 4ms = 40ms */
93 
94 /** Keyboard auto-repeat hold-off (in units of USBKBD_IDLE_DURATION)
95  *
96  * This is a policy decision.  We choose to use an autorepeat delay of
97  * approximately 500ms.
98  */
99 #define USBKBD_HOLDOFF 12 /* 12 x 40ms = 480ms */
100 
101 /** Interrupt endpoint maximum fill level
102  *
103  * When idling, we are likely to poll the USB endpoint at only the
104  * 18.2Hz system timer tick rate.  With a typical observed bInterval
105  * of 10ms (which will be rounded down to 8ms by the HCI drivers),
106  * this gives approximately 7 completions per poll.
107  */
108 #define USBKBD_INTR_MAX_FILL 8
109 
110 /** Keyboard buffer size
111  *
112  * Must be a power of two.
113  */
114 #define USBKBD_BUFSIZE 8
115 
116 /** A USB keyboard device */
117 struct usb_keyboard {
118 	/** Name */
119 	const char *name;
120 	/** List of all USB keyboards */
121 	struct list_head list;
122 
123 	/** USB bus */
124 	struct usb_bus *bus;
125 	/** USB human interface device */
126 	struct usb_hid hid;
127 
128 	/** Most recent keyboard report */
129 	struct usb_keyboard_report report;
130 	/** Most recently pressed non-modifier key (if any) */
131 	unsigned int keycode;
132 	/** Autorepeat hold-off time (in number of completions reported) */
133 	unsigned int holdoff;
134 
135 	/** Keyboard LED state */
136 	uint8_t leds;
137 	/** Keyboard LEDs changed */
138 	uint8_t leds_changed;
139 
140 	/** Keyboard buffer
141 	 *
142 	 * This stores iPXE key values.
143 	 */
144 	unsigned int key[USBKBD_BUFSIZE];
145 	/** Keyboard buffer producer counter */
146 	unsigned int prod;
147 	/** Keyboard buffer consumer counter */
148 	unsigned int cons;
149 	/** Keyboard buffer sub-consumer counter
150 	 *
151 	 * This represents the index within the ANSI escape sequence
152 	 * corresponding to an iPXE key value.
153 	 */
154 	unsigned int subcons;
155 };
156 
157 /**
158  * Calculate keyboard buffer fill level
159  *
160  * @v kbd		USB keyboard
161  * @ret fill		Keyboard buffer fill level
162  */
163 static inline __attribute__ (( always_inline )) unsigned int
usbkbd_fill(struct usb_keyboard * kbd)164 usbkbd_fill ( struct usb_keyboard *kbd ) {
165 	unsigned int fill = ( kbd->prod - kbd->cons );
166 
167 	assert ( fill <= USBKBD_BUFSIZE );
168 	return fill;
169 }
170 
171 #endif /* _USBKBD_H */
172