Ignore:
File:
1 edited

Legend:

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

    r5da7199 rce2a1c2  
    6464        //int32_t *keys;
    6565        /** Count of stored keys (i.e. number of keys in the report). */
    66         //size_t key_count;     
     66        //size_t key_count;
    6767        /** IPC session to the console device (for sending key events). */
    6868        async_sess_t *console_sess;
     69        /** DDF function */
     70        ddf_fun_t *fun;
    6971} usb_multimedia_t;
    7072
     
    8688{
    8789        usb_log_debug(NAME " default_connection_handler()\n");
    88        
     90
    8991        usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data;
    90        
     92
    9193        if (multim_dev == NULL) {
    9294                async_answer_0(icallid, EINVAL);
    9395                return;
    9496        }
    95        
     97
    9698        async_sess_t *sess =
    9799            async_callback_receive_start(EXCHANGE_SERIALIZE, icall);
     
    137139        assert(hid_dev != NULL);
    138140        assert(multim_dev != NULL);
    139        
     141
    140142        kbd_event_t ev;
    141        
     143
    142144        ev.type = type;
    143145        ev.key = key;
     
    151153                return;
    152154        }
    153        
     155
    154156        async_exch_t *exch = async_exchange_begin(multim_dev->console_sess);
    155157        async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c);
     
    159161/*----------------------------------------------------------------------------*/
    160162
    161 static int usb_multimedia_create_function(usb_hid_dev_t *hid_dev,
    162     usb_multimedia_t *multim_dev)
    163 {
     163int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data)
     164{
     165        if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
     166                return EINVAL; /*! @todo Other return code? */
     167        }
     168
     169        usb_log_debug(NAME " Initializing HID/multimedia structure...\n");
     170
    164171        /* Create the exposed function. */
    165         ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
    166             NAME);
     172        ddf_fun_t *fun = ddf_fun_create(
     173            hid_dev->usb_dev->ddf_dev, fun_exposed, NAME);
    167174        if (fun == NULL) {
    168175                usb_log_error("Could not create DDF function node.\n");
    169176                return ENOMEM;
    170177        }
    171        
     178
    172179        fun->ops = &multimedia_ops;
    173         fun->driver_data = multim_dev;   // TODO: maybe change to hid_dev->data
    174        
     180
     181        usb_multimedia_t *multim_dev =
     182            ddf_fun_data_alloc(fun, sizeof(usb_multimedia_t));
     183        if (multim_dev == NULL) {
     184                ddf_fun_destroy(fun);
     185                return ENOMEM;
     186        }
     187
     188        multim_dev->console_sess = NULL;
     189        multim_dev->fun = fun;
     190
     191        //todo Autorepeat?
     192
    175193        int rc = ddf_fun_bind(fun);
    176194        if (rc != EOK) {
    177195                usb_log_error("Could not bind DDF function: %s.\n",
    178196                    str_error(rc));
    179                 // TODO: Can / should I destroy the DDF function?
    180197                ddf_fun_destroy(fun);
    181198                return rc;
    182199        }
    183        
     200
    184201        usb_log_debug("%s function created (handle: %" PRIun ").\n",
    185202            NAME, fun->handle);
    186        
     203
    187204        rc = ddf_fun_add_to_category(fun, "keyboard");
    188205        if (rc != EOK) {
     
    190207                    "Could not add DDF function to category 'keyboard': %s.\n",
    191208                    str_error(rc));
    192                 // TODO: Can / should I destroy the DDF function?
    193209                ddf_fun_destroy(fun);
    194210                return rc;
    195211        }
    196        
    197         return EOK;
    198 }
    199 
    200 /*----------------------------------------------------------------------------*/
    201 
    202 int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data)
    203 {
    204         if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
    205                 return EINVAL; /*! @todo Other return code? */
    206         }
    207        
    208         usb_log_debug(NAME " Initializing HID/multimedia structure...\n");
    209        
    210         usb_multimedia_t *multim_dev = (usb_multimedia_t *)malloc(
    211             sizeof(usb_multimedia_t));
    212         if (multim_dev == NULL) {
    213                 return ENOMEM;
    214         }
    215        
    216         multim_dev->console_sess = NULL;
    217        
    218         /*! @todo Autorepeat */
    219        
    220         // save the KBD device structure into the HID device structure
     212
     213        /* Save the KBD device structure into the HID device structure. */
    221214        *data = multim_dev;
    222        
    223         usb_log_debug(NAME " HID/multimedia device structure initialized.\n");
    224        
    225         int rc = usb_multimedia_create_function(hid_dev, multim_dev);
    226         if (rc != EOK)
    227                 return rc;
    228        
     215
    229216        usb_log_debug(NAME " HID/multimedia structure initialized.\n");
    230        
    231217        return EOK;
    232218}
     
    239225                return;
    240226        }
    241        
     227
    242228        if (data != NULL) {
    243229                usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
    244230                // hangup session to the console
    245231                async_hangup(multim_dev->console_sess);
     232                const int ret = ddf_fun_unbind(multim_dev->fun);
     233                if (ret != EOK) {
     234                        usb_log_error("Failed to unbind multim function.\n");
     235                } else {
     236                        usb_log_debug2("%s unbound.\n", multim_dev->fun->name);
     237                        ddf_fun_destroy(multim_dev->fun);
     238                }
    246239        }
    247240}
     
    257250
    258251        usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
    259        
     252
    260253        usb_hid_report_path_t *path = usb_hid_report_path();
    261254        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
     
    264257
    265258        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    266             hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END
    267             | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
     259            &hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END
     260            | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    268261            USB_HID_REPORT_TYPE_INPUT);
    269262
     
    283276                                               key);
    284277                }
    285                
     278
    286279                field = usb_hid_report_get_sibling(
    287                     hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
     280                    &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
    288281                    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    289282                    USB_HID_REPORT_TYPE_INPUT);
    290         }       
     283        }
    291284
    292285        usb_hid_report_path_free(path);
    293        
     286
    294287        return true;
    295288}
Note: See TracChangeset for help on using the changeset viewer.