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