Changeset 2303
- Timestamp:
- 06/19/07 15:16:05 (6 years ago)
- Location:
- trunk/src/host/qemu-neo1973
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/host/qemu-neo1973/hw/usb-hid.c
r1948 r2303 3 3 * 4 4 * Copyright (c) 2005 Fabrice Bellard 5 * Copyright (c) 2007 OpenMoko, Inc. (andrew@openedhand.com) 5 6 * 6 7 * Permission is hereby granted, free of charge, to any person obtaining a copy … … 28 29 #define GET_IDLE 0xa102 29 30 #define GET_PROTOCOL 0xa103 31 #define SET_REPORT 0x2101 30 32 #define SET_IDLE 0x210a 31 33 #define SET_PROTOCOL 0x210b 32 34 33 #define USB_MOUSE 1 34 #define USB_TABLET 2 35 #define USB_MOUSE 1 36 #define USB_TABLET 2 37 #define USB_KEYBOARD 3 35 38 36 39 typedef struct USBMouseState { 37 USBDevice dev;38 40 int dx, dy, dz, buttons_state; 39 41 int x, y; 40 int kind;41 42 int mouse_grabbed; 42 43 QEMUPutMouseEntry *eh_entry; 43 44 } USBMouseState; 45 46 typedef struct USBKeyboardState { 47 uint16_t modifiers; 48 uint8_t leds; 49 uint8_t key[16]; 50 int keys; 51 } USBKeyboardState; 52 53 typedef struct USBHIDState { 54 USBDevice dev; 55 union { 56 USBMouseState ptr; 57 USBKeyboardState kbd; 58 }; 59 int kind; 60 int protocol; 61 int idle; 62 } USBHIDState; 44 63 45 64 /* mostly the same values as the Bochs USB Mouse device */ … … 172 191 0x08, 0x00, /* u16 ep_wMaxPacketSize; */ 173 192 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */ 193 }; 194 195 static const uint8_t qemu_keyboard_config_descriptor[] = { 196 /* one configuration */ 197 0x09, /* u8 bLength; */ 198 0x02, /* u8 bDescriptorType; Configuration */ 199 0x22, 0x00, /* u16 wTotalLength; */ 200 0x01, /* u8 bNumInterfaces; (1) */ 201 0x01, /* u8 bConfigurationValue; */ 202 0x04, /* u8 iConfiguration; */ 203 0xa0, /* u8 bmAttributes; 204 Bit 7: must be set, 205 6: Self-powered, 206 5: Remote wakeup, 207 4..0: resvd */ 208 0x32, /* u8 MaxPower; */ 209 210 /* USB 1.1: 211 * USB 2.0, single TT organization (mandatory): 212 * one interface, protocol 0 213 * 214 * USB 2.0, multiple TT organization (optional): 215 * two interfaces, protocols 1 (like single TT) 216 * and 2 (multiple TT mode) ... config is 217 * sometimes settable 218 * NOT IMPLEMENTED 219 */ 220 221 /* one interface */ 222 0x09, /* u8 if_bLength; */ 223 0x04, /* u8 if_bDescriptorType; Interface */ 224 0x00, /* u8 if_bInterfaceNumber; */ 225 0x00, /* u8 if_bAlternateSetting; */ 226 0x01, /* u8 if_bNumEndpoints; */ 227 0x03, /* u8 if_bInterfaceClass; HID */ 228 0x01, /* u8 if_bInterfaceSubClass; Boot */ 229 0x01, /* u8 if_bInterfaceProtocol; Keyboard */ 230 0x05, /* u8 if_iInterface; */ 231 232 /* HID descriptor */ 233 0x09, /* u8 bLength; */ 234 0x21, /* u8 bDescriptorType; */ 235 0x01, 0x11, /* u16 HID_class */ 236 0x00, /* u8 country_code */ 237 0x01, /* u8 num_descriptors */ 238 0x22, /* u8 type; Report */ 239 0x3f, 0x00, /* u16 len */ 240 241 /* one endpoint (status change endpoint) */ 242 0x07, /* u8 ep_bLength; */ 243 0x05, /* u8 ep_bDescriptorType; Endpoint */ 244 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */ 245 0x03, /* u8 ep_bmAttributes; Interrupt */ 246 0x08, 0x00, /* u16 ep_wMaxPacketSize; */ 247 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */ 174 248 }; 175 249 … … 224 298 }; 225 299 300 static const uint8_t qemu_keyboard_hid_report_descriptor[] = { 301 0x05, 0x01, /* Usage Page (Generic Desktop) */ 302 0x09, 0x06, /* Usage (Keyboard) */ 303 0xa1, 0x01, /* Collection (Application) */ 304 0x75, 0x01, /* Report Size (1) */ 305 0x95, 0x08, /* Report Count (8) */ 306 0x05, 0x07, /* Usage Page (Key Codes) */ 307 0x19, 0xe0, /* Usage Minimum (224) */ 308 0x29, 0xe7, /* Usage Maximum (231) */ 309 0x15, 0x00, /* Logical Minimum (0) */ 310 0x25, 0x01, /* Logical Maximum (1) */ 311 0x81, 0x02, /* Input (Data, Variable, Absolute) */ 312 0x95, 0x01, /* Report Count (1) */ 313 0x75, 0x08, /* Report Size (8) */ 314 0x81, 0x01, /* Input (Constant) */ 315 0x95, 0x05, /* Report Count (5) */ 316 0x75, 0x01, /* Report Size (1) */ 317 0x05, 0x08, /* Usage Page (LEDs) */ 318 0x19, 0x01, /* Usage Minimum (1) */ 319 0x29, 0x05, /* Usage Maximum (5) */ 320 0x91, 0x02, /* Output (Data, Variable, Absolute) */ 321 0x95, 0x01, /* Report Count (1) */ 322 0x75, 0x03, /* Report Size (3) */ 323 0x91, 0x01, /* Output (Constant) */ 324 0x95, 0x06, /* Report Count (6) */ 325 0x75, 0x08, /* Report Size (8) */ 326 0x15, 0x00, /* Logical Minimum (0) */ 327 0x25, 0xff, /* Logical Maximum (255) */ 328 0x05, 0x07, /* Usage Page (Key Codes) */ 329 0x19, 0x00, /* Usage Minimum (0) */ 330 0x29, 0xff, /* Usage Maximum (255) */ 331 0x81, 0x00, /* Input (Data, Array) */ 332 0xc0, /* End Collection */ 333 }; 334 335 #define USB_HID_USAGE_ERROR_ROLLOVER 0x01 336 #define USB_HID_USAGE_POSTFAIL 0x02 337 #define USB_HID_USAGE_ERROR_UNDEFINED 0x03 338 339 /* Indices are QEMU keycodes, values are from HID Usage Table. Indices 340 * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */ 341 static const uint8_t usb_hid_usage_keys[0x100] = { 342 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 343 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b, 344 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c, 345 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16, 346 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33, 347 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19, 348 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55, 349 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 350 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f, 351 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59, 352 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44, 353 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 354 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00, 355 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 357 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 358 359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 362 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00, 363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 365 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46, 366 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 367 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a, 368 0x52, 0x4b, 0x00, 0x50, 0x4f, 0x00, 0x00, 0x4d, 369 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00, 370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 375 }; 376 226 377 static void usb_mouse_event(void *opaque, 227 378 int dx1, int dy1, int dz1, int buttons_state) … … 244 395 s->dz += dz; 245 396 s->buttons_state = buttons_state; 397 } 398 399 static void usb_keyboard_event(void *opaque, int keycode) 400 { 401 USBKeyboardState *s = opaque; 402 uint8_t hid_code, key; 403 int i; 404 405 key = keycode & 0x7f; 406 hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))]; 407 s->modifiers &= ~(1 << 8); 408 409 switch (hid_code) { 410 case 0x00: 411 return; 412 413 case 0xe0: 414 if (s->modifiers & (1 << 9)) { 415 s->modifiers ^= 3 << 8; 416 return; 417 } 418 case 0xe1 ... 0xe7: 419 if (keycode & (1 << 7)) { 420 s->modifiers &= ~(1 << (hid_code & 0x0f)); 421 return; 422 } 423 case 0xe8 ... 0xef: 424 s->modifiers |= 1 << (hid_code & 0x0f); 425 return; 426 427 default: 428 if (keycode & (1 << 7)) { 429 s->keys --; 430 for (i = 0; i <= s->keys; i ++) 431 if (s->key[i] == hid_code) { 432 s->key[i] = s->key[s->keys]; 433 s->key[s->keys] = 0x00; 434 return; 435 } 436 } else { 437 for (i = 0; i < s->keys; i ++) 438 if (s->key[i] == hid_code) 439 return; 440 if (s->keys < sizeof(s->key)) 441 s->key[s->keys] = hid_code; 442 s->keys ++; 443 } 444 } 246 445 } 247 446 … … 327 526 } 328 527 528 static int usb_keyboard_poll(USBKeyboardState *s, uint8_t *buf, int len) 529 { 530 if (len < 2) 531 return 0; 532 533 buf[0] = s->modifiers & 0xff; 534 buf[1] = 0; 535 if (s->keys > 6) 536 memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2); 537 else 538 memcpy(buf + 2, s->key, MIN(8, len) - 2); 539 540 return MIN(8, len); 541 } 542 543 static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len) 544 { 545 if (len > 0) { 546 /* 0x01: Num Lock LED 547 * 0x02: Caps Lock LED 548 * 0x04: Scroll Lock LED 549 * 0x08: Compose LED 550 * 0x10: Kana LED */ 551 s->leds = buf[0]; 552 } 553 return 0; 554 } 555 329 556 static void usb_mouse_handle_reset(USBDevice *dev) 330 557 { 331 USBMouseState *s = (USBMouseState *)dev; 332 333 s->dx = 0; 334 s->dy = 0; 335 s->dz = 0; 336 s->x = 0; 337 s->y = 0; 338 s->buttons_state = 0; 339 } 340 341 static int usb_mouse_handle_control(USBDevice *dev, int request, int value, 558 USBHIDState *s = (USBHIDState *)dev; 559 560 s->ptr.dx = 0; 561 s->ptr.dy = 0; 562 s->ptr.dz = 0; 563 s->ptr.x = 0; 564 s->ptr.y = 0; 565 s->ptr.buttons_state = 0; 566 s->protocol = 1; 567 } 568 569 static void usb_keyboard_handle_reset(USBDevice *dev) 570 { 571 USBHIDState *s = (USBHIDState *)dev; 572 573 s->protocol = 1; 574 } 575 576 static int usb_hid_handle_control(USBDevice *dev, int request, int value, 342 577 int index, int length, uint8_t *data) 343 578 { 344 USB MouseState *s = (USBMouseState *)dev;579 USBHIDState *s = (USBHIDState *)dev; 345 580 int ret = 0; 346 581 … … 388 623 sizeof(qemu_tablet_config_descriptor)); 389 624 ret = sizeof(qemu_tablet_config_descriptor); 390 } 625 } else if (s->kind == USB_KEYBOARD) { 626 memcpy(data, qemu_keyboard_config_descriptor, 627 sizeof(qemu_keyboard_config_descriptor)); 628 ret = sizeof(qemu_keyboard_config_descriptor); 629 } 391 630 break; 392 631 case USB_DT_STRING: … … 406 645 case 2: 407 646 /* product description */ 408 if (s->kind == USB_MOUSE) 409 ret = set_usb_string(data, "QEMU USB Mouse"); 410 else if (s->kind == USB_TABLET) 411 ret = set_usb_string(data, "QEMU USB Tablet"); 647 ret = set_usb_string(data, s->dev.devname); 412 648 break; 413 649 case 3: … … 455 691 sizeof(qemu_tablet_hid_report_descriptor)); 456 692 ret = sizeof(qemu_tablet_hid_report_descriptor); 457 } 458 break; 693 } else if (s->kind == USB_KEYBOARD) { 694 memcpy(data, qemu_keyboard_hid_report_descriptor, 695 sizeof(qemu_keyboard_hid_report_descriptor)); 696 ret = sizeof(qemu_keyboard_hid_report_descriptor); 697 } 698 break; 459 699 default: 460 700 goto fail; … … 463 703 case GET_REPORT: 464 704 if (s->kind == USB_MOUSE) 465 ret = usb_mouse_poll(s, data, length);705 ret = usb_mouse_poll(&s->ptr, data, length); 466 706 else if (s->kind == USB_TABLET) 467 ret = usb_tablet_poll(s, data, length); 707 ret = usb_tablet_poll(&s->ptr, data, length); 708 else if (s->kind == USB_KEYBOARD) 709 ret = usb_keyboard_poll(&s->kbd, data, length); 710 break; 711 case SET_REPORT: 712 if (s->kind == USB_KEYBOARD) 713 ret = usb_keyboard_write(&s->kbd, data, length); 714 else 715 goto fail; 716 break; 717 case GET_PROTOCOL: 718 if (s->kind != USB_KEYBOARD) 719 goto fail; 720 ret = 1; 721 data[0] = s->protocol; 722 break; 723 case SET_PROTOCOL: 724 if (s->kind != USB_KEYBOARD) 725 goto fail; 726 ret = 0; 727 s->protocol = value; 728 break; 729 case GET_IDLE: 730 ret = 1; 731 data[0] = s->idle; 468 732 break; 469 733 case SET_IDLE: 734 s->idle = value; 470 735 ret = 0; 471 736 break; … … 478 743 } 479 744 480 static int usb_ mouse_handle_data(USBDevice *dev, USBPacket *p)481 { 482 USB MouseState *s = (USBMouseState *)dev;745 static int usb_hid_handle_data(USBDevice *dev, USBPacket *p) 746 { 747 USBHIDState *s = (USBHIDState *)dev; 483 748 int ret = 0; 484 749 … … 486 751 case USB_TOKEN_IN: 487 752 if (p->devep == 1) { 488 if (s->kind == USB_MOUSE) 489 ret = usb_mouse_poll(s, p->data, p->len); 490 else if (s->kind == USB_TABLET) 491 ret = usb_tablet_poll(s, p->data, p->len); 753 if (s->kind == USB_MOUSE) 754 ret = usb_mouse_poll(&s->ptr, p->data, p->len); 755 else if (s->kind == USB_TABLET) 756 ret = usb_tablet_poll(&s->ptr, p->data, p->len); 757 else if (s->kind == USB_KEYBOARD) 758 ret = usb_keyboard_poll(&s->kbd, p->data, p->len); 492 759 } else { 493 760 goto fail; … … 503 770 } 504 771 505 static void usb_mouse_handle_destroy(USBDevice *dev) 506 { 507 USBMouseState *s = (USBMouseState *)dev; 508 509 qemu_remove_mouse_event_handler(s->eh_entry); 772 static void usb_hid_handle_destroy(USBDevice *dev) 773 { 774 USBHIDState *s = (USBHIDState *)dev; 775 776 if (!s->kind == USB_KEYBOARD) 777 qemu_remove_mouse_event_handler(s->ptr.eh_entry); 778 /* TODO: else */ 510 779 qemu_free(s); 511 780 } … … 513 782 USBDevice *usb_tablet_init(void) 514 783 { 515 USB MouseState *s;516 517 s = qemu_mallocz(sizeof(USB MouseState));784 USBHIDState *s; 785 786 s = qemu_mallocz(sizeof(USBHIDState)); 518 787 if (!s) 519 788 return NULL; … … 522 791 523 792 s->dev.handle_reset = usb_mouse_handle_reset; 524 s->dev.handle_control = usb_ mouse_handle_control;525 s->dev.handle_data = usb_ mouse_handle_data;526 s->dev.handle_destroy = usb_ mouse_handle_destroy;793 s->dev.handle_control = usb_hid_handle_control; 794 s->dev.handle_data = usb_hid_handle_data; 795 s->dev.handle_destroy = usb_hid_handle_destroy; 527 796 s->kind = USB_TABLET; 528 797 … … 534 803 USBDevice *usb_mouse_init(void) 535 804 { 536 USB MouseState *s;537 538 s = qemu_mallocz(sizeof(USB MouseState));805 USBHIDState *s; 806 807 s = qemu_mallocz(sizeof(USBHIDState)); 539 808 if (!s) 540 809 return NULL; … … 543 812 544 813 s->dev.handle_reset = usb_mouse_handle_reset; 545 s->dev.handle_control = usb_ mouse_handle_control;546 s->dev.handle_data = usb_ mouse_handle_data;547 s->dev.handle_destroy = usb_ mouse_handle_destroy;814 s->dev.handle_control = usb_hid_handle_control; 815 s->dev.handle_data = usb_hid_handle_data; 816 s->dev.handle_destroy = usb_hid_handle_destroy; 548 817 s->kind = USB_MOUSE; 549 818 … … 552 821 return (USBDevice *)s; 553 822 } 823 824 USBDevice *usb_keyboard_init(void) 825 { 826 USBHIDState *s; 827 828 s = qemu_mallocz(sizeof(USBHIDState)); 829 if (!s) 830 return NULL; 831 s->dev.speed = USB_SPEED_FULL; 832 s->dev.handle_packet = usb_generic_handle_packet; 833 834 s->dev.handle_reset = usb_keyboard_handle_reset; 835 s->dev.handle_control = usb_hid_handle_control; 836 s->dev.handle_data = usb_hid_handle_data; 837 s->dev.handle_destroy = usb_hid_handle_destroy; 838 s->kind = USB_KEYBOARD; 839 840 pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Keyboard"); 841 842 qemu_add_kbd_event_handler(usb_keyboard_event, &s->kbd); 843 844 return (USBDevice *) s; 845 } -
trunk/src/host/qemu-neo1973/hw/usb.h
r2289 r2303 224 224 USBDevice *usb_mouse_init(void); 225 225 USBDevice *usb_tablet_init(void); 226 USBDevice *usb_keyboard_init(void); 226 227 227 228 /* usb-msd.c */ -
trunk/src/host/qemu-neo1973/vl.c
r2289 r2303 4371 4371 dev = usb_mouse_init(); 4372 4372 } else if (!strcmp(devname, "tablet")) { 4373 dev = usb_tablet_init(); 4373 dev = usb_tablet_init(); 4374 } else if (!strcmp(devname, "keyboard")) { 4375 dev = usb_keyboard_init(); 4374 4376 } else if (strstart(devname, "disk:", &p)) { 4375 4377 dev = usb_msd_init(p);
Note: See TracChangeset
for help on using the changeset viewer.
