Changeset 3d4aa055 in mainline for uspace/drv/usbhid
- Timestamp:
- 2011-05-06T13:08:10Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 075c1eb, 3da17644
- Parents:
- a58dd620 (diff), 310c4df (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- uspace/drv/usbhid
- Files:
-
- 1 added
- 15 edited
- 1 moved
-
Makefile (modified) (1 diff)
-
generic/hiddev.c (modified) (2 diffs)
-
generic/hiddev.h (modified) (1 diff)
-
kbd/conv.c (modified) (1 diff)
-
kbd/kbddev.c (modified) (20 diffs)
-
kbd/kbddev.h (modified) (1 diff)
-
lgtch-ultrax/keymap.c (added)
-
lgtch-ultrax/keymap.h (moved) (moved from uspace/lib/usbvirt/src/debug.c ) (2 diffs)
-
lgtch-ultrax/lgtch-ultrax.c (modified) (2 diffs)
-
lgtch-ultrax/lgtch-ultrax.h (modified) (1 diff)
-
main.c (modified) (1 diff)
-
mouse/mousedev.c (modified) (8 diffs)
-
mouse/mousedev.h (modified) (1 diff)
-
subdrivers.c (modified) (2 diffs)
-
subdrivers.h (modified) (1 diff)
-
usbhid.c (modified) (10 diffs)
-
usbhid.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhid/Makefile
ra58dd620 r3d4aa055 47 47 mouse/mousedev.c \ 48 48 lgtch-ultrax/lgtch-ultrax.c \ 49 lgtch-ultrax/keymap.c \ 49 50 $(STOLEN_LAYOUT_SOURCES) 50 51 -
uspace/drv/usbhid/generic/hiddev.c
ra58dd620 r3d4aa055 37 37 #include <usb/debug.h> 38 38 #include <usb/classes/classes.h> 39 #include <errno.h> 40 #include <str_error.h> 41 42 #include <usbhid_iface.h> 39 43 40 44 #include "hiddev.h" … … 55 59 /*----------------------------------------------------------------------------*/ 56 60 61 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun); 62 63 static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer, 64 size_t size, size_t *act_size, unsigned int flags); 65 66 /*----------------------------------------------------------------------------*/ 67 68 static usbhid_iface_t usb_generic_iface = { 69 .get_event = usb_generic_hid_get_event, 70 .get_event_length = usb_generic_hid_get_event_length 71 }; 72 73 static ddf_dev_ops_t usb_generic_hid_ops = { 74 .interfaces[USBHID_DEV_IFACE] = &usb_generic_iface 75 }; 76 77 /*----------------------------------------------------------------------------*/ 78 79 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun) 80 { 81 if (fun == NULL || fun->driver_data) { 82 return 0; 83 } 84 85 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 86 87 return hid_dev->input_report_size; 88 } 89 90 /*----------------------------------------------------------------------------*/ 91 92 static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer, 93 size_t size, size_t *act_size, unsigned int flags) 94 { 95 if (fun == NULL || fun->driver_data) { 96 return EINVAL; 97 } 98 99 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 100 101 if (hid_dev->input_report_size > size) { 102 return EINVAL; // TODO: other error code 103 } 104 105 /*! @todo This should probably be atomic. */ 106 memcpy(buffer, hid_dev->input_report, hid_dev->input_report_size); 107 *act_size = hid_dev->input_report_size; 108 109 // clear the buffer so that it will not be received twice 110 memset(hid_dev->input_report, 0, hid_dev->input_report_size); 111 112 return EOK; 113 } 114 115 /*----------------------------------------------------------------------------*/ 116 117 static int usb_generic_hid_create_function(usb_hid_dev_t *hid_dev) 118 { 119 /* Create the function exposed under /dev/devices. */ 120 /** @todo Generate numbers for the devices? */ 121 usb_log_debug("Creating DDF function %s...\n", HID_GENERIC_FUN_NAME); 122 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 123 HID_GENERIC_FUN_NAME); 124 if (fun == NULL) { 125 usb_log_error("Could not create DDF function node.\n"); 126 return ENOMEM; 127 } 128 129 int rc = ddf_fun_bind(fun); 130 if (rc != EOK) { 131 usb_log_error("Could not bind DDF function: %s.\n", 132 str_error(rc)); 133 ddf_fun_destroy(fun); 134 return rc; 135 } 136 137 fun->ops = &usb_generic_hid_ops; 138 fun->driver_data = hid_dev; 139 140 return EOK; 141 } 142 143 /*----------------------------------------------------------------------------*/ 144 145 int usb_generic_hid_init(usb_hid_dev_t *hid_dev) 146 { 147 if (hid_dev == NULL) { 148 return EINVAL; 149 } 150 151 return usb_generic_hid_create_function(hid_dev); 152 } 153 154 /*----------------------------------------------------------------------------*/ 155 57 156 bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, 58 157 uint8_t *buffer, size_t buffer_size) -
uspace/drv/usbhid/generic/hiddev.h
ra58dd620 r3d4aa055 46 46 const char *HID_GENERIC_CLASS_NAME; 47 47 48 /*----------------------------------------------------------------------------*/ 49 50 int usb_generic_hid_init(struct usb_hid_dev *hid_dev); 51 48 52 bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, 49 53 uint8_t *buffer, size_t buffer_size); -
uspace/drv/usbhid/kbd/conv.c
ra58dd620 r3d4aa055 99 99 [0x30] = KC_RBRACKET, 100 100 [0x31] = KC_BACKSLASH, 101 //[0x32] = KC_, // TODO: HASH??? maybe some as 0x31 - backslash 101 //[0x32] = KC_, // TODO: HASH??? maybe same as 0x31 - backslash 102 [0x32] = KC_BACKSLASH, 102 103 [0x33] = KC_SEMICOLON, 103 104 [0x34] = KC_QUOTE, // same as APOSTROPHE? (') -
uspace/drv/usbhid/kbd/kbddev.c
ra58dd620 r3d4aa055 177 177 /*----------------------------------------------------------------------------*/ 178 178 179 static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,180 uint8_t report_id, void *arg);181 182 static const usb_hid_report_in_callbacks_t usb_kbd_parser_callbacks = {183 .keyboard = usb_kbd_process_keycodes184 };179 //static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count, 180 // uint8_t report_id, void *arg); 181 182 //static const usb_hid_report_in_callbacks_t usb_kbd_parser_callbacks = { 183 // .keyboard = usb_kbd_process_keycodes 184 //}; 185 185 186 186 /*----------------------------------------------------------------------------*/ … … 203 203 /*----------------------------------------------------------------------------*/ 204 204 /** Mapping of USB modifier key codes to generic modifier key codes. */ 205 static const keycode_t usbhid_modifiers_keycodes[USB_HID_MOD_COUNT] = {206 KC_LCTRL, /* USB_HID_MOD_LCTRL */207 KC_LSHIFT, /* USB_HID_MOD_LSHIFT */208 KC_LALT, /* USB_HID_MOD_LALT */209 0, /* USB_HID_MOD_LGUI */210 KC_RCTRL, /* USB_HID_MOD_RCTRL */211 KC_RSHIFT, /* USB_HID_MOD_RSHIFT */212 KC_RALT, /* USB_HID_MOD_RALT */213 0, /* USB_HID_MOD_RGUI */214 };215 216 typedef enum usbhid_lock_code {217 USB_KBD_LOCK_NUM = 0x53,218 USB_KBD_LOCK_CAPS = 0x39,219 USB_KBD_LOCK_SCROLL = 0x47,220 USB_KBD_LOCK_COUNT = 3221 } usbhid_lock_code;222 223 static const usbhid_lock_code usbhid_lock_codes[USB_KBD_LOCK_COUNT] = {224 USB_KBD_LOCK_NUM,225 USB_KBD_LOCK_CAPS,226 USB_KBD_LOCK_SCROLL227 };205 //static const keycode_t usbhid_modifiers_keycodes[USB_HID_MOD_COUNT] = { 206 // KC_LCTRL, /* USB_HID_MOD_LCTRL */ 207 // KC_LSHIFT, /* USB_HID_MOD_LSHIFT */ 208 // KC_LALT, /* USB_HID_MOD_LALT */ 209 // 0, /* USB_HID_MOD_LGUI */ 210 // KC_RCTRL, /* USB_HID_MOD_RCTRL */ 211 // KC_RSHIFT, /* USB_HID_MOD_RSHIFT */ 212 // KC_RALT, /* USB_HID_MOD_RALT */ 213 // 0, /* USB_HID_MOD_RGUI */ 214 //}; 215 216 //typedef enum usbhid_lock_code { 217 // USB_KBD_LOCK_NUM = 0x53, 218 // USB_KBD_LOCK_CAPS = 0x39, 219 // USB_KBD_LOCK_SCROLL = 0x47, 220 // USB_KBD_LOCK_COUNT = 3 221 //} usbhid_lock_code; 222 223 //static const usbhid_lock_code usbhid_lock_codes[USB_KBD_LOCK_COUNT] = { 224 // USB_KBD_LOCK_NUM, 225 // USB_KBD_LOCK_CAPS, 226 // USB_KBD_LOCK_SCROLL 227 //}; 228 228 229 229 /*----------------------------------------------------------------------------*/ … … 299 299 return; 300 300 } 301 302 unsigned i = 0; 303 301 304 302 /* Reset the LED data. */ 305 303 memset(kbd_dev->led_data, 0, kbd_dev->led_output_size * sizeof(int32_t)); 306 307 if ((kbd_dev->mods & KM_NUM_LOCK) && (i < kbd_dev->led_output_size)) { 308 kbd_dev->led_data[i++] = USB_HID_LED_NUM_LOCK; 309 } 310 311 if ((kbd_dev->mods & KM_CAPS_LOCK) && (i < kbd_dev->led_output_size)) { 312 kbd_dev->led_data[i++] = USB_HID_LED_CAPS_LOCK; 313 } 314 315 if ((kbd_dev->mods & KM_SCROLL_LOCK) 316 && (i < kbd_dev->led_output_size)) { 317 kbd_dev->led_data[i++] = USB_HID_LED_SCROLL_LOCK; 318 } 319 320 // TODO: COMPOSE and KANA 321 322 usb_log_debug("Creating output report.\n"); 323 324 int rc = usb_hid_report_output_translate(hid_dev->parser, 325 kbd_dev->led_path, 326 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 327 kbd_dev->output_buffer, 328 kbd_dev->output_size, kbd_dev->led_data, kbd_dev->led_output_size); 304 usb_log_debug("Creating output report:\n"); 305 306 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 307 hid_dev->report, NULL, kbd_dev->led_path, 308 USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY | USB_HID_PATH_COMPARE_END, 309 USB_HID_REPORT_TYPE_OUTPUT); 310 311 while (field != NULL) { 312 313 if ((field->usage == USB_HID_LED_NUM_LOCK) 314 && (kbd_dev->mods & KM_NUM_LOCK)){ 315 field->value = 1; 316 } 317 318 if ((field->usage == USB_HID_LED_CAPS_LOCK) 319 && (kbd_dev->mods & KM_CAPS_LOCK)){ 320 field->value = 1; 321 } 322 323 if ((field->usage == USB_HID_LED_SCROLL_LOCK) 324 && (kbd_dev->mods & KM_SCROLL_LOCK)){ 325 field->value = 1; 326 } 327 328 field = usb_hid_report_get_sibling(hid_dev->report, field, 329 kbd_dev->led_path, USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 330 | USB_HID_PATH_COMPARE_END, USB_HID_REPORT_TYPE_OUTPUT); 331 } 332 333 // TODO: what about the Report ID? 334 int rc = usb_hid_report_output_translate(hid_dev->report, 0, 335 kbd_dev->output_buffer, kbd_dev->output_size); 329 336 330 337 if (rc != EOK) { … … 485 492 */ 486 493 static void usb_kbd_check_key_changes(usb_hid_dev_t *hid_dev, 487 usb_kbd_t *kbd_dev , const uint8_t *key_codes, size_t count)494 usb_kbd_t *kbd_dev/*, const uint8_t *key_codes, size_t count*/) 488 495 { 489 496 unsigned int key; … … 499 506 */ 500 507 i = 0; 501 while (i < count && key_codes[i] != ERROR_ROLLOVER) {508 while (i < kbd_dev->key_count && kbd_dev->keys[i] != ERROR_ROLLOVER) { 502 509 ++i; 503 510 } 504 if (i != count) {511 if (i != kbd_dev->key_count) { 505 512 usb_log_debug("Phantom state occured.\n"); 506 513 // phantom state, do nothing … … 508 515 } 509 516 510 /* TODO: quite dummy right now, think of better implementation */511 assert(count == kbd_dev->key_count);512 513 517 /* 514 518 * 1) Key releases 515 519 */ 516 for (j = 0; j < count; ++j) {520 for (j = 0; j < kbd_dev->key_count; ++j) { 517 521 // try to find the old key in the new key list 518 522 i = 0; 519 523 while (i < kbd_dev->key_count 520 && k ey_codes[i] != kbd_dev->keys[j]) {524 && kbd_dev->keys[i] != kbd_dev->keys_old[j]) { 521 525 ++i; 522 526 } 523 527 524 if (i == count) {528 if (i == kbd_dev->key_count) { 525 529 // not found, i.e. the key was released 526 key = usbhid_parse_scancode(kbd_dev->keys [j]);530 key = usbhid_parse_scancode(kbd_dev->keys_old[j]); 527 531 if (!usb_kbd_is_lock(key)) { 528 532 usb_kbd_repeat_stop(kbd_dev, key); … … 541 545 // try to find the new key in the old key list 542 546 j = 0; 543 while (j < count && kbd_dev->keys[j] != key_codes[i]) { 547 while (j < kbd_dev->key_count 548 && kbd_dev->keys_old[j] != kbd_dev->keys[i]) { 544 549 ++j; 545 550 } 546 551 547 if (j == count) {552 if (j == kbd_dev->key_count) { 548 553 // not found, i.e. new key pressed 549 key = usbhid_parse_scancode(k ey_codes[i]);554 key = usbhid_parse_scancode(kbd_dev->keys[i]); 550 555 usb_log_debug2("Key pressed: %d (keycode: %d)\n", key, 551 key_codes[i]); 552 usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, 553 key); 556 kbd_dev->keys[i]); 557 usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, key); 554 558 if (!usb_kbd_is_lock(key)) { 555 559 usb_kbd_repeat_start(kbd_dev, key); … … 560 564 } 561 565 562 memcpy(kbd_dev->keys, key_codes, count); 563 564 usb_log_debug("New stored keycodes: %s\n", 565 usb_debug_str_buffer(kbd_dev->keys, kbd_dev->key_count, 0)); 566 // usb_log_debug("Old keys: "); 567 // for (i = 0; i < kbd_dev->key_count; ++i) { 568 // usb_log_debug("%d ", kbd_dev->keys_old[i]); 569 // } 570 // usb_log_debug("\n"); 571 572 573 // usb_log_debug("New keys: "); 574 // for (i = 0; i < kbd_dev->key_count; ++i) { 575 // usb_log_debug("%d ", kbd_dev->keys[i]); 576 // } 577 // usb_log_debug("\n"); 578 579 memcpy(kbd_dev->keys_old, kbd_dev->keys, kbd_dev->key_count * 4); 580 581 usb_log_debug2("New stored keys: "); 582 for (i = 0; i < kbd_dev->key_count; ++i) { 583 usb_log_debug2("%d ", kbd_dev->keys_old[i]); 584 } 585 usb_log_debug2("\n"); 566 586 } 567 587 … … 585 605 * @sa usb_kbd_check_key_changes(), usb_kbd_check_modifier_changes() 586 606 */ 587 static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,588 uint8_t report_id, void *arg)589 {590 if (arg == NULL) {591 usb_log_warning("Missing argument in callback "592 "usbhid_process_keycodes().\n");593 return;594 }595 596 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;597 598 if (hid_dev->data == NULL) {599 usb_log_warning("Missing KBD device structure in callback.\n");600 return;601 }602 603 usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;604 605 usb_log_debug("Got keys from parser (report id: %u): %s\n",606 report_id, usb_debug_str_buffer(key_codes, count, 0));607 608 if (count != kbd_dev->key_count) {609 usb_log_warning("Number of received keycodes (%zu) differs from"610 " expected (%zu).\n", count, kbd_dev->key_count);611 return;612 }613 614 ///usb_kbd_check_modifier_changes(kbd_dev, key_codes, count);615 usb_kbd_check_key_changes(hid_dev, kbd_dev, key_codes, count);616 }607 //static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count, 608 // uint8_t report_id, void *arg) 609 //{ 610 // if (arg == NULL) { 611 // usb_log_warning("Missing argument in callback " 612 // "usbhid_process_keycodes().\n"); 613 // return; 614 // } 615 616 // usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 617 618 // if (hid_dev->data == NULL) { 619 // usb_log_warning("Missing KBD device structure in callback.\n"); 620 // return; 621 // } 622 623 // usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data; 624 625 // usb_log_debug("Got keys from parser (report id: %u): %s\n", 626 // report_id, usb_debug_str_buffer(key_codes, count, 0)); 627 628 // if (count != kbd_dev->key_count) { 629 // usb_log_warning("Number of received keycodes (%zu) differs from" 630 // " expected (%zu).\n", count, kbd_dev->key_count); 631 // return; 632 // } 633 634 // ///usb_kbd_check_modifier_changes(kbd_dev, key_codes, count); 635 // usb_kbd_check_key_changes(hid_dev, kbd_dev, key_codes, count); 636 //} 617 637 618 638 /*----------------------------------------------------------------------------*/ … … 638 658 uint8_t *buffer, size_t actual_size) 639 659 { 640 assert(hid_dev->parser != NULL); 660 assert(hid_dev->report != NULL); 661 assert(hid_dev != NULL); 662 assert(hid_dev->data != NULL); 663 664 usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data; 641 665 642 666 usb_log_debug("Calling usb_hid_parse_report() with " … … 648 672 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 649 673 //usb_hid_report_path_set_report_id(path, 0); 650 651 int rc = usb_hid_parse_report(hid_dev->parser, buffer, 652 actual_size, path, 674 675 uint8_t report_id; 676 int rc = usb_hid_parse_report(hid_dev->report, buffer, actual_size, 677 &report_id); 678 679 if (rc != EOK) { 680 usb_log_warning("Error in usb_hid_parse_report():" 681 "%s\n", str_error(rc)); 682 } 683 684 usb_hid_report_path_set_report_id (path, report_id); 685 686 // fill in the currently pressed keys 687 688 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 689 hid_dev->report, NULL, path, 653 690 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 654 &usb_kbd_parser_callbacks, hid_dev); 655 691 USB_HID_REPORT_TYPE_INPUT); 692 unsigned i = 0; 693 694 while (field != NULL) { 695 usb_log_debug2("FIELD (%p) - VALUE(%d) USAGE(%u)\n", 696 field, field->value, field->usage); 697 698 assert(i < kbd_dev->key_count); 699 // if (i == kbd_dev->key_count) { 700 // break; 701 // } 702 703 // save the key usage 704 /* TODO: maybe it's not good to save value, nor usage 705 * as the value may be e.g. 1 for LEDs and usage may be 706 * value of the LED. On the other hand, in case of normal 707 * keys, the usage is more important and we must check 708 * that. One possible solution: distinguish between those 709 * two parts of the Report somehow. 710 */ 711 if (field->value != 0) { 712 kbd_dev->keys[i] = field->usage; 713 } 714 else { 715 kbd_dev->keys[i] = 0; 716 } 717 usb_log_debug2("Saved %u. key usage %d\n", i, kbd_dev->keys[i]); 718 719 ++i; 720 field = usb_hid_report_get_sibling(hid_dev->report, field, path, 721 USB_HID_PATH_COMPARE_END 722 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 723 USB_HID_REPORT_TYPE_INPUT); 724 } 725 656 726 usb_hid_report_path_free(path); 657 727 658 if (rc != EOK) { 659 usb_log_warning("Error in usb_hid_boot_keyboard_input_report():" 660 "%s\n", str_error(rc)); 661 } 728 usb_kbd_check_key_changes(hid_dev, kbd_dev); 662 729 } 663 730 … … 696 763 697 764 return kbd_dev; 765 } 766 767 /*----------------------------------------------------------------------------*/ 768 769 static int usb_kbd_create_function(usb_hid_dev_t *hid_dev) 770 { 771 assert(hid_dev != NULL); 772 assert(hid_dev->usb_dev != NULL); 773 774 /* Create the function exposed under /dev/devices. */ 775 usb_log_debug("Creating DDF function %s...\n", HID_KBD_FUN_NAME); 776 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 777 HID_KBD_FUN_NAME); 778 if (fun == NULL) { 779 usb_log_error("Could not create DDF function node.\n"); 780 return ENOMEM; 781 } 782 783 /* 784 * Store the initialized HID device and HID ops 785 * to the DDF function. 786 */ 787 fun->ops = &hid_dev->ops; 788 fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data 789 790 int rc = ddf_fun_bind(fun); 791 if (rc != EOK) { 792 usb_log_error("Could not bind DDF function: %s.\n", 793 str_error(rc)); 794 ddf_fun_destroy(fun); 795 return rc; 796 } 797 798 usb_log_debug("Adding DDF function to class %s...\n", 799 HID_KBD_CLASS_NAME); 800 rc = ddf_fun_add_to_class(fun, HID_KBD_CLASS_NAME); 801 if (rc != EOK) { 802 usb_log_error( 803 "Could not add DDF function to class %s: %s.\n", 804 HID_KBD_CLASS_NAME, str_error(rc)); 805 ddf_fun_destroy(fun); 806 return rc; 807 } 808 809 return EOK; 698 810 } 699 811 … … 747 859 748 860 kbd_dev->key_count = usb_hid_report_input_length( 749 hid_dev-> parser, path,861 hid_dev->report, path, 750 862 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY); 751 863 usb_hid_report_path_free(path); … … 753 865 usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count); 754 866 755 kbd_dev->keys = ( uint8_t *)calloc(kbd_dev->key_count, sizeof(uint8_t));867 kbd_dev->keys = (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t)); 756 868 757 869 if (kbd_dev->keys == NULL) { … … 761 873 } 762 874 875 kbd_dev->keys_old = 876 (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t)); 877 878 if (kbd_dev->keys_old == NULL) { 879 usb_log_fatal("No memory!\n"); 880 free(kbd_dev->keys); 881 free(kbd_dev); 882 return ENOMEM; 883 } 884 763 885 /* 764 886 * Output report 765 887 */ 766 888 kbd_dev->output_size = 0; 767 kbd_dev->output_buffer = usb_hid_report_output(hid_dev-> parser,768 &kbd_dev->output_size );769 if (kbd_dev->output_buffer == NULL && kbd_dev->output_size != 0) {889 kbd_dev->output_buffer = usb_hid_report_output(hid_dev->report, 890 &kbd_dev->output_size, 0); 891 if (kbd_dev->output_buffer == NULL) { 770 892 usb_log_warning("Error creating output report buffer.\n"); 771 893 free(kbd_dev->keys); 772 free(kbd_dev); 773 return ENOMEM; 894 return ENOMEM; /* TODO: other error code */ 774 895 } 775 896 … … 780 901 kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0); 781 902 782 kbd_dev->led_output_size = usb_hid_report_output_size(hid_dev-> parser,903 kbd_dev->led_output_size = usb_hid_report_output_size(hid_dev->report, 783 904 kbd_dev->led_path, 784 905 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY); … … 854 975 usb_log_debug("HID/KBD device structure initialized.\n"); 855 976 977 usb_log_debug("Creating KBD function...\n"); 978 int rc = usb_kbd_create_function(hid_dev); 979 if (rc != EOK) { 980 usb_kbd_free(&kbd_dev); 981 return rc; 982 } 983 856 984 return EOK; 857 985 } … … 908 1036 } 909 1037 910 // free the output buffer 911 usb_hid_report_output_free((*kbd_dev)->output_buffer); 1038 // free all buffers 1039 if ((*kbd_dev)->keys != NULL) { 1040 free((*kbd_dev)->keys); 1041 } 1042 if ((*kbd_dev)->keys_old != NULL) { 1043 free((*kbd_dev)->keys_old); 1044 } 1045 if ((*kbd_dev)->led_data != NULL) { 1046 free((*kbd_dev)->led_data); 1047 } 1048 if ((*kbd_dev)->led_path != NULL) { 1049 usb_hid_report_path_free((*kbd_dev)->led_path); 1050 } 1051 if ((*kbd_dev)->output_buffer != NULL) { 1052 usb_hid_report_output_free((*kbd_dev)->output_buffer); 1053 } 912 1054 913 1055 free(*kbd_dev); … … 929 1071 } else { 930 1072 usb_kbd_free(&kbd_dev); 1073 hid_dev->data = NULL; 931 1074 } 932 1075 } … … 937 1080 int usb_kbd_set_boot_protocol(usb_hid_dev_t *hid_dev) 938 1081 { 939 int rc = usb_hid_parse_report_descriptor(hid_dev-> parser,1082 int rc = usb_hid_parse_report_descriptor(hid_dev->report, 940 1083 USB_KBD_BOOT_REPORT_DESCRIPTOR, 941 1084 USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE); -
uspace/drv/usbhid/kbd/kbddev.h
ra58dd620 r3d4aa055 65 65 */ 66 66 typedef struct usb_kbd_t { 67 /** Previously pressed keys (not translated to key codes). */ 68 int32_t *keys_old; 67 69 /** Currently pressed keys (not translated to key codes). */ 68 uint8_t *keys;70 int32_t *keys; 69 71 /** Count of stored keys (i.e. number of keys in the report). */ 70 72 size_t key_count; -
uspace/drv/usbhid/lgtch-ultrax/keymap.h
ra58dd620 r3d4aa055 1 1 /* 2 * Copyright (c) 201 0 Vojtech Horky2 * Copyright (c) 2011 Lubos Slovak 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup libusbvirt29 /** @addtogroup drvusbhid 30 30 * @{ 31 31 */ 32 32 /** @file 33 * @brief Debugging support.33 * USB multimedia key to keycode mapping. 34 34 */ 35 #include <stdio.h>36 #include <bool.h>37 35 38 #include "private.h" 36 #ifndef USB_HID_LGTCH_ULTRAX_KEYMAP_H_ 37 #define USB_HID_LGTCH_ULTRAX_KEYMAP_H_ 39 38 39 unsigned int usb_lgtch_map_usage(int usage); 40 40 41 static void debug_print(int level, uint8_t tag, 42 int current_level, uint8_t enabled_tags, 43 const char *format, va_list args) 44 { 45 if (level > current_level) { 46 return; 47 } 48 49 if ((tag & enabled_tags) == 0) { 50 return; 51 } 52 53 bool print_prefix = true; 54 55 if ((format[0] == '%') && (format[1] == 'M')) { 56 format += 2; 57 print_prefix = false; 58 } 59 60 if (print_prefix) { 61 printf("[vusb]: "); 62 while (--level > 0) { 63 printf(" "); 64 } 65 } 66 67 vprintf(format, args); 68 69 if (print_prefix) { 70 printf("\n"); 71 } 72 } 73 74 75 void user_debug(usbvirt_device_t *device, int level, uint8_t tag, 76 const char *format, ...) 77 { 78 va_list args; 79 va_start(args, format); 80 81 debug_print(level, tag, 82 device->debug_level, device->debug_enabled_tags, 83 format, args); 84 85 va_end(args); 86 } 87 88 void lib_debug(usbvirt_device_t *device, int level, uint8_t tag, 89 const char *format, ...) 90 { 91 va_list args; 92 va_start(args, format); 93 94 debug_print(level, tag, 95 device->lib_debug_level, device->lib_debug_enabled_tags, 96 format, args); 97 98 va_end(args); 99 } 41 #endif /* USB_HID_LGTCH_ULTRAX_KEYMAP_H_ */ 100 42 101 43 /** -
uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c
ra58dd620 r3d4aa055 38 38 #include "lgtch-ultrax.h" 39 39 #include "../usbhid.h" 40 #include "keymap.h" 40 41 41 42 #include <usb/classes/hidparser.h> 42 43 #include <usb/debug.h> 44 #include <usb/classes/hidut.h> 45 43 46 #include <errno.h> 44 47 #include <str_error.h> 45 48 49 #include <ipc/kbd.h> 50 #include <io/console.h> 51 46 52 #define NAME "lgtch-ultrax" 47 53 48 /*----------------------------------------------------------------------------*/ 49 50 static void usb_lgtch_process_keycodes(const uint8_t *key_codes, size_t count, 51 uint8_t report_id, void *arg); 52 53 static const usb_hid_report_in_callbacks_t usb_lgtch_parser_callbacks = { 54 .keyboard = usb_lgtch_process_keycodes 54 typedef enum usb_lgtch_flags { 55 USB_LGTCH_STATUS_UNINITIALIZED = 0, 56 USB_LGTCH_STATUS_INITIALIZED = 1, 57 USB_LGTCH_STATUS_TO_DESTROY = -1 58 } usb_lgtch_flags; 59 60 /*----------------------------------------------------------------------------*/ 61 /** 62 * Logitech UltraX device type. 63 */ 64 typedef struct usb_lgtch_ultrax_t { 65 /** Previously pressed keys (not translated to key codes). */ 66 int32_t *keys_old; 67 /** Currently pressed keys (not translated to key codes). */ 68 int32_t *keys; 69 /** Count of stored keys (i.e. number of keys in the report). */ 70 size_t key_count; 71 72 /** IPC phone to the console device (for sending key events). */ 73 int console_phone; 74 75 /** Information for auto-repeat of keys. */ 76 // usb_kbd_repeat_t repeat; 77 78 /** Mutex for accessing the information about auto-repeat. */ 79 // fibril_mutex_t *repeat_mtx; 80 81 /** State of the structure (for checking before use). 82 * 83 * 0 - not initialized 84 * 1 - initialized 85 * -1 - ready for destroying 86 */ 87 int initialized; 88 } usb_lgtch_ultrax_t; 89 90 91 /*----------------------------------------------------------------------------*/ 92 /** 93 * Default handler for IPC methods not handled by DDF. 94 * 95 * Currently recognizes only one method (IPC_M_CONNECT_TO_ME), in which case it 96 * assumes the caller is the console and thus it stores IPC phone to it for 97 * later use by the driver to notify about key events. 98 * 99 * @param fun Device function handling the call. 100 * @param icallid Call id. 101 * @param icall Call data. 102 */ 103 static void default_connection_handler(ddf_fun_t *fun, 104 ipc_callid_t icallid, ipc_call_t *icall) 105 { 106 usb_log_debug(NAME " default_connection_handler()\n"); 107 108 sysarg_t method = IPC_GET_IMETHOD(*icall); 109 110 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 111 112 if (hid_dev == NULL || hid_dev->data == NULL) { 113 async_answer_0(icallid, EINVAL); 114 return; 115 } 116 117 assert(hid_dev != NULL); 118 assert(hid_dev->data != NULL); 119 usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)hid_dev->data; 120 121 if (method == IPC_M_CONNECT_TO_ME) { 122 int callback = IPC_GET_ARG5(*icall); 123 124 if (lgtch_dev->console_phone != -1) { 125 async_answer_0(icallid, ELIMIT); 126 return; 127 } 128 129 lgtch_dev->console_phone = callback; 130 usb_log_debug(NAME " Saved phone to console: %d\n", callback); 131 async_answer_0(icallid, EOK); 132 return; 133 } 134 135 async_answer_0(icallid, EINVAL); 136 } 137 138 /*----------------------------------------------------------------------------*/ 139 140 static ddf_dev_ops_t lgtch_ultrax_ops = { 141 .default_handler = default_connection_handler 55 142 }; 56 143 57 144 /*----------------------------------------------------------------------------*/ 58 145 59 static void usb_lgtch_process_keycodes(const uint8_t *key_codes, size_t count, 60 uint8_t report_id, void *arg) 61 { 62 // TODO: checks 63 64 usb_log_debug(NAME " Got keys from parser (report id: %u): %s\n", 65 report_id, usb_debug_str_buffer(key_codes, count, 0)); 146 //static void usb_lgtch_process_keycodes(const uint8_t *key_codes, size_t count, 147 // uint8_t report_id, void *arg); 148 149 //static const usb_hid_report_in_callbacks_t usb_lgtch_parser_callbacks = { 150 // .keyboard = usb_lgtch_process_keycodes 151 //}; 152 153 ///*----------------------------------------------------------------------------*/ 154 155 //static void usb_lgtch_process_keycodes(const uint8_t *key_codes, size_t count, 156 // uint8_t report_id, void *arg) 157 //{ 158 // // TODO: checks 159 160 // usb_log_debug(NAME " Got keys from parser (report id: %u): %s\n", 161 // report_id, usb_debug_str_buffer(key_codes, count, 0)); 162 //} 163 164 /*----------------------------------------------------------------------------*/ 165 /** 166 * Processes key events. 167 * 168 * @note This function was copied from AT keyboard driver and modified to suit 169 * USB keyboard. 170 * 171 * @note Lock keys are not sent to the console, as they are completely handled 172 * in the driver. It may, however, be required later that the driver 173 * sends also these keys to application (otherwise it cannot use those 174 * keys at all). 175 * 176 * @param hid_dev 177 * @param lgtch_dev 178 * @param type Type of the event (press / release). Recognized values: 179 * KEY_PRESS, KEY_RELEASE 180 * @param key Key code of the key according to HID Usage Tables. 181 */ 182 static void usb_lgtch_push_ev(usb_hid_dev_t *hid_dev, int type, 183 unsigned int key) 184 { 185 assert(hid_dev != NULL); 186 assert(hid_dev->data != NULL); 187 188 usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)hid_dev->data; 189 190 console_event_t ev; 191 192 ev.type = type; 193 ev.key = key; 194 ev.mods = 0; 195 196 ev.c = 0; 197 198 usb_log_debug2(NAME " Sending key %d to the console\n", ev.key); 199 if (lgtch_dev->console_phone < 0) { 200 usb_log_warning( 201 "Connection to console not ready, key discarded.\n"); 202 return; 203 } 204 205 async_msg_4(lgtch_dev->console_phone, KBD_EVENT, ev.type, ev.key, 206 ev.mods, ev.c); 207 } 208 209 /*----------------------------------------------------------------------------*/ 210 211 static void usb_lgtch_free(usb_lgtch_ultrax_t **lgtch_dev) 212 { 213 if (lgtch_dev == NULL || *lgtch_dev == NULL) { 214 return; 215 } 216 217 // hangup phone to the console 218 async_hangup((*lgtch_dev)->console_phone); 219 220 // if ((*lgtch_dev)->repeat_mtx != NULL) { 221 // /* TODO: replace by some check and wait */ 222 // assert(!fibril_mutex_is_locked((*lgtch_dev)->repeat_mtx)); 223 // free((*lgtch_dev)->repeat_mtx); 224 // } 225 226 // free all buffers 227 if ((*lgtch_dev)->keys != NULL) { 228 free((*lgtch_dev)->keys); 229 } 230 if ((*lgtch_dev)->keys_old != NULL) { 231 free((*lgtch_dev)->keys_old); 232 } 233 234 free(*lgtch_dev); 235 *lgtch_dev = NULL; 236 } 237 238 /*----------------------------------------------------------------------------*/ 239 240 static int usb_lgtch_create_function(usb_hid_dev_t *hid_dev) 241 { 242 /* Create the function exposed under /dev/devices. */ 243 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 244 NAME); 245 if (fun == NULL) { 246 usb_log_error("Could not create DDF function node.\n"); 247 return ENOMEM; 248 } 249 250 /* 251 * Store the initialized HID device and HID ops 252 * to the DDF function. 253 */ 254 fun->ops = &lgtch_ultrax_ops; 255 fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data 256 257 int rc = ddf_fun_bind(fun); 258 if (rc != EOK) { 259 usb_log_error("Could not bind DDF function: %s.\n", 260 str_error(rc)); 261 // TODO: Can / should I destroy the DDF function? 262 ddf_fun_destroy(fun); 263 return rc; 264 } 265 266 rc = ddf_fun_add_to_class(fun, "keyboard"); 267 if (rc != EOK) { 268 usb_log_error( 269 "Could not add DDF function to class 'keyboard': %s.\n", 270 str_error(rc)); 271 // TODO: Can / should I destroy the DDF function? 272 ddf_fun_destroy(fun); 273 return rc; 274 } 275 276 return EOK; 277 } 278 279 /*----------------------------------------------------------------------------*/ 280 281 int usb_lgtch_init(struct usb_hid_dev *hid_dev) 282 { 283 if (hid_dev == NULL || hid_dev->usb_dev == NULL) { 284 return EINVAL; /*! @todo Other return code? */ 285 } 286 287 usb_log_debug(NAME " Initializing HID/lgtch_ultrax structure...\n"); 288 289 usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)malloc( 290 sizeof(usb_lgtch_ultrax_t)); 291 if (lgtch_dev == NULL) { 292 return ENOMEM; 293 } 294 295 lgtch_dev->console_phone = -1; 296 297 usb_hid_report_path_t *path = usb_hid_report_path(); 298 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0); 299 300 usb_hid_report_path_set_report_id(path, 1); 301 302 lgtch_dev->key_count = usb_hid_report_input_length( 303 hid_dev->report, path, 304 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY); 305 usb_hid_report_path_free(path); 306 307 usb_log_debug(NAME " Size of the input report: %zu\n", 308 lgtch_dev->key_count); 309 310 lgtch_dev->keys = (int32_t *)calloc(lgtch_dev->key_count, 311 sizeof(int32_t)); 312 313 if (lgtch_dev->keys == NULL) { 314 usb_log_fatal("No memory!\n"); 315 free(lgtch_dev); 316 return ENOMEM; 317 } 318 319 lgtch_dev->keys_old = 320 (int32_t *)calloc(lgtch_dev->key_count, sizeof(int32_t)); 321 322 if (lgtch_dev->keys_old == NULL) { 323 usb_log_fatal("No memory!\n"); 324 free(lgtch_dev->keys); 325 free(lgtch_dev); 326 return ENOMEM; 327 } 328 329 /*! @todo Autorepeat */ 330 331 // save the KBD device structure into the HID device structure 332 hid_dev->data = lgtch_dev; 333 334 lgtch_dev->initialized = USB_LGTCH_STATUS_INITIALIZED; 335 usb_log_debug(NAME " HID/lgtch_ultrax device structure initialized.\n"); 336 337 int rc = usb_lgtch_create_function(hid_dev); 338 if (rc != EOK) { 339 usb_lgtch_free(&lgtch_dev); 340 return rc; 341 } 342 343 usb_log_debug(NAME " HID/lgtch_ultrax structure initialized.\n"); 344 345 return EOK; 346 } 347 348 /*----------------------------------------------------------------------------*/ 349 350 void usb_lgtch_deinit(struct usb_hid_dev *hid_dev) 351 { 352 if (hid_dev == NULL) { 353 return; 354 } 355 356 if (hid_dev->data != NULL) { 357 usb_lgtch_ultrax_t *lgtch_dev = 358 (usb_lgtch_ultrax_t *)hid_dev->data; 359 // if (usb_kbd_is_initialized(kbd_dev)) { 360 // usb_kbd_mark_unusable(kbd_dev); 361 // } else { 362 usb_lgtch_free(&lgtch_dev); 363 hid_dev->data = NULL; 364 // } 365 } 66 366 } 67 367 … … 81 381 usb_hid_report_path_t *path = usb_hid_report_path(); 82 382 usb_hid_report_path_append_item(path, 0xc, 0); 83 usb_hid_report_path_set_report_id(path, 1); 84 85 int rc = usb_hid_parse_report(hid_dev->parser, buffer, 86 buffer_size, path, 87 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 88 &usb_lgtch_parser_callbacks, hid_dev); 383 384 uint8_t report_id; 385 386 int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 387 &report_id); 388 389 if (rc != EOK) { 390 usb_log_warning(NAME "Error in usb_hid_parse_report(): %s\n", 391 str_error(rc)); 392 return true; 393 } 394 395 usb_hid_report_path_set_report_id(path, report_id); 396 397 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 398 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END 399 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 400 USB_HID_REPORT_TYPE_INPUT); 401 402 unsigned int key; 403 404 /*! @todo Is this iterating OK if done multiple times? 405 * @todo The parsing is not OK 406 */ 407 while (field != NULL) { 408 usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n", field->value, 409 field->usage); 410 411 key = usb_lgtch_map_usage(field->usage); 412 usb_lgtch_push_ev(hid_dev, KEY_PRESS, key); 413 414 field = usb_hid_report_get_sibling( 415 hid_dev->report, field, path, USB_HID_PATH_COMPARE_END 416 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 417 USB_HID_REPORT_TYPE_INPUT); 418 } 89 419 90 420 usb_hid_report_path_free(path); 91 92 if (rc != EOK) {93 usb_log_warning("Error in usb_hid_boot_keyboard_input_report():"94 "%s\n", str_error(rc));95 }96 421 97 422 return true; -
uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.h
ra58dd620 r3d4aa055 40 40 41 41 struct usb_hid_dev; 42 //struct usb_hid_subdriver_mapping;43 42 44 43 /*----------------------------------------------------------------------------*/ 45 44 46 //extern struct usb_hid_subdriver_mapping usb_lgtch_mapping;45 int usb_lgtch_init(struct usb_hid_dev *hid_dev); 47 46 48 /*----------------------------------------------------------------------------*/ 49 50 //int usb_lgtch_init(struct usb_hid_dev *hid_dev); 47 void usb_lgtch_deinit(struct usb_hid_dev *hid_dev); 51 48 52 49 bool usb_lgtch_polling_callback(struct usb_hid_dev *hid_dev, uint8_t *buffer, -
uspace/drv/usbhid/main.c
ra58dd620 r3d4aa055 99 99 usb_log_debug("USB/HID device structure initialized.\n"); 100 100 101 /* Create the function exposed under /dev/devices. */102 ddf_fun_t *hid_fun = ddf_fun_create(dev->ddf_dev, fun_exposed,103 usb_hid_get_function_name(hid_dev));104 if (hid_fun == NULL) {105 usb_log_error("Could not create DDF function node.\n");106 usb_hid_free(&hid_dev);107 return ENOMEM;108 }109 110 101 /* 111 * Store the initialized HID device and HID ops 112 * to the DDF function. 113 */ 114 hid_fun->ops = &hid_dev->ops; 115 hid_fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data 116 117 rc = ddf_fun_bind(hid_fun); 118 if (rc != EOK) { 119 usb_log_error("Could not bind DDF function: %s.\n", 120 str_error(rc)); 121 // TODO: Can / should I destroy the DDF function? 122 ddf_fun_destroy(hid_fun); 123 usb_hid_free(&hid_dev); 124 return rc; 125 } 126 127 rc = ddf_fun_add_to_class(hid_fun, usb_hid_get_class_name(hid_dev)); 128 if (rc != EOK) { 129 usb_log_error( 130 "Could not add DDF function to class 'hid': %s.\n", 131 str_error(rc)); 132 // TODO: Can / should I destroy the DDF function? 133 ddf_fun_destroy(hid_fun); 134 usb_hid_free(&hid_dev); 135 return rc; 136 } 102 * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da 103 * do nej. 104 * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi 105 * vyplnenu strukturu usbhid_iface_t. 106 * 3) klientska aplikacia - musi si rucne vytvorit telefon 107 * (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az 108 * k tej fcii. 109 * pouzit usb/classes/hid/iface.h - prvy int je telefon 110 */ 137 111 138 112 /* Start automated polling function. -
uspace/drv/usbhid/mouse/mousedev.c
ra58dd620 r3d4aa055 39 39 #include <usb/classes/hid.h> 40 40 #include <usb/classes/hidreq.h> 41 #include <usb/classes/hidut.h> 41 42 #include <errno.h> 42 43 #include <str_error.h> … … 45 46 #include "mousedev.h" 46 47 #include "../usbhid.h" 48 49 #define NAME "mouse" 47 50 48 51 /*----------------------------------------------------------------------------*/ … … 62 65 /** Default idle rate for mouses. */ 63 66 static const uint8_t IDLE_RATE = 0; 67 static const size_t USB_MOUSE_BUTTON_COUNT = 3; 64 68 65 69 /*----------------------------------------------------------------------------*/ … … 170 174 /*----------------------------------------------------------------------------*/ 171 175 172 static bool usb_mouse_process_boot_report(usb_ mouse_t *mouse_dev,176 static bool usb_mouse_process_boot_report(usb_hid_dev_t *hid_dev, 173 177 uint8_t *buffer, size_t buffer_size) 174 178 { 179 usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data; 180 175 181 usb_log_debug2("got buffer: %s.\n", 176 182 usb_debug_str_buffer(buffer, buffer_size, 0)); 177 178 uint8_t butt = buffer[0]; 179 char str_buttons[4] = { 180 butt & 1 ? '#' : '.', 181 butt & 2 ? '#' : '.', 182 butt & 4 ? '#' : '.', 183 0 184 }; 185 186 int shift_x = ((int) buffer[1]) - 127; 187 int shift_y = ((int) buffer[2]) - 127; 188 int wheel = ((int) buffer[3]) - 127; 189 190 if (buffer[1] == 0) { 191 shift_x = 0; 192 } 193 if (buffer[2] == 0) { 194 shift_y = 0; 195 } 196 if (buffer[3] == 0) { 197 wheel = 0; 198 } 199 200 if (mouse_dev->console_phone >= 0) { 201 usb_log_debug("Console phone: %d\n", mouse_dev->console_phone); 202 if ((shift_x != 0) || (shift_y != 0)) { 203 /* FIXME: guessed for QEMU */ 183 184 if (mouse_dev->console_phone < 0) { 185 usb_log_error(NAME " No console phone.\n"); 186 return false; // ?? 187 } 188 189 /* 190 * parse the input report 191 */ 192 193 usb_log_debug(NAME " Calling usb_hid_parse_report() with " 194 "buffer %s\n", usb_debug_str_buffer(buffer, buffer_size, 0)); 195 196 uint8_t report_id; 197 198 int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 199 &report_id); 200 201 if (rc != EOK) { 202 usb_log_warning(NAME "Error in usb_hid_parse_report(): %s\n", 203 str_error(rc)); 204 return true; 205 } 206 207 /* 208 * X 209 */ 210 int shift_x = 0; 211 212 usb_hid_report_path_t *path = usb_hid_report_path(); 213 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP, 214 USB_HIDUT_USAGE_GENERIC_DESKTOP_X); 215 216 usb_hid_report_path_set_report_id(path, report_id); 217 218 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 219 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END, 220 USB_HID_REPORT_TYPE_INPUT); 221 222 if (field != NULL) { 223 usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value, 224 field->usage); 225 shift_x = field->value; 226 } 227 228 usb_hid_report_path_free(path); 229 230 /* 231 * Y 232 */ 233 int shift_y = 0; 234 235 path = usb_hid_report_path(); 236 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP, 237 USB_HIDUT_USAGE_GENERIC_DESKTOP_Y); 238 239 usb_hid_report_path_set_report_id(path, report_id); 240 241 field = usb_hid_report_get_sibling( 242 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END, 243 USB_HID_REPORT_TYPE_INPUT); 244 245 if (field != NULL) { 246 usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value, 247 field->usage); 248 shift_y = field->value; 249 } 250 251 usb_hid_report_path_free(path); 252 253 if ((shift_x != 0) || (shift_y != 0)) { 254 async_req_2_0(mouse_dev->console_phone, 255 MEVENT_MOVE, shift_x, shift_y); 256 } 257 258 /* 259 * Buttons 260 */ 261 path = usb_hid_report_path(); 262 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0); 263 usb_hid_report_path_set_report_id(path, report_id); 264 265 field = usb_hid_report_get_sibling( 266 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END 267 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 268 USB_HID_REPORT_TYPE_INPUT); 269 270 while (field != NULL) { 271 usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value, 272 field->usage); 273 274 if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0 275 && field->value != 0) { 204 276 async_req_2_0(mouse_dev->console_phone, 205 MEVENT_MOVE, 206 - shift_x / 10, - shift_y / 10); 207 } else { 208 usb_log_error("No move reported\n"); 209 } 210 if (butt) { 211 /* FIXME: proper button clicking. */ 212 async_req_2_0(mouse_dev->console_phone, 213 MEVENT_BUTTON, 1, 1); 214 async_req_2_0(mouse_dev->console_phone, 215 MEVENT_BUTTON, 1, 0); 216 } 217 } else { 218 usb_log_error("No console phone in mouse!!\n"); 219 } 220 221 usb_log_debug("buttons=%s dX=%+3d dY=%+3d wheel=%+3d\n", 222 str_buttons, shift_x, shift_y, wheel); 223 224 /* Guess. */ 225 //async_usleep(1000); 226 // no sleep right now 277 MEVENT_BUTTON, field->usage, 1); 278 mouse_dev->buttons[field->usage - field->usage_minimum] 279 = field->value; 280 } else if ( 281 mouse_dev->buttons[field->usage - field->usage_minimum] != 0 282 && field->value == 0) { 283 async_req_2_0(mouse_dev->console_phone, 284 MEVENT_BUTTON, field->usage, 0); 285 mouse_dev->buttons[field->usage - field->usage_minimum] 286 = field->value; 287 } 288 289 field = usb_hid_report_get_sibling( 290 hid_dev->report, field, path, USB_HID_PATH_COMPARE_END 291 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 292 USB_HID_REPORT_TYPE_INPUT); 293 } 294 295 usb_hid_report_path_free(path); 227 296 228 297 return true; 298 } 299 300 /*----------------------------------------------------------------------------*/ 301 302 static int usb_mouse_create_function(usb_hid_dev_t *hid_dev) 303 { 304 /* Create the function exposed under /dev/devices. */ 305 usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME); 306 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 307 HID_MOUSE_FUN_NAME); 308 if (fun == NULL) { 309 usb_log_error("Could not create DDF function node.\n"); 310 return ENOMEM; 311 } 312 313 /* 314 * Store the initialized HID device and HID ops 315 * to the DDF function. 316 */ 317 fun->ops = &hid_dev->ops; 318 fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data 319 320 int rc = ddf_fun_bind(fun); 321 if (rc != EOK) { 322 usb_log_error("Could not bind DDF function: %s.\n", 323 str_error(rc)); 324 ddf_fun_destroy(fun); 325 return rc; 326 } 327 328 usb_log_debug("Adding DDF function to class %s...\n", 329 HID_MOUSE_CLASS_NAME); 330 rc = ddf_fun_add_to_class(fun, HID_MOUSE_CLASS_NAME); 331 if (rc != EOK) { 332 usb_log_error( 333 "Could not add DDF function to class %s: %s.\n", 334 HID_MOUSE_CLASS_NAME, str_error(rc)); 335 ddf_fun_destroy(fun); 336 return rc; 337 } 338 339 return EOK; 229 340 } 230 341 … … 248 359 } 249 360 361 mouse_dev->buttons = (int32_t *)calloc(USB_MOUSE_BUTTON_COUNT, 362 sizeof(int32_t)); 363 364 if (mouse_dev->buttons == NULL) { 365 usb_log_fatal("No memory!\n"); 366 free(mouse_dev); 367 return ENOMEM; 368 } 369 250 370 // save the Mouse device structure into the HID device structure 251 371 hid_dev->data = mouse_dev; … … 255 375 256 376 // TODO: how to know if the device supports the request??? 257 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 258 hid_dev->usb_dev->interface_no, IDLE_RATE); 377 // usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 378 // hid_dev->usb_dev->interface_no, IDLE_RATE); 379 380 int rc = usb_mouse_create_function(hid_dev); 381 if (rc != EOK) { 382 usb_mouse_free(&mouse_dev); 383 return rc; 384 } 259 385 260 386 return EOK; … … 280 406 return false; 281 407 } 282 usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data; 283 284 return usb_mouse_process_boot_report(mouse_dev, buffer, buffer_size); 408 409 return usb_mouse_process_boot_report(hid_dev, buffer, buffer_size); 285 410 } 286 411 … … 296 421 int usb_mouse_set_boot_protocol(usb_hid_dev_t *hid_dev) 297 422 { 298 int rc = usb_hid_parse_report_descriptor(hid_dev-> parser,423 int rc = usb_hid_parse_report_descriptor(hid_dev->report, 299 424 USB_MOUSE_BOOT_REPORT_DESCRIPTOR, 300 425 USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE); -
uspace/drv/usbhid/mouse/mousedev.h
ra58dd620 r3d4aa055 49 49 /** IPC phone to console (consumer). */ 50 50 int console_phone; 51 52 int32_t *buttons; 51 53 } usb_mouse_t; 52 54 -
uspace/drv/usbhid/subdrivers.c
ra58dd620 r3d4aa055 55 55 USB_HID_PATH_COMPARE_END 56 56 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 57 0,58 0,57 -1, 58 -1, 59 59 { 60 60 .init = usb_kbd_init, … … 73 73 0xc30e, 74 74 { 75 .init = NULL,76 .deinit = NULL,75 .init = usb_lgtch_init, 76 .deinit = usb_lgtch_deinit, 77 77 .poll = usb_lgtch_polling_callback, 78 78 .poll_end = NULL 79 79 } 80 80 }, 81 {NULL, -1, 0, 0, 0, {NULL, NULL, NULL, NULL}}81 {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL}} 82 82 }; 83 83 -
uspace/drv/usbhid/subdrivers.h
ra58dd620 r3d4aa055 56 56 int report_id; 57 57 int compare; 58 uint16_t vendor_id;59 uint16_t product_id;58 int vendor_id; 59 int product_id; 60 60 usb_hid_subdriver_t subdriver; 61 61 } usb_hid_subdriver_mapping_t; -
uspace/drv/usbhid/usbhid.c
ra58dd620 r3d4aa055 136 136 137 137 // set the init callback 138 hid_dev->subdrivers[0].init = NULL;138 hid_dev->subdrivers[0].init = usb_generic_hid_init; 139 139 140 140 // set the polling callback … … 158 158 const usb_hid_subdriver_mapping_t *mapping) 159 159 { 160 return false; 160 assert(hid_dev != NULL); 161 assert(hid_dev->usb_dev != NULL); 162 163 return (hid_dev->usb_dev->descriptors.device.vendor_id 164 == mapping->vendor_id 165 && hid_dev->usb_dev->descriptors.device.product_id 166 == mapping->product_id); 161 167 } 162 168 … … 192 198 } 193 199 194 assert(hid_dev-> parser!= NULL);200 assert(hid_dev->report != NULL); 195 201 196 202 usb_log_debug("Compare flags: %d\n", mapping->compare); 197 size_t size = usb_hid_report_input_length(hid_dev-> parser, usage_path,203 size_t size = usb_hid_report_input_length(hid_dev->report, usage_path, 198 204 mapping->compare); 199 205 usb_log_debug("Size of the input report: %zuB\n", size); … … 251 257 while (count < USB_HID_MAX_SUBDRIVERS && 252 258 (mapping->usage_path != NULL 253 || mapping->vendor_id != 0 || mapping->product_id != 0)) {259 || mapping->vendor_id >= 0 || mapping->product_id >= 0)) { 254 260 // check the vendor & product ID 255 if (mapping->vendor_id != 0 && mapping->product_id ==0) {256 usb_log_warning("Missing Product ID for Vendor ID % u\n",261 if (mapping->vendor_id >= 0 && mapping->product_id < 0) { 262 usb_log_warning("Missing Product ID for Vendor ID %d\n", 257 263 mapping->vendor_id); 258 264 return EINVAL; 259 265 } 260 if (mapping->product_id != 0 && mapping->vendor_id ==0) {261 usb_log_warning("Missing Vendor ID for Product ID % u\n",266 if (mapping->product_id >= 0 && mapping->vendor_id < 0) { 267 usb_log_warning("Missing Vendor ID for Product ID %d\n", 262 268 mapping->product_id); 263 269 return EINVAL; … … 267 273 matched = false; 268 274 269 if (mapping->vendor_id != 0) {270 assert(mapping->product_id != 0);275 if (mapping->vendor_id >= 0) { 276 assert(mapping->product_id >= 0); 271 277 usb_log_debug("Comparing device against vendor ID %u" 272 278 " and product ID %u.\n", mapping->vendor_id, … … 341 347 } 342 348 343 hid_dev-> parser = (usb_hid_report_parser_t *)(malloc(sizeof(344 usb_hid_report_ parser_t)));345 if (hid_dev-> parser== NULL) {349 hid_dev->report = (usb_hid_report_t *)(malloc(sizeof( 350 usb_hid_report_t))); 351 if (hid_dev->report == NULL) { 346 352 usb_log_fatal("No memory!\n"); 347 353 free(hid_dev); … … 382 388 return rc; 383 389 } 384 385 /* Initialize the report parser. */ 386 rc = usb_hid_parser_init(hid_dev->parser); 387 if (rc != EOK) { 388 usb_log_error("Failed to initialize report parser.\n"); 389 //usb_hid_free(&hid_dev); 390 return rc; 391 } 392 390 393 391 /* Get the report descriptor and parse it. */ 394 392 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 395 hid_dev-> parser);393 hid_dev->report); 396 394 397 395 bool fallback = false; … … 492 490 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 493 491 492 int allocated = (hid_dev->input_report != NULL); 493 494 if (!allocated 495 || hid_dev->input_report_size < buffer_size) { 496 uint8_t *input_old = hid_dev->input_report; 497 uint8_t *input_new = (uint8_t *)malloc(buffer_size); 498 499 if (input_new == NULL) { 500 usb_log_error("Failed to allocate space for input " 501 "buffer. This event may not be reported\n"); 502 memset(hid_dev->input_report, 0, 503 hid_dev->input_report_size); 504 } else { 505 memcpy(input_new, input_old, 506 hid_dev->input_report_size); 507 hid_dev->input_report = input_new; 508 if (allocated) { 509 free(input_old); 510 } 511 } 512 } 513 514 /*! @todo This should probably be atomic. */ 515 memcpy(hid_dev->input_report, buffer, buffer_size); 516 hid_dev->input_report_size = buffer_size; 517 494 518 bool cont = false; 495 519 … … 530 554 /*----------------------------------------------------------------------------*/ 531 555 532 const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev)533 {534 switch (hid_dev->poll_pipe_index) {535 case USB_HID_KBD_POLL_EP_NO:536 return HID_KBD_FUN_NAME;537 break;538 case USB_HID_MOUSE_POLL_EP_NO:539 return HID_MOUSE_FUN_NAME;540 break;541 default:542 return HID_GENERIC_FUN_NAME;543 }544 }545 546 /*----------------------------------------------------------------------------*/ 547 548 const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev)549 {550 // this means that only boot protocol keyboards will be connected551 // to the console; there is probably no better way to do this552 553 switch (hid_dev->poll_pipe_index) {554 case USB_HID_KBD_POLL_EP_NO:555 return HID_KBD_CLASS_NAME;556 break;557 case USB_HID_MOUSE_POLL_EP_NO:558 return HID_MOUSE_CLASS_NAME;559 break;560 default:561 return HID_GENERIC_CLASS_NAME;562 }563 }556 //const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev) 557 //{ 558 // switch (hid_dev->poll_pipe_index) { 559 // case USB_HID_KBD_POLL_EP_NO: 560 // return HID_KBD_FUN_NAME; 561 // break; 562 // case USB_HID_MOUSE_POLL_EP_NO: 563 // return HID_MOUSE_FUN_NAME; 564 // break; 565 // default: 566 // return HID_GENERIC_FUN_NAME; 567 // } 568 //} 569 570 /*----------------------------------------------------------------------------*/ 571 572 //const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev) 573 //{ 574 // // this means that only boot protocol keyboards will be connected 575 // // to the console; there is probably no better way to do this 576 577 // switch (hid_dev->poll_pipe_index) { 578 // case USB_HID_KBD_POLL_EP_NO: 579 // return HID_KBD_CLASS_NAME; 580 // break; 581 // case USB_HID_MOUSE_POLL_EP_NO: 582 // return HID_MOUSE_CLASS_NAME; 583 // break; 584 // default: 585 // return HID_GENERIC_CLASS_NAME; 586 // } 587 //} 564 588 565 589 /*----------------------------------------------------------------------------*/ … … 591 615 592 616 // destroy the parser 593 if ((*hid_dev)-> parser!= NULL) {594 usb_hid_free_report _parser((*hid_dev)->parser);617 if ((*hid_dev)->report != NULL) { 618 usb_hid_free_report((*hid_dev)->report); 595 619 } 596 620 -
uspace/drv/usbhid/usbhid.h
ra58dd620 r3d4aa055 91 91 92 92 /** HID Report parser. */ 93 usb_hid_report_parser_t *parser; 93 usb_hid_report_t *report; 94 95 uint8_t *input_report; 96 97 size_t input_report_size; 94 98 95 99 /** Arbitrary data (e.g. a special structure for handling keyboard). */ … … 120 124 void *arg); 121 125 122 const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev);126 //const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev); 123 127 124 const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev);128 //const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev); 125 129 126 130 void usb_hid_free(usb_hid_dev_t **hid_dev);
Note:
See TracChangeset
for help on using the changeset viewer.
