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 Diff line number Diff line
@@ -53,7 +53,7 @@ struct usb_acecad {
	char name[128];
	char phys[64];
	struct usb_device *usbdev;
	struct input_dev dev;
	struct input_dev *input;
	struct urb *irq;

	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;
	unsigned char *data = acecad->data;
	struct input_dev *dev = &acecad->dev;
	struct input_dev *dev = acecad->input;
	int prox, 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_endpoint_descriptor *endpoint;
	struct usb_acecad *acecad;
	struct input_dev *input_dev;
	int pipe, maxp;
	char path[64];

	if (interface->desc.bNumEndpoints != 1)
		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));

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

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

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

	if (dev->manufacturer)
		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));
	}

	usb_make_path(dev, path, sizeof(path));
	snprintf(acecad->phys, sizeof(acecad->phys), "%s/input0", path);
	usb_make_path(dev, acecad->phys, sizeof(acecad->phys));
	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);
	acecad->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
	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->open = usb_acecad_open;
	input_dev->close = usb_acecad_close;

	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) {
		case 0:
			acecad->dev.absmax[ABS_X] = 5000;
			acecad->dev.absmax[ABS_Y] = 3750;
			acecad->dev.absmax[ABS_PRESSURE] = 512;
			input_dev->absmax[ABS_X] = 5000;
			input_dev->absmax[ABS_Y] = 3750;
			input_dev->absmax[ABS_PRESSURE] = 512;
			if (!strlen(acecad->name))
				snprintf(acecad->name, sizeof(acecad->name),
					"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;
		case 1:
			acecad->dev.absmax[ABS_X] = 3000;
			acecad->dev.absmax[ABS_Y] = 2250;
			acecad->dev.absmax[ABS_PRESSURE] = 1024;
			input_dev->absmax[ABS_X] = 3000;
			input_dev->absmax[ABS_Y] = 2250;
			input_dev->absmax[ABS_PRESSURE] = 1024;
			if (!strlen(acecad->name))
				snprintf(acecad->name, sizeof(acecad->name),
					"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;
	}

	acecad->dev.absfuzz[ABS_X] = 4;
	acecad->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;
	input_dev->absfuzz[ABS_X] = 4;
	input_dev->absfuzz[ABS_Y] = 4;

	usb_fill_int_urb(acecad->irq, dev, pipe,
			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_flags |= URB_NO_TRANSFER_DMA_MAP;

	input_register_device(&acecad->dev);

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

	usb_set_intfdata(intf, acecad);

	return 0;

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

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

struct aiptek {
	struct input_dev inputdev;		/* input device struct           */
	struct input_dev *inputdev;		/* input device struct           */
	struct usb_device *usbdev;		/* usb device struct             */
	struct urb *urb;			/* urb for incoming reports      */
	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;
	unsigned char *data = aiptek->data;
	struct input_dev *inputdev = &aiptek->inputdev;
	struct input_dev *inputdev = aiptek->inputdev;
	int jitterable = 0;
	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 */
	if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0)
		return ret;
	aiptek->inputdev.absmin[ABS_X] = 0;
	aiptek->inputdev.absmax[ABS_X] = ret - 1;
	aiptek->inputdev->absmin[ABS_X] = 0;
	aiptek->inputdev->absmax[ABS_X] = ret - 1;

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

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

	/* Depending on whether we are in absolute or relative mode, we will
	 * 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 snprintf(buf, PAGE_SIZE, "%dx%d\n",
			aiptek->inputdev.absmax[ABS_X] + 1,
			aiptek->inputdev.absmax[ABS_Y] + 1);
			aiptek->inputdev->absmax[ABS_X] + 1,
			aiptek->inputdev->absmax[ABS_Y] + 1);
}

/* 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 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);
@@ -1063,7 +1063,7 @@ static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute *
	if (aiptek == NULL)
		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);
@@ -1977,7 +1977,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
	struct input_dev *inputdev;
	struct input_handle *inputhandle;
	struct list_head *node, *next;
	char path[64 + 1];
	int i;
	int speeds[] = { 0,
		AIPTEK_PROGRAMMABLE_DELAY_50,
@@ -1996,24 +1995,26 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
	 */
	speeds[0] = programmableDelay;

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

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

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

	aiptek->inputdev = inputdev;
	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
	 * 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
	 */
	memcpy(&aiptek->newSetting, &aiptek->curSetting,
	       sizeof(struct aiptek_settings));
	aiptek->newSetting = aiptek->curSetting;

	/* 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
	 * an input device.
	 */
	aiptek->inputdev.evbit[0] |= BIT(EV_KEY)
	inputdev->evbit[0] |= BIT(EV_KEY)
	    | BIT(EV_ABS)
	    | BIT(EV_REL)
	    | BIT(EV_MSC);

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

	aiptek->inputdev.relbit[0] |=
	inputdev->relbit[0] |=
	    (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));

	aiptek->inputdev.keybit[LONG(BTN_DIGI)] |=
	inputdev->keybit[LONG(BTN_DIGI)] |=
	    (BIT(BTN_TOOL_PEN) |
	     BIT(BTN_TOOL_RUBBER) |
	     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_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
	 * as the keycodes are discontiguous.
	 */
	for (i = 0; i < sizeof(macroKeyEvents) / sizeof(macroKeyEvents[0]); ++i)
		set_bit(macroKeyEvents[i], aiptek->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);
		set_bit(macroKeyEvents[i], inputdev->keybit);

	/* 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
	 * values in. Later, we'll ask the tablet to put in the correct
	 * values.
	 */
	aiptek->inputdev.absmin[ABS_X] = 0;
	aiptek->inputdev.absmax[ABS_X] = 2999;
	aiptek->inputdev.absmin[ABS_Y] = 0;
	aiptek->inputdev.absmax[ABS_Y] = 2249;
	aiptek->inputdev.absmin[ABS_PRESSURE] = 0;
	aiptek->inputdev.absmax[ABS_PRESSURE] = 511;
	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;
	input_set_abs_params(inputdev, ABS_X, 0, 2999, 0, 0);
	input_set_abs_params(inputdev, ABS_X, 0, 2249, 0, 0);
	input_set_abs_params(inputdev, ABS_PRESSURE, 0, 511, 0, 0);
	input_set_abs_params(inputdev, ABS_TILT_X, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
	input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
	input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0);

	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_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
	 * specified in newSetting, and also queries the tablet's
	 * 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) {
		aiptek->curSetting.programmableDelay = speeds[i];
		(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",
			     aiptek->curSetting.programmableDelay);
			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.
	 */
	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");

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

/* Structure to hold all of our device specific stuff */
struct atp {
	char			phys[64];
	struct usb_device *	udev;		/* usb device */
	struct urb *		urb;		/* usb request block */
	signed char *		data;		/* transferred data */
	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			x_old;		/* last reported x/y, */
	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++)
			if (dev->xy_cur[i]) {
				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_XFACT - 1,
						     ATP_FUZZ, 0);
@@ -260,12 +261,12 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
				       "Xz: %3d Yz: %3d\n",
				       x, y, x_z, y_z);

			input_report_key(&dev->input, BTN_TOUCH, 1);
			input_report_abs(&dev->input, ABS_X, x);
			input_report_abs(&dev->input, ABS_Y, y);
			input_report_abs(&dev->input, ABS_PRESSURE,
			input_report_key(dev->input, BTN_TOUCH, 1);
			input_report_abs(dev->input, ABS_X, x);
			input_report_abs(dev->input, ABS_Y, y);
			input_report_abs(dev->input, ABS_PRESSURE,
					 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->y_old = y;
@@ -273,17 +274,17 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
	else if (!x && !y) {

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

		/* reset the accumulator on release */
		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:
	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)
{
	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_endpoint_descriptor *endpoint;
	int int_in_endpointAddr = 0;
	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 */
	/* 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) {
		retval = -EIO;
		err("Could not find int-in endpoint");
		goto err_endpoint;
		return -EIO;
	}

	/* save our data pointer in this interface device */
	usb_set_intfdata(iface, dev);
	/* allocate memory for our device state and initialize it */
	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);
	if (!dev->urb) {
		retval = -ENOMEM;
		goto err_usballoc;
		goto err_free_devs;
	}

	dev->data = usb_buffer_alloc(dev->udev, ATP_DATASIZE, GFP_KERNEL,
				     &dev->urb->transfer_dma);
	if (!dev->data) {
		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);

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

	input_dev->name = "appletouch";
	input_dev->phys = dev->phys;
	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,
	 * 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);
	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);
	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(BTN_TOUCH, dev->input.keybit);
	set_bit(BTN_TOOL_FINGER, dev->input.keybit);
	set_bit(BTN_TOOL_DOUBLETAP, dev->input.keybit);
	set_bit(BTN_TOOL_TRIPLETAP, dev->input.keybit);
	set_bit(BTN_LEFT, dev->input.keybit);
	set_bit(EV_KEY, input_dev->evbit);
	set_bit(BTN_TOUCH, input_dev->keybit);
	set_bit(BTN_TOOL_FINGER, input_dev->keybit);
	set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
	set_bit(BTN_TOOL_TRIPLETAP, input_dev->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;

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

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

File changed.

Preview size limit exceeded, changes collapsed.

+27 −24
Original line number 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_device *hid;
	unsigned quirks = 0, rsize = 0;
	char *buf, *rdesc;
	int n, insize = 0;
	char *rdesc;
	int n, len, insize = 0;

	for (n = 0; hid_blacklist[n].idVendor; n++)
		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)
		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))) {
		dbg("class descriptor not present\n");
		return NULL;
@@ -1749,32 +1750,34 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)

	hid->name[0] = 0;

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

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

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

	usb_make_path(dev, buf, 64);
	snprintf(hid->phys, 64, "%s/input%d", buf,
			intf->altsetting[0].desc.bInterfaceNumber);
	usb_make_path(dev, hid->phys, sizeof(hid->phys));
	strlcat(hid->phys, "/input", sizeof(hid->phys));
	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)
		hid->uniq[0] = 0;

	kfree(buf);

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

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