Ejemplo n.º 1
0
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 wacom_features *features;
	struct input_dev *input_dev;
	int error;

	if (!id->driver_info)
		return -EINVAL;

	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) {
		error = -ENOMEM;
		goto fail1;
	}

	wacom_wac->features = *((struct wacom_features *)id->driver_info);
	features = &wacom_wac->features;
	if (features->pktlen > WACOM_PKGLEN_MAX) {
		error = -EINVAL;
		goto fail1;
	}

	wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX,
					   GFP_KERNEL, &wacom->data_dma);
	if (!wacom_wac->data) {
		error = -ENOMEM;
		goto fail1;
	}

	wacom->irq = usb_alloc_urb(0, GFP_KERNEL);
	if (!wacom->irq) {
		error = -ENOMEM;
		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));

	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;

	/* Retrieve the physical and logical size for OEM devices */
	error = wacom_retrieve_hid_descriptor(intf, features);
	if (error)
		goto fail2;

	strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name));

	if (features->type == TABLETPC || features->type == TABLETPC2FG) {
		/* Append the device type to the name */
		strlcat(wacom_wac->name,
			features->device_type == BTN_TOOL_PEN ?
				" Pen" : " Finger",
			sizeof(wacom_wac->name));
	}

	input_dev->name = wacom_wac->name;
	wacom->wacom_wac = wacom_wac;

	input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH);

	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);
	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, 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;

	/* Note that if query fails it is not a hard failure */
	wacom_query_tablet_data(intf, features);

	usb_set_intfdata(intf, wacom);
	return 0;

 fail3:	usb_free_urb(wacom->irq);
 fail2:	usb_buffer_free(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma);
 fail1:	input_free_device(input_dev);
	kfree(wacom);
	kfree(wacom_wac);
	return error;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}