iPXE
usbkbd.h
Go to the documentation of this file.
00001 #ifndef _USBKBD_H
00002 #define _USBKBD_H
00003 
00004 /** @file
00005  *
00006  * USB keyboard driver
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <assert.h>
00013 #include <ipxe/usb.h>
00014 #include <ipxe/usbhid.h>
00015 
00016 /** Keyboard protocol */
00017 #define USBKBD_PROTOCOL 1
00018 
00019 /** A USB keyboard report */
00020 struct usb_keyboard_report {
00021         /** Modifier keys */
00022         uint8_t modifiers;
00023         /** Reserved */
00024         uint8_t reserved;
00025         /** Keycodes */
00026         uint8_t keycode[6];
00027 } __attribute__ (( packed ));
00028 
00029 /** USB modifier keys */
00030 enum usb_keyboard_modifier {
00031         /** Left Ctrl key */
00032         USBKBD_CTRL_LEFT = 0x01,
00033         /** Left Shift key */
00034         USBKBD_SHIFT_LEFT = 0x02,
00035         /** Left Alt key */
00036         USBKBD_ALT_LEFT = 0x04,
00037         /** Left GUI key */
00038         USBKBD_GUI_LEFT = 0x08,
00039         /** Right Ctrl key */
00040         USBKBD_CTRL_RIGHT = 0x10,
00041         /** Right Shift key */
00042         USBKBD_SHIFT_RIGHT = 0x20,
00043         /** Right Alt key */
00044         USBKBD_ALT_RIGHT = 0x40,
00045         /** Right GUI key */
00046         USBKBD_GUI_RIGHT = 0x80,
00047 };
00048 
00049 /** Either Ctrl key */
00050 #define USBKBD_CTRL ( USBKBD_CTRL_LEFT | USBKBD_CTRL_RIGHT )
00051 
00052 /** Either Shift key */
00053 #define USBKBD_SHIFT ( USBKBD_SHIFT_LEFT | USBKBD_SHIFT_RIGHT )
00054 
00055 /** Either Alt key */
00056 #define USBKBD_ALT ( USBKBD_ALT_LEFT | USBKBD_ALT_RIGHT )
00057 
00058 /** Either GUI key */
00059 #define USBKBD_GUI ( USBKBD_GUI_LEFT | USBKBD_GUI_RIGHT )
00060 
00061 /** USB keycodes */
00062 enum usb_keycode {
00063         USBKBD_KEY_A = 0x04,
00064         USBKBD_KEY_Z = 0x1d,
00065         USBKBD_KEY_1 = 0x1e,
00066         USBKBD_KEY_0 = 0x27,
00067         USBKBD_KEY_ENTER = 0x28,
00068         USBKBD_KEY_SPACE = 0x2c,
00069         USBKBD_KEY_MINUS = 0x2d,
00070         USBKBD_KEY_SLASH = 0x38,
00071         USBKBD_KEY_CAPS_LOCK = 0x39,
00072         USBKBD_KEY_F1 = 0x3a,
00073         USBKBD_KEY_UP = 0x52,
00074         USBKBD_KEY_NUM_LOCK = 0x53,
00075         USBKBD_KEY_PAD_ENTER = 0x58,
00076         USBKBD_KEY_PAD_1 = 0x59,
00077         USBKBD_KEY_PAD_DOT = 0x63,
00078 };
00079 
00080 /** USB keyboard LEDs */
00081 enum usb_keyboard_led {
00082         USBKBD_LED_NUM_LOCK = 0x01,
00083         USBKBD_LED_CAPS_LOCK = 0x02,
00084         USBKBD_LED_SCROLL_LOCK = 0x04,
00085 };
00086 
00087 /** Keyboard idle duration (in 4ms units)
00088  *
00089  * This is a policy decision.  We choose to use an autorepeat rate of
00090  * approximately 40ms.
00091  */
00092 #define USBKBD_IDLE_DURATION 10 /* 10 x 4ms = 40ms */
00093 
00094 /** Keyboard auto-repeat hold-off (in units of USBKBD_IDLE_DURATION)
00095  *
00096  * This is a policy decision.  We choose to use an autorepeat delay of
00097  * approximately 500ms.
00098  */
00099 #define USBKBD_HOLDOFF 12 /* 12 x 40ms = 480ms */
00100 
00101 /** Interrupt endpoint maximum fill level
00102  *
00103  * When idling, we are likely to poll the USB endpoint at only the
00104  * 18.2Hz system timer tick rate.  With a typical observed bInterval
00105  * of 10ms (which will be rounded down to 8ms by the HCI drivers),
00106  * this gives approximately 7 completions per poll.
00107  */
00108 #define USBKBD_INTR_MAX_FILL 8
00109 
00110 /** Keyboard buffer size
00111  *
00112  * Must be a power of two.
00113  */
00114 #define USBKBD_BUFSIZE 8
00115 
00116 /** A USB keyboard device */
00117 struct usb_keyboard {
00118         /** Name */
00119         const char *name;
00120         /** List of all USB keyboards */
00121         struct list_head list;
00122 
00123         /** USB bus */
00124         struct usb_bus *bus;
00125         /** USB human interface device */
00126         struct usb_hid hid;
00127 
00128         /** Most recent keyboard report */
00129         struct usb_keyboard_report report;
00130         /** Most recently pressed non-modifier key (if any) */
00131         unsigned int keycode;
00132         /** Autorepeat hold-off time (in number of completions reported) */
00133         unsigned int holdoff;
00134 
00135         /** Keyboard LED state */
00136         uint8_t leds;
00137         /** Keyboard LEDs changed */
00138         uint8_t leds_changed;
00139 
00140         /** Keyboard buffer
00141          *
00142          * This stores iPXE key values.
00143          */
00144         unsigned int key[USBKBD_BUFSIZE];
00145         /** Keyboard buffer producer counter */
00146         unsigned int prod;
00147         /** Keyboard buffer consumer counter */
00148         unsigned int cons;
00149         /** Keyboard buffer sub-consumer counter
00150          *
00151          * This represents the index within the ANSI escape sequence
00152          * corresponding to an iPXE key value.
00153          */
00154         unsigned int subcons;
00155 };
00156 
00157 /**
00158  * Calculate keyboard buffer fill level
00159  *
00160  * @v kbd               USB keyboard
00161  * @ret fill            Keyboard buffer fill level
00162  */
00163 static inline __attribute__ (( always_inline )) unsigned int
00164 usbkbd_fill ( struct usb_keyboard *kbd ) {
00165         unsigned int fill = ( kbd->prod - kbd->cons );
00166 
00167         assert ( fill <= USBKBD_BUFSIZE );
00168         return fill;
00169 }
00170 
00171 #endif /* _USBKBD_H */