usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
if (!usbtouch->irq) {
dbg("%s - usb_alloc_urb failed: usbtouch->irq", __func__);
goto out_free_buffers;
}
usbtouch->udev = udev;
usbtouch->input = input_dev;
if (udev->manufacturer)
strlcpy(usbtouch->name, udev->manufacturer, sizeof(usbtouch->name));
if (udev->product) {
if (udev->manufacturer)
strlcat(usbtouch->name, " ", sizeof(usbtouch->name));
strlcat(usbtouch->name, udev->product, sizeof(usbtouch->name));
}
if (!strlen(usbtouch->name))
snprintf(usbtouch->name, sizeof(usbtouch->name),
"USB Touchscreen %04x:%04x",
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct));
usb_make_path(udev, usbtouch->phys, sizeof(usbtouch->phys));
strlcat(usbtouch->phys, "/input0", sizeof(usbtouch->phys));
input_dev->name = usbtouch->name;
input_dev->phys = usbtouch->phys;
usb_to_input_id(udev, &input_dev->id);
input_dev->dev.parent = &intf->dev;
input_set_drvdata(input_dev, usbtouch);
input_dev->open = usbtouch_open;
input_dev->close = usbtouch_close;
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0);
input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0);
if (type->max_press)
input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press,
type->max_press, 0, 0);
usb_fill_int_urb(usbtouch->irq, usbtouch->udev,
usb_rcvintpipe(usbtouch->udev, endpoint->bEndpointAddress),
usbtouch->data, type->rept_size,
usbtouch_irq, usbtouch, endpoint->bInterval);
usbtouch->irq->dev = usbtouch->udev;
usbtouch->irq->transfer_dma = usbtouch->data_dma;
usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
/* device specific init */
if (type->init) {
err = type->init(usbtouch);
if (err) {
dbg("%s - type->init() failed, err: %d", __func__, err);
goto out_free_buffers;
}
}
err = input_register_device(usbtouch->input);
if (err) {
dbg("%s - input_register_device failed, err: %d", __func__, err);
goto out_free_buffers;
}
usb_set_intfdata(intf, usbtouch);
if (usbtouch->type->irq_always)
usb_submit_urb(usbtouch->irq, GFP_KERNEL);
return 0;
out_free_buffers:
usbtouch_free_buffers(udev, usbtouch);
out_free:
input_free_device(input_dev);
kfree(usbtouch);
return err;
}
static void usbtouch_disconnect(struct usb_interface *intf)
{
struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
dbg("%s - called", __func__);
if (!usbtouch)
return;
dbg("%s - usbtouch is initialized, cleaning up", __func__);
usb_set_intfdata(intf, NULL);
/* this will stop IO via close */
input_unregister_device(usbtouch->input);
usb_free_urb(usbtouch->irq);
usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch);
kfree(usbtouch);
}
MODULE_DEVICE_TABLE(usb, usbtouch_devices);