Ignore:
Timestamp:
2011-05-18T09:34:56Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
33d19a7
Parents:
d736fe38 (diff), b2995c3 (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:

Development branch changes

File:
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhid/multimedia/multimedia.c

    rd736fe38 rc7b5826  
    3232/**
    3333 * @file
    34  * USB Logitech UltraX Keyboard sample driver.
    35  */
    36 
    37 
    38 #include "lgtch-ultrax.h"
     34 * USB Keyboard multimedia keys subdriver.
     35 */
     36
     37
     38#include "multimedia.h"
    3939#include "../usbhid.h"
    4040#include "keymap.h"
    4141
    42 #include <usb/classes/hidparser.h>
     42#include <usb/hid/hidparser.h>
    4343#include <usb/debug.h>
    44 #include <usb/classes/hidut.h>
     44#include <usb/hid/usages/core.h>
    4545
    4646#include <errno.h>
     
    5050#include <io/console.h>
    5151
    52 #define NAME "lgtch-ultrax"
    53 
    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;
     52#define NAME "multimedia-keys"
    5953
    6054/*----------------------------------------------------------------------------*/
     
    6256 * Logitech UltraX device type.
    6357 */
    64 typedef struct usb_lgtch_ultrax_t {
     58typedef struct usb_multimedia_t {
    6559        /** Previously pressed keys (not translated to key codes). */
    6660        int32_t *keys_old;
     
    6862        int32_t *keys;
    6963        /** Count of stored keys (i.e. number of keys in the report). */
    70         size_t key_count;
    71        
     64        size_t key_count;       
    7265        /** IPC phone to the console device (for sending key events). */
    7366        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;
     67} usb_multimedia_t;
    8968
    9069
     
    10887        sysarg_t method = IPC_GET_IMETHOD(*icall);
    10988       
    110         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
    111        
    112         if (hid_dev == NULL || hid_dev->data == NULL) {
     89        usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data;
     90        //usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
     91       
     92        if (multim_dev == NULL) {
    11393                async_answer_0(icallid, EINVAL);
    11494                return;
    11595        }
    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;
    12096
    12197        if (method == IPC_M_CONNECT_TO_ME) {
    12298                int callback = IPC_GET_ARG5(*icall);
    12399
    124                 if (lgtch_dev->console_phone != -1) {
     100                if (multim_dev->console_phone != -1) {
    125101                        async_answer_0(icallid, ELIMIT);
    126102                        return;
    127103                }
    128104
    129                 lgtch_dev->console_phone = callback;
     105                multim_dev->console_phone = callback;
    130106                usb_log_debug(NAME " Saved phone to console: %d\n", callback);
    131107                async_answer_0(icallid, EOK);
     
    138114/*----------------------------------------------------------------------------*/
    139115
    140 static ddf_dev_ops_t lgtch_ultrax_ops = {
     116static ddf_dev_ops_t multimedia_ops = {
    141117        .default_handler = default_connection_handler
    142118};
    143 
    144 /*----------------------------------------------------------------------------*/
    145 
    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 //}
    163119
    164120/*----------------------------------------------------------------------------*/
     
    180136 * @param key Key code of the key according to HID Usage Tables.
    181137 */
    182 static void usb_lgtch_push_ev(usb_hid_dev_t *hid_dev, int type,
    183     unsigned int key)
     138static void usb_multimedia_push_ev(usb_hid_dev_t *hid_dev,
     139    usb_multimedia_t *multim_dev, int type, unsigned int key)
    184140{
    185141        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;
     142        assert(multim_dev != NULL);
     143       
     144//      usb_multimedia_t *multim_dev = (usb_multimedia_t *)hid_dev->data;
    189145       
    190146        console_event_t ev;
     
    193149        ev.key = key;
    194150        ev.mods = 0;
    195 
    196151        ev.c = 0;
    197152
    198153        usb_log_debug2(NAME " Sending key %d to the console\n", ev.key);
    199         if (lgtch_dev->console_phone < 0) {
     154        if (multim_dev->console_phone < 0) {
    200155                usb_log_warning(
    201156                    "Connection to console not ready, key discarded.\n");
     
    203158        }
    204159       
    205         async_msg_4(lgtch_dev->console_phone, KBD_EVENT, ev.type, ev.key,
     160        async_msg_4(multim_dev->console_phone, KBD_EVENT, ev.type, ev.key,
    206161            ev.mods, ev.c);
    207162}
     
    209164/*----------------------------------------------------------------------------*/
    210165
    211 static void usb_lgtch_free(usb_lgtch_ultrax_t **lgtch_dev)
    212 {
    213         if (lgtch_dev == NULL || *lgtch_dev == NULL) {
     166static void usb_multimedia_free(usb_multimedia_t **multim_dev)
     167{
     168        if (multim_dev == NULL || *multim_dev == NULL) {
    214169                return;
    215170        }
    216171       
    217172        // 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 //      }
     173        async_hangup((*multim_dev)->console_phone);
    225174       
    226175        // 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)
     176        if ((*multim_dev)->keys != NULL) {
     177                free((*multim_dev)->keys);
     178        }
     179        if ((*multim_dev)->keys_old != NULL) {
     180                free((*multim_dev)->keys_old);
     181        }
     182
     183        free(*multim_dev);
     184        *multim_dev = NULL;
     185}
     186
     187/*----------------------------------------------------------------------------*/
     188
     189static int usb_multimedia_create_function(usb_hid_dev_t *hid_dev,
     190    usb_multimedia_t *multim_dev)
    241191{
    242192        /* Create the function exposed under /dev/devices. */
     
    248198        }
    249199       
    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
     200        fun->ops = &multimedia_ops;
     201        fun->driver_data = multim_dev;   // TODO: maybe change to hid_dev->data
    256202       
    257203        int rc = ddf_fun_bind(fun);
     
    279225/*----------------------------------------------------------------------------*/
    280226
    281 int usb_lgtch_init(struct usb_hid_dev *hid_dev)
     227int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data)
    282228{
    283229        if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
     
    285231        }
    286232       
    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) {
     233        usb_log_debug(NAME " Initializing HID/multimedia structure...\n");
     234       
     235        usb_multimedia_t *multim_dev = (usb_multimedia_t *)malloc(
     236            sizeof(usb_multimedia_t));
     237        if (multim_dev == NULL) {
    292238                return ENOMEM;
    293239        }
    294240       
    295         lgtch_dev->console_phone = -1;
     241        multim_dev->console_phone = -1;
    296242       
    297243        usb_hid_report_path_t *path = usb_hid_report_path();
     
    300246        usb_hid_report_path_set_report_id(path, 1);
    301247       
    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);
     248        multim_dev->key_count = usb_hid_report_size(
     249            hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
     250
    305251        usb_hid_report_path_free(path);
    306252       
    307253        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,
     254            multim_dev->key_count);
     255       
     256        multim_dev->keys = (int32_t *)calloc(multim_dev->key_count,
    311257            sizeof(int32_t));
    312258       
    313         if (lgtch_dev->keys == NULL) {
     259        if (multim_dev->keys == NULL) {
    314260                usb_log_fatal("No memory!\n");
    315                 free(lgtch_dev);
     261                free(multim_dev);
    316262                return ENOMEM;
    317263        }
    318264       
    319         lgtch_dev->keys_old =
    320                 (int32_t *)calloc(lgtch_dev->key_count, sizeof(int32_t));
    321        
    322         if (lgtch_dev->keys_old == NULL) {
     265        multim_dev->keys_old =
     266                (int32_t *)calloc(multim_dev->key_count, sizeof(int32_t));
     267       
     268        if (multim_dev->keys_old == NULL) {
    323269                usb_log_fatal("No memory!\n");
    324                 free(lgtch_dev->keys);
    325                 free(lgtch_dev);
     270                free(multim_dev->keys);
     271                free(multim_dev);
    326272                return ENOMEM;
    327273        }
     
    330276       
    331277        // 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);
     278        *data = multim_dev;
     279       
     280        usb_log_debug(NAME " HID/multimedia device structure initialized.\n");
     281       
     282        int rc = usb_multimedia_create_function(hid_dev, multim_dev);
    338283        if (rc != EOK) {
    339                 usb_lgtch_free(&lgtch_dev);
     284                usb_multimedia_free(&multim_dev);
    340285                return rc;
    341286        }
    342287       
    343         usb_log_debug(NAME " HID/lgtch_ultrax structure initialized.\n");
     288        usb_log_debug(NAME " HID/multimedia structure initialized.\n");
    344289       
    345290        return EOK;
     
    348293/*----------------------------------------------------------------------------*/
    349294
    350 void usb_lgtch_deinit(struct usb_hid_dev *hid_dev)
     295void usb_multimedia_deinit(struct usb_hid_dev *hid_dev, void *data)
    351296{
    352297        if (hid_dev == NULL) {
     
    354299        }
    355300       
    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         }
    366 }
    367 
    368 /*----------------------------------------------------------------------------*/
    369 
    370 bool usb_lgtch_polling_callback(struct usb_hid_dev *hid_dev,
     301        if (data != NULL) {
     302                usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
     303                usb_multimedia_free(&multim_dev);
     304        }
     305}
     306
     307/*----------------------------------------------------------------------------*/
     308
     309bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data,
    371310    uint8_t *buffer, size_t buffer_size)
    372311{
     
    375314        usb_log_debug(NAME " usb_lgtch_polling_callback(%p, %p, %zu)\n",
    376315            hid_dev, buffer, buffer_size);
     316       
     317        if (data == NULL) {
     318                return EINVAL;  // TODO: other error code?
     319        }
     320       
     321        usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
    377322
    378323        usb_log_debug(NAME " Calling usb_hid_parse_report() with "
     
    380325       
    381326        usb_hid_report_path_t *path = usb_hid_report_path();
    382         usb_hid_report_path_append_item(path, 0xc, 0);
     327        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
    383328
    384329        uint8_t report_id;
     
    400345            USB_HID_REPORT_TYPE_INPUT);
    401346       
    402         unsigned int key;
     347//      unsigned int key;
    403348       
    404349        /*! @todo Is this iterating OK if done multiple times?
     
    406351         */
    407352        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);
     353                if(field->value != 0) {
     354                        usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n",
     355                            field->value, field->usage);
     356                        unsigned int key =
     357                            usb_multimedia_map_usage(field->usage);
     358                        const char *key_str =
     359                            usb_multimedia_usage_to_str(field->usage);
     360                        usb_log_info("Pressed key: %s\n", key_str);
     361                        usb_multimedia_push_ev(hid_dev, multim_dev, KEY_PRESS,
     362                                               key);
     363                }
    413364               
    414365                field = usb_hid_report_get_sibling(
Note: See TracChangeset for help on using the changeset viewer.