]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/usb_kbd.c
x86: Add CBMEM console driver for coreboot
[karo-tx-uboot.git] / common / usb_kbd.c
1 /*
2  * (C) Copyright 2001
3  * Denis Peter, MPL AG Switzerland
4  *
5  * Part of this source has been derived from the Linux USB
6  * project.
7  *
8  * See file CREDITS for list of people who contributed to this
9  * project.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of
14  * the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24  * MA 02111-1307 USA
25  *
26  */
27 #include <common.h>
28 #include <malloc.h>
29 #include <stdio_dev.h>
30 #include <asm/byteorder.h>
31
32 #include <usb.h>
33
34 #ifdef  USB_KBD_DEBUG
35 #define USB_KBD_PRINTF(fmt, args...)    printf(fmt, ##args)
36 #else
37 #define USB_KBD_PRINTF(fmt, args...)
38 #endif
39
40 /*
41  * If overwrite_console returns 1, the stdin, stderr and stdout
42  * are switched to the serial port, else the settings in the
43  * environment are used
44  */
45 #ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
46 extern int overwrite_console(void);
47 #else
48 int overwrite_console(void)
49 {
50         return 0;
51 }
52 #endif
53
54 /* Keyboard sampling rate */
55 #define REPEAT_RATE     (40 / 4)        /* 40msec -> 25cps */
56 #define REPEAT_DELAY    10              /* 10 x REPEAT_RATE = 400msec */
57
58 #define NUM_LOCK        0x53
59 #define CAPS_LOCK       0x39
60 #define SCROLL_LOCK     0x47
61
62 /* Modifier bits */
63 #define LEFT_CNTR       (1 << 0)
64 #define LEFT_SHIFT      (1 << 1)
65 #define LEFT_ALT        (1 << 2)
66 #define LEFT_GUI        (1 << 3)
67 #define RIGHT_CNTR      (1 << 4)
68 #define RIGHT_SHIFT     (1 << 5)
69 #define RIGHT_ALT       (1 << 6)
70 #define RIGHT_GUI       (1 << 7)
71
72 /* Size of the keyboard buffer */
73 #define USB_KBD_BUFFER_LEN      0x20
74
75 /* Device name */
76 #define DEVNAME                 "usbkbd"
77
78 /* Keyboard maps */
79 static const unsigned char usb_kbd_numkey[] = {
80         '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
81         '\r', 0x1b, '\b', '\t', ' ', '-', '=', '[', ']',
82         '\\', '#', ';', '\'', '`', ',', '.', '/'
83 };
84 static const unsigned char usb_kbd_numkey_shifted[] = {
85         '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
86         '\r', 0x1b, '\b', '\t', ' ', '_', '+', '{', '}',
87         '|', '~', ':', '"', '~', '<', '>', '?'
88 };
89
90 static const unsigned char usb_kbd_num_keypad[] = {
91         '/', '*', '-', '+', '\r',
92         '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
93         '.', 0, 0, 0, '='
94 };
95
96 /*
97  * map arrow keys to ^F/^B ^N/^P, can't really use the proper
98  * ANSI sequence for arrow keys because the queuing code breaks
99  * when a single keypress expands to 3 queue elements
100  */
101 static const unsigned char usb_kbd_arrow[] = {
102         0x6, 0x2, 0xe, 0x10
103 };
104
105 /*
106  * NOTE: It's important for the NUM, CAPS, SCROLL-lock bits to be in this
107  *       order. See usb_kbd_setled() function!
108  */
109 #define USB_KBD_NUMLOCK         (1 << 0)
110 #define USB_KBD_CAPSLOCK        (1 << 1)
111 #define USB_KBD_SCROLLLOCK      (1 << 2)
112 #define USB_KBD_CTRL            (1 << 3)
113
114 #define USB_KBD_LEDMASK         \
115         (USB_KBD_NUMLOCK | USB_KBD_CAPSLOCK | USB_KBD_SCROLLLOCK)
116
117 struct usb_kbd_pdata {
118         uint32_t        repeat_delay;
119
120         uint32_t        usb_in_pointer;
121         uint32_t        usb_out_pointer;
122         uint8_t         usb_kbd_buffer[USB_KBD_BUFFER_LEN];
123
124         uint8_t         *new;
125         uint8_t         old[8];
126
127         uint8_t         flags;
128 };
129
130 /* Generic keyboard event polling. */
131 void usb_kbd_generic_poll(void)
132 {
133         struct stdio_dev *dev;
134         struct usb_device *usb_kbd_dev;
135         struct usb_kbd_pdata *data;
136         struct usb_interface *iface;
137         struct usb_endpoint_descriptor *ep;
138         int pipe;
139         int maxp;
140
141         /* Get the pointer to USB Keyboard device pointer */
142         dev = stdio_get_by_name(DEVNAME);
143         usb_kbd_dev = (struct usb_device *)dev->priv;
144         data = usb_kbd_dev->privptr;
145         iface = &usb_kbd_dev->config.if_desc[0];
146         ep = &iface->ep_desc[0];
147         pipe = usb_rcvintpipe(usb_kbd_dev, ep->bEndpointAddress);
148
149         /* Submit a interrupt transfer request */
150         maxp = usb_maxpacket(usb_kbd_dev, pipe);
151         usb_submit_int_msg(usb_kbd_dev, pipe, data->new,
152                         maxp > 8 ? 8 : maxp, ep->bInterval);
153 }
154
155 /* Puts character in the queue and sets up the in and out pointer. */
156 static void usb_kbd_put_queue(struct usb_kbd_pdata *data, char c)
157 {
158         if (data->usb_in_pointer == USB_KBD_BUFFER_LEN - 1) {
159                 /* Check for buffer full. */
160                 if (data->usb_out_pointer == 0)
161                         return;
162
163                 data->usb_in_pointer = 0;
164         } else {
165                 /* Check for buffer full. */
166                 if (data->usb_in_pointer == data->usb_out_pointer - 1)
167                         return;
168
169                 data->usb_in_pointer++;
170         }
171
172         data->usb_kbd_buffer[data->usb_in_pointer] = c;
173 }
174
175 /*
176  * Set the LEDs. Since this is used in the irq routine, the control job is
177  * issued with a timeout of 0. This means, that the job is queued without
178  * waiting for job completion.
179  */
180 static void usb_kbd_setled(struct usb_device *dev)
181 {
182         struct usb_interface *iface = &dev->config.if_desc[0];
183         struct usb_kbd_pdata *data = dev->privptr;
184         uint32_t leds = data->flags & USB_KBD_LEDMASK;
185
186         usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
187                 USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
188                 0x200, iface->desc.bInterfaceNumber, (void *)&leds, 1, 0);
189 }
190
191 #define CAPITAL_MASK    0x20
192 /* Translate the scancode in ASCII */
193 static int usb_kbd_translate(struct usb_kbd_pdata *data, unsigned char scancode,
194                                 unsigned char modifier, int pressed)
195 {
196         uint8_t keycode = 0;
197
198         /* Key released */
199         if (pressed == 0) {
200                 data->repeat_delay = 0;
201                 return 0;
202         }
203
204         if (pressed == 2) {
205                 data->repeat_delay++;
206                 if (data->repeat_delay < REPEAT_DELAY)
207                         return 0;
208
209                 data->repeat_delay = REPEAT_DELAY;
210         }
211
212         /* Alphanumeric values */
213         if ((scancode > 3) && (scancode <= 0x1d)) {
214                 keycode = scancode - 4 + 'a';
215
216                 if (data->flags & USB_KBD_CAPSLOCK)
217                         keycode &= ~CAPITAL_MASK;
218
219                 if (modifier & (LEFT_SHIFT | RIGHT_SHIFT)) {
220                         /* Handle CAPSLock + Shift pressed simultaneously */
221                         if (keycode & CAPITAL_MASK)
222                                 keycode &= ~CAPITAL_MASK;
223                         else
224                                 keycode |= CAPITAL_MASK;
225                 }
226         }
227
228         if ((scancode > 0x1d) && (scancode < 0x3a)) {
229                 /* Shift pressed */
230                 if (modifier & (LEFT_SHIFT | RIGHT_SHIFT))
231                         keycode = usb_kbd_numkey_shifted[scancode - 0x1e];
232                 else
233                         keycode = usb_kbd_numkey[scancode - 0x1e];
234         }
235
236         /* Arrow keys */
237         if ((scancode >= 0x4f) && (scancode <= 0x52))
238                 keycode = usb_kbd_arrow[scancode - 0x4f];
239
240         /* Numeric keypad */
241         if ((scancode >= 0x54) && (scancode <= 0x67))
242                 keycode = usb_kbd_num_keypad[scancode - 0x54];
243
244         if (data->flags & USB_KBD_CTRL)
245                 keycode = scancode - 0x3;
246
247         if (pressed == 1) {
248                 if (scancode == NUM_LOCK) {
249                         data->flags ^= USB_KBD_NUMLOCK;
250                         return 1;
251                 }
252
253                 if (scancode == CAPS_LOCK) {
254                         data->flags ^= USB_KBD_CAPSLOCK;
255                         return 1;
256                 }
257                 if (scancode == SCROLL_LOCK) {
258                         data->flags ^= USB_KBD_SCROLLLOCK;
259                         return 1;
260                 }
261         }
262
263         /* Report keycode if any */
264         if (keycode) {
265                 USB_KBD_PRINTF("%c", keycode);
266                 usb_kbd_put_queue(data, keycode);
267         }
268
269         return 0;
270 }
271
272 static uint32_t usb_kbd_service_key(struct usb_device *dev, int i, int up)
273 {
274         uint32_t res = 0;
275         struct usb_kbd_pdata *data = dev->privptr;
276         uint8_t *new;
277         uint8_t *old;
278
279         if (up) {
280                 new = data->old;
281                 old = data->new;
282         } else {
283                 new = data->new;
284                 old = data->old;
285         }
286
287         if ((old[i] > 3) && (memscan(new + 2, old[i], 6) == new + 8))
288                 res |= usb_kbd_translate(data, old[i], data->new[0], up);
289
290         return res;
291 }
292
293 /* Interrupt service routine */
294 static int usb_kbd_irq_worker(struct usb_device *dev)
295 {
296         struct usb_kbd_pdata *data = dev->privptr;
297         int i, res = 0;
298
299         /* No combo key pressed */
300         if (data->new[0] == 0x00)
301                 data->flags &= ~USB_KBD_CTRL;
302         /* Left or Right Ctrl pressed */
303         else if ((data->new[0] == LEFT_CNTR) || (data->new[0] == RIGHT_CNTR))
304                 data->flags |= USB_KBD_CTRL;
305
306         for (i = 2; i < 8; i++) {
307                 res |= usb_kbd_service_key(dev, i, 0);
308                 res |= usb_kbd_service_key(dev, i, 1);
309         }
310
311         /* Key is still pressed */
312         if ((data->new[2] > 3) && (data->old[2] == data->new[2]))
313                 res |= usb_kbd_translate(data, data->new[2], data->new[0], 2);
314
315         if (res == 1)
316                 usb_kbd_setled(dev);
317
318         memcpy(data->old, data->new, 8);
319
320         return 1;
321 }
322
323 /* Keyboard interrupt handler */
324 static int usb_kbd_irq(struct usb_device *dev)
325 {
326         if ((dev->irq_status != 0) || (dev->irq_act_len != 8)) {
327                 USB_KBD_PRINTF("USB KBD: Error %lX, len %d\n",
328                                 dev->irq_status, dev->irq_act_len);
329                 return 1;
330         }
331
332         return usb_kbd_irq_worker(dev);
333 }
334
335 /* Interrupt polling */
336 static inline void usb_kbd_poll_for_event(struct usb_device *dev)
337 {
338 #if     defined(CONFIG_SYS_USB_EVENT_POLL)
339         struct usb_interface *iface;
340         struct usb_endpoint_descriptor *ep;
341         struct usb_kbd_pdata *data;
342         int pipe;
343         int maxp;
344
345         /* Get the pointer to USB Keyboard device pointer */
346         data = dev->privptr;
347         iface = &dev->config.if_desc[0];
348         ep = &iface->ep_desc[0];
349         pipe = usb_rcvintpipe(dev, ep->bEndpointAddress);
350
351         /* Submit a interrupt transfer request */
352         maxp = usb_maxpacket(dev, pipe);
353         usb_submit_int_msg(dev, pipe, &data->new[0],
354                         maxp > 8 ? 8 : maxp, ep->bInterval);
355
356         usb_kbd_irq_worker(dev);
357 #elif   defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP)
358         struct usb_interface *iface;
359         struct usb_kbd_pdata *data = dev->privptr;
360         iface = &dev->config.if_desc[0];
361         usb_get_report(dev, iface->desc.bInterfaceNumber,
362                         1, 0, data->new, sizeof(data->new));
363         if (memcmp(data->old, data->new, sizeof(data->new)))
364                 usb_kbd_irq_worker(dev);
365 #endif
366 }
367
368 /* test if a character is in the queue */
369 static int usb_kbd_testc(void)
370 {
371         struct stdio_dev *dev;
372         struct usb_device *usb_kbd_dev;
373         struct usb_kbd_pdata *data;
374
375         dev = stdio_get_by_name(DEVNAME);
376         usb_kbd_dev = (struct usb_device *)dev->priv;
377         data = usb_kbd_dev->privptr;
378
379         usb_kbd_poll_for_event(usb_kbd_dev);
380
381         return !(data->usb_in_pointer == data->usb_out_pointer);
382 }
383
384 /* gets the character from the queue */
385 static int usb_kbd_getc(void)
386 {
387         struct stdio_dev *dev;
388         struct usb_device *usb_kbd_dev;
389         struct usb_kbd_pdata *data;
390
391         dev = stdio_get_by_name(DEVNAME);
392         usb_kbd_dev = (struct usb_device *)dev->priv;
393         data = usb_kbd_dev->privptr;
394
395         while (data->usb_in_pointer == data->usb_out_pointer)
396                 usb_kbd_poll_for_event(usb_kbd_dev);
397
398         if (data->usb_out_pointer == USB_KBD_BUFFER_LEN - 1)
399                 data->usb_out_pointer = 0;
400         else
401                 data->usb_out_pointer++;
402
403         return data->usb_kbd_buffer[data->usb_out_pointer];
404 }
405
406 /* probes the USB device dev for keyboard type. */
407 static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
408 {
409         struct usb_interface *iface;
410         struct usb_endpoint_descriptor *ep;
411         struct usb_kbd_pdata *data;
412         int pipe, maxp;
413
414         if (dev->descriptor.bNumConfigurations != 1)
415                 return 0;
416
417         iface = &dev->config.if_desc[ifnum];
418
419         if (iface->desc.bInterfaceClass != 3)
420                 return 0;
421
422         if (iface->desc.bInterfaceSubClass != 1)
423                 return 0;
424
425         if (iface->desc.bInterfaceProtocol != 1)
426                 return 0;
427
428         if (iface->desc.bNumEndpoints != 1)
429                 return 0;
430
431         ep = &iface->ep_desc[0];
432
433         /* Check if endpoint 1 is interrupt endpoint */
434         if (!(ep->bEndpointAddress & 0x80))
435                 return 0;
436
437         if ((ep->bmAttributes & 3) != 3)
438                 return 0;
439
440         USB_KBD_PRINTF("USB KBD: found set protocol...\n");
441
442         data = malloc(sizeof(struct usb_kbd_pdata));
443         if (!data) {
444                 printf("USB KBD: Error allocating private data\n");
445                 return 0;
446         }
447
448         /* Clear private data */
449         memset(data, 0, sizeof(struct usb_kbd_pdata));
450
451         /* allocate input buffer aligned and sized to USB DMA alignment */
452         data->new = memalign(USB_DMA_MINALIGN, roundup(8, USB_DMA_MINALIGN));
453
454         /* Insert private data into USB device structure */
455         dev->privptr = data;
456
457         /* Set IRQ handler */
458         dev->irq_handle = usb_kbd_irq;
459
460         pipe = usb_rcvintpipe(dev, ep->bEndpointAddress);
461         maxp = usb_maxpacket(dev, pipe);
462
463         /* We found a USB Keyboard, install it. */
464         usb_set_protocol(dev, iface->desc.bInterfaceNumber, 0);
465
466         USB_KBD_PRINTF("USB KBD: found set idle...\n");
467         usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE, 0);
468
469         USB_KBD_PRINTF("USB KBD: enable interrupt pipe...\n");
470         usb_submit_int_msg(dev, pipe, data->new, maxp > 8 ? 8 : maxp,
471                                 ep->bInterval);
472
473         /* Success. */
474         return 1;
475 }
476
477 /* Search for keyboard and register it if found. */
478 int drv_usb_kbd_init(void)
479 {
480         struct stdio_dev usb_kbd_dev, *old_dev;
481         struct usb_device *dev;
482         char *stdinname = getenv("stdin");
483         int error, i;
484
485         /* Scan all USB Devices */
486         for (i = 0; i < USB_MAX_DEVICE; i++) {
487                 /* Get USB device. */
488                 dev = usb_get_dev_index(i);
489                 if (!dev)
490                         return -1;
491
492                 if (dev->devnum == -1)
493                         continue;
494
495                 /* Try probing the keyboard */
496                 if (usb_kbd_probe(dev, 0) != 1)
497                         continue;
498
499                 /* We found a keyboard, check if it is already registered. */
500                 USB_KBD_PRINTF("USB KBD: found set up device.\n");
501                 old_dev = stdio_get_by_name(DEVNAME);
502                 if (old_dev) {
503                         /* Already registered, just return ok. */
504                         USB_KBD_PRINTF("USB KBD: is already registered.\n");
505                         return 1;
506                 }
507
508                 /* Register the keyboard */
509                 USB_KBD_PRINTF("USB KBD: register.\n");
510                 memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));
511                 strcpy(usb_kbd_dev.name, DEVNAME);
512                 usb_kbd_dev.flags =  DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
513                 usb_kbd_dev.putc = NULL;
514                 usb_kbd_dev.puts = NULL;
515                 usb_kbd_dev.getc = usb_kbd_getc;
516                 usb_kbd_dev.tstc = usb_kbd_testc;
517                 usb_kbd_dev.priv = (void *)dev;
518                 error = stdio_register(&usb_kbd_dev);
519                 if (error)
520                         return error;
521
522 #ifdef CONFIG_CONSOLE_MUX
523                 error = iomux_doenv(stdin, stdinname);
524                 if (error)
525                         return error;
526 #else
527                 /* Check if this is the standard input device. */
528                 if (strcmp(stdinname, DEVNAME))
529                         return 1;
530
531                 /* Reassign the console */
532                 if (overwrite_console())
533                         return 1;
534
535                 error = console_assign(stdin, DEVNAME);
536                 if (error)
537                         return error;
538 #endif
539
540                 return 1;
541         }
542
543         /* No USB Keyboard found */
544         return -1;
545 }
546
547 /* Deregister the keyboard. */
548 int usb_kbd_deregister(void)
549 {
550 #ifdef CONFIG_SYS_STDIO_DEREGISTER
551         return stdio_deregister(DEVNAME);
552 #else
553         return 1;
554 #endif
555 }