Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5b7c7c3 authored by Dmitry Torokhov's avatar Dmitry Torokhov Committed by Greg Kroah-Hartman
Browse files

[PATCH] drivers/usb/input: convert to dynamic input_dev allocation



Input: convert drivers/iusb/input to dynamic input_dev allocation

This is required for input_dev sysfs integration

Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 3c42f0c3
Loading
Loading
Loading
Loading
+39 −37
Original line number Original line Diff line number Diff line
@@ -53,7 +53,7 @@ struct usb_acecad {
	char name[128];
	char name[128];
	char phys[64];
	char phys[64];
	struct usb_device *usbdev;
	struct usb_device *usbdev;
	struct input_dev dev;
	struct input_dev *input;
	struct urb *irq;
	struct urb *irq;


	signed char *data;
	signed char *data;
@@ -64,7 +64,7 @@ static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs)
{
{
	struct usb_acecad *acecad = urb->context;
	struct usb_acecad *acecad = urb->context;
	unsigned char *data = acecad->data;
	unsigned char *data = acecad->data;
	struct input_dev *dev = &acecad->dev;
	struct input_dev *dev = acecad->input;
	int prox, status;
	int prox, status;


	switch (urb->status) {
	switch (urb->status) {
@@ -135,8 +135,8 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
	struct usb_host_interface *interface = intf->cur_altsetting;
	struct usb_host_interface *interface = intf->cur_altsetting;
	struct usb_endpoint_descriptor *endpoint;
	struct usb_endpoint_descriptor *endpoint;
	struct usb_acecad *acecad;
	struct usb_acecad *acecad;
	struct input_dev *input_dev;
	int pipe, maxp;
	int pipe, maxp;
	char path[64];


	if (interface->desc.bNumEndpoints != 1)
	if (interface->desc.bNumEndpoints != 1)
		return -ENODEV;
		return -ENODEV;
@@ -153,8 +153,9 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));


	acecad = kzalloc(sizeof(struct usb_acecad), GFP_KERNEL);
	acecad = kzalloc(sizeof(struct usb_acecad), GFP_KERNEL);
	if (!acecad)
	input_dev = input_allocate_device();
		return -ENOMEM;
	if (!acecad || !input_dev)
		goto fail1;


	acecad->data = usb_buffer_alloc(dev, 8, SLAB_KERNEL, &acecad->data_dma);
	acecad->data = usb_buffer_alloc(dev, 8, SLAB_KERNEL, &acecad->data_dma);
	if (!acecad->data)
	if (!acecad->data)
@@ -164,6 +165,9 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
	if (!acecad->irq)
	if (!acecad->irq)
		goto fail2;
		goto fail2;


	acecad->usbdev = dev;
	acecad->input = input_dev;

	if (dev->manufacturer)
	if (dev->manufacturer)
		strlcpy(acecad->name, dev->manufacturer, sizeof(acecad->name));
		strlcpy(acecad->name, dev->manufacturer, sizeof(acecad->name));


@@ -173,48 +177,48 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
		strlcat(acecad->name, dev->product, sizeof(acecad->name));
		strlcat(acecad->name, dev->product, sizeof(acecad->name));
	}
	}


	usb_make_path(dev, path, sizeof(path));
	usb_make_path(dev, acecad->phys, sizeof(acecad->phys));
	snprintf(acecad->phys, sizeof(acecad->phys), "%s/input0", path);
	strlcat(acecad->phys, "/input0", sizeof(acecad->phys));


	acecad->usbdev = dev;
	input_dev->name = acecad->name;
	input_dev->phys = acecad->phys;
	usb_to_input_id(dev, &input_dev->id);
	input_dev->cdev.dev = &intf->dev;
	input_dev->private = acecad;


	acecad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
	input_dev->open = usb_acecad_open;
	acecad->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
	input_dev->close = usb_acecad_close;
	acecad->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);

	acecad->dev.keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
	input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
	input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
	input_dev->keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);


	switch (id->driver_info) {
	switch (id->driver_info) {
		case 0:
		case 0:
			acecad->dev.absmax[ABS_X] = 5000;
			input_dev->absmax[ABS_X] = 5000;
			acecad->dev.absmax[ABS_Y] = 3750;
			input_dev->absmax[ABS_Y] = 3750;
			acecad->dev.absmax[ABS_PRESSURE] = 512;
			input_dev->absmax[ABS_PRESSURE] = 512;
			if (!strlen(acecad->name))
			if (!strlen(acecad->name))
				snprintf(acecad->name, sizeof(acecad->name),
				snprintf(acecad->name, sizeof(acecad->name),
					"USB Acecad Flair Tablet %04x:%04x",
					"USB Acecad Flair Tablet %04x:%04x",
					dev->descriptor.idVendor, dev->descriptor.idProduct);
					le16_to_cpu(dev->descriptor.idVendor),
					le16_to_cpu(dev->descriptor.idProduct));
			break;
			break;
		case 1:
		case 1:
			acecad->dev.absmax[ABS_X] = 3000;
			input_dev->absmax[ABS_X] = 3000;
			acecad->dev.absmax[ABS_Y] = 2250;
			input_dev->absmax[ABS_Y] = 2250;
			acecad->dev.absmax[ABS_PRESSURE] = 1024;
			input_dev->absmax[ABS_PRESSURE] = 1024;
			if (!strlen(acecad->name))
			if (!strlen(acecad->name))
				snprintf(acecad->name, sizeof(acecad->name),
				snprintf(acecad->name, sizeof(acecad->name),
					"USB Acecad 302 Tablet %04x:%04x",
					"USB Acecad 302 Tablet %04x:%04x",
					dev->descriptor.idVendor, dev->descriptor.idProduct);
					le16_to_cpu(dev->descriptor.idVendor),
					le16_to_cpu(dev->descriptor.idProduct));
			break;
			break;
	}
	}


	acecad->dev.absfuzz[ABS_X] = 4;
	input_dev->absfuzz[ABS_X] = 4;
	acecad->dev.absfuzz[ABS_Y] = 4;
	input_dev->absfuzz[ABS_Y] = 4;

	acecad->dev.private = acecad;
	acecad->dev.open = usb_acecad_open;
	acecad->dev.close = usb_acecad_close;

	acecad->dev.name = acecad->name;
	acecad->dev.phys = acecad->phys;
	usb_to_input_id(dev, &acecad->dev.id);
	acecad->dev.dev = &intf->dev;


	usb_fill_int_urb(acecad->irq, dev, pipe,
	usb_fill_int_urb(acecad->irq, dev, pipe,
			acecad->data, maxp > 8 ? 8 : maxp,
			acecad->data, maxp > 8 ? 8 : maxp,
@@ -222,17 +226,15 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
	acecad->irq->transfer_dma = acecad->data_dma;
	acecad->irq->transfer_dma = acecad->data_dma;
	acecad->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	acecad->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;


	input_register_device(&acecad->dev);
	input_register_device(acecad->input);

	printk(KERN_INFO "input: %s with packet size %d on %s\n",
		acecad->name, maxp, path);


	usb_set_intfdata(intf, acecad);
	usb_set_intfdata(intf, acecad);


	return 0;
	return 0;


 fail2:	usb_buffer_free(dev, 8, acecad->data, acecad->data_dma);
 fail2:	usb_buffer_free(dev, 8, acecad->data, acecad->data_dma);
 fail1:	kfree(acecad);
 fail1: input_free_device(input_dev);
	kfree(acecad);
	return -ENOMEM;
	return -ENOMEM;
}
}


@@ -243,7 +245,7 @@ static void usb_acecad_disconnect(struct usb_interface *intf)
	usb_set_intfdata(intf, NULL);
	usb_set_intfdata(intf, NULL);
	if (acecad) {
	if (acecad) {
		usb_kill_urb(acecad->irq);
		usb_kill_urb(acecad->irq);
		input_unregister_device(&acecad->dev);
		input_unregister_device(acecad->input);
		usb_free_urb(acecad->irq);
		usb_free_urb(acecad->irq);
		usb_buffer_free(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma);
		usb_buffer_free(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma);
		kfree(acecad);
		kfree(acecad);
+93 −116
Original line number Original line Diff line number Diff line
@@ -317,7 +317,7 @@ struct aiptek_settings {
};
};


struct aiptek {
struct aiptek {
	struct input_dev inputdev;		/* input device struct           */
	struct input_dev *inputdev;		/* input device struct           */
	struct usb_device *usbdev;		/* usb device struct             */
	struct usb_device *usbdev;		/* usb device struct             */
	struct urb *urb;			/* urb for incoming reports      */
	struct urb *urb;			/* urb for incoming reports      */
	dma_addr_t data_dma;			/* our dma stuffage              */
	dma_addr_t data_dma;			/* our dma stuffage              */
@@ -402,7 +402,7 @@ static void aiptek_irq(struct urb *urb, struct pt_regs *regs)
{
{
	struct aiptek *aiptek = urb->context;
	struct aiptek *aiptek = urb->context;
	unsigned char *data = aiptek->data;
	unsigned char *data = aiptek->data;
	struct input_dev *inputdev = &aiptek->inputdev;
	struct input_dev *inputdev = aiptek->inputdev;
	int jitterable = 0;
	int jitterable = 0;
	int retval, macro, x, y, z, left, right, middle, p, dv, tip, bs, pck;
	int retval, macro, x, y, z, left, right, middle, p, dv, tip, bs, pck;


@@ -955,20 +955,20 @@ static int aiptek_program_tablet(struct aiptek *aiptek)
	/* Query getXextension */
	/* Query getXextension */
	if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0)
	if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0)
		return ret;
		return ret;
	aiptek->inputdev.absmin[ABS_X] = 0;
	aiptek->inputdev->absmin[ABS_X] = 0;
	aiptek->inputdev.absmax[ABS_X] = ret - 1;
	aiptek->inputdev->absmax[ABS_X] = ret - 1;


	/* Query getYextension */
	/* Query getYextension */
	if ((ret = aiptek_query(aiptek, 0x01, 0x01)) < 0)
	if ((ret = aiptek_query(aiptek, 0x01, 0x01)) < 0)
		return ret;
		return ret;
	aiptek->inputdev.absmin[ABS_Y] = 0;
	aiptek->inputdev->absmin[ABS_Y] = 0;
	aiptek->inputdev.absmax[ABS_Y] = ret - 1;
	aiptek->inputdev->absmax[ABS_Y] = ret - 1;


	/* Query getPressureLevels */
	/* Query getPressureLevels */
	if ((ret = aiptek_query(aiptek, 0x08, 0x00)) < 0)
	if ((ret = aiptek_query(aiptek, 0x08, 0x00)) < 0)
		return ret;
		return ret;
	aiptek->inputdev.absmin[ABS_PRESSURE] = 0;
	aiptek->inputdev->absmin[ABS_PRESSURE] = 0;
	aiptek->inputdev.absmax[ABS_PRESSURE] = ret - 1;
	aiptek->inputdev->absmax[ABS_PRESSURE] = ret - 1;


	/* Depending on whether we are in absolute or relative mode, we will
	/* Depending on whether we are in absolute or relative mode, we will
	 * do a switchToTablet(absolute) or switchToMouse(relative) command.
	 * do a switchToTablet(absolute) or switchToMouse(relative) command.
@@ -1025,8 +1025,8 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr
		return 0;
		return 0;


	return snprintf(buf, PAGE_SIZE, "%dx%d\n",
	return snprintf(buf, PAGE_SIZE, "%dx%d\n",
			aiptek->inputdev.absmax[ABS_X] + 1,
			aiptek->inputdev->absmax[ABS_X] + 1,
			aiptek->inputdev.absmax[ABS_Y] + 1);
			aiptek->inputdev->absmax[ABS_Y] + 1);
}
}


/* These structs define the sysfs files, param #1 is the name of the
/* These structs define the sysfs files, param #1 is the name of the
@@ -1048,7 +1048,7 @@ static ssize_t show_tabletProductId(struct device *dev, struct device_attribute
		return 0;
		return 0;


	return snprintf(buf, PAGE_SIZE, "0x%04x\n",
	return snprintf(buf, PAGE_SIZE, "0x%04x\n",
			aiptek->inputdev.id.product);
			aiptek->inputdev->id.product);
}
}


static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL);
static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL);
@@ -1063,7 +1063,7 @@ static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute *
	if (aiptek == NULL)
	if (aiptek == NULL)
		return 0;
		return 0;


	return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev.id.vendor);
	return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev->id.vendor);
}
}


static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL);
static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL);
@@ -1977,7 +1977,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
	struct input_dev *inputdev;
	struct input_dev *inputdev;
	struct input_handle *inputhandle;
	struct input_handle *inputhandle;
	struct list_head *node, *next;
	struct list_head *node, *next;
	char path[64 + 1];
	int i;
	int i;
	int speeds[] = { 0,
	int speeds[] = { 0,
		AIPTEK_PROGRAMMABLE_DELAY_50,
		AIPTEK_PROGRAMMABLE_DELAY_50,
@@ -1996,24 +1995,26 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
	 */
	 */
	speeds[0] = programmableDelay;
	speeds[0] = programmableDelay;


	if ((aiptek = kmalloc(sizeof(struct aiptek), GFP_KERNEL)) == NULL)
	aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL);
		return -ENOMEM;
	inputdev = input_allocate_device();
	memset(aiptek, 0, sizeof(struct aiptek));
	if (!aiptek || !inputdev)
		goto fail1;


	aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
	aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
					SLAB_ATOMIC, &aiptek->data_dma);
					SLAB_ATOMIC, &aiptek->data_dma);
	if (aiptek->data == NULL) {
	if (!aiptek->data)
		kfree(aiptek);
		goto fail1;
		return -ENOMEM;
	}


	aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
	aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
	if (aiptek->urb == NULL) {
	if (!aiptek->urb)
		usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
		goto fail2;
				aiptek->data_dma);

		kfree(aiptek);
	aiptek->inputdev = inputdev;
		return -ENOMEM;
	aiptek->usbdev = usbdev;
	}
	aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber;
	aiptek->inDelay = 0;
	aiptek->endDelay = 0;
	aiptek->previousJitterable = 0;


	/* Set up the curSettings struct. Said struct contains the current
	/* Set up the curSettings struct. Said struct contains the current
	 * programmable parameters. The newSetting struct contains changes
	 * programmable parameters. The newSetting struct contains changes
@@ -2036,31 +2037,48 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)


	/* Both structs should have equivalent settings
	/* Both structs should have equivalent settings
	 */
	 */
	memcpy(&aiptek->newSetting, &aiptek->curSetting,
	aiptek->newSetting = aiptek->curSetting;
	       sizeof(struct aiptek_settings));

	/* Determine the usb devices' physical path.
	 * Asketh not why we always pretend we're using "../input0",
	 * but I suspect this will have to be refactored one
	 * day if a single USB device can be a keyboard & a mouse
	 * & a tablet, and the inputX number actually will tell
	 * us something...
	 */
	usb_make_path(usbdev, aiptek->features.usbPath,
			sizeof(aiptek->features.usbPath));
	strlcat(aiptek->features.usbPath, "/input0",
		sizeof(aiptek->features.usbPath));

	/* Set up client data, pointers to open and close routines
	 * for the input device.
	 */
	inputdev->name = "Aiptek";
	inputdev->phys = aiptek->features.usbPath;
	usb_to_input_id(usbdev, &inputdev->id);
	inputdev->cdev.dev = &intf->dev;
	inputdev->private = aiptek;
	inputdev->open = aiptek_open;
	inputdev->close = aiptek_close;


	/* Now program the capacities of the tablet, in terms of being
	/* Now program the capacities of the tablet, in terms of being
	 * an input device.
	 * an input device.
	 */
	 */
	aiptek->inputdev.evbit[0] |= BIT(EV_KEY)
	inputdev->evbit[0] |= BIT(EV_KEY)
	    | BIT(EV_ABS)
	    | BIT(EV_ABS)
	    | BIT(EV_REL)
	    | BIT(EV_REL)
	    | BIT(EV_MSC);
	    | BIT(EV_MSC);


	aiptek->inputdev.absbit[0] |=
	inputdev->absbit[0] |= BIT(ABS_MISC);
	    (BIT(ABS_X) |
	     BIT(ABS_Y) |
	     BIT(ABS_PRESSURE) |
	     BIT(ABS_TILT_X) |
	     BIT(ABS_TILT_Y) | BIT(ABS_WHEEL) | BIT(ABS_MISC));


	aiptek->inputdev.relbit[0] |=
	inputdev->relbit[0] |=
	    (BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_MISC));
	    (BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_MISC));


	aiptek->inputdev.keybit[LONG(BTN_LEFT)] |=
	inputdev->keybit[LONG(BTN_LEFT)] |=
	    (BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE));
	    (BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE));


	aiptek->inputdev.keybit[LONG(BTN_DIGI)] |=
	inputdev->keybit[LONG(BTN_DIGI)] |=
	    (BIT(BTN_TOOL_PEN) |
	    (BIT(BTN_TOOL_PEN) |
	     BIT(BTN_TOOL_RUBBER) |
	     BIT(BTN_TOOL_RUBBER) |
	     BIT(BTN_TOOL_PENCIL) |
	     BIT(BTN_TOOL_PENCIL) |
@@ -2070,70 +2088,26 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
	     BIT(BTN_TOOL_LENS) |
	     BIT(BTN_TOOL_LENS) |
	     BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2));
	     BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2));


	aiptek->inputdev.mscbit[0] = BIT(MSC_SERIAL);
	inputdev->mscbit[0] = BIT(MSC_SERIAL);


	/* Programming the tablet macro keys needs to be done with a for loop
	/* Programming the tablet macro keys needs to be done with a for loop
	 * as the keycodes are discontiguous.
	 * as the keycodes are discontiguous.
	 */
	 */
	for (i = 0; i < sizeof(macroKeyEvents) / sizeof(macroKeyEvents[0]); ++i)
	for (i = 0; i < sizeof(macroKeyEvents) / sizeof(macroKeyEvents[0]); ++i)
		set_bit(macroKeyEvents[i], aiptek->inputdev.keybit);
		set_bit(macroKeyEvents[i], inputdev->keybit);

	/* Set up client data, pointers to open and close routines
	 * for the input device.
	 */
	aiptek->inputdev.private = aiptek;
	aiptek->inputdev.open = aiptek_open;
	aiptek->inputdev.close = aiptek_close;

	/* Determine the usb devices' physical path.
	 * Asketh not why we always pretend we're using "../input0",
	 * but I suspect this will have to be refactored one
	 * day if a single USB device can be a keyboard & a mouse
	 * & a tablet, and the inputX number actually will tell
	 * us something...
	 */
	if (usb_make_path(usbdev, path, 64) > 0)
		sprintf(aiptek->features.usbPath, "%s/input0", path);


	/* Program the input device coordinate capacities. We do not yet
	/*
	 * Program the input device coordinate capacities. We do not yet
	 * know what maximum X, Y, and Z values are, so we're putting fake
	 * know what maximum X, Y, and Z values are, so we're putting fake
	 * values in. Later, we'll ask the tablet to put in the correct
	 * values in. Later, we'll ask the tablet to put in the correct
	 * values.
	 * values.
	 */
	 */
	aiptek->inputdev.absmin[ABS_X] = 0;
	input_set_abs_params(inputdev, ABS_X, 0, 2999, 0, 0);
	aiptek->inputdev.absmax[ABS_X] = 2999;
	input_set_abs_params(inputdev, ABS_X, 0, 2249, 0, 0);
	aiptek->inputdev.absmin[ABS_Y] = 0;
	input_set_abs_params(inputdev, ABS_PRESSURE, 0, 511, 0, 0);
	aiptek->inputdev.absmax[ABS_Y] = 2249;
	input_set_abs_params(inputdev, ABS_TILT_X, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
	aiptek->inputdev.absmin[ABS_PRESSURE] = 0;
	input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
	aiptek->inputdev.absmax[ABS_PRESSURE] = 511;
	input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0);
	aiptek->inputdev.absmin[ABS_TILT_X] = AIPTEK_TILT_MIN;
	aiptek->inputdev.absmax[ABS_TILT_X] = AIPTEK_TILT_MAX;
	aiptek->inputdev.absmin[ABS_TILT_Y] = AIPTEK_TILT_MIN;
	aiptek->inputdev.absmax[ABS_TILT_Y] = AIPTEK_TILT_MAX;
	aiptek->inputdev.absmin[ABS_WHEEL] = AIPTEK_WHEEL_MIN;
	aiptek->inputdev.absmax[ABS_WHEEL] = AIPTEK_WHEEL_MAX - 1;
	aiptek->inputdev.absfuzz[ABS_X] = 0;
	aiptek->inputdev.absfuzz[ABS_Y] = 0;
	aiptek->inputdev.absfuzz[ABS_PRESSURE] = 0;
	aiptek->inputdev.absfuzz[ABS_TILT_X] = 0;
	aiptek->inputdev.absfuzz[ABS_TILT_Y] = 0;
	aiptek->inputdev.absfuzz[ABS_WHEEL] = 0;
	aiptek->inputdev.absflat[ABS_X] = 0;
	aiptek->inputdev.absflat[ABS_Y] = 0;
	aiptek->inputdev.absflat[ABS_PRESSURE] = 0;
	aiptek->inputdev.absflat[ABS_TILT_X] = 0;
	aiptek->inputdev.absflat[ABS_TILT_Y] = 0;
	aiptek->inputdev.absflat[ABS_WHEEL] = 0;
	aiptek->inputdev.name = "Aiptek";
	aiptek->inputdev.phys = aiptek->features.usbPath;
	usb_to_input_id(usbdev, &aiptek->inputdev.id);
	aiptek->inputdev.dev = &intf->dev;

	aiptek->usbdev = usbdev;
	aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber;
	aiptek->inDelay = 0;
	aiptek->endDelay = 0;
	aiptek->previousJitterable = 0;


	endpoint = &intf->altsetting[0].endpoint[0].desc;
	endpoint = &intf->altsetting[0].endpoint[0].desc;


@@ -2150,28 +2124,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
	aiptek->urb->transfer_dma = aiptek->data_dma;
	aiptek->urb->transfer_dma = aiptek->data_dma;
	aiptek->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	aiptek->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;


	/* Register the tablet as an Input Device
	 */
	input_register_device(&aiptek->inputdev);

	/* We now will look for the evdev device which is mapped to
	 * the tablet. The partial name is kept in the link list of
	 * input_handles associated with this input device.
	 * What identifies an evdev input_handler is that it begins
	 * with 'event', continues with a digit, and that in turn
	 * is mapped to /{devfs}/input/eventN.
	 */
	inputdev = &aiptek->inputdev;
	list_for_each_safe(node, next, &inputdev->h_list) {
		inputhandle = to_handle(node);
		if (strncmp(inputhandle->name, "event", 5) == 0) {
			strcpy(aiptek->features.inputPath, inputhandle->name);
			break;
		}
	}

	info("input: Aiptek on %s (%s)\n", path, aiptek->features.inputPath);

	/* Program the tablet. This sets the tablet up in the mode
	/* Program the tablet. This sets the tablet up in the mode
	 * specified in newSetting, and also queries the tablet's
	 * specified in newSetting, and also queries the tablet's
	 * physical capacities.
	 * physical capacities.
@@ -2186,13 +2138,32 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
	for (i = 0; i < sizeof(speeds) / sizeof(speeds[0]); ++i) {
	for (i = 0; i < sizeof(speeds) / sizeof(speeds[0]); ++i) {
		aiptek->curSetting.programmableDelay = speeds[i];
		aiptek->curSetting.programmableDelay = speeds[i];
		(void)aiptek_program_tablet(aiptek);
		(void)aiptek_program_tablet(aiptek);
		if (aiptek->inputdev.absmax[ABS_X] > 0) {
		if (aiptek->inputdev->absmax[ABS_X] > 0) {
			info("input: Aiptek using %d ms programming speed\n",
			info("input: Aiptek using %d ms programming speed\n",
			     aiptek->curSetting.programmableDelay);
			     aiptek->curSetting.programmableDelay);
			break;
			break;
		}
		}
	}
	}


	/* Register the tablet as an Input Device
	 */
	input_register_device(aiptek->inputdev);

	/* We now will look for the evdev device which is mapped to
	 * the tablet. The partial name is kept in the link list of
	 * input_handles associated with this input device.
	 * What identifies an evdev input_handler is that it begins
	 * with 'event', continues with a digit, and that in turn
	 * is mapped to /{devfs}/input/eventN.
	 */
	list_for_each_safe(node, next, &inputdev->h_list) {
		inputhandle = to_handle(node);
		if (strncmp(inputhandle->name, "event", 5) == 0) {
			strcpy(aiptek->features.inputPath, inputhandle->name);
			break;
		}
	}

	/* Associate this driver's struct with the usb interface.
	/* Associate this driver's struct with the usb interface.
	 */
	 */
	usb_set_intfdata(intf, aiptek);
	usb_set_intfdata(intf, aiptek);
@@ -2207,6 +2178,12 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
		info("aiptek: error loading 'evdev' module");
		info("aiptek: error loading 'evdev' module");


	return 0;
	return 0;

fail2:	usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
			aiptek->data_dma);
fail1:	input_free_device(inputdev);
	kfree(aiptek);
	return -ENOMEM;
}
}


/* Forward declaration */
/* Forward declaration */
@@ -2234,7 +2211,7 @@ static void aiptek_disconnect(struct usb_interface *intf)
		/* Free & unhook everything from the system.
		/* Free & unhook everything from the system.
		 */
		 */
		usb_kill_urb(aiptek->urb);
		usb_kill_urb(aiptek->urb);
		input_unregister_device(&aiptek->inputdev);
		input_unregister_device(aiptek->inputdev);
		aiptek_delete_files(&intf->dev);
		aiptek_delete_files(&intf->dev);
		usb_free_urb(aiptek->urb);
		usb_free_urb(aiptek->urb);
		usb_buffer_free(interface_to_usbdev(intf),
		usb_buffer_free(interface_to_usbdev(intf),
+68 −62
Original line number Original line Diff line number Diff line
@@ -93,11 +93,12 @@ MODULE_DEVICE_TABLE (usb, atp_table);


/* Structure to hold all of our device specific stuff */
/* Structure to hold all of our device specific stuff */
struct atp {
struct atp {
	char			phys[64];
	struct usb_device *	udev;		/* usb device */
	struct usb_device *	udev;		/* usb device */
	struct urb *		urb;		/* usb request block */
	struct urb *		urb;		/* usb request block */
	signed char *		data;		/* transferred data */
	signed char *		data;		/* transferred data */
	int			open;		/* non-zero if opened */
	int			open;		/* non-zero if opened */
	struct input_dev	input;		/* input dev */
	struct input_dev	*input;		/* input dev */
	int			valid;		/* are the sensors valid ? */
	int			valid;		/* are the sensors valid ? */
	int			x_old;		/* last reported x/y, */
	int			x_old;		/* last reported x/y, */
	int			y_old;		/* used for smoothing */
	int			y_old;		/* used for smoothing */
@@ -219,7 +220,7 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
		for (i = 16; i < ATP_XSENSORS; i++)
		for (i = 16; i < ATP_XSENSORS; i++)
			if (dev->xy_cur[i]) {
			if (dev->xy_cur[i]) {
				printk("appletouch: 17\" model detected.\n");
				printk("appletouch: 17\" model detected.\n");
				input_set_abs_params(&dev->input, ABS_X, 0,
				input_set_abs_params(dev->input, ABS_X, 0,
						     (ATP_XSENSORS - 1) *
						     (ATP_XSENSORS - 1) *
						     ATP_XFACT - 1,
						     ATP_XFACT - 1,
						     ATP_FUZZ, 0);
						     ATP_FUZZ, 0);
@@ -260,12 +261,12 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
				       "Xz: %3d Yz: %3d\n",
				       "Xz: %3d Yz: %3d\n",
				       x, y, x_z, y_z);
				       x, y, x_z, y_z);


			input_report_key(&dev->input, BTN_TOUCH, 1);
			input_report_key(dev->input, BTN_TOUCH, 1);
			input_report_abs(&dev->input, ABS_X, x);
			input_report_abs(dev->input, ABS_X, x);
			input_report_abs(&dev->input, ABS_Y, y);
			input_report_abs(dev->input, ABS_Y, y);
			input_report_abs(&dev->input, ABS_PRESSURE,
			input_report_abs(dev->input, ABS_PRESSURE,
					 min(ATP_PRESSURE, x_z + y_z));
					 min(ATP_PRESSURE, x_z + y_z));
			atp_report_fingers(&dev->input, max(x_f, y_f));
			atp_report_fingers(dev->input, max(x_f, y_f));
		}
		}
		dev->x_old = x;
		dev->x_old = x;
		dev->y_old = y;
		dev->y_old = y;
@@ -273,17 +274,17 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
	else if (!x && !y) {
	else if (!x && !y) {


		dev->x_old = dev->y_old = -1;
		dev->x_old = dev->y_old = -1;
		input_report_key(&dev->input, BTN_TOUCH, 0);
		input_report_key(dev->input, BTN_TOUCH, 0);
		input_report_abs(&dev->input, ABS_PRESSURE, 0);
		input_report_abs(dev->input, ABS_PRESSURE, 0);
		atp_report_fingers(&dev->input, 0);
		atp_report_fingers(dev->input, 0);


		/* reset the accumulator on release */
		/* reset the accumulator on release */
		memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
		memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
	}
	}


	input_report_key(&dev->input, BTN_LEFT, !!dev->data[80]);
	input_report_key(dev->input, BTN_LEFT, !!dev->data[80]);


	input_sync(&dev->input);
	input_sync(dev->input);


exit:
exit:
	retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
	retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
@@ -314,21 +315,14 @@ static void atp_close(struct input_dev *input)


static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
{
{
	struct atp *dev = NULL;
	struct atp *dev;
	struct input_dev *input_dev;
	struct usb_device *udev = interface_to_usbdev(iface);
	struct usb_host_interface *iface_desc;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	struct usb_endpoint_descriptor *endpoint;
	int int_in_endpointAddr = 0;
	int int_in_endpointAddr = 0;
	int i, retval = -ENOMEM;
	int i, retval = -ENOMEM;


	/* allocate memory for our device state and initialize it */
	dev = kmalloc(sizeof(struct atp), GFP_KERNEL);
	if (dev == NULL) {
		err("Out of memory");
		goto err_kmalloc;
	}
	memset(dev, 0, sizeof(struct atp));

	dev->udev = interface_to_usbdev(iface);


	/* set up the endpoint information */
	/* set up the endpoint information */
	/* use only the first interrupt-in endpoint */
	/* use only the first interrupt-in endpoint */
@@ -345,70 +339,82 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
		}
		}
	}
	}
	if (!int_in_endpointAddr) {
	if (!int_in_endpointAddr) {
		retval = -EIO;
		err("Could not find int-in endpoint");
		err("Could not find int-in endpoint");
		goto err_endpoint;
		return -EIO;
	}
	}


	/* save our data pointer in this interface device */
	/* allocate memory for our device state and initialize it */
	usb_set_intfdata(iface, dev);
	dev = kzalloc(sizeof(struct atp), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!dev || !input_dev) {
		err("Out of memory");
		goto err_free_devs;
	}

	dev->udev = udev;
	dev->input = input_dev;


	dev->urb = usb_alloc_urb(0, GFP_KERNEL);
	dev->urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->urb) {
	if (!dev->urb) {
		retval = -ENOMEM;
		retval = -ENOMEM;
		goto err_usballoc;
		goto err_free_devs;
	}
	}

	dev->data = usb_buffer_alloc(dev->udev, ATP_DATASIZE, GFP_KERNEL,
	dev->data = usb_buffer_alloc(dev->udev, ATP_DATASIZE, GFP_KERNEL,
				     &dev->urb->transfer_dma);
				     &dev->urb->transfer_dma);
	if (!dev->data) {
	if (!dev->data) {
		retval = -ENOMEM;
		retval = -ENOMEM;
		goto err_usbbufalloc;
		goto err_free_urb;
	}
	}
	usb_fill_int_urb(dev->urb, dev->udev,

			 usb_rcvintpipe(dev->udev, int_in_endpointAddr),
	usb_fill_int_urb(dev->urb, udev,
			 usb_rcvintpipe(udev, int_in_endpointAddr),
			 dev->data, ATP_DATASIZE, atp_complete, dev, 1);
			 dev->data, ATP_DATASIZE, atp_complete, dev, 1);


	init_input_dev(&dev->input);
	usb_make_path(udev, dev->phys, sizeof(dev->phys));
	dev->input.name = "appletouch";
	strlcat(dev->phys, "/input0", sizeof(dev->phys));
	dev->input.dev = &iface->dev;

	dev->input.private = dev;
	input_dev->name = "appletouch";
	dev->input.open = atp_open;
	input_dev->phys = dev->phys;
	dev->input.close = atp_close;
	usb_to_input_id(dev->udev, &input_dev->id);
	input_dev->cdev.dev = &iface->dev;


	usb_to_input_id(dev->udev, &dev->input.id);
	input_dev->private = dev;
	input_dev->open = atp_open;
	input_dev->close = atp_close;


	set_bit(EV_ABS, dev->input.evbit);
	set_bit(EV_ABS, input_dev->evbit);


	/*
	/*
	 * 12" and 15" Powerbooks only have 16 x sensors,
	 * 12" and 15" Powerbooks only have 16 x sensors,
	 * 17" models are detected later.
	 * 17" models are detected later.
	 */
	 */
	input_set_abs_params(&dev->input, ABS_X, 0,
	input_set_abs_params(input_dev, ABS_X, 0,
			     (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
			     (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
	input_set_abs_params(&dev->input, ABS_Y, 0,
	input_set_abs_params(input_dev, ABS_Y, 0,
			     (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
			     (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
	input_set_abs_params(&dev->input, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
	input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);


	set_bit(EV_KEY, dev->input.evbit);
	set_bit(EV_KEY, input_dev->evbit);
	set_bit(BTN_TOUCH, dev->input.keybit);
	set_bit(BTN_TOUCH, input_dev->keybit);
	set_bit(BTN_TOOL_FINGER, dev->input.keybit);
	set_bit(BTN_TOOL_FINGER, input_dev->keybit);
	set_bit(BTN_TOOL_DOUBLETAP, dev->input.keybit);
	set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
	set_bit(BTN_TOOL_TRIPLETAP, dev->input.keybit);
	set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
	set_bit(BTN_LEFT, dev->input.keybit);
	set_bit(BTN_LEFT, input_dev->keybit);


	input_register_device(&dev->input);
	input_register_device(dev->input);


	printk(KERN_INFO "input: appletouch connected\n");
	/* save our data pointer in this interface device */
	usb_set_intfdata(iface, dev);


	return 0;
	return 0;


err_usbbufalloc:
 err_free_urb:
	usb_free_urb(dev->urb);
	usb_free_urb(dev->urb);
err_usballoc:
 err_free_devs:
	usb_set_intfdata(iface, NULL);
	usb_set_intfdata(iface, NULL);
err_endpoint:
	kfree(dev);
	kfree(dev);
err_kmalloc:
	input_free_device(input_dev);
	return retval;
	return retval;
}
}


@@ -419,7 +425,7 @@ static void atp_disconnect(struct usb_interface *iface)
	usb_set_intfdata(iface, NULL);
	usb_set_intfdata(iface, NULL);
	if (dev) {
	if (dev) {
		usb_kill_urb(dev->urb);
		usb_kill_urb(dev->urb);
		input_unregister_device(&dev->input);
		input_unregister_device(dev->input);
		usb_free_urb(dev->urb);
		usb_free_urb(dev->urb);
		usb_buffer_free(dev->udev, ATP_DATASIZE,
		usb_buffer_free(dev->udev, ATP_DATASIZE,
				dev->data, dev->urb->transfer_dma);
				dev->data, dev->urb->transfer_dma);
+89 −84

File changed.

Preview size limit exceeded, changes collapsed.

+27 −24
Original line number Original line Diff line number Diff line
@@ -1619,8 +1619,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
	struct hid_descriptor *hdesc;
	struct hid_descriptor *hdesc;
	struct hid_device *hid;
	struct hid_device *hid;
	unsigned quirks = 0, rsize = 0;
	unsigned quirks = 0, rsize = 0;
	char *buf, *rdesc;
	char *rdesc;
	int n, insize = 0;
	int n, len, insize = 0;


	for (n = 0; hid_blacklist[n].idVendor; n++)
	for (n = 0; hid_blacklist[n].idVendor; n++)
		if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) &&
		if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) &&
@@ -1630,7 +1630,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
	if (quirks & HID_QUIRK_IGNORE)
	if (quirks & HID_QUIRK_IGNORE)
		return NULL;
		return NULL;


	if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->desc.bNumEndpoints) ||
	if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
	    (!interface->desc.bNumEndpoints ||
	     usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
	     usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
		dbg("class descriptor not present\n");
		dbg("class descriptor not present\n");
		return NULL;
		return NULL;
@@ -1749,32 +1750,34 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)


	hid->name[0] = 0;
	hid->name[0] = 0;


	if (!(buf = kmalloc(64, GFP_KERNEL)))
	if (dev->manufacturer)
		goto fail;
		strlcpy(hid->name, dev->manufacturer, sizeof(hid->name));


	if (dev->manufacturer) {
	if (dev->product) {
		strcat(hid->name, dev->manufacturer);
		if (dev->manufacturer)
		if (dev->product)
			strlcat(hid->name, " ", sizeof(hid->name));
			snprintf(hid->name, 64, "%s %s", hid->name, dev->product);
		strlcat(hid->name, dev->product, sizeof(hid->name));
	} else if (dev->product) {
	}
			snprintf(hid->name, 128, "%s", dev->product);

	} else
	if (!strlen(hid->name))
		snprintf(hid->name, 128, "%04x:%04x",
		snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x",
			 le16_to_cpu(dev->descriptor.idVendor),
			 le16_to_cpu(dev->descriptor.idVendor),
			 le16_to_cpu(dev->descriptor.idProduct));
			 le16_to_cpu(dev->descriptor.idProduct));


	usb_make_path(dev, buf, 64);
	usb_make_path(dev, hid->phys, sizeof(hid->phys));
	snprintf(hid->phys, 64, "%s/input%d", buf,
	strlcat(hid->phys, "/input", sizeof(hid->phys));
			intf->altsetting[0].desc.bInterfaceNumber);
	len = strlen(hid->phys);
	if (len < sizeof(hid->phys) - 1)
		snprintf(hid->phys + len, sizeof(hid->phys) - len,
			 "%d", intf->altsetting[0].desc.bInterfaceNumber);


	if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
	if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
		hid->uniq[0] = 0;
		hid->uniq[0] = 0;


	kfree(buf);

	hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
	hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
	if (!hid->urbctrl)
	if (!hid->urbctrl)
		goto fail;
		goto fail;

	usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr,
	usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr,
			     hid->ctrlbuf, 1, hid_ctrl, hid);
			     hid->ctrlbuf, 1, hid_ctrl, hid);
	hid->urbctrl->setup_dma = hid->cr_dma;
	hid->urbctrl->setup_dma = hid->cr_dma;
Loading