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 <stdio_dev.h> 29 #include <asm/byteorder.h> 30 31 #include <usb.h> 32 33 #undef USB_KBD_DEBUG 34 /* 35 * If overwrite_console returns 1, the stdin, stderr and stdout 36 * are switched to the serial port, else the settings in the 37 * environment are used 38 */ 39 #ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE 40 extern int overwrite_console(void); 41 #else 42 int overwrite_console(void) 43 { 44 return 0; 45 } 46 #endif 47 48 #ifdef USB_KBD_DEBUG 49 #define USB_KBD_PRINTF(fmt, args...) printf(fmt, ##args) 50 #else 51 #define USB_KBD_PRINTF(fmt, args...) 52 #endif 53 54 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 63 /* Modifier bits */ 64 #define LEFT_CNTR 0 65 #define LEFT_SHIFT 1 66 #define LEFT_ALT 2 67 #define LEFT_GUI 3 68 #define RIGHT_CNTR 4 69 #define RIGHT_SHIFT 5 70 #define RIGHT_ALT 6 71 #define RIGHT_GUI 7 72 73 #define USB_KBD_BUFFER_LEN 0x20 /* size of the keyboardbuffer */ 74 75 static char usb_kbd_buffer[USB_KBD_BUFFER_LEN]; 76 static int usb_in_pointer; 77 static int usb_out_pointer; 78 79 unsigned char new[8]; 80 unsigned char old[8]; 81 int repeat_delay; 82 #define DEVNAME "usbkbd" 83 static unsigned char num_lock; 84 static unsigned char caps_lock; 85 static unsigned char scroll_lock; 86 static unsigned char ctrl; 87 88 static unsigned char leds __attribute__((aligned(0x4))); 89 90 static unsigned char usb_kbd_numkey[] = { 91 '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 92 '\r', 0x1b, '\b', '\t', ' ', '-', '=', '[', ']', 93 '\\', '#', ';', '\'', '`', ',', '.', '/' 94 }; 95 static unsigned char usb_kbd_numkey_shifted[] = { 96 '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', 97 '\r', 0x1b, '\b', '\t', ' ', '_', '+', '{', '}', 98 '|', '~', ':', '"', '~', '<', '>', '?' 99 }; 100 101 static int usb_kbd_irq_worker(struct usb_device *dev); 102 103 /****************************************************************** 104 * Interrupt polling 105 ******************************************************************/ 106 static inline void usb_kbd_poll_for_event(struct usb_device *dev) 107 { 108 #if defined(CONFIG_SYS_USB_EVENT_POLL) 109 usb_event_poll(); 110 usb_kbd_irq_worker(dev); 111 #elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) 112 struct usb_interface *iface; 113 iface = &dev->config.if_desc[0]; 114 usb_get_report(dev, iface->desc.bInterfaceNumber, 115 1, 1, new, sizeof(new)); 116 if (memcmp(old, new, sizeof(new))) 117 usb_kbd_irq_worker(dev); 118 #endif 119 } 120 121 /****************************************************************** 122 * Queue handling 123 ******************************************************************/ 124 /* puts character in the queue and sets up the in and out pointer */ 125 static void usb_kbd_put_queue(char data) 126 { 127 if ((usb_in_pointer+1) == USB_KBD_BUFFER_LEN) { 128 if (usb_out_pointer == 0) 129 return; /* buffer full */ 130 else 131 usb_in_pointer = 0; 132 } else { 133 if ((usb_in_pointer+1) == usb_out_pointer) 134 return; /* buffer full */ 135 usb_in_pointer++; 136 } 137 usb_kbd_buffer[usb_in_pointer] = data; 138 return; 139 } 140 141 /* test if a character is in the queue */ 142 static int usb_kbd_testc(void) 143 { 144 struct stdio_dev *dev; 145 struct usb_device *usb_kbd_dev; 146 147 dev = stdio_get_by_name("usbkbd"); 148 usb_kbd_dev = (struct usb_device *)dev->priv; 149 150 usb_kbd_poll_for_event(usb_kbd_dev); 151 152 if (usb_in_pointer == usb_out_pointer) 153 return 0; /* no data */ 154 else 155 return 1; 156 } 157 /* gets the character from the queue */ 158 static int usb_kbd_getc(void) 159 { 160 char c; 161 162 struct stdio_dev *dev; 163 struct usb_device *usb_kbd_dev; 164 165 dev = stdio_get_by_name("usbkbd"); 166 usb_kbd_dev = (struct usb_device *)dev->priv; 167 168 while (usb_in_pointer == usb_out_pointer) 169 usb_kbd_poll_for_event(usb_kbd_dev); 170 171 if ((usb_out_pointer+1) == USB_KBD_BUFFER_LEN) 172 usb_out_pointer = 0; 173 else 174 usb_out_pointer++; 175 c = usb_kbd_buffer[usb_out_pointer]; 176 return (int)c; 177 178 } 179 180 /* forward decleration */ 181 static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum); 182 183 /* search for keyboard and register it if found */ 184 int drv_usb_kbd_init(void) 185 { 186 int error, i; 187 struct stdio_dev usb_kbd_dev, *old_dev; 188 struct usb_device *dev; 189 char *stdinname = getenv("stdin"); 190 191 usb_in_pointer = 0; 192 usb_out_pointer = 0; 193 /* scan all USB Devices */ 194 for (i = 0 ; i < USB_MAX_DEVICE ; i++) { 195 dev = usb_get_dev_index(i); /* get device */ 196 if (dev == NULL) 197 return -1; 198 if (dev->devnum != -1) { 199 /* Ok, we found a keyboard */ 200 if (usb_kbd_probe(dev, 0) == 1) { 201 /* check, if it is already registered */ 202 USB_KBD_PRINTF("USB KBD found set up " 203 "device.\n"); 204 old_dev = stdio_get_by_name(DEVNAME); 205 if (old_dev) { 206 /* already registered, just return ok */ 207 USB_KBD_PRINTF("USB KBD is already " 208 "registered.\n"); 209 return 1; 210 } 211 /* register the keyboard */ 212 USB_KBD_PRINTF("USB KBD register.\n"); 213 memset(&usb_kbd_dev, 0, 214 sizeof(struct stdio_dev)); 215 strcpy(usb_kbd_dev.name, DEVNAME); 216 usb_kbd_dev.flags = DEV_FLAGS_INPUT | 217 DEV_FLAGS_SYSTEM; 218 usb_kbd_dev.putc = NULL; 219 usb_kbd_dev.puts = NULL; 220 usb_kbd_dev.getc = usb_kbd_getc; 221 usb_kbd_dev.tstc = usb_kbd_testc; 222 usb_kbd_dev.priv = (void *)dev; 223 error = stdio_register(&usb_kbd_dev); 224 if (error == 0) { 225 /* 226 * check if this is the standard 227 * input device 228 */ 229 if (strcmp(stdinname, DEVNAME) == 0) { 230 /* reassign the console */ 231 if (overwrite_console()) 232 return 1; 233 error = console_assign(stdin, 234 DEVNAME); 235 if (error == 0) 236 return 1; 237 else 238 return error; 239 } 240 return 1; 241 } 242 return error; 243 } 244 } 245 } 246 /* no USB Keyboard found */ 247 return -1; 248 } 249 250 251 /* deregistering the keyboard */ 252 int usb_kbd_deregister(void) 253 { 254 #ifdef CONFIG_SYS_STDIO_DEREGISTER 255 return stdio_deregister(DEVNAME); 256 #else 257 return 1; 258 #endif 259 } 260 261 /************************************************************************** 262 * Low Level drivers 263 */ 264 265 /* set the LEDs. Since this is used in the irq routine, the control job 266 is issued with a timeout of 0. This means, that the job is queued without 267 waiting for job completion */ 268 269 static void usb_kbd_setled(struct usb_device *dev) 270 { 271 struct usb_interface *iface; 272 iface = &dev->config.if_desc[0]; 273 leds = 0; 274 if (scroll_lock != 0) 275 leds |= 1; 276 leds <<= 1; 277 if (caps_lock != 0) 278 leds |= 1; 279 leds <<= 1; 280 if (num_lock != 0) 281 leds |= 1; 282 usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 283 USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 284 0x200, iface->desc.bInterfaceNumber, (void *)&leds, 1, 0); 285 286 } 287 288 289 #define CAPITAL_MASK 0x20 290 /* Translate the scancode in ASCII */ 291 static int usb_kbd_translate(unsigned char scancode, unsigned char modifier, 292 int pressed) 293 { 294 unsigned char keycode; 295 296 if (pressed == 0) { 297 /* key released */ 298 repeat_delay = 0; 299 return 0; 300 } 301 if (pressed == 2) { 302 repeat_delay++; 303 if (repeat_delay < REPEAT_DELAY) 304 return 0; 305 repeat_delay = REPEAT_DELAY; 306 } 307 keycode = 0; 308 if ((scancode > 3) && (scancode <= 0x1d)) { /* alpha numeric values */ 309 keycode = scancode - 4 + 0x61; 310 if (caps_lock) 311 /* switch to capital Letters */ 312 keycode &= ~CAPITAL_MASK; 313 if (((modifier&(1 << LEFT_SHIFT)) != 0) || 314 ((modifier&(1 << RIGHT_SHIFT)) != 0)) { 315 if (keycode & CAPITAL_MASK) 316 /* switch to capital Letters */ 317 keycode &= ~CAPITAL_MASK; 318 else 319 /* switch to non capital Letters */ 320 keycode |= CAPITAL_MASK; 321 } 322 } 323 if ((scancode > 0x1d) && (scancode < 0x3A)) { 324 if (((modifier&(1 << LEFT_SHIFT)) != 0) || 325 ((modifier&(1 << RIGHT_SHIFT)) != 0)) /* shifted */ 326 keycode = usb_kbd_numkey_shifted[scancode-0x1e]; 327 else /* non shifted */ 328 keycode = usb_kbd_numkey[scancode-0x1e]; 329 } 330 331 if (ctrl) 332 keycode = scancode - 0x3; 333 334 if (pressed == 1) { 335 if (scancode == NUM_LOCK) { 336 num_lock = ~num_lock; 337 return 1; 338 } 339 if (scancode == CAPS_LOCK) { 340 caps_lock = ~caps_lock; 341 return 1; 342 } 343 if (scancode == SCROLL_LOCK) { 344 scroll_lock = ~scroll_lock; 345 return 1; 346 } 347 } 348 if (keycode != 0) { 349 USB_KBD_PRINTF("%c", keycode); 350 usb_kbd_put_queue(keycode); 351 } 352 return 0; 353 } 354 355 /* Interrupt service routine */ 356 static int usb_kbd_irq_worker(struct usb_device *dev) 357 { 358 int i, res; 359 360 res = 0; 361 362 switch (new[0]) { 363 case 0x0: /* No combo key pressed */ 364 ctrl = 0; 365 break; 366 case 0x01: /* Left Ctrl pressed */ 367 case 0x10: /* Right Ctrl pressed */ 368 ctrl = 1; 369 break; 370 } 371 372 for (i = 2; i < 8; i++) { 373 if (old[i] > 3 && memscan(&new[2], old[i], 6) == &new[8]) 374 res |= usb_kbd_translate(old[i], new[0], 0); 375 376 if (new[i] > 3 && memscan(&old[2], new[i], 6) == &old[8]) 377 res |= usb_kbd_translate(new[i], new[0], 1); 378 } 379 380 if ((new[2] > 3) && (old[2] == new[2])) /* still pressed */ 381 res |= usb_kbd_translate(new[2], new[0], 2); 382 if (res == 1) 383 usb_kbd_setled(dev); 384 385 memcpy(&old[0], &new[0], 8); 386 387 return 1; /* install IRQ Handler again */ 388 } 389 390 static int usb_kbd_irq(struct usb_device *dev) 391 { 392 if ((dev->irq_status != 0) || (dev->irq_act_len != 8)) { 393 USB_KBD_PRINTF("usb_keyboard Error %lX, len %d\n", 394 dev->irq_status, dev->irq_act_len); 395 return 1; 396 } 397 398 return usb_kbd_irq_worker(dev); 399 } 400 401 /* probes the USB device dev for keyboard type */ 402 static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) 403 { 404 struct usb_interface *iface; 405 struct usb_endpoint_descriptor *ep; 406 int pipe, maxp; 407 408 if (dev->descriptor.bNumConfigurations != 1) 409 return 0; 410 iface = &dev->config.if_desc[ifnum]; 411 412 if (iface->desc.bInterfaceClass != 3) 413 return 0; 414 if (iface->desc.bInterfaceSubClass != 1) 415 return 0; 416 if (iface->desc.bInterfaceProtocol != 1) 417 return 0; 418 if (iface->desc.bNumEndpoints != 1) 419 return 0; 420 421 ep = &iface->ep_desc[0]; 422 423 if (!(ep->bEndpointAddress & 0x80)) 424 return 0; 425 if ((ep->bmAttributes & 3) != 3) 426 return 0; 427 USB_KBD_PRINTF("USB KBD found set protocol...\n"); 428 /* ok, we found a USB Keyboard, install it */ 429 /* usb_kbd_get_hid_desc(dev); */ 430 usb_set_protocol(dev, iface->desc.bInterfaceNumber, 0); 431 USB_KBD_PRINTF("USB KBD found set idle...\n"); 432 usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE, 0); 433 memset(&new[0], 0, 8); 434 memset(&old[0], 0, 8); 435 repeat_delay = 0; 436 pipe = usb_rcvintpipe(dev, ep->bEndpointAddress); 437 maxp = usb_maxpacket(dev, pipe); 438 dev->irq_handle = usb_kbd_irq; 439 USB_KBD_PRINTF("USB KBD enable interrupt pipe...\n"); 440 usb_submit_int_msg(dev, pipe, &new[0], maxp > 8 ? 8 : maxp, 441 ep->bInterval); 442 return 1; 443 } 444 445 446 #if 0 447 struct usb_hid_descriptor { 448 unsigned char bLength; 449 unsigned char bDescriptorType; /* 0x21 for HID */ 450 unsigned short bcdHID; /* release number */ 451 unsigned char bCountryCode; 452 unsigned char bNumDescriptors; 453 unsigned char bReportDescriptorType; 454 unsigned short wDescriptorLength; 455 } __packed; 456 457 /* 458 * We parse each description item into this structure. Short items data 459 * values are expanded to 32-bit signed int, long items contain a pointer 460 * into the data area. 461 */ 462 463 struct hid_item { 464 unsigned char format; 465 unsigned char size; 466 unsigned char type; 467 unsigned char tag; 468 union { 469 unsigned char u8; 470 char s8; 471 unsigned short u16; 472 short s16; 473 unsigned long u32; 474 long s32; 475 unsigned char *longdata; 476 } data; 477 }; 478 479 /* 480 * HID report item format 481 */ 482 483 #define HID_ITEM_FORMAT_SHORT 0 484 #define HID_ITEM_FORMAT_LONG 1 485 486 /* 487 * Special tag indicating long items 488 */ 489 490 #define HID_ITEM_TAG_LONG 15 491 492 493 static struct usb_hid_descriptor usb_kbd_hid_desc; 494 495 void usb_kbd_display_hid(struct usb_hid_descriptor *hid) 496 { 497 printf("USB_HID_DESC:\n"); 498 printf(" bLenght 0x%x\n", hid->bLength); 499 printf(" bcdHID 0x%x\n", hid->bcdHID); 500 printf(" bCountryCode %d\n", hid->bCountryCode); 501 printf(" bNumDescriptors 0x%x\n", hid->bNumDescriptors); 502 printf(" bReportDescriptorType 0x%x\n", hid->bReportDescriptorType); 503 printf(" wDescriptorLength 0x%x\n", hid->wDescriptorLength); 504 } 505 506 507 /* 508 * Fetch a report description item from the data stream. We support long 509 * items, though they are not used yet. 510 */ 511 512 static int fetch_item(unsigned char *start, unsigned char *end, 513 struct hid_item *item) 514 { 515 if ((end - start) > 0) { 516 unsigned char b = *start++; 517 item->type = (b >> 2) & 3; 518 item->tag = (b >> 4) & 15; 519 if (item->tag == HID_ITEM_TAG_LONG) { 520 item->format = HID_ITEM_FORMAT_LONG; 521 if ((end - start) >= 2) { 522 item->size = *start++; 523 item->tag = *start++; 524 if ((end - start) >= item->size) { 525 item->data.longdata = start; 526 start += item->size; 527 return item->size; 528 } 529 } 530 } else { 531 item->format = HID_ITEM_FORMAT_SHORT; 532 item->size = b & 3; 533 switch (item->size) { 534 case 0: 535 return item->size; 536 case 1: 537 if ((end - start) >= 1) { 538 item->data.u8 = *start++; 539 return item->size; 540 } 541 break; 542 case 2: 543 if ((end - start) >= 2) { 544 item->data.u16 = le16_to_cpu( 545 (unsigned short *)start); 546 start += 2; 547 return item->size; 548 } 549 case 3: 550 item->size++; 551 if ((end - start) >= 4) { 552 item->data.u32 = le32_to_cpu( 553 (unsigned long *)start); 554 start += 4; 555 return item->size; 556 } 557 } 558 } 559 } 560 return -1; 561 } 562 563 /* 564 * HID report descriptor item type (prefix bit 2, 3) 565 */ 566 567 #define HID_ITEM_TYPE_MAIN 0 568 #define HID_ITEM_TYPE_GLOBAL 1 569 #define HID_ITEM_TYPE_LOCAL 2 570 #define HID_ITEM_TYPE_RESERVED 3 571 /* 572 * HID report descriptor main item tags 573 */ 574 575 #define HID_MAIN_ITEM_TAG_INPUT 8 576 #define HID_MAIN_ITEM_TAG_OUTPUT 9 577 #define HID_MAIN_ITEM_TAG_FEATURE 11 578 #define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION 10 579 #define HID_MAIN_ITEM_TAG_END_COLLECTION 12 580 /* 581 * HID report descriptor main item contents 582 */ 583 584 #define HID_MAIN_ITEM_CONSTANT 0x001 585 #define HID_MAIN_ITEM_VARIABLE 0x002 586 #define HID_MAIN_ITEM_RELATIVE 0x004 587 #define HID_MAIN_ITEM_WRAP 0x008 588 #define HID_MAIN_ITEM_NONLINEAR 0x010 589 #define HID_MAIN_ITEM_NO_PREFERRED 0x020 590 #define HID_MAIN_ITEM_NULL_STATE 0x040 591 #define HID_MAIN_ITEM_VOLATILE 0x080 592 #define HID_MAIN_ITEM_BUFFERED_BYTE 0x100 593 594 /* 595 * HID report descriptor collection item types 596 */ 597 598 #define HID_COLLECTION_PHYSICAL 0 599 #define HID_COLLECTION_APPLICATION 1 600 #define HID_COLLECTION_LOGICAL 2 601 /* 602 * HID report descriptor global item tags 603 */ 604 605 #define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0 606 #define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM 1 607 #define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM 2 608 #define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM 3 609 #define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM 4 610 #define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 5 611 #define HID_GLOBAL_ITEM_TAG_UNIT 6 612 #define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 7 613 #define HID_GLOBAL_ITEM_TAG_REPORT_ID 8 614 #define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 9 615 #define HID_GLOBAL_ITEM_TAG_PUSH 10 616 #define HID_GLOBAL_ITEM_TAG_POP 11 617 618 /* 619 * HID report descriptor local item tags 620 */ 621 622 #define HID_LOCAL_ITEM_TAG_USAGE 0 623 #define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM 1 624 #define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM 2 625 #define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 3 626 #define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4 627 #define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5 628 #define HID_LOCAL_ITEM_TAG_STRING_INDEX 7 629 #define HID_LOCAL_ITEM_TAG_STRING_MINIMUM 8 630 #define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM 9 631 #define HID_LOCAL_ITEM_TAG_DELIMITER 10 632 633 634 static void usb_kbd_show_item(struct hid_item *item) 635 { 636 switch (item->type) { 637 case HID_ITEM_TYPE_MAIN: 638 switch (item->tag) { 639 case HID_MAIN_ITEM_TAG_INPUT: 640 printf("Main Input"); 641 break; 642 case HID_MAIN_ITEM_TAG_OUTPUT: 643 printf("Main Output"); 644 break; 645 case HID_MAIN_ITEM_TAG_FEATURE: 646 printf("Main Feature"); 647 break; 648 case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: 649 printf("Main Begin Collection"); 650 break; 651 case HID_MAIN_ITEM_TAG_END_COLLECTION: 652 printf("Main End Collection"); 653 break; 654 default: 655 printf("Main reserved %d", item->tag); 656 break; 657 } 658 break; 659 case HID_ITEM_TYPE_GLOBAL: 660 switch (item->tag) { 661 case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: 662 printf("- Global Usage Page"); 663 break; 664 case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: 665 printf("- Global Logical Minimum"); 666 break; 667 case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: 668 printf("- Global Logical Maximum"); 669 break; 670 case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: 671 printf("- Global physical Minimum"); 672 break; 673 case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: 674 printf("- Global physical Maximum"); 675 break; 676 case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: 677 printf("- Global Unit Exponent"); 678 break; 679 case HID_GLOBAL_ITEM_TAG_UNIT: 680 printf("- Global Unit"); 681 break; 682 case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: 683 printf("- Global Report Size"); 684 break; 685 case HID_GLOBAL_ITEM_TAG_REPORT_ID: 686 printf("- Global Report ID"); 687 break; 688 case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: 689 printf("- Global Report Count"); 690 break; 691 case HID_GLOBAL_ITEM_TAG_PUSH: 692 printf("- Global Push"); 693 break; 694 case HID_GLOBAL_ITEM_TAG_POP: 695 printf("- Global Pop"); 696 break; 697 default: 698 printf("- Global reserved %d", item->tag); 699 break; 700 } 701 break; 702 case HID_ITEM_TYPE_LOCAL: 703 switch (item->tag) { 704 case HID_LOCAL_ITEM_TAG_USAGE: 705 printf("-- Local Usage"); 706 break; 707 case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: 708 printf("-- Local Usage Minimum"); 709 break; 710 case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: 711 printf("-- Local Usage Maximum"); 712 break; 713 case HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX: 714 printf("-- Local Designator Index"); 715 break; 716 case HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM: 717 printf("-- Local Designator Minimum"); 718 break; 719 case HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM: 720 printf("-- Local Designator Maximum"); 721 break; 722 case HID_LOCAL_ITEM_TAG_STRING_INDEX: 723 printf("-- Local String Index"); 724 break; 725 case HID_LOCAL_ITEM_TAG_STRING_MINIMUM: 726 printf("-- Local String Minimum"); 727 break; 728 case HID_LOCAL_ITEM_TAG_STRING_MAXIMUM: 729 printf("-- Local String Maximum"); 730 break; 731 case HID_LOCAL_ITEM_TAG_DELIMITER: 732 printf("-- Local Delimiter"); 733 break; 734 default: 735 printf("-- Local reserved %d", item->tag); 736 break; 737 } 738 break; 739 default: 740 printf("--- reserved %d", item->type); 741 break; 742 } 743 switch (item->size) { 744 case 1: 745 printf(" %d", item->data.u8); 746 break; 747 case 2: 748 printf(" %d", item->data.u16); 749 break; 750 case 4: 751 printf(" %ld", item->data.u32); 752 break; 753 } 754 printf("\n"); 755 } 756 757 758 static int usb_kbd_get_hid_desc(struct usb_device *dev) 759 { 760 unsigned char buffer[256]; 761 struct usb_descriptor_header *head; 762 struct usb_config_descriptor *config; 763 int index, len, i; 764 unsigned char *start, *end; 765 struct hid_item item; 766 767 if (usb_get_configuration_no(dev, &buffer[0], 0) == -1) 768 return -1; 769 head = (struct usb_descriptor_header *)&buffer[0]; 770 if (head->bDescriptorType != USB_DT_CONFIG) { 771 printf(" ERROR: NOT USB_CONFIG_DESC %x\n", 772 head->bDescriptorType); 773 return -1; 774 } 775 index = head->bLength; 776 config = (struct usb_config_descriptor *)&buffer[0]; 777 len = le16_to_cpu(config->wTotalLength); 778 /* 779 * Ok the first entry must be a configuration entry, 780 * now process the others 781 */ 782 head = (struct usb_descriptor_header *)&buffer[index]; 783 while (index+1 < len) { 784 if (head->bDescriptorType == USB_DT_HID) { 785 printf("HID desc found\n"); 786 memcpy(&usb_kbd_hid_desc, &buffer[index], 787 buffer[index]); 788 le16_to_cpus(&usb_kbd_hid_desc.bcdHID); 789 le16_to_cpus(&usb_kbd_hid_desc.wDescriptorLength); 790 usb_kbd_display_hid(&usb_kbd_hid_desc); 791 len = 0; 792 break; 793 } 794 index += head->bLength; 795 head = (struct usb_descriptor_header *)&buffer[index]; 796 } 797 if (len > 0) 798 return -1; 799 len = usb_kbd_hid_desc.wDescriptorLength; 800 index = usb_get_class_descriptor(dev, 0, USB_DT_REPORT, 0, &buffer[0], 801 len); 802 if (index < 0) { 803 printf("reading report descriptor failed\n"); 804 return -1; 805 } 806 printf(" report descriptor (size %u, read %d)\n", len, index); 807 start = &buffer[0]; 808 end = &buffer[len]; 809 i = 0; 810 do { 811 index = fetch_item(start, end, &item); 812 i += index; 813 i++; 814 if (index >= 0) 815 usb_kbd_show_item(&item); 816 817 start += index; 818 start++; 819 } while (index >= 0); 820 821 } 822 823 #endif 824