| #ifndef _USBKBD_H |
| #define _USBKBD_H |
| |
| /** @file |
| * |
| * USB keyboard driver |
| * |
| */ |
| |
| FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); |
| |
| #include <assert.h> |
| #include <ipxe/usb.h> |
| #include <ipxe/usbhid.h> |
| |
| /** Keyboard protocol */ |
| #define USBKBD_PROTOCOL 1 |
| |
| /** A USB keyboard report */ |
| struct usb_keyboard_report { |
| /** Modifier keys */ |
| uint8_t modifiers; |
| /** Reserved */ |
| uint8_t reserved; |
| /** Keycodes */ |
| uint8_t keycode[6]; |
| } __attribute__ (( packed )); |
| |
| /** USB modifier keys */ |
| enum usb_keyboard_modifier { |
| /** Left Ctrl key */ |
| USBKBD_CTRL_LEFT = 0x01, |
| /** Left Shift key */ |
| USBKBD_SHIFT_LEFT = 0x02, |
| /** Left Alt key */ |
| USBKBD_ALT_LEFT = 0x04, |
| /** Left GUI key */ |
| USBKBD_GUI_LEFT = 0x08, |
| /** Right Ctrl key */ |
| USBKBD_CTRL_RIGHT = 0x10, |
| /** Right Shift key */ |
| USBKBD_SHIFT_RIGHT = 0x20, |
| /** Right Alt key */ |
| USBKBD_ALT_RIGHT = 0x40, |
| /** Right GUI key */ |
| USBKBD_GUI_RIGHT = 0x80, |
| }; |
| |
| /** Either Ctrl key */ |
| #define USBKBD_CTRL ( USBKBD_CTRL_LEFT | USBKBD_CTRL_RIGHT ) |
| |
| /** Either Shift key */ |
| #define USBKBD_SHIFT ( USBKBD_SHIFT_LEFT | USBKBD_SHIFT_RIGHT ) |
| |
| /** Either Alt key */ |
| #define USBKBD_ALT ( USBKBD_ALT_LEFT | USBKBD_ALT_RIGHT ) |
| |
| /** Either GUI key */ |
| #define USBKBD_GUI ( USBKBD_GUI_LEFT | USBKBD_GUI_RIGHT ) |
| |
| /** USB keycodes */ |
| enum usb_keycode { |
| USBKBD_KEY_A = 0x04, |
| USBKBD_KEY_Z = 0x1d, |
| USBKBD_KEY_1 = 0x1e, |
| USBKBD_KEY_0 = 0x27, |
| USBKBD_KEY_ENTER = 0x28, |
| USBKBD_KEY_SPACE = 0x2c, |
| USBKBD_KEY_MINUS = 0x2d, |
| USBKBD_KEY_SLASH = 0x38, |
| USBKBD_KEY_CAPS_LOCK = 0x39, |
| USBKBD_KEY_F1 = 0x3a, |
| USBKBD_KEY_UP = 0x52, |
| USBKBD_KEY_NUM_LOCK = 0x53, |
| USBKBD_KEY_PAD_ENTER = 0x58, |
| USBKBD_KEY_PAD_1 = 0x59, |
| USBKBD_KEY_PAD_DOT = 0x63, |
| USBKBD_KEY_NON_US = 0x64, |
| }; |
| |
| /** USB keyboard LEDs */ |
| enum usb_keyboard_led { |
| USBKBD_LED_NUM_LOCK = 0x01, |
| USBKBD_LED_CAPS_LOCK = 0x02, |
| USBKBD_LED_SCROLL_LOCK = 0x04, |
| }; |
| |
| /** Keyboard idle duration (in 4ms units) |
| * |
| * This is a policy decision. We choose to use an autorepeat rate of |
| * approximately 40ms. |
| */ |
| #define USBKBD_IDLE_DURATION 10 /* 10 x 4ms = 40ms */ |
| |
| /** Keyboard auto-repeat hold-off (in units of USBKBD_IDLE_DURATION) |
| * |
| * This is a policy decision. We choose to use an autorepeat delay of |
| * approximately 500ms. |
| */ |
| #define USBKBD_HOLDOFF 12 /* 12 x 40ms = 480ms */ |
| |
| /** Interrupt endpoint maximum fill level |
| * |
| * When idling, we are likely to poll the USB endpoint at only the |
| * 18.2Hz system timer tick rate. With a typical observed bInterval |
| * of 10ms (which will be rounded down to 8ms by the HCI drivers), |
| * this gives approximately 7 completions per poll. |
| */ |
| #define USBKBD_INTR_MAX_FILL 8 |
| |
| /** Keyboard buffer size |
| * |
| * Must be a power of two. |
| */ |
| #define USBKBD_BUFSIZE 8 |
| |
| /** A USB keyboard device */ |
| struct usb_keyboard { |
| /** Name */ |
| const char *name; |
| /** List of all USB keyboards */ |
| struct list_head list; |
| |
| /** USB bus */ |
| struct usb_bus *bus; |
| /** USB human interface device */ |
| struct usb_hid hid; |
| |
| /** Most recent keyboard report */ |
| struct usb_keyboard_report report; |
| /** Most recently pressed non-modifier key (if any) */ |
| unsigned int keycode; |
| /** Autorepeat hold-off time (in number of completions reported) */ |
| unsigned int holdoff; |
| |
| /** Keyboard LED state */ |
| uint8_t leds; |
| /** Keyboard LEDs changed */ |
| uint8_t leds_changed; |
| |
| /** Keyboard buffer |
| * |
| * This stores iPXE key values. |
| */ |
| unsigned int key[USBKBD_BUFSIZE]; |
| /** Keyboard buffer producer counter */ |
| unsigned int prod; |
| /** Keyboard buffer consumer counter */ |
| unsigned int cons; |
| /** Keyboard buffer sub-consumer counter |
| * |
| * This represents the index within the ANSI escape sequence |
| * corresponding to an iPXE key value. |
| */ |
| unsigned int subcons; |
| }; |
| |
| /** |
| * Calculate keyboard buffer fill level |
| * |
| * @v kbd USB keyboard |
| * @ret fill Keyboard buffer fill level |
| */ |
| static inline __attribute__ (( always_inline )) unsigned int |
| usbkbd_fill ( struct usb_keyboard *kbd ) { |
| unsigned int fill = ( kbd->prod - kbd->cons ); |
| |
| assert ( fill <= USBKBD_BUFSIZE ); |
| return fill; |
| } |
| |
| #endif /* _USBKBD_H */ |