static int uinput_create_device(struct uinput_device *udev) { struct input_dev *dev = udev->dev; int error; if (udev->state != UIST_SETUP_COMPLETE) { printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME); return -EINVAL; } if (udev->ff_effects_max) { error = input_ff_create(dev, udev->ff_effects_max); if (error) goto fail1; dev->ff->upload = uinput_dev_upload_effect; dev->ff->erase = uinput_dev_erase_effect; dev->ff->playback = uinput_dev_playback; dev->ff->set_gain = uinput_dev_set_gain; dev->ff->set_autocenter = uinput_dev_set_autocenter; } error = input_register_device(udev->dev); if (error) goto fail2; udev->state = UIST_CREATED; return 0; fail2: input_ff_destroy(dev); fail1: uinput_destroy_device(udev); return error; }
static int __devinit twl4030_vibra_probe(struct platform_device *pdev) { struct twl4030_vibra_data *pdata = pdev->dev.platform_data; struct vibra_info *info; int ret; if (!pdata) { dev_dbg(&pdev->dev, "platform_data not available\n"); return -EINVAL; } info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; info->dev = &pdev->dev; info->coexist = pdata->coexist; INIT_WORK(&info->play_work, vibra_play_work); info->input_dev = input_allocate_device(); if (info->input_dev == NULL) { dev_err(&pdev->dev, "couldn't allocate input device\n"); ret = -ENOMEM; goto err_kzalloc; } input_set_drvdata(info->input_dev, info); info->input_dev->name = "twl4030:vibrator"; info->input_dev->id.version = 1; info->input_dev->dev.parent = pdev->dev.parent; info->input_dev->open = twl4030_vibra_open; info->input_dev->close = twl4030_vibra_close; __set_bit(FF_RUMBLE, info->input_dev->ffbit); ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); if (ret < 0) { dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n"); goto err_ialloc; } ret = input_register_device(info->input_dev); if (ret < 0) { dev_dbg(&pdev->dev, "couldn't register input device\n"); goto err_iff; } vibra_disable_leds(); platform_set_drvdata(pdev, info); return 0; err_iff: input_ff_destroy(info->input_dev); err_ialloc: input_free_device(info->input_dev); err_kzalloc: kfree(info); return ret; }
static int twl4030_vibra_probe(struct platform_device *pdev) { struct twl4030_vibra_data *pdata = dev_get_platdata(&pdev->dev); struct device_node *twl4030_core_node = pdev->dev.parent->of_node; struct vibra_info *info; int ret; if (!pdata && !twl4030_core_node) { dev_dbg(&pdev->dev, "platform_data not available\n"); return -EINVAL; } info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; info->dev = &pdev->dev; info->coexist = twl4030_vibra_check_coexist(pdata, twl4030_core_node); INIT_WORK(&info->play_work, vibra_play_work); info->input_dev = devm_input_allocate_device(&pdev->dev); if (info->input_dev == NULL) { dev_err(&pdev->dev, "couldn't allocate input device\n"); return -ENOMEM; } input_set_drvdata(info->input_dev, info); info->input_dev->name = "twl4030:vibrator"; info->input_dev->id.version = 1; info->input_dev->dev.parent = pdev->dev.parent; info->input_dev->close = twl4030_vibra_close; __set_bit(FF_RUMBLE, info->input_dev->ffbit); ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); if (ret < 0) { dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n"); return ret; } ret = input_register_device(info->input_dev); if (ret < 0) { dev_dbg(&pdev->dev, "couldn't register input device\n"); goto err_iff; } vibra_disable_leds(); platform_set_drvdata(pdev, info); return 0; err_iff: input_ff_destroy(info->input_dev); return ret; }
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct usb_xpad *xpad; struct input_dev *input_dev; struct usb_endpoint_descriptor *ep_irq_in; int ep_irq_in_idx; int i, error; for (i = 0; xpad_device[i].idVendor; i++) { if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct)) break; } if (xpad_device[i].xtype == XTYPE_XBOXONE && intf->cur_altsetting->desc.bInterfaceNumber != 0) { /* * The Xbox One controller lists three interfaces all with the * same interface class, subclass and protocol. Differentiate by * interface number. */ return -ENODEV; } xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); input_dev = input_allocate_device(); if (!xpad || !input_dev) { error = -ENOMEM; goto fail1; } xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, GFP_KERNEL, &xpad->idata_dma); if (!xpad->idata) { error = -ENOMEM; goto fail1; } xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_in) { error = -ENOMEM; goto fail2; } xpad->udev = udev; xpad->intf = intf; xpad->mapping = xpad_device[i].mapping; xpad->xtype = xpad_device[i].xtype; if (xpad->xtype == XTYPE_UNKNOWN) { if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) xpad->xtype = XTYPE_XBOX360W; else xpad->xtype = XTYPE_XBOX360; } else xpad->xtype = XTYPE_XBOX; if (dpad_to_buttons) xpad->mapping |= MAP_DPAD_TO_BUTTONS; if (triggers_to_buttons) xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS; if (sticks_to_null) xpad->mapping |= MAP_STICKS_TO_NULL; } xpad->dev = input_dev; usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); input_dev->name = xpad_device[i].name; input_dev->phys = xpad->phys; usb_to_input_id(udev, &input_dev->id); input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, xpad); input_dev->open = xpad_open; input_dev->close = xpad_close; input_dev->evbit[0] = BIT_MASK(EV_KEY); if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { input_dev->evbit[0] |= BIT_MASK(EV_ABS); /* set up axes */ for (i = 0; xpad_abs[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs[i]); } /* set up standard buttons */ for (i = 0; xpad_common_btn[i] >= 0; i++) __set_bit(xpad_common_btn[i], input_dev->keybit); /* set up model-specific ones */ if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W || xpad->xtype == XTYPE_XBOXONE) { for (i = 0; xpad360_btn[i] >= 0; i++) __set_bit(xpad360_btn[i], input_dev->keybit); } else { for (i = 0; xpad_btn[i] >= 0; i++) __set_bit(xpad_btn[i], input_dev->keybit); } if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { for (i = 0; xpad_btn_pad[i] >= 0; i++) __set_bit(xpad_btn_pad[i], input_dev->keybit); } else { for (i = 0; xpad_abs_pad[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_pad[i]); } if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { for (i = 0; xpad_btn_triggers[i] >= 0; i++) __set_bit(xpad_btn_triggers[i], input_dev->keybit); } else { for (i = 0; xpad_abs_triggers[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); } error = xpad_init_output(intf, xpad); if (error) goto fail3; error = xpad_init_ff(xpad); if (error) goto fail4; error = xpad_led_probe(xpad); if (error) goto fail5; /* Xbox One controller has in/out endpoints swapped. */ ep_irq_in_idx = xpad->xtype == XTYPE_XBOXONE ? 1 : 0; ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc; usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), xpad->idata, XPAD_PKT_LEN, xpad_irq_in, xpad, ep_irq_in->bInterval); xpad->irq_in->transfer_dma = xpad->idata_dma; xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; error = input_register_device(xpad->dev); if (error) goto fail6; usb_set_intfdata(intf, xpad); if (xpad->xtype == XTYPE_XBOX360W) { /* * Setup the message to set the LEDs on the * controller when it shows up */ xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->bulk_out) { error = -ENOMEM; goto fail7; } xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); if (!xpad->bdata) { error = -ENOMEM; goto fail8; } xpad->bdata[2] = 0x08; switch (intf->cur_altsetting->desc.bInterfaceNumber) { case 0: xpad->bdata[3] = 0x42; break; case 2: xpad->bdata[3] = 0x43; break; case 4: xpad->bdata[3] = 0x44; break; case 6: xpad->bdata[3] = 0x45; } ep_irq_in = &intf->cur_altsetting->endpoint[1].desc; if (usb_endpoint_is_bulk_out(ep_irq_in)) { usb_fill_bulk_urb(xpad->bulk_out, udev, usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress), xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad); } else { usb_fill_int_urb(xpad->bulk_out, udev, usb_sndintpipe(udev, ep_irq_in->bEndpointAddress), xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad, 0); } /* * Submit the int URB immediately rather than waiting for open * because we get status messages from the device whether * or not any controllers are attached. In fact, it's * exactly the message that a controller has arrived that * we're waiting for. */ xpad->irq_in->dev = xpad->udev; error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); if (error) goto fail9; } return 0; fail9: kfree(xpad->bdata); fail8: usb_free_urb(xpad->bulk_out); fail7: input_unregister_device(input_dev); input_dev = NULL; fail6: xpad_led_disconnect(xpad); fail5: if (input_dev) input_ff_destroy(input_dev); fail4: xpad_deinit_output(xpad); fail3: usb_free_urb(xpad->irq_in); fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); fail1: input_free_device(input_dev); kfree(xpad); return error; }
static int xpad_init_input(struct usb_xpad *xpad) { struct input_dev *input_dev; int i, error; input_dev = input_allocate_device(); if (!input_dev) return -ENOMEM; xpad->dev = input_dev; input_dev->name = xpad->name; input_dev->phys = xpad->phys; usb_to_input_id(xpad->udev, &input_dev->id); input_dev->dev.parent = &xpad->intf->dev; input_set_drvdata(input_dev, xpad); input_dev->open = xpad_open; input_dev->close = xpad_close; __set_bit(EV_KEY, input_dev->evbit); if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { __set_bit(EV_ABS, input_dev->evbit); /* set up axes */ for (i = 0; xpad_abs[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs[i]); } /* set up standard buttons */ for (i = 0; xpad_common_btn[i] >= 0; i++) __set_bit(xpad_common_btn[i], input_dev->keybit); /* set up model-specific ones */ if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W || xpad->xtype == XTYPE_XBOXONE) { for (i = 0; xpad360_btn[i] >= 0; i++) __set_bit(xpad360_btn[i], input_dev->keybit); } else { for (i = 0; xpad_btn[i] >= 0; i++) __set_bit(xpad_btn[i], input_dev->keybit); } if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { for (i = 0; xpad_btn_pad[i] >= 0; i++) __set_bit(xpad_btn_pad[i], input_dev->keybit); } /* * This should be a simple else block. However historically * xbox360w has mapped DPAD to buttons while xbox360 did not. This * made no sense, but now we can not just switch back and have to * support both behaviors. */ if (!(xpad->mapping & MAP_DPAD_TO_BUTTONS) || xpad->xtype == XTYPE_XBOX360W) { for (i = 0; xpad_abs_pad[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_pad[i]); } if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { for (i = 0; xpad_btn_triggers[i] >= 0; i++) __set_bit(xpad_btn_triggers[i], input_dev->keybit); } else { for (i = 0; xpad_abs_triggers[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); } error = xpad_init_ff(xpad); if (error) goto err_free_input; error = xpad_led_probe(xpad); if (error) goto err_destroy_ff; error = input_register_device(xpad->dev); if (error) goto err_disconnect_led; return 0; err_disconnect_led: xpad_led_disconnect(xpad); err_destroy_ff: input_ff_destroy(input_dev); err_free_input: input_free_device(input_dev); return error; }
static int max77660_haptic_probe(struct platform_device *pdev) { /* we register the parent platform data */ struct max77660_platform_data *parent_pdata; struct max77660_haptic_platform_data *haptic_pdata; struct max77660_haptic *chip; struct input_dev *input_dev; int ret; parent_pdata = dev_get_platdata(pdev->dev.parent); if (!parent_pdata) { dev_err(&pdev->dev, "no haptic parent platform data\n"); return -EINVAL; } if ((!parent_pdata->haptic_pdata) || !parent_pdata->haptic_pdata->pdata) { dev_err(&pdev->dev, "no haptic platform data\n"); return -EINVAL; } haptic_pdata = parent_pdata->haptic_pdata->pdata; chip = devm_kzalloc(&pdev->dev, sizeof(struct max77660_haptic), GFP_KERNEL); if (!chip) { dev_err(&pdev->dev, "unable to allocate memory\n"); return -ENOMEM; } input_dev = input_allocate_device(); if (!input_dev) { dev_err(&pdev->dev, "unable to allocate memory for input dev\n"); ret = -ENOMEM; goto err_input_alloc; } chip->dev = &pdev->dev; chip->input_dev = input_dev; chip->type = haptic_pdata->type; chip->mode = haptic_pdata->mode; if (chip->mode == MAX77660_INTERNAL_MODE) { chip->internal_mode_pattern = haptic_pdata->internal_mode_pattern; chip->pattern_cycle = haptic_pdata->pattern_cycle; chip->pattern_signal_period = haptic_pdata->pattern_signal_period; chip->feedback_duty_cycle = haptic_pdata->feedback_duty_cycle; chip->invert = haptic_pdata->invert; chip->cont_mode = haptic_pdata->cont_mode; chip->motor_startup_val = haptic_pdata->motor_startup_val; chip->scf_val = haptic_pdata->scf_val; } if (chip->mode == MAX77660_EXTERNAL_MODE) { chip->pwm = pwm_request(haptic_pdata->pwm_channel_id, "max-vbrtr"); if (IS_ERR(chip->pwm)) { dev_err(&pdev->dev, "unable to request PWM for haptic\n"); ret = PTR_ERR(chip->pwm); goto err_pwm; } } chip->regulator = regulator_get(&pdev->dev, "vdd_vbrtr"); if (IS_ERR(chip->regulator)) { dev_err(&pdev->dev, "unable to get regulator\n"); ret = PTR_ERR(chip->regulator); goto err_regulator; } register_input: dev_set_drvdata(&pdev->dev, chip); input_dev->name = MAX77660_HAPTIC_DRIVER_MATCHED_NAME; input_dev->id.version = 1; input_dev->dev.parent = &pdev->dev; input_set_drvdata(input_dev, chip); input_set_capability(input_dev, EV_FF, FF_RUMBLE); ret = input_ff_create_memless(input_dev, NULL, max77660_haptic_play_effect); if (ret) { dev_err(&pdev->dev, "unable to create FF device(ret : %d)\n", ret); goto err_ff_memless; } INIT_WORK(&chip->work, max77660_haptic_play_effect_work); ret = input_register_device(input_dev); if (ret) { dev_err(&pdev->dev, "unable to register input device(ret : %d)\n", ret); goto err_input_register; } ret = sysfs_create_group(&pdev->dev.kobj, &max77660_haptics_attr_group); if (ret < 0) dev_err(&pdev->dev, "unable to create sysfs %d\n", ret); return 0; err_input_register: destroy_work_on_stack(&chip->work); input_ff_destroy(input_dev); err_ff_memless: regulator_put(chip->regulator); err_regulator: if (chip->mode == MAX77660_EXTERNAL_MODE) pwm_free(chip->pwm); err_pwm: input_free_device(input_dev); err_input_alloc: dev_err(&pdev->dev, "Error: %s return ret=%d\n", __func__, ret); return ret; }
static int __devinit max8997_haptic_probe(struct platform_device *pdev) { struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); const struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev); const struct max8997_haptic_platform_data *haptic_pdata = pdata->haptic_pdata; struct max8997_haptic *chip; struct input_dev *input_dev; int error; if (!haptic_pdata) { dev_err(&pdev->dev, "no haptic platform data\n"); return -EINVAL; } chip = kzalloc(sizeof(struct max8997_haptic), GFP_KERNEL); input_dev = input_allocate_device(); if (!chip || !input_dev) { dev_err(&pdev->dev, "unable to allocate memory\n"); error = -ENOMEM; goto err_free_mem; } INIT_WORK(&chip->work, max8997_haptic_play_effect_work); mutex_init(&chip->mutex); chip->client = iodev->haptic; chip->dev = &pdev->dev; chip->input_dev = input_dev; chip->pwm_period = haptic_pdata->pwm_period; chip->type = haptic_pdata->type; chip->mode = haptic_pdata->mode; chip->pwm_divisor = haptic_pdata->pwm_divisor; switch (chip->mode) { case MAX8997_INTERNAL_MODE: chip->internal_mode_pattern = haptic_pdata->internal_mode_pattern; chip->pattern_cycle = haptic_pdata->pattern_cycle; chip->pattern_signal_period = haptic_pdata->pattern_signal_period; break; case MAX8997_EXTERNAL_MODE: chip->pwm = pwm_request(haptic_pdata->pwm_channel_id, "max8997-haptic"); if (IS_ERR(chip->pwm)) { error = PTR_ERR(chip->pwm); dev_err(&pdev->dev, "unable to request PWM for haptic, error: %d\n", error); goto err_free_mem; } break; default: dev_err(&pdev->dev, "Invalid chip mode specified (%d)\n", chip->mode); error = -EINVAL; goto err_free_mem; } chip->regulator = regulator_get(&pdev->dev, "inmotor"); if (IS_ERR(chip->regulator)) { error = PTR_ERR(chip->regulator); dev_err(&pdev->dev, "unable to get regulator, error: %d\n", error); goto err_free_pwm; } input_dev->name = "max8997-haptic"; input_dev->id.version = 1; input_dev->dev.parent = &pdev->dev; input_dev->close = max8997_haptic_close; input_set_drvdata(input_dev, chip); input_set_capability(input_dev, EV_FF, FF_RUMBLE); error = input_ff_create_memless(input_dev, NULL, max8997_haptic_play_effect); if (error) { dev_err(&pdev->dev, "unable to create FF device, error: %d\n", error); goto err_put_regulator; } error = input_register_device(input_dev); if (error) { dev_err(&pdev->dev, "unable to register input device, error: %d\n", error); goto err_destroy_ff; } platform_set_drvdata(pdev, chip); return 0; err_destroy_ff: input_ff_destroy(input_dev); err_put_regulator: regulator_put(chip->regulator); err_free_pwm: if (chip->mode == MAX8997_EXTERNAL_MODE) pwm_free(chip->pwm); err_free_mem: input_free_device(input_dev); kfree(chip); return error; }
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct usb_xpad *xpad; struct input_dev *input_dev; struct usb_endpoint_descriptor *ep_irq_in; int i, error; for (i = 0; xpad_device[i].idVendor; i++) { if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct)) break; } xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); input_dev = input_allocate_device(); if (!xpad || !input_dev) { error = -ENOMEM; goto fail1; } xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, GFP_KERNEL, &xpad->idata_dma); if (!xpad->idata) { error = -ENOMEM; goto fail1; } xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_in) { error = -ENOMEM; goto fail2; } xpad->udev = udev; xpad->mapping = xpad_device[i].mapping; xpad->xtype = xpad_device[i].xtype; if (xpad->xtype == XTYPE_UNKNOWN) { if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) xpad->xtype = XTYPE_XBOX360W; else xpad->xtype = XTYPE_XBOX360; } else xpad->xtype = XTYPE_XBOX; if (dpad_to_buttons) xpad->mapping |= MAP_DPAD_TO_BUTTONS; if (triggers_to_buttons) xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS; if (sticks_to_null) xpad->mapping |= MAP_STICKS_TO_NULL; } xpad->dev = input_dev; usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); input_dev->name = xpad_device[i].name; input_dev->phys = xpad->phys; usb_to_input_id(udev, &input_dev->id); input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, xpad); input_dev->open = xpad_open; input_dev->close = xpad_close; input_dev->evbit[0] = BIT_MASK(EV_KEY); if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { input_dev->evbit[0] |= BIT_MASK(EV_ABS); for (i = 0; xpad_abs[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs[i]); } for (i = 0; xpad_common_btn[i] >= 0; i++) __set_bit(xpad_common_btn[i], input_dev->keybit); if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) { for (i = 0; xpad360_btn[i] >= 0; i++) __set_bit(xpad360_btn[i], input_dev->keybit); } else { for (i = 0; xpad_btn[i] >= 0; i++) __set_bit(xpad_btn[i], input_dev->keybit); } if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { for (i = 0; xpad_btn_pad[i] >= 0; i++) __set_bit(xpad_btn_pad[i], input_dev->keybit); } else { for (i = 0; xpad_abs_pad[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_pad[i]); } if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { for (i = 0; xpad_btn_triggers[i] >= 0; i++) __set_bit(xpad_btn_triggers[i], input_dev->keybit); } else { for (i = 0; xpad_abs_triggers[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); } error = xpad_init_output(intf, xpad); if (error) goto fail3; error = xpad_init_ff(xpad); if (error) goto fail4; error = xpad_led_probe(xpad); if (error) goto fail5; ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), xpad->idata, XPAD_PKT_LEN, xpad_irq_in, xpad, ep_irq_in->bInterval); xpad->irq_in->transfer_dma = xpad->idata_dma; xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; error = input_register_device(xpad->dev); if (error) goto fail6; usb_set_intfdata(intf, xpad); if (xpad->xtype == XTYPE_XBOX360W) { xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->bulk_out) { error = -ENOMEM; goto fail7; } xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); if (!xpad->bdata) { error = -ENOMEM; goto fail8; } xpad->bdata[2] = 0x08; switch (intf->cur_altsetting->desc.bInterfaceNumber) { case 0: xpad->bdata[3] = 0x42; break; case 2: xpad->bdata[3] = 0x43; break; case 4: xpad->bdata[3] = 0x44; break; case 6: xpad->bdata[3] = 0x45; } ep_irq_in = &intf->cur_altsetting->endpoint[1].desc; usb_fill_bulk_urb(xpad->bulk_out, udev, usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress), xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad); xpad->irq_in->dev = xpad->udev; error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); if (error) goto fail9; } return 0; fail9: kfree(xpad->bdata); fail8: usb_free_urb(xpad->bulk_out); fail7: input_unregister_device(input_dev); input_dev = NULL; fail6: xpad_led_disconnect(xpad); fail5: if (input_dev) input_ff_destroy(input_dev); fail4: xpad_deinit_output(xpad); fail3: usb_free_urb(xpad->irq_in); fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); fail1: input_free_device(input_dev); kfree(xpad); return error; }
static int __devinit pm8xxx_vib_probe(struct platform_device *pdev) { struct pm8xxx_vib *vib; struct input_dev *input_dev; int error; u8 val; vib = kzalloc(sizeof(*vib), GFP_KERNEL); input_dev = input_allocate_device(); if (!vib || !input_dev) { dev_err(&pdev->dev, "couldn't allocate memory\n"); error = -ENOMEM; goto err_free_mem; } INIT_WORK(&vib->work, pm8xxx_work_handler); vib->dev = &pdev->dev; vib->vib_input_dev = input_dev; error = pm8xxx_vib_read_u8(vib, &val, VIB_DRV); if (error < 0) goto err_free_mem; val &= ~VIB_DRV_EN_MANUAL_MASK; error = pm8xxx_vib_write_u8(vib, val, VIB_DRV); if (error < 0) goto err_free_mem; vib->reg_vib_drv = val; input_dev->name = "pm8xxx_vib_ffmemless"; input_dev->id.version = 1; input_dev->dev.parent = &pdev->dev; input_dev->close = pm8xxx_vib_close; input_set_drvdata(input_dev, vib); input_set_capability(vib->vib_input_dev, EV_FF, FF_RUMBLE); error = input_ff_create_memless(input_dev, NULL, pm8xxx_vib_play_effect); if (error) { dev_err(&pdev->dev, "couldn't register vibrator as FF device\n"); goto err_free_mem; } error = input_register_device(input_dev); if (error) { dev_err(&pdev->dev, "couldn't register input device\n"); goto err_destroy_memless; } platform_set_drvdata(pdev, vib); return 0; err_destroy_memless: input_ff_destroy(input_dev); err_free_mem: input_free_device(input_dev); kfree(vib); return error; }
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct usb_xpad *xpad; struct input_dev *input_dev; struct usb_endpoint_descriptor *ep_irq_in; int i, error; for (i = 0; xpad_device[i].idVendor; i++) { if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct)) break; } xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); input_dev = input_allocate_device(); if (!xpad || !input_dev) { error = -ENOMEM; goto fail1; } xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, GFP_KERNEL, &xpad->idata_dma); if (!xpad->idata) { error = -ENOMEM; goto fail1; } xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_in) { error = -ENOMEM; goto fail2; } xpad->udev = udev; xpad->mapping = xpad_device[i].mapping; xpad->xtype = xpad_device[i].xtype; if (xpad->xtype == XTYPE_UNKNOWN) { if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) xpad->xtype = XTYPE_XBOX360W; else xpad->xtype = XTYPE_XBOX360; } else xpad->xtype = XTYPE_XBOX; if (dpad_to_buttons) xpad->mapping |= MAP_DPAD_TO_BUTTONS; if (triggers_to_buttons) xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS; if (sticks_to_null) xpad->mapping |= MAP_STICKS_TO_NULL; } xpad->dev = input_dev; usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); input_dev->name = xpad_device[i].name; input_dev->phys = xpad->phys; usb_to_input_id(udev, &input_dev->id); input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, xpad); input_dev->open = xpad_open; input_dev->close = xpad_close; input_dev->evbit[0] = BIT_MASK(EV_KEY); if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { input_dev->evbit[0] |= BIT_MASK(EV_ABS); /* set up axes */ for (i = 0; xpad_abs[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs[i]); } /* set up standard buttons */ for (i = 0; xpad_common_btn[i] >= 0; i++) __set_bit(xpad_common_btn[i], input_dev->keybit); /* set up model-specific ones */ if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) { for (i = 0; xpad360_btn[i] >= 0; i++) __set_bit(xpad360_btn[i], input_dev->keybit); } else { for (i = 0; xpad_btn[i] >= 0; i++) __set_bit(xpad_btn[i], input_dev->keybit); } if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { for (i = 0; xpad_btn_pad[i] >= 0; i++) __set_bit(xpad_btn_pad[i], input_dev->keybit); } else { for (i = 0; xpad_abs_pad[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_pad[i]); } if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { for (i = 0; xpad_btn_triggers[i] >= 0; i++) __set_bit(xpad_btn_triggers[i], input_dev->keybit); } else { for (i = 0; xpad_abs_triggers[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); } error = xpad_init_output(intf, xpad); if (error) goto fail3; error = xpad_init_ff(xpad); if (error) goto fail4; error = xpad_led_probe(xpad); if (error) goto fail5; ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), xpad->idata, XPAD_PKT_LEN, xpad_irq_in, xpad, ep_irq_in->bInterval); xpad->irq_in->transfer_dma = xpad->idata_dma; xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; INIT_WORK(&xpad->submit_urb, xpad_do_submit_urb); error = input_register_device(xpad->dev); if (error) goto fail6; usb_set_intfdata(intf, xpad); xpad->interface_number = intf->cur_altsetting->desc.bInterfaceNumber; /* * Submit the int URB immediately rather than waiting for open * because we get status messages from the device whether * or not any controllers are attached. In fact, it's * exactly the message that a controller has arrived that * we're waiting for. */ if (xpad->xtype == XTYPE_XBOX360W) { xpad->irq_in->dev = xpad->udev; error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); if (error) goto fail7; } return 0; fail7: input_unregister_device(input_dev); input_dev = NULL; fail6: xpad_led_disconnect(xpad); fail5: if (input_dev) input_ff_destroy(input_dev); fail4: xpad_deinit_output(xpad); fail3: cancel_work_sync(&xpad->submit_urb); usb_free_urb(xpad->irq_in); fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); fail1: input_free_device(input_dev); kfree(xpad); return error; }
static int __devinit twl6040_vibra_probe(struct platform_device *pdev) { struct twl4030_vibra_data *pdata = pdev->dev.platform_data; struct vibra_info *info; int ret; if (!pdata) { dev_err(&pdev->dev, "platform_data not available\n"); return -EINVAL; } info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { dev_err(&pdev->dev, "couldn't allocate memory\n"); return -ENOMEM; } info->dev = &pdev->dev; info->twl6040 = dev_get_drvdata(pdev->dev.parent); info->vibldrv_res = pdata->vibldrv_res; info->vibrdrv_res = pdata->vibrdrv_res; info->viblmotor_res = pdata->viblmotor_res; info->vibrmotor_res = pdata->vibrmotor_res; if ((!info->vibldrv_res && !info->viblmotor_res) || (!info->vibrdrv_res && !info->vibrmotor_res)) { dev_err(info->dev, "invalid vibra driver/motor resistance\n"); ret = -EINVAL; goto err_kzalloc; } info->irq = platform_get_irq(pdev, 0); if (info->irq < 0) { dev_err(info->dev, "invalid irq\n"); ret = -EINVAL; goto err_kzalloc; } mutex_init(&info->mutex); info->input_dev = input_allocate_device(); if (info->input_dev == NULL) { dev_err(info->dev, "couldn't allocate input device\n"); ret = -ENOMEM; goto err_kzalloc; } input_set_drvdata(info->input_dev, info); info->input_dev->name = "twl6040:vibrator"; info->input_dev->id.version = 1; info->input_dev->dev.parent = pdev->dev.parent; info->input_dev->close = twl6040_vibra_close; __set_bit(FF_RUMBLE, info->input_dev->ffbit); ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); if (ret < 0) { dev_err(info->dev, "couldn't register vibrator to FF\n"); goto err_ialloc; } ret = input_register_device(info->input_dev); if (ret < 0) { dev_err(info->dev, "couldn't register input device\n"); goto err_iff; } platform_set_drvdata(pdev, info); ret = request_threaded_irq(info->irq, NULL, twl6040_vib_irq_handler, 0, "twl6040_irq_vib", info); if (ret) { dev_err(info->dev, "VIB IRQ request failed: %d\n", ret); goto err_irq; } info->supplies[0].supply = "vddvibl"; info->supplies[1].supply = "vddvibr"; ret = regulator_bulk_get(info->dev, ARRAY_SIZE(info->supplies), info->supplies); if (ret) { dev_err(info->dev, "couldn't get regulators %d\n", ret); goto err_regulator; } if (pdata->vddvibl_uV) { ret = regulator_set_voltage(info->supplies[0].consumer, pdata->vddvibl_uV, pdata->vddvibl_uV); if (ret) { dev_err(info->dev, "failed to set VDDVIBL volt %d\n", ret); goto err_voltage; } } if (pdata->vddvibr_uV) { ret = regulator_set_voltage(info->supplies[1].consumer, pdata->vddvibr_uV, pdata->vddvibr_uV); if (ret) { dev_err(info->dev, "failed to set VDDVIBR volt %d\n", ret); goto err_voltage; } } info->workqueue = alloc_workqueue("twl6040-vibra", 0, 0); if (info->workqueue == NULL) { dev_err(info->dev, "couldn't create workqueue\n"); ret = -ENOMEM; goto err_voltage; } INIT_WORK(&info->play_work, vibra_play_work); return 0; err_voltage: regulator_bulk_free(ARRAY_SIZE(info->supplies), info->supplies); err_regulator: free_irq(info->irq, info); err_irq: input_unregister_device(info->input_dev); info->input_dev = NULL; err_iff: if (info->input_dev) input_ff_destroy(info->input_dev); err_ialloc: input_free_device(info->input_dev); err_kzalloc: kfree(info); return ret; }
static int __devinit pmic8058_vib_probe(struct platform_device *pdev) { struct pmic8058_vibrator_pdata *pdata = pdev->dev.platform_data; struct pmic8058_vib *vib; u8 val; int rc; struct pm8058_chip *pm_chip; pm_chip = dev_get_drvdata(pdev->parent.dev); if (pm_chip == NULL) { dev_err(&pdev->dev, "no parent data passed in\n"); return -EFAULT; } if (!pdata) return -EINVAL; if (pdata->level_mV < VIB_MIN_LEVEL_mV || pdata->level_mV > VIB_MAX_LEVEL_mV) return -EINVAL; vib = kzalloc(sizeof(*vib), GFP_KERNEL); if (!vib) return -ENOMEM; vib->pm_chip = pm_chip; vib->enabled = 0; vib->pdata = pdata; vib->level = pdata->level_mV / 100; vib->dev = &pdev->dev; spin_lock_init(&vib->lock); INIT_WORK(&vib->work, pmic8058_work_handler); vib->info = input_allocate_device(); if (vib->info == NULL) { dev_err(&pdev->dev, "couldn't allocate input device\n"); return -ENOMEM; } input_set_drvdata(vib->info, vib); vib->info->name = "pmic8058:vibrator"; vib->info->id.version = 1; vib->info->dev.parent = pdev->dev.parent; __set_bit(FF_RUMBLE, vib->info->ffbit); __dump_vib_regs(vib, "boot_vib_default"); /* */ rc = pmic8058_vib_read_u8(vib, &val, VIB_DRV); if (rc < 0) goto err_read_vib; val &= ~VIB_DRV_EN_MANUAL_MASK; rc = pmic8058_vib_write_u8(vib, val, VIB_DRV); if (rc < 0) goto err_read_vib; vib->reg_vib_drv = val; rc = input_ff_create_memless(vib->info, NULL, pmic8058_vib_play_effect); if (rc < 0) { dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n"); goto create_memless_err; } platform_set_drvdata(pdev, vib); rc = input_register_device(vib->info); if (rc < 0) { dev_dbg(&pdev->dev, "couldn't register input device\n"); goto reg_err; } return 0; reg_err: input_ff_destroy(vib->info); create_memless_err: input_free_device(vib->info); err_read_vib: kfree(vib); return rc; }
static int regulator_haptic_probe(struct platform_device *pdev) { struct regulator_haptic *haptic; struct input_dev *input_dev; char *select_regulator_name; int error; haptic = kzalloc(sizeof(*haptic), GFP_KERNEL); if (!haptic) { printk("regulator-haptic : unable to allocate memory for haptic\n"); return -ENOMEM; } input_dev = input_allocate_device(); if (!input_dev) { printk("regulator-haptic : unalbe to allocate memory\n"); error = -ENOMEM; goto err_kfree_mem; } INIT_WORK(&haptic->work, regulator_haptic_work); mutex_init(&haptic->mutex); haptic->input_dev = input_dev; haptic->dev = &pdev->dev; select_regulator_name = get_regulator_name(); if(!strcmp(select_regulator_name, ERROR_NAME)) { pr_info("%s : error regulator_name\n", __func__); error = -ENOMEM; goto err_kfree_mem; } haptic->regulator = regulator_get(&pdev->dev, select_regulator_name); if (IS_ERR(haptic->regulator)) { error = PTR_ERR(haptic->regulator); printk("regulator-haptic : unable to get regulator, err : %d\n", error); goto err_ifree_mem; } set_haptic_data(haptic); haptic->input_dev->name = "regulator-haptic"; haptic->input_dev->dev.parent = &pdev->dev; haptic->input_dev->close = regulator_haptic_close; haptic->enabled = false; input_set_drvdata(haptic->input_dev, haptic); input_set_capability(haptic->input_dev, EV_FF, FF_RUMBLE); error = input_ff_create_memless(input_dev, NULL, regulator_haptic_play); if (error) { printk("regulator-haptic : input_ff_create_memless() failed : %d\n", error); goto err_put_regulator; } error = input_register_device(haptic->input_dev); if (error) { printk("regulator-haptic : couldn't register input device : %d\n", error); goto err_destroy_ff; } platform_set_drvdata(pdev, haptic); return 0; err_destroy_ff: input_ff_destroy(haptic->input_dev); err_put_regulator: regulator_put(haptic->regulator); err_ifree_mem: input_free_device(haptic->input_dev); err_kfree_mem: kfree(haptic); return error; }
static int __devinit max77665_haptic_probe(struct platform_device *pdev) { struct max77665_haptic_platform_data *haptic_pdata = pdev->dev.platform_data; struct max77665_haptic *chip; struct edp_manager *battery_manager = NULL; struct input_dev *input_dev; int ret; if (!haptic_pdata) { dev_err(&pdev->dev, "no haptic platform data\n"); return -EINVAL; } chip = devm_kzalloc(&pdev->dev, sizeof(struct max77665_haptic), GFP_KERNEL); if (!chip) { dev_err(&pdev->dev, "unable to allocate memory\n"); return -ENOMEM; } input_dev = input_allocate_device(); if (!input_dev) { dev_err(&pdev->dev, "unable to allocate memory for input dev\n"); ret = -ENOMEM; goto err_input_alloc; } chip->dev = &pdev->dev; chip->input_dev = input_dev; chip->pwm_period = haptic_pdata->pwm_period; chip->type = haptic_pdata->type; chip->mode = haptic_pdata->mode; chip->pwm_divisor = haptic_pdata->pwm_divisor; if (chip->mode == MAX77665_INTERNAL_MODE) { chip->internal_mode_pattern = haptic_pdata->internal_mode_pattern; chip->pattern_cycle = haptic_pdata->pattern_cycle; chip->pattern_signal_period = haptic_pdata->pattern_signal_period; chip->feedback_duty_cycle = haptic_pdata->feedback_duty_cycle; chip->invert = haptic_pdata->invert; chip->cont_mode = haptic_pdata->cont_mode; chip->motor_startup_val = haptic_pdata->motor_startup_val; chip->scf_val = haptic_pdata->scf_val; } if (chip->mode == MAX77665_EXTERNAL_MODE) { chip->pwm = pwm_request(haptic_pdata->pwm_channel_id, "max-vbrtr"); if (IS_ERR(chip->pwm)) { dev_err(&pdev->dev, "unable to request PWM for haptic\n"); ret = PTR_ERR(chip->pwm); goto err_pwm; } } chip->regulator = regulator_get(&pdev->dev, "vdd_vbrtr"); if (IS_ERR(chip->regulator)) { dev_err(&pdev->dev, "unable to get regulator\n"); ret = PTR_ERR(chip->regulator); goto err_regulator; } if (haptic_pdata->edp_states == NULL) goto register_input; chip->haptic_edp_client = devm_kzalloc(&pdev->dev, sizeof(struct edp_client), GFP_KERNEL); if (IS_ERR_OR_NULL(chip->haptic_edp_client)) { dev_err(&pdev->dev, "could not allocate edp client\n"); goto register_input; } chip->haptic_edp_client->name[EDP_NAME_LEN - 1] = '\0'; strncpy(chip->haptic_edp_client->name, "vibrator", EDP_NAME_LEN - 1); chip->haptic_edp_client->states = haptic_pdata->edp_states; chip->haptic_edp_client->num_states = MAX77665_HAPTIC_EDP_NUM_STATES; chip->haptic_edp_client->e0_index = MAX77665_HAPTIC_EDP_LOW; chip->haptic_edp_client->priority = EDP_MAX_PRIO + 2; chip->haptic_edp_client->throttle = max77665_haptic_throttle; chip->haptic_edp_client->private_data = chip; battery_manager = edp_get_manager("battery"); if (!battery_manager) { dev_err(&pdev->dev, "unable to get edp manager\n"); } else { ret = edp_register_client(battery_manager, chip->haptic_edp_client); if (ret) { dev_err(&pdev->dev, "unable to register edp client\n"); } else { ret = edp_update_client_request(chip->haptic_edp_client, MAX77665_HAPTIC_EDP_LOW, NULL); if (ret) { dev_err(&pdev->dev, "unable to set E0 EDP state\n"); edp_unregister_client(chip->haptic_edp_client); } else { goto register_input; } } } devm_kfree(&pdev->dev, chip->haptic_edp_client); chip->haptic_edp_client = NULL; register_input: dev_set_drvdata(&pdev->dev, chip); input_dev->name = "max77665-haptic"; input_dev->id.version = 1; input_dev->dev.parent = &pdev->dev; input_set_drvdata(input_dev, chip); input_set_capability(input_dev, EV_FF, FF_RUMBLE); ret = input_ff_create_memless(input_dev, NULL, max77665_haptic_play_effect); if (ret) { dev_err(&pdev->dev, "unable to create FF device(ret : %d)\n", ret); goto err_ff_memless; } INIT_WORK(&chip->work, max77665_haptic_play_effect_work); ret = input_register_device(input_dev); if (ret) { dev_err(&pdev->dev, "unable to register input device(ret : %d)\n", ret); goto err_input_register; } ret = sysfs_create_group(&pdev->dev.kobj, &max77665_haptics_attr_group); if (ret < 0) { dev_err(&pdev->dev, "unable to create sysfs %d\n", ret); } return 0; err_input_register: destroy_work_on_stack(&chip->work); input_ff_destroy(input_dev); err_ff_memless: regulator_put(chip->regulator); err_regulator: if (chip->mode == MAX77665_EXTERNAL_MODE) pwm_free(chip->pwm); err_pwm: input_free_device(input_dev); err_input_alloc: kfree(chip); return ret; }
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) //探针函数 相当于设备驱动的主函数 { struct usb_device *udev = interface_to_usbdev(intf); //根据usb设备接口获取到usb设备 实际 返回的是 intf->dev.parent 即设备的父亲 struct usb_xpad *xpad; //自己的定义的手柄设备类型 struct input_dev *input_dev;//输入设备 struct usb_endpoint_descriptor *ep_irq_in; //in endpoint 的描述 int ep_irq_in_idx; int i, error; for (i = 0; xpad_device[i].idVendor; i++) //根据实际插入的设备的生产商id和产品id 找到匹配的设备 { if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct)) break; } xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); //在内核空间为手柄设备申请内存空间 input_dev = input_allocate_device(); //为输入设备在内核空间申请内存空间 input_allocate_device()这个函数是用kzalloc函数申请了空间后 然后对该内存进行了初始化 if (!xpad || !input_dev) //申请空间失败 { error = -ENOMEM; goto fail1; } //usb_alloc_coherent (struct usb_device *dev,size_t size,gfp_t mem_flags,dma_addr_t *dma)--allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP //分配DMA接口的缓冲区 返回 idata_dma 和 idata(raw packet,原始数据包) xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, GFP_KERNEL, &xpad->idata_dma); if (!xpad->idata) //返回raw packet(原始数据包)失败 { error = -ENOMEM; goto fail1; } //usb_alloc_urb (int iso_packets,gfp_t mem_flags) create a new urb for a USB driver to use iso_packets = 0 when use interrupt endpoints //创建新的urb给设备使用 xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_in) //urb创建失败 { error = -ENOMEM; goto fail2; } xpad->udev = udev; //保存usb设备信息 xpad->intf = intf; //保存usb接口信息 xpad->dev = input_dev; //保存输入设备信息 //创建物理路径 usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); //input0类型的 input_dev->name = xpad_device[i].name; //保存输入设备名字 input_dev->phys = xpad->phys; //保存输入设备的物理路径 usb_to_input_id(udev, &input_dev->id); //保存输入设备ID input_dev->dev.parent = &intf->dev; //保存输入设备的设备 输入设备的父亲是usb接口 , usb接口的父亲 usb设备 input_set_drvdata(input_dev, xpad); input_dev->open = xpad_open; //输入设备的打开函数 input_dev->close = xpad_close; //输入设备的关闭函数 //BIT_MASK(nr) (1UL<<((nr)%BITS_PER_LONG)) input_dev->evbit[0] = BIT_MASK(EV_KEY); //注册键盘事件 input_dev->evbit[0] |= BIT_MASK(EV_REL); //注册相对轴事件 input_dev->evbit[0] |= BIT_MASK(EV_ABS); //注册绝对轴事件 /* set up axes */ for (i = 0; xpad_abs[i] >= 0; i++) ///注册对应的绝对轴 xpad_set_up_abs(input_dev, xpad_abs[i]); xpad_set_up_rel(input_dev, REL_WHEEL); //注册对应的相对轴 for (i = 0 ; key_need_register[i] >= 0; i++) __set_bit(key_need_register[i], input_dev->keybit); //注册按键 for (i = 0; xpad_common_btn[i] >= 0; i++) __set_bit(xpad_common_btn[i], input_dev->keybit); //注册游戏手柄按键 for (i = 0; xpad360_btn[i] >= 0; i++) __set_bit(xpad360_btn[i], input_dev->keybit); //注册LT RT按键 for (i = 0; xpad_abs_triggers[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); //初始化设备输出 error = xpad_init_output(intf, xpad); if (error) goto fail3; ep_irq_in_idx = 0; ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc; //根据usb接口得到 in endpoint口的描述信息 //函数结构 usb_fill_int_urb(struct urb* urb,struct usb_device * dev,unsigned int pipe,void * transfer_buffer,int buffer_length,usb_complete_t complete,void * context,int interval) //根据 usb设备,usb管道,输入缓冲区的首地址,缓冲区长度,urb入口函数,手柄设备数据信息,in endpoint口的轮换间隔信息 得到 输入的urb usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), xpad->idata, XPAD_PKT_LEN, xpad_irq_in, xpad, ep_irq_in->bInterval); xpad->irq_in->transfer_dma = xpad->idata_dma; //传输的DMA接口地址 xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; //传输标志(允许DMA方式传输) urb->transfer_dma valid on submit //根据输入设备信息 注册设备 error = input_register_device(xpad->dev); if (error) goto fail5; usb_set_intfdata(intf, xpad); return 0; fail5: if (input_dev) input_ff_destroy(input_dev); //free force feedback structures fail4: xpad_deinit_output(xpad); //free out urb and out dma fail3: usb_free_urb(xpad->irq_in); //free in urb fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); //free in dma fail1: input_free_device(input_dev); //free input_dev kfree(xpad); //free xpad return error; }