static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct usb_host_interface *interface = intf->cur_altsetting; struct usb_endpoint_descriptor *endpoint; struct wacom *wacom; struct wacom_wac *wacom_wac; struct wacom_features *features; struct input_dev *input_dev; int error = -ENOMEM; char rep_data[2], limit = 0; struct hid_descriptor *hid_desc; wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); input_dev = input_allocate_device(); if (!wacom || !input_dev || !wacom_wac) goto fail1; wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); if (!wacom_wac->data) goto fail1; wacom->irq = usb_alloc_urb(0, GFP_KERNEL); if (!wacom->irq) goto fail2; wacom->usbdev = dev; wacom->dev = input_dev; wacom->intf = intf; mutex_init(&wacom->lock); usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); wacom_wac->features = features = get_wacom_feature(id); BUG_ON(features->pktlen > 10); input_dev->name = wacom_wac->features->name; wacom->wacom_wac = wacom_wac; usb_to_input_id(dev, &input_dev->id); input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, wacom); input_dev->open = wacom_open; input_dev->close = wacom_close; endpoint = &intf->cur_altsetting->endpoint[0].desc; /* Initialize touch_x_max and touch_y_max in case it is not defined */ if (wacom_wac->features->type == TABLETPC) { features->touch_x_max = 1023; features->touch_y_max = 1023; } else { features->touch_x_max = 0; features->touch_y_max = 0; } /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ if (wacom_wac->features->type == TABLETPC) { if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { if (usb_get_extra_descriptor(&interface->endpoint[0], HID_DEVICET_REPORT, &hid_desc)) { printk("wacom: can not retrive extra class descriptor\n"); goto fail2; } } error = wacom_parse_hid(intf, hid_desc, wacom_wac); if (error) goto fail2; } input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS); input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); if (features->type == TABLETPC) { input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); input_set_abs_params(input_dev, ABS_RX, 0, features->touch_x_max, 4, 0); input_set_abs_params(input_dev, ABS_RY, 0, features->touch_y_max, 4, 0); } input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); wacom_init_input_dev(input_dev, wacom_wac); usb_fill_int_urb(wacom->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), wacom_wac->data, wacom_wac->features->pktlen, wacom_sys_irq, wacom, endpoint->bInterval); wacom->irq->transfer_dma = wacom->data_dma; wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; error = input_register_device(wacom->dev); if (error) goto fail3; /* * Ask the tablet to report tablet data if it is not a Tablet PC. * Repeat until it succeeds */ if (wacom_wac->features->type != TABLETPC) { do { rep_data[0] = 2; rep_data[1] = 2; error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); if (error >= 0) error = usb_get_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); } while ((error < 0 || rep_data[1] != 2) && limit++ < 5); } usb_set_intfdata(intf, wacom); return 0; fail3: usb_free_urb(wacom->irq); fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); fail1: input_free_device(input_dev); kfree(wacom); kfree(wacom_wac); return error; }
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct usb_endpoint_descriptor *endpoint; struct wacom *wacom; struct wacom_wac *wacom_wac; struct input_dev *input_dev; int error = -ENOMEM; char rep_data[2], limit = 0; wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); input_dev = input_allocate_device(); if (!wacom || !input_dev || !wacom_wac) goto fail1; wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); if (!wacom_wac->data) goto fail1; wacom->irq = usb_alloc_urb(0, GFP_KERNEL); if (!wacom->irq) goto fail2; wacom->usbdev = dev; wacom->dev = input_dev; usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); wacom_wac->features = get_wacom_feature(id); BUG_ON(wacom_wac->features->pktlen > 10); input_dev->name = wacom_wac->features->name; wacom->wacom_wac = wacom_wac; usb_to_input_id(dev, &input_dev->id); input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, wacom); input_dev->open = wacom_open; input_dev->close = wacom_close; input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS); input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0); input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); wacom_init_input_dev(input_dev, wacom_wac); endpoint = &intf->cur_altsetting->endpoint[0].desc; usb_fill_int_urb(wacom->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), wacom_wac->data, wacom_wac->features->pktlen, wacom_sys_irq, wacom, endpoint->bInterval); wacom->irq->transfer_dma = wacom->data_dma; wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; error = input_register_device(wacom->dev); if (error) goto fail3; /* Ask the tablet to report tablet data. Repeat until it succeeds */ do { rep_data[0] = 2; rep_data[1] = 2; usb_set_report(intf, 3, 2, rep_data, 2); usb_get_report(intf, 3, 2, rep_data, 2); } while (rep_data[1] != 2 && limit++ < 5); usb_set_intfdata(intf, wacom); return 0; fail3: usb_free_urb(wacom->irq); fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); fail1: input_free_device(input_dev); kfree(wacom); kfree(wacom_wac); return error; }