Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / SLOF / lib / libusb / usb-hid.c
1 /*****************************************************************************
2  * Copyright (c) 2013 IBM Corporation
3  * All rights reserved.
4  * This program and the accompanying materials
5  * are made available under the terms of the BSD License
6  * which accompanies this distribution, and is available at
7  * http://www.opensource.org/licenses/bsd-license.php
8  *
9  * Contributors:
10  *     IBM Corporation - initial implementation
11  *****************************************************************************/
12
13 #include <stdio.h>
14 #include <string.h>
15 #include <termctrl.h>
16
17 #include "usb-core.h"
18 #include "usb-key.h"
19
20 /*
21  * HID Spec Version 1.11
22  */
23
24 #define HID_REQ_GET_REPORT              0x01
25 #define HID_REQ_GET_IDLE                0x02
26 #define HID_REQ_GET_PROTOCOL            0x03
27 #define HID_REQ_SET_REPORT              0x09
28 #define HID_REQ_SET_IDLE                0x0A
29 #define HID_REQ_SET_PROTOCOL            0x0B
30
31 //#define KEY_DEBUG
32
33 /* HID SPEC - 7.2.6 Set_Protocol Request */
34 static int usb_hid_set_protocol(struct usb_dev *dev, uint16_t value)
35 {
36         struct usb_dev_req req;
37         if (!dev)
38                 return false;
39         req.bmRequestType = REQT_TYPE_CLASS | REQT_REC_INTERFACE | REQT_DIR_OUT;
40         req.bRequest = HID_REQ_SET_PROTOCOL;
41         req.wValue = cpu_to_le16(value);
42         req.wIndex = cpu_to_le16(dev->intf_num);
43         req.wLength = 0;
44         return usb_send_ctrl(dev->control, &req, NULL);
45 }
46
47 /* HID SPEC - 7.2.4 Set_Idle Request */
48 static int usb_hid_set_idle(struct usb_dev *dev, uint16_t ms_delay)
49 {
50         struct usb_dev_req req;
51         if (!dev)
52                 return false;
53         req.bmRequestType = REQT_TYPE_CLASS | REQT_REC_INTERFACE | REQT_DIR_OUT;
54         req.bRequest = HID_REQ_SET_IDLE;
55         req.wValue = cpu_to_le16((ms_delay/4) << 8);
56         req.wIndex = cpu_to_le16(dev->intf_num);
57         req.wLength = 0;
58         return usb_send_ctrl(dev->control, &req, NULL);
59 }
60
61 /* HID SPEC - 7.2.1 Get Report Request */
62 static int usb_hid_get_report(struct usb_dev *dev, void *data, size_t size)
63 {
64         struct usb_dev_req req;
65         if (!dev)
66                 return false;
67         req.bmRequestType = REQT_TYPE_CLASS | REQT_REC_INTERFACE | REQT_DIR_IN;
68         req.bRequest = HID_REQ_GET_REPORT;
69         req.wIndex = cpu_to_le16(dev->intf_num);
70
71         req.wLength = cpu_to_le16((uint16_t)size);
72         req.wValue = cpu_to_le16(1 << 8);
73         return usb_send_ctrl(dev->control, &req, data);
74 }
75
76 /* ring buffer with RD/WR indices for key buffering */
77 static uint8_t keybuf[256];     /* size fixed to byte range !   */
78 uint8_t r_ptr = 0;              /* RD-index for Keyboard-Buffer */
79 uint8_t w_ptr = 0;              /* WR-index for Keyboard-Buffer */
80
81 /* variables for LED status */
82 uint8_t set_leds;
83 const uint8_t *key_std       = NULL;
84 const uint8_t *key_std_shift = NULL;
85
86 /**
87  * read character from Keyboard-Buffer
88  *
89  * @param   -
90  * @return  > 0  Keycode
91  *          = 0  if no key available
92  */
93 static int read_key(void)
94 {
95         if (r_ptr != w_ptr)
96                 return (int)keybuf[r_ptr++];
97         else
98                 return false;
99 }
100
101 /**
102  * Store character into Keyboard-Buffer
103  *
104  * @param   Key = detected ASCII-Key (> 0)
105  * @return  -
106  */
107 static void write_key(uint8_t key)
108 {
109         if ((w_ptr + 1) != r_ptr)
110                 keybuf[w_ptr++] = key;
111 }
112
113 /**
114  * Convert keyboard usage-ID to ANSI-Code
115  *
116  * @param   Ctrl=Modifier Byte
117  *          Key =Usage ID from USB Keyboard
118  * @return  -
119  */
120 static void get_char(uint8_t ctrl, uint8_t keypos)
121 {
122         uint8_t ch;
123
124 #ifdef KEY_DEBUG
125         printf("pos %02X\n", keypos);
126 #endif
127
128         if (set_leds & LED_CAPS_LOCK)                   /* is CAPS Lock set ? */
129                 ctrl |= MODIFIER_SHIFT;                     /* simulate shift */
130
131         if (ctrl == 0) {
132                 ch = key_std[keypos];
133                 if (ch != 0)
134                         write_key(ch);
135                 return;
136         }
137
138         if (ctrl & MODIFIER_SHIFT) {
139                 ch = key_std_shift[keypos];
140                 if (ch != 0)
141                         write_key(ch);
142                 return;
143         }
144
145         if (ctrl & MODIFIER_CTRL) {
146                 ch = keycodes_ctrl[keypos];
147                 if (ch != 0)
148                         write_key(ch);
149                 return;
150         }
151
152         if (ctrl == MODIFIER_ALT_GR) {
153                 ch = keycodes_alt_GR[keypos];
154                 if (ch != 0)
155                         write_key(ch);
156                 return;
157         }
158 }
159
160 static void check_key_code(uint8_t *buf)
161 {
162         static uint8_t key_last[6];                 /* list of processed keys */
163         uint8_t i, j, key_pos;
164
165         /* set translation table to defaults */
166         if ((key_std == NULL) || (key_std_shift == NULL)) {
167                 key_std       = keycodes_std_US;
168                 key_std_shift = keycodes_shift_US;
169         }
170
171         if (buf[0] & MODIFIER_SHIFT)       /* any shift key pressed ? */
172                 set_leds &= ~LED_CAPS_LOCK;       /* CAPS-LOCK-LED always off */
173
174         i = 2;  /* skip modifier byte and reserved byte */
175         while (i < 8) {
176                 key_pos = buf[i];
177                 if ((key_pos != 0) && (key_pos <= 100)) {    /* support for 101 keys */
178                         j = 0;
179                         /* search if already processed */
180                         while ((j < 6) && (key_pos != key_last[j]))
181                                 j++;
182
183                         if (j >= 6) {          /* not found (= not processed) */
184                                 switch (key_pos) {
185                                 case 0x39:                 /* caps-lock key ? */
186                                 case 0x32:                 /* caps-lock key ? */
187                                         set_leds ^= LED_CAPS_LOCK;
188                                         break;
189
190                                 case 0x3a:                              /* F1 */
191                                         write_key(0x1b);
192                                         write_key(0x5b);
193                                         write_key(0x31);
194                                         write_key(0x31);
195                                         write_key(0x7e);
196                                         break;
197
198                                 case 0x3b:                              /* F2 */
199                                         write_key(0x1b);
200                                         write_key(0x5b);
201                                         write_key(0x31);
202                                         write_key(0x32);
203                                         write_key(0x7e);
204                                         break;
205
206                                 case 0x3c:
207                                         write_key(0x1b);               /* F3 */
208                                         write_key(0x5b);
209                                         write_key(0x31);
210                                         write_key(0x33);
211                                         write_key(0x7e);
212                                         break;
213
214                                 case 0x3d:
215                                         write_key(0x1b);                /* F4 */
216                                         write_key(0x5b);
217                                         write_key(0x31);
218                                         write_key(0x34);
219                                         write_key(0x7e);
220                                         break;
221
222                                 case 0x3e:
223                                         write_key(0x1b);                /* F5 */
224                                         write_key(0x5b);
225                                         write_key(0x31);
226                                         write_key(0x35);
227                                         write_key(0x7e);
228                                         break;
229
230                                 case 0x3f:
231                                         write_key(0x1b);                /* F6 */
232                                         write_key(0x5b);
233                                         write_key(0x31);
234                                         write_key(0x37);
235                                         write_key(0x7e);
236                                         break;
237
238                                 case 0x40:
239                                         write_key(0x1b);                /* F7 */
240                                         write_key(0x5b);
241                                         write_key(0x31);
242                                         write_key(0x38);
243                                         write_key(0x7e);
244                                         break;
245
246                                 case 0x41:
247                                         write_key(0x1b);                /* F8 */
248                                         write_key(0x5b);
249                                         write_key(0x31);
250                                         write_key(0x39);
251                                         write_key(0x7e);
252                                         break;
253
254                                 case 0x42:
255                                         write_key(0x1b);                /* F9 */
256                                         write_key(0x5b);
257                                         write_key(0x31);
258                                         write_key(0x30);
259                                         write_key(0x7e);
260                                         break;
261
262                                 case 0x43:
263                                         write_key(0x1b);               /* F10 */
264                                         write_key(0x5b);
265                                         write_key(0x31);
266                                         write_key(0x31);
267                                         write_key(0x7e);
268                                         break;
269
270                                 case 0x44:
271                                         write_key(0x1b);               /* F11 */
272                                         write_key(0x5b);
273                                         write_key(0x31);
274                                         write_key(0x33);
275                                         write_key(0x7e);
276                                         break;
277
278                                 case 0x45:
279                                         write_key(0x1b);               /* F12 */
280                                         write_key(0x5b);
281                                         write_key(0x31);
282                                         write_key(0x34);
283                                         write_key(0x7e);
284                                         break;
285
286                                 case 0x47:               /* scroll-lock key ? */
287                                         set_leds ^= LED_SCROLL_LOCK;
288                                         break;
289
290                                 case 0x49:
291                                         write_key(0x1b);               /* INS */
292                                         write_key(0x5b);
293                                         write_key(0x31);
294                                         write_key(0x7e);
295                                         break;
296
297                                 case 0x4a:
298                                         write_key(0x1b);              /* HOME */
299                                         write_key(0x5b);
300                                         write_key(0x32);
301                                         write_key(0x7e);
302                                         break;
303
304                                 case 0x4b:
305                                         write_key(0x1b);              /* PgUp */
306                                         write_key(0x5b);
307                                         write_key(0x33);
308                                         write_key(0x7e);
309                                         break;
310
311                                 case 0x4c:
312                                         write_key(0x1b);               /* DEL */
313                                         write_key(0x5b);
314                                         write_key(0x34);
315                                         write_key(0x7e);
316                                         break;
317
318                                 case 0x4d:
319                                         write_key(0x1b);               /* END */
320                                         write_key(0x5b);
321                                         write_key(0x35);
322                                         write_key(0x7e);
323                                         break;
324
325                                 case 0x4e:
326                                         write_key(0x1b);              /* PgDn */
327                                         write_key(0x5b);
328                                         write_key(0x36);
329                                         write_key(0x7e);
330                                         break;
331
332                                 case 0x4f:
333                                         write_key(0x1b);           /* R-Arrow */
334                                         write_key(0x5b);
335                                         write_key(0x43);
336                                         break;
337
338                                 case 0x50:
339                                         write_key(0x1b);           /* L-Arrow */
340                                         write_key(0x5b);
341                                         write_key(0x44);
342                                         break;
343
344                                 case 0x51:
345                                         write_key(0x1b);           /* D-Arrow */
346                                         write_key(0x5b);
347                                         write_key(0x42);
348                                         break;
349
350                                 case 0x52:
351                                         write_key(0x1b);           /* U-Arrow */
352                                         write_key(0x5b);
353                                         write_key(0x41);
354                                         break;
355
356                                 case 0x53:                  /* num-lock key ? */
357                                         set_leds ^= LED_NUM_LOCK;
358                                         break;
359
360                                 default:
361                                         /* convert key position to ASCII code */
362                                         get_char(buf[0], key_pos);
363                                         break;
364                                 }
365                         }
366                 }
367                 i++;
368         }
369         /*****************************************/
370         /* all keys are processed, create a copy */
371         /* to flag them as processed             */
372         /*****************************************/
373         for (i = 2, j = 0; j < 6; i++, j++)
374                 key_last[j] = buf[i];      /* copy all actual keys to last */
375 }
376
377 #define USB_HID_SIZE 128
378 uint32_t *kbd_buffer;
379
380 int usb_hid_kbd_init(struct usb_dev *dev)
381 {
382         int i;
383         uint8_t key[8];
384
385         usb_hid_set_protocol(dev, 0);
386         usb_hid_set_idle(dev, 500);
387
388         memset(key, 0, 8);
389         if (usb_hid_get_report(dev, key, 8))
390                 check_key_code(key);
391
392         kbd_buffer = SLOF_dma_alloc(USB_HID_SIZE);
393         if (!kbd_buffer) {
394                 printf("%s: unable to allocate keyboard buffer\n", __func__);
395                 return false;
396         }
397
398 #ifdef KEY_DEBUG
399         printf("HID kbd init %d\n", dev->ep_cnt);
400 #endif
401         for (i = 0; i < dev->ep_cnt; i++) {
402                 if ((dev->ep[i].bmAttributes & USB_EP_TYPE_MASK)
403                         == USB_EP_TYPE_INTR)
404                         usb_dev_populate_pipe(dev, &dev->ep[i], kbd_buffer, USB_HID_SIZE);
405         }
406         return true;
407 }
408
409 int usb_hid_kbd_exit(struct usb_dev *dev)
410 {
411         if (dev->intr) {
412                 usb_put_pipe(dev->intr);
413                 dev->intr = NULL;
414         }
415         SLOF_dma_free(kbd_buffer, USB_HID_SIZE);
416         return true;
417 }
418
419 static int usb_poll_key(void *vdev)
420 {
421         struct usb_dev *dev = vdev;
422         uint8_t key[8];
423         int rc;
424
425         memset(key, 0, 8);
426         rc = usb_poll_intr(dev->intr, key);
427         if (rc)
428                 check_key_code(key);
429         return rc;
430 }
431
432 unsigned char usb_key_available(void *dev)
433 {
434         if (!dev)
435                 return false;
436
437         usb_poll_key(dev);
438         if (r_ptr != w_ptr)
439                 return true;
440         else
441                 return false;
442 }
443
444 unsigned char usb_read_keyb(void *vdev)
445 {
446         if (!vdev)
447                 return false;
448
449         while (usb_poll_key(vdev)) {
450                 /* loop for all pending keys */
451         }
452         return read_key();
453 }