Changeset f1fae414 in mainline for uspace/drv/bus/usb/usbhid


Ignore:
Timestamp:
2011-06-22T01:34:53Z (15 years ago)
Author:
Petr Koupy <petr.koupy@…>
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.
Message:

Merge mainline changes.

Location:
uspace/drv/bus/usb/usbhid
Files:
25 moved

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbhid/Makefile

    r72ec8cc rf1fae414  
    2727#
    2828
    29 USPACE_PREFIX = ../..
     29USPACE_PREFIX = ../../../..
    3030
    3131LIBS = \
     
    3434        $(LIBUSB_PREFIX)/libusb.a \
    3535        $(LIBDRV_PREFIX)/libdrv.a
     36
    3637EXTRA_CFLAGS += \
    3738        -I. \
     
    4344BINARY = usbhid
    4445
    45 STOLEN_LAYOUT_SOURCES = \
    46         kbd/layout/us_qwerty.c \
    47         kbd/layout/us_dvorak.c \
    48         kbd/layout/cz.c
     46SUBDRIVER_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
    4953
    5054SOURCES = \
     
    5256        usbhid.c \
    5357        subdrivers.c \
    54         kbd/conv.c \
    55         kbd/kbddev.c \
    56         kbd/kbdrepeat.c \
    5758        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)
    6660
    6761include $(USPACE_PREFIX)/Makefile.common
    68 
    69 kbd/layout/%.c: $(SRV_KBD)/layout/%.c
    70         ln -sfn ../../$< $@
  • uspace/drv/bus/usb/usbhid/generic/hiddev.c

    r72ec8cc rf1fae414  
    231231/*----------------------------------------------------------------------------*/
    232232
    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);
     233bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, void *data)
     234{
    239235        return true;
    240236}
  • uspace/drv/bus/usb/usbhid/generic/hiddev.h

    r72ec8cc rf1fae414  
    5050int usb_generic_hid_init(struct usb_hid_dev *hid_dev, void **data);
    5151
    52 bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, void *data,
    53     uint8_t *buffer, size_t buffer_size);
     52bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, void *data);
    5453
    5554#endif // USB_HID_HIDDDEV_H_
  • uspace/drv/bus/usb/usbhid/kbd/kbddev.c

    r72ec8cc rf1fae414  
    4040
    4141#include <io/keycode.h>
    42 #include <ipc/kbd.h>
     42#include <io/console.h>
     43#include <ipc/kbdev.h>
    4344#include <async.h>
    4445#include <async_obsolete.h>
    4546#include <fibril.h>
    4647#include <fibril_synch.h>
     48
     49#include <ddf/log.h>
    4750
    4851#include <usb/usb.h>
     
    6366#include "kbddev.h"
    6467
    65 #include "layout.h"
    6668#include "conv.h"
    6769#include "kbdrepeat.h"
     
    7375
    7476/*----------------------------------------------------------------------------*/
    75 /** Default modifiers when the keyboard is initialized. */
     77
    7678static const unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK;
    7779
     
    101103const char *HID_KBD_FUN_NAME = "keyboard";
    102104const char *HID_KBD_CLASS_NAME = "keyboard";
     105
     106static void usb_kbd_set_led(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev);
    103107
    104108/*----------------------------------------------------------------------------*/
     
    154158
    155159/*----------------------------------------------------------------------------*/
    156 /* Keyboard layouts                                                           */
    157 /*----------------------------------------------------------------------------*/
    158 
    159 #define NUM_LAYOUTS 3
    160 
    161 /** Keyboard layout map. */
    162 static layout_op_t *layout[NUM_LAYOUTS] = {
    163         &us_qwerty_op,
    164         &us_dvorak_op,
    165         &cz_op
    166 };
    167 
    168 static int active_layout = 0;
    169 
    170 /*----------------------------------------------------------------------------*/
    171160/* IPC method handler                                                         */
    172161/*----------------------------------------------------------------------------*/
     
    174163static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
    175164
    176 /** 
     165/**
    177166 * Default handler for IPC methods not handled by DDF.
    178167 *
     
    189178{
    190179        sysarg_t method = IPC_GET_IMETHOD(*icall);
     180        int callback;
    191181       
    192182        usb_kbd_t *kbd_dev = (usb_kbd_t *)fun->driver_data;
     
    198188        }
    199189
    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);
    202193
    203194                if (kbd_dev->console_phone != -1) {
     
    212203                usb_log_debug("default_connection_handler: OK\n");
    213204                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        }
    219216}
    220217
     
    225222 * Handles turning of LED lights on and off.
    226223 *
    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.
    230228 *
    231229 * This functions sets the LED lights according to current settings of modifiers
     
    249247            USB_HID_REPORT_TYPE_OUTPUT);
    250248       
    251         while (field != NULL) {         
     249        while (field != NULL) {
    252250               
    253251                if ((field->usage == USB_HID_LED_NUM_LOCK)
     
    292290
    293291/*----------------------------------------------------------------------------*/
    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 *
    305294 * @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:
    307296 *             KEY_PRESS, KEY_RELEASE
    308  * @param key Key code of the key according to HID Usage Tables.
     297 * @param key Key code
    309298 */
    310299void usb_kbd_push_ev(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev, int type,
    311300    unsigned int key)
    312301{
    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);
    399303        if (kbd_dev->console_phone < 0) {
    400304                usb_log_warning(
     
    403307        }
    404308       
    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);
    407310}
    408311
     
    414317            || key_code == KC_SCROLL_LOCK
    415318            || key_code == KC_CAPS_LOCK);
     319}
     320
     321static 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;
    416330}
    417331
     
    436350{
    437351        unsigned int key;
    438         unsigned int i, j;
     352        size_t i;
    439353       
    440354        /*
     
    446360         * whole input report.
    447361         */
    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");
    455366                return;
    456367        }
    457368       
    458369        /*
    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);
    472380                        if (!usb_kbd_is_lock(key)) {
    473381                                usb_kbd_repeat_stop(kbd_dev, key);
    474382                        }
    475383                        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
    484391         */
    485392        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) {
    495399                        key = usbhid_parse_scancode(kbd_dev->keys[i]);
    496                         usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,
    497                             kbd_dev->keys[i]);
    498400                        if (!usb_kbd_is_lock(key)) {
    499401                                usb_kbd_repeat_start(kbd_dev, key);
    500402                        }
    501403                        usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, key);
    502                 } else {
    503                         // found, nothing happens
     404                        usb_log_debug2("Key pressed: %u "
     405                            "(USB code %" PRIu32 ")\n", key, new_key);
    504406                }
    505407        }
     
    507409        memcpy(kbd_dev->keys_old, kbd_dev->keys, kbd_dev->key_count * 4);
    508410       
    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);
    514415}
    515416
     
    533434 *     usb_hid_parse_report().
    534435 */
    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)
     436static void usb_kbd_process_data(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev)
    537437{
    538438        assert(hid_dev->report != NULL);
    539439        assert(hid_dev != NULL);
    540440        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));
    544441       
    545442        usb_hid_report_path_t *path = usb_hid_report_path();
    546443        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    547444
    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);
    558446       
    559447        // fill in the currently pressed keys
     
    716604                return ENOMEM;  // TODO: some other code??
    717605        }
     606
     607        /* Store link to HID device */
     608        kbd_dev->hid_dev = hid_dev;
    718609       
    719610        /*
     
    787678        /*
    788679         * Modifiers and locks
    789          */     
     680         */
    790681        kbd_dev->modifiers = 0;
    791682        kbd_dev->mods = DEFAULT_ACTIVE_MODS;
     
    794685        /*
    795686         * Autorepeat
    796          */     
     687         */
    797688        kbd_dev->repeat.key_new = 0;
    798689        kbd_dev->repeat.key_repeated = 0;
     
    852743/*----------------------------------------------------------------------------*/
    853744
    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) {
     745bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, void *data)
     746{
     747        if (hid_dev == NULL/* || buffer == NULL*/ || data == NULL) {
    858748                // do not continue polling (???)
    859749                return false;
     
    864754       
    865755        // 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);
    867757       
    868758        return true;
     
    900790        if ((*kbd_dev)->repeat_mtx != NULL) {
    901791                //assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx));
     792                // FIXME - the fibril_mutex_is_locked may not cause
     793                // fibril scheduling
    902794                while (fibril_mutex_is_locked((*kbd_dev)->repeat_mtx)) {}
    903795                free((*kbd_dev)->repeat_mtx);
  • uspace/drv/bus/usb/usbhid/kbd/kbddev.h

    r72ec8cc rf1fae414  
    6565 */
    6666typedef struct usb_kbd_t {
     67        /** Link to HID device structure */
     68        struct usb_hid_dev *hid_dev;
     69
    6770        /** Previously pressed keys (not translated to key codes). */
    6871        int32_t *keys_old;
     
    122125int usb_kbd_init(struct usb_hid_dev *hid_dev, void **data);
    123126
    124 bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, void *data,
    125                               uint8_t *buffer, size_t buffer_size);
     127bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, void *data);
    126128
    127129int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev);
  • uspace/drv/bus/usb/usbhid/kbd/kbdrepeat.c

    r72ec8cc rf1fae414  
    9797                                delay = kbd->repeat.delay_between;
    9898                        } else {
    99                                 usb_log_debug("New key to repeat: %u.\n",
     99                                usb_log_debug2("New key to repeat: %u.\n",
    100100                                    kbd->repeat.key_new);
    101101                                kbd->repeat.key_repeated = kbd->repeat.key_new;
     
    104104                } else {
    105105                        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",
    107107                                    kbd->repeat.key_repeated);
    108108                                kbd->repeat.key_repeated = 0;
  • uspace/drv/bus/usb/usbhid/mouse/mousedev.c

    r72ec8cc rf1fae414  
    4444#include <async_obsolete.h>
    4545#include <str_error.h>
    46 #include <ipc/mouse.h>
     46#include <ipc/mouseev.h>
    4747#include <io/console.h>
    4848
    49 #include <ipc/kbd.h>
     49#include <ipc/kbdev.h>
    5050#include <io/keycode.h>
    5151
    5252#include "mousedev.h"
    5353#include "../usbhid.h"
     54
     55/** Number of simulated arrow-key presses for singel wheel step. */
     56#define ARROWS_PER_SINGLE_WHEEL 3
    5457
    5558// FIXME: remove this header
     
    201204static void usb_mouse_send_wheel(const usb_mouse_t *mouse_dev, int wheel)
    202205{
    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;
    209207
    210208        if (mouse_dev->wheel_phone < 0) {
    211209                usb_log_warning(
    212                     "Connection to console not ready, key discarded.\n");
     210                    "Connection to console not ready, wheel roll discarded.\n");
    213211                return;
    214212        }
    215213       
    216         int count = (wheel < 0) ? -wheel : wheel;
     214        int count = ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL;
    217215        int i;
    218216       
    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
     229static 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
     253static bool usb_mouse_process_report(usb_hid_dev_t *hid_dev,
     254    usb_mouse_t *mouse_dev)
    234255{
    235256        assert(mouse_dev != NULL);
    236        
    237         usb_log_debug2("got buffer: %s.\n",
    238             usb_debug_str_buffer(buffer, buffer_size, 0));
    239257       
    240258        if (mouse_dev->mouse_phone < 0) {
     
    243261        }
    244262
    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
    309270        if ((shift_x != 0) || (shift_y != 0)) {
    310271                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        }
    341278       
    342279        /*
    343280         * Buttons
    344281         */
    345         path = usb_hid_report_path();
     282        usb_hid_report_path_t *path = usb_hid_report_path();
    346283        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(
    350287            hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END
    351288            | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     
    353290
    354291        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,
    356293                    field->usage);
    357294               
     
    359296                    && field->value != 0) {
    360297                        async_obsolete_req_2_0(mouse_dev->mouse_phone,
    361                             MEVENT_BUTTON, field->usage, 1);
     298                            MOUSEEV_BUTTON_EVENT, field->usage, 1);
    362299                        mouse_dev->buttons[field->usage - field->usage_minimum]
    363300                            = 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
    366302                    && field->value == 0) {
    367                        async_obsolete_req_2_0(mouse_dev->mouse_phone,
    368                            MEVENT_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                }
    372308               
    373309                field = usb_hid_report_get_sibling(
     
    510446/*----------------------------------------------------------------------------*/
    511447
    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        
     448bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, void *data)
     449{
    518450        if (hid_dev == NULL || data == NULL) {
    519451                usb_log_error("Missing argument to the mouse polling callback."
     
    524456        usb_mouse_t *mouse_dev = (usb_mouse_t *)data;
    525457               
    526         return usb_mouse_process_report(hid_dev, mouse_dev, buffer,
    527                                         buffer_size);
     458        return usb_mouse_process_report(hid_dev, mouse_dev);
    528459}
    529460
  • uspace/drv/bus/usb/usbhid/mouse/mousedev.h

    r72ec8cc rf1fae414  
    6565int usb_mouse_init(struct usb_hid_dev *hid_dev, void **data);
    6666
    67 bool usb_mouse_polling_callback(struct usb_hid_dev *hid_dev, void *data,
    68     uint8_t *buffer, size_t buffer_size);
     67bool usb_mouse_polling_callback(struct usb_hid_dev *hid_dev, void *data);
    6968
    7069void usb_mouse_deinit(struct usb_hid_dev *hid_dev, void *data);
  • uspace/drv/bus/usb/usbhid/multimedia/multimedia.c

    r72ec8cc rf1fae414  
    5050#include <str_error.h>
    5151
    52 #include <ipc/kbd.h>
     52#include <ipc/kbdev.h>
    5353#include <io/console.h>
    5454
     
    9494       
    9595        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;
    9796       
    9897        if (multim_dev == NULL) {
     
    162161        }
    163162       
    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,
    165164            ev.mods, ev.c);
    166165}
     
    274273/*----------------------------------------------------------------------------*/
    275274
    276 bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data,
    277     uint8_t *buffer, size_t buffer_size)
     275bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data)
    278276{
    279277        // TODO: checks
    280         if (hid_dev == NULL || data == NULL || buffer == NULL) {
     278        if (hid_dev == NULL || data == NULL) {
    281279                return false;
    282280        }
    283        
    284         usb_log_debug(NAME " usb_lgtch_polling_callback(%p, %p, %zu)\n",
    285             hid_dev, buffer, buffer_size);
    286        
     281
    287282        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));
    291283       
    292284        usb_hid_report_path_t *path = usb_hid_report_path();
    293285        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
    294286
    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);
    307288
    308289        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
  • uspace/drv/bus/usb/usbhid/multimedia/multimedia.h

    r72ec8cc rf1fae414  
    4747void usb_multimedia_deinit(struct usb_hid_dev *hid_dev, void *data);
    4848
    49 bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data,
    50     uint8_t *buffer, size_t buffer_size);
     49bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data);
    5150
    5251/*----------------------------------------------------------------------------*/
  • uspace/drv/bus/usb/usbhid/subdrivers.h

    r72ec8cc rf1fae414  
    4949/*----------------------------------------------------------------------------*/
    5050
    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.
    5357 */
    5458typedef 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         */
    5565        const usb_hid_subdriver_usage_t *usage_path;
     66       
     67        /** Report ID for which the path should apply. */
    5668        int report_id;
     69       
     70        /** Compare type for the Usage path. */
    5771        int compare;
     72       
     73        /** Vendor ID (set to -1 if not specified). */
    5874        int vendor_id;
     75       
     76        /** Product ID (set to -1 if not specified). */
    5977        int product_id;
     78       
     79        /** Subdriver for controlling this device. */
    6080        usb_hid_subdriver_t subdriver;
    6181} usb_hid_subdriver_mapping_t;
  • uspace/drv/bus/usb/usbhid/usbhid.c

    r72ec8cc rf1fae414  
    572572       
    573573        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));
    576577
    577578        if (hid_dev->max_input_report_size >= buffer_size) {
     
    582583        }
    583584       
     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       
    584595        bool cont = false;
    585596       
     
    588599                if (hid_dev->subdrivers[i].poll != NULL
    589600                    && hid_dev->subdrivers[i].poll(hid_dev,
    590                         hid_dev->subdrivers[i].data, buffer, buffer_size)) {
     601                        hid_dev->subdrivers[i].data)) {
    591602                        cont = true;
    592603                }
  • uspace/drv/bus/usb/usbhid/usbhid.h

    r72ec8cc rf1fae414  
    4646#include <bool.h>
    4747
    48 struct usb_hid_dev;
     48typedef struct usb_hid_dev usb_hid_dev_t;
     49typedef struct usb_hid_subdriver usb_hid_subdriver_t;
    4950
    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 */
     57typedef int (*usb_hid_driver_init_t)(usb_hid_dev_t *dev, void **data);
    5658
    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 */
     64typedef 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 */
     72typedef 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 */
     81typedef void (*usb_hid_driver_poll_ended_t)(usb_hid_dev_t *dev, void *data,
     82    bool ended_due_to_errors);
     83
     84struct usb_hid_subdriver {
    5885        /** Function to be called when initializing HID device. */
    5986        usb_hid_driver_init_t init;
     
    6188        usb_hid_driver_deinit_t deinit;
    6289        /** Function to be called when data arrives from the device. */
    63         usb_hid_driver_poll poll;
     90        usb_hid_driver_poll_t poll;
    6491        /** Function to be called when polling ends. */
    65         usb_hid_driver_poll_ended poll_end;
     92        usb_hid_driver_poll_ended_t poll_end;
    6693        /** Arbitrary data needed by the subdriver. */
    6794        void *data;
    68 } usb_hid_subdriver_t;
     95};
    6996
    7097/*----------------------------------------------------------------------------*/
     
    7299 * Structure for holding general HID device data.
    73100 */
    74 typedef struct usb_hid_dev {
     101struct usb_hid_dev {
    75102        /** Structure holding generic USB device information. */
    76103        usb_device_t *usb_dev;
     
    94121        usb_hid_report_t *report;
    95122       
     123        uint8_t report_id;
     124       
    96125        uint8_t *input_report;
    97126       
     
    100129       
    101130        int report_nr;
    102 } usb_hid_dev_t;
     131};
    103132
    104133/*----------------------------------------------------------------------------*/
Note: See TracChangeset for help on using the changeset viewer.