Changeset f1fae414 in mainline for uspace/drv/bus/usb/usbhid
- Timestamp:
- 2011-06-22T01:34:53Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8d7e82c1, cac458f
- Parents:
- 72ec8cc (diff), bf172825 (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/bus/usb/usbhid
- Files:
-
- 25 moved
-
Makefile (moved) (moved from uspace/drv/usbhid/Makefile ) (4 diffs)
-
generic/hiddev.c (moved) (moved from uspace/drv/usbhid/generic/hiddev.c ) (1 diff)
-
generic/hiddev.h (moved) (moved from uspace/drv/usbhid/generic/hiddev.h ) (1 diff)
-
kbd.h (moved) (moved from uspace/drv/usbhid/kbd.h )
-
kbd/conv.c (moved) (moved from uspace/drv/usbhid/kbd/conv.c )
-
kbd/conv.h (moved) (moved from uspace/drv/usbhid/kbd/conv.h )
-
kbd/kbddev.c (moved) (moved from uspace/drv/usbhid/kbd/kbddev.c ) (24 diffs)
-
kbd/kbddev.h (moved) (moved from uspace/drv/usbhid/kbd/kbddev.h ) (2 diffs)
-
kbd/kbdrepeat.c (moved) (moved from uspace/drv/usbhid/kbd/kbdrepeat.c ) (2 diffs)
-
kbd/kbdrepeat.h (moved) (moved from uspace/drv/usbhid/kbd/kbdrepeat.h )
-
kbd/layout.h (moved) (moved from uspace/drv/usbhid/kbd/layout.h )
-
kbd/main.c (moved) (moved from uspace/drv/usbhid/kbd/main.c )
-
layout.h (moved) (moved from uspace/drv/usbhid/layout.h )
-
main.c (moved) (moved from uspace/drv/usbhid/main.c )
-
mouse/mousedev.c (moved) (moved from uspace/drv/usbhid/mouse/mousedev.c ) (7 diffs)
-
mouse/mousedev.h (moved) (moved from uspace/drv/usbhid/mouse/mousedev.h ) (1 diff)
-
multimedia/keymap.c (moved) (moved from uspace/drv/usbhid/multimedia/keymap.c )
-
multimedia/keymap.h (moved) (moved from uspace/drv/usbhid/multimedia/keymap.h )
-
multimedia/multimedia.c (moved) (moved from uspace/drv/usbhid/multimedia/multimedia.c ) (4 diffs)
-
multimedia/multimedia.h (moved) (moved from uspace/drv/usbhid/multimedia/multimedia.h ) (1 diff)
-
subdrivers.c (moved) (moved from uspace/drv/usbhid/subdrivers.c )
-
subdrivers.h (moved) (moved from uspace/drv/usbhid/subdrivers.h ) (1 diff)
-
usbhid.c (moved) (moved from uspace/drv/usbhid/usbhid.c ) (3 diffs)
-
usbhid.h (moved) (moved from uspace/drv/usbhid/usbhid.h ) (5 diffs)
-
usbhid.ma (moved) (moved from uspace/drv/usbhid/usbhid.ma )
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhid/Makefile
r72ec8cc rf1fae414 27 27 # 28 28 29 USPACE_PREFIX = ../.. 29 USPACE_PREFIX = ../../../.. 30 30 31 31 LIBS = \ … … 34 34 $(LIBUSB_PREFIX)/libusb.a \ 35 35 $(LIBDRV_PREFIX)/libdrv.a 36 36 37 EXTRA_CFLAGS += \ 37 38 -I. \ … … 43 44 BINARY = usbhid 44 45 45 STOLEN_LAYOUT_SOURCES = \ 46 kbd/layout/us_qwerty.c \ 47 kbd/layout/us_dvorak.c \ 48 kbd/layout/cz.c 46 SUBDRIVER_SOURCES = \ 47 kbd/conv.c \ 48 kbd/kbddev.c \ 49 kbd/kbdrepeat.c \ 50 mouse/mousedev.c \ 51 multimedia/multimedia.c \ 52 multimedia/keymap.c 49 53 50 54 SOURCES = \ … … 52 56 usbhid.c \ 53 57 subdrivers.c \ 54 kbd/conv.c \55 kbd/kbddev.c \56 kbd/kbdrepeat.c \57 58 generic/hiddev.c \ 58 mouse/mousedev.c \ 59 multimedia/multimedia.c \ 60 multimedia/keymap.c \ 61 $(STOLEN_LAYOUT_SOURCES) 62 63 EXTRA_CLEAN = $(STOLEN_LAYOUT_SOURCES) 64 65 SRV_KBD = $(USPACE_PREFIX)/srv/hid/kbd 59 $(SUBDRIVER_SOURCES) 66 60 67 61 include $(USPACE_PREFIX)/Makefile.common 68 69 kbd/layout/%.c: $(SRV_KBD)/layout/%.c70 ln -sfn ../../$< $@ -
uspace/drv/bus/usb/usbhid/generic/hiddev.c
r72ec8cc rf1fae414 231 231 /*----------------------------------------------------------------------------*/ 232 232 233 bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, void *data, 234 uint8_t *buffer, size_t buffer_size) 235 { 236 usb_log_debug2("usb_hid_polling_callback(%p, %p, %zu)\n", 237 hid_dev, buffer, buffer_size); 238 usb_debug_str_buffer(buffer, buffer_size, 0); 233 bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, void *data) 234 { 239 235 return true; 240 236 } -
uspace/drv/bus/usb/usbhid/generic/hiddev.h
r72ec8cc rf1fae414 50 50 int usb_generic_hid_init(struct usb_hid_dev *hid_dev, void **data); 51 51 52 bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, void *data, 53 uint8_t *buffer, size_t buffer_size); 52 bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, void *data); 54 53 55 54 #endif // USB_HID_HIDDDEV_H_ -
uspace/drv/bus/usb/usbhid/kbd/kbddev.c
r72ec8cc rf1fae414 40 40 41 41 #include <io/keycode.h> 42 #include <ipc/kbd.h> 42 #include <io/console.h> 43 #include <ipc/kbdev.h> 43 44 #include <async.h> 44 45 #include <async_obsolete.h> 45 46 #include <fibril.h> 46 47 #include <fibril_synch.h> 48 49 #include <ddf/log.h> 47 50 48 51 #include <usb/usb.h> … … 63 66 #include "kbddev.h" 64 67 65 #include "layout.h"66 68 #include "conv.h" 67 69 #include "kbdrepeat.h" … … 73 75 74 76 /*----------------------------------------------------------------------------*/ 75 /** Default modifiers when the keyboard is initialized. */ 77 76 78 static const unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK; 77 79 … … 101 103 const char *HID_KBD_FUN_NAME = "keyboard"; 102 104 const char *HID_KBD_CLASS_NAME = "keyboard"; 105 106 static void usb_kbd_set_led(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev); 103 107 104 108 /*----------------------------------------------------------------------------*/ … … 154 158 155 159 /*----------------------------------------------------------------------------*/ 156 /* Keyboard layouts */157 /*----------------------------------------------------------------------------*/158 159 #define NUM_LAYOUTS 3160 161 /** Keyboard layout map. */162 static layout_op_t *layout[NUM_LAYOUTS] = {163 &us_qwerty_op,164 &us_dvorak_op,165 &cz_op166 };167 168 static int active_layout = 0;169 170 /*----------------------------------------------------------------------------*/171 160 /* IPC method handler */ 172 161 /*----------------------------------------------------------------------------*/ … … 174 163 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 175 164 176 /** 165 /** 177 166 * Default handler for IPC methods not handled by DDF. 178 167 * … … 189 178 { 190 179 sysarg_t method = IPC_GET_IMETHOD(*icall); 180 int callback; 191 181 192 182 usb_kbd_t *kbd_dev = (usb_kbd_t *)fun->driver_data; … … 198 188 } 199 189 200 if (method == IPC_M_CONNECT_TO_ME) { 201 int callback = IPC_GET_ARG5(*icall); 190 switch (method) { 191 case IPC_M_CONNECT_TO_ME: 192 callback = IPC_GET_ARG5(*icall); 202 193 203 194 if (kbd_dev->console_phone != -1) { … … 212 203 usb_log_debug("default_connection_handler: OK\n"); 213 204 async_answer_0(icallid, EOK); 214 return; 215 } 216 217 usb_log_debug("default_connection_handler: Wrong function.\n"); 218 async_answer_0(icallid, EINVAL); 205 break; 206 case KBDEV_SET_IND: 207 kbd_dev->mods = IPC_GET_ARG1(*icall); 208 usb_kbd_set_led(kbd_dev->hid_dev, kbd_dev); 209 async_answer_0(icallid, EOK); 210 break; 211 default: 212 usb_log_debug("default_connection_handler: Wrong function.\n"); 213 async_answer_0(icallid, EINVAL); 214 break; 215 } 219 216 } 220 217 … … 225 222 * Handles turning of LED lights on and off. 226 223 * 227 * In case of USB keyboards, the LEDs are handled in the driver, not in the 228 * device. When there should be a change (lock key was pressed), the driver 229 * uses a Set_Report request sent to the device to set the state of the LEDs. 224 * As with most other keyboards, the LED indicators in USB keyboards are 225 * driven by software. When state of some modifier changes, the input server 226 * will call us and tell us to update the LED state and what the new state 227 * should be. 230 228 * 231 229 * This functions sets the LED lights according to current settings of modifiers … … 249 247 USB_HID_REPORT_TYPE_OUTPUT); 250 248 251 while (field != NULL) { 249 while (field != NULL) { 252 250 253 251 if ((field->usage == USB_HID_LED_NUM_LOCK) … … 292 290 293 291 /*----------------------------------------------------------------------------*/ 294 /** 295 * Processes key events. 296 * 297 * @note This function was copied from AT keyboard driver and modified to suit 298 * USB keyboard. 299 * 300 * @note Lock keys are not sent to the console, as they are completely handled 301 * in the driver. It may, however, be required later that the driver 302 * sends also these keys to application (otherwise it cannot use those 303 * keys at all). 304 * 292 /** Send key event. 293 * 305 294 * @param kbd_dev Keyboard device structure. 306 * @param type Type of the event (press / release). Recognized values: 295 * @param type Type of the event (press / release). Recognized values: 307 296 * KEY_PRESS, KEY_RELEASE 308 * @param key Key code of the key according to HID Usage Tables.297 * @param key Key code 309 298 */ 310 299 void usb_kbd_push_ev(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev, int type, 311 300 unsigned int key) 312 301 { 313 kbd_event_t ev; 314 unsigned mod_mask; 315 316 /* 317 * These parts are copy-pasted from the AT keyboard driver. 318 * 319 * They definitely require some refactoring, but will keep it for later 320 * when the console and keyboard system is changed in HelenOS. 321 */ 322 switch (key) { 323 case KC_LCTRL: mod_mask = KM_LCTRL; break; 324 case KC_RCTRL: mod_mask = KM_RCTRL; break; 325 case KC_LSHIFT: mod_mask = KM_LSHIFT; break; 326 case KC_RSHIFT: mod_mask = KM_RSHIFT; break; 327 case KC_LALT: mod_mask = KM_LALT; break; 328 case KC_RALT: mod_mask = KM_RALT; break; 329 default: mod_mask = 0; break; 330 } 331 332 if (mod_mask != 0) { 333 if (type == KEY_PRESS) 334 kbd_dev->mods = kbd_dev->mods | mod_mask; 335 else 336 kbd_dev->mods = kbd_dev->mods & ~mod_mask; 337 } 338 339 switch (key) { 340 case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break; 341 case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break; 342 case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break; 343 default: mod_mask = 0; break; 344 } 345 346 if (mod_mask != 0) { 347 if (type == KEY_PRESS) { 348 /* 349 * Only change lock state on transition from released 350 * to pressed. This prevents autorepeat from messing 351 * up the lock state. 352 */ 353 unsigned int locks_old = kbd_dev->lock_keys; 354 355 kbd_dev->mods = 356 kbd_dev->mods ^ (mod_mask & ~kbd_dev->lock_keys); 357 kbd_dev->lock_keys = kbd_dev->lock_keys | mod_mask; 358 359 /* Update keyboard lock indicator lights. */ 360 if (kbd_dev->lock_keys != locks_old 361 && hid_dev != NULL) { // ugly hack 362 usb_kbd_set_led(hid_dev, kbd_dev); 363 } 364 } else { 365 kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask; 366 } 367 } 368 369 if (key == KC_CAPS_LOCK || key == KC_NUM_LOCK || key == KC_SCROLL_LOCK) { 370 // do not send anything to the console, this is our business 371 return; 372 } 373 374 if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F1) { 375 active_layout = 0; 376 layout[active_layout]->reset(); 377 return; 378 } 379 380 if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F2) { 381 active_layout = 1; 382 layout[active_layout]->reset(); 383 return; 384 } 385 386 if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F3) { 387 active_layout = 2; 388 layout[active_layout]->reset(); 389 return; 390 } 391 392 ev.type = type; 393 ev.key = key; 394 ev.mods = kbd_dev->mods; 395 396 ev.c = layout[active_layout]->parse_ev(&ev); 397 398 usb_log_debug2("Sending key %d to the console\n", ev.key); 302 usb_log_debug2("Sending kbdev event %d/%d to the console\n", type, key); 399 303 if (kbd_dev->console_phone < 0) { 400 304 usb_log_warning( … … 403 307 } 404 308 405 async_obsolete_msg_4(kbd_dev->console_phone, KBD_EVENT, ev.type, ev.key, 406 ev.mods, ev.c); 309 async_obsolete_msg_2(kbd_dev->console_phone, KBDEV_EVENT, type, key); 407 310 } 408 311 … … 414 317 || key_code == KC_SCROLL_LOCK 415 318 || key_code == KC_CAPS_LOCK); 319 } 320 321 static size_t find_in_array_int32(int32_t val, int32_t *arr, size_t arr_size) 322 { 323 for (size_t i = 0; i < arr_size; i++) { 324 if (arr[i] == val) { 325 return i; 326 } 327 } 328 329 return (size_t) -1; 416 330 } 417 331 … … 436 350 { 437 351 unsigned int key; 438 unsigned int i, j;352 size_t i; 439 353 440 354 /* … … 446 360 * whole input report. 447 361 */ 448 i = 0; 449 while (i < kbd_dev->key_count && kbd_dev->keys[i] != ERROR_ROLLOVER) { 450 ++i; 451 } 452 if (i != kbd_dev->key_count) { 453 usb_log_debug("Phantom state occured.\n"); 454 // phantom state, do nothing 362 i = find_in_array_int32(ERROR_ROLLOVER, kbd_dev->keys, 363 kbd_dev->key_count); 364 if (i != (size_t) -1) { 365 usb_log_debug("Detected phantom state.\n"); 455 366 return; 456 367 } 457 368 458 369 /* 459 * 1) Key releases 460 */ 461 for (j = 0; j < kbd_dev->key_count; ++j) { 462 // try to find the old key in the new key list 463 i = 0; 464 while (i < kbd_dev->key_count 465 && kbd_dev->keys[i] != kbd_dev->keys_old[j]) { 466 ++i; 467 } 468 469 if (i == kbd_dev->key_count) { 470 // not found, i.e. the key was released 471 key = usbhid_parse_scancode(kbd_dev->keys_old[j]); 370 * Key releases 371 */ 372 for (i = 0; i < kbd_dev->key_count; i++) { 373 int32_t old_key = kbd_dev->keys_old[i]; 374 /* Find the old key among currently pressed keys. */ 375 size_t pos = find_in_array_int32(old_key, kbd_dev->keys, 376 kbd_dev->key_count); 377 /* If the key was not found, we need to signal release. */ 378 if (pos == (size_t) -1) { 379 key = usbhid_parse_scancode(old_key); 472 380 if (!usb_kbd_is_lock(key)) { 473 381 usb_kbd_repeat_stop(kbd_dev, key); 474 382 } 475 383 usb_kbd_push_ev(hid_dev, kbd_dev, KEY_RELEASE, key); 476 usb_log_debug2("Key released: %d\n", key); 477 } else { 478 // found, nothing happens 479 } 480 } 481 482 /* 483 * 1) Key presses 384 usb_log_debug2("Key released: %u " 385 "(USB code %" PRIu32 ")\n", key, old_key); 386 } 387 } 388 389 /* 390 * Key presses 484 391 */ 485 392 for (i = 0; i < kbd_dev->key_count; ++i) { 486 // try to find the new key in the old key list 487 j = 0; 488 while (j < kbd_dev->key_count 489 && kbd_dev->keys_old[j] != kbd_dev->keys[i]) { 490 ++j; 491 } 492 493 if (j == kbd_dev->key_count) { 494 // not found, i.e. new key pressed 393 int32_t new_key = kbd_dev->keys[i]; 394 /* Find the new key among already pressed keys. */ 395 size_t pos = find_in_array_int32(new_key, kbd_dev->keys_old, 396 kbd_dev->key_count); 397 /* If the key was not found, we need to signal press. */ 398 if (pos == (size_t) -1) { 495 399 key = usbhid_parse_scancode(kbd_dev->keys[i]); 496 usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,497 kbd_dev->keys[i]);498 400 if (!usb_kbd_is_lock(key)) { 499 401 usb_kbd_repeat_start(kbd_dev, key); 500 402 } 501 403 usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, key); 502 } else {503 // found, nothing happens404 usb_log_debug2("Key pressed: %u " 405 "(USB code %" PRIu32 ")\n", key, new_key); 504 406 } 505 407 } … … 507 409 memcpy(kbd_dev->keys_old, kbd_dev->keys, kbd_dev->key_count * 4); 508 410 509 usb_log_debug2("New stored keys: "); 510 for (i = 0; i < kbd_dev->key_count; ++i) { 511 usb_log_debug2("%d ", kbd_dev->keys_old[i]); 512 } 513 usb_log_debug2("\n"); 411 char key_buffer[512]; 412 ddf_dump_buffer(key_buffer, 512, 413 kbd_dev->keys_old, 4, kbd_dev->key_count, 0); 414 usb_log_debug2("Stored keys %s.\n", key_buffer); 514 415 } 515 416 … … 533 434 * usb_hid_parse_report(). 534 435 */ 535 static void usb_kbd_process_data(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev, 536 uint8_t *buffer, size_t actual_size) 436 static void usb_kbd_process_data(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev) 537 437 { 538 438 assert(hid_dev->report != NULL); 539 439 assert(hid_dev != NULL); 540 440 assert(kbd_dev != NULL); 541 542 usb_log_debug("Calling usb_hid_parse_report() with "543 "buffer %s\n", usb_debug_str_buffer(buffer, actual_size, 0));544 441 545 442 usb_hid_report_path_t *path = usb_hid_report_path(); 546 443 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 547 444 548 uint8_t report_id; 549 int rc = usb_hid_parse_report(hid_dev->report, buffer, actual_size, 550 &report_id); 551 552 if (rc != EOK) { 553 usb_log_warning("Error in usb_hid_parse_report():" 554 "%s\n", str_error(rc)); 555 } 556 557 usb_hid_report_path_set_report_id (path, report_id); 445 usb_hid_report_path_set_report_id (path, hid_dev->report_id); 558 446 559 447 // fill in the currently pressed keys … … 716 604 return ENOMEM; // TODO: some other code?? 717 605 } 606 607 /* Store link to HID device */ 608 kbd_dev->hid_dev = hid_dev; 718 609 719 610 /* … … 787 678 /* 788 679 * Modifiers and locks 789 */ 680 */ 790 681 kbd_dev->modifiers = 0; 791 682 kbd_dev->mods = DEFAULT_ACTIVE_MODS; … … 794 685 /* 795 686 * Autorepeat 796 */ 687 */ 797 688 kbd_dev->repeat.key_new = 0; 798 689 kbd_dev->repeat.key_repeated = 0; … … 852 743 /*----------------------------------------------------------------------------*/ 853 744 854 bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, void *data, 855 uint8_t *buffer, size_t buffer_size) 856 { 857 if (hid_dev == NULL || buffer == NULL || data == NULL) { 745 bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, void *data) 746 { 747 if (hid_dev == NULL/* || buffer == NULL*/ || data == NULL) { 858 748 // do not continue polling (???) 859 749 return false; … … 864 754 865 755 // TODO: add return value from this function 866 usb_kbd_process_data(hid_dev, kbd_dev , buffer, buffer_size);756 usb_kbd_process_data(hid_dev, kbd_dev); 867 757 868 758 return true; … … 900 790 if ((*kbd_dev)->repeat_mtx != NULL) { 901 791 //assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx)); 792 // FIXME - the fibril_mutex_is_locked may not cause 793 // fibril scheduling 902 794 while (fibril_mutex_is_locked((*kbd_dev)->repeat_mtx)) {} 903 795 free((*kbd_dev)->repeat_mtx); -
uspace/drv/bus/usb/usbhid/kbd/kbddev.h
r72ec8cc rf1fae414 65 65 */ 66 66 typedef struct usb_kbd_t { 67 /** Link to HID device structure */ 68 struct usb_hid_dev *hid_dev; 69 67 70 /** Previously pressed keys (not translated to key codes). */ 68 71 int32_t *keys_old; … … 122 125 int usb_kbd_init(struct usb_hid_dev *hid_dev, void **data); 123 126 124 bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, void *data, 125 uint8_t *buffer, size_t buffer_size); 127 bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, void *data); 126 128 127 129 int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev); -
uspace/drv/bus/usb/usbhid/kbd/kbdrepeat.c
r72ec8cc rf1fae414 97 97 delay = kbd->repeat.delay_between; 98 98 } else { 99 usb_log_debug ("New key to repeat: %u.\n",99 usb_log_debug2("New key to repeat: %u.\n", 100 100 kbd->repeat.key_new); 101 101 kbd->repeat.key_repeated = kbd->repeat.key_new; … … 104 104 } else { 105 105 if (kbd->repeat.key_repeated > 0) { 106 usb_log_debug ("Stopping to repeat key: %u.\n",106 usb_log_debug2("Stopping to repeat key: %u.\n", 107 107 kbd->repeat.key_repeated); 108 108 kbd->repeat.key_repeated = 0; -
uspace/drv/bus/usb/usbhid/mouse/mousedev.c
r72ec8cc rf1fae414 44 44 #include <async_obsolete.h> 45 45 #include <str_error.h> 46 #include <ipc/mouse .h>46 #include <ipc/mouseev.h> 47 47 #include <io/console.h> 48 48 49 #include <ipc/kbd .h>49 #include <ipc/kbdev.h> 50 50 #include <io/keycode.h> 51 51 52 52 #include "mousedev.h" 53 53 #include "../usbhid.h" 54 55 /** Number of simulated arrow-key presses for singel wheel step. */ 56 #define ARROWS_PER_SINGLE_WHEEL 3 54 57 55 58 // FIXME: remove this header … … 201 204 static void usb_mouse_send_wheel(const usb_mouse_t *mouse_dev, int wheel) 202 205 { 203 kbd_event_t ev; 204 205 ev.type = KEY_PRESS; 206 ev.key = (wheel > 0) ? KC_UP : (wheel < 0) ? KC_DOWN : 0; 207 ev.mods = 0; 208 ev.c = 0; 206 unsigned int key = (wheel > 0) ? KC_UP : KC_DOWN; 209 207 210 208 if (mouse_dev->wheel_phone < 0) { 211 209 usb_log_warning( 212 "Connection to console not ready, keydiscarded.\n");210 "Connection to console not ready, wheel roll discarded.\n"); 213 211 return; 214 212 } 215 213 216 int count = ( wheel < 0) ? -wheel : wheel;214 int count = ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL; 217 215 int i; 218 216 219 for (i = 0; i < count * 3; ++i) { 220 usb_log_debug2("Sending key %d to the console\n", ev.key); 221 async_obsolete_msg_4(mouse_dev->wheel_phone, KBD_EVENT, ev.type, 222 ev.key, ev.mods, ev.c); 223 // send key release right away 224 async_obsolete_msg_4(mouse_dev->wheel_phone, KBD_EVENT, KEY_RELEASE, 225 ev.key, ev.mods, ev.c); 226 } 227 } 228 229 /*----------------------------------------------------------------------------*/ 230 231 static bool usb_mouse_process_report(usb_hid_dev_t *hid_dev, 232 usb_mouse_t *mouse_dev, uint8_t *buffer, 233 size_t buffer_size) 217 for (i = 0; i < count; i++) { 218 /* Send arrow press and release. */ 219 usb_log_debug2("Sending key %d to the console\n", key); 220 async_obsolete_msg_4(mouse_dev->wheel_phone, KBDEV_EVENT, 221 KEY_PRESS, key, 0, 0); 222 async_obsolete_msg_4(mouse_dev->wheel_phone, KBDEV_EVENT, 223 KEY_RELEASE, key, 0, 0); 224 } 225 } 226 227 /*----------------------------------------------------------------------------*/ 228 229 static int get_mouse_axis_move_value(uint8_t rid, usb_hid_report_t *report, 230 int32_t usage) 231 { 232 int result = 0; 233 234 usb_hid_report_path_t *path = usb_hid_report_path(); 235 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP, 236 usage); 237 238 usb_hid_report_path_set_report_id(path, rid); 239 240 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 241 report, NULL, path, USB_HID_PATH_COMPARE_END, 242 USB_HID_REPORT_TYPE_INPUT); 243 244 if (field != NULL) { 245 result = field->value; 246 } 247 248 usb_hid_report_path_free(path); 249 250 return result; 251 } 252 253 static bool usb_mouse_process_report(usb_hid_dev_t *hid_dev, 254 usb_mouse_t *mouse_dev) 234 255 { 235 256 assert(mouse_dev != NULL); 236 237 usb_log_debug2("got buffer: %s.\n",238 usb_debug_str_buffer(buffer, buffer_size, 0));239 257 240 258 if (mouse_dev->mouse_phone < 0) { … … 243 261 } 244 262 245 /* 246 * parse the input report 247 */ 248 249 usb_log_debug(NAME " Calling usb_hid_parse_report() with " 250 "buffer %s\n", usb_debug_str_buffer(buffer, buffer_size, 0)); 251 252 uint8_t report_id; 253 254 int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 255 &report_id); 256 257 if (rc != EOK) { 258 usb_log_warning(NAME "Error in usb_hid_parse_report(): %s\n", 259 str_error(rc)); 260 return true; 261 } 262 263 /* 264 * X 265 */ 266 int shift_x = 0; 267 268 usb_hid_report_path_t *path = usb_hid_report_path(); 269 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP, 270 USB_HIDUT_USAGE_GENERIC_DESKTOP_X); 271 272 usb_hid_report_path_set_report_id(path, report_id); 273 274 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 275 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END, 276 USB_HID_REPORT_TYPE_INPUT); 277 278 if (field != NULL) { 279 usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value, 280 field->usage); 281 shift_x = field->value; 282 } 283 284 usb_hid_report_path_free(path); 285 286 /* 287 * Y 288 */ 289 int shift_y = 0; 290 291 path = usb_hid_report_path(); 292 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP, 293 USB_HIDUT_USAGE_GENERIC_DESKTOP_Y); 294 295 usb_hid_report_path_set_report_id(path, report_id); 296 297 field = usb_hid_report_get_sibling( 298 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END, 299 USB_HID_REPORT_TYPE_INPUT); 300 301 if (field != NULL) { 302 usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value, 303 field->usage); 304 shift_y = field->value; 305 } 306 307 usb_hid_report_path_free(path); 308 263 int shift_x = get_mouse_axis_move_value(hid_dev->report_id, 264 hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_X); 265 int shift_y = get_mouse_axis_move_value(hid_dev->report_id, 266 hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_Y); 267 int wheel = get_mouse_axis_move_value(hid_dev->report_id, 268 hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL); 269 309 270 if ((shift_x != 0) || (shift_y != 0)) { 310 271 async_obsolete_req_2_0(mouse_dev->mouse_phone, 311 MEVENT_MOVE, shift_x, shift_y); 312 } 313 314 /* 315 * Wheel 316 */ 317 int wheel = 0; 318 319 path = usb_hid_report_path(); 320 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP, 321 USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL); 322 323 usb_hid_report_path_set_report_id(path, report_id); 324 325 field = usb_hid_report_get_sibling( 326 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END, 327 USB_HID_REPORT_TYPE_INPUT); 328 329 if (field != NULL) { 330 usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value, 331 field->usage); 332 wheel = field->value; 333 } 334 335 usb_hid_report_path_free(path); 336 337 // send arrow up for positive direction and arrow down for negative 338 // direction; three arrows for difference of 1 339 usb_mouse_send_wheel(mouse_dev, wheel); 340 272 MOUSEEV_MOVE_EVENT, shift_x, shift_y); 273 } 274 275 if (wheel != 0) { 276 usb_mouse_send_wheel(mouse_dev, wheel); 277 } 341 278 342 279 /* 343 280 * Buttons 344 281 */ 345 path = usb_hid_report_path();282 usb_hid_report_path_t *path = usb_hid_report_path(); 346 283 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0); 347 usb_hid_report_path_set_report_id(path, report_id);348 349 field = usb_hid_report_get_sibling(284 usb_hid_report_path_set_report_id(path, hid_dev->report_id); 285 286 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 350 287 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END 351 288 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, … … 353 290 354 291 while (field != NULL) { 355 usb_log_debug (NAME " VALUE(%X) USAGE(%X)\n", field->value,292 usb_log_debug2(NAME " VALUE(%X) USAGE(%X)\n", field->value, 356 293 field->usage); 357 294 … … 359 296 && field->value != 0) { 360 297 async_obsolete_req_2_0(mouse_dev->mouse_phone, 361 M EVENT_BUTTON, field->usage, 1);298 MOUSEEV_BUTTON_EVENT, field->usage, 1); 362 299 mouse_dev->buttons[field->usage - field->usage_minimum] 363 300 = field->value; 364 } else if ( 365 mouse_dev->buttons[field->usage - field->usage_minimum] != 0 301 } else if (mouse_dev->buttons[field->usage - field->usage_minimum] != 0 366 302 && field->value == 0) { 367 async_obsolete_req_2_0(mouse_dev->mouse_phone,368 M EVENT_BUTTON, field->usage, 0);369 mouse_dev->buttons[field->usage - field->usage_minimum]370 =field->value;371 }303 async_obsolete_req_2_0(mouse_dev->mouse_phone, 304 MOUSEEV_BUTTON_EVENT, field->usage, 0); 305 mouse_dev->buttons[field->usage - field->usage_minimum] = 306 field->value; 307 } 372 308 373 309 field = usb_hid_report_get_sibling( … … 510 446 /*----------------------------------------------------------------------------*/ 511 447 512 bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, void *data, 513 uint8_t *buffer, size_t buffer_size) 514 { 515 usb_log_debug("usb_mouse_polling_callback()\n"); 516 usb_debug_str_buffer(buffer, buffer_size, 0); 517 448 bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, void *data) 449 { 518 450 if (hid_dev == NULL || data == NULL) { 519 451 usb_log_error("Missing argument to the mouse polling callback." … … 524 456 usb_mouse_t *mouse_dev = (usb_mouse_t *)data; 525 457 526 return usb_mouse_process_report(hid_dev, mouse_dev, buffer, 527 buffer_size); 458 return usb_mouse_process_report(hid_dev, mouse_dev); 528 459 } 529 460 -
uspace/drv/bus/usb/usbhid/mouse/mousedev.h
r72ec8cc rf1fae414 65 65 int usb_mouse_init(struct usb_hid_dev *hid_dev, void **data); 66 66 67 bool usb_mouse_polling_callback(struct usb_hid_dev *hid_dev, void *data, 68 uint8_t *buffer, size_t buffer_size); 67 bool usb_mouse_polling_callback(struct usb_hid_dev *hid_dev, void *data); 69 68 70 69 void usb_mouse_deinit(struct usb_hid_dev *hid_dev, void *data); -
uspace/drv/bus/usb/usbhid/multimedia/multimedia.c
r72ec8cc rf1fae414 50 50 #include <str_error.h> 51 51 52 #include <ipc/kbd .h>52 #include <ipc/kbdev.h> 53 53 #include <io/console.h> 54 54 … … 94 94 95 95 usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data; 96 //usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;97 96 98 97 if (multim_dev == NULL) { … … 162 161 } 163 162 164 async_obsolete_msg_4(multim_dev->console_phone, KBD _EVENT, ev.type, ev.key,163 async_obsolete_msg_4(multim_dev->console_phone, KBDEV_EVENT, ev.type, ev.key, 165 164 ev.mods, ev.c); 166 165 } … … 274 273 /*----------------------------------------------------------------------------*/ 275 274 276 bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data, 277 uint8_t *buffer, size_t buffer_size) 275 bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data) 278 276 { 279 277 // TODO: checks 280 if (hid_dev == NULL || data == NULL || buffer == NULL) {278 if (hid_dev == NULL || data == NULL) { 281 279 return false; 282 280 } 283 284 usb_log_debug(NAME " usb_lgtch_polling_callback(%p, %p, %zu)\n", 285 hid_dev, buffer, buffer_size); 286 281 287 282 usb_multimedia_t *multim_dev = (usb_multimedia_t *)data; 288 289 usb_log_debug(NAME " Calling usb_hid_parse_report() with "290 "buffer %s\n", usb_debug_str_buffer(buffer, buffer_size, 0));291 283 292 284 usb_hid_report_path_t *path = usb_hid_report_path(); 293 285 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0); 294 286 295 uint8_t report_id; 296 297 int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 298 &report_id); 299 300 if (rc != EOK) { 301 usb_log_warning(NAME "Error in usb_hid_parse_report(): %s\n", 302 str_error(rc)); 303 return true; 304 } 305 306 usb_hid_report_path_set_report_id(path, report_id); 287 usb_hid_report_path_set_report_id(path, hid_dev->report_id); 307 288 308 289 usb_hid_report_field_t *field = usb_hid_report_get_sibling( -
uspace/drv/bus/usb/usbhid/multimedia/multimedia.h
r72ec8cc rf1fae414 47 47 void usb_multimedia_deinit(struct usb_hid_dev *hid_dev, void *data); 48 48 49 bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data, 50 uint8_t *buffer, size_t buffer_size); 49 bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data); 51 50 52 51 /*----------------------------------------------------------------------------*/ -
uspace/drv/bus/usb/usbhid/subdrivers.h
r72ec8cc rf1fae414 49 49 /*----------------------------------------------------------------------------*/ 50 50 51 /* TODO: This mapping must contain some other information to get the proper 52 * interface. 51 /** Structure representing the mapping between device requirements and the 52 * subdriver supposed to handle this device. 53 * 54 * By filling in this structure and adding it to the usb_hid_subdrivers array, 55 * a new subdriver mapping will be created and used by the HID driver when it 56 * searches for appropriate subdrivers for a device. 53 57 */ 54 58 typedef struct usb_hid_subdriver_mapping { 59 /** Usage path that the device's Input reports must contain. 60 * 61 * It is an array of pairs <usage_page, usage>, terminated by a <0, 0> 62 * pair. If you do not wish to specify the device in this way, set this 63 * to NULL. 64 */ 55 65 const usb_hid_subdriver_usage_t *usage_path; 66 67 /** Report ID for which the path should apply. */ 56 68 int report_id; 69 70 /** Compare type for the Usage path. */ 57 71 int compare; 72 73 /** Vendor ID (set to -1 if not specified). */ 58 74 int vendor_id; 75 76 /** Product ID (set to -1 if not specified). */ 59 77 int product_id; 78 79 /** Subdriver for controlling this device. */ 60 80 usb_hid_subdriver_t subdriver; 61 81 } usb_hid_subdriver_mapping_t; -
uspace/drv/bus/usb/usbhid/usbhid.c
r72ec8cc rf1fae414 572 572 573 573 assert(hid_dev->input_report != NULL); 574 usb_log_debug("Max input report size: %zu, buffer size: %zu\n", 575 hid_dev->max_input_report_size, buffer_size); 574 usb_log_debug("New data [%zu/%zu]: %s\n", buffer_size, 575 hid_dev->max_input_report_size, 576 usb_debug_str_buffer(buffer, buffer_size, 0)); 576 577 577 578 if (hid_dev->max_input_report_size >= buffer_size) { … … 582 583 } 583 584 585 // parse the input report 586 587 int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 588 &hid_dev->report_id); 589 590 if (rc != EOK) { 591 usb_log_warning("Error in usb_hid_parse_report():" 592 "%s\n", str_error(rc)); 593 } 594 584 595 bool cont = false; 585 596 … … 588 599 if (hid_dev->subdrivers[i].poll != NULL 589 600 && hid_dev->subdrivers[i].poll(hid_dev, 590 hid_dev->subdrivers[i].data , buffer, buffer_size)) {601 hid_dev->subdrivers[i].data)) { 591 602 cont = true; 592 603 } -
uspace/drv/bus/usb/usbhid/usbhid.h
r72ec8cc rf1fae414 46 46 #include <bool.h> 47 47 48 struct usb_hid_dev; 48 typedef struct usb_hid_dev usb_hid_dev_t; 49 typedef struct usb_hid_subdriver usb_hid_subdriver_t; 49 50 50 typedef int (*usb_hid_driver_init_t)(struct usb_hid_dev *, void **data); 51 typedef void (*usb_hid_driver_deinit_t)(struct usb_hid_dev *, void *data); 52 typedef bool (*usb_hid_driver_poll)(struct usb_hid_dev *, void *data, uint8_t *, 53 size_t); 54 typedef int (*usb_hid_driver_poll_ended)(struct usb_hid_dev *, void *data, 55 bool reason); 51 /** Subdriver initialization callback. 52 * 53 * @param dev Backing USB HID device. 54 * @param data Custom subdriver data (pointer where to store them). 55 * @return Error code. 56 */ 57 typedef int (*usb_hid_driver_init_t)(usb_hid_dev_t *dev, void **data); 56 58 57 typedef struct usb_hid_subdriver { 59 /** Subdriver deinitialization callback. 60 * 61 * @param dev Backing USB HID device. 62 * @param data Custom subdriver data. 63 */ 64 typedef void (*usb_hid_driver_deinit_t)(usb_hid_dev_t *dev, void *data); 65 66 /** Subdriver callback on data from device. 67 * 68 * @param dev Backing USB HID device. 69 * @param data Custom subdriver data. 70 * @return Whether to continue polling (typically true always). 71 */ 72 typedef bool (*usb_hid_driver_poll_t)(usb_hid_dev_t *dev, void *data); 73 74 /** Subdriver callback after communication with the device ceased. 75 * 76 * @param dev Backing USB HID device. 77 * @param data Custom subdriver data. 78 * @param ended_due_to_errors Whether communication ended due to errors in 79 * communication (true) or deliberately by driver (false). 80 */ 81 typedef void (*usb_hid_driver_poll_ended_t)(usb_hid_dev_t *dev, void *data, 82 bool ended_due_to_errors); 83 84 struct usb_hid_subdriver { 58 85 /** Function to be called when initializing HID device. */ 59 86 usb_hid_driver_init_t init; … … 61 88 usb_hid_driver_deinit_t deinit; 62 89 /** Function to be called when data arrives from the device. */ 63 usb_hid_driver_poll poll;90 usb_hid_driver_poll_t poll; 64 91 /** Function to be called when polling ends. */ 65 usb_hid_driver_poll_ended poll_end;92 usb_hid_driver_poll_ended_t poll_end; 66 93 /** Arbitrary data needed by the subdriver. */ 67 94 void *data; 68 } usb_hid_subdriver_t;95 }; 69 96 70 97 /*----------------------------------------------------------------------------*/ … … 72 99 * Structure for holding general HID device data. 73 100 */ 74 typedefstruct usb_hid_dev {101 struct usb_hid_dev { 75 102 /** Structure holding generic USB device information. */ 76 103 usb_device_t *usb_dev; … … 94 121 usb_hid_report_t *report; 95 122 123 uint8_t report_id; 124 96 125 uint8_t *input_report; 97 126 … … 100 129 101 130 int report_nr; 102 } usb_hid_dev_t;131 }; 103 132 104 133 /*----------------------------------------------------------------------------*/
Note:
See TracChangeset
for help on using the changeset viewer.
