static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret, i; struct mt_device *td; struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ for (i = 0; mt_classes[i].name ; i++) { if (id->driver_data == mt_classes[i].name) { mtclass = &(mt_classes[i]); break; } } /* This allows the driver to correctly support devices * that emit events over several HID messages. */ hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; td = kzalloc(sizeof(struct mt_device) + mtclass->maxcontacts * sizeof(struct mt_slot), GFP_KERNEL); if (!td) { dev_err(&hdev->dev, "cannot allocate multitouch data\n"); return -ENOMEM; } td->mtclass = mtclass; td->inputmode = -1; hid_set_drvdata(hdev, td); ret = hid_parse(hdev); if (ret != 0) goto fail; ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) goto fail; mt_set_input_mode(hdev); return 0; fail: kfree(td); return ret; }
static void lenovo_remove_tpkbd(struct hid_device *hdev) { struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); /* * Only the trackpoint half of the keyboard has drvdata and stuff that * needs unregistering. */ if (data_pointer == NULL) return; sysfs_remove_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd); led_classdev_unregister(&data_pointer->led_micmute); led_classdev_unregister(&data_pointer->led_mute); hid_set_drvdata(hdev, NULL); }
static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; struct mmm_data *md; md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL); if (!md) { dev_err(&hdev->dev, "cannot allocate 3M data\n"); return -ENOMEM; } hid_set_drvdata(hdev, md); ret = hid_parse(hdev); if (!ret) ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) kfree(md); return ret; }
static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id) { int rc; struct usb_interface *intf = to_usb_interface(hdev->dev.parent); struct huion_drvdata *drvdata; /* Allocate and assign driver data */ drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL); if (drvdata == NULL) { hid_err(hdev, "failed to allocate driver data\n"); return -ENOMEM; } hid_set_drvdata(hdev, drvdata); switch (id->product) { case USB_DEVICE_ID_HUION_TABLET: /* If this is the pen interface */ if (intf->cur_altsetting->desc.bInterfaceNumber == 0) { rc = huion_tablet_enable(hdev); if (rc) { hid_err(hdev, "tablet enabling failed\n"); return rc; } } break; } rc = hid_parse(hdev); if (rc) { hid_err(hdev, "parse failed\n"); return rc; } rc = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (rc) { hid_err(hdev, "hw start failed\n"); return rc; } return 0; }
static int apple_probe(struct hid_device *hdev, const struct hid_device_id *id) { unsigned long quirks = id->driver_data; struct apple_sc *asc; unsigned int connect_mask = HID_CONNECT_DEFAULT; int ret; asc = kzalloc(sizeof(*asc), GFP_KERNEL); if (asc == NULL) { dev_err(&hdev->dev, "can't alloc apple descriptor\n"); return -ENOMEM; } asc->quirks = quirks; hid_set_drvdata(hdev, asc); ret = hid_parse(hdev); if (ret) { dev_err(&hdev->dev, "parse failed\n"); goto err_free; } if (quirks & APPLE_HIDDEV) connect_mask |= HID_CONNECT_HIDDEV_FORCE; if (quirks & APPLE_IGNORE_HIDINPUT) connect_mask &= ~HID_CONNECT_HIDINPUT; ret = hid_hw_start(hdev, connect_mask); if (ret) { dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } return 0; err_free: kfree(asc); return ret; }
static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; unsigned long quirks = id->driver_data; struct sony_sc *sc; sc = kzalloc(sizeof(*sc), GFP_KERNEL); if (sc == NULL) { dev_err(&hdev->dev, "can't alloc apple descriptor\n"); return -ENOMEM; } sc->quirks = quirks; hid_set_drvdata(hdev, sc); ret = hid_parse(hdev); if (ret) { dev_err(&hdev->dev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | HID_CONNECT_HIDDEV_FORCE); if (ret) { dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } ret = sony_set_operational(hdev); if (ret) goto err_stop; return 0; err_stop: hid_hw_stop(hdev); err_free: kfree(sc); return ret; }
static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; struct ntrig_data *nd; nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); if (!nd) { dev_err(&hdev->dev, "cannot allocate N-Trig data\n"); return -ENOMEM; } nd->reading_a_point = 0; nd->found_contact_id = 0; hid_set_drvdata(hdev, nd); ret = hid_parse(hdev); if (!ret) ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) kfree (nd); return ret; }
static int lenovo_probe_cptkbd(struct hid_device *hdev) { int ret; struct lenovo_drvdata_cptkbd *cptkbd_data; /* All the custom action happens on the USBMOUSE device for USB */ if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD && hdev->type != HID_TYPE_USBMOUSE) { hid_dbg(hdev, "Ignoring keyboard half of device\n"); return 0; } cptkbd_data = devm_kzalloc(&hdev->dev, sizeof(*cptkbd_data), GFP_KERNEL); if (cptkbd_data == NULL) { hid_err(hdev, "can't alloc keyboard descriptor\n"); return -ENOMEM; } hid_set_drvdata(hdev, cptkbd_data); /* * Tell the keyboard a driver understands it, and turn F7, F9, F11 into * regular keys */ ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); if (ret) hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); /* Turn Fn-Lock on by default */ cptkbd_data->fn_lock = true; lenovo_features_set_cptkbd(hdev); ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd); if (ret) hid_warn(hdev, "Could not create sysfs group: %d\n", ret); return 0; }
static int mosart_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; struct mosart_data *td; td = kmalloc(sizeof(struct mosart_data), GFP_KERNEL); if (!td) { hid_err(hdev, "cannot allocate MosArt data\n"); return -ENOMEM; } td->valid = false; td->activity = false; td->activity_now = false; td->first = false; hid_set_drvdata(hdev, td); /* currently, it's better to have one evdev device only */ #if 0 hdev->quirks |= HID_QUIRK_MULTI_INPUT; #endif ret = hid_parse(hdev); if (ret == 0) ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret == 0) { struct hid_report_enum *re = hdev->report_enum + HID_FEATURE_REPORT; struct hid_report *r = re->report_id_hash[7]; r->field[0]->value[0] = 0x02; usbhid_submit_report(hdev, r, USB_DIR_OUT); } else kfree(td); return ret; }
static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) { unsigned long quirks = id->driver_data; unsigned int connect_mask = HID_CONNECT_DEFAULT; int ret; hid_set_drvdata(hdev, (void *)quirks); if (quirks & LG_NOGET) hdev->quirks |= HID_QUIRK_NOGET; ret = hid_parse(hdev); if (ret) { dev_err(&hdev->dev, "parse failed\n"); goto err_free; } if (quirks & (LG_FF | LG_FF2)) connect_mask &= ~HID_CONNECT_FF; ret = hid_hw_start(hdev, connect_mask); if (ret) { dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } if (quirks & LG_RESET_LEDS) usbhid_set_leds(hdev); if (quirks & LG_FF) lgff_init(hdev); if (quirks & LG_FF2) lg2ff_init(hdev); return 0; err_free: return ret; }
static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id) { unsigned long quirks = id->driver_data; int ret; hid_set_drvdata(hdev, (void *)quirks); ret = hid_parse(hdev); if (ret) { hid_err(hdev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { hid_err(hdev, "hw start failed\n"); goto err_free; } return 0; err_free: return ret; }
static void picolcd_remove(struct hid_device *hdev) { struct picolcd_data *data = hid_get_drvdata(hdev); unsigned long flags; dbg_hid(PICOLCD_NAME " hardware remove...\n"); spin_lock_irqsave(&data->lock, flags); data->status |= PICOLCD_FAILED; spin_unlock_irqrestore(&data->lock, flags); picolcd_exit_devfs(data); device_remove_file(&hdev->dev, &dev_attr_operation_mode); device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay); hid_hw_close(hdev); hid_hw_stop(hdev); /* Shortcut potential pending reply that will never arrive */ spin_lock_irqsave(&data->lock, flags); if (data->pending) complete(&data->pending->ready); spin_unlock_irqrestore(&data->lock, flags); /* Cleanup LED */ picolcd_exit_leds(data); /* Clean up the framebuffer */ picolcd_exit_backlight(data); picolcd_exit_lcd(data); picolcd_exit_framebuffer(data); /* Cleanup input */ picolcd_exit_cir(data); picolcd_exit_keys(data); hid_set_drvdata(hdev, NULL); mutex_destroy(&data->mutex); /* Finally, clean up the picolcd data itself */ kfree(data); }
static int cando_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; struct cando_data *td; td = kmalloc(sizeof(struct cando_data), GFP_KERNEL); if (!td) { hid_err(hdev, "cannot allocate Cando Touch data\n"); return -ENOMEM; } hid_set_drvdata(hdev, td); td->first = false; td->oldest = -1; td->valid = false; ret = hid_parse(hdev); if (!ret) ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) kfree(td); return ret; }
static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id) { unsigned long quirks = id->driver_data; int ret; hid_set_drvdata(hdev, (void *)quirks); ret = hid_parse(hdev); if (ret) { dev_err(&hdev->dev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & BELKIN_HIDDEV) ? HID_CONNECT_HIDDEV_FORCE : 0)); if (ret) { dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } return 0; err_free: return ret; }
static void egalax_remove(struct hid_device *hdev) { hid_hw_stop(hdev); kfree(hid_get_drvdata(hdev)); hid_set_drvdata(hdev, NULL); }
static int razer_kbd_probe(struct hid_device *hdev, const struct hid_device_id *id) { int retval; struct usb_interface *intf = to_usb_interface(hdev->dev.parent); //struct usb_device *usb_dev = interface_to_usbdev(intf); struct razer_kbd_device *dev = NULL; dev = kzalloc(sizeof(struct razer_kbd_device),GFP_KERNEL); if(dev == NULL) { dev_err(&intf->dev, "out of memory\n"); retval = -ENOMEM; goto exit; } retval = device_create_file(&hdev->dev, &dev_attr_mode_wave); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_mode_spectrum); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_mode_none); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_mode_reactive); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_mode_breath); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_mode_custom); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_mode_static); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_temp_clear_row); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_set_key_row); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_reset); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_macro_keys); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_set_brightness); if (retval) goto exit_free; hid_set_drvdata(hdev, dev); retval = hid_parse(hdev); if(retval) { hid_err(hdev,"parse failed\n"); goto exit_free; } retval = hid_hw_start(hdev,HID_CONNECT_DEFAULT); if (retval) { hid_err(hdev,"hw start failed\n"); goto exit_free; } //razer_reset(usb_dev); //razer_activate_macro_keys(usb_dev); //msleep(3000); return 0; exit: return retval; exit_free: kfree(dev); return retval; }
static int logi_dj_probe(struct hid_device *hdev, const struct hid_device_id *id) { struct usb_interface *intf = to_usb_interface(hdev->dev.parent); struct dj_receiver_dev *djrcv_dev; int retval; if (is_dj_device((struct dj_device *)hdev->driver_data)) return -ENODEV; dbg_hid("%s called for ifnum %d\n", __func__, intf->cur_altsetting->desc.bInterfaceNumber); /* Ignore interfaces 0 and 1, they will not carry any data, dont create * any hid_device for them */ if (intf->cur_altsetting->desc.bInterfaceNumber != LOGITECH_DJ_INTERFACE_NUMBER) { dbg_hid("%s: ignoring ifnum %d\n", __func__, intf->cur_altsetting->desc.bInterfaceNumber); return -ENODEV; } /* Treat interface 2 */ djrcv_dev = kzalloc(sizeof(struct dj_receiver_dev), GFP_KERNEL); if (!djrcv_dev) { dev_err(&hdev->dev, "%s:failed allocating dj_receiver_dev\n", __func__); return -ENOMEM; } djrcv_dev->hdev = hdev; INIT_WORK(&djrcv_dev->work, delayedwork_callback); spin_lock_init(&djrcv_dev->lock); if (kfifo_alloc(&djrcv_dev->notif_fifo, DJ_MAX_NUMBER_NOTIFICATIONS * sizeof(struct dj_report), GFP_KERNEL)) { dev_err(&hdev->dev, "%s:failed allocating notif_fifo\n", __func__); kfree(djrcv_dev); return -ENOMEM; } hid_set_drvdata(hdev, djrcv_dev); /* Call to usbhid to fetch the HID descriptors of interface 2 and * subsequently call to the hid/hid-core to parse the fetched * descriptors, this will in turn create the hidraw and hiddev nodes * for interface 2 of the receiver */ retval = hid_parse(hdev); if (retval) { dev_err(&hdev->dev, "%s:parse of interface 2 failed\n", __func__); goto hid_parse_fail; } /* Starts the usb device and connects to upper interfaces hiddev and * hidraw */ retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (retval) { dev_err(&hdev->dev, "%s:hid_hw_start returned error\n", __func__); goto hid_hw_start_fail; } retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0); if (retval < 0) { dev_err(&hdev->dev, "%s:logi_dj_recv_switch_to_dj_mode returned error:%d\n", __func__, retval); goto switch_to_dj_mode_fail; } /* This is enabling the polling urb on the IN endpoint */ retval = hdev->ll_driver->open(hdev); if (retval < 0) { dev_err(&hdev->dev, "%s:hdev->ll_driver->open returned " "error:%d\n", __func__, retval); goto llopen_failed; } retval = logi_dj_recv_query_paired_devices(djrcv_dev); if (retval < 0) { dev_err(&hdev->dev, "%s:logi_dj_recv_query_paired_devices " "error:%d\n", __func__, retval); goto logi_dj_recv_query_paired_devices_failed; } return retval; logi_dj_recv_query_paired_devices_failed: hdev->ll_driver->close(hdev); llopen_failed: switch_to_dj_mode_fail: hid_hw_stop(hdev); hid_hw_start_fail: hid_parse_fail: kfifo_free(&djrcv_dev->notif_fifo); kfree(djrcv_dev); hid_set_drvdata(hdev, NULL); return retval; }
static int rmi_hid_probe(struct hid_device *hdev, const struct hid_device_id *id) { struct rmi_transport_device *xport = NULL; struct rmi_hid_data *data = NULL; unsigned int connect_mask = HID_CONNECT_HIDRAW | HID_CONNECT_HIDDEV; int ret; dev_dbg(&hdev->dev, "%s\n", __func__); xport = devm_kzalloc(&hdev->dev, sizeof(struct rmi_transport_device), GFP_KERNEL); if (!xport) { ret = -ENOMEM; goto err; } data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_hid_data), GFP_KERNEL); if (!data) { ret =-ENOMEM; goto err; } data->xport = xport; xport->data = data; xport->dev = &hdev->dev; xport->write_block = rmi_hid_write_block; xport->read_block = rmi_hid_read_block; xport->info.proto_type = RMI_PROTOCOL_HID; xport->info.proto = transport_proto_name; xport->post_reset = rmi_hid_post_reset; hid_set_drvdata(hdev, xport); ret = hid_parse(hdev); if (ret) { hid_err(hdev, "parse failed\n"); goto err; } data->input_report_size = (hdev->report_enum[HID_INPUT_REPORT] .report_id_hash[RMI_ATTN_REPORT_ID]->size >> 3) + 1 /* report id */; data->output_report_size = (hdev->report_enum[HID_OUTPUT_REPORT] .report_id_hash[RMI_WRITE_REPORT_ID]->size >> 3) + 1 /* report id */; data->feature_report_size = (hdev->report_enum[HID_FEATURE_REPORT] .report_id_hash[RMI_SET_RMI_MODE_REPORT_ID]->size >> 3) + 1 /* report id */; dev_dbg(&hdev->dev, "input report size %d\n", data->input_report_size); dev_dbg(&hdev->dev, "output report size %d\n", data->output_report_size); dev_dbg(&hdev->dev, "feature report size %d\n", data->feature_report_size); data->input_queue = devm_kzalloc(&hdev->dev, data->input_report_size * RMI_HID_INPUT_REPORT_QUEUE_LEN, GFP_KERNEL); if (!data->input_queue) { ret = -ENOMEM; goto err; } data->writeReport = devm_kzalloc(&hdev->dev, data->output_report_size, GFP_KERNEL); if (!data->writeReport) { ret = -ENOMEM; goto err; } data->readReport = devm_kzalloc(&hdev->dev, data->input_report_size, GFP_KERNEL); if (!data->readReport) { ret = -ENOMEM; goto err; } data->attnReport = devm_kzalloc(&hdev->dev, data->input_report_size, GFP_KERNEL); if (!data->attnReport) { ret = -ENOMEM; goto err; } tp_platformdata.pm_data = hdev; xport->dev->platform_data = &tp_platformdata; #ifdef TOUCHPAD_WAKE_SYSTEM if (tp_platformdata.f11_sensor_data[0].sensor_type == rmi_sensor_touchpad) { device_init_wakeup(hdev->dev.parent, 1); } #endif spin_lock_init(&data->input_queue_consumer_lock); spin_lock_init(&data->input_queue_producer_lock); data->input_queue_head = 0; data->input_queue_tail = 0; INIT_WORK(&data->attn_report_work, rmi_hid_attn_report_work); INIT_WORK(&data->reset_work, rmi_hid_reset_work); init_waitqueue_head(&data->wait); mutex_init(&data->page_mutex); ret = hid_hw_start(hdev, connect_mask); if (ret) { hid_err(hdev, "hw start failed\n"); goto err; } dev_dbg(&hdev->dev, "Opening low level driver\n"); hdev->ll_driver->open(hdev); /* Allow incoming hid reports */ hid_device_io_start(hdev); ret = rmi_hid_set_mode(hdev, RMI_HID_MODE_ATTN_REPORTS); if (ret < 0) { dev_err(&hdev->dev, "failed to set rmi mode\n"); goto rmi_read_failed; } ret = rmi_set_page(xport, 0); if (ret < 0) { dev_err(&hdev->dev, "failed to set page select to 0.\n"); goto rmi_read_failed; } ret = rmi_register_transport_device(xport); if (ret) { dev_err(&hdev->dev, "failed to register transport device at %s\n", hdev->phys); goto rmi_read_failed; } if (!xport->probe_succeeded) { dev_err(&hdev->dev, "Probe failed in rmi_driver\n"); ret = -ENODEV; goto rmi_driver_probe_failed; } set_bit(RMI_HID_STARTED, &data->flags); if (IS_ENABLED(CONFIG_RMI4_DEBUG)) ret = setup_debugfs(xport->rmi_dev, data); dev_info(&hdev->dev, "registered rmi hid driver at %s\n", hdev->phys); return 0; rmi_driver_probe_failed: rmi_unregister_transport_device(xport); rmi_read_failed: hdev->ll_driver->close(hdev); hid_hw_stop(hdev); err: return ret; }
/** * Probe method is ran whenever a device is binded to the driver * * TODO remove goto's */ static int razer_kbd_probe(struct hid_device *hdev, const struct hid_device_id *id) { int retval; struct usb_interface *intf = to_usb_interface(hdev->dev.parent); struct usb_device *usb_dev = interface_to_usbdev(intf); struct razer_kbd_device *dev = NULL; dev = kzalloc(sizeof(struct razer_kbd_device), GFP_KERNEL); if(dev == NULL) { dev_err(&intf->dev, "out of memory\n"); retval = -ENOMEM; goto exit; } if(usb_dev->descriptor.idProduct == USB_DEVICE_ID_RAZER_BLACKWIDOW_ULTIMATE_2013) { retval = device_create_file(&hdev->dev, &dev_attr_mode_pulsate); if (retval) goto exit_free; } else { retval = device_create_file(&hdev->dev, &dev_attr_mode_wave); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_mode_spectrum); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_mode_none); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_mode_reactive); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_mode_breath); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_mode_custom); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_temp_clear_row); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_set_key_row); if (retval) goto exit_free; } retval = device_create_file(&hdev->dev, &dev_attr_get_serial); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_device_type); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_mode_game); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_mode_static); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_reset); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_macro_keys); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_set_brightness); if (retval) goto exit_free; retval = device_create_file(&hdev->dev, &dev_attr_test); if (retval) goto exit_free; hid_set_drvdata(hdev, dev); retval = hid_parse(hdev); if(retval) { hid_err(hdev, "parse failed\n"); goto exit_free; } retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (retval) { hid_err(hdev, "hw start failed\n"); goto exit_free; } razer_reset(usb_dev); usb_disable_autosuspend(usb_dev); //razer_activate_macro_keys(usb_dev); //msleep(3000); return 0; exit: return retval; exit_free: kfree(dev); return retval; }
/** * Probe method is ran whenever a device is binded to the driver * * TODO remove goto's */ static int razer_mousemat_probe(struct hid_device *hdev, const struct hid_device_id *id) { int retval = 0; struct usb_interface *intf = to_usb_interface(hdev->dev.parent); struct usb_device *usb_dev = interface_to_usbdev(intf); struct razer_mousemat_device *dev = NULL; dev = kzalloc(sizeof(struct razer_mousemat_device), GFP_KERNEL); if(dev == NULL) { dev_err(&intf->dev, "out of memory\n"); retval = -ENOMEM; goto exit; } if(intf->cur_altsetting->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) { switch(usb_dev->descriptor.idProduct) { case USB_DEVICE_ID_RAZER_GOLIATHUS_CHROMA: case USB_DEVICE_ID_RAZER_GOLIATHUS_CHROMA_EXTENDED: CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_version); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_custom_frame); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_reactive_trigger); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_spectrum); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_none); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_reactive); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_breath); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_custom); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_serial); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_firmware_version); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_type); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_static); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_brightness); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_mode); // Device initial brightness is always 100% anyway saved_brightness = 0xFF; break; default: CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_version); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_custom_frame); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_reactive_trigger); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_wave); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_spectrum); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_none); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_reactive); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_breath); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_custom); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_serial); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_firmware_version); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_type); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_static); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_brightness); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_mode); break; } } if (retval) goto exit_free; hid_set_drvdata(hdev, dev); retval = hid_parse(hdev); if(retval) { hid_err(hdev, "parse failed\n"); goto exit_free; } retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (retval) { hid_err(hdev, "hw start failed\n"); goto exit_free; } usb_disable_autosuspend(usb_dev); return 0; exit: return retval; exit_free: kfree(dev); return retval; }
static int g19_probe(struct hid_device *hdev, const struct hid_device_id *id) { unsigned long irq_flags; int error; struct g19_data *data; int i; int led_num; struct usb_interface *intf; struct usb_device *usbdev; struct list_head *feature_report_list = &hdev->report_enum[HID_FEATURE_REPORT].report_list; struct hid_report *report; char *led_name; dev_dbg(&hdev->dev, "Logitech G19 HID hardware probe..."); /* Get the usb device to send the start report on */ intf = to_usb_interface(hdev->dev.parent); usbdev = interface_to_usbdev(intf); /* * Let's allocate the g19 data structure, set some reasonable * defaults, and associate it with the device */ data = kzalloc(sizeof(struct g19_data), GFP_KERNEL); if (data == NULL) { dev_err(&hdev->dev, "can't allocate space for Logitech G19 device attributes\n"); error = -ENOMEM; goto err_no_cleanup; } spin_lock_init(&data->lock); init_completion(&data->ready); data->hdev = hdev; data->ep1_urb = usb_alloc_urb(0, GFP_KERNEL); if (data->ep1_urb == NULL) { dev_err(&hdev->dev, G19_NAME ": ERROR: can't alloc ep1 urb stuff\n"); error = -ENOMEM; goto err_cleanup_data; } hid_set_drvdata(hdev, data); dbg_hid("Preparing to parse " G19_NAME " hid reports\n"); /* Parse the device reports and start it up */ error = hid_parse(hdev); if (error) { dev_err(&hdev->dev, G19_NAME " device report parse failed\n"); error = -EINVAL; goto err_cleanup_ep1_urb; } error = hid_hw_start(hdev, HID_CONNECT_DEFAULT | HID_CONNECT_HIDINPUT_FORCE); if (error) { dev_err(&hdev->dev, G19_NAME " hardware start failed\n"); error = -EINVAL; goto err_cleanup_ep1_urb; } dbg_hid(G19_NAME " claimed: %d\n", hdev->claimed); error = hdev->ll_driver->open(hdev); if (error) { dev_err(&hdev->dev, G19_NAME " failed to open input interrupt pipe for key and joystick events\n"); error = -EINVAL; goto err_cleanup_ep1_urb; } /* Set up the input device for the key I/O */ data->input_dev = input_allocate_device(); if (data->input_dev == NULL) { dev_err(&hdev->dev, G19_NAME " error initializing the input device"); error = -ENOMEM; goto err_cleanup_ep1_urb; } input_set_drvdata(data->input_dev, hdev); data->input_dev->name = G19_NAME; data->input_dev->phys = hdev->phys; data->input_dev->uniq = hdev->uniq; data->input_dev->id.bustype = hdev->bus; data->input_dev->id.vendor = hdev->vendor; data->input_dev->id.product = hdev->product; data->input_dev->id.version = hdev->version; data->input_dev->dev.parent = hdev->dev.parent; data->input_dev->keycode = data->keycode; data->input_dev->keycodemax = G19_KEYMAP_SIZE; data->input_dev->keycodesize = sizeof(int); data->input_dev->setkeycode = g19_input_setkeycode; data->input_dev->getkeycode = g19_input_getkeycode; input_set_capability(data->input_dev, EV_KEY, KEY_UNKNOWN); data->input_dev->evbit[0] |= BIT_MASK(EV_REP); g19_initialize_keymap(data); error = input_register_device(data->input_dev); if (error) { dev_err(&hdev->dev, G19_NAME " error registering the input device"); error = -EINVAL; goto err_cleanup_input_dev; } if (list_empty(feature_report_list)) { dev_err(&hdev->dev, "no feature report found\n"); error = -ENODEV; goto err_cleanup_input_dev_reg; } dbg_hid(G19_NAME " feature report found\n"); list_for_each_entry(report, feature_report_list, list) { switch (report->id) { case 0x04: data->feature_report_4 = report; break; case 0x05: data->led_report = report; break; case 0x06: data->start_input_report = report; break; case 0x07: data->backlight_report = report; break; default: break; } dbg_hid(G19_NAME " Feature report: id=%u type=%u size=%u maxfield=%u report_count=%u\n", report->id, report->type, report->size, report->maxfield, report->field[0]->report_count); } dbg_hid("Found all reports\n"); /* Create the LED structures */ for (i = 0; i < LED_COUNT; i++) { data->led_cdev[i] = kzalloc(sizeof(struct led_classdev), GFP_KERNEL); if (data->led_cdev[i] == NULL) { dev_err(&hdev->dev, G19_NAME " error allocating memory for led %d", i); error = -ENOMEM; goto err_cleanup_led_structs; } /* Set the accessor functions by copying from template*/ *(data->led_cdev[i]) = g19_led_cdevs[i]; /* * Allocate memory for the LED name * * Since led_classdev->name is a const char* we'll use an * intermediate until the name is formatted with sprintf(). */ led_name = kzalloc(sizeof(char)*20, GFP_KERNEL); if (led_name == NULL) { dev_err(&hdev->dev, G19_NAME " error allocating memory for led %d name", i); error = -ENOMEM; goto err_cleanup_led_structs; } switch (i) { case G19_LED_M1: case G19_LED_M2: case G19_LED_M3: sprintf(led_name, "g19_%d:orange:m%d", hdev->minor, i+1); break; case G19_LED_MR: sprintf(led_name, "g19_%d:red:mr", hdev->minor); break; case G19_LED_BL_R: sprintf(led_name, "g19_%d:red:bl", hdev->minor); break; case G19_LED_BL_G: sprintf(led_name, "g19_%d:green:bl", hdev->minor); break; case G19_LED_BL_B: sprintf(led_name, "g19_%d:blue:bl", hdev->minor); break; case G19_LED_BL_SCREEN: sprintf(led_name, "g19_%d:white:screen", hdev->minor); break; } data->led_cdev[i]->name = led_name; } for (i = 0; i < LED_COUNT; i++) { led_num = i; error = led_classdev_register(&hdev->dev, data->led_cdev[i]); if (error < 0) { dev_err(&hdev->dev, G19_NAME " error registering led %d", i); error = -EINVAL; goto err_cleanup_registered_leds; } } data->gfb_data = gfb_probe(hdev, GFB_PANEL_TYPE_320_240_16); if (data->gfb_data == NULL) { dev_err(&hdev->dev, G19_NAME " error registering framebuffer\n"); goto err_cleanup_registered_leds; } dbg_hid("Waiting for G19 to activate\n"); /* Add the sysfs attributes */ error = sysfs_create_group(&(hdev->dev.kobj), &g19_attr_group); if (error) { dev_err(&hdev->dev, G19_NAME " failed to create sysfs group attributes\n"); goto err_cleanup_registered_leds; } /* * Wait here for stage 1 (substages 1-3) to complete */ wait_for_completion_timeout(&data->ready, HZ); /* Protect data->ready_stages before checking whether we're ready to proceed */ spin_lock_irqsave(&data->lock, irq_flags); if (data->ready_stages != G19_READY_STAGE_1) { dev_warn(&hdev->dev, G19_NAME " hasn't completed stage 1 yet, forging ahead with initialization\n"); /* Force the stage */ data->ready_stages = G19_READY_STAGE_1; } init_completion(&data->ready); data->ready_stages |= G19_READY_SUBSTAGE_4; spin_unlock_irqrestore(&data->lock, irq_flags); /* * Send the init report, then follow with the input report to trigger * report 6 and wait for us to get a response. */ g19_feature_report_4_send(hdev, G19_REPORT_4_INIT); usbhid_submit_report(hdev, data->start_input_report, USB_DIR_IN); wait_for_completion_timeout(&data->ready, HZ); /* Protect data->ready_stages before checking whether we're ready to proceed */ spin_lock_irqsave(&data->lock, irq_flags); if (data->ready_stages != G19_READY_STAGE_2) { dev_warn(&hdev->dev, G19_NAME " hasn't completed stage 2 yet, forging ahead with initialization\n"); /* Force the stage */ data->ready_stages = G19_READY_STAGE_2; } init_completion(&data->ready); data->ready_stages |= G19_READY_SUBSTAGE_6; spin_unlock_irqrestore(&data->lock, irq_flags); /* * Clear the LEDs */ g19_led_send(hdev); data->rgb[0] = G19_DEFAULT_RED; data->rgb[1] = G19_DEFAULT_GREEN; data->rgb[2] = G19_DEFAULT_BLUE; g19_rgb_send(hdev); data->screen_bl = G19_DEFAULT_BRIGHTNESS; g19_screen_bl_send(hdev); /* * Send the finalize report, then follow with the input report to trigger * report 6 and wait for us to get a response. */ g19_feature_report_4_send(hdev, G19_REPORT_4_FINALIZE); usbhid_submit_report(hdev, data->start_input_report, USB_DIR_IN); usbhid_submit_report(hdev, data->start_input_report, USB_DIR_IN); wait_for_completion_timeout(&data->ready, HZ); /* Protect data->ready_stages before checking whether we're ready to proceed */ spin_lock_irqsave(&data->lock, irq_flags); if (data->ready_stages != G19_READY_STAGE_3) { dev_warn(&hdev->dev, G19_NAME " hasn't completed stage 3 yet, forging ahead with initialization\n"); /* Force the stage */ data->ready_stages = G19_READY_STAGE_3; } else { dbg_hid(G19_NAME " stage 3 complete\n"); } spin_unlock_irqrestore(&data->lock, irq_flags); g19_set_keymap_switching(hdev, 1); g19_ep1_read(hdev); dbg_hid("G19 activated and initialized\n"); /* Everything went well */ return 0; err_cleanup_registered_leds: for (i = 0; i < led_num; i++) led_classdev_unregister(data->led_cdev[i]); err_cleanup_led_structs: for (i = 0; i < LED_COUNT; i++) { if (data->led_cdev[i] != NULL) { if (data->led_cdev[i]->name != NULL) kfree(data->led_cdev[i]->name); kfree(data->led_cdev[i]); } } err_cleanup_input_dev_reg: input_unregister_device(data->input_dev); err_cleanup_input_dev: input_free_device(data->input_dev); err_cleanup_ep1_urb: usb_free_urb(data->ep1_urb); err_cleanup_data: /* Make sure we clean up the allocated data structure */ kfree(data); err_no_cleanup: hid_set_drvdata(hdev, NULL); return error; }
static int ntrig_usbhid_probe(struct hid_device *hdev, const struct hid_device_id *id) { char phys_path[256]; int ret; struct ntrig_usbhid_data* nd; struct usb_interface* intf; struct usb_device* dev; struct usb_host_interface* interface; struct usb_endpoint_descriptor* endpoint; struct _ntrig_dev_ncp_func ncp_func; struct _ntrig_dev_hid_func hid_func; intf = to_usb_interface(hdev->dev.parent); dev = interface_to_usbdev(intf); interface= intf->cur_altsetting; endpoint = &interface->endpoint[0].desc; nd = kmalloc(sizeof(struct ntrig_usbhid_data), GFP_KERNEL); if (!nd) { dev_err(&hdev->dev, "cannot allocate N-Trig data\n"); return -ENOMEM; } if(DTRG_NO_ERROR != allocate_device(&nd->ntrig_dispatcher)){ dev_err(&hdev->dev, "cannot allocate N-Trig dispatcher\n"); return DTRG_FAILED; } hid_set_drvdata(hdev, nd); ret = hid_parse(hdev); if (ret) { dev_err(&hdev->dev, "parse failed, error code=%d\n", ret); goto err_free; } if (NCP_EP_ADDRESS == endpoint->bEndpointAddress) { ret = hid_hw_start(hdev, ~HID_QUIRK_MULTI_INPUT); if (ret) { dev_err(&hdev->dev, "hw start failed NCP, error code=%d\n", ret); goto err_free; } /* register device in the dispatcher - set device and function pointers for ncp set sensor id in the device data structure */ // NOTE: registration of ncp_read, ncp_write & dev is linked. // It's the resposibility of this function to set these parameters together ncp_func.dev = (void *) hdev; ncp_func.read = NTRIGReadNCP; ncp_func.write = NTRIGWriteNCP; nd->sensor_id = RegNtrigDispatcher(TYPE_BUS_USB_HID, hdev->uniq, &ncp_func, NULL); // TODO: define behavior in case of fail if (nd->sensor_id == DTRG_FAILED) { ntrig_dbg("%s: Cannot register device to dispatcher\n", __FUNCTION__); goto err_free; } ntrig_dbg("%s NCP dev registered with dispatcher, bus_id = %s, sensor_id = %d\n", __FUNCTION__, hdev->uniq, nd->sensor_id); return 0; } else { ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { dev_err(&hdev->dev, "hw start failed TOUCH, error code=%d\n", ret); goto err_free; } ret = ntrig_usbhid_send_report(hdev, REPORTID_DRIVER_ALIVE, NULL, 0); if (ret < 0) { dev_err(&hdev->dev, "send set feature failed, error code=%d\n", ret); goto err_free; } /* register device in the dispatcher - no need to set device and function pointers for touch events set sensor id in the device data structure */ // NOTE: registration of ncp_read, ncp_write & dev is linked. // It's the resposibility of this function to set these parameters together hid_func.dev = (void *)hdev; hid_func.read = NTRIGReadSensor; hid_func.write = NTRIGWriteSensor; nd->sensor_id = RegNtrigDispatcher(TYPE_BUS_USB_HID, hdev->uniq, NULL, &hid_func); // TODO: define behavior in case of fail if (nd->sensor_id == DTRG_FAILED) { ntrig_dbg("%s: Cannot register device to dispatcher\n", __FUNCTION__); goto err_free; } ntrig_dbg("%s HID dev registered with dispatcher, bus_id = %s, sensor_id = %d\n", __FUNCTION__, hdev->uniq, nd->sensor_id); } /** * Create additional single touch queue */ usb_make_path(dev, phys_path, sizeof(phys_path)); strlcat(phys_path, "/input0", sizeof(phys_path)); nd->ntrig_dispatcher->phys = phys_path; nd->ntrig_dispatcher->name = "USBHID"; nd->ntrig_dispatcher->pressure_min= 0; nd->ntrig_dispatcher->pressure_max= 0xFF; create_single_touch(nd->ntrig_dispatcher, nd->sensor_id); create_multi_touch (nd->ntrig_dispatcher, nd->sensor_id); nd->battery_status = PEN_BUTTON_BATTERY_NOT_AVAILABLE; ntrig_dbg("Iside %s, bus_id = %d, name = %s, phys = %s, uniq = %s\n", __FUNCTION__, hdev->bus, hdev->name, hdev->phys, hdev->uniq ); ntrig_dbg("End of %s\n", __FUNCTION__); return DTRG_NO_ERROR; err_free: ntrig_dbg("Error End of %s\n", __FUNCTION__); remove_device(&nd->ntrig_dispatcher); kfree(nd); return DTRG_FAILED; }
static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) { unsigned int connect_mask = HID_CONNECT_DEFAULT; struct lg_drv_data *drv_data; int ret; drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL); if (!drv_data) { hid_err(hdev, "Insufficient memory, cannot allocate driver data\n"); return -ENOMEM; } drv_data->quirks = id->driver_data; hid_set_drvdata(hdev, (void *)drv_data); if (drv_data->quirks & LG_NOGET) hdev->quirks |= HID_QUIRK_NOGET; ret = hid_parse(hdev); if (ret) { hid_err(hdev, "parse failed\n"); goto err_free; } if (drv_data->quirks & (LG_FF | LG_FF2 | LG_FF3 | LG_FF4)) connect_mask &= ~HID_CONNECT_FF; ret = hid_hw_start(hdev, connect_mask); if (ret) { hid_err(hdev, "hw start failed\n"); goto err_free; } /* Setup wireless link with Logitech Wii wheel */ if (hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) { unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf), HID_FEATURE_REPORT, HID_REQ_SET_REPORT); if (ret >= 0) { /* insert a little delay of 10 jiffies ~ 40ms */ wait_queue_head_t wait; init_waitqueue_head (&wait); wait_event_interruptible_timeout(wait, 0, 10); /* Select random Address */ buf[1] = 0xB2; get_random_bytes(&buf[2], 2); ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf), HID_FEATURE_REPORT, HID_REQ_SET_REPORT); } } if (drv_data->quirks & LG_FF) lgff_init(hdev); if (drv_data->quirks & LG_FF2) lg2ff_init(hdev); if (drv_data->quirks & LG_FF3) lg3ff_init(hdev); if (drv_data->quirks & LG_FF4) lg4ff_init(hdev); return 0; err_free: kfree(drv_data); return ret; }
static int g15_probe(struct hid_device *hdev, const struct hid_device_id *id) { unsigned long irq_flags; int error; struct gcommon_data *gdata; struct g15_data *g15data; int i; int led_num; struct usb_interface *intf; struct usb_device *usbdev; struct list_head *feature_report_list = &hdev->report_enum[HID_FEATURE_REPORT].report_list; struct list_head *output_report_list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list; struct hid_report *report; char *led_name; dev_dbg(&hdev->dev, "Logitech G15 HID hardware probe..."); /* Get the usb device to send the start report on */ intf = to_usb_interface(hdev->dev.parent); usbdev = interface_to_usbdev(intf); /* * Let's allocate the g15 data structure, set some reasonable * defaults, and associate it with the device */ gdata = kzalloc(sizeof(struct gcommon_data), GFP_KERNEL); if (gdata == NULL) { dev_err(&hdev->dev, "can't allocate space for Logitech G15 device attributes\n"); error = -ENOMEM; goto err_no_cleanup; } g15data = kzalloc(sizeof(struct g15_data), GFP_KERNEL); if (g15data == NULL) { dev_err(&hdev->dev, "can't allocate space for Logitech G15 device attributes\n"); error = -ENOMEM; goto err_cleanup_gdata; } gdata->data = g15data; spin_lock_init(&gdata->lock); init_completion(&g15data->ready); gdata->hdev = hdev; hid_set_drvdata(hdev, gdata); dbg_hid("Preparing to parse " G15_NAME " hid reports\n"); /* Parse the device reports and start it up */ error = hid_parse(hdev); if (error) { dev_err(&hdev->dev, G15_NAME " device report parse failed\n"); error = -EINVAL; goto err_cleanup_g15data; } error = hid_hw_start(hdev, HID_CONNECT_DEFAULT | HID_CONNECT_HIDINPUT_FORCE); if (error) { dev_err(&hdev->dev, G15_NAME " hardware start failed\n"); error = -EINVAL; goto err_cleanup_g15data; } dbg_hid(G15_NAME " claimed: %d\n", hdev->claimed); error = hdev->ll_driver->open(hdev); if (error) { dev_err(&hdev->dev, G15_NAME " failed to open input interrupt pipe for key and joystick events\n"); error = -EINVAL; goto err_cleanup_g15data; } /* Set up the input device for the key I/O */ gdata->input_dev = input_allocate_device(); if (gdata->input_dev == NULL) { dev_err(&hdev->dev, G15_NAME " error initializing the input device"); error = -ENOMEM; goto err_cleanup_g15data; } input_set_drvdata(gdata->input_dev, gdata); gdata->input_dev->name = G15_NAME; gdata->input_dev->phys = hdev->phys; gdata->input_dev->uniq = hdev->uniq; gdata->input_dev->id.bustype = hdev->bus; gdata->input_dev->id.vendor = hdev->vendor; gdata->input_dev->id.product = hdev->product; gdata->input_dev->id.version = hdev->version; gdata->input_dev->dev.parent = hdev->dev.parent; gdata->input_dev->keycode = gdata->input_data.keycode; gdata->input_dev->keycodemax = G15_KEYMAP_SIZE; gdata->input_dev->keycodesize = sizeof(int); gdata->input_dev->setkeycode = ginput_setkeycode; gdata->input_dev->getkeycode = ginput_getkeycode; input_set_capability(gdata->input_dev, EV_KEY, KEY_UNKNOWN); gdata->input_dev->evbit[0] |= BIT_MASK(EV_REP); gdata->input_data.notify_keymap_switched = g15_notify_keymap_switched; error = ginput_alloc(gdata, G15_KEYS); if (error) { dev_err(&hdev->dev, G15_NAME " error allocating memory for the input device"); goto err_cleanup_input_dev; } g15_initialize_keymap(gdata); error = input_register_device(gdata->input_dev); if (error) { dev_err(&hdev->dev, G15_NAME " error registering the input device"); error = -EINVAL; goto err_cleanup_input_dev_data; } dbg_hid(KERN_INFO G15_NAME " allocated framebuffer\n"); dbg_hid(KERN_INFO G15_NAME " allocated deferred IO structure\n"); if (list_empty(feature_report_list)) { dev_err(&hdev->dev, "no feature report found\n"); error = -ENODEV; goto err_cleanup_input_dev_reg; } dbg_hid(G15_NAME " feature report found\n"); list_for_each_entry(report, feature_report_list, list) { switch (report->id) { case 0x02: /* G15 has only one feature report 0x02 */ g15data->feature_report_4 = g15data->led_report = g15data->start_input_report = g15data->backlight_report = report; break; default: break; } dbg_hid(G15_NAME " Feature report: id=%u type=%u size=%u maxfield=%u report_count=%u\n", report->id, report->type, report->size, report->maxfield, report->field[0]->report_count); } if (list_empty(output_report_list)) { dev_err(&hdev->dev, "no output report found\n"); error = -ENODEV; goto err_cleanup_input_dev_reg; } dbg_hid(G15_NAME " output report found\n"); list_for_each_entry(report, output_report_list, list) { dbg_hid(G15_NAME " output report %d found size=%u maxfield=%u\n", report->id, report->size, report->maxfield); if (report->maxfield > 0) { dbg_hid(G15_NAME " offset=%u size=%u count=%u type=%u\n", report->field[0]->report_offset, report->field[0]->report_size, report->field[0]->report_count, report->field[0]->report_type); } switch (report->id) { case 0x03: g15data->output_report_3 = report; break; } }
/** * Probe method is ran whenever a device is binded to the driver * * TODO remove goto's */ static int razer_core_probe(struct hid_device *hdev, const struct hid_device_id *id) { int retval = 0; struct usb_interface *intf = to_usb_interface(hdev->dev.parent); struct usb_device *usb_dev = interface_to_usbdev(intf); struct razer_core_device *dev = NULL; dev = kzalloc(sizeof(struct razer_core_device), GFP_KERNEL); if(dev == NULL) { dev_err(&intf->dev, "out of memory\n"); retval = -ENOMEM; goto exit; } // Initialise mutex mutex_init(&dev->lock); // Setup values dev->usb_dev = usb_dev; CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_version); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_custom_frame); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_wave); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_spectrum); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_none); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_reactive); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_breath); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_custom); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_serial); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_firmware_version); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_type); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_static); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_brightness); CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_device_mode); if (retval) { goto exit_free; } dev_set_drvdata(&hdev->dev, dev); hid_set_drvdata(hdev, dev); retval = hid_parse(hdev); if(retval) { hid_err(hdev, "parse failed\n"); goto exit_free; } retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (retval) { hid_err(hdev, "hw start failed\n"); goto exit_free; } usb_disable_autosuspend(usb_dev); return 0; exit: return retval; exit_free: kfree(dev); return retval; }
static int logi_dj_probe(struct hid_device *hdev, const struct hid_device_id *id) { struct usb_interface *intf = to_usb_interface(hdev->dev.parent); struct dj_receiver_dev *djrcv_dev; int retval; if (is_dj_device((struct dj_device *)hdev->driver_data)) return -ENODEV; dbg_hid("%s called for ifnum %d\n", __func__, intf->cur_altsetting->desc.bInterfaceNumber); if (intf->cur_altsetting->desc.bInterfaceNumber != LOGITECH_DJ_INTERFACE_NUMBER) { dbg_hid("%s: ignoring ifnum %d\n", __func__, intf->cur_altsetting->desc.bInterfaceNumber); return -ENODEV; } djrcv_dev = kzalloc(sizeof(struct dj_receiver_dev), GFP_KERNEL); if (!djrcv_dev) { dev_err(&hdev->dev, "%s:failed allocating dj_receiver_dev\n", __func__); return -ENOMEM; } djrcv_dev->hdev = hdev; INIT_WORK(&djrcv_dev->work, delayedwork_callback); spin_lock_init(&djrcv_dev->lock); if (kfifo_alloc(&djrcv_dev->notif_fifo, DJ_MAX_NUMBER_NOTIFICATIONS * sizeof(struct dj_report), GFP_KERNEL)) { dev_err(&hdev->dev, "%s:failed allocating notif_fifo\n", __func__); kfree(djrcv_dev); return -ENOMEM; } hid_set_drvdata(hdev, djrcv_dev); retval = hid_parse(hdev); if (retval) { dev_err(&hdev->dev, "%s:parse of interface 2 failed\n", __func__); goto hid_parse_fail; } retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (retval) { dev_err(&hdev->dev, "%s:hid_hw_start returned error\n", __func__); goto hid_hw_start_fail; } retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0); if (retval < 0) { dev_err(&hdev->dev, "%s:logi_dj_recv_switch_to_dj_mode returned error:%d\n", __func__, retval); goto switch_to_dj_mode_fail; } retval = hdev->ll_driver->open(hdev); if (retval < 0) { dev_err(&hdev->dev, "%s:hdev->ll_driver->open returned " "error:%d\n", __func__, retval); goto llopen_failed; } retval = logi_dj_recv_query_paired_devices(djrcv_dev); if (retval < 0) { dev_err(&hdev->dev, "%s:logi_dj_recv_query_paired_devices " "error:%d\n", __func__, retval); goto logi_dj_recv_query_paired_devices_failed; } return retval; logi_dj_recv_query_paired_devices_failed: hdev->ll_driver->close(hdev); llopen_failed: switch_to_dj_mode_fail: hid_hw_stop(hdev); hid_hw_start_fail: hid_parse_fail: kfifo_free(&djrcv_dev->notif_fifo); kfree(djrcv_dev); hid_set_drvdata(hdev, NULL); return retval; }
static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) { struct usb_interface *iface = to_usb_interface(hdev->dev.parent); __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber; unsigned int connect_mask = HID_CONNECT_DEFAULT; struct lg_drv_data *drv_data; int ret; /* G29 only work with the 1st interface */ if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) && (iface_num != 0)) { dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num); return -ENODEV; } drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL); if (!drv_data) { hid_err(hdev, "Insufficient memory, cannot allocate driver data\n"); return -ENOMEM; } drv_data->quirks = id->driver_data; hid_set_drvdata(hdev, (void *)drv_data); if (drv_data->quirks & LG_NOGET) hdev->quirks |= HID_QUIRK_NOGET; ret = hid_parse(hdev); if (ret) { hid_err(hdev, "parse failed\n"); goto err_free; } if (drv_data->quirks & (LG_FF | LG_FF2 | LG_FF3 | LG_FF4)) connect_mask &= ~HID_CONNECT_FF; ret = hid_hw_start(hdev, connect_mask); if (ret) { hid_err(hdev, "hw start failed\n"); goto err_free; } /* Setup wireless link with Logitech Wii wheel */ if (hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) { unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf), HID_FEATURE_REPORT, HID_REQ_SET_REPORT); if (ret >= 0) { /* insert a little delay of 10 jiffies ~ 40ms */ wait_queue_head_t wait; init_waitqueue_head (&wait); wait_event_interruptible_timeout(wait, 0, msecs_to_jiffies(40)); /* Select random Address */ buf[1] = 0xB2; get_random_bytes(&buf[2], 2); ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf), HID_FEATURE_REPORT, HID_REQ_SET_REPORT); } } if (drv_data->quirks & LG_FF) ret = lgff_init(hdev); else if (drv_data->quirks & LG_FF2) ret = lg2ff_init(hdev); else if (drv_data->quirks & LG_FF3) ret = lg3ff_init(hdev); else if (drv_data->quirks & LG_FF4) ret = lg4ff_init(hdev); if (ret) goto err_free; return 0; err_free: kfree(drv_data); return ret; }
static void gfrm_remove(struct hid_device *hdev) { hid_hw_stop(hdev); hid_set_drvdata(hdev, NULL); }
static int mousevsc_probe(struct hv_device *device, const struct hv_vmbus_device_id *dev_id) { int ret; struct mousevsc_dev *input_dev; struct hid_device *hid_dev; input_dev = mousevsc_alloc_device(device); if (!input_dev) return -ENOMEM; ret = vmbus_open(device->channel, INPUTVSC_SEND_RING_BUFFER_SIZE, INPUTVSC_RECV_RING_BUFFER_SIZE, NULL, 0, mousevsc_on_channel_callback, device ); if (ret) goto probe_err0; ret = mousevsc_connect_to_vsp(device); if (ret) goto probe_err1; /* workaround SA-167 */ if (input_dev->report_desc[14] == 0x25) input_dev->report_desc[14] = 0x29; hid_dev = hid_allocate_device(); if (IS_ERR(hid_dev)) { ret = PTR_ERR(hid_dev); goto probe_err1; } hid_dev->ll_driver = &mousevsc_ll_driver; hid_dev->driver = &mousevsc_hid_driver; hid_dev->bus = BUS_VIRTUAL; hid_dev->vendor = input_dev->hid_dev_info.vendor; hid_dev->product = input_dev->hid_dev_info.product; hid_dev->version = input_dev->hid_dev_info.version; input_dev->hid_device = hid_dev; sprintf(hid_dev->name, "%s", "Microsoft Vmbus HID-compliant Mouse"); hid_set_drvdata(hid_dev, device); ret = hid_add_device(hid_dev); if (ret) goto probe_err1; ret = hid_parse(hid_dev); if (ret) { hid_err(hid_dev, "parse failed\n"); goto probe_err2; } ret = hid_hw_start(hid_dev, HID_CONNECT_HIDINPUT | HID_CONNECT_HIDDEV); if (ret) { hid_err(hid_dev, "hw start failed\n"); goto probe_err2; } input_dev->connected = true; input_dev->init_complete = true; return ret; probe_err2: hid_destroy_device(hid_dev); probe_err1: vmbus_close(device->channel); probe_err0: mousevsc_free_device(input_dev); return ret; }
static int lenovo_probe_tpkbd(struct hid_device *hdev) { struct device *dev = &hdev->dev; struct lenovo_drvdata_tpkbd *data_pointer; size_t name_sz = strlen(dev_name(dev)) + 16; char *name_mute, *name_micmute; int i; int ret; /* * Only register extra settings against subdevice where input_mapping * set drvdata to 1, i.e. the trackpoint. */ if (!hid_get_drvdata(hdev)) return 0; hid_set_drvdata(hdev, NULL); /* Validate required reports. */ for (i = 0; i < 4; i++) { if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1)) return -ENODEV; } if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 3, 0, 2)) return -ENODEV; ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd); if (ret) hid_warn(hdev, "Could not create sysfs group: %d\n", ret); data_pointer = devm_kzalloc(&hdev->dev, sizeof(struct lenovo_drvdata_tpkbd), GFP_KERNEL); if (data_pointer == NULL) { hid_err(hdev, "Could not allocate memory for driver data\n"); return -ENOMEM; } // set same default values as windows driver data_pointer->sensitivity = 0xa0; data_pointer->press_speed = 0x38; name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL); name_micmute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL); if (name_mute == NULL || name_micmute == NULL) { hid_err(hdev, "Could not allocate memory for led data\n"); return -ENOMEM; } snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev)); snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev)); hid_set_drvdata(hdev, data_pointer); data_pointer->led_mute.name = name_mute; data_pointer->led_mute.brightness_get = lenovo_led_brightness_get_tpkbd; data_pointer->led_mute.brightness_set = lenovo_led_brightness_set_tpkbd; data_pointer->led_mute.dev = dev; led_classdev_register(dev, &data_pointer->led_mute); data_pointer->led_micmute.name = name_micmute; data_pointer->led_micmute.brightness_get = lenovo_led_brightness_get_tpkbd; data_pointer->led_micmute.brightness_set = lenovo_led_brightness_set_tpkbd; data_pointer->led_micmute.dev = dev; led_classdev_register(dev, &data_pointer->led_micmute); lenovo_features_set_tpkbd(hdev); return 0; }