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

[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
...@@ -53,7 +53,7 @@ struct usb_acecad { ...@@ -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) ...@@ -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_ ...@@ -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_ ...@@ -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_ ...@@ -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_ ...@@ -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_ ...@@ -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) ...@@ -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);
......
...@@ -317,7 +317,7 @@ struct aiptek_settings { ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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 * ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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),
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#define APPLE_VENDOR_ID 0x05AC #define APPLE_VENDOR_ID 0x05AC
#define ATP_DEVICE(prod) \ #define ATP_DEVICE(prod) \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
USB_DEVICE_ID_MATCH_INT_CLASS | \ USB_DEVICE_ID_MATCH_INT_CLASS | \
USB_DEVICE_ID_MATCH_INT_PROTOCOL, \ USB_DEVICE_ID_MATCH_INT_PROTOCOL, \
.idVendor = APPLE_VENDOR_ID, \ .idVendor = APPLE_VENDOR_ID, \
...@@ -78,9 +78,9 @@ MODULE_DEVICE_TABLE (usb, atp_table); ...@@ -78,9 +78,9 @@ MODULE_DEVICE_TABLE (usb, atp_table);
* We try to keep the touchpad aspect ratio while still doing only simple * We try to keep the touchpad aspect ratio while still doing only simple
* arithmetics. * arithmetics.
* The factors below give coordinates like: * The factors below give coordinates like:
* 0 <= x < 960 on 12" and 15" Powerbooks * 0 <= x < 960 on 12" and 15" Powerbooks
* 0 <= x < 1600 on 17" Powerbooks * 0 <= x < 1600 on 17" Powerbooks
* 0 <= y < 646 * 0 <= y < 646
*/ */
#define ATP_XFACT 64 #define ATP_XFACT 64
#define ATP_YFACT 43 #define ATP_YFACT 43
...@@ -93,11 +93,12 @@ MODULE_DEVICE_TABLE (usb, atp_table); ...@@ -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 */
...@@ -114,11 +115,11 @@ struct atp { ...@@ -114,11 +115,11 @@ struct atp {
int i; \ int i; \
printk("appletouch: %s %lld", msg, (long long)jiffies); \ printk("appletouch: %s %lld", msg, (long long)jiffies); \
for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) \ for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) \
printk(" %02x", tab[i]); \ printk(" %02x", tab[i]); \
printk("\n"); \ printk("\n"); \
} }
#define dprintk(format, a...) \ #define dprintk(format, a...) \
do { \ do { \
if (debug) printk(format, ##a); \ if (debug) printk(format, ##a); \
} while (0) } while (0)
...@@ -219,8 +220,8 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs) ...@@ -219,8 +220,8 @@ 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);
break; break;
...@@ -260,12 +261,12 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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);
......
...@@ -112,7 +112,6 @@ ...@@ -112,7 +112,6 @@
#define NAME_BUFSIZE 80 /* size of product name, path buffers */ #define NAME_BUFSIZE 80 /* size of product name, path buffers */
#define DATA_BUFSIZE 63 /* size of URB data buffers */ #define DATA_BUFSIZE 63 /* size of URB data buffers */
#define ATI_INPUTNUM 1 /* Which input device to register as */
static unsigned long channel_mask; static unsigned long channel_mask;
module_param(channel_mask, ulong, 0444); module_param(channel_mask, ulong, 0444);
...@@ -162,7 +161,7 @@ static char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; ...@@ -162,7 +161,7 @@ static char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
static DECLARE_MUTEX(disconnect_sem); static DECLARE_MUTEX(disconnect_sem);
struct ati_remote { struct ati_remote {
struct input_dev idev; struct input_dev *idev;
struct usb_device *udev; struct usb_device *udev;
struct usb_interface *interface; struct usb_interface *interface;
...@@ -198,15 +197,13 @@ struct ati_remote { ...@@ -198,15 +197,13 @@ struct ati_remote {
#define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/ #define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/
/* Translation table from hardware messages to input events. */ /* Translation table from hardware messages to input events. */
static struct static struct {
{
short kind; short kind;
unsigned char data1, data2; unsigned char data1, data2;
int type; int type;
unsigned int code; unsigned int code;
int value; int value;
} ati_remote_tbl[] = } ati_remote_tbl[] = {
{
/* Directional control pad axes */ /* Directional control pad axes */
{KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */ {KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */
{KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */ {KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */
...@@ -286,7 +283,6 @@ static struct ...@@ -286,7 +283,6 @@ static struct
/* Local function prototypes */ /* Local function prototypes */
static void ati_remote_dump (unsigned char *data, unsigned int actual_length); static void ati_remote_dump (unsigned char *data, unsigned int actual_length);
static void ati_remote_delete (struct ati_remote *dev);
static int ati_remote_open (struct input_dev *inputdev); static int ati_remote_open (struct input_dev *inputdev);
static void ati_remote_close (struct input_dev *inputdev); static void ati_remote_close (struct input_dev *inputdev);
static int ati_remote_sendpacket (struct ati_remote *ati_remote, u16 cmd, unsigned char *data); static int ati_remote_sendpacket (struct ati_remote *ati_remote, u16 cmd, unsigned char *data);
...@@ -428,7 +424,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) ...@@ -428,7 +424,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
{ {
struct ati_remote *ati_remote = urb->context; struct ati_remote *ati_remote = urb->context;
unsigned char *data= ati_remote->inbuf; unsigned char *data= ati_remote->inbuf;
struct input_dev *dev = &ati_remote->idev; struct input_dev *dev = ati_remote->idev;
int index, acc; int index, acc;
int remote_num; int remote_num;
...@@ -587,38 +583,55 @@ static void ati_remote_irq_in(struct urb *urb, struct pt_regs *regs) ...@@ -587,38 +583,55 @@ static void ati_remote_irq_in(struct urb *urb, struct pt_regs *regs)
} }
/* /*
* ati_remote_delete * ati_remote_alloc_buffers
*/ */
static void ati_remote_delete(struct ati_remote *ati_remote) static int ati_remote_alloc_buffers(struct usb_device *udev,
struct ati_remote *ati_remote)
{ {
if (ati_remote->irq_urb) ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
usb_kill_urb(ati_remote->irq_urb); &ati_remote->inbuf_dma);
if (!ati_remote->inbuf)
return -1;
if (ati_remote->out_urb) ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
usb_kill_urb(ati_remote->out_urb); &ati_remote->outbuf_dma);
if (!ati_remote->outbuf)
return -1;
input_unregister_device(&ati_remote->idev); ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!ati_remote->irq_urb)
return -1;
if (ati_remote->inbuf) ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL);
usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, if (!ati_remote->out_urb)
ati_remote->inbuf, ati_remote->inbuf_dma); return -1;
if (ati_remote->outbuf) return 0;
usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, }
ati_remote->outbuf, ati_remote->outbuf_dma);
/*
* ati_remote_free_buffers
*/
static void ati_remote_free_buffers(struct ati_remote *ati_remote)
{
if (ati_remote->irq_urb) if (ati_remote->irq_urb)
usb_free_urb(ati_remote->irq_urb); usb_free_urb(ati_remote->irq_urb);
if (ati_remote->out_urb) if (ati_remote->out_urb)
usb_free_urb(ati_remote->out_urb); usb_free_urb(ati_remote->out_urb);
kfree(ati_remote); if (ati_remote->inbuf)
usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
ati_remote->inbuf, ati_remote->inbuf_dma);
if (ati_remote->outbuf)
usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
ati_remote->inbuf, ati_remote->outbuf_dma);
} }
static void ati_remote_input_init(struct ati_remote *ati_remote) static void ati_remote_input_init(struct ati_remote *ati_remote)
{ {
struct input_dev *idev = &(ati_remote->idev); struct input_dev *idev = ati_remote->idev;
int i; int i;
idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
...@@ -637,7 +650,7 @@ static void ati_remote_input_init(struct ati_remote *ati_remote) ...@@ -637,7 +650,7 @@ static void ati_remote_input_init(struct ati_remote *ati_remote)
idev->phys = ati_remote->phys; idev->phys = ati_remote->phys;
usb_to_input_id(ati_remote->udev, &idev->id); usb_to_input_id(ati_remote->udev, &idev->id);
idev->dev = &ati_remote->udev->dev; idev->cdev.dev = &ati_remote->udev->dev;
} }
static int ati_remote_initialize(struct ati_remote *ati_remote) static int ati_remote_initialize(struct ati_remote *ati_remote)
...@@ -674,7 +687,7 @@ static int ati_remote_initialize(struct ati_remote *ati_remote) ...@@ -674,7 +687,7 @@ static int ati_remote_initialize(struct ati_remote *ati_remote)
(ati_remote_sendpacket(ati_remote, 0x8007, init2))) { (ati_remote_sendpacket(ati_remote, 0x8007, init2))) {
dev_err(&ati_remote->interface->dev, dev_err(&ati_remote->interface->dev,
"Initializing ati_remote hardware failed.\n"); "Initializing ati_remote hardware failed.\n");
return 1; return -EIO;
} }
return 0; return 0;
...@@ -686,95 +699,83 @@ static int ati_remote_initialize(struct ati_remote *ati_remote) ...@@ -686,95 +699,83 @@ static int ati_remote_initialize(struct ati_remote *ati_remote)
static int ati_remote_probe(struct usb_interface *interface, const struct usb_device_id *id) static int ati_remote_probe(struct usb_interface *interface, const struct usb_device_id *id)
{ {
struct usb_device *udev = interface_to_usbdev(interface); struct usb_device *udev = interface_to_usbdev(interface);
struct ati_remote *ati_remote = NULL; struct usb_host_interface *iface_host = interface->cur_altsetting;
struct usb_host_interface *iface_host; struct usb_endpoint_descriptor *endpoint_in, *endpoint_out;
int retval = -ENOMEM; struct ati_remote *ati_remote;
char path[64]; struct input_dev *input_dev;
int err = -ENOMEM;
/* Allocate and clear an ati_remote struct */
if (!(ati_remote = kmalloc(sizeof (struct ati_remote), GFP_KERNEL)))
return -ENOMEM;
memset(ati_remote, 0x00, sizeof (struct ati_remote));
iface_host = interface->cur_altsetting;
if (iface_host->desc.bNumEndpoints != 2) { if (iface_host->desc.bNumEndpoints != 2) {
err("%s: Unexpected desc.bNumEndpoints\n", __FUNCTION__); err("%s: Unexpected desc.bNumEndpoints\n", __FUNCTION__);
retval = -ENODEV; return -ENODEV;
goto error;
} }
ati_remote->endpoint_in = &(iface_host->endpoint[0].desc); endpoint_in = &iface_host->endpoint[0].desc;
ati_remote->endpoint_out = &(iface_host->endpoint[1].desc); endpoint_out = &iface_host->endpoint[1].desc;
ati_remote->udev = udev;
ati_remote->interface = interface;
if (!(ati_remote->endpoint_in->bEndpointAddress & 0x80)) { if (!(endpoint_in->bEndpointAddress & USB_DIR_IN)) {
err("%s: Unexpected endpoint_in->bEndpointAddress\n", __FUNCTION__); err("%s: Unexpected endpoint_in->bEndpointAddress\n", __FUNCTION__);
retval = -ENODEV; return -ENODEV;
goto error;
} }
if ((ati_remote->endpoint_in->bmAttributes & 3) != 3) { if ((endpoint_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
err("%s: Unexpected endpoint_in->bmAttributes\n", __FUNCTION__); err("%s: Unexpected endpoint_in->bmAttributes\n", __FUNCTION__);
retval = -ENODEV; return -ENODEV;
goto error;
} }
if (le16_to_cpu(ati_remote->endpoint_in->wMaxPacketSize) == 0) { if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) {
err("%s: endpoint_in message size==0? \n", __FUNCTION__); err("%s: endpoint_in message size==0? \n", __FUNCTION__);
retval = -ENODEV; return -ENODEV;
goto error;
} }
/* Allocate URB buffers, URBs */ ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL);
ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC, input_dev = input_allocate_device();
&ati_remote->inbuf_dma); if (!ati_remote || !input_dev)
if (!ati_remote->inbuf) goto fail1;
goto error;
ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC, /* Allocate URB buffers, URBs */
&ati_remote->outbuf_dma); if (ati_remote_alloc_buffers(udev, ati_remote))
if (!ati_remote->outbuf) goto fail2;
goto error;
ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); ati_remote->endpoint_in = endpoint_in;
if (!ati_remote->irq_urb) ati_remote->endpoint_out = endpoint_out;
goto error; ati_remote->udev = udev;
ati_remote->idev = input_dev;
ati_remote->interface = interface;
ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL); usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys));
if (!ati_remote->out_urb) strlcpy(ati_remote->phys, "/input0", sizeof(ati_remote->phys));
goto error;
usb_make_path(udev, path, NAME_BUFSIZE);
sprintf(ati_remote->phys, "%s/input%d", path, ATI_INPUTNUM);
if (udev->manufacturer) if (udev->manufacturer)
strcat(ati_remote->name, udev->manufacturer); strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name));
if (udev->product) if (udev->product)
sprintf(ati_remote->name, "%s %s", ati_remote->name, udev->product); snprintf(ati_remote->name, sizeof(ati_remote->name),
"%s %s", ati_remote->name, udev->product);
if (!strlen(ati_remote->name)) if (!strlen(ati_remote->name))
sprintf(ati_remote->name, DRIVER_DESC "(%04x,%04x)", snprintf(ati_remote->name, sizeof(ati_remote->name),
DRIVER_DESC "(%04x,%04x)",
le16_to_cpu(ati_remote->udev->descriptor.idVendor), le16_to_cpu(ati_remote->udev->descriptor.idVendor),
le16_to_cpu(ati_remote->udev->descriptor.idProduct)); le16_to_cpu(ati_remote->udev->descriptor.idProduct));
ati_remote_input_init(ati_remote);
/* Device Hardware Initialization - fills in ati_remote->idev from udev. */ /* Device Hardware Initialization - fills in ati_remote->idev from udev. */
retval = ati_remote_initialize(ati_remote); err = ati_remote_initialize(ati_remote);
if (retval) if (err)
goto error; goto fail3;
/* Set up and register input device */ /* Set up and register input device */
ati_remote_input_init(ati_remote); input_register_device(ati_remote->idev);
input_register_device(&ati_remote->idev);
dev_info(&ati_remote->interface->dev, "Input registered: %s on %s\n",
ati_remote->name, path);
usb_set_intfdata(interface, ati_remote); usb_set_intfdata(interface, ati_remote);
return 0;
error: fail3: usb_kill_urb(ati_remote->irq_urb);
if (retval) usb_kill_urb(ati_remote->out_urb);
ati_remote_delete(ati_remote); fail2: ati_remote_free_buffers(ati_remote);
fail1: input_free_device(input_dev);
return retval; kfree(ati_remote);
return err;
} }
/* /*
...@@ -791,7 +792,11 @@ static void ati_remote_disconnect(struct usb_interface *interface) ...@@ -791,7 +792,11 @@ static void ati_remote_disconnect(struct usb_interface *interface)
return; return;
} }
ati_remote_delete(ati_remote); usb_kill_urb(ati_remote->irq_urb);
usb_kill_urb(ati_remote->out_urb);
input_unregister_device(ati_remote->idev);
ati_remote_free_buffers(ati_remote);
kfree(ati_remote);
} }
/* /*
......
...@@ -1619,8 +1619,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) ...@@ -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,10 +1630,11 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) ...@@ -1630,10 +1630,11 @@ 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) &&
usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { (!interface->desc.bNumEndpoints ||
dbg("class descriptor not present\n"); usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
return NULL; dbg("class descriptor not present\n");
return NULL;
} }
for (n = 0; n < hdesc->bNumDescriptors; n++) for (n = 0; n < hdesc->bNumDescriptors; n++)
...@@ -1749,32 +1750,34 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) ...@@ -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->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));
if (dev->manufacturer) { usb_make_path(dev, hid->phys, sizeof(hid->phys));
strcat(hid->name, dev->manufacturer); strlcat(hid->phys, "/input", sizeof(hid->phys));
if (dev->product) len = strlen(hid->phys);
snprintf(hid->name, 64, "%s %s", hid->name, dev->product); if (len < sizeof(hid->phys) - 1)
} else if (dev->product) { snprintf(hid->phys + len, sizeof(hid->phys) - len,
snprintf(hid->name, 128, "%s", dev->product); "%d", intf->altsetting[0].desc.bInterfaceNumber);
} else
snprintf(hid->name, 128, "%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);
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;
......
...@@ -76,8 +76,8 @@ static struct { ...@@ -76,8 +76,8 @@ static struct {
static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
struct hid_usage *usage) struct hid_usage *usage)
{ {
struct input_dev *input = &hidinput->input; struct input_dev *input = hidinput->input;
struct hid_device *device = hidinput->input.private; struct hid_device *device = input->private;
int max = 0, code; int max = 0, code;
unsigned long *bit = NULL; unsigned long *bit = NULL;
...@@ -461,7 +461,8 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct ...@@ -461,7 +461,8 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
if (!field->hidinput) if (!field->hidinput)
return; return;
input = &field->hidinput->input;
input = field->hidinput->input;
input_regs(input, regs); input_regs(input, regs);
...@@ -533,13 +534,10 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct ...@@ -533,13 +534,10 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
void hidinput_report_event(struct hid_device *hid, struct hid_report *report) void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
{ {
struct list_head *lh;
struct hid_input *hidinput; struct hid_input *hidinput;
list_for_each (lh, &hid->inputs) { list_for_each_entry(hidinput, &hid->inputs, list)
hidinput = list_entry(lh, struct hid_input, list); input_sync(hidinput->input);
input_sync(&hidinput->input);
}
} }
static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field) static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
...@@ -604,6 +602,7 @@ int hidinput_connect(struct hid_device *hid) ...@@ -604,6 +602,7 @@ int hidinput_connect(struct hid_device *hid)
struct usb_device *dev = hid->dev; struct usb_device *dev = hid->dev;
struct hid_report *report; struct hid_report *report;
struct hid_input *hidinput = NULL; struct hid_input *hidinput = NULL;
struct input_dev *input_dev;
int i, j, k; int i, j, k;
INIT_LIST_HEAD(&hid->inputs); INIT_LIST_HEAD(&hid->inputs);
...@@ -624,25 +623,28 @@ int hidinput_connect(struct hid_device *hid) ...@@ -624,25 +623,28 @@ int hidinput_connect(struct hid_device *hid)
continue; continue;
if (!hidinput) { if (!hidinput) {
hidinput = kmalloc(sizeof(*hidinput), GFP_KERNEL); hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
if (!hidinput) { input_dev = input_allocate_device();
if (!hidinput || !input_dev) {
kfree(hidinput);
input_free_device(input_dev);
err("Out of memory during hid input probe"); err("Out of memory during hid input probe");
return -1; return -1;
} }
memset(hidinput, 0, sizeof(*hidinput));
list_add_tail(&hidinput->list, &hid->inputs); input_dev->private = hid;
input_dev->event = hidinput_input_event;
input_dev->open = hidinput_open;
input_dev->close = hidinput_close;
hidinput->input.private = hid; input_dev->name = hid->name;
hidinput->input.event = hidinput_input_event; input_dev->phys = hid->phys;
hidinput->input.open = hidinput_open; input_dev->uniq = hid->uniq;
hidinput->input.close = hidinput_close; usb_to_input_id(dev, &input_dev->id);
input_dev->cdev.dev = &hid->intf->dev;
hidinput->input.name = hid->name; hidinput->input = input_dev;
hidinput->input.phys = hid->phys; list_add_tail(&hidinput->list, &hid->inputs);
hidinput->input.uniq = hid->uniq;
usb_to_input_id(dev, &hidinput->input.id);
hidinput->input.dev = &hid->intf->dev;
} }
for (i = 0; i < report->maxfield; i++) for (i = 0; i < report->maxfield; i++)
...@@ -657,7 +659,7 @@ int hidinput_connect(struct hid_device *hid) ...@@ -657,7 +659,7 @@ int hidinput_connect(struct hid_device *hid)
* UGCI) cram a lot of unrelated inputs into the * UGCI) cram a lot of unrelated inputs into the
* same interface. */ * same interface. */
hidinput->report = report; hidinput->report = report;
input_register_device(&hidinput->input); input_register_device(hidinput->input);
hidinput = NULL; hidinput = NULL;
} }
} }
...@@ -667,7 +669,7 @@ int hidinput_connect(struct hid_device *hid) ...@@ -667,7 +669,7 @@ int hidinput_connect(struct hid_device *hid)
* only useful in this case, and not for multi-input quirks. */ * only useful in this case, and not for multi-input quirks. */
if (hidinput) { if (hidinput) {
hid_ff_init(hid); hid_ff_init(hid);
input_register_device(&hidinput->input); input_register_device(hidinput->input);
} }
return 0; return 0;
...@@ -675,13 +677,11 @@ int hidinput_connect(struct hid_device *hid) ...@@ -675,13 +677,11 @@ int hidinput_connect(struct hid_device *hid)
void hidinput_disconnect(struct hid_device *hid) void hidinput_disconnect(struct hid_device *hid)
{ {
struct list_head *lh, *next; struct hid_input *hidinput, *next;
struct hid_input *hidinput;
list_for_each_safe(lh, next, &hid->inputs) { list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
hidinput = list_entry(lh, struct hid_input, list);
input_unregister_device(&hidinput->input);
list_del(&hidinput->list); list_del(&hidinput->list);
input_unregister_device(hidinput->input);
kfree(hidinput); kfree(hidinput);
} }
} }
...@@ -255,22 +255,19 @@ static void hid_lgff_input_init(struct hid_device* hid) ...@@ -255,22 +255,19 @@ static void hid_lgff_input_init(struct hid_device* hid)
u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor); u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor);
u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct); u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct);
struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
struct input_dev *input_dev = hidinput->input;
while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct)) while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct))
dev++; dev++;
ff = dev->ff; for (ff = dev->ff; *ff >= 0; ff++)
set_bit(*ff, input_dev->ffbit);
while (*ff >= 0) { input_dev->upload_effect = hid_lgff_upload_effect;
set_bit(*ff, hidinput->input.ffbit); input_dev->flush = hid_lgff_flush;
++ff;
}
hidinput->input.upload_effect = hid_lgff_upload_effect;
hidinput->input.flush = hid_lgff_flush;
set_bit(EV_FF, hidinput->input.evbit); set_bit(EV_FF, input_dev->evbit);
hidinput->input.ff_effects_max = LGFF_EFFECTS; input_dev->ff_effects_max = LGFF_EFFECTS;
} }
static void hid_lgff_exit(struct hid_device* hid) static void hid_lgff_exit(struct hid_device* hid)
......
...@@ -111,6 +111,7 @@ int hid_tmff_init(struct hid_device *hid) ...@@ -111,6 +111,7 @@ int hid_tmff_init(struct hid_device *hid)
struct tmff_device *private; struct tmff_device *private;
struct list_head *pos; struct list_head *pos;
struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
struct input_dev *input_dev = hidinput->input;
private = kmalloc(sizeof(struct tmff_device), GFP_KERNEL); private = kmalloc(sizeof(struct tmff_device), GFP_KERNEL);
if (!private) if (!private)
...@@ -155,7 +156,7 @@ int hid_tmff_init(struct hid_device *hid) ...@@ -155,7 +156,7 @@ int hid_tmff_init(struct hid_device *hid)
private->report = report; private->report = report;
private->rumble = field; private->rumble = field;
set_bit(FF_RUMBLE, hidinput->input.ffbit); set_bit(FF_RUMBLE, input_dev->ffbit);
break; break;
default: default:
...@@ -164,11 +165,11 @@ int hid_tmff_init(struct hid_device *hid) ...@@ -164,11 +165,11 @@ int hid_tmff_init(struct hid_device *hid)
} }
/* Fallthrough to here only when a valid usage is found */ /* Fallthrough to here only when a valid usage is found */
hidinput->input.upload_effect = hid_tmff_upload_effect; input_dev->upload_effect = hid_tmff_upload_effect;
hidinput->input.flush = hid_tmff_flush; input_dev->flush = hid_tmff_flush;
set_bit(EV_FF, hidinput->input.evbit); set_bit(EV_FF, input_dev->evbit);
hidinput->input.ff_effects_max = TMFF_EFFECTS; input_dev->ff_effects_max = TMFF_EFFECTS;
} }
} }
......
...@@ -371,7 +371,7 @@ struct hid_control_fifo { ...@@ -371,7 +371,7 @@ struct hid_control_fifo {
struct hid_input { struct hid_input {
struct list_head list; struct list_head list;
struct hid_report *report; struct hid_report *report;
struct input_dev input; struct input_dev *input;
}; };
struct hid_device { /* device report descriptor */ struct hid_device { /* device report descriptor */
......
...@@ -73,7 +73,7 @@ MODULE_LICENSE( DRIVER_LICENSE ); ...@@ -73,7 +73,7 @@ MODULE_LICENSE( DRIVER_LICENSE );
struct itmtouch_dev { struct itmtouch_dev {
struct usb_device *usbdev; /* usb device */ struct usb_device *usbdev; /* usb device */
struct input_dev inputdev; /* input device */ struct input_dev *inputdev; /* input device */
struct urb *readurb; /* urb */ struct urb *readurb; /* urb */
char rbuf[ITM_BUFSIZE]; /* data */ char rbuf[ITM_BUFSIZE]; /* data */
int users; int users;
...@@ -88,9 +88,9 @@ static struct usb_device_id itmtouch_ids [] = { ...@@ -88,9 +88,9 @@ static struct usb_device_id itmtouch_ids [] = {
static void itmtouch_irq(struct urb *urb, struct pt_regs *regs) static void itmtouch_irq(struct urb *urb, struct pt_regs *regs)
{ {
struct itmtouch_dev * itmtouch = urb->context; struct itmtouch_dev *itmtouch = urb->context;
unsigned char *data = urb->transfer_buffer; unsigned char *data = urb->transfer_buffer;
struct input_dev *dev = &itmtouch->inputdev; struct input_dev *dev = itmtouch->inputdev;
int retval; int retval;
switch (urb->status) { switch (urb->status) {
...@@ -156,49 +156,62 @@ static void itmtouch_close(struct input_dev *input) ...@@ -156,49 +156,62 @@ static void itmtouch_close(struct input_dev *input)
static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id *id) static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id *id)
{ {
struct itmtouch_dev *itmtouch; struct itmtouch_dev *itmtouch;
struct input_dev *input_dev;
struct usb_host_interface *interface; struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *endpoint;
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
unsigned int pipe; unsigned int pipe;
unsigned int maxp; unsigned int maxp;
char path[PATH_SIZE];
interface = intf->cur_altsetting; interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc; endpoint = &interface->endpoint[0].desc;
if (!(itmtouch = kzalloc(sizeof(struct itmtouch_dev), GFP_KERNEL))) { itmtouch = kzalloc(sizeof(struct itmtouch_dev), GFP_KERNEL);
input_dev = input_allocate_device();
if (!itmtouch || !input_dev) {
err("%s - Out of memory.", __FUNCTION__); err("%s - Out of memory.", __FUNCTION__);
return -ENOMEM; goto fail;
} }
itmtouch->usbdev = udev; itmtouch->usbdev = udev;
itmtouch->inputdev = input_dev;
itmtouch->inputdev.private = itmtouch; if (udev->manufacturer)
itmtouch->inputdev.open = itmtouch_open; strlcpy(itmtouch->name, udev->manufacturer, sizeof(itmtouch->name));
itmtouch->inputdev.close = itmtouch_close;
usb_make_path(udev, path, PATH_SIZE); if (udev->product) {
if (udev->manufacturer)
itmtouch->inputdev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); strlcat(itmtouch->name, " ", sizeof(itmtouch->name));
itmtouch->inputdev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); strlcat(itmtouch->name, udev->product, sizeof(itmtouch->name));
itmtouch->inputdev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); }
itmtouch->inputdev.name = itmtouch->name;
itmtouch->inputdev.phys = itmtouch->phys;
usb_to_input_id(udev, &itmtouch->inputdev.id);
itmtouch->inputdev.dev = &intf->dev;
if (!strlen(itmtouch->name)) if (!strlen(itmtouch->name))
sprintf(itmtouch->name, "USB ITM touchscreen"); sprintf(itmtouch->name, "USB ITM touchscreen");
usb_make_path(udev, itmtouch->phys, sizeof(itmtouch->phys));
strlcpy(itmtouch->phys, "/input0", sizeof(itmtouch->phys));
input_dev->name = itmtouch->name;
input_dev->phys = itmtouch->phys;
usb_to_input_id(udev, &input_dev->id);
input_dev->cdev.dev = &intf->dev;
input_dev->private = itmtouch;
input_dev->open = itmtouch_open;
input_dev->close = itmtouch_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_TOUCH)] = BIT(BTN_TOUCH);
/* device limits */ /* device limits */
/* as specified by the ITM datasheet, X and Y are 12bit, /* as specified by the ITM datasheet, X and Y are 12bit,
* Z (pressure) is 8 bit. However, the fields are defined up * Z (pressure) is 8 bit. However, the fields are defined up
* to 14 bits for future possible expansion. * to 14 bits for future possible expansion.
*/ */
input_set_abs_params(&itmtouch->inputdev, ABS_X, 0, 0x0FFF, 2, 0); input_set_abs_params(input_dev, ABS_X, 0, 0x0FFF, 2, 0);
input_set_abs_params(&itmtouch->inputdev, ABS_Y, 0, 0x0FFF, 2, 0); input_set_abs_params(input_dev, ABS_Y, 0, 0x0FFF, 2, 0);
input_set_abs_params(&itmtouch->inputdev, ABS_PRESSURE, 0, 0xFF, 2, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xFF, 2, 0);
/* initialise the URB so we can read from the transport stream */ /* initialise the URB so we can read from the transport stream */
pipe = usb_rcvintpipe(itmtouch->usbdev, endpoint->bEndpointAddress); pipe = usb_rcvintpipe(itmtouch->usbdev, endpoint->bEndpointAddress);
...@@ -208,22 +221,23 @@ static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id ...@@ -208,22 +221,23 @@ static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id
maxp = ITM_BUFSIZE; maxp = ITM_BUFSIZE;
itmtouch->readurb = usb_alloc_urb(0, GFP_KERNEL); itmtouch->readurb = usb_alloc_urb(0, GFP_KERNEL);
if (!itmtouch->readurb) { if (!itmtouch->readurb) {
dbg("%s - usb_alloc_urb failed: itmtouch->readurb", __FUNCTION__); dbg("%s - usb_alloc_urb failed: itmtouch->readurb", __FUNCTION__);
kfree(itmtouch); goto fail;
return -ENOMEM;
} }
usb_fill_int_urb(itmtouch->readurb, itmtouch->usbdev, pipe, itmtouch->rbuf, usb_fill_int_urb(itmtouch->readurb, itmtouch->usbdev, pipe, itmtouch->rbuf,
maxp, itmtouch_irq, itmtouch, endpoint->bInterval); maxp, itmtouch_irq, itmtouch, endpoint->bInterval);
input_register_device(&itmtouch->inputdev); input_register_device(itmtouch->inputdev);
printk(KERN_INFO "itmtouch: %s registered on %s\n", itmtouch->name, path);
usb_set_intfdata(intf, itmtouch); usb_set_intfdata(intf, itmtouch);
return 0; return 0;
fail: input_free_device(input_dev);
kfree(itmtouch);
return -ENOMEM;
} }
static void itmtouch_disconnect(struct usb_interface *intf) static void itmtouch_disconnect(struct usb_interface *intf)
...@@ -233,7 +247,7 @@ static void itmtouch_disconnect(struct usb_interface *intf) ...@@ -233,7 +247,7 @@ static void itmtouch_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
if (itmtouch) { if (itmtouch) {
input_unregister_device(&itmtouch->inputdev); input_unregister_device(itmtouch->inputdev);
usb_kill_urb(itmtouch->readurb); usb_kill_urb(itmtouch->readurb);
usb_free_urb(itmtouch->readurb); usb_free_urb(itmtouch->readurb);
kfree(itmtouch); kfree(itmtouch);
......
...@@ -34,7 +34,7 @@ MODULE_PARM_DESC(kb_pressure_click, "pressure threshold for clicks"); ...@@ -34,7 +34,7 @@ MODULE_PARM_DESC(kb_pressure_click, "pressure threshold for clicks");
struct kbtab { struct kbtab {
signed char *data; signed char *data;
dma_addr_t data_dma; dma_addr_t data_dma;
struct input_dev dev; struct input_dev *dev;
struct usb_device *usbdev; struct usb_device *usbdev;
struct urb *irq; struct urb *irq;
int x, y; int x, y;
...@@ -48,7 +48,7 @@ static void kbtab_irq(struct urb *urb, struct pt_regs *regs) ...@@ -48,7 +48,7 @@ static void kbtab_irq(struct urb *urb, struct pt_regs *regs)
{ {
struct kbtab *kbtab = urb->context; struct kbtab *kbtab = urb->context;
unsigned char *data = kbtab->data; unsigned char *data = kbtab->data;
struct input_dev *dev = &kbtab->dev; struct input_dev *dev = kbtab->dev;
int retval; int retval;
switch (urb->status) { switch (urb->status) {
...@@ -124,53 +124,43 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -124,53 +124,43 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
struct usb_device *dev = interface_to_usbdev(intf); struct usb_device *dev = interface_to_usbdev(intf);
struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *endpoint;
struct kbtab *kbtab; struct kbtab *kbtab;
char path[64]; struct input_dev *input_dev;
if (!(kbtab = kmalloc(sizeof(struct kbtab), GFP_KERNEL))) kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
return -ENOMEM; input_dev = input_allocate_device();
memset(kbtab, 0, sizeof(struct kbtab)); if (!kbtab || !input_dev)
goto fail1;
kbtab->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &kbtab->data_dma); kbtab->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &kbtab->data_dma);
if (!kbtab->data) { if (!kbtab->data)
kfree(kbtab); goto fail1;
return -ENOMEM;
}
kbtab->irq = usb_alloc_urb(0, GFP_KERNEL); kbtab->irq = usb_alloc_urb(0, GFP_KERNEL);
if (!kbtab->irq) { if (!kbtab->irq)
usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma); goto fail2;
kfree(kbtab);
return -ENOMEM;
}
kbtab->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
kbtab->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
kbtab->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
kbtab->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH);
kbtab->dev.mscbit[0] |= BIT(MSC_SERIAL); kbtab->usbdev = dev;
kbtab->dev = input_dev;
kbtab->dev.absmax[ABS_X] = 0x2000;
kbtab->dev.absmax[ABS_Y] = 0x1750;
kbtab->dev.absmax[ABS_PRESSURE] = 0xff;
kbtab->dev.absfuzz[ABS_X] = 4; usb_make_path(dev, kbtab->phys, sizeof(kbtab->phys));
kbtab->dev.absfuzz[ABS_Y] = 4; strlcat(kbtab->phys, "/input0", sizeof(kbtab->phys));
kbtab->dev.private = kbtab; input_dev->name = "KB Gear Tablet";
kbtab->dev.open = kbtab_open; input_dev->phys = kbtab->phys;
kbtab->dev.close = kbtab_close; usb_to_input_id(dev, &input_dev->id);
input_dev->cdev.dev = &intf->dev;
input_dev->private = kbtab;
usb_make_path(dev, path, 64); input_dev->open = kbtab_open;
sprintf(kbtab->phys, "%s/input0", path); input_dev->close = kbtab_close;
kbtab->dev.name = "KB Gear Tablet"; input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
kbtab->dev.phys = kbtab->phys; input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
usb_to_input_id(dev, &kbtab->dev.id); input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH);
kbtab->dev.dev = &intf->dev; input_dev->mscbit[0] |= BIT(MSC_SERIAL);
kbtab->usbdev = dev; input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0);
input_set_abs_params(input_dev, ABS_X, 0, 0x1750, 4, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0);
endpoint = &intf->cur_altsetting->endpoint[0].desc; endpoint = &intf->cur_altsetting->endpoint[0].desc;
...@@ -181,23 +171,25 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -181,23 +171,25 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
kbtab->irq->transfer_dma = kbtab->data_dma; kbtab->irq->transfer_dma = kbtab->data_dma;
kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
input_register_device(&kbtab->dev); input_register_device(kbtab->dev);
printk(KERN_INFO "input: KB Gear Tablet on %s\n", path);
usb_set_intfdata(intf, kbtab); usb_set_intfdata(intf, kbtab);
return 0; return 0;
fail2: usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
fail1: input_free_device(input_dev);
kfree(kbtab);
return -ENOMEM;
} }
static void kbtab_disconnect(struct usb_interface *intf) static void kbtab_disconnect(struct usb_interface *intf)
{ {
struct kbtab *kbtab = usb_get_intfdata (intf); struct kbtab *kbtab = usb_get_intfdata(intf);
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
if (kbtab) { if (kbtab) {
usb_kill_urb(kbtab->irq); usb_kill_urb(kbtab->irq);
input_unregister_device(&kbtab->dev); input_unregister_device(kbtab->dev);
usb_free_urb(kbtab->irq); usb_free_urb(kbtab->irq);
usb_buffer_free(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma); usb_buffer_free(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma);
kfree(kbtab); kfree(kbtab);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/usb_input.h>
#define DRIVER_VERSION "v0.1" #define DRIVER_VERSION "v0.1"
#define DRIVER_AUTHOR "Michael Downey <downey@zymeta.com>" #define DRIVER_AUTHOR "Michael Downey <downey@zymeta.com>"
...@@ -75,7 +76,7 @@ struct usb_keyspan { ...@@ -75,7 +76,7 @@ struct usb_keyspan {
char name[128]; char name[128];
char phys[64]; char phys[64];
struct usb_device* udev; struct usb_device* udev;
struct input_dev input; struct input_dev *input;
struct usb_interface* interface; struct usb_interface* interface;
struct usb_endpoint_descriptor* in_endpoint; struct usb_endpoint_descriptor* in_endpoint;
struct urb* irq_urb; struct urb* irq_urb;
...@@ -136,12 +137,11 @@ static struct usb_driver keyspan_driver; ...@@ -136,12 +137,11 @@ static struct usb_driver keyspan_driver;
*/ */
static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/ static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/
{ {
char codes[4*RECV_SIZE]; char codes[4 * RECV_SIZE];
int i; int i;
for (i = 0; i < RECV_SIZE; i++) { for (i = 0; i < RECV_SIZE; i++)
snprintf(codes+i*3, 4, "%02x ", dev->in_buffer[i]); snprintf(codes + i * 3, 4, "%02x ", dev->in_buffer[i]);
}
dev_info(&dev->udev->dev, "%s\n", codes); dev_info(&dev->udev->dev, "%s\n", codes);
} }
...@@ -153,7 +153,7 @@ static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/ ...@@ -153,7 +153,7 @@ static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/
static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed) static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
{ {
if (dev->data.bits_left >= bits_needed) if (dev->data.bits_left >= bits_needed)
return(0); return 0;
/* /*
* Somehow we've missed the last message. The message will be repeated * Somehow we've missed the last message. The message will be repeated
...@@ -162,7 +162,7 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed) ...@@ -162,7 +162,7 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
if (dev->data.pos >= dev->data.len) { if (dev->data.pos >= dev->data.len) {
dev_dbg(&dev->udev, "%s - Error ran out of data. pos: %d, len: %d\n", dev_dbg(&dev->udev, "%s - Error ran out of data. pos: %d, len: %d\n",
__FUNCTION__, dev->data.pos, dev->data.len); __FUNCTION__, dev->data.pos, dev->data.len);
return(-1); return -1;
} }
/* Load as much as we can into the tester. */ /* Load as much as we can into the tester. */
...@@ -172,7 +172,7 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed) ...@@ -172,7 +172,7 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
dev->data.bits_left += 8; dev->data.bits_left += 8;
} }
return(0); return 0;
} }
/* /*
...@@ -311,10 +311,10 @@ static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs) ...@@ -311,10 +311,10 @@ static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs)
__FUNCTION__, message.system, message.button, message.toggle); __FUNCTION__, message.system, message.button, message.toggle);
if (message.toggle != remote->toggle) { if (message.toggle != remote->toggle) {
input_regs(&remote->input, regs); input_regs(remote->input, regs);
input_report_key(&remote->input, keyspan_key_table[message.button], 1); input_report_key(remote->input, keyspan_key_table[message.button], 1);
input_report_key(&remote->input, keyspan_key_table[message.button], 0); input_report_key(remote->input, keyspan_key_table[message.button], 0);
input_sync(&remote->input); input_sync(remote->input);
remote->toggle = message.toggle; remote->toggle = message.toggle;
} }
...@@ -397,14 +397,9 @@ static int keyspan_open(struct input_dev *dev) ...@@ -397,14 +397,9 @@ static int keyspan_open(struct input_dev *dev)
{ {
struct usb_keyspan *remote = dev->private; struct usb_keyspan *remote = dev->private;
if (remote->open++)
return 0;
remote->irq_urb->dev = remote->udev; remote->irq_urb->dev = remote->udev;
if (usb_submit_urb(remote->irq_urb, GFP_KERNEL)) { if (usb_submit_urb(remote->irq_urb, GFP_KERNEL))
remote->open--;
return -EIO; return -EIO;
}
return 0; return 0;
} }
...@@ -413,8 +408,26 @@ static void keyspan_close(struct input_dev *dev) ...@@ -413,8 +408,26 @@ static void keyspan_close(struct input_dev *dev)
{ {
struct usb_keyspan *remote = dev->private; struct usb_keyspan *remote = dev->private;
if (!--remote->open) usb_kill_urb(remote->irq_urb);
usb_kill_urb(remote->irq_urb); }
static struct usb_endpoint_descriptor *keyspan_get_in_endpoint(struct usb_host_interface *iface)
{
struct usb_endpoint_descriptor *endpoint;
int i;
for (i = 0; i < iface->desc.bNumEndpoints; ++i) {
endpoint = &iface->endpoint[i].desc;
if ((endpoint->bEndpointAddress & USB_DIR_IN) &&
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
/* we found our interrupt in endpoint */
return endpoint;
}
}
return NULL;
} }
/* /*
...@@ -422,110 +435,78 @@ static void keyspan_close(struct input_dev *dev) ...@@ -422,110 +435,78 @@ static void keyspan_close(struct input_dev *dev)
*/ */
static int keyspan_probe(struct usb_interface *interface, const struct usb_device_id *id) static int keyspan_probe(struct usb_interface *interface, const struct usb_device_id *id)
{ {
int i; struct usb_device *udev = interface_to_usbdev(interface);
int retval = -ENOMEM;
char path[64];
char *buf;
struct usb_keyspan *remote = NULL;
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *endpoint;
struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface)); struct usb_keyspan *remote;
struct input_dev *input_dev;
int i, retval;
/* allocate memory for our device state and initialize it */ endpoint = keyspan_get_in_endpoint(interface->cur_altsetting);
remote = kmalloc(sizeof(*remote), GFP_KERNEL); if (!endpoint)
if (remote == NULL) { return -ENODEV;
err("Out of memory\n");
goto error; remote = kzalloc(sizeof(*remote), GFP_KERNEL);
input_dev = input_allocate_device();
if (!remote || !input_dev) {
retval = -ENOMEM;
goto fail1;
} }
memset(remote, 0x00, sizeof(*remote));
remote->udev = udev; remote->udev = udev;
remote->input = input_dev;
remote->interface = interface; remote->interface = interface;
remote->in_endpoint = endpoint;
remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */ remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */
/* set up the endpoint information */ remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma);
/* use only the first in interrupt endpoint */ if (!remote->in_buffer) {
iface_desc = interface->cur_altsetting; retval = -ENOMEM;
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { goto fail1;
endpoint = &iface_desc->endpoint[i].desc;
if (!remote->in_endpoint &&
(endpoint->bEndpointAddress & USB_DIR_IN) &&
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
/* we found our interrupt in endpoint */
remote->in_endpoint = endpoint;
remote->in_buffer = usb_buffer_alloc(remote->udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma);
if (!remote->in_buffer) {
retval = -ENOMEM;
goto error;
}
}
}
if (!remote->in_endpoint) {
err("Could not find interrupt input endpoint.\n");
retval = -ENODEV;
goto error;
} }
remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!remote->irq_urb) { if (!remote->irq_urb) {
err("Failed to allocate urb.\n");
retval = -ENOMEM; retval = -ENOMEM;
goto error; goto fail2;
} }
retval = keyspan_setup(remote->udev); retval = keyspan_setup(udev);
if (retval) { if (retval) {
err("Failed to setup device.\n");
retval = -ENODEV; retval = -ENODEV;
goto error; goto fail3;
}
/*
* Setup the input system with the bits we are going to be reporting
*/
remote->input.evbit[0] = BIT(EV_KEY); /* We will only report KEY events. */
for (i = 0; i < 32; ++i) {
if (keyspan_key_table[i] != KEY_RESERVED) {
set_bit(keyspan_key_table[i], remote->input.keybit);
}
} }
remote->input.private = remote; if (udev->manufacturer)
remote->input.open = keyspan_open; strlcpy(remote->name, udev->manufacturer, sizeof(remote->name));
remote->input.close = keyspan_close;
usb_make_path(remote->udev, path, 64);
sprintf(remote->phys, "%s/input0", path);
remote->input.name = remote->name; if (udev->product) {
remote->input.phys = remote->phys; if (udev->manufacturer)
remote->input.id.bustype = BUS_USB; strlcat(remote->name, " ", sizeof(remote->name));
remote->input.id.vendor = le16_to_cpu(remote->udev->descriptor.idVendor); strlcat(remote->name, udev->product, sizeof(remote->name));
remote->input.id.product = le16_to_cpu(remote->udev->descriptor.idProduct);
remote->input.id.version = le16_to_cpu(remote->udev->descriptor.bcdDevice);
if (!(buf = kmalloc(63, GFP_KERNEL))) {
usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
kfree(remote);
return -ENOMEM;
} }
if (remote->udev->descriptor.iManufacturer && if (!strlen(remote->name))
usb_string(remote->udev, remote->udev->descriptor.iManufacturer, buf, 63) > 0) snprintf(remote->name, sizeof(remote->name),
strcat(remote->name, buf); "USB Keyspan Remote %04x:%04x",
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct));
if (remote->udev->descriptor.iProduct && usb_make_path(udev, remote->phys, sizeof(remote->phys));
usb_string(remote->udev, remote->udev->descriptor.iProduct, buf, 63) > 0) strlcat(remote->phys, "/input0", sizeof(remote->phys));
sprintf(remote->name, "%s %s", remote->name, buf);
if (!strlen(remote->name)) input_dev->name = remote->name;
sprintf(remote->name, "USB Keyspan Remote %04x:%04x", input_dev->phys = remote->phys;
remote->input.id.vendor, remote->input.id.product); usb_to_input_id(udev, &input_dev->id);
input_dev->cdev.dev = &interface->dev;
kfree(buf); input_dev->evbit[0] = BIT(EV_KEY); /* We will only report KEY events. */
for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++)
if (keyspan_key_table[i] != KEY_RESERVED)
set_bit(keyspan_key_table[i], input_dev->keybit);
input_dev->private = remote;
input_dev->open = keyspan_open;
input_dev->close = keyspan_close;
/* /*
* Initialize the URB to access the device. The urb gets sent to the device in keyspan_open() * Initialize the URB to access the device. The urb gets sent to the device in keyspan_open()
...@@ -538,27 +519,17 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic ...@@ -538,27 +519,17 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
/* we can register the device now, as it is ready */ /* we can register the device now, as it is ready */
input_register_device(&remote->input); input_register_device(remote->input);
/* save our data pointer in this interface device */ /* save our data pointer in this interface device */
usb_set_intfdata(interface, remote); usb_set_intfdata(interface, remote);
/* let the user know what node this device is now attached to */
info("connected: %s on %s", remote->name, path);
return 0; return 0;
error: fail3: usb_free_urb(remote->irq_urb);
/* fail2: usb_buffer_free(udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
* In case of error we need to clean up any allocated buffers fail1: kfree(remote);
*/ input_free_device(input_dev);
if (remote->irq_urb)
usb_free_urb(remote->irq_urb);
if (remote->in_buffer)
usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
if (remote)
kfree(remote);
return retval; return retval;
} }
...@@ -570,23 +541,16 @@ static void keyspan_disconnect(struct usb_interface *interface) ...@@ -570,23 +541,16 @@ static void keyspan_disconnect(struct usb_interface *interface)
{ {
struct usb_keyspan *remote; struct usb_keyspan *remote;
/* prevent keyspan_open() from racing keyspan_disconnect() */
lock_kernel();
remote = usb_get_intfdata(interface); remote = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL); usb_set_intfdata(interface, NULL);
if (remote) { /* We have a valid driver structure so clean up everything we allocated. */ if (remote) { /* We have a valid driver structure so clean up everything we allocated. */
input_unregister_device(&remote->input); input_unregister_device(remote->input);
usb_kill_urb(remote->irq_urb); usb_kill_urb(remote->irq_urb);
usb_free_urb(remote->irq_urb); usb_free_urb(remote->irq_urb);
usb_buffer_free(interface_to_usbdev(interface), RECV_SIZE, remote->in_buffer, remote->in_dma); usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
kfree(remote); kfree(remote);
} }
unlock_kernel();
info("USB Keyspan now disconnected");
} }
/* /*
......
...@@ -98,7 +98,7 @@ struct mtouch_usb { ...@@ -98,7 +98,7 @@ struct mtouch_usb {
dma_addr_t data_dma; dma_addr_t data_dma;
struct urb *irq; struct urb *irq;
struct usb_device *udev; struct usb_device *udev;
struct input_dev input; struct input_dev *input;
char name[128]; char name[128];
char phys[64]; char phys[64];
}; };
...@@ -135,14 +135,14 @@ static void mtouchusb_irq(struct urb *urb, struct pt_regs *regs) ...@@ -135,14 +135,14 @@ static void mtouchusb_irq(struct urb *urb, struct pt_regs *regs)
goto exit; goto exit;
} }
input_regs(&mtouch->input, regs); input_regs(mtouch->input, regs);
input_report_key(&mtouch->input, BTN_TOUCH, input_report_key(mtouch->input, BTN_TOUCH,
MTOUCHUSB_GET_TOUCHED(mtouch->data)); MTOUCHUSB_GET_TOUCHED(mtouch->data));
input_report_abs(&mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data)); input_report_abs(mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data));
input_report_abs(&mtouch->input, ABS_Y, input_report_abs(mtouch->input, ABS_Y,
(raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC) (raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC)
- MTOUCHUSB_GET_YC(mtouch->data)); - MTOUCHUSB_GET_YC(mtouch->data));
input_sync(&mtouch->input); input_sync(mtouch->input);
exit: exit:
retval = usb_submit_urb(urb, GFP_ATOMIC); retval = usb_submit_urb(urb, GFP_ATOMIC);
...@@ -195,10 +195,10 @@ static void mtouchusb_free_buffers(struct usb_device *udev, struct mtouch_usb *m ...@@ -195,10 +195,10 @@ static void mtouchusb_free_buffers(struct usb_device *udev, struct mtouch_usb *m
static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_id *id) static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{ {
struct mtouch_usb *mtouch; struct mtouch_usb *mtouch;
struct input_dev *input_dev;
struct usb_host_interface *interface; struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *endpoint;
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
char path[64];
int nRet; int nRet;
dbg("%s - called", __FUNCTION__); dbg("%s - called", __FUNCTION__);
...@@ -209,57 +209,55 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i ...@@ -209,57 +209,55 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i
dbg("%s - setting endpoint", __FUNCTION__); dbg("%s - setting endpoint", __FUNCTION__);
endpoint = &interface->endpoint[0].desc; endpoint = &interface->endpoint[0].desc;
if (!(mtouch = kmalloc(sizeof(struct mtouch_usb), GFP_KERNEL))) { mtouch = kzalloc(sizeof(struct mtouch_usb), GFP_KERNEL);
input_dev = input_allocate_device();
if (!mtouch || !input_dev) {
err("%s - Out of memory.", __FUNCTION__); err("%s - Out of memory.", __FUNCTION__);
return -ENOMEM; goto fail1;
} }
memset(mtouch, 0, sizeof(struct mtouch_usb));
mtouch->udev = udev;
dbg("%s - allocating buffers", __FUNCTION__); dbg("%s - allocating buffers", __FUNCTION__);
if (mtouchusb_alloc_buffers(udev, mtouch)) { if (mtouchusb_alloc_buffers(udev, mtouch))
mtouchusb_free_buffers(udev, mtouch); goto fail2;
kfree(mtouch);
return -ENOMEM;
}
mtouch->input.private = mtouch; mtouch->udev = udev;
mtouch->input.open = mtouchusb_open; mtouch->input = input_dev;
mtouch->input.close = mtouchusb_close;
usb_make_path(udev, path, 64);
sprintf(mtouch->phys, "%s/input0", path);
mtouch->input.name = mtouch->name;
mtouch->input.phys = mtouch->phys;
usb_to_input_id(udev, &mtouch->input.id);
mtouch->input.dev = &intf->dev;
mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
mtouch->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
mtouch->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
/* Used to Scale Compensated Data and Flip Y */
mtouch->input.absmin[ABS_X] = MTOUCHUSB_MIN_XC;
mtouch->input.absmax[ABS_X] = raw_coordinates ?
MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC;
mtouch->input.absfuzz[ABS_X] = MTOUCHUSB_XC_FUZZ;
mtouch->input.absflat[ABS_X] = MTOUCHUSB_XC_FLAT;
mtouch->input.absmin[ABS_Y] = MTOUCHUSB_MIN_YC;
mtouch->input.absmax[ABS_Y] = raw_coordinates ?
MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC;
mtouch->input.absfuzz[ABS_Y] = MTOUCHUSB_YC_FUZZ;
mtouch->input.absflat[ABS_Y] = MTOUCHUSB_YC_FLAT;
if (udev->manufacturer) if (udev->manufacturer)
strcat(mtouch->name, udev->manufacturer); strlcpy(mtouch->name, udev->manufacturer, sizeof(mtouch->name));
if (udev->product)
sprintf(mtouch->name, "%s %s", mtouch->name, udev->product); if (udev->product) {
if (udev->manufacturer)
strlcat(mtouch->name, " ", sizeof(mtouch->name));
strlcat(mtouch->name, udev->product, sizeof(mtouch->name));
}
if (!strlen(mtouch->name)) if (!strlen(mtouch->name))
sprintf(mtouch->name, "USB Touchscreen %04x:%04x", snprintf(mtouch->name, sizeof(mtouch->name),
mtouch->input.id.vendor, mtouch->input.id.product); "USB Touchscreen %04x:%04x",
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct));
usb_make_path(udev, mtouch->phys, sizeof(mtouch->phys));
strlcpy(mtouch->phys, "/input0", sizeof(mtouch->phys));
input_dev->name = mtouch->name;
input_dev->phys = mtouch->phys;
usb_to_input_id(udev, &input_dev->id);
input_dev->cdev.dev = &intf->dev;
input_dev->private = mtouch;
input_dev->open = mtouchusb_open;
input_dev->close = mtouchusb_close;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
input_set_abs_params(input_dev, ABS_X, MTOUCHUSB_MIN_XC,
raw_coordinates ? MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC,
MTOUCHUSB_XC_FUZZ, MTOUCHUSB_XC_FLAT);
input_set_abs_params(input_dev, ABS_Y, MTOUCHUSB_MIN_YC,
raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC,
MTOUCHUSB_YC_FUZZ, MTOUCHUSB_YC_FLAT);
nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0), nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0),
MTOUCHUSB_RESET, MTOUCHUSB_RESET,
...@@ -272,9 +270,7 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i ...@@ -272,9 +270,7 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i
mtouch->irq = usb_alloc_urb(0, GFP_KERNEL); mtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
if (!mtouch->irq) { if (!mtouch->irq) {
dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__); dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__);
mtouchusb_free_buffers(udev, mtouch); goto fail2;
kfree(mtouch);
return -ENOMEM;
} }
dbg("%s - usb_fill_int_urb", __FUNCTION__); dbg("%s - usb_fill_int_urb", __FUNCTION__);
...@@ -284,7 +280,7 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i ...@@ -284,7 +280,7 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i
mtouchusb_irq, mtouch, endpoint->bInterval); mtouchusb_irq, mtouch, endpoint->bInterval);
dbg("%s - input_register_device", __FUNCTION__); dbg("%s - input_register_device", __FUNCTION__);
input_register_device(&mtouch->input); input_register_device(mtouch->input);
nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0), nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0),
MTOUCHUSB_ASYNC_REPORT, MTOUCHUSB_ASYNC_REPORT,
...@@ -293,10 +289,13 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i ...@@ -293,10 +289,13 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i
dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d", dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
__FUNCTION__, nRet); __FUNCTION__, nRet);
printk(KERN_INFO "input: %s on %s\n", mtouch->name, path);
usb_set_intfdata(intf, mtouch); usb_set_intfdata(intf, mtouch);
return 0; return 0;
fail2: mtouchusb_free_buffers(udev, mtouch);
fail1: input_free_device(input_dev);
kfree(mtouch);
return -ENOMEM;
} }
static void mtouchusb_disconnect(struct usb_interface *intf) static void mtouchusb_disconnect(struct usb_interface *intf)
...@@ -308,7 +307,7 @@ static void mtouchusb_disconnect(struct usb_interface *intf) ...@@ -308,7 +307,7 @@ static void mtouchusb_disconnect(struct usb_interface *intf)
if (mtouch) { if (mtouch) {
dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__); dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__);
usb_kill_urb(mtouch->irq); usb_kill_urb(mtouch->irq);
input_unregister_device(&mtouch->input); input_unregister_device(mtouch->input);
usb_free_urb(mtouch->irq); usb_free_urb(mtouch->irq);
mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch); mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch);
kfree(mtouch); kfree(mtouch);
......
...@@ -262,6 +262,7 @@ int hid_pid_init(struct hid_device *hid) ...@@ -262,6 +262,7 @@ int hid_pid_init(struct hid_device *hid)
{ {
struct hid_ff_pid *private; struct hid_ff_pid *private;
struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list); struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list);
struct input_dev *input_dev = hidinput->input;
private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL); private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL);
if (!private) if (!private)
...@@ -281,11 +282,12 @@ int hid_pid_init(struct hid_device *hid) ...@@ -281,11 +282,12 @@ int hid_pid_init(struct hid_device *hid)
usb_fill_control_urb(private->urbffout, hid->dev, 0, usb_fill_control_urb(private->urbffout, hid->dev, 0,
(void *)&private->ffcr, private->ctrl_buffer, 8, (void *)&private->ffcr, private->ctrl_buffer, 8,
hid_pid_ctrl_out, hid); hid_pid_ctrl_out, hid);
hidinput->input.upload_effect = hid_pid_upload_effect;
hidinput->input.flush = hid_pid_flush; input_dev->upload_effect = hid_pid_upload_effect;
hidinput->input.ff_effects_max = 8; // A random default input_dev->flush = hid_pid_flush;
set_bit(EV_FF, hidinput->input.evbit); input_dev->ff_effects_max = 8; // A random default
set_bit(EV_FF_STATUS, hidinput->input.evbit); set_bit(EV_FF, input_dev->evbit);
set_bit(EV_FF_STATUS, input_dev->evbit);
spin_lock_init(&private->lock); spin_lock_init(&private->lock);
......
...@@ -68,7 +68,7 @@ struct powermate_device { ...@@ -68,7 +68,7 @@ struct powermate_device {
struct usb_ctrlrequest *configcr; struct usb_ctrlrequest *configcr;
dma_addr_t configcr_dma; dma_addr_t configcr_dma;
struct usb_device *udev; struct usb_device *udev;
struct input_dev input; struct input_dev *input;
spinlock_t lock; spinlock_t lock;
int static_brightness; int static_brightness;
int pulse_speed; int pulse_speed;
...@@ -106,10 +106,10 @@ static void powermate_irq(struct urb *urb, struct pt_regs *regs) ...@@ -106,10 +106,10 @@ static void powermate_irq(struct urb *urb, struct pt_regs *regs)
} }
/* handle updates to device state */ /* handle updates to device state */
input_regs(&pm->input, regs); input_regs(pm->input, regs);
input_report_key(&pm->input, BTN_0, pm->data[0] & 0x01); input_report_key(pm->input, BTN_0, pm->data[0] & 0x01);
input_report_rel(&pm->input, REL_DIAL, pm->data[1]); input_report_rel(pm->input, REL_DIAL, pm->data[1]);
input_sync(&pm->input); input_sync(pm->input);
exit: exit:
retval = usb_submit_urb (urb, GFP_ATOMIC); retval = usb_submit_urb (urb, GFP_ATOMIC);
...@@ -153,10 +153,10 @@ static void powermate_sync_state(struct powermate_device *pm) ...@@ -153,10 +153,10 @@ static void powermate_sync_state(struct powermate_device *pm)
Only values of 'arg' quite close to 255 are particularly useful/spectacular. Only values of 'arg' quite close to 255 are particularly useful/spectacular.
*/ */
if (pm->pulse_speed < 255){ if (pm->pulse_speed < 255) {
op = 0; // divide op = 0; // divide
arg = 255 - pm->pulse_speed; arg = 255 - pm->pulse_speed;
} else if (pm->pulse_speed > 255){ } else if (pm->pulse_speed > 255) {
op = 2; // multiply op = 2; // multiply
arg = pm->pulse_speed - 255; arg = pm->pulse_speed - 255;
} else { } else {
...@@ -166,11 +166,11 @@ static void powermate_sync_state(struct powermate_device *pm) ...@@ -166,11 +166,11 @@ static void powermate_sync_state(struct powermate_device *pm)
pm->configcr->wValue = cpu_to_le16( (pm->pulse_table << 8) | SET_PULSE_MODE ); pm->configcr->wValue = cpu_to_le16( (pm->pulse_table << 8) | SET_PULSE_MODE );
pm->configcr->wIndex = cpu_to_le16( (arg << 8) | op ); pm->configcr->wIndex = cpu_to_le16( (arg << 8) | op );
pm->requires_update &= ~UPDATE_PULSE_MODE; pm->requires_update &= ~UPDATE_PULSE_MODE;
}else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS){ } else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS) {
pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS ); pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS );
pm->configcr->wIndex = cpu_to_le16( pm->static_brightness ); pm->configcr->wIndex = cpu_to_le16( pm->static_brightness );
pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS; pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS;
}else{ } else {
printk(KERN_ERR "powermate: unknown update required"); printk(KERN_ERR "powermate: unknown update required");
pm->requires_update = 0; /* fudge the bug */ pm->requires_update = 0; /* fudge the bug */
return; return;
...@@ -228,19 +228,19 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne ...@@ -228,19 +228,19 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne
spin_lock_irqsave(&pm->lock, flags); spin_lock_irqsave(&pm->lock, flags);
/* mark state updates which are required */ /* mark state updates which are required */
if (static_brightness != pm->static_brightness){ if (static_brightness != pm->static_brightness) {
pm->static_brightness = static_brightness; pm->static_brightness = static_brightness;
pm->requires_update |= UPDATE_STATIC_BRIGHTNESS; pm->requires_update |= UPDATE_STATIC_BRIGHTNESS;
} }
if (pulse_asleep != pm->pulse_asleep){ if (pulse_asleep != pm->pulse_asleep) {
pm->pulse_asleep = pulse_asleep; pm->pulse_asleep = pulse_asleep;
pm->requires_update |= (UPDATE_PULSE_ASLEEP | UPDATE_STATIC_BRIGHTNESS); pm->requires_update |= (UPDATE_PULSE_ASLEEP | UPDATE_STATIC_BRIGHTNESS);
} }
if (pulse_awake != pm->pulse_awake){ if (pulse_awake != pm->pulse_awake) {
pm->pulse_awake = pulse_awake; pm->pulse_awake = pulse_awake;
pm->requires_update |= (UPDATE_PULSE_AWAKE | UPDATE_STATIC_BRIGHTNESS); pm->requires_update |= (UPDATE_PULSE_AWAKE | UPDATE_STATIC_BRIGHTNESS);
} }
if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table){ if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table) {
pm->pulse_speed = pulse_speed; pm->pulse_speed = pulse_speed;
pm->pulse_table = pulse_table; pm->pulse_table = pulse_table;
pm->requires_update |= UPDATE_PULSE_MODE; pm->requires_update |= UPDATE_PULSE_MODE;
...@@ -283,6 +283,7 @@ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_dev ...@@ -283,6 +283,7 @@ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_dev
SLAB_ATOMIC, &pm->data_dma); SLAB_ATOMIC, &pm->data_dma);
if (!pm->data) if (!pm->data)
return -1; return -1;
pm->configcr = usb_buffer_alloc(udev, sizeof(*(pm->configcr)), pm->configcr = usb_buffer_alloc(udev, sizeof(*(pm->configcr)),
SLAB_ATOMIC, &pm->configcr_dma); SLAB_ATOMIC, &pm->configcr_dma);
if (!pm->configcr) if (!pm->configcr)
...@@ -308,8 +309,9 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i ...@@ -308,8 +309,9 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
struct usb_host_interface *interface; struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *endpoint;
struct powermate_device *pm; struct powermate_device *pm;
struct input_dev *input_dev;
int pipe, maxp; int pipe, maxp;
char path[64]; int err = -ENOMEM;
interface = intf->cur_altsetting; interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc; endpoint = &interface->endpoint[0].desc;
...@@ -323,42 +325,61 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i ...@@ -323,42 +325,61 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
0, interface->desc.bInterfaceNumber, NULL, 0, 0, interface->desc.bInterfaceNumber, NULL, 0,
USB_CTRL_SET_TIMEOUT); USB_CTRL_SET_TIMEOUT);
if (!(pm = kmalloc(sizeof(struct powermate_device), GFP_KERNEL))) pm = kzalloc(sizeof(struct powermate_device), GFP_KERNEL);
return -ENOMEM; input_dev = input_allocate_device();
if (!pm || !input_dev)
memset(pm, 0, sizeof(struct powermate_device)); goto fail1;
pm->udev = udev;
if (powermate_alloc_buffers(udev, pm)) { if (powermate_alloc_buffers(udev, pm))
powermate_free_buffers(udev, pm); goto fail2;
kfree(pm);
return -ENOMEM;
}
pm->irq = usb_alloc_urb(0, GFP_KERNEL); pm->irq = usb_alloc_urb(0, GFP_KERNEL);
if (!pm->irq) { if (!pm->irq)
powermate_free_buffers(udev, pm); goto fail2;
kfree(pm);
return -ENOMEM;
}
pm->config = usb_alloc_urb(0, GFP_KERNEL); pm->config = usb_alloc_urb(0, GFP_KERNEL);
if (!pm->config) { if (!pm->config)
usb_free_urb(pm->irq); goto fail3;
powermate_free_buffers(udev, pm);
kfree(pm); pm->udev = udev;
return -ENOMEM; pm->input = input_dev;
}
usb_make_path(udev, pm->phys, sizeof(pm->phys));
strlcpy(pm->phys, "/input0", sizeof(pm->phys));
spin_lock_init(&pm->lock); spin_lock_init(&pm->lock);
init_input_dev(&pm->input);
switch (le16_to_cpu(udev->descriptor.idProduct)) {
case POWERMATE_PRODUCT_NEW:
input_dev->name = pm_name_powermate;
break;
case POWERMATE_PRODUCT_OLD:
input_dev->name = pm_name_soundknob;
break;
default:
input_dev->name = pm_name_soundknob;
printk(KERN_WARNING "powermate: unknown product id %04x\n",
le16_to_cpu(udev->descriptor.idProduct));
}
input_dev->phys = pm->phys;
usb_to_input_id(udev, &input_dev->id);
input_dev->cdev.dev = &intf->dev;
input_dev->private = pm;
input_dev->event = powermate_input_event;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC);
input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
input_dev->relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
input_dev->mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
/* get a handle to the interrupt data pipe */ /* get a handle to the interrupt data pipe */
pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
if(maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX){ if (maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX) {
printk("powermate: Expected payload of %d--%d bytes, found %d bytes!\n", printk(KERN_WARNING "powermate: Expected payload of %d--%d bytes, found %d bytes!\n",
POWERMATE_PAYLOAD_SIZE_MIN, POWERMATE_PAYLOAD_SIZE_MAX, maxp); POWERMATE_PAYLOAD_SIZE_MIN, POWERMATE_PAYLOAD_SIZE_MAX, maxp);
maxp = POWERMATE_PAYLOAD_SIZE_MAX; maxp = POWERMATE_PAYLOAD_SIZE_MAX;
} }
...@@ -371,35 +392,11 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i ...@@ -371,35 +392,11 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
/* register our interrupt URB with the USB system */ /* register our interrupt URB with the USB system */
if (usb_submit_urb(pm->irq, GFP_KERNEL)) { if (usb_submit_urb(pm->irq, GFP_KERNEL)) {
powermate_free_buffers(udev, pm); err = -EIO;
kfree(pm); goto fail4;
return -EIO; /* failure */
} }
switch (le16_to_cpu(udev->descriptor.idProduct)) { input_register_device(pm->input);
case POWERMATE_PRODUCT_NEW: pm->input.name = pm_name_powermate; break;
case POWERMATE_PRODUCT_OLD: pm->input.name = pm_name_soundknob; break;
default:
pm->input.name = pm_name_soundknob;
printk(KERN_WARNING "powermate: unknown product id %04x\n",
le16_to_cpu(udev->descriptor.idProduct));
}
pm->input.private = pm;
pm->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC);
pm->input.keybit[LONG(BTN_0)] = BIT(BTN_0);
pm->input.relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
pm->input.mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
usb_to_input_id(udev, &pm->input.id);
pm->input.event = powermate_input_event;
pm->input.dev = &intf->dev;
pm->input.phys = pm->phys;
input_register_device(&pm->input);
usb_make_path(udev, path, 64);
snprintf(pm->phys, 64, "%s/input0", path);
printk(KERN_INFO "input: %s on %s\n", pm->input.name, pm->input.phys);
/* force an update of everything */ /* force an update of everything */
pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS; pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS;
...@@ -407,6 +404,13 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i ...@@ -407,6 +404,13 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
usb_set_intfdata(intf, pm); usb_set_intfdata(intf, pm);
return 0; return 0;
fail4: usb_free_urb(pm->config);
fail3: usb_free_urb(pm->irq);
fail2: powermate_free_buffers(udev, pm);
fail1: input_free_device(input_dev);
kfree(pm);
return err;
} }
/* Called when a USB device we've accepted ownership of is removed */ /* Called when a USB device we've accepted ownership of is removed */
...@@ -418,7 +422,7 @@ static void powermate_disconnect(struct usb_interface *intf) ...@@ -418,7 +422,7 @@ static void powermate_disconnect(struct usb_interface *intf)
if (pm) { if (pm) {
pm->requires_update = 0; pm->requires_update = 0;
usb_kill_urb(pm->irq); usb_kill_urb(pm->irq);
input_unregister_device(&pm->input); input_unregister_device(pm->input);
usb_free_urb(pm->irq); usb_free_urb(pm->irq);
usb_free_urb(pm->config); usb_free_urb(pm->config);
powermate_free_buffers(interface_to_usbdev(intf), pm); powermate_free_buffers(interface_to_usbdev(intf), pm);
......
...@@ -68,7 +68,7 @@ struct touchkit_usb { ...@@ -68,7 +68,7 @@ struct touchkit_usb {
dma_addr_t data_dma; dma_addr_t data_dma;
struct urb *irq; struct urb *irq;
struct usb_device *udev; struct usb_device *udev;
struct input_dev input; struct input_dev *input;
char name[128]; char name[128];
char phys[64]; char phys[64];
}; };
...@@ -115,12 +115,12 @@ static void touchkit_irq(struct urb *urb, struct pt_regs *regs) ...@@ -115,12 +115,12 @@ static void touchkit_irq(struct urb *urb, struct pt_regs *regs)
y = TOUCHKIT_GET_Y(touchkit->data); y = TOUCHKIT_GET_Y(touchkit->data);
} }
input_regs(&touchkit->input, regs); input_regs(touchkit->input, regs);
input_report_key(&touchkit->input, BTN_TOUCH, input_report_key(touchkit->input, BTN_TOUCH,
TOUCHKIT_GET_TOUCHED(touchkit->data)); TOUCHKIT_GET_TOUCHED(touchkit->data));
input_report_abs(&touchkit->input, ABS_X, x); input_report_abs(touchkit->input, ABS_X, x);
input_report_abs(&touchkit->input, ABS_Y, y); input_report_abs(touchkit->input, ABS_Y, y);
input_sync(&touchkit->input); input_sync(touchkit->input);
exit: exit:
retval = usb_submit_urb(urb, GFP_ATOMIC); retval = usb_submit_urb(urb, GFP_ATOMIC);
...@@ -171,87 +171,81 @@ static void touchkit_free_buffers(struct usb_device *udev, ...@@ -171,87 +171,81 @@ static void touchkit_free_buffers(struct usb_device *udev,
static int touchkit_probe(struct usb_interface *intf, static int touchkit_probe(struct usb_interface *intf,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
int ret;
struct touchkit_usb *touchkit; struct touchkit_usb *touchkit;
struct input_dev *input_dev;
struct usb_host_interface *interface; struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *endpoint;
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
char path[64];
interface = intf->cur_altsetting; interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc; endpoint = &interface->endpoint[0].desc;
touchkit = kmalloc(sizeof(struct touchkit_usb), GFP_KERNEL); touchkit = kzalloc(sizeof(struct touchkit_usb), GFP_KERNEL);
if (!touchkit) input_dev = input_allocate_device();
return -ENOMEM; if (!touchkit || !input_dev)
memset(touchkit, 0, sizeof(struct touchkit_usb));
touchkit->udev = udev;
if (touchkit_alloc_buffers(udev, touchkit)) {
ret = -ENOMEM;
goto out_free; goto out_free;
}
touchkit->input.private = touchkit;
touchkit->input.open = touchkit_open;
touchkit->input.close = touchkit_close;
usb_make_path(udev, path, 64);
sprintf(touchkit->phys, "%s/input0", path);
touchkit->input.name = touchkit->name;
touchkit->input.phys = touchkit->phys;
usb_to_input_id(udev, &touchkit->input.id);
touchkit->input.dev = &intf->dev;
touchkit->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
touchkit->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
touchkit->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
/* Used to Scale Compensated Data */
touchkit->input.absmin[ABS_X] = TOUCHKIT_MIN_XC;
touchkit->input.absmax[ABS_X] = TOUCHKIT_MAX_XC;
touchkit->input.absfuzz[ABS_X] = TOUCHKIT_XC_FUZZ;
touchkit->input.absflat[ABS_X] = TOUCHKIT_XC_FLAT;
touchkit->input.absmin[ABS_Y] = TOUCHKIT_MIN_YC;
touchkit->input.absmax[ABS_Y] = TOUCHKIT_MAX_YC;
touchkit->input.absfuzz[ABS_Y] = TOUCHKIT_YC_FUZZ;
touchkit->input.absflat[ABS_Y] = TOUCHKIT_YC_FLAT;
if (udev->manufacturer)
strcat(touchkit->name, udev->manufacturer);
if (udev->product)
sprintf(touchkit->name, "%s %s", touchkit->name, udev->product);
if (!strlen(touchkit->name)) if (touchkit_alloc_buffers(udev, touchkit))
sprintf(touchkit->name, "USB Touchscreen %04x:%04x", goto out_free;
touchkit->input.id.vendor, touchkit->input.id.product);
touchkit->irq = usb_alloc_urb(0, GFP_KERNEL); touchkit->irq = usb_alloc_urb(0, GFP_KERNEL);
if (!touchkit->irq) { if (!touchkit->irq) {
dbg("%s - usb_alloc_urb failed: touchkit->irq", __FUNCTION__); dbg("%s - usb_alloc_urb failed: touchkit->irq", __FUNCTION__);
ret = -ENOMEM;
goto out_free_buffers; goto out_free_buffers;
} }
touchkit->udev = udev;
touchkit->input = input_dev;
if (udev->manufacturer)
strlcpy(touchkit->name, udev->manufacturer, sizeof(touchkit->name));
if (udev->product) {
if (udev->manufacturer)
strlcat(touchkit->name, " ", sizeof(touchkit->name));
strlcat(touchkit->name, udev->product, sizeof(touchkit->name));
}
if (!strlen(touchkit->name))
snprintf(touchkit->name, sizeof(touchkit->name),
"USB Touchscreen %04x:%04x",
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct));
usb_make_path(udev, touchkit->phys, sizeof(touchkit->phys));
strlcpy(touchkit->phys, "/input0", sizeof(touchkit->phys));
input_dev->name = touchkit->name;
input_dev->phys = touchkit->phys;
usb_to_input_id(udev, &input_dev->id);
input_dev->cdev.dev = &intf->dev;
input_dev->private = touchkit;
input_dev->open = touchkit_open;
input_dev->close = touchkit_close;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
input_set_abs_params(input_dev, ABS_X, TOUCHKIT_MIN_XC, TOUCHKIT_MAX_XC,
TOUCHKIT_XC_FUZZ, TOUCHKIT_XC_FLAT);
input_set_abs_params(input_dev, ABS_Y, TOUCHKIT_MIN_YC, TOUCHKIT_MAX_YC,
TOUCHKIT_YC_FUZZ, TOUCHKIT_YC_FLAT);
usb_fill_int_urb(touchkit->irq, touchkit->udev, usb_fill_int_urb(touchkit->irq, touchkit->udev,
usb_rcvintpipe(touchkit->udev, 0x81), usb_rcvintpipe(touchkit->udev, 0x81),
touchkit->data, TOUCHKIT_REPORT_DATA_SIZE, touchkit->data, TOUCHKIT_REPORT_DATA_SIZE,
touchkit_irq, touchkit, endpoint->bInterval); touchkit_irq, touchkit, endpoint->bInterval);
input_register_device(&touchkit->input); input_register_device(touchkit->input);
printk(KERN_INFO "input: %s on %s\n", touchkit->name, path);
usb_set_intfdata(intf, touchkit); usb_set_intfdata(intf, touchkit);
return 0; return 0;
out_free_buffers: out_free_buffers:
touchkit_free_buffers(udev, touchkit); touchkit_free_buffers(udev, touchkit);
out_free: out_free:
input_free_device(input_dev);
kfree(touchkit); kfree(touchkit);
return ret; return -ENOMEM;
} }
static void touchkit_disconnect(struct usb_interface *intf) static void touchkit_disconnect(struct usb_interface *intf)
...@@ -265,8 +259,8 @@ static void touchkit_disconnect(struct usb_interface *intf) ...@@ -265,8 +259,8 @@ static void touchkit_disconnect(struct usb_interface *intf)
dbg("%s - touchkit is initialized, cleaning up", __FUNCTION__); dbg("%s - touchkit is initialized, cleaning up", __FUNCTION__);
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
input_unregister_device(&touchkit->input);
usb_kill_urb(touchkit->irq); usb_kill_urb(touchkit->irq);
input_unregister_device(touchkit->input);
usb_free_urb(touchkit->irq); usb_free_urb(touchkit->irq);
touchkit_free_buffers(interface_to_usbdev(intf), touchkit); touchkit_free_buffers(interface_to_usbdev(intf), touchkit);
kfree(touchkit); kfree(touchkit);
......
...@@ -66,7 +66,7 @@ static unsigned char usb_kbd_keycode[256] = { ...@@ -66,7 +66,7 @@ static unsigned char usb_kbd_keycode[256] = {
}; };
struct usb_kbd { struct usb_kbd {
struct input_dev dev; struct input_dev *dev;
struct usb_device *usbdev; struct usb_device *usbdev;
unsigned char old[8]; unsigned char old[8];
struct urb *irq, *led; struct urb *irq, *led;
...@@ -99,29 +99,29 @@ static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs) ...@@ -99,29 +99,29 @@ static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs)
goto resubmit; goto resubmit;
} }
input_regs(&kbd->dev, regs); input_regs(kbd->dev, regs);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
input_report_key(&kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1); input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
for (i = 2; i < 8; i++) { for (i = 2; i < 8; i++) {
if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) { if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {
if (usb_kbd_keycode[kbd->old[i]]) if (usb_kbd_keycode[kbd->old[i]])
input_report_key(&kbd->dev, usb_kbd_keycode[kbd->old[i]], 0); input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
else else
info("Unknown key (scancode %#x) released.", kbd->old[i]); info("Unknown key (scancode %#x) released.", kbd->old[i]);
} }
if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) { if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
if (usb_kbd_keycode[kbd->new[i]]) if (usb_kbd_keycode[kbd->new[i]])
input_report_key(&kbd->dev, usb_kbd_keycode[kbd->new[i]], 1); input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
else else
info("Unknown key (scancode %#x) pressed.", kbd->new[i]); info("Unknown key (scancode %#x) pressed.", kbd->new[i]);
} }
} }
input_sync(&kbd->dev); input_sync(kbd->dev);
memcpy(kbd->old, kbd->new, 8); memcpy(kbd->old, kbd->new, 8);
...@@ -227,12 +227,12 @@ static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd) ...@@ -227,12 +227,12 @@ static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)
static int usb_kbd_probe(struct usb_interface *iface, static int usb_kbd_probe(struct usb_interface *iface,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
struct usb_device * dev = interface_to_usbdev(iface); struct usb_device *dev = interface_to_usbdev(iface);
struct usb_host_interface *interface; struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *endpoint;
struct usb_kbd *kbd; struct usb_kbd *kbd;
struct input_dev *input_dev;
int i, pipe, maxp; int i, pipe, maxp;
char path[64];
interface = iface->cur_altsetting; interface = iface->cur_altsetting;
...@@ -240,37 +240,59 @@ static int usb_kbd_probe(struct usb_interface *iface, ...@@ -240,37 +240,59 @@ static int usb_kbd_probe(struct usb_interface *iface,
return -ENODEV; return -ENODEV;
endpoint = &interface->endpoint[0].desc; endpoint = &interface->endpoint[0].desc;
if (!(endpoint->bEndpointAddress & 0x80)) if (!(endpoint->bEndpointAddress & USB_DIR_IN))
return -ENODEV; return -ENODEV;
if ((endpoint->bmAttributes & 3) != 3) if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
return -ENODEV; return -ENODEV;
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) kbd = kzalloc(sizeof(struct usb_kbd), GFP_KERNEL);
return -ENOMEM; input_dev = input_allocate_device();
memset(kbd, 0, sizeof(struct usb_kbd)); if (!kbd || !input_dev)
goto fail1;
if (usb_kbd_alloc_mem(dev, kbd)) { if (usb_kbd_alloc_mem(dev, kbd))
usb_kbd_free_mem(dev, kbd); goto fail2;
kfree(kbd);
return -ENOMEM;
}
kbd->usbdev = dev; kbd->usbdev = dev;
kbd->dev = input_dev;
if (dev->manufacturer)
strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name));
if (dev->product) {
if (dev->manufacturer)
strlcat(kbd->name, " ", sizeof(kbd->name));
strlcat(kbd->name, dev->product, sizeof(kbd->name));
}
if (!strlen(kbd->name))
snprintf(kbd->name, sizeof(kbd->name),
"USB HIDBP Keyboard %04x:%04x",
le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
usb_make_path(dev, kbd->phys, sizeof(kbd->phys));
strlcpy(kbd->phys, "/input0", sizeof(kbd->phys));
kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); input_dev->name = kbd->name;
kbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA); input_dev->phys = kbd->phys;
usb_to_input_id(dev, &input_dev->id);
input_dev->cdev.dev = &iface->dev;
input_dev->private = kbd;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);
for (i = 0; i < 255; i++) for (i = 0; i < 255; i++)
set_bit(usb_kbd_keycode[i], kbd->dev.keybit); set_bit(usb_kbd_keycode[i], input_dev->keybit);
clear_bit(0, kbd->dev.keybit); clear_bit(0, input_dev->keybit);
kbd->dev.private = kbd; input_dev->event = usb_kbd_event;
kbd->dev.event = usb_kbd_event; input_dev->open = usb_kbd_open;
kbd->dev.open = usb_kbd_open; input_dev->close = usb_kbd_close;
kbd->dev.close = usb_kbd_close;
usb_fill_int_urb(kbd->irq, dev, pipe, usb_fill_int_urb(kbd->irq, dev, pipe,
kbd->new, (maxp > 8 ? 8 : maxp), kbd->new, (maxp > 8 ? 8 : maxp),
...@@ -284,37 +306,22 @@ static int usb_kbd_probe(struct usb_interface *iface, ...@@ -284,37 +306,22 @@ static int usb_kbd_probe(struct usb_interface *iface,
kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber); kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
kbd->cr->wLength = cpu_to_le16(1); kbd->cr->wLength = cpu_to_le16(1);
usb_make_path(dev, path, 64);
sprintf(kbd->phys, "%s/input0", path);
kbd->dev.name = kbd->name;
kbd->dev.phys = kbd->phys;
usb_to_input_id(dev, &kbd->dev.id);
kbd->dev.dev = &iface->dev;
if (dev->manufacturer)
strcat(kbd->name, dev->manufacturer);
if (dev->product)
sprintf(kbd->name, "%s %s", kbd->name, dev->product);
if (!strlen(kbd->name))
sprintf(kbd->name, "USB HIDBP Keyboard %04x:%04x",
kbd->dev.id.vendor, kbd->dev.id.product);
usb_fill_control_urb(kbd->led, dev, usb_sndctrlpipe(dev, 0), usb_fill_control_urb(kbd->led, dev, usb_sndctrlpipe(dev, 0),
(void *) kbd->cr, kbd->leds, 1, (void *) kbd->cr, kbd->leds, 1,
usb_kbd_led, kbd); usb_kbd_led, kbd);
kbd->led->setup_dma = kbd->cr_dma; kbd->led->setup_dma = kbd->cr_dma;
kbd->led->transfer_dma = kbd->leds_dma; kbd->led->transfer_dma = kbd->leds_dma;
kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
| URB_NO_SETUP_DMA_MAP);
input_register_device(&kbd->dev); input_register_device(kbd->dev);
printk(KERN_INFO "input: %s on %s\n", kbd->name, path);
usb_set_intfdata(iface, kbd); usb_set_intfdata(iface, kbd);
return 0; return 0;
fail2: usb_kbd_free_mem(dev, kbd);
fail1: input_free_device(input_dev);
kfree(kbd);
return -ENOMEM;
} }
static void usb_kbd_disconnect(struct usb_interface *intf) static void usb_kbd_disconnect(struct usb_interface *intf)
...@@ -324,7 +331,7 @@ static void usb_kbd_disconnect(struct usb_interface *intf) ...@@ -324,7 +331,7 @@ static void usb_kbd_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
if (kbd) { if (kbd) {
usb_kill_urb(kbd->irq); usb_kill_urb(kbd->irq);
input_unregister_device(&kbd->dev); input_unregister_device(kbd->dev);
usb_kbd_free_mem(interface_to_usbdev(intf), kbd); usb_kbd_free_mem(interface_to_usbdev(intf), kbd);
kfree(kbd); kfree(kbd);
} }
......
...@@ -50,7 +50,7 @@ struct usb_mouse { ...@@ -50,7 +50,7 @@ struct usb_mouse {
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 *dev;
struct urb *irq; struct urb *irq;
signed char *data; signed char *data;
...@@ -61,7 +61,7 @@ static void usb_mouse_irq(struct urb *urb, struct pt_regs *regs) ...@@ -61,7 +61,7 @@ static void usb_mouse_irq(struct urb *urb, struct pt_regs *regs)
{ {
struct usb_mouse *mouse = urb->context; struct usb_mouse *mouse = urb->context;
signed char *data = mouse->data; signed char *data = mouse->data;
struct input_dev *dev = &mouse->dev; struct input_dev *dev = mouse->dev;
int status; int status;
switch (urb->status) { switch (urb->status) {
...@@ -115,14 +115,14 @@ static void usb_mouse_close(struct input_dev *dev) ...@@ -115,14 +115,14 @@ static void usb_mouse_close(struct input_dev *dev)
usb_kill_urb(mouse->irq); usb_kill_urb(mouse->irq);
} }
static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_id * id) static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)
{ {
struct usb_device * dev = interface_to_usbdev(intf); struct usb_device *dev = interface_to_usbdev(intf);
struct usb_host_interface *interface; struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *endpoint;
struct usb_mouse *mouse; struct usb_mouse *mouse;
struct input_dev *input_dev;
int pipe, maxp; int pipe, maxp;
char path[64];
interface = intf->cur_altsetting; interface = intf->cur_altsetting;
...@@ -130,59 +130,62 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_ ...@@ -130,59 +130,62 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_
return -ENODEV; return -ENODEV;
endpoint = &interface->endpoint[0].desc; endpoint = &interface->endpoint[0].desc;
if (!(endpoint->bEndpointAddress & 0x80)) if (!(endpoint->bEndpointAddress & USB_DIR_IN))
return -ENODEV; return -ENODEV;
if ((endpoint->bmAttributes & 3) != 3) if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
return -ENODEV; return -ENODEV;
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);
return -ENOMEM; input_dev = input_allocate_device();
memset(mouse, 0, sizeof(struct usb_mouse)); if (!mouse || !input_dev)
goto fail1;
mouse->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &mouse->data_dma); mouse->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &mouse->data_dma);
if (!mouse->data) { if (!mouse->data)
kfree(mouse); goto fail1;
return -ENOMEM;
}
mouse->irq = usb_alloc_urb(0, GFP_KERNEL); mouse->irq = usb_alloc_urb(0, GFP_KERNEL);
if (!mouse->irq) { if (!mouse->irq)
usb_buffer_free(dev, 8, mouse->data, mouse->data_dma); goto fail2;
kfree(mouse);
return -ENODEV;
}
mouse->usbdev = dev; mouse->usbdev = dev;
mouse->dev = input_dev;
if (dev->manufacturer)
strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));
mouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); if (dev->product) {
mouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); if (dev->manufacturer)
mouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); strlcat(mouse->name, " ", sizeof(mouse->name));
mouse->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA); strlcat(mouse->name, dev->product, sizeof(mouse->name));
mouse->dev.relbit[0] |= BIT(REL_WHEEL); }
mouse->dev.private = mouse; if (!strlen(mouse->name))
mouse->dev.open = usb_mouse_open; snprintf(mouse->name, sizeof(mouse->name),
mouse->dev.close = usb_mouse_close; "USB HIDBP Mouse %04x:%04x",
le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
usb_make_path(dev, path, 64); usb_make_path(dev, mouse->phys, sizeof(mouse->phys));
sprintf(mouse->phys, "%s/input0", path); strlcat(mouse->phys, "/input0", sizeof(mouse->phys));
mouse->dev.name = mouse->name; input_dev->name = mouse->name;
mouse->dev.phys = mouse->phys; input_dev->phys = mouse->phys;
usb_to_input_id(dev, &mouse->dev.id); usb_to_input_id(dev, &input_dev->id);
mouse->dev.dev = &intf->dev; input_dev->cdev.dev = &intf->dev;
if (dev->manufacturer) input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
strcat(mouse->name, dev->manufacturer); input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
if (dev->product) input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
sprintf(mouse->name, "%s %s", mouse->name, dev->product); input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
input_dev->relbit[0] |= BIT(REL_WHEEL);
if (!strlen(mouse->name)) input_dev->private = mouse;
sprintf(mouse->name, "USB HIDBP Mouse %04x:%04x", input_dev->open = usb_mouse_open;
mouse->dev.id.vendor, mouse->dev.id.product); input_dev->close = usb_mouse_close;
usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data, usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,
(maxp > 8 ? 8 : maxp), (maxp > 8 ? 8 : maxp),
...@@ -190,11 +193,15 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_ ...@@ -190,11 +193,15 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_
mouse->irq->transfer_dma = mouse->data_dma; mouse->irq->transfer_dma = mouse->data_dma;
mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
input_register_device(&mouse->dev); input_register_device(mouse->dev);
printk(KERN_INFO "input: %s on %s\n", mouse->name, path);
usb_set_intfdata(intf, mouse); usb_set_intfdata(intf, mouse);
return 0; return 0;
fail2: usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
fail1: input_free_device(input_dev);
kfree(mouse);
return -ENOMEM;
} }
static void usb_mouse_disconnect(struct usb_interface *intf) static void usb_mouse_disconnect(struct usb_interface *intf)
...@@ -204,7 +211,7 @@ static void usb_mouse_disconnect(struct usb_interface *intf) ...@@ -204,7 +211,7 @@ static void usb_mouse_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
if (mouse) { if (mouse) {
usb_kill_urb(mouse->irq); usb_kill_urb(mouse->irq);
input_unregister_device(&mouse->dev); input_unregister_device(mouse->dev);
usb_free_urb(mouse->irq); usb_free_urb(mouse->irq);
usb_buffer_free(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma); usb_buffer_free(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
kfree(mouse); kfree(mouse);
......
...@@ -111,7 +111,7 @@ struct wacom_features { ...@@ -111,7 +111,7 @@ struct wacom_features {
struct wacom { struct wacom {
signed char *data; signed char *data;
dma_addr_t data_dma; dma_addr_t data_dma;
struct input_dev dev; struct input_dev *dev;
struct usb_device *usbdev; struct usb_device *usbdev;
struct urb *irq; struct urb *irq;
struct wacom_features *features; struct wacom_features *features;
...@@ -135,7 +135,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) ...@@ -135,7 +135,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
{ {
struct wacom *wacom = urb->context; struct wacom *wacom = urb->context;
unsigned char *data = wacom->data; unsigned char *data = wacom->data;
struct input_dev *dev = &wacom->dev; struct input_dev *dev = wacom->dev;
int prox, pressure; int prox, pressure;
int retval; int retval;
...@@ -225,7 +225,7 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs) ...@@ -225,7 +225,7 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs)
{ {
struct wacom *wacom = urb->context; struct wacom *wacom = urb->context;
unsigned char *data = wacom->data; unsigned char *data = wacom->data;
struct input_dev *dev = &wacom->dev; struct input_dev *dev = wacom->dev;
int retval; int retval;
switch (urb->status) { switch (urb->status) {
...@@ -275,7 +275,7 @@ static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs) ...@@ -275,7 +275,7 @@ static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs)
{ {
struct wacom *wacom = urb->context; struct wacom *wacom = urb->context;
unsigned char *data = wacom->data; unsigned char *data = wacom->data;
struct input_dev *dev = &wacom->dev; struct input_dev *dev = wacom->dev;
int retval; int retval;
switch (urb->status) { switch (urb->status) {
...@@ -318,7 +318,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) ...@@ -318,7 +318,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
{ {
struct wacom *wacom = urb->context; struct wacom *wacom = urb->context;
unsigned char *data = wacom->data; unsigned char *data = wacom->data;
struct input_dev *dev = &wacom->dev; struct input_dev *dev = wacom->dev;
int x, y; int x, y;
int retval; int retval;
...@@ -397,7 +397,7 @@ static int wacom_intuos_inout(struct urb *urb) ...@@ -397,7 +397,7 @@ static int wacom_intuos_inout(struct urb *urb)
{ {
struct wacom *wacom = urb->context; struct wacom *wacom = urb->context;
unsigned char *data = wacom->data; unsigned char *data = wacom->data;
struct input_dev *dev = &wacom->dev; struct input_dev *dev = wacom->dev;
int idx; int idx;
/* tool number */ /* tool number */
...@@ -479,7 +479,7 @@ static void wacom_intuos_general(struct urb *urb) ...@@ -479,7 +479,7 @@ static void wacom_intuos_general(struct urb *urb)
{ {
struct wacom *wacom = urb->context; struct wacom *wacom = urb->context;
unsigned char *data = wacom->data; unsigned char *data = wacom->data;
struct input_dev *dev = &wacom->dev; struct input_dev *dev = wacom->dev;
unsigned int t; unsigned int t;
/* general pen packet */ /* general pen packet */
...@@ -509,7 +509,7 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) ...@@ -509,7 +509,7 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs)
{ {
struct wacom *wacom = urb->context; struct wacom *wacom = urb->context;
unsigned char *data = wacom->data; unsigned char *data = wacom->data;
struct input_dev *dev = &wacom->dev; struct input_dev *dev = wacom->dev;
unsigned int t; unsigned int t;
int idx; int idx;
int retval; int retval;
...@@ -738,95 +738,83 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -738,95 +738,83 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
{ {
struct usb_device *dev = interface_to_usbdev(intf); struct usb_device *dev = interface_to_usbdev(intf);
struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *endpoint;
char rep_data[2] = {0x02, 0x02};
struct wacom *wacom; struct wacom *wacom;
char path[64]; struct input_dev *input_dev;
char rep_data[2] = {0x02, 0x02};
if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
return -ENOMEM; input_dev = input_allocate_device();
memset(wacom, 0, sizeof(struct wacom)); if (!wacom || !input_dev)
goto fail1;
wacom->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); wacom->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma);
if (!wacom->data) { if (!wacom->data)
kfree(wacom); goto fail1;
return -ENOMEM;
}
wacom->irq = usb_alloc_urb(0, GFP_KERNEL); wacom->irq = usb_alloc_urb(0, GFP_KERNEL);
if (!wacom->irq) { if (!wacom->irq)
usb_buffer_free(dev, 10, wacom->data, wacom->data_dma); goto fail2;
kfree(wacom);
return -ENOMEM; wacom->usbdev = dev;
} wacom->dev = input_dev;
usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
wacom->features = wacom_features + (id - wacom_ids); wacom->features = wacom_features + (id - wacom_ids);
if (wacom->features->pktlen > 10)
BUG();
input_dev->name = wacom->features->name;
usb_to_input_id(dev, &input_dev->id);
wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); input_dev->cdev.dev = &intf->dev;
wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); input_dev->private = wacom;
wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS); input_dev->open = wacom_open;
input_dev->close = wacom_close;
input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
input_set_abs_params(input_dev, ABS_X, 0, wacom->features->y_max, 4, 0);
input_set_abs_params(input_dev, ABS_Y, 0, wacom->features->y_max, 4, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0);
switch (wacom->features->type) { switch (wacom->features->type) {
case GRAPHIRE: case GRAPHIRE:
wacom->dev.evbit[0] |= BIT(EV_REL); input_dev->evbit[0] |= BIT(EV_REL);
wacom->dev.relbit[0] |= BIT(REL_WHEEL); input_dev->relbit[0] |= BIT(REL_WHEEL);
wacom->dev.absbit[0] |= BIT(ABS_DISTANCE); input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom->features->distance_max, 0, 0);
break; break;
case INTUOS3: case INTUOS3:
case CINTIQ: case CINTIQ:
wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
wacom->dev.absbit[0] |= BIT(ABS_RX) | BIT(ABS_RY); input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0);
input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0);
/* fall through */ /* fall through */
case INTUOS: case INTUOS:
wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
wacom->dev.mscbit[0] |= BIT(MSC_SERIAL); input_dev->mscbit[0] |= BIT(MSC_SERIAL);
wacom->dev.relbit[0] |= BIT(REL_WHEEL); input_dev->relbit[0] |= BIT(REL_WHEEL);
wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH)
| BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2);
wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE); input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom->features->distance_max, 0, 0);
input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0);
input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0);
input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
break; break;
case PL: case PL:
wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER); input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
break; break;
} }
wacom->dev.absmax[ABS_X] = wacom->features->x_max;
wacom->dev.absmax[ABS_Y] = wacom->features->y_max;
wacom->dev.absmax[ABS_PRESSURE] = wacom->features->pressure_max;
wacom->dev.absmax[ABS_DISTANCE] = wacom->features->distance_max;
wacom->dev.absmax[ABS_TILT_X] = 127;
wacom->dev.absmax[ABS_TILT_Y] = 127;
wacom->dev.absmax[ABS_WHEEL] = 1023;
wacom->dev.absmax[ABS_RX] = 4097;
wacom->dev.absmax[ABS_RY] = 4097;
wacom->dev.absmin[ABS_RZ] = -900;
wacom->dev.absmax[ABS_RZ] = 899;
wacom->dev.absmin[ABS_THROTTLE] = -1023;
wacom->dev.absmax[ABS_THROTTLE] = 1023;
wacom->dev.absfuzz[ABS_X] = 4;
wacom->dev.absfuzz[ABS_Y] = 4;
wacom->dev.private = wacom;
wacom->dev.open = wacom_open;
wacom->dev.close = wacom_close;
usb_make_path(dev, path, 64);
sprintf(wacom->phys, "%s/input0", path);
wacom->dev.name = wacom->features->name;
wacom->dev.phys = wacom->phys;
usb_to_input_id(dev, &wacom->dev.id);
wacom->dev.dev = &intf->dev;
wacom->usbdev = dev;
endpoint = &intf->cur_altsetting->endpoint[0].desc; endpoint = &intf->cur_altsetting->endpoint[0].desc;
if (wacom->features->pktlen > 10) if (wacom->features->pktlen > 10)
...@@ -839,18 +827,20 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -839,18 +827,20 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
wacom->irq->transfer_dma = wacom->data_dma; wacom->irq->transfer_dma = wacom->data_dma;
wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
input_register_device(&wacom->dev); input_register_device(wacom->dev);
/* ask the tablet to report tablet data */ /* ask the tablet to report tablet data */
usb_set_report(intf, 3, 2, rep_data, 2); usb_set_report(intf, 3, 2, rep_data, 2);
/* repeat once (not sure why the first call often fails) */ /* repeat once (not sure why the first call often fails) */
usb_set_report(intf, 3, 2, rep_data, 2); usb_set_report(intf, 3, 2, rep_data, 2);
printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path);
usb_set_intfdata(intf, wacom); usb_set_intfdata(intf, wacom);
return 0; return 0;
fail2: usb_buffer_free(dev, 10, wacom->data, wacom->data_dma);
fail1: input_free_device(input_dev);
kfree(wacom);
return -ENOMEM;
} }
static void wacom_disconnect(struct usb_interface *intf) static void wacom_disconnect(struct usb_interface *intf)
...@@ -860,7 +850,7 @@ static void wacom_disconnect(struct usb_interface *intf) ...@@ -860,7 +850,7 @@ static void wacom_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
if (wacom) { if (wacom) {
usb_kill_urb(wacom->irq); usb_kill_urb(wacom->irq);
input_unregister_device(&wacom->dev); input_unregister_device(wacom->dev);
usb_free_urb(wacom->irq); usb_free_urb(wacom->irq);
usb_buffer_free(interface_to_usbdev(intf), 10, wacom->data, wacom->data_dma); usb_buffer_free(interface_to_usbdev(intf), 10, wacom->data, wacom->data_dma);
kfree(wacom); kfree(wacom);
......
...@@ -103,7 +103,7 @@ static struct usb_device_id xpad_table [] = { ...@@ -103,7 +103,7 @@ static struct usb_device_id xpad_table [] = {
MODULE_DEVICE_TABLE (usb, xpad_table); MODULE_DEVICE_TABLE (usb, xpad_table);
struct usb_xpad { struct usb_xpad {
struct input_dev dev; /* input device interface */ struct input_dev *dev; /* input device interface */
struct usb_device *udev; /* usb device */ struct usb_device *udev; /* usb device */
struct urb *irq_in; /* urb for interrupt in report */ struct urb *irq_in; /* urb for interrupt in report */
...@@ -125,7 +125,7 @@ struct usb_xpad { ...@@ -125,7 +125,7 @@ struct usb_xpad {
static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs) static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs)
{ {
struct input_dev *dev = &xpad->dev; struct input_dev *dev = xpad->dev;
input_regs(dev, regs); input_regs(dev, regs);
...@@ -214,9 +214,9 @@ static void xpad_close (struct input_dev *dev) ...@@ -214,9 +214,9 @@ static void xpad_close (struct input_dev *dev)
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
{ {
struct usb_device *udev = interface_to_usbdev (intf); struct usb_device *udev = interface_to_usbdev (intf);
struct usb_xpad *xpad = NULL; struct usb_xpad *xpad;
struct input_dev *input_dev;
struct usb_endpoint_descriptor *ep_irq_in; struct usb_endpoint_descriptor *ep_irq_in;
char path[64];
int i; int i;
for (i = 0; xpad_device[i].idVendor; i++) { for (i = 0; xpad_device[i].idVendor; i++) {
...@@ -225,89 +225,80 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id ...@@ -225,89 +225,80 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
break; break;
} }
if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) { xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
err("cannot allocate memory for new pad"); input_dev = input_allocate_device();
return -ENOMEM; if (!xpad || !input_dev)
} goto fail1;
memset(xpad, 0, sizeof(struct usb_xpad));
xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN, xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN,
SLAB_ATOMIC, &xpad->idata_dma); SLAB_ATOMIC, &xpad->idata_dma);
if (!xpad->idata) { if (!xpad->idata)
kfree(xpad); goto fail1;
return -ENOMEM;
}
xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
if (!xpad->irq_in) { if (!xpad->irq_in)
err("cannot allocate memory for new pad irq urb"); goto fail2;
usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
kfree(xpad);
return -ENOMEM;
}
ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
usb_fill_int_urb(xpad->irq_in, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
xpad, ep_irq_in->bInterval);
xpad->irq_in->transfer_dma = xpad->idata_dma;
xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
xpad->udev = udev; xpad->udev = udev;
xpad->dev = input_dev;
usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
strlcat(xpad->phys, "/input0", sizeof(xpad->phys));
usb_to_input_id(udev, &xpad->dev.id); input_dev->name = xpad_device[i].name;
xpad->dev.dev = &intf->dev; input_dev->phys = xpad->phys;
xpad->dev.private = xpad; usb_to_input_id(udev, &input_dev->id);
xpad->dev.name = xpad_device[i].name; input_dev->cdev.dev = &intf->dev;
xpad->dev.phys = xpad->phys; input_dev->private = xpad;
xpad->dev.open = xpad_open; input_dev->open = xpad_open;
xpad->dev.close = xpad_close; input_dev->close = xpad_close;
usb_make_path(udev, path, 64);
snprintf(xpad->phys, 64, "%s/input0", path);
xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; xpad_btn[i] >= 0; i++) for (i = 0; xpad_btn[i] >= 0; i++)
set_bit(xpad_btn[i], xpad->dev.keybit); set_bit(xpad_btn[i], input_dev->keybit);
for (i = 0; xpad_abs[i] >= 0; i++) { for (i = 0; xpad_abs[i] >= 0; i++) {
signed short t = xpad_abs[i]; signed short t = xpad_abs[i];
set_bit(t, xpad->dev.absbit); set_bit(t, input_dev->absbit);
switch (t) { switch (t) {
case ABS_X: case ABS_X:
case ABS_Y: case ABS_Y:
case ABS_RX: case ABS_RX:
case ABS_RY: /* the two sticks */ case ABS_RY: /* the two sticks */
xpad->dev.absmax[t] = 32767; input_set_abs_params(input_dev, t, -32768, 32767, 16, 128);
xpad->dev.absmin[t] = -32768;
xpad->dev.absflat[t] = 128;
xpad->dev.absfuzz[t] = 16;
break; break;
case ABS_Z: case ABS_Z:
case ABS_RZ: /* the triggers */ case ABS_RZ: /* the triggers */
xpad->dev.absmax[t] = 255; input_set_abs_params(input_dev, t, 0, 255, 0, 0);
xpad->dev.absmin[t] = 0;
break; break;
case ABS_HAT0X: case ABS_HAT0X:
case ABS_HAT0Y: /* the d-pad */ case ABS_HAT0Y: /* the d-pad */
xpad->dev.absmax[t] = 1; input_set_abs_params(input_dev, t, -1, 1, 0, 0);
xpad->dev.absmin[t] = -1;
break; break;
} }
} }
input_register_device(&xpad->dev); ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
usb_fill_int_urb(xpad->irq_in, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
xpad, ep_irq_in->bInterval);
xpad->irq_in->transfer_dma = xpad->idata_dma;
xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
printk(KERN_INFO "input: %s on %s", xpad->dev.name, path); input_register_device(xpad->dev);
usb_set_intfdata(intf, xpad); usb_set_intfdata(intf, xpad);
return 0; return 0;
fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
fail1: input_free_device(input_dev);
kfree(xpad);
return -ENOMEM;
} }
static void xpad_disconnect(struct usb_interface *intf) static void xpad_disconnect(struct usb_interface *intf)
...@@ -317,7 +308,7 @@ static void xpad_disconnect(struct usb_interface *intf) ...@@ -317,7 +308,7 @@ static void xpad_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
if (xpad) { if (xpad) {
usb_kill_urb(xpad->irq_in); usb_kill_urb(xpad->irq_in);
input_unregister_device(&xpad->dev); input_unregister_device(xpad->dev);
usb_free_urb(xpad->irq_in); usb_free_urb(xpad->irq_in);
usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
kfree(xpad); kfree(xpad);
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/usb_input.h>
#include "map_to_7segment.h" #include "map_to_7segment.h"
#include "yealink.h" #include "yealink.h"
...@@ -101,12 +102,12 @@ static const struct lcd_segment_map { ...@@ -101,12 +102,12 @@ static const struct lcd_segment_map {
}; };
struct yealink_dev { struct yealink_dev {
struct input_dev idev; /* input device */ struct input_dev *idev; /* input device */
struct usb_device *udev; /* usb device */ struct usb_device *udev; /* usb device */
/* irq input channel */ /* irq input channel */
struct yld_ctl_packet *irq_data; struct yld_ctl_packet *irq_data;
dma_addr_t irq_dma; dma_addr_t irq_dma;
struct urb *urb_irq; struct urb *urb_irq;
/* control output channel */ /* control output channel */
...@@ -237,7 +238,7 @@ static int map_p1k_to_key(int scancode) ...@@ -237,7 +238,7 @@ static int map_p1k_to_key(int scancode)
*/ */
static void report_key(struct yealink_dev *yld, int key, struct pt_regs *regs) static void report_key(struct yealink_dev *yld, int key, struct pt_regs *regs)
{ {
struct input_dev *idev = &yld->idev; struct input_dev *idev = yld->idev;
input_regs(idev, regs); input_regs(idev, regs);
if (yld->key_code >= 0) { if (yld->key_code >= 0) {
...@@ -809,8 +810,12 @@ static int usb_cleanup(struct yealink_dev *yld, int err) ...@@ -809,8 +810,12 @@ static int usb_cleanup(struct yealink_dev *yld, int err)
} }
if (yld->urb_ctl) if (yld->urb_ctl)
usb_free_urb(yld->urb_ctl); usb_free_urb(yld->urb_ctl);
if (yld->idev.dev) if (yld->idev) {
input_unregister_device(&yld->idev); if (err)
input_free_device(yld->idev);
else
input_unregister_device(yld->idev);
}
if (yld->ctl_req) if (yld->ctl_req)
usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)), usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)),
yld->ctl_req, yld->ctl_req_dma); yld->ctl_req, yld->ctl_req_dma);
...@@ -857,7 +862,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -857,7 +862,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
struct usb_host_interface *interface; struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *endpoint;
struct yealink_dev *yld; struct yealink_dev *yld;
char path[64]; struct input_dev *input_dev;
int ret, pipe, i; int ret, pipe, i;
i = usb_match(udev); i = usb_match(udev);
...@@ -866,17 +871,21 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -866,17 +871,21 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
interface = intf->cur_altsetting; interface = intf->cur_altsetting;
endpoint = &interface->endpoint[0].desc; endpoint = &interface->endpoint[0].desc;
if (!(endpoint->bEndpointAddress & 0x80)) if (!(endpoint->bEndpointAddress & USB_DIR_IN))
return -EIO; return -EIO;
if ((endpoint->bmAttributes & 3) != 3) if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
return -EIO; return -EIO;
if ((yld = kmalloc(sizeof(struct yealink_dev), GFP_KERNEL)) == NULL) yld = kzalloc(sizeof(struct yealink_dev), GFP_KERNEL);
if (!yld)
return -ENOMEM; return -ENOMEM;
memset(yld, 0, sizeof(*yld));
yld->udev = udev; yld->udev = udev;
yld->idev = input_dev = input_allocate_device();
if (!input_dev)
return usb_cleanup(yld, -ENOMEM);
/* allocate usb buffers */ /* allocate usb buffers */
yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN, yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
SLAB_ATOMIC, &yld->irq_dma); SLAB_ATOMIC, &yld->irq_dma);
...@@ -935,42 +944,37 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -935,42 +944,37 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
yld->urb_ctl->dev = udev; yld->urb_ctl->dev = udev;
/* find out the physical bus location */ /* find out the physical bus location */
if (usb_make_path(udev, path, sizeof(path)) > 0) usb_make_path(udev, yld->phys, sizeof(yld->phys));
snprintf(yld->phys, sizeof(yld->phys)-1, "%s/input0", path); strlcat(yld->phys, "/input0", sizeof(yld->phys));
/* register settings for the input device */ /* register settings for the input device */
init_input_dev(&yld->idev); input_dev->name = yld_device[i].name;
yld->idev.private = yld; input_dev->phys = yld->phys;
yld->idev.id.bustype = BUS_USB; usb_to_input_id(udev, &input_dev->id);
yld->idev.id.vendor = le16_to_cpu(udev->descriptor.idVendor); input_dev->cdev.dev = &intf->dev;
yld->idev.id.product = le16_to_cpu(udev->descriptor.idProduct);
yld->idev.id.version = le16_to_cpu(udev->descriptor.bcdDevice); input_dev->private = yld;
yld->idev.dev = &intf->dev; input_dev->open = input_open;
yld->idev.name = yld_device[i].name; input_dev->close = input_close;
yld->idev.phys = yld->phys; /* input_dev->event = input_ev; TODO */
/* yld->idev.event = input_ev; TODO */
yld->idev.open = input_open;
yld->idev.close = input_close;
/* register available key events */ /* register available key events */
yld->idev.evbit[0] = BIT(EV_KEY); input_dev->evbit[0] = BIT(EV_KEY);
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
int k = map_p1k_to_key(i); int k = map_p1k_to_key(i);
if (k >= 0) { if (k >= 0) {
set_bit(k & 0xff, yld->idev.keybit); set_bit(k & 0xff, input_dev->keybit);
if (k >> 8) if (k >> 8)
set_bit(k >> 8, yld->idev.keybit); set_bit(k >> 8, input_dev->keybit);
} }
} }
printk(KERN_INFO "input: %s on %s\n", yld->idev.name, path); input_register_device(yld->idev);
input_register_device(&yld->idev);
usb_set_intfdata(intf, yld); usb_set_intfdata(intf, yld);
/* clear visible elements */ /* clear visible elements */
for (i=0; i<ARRAY_SIZE(lcdMap); i++) for (i = 0; i < ARRAY_SIZE(lcdMap); i++)
setChar(yld, i, ' '); setChar(yld, i, ' ');
/* display driver version on LCD line 3 */ /* display driver version on LCD line 3 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment