diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-27 17:47:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-27 17:47:31 -0400 |
commit | 3e0777b8fa96f7073ed5d13d3bc1d573b766bef9 (patch) | |
tree | 3849e8457dd8f038ab7da025c708e275b43ea9c1 /drivers/usb/input | |
parent | a94130e00038ebeb2f66901a4a4a9e05a03051c1 (diff) | |
parent | e5119885f00874453e837e3407014b73de2f4741 (diff) |
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/dtor/input.git manually
Some manual fixups required due to clashes with the PF_FREEZE cleanups.
Diffstat (limited to 'drivers/usb/input')
-rw-r--r-- | drivers/usb/input/Kconfig | 24 | ||||
-rw-r--r-- | drivers/usb/input/Makefile | 2 | ||||
-rw-r--r-- | drivers/usb/input/acecad.c | 285 | ||||
-rw-r--r-- | drivers/usb/input/aiptek.c | 32 | ||||
-rw-r--r-- | drivers/usb/input/ati_remote.c | 247 | ||||
-rw-r--r-- | drivers/usb/input/hid-core.c | 26 | ||||
-rw-r--r-- | drivers/usb/input/hid-debug.h | 16 | ||||
-rw-r--r-- | drivers/usb/input/hid-input.c | 16 | ||||
-rw-r--r-- | drivers/usb/input/hid-lgff.c | 18 | ||||
-rw-r--r-- | drivers/usb/input/hid.h | 18 | ||||
-rw-r--r-- | drivers/usb/input/hiddev.c | 56 | ||||
-rw-r--r-- | drivers/usb/input/itmtouch.c | 268 | ||||
-rw-r--r-- | drivers/usb/input/kbtab.c | 17 | ||||
-rw-r--r-- | drivers/usb/input/mtouchusb.c | 410 | ||||
-rw-r--r-- | drivers/usb/input/powermate.c | 30 | ||||
-rw-r--r-- | drivers/usb/input/touchkitusb.c | 11 | ||||
-rw-r--r-- | drivers/usb/input/usbkbd.c | 29 | ||||
-rw-r--r-- | drivers/usb/input/usbmouse.c | 31 | ||||
-rw-r--r-- | drivers/usb/input/wacom.c | 398 | ||||
-rw-r--r-- | drivers/usb/input/xpad.c | 75 |
20 files changed, 1230 insertions, 779 deletions
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index d28e7eab6f98..fd59f6bdd67f 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig | |||
@@ -151,6 +151,18 @@ config USB_WACOM | |||
151 | To compile this driver as a module, choose M here: the | 151 | To compile this driver as a module, choose M here: the |
152 | module will be called wacom. | 152 | module will be called wacom. |
153 | 153 | ||
154 | config USB_ACECAD | ||
155 | tristate "Acecad Flair tablet support" | ||
156 | depends on USB && INPUT | ||
157 | help | ||
158 | Say Y here if you want to use the USB version of the Acecad Flair | ||
159 | tablet. Make sure to say Y to "Mouse support" | ||
160 | (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" | ||
161 | (CONFIG_INPUT_EVDEV) as well. | ||
162 | |||
163 | To compile this driver as a module, choose M here: the | ||
164 | module will be called acecad. | ||
165 | |||
154 | config USB_KBTAB | 166 | config USB_KBTAB |
155 | tristate "KB Gear JamStudio tablet support" | 167 | tristate "KB Gear JamStudio tablet support" |
156 | depends on USB && INPUT | 168 | depends on USB && INPUT |
@@ -190,6 +202,18 @@ config USB_MTOUCH | |||
190 | To compile this driver as a module, choose M here: the | 202 | To compile this driver as a module, choose M here: the |
191 | module will be called mtouchusb. | 203 | module will be called mtouchusb. |
192 | 204 | ||
205 | config USB_ITMTOUCH | ||
206 | tristate "ITM Touch USB Touchscreen Driver" | ||
207 | depends on USB && INPUT | ||
208 | ---help--- | ||
209 | Say Y here if you want to use a ITM Touch USB | ||
210 | Touchscreen controller. | ||
211 | |||
212 | This touchscreen is used in LG 1510SF monitors. | ||
213 | |||
214 | To compile this driver as a module, choose M here: the | ||
215 | module will be called itmtouch. | ||
216 | |||
193 | config USB_EGALAX | 217 | config USB_EGALAX |
194 | tristate "eGalax TouchKit USB Touchscreen Driver" | 218 | tristate "eGalax TouchKit USB Touchscreen Driver" |
195 | depends on USB && INPUT | 219 | depends on USB && INPUT |
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index 6bcedd16b0a1..831b2b0f1f05 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile | |||
@@ -33,7 +33,9 @@ obj-$(CONFIG_USB_KBD) += usbkbd.o | |||
33 | obj-$(CONFIG_USB_KBTAB) += kbtab.o | 33 | obj-$(CONFIG_USB_KBTAB) += kbtab.o |
34 | obj-$(CONFIG_USB_MOUSE) += usbmouse.o | 34 | obj-$(CONFIG_USB_MOUSE) += usbmouse.o |
35 | obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o | 35 | obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o |
36 | obj-$(CONFIG_USB_ITMTOUCH) += itmtouch.o | ||
36 | obj-$(CONFIG_USB_EGALAX) += touchkitusb.o | 37 | obj-$(CONFIG_USB_EGALAX) += touchkitusb.o |
37 | obj-$(CONFIG_USB_POWERMATE) += powermate.o | 38 | obj-$(CONFIG_USB_POWERMATE) += powermate.o |
38 | obj-$(CONFIG_USB_WACOM) += wacom.o | 39 | obj-$(CONFIG_USB_WACOM) += wacom.o |
40 | obj-$(CONFIG_USB_ACECAD) += acecad.o | ||
39 | obj-$(CONFIG_USB_XPAD) += xpad.o | 41 | obj-$(CONFIG_USB_XPAD) += xpad.o |
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c new file mode 100644 index 000000000000..ebcf7c955800 --- /dev/null +++ b/drivers/usb/input/acecad.c | |||
@@ -0,0 +1,285 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2001-2005 Edouard TISSERANT <edouard.tisserant@wanadoo.fr> | ||
3 | * Copyright (c) 2004-2005 Stephane VOLTZ <svoltz@numericable.fr> | ||
4 | * | ||
5 | * USB Acecad "Acecad Flair" tablet support | ||
6 | * | ||
7 | * Changelog: | ||
8 | * v3.2 - Added sysfs support | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/input.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/usb.h> | ||
34 | |||
35 | /* | ||
36 | * Version Information | ||
37 | */ | ||
38 | #define DRIVER_VERSION "v3.2" | ||
39 | #define DRIVER_DESC "USB Acecad Flair tablet driver" | ||
40 | #define DRIVER_LICENSE "GPL" | ||
41 | #define DRIVER_AUTHOR "Edouard TISSERANT <edouard.tisserant@wanadoo.fr>" | ||
42 | |||
43 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
44 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
45 | MODULE_LICENSE(DRIVER_LICENSE); | ||
46 | |||
47 | #define USB_VENDOR_ID_ACECAD 0x0460 | ||
48 | #define USB_DEVICE_ID_FLAIR 0x0004 | ||
49 | #define USB_DEVICE_ID_302 0x0008 | ||
50 | |||
51 | struct usb_acecad { | ||
52 | char name[128]; | ||
53 | char phys[64]; | ||
54 | struct usb_device *usbdev; | ||
55 | struct input_dev dev; | ||
56 | struct urb *irq; | ||
57 | |||
58 | signed char *data; | ||
59 | dma_addr_t data_dma; | ||
60 | }; | ||
61 | |||
62 | static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs) | ||
63 | { | ||
64 | struct usb_acecad *acecad = urb->context; | ||
65 | unsigned char *data = acecad->data; | ||
66 | struct input_dev *dev = &acecad->dev; | ||
67 | int prox, status; | ||
68 | |||
69 | switch (urb->status) { | ||
70 | case 0: | ||
71 | /* success */ | ||
72 | break; | ||
73 | case -ECONNRESET: | ||
74 | case -ENOENT: | ||
75 | case -ESHUTDOWN: | ||
76 | /* this urb is terminated, clean up */ | ||
77 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); | ||
78 | return; | ||
79 | default: | ||
80 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | ||
81 | goto resubmit; | ||
82 | } | ||
83 | |||
84 | prox = (data[0] & 0x04) >> 2; | ||
85 | input_report_key(dev, BTN_TOOL_PEN, prox); | ||
86 | |||
87 | if (prox) { | ||
88 | int x = data[1] | (data[2] << 8); | ||
89 | int y = data[3] | (data[4] << 8); | ||
90 | /*Pressure should compute the same way for flair and 302*/ | ||
91 | int pressure = data[5] | ((int)data[6] << 8); | ||
92 | int touch = data[0] & 0x01; | ||
93 | int stylus = (data[0] & 0x10) >> 4; | ||
94 | int stylus2 = (data[0] & 0x20) >> 5; | ||
95 | input_report_abs(dev, ABS_X, x); | ||
96 | input_report_abs(dev, ABS_Y, y); | ||
97 | input_report_abs(dev, ABS_PRESSURE, pressure); | ||
98 | input_report_key(dev, BTN_TOUCH, touch); | ||
99 | input_report_key(dev, BTN_STYLUS, stylus); | ||
100 | input_report_key(dev, BTN_STYLUS2, stylus2); | ||
101 | } | ||
102 | |||
103 | /* event termination */ | ||
104 | input_sync(dev); | ||
105 | |||
106 | resubmit: | ||
107 | status = usb_submit_urb (urb, GFP_ATOMIC); | ||
108 | if (status) | ||
109 | err ("can't resubmit intr, %s-%s/input0, status %d", | ||
110 | acecad->usbdev->bus->bus_name, acecad->usbdev->devpath, status); | ||
111 | } | ||
112 | |||
113 | static int usb_acecad_open(struct input_dev *dev) | ||
114 | { | ||
115 | struct usb_acecad *acecad = dev->private; | ||
116 | |||
117 | acecad->irq->dev = acecad->usbdev; | ||
118 | if (usb_submit_urb(acecad->irq, GFP_KERNEL)) | ||
119 | return -EIO; | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static void usb_acecad_close(struct input_dev *dev) | ||
125 | { | ||
126 | struct usb_acecad *acecad = dev->private; | ||
127 | |||
128 | usb_kill_urb(acecad->irq); | ||
129 | } | ||
130 | |||
131 | static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
132 | { | ||
133 | struct usb_device *dev = interface_to_usbdev(intf); | ||
134 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
135 | struct usb_endpoint_descriptor *endpoint; | ||
136 | struct usb_acecad *acecad; | ||
137 | int pipe, maxp; | ||
138 | char path[64]; | ||
139 | |||
140 | if (interface->desc.bNumEndpoints != 1) | ||
141 | return -ENODEV; | ||
142 | |||
143 | endpoint = &interface->endpoint[0].desc; | ||
144 | |||
145 | if (!(endpoint->bEndpointAddress & 0x80)) | ||
146 | return -ENODEV; | ||
147 | |||
148 | if ((endpoint->bmAttributes & 3) != 3) | ||
149 | return -ENODEV; | ||
150 | |||
151 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | ||
152 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | ||
153 | |||
154 | acecad = kcalloc(1, sizeof(struct usb_acecad), GFP_KERNEL); | ||
155 | if (!acecad) | ||
156 | return -ENOMEM; | ||
157 | |||
158 | acecad->data = usb_buffer_alloc(dev, 8, SLAB_KERNEL, &acecad->data_dma); | ||
159 | if (!acecad->data) | ||
160 | goto fail1; | ||
161 | |||
162 | acecad->irq = usb_alloc_urb(0, GFP_KERNEL); | ||
163 | if (!acecad->irq) | ||
164 | goto fail2; | ||
165 | |||
166 | if (dev->manufacturer) | ||
167 | strlcpy(acecad->name, dev->manufacturer, sizeof(acecad->name)); | ||
168 | |||
169 | if (dev->product) { | ||
170 | if (dev->manufacturer) | ||
171 | strlcat(acecad->name, " ", sizeof(acecad->name)); | ||
172 | strlcat(acecad->name, dev->product, sizeof(acecad->name)); | ||
173 | } | ||
174 | |||
175 | usb_make_path(dev, path, sizeof(path)); | ||
176 | snprintf(acecad->phys, sizeof(acecad->phys), "%s/input0", path); | ||
177 | |||
178 | acecad->usbdev = dev; | ||
179 | |||
180 | acecad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | ||
181 | acecad->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); | ||
182 | acecad->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); | ||
183 | acecad->dev.keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2); | ||
184 | |||
185 | switch (id->driver_info) { | ||
186 | case 0: | ||
187 | acecad->dev.absmax[ABS_X] = 5000; | ||
188 | acecad->dev.absmax[ABS_Y] = 3750; | ||
189 | acecad->dev.absmax[ABS_PRESSURE] = 512; | ||
190 | if (!strlen(acecad->name)) | ||
191 | snprintf(acecad->name, sizeof(acecad->name), | ||
192 | "USB Acecad Flair Tablet %04x:%04x", | ||
193 | dev->descriptor.idVendor, dev->descriptor.idProduct); | ||
194 | break; | ||
195 | case 1: | ||
196 | acecad->dev.absmax[ABS_X] = 3000; | ||
197 | acecad->dev.absmax[ABS_Y] = 2250; | ||
198 | acecad->dev.absmax[ABS_PRESSURE] = 1024; | ||
199 | if (!strlen(acecad->name)) | ||
200 | snprintf(acecad->name, sizeof(acecad->name), | ||
201 | "USB Acecad 302 Tablet %04x:%04x", | ||
202 | dev->descriptor.idVendor, dev->descriptor.idProduct); | ||
203 | break; | ||
204 | } | ||
205 | |||
206 | acecad->dev.absfuzz[ABS_X] = 4; | ||
207 | acecad->dev.absfuzz[ABS_Y] = 4; | ||
208 | |||
209 | acecad->dev.private = acecad; | ||
210 | acecad->dev.open = usb_acecad_open; | ||
211 | acecad->dev.close = usb_acecad_close; | ||
212 | |||
213 | acecad->dev.name = acecad->name; | ||
214 | acecad->dev.phys = acecad->phys; | ||
215 | acecad->dev.id.bustype = BUS_USB; | ||
216 | acecad->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); | ||
217 | acecad->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); | ||
218 | acecad->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); | ||
219 | acecad->dev.dev = &intf->dev; | ||
220 | |||
221 | usb_fill_int_urb(acecad->irq, dev, pipe, | ||
222 | acecad->data, maxp > 8 ? 8 : maxp, | ||
223 | usb_acecad_irq, acecad, endpoint->bInterval); | ||
224 | acecad->irq->transfer_dma = acecad->data_dma; | ||
225 | acecad->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
226 | |||
227 | input_register_device(&acecad->dev); | ||
228 | |||
229 | printk(KERN_INFO "input: %s with packet size %d on %s\n", | ||
230 | acecad->name, maxp, path); | ||
231 | |||
232 | usb_set_intfdata(intf, acecad); | ||
233 | |||
234 | return 0; | ||
235 | |||
236 | fail2: usb_buffer_free(dev, 8, acecad->data, acecad->data_dma); | ||
237 | fail1: kfree(acecad); | ||
238 | return -ENOMEM; | ||
239 | } | ||
240 | |||
241 | static void usb_acecad_disconnect(struct usb_interface *intf) | ||
242 | { | ||
243 | struct usb_acecad *acecad = usb_get_intfdata(intf); | ||
244 | |||
245 | usb_set_intfdata(intf, NULL); | ||
246 | if (acecad) { | ||
247 | usb_kill_urb(acecad->irq); | ||
248 | input_unregister_device(&acecad->dev); | ||
249 | usb_free_urb(acecad->irq); | ||
250 | usb_buffer_free(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma); | ||
251 | kfree(acecad); | ||
252 | } | ||
253 | } | ||
254 | |||
255 | static struct usb_device_id usb_acecad_id_table [] = { | ||
256 | { USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_FLAIR), .driver_info = 0 }, | ||
257 | { USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_302), .driver_info = 1 }, | ||
258 | { } | ||
259 | }; | ||
260 | |||
261 | MODULE_DEVICE_TABLE(usb, usb_acecad_id_table); | ||
262 | |||
263 | static struct usb_driver usb_acecad_driver = { | ||
264 | .owner = THIS_MODULE, | ||
265 | .name = "usb_acecad", | ||
266 | .probe = usb_acecad_probe, | ||
267 | .disconnect = usb_acecad_disconnect, | ||
268 | .id_table = usb_acecad_id_table, | ||
269 | }; | ||
270 | |||
271 | static int __init usb_acecad_init(void) | ||
272 | { | ||
273 | int result = usb_register(&usb_acecad_driver); | ||
274 | if (result == 0) | ||
275 | info(DRIVER_VERSION ":" DRIVER_DESC); | ||
276 | return result; | ||
277 | } | ||
278 | |||
279 | static void __exit usb_acecad_exit(void) | ||
280 | { | ||
281 | usb_deregister(&usb_acecad_driver); | ||
282 | } | ||
283 | |||
284 | module_init(usb_acecad_init); | ||
285 | module_exit(usb_acecad_exit); | ||
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index e991f7ed7330..6bb0f25e8e93 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Native support for the Aiptek HyperPen USB Tablets | 2 | * Native support for the Aiptek HyperPen USB Tablets |
3 | * (4000U/5000U/6000U/8000U/12000U) | 3 | * (4000U/5000U/6000U/8000U/12000U) |
4 | * | 4 | * |
5 | * Copyright (c) 2001 Chris Atenasio <chris@crud.net> | 5 | * Copyright (c) 2001 Chris Atenasio <chris@crud.net> |
6 | * Copyright (c) 2002-2004 Bryan W. Headley <bwheadley@earthlink.net> | 6 | * Copyright (c) 2002-2004 Bryan W. Headley <bwheadley@earthlink.net> |
7 | * | 7 | * |
@@ -31,7 +31,7 @@ | |||
31 | * - Added support for the sysfs interface, deprecating the | 31 | * - Added support for the sysfs interface, deprecating the |
32 | * procfs interface for 2.5.x kernel. Also added support for | 32 | * procfs interface for 2.5.x kernel. Also added support for |
33 | * Wheel command. Bryan W. Headley July-15-2003. | 33 | * Wheel command. Bryan W. Headley July-15-2003. |
34 | * v1.2 - Reworked jitter timer as a kernel thread. | 34 | * v1.2 - Reworked jitter timer as a kernel thread. |
35 | * Bryan W. Headley November-28-2003/Jan-10-2004. | 35 | * Bryan W. Headley November-28-2003/Jan-10-2004. |
36 | * v1.3 - Repaired issue of kernel thread going nuts on single-processor | 36 | * v1.3 - Repaired issue of kernel thread going nuts on single-processor |
37 | * machines, introduced programmableDelay as a command line | 37 | * machines, introduced programmableDelay as a command line |
@@ -49,10 +49,10 @@ | |||
49 | * NOTE: | 49 | * NOTE: |
50 | * This kernel driver is augmented by the "Aiptek" XFree86 input | 50 | * This kernel driver is augmented by the "Aiptek" XFree86 input |
51 | * driver for your X server, as well as the Gaiptek GUI Front-end | 51 | * driver for your X server, as well as the Gaiptek GUI Front-end |
52 | * "Tablet Manager". | 52 | * "Tablet Manager". |
53 | * These three products are highly interactive with one another, | 53 | * These three products are highly interactive with one another, |
54 | * so therefore it's easier to document them all as one subsystem. | 54 | * so therefore it's easier to document them all as one subsystem. |
55 | * Please visit the project's "home page", located at, | 55 | * Please visit the project's "home page", located at, |
56 | * http://aiptektablet.sourceforge.net. | 56 | * http://aiptektablet.sourceforge.net. |
57 | * | 57 | * |
58 | * This program is free software; you can redistribute it and/or modify | 58 | * This program is free software; you can redistribute it and/or modify |
@@ -156,7 +156,7 @@ | |||
156 | * Command/Data Description Return Bytes Return Value | 156 | * Command/Data Description Return Bytes Return Value |
157 | * 0x10/0x00 SwitchToMouse 0 | 157 | * 0x10/0x00 SwitchToMouse 0 |
158 | * 0x10/0x01 SwitchToTablet 0 | 158 | * 0x10/0x01 SwitchToTablet 0 |
159 | * 0x18/0x04 SetResolution 0 | 159 | * 0x18/0x04 SetResolution 0 |
160 | * 0x12/0xFF AutoGainOn 0 | 160 | * 0x12/0xFF AutoGainOn 0 |
161 | * 0x17/0x00 FilterOn 0 | 161 | * 0x17/0x00 FilterOn 0 |
162 | * 0x01/0x00 GetXExtension 2 MaxX | 162 | * 0x01/0x00 GetXExtension 2 MaxX |
@@ -247,7 +247,7 @@ | |||
247 | #define AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE 2 | 247 | #define AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE 2 |
248 | #define AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED 3 | 248 | #define AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED 3 |
249 | 249 | ||
250 | /* Time to wait (in ms) to help mask hand jittering | 250 | /* Time to wait (in ms) to help mask hand jittering |
251 | * when pressing the stylus buttons. | 251 | * when pressing the stylus buttons. |
252 | */ | 252 | */ |
253 | #define AIPTEK_JITTER_DELAY_DEFAULT 50 | 253 | #define AIPTEK_JITTER_DELAY_DEFAULT 50 |
@@ -324,7 +324,6 @@ struct aiptek { | |||
324 | struct aiptek_settings curSetting; /* tablet's current programmable */ | 324 | struct aiptek_settings curSetting; /* tablet's current programmable */ |
325 | struct aiptek_settings newSetting; /* ... and new param settings */ | 325 | struct aiptek_settings newSetting; /* ... and new param settings */ |
326 | unsigned int ifnum; /* interface number for IO */ | 326 | unsigned int ifnum; /* interface number for IO */ |
327 | int openCount; /* module use counter */ | ||
328 | int diagnostic; /* tablet diagnostic codes */ | 327 | int diagnostic; /* tablet diagnostic codes */ |
329 | unsigned long eventCount; /* event count */ | 328 | unsigned long eventCount; /* event count */ |
330 | int inDelay; /* jitter: in jitter delay? */ | 329 | int inDelay; /* jitter: in jitter delay? */ |
@@ -791,7 +790,7 @@ exit: | |||
791 | * specific Aiptek model numbers, because there has been overlaps, | 790 | * specific Aiptek model numbers, because there has been overlaps, |
792 | * use, and reuse of id's in existing models. Certain models have | 791 | * use, and reuse of id's in existing models. Certain models have |
793 | * been known to use more than one ID, indicative perhaps of | 792 | * been known to use more than one ID, indicative perhaps of |
794 | * manufacturing revisions. In any event, we consider these | 793 | * manufacturing revisions. In any event, we consider these |
795 | * IDs to not be model-specific nor unique. | 794 | * IDs to not be model-specific nor unique. |
796 | */ | 795 | */ |
797 | static const struct usb_device_id aiptek_ids[] = { | 796 | static const struct usb_device_id aiptek_ids[] = { |
@@ -814,15 +813,9 @@ static int aiptek_open(struct input_dev *inputdev) | |||
814 | { | 813 | { |
815 | struct aiptek *aiptek = inputdev->private; | 814 | struct aiptek *aiptek = inputdev->private; |
816 | 815 | ||
817 | if (aiptek->openCount++ > 0) { | ||
818 | return 0; | ||
819 | } | ||
820 | |||
821 | aiptek->urb->dev = aiptek->usbdev; | 816 | aiptek->urb->dev = aiptek->usbdev; |
822 | if (usb_submit_urb(aiptek->urb, GFP_KERNEL) != 0) { | 817 | if (usb_submit_urb(aiptek->urb, GFP_KERNEL) != 0) |
823 | aiptek->openCount--; | ||
824 | return -EIO; | 818 | return -EIO; |
825 | } | ||
826 | 819 | ||
827 | return 0; | 820 | return 0; |
828 | } | 821 | } |
@@ -834,13 +827,11 @@ static void aiptek_close(struct input_dev *inputdev) | |||
834 | { | 827 | { |
835 | struct aiptek *aiptek = inputdev->private; | 828 | struct aiptek *aiptek = inputdev->private; |
836 | 829 | ||
837 | if (--aiptek->openCount == 0) { | 830 | usb_kill_urb(aiptek->urb); |
838 | usb_kill_urb(aiptek->urb); | ||
839 | } | ||
840 | } | 831 | } |
841 | 832 | ||
842 | /*********************************************************************** | 833 | /*********************************************************************** |
843 | * aiptek_set_report and aiptek_get_report() are borrowed from Linux 2.4.x, | 834 | * aiptek_set_report and aiptek_get_report() are borrowed from Linux 2.4.x, |
844 | * where they were known as usb_set_report and usb_get_report. | 835 | * where they were known as usb_set_report and usb_get_report. |
845 | */ | 836 | */ |
846 | static int | 837 | static int |
@@ -2252,7 +2243,6 @@ static void aiptek_disconnect(struct usb_interface *intf) | |||
2252 | AIPTEK_PACKET_LENGTH, | 2243 | AIPTEK_PACKET_LENGTH, |
2253 | aiptek->data, aiptek->data_dma); | 2244 | aiptek->data, aiptek->data_dma); |
2254 | kfree(aiptek); | 2245 | kfree(aiptek); |
2255 | aiptek = NULL; | ||
2256 | } | 2246 | } |
2257 | } | 2247 | } |
2258 | 2248 | ||
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index 860df26323b1..db95c975952b 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c | |||
@@ -1,15 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * USB ATI Remote support | 2 | * USB ATI Remote support |
3 | * | 3 | * |
4 | * Version 2.2.0 Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net> | 4 | * Version 2.2.0 Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net> |
5 | * Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev | 5 | * Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev |
6 | * | 6 | * |
7 | * This 2.2.0 version is a rewrite / cleanup of the 2.1.1 driver, including | 7 | * This 2.2.0 version is a rewrite / cleanup of the 2.1.1 driver, including |
8 | * porting to the 2.6 kernel interfaces, along with other modification | 8 | * porting to the 2.6 kernel interfaces, along with other modification |
9 | * to better match the style of the existing usb/input drivers. However, the | 9 | * to better match the style of the existing usb/input drivers. However, the |
10 | * protocol and hardware handling is essentially unchanged from 2.1.1. | 10 | * protocol and hardware handling is essentially unchanged from 2.1.1. |
11 | * | 11 | * |
12 | * The 2.1.1 driver was derived from the usbati_remote and usbkbd drivers by | 12 | * The 2.1.1 driver was derived from the usbati_remote and usbkbd drivers by |
13 | * Vojtech Pavlik. | 13 | * Vojtech Pavlik. |
14 | * | 14 | * |
15 | * Changes: | 15 | * Changes: |
@@ -23,64 +23,64 @@ | |||
23 | * Added support for the "Lola" remote contributed by: | 23 | * Added support for the "Lola" remote contributed by: |
24 | * Seth Cohn <sethcohn@yahoo.com> | 24 | * Seth Cohn <sethcohn@yahoo.com> |
25 | * | 25 | * |
26 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | 26 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
27 | * | 27 | * |
28 | * This program is free software; you can redistribute it and/or modify | 28 | * This program is free software; you can redistribute it and/or modify |
29 | * it under the terms of the GNU General Public License as published by | 29 | * it under the terms of the GNU General Public License as published by |
30 | * the Free Software Foundation; either version 2 of the License, or | 30 | * the Free Software Foundation; either version 2 of the License, or |
31 | * (at your option) any later version. | 31 | * (at your option) any later version. |
32 | * | 32 | * |
33 | * This program is distributed in the hope that it will be useful, | 33 | * This program is distributed in the hope that it will be useful, |
34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
36 | * GNU General Public License for more details. | 36 | * GNU General Public License for more details. |
37 | * | 37 | * |
38 | * You should have received a copy of the GNU General Public License | 38 | * You should have received a copy of the GNU General Public License |
39 | * along with this program; if not, write to the Free Software | 39 | * along with this program; if not, write to the Free Software |
40 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 40 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
41 | * | 41 | * |
42 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | 42 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
43 | * | 43 | * |
44 | * Hardware & software notes | 44 | * Hardware & software notes |
45 | * | 45 | * |
46 | * These remote controls are distributed by ATI as part of their | 46 | * These remote controls are distributed by ATI as part of their |
47 | * "All-In-Wonder" video card packages. The receiver self-identifies as a | 47 | * "All-In-Wonder" video card packages. The receiver self-identifies as a |
48 | * "USB Receiver" with manufacturer "X10 Wireless Technology Inc". | 48 | * "USB Receiver" with manufacturer "X10 Wireless Technology Inc". |
49 | * | 49 | * |
50 | * The "Lola" remote is available from X10. See: | 50 | * The "Lola" remote is available from X10. See: |
51 | * http://www.x10.com/products/lola_sg1.htm | 51 | * http://www.x10.com/products/lola_sg1.htm |
52 | * The Lola is similar to the ATI remote but has no mouse support, and slightly | 52 | * The Lola is similar to the ATI remote but has no mouse support, and slightly |
53 | * different keys. | 53 | * different keys. |
54 | * | 54 | * |
55 | * It is possible to use multiple receivers and remotes on multiple computers | 55 | * It is possible to use multiple receivers and remotes on multiple computers |
56 | * simultaneously by configuring them to use specific channels. | 56 | * simultaneously by configuring them to use specific channels. |
57 | * | 57 | * |
58 | * The RF protocol used by the remote supports 16 distinct channels, 1 to 16. | 58 | * The RF protocol used by the remote supports 16 distinct channels, 1 to 16. |
59 | * Actually, it may even support more, at least in some revisions of the | 59 | * Actually, it may even support more, at least in some revisions of the |
60 | * hardware. | 60 | * hardware. |
61 | * | 61 | * |
62 | * Each remote can be configured to transmit on one channel as follows: | 62 | * Each remote can be configured to transmit on one channel as follows: |
63 | * - Press and hold the "hand icon" button. | 63 | * - Press and hold the "hand icon" button. |
64 | * - When the red LED starts to blink, let go of the "hand icon" button. | 64 | * - When the red LED starts to blink, let go of the "hand icon" button. |
65 | * - When it stops blinking, input the channel code as two digits, from 01 | 65 | * - When it stops blinking, input the channel code as two digits, from 01 |
66 | * to 16, and press the hand icon again. | 66 | * to 16, and press the hand icon again. |
67 | * | 67 | * |
68 | * The timing can be a little tricky. Try loading the module with debug=1 | 68 | * The timing can be a little tricky. Try loading the module with debug=1 |
69 | * to have the kernel print out messages about the remote control number | 69 | * to have the kernel print out messages about the remote control number |
70 | * and mask. Note: debugging prints remote numbers as zero-based hexadecimal. | 70 | * and mask. Note: debugging prints remote numbers as zero-based hexadecimal. |
71 | * | 71 | * |
72 | * The driver has a "channel_mask" parameter. This bitmask specifies which | 72 | * The driver has a "channel_mask" parameter. This bitmask specifies which |
73 | * channels will be ignored by the module. To mask out channels, just add | 73 | * channels will be ignored by the module. To mask out channels, just add |
74 | * all the 2^channel_number values together. | 74 | * all the 2^channel_number values together. |
75 | * | 75 | * |
76 | * For instance, set channel_mask = 2^4 = 16 (binary 10000) to make ati_remote | 76 | * For instance, set channel_mask = 2^4 = 16 (binary 10000) to make ati_remote |
77 | * ignore signals coming from remote controls transmitting on channel 4, but | 77 | * ignore signals coming from remote controls transmitting on channel 4, but |
78 | * accept all other channels. | 78 | * accept all other channels. |
79 | * | 79 | * |
80 | * Or, set channel_mask = 65533, (0xFFFD), and all channels except 1 will be | 80 | * Or, set channel_mask = 65533, (0xFFFD), and all channels except 1 will be |
81 | * ignored. | 81 | * ignored. |
82 | * | 82 | * |
83 | * The default is 0 (respond to all channels). Bit 0 and bits 17-32 of this | 83 | * The default is 0 (respond to all channels). Bit 0 and bits 17-32 of this |
84 | * parameter are unused. | 84 | * parameter are unused. |
85 | * | 85 | * |
86 | */ | 86 | */ |
@@ -99,13 +99,13 @@ | |||
99 | /* | 99 | /* |
100 | * Module and Version Information, Module Parameters | 100 | * Module and Version Information, Module Parameters |
101 | */ | 101 | */ |
102 | 102 | ||
103 | #define ATI_REMOTE_VENDOR_ID 0x0bc7 | 103 | #define ATI_REMOTE_VENDOR_ID 0x0bc7 |
104 | #define ATI_REMOTE_PRODUCT_ID 0x004 | 104 | #define ATI_REMOTE_PRODUCT_ID 0x004 |
105 | #define LOLA_REMOTE_PRODUCT_ID 0x002 | 105 | #define LOLA_REMOTE_PRODUCT_ID 0x002 |
106 | #define MEDION_REMOTE_PRODUCT_ID 0x006 | 106 | #define MEDION_REMOTE_PRODUCT_ID 0x006 |
107 | 107 | ||
108 | #define DRIVER_VERSION "2.2.1" | 108 | #define DRIVER_VERSION "2.2.1" |
109 | #define DRIVER_AUTHOR "Torrey Hoffman <thoffman@arnor.net>" | 109 | #define DRIVER_AUTHOR "Torrey Hoffman <thoffman@arnor.net>" |
110 | #define DRIVER_DESC "ATI/X10 RF USB Remote Control" | 110 | #define DRIVER_DESC "ATI/X10 RF USB Remote Control" |
111 | 111 | ||
@@ -113,18 +113,18 @@ | |||
113 | #define DATA_BUFSIZE 63 /* size of URB data buffers */ | 113 | #define DATA_BUFSIZE 63 /* size of URB data buffers */ |
114 | #define ATI_INPUTNUM 1 /* Which input device to register as */ | 114 | #define ATI_INPUTNUM 1 /* Which input device to register as */ |
115 | 115 | ||
116 | static unsigned long channel_mask = 0; | 116 | static unsigned long channel_mask; |
117 | module_param(channel_mask, ulong, 0444); | 117 | module_param(channel_mask, ulong, 0444); |
118 | MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore"); | 118 | MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore"); |
119 | 119 | ||
120 | static int debug = 0; | 120 | static int debug; |
121 | module_param(debug, int, 0444); | 121 | module_param(debug, int, 0444); |
122 | MODULE_PARM_DESC(debug, "Enable extra debug messages and information"); | 122 | MODULE_PARM_DESC(debug, "Enable extra debug messages and information"); |
123 | 123 | ||
124 | #define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0) | 124 | #define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0) |
125 | #undef err | 125 | #undef err |
126 | #define err(format, arg...) printk(KERN_ERR format , ## arg) | 126 | #define err(format, arg...) printk(KERN_ERR format , ## arg) |
127 | 127 | ||
128 | static struct usb_device_id ati_remote_table[] = { | 128 | static struct usb_device_id ati_remote_table[] = { |
129 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) }, | 129 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) }, |
130 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) }, | 130 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) }, |
@@ -148,7 +148,7 @@ static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; | |||
148 | /* Acceleration curve for directional control pad */ | 148 | /* Acceleration curve for directional control pad */ |
149 | static char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; | 149 | static char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; |
150 | 150 | ||
151 | /* Duplicate event filtering time. | 151 | /* Duplicate event filtering time. |
152 | * Sequential, identical KIND_FILTERED inputs with less than | 152 | * Sequential, identical KIND_FILTERED inputs with less than |
153 | * FILTER_TIME jiffies between them are considered as repeat | 153 | * FILTER_TIME jiffies between them are considered as repeat |
154 | * events. The hardware generates 5 events for the first keypress | 154 | * events. The hardware generates 5 events for the first keypress |
@@ -161,10 +161,10 @@ static char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; | |||
161 | static DECLARE_MUTEX(disconnect_sem); | 161 | static DECLARE_MUTEX(disconnect_sem); |
162 | 162 | ||
163 | struct ati_remote { | 163 | struct ati_remote { |
164 | struct input_dev idev; | 164 | struct input_dev idev; |
165 | struct usb_device *udev; | 165 | struct usb_device *udev; |
166 | struct usb_interface *interface; | 166 | struct usb_interface *interface; |
167 | 167 | ||
168 | struct urb *irq_urb; | 168 | struct urb *irq_urb; |
169 | struct urb *out_urb; | 169 | struct urb *out_urb; |
170 | struct usb_endpoint_descriptor *endpoint_in; | 170 | struct usb_endpoint_descriptor *endpoint_in; |
@@ -174,13 +174,11 @@ struct ati_remote { | |||
174 | dma_addr_t inbuf_dma; | 174 | dma_addr_t inbuf_dma; |
175 | dma_addr_t outbuf_dma; | 175 | dma_addr_t outbuf_dma; |
176 | 176 | ||
177 | int open; /* open counter */ | ||
178 | |||
179 | unsigned char old_data[2]; /* Detect duplicate events */ | 177 | unsigned char old_data[2]; /* Detect duplicate events */ |
180 | unsigned long old_jiffies; | 178 | unsigned long old_jiffies; |
181 | unsigned long acc_jiffies; /* handle acceleration */ | 179 | unsigned long acc_jiffies; /* handle acceleration */ |
182 | unsigned int repeat_count; | 180 | unsigned int repeat_count; |
183 | 181 | ||
184 | char name[NAME_BUFSIZE]; | 182 | char name[NAME_BUFSIZE]; |
185 | char phys[NAME_BUFSIZE]; | 183 | char phys[NAME_BUFSIZE]; |
186 | 184 | ||
@@ -206,14 +204,14 @@ static struct | |||
206 | int type; | 204 | int type; |
207 | unsigned int code; | 205 | unsigned int code; |
208 | int value; | 206 | int value; |
209 | } ati_remote_tbl[] = | 207 | } ati_remote_tbl[] = |
210 | { | 208 | { |
211 | /* Directional control pad axes */ | 209 | /* Directional control pad axes */ |
212 | {KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */ | 210 | {KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */ |
213 | {KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */ | 211 | {KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */ |
214 | {KIND_ACCEL, 0x37, 0x72, EV_REL, REL_Y, -1}, /* up */ | 212 | {KIND_ACCEL, 0x37, 0x72, EV_REL, REL_Y, -1}, /* up */ |
215 | {KIND_ACCEL, 0x38, 0x73, EV_REL, REL_Y, 1}, /* down */ | 213 | {KIND_ACCEL, 0x38, 0x73, EV_REL, REL_Y, 1}, /* down */ |
216 | /* Directional control pad diagonals */ | 214 | /* Directional control pad diagonals */ |
217 | {KIND_LU, 0x39, 0x74, EV_REL, 0, 0}, /* left up */ | 215 | {KIND_LU, 0x39, 0x74, EV_REL, 0, 0}, /* left up */ |
218 | {KIND_RU, 0x3a, 0x75, EV_REL, 0, 0}, /* right up */ | 216 | {KIND_RU, 0x3a, 0x75, EV_REL, 0, 0}, /* right up */ |
219 | {KIND_LD, 0x3c, 0x77, EV_REL, 0, 0}, /* left down */ | 217 | {KIND_LD, 0x3c, 0x77, EV_REL, 0, 0}, /* left down */ |
@@ -225,7 +223,7 @@ static struct | |||
225 | {KIND_LITERAL, 0x41, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */ | 223 | {KIND_LITERAL, 0x41, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */ |
226 | {KIND_LITERAL, 0x42, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */ | 224 | {KIND_LITERAL, 0x42, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */ |
227 | 225 | ||
228 | /* Artificial "doubleclick" events are generated by the hardware. | 226 | /* Artificial "doubleclick" events are generated by the hardware. |
229 | * They are mapped to the "side" and "extra" mouse buttons here. */ | 227 | * They are mapped to the "side" and "extra" mouse buttons here. */ |
230 | {KIND_FILTERED, 0x3f, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */ | 228 | {KIND_FILTERED, 0x3f, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */ |
231 | {KIND_FILTERED, 0x43, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */ | 229 | {KIND_FILTERED, 0x43, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */ |
@@ -273,15 +271,15 @@ static struct | |||
273 | {KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_PLAY, 1}, /* ( >) */ | 271 | {KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_PLAY, 1}, /* ( >) */ |
274 | {KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_REWIND, 1}, /* (<<) */ | 272 | {KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_REWIND, 1}, /* (<<) */ |
275 | {KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_FORWARD, 1}, /* (>>) */ | 273 | {KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_FORWARD, 1}, /* (>>) */ |
276 | {KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1}, /* ([]) */ | 274 | {KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1}, /* ([]) */ |
277 | {KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_PAUSE, 1}, /* ('') */ | 275 | {KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_PAUSE, 1}, /* ('') */ |
278 | {KIND_FILTERED, 0xf0, 0x2b, EV_KEY, KEY_PREVIOUS, 1}, /* (<-) */ | 276 | {KIND_FILTERED, 0xf0, 0x2b, EV_KEY, KEY_PREVIOUS, 1}, /* (<-) */ |
279 | {KIND_FILTERED, 0xef, 0x2a, EV_KEY, KEY_NEXT, 1}, /* (>+) */ | 277 | {KIND_FILTERED, 0xef, 0x2a, EV_KEY, KEY_NEXT, 1}, /* (>+) */ |
280 | {KIND_FILTERED, 0xf2, 0x2D, EV_KEY, KEY_INFO, 1}, /* PLAYING */ | 278 | {KIND_FILTERED, 0xf2, 0x2D, EV_KEY, KEY_INFO, 1}, /* PLAYING */ |
281 | {KIND_FILTERED, 0xf3, 0x2E, EV_KEY, KEY_HOME, 1}, /* TOP */ | 279 | {KIND_FILTERED, 0xf3, 0x2E, EV_KEY, KEY_HOME, 1}, /* TOP */ |
282 | {KIND_FILTERED, 0xf4, 0x2F, EV_KEY, KEY_END, 1}, /* END */ | 280 | {KIND_FILTERED, 0xf4, 0x2F, EV_KEY, KEY_END, 1}, /* END */ |
283 | {KIND_FILTERED, 0xf5, 0x30, EV_KEY, KEY_SELECT, 1}, /* SELECT */ | 281 | {KIND_FILTERED, 0xf5, 0x30, EV_KEY, KEY_SELECT, 1}, /* SELECT */ |
284 | 282 | ||
285 | {KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0} | 283 | {KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0} |
286 | }; | 284 | }; |
287 | 285 | ||
@@ -315,7 +313,7 @@ static void ati_remote_dump(unsigned char *data, unsigned int len) | |||
315 | if ((len == 1) && (data[0] != (unsigned char)0xff) && (data[0] != 0x00)) | 313 | if ((len == 1) && (data[0] != (unsigned char)0xff) && (data[0] != 0x00)) |
316 | warn("Weird byte 0x%02x", data[0]); | 314 | warn("Weird byte 0x%02x", data[0]); |
317 | else if (len == 4) | 315 | else if (len == 4) |
318 | warn("Weird key %02x %02x %02x %02x", | 316 | warn("Weird key %02x %02x %02x %02x", |
319 | data[0], data[1], data[2], data[3]); | 317 | data[0], data[1], data[2], data[3]); |
320 | else | 318 | else |
321 | warn("Weird data, len=%d %02x %02x %02x %02x %02x %02x ...", | 319 | warn("Weird data, len=%d %02x %02x %02x %02x %02x %02x ...", |
@@ -328,25 +326,16 @@ static void ati_remote_dump(unsigned char *data, unsigned int len) | |||
328 | static int ati_remote_open(struct input_dev *inputdev) | 326 | static int ati_remote_open(struct input_dev *inputdev) |
329 | { | 327 | { |
330 | struct ati_remote *ati_remote = inputdev->private; | 328 | struct ati_remote *ati_remote = inputdev->private; |
331 | int retval = 0; | ||
332 | |||
333 | down(&disconnect_sem); | ||
334 | |||
335 | if (ati_remote->open++) | ||
336 | goto exit; | ||
337 | 329 | ||
338 | /* On first open, submit the read urb which was set up previously. */ | 330 | /* On first open, submit the read urb which was set up previously. */ |
339 | ati_remote->irq_urb->dev = ati_remote->udev; | 331 | ati_remote->irq_urb->dev = ati_remote->udev; |
340 | if (usb_submit_urb(ati_remote->irq_urb, GFP_KERNEL)) { | 332 | if (usb_submit_urb(ati_remote->irq_urb, GFP_KERNEL)) { |
341 | dev_err(&ati_remote->interface->dev, | 333 | dev_err(&ati_remote->interface->dev, |
342 | "%s: usb_submit_urb failed!\n", __FUNCTION__); | 334 | "%s: usb_submit_urb failed!\n", __FUNCTION__); |
343 | ati_remote->open--; | 335 | return -EIO; |
344 | retval = -EIO; | ||
345 | } | 336 | } |
346 | 337 | ||
347 | exit: | 338 | return 0; |
348 | up(&disconnect_sem); | ||
349 | return retval; | ||
350 | } | 339 | } |
351 | 340 | ||
352 | /* | 341 | /* |
@@ -355,9 +344,8 @@ exit: | |||
355 | static void ati_remote_close(struct input_dev *inputdev) | 344 | static void ati_remote_close(struct input_dev *inputdev) |
356 | { | 345 | { |
357 | struct ati_remote *ati_remote = inputdev->private; | 346 | struct ati_remote *ati_remote = inputdev->private; |
358 | 347 | ||
359 | if (!--ati_remote->open) | 348 | usb_kill_urb(ati_remote->irq_urb); |
360 | usb_kill_urb(ati_remote->irq_urb); | ||
361 | } | 349 | } |
362 | 350 | ||
363 | /* | 351 | /* |
@@ -366,13 +354,13 @@ static void ati_remote_close(struct input_dev *inputdev) | |||
366 | static void ati_remote_irq_out(struct urb *urb, struct pt_regs *regs) | 354 | static void ati_remote_irq_out(struct urb *urb, struct pt_regs *regs) |
367 | { | 355 | { |
368 | struct ati_remote *ati_remote = urb->context; | 356 | struct ati_remote *ati_remote = urb->context; |
369 | 357 | ||
370 | if (urb->status) { | 358 | if (urb->status) { |
371 | dev_dbg(&ati_remote->interface->dev, "%s: status %d\n", | 359 | dev_dbg(&ati_remote->interface->dev, "%s: status %d\n", |
372 | __FUNCTION__, urb->status); | 360 | __FUNCTION__, urb->status); |
373 | return; | 361 | return; |
374 | } | 362 | } |
375 | 363 | ||
376 | ati_remote->send_flags |= SEND_FLAG_COMPLETE; | 364 | ati_remote->send_flags |= SEND_FLAG_COMPLETE; |
377 | wmb(); | 365 | wmb(); |
378 | wake_up(&ati_remote->wait); | 366 | wake_up(&ati_remote->wait); |
@@ -380,16 +368,16 @@ static void ati_remote_irq_out(struct urb *urb, struct pt_regs *regs) | |||
380 | 368 | ||
381 | /* | 369 | /* |
382 | * ati_remote_sendpacket | 370 | * ati_remote_sendpacket |
383 | * | 371 | * |
384 | * Used to send device initialization strings | 372 | * Used to send device initialization strings |
385 | */ | 373 | */ |
386 | static int ati_remote_sendpacket(struct ati_remote *ati_remote, u16 cmd, unsigned char *data) | 374 | static int ati_remote_sendpacket(struct ati_remote *ati_remote, u16 cmd, unsigned char *data) |
387 | { | 375 | { |
388 | int retval = 0; | 376 | int retval = 0; |
389 | 377 | ||
390 | /* Set up out_urb */ | 378 | /* Set up out_urb */ |
391 | memcpy(ati_remote->out_urb->transfer_buffer + 1, data, LO(cmd)); | 379 | memcpy(ati_remote->out_urb->transfer_buffer + 1, data, LO(cmd)); |
392 | ((char *) ati_remote->out_urb->transfer_buffer)[0] = HI(cmd); | 380 | ((char *) ati_remote->out_urb->transfer_buffer)[0] = HI(cmd); |
393 | 381 | ||
394 | ati_remote->out_urb->transfer_buffer_length = LO(cmd) + 1; | 382 | ati_remote->out_urb->transfer_buffer_length = LO(cmd) + 1; |
395 | ati_remote->out_urb->dev = ati_remote->udev; | 383 | ati_remote->out_urb->dev = ati_remote->udev; |
@@ -397,17 +385,17 @@ static int ati_remote_sendpacket(struct ati_remote *ati_remote, u16 cmd, unsigne | |||
397 | 385 | ||
398 | retval = usb_submit_urb(ati_remote->out_urb, GFP_ATOMIC); | 386 | retval = usb_submit_urb(ati_remote->out_urb, GFP_ATOMIC); |
399 | if (retval) { | 387 | if (retval) { |
400 | dev_dbg(&ati_remote->interface->dev, | 388 | dev_dbg(&ati_remote->interface->dev, |
401 | "sendpacket: usb_submit_urb failed: %d\n", retval); | 389 | "sendpacket: usb_submit_urb failed: %d\n", retval); |
402 | return retval; | 390 | return retval; |
403 | } | 391 | } |
404 | 392 | ||
405 | wait_event_timeout(ati_remote->wait, | 393 | wait_event_timeout(ati_remote->wait, |
406 | ((ati_remote->out_urb->status != -EINPROGRESS) || | 394 | ((ati_remote->out_urb->status != -EINPROGRESS) || |
407 | (ati_remote->send_flags & SEND_FLAG_COMPLETE)), | 395 | (ati_remote->send_flags & SEND_FLAG_COMPLETE)), |
408 | HZ); | 396 | HZ); |
409 | usb_kill_urb(ati_remote->out_urb); | 397 | usb_kill_urb(ati_remote->out_urb); |
410 | 398 | ||
411 | return retval; | 399 | return retval; |
412 | } | 400 | } |
413 | 401 | ||
@@ -419,15 +407,15 @@ static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2) | |||
419 | int i; | 407 | int i; |
420 | 408 | ||
421 | for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) { | 409 | for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) { |
422 | /* | 410 | /* |
423 | * Decide if the table entry matches the remote input. | 411 | * Decide if the table entry matches the remote input. |
424 | */ | 412 | */ |
425 | if ((((ati_remote_tbl[i].data1 & 0x0f) == (d1 & 0x0f))) && | 413 | if ((((ati_remote_tbl[i].data1 & 0x0f) == (d1 & 0x0f))) && |
426 | ((((ati_remote_tbl[i].data1 >> 4) - | 414 | ((((ati_remote_tbl[i].data1 >> 4) - |
427 | (d1 >> 4) + rem) & 0x0f) == 0x0f) && | 415 | (d1 >> 4) + rem) & 0x0f) == 0x0f) && |
428 | (ati_remote_tbl[i].data2 == d2)) | 416 | (ati_remote_tbl[i].data2 == d2)) |
429 | return i; | 417 | return i; |
430 | 418 | ||
431 | } | 419 | } |
432 | return -1; | 420 | return -1; |
433 | } | 421 | } |
@@ -435,16 +423,16 @@ static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2) | |||
435 | /* | 423 | /* |
436 | * ati_remote_report_input | 424 | * ati_remote_report_input |
437 | */ | 425 | */ |
438 | static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | 426 | static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) |
439 | { | 427 | { |
440 | struct ati_remote *ati_remote = urb->context; | 428 | struct ati_remote *ati_remote = urb->context; |
441 | unsigned char *data= ati_remote->inbuf; | 429 | unsigned char *data= ati_remote->inbuf; |
442 | struct input_dev *dev = &ati_remote->idev; | 430 | struct input_dev *dev = &ati_remote->idev; |
443 | int index, acc; | 431 | int index, acc; |
444 | int remote_num; | 432 | int remote_num; |
445 | 433 | ||
446 | /* Deal with strange looking inputs */ | 434 | /* Deal with strange looking inputs */ |
447 | if ( (urb->actual_length != 4) || (data[0] != 0x14) || | 435 | if ( (urb->actual_length != 4) || (data[0] != 0x14) || |
448 | ((data[3] & 0x0f) != 0x00) ) { | 436 | ((data[3] & 0x0f) != 0x00) ) { |
449 | ati_remote_dump(data, urb->actual_length); | 437 | ati_remote_dump(data, urb->actual_length); |
450 | return; | 438 | return; |
@@ -453,7 +441,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
453 | /* Mask unwanted remote channels. */ | 441 | /* Mask unwanted remote channels. */ |
454 | /* note: remote_num is 0-based, channel 1 on remote == 0 here */ | 442 | /* note: remote_num is 0-based, channel 1 on remote == 0 here */ |
455 | remote_num = (data[3] >> 4) & 0x0f; | 443 | remote_num = (data[3] >> 4) & 0x0f; |
456 | if (channel_mask & (1 << (remote_num + 1))) { | 444 | if (channel_mask & (1 << (remote_num + 1))) { |
457 | dbginfo(&ati_remote->interface->dev, | 445 | dbginfo(&ati_remote->interface->dev, |
458 | "Masked input from channel 0x%02x: data %02x,%02x, mask= 0x%02lx\n", | 446 | "Masked input from channel 0x%02x: data %02x,%02x, mask= 0x%02lx\n", |
459 | remote_num, data[1], data[2], channel_mask); | 447 | remote_num, data[1], data[2], channel_mask); |
@@ -463,37 +451,36 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
463 | /* Look up event code index in translation table */ | 451 | /* Look up event code index in translation table */ |
464 | index = ati_remote_event_lookup(remote_num, data[1], data[2]); | 452 | index = ati_remote_event_lookup(remote_num, data[1], data[2]); |
465 | if (index < 0) { | 453 | if (index < 0) { |
466 | dev_warn(&ati_remote->interface->dev, | 454 | dev_warn(&ati_remote->interface->dev, |
467 | "Unknown input from channel 0x%02x: data %02x,%02x\n", | 455 | "Unknown input from channel 0x%02x: data %02x,%02x\n", |
468 | remote_num, data[1], data[2]); | 456 | remote_num, data[1], data[2]); |
469 | return; | 457 | return; |
470 | } | 458 | } |
471 | dbginfo(&ati_remote->interface->dev, | 459 | dbginfo(&ati_remote->interface->dev, |
472 | "channel 0x%02x; data %02x,%02x; index %d; keycode %d\n", | 460 | "channel 0x%02x; data %02x,%02x; index %d; keycode %d\n", |
473 | remote_num, data[1], data[2], index, ati_remote_tbl[index].code); | 461 | remote_num, data[1], data[2], index, ati_remote_tbl[index].code); |
474 | 462 | ||
475 | if (ati_remote_tbl[index].kind == KIND_LITERAL) { | 463 | if (ati_remote_tbl[index].kind == KIND_LITERAL) { |
476 | input_regs(dev, regs); | 464 | input_regs(dev, regs); |
477 | input_event(dev, ati_remote_tbl[index].type, | 465 | input_event(dev, ati_remote_tbl[index].type, |
478 | ati_remote_tbl[index].code, | 466 | ati_remote_tbl[index].code, |
479 | ati_remote_tbl[index].value); | 467 | ati_remote_tbl[index].value); |
480 | input_sync(dev); | 468 | input_sync(dev); |
481 | 469 | ||
482 | ati_remote->old_jiffies = jiffies; | 470 | ati_remote->old_jiffies = jiffies; |
483 | return; | 471 | return; |
484 | } | 472 | } |
485 | 473 | ||
486 | if (ati_remote_tbl[index].kind == KIND_FILTERED) { | 474 | if (ati_remote_tbl[index].kind == KIND_FILTERED) { |
487 | /* Filter duplicate events which happen "too close" together. */ | 475 | /* Filter duplicate events which happen "too close" together. */ |
488 | if ((ati_remote->old_data[0] == data[1]) && | 476 | if ((ati_remote->old_data[0] == data[1]) && |
489 | (ati_remote->old_data[1] == data[2]) && | 477 | (ati_remote->old_data[1] == data[2]) && |
490 | ((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) { | 478 | ((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) { |
491 | ati_remote->repeat_count++; | 479 | ati_remote->repeat_count++; |
492 | } | 480 | } else { |
493 | else { | ||
494 | ati_remote->repeat_count = 0; | 481 | ati_remote->repeat_count = 0; |
495 | } | 482 | } |
496 | 483 | ||
497 | ati_remote->old_data[0] = data[1]; | 484 | ati_remote->old_data[0] = data[1]; |
498 | ati_remote->old_data[1] = data[2]; | 485 | ati_remote->old_data[1] = data[2]; |
499 | ati_remote->old_jiffies = jiffies; | 486 | ati_remote->old_jiffies = jiffies; |
@@ -501,7 +488,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
501 | if ((ati_remote->repeat_count > 0) | 488 | if ((ati_remote->repeat_count > 0) |
502 | && (ati_remote->repeat_count < 5)) | 489 | && (ati_remote->repeat_count < 5)) |
503 | return; | 490 | return; |
504 | 491 | ||
505 | 492 | ||
506 | input_regs(dev, regs); | 493 | input_regs(dev, regs); |
507 | input_event(dev, ati_remote_tbl[index].type, | 494 | input_event(dev, ati_remote_tbl[index].type, |
@@ -511,13 +498,13 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
511 | input_sync(dev); | 498 | input_sync(dev); |
512 | 499 | ||
513 | return; | 500 | return; |
514 | } | 501 | } |
515 | 502 | ||
516 | /* | 503 | /* |
517 | * Other event kinds are from the directional control pad, and have an | 504 | * Other event kinds are from the directional control pad, and have an |
518 | * acceleration factor applied to them. Without this acceleration, the | 505 | * acceleration factor applied to them. Without this acceleration, the |
519 | * control pad is mostly unusable. | 506 | * control pad is mostly unusable. |
520 | * | 507 | * |
521 | * If elapsed time since last event is > 1/4 second, user "stopped", | 508 | * If elapsed time since last event is > 1/4 second, user "stopped", |
522 | * so reset acceleration. Otherwise, user is probably holding the control | 509 | * so reset acceleration. Otherwise, user is probably holding the control |
523 | * pad down, so we increase acceleration, ramping up over two seconds to | 510 | * pad down, so we increase acceleration, ramping up over two seconds to |
@@ -559,7 +546,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
559 | input_report_rel(dev, REL_Y, acc); | 546 | input_report_rel(dev, REL_Y, acc); |
560 | break; | 547 | break; |
561 | default: | 548 | default: |
562 | dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n", | 549 | dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n", |
563 | ati_remote_tbl[index].kind); | 550 | ati_remote_tbl[index].kind); |
564 | } | 551 | } |
565 | input_sync(dev); | 552 | input_sync(dev); |
@@ -586,12 +573,12 @@ static void ati_remote_irq_in(struct urb *urb, struct pt_regs *regs) | |||
586 | case -ESHUTDOWN: | 573 | case -ESHUTDOWN: |
587 | dev_dbg(&ati_remote->interface->dev, "%s: urb error status, unlink? \n", | 574 | dev_dbg(&ati_remote->interface->dev, "%s: urb error status, unlink? \n", |
588 | __FUNCTION__); | 575 | __FUNCTION__); |
589 | return; | 576 | return; |
590 | default: /* error */ | 577 | default: /* error */ |
591 | dev_dbg(&ati_remote->interface->dev, "%s: Nonzero urb status %d\n", | 578 | dev_dbg(&ati_remote->interface->dev, "%s: Nonzero urb status %d\n", |
592 | __FUNCTION__, urb->status); | 579 | __FUNCTION__, urb->status); |
593 | } | 580 | } |
594 | 581 | ||
595 | retval = usb_submit_urb(urb, SLAB_ATOMIC); | 582 | retval = usb_submit_urb(urb, SLAB_ATOMIC); |
596 | if (retval) | 583 | if (retval) |
597 | dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n", | 584 | dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n", |
@@ -603,8 +590,6 @@ static void ati_remote_irq_in(struct urb *urb, struct pt_regs *regs) | |||
603 | */ | 590 | */ |
604 | static void ati_remote_delete(struct ati_remote *ati_remote) | 591 | static void ati_remote_delete(struct ati_remote *ati_remote) |
605 | { | 592 | { |
606 | if (!ati_remote) return; | ||
607 | |||
608 | if (ati_remote->irq_urb) | 593 | if (ati_remote->irq_urb) |
609 | usb_kill_urb(ati_remote->irq_urb); | 594 | usb_kill_urb(ati_remote->irq_urb); |
610 | 595 | ||
@@ -614,16 +599,16 @@ static void ati_remote_delete(struct ati_remote *ati_remote) | |||
614 | input_unregister_device(&ati_remote->idev); | 599 | input_unregister_device(&ati_remote->idev); |
615 | 600 | ||
616 | if (ati_remote->inbuf) | 601 | if (ati_remote->inbuf) |
617 | usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, | 602 | usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, |
618 | ati_remote->inbuf, ati_remote->inbuf_dma); | 603 | ati_remote->inbuf, ati_remote->inbuf_dma); |
619 | 604 | ||
620 | if (ati_remote->outbuf) | 605 | if (ati_remote->outbuf) |
621 | usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, | 606 | usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, |
622 | ati_remote->outbuf, ati_remote->outbuf_dma); | 607 | ati_remote->outbuf, ati_remote->outbuf_dma); |
623 | 608 | ||
624 | if (ati_remote->irq_urb) | 609 | if (ati_remote->irq_urb) |
625 | usb_free_urb(ati_remote->irq_urb); | 610 | usb_free_urb(ati_remote->irq_urb); |
626 | 611 | ||
627 | if (ati_remote->out_urb) | 612 | if (ati_remote->out_urb) |
628 | usb_free_urb(ati_remote->out_urb); | 613 | usb_free_urb(ati_remote->out_urb); |
629 | 614 | ||
@@ -636,21 +621,21 @@ static void ati_remote_input_init(struct ati_remote *ati_remote) | |||
636 | int i; | 621 | int i; |
637 | 622 | ||
638 | idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | 623 | idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); |
639 | idev->keybit[LONG(BTN_MOUSE)] = ( BIT(BTN_LEFT) | BIT(BTN_RIGHT) | | 624 | idev->keybit[LONG(BTN_MOUSE)] = ( BIT(BTN_LEFT) | BIT(BTN_RIGHT) | |
640 | BIT(BTN_SIDE) | BIT(BTN_EXTRA) ); | 625 | BIT(BTN_SIDE) | BIT(BTN_EXTRA) ); |
641 | idev->relbit[0] = BIT(REL_X) | BIT(REL_Y); | 626 | idev->relbit[0] = BIT(REL_X) | BIT(REL_Y); |
642 | for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) | 627 | for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) |
643 | if (ati_remote_tbl[i].type == EV_KEY) | 628 | if (ati_remote_tbl[i].type == EV_KEY) |
644 | set_bit(ati_remote_tbl[i].code, idev->keybit); | 629 | set_bit(ati_remote_tbl[i].code, idev->keybit); |
645 | 630 | ||
646 | idev->private = ati_remote; | 631 | idev->private = ati_remote; |
647 | idev->open = ati_remote_open; | 632 | idev->open = ati_remote_open; |
648 | idev->close = ati_remote_close; | 633 | idev->close = ati_remote_close; |
649 | 634 | ||
650 | idev->name = ati_remote->name; | 635 | idev->name = ati_remote->name; |
651 | idev->phys = ati_remote->phys; | 636 | idev->phys = ati_remote->phys; |
652 | 637 | ||
653 | idev->id.bustype = BUS_USB; | 638 | idev->id.bustype = BUS_USB; |
654 | idev->id.vendor = le16_to_cpu(ati_remote->udev->descriptor.idVendor); | 639 | idev->id.vendor = le16_to_cpu(ati_remote->udev->descriptor.idVendor); |
655 | idev->id.product = le16_to_cpu(ati_remote->udev->descriptor.idProduct); | 640 | idev->id.product = le16_to_cpu(ati_remote->udev->descriptor.idProduct); |
656 | idev->id.version = le16_to_cpu(ati_remote->udev->descriptor.bcdDevice); | 641 | idev->id.version = le16_to_cpu(ati_remote->udev->descriptor.bcdDevice); |
@@ -660,27 +645,27 @@ static int ati_remote_initialize(struct ati_remote *ati_remote) | |||
660 | { | 645 | { |
661 | struct usb_device *udev = ati_remote->udev; | 646 | struct usb_device *udev = ati_remote->udev; |
662 | int pipe, maxp; | 647 | int pipe, maxp; |
663 | 648 | ||
664 | init_waitqueue_head(&ati_remote->wait); | 649 | init_waitqueue_head(&ati_remote->wait); |
665 | 650 | ||
666 | /* Set up irq_urb */ | 651 | /* Set up irq_urb */ |
667 | pipe = usb_rcvintpipe(udev, ati_remote->endpoint_in->bEndpointAddress); | 652 | pipe = usb_rcvintpipe(udev, ati_remote->endpoint_in->bEndpointAddress); |
668 | maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); | 653 | maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); |
669 | maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp; | 654 | maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp; |
670 | 655 | ||
671 | usb_fill_int_urb(ati_remote->irq_urb, udev, pipe, ati_remote->inbuf, | 656 | usb_fill_int_urb(ati_remote->irq_urb, udev, pipe, ati_remote->inbuf, |
672 | maxp, ati_remote_irq_in, ati_remote, | 657 | maxp, ati_remote_irq_in, ati_remote, |
673 | ati_remote->endpoint_in->bInterval); | 658 | ati_remote->endpoint_in->bInterval); |
674 | ati_remote->irq_urb->transfer_dma = ati_remote->inbuf_dma; | 659 | ati_remote->irq_urb->transfer_dma = ati_remote->inbuf_dma; |
675 | ati_remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 660 | ati_remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
676 | 661 | ||
677 | /* Set up out_urb */ | 662 | /* Set up out_urb */ |
678 | pipe = usb_sndintpipe(udev, ati_remote->endpoint_out->bEndpointAddress); | 663 | pipe = usb_sndintpipe(udev, ati_remote->endpoint_out->bEndpointAddress); |
679 | maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); | 664 | maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); |
680 | maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp; | 665 | maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp; |
681 | 666 | ||
682 | usb_fill_int_urb(ati_remote->out_urb, udev, pipe, ati_remote->outbuf, | 667 | usb_fill_int_urb(ati_remote->out_urb, udev, pipe, ati_remote->outbuf, |
683 | maxp, ati_remote_irq_out, ati_remote, | 668 | maxp, ati_remote_irq_out, ati_remote, |
684 | ati_remote->endpoint_out->bInterval); | 669 | ati_remote->endpoint_out->bInterval); |
685 | ati_remote->out_urb->transfer_dma = ati_remote->outbuf_dma; | 670 | ati_remote->out_urb->transfer_dma = ati_remote->outbuf_dma; |
686 | ati_remote->out_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 671 | ati_remote->out_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
@@ -688,11 +673,11 @@ static int ati_remote_initialize(struct ati_remote *ati_remote) | |||
688 | /* send initialization strings */ | 673 | /* send initialization strings */ |
689 | if ((ati_remote_sendpacket(ati_remote, 0x8004, init1)) || | 674 | if ((ati_remote_sendpacket(ati_remote, 0x8004, init1)) || |
690 | (ati_remote_sendpacket(ati_remote, 0x8007, init2))) { | 675 | (ati_remote_sendpacket(ati_remote, 0x8007, init2))) { |
691 | dev_err(&ati_remote->interface->dev, | 676 | dev_err(&ati_remote->interface->dev, |
692 | "Initializing ati_remote hardware failed.\n"); | 677 | "Initializing ati_remote hardware failed.\n"); |
693 | return 1; | 678 | return 1; |
694 | } | 679 | } |
695 | 680 | ||
696 | return 0; | 681 | return 0; |
697 | } | 682 | } |
698 | 683 | ||
@@ -769,7 +754,7 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de | |||
769 | 754 | ||
770 | if (!strlen(ati_remote->name)) | 755 | if (!strlen(ati_remote->name)) |
771 | sprintf(ati_remote->name, DRIVER_DESC "(%04x,%04x)", | 756 | sprintf(ati_remote->name, DRIVER_DESC "(%04x,%04x)", |
772 | le16_to_cpu(ati_remote->udev->descriptor.idVendor), | 757 | le16_to_cpu(ati_remote->udev->descriptor.idVendor), |
773 | le16_to_cpu(ati_remote->udev->descriptor.idProduct)); | 758 | le16_to_cpu(ati_remote->udev->descriptor.idProduct)); |
774 | 759 | ||
775 | /* Device Hardware Initialization - fills in ati_remote->idev from udev. */ | 760 | /* Device Hardware Initialization - fills in ati_remote->idev from udev. */ |
@@ -781,11 +766,11 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de | |||
781 | ati_remote_input_init(ati_remote); | 766 | ati_remote_input_init(ati_remote); |
782 | input_register_device(&ati_remote->idev); | 767 | input_register_device(&ati_remote->idev); |
783 | 768 | ||
784 | dev_info(&ati_remote->interface->dev, "Input registered: %s on %s\n", | 769 | dev_info(&ati_remote->interface->dev, "Input registered: %s on %s\n", |
785 | ati_remote->name, path); | 770 | ati_remote->name, path); |
786 | 771 | ||
787 | usb_set_intfdata(interface, ati_remote); | 772 | usb_set_intfdata(interface, ati_remote); |
788 | 773 | ||
789 | error: | 774 | error: |
790 | if (retval) | 775 | if (retval) |
791 | ati_remote_delete(ati_remote); | 776 | ati_remote_delete(ati_remote); |
@@ -800,18 +785,14 @@ static void ati_remote_disconnect(struct usb_interface *interface) | |||
800 | { | 785 | { |
801 | struct ati_remote *ati_remote; | 786 | struct ati_remote *ati_remote; |
802 | 787 | ||
803 | down(&disconnect_sem); | ||
804 | |||
805 | ati_remote = usb_get_intfdata(interface); | 788 | ati_remote = usb_get_intfdata(interface); |
806 | usb_set_intfdata(interface, NULL); | 789 | usb_set_intfdata(interface, NULL); |
807 | if (!ati_remote) { | 790 | if (!ati_remote) { |
808 | warn("%s - null device?\n", __FUNCTION__); | 791 | warn("%s - null device?\n", __FUNCTION__); |
809 | return; | 792 | return; |
810 | } | 793 | } |
811 | |||
812 | ati_remote_delete(ati_remote); | ||
813 | 794 | ||
814 | up(&disconnect_sem); | 795 | ati_remote_delete(ati_remote); |
815 | } | 796 | } |
816 | 797 | ||
817 | /* | 798 | /* |
@@ -820,7 +801,7 @@ static void ati_remote_disconnect(struct usb_interface *interface) | |||
820 | static int __init ati_remote_init(void) | 801 | static int __init ati_remote_init(void) |
821 | { | 802 | { |
822 | int result; | 803 | int result; |
823 | 804 | ||
824 | result = usb_register(&ati_remote_driver); | 805 | result = usb_register(&ati_remote_driver); |
825 | if (result) | 806 | if (result) |
826 | err("usb_register error #%d\n", result); | 807 | err("usb_register error #%d\n", result); |
@@ -838,8 +819,8 @@ static void __exit ati_remote_exit(void) | |||
838 | usb_deregister(&ati_remote_driver); | 819 | usb_deregister(&ati_remote_driver); |
839 | } | 820 | } |
840 | 821 | ||
841 | /* | 822 | /* |
842 | * module specification | 823 | * module specification |
843 | */ | 824 | */ |
844 | 825 | ||
845 | module_init(ati_remote_init); | 826 | module_init(ati_remote_init); |
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 740dec1f521d..100b49bd1d3e 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -232,7 +232,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign | |||
232 | report->size += parser->global.report_size * parser->global.report_count; | 232 | report->size += parser->global.report_size * parser->global.report_count; |
233 | 233 | ||
234 | if (!parser->local.usage_index) /* Ignore padding fields */ | 234 | if (!parser->local.usage_index) /* Ignore padding fields */ |
235 | return 0; | 235 | return 0; |
236 | 236 | ||
237 | usages = max_t(int, parser->local.usage_index, parser->global.report_count); | 237 | usages = max_t(int, parser->local.usage_index, parser->global.report_count); |
238 | 238 | ||
@@ -765,7 +765,7 @@ static __inline__ __u32 s32ton(__s32 value, unsigned n) | |||
765 | static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) | 765 | static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) |
766 | { | 766 | { |
767 | report += (offset >> 5) << 2; offset &= 31; | 767 | report += (offset >> 5) << 2; offset &= 31; |
768 | return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1 << n) - 1); | 768 | return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1); |
769 | } | 769 | } |
770 | 770 | ||
771 | static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) | 771 | static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) |
@@ -1233,6 +1233,13 @@ int hid_wait_io(struct hid_device *hid) | |||
1233 | return 0; | 1233 | return 0; |
1234 | } | 1234 | } |
1235 | 1235 | ||
1236 | static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle) | ||
1237 | { | ||
1238 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
1239 | HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (idle << 8) | report, | ||
1240 | ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
1241 | } | ||
1242 | |||
1236 | static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, | 1243 | static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, |
1237 | unsigned char type, void *buf, int size) | 1244 | unsigned char type, void *buf, int size) |
1238 | { | 1245 | { |
@@ -1301,10 +1308,6 @@ void hid_init_reports(struct hid_device *hid) | |||
1301 | 1308 | ||
1302 | if (err) | 1309 | if (err) |
1303 | warn("timeout initializing reports\n"); | 1310 | warn("timeout initializing reports\n"); |
1304 | |||
1305 | usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0), | ||
1306 | HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, | ||
1307 | hid->ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
1308 | } | 1311 | } |
1309 | 1312 | ||
1310 | #define USB_VENDOR_ID_WACOM 0x056a | 1313 | #define USB_VENDOR_ID_WACOM 0x056a |
@@ -1318,6 +1321,10 @@ void hid_init_reports(struct hid_device *hid) | |||
1318 | #define USB_DEVICE_ID_WACOM_INTUOS3 0x00B0 | 1321 | #define USB_DEVICE_ID_WACOM_INTUOS3 0x00B0 |
1319 | #define USB_DEVICE_ID_WACOM_CINTIQ 0x003F | 1322 | #define USB_DEVICE_ID_WACOM_CINTIQ 0x003F |
1320 | 1323 | ||
1324 | #define USB_VENDOR_ID_ACECAD 0x0460 | ||
1325 | #define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 | ||
1326 | #define USB_DEVICE_ID_ACECAD_302 0x0008 | ||
1327 | |||
1321 | #define USB_VENDOR_ID_KBGEAR 0x084e | 1328 | #define USB_VENDOR_ID_KBGEAR 0x084e |
1322 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 | 1329 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 |
1323 | 1330 | ||
@@ -1502,6 +1509,9 @@ static struct hid_blacklist { | |||
1502 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, | 1509 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, |
1503 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, | 1510 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, |
1504 | 1511 | ||
1512 | { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, | ||
1513 | { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, | ||
1514 | |||
1505 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, | 1515 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, |
1506 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, | 1516 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, |
1507 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, | 1517 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, |
@@ -1590,6 +1600,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
1590 | return NULL; | 1600 | return NULL; |
1591 | } | 1601 | } |
1592 | 1602 | ||
1603 | hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); | ||
1604 | |||
1593 | if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { | 1605 | if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { |
1594 | dbg("reading report descriptor failed"); | 1606 | dbg("reading report descriptor failed"); |
1595 | kfree(rdesc); | 1607 | kfree(rdesc); |
@@ -1635,7 +1647,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
1635 | /* Change the polling interval of mice. */ | 1647 | /* Change the polling interval of mice. */ |
1636 | if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) | 1648 | if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) |
1637 | interval = hid_mousepoll_interval; | 1649 | interval = hid_mousepoll_interval; |
1638 | 1650 | ||
1639 | if (endpoint->bEndpointAddress & USB_DIR_IN) { | 1651 | if (endpoint->bEndpointAddress & USB_DIR_IN) { |
1640 | if (hid->urbin) | 1652 | if (hid->urbin) |
1641 | continue; | 1653 | continue; |
diff --git a/drivers/usb/input/hid-debug.h b/drivers/usb/input/hid-debug.h index 2b91705740a7..52437e5e2e78 100644 --- a/drivers/usb/input/hid-debug.h +++ b/drivers/usb/input/hid-debug.h | |||
@@ -67,7 +67,7 @@ static const struct hid_usage_entry hid_usage_table[] = { | |||
67 | {0, 0x44, "Vbry"}, | 67 | {0, 0x44, "Vbry"}, |
68 | {0, 0x45, "Vbrz"}, | 68 | {0, 0x45, "Vbrz"}, |
69 | {0, 0x46, "Vno"}, | 69 | {0, 0x46, "Vno"}, |
70 | {0, 0x80, "SystemControl"}, | 70 | {0, 0x80, "SystemControl"}, |
71 | {0, 0x81, "SystemPowerDown"}, | 71 | {0, 0x81, "SystemPowerDown"}, |
72 | {0, 0x82, "SystemSleep"}, | 72 | {0, 0x82, "SystemSleep"}, |
73 | {0, 0x83, "SystemWakeUp"}, | 73 | {0, 0x83, "SystemWakeUp"}, |
@@ -347,7 +347,7 @@ __inline__ static void tab(int n) { | |||
347 | 347 | ||
348 | static void hid_dump_field(struct hid_field *field, int n) { | 348 | static void hid_dump_field(struct hid_field *field, int n) { |
349 | int j; | 349 | int j; |
350 | 350 | ||
351 | if (field->physical) { | 351 | if (field->physical) { |
352 | tab(n); | 352 | tab(n); |
353 | printk("Physical("); | 353 | printk("Physical("); |
@@ -408,7 +408,7 @@ static void hid_dump_field(struct hid_field *field, int n) { | |||
408 | printk("%s", units[sys][i]); | 408 | printk("%s", units[sys][i]); |
409 | if(nibble != 1) { | 409 | if(nibble != 1) { |
410 | /* This is a _signed_ nibble(!) */ | 410 | /* This is a _signed_ nibble(!) */ |
411 | 411 | ||
412 | int val = nibble & 0x7; | 412 | int val = nibble & 0x7; |
413 | if(nibble & 0x08) | 413 | if(nibble & 0x08) |
414 | val = -((0x7 & ~val) +1); | 414 | val = -((0x7 & ~val) +1); |
@@ -443,7 +443,7 @@ static void __attribute__((unused)) hid_dump_device(struct hid_device *device) { | |||
443 | struct list_head *list; | 443 | struct list_head *list; |
444 | unsigned i,k; | 444 | unsigned i,k; |
445 | static char *table[] = {"INPUT", "OUTPUT", "FEATURE"}; | 445 | static char *table[] = {"INPUT", "OUTPUT", "FEATURE"}; |
446 | 446 | ||
447 | for (i = 0; i < HID_REPORT_TYPES; i++) { | 447 | for (i = 0; i < HID_REPORT_TYPES; i++) { |
448 | report_enum = device->report_enum + i; | 448 | report_enum = device->report_enum + i; |
449 | list = report_enum->report_list.next; | 449 | list = report_enum->report_list.next; |
@@ -664,8 +664,8 @@ static char *keys[KEY_MAX + 1] = { | |||
664 | static char *relatives[REL_MAX + 1] = { | 664 | static char *relatives[REL_MAX + 1] = { |
665 | [REL_X] = "X", [REL_Y] = "Y", | 665 | [REL_X] = "X", [REL_Y] = "Y", |
666 | [REL_Z] = "Z", [REL_HWHEEL] = "HWheel", | 666 | [REL_Z] = "Z", [REL_HWHEEL] = "HWheel", |
667 | [REL_DIAL] = "Dial", [REL_WHEEL] = "Wheel", | 667 | [REL_DIAL] = "Dial", [REL_WHEEL] = "Wheel", |
668 | [REL_MISC] = "Misc", | 668 | [REL_MISC] = "Misc", |
669 | }; | 669 | }; |
670 | 670 | ||
671 | static char *absolutes[ABS_MAX + 1] = { | 671 | static char *absolutes[ABS_MAX + 1] = { |
@@ -690,9 +690,9 @@ static char *misc[MSC_MAX + 1] = { | |||
690 | }; | 690 | }; |
691 | 691 | ||
692 | static char *leds[LED_MAX + 1] = { | 692 | static char *leds[LED_MAX + 1] = { |
693 | [LED_NUML] = "NumLock", [LED_CAPSL] = "CapsLock", | 693 | [LED_NUML] = "NumLock", [LED_CAPSL] = "CapsLock", |
694 | [LED_SCROLLL] = "ScrollLock", [LED_COMPOSE] = "Compose", | 694 | [LED_SCROLLL] = "ScrollLock", [LED_COMPOSE] = "Compose", |
695 | [LED_KANA] = "Kana", [LED_SLEEP] = "Sleep", | 695 | [LED_KANA] = "Kana", [LED_SLEEP] = "Sleep", |
696 | [LED_SUSPEND] = "Suspend", [LED_MUTE] = "Mute", | 696 | [LED_SUSPEND] = "Suspend", [LED_MUTE] = "Mute", |
697 | [LED_MISC] = "Misc", | 697 | [LED_MISC] = "Misc", |
698 | }; | 698 | }; |
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 5553c3553e9d..9ac1e9095334 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c | |||
@@ -164,7 +164,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
164 | case HID_GD_X: case HID_GD_Y: case HID_GD_Z: | 164 | case HID_GD_X: case HID_GD_Y: case HID_GD_Z: |
165 | case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ: | 165 | case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ: |
166 | case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL: | 166 | case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL: |
167 | if (field->flags & HID_MAIN_ITEM_RELATIVE) | 167 | if (field->flags & HID_MAIN_ITEM_RELATIVE) |
168 | map_rel(usage->hid & 0xf); | 168 | map_rel(usage->hid & 0xf); |
169 | else | 169 | else |
170 | map_abs(usage->hid & 0xf); | 170 | map_abs(usage->hid & 0xf); |
@@ -297,7 +297,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
297 | case HID_UP_MSVENDOR: | 297 | case HID_UP_MSVENDOR: |
298 | 298 | ||
299 | goto ignore; | 299 | goto ignore; |
300 | 300 | ||
301 | case HID_UP_PID: | 301 | case HID_UP_PID: |
302 | 302 | ||
303 | set_bit(EV_FF, input->evbit); | 303 | set_bit(EV_FF, input->evbit); |
@@ -349,7 +349,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
349 | goto ignore; | 349 | goto ignore; |
350 | 350 | ||
351 | if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) && | 351 | if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) && |
352 | (usage->type == EV_REL) && (usage->code == REL_WHEEL)) | 352 | (usage->type == EV_REL) && (usage->code == REL_WHEEL)) |
353 | set_bit(REL_HWHEEL, bit); | 353 | set_bit(REL_HWHEEL, bit); |
354 | 354 | ||
355 | if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) | 355 | if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) |
@@ -365,11 +365,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
365 | a = field->logical_minimum = 0; | 365 | a = field->logical_minimum = 0; |
366 | b = field->logical_maximum = 255; | 366 | b = field->logical_maximum = 255; |
367 | } | 367 | } |
368 | 368 | ||
369 | if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK) | 369 | if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK) |
370 | input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4); | 370 | input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4); |
371 | else input_set_abs_params(input, usage->code, a, b, 0, 0); | 371 | else input_set_abs_params(input, usage->code, a, b, 0, 0); |
372 | 372 | ||
373 | } | 373 | } |
374 | 374 | ||
375 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { | 375 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { |
@@ -420,7 +420,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
420 | return; | 420 | return; |
421 | } | 421 | } |
422 | 422 | ||
423 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { | 423 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { |
424 | int hat_dir = usage->hat_dir; | 424 | int hat_dir = usage->hat_dir; |
425 | if (!hat_dir) | 425 | if (!hat_dir) |
426 | hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1; | 426 | hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1; |
@@ -551,7 +551,7 @@ int hidinput_connect(struct hid_device *hid) | |||
551 | for (i = 0; i < hid->maxcollection; i++) | 551 | for (i = 0; i < hid->maxcollection; i++) |
552 | if (hid->collection[i].type == HID_COLLECTION_APPLICATION || | 552 | if (hid->collection[i].type == HID_COLLECTION_APPLICATION || |
553 | hid->collection[i].type == HID_COLLECTION_PHYSICAL) | 553 | hid->collection[i].type == HID_COLLECTION_PHYSICAL) |
554 | if (IS_INPUT_APPLICATION(hid->collection[i].usage)) | 554 | if (IS_INPUT_APPLICATION(hid->collection[i].usage)) |
555 | break; | 555 | break; |
556 | 556 | ||
557 | if (i == hid->maxcollection) | 557 | if (i == hid->maxcollection) |
@@ -592,7 +592,7 @@ int hidinput_connect(struct hid_device *hid) | |||
592 | for (j = 0; j < report->field[i]->maxusage; j++) | 592 | for (j = 0; j < report->field[i]->maxusage; j++) |
593 | hidinput_configure_usage(hidinput, report->field[i], | 593 | hidinput_configure_usage(hidinput, report->field[i], |
594 | report->field[i]->usage + j); | 594 | report->field[i]->usage + j); |
595 | 595 | ||
596 | if (hid->quirks & HID_QUIRK_MULTI_INPUT) { | 596 | if (hid->quirks & HID_QUIRK_MULTI_INPUT) { |
597 | /* This will leave hidinput NULL, so that it | 597 | /* This will leave hidinput NULL, so that it |
598 | * allocates another one if we have more inputs on | 598 | * allocates another one if we have more inputs on |
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c index 0d7404bab92f..0c4c77aa31ea 100644 --- a/drivers/usb/input/hid-lgff.c +++ b/drivers/usb/input/hid-lgff.c | |||
@@ -94,7 +94,7 @@ struct lgff_device { | |||
94 | isn't really necessary */ | 94 | isn't really necessary */ |
95 | 95 | ||
96 | unsigned long flags[1]; /* Contains various information about the | 96 | unsigned long flags[1]; /* Contains various information about the |
97 | state of the driver for this device */ | 97 | state of the driver for this device */ |
98 | 98 | ||
99 | struct timer_list timer; | 99 | struct timer_list timer; |
100 | }; | 100 | }; |
@@ -234,7 +234,7 @@ static struct hid_report* hid_lgff_duplicate_report(struct hid_report* report) | |||
234 | kfree(ret); | 234 | kfree(ret); |
235 | return NULL; | 235 | return NULL; |
236 | } | 236 | } |
237 | memset(ret->field[0]->value, 0, sizeof(s32[8])); | 237 | memset(ret->field[0]->value, 0, sizeof(s32[8])); |
238 | 238 | ||
239 | return ret; | 239 | return ret; |
240 | } | 240 | } |
@@ -295,11 +295,11 @@ static int hid_lgff_event(struct hid_device *hid, struct input_dev* input, | |||
295 | unsigned long flags; | 295 | unsigned long flags; |
296 | 296 | ||
297 | if (type != EV_FF) return -EINVAL; | 297 | if (type != EV_FF) return -EINVAL; |
298 | if (!LGFF_CHECK_OWNERSHIP(code, lgff)) return -EACCES; | 298 | if (!LGFF_CHECK_OWNERSHIP(code, lgff)) return -EACCES; |
299 | if (value < 0) return -EINVAL; | 299 | if (value < 0) return -EINVAL; |
300 | 300 | ||
301 | spin_lock_irqsave(&lgff->lock, flags); | 301 | spin_lock_irqsave(&lgff->lock, flags); |
302 | 302 | ||
303 | if (value > 0) { | 303 | if (value > 0) { |
304 | if (test_bit(EFFECT_STARTED, effect->flags)) { | 304 | if (test_bit(EFFECT_STARTED, effect->flags)) { |
305 | spin_unlock_irqrestore(&lgff->lock, flags); | 305 | spin_unlock_irqrestore(&lgff->lock, flags); |
@@ -345,7 +345,7 @@ static int hid_lgff_flush(struct input_dev *dev, struct file *file) | |||
345 | and perform ioctls on the same fd all at the same time */ | 345 | and perform ioctls on the same fd all at the same time */ |
346 | if ( current->pid == lgff->effects[i].owner | 346 | if ( current->pid == lgff->effects[i].owner |
347 | && test_bit(EFFECT_USED, lgff->effects[i].flags)) { | 347 | && test_bit(EFFECT_USED, lgff->effects[i].flags)) { |
348 | 348 | ||
349 | if (hid_lgff_erase(dev, i)) | 349 | if (hid_lgff_erase(dev, i)) |
350 | warn("erase effect %d failed", i); | 350 | warn("erase effect %d failed", i); |
351 | } | 351 | } |
@@ -378,7 +378,7 @@ static int hid_lgff_upload_effect(struct input_dev* input, | |||
378 | struct lgff_effect new; | 378 | struct lgff_effect new; |
379 | int id; | 379 | int id; |
380 | unsigned long flags; | 380 | unsigned long flags; |
381 | 381 | ||
382 | dbg("ioctl rumble"); | 382 | dbg("ioctl rumble"); |
383 | 383 | ||
384 | if (!test_bit(effect->type, input->ffbit)) return -EINVAL; | 384 | if (!test_bit(effect->type, input->ffbit)) return -EINVAL; |
@@ -441,7 +441,7 @@ static void hid_lgff_timer(unsigned long timer_data) | |||
441 | 441 | ||
442 | spin_lock_irqsave(&lgff->lock, flags); | 442 | spin_lock_irqsave(&lgff->lock, flags); |
443 | 443 | ||
444 | for (i=0; i<LGFF_EFFECTS; ++i) { | 444 | for (i=0; i<LGFF_EFFECTS; ++i) { |
445 | struct lgff_effect* effect = lgff->effects +i; | 445 | struct lgff_effect* effect = lgff->effects +i; |
446 | 446 | ||
447 | if (test_bit(EFFECT_PLAYING, effect->flags)) { | 447 | if (test_bit(EFFECT_PLAYING, effect->flags)) { |
@@ -491,7 +491,7 @@ static void hid_lgff_timer(unsigned long timer_data) | |||
491 | set_bit(EFFECT_PLAYING, lgff->effects[i].flags); | 491 | set_bit(EFFECT_PLAYING, lgff->effects[i].flags); |
492 | } | 492 | } |
493 | } | 493 | } |
494 | } | 494 | } |
495 | 495 | ||
496 | #define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff | 496 | #define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff |
497 | 497 | ||
@@ -524,5 +524,5 @@ static void hid_lgff_timer(unsigned long timer_data) | |||
524 | add_timer(&lgff->timer); | 524 | add_timer(&lgff->timer); |
525 | } | 525 | } |
526 | 526 | ||
527 | spin_unlock_irqrestore(&lgff->lock, flags); | 527 | spin_unlock_irqrestore(&lgff->lock, flags); |
528 | } | 528 | } |
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h index 6d9329c698d9..c1b6b69bc4a4 100644 --- a/drivers/usb/input/hid.h +++ b/drivers/usb/input/hid.h | |||
@@ -118,7 +118,7 @@ struct hid_item { | |||
118 | #define HID_MAIN_ITEM_CONSTANT 0x001 | 118 | #define HID_MAIN_ITEM_CONSTANT 0x001 |
119 | #define HID_MAIN_ITEM_VARIABLE 0x002 | 119 | #define HID_MAIN_ITEM_VARIABLE 0x002 |
120 | #define HID_MAIN_ITEM_RELATIVE 0x004 | 120 | #define HID_MAIN_ITEM_RELATIVE 0x004 |
121 | #define HID_MAIN_ITEM_WRAP 0x008 | 121 | #define HID_MAIN_ITEM_WRAP 0x008 |
122 | #define HID_MAIN_ITEM_NONLINEAR 0x010 | 122 | #define HID_MAIN_ITEM_NONLINEAR 0x010 |
123 | #define HID_MAIN_ITEM_NO_PREFERRED 0x020 | 123 | #define HID_MAIN_ITEM_NO_PREFERRED 0x020 |
124 | #define HID_MAIN_ITEM_NULL_STATE 0x040 | 124 | #define HID_MAIN_ITEM_NULL_STATE 0x040 |
@@ -172,14 +172,14 @@ struct hid_item { | |||
172 | #define HID_USAGE_PAGE 0xffff0000 | 172 | #define HID_USAGE_PAGE 0xffff0000 |
173 | 173 | ||
174 | #define HID_UP_UNDEFINED 0x00000000 | 174 | #define HID_UP_UNDEFINED 0x00000000 |
175 | #define HID_UP_GENDESK 0x00010000 | 175 | #define HID_UP_GENDESK 0x00010000 |
176 | #define HID_UP_KEYBOARD 0x00070000 | 176 | #define HID_UP_KEYBOARD 0x00070000 |
177 | #define HID_UP_LED 0x00080000 | 177 | #define HID_UP_LED 0x00080000 |
178 | #define HID_UP_BUTTON 0x00090000 | 178 | #define HID_UP_BUTTON 0x00090000 |
179 | #define HID_UP_ORDINAL 0x000a0000 | 179 | #define HID_UP_ORDINAL 0x000a0000 |
180 | #define HID_UP_CONSUMER 0x000c0000 | 180 | #define HID_UP_CONSUMER 0x000c0000 |
181 | #define HID_UP_DIGITIZER 0x000d0000 | 181 | #define HID_UP_DIGITIZER 0x000d0000 |
182 | #define HID_UP_PID 0x000f0000 | 182 | #define HID_UP_PID 0x000f0000 |
183 | #define HID_UP_HPVENDOR 0xff7f0000 | 183 | #define HID_UP_HPVENDOR 0xff7f0000 |
184 | #define HID_UP_MSVENDOR 0xff000000 | 184 | #define HID_UP_MSVENDOR 0xff000000 |
185 | 185 | ||
@@ -406,7 +406,7 @@ struct hid_device { /* device report descriptor */ | |||
406 | dma_addr_t outbuf_dma; /* Output buffer dma */ | 406 | dma_addr_t outbuf_dma; /* Output buffer dma */ |
407 | spinlock_t outlock; /* Output fifo spinlock */ | 407 | spinlock_t outlock; /* Output fifo spinlock */ |
408 | 408 | ||
409 | unsigned claimed; /* Claimed by hidinput, hiddev? */ | 409 | unsigned claimed; /* Claimed by hidinput, hiddev? */ |
410 | unsigned quirks; /* Various quirks the device can pull on us */ | 410 | unsigned quirks; /* Various quirks the device can pull on us */ |
411 | 411 | ||
412 | struct list_head inputs; /* The list of inputs */ | 412 | struct list_head inputs; /* The list of inputs */ |
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 96b7c9067951..4c13331b5f41 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c | |||
@@ -95,7 +95,7 @@ hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo) | |||
95 | return NULL; | 95 | return NULL; |
96 | rinfo->report_id = ((struct hid_report *) list)->id; | 96 | rinfo->report_id = ((struct hid_report *) list)->id; |
97 | break; | 97 | break; |
98 | 98 | ||
99 | case HID_REPORT_ID_NEXT: | 99 | case HID_REPORT_ID_NEXT: |
100 | list = (struct list_head *) | 100 | list = (struct list_head *) |
101 | report_enum->report_id_hash[rinfo->report_id & HID_REPORT_ID_MASK]; | 101 | report_enum->report_id_hash[rinfo->report_id & HID_REPORT_ID_MASK]; |
@@ -106,7 +106,7 @@ hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo) | |||
106 | return NULL; | 106 | return NULL; |
107 | rinfo->report_id = ((struct hid_report *) list)->id; | 107 | rinfo->report_id = ((struct hid_report *) list)->id; |
108 | break; | 108 | break; |
109 | 109 | ||
110 | default: | 110 | default: |
111 | return NULL; | 111 | return NULL; |
112 | } | 112 | } |
@@ -158,7 +158,7 @@ static void hiddev_send_event(struct hid_device *hid, | |||
158 | if (uref->field_index != HID_FIELD_INDEX_NONE || | 158 | if (uref->field_index != HID_FIELD_INDEX_NONE || |
159 | (list->flags & HIDDEV_FLAG_REPORT) != 0) { | 159 | (list->flags & HIDDEV_FLAG_REPORT) != 0) { |
160 | list->buffer[list->head] = *uref; | 160 | list->buffer[list->head] = *uref; |
161 | list->head = (list->head + 1) & | 161 | list->head = (list->head + 1) & |
162 | (HIDDEV_BUFFER_SIZE - 1); | 162 | (HIDDEV_BUFFER_SIZE - 1); |
163 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | 163 | kill_fasync(&list->fasync, SIGIO, POLL_IN); |
164 | } | 164 | } |
@@ -179,9 +179,9 @@ void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, | |||
179 | unsigned type = field->report_type; | 179 | unsigned type = field->report_type; |
180 | struct hiddev_usage_ref uref; | 180 | struct hiddev_usage_ref uref; |
181 | 181 | ||
182 | uref.report_type = | 182 | uref.report_type = |
183 | (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : | 183 | (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : |
184 | ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : | 184 | ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : |
185 | ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0)); | 185 | ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0)); |
186 | uref.report_id = field->report->id; | 186 | uref.report_id = field->report->id; |
187 | uref.field_index = field->index; | 187 | uref.field_index = field->index; |
@@ -199,9 +199,9 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report) | |||
199 | struct hiddev_usage_ref uref; | 199 | struct hiddev_usage_ref uref; |
200 | 200 | ||
201 | memset(&uref, 0, sizeof(uref)); | 201 | memset(&uref, 0, sizeof(uref)); |
202 | uref.report_type = | 202 | uref.report_type = |
203 | (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : | 203 | (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : |
204 | ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : | 204 | ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : |
205 | ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0)); | 205 | ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0)); |
206 | uref.report_id = report->id; | 206 | uref.report_id = report->id; |
207 | uref.field_index = HID_FIELD_INDEX_NONE; | 207 | uref.field_index = HID_FIELD_INDEX_NONE; |
@@ -236,7 +236,7 @@ static int hiddev_release(struct inode * inode, struct file * file) | |||
236 | *listptr = (*listptr)->next; | 236 | *listptr = (*listptr)->next; |
237 | 237 | ||
238 | if (!--list->hiddev->open) { | 238 | if (!--list->hiddev->open) { |
239 | if (list->hiddev->exist) | 239 | if (list->hiddev->exist) |
240 | hid_close(list->hiddev->hid); | 240 | hid_close(list->hiddev->hid); |
241 | else | 241 | else |
242 | kfree(list->hiddev); | 242 | kfree(list->hiddev); |
@@ -303,7 +303,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun | |||
303 | if (list->head == list->tail) { | 303 | if (list->head == list->tail) { |
304 | add_wait_queue(&list->hiddev->wait, &wait); | 304 | add_wait_queue(&list->hiddev->wait, &wait); |
305 | set_current_state(TASK_INTERRUPTIBLE); | 305 | set_current_state(TASK_INTERRUPTIBLE); |
306 | 306 | ||
307 | while (list->head == list->tail) { | 307 | while (list->head == list->tail) { |
308 | if (file->f_flags & O_NONBLOCK) { | 308 | if (file->f_flags & O_NONBLOCK) { |
309 | retval = -EAGAIN; | 309 | retval = -EAGAIN; |
@@ -317,7 +317,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun | |||
317 | retval = -EIO; | 317 | retval = -EIO; |
318 | break; | 318 | break; |
319 | } | 319 | } |
320 | 320 | ||
321 | schedule(); | 321 | schedule(); |
322 | } | 322 | } |
323 | 323 | ||
@@ -329,7 +329,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun | |||
329 | return retval; | 329 | return retval; |
330 | 330 | ||
331 | 331 | ||
332 | while (list->head != list->tail && | 332 | while (list->head != list->tail && |
333 | retval + event_size <= count) { | 333 | retval + event_size <= count) { |
334 | if ((list->flags & HIDDEV_FLAG_UREF) == 0) { | 334 | if ((list->flags & HIDDEV_FLAG_UREF) == 0) { |
335 | if (list->buffer[list->tail].field_index != | 335 | if (list->buffer[list->tail].field_index != |
@@ -405,10 +405,10 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
405 | return -EINVAL; | 405 | return -EINVAL; |
406 | 406 | ||
407 | for (i = 0; i < hid->maxcollection; i++) | 407 | for (i = 0; i < hid->maxcollection; i++) |
408 | if (hid->collection[i].type == | 408 | if (hid->collection[i].type == |
409 | HID_COLLECTION_APPLICATION && arg-- == 0) | 409 | HID_COLLECTION_APPLICATION && arg-- == 0) |
410 | break; | 410 | break; |
411 | 411 | ||
412 | if (i == hid->maxcollection) | 412 | if (i == hid->maxcollection) |
413 | return -EINVAL; | 413 | return -EINVAL; |
414 | 414 | ||
@@ -562,7 +562,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
562 | if (!uref_multi) | 562 | if (!uref_multi) |
563 | return -ENOMEM; | 563 | return -ENOMEM; |
564 | uref = &uref_multi->uref; | 564 | uref = &uref_multi->uref; |
565 | if (copy_from_user(uref, user_arg, sizeof(*uref))) | 565 | if (copy_from_user(uref, user_arg, sizeof(*uref))) |
566 | goto fault; | 566 | goto fault; |
567 | 567 | ||
568 | rinfo.report_type = uref->report_type; | 568 | rinfo.report_type = uref->report_type; |
@@ -595,7 +595,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
595 | return -ENOMEM; | 595 | return -ENOMEM; |
596 | uref = &uref_multi->uref; | 596 | uref = &uref_multi->uref; |
597 | if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) { | 597 | if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) { |
598 | if (copy_from_user(uref_multi, user_arg, | 598 | if (copy_from_user(uref_multi, user_arg, |
599 | sizeof(*uref_multi))) | 599 | sizeof(*uref_multi))) |
600 | goto fault; | 600 | goto fault; |
601 | } else { | 601 | } else { |
@@ -603,7 +603,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
603 | goto fault; | 603 | goto fault; |
604 | } | 604 | } |
605 | 605 | ||
606 | if (cmd != HIDIOCGUSAGE && | 606 | if (cmd != HIDIOCGUSAGE && |
607 | cmd != HIDIOCGUSAGES && | 607 | cmd != HIDIOCGUSAGES && |
608 | uref->report_type == HID_REPORT_TYPE_INPUT) | 608 | uref->report_type == HID_REPORT_TYPE_INPUT) |
609 | goto inval; | 609 | goto inval; |
@@ -651,16 +651,16 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
651 | return field->usage[uref->usage_index].collection_index; | 651 | return field->usage[uref->usage_index].collection_index; |
652 | case HIDIOCGUSAGES: | 652 | case HIDIOCGUSAGES: |
653 | for (i = 0; i < uref_multi->num_values; i++) | 653 | for (i = 0; i < uref_multi->num_values; i++) |
654 | uref_multi->values[i] = | 654 | uref_multi->values[i] = |
655 | field->value[uref->usage_index + i]; | 655 | field->value[uref->usage_index + i]; |
656 | if (copy_to_user(user_arg, uref_multi, | 656 | if (copy_to_user(user_arg, uref_multi, |
657 | sizeof(*uref_multi))) | 657 | sizeof(*uref_multi))) |
658 | goto fault; | 658 | goto fault; |
659 | goto goodreturn; | 659 | goto goodreturn; |
660 | case HIDIOCSUSAGES: | 660 | case HIDIOCSUSAGES: |
661 | for (i = 0; i < uref_multi->num_values; i++) | 661 | for (i = 0; i < uref_multi->num_values; i++) |
662 | field->value[uref->usage_index + i] = | 662 | field->value[uref->usage_index + i] = |
663 | uref_multi->values[i]; | 663 | uref_multi->values[i]; |
664 | goto goodreturn; | 664 | goto goodreturn; |
665 | } | 665 | } |
666 | 666 | ||
@@ -670,7 +670,7 @@ goodreturn: | |||
670 | fault: | 670 | fault: |
671 | kfree(uref_multi); | 671 | kfree(uref_multi); |
672 | return -EFAULT; | 672 | return -EFAULT; |
673 | inval: | 673 | inval: |
674 | kfree(uref_multi); | 674 | kfree(uref_multi); |
675 | return -EINVAL; | 675 | return -EINVAL; |
676 | 676 | ||
@@ -734,7 +734,7 @@ static struct usb_class_driver hiddev_class = { | |||
734 | .name = "usb/hid/hiddev%d", | 734 | .name = "usb/hid/hiddev%d", |
735 | .fops = &hiddev_fops, | 735 | .fops = &hiddev_fops, |
736 | .mode = S_IFCHR | S_IRUGO | S_IWUSR, | 736 | .mode = S_IFCHR | S_IRUGO | S_IWUSR, |
737 | .minor_base = HIDDEV_MINOR_BASE, | 737 | .minor_base = HIDDEV_MINOR_BASE, |
738 | }; | 738 | }; |
739 | 739 | ||
740 | /* | 740 | /* |
@@ -747,7 +747,7 @@ int hiddev_connect(struct hid_device *hid) | |||
747 | int retval; | 747 | int retval; |
748 | 748 | ||
749 | for (i = 0; i < hid->maxcollection; i++) | 749 | for (i = 0; i < hid->maxcollection; i++) |
750 | if (hid->collection[i].type == | 750 | if (hid->collection[i].type == |
751 | HID_COLLECTION_APPLICATION && | 751 | HID_COLLECTION_APPLICATION && |
752 | !IS_INPUT_APPLICATION(hid->collection[i].usage)) | 752 | !IS_INPUT_APPLICATION(hid->collection[i].usage)) |
753 | break; | 753 | break; |
@@ -755,11 +755,11 @@ int hiddev_connect(struct hid_device *hid) | |||
755 | if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDDEV) == 0) | 755 | if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDDEV) == 0) |
756 | return -1; | 756 | return -1; |
757 | 757 | ||
758 | if (!(hiddev = kmalloc(sizeof(struct hiddev), GFP_KERNEL))) | 758 | if (!(hiddev = kmalloc(sizeof(struct hiddev), GFP_KERNEL))) |
759 | return -1; | 759 | return -1; |
760 | memset(hiddev, 0, sizeof(struct hiddev)); | 760 | memset(hiddev, 0, sizeof(struct hiddev)); |
761 | 761 | ||
762 | retval = usb_register_dev(hid->intf, &hiddev_class); | 762 | retval = usb_register_dev(hid->intf, &hiddev_class); |
763 | if (retval) { | 763 | if (retval) { |
764 | err("Not able to get a minor for this device."); | 764 | err("Not able to get a minor for this device."); |
765 | kfree(hiddev); | 765 | kfree(hiddev); |
@@ -768,12 +768,12 @@ int hiddev_connect(struct hid_device *hid) | |||
768 | 768 | ||
769 | init_waitqueue_head(&hiddev->wait); | 769 | init_waitqueue_head(&hiddev->wait); |
770 | 770 | ||
771 | hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; | 771 | hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; |
772 | 772 | ||
773 | hiddev->hid = hid; | 773 | hiddev->hid = hid; |
774 | hiddev->exist = 1; | 774 | hiddev->exist = 1; |
775 | 775 | ||
776 | hid->minor = hid->intf->minor; | 776 | hid->minor = hid->intf->minor; |
777 | hid->hiddev = hiddev; | 777 | hid->hiddev = hiddev; |
778 | 778 | ||
779 | return 0; | 779 | return 0; |
@@ -818,7 +818,7 @@ void hiddev_disconnect(struct hid_device *hid) | |||
818 | /* We never attach in this manner, and rely on HID to connect us. This | 818 | /* We never attach in this manner, and rely on HID to connect us. This |
819 | * is why there is no disconnect routine defined in the usb_driver either. | 819 | * is why there is no disconnect routine defined in the usb_driver either. |
820 | */ | 820 | */ |
821 | static int hiddev_usbd_probe(struct usb_interface *intf, | 821 | static int hiddev_usbd_probe(struct usb_interface *intf, |
822 | const struct usb_device_id *hiddev_info) | 822 | const struct usb_device_id *hiddev_info) |
823 | { | 823 | { |
824 | return -ENODEV; | 824 | return -ENODEV; |
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c new file mode 100644 index 000000000000..47dec6a1b344 --- /dev/null +++ b/drivers/usb/input/itmtouch.c | |||
@@ -0,0 +1,268 @@ | |||
1 | /****************************************************************************** | ||
2 | * itmtouch.c -- Driver for ITM touchscreen panel | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation; either version 2 of the | ||
7 | * License, or (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | * | ||
18 | * Based upon original work by Chris Collins <xfire-itmtouch@xware.cx>. | ||
19 | * | ||
20 | * Kudos to ITM for providing me with the datasheet for the panel, | ||
21 | * even though it was a day later than I had finished writing this | ||
22 | * driver. | ||
23 | * | ||
24 | * It has meant that I've been able to correct my interpretation of the | ||
25 | * protocol packets however. | ||
26 | * | ||
27 | * CC -- 2003/9/29 | ||
28 | * | ||
29 | * History | ||
30 | * 1.0 & 1.1 2003 (CC) vojtech@suse.cz | ||
31 | * Original version for 2.4.x kernels | ||
32 | * | ||
33 | * 1.2 02/03/2005 (HCE) hc@mivu.no | ||
34 | * Complete rewrite to support Linux 2.6.10, thanks to mtouchusb.c for hints. | ||
35 | * Unfortunately no calibration support at this time. | ||
36 | * | ||
37 | * 1.2.1 09/03/2005 (HCE) hc@mivu.no | ||
38 | * Code cleanup and adjusting syntax to start matching kernel standards | ||
39 | * | ||
40 | *****************************************************************************/ | ||
41 | |||
42 | #include <linux/config.h> | ||
43 | |||
44 | #ifdef CONFIG_USB_DEBUG | ||
45 | #define DEBUG | ||
46 | #else | ||
47 | #undef DEBUG | ||
48 | #endif | ||
49 | |||
50 | #include <linux/kernel.h> | ||
51 | #include <linux/slab.h> | ||
52 | #include <linux/input.h> | ||
53 | #include <linux/module.h> | ||
54 | #include <linux/init.h> | ||
55 | #include <linux/usb.h> | ||
56 | |||
57 | /* only an 8 byte buffer necessary for a single packet */ | ||
58 | #define ITM_BUFSIZE 8 | ||
59 | #define PATH_SIZE 64 | ||
60 | |||
61 | #define USB_VENDOR_ID_ITMINC 0x0403 | ||
62 | #define USB_PRODUCT_ID_TOUCHPANEL 0xf9e9 | ||
63 | |||
64 | #define DRIVER_AUTHOR "Hans-Christian Egtvedt <hc@mivu.no>" | ||
65 | #define DRIVER_VERSION "v1.2.1" | ||
66 | #define DRIVER_DESC "USB ITM Inc Touch Panel Driver" | ||
67 | #define DRIVER_LICENSE "GPL" | ||
68 | |||
69 | MODULE_AUTHOR( DRIVER_AUTHOR ); | ||
70 | MODULE_DESCRIPTION( DRIVER_DESC ); | ||
71 | MODULE_LICENSE( DRIVER_LICENSE ); | ||
72 | |||
73 | struct itmtouch_dev { | ||
74 | struct usb_device *usbdev; /* usb device */ | ||
75 | struct input_dev inputdev; /* input device */ | ||
76 | struct urb *readurb; /* urb */ | ||
77 | char rbuf[ITM_BUFSIZE]; /* data */ | ||
78 | int users; | ||
79 | char name[128]; | ||
80 | char phys[64]; | ||
81 | }; | ||
82 | |||
83 | static struct usb_device_id itmtouch_ids [] = { | ||
84 | { USB_DEVICE(USB_VENDOR_ID_ITMINC, USB_PRODUCT_ID_TOUCHPANEL) }, | ||
85 | { } | ||
86 | }; | ||
87 | |||
88 | static void itmtouch_irq(struct urb *urb, struct pt_regs *regs) | ||
89 | { | ||
90 | struct itmtouch_dev * itmtouch = urb->context; | ||
91 | unsigned char *data = urb->transfer_buffer; | ||
92 | struct input_dev *dev = &itmtouch->inputdev; | ||
93 | int retval; | ||
94 | |||
95 | switch (urb->status) { | ||
96 | case 0: | ||
97 | /* success */ | ||
98 | break; | ||
99 | case -ETIMEDOUT: | ||
100 | /* this urb is timing out */ | ||
101 | dbg("%s - urb timed out - was the device unplugged?", | ||
102 | __FUNCTION__); | ||
103 | return; | ||
104 | case -ECONNRESET: | ||
105 | case -ENOENT: | ||
106 | case -ESHUTDOWN: | ||
107 | /* this urb is terminated, clean up */ | ||
108 | dbg("%s - urb shutting down with status: %d", | ||
109 | __FUNCTION__, urb->status); | ||
110 | return; | ||
111 | default: | ||
112 | dbg("%s - nonzero urb status received: %d", | ||
113 | __FUNCTION__, urb->status); | ||
114 | goto exit; | ||
115 | } | ||
116 | |||
117 | input_regs(dev, regs); | ||
118 | |||
119 | /* if pressure has been released, then don't report X/Y */ | ||
120 | if (data[7] & 0x20) { | ||
121 | input_report_abs(dev, ABS_X, (data[0] & 0x1F) << 7 | (data[3] & 0x7F)); | ||
122 | input_report_abs(dev, ABS_Y, (data[1] & 0x1F) << 7 | (data[4] & 0x7F)); | ||
123 | } | ||
124 | |||
125 | input_report_abs(dev, ABS_PRESSURE, (data[2] & 1) << 7 | (data[5] & 0x7F)); | ||
126 | input_report_key(dev, BTN_TOUCH, ~data[7] & 0x20); | ||
127 | input_sync(dev); | ||
128 | |||
129 | exit: | ||
130 | retval = usb_submit_urb (urb, GFP_ATOMIC); | ||
131 | if (retval) | ||
132 | printk(KERN_ERR "%s - usb_submit_urb failed with result: %d", | ||
133 | __FUNCTION__, retval); | ||
134 | } | ||
135 | |||
136 | static int itmtouch_open(struct input_dev *input) | ||
137 | { | ||
138 | struct itmtouch_dev *itmtouch = input->private; | ||
139 | |||
140 | itmtouch->readurb->dev = itmtouch->usbdev; | ||
141 | |||
142 | if (usb_submit_urb(itmtouch->readurb, GFP_KERNEL)) | ||
143 | return -EIO; | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static void itmtouch_close(struct input_dev *input) | ||
149 | { | ||
150 | struct itmtouch_dev *itmtouch = input->private; | ||
151 | |||
152 | usb_kill_urb(itmtouch->readurb); | ||
153 | } | ||
154 | |||
155 | static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
156 | { | ||
157 | struct itmtouch_dev *itmtouch; | ||
158 | struct usb_host_interface *interface; | ||
159 | struct usb_endpoint_descriptor *endpoint; | ||
160 | struct usb_device *udev = interface_to_usbdev(intf); | ||
161 | unsigned int pipe; | ||
162 | unsigned int maxp; | ||
163 | char path[PATH_SIZE]; | ||
164 | |||
165 | interface = intf->cur_altsetting; | ||
166 | endpoint = &interface->endpoint[0].desc; | ||
167 | |||
168 | if (!(itmtouch = kcalloc(1, sizeof(struct itmtouch_dev), GFP_KERNEL))) { | ||
169 | err("%s - Out of memory.", __FUNCTION__); | ||
170 | return -ENOMEM; | ||
171 | } | ||
172 | |||
173 | itmtouch->usbdev = udev; | ||
174 | |||
175 | itmtouch->inputdev.private = itmtouch; | ||
176 | itmtouch->inputdev.open = itmtouch_open; | ||
177 | itmtouch->inputdev.close = itmtouch_close; | ||
178 | |||
179 | usb_make_path(udev, path, PATH_SIZE); | ||
180 | |||
181 | itmtouch->inputdev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | ||
182 | itmtouch->inputdev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); | ||
183 | itmtouch->inputdev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | ||
184 | |||
185 | itmtouch->inputdev.name = itmtouch->name; | ||
186 | itmtouch->inputdev.phys = itmtouch->phys; | ||
187 | itmtouch->inputdev.id.bustype = BUS_USB; | ||
188 | itmtouch->inputdev.id.vendor = udev->descriptor.idVendor; | ||
189 | itmtouch->inputdev.id.product = udev->descriptor.idProduct; | ||
190 | itmtouch->inputdev.id.version = udev->descriptor.bcdDevice; | ||
191 | itmtouch->inputdev.dev = &intf->dev; | ||
192 | |||
193 | if (!strlen(itmtouch->name)) | ||
194 | sprintf(itmtouch->name, "USB ITM touchscreen"); | ||
195 | |||
196 | /* device limits */ | ||
197 | /* as specified by the ITM datasheet, X and Y are 12bit, | ||
198 | * Z (pressure) is 8 bit. However, the fields are defined up | ||
199 | * to 14 bits for future possible expansion. | ||
200 | */ | ||
201 | input_set_abs_params(&itmtouch->inputdev, ABS_X, 0, 0x0FFF, 2, 0); | ||
202 | input_set_abs_params(&itmtouch->inputdev, ABS_Y, 0, 0x0FFF, 2, 0); | ||
203 | input_set_abs_params(&itmtouch->inputdev, ABS_PRESSURE, 0, 0xFF, 2, 0); | ||
204 | |||
205 | /* initialise the URB so we can read from the transport stream */ | ||
206 | pipe = usb_rcvintpipe(itmtouch->usbdev, endpoint->bEndpointAddress); | ||
207 | maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); | ||
208 | |||
209 | if (maxp > ITM_BUFSIZE) | ||
210 | maxp = ITM_BUFSIZE; | ||
211 | |||
212 | itmtouch->readurb = usb_alloc_urb(0, GFP_KERNEL); | ||
213 | |||
214 | if (!itmtouch->readurb) { | ||
215 | dbg("%s - usb_alloc_urb failed: itmtouch->readurb", __FUNCTION__); | ||
216 | kfree(itmtouch); | ||
217 | return -ENOMEM; | ||
218 | } | ||
219 | |||
220 | usb_fill_int_urb(itmtouch->readurb, itmtouch->usbdev, pipe, itmtouch->rbuf, | ||
221 | maxp, itmtouch_irq, itmtouch, endpoint->bInterval); | ||
222 | |||
223 | input_register_device(&itmtouch->inputdev); | ||
224 | |||
225 | printk(KERN_INFO "itmtouch: %s registered on %s\n", itmtouch->name, path); | ||
226 | usb_set_intfdata(intf, itmtouch); | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static void itmtouch_disconnect(struct usb_interface *intf) | ||
232 | { | ||
233 | struct itmtouch_dev *itmtouch = usb_get_intfdata(intf); | ||
234 | |||
235 | usb_set_intfdata(intf, NULL); | ||
236 | |||
237 | if (itmtouch) { | ||
238 | input_unregister_device(&itmtouch->inputdev); | ||
239 | usb_kill_urb(itmtouch->readurb); | ||
240 | usb_free_urb(itmtouch->readurb); | ||
241 | kfree(itmtouch); | ||
242 | } | ||
243 | } | ||
244 | |||
245 | MODULE_DEVICE_TABLE(usb, itmtouch_ids); | ||
246 | |||
247 | static struct usb_driver itmtouch_driver = { | ||
248 | .owner = THIS_MODULE, | ||
249 | .name = "itmtouch", | ||
250 | .probe = itmtouch_probe, | ||
251 | .disconnect = itmtouch_disconnect, | ||
252 | .id_table = itmtouch_ids, | ||
253 | }; | ||
254 | |||
255 | static int __init itmtouch_init(void) | ||
256 | { | ||
257 | info(DRIVER_DESC " " DRIVER_VERSION); | ||
258 | info(DRIVER_AUTHOR); | ||
259 | return usb_register(&itmtouch_driver); | ||
260 | } | ||
261 | |||
262 | static void __exit itmtouch_exit(void) | ||
263 | { | ||
264 | usb_deregister(&itmtouch_driver); | ||
265 | } | ||
266 | |||
267 | module_init(itmtouch_init); | ||
268 | module_exit(itmtouch_exit); | ||
diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c index a68c5b4e7b37..d2f0f90a9bcd 100644 --- a/drivers/usb/input/kbtab.c +++ b/drivers/usb/input/kbtab.c | |||
@@ -36,7 +36,6 @@ struct kbtab { | |||
36 | struct input_dev dev; | 36 | struct input_dev dev; |
37 | struct usb_device *usbdev; | 37 | struct usb_device *usbdev; |
38 | struct urb *irq; | 38 | struct urb *irq; |
39 | int open; | ||
40 | int x, y; | 39 | int x, y; |
41 | int button; | 40 | int button; |
42 | int pressure; | 41 | int pressure; |
@@ -79,12 +78,12 @@ static void kbtab_irq(struct urb *urb, struct pt_regs *regs) | |||
79 | /*input_report_key(dev, BTN_TOUCH , data[0] & 0x01);*/ | 78 | /*input_report_key(dev, BTN_TOUCH , data[0] & 0x01);*/ |
80 | input_report_key(dev, BTN_RIGHT, data[0] & 0x02); | 79 | input_report_key(dev, BTN_RIGHT, data[0] & 0x02); |
81 | 80 | ||
82 | if( -1 == kb_pressure_click){ | 81 | if (-1 == kb_pressure_click) { |
83 | input_report_abs(dev, ABS_PRESSURE, kbtab->pressure); | 82 | input_report_abs(dev, ABS_PRESSURE, kbtab->pressure); |
84 | } else { | 83 | } else { |
85 | input_report_key(dev, BTN_LEFT, (kbtab->pressure > kb_pressure_click) ? 1 : 0); | 84 | input_report_key(dev, BTN_LEFT, (kbtab->pressure > kb_pressure_click) ? 1 : 0); |
86 | }; | 85 | }; |
87 | 86 | ||
88 | input_sync(dev); | 87 | input_sync(dev); |
89 | 88 | ||
90 | exit: | 89 | exit: |
@@ -105,14 +104,9 @@ static int kbtab_open(struct input_dev *dev) | |||
105 | { | 104 | { |
106 | struct kbtab *kbtab = dev->private; | 105 | struct kbtab *kbtab = dev->private; |
107 | 106 | ||
108 | if (kbtab->open++) | ||
109 | return 0; | ||
110 | |||
111 | kbtab->irq->dev = kbtab->usbdev; | 107 | kbtab->irq->dev = kbtab->usbdev; |
112 | if (usb_submit_urb(kbtab->irq, GFP_KERNEL)) { | 108 | if (usb_submit_urb(kbtab->irq, GFP_KERNEL)) |
113 | kbtab->open--; | ||
114 | return -EIO; | 109 | return -EIO; |
115 | } | ||
116 | 110 | ||
117 | return 0; | 111 | return 0; |
118 | } | 112 | } |
@@ -121,8 +115,7 @@ static void kbtab_close(struct input_dev *dev) | |||
121 | { | 115 | { |
122 | struct kbtab *kbtab = dev->private; | 116 | struct kbtab *kbtab = dev->private; |
123 | 117 | ||
124 | if (!--kbtab->open) | 118 | usb_kill_urb(kbtab->irq); |
125 | usb_kill_urb(kbtab->irq); | ||
126 | } | 119 | } |
127 | 120 | ||
128 | static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *id) | 121 | static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *id) |
@@ -161,7 +154,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
161 | kbtab->dev.absmax[ABS_X] = 0x2000; | 154 | kbtab->dev.absmax[ABS_X] = 0x2000; |
162 | kbtab->dev.absmax[ABS_Y] = 0x1750; | 155 | kbtab->dev.absmax[ABS_Y] = 0x1750; |
163 | kbtab->dev.absmax[ABS_PRESSURE] = 0xff; | 156 | kbtab->dev.absmax[ABS_PRESSURE] = 0xff; |
164 | 157 | ||
165 | kbtab->dev.absfuzz[ABS_X] = 4; | 158 | kbtab->dev.absfuzz[ABS_X] = 4; |
166 | kbtab->dev.absfuzz[ABS_Y] = 4; | 159 | kbtab->dev.absfuzz[ABS_Y] = 4; |
167 | 160 | ||
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c index ab1a2a30ce7c..09b5cc7c66de 100644 --- a/drivers/usb/input/mtouchusb.c +++ b/drivers/usb/input/mtouchusb.c | |||
@@ -42,9 +42,9 @@ | |||
42 | #include <linux/config.h> | 42 | #include <linux/config.h> |
43 | 43 | ||
44 | #ifdef CONFIG_USB_DEBUG | 44 | #ifdef CONFIG_USB_DEBUG |
45 | #define DEBUG | 45 | #define DEBUG |
46 | #else | 46 | #else |
47 | #undef DEBUG | 47 | #undef DEBUG |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | #include <linux/kernel.h> | 50 | #include <linux/kernel.h> |
@@ -93,275 +93,255 @@ module_param(raw_coordinates, bool, S_IRUGO | S_IWUSR); | |||
93 | MODULE_PARM_DESC(raw_coordinates, "report raw coordinate values (y, default) or hardware-calibrated coordinate values (n)"); | 93 | MODULE_PARM_DESC(raw_coordinates, "report raw coordinate values (y, default) or hardware-calibrated coordinate values (n)"); |
94 | 94 | ||
95 | struct mtouch_usb { | 95 | struct mtouch_usb { |
96 | unsigned char *data; | 96 | unsigned char *data; |
97 | dma_addr_t data_dma; | 97 | dma_addr_t data_dma; |
98 | struct urb *irq; | 98 | struct urb *irq; |
99 | struct usb_device *udev; | 99 | struct usb_device *udev; |
100 | struct input_dev input; | 100 | struct input_dev input; |
101 | int open; | 101 | char name[128]; |
102 | char name[128]; | 102 | char phys[64]; |
103 | char phys[64]; | ||
104 | }; | 103 | }; |
105 | 104 | ||
106 | static struct usb_device_id mtouchusb_devices [] = { | 105 | static struct usb_device_id mtouchusb_devices[] = { |
107 | { USB_DEVICE(0x0596, 0x0001) }, | 106 | { USB_DEVICE(0x0596, 0x0001) }, |
108 | { } | 107 | { } |
109 | }; | 108 | }; |
110 | 109 | ||
111 | static void mtouchusb_irq(struct urb *urb, struct pt_regs *regs) | 110 | static void mtouchusb_irq(struct urb *urb, struct pt_regs *regs) |
112 | { | 111 | { |
113 | struct mtouch_usb *mtouch = urb->context; | 112 | struct mtouch_usb *mtouch = urb->context; |
114 | int retval; | 113 | int retval; |
115 | 114 | ||
116 | switch (urb->status) { | 115 | switch (urb->status) { |
117 | case 0: | 116 | case 0: |
118 | /* success */ | 117 | /* success */ |
119 | break; | 118 | break; |
120 | case -ETIMEDOUT: | 119 | case -ETIMEDOUT: |
121 | /* this urb is timing out */ | 120 | /* this urb is timing out */ |
122 | dbg("%s - urb timed out - was the device unplugged?", | 121 | dbg("%s - urb timed out - was the device unplugged?", |
123 | __FUNCTION__); | 122 | __FUNCTION__); |
124 | return; | 123 | return; |
125 | case -ECONNRESET: | 124 | case -ECONNRESET: |
126 | case -ENOENT: | 125 | case -ENOENT: |
127 | case -ESHUTDOWN: | 126 | case -ESHUTDOWN: |
128 | /* this urb is terminated, clean up */ | 127 | /* this urb is terminated, clean up */ |
129 | dbg("%s - urb shutting down with status: %d", | 128 | dbg("%s - urb shutting down with status: %d", |
130 | __FUNCTION__, urb->status); | 129 | __FUNCTION__, urb->status); |
131 | return; | 130 | return; |
132 | default: | 131 | default: |
133 | dbg("%s - nonzero urb status received: %d", | 132 | dbg("%s - nonzero urb status received: %d", |
134 | __FUNCTION__, urb->status); | 133 | __FUNCTION__, urb->status); |
135 | goto exit; | 134 | goto exit; |
136 | } | 135 | } |
137 | 136 | ||
138 | input_regs(&mtouch->input, regs); | 137 | input_regs(&mtouch->input, regs); |
139 | input_report_key(&mtouch->input, BTN_TOUCH, | 138 | input_report_key(&mtouch->input, BTN_TOUCH, |
140 | MTOUCHUSB_GET_TOUCHED(mtouch->data)); | 139 | MTOUCHUSB_GET_TOUCHED(mtouch->data)); |
141 | input_report_abs(&mtouch->input, ABS_X, | 140 | input_report_abs(&mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data)); |
142 | MTOUCHUSB_GET_XC(mtouch->data)); | 141 | input_report_abs(&mtouch->input, ABS_Y, |
143 | input_report_abs(&mtouch->input, ABS_Y, | ||
144 | (raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC) | 142 | (raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC) |
145 | - MTOUCHUSB_GET_YC(mtouch->data)); | 143 | - MTOUCHUSB_GET_YC(mtouch->data)); |
146 | input_sync(&mtouch->input); | 144 | input_sync(&mtouch->input); |
147 | 145 | ||
148 | exit: | 146 | exit: |
149 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 147 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
150 | if (retval) | 148 | if (retval) |
151 | err ("%s - usb_submit_urb failed with result: %d", | 149 | err("%s - usb_submit_urb failed with result: %d", |
152 | __FUNCTION__, retval); | 150 | __FUNCTION__, retval); |
153 | } | 151 | } |
154 | 152 | ||
155 | static int mtouchusb_open (struct input_dev *input) | 153 | static int mtouchusb_open(struct input_dev *input) |
156 | { | 154 | { |
157 | struct mtouch_usb *mtouch = input->private; | 155 | struct mtouch_usb *mtouch = input->private; |
158 | 156 | ||
159 | if (mtouch->open++) | 157 | mtouch->irq->dev = mtouch->udev; |
160 | return 0; | ||
161 | 158 | ||
162 | mtouch->irq->dev = mtouch->udev; | 159 | if (usb_submit_urb(mtouch->irq, GFP_ATOMIC)) |
160 | return -EIO; | ||
163 | 161 | ||
164 | if (usb_submit_urb (mtouch->irq, GFP_ATOMIC)) { | 162 | return 0; |
165 | mtouch->open--; | ||
166 | return -EIO; | ||
167 | } | ||
168 | |||
169 | return 0; | ||
170 | } | 163 | } |
171 | 164 | ||
172 | static void mtouchusb_close (struct input_dev *input) | 165 | static void mtouchusb_close(struct input_dev *input) |
173 | { | 166 | { |
174 | struct mtouch_usb *mtouch = input->private; | 167 | struct mtouch_usb *mtouch = input->private; |
175 | 168 | ||
176 | if (!--mtouch->open) | 169 | usb_kill_urb(mtouch->irq); |
177 | usb_kill_urb (mtouch->irq); | ||
178 | } | 170 | } |
179 | 171 | ||
180 | static int mtouchusb_alloc_buffers(struct usb_device *udev, struct mtouch_usb *mtouch) | 172 | static int mtouchusb_alloc_buffers(struct usb_device *udev, struct mtouch_usb *mtouch) |
181 | { | 173 | { |
182 | dbg("%s - called", __FUNCTION__); | 174 | dbg("%s - called", __FUNCTION__); |
183 | 175 | ||
184 | mtouch->data = usb_buffer_alloc(udev, MTOUCHUSB_REPORT_DATA_SIZE, | 176 | mtouch->data = usb_buffer_alloc(udev, MTOUCHUSB_REPORT_DATA_SIZE, |
185 | SLAB_ATOMIC, &mtouch->data_dma); | 177 | SLAB_ATOMIC, &mtouch->data_dma); |
186 | 178 | ||
187 | if (!mtouch->data) | 179 | if (!mtouch->data) |
188 | return -1; | 180 | return -1; |
189 | 181 | ||
190 | return 0; | 182 | return 0; |
191 | } | 183 | } |
192 | 184 | ||
193 | static void mtouchusb_free_buffers(struct usb_device *udev, struct mtouch_usb *mtouch) | 185 | static void mtouchusb_free_buffers(struct usb_device *udev, struct mtouch_usb *mtouch) |
194 | { | 186 | { |
195 | dbg("%s - called", __FUNCTION__); | 187 | dbg("%s - called", __FUNCTION__); |
196 | 188 | ||
197 | if (mtouch->data) | 189 | if (mtouch->data) |
198 | usb_buffer_free(udev, MTOUCHUSB_REPORT_DATA_SIZE, | 190 | usb_buffer_free(udev, MTOUCHUSB_REPORT_DATA_SIZE, |
199 | mtouch->data, mtouch->data_dma); | 191 | mtouch->data, mtouch->data_dma); |
200 | } | 192 | } |
201 | 193 | ||
202 | static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_id *id) | 194 | static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_id *id) |
203 | { | 195 | { |
204 | struct mtouch_usb *mtouch; | 196 | struct mtouch_usb *mtouch; |
205 | struct usb_host_interface *interface; | 197 | struct usb_host_interface *interface; |
206 | struct usb_endpoint_descriptor *endpoint; | 198 | struct usb_endpoint_descriptor *endpoint; |
207 | struct usb_device *udev = interface_to_usbdev (intf); | 199 | struct usb_device *udev = interface_to_usbdev(intf); |
208 | char path[64]; | 200 | char path[64]; |
209 | int nRet; | 201 | int nRet; |
210 | 202 | ||
211 | dbg("%s - called", __FUNCTION__); | 203 | dbg("%s - called", __FUNCTION__); |
212 | 204 | ||
213 | dbg("%s - setting interface", __FUNCTION__); | 205 | dbg("%s - setting interface", __FUNCTION__); |
214 | interface = intf->cur_altsetting; | 206 | interface = intf->cur_altsetting; |
215 | 207 | ||
216 | dbg("%s - setting endpoint", __FUNCTION__); | 208 | dbg("%s - setting endpoint", __FUNCTION__); |
217 | endpoint = &interface->endpoint[0].desc; | 209 | endpoint = &interface->endpoint[0].desc; |
218 | 210 | ||
219 | if (!(mtouch = kmalloc (sizeof (struct mtouch_usb), GFP_KERNEL))) { | 211 | if (!(mtouch = kmalloc(sizeof(struct mtouch_usb), GFP_KERNEL))) { |
220 | err("%s - Out of memory.", __FUNCTION__); | 212 | err("%s - Out of memory.", __FUNCTION__); |
221 | return -ENOMEM; | 213 | return -ENOMEM; |
222 | } | 214 | } |
223 | 215 | ||
224 | memset(mtouch, 0, sizeof(struct mtouch_usb)); | 216 | memset(mtouch, 0, sizeof(struct mtouch_usb)); |
225 | mtouch->udev = udev; | 217 | mtouch->udev = udev; |
226 | 218 | ||
227 | dbg("%s - allocating buffers", __FUNCTION__); | 219 | dbg("%s - allocating buffers", __FUNCTION__); |
228 | if (mtouchusb_alloc_buffers(udev, mtouch)) { | 220 | if (mtouchusb_alloc_buffers(udev, mtouch)) { |
229 | mtouchusb_free_buffers(udev, mtouch); | 221 | mtouchusb_free_buffers(udev, mtouch); |
230 | kfree(mtouch); | 222 | kfree(mtouch); |
231 | return -ENOMEM; | 223 | return -ENOMEM; |
232 | } | 224 | } |
233 | 225 | ||
234 | mtouch->input.private = mtouch; | 226 | mtouch->input.private = mtouch; |
235 | mtouch->input.open = mtouchusb_open; | 227 | mtouch->input.open = mtouchusb_open; |
236 | mtouch->input.close = mtouchusb_close; | 228 | mtouch->input.close = mtouchusb_close; |
237 | 229 | ||
238 | usb_make_path(udev, path, 64); | 230 | usb_make_path(udev, path, 64); |
239 | sprintf(mtouch->phys, "%s/input0", path); | 231 | sprintf(mtouch->phys, "%s/input0", path); |
240 | 232 | ||
241 | mtouch->input.name = mtouch->name; | 233 | mtouch->input.name = mtouch->name; |
242 | mtouch->input.phys = mtouch->phys; | 234 | mtouch->input.phys = mtouch->phys; |
243 | mtouch->input.id.bustype = BUS_USB; | 235 | mtouch->input.id.bustype = BUS_USB; |
244 | mtouch->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor); | 236 | mtouch->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor); |
245 | mtouch->input.id.product = le16_to_cpu(udev->descriptor.idProduct); | 237 | mtouch->input.id.product = le16_to_cpu(udev->descriptor.idProduct); |
246 | mtouch->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice); | 238 | mtouch->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice); |
247 | mtouch->input.dev = &intf->dev; | 239 | mtouch->input.dev = &intf->dev; |
248 | 240 | ||
249 | mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 241 | mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
250 | mtouch->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); | 242 | mtouch->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); |
251 | mtouch->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 243 | mtouch->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
252 | 244 | ||
253 | /* Used to Scale Compensated Data and Flip Y */ | 245 | /* Used to Scale Compensated Data and Flip Y */ |
254 | mtouch->input.absmin[ABS_X] = MTOUCHUSB_MIN_XC; | 246 | mtouch->input.absmin[ABS_X] = MTOUCHUSB_MIN_XC; |
255 | mtouch->input.absmax[ABS_X] = raw_coordinates ? \ | 247 | mtouch->input.absmax[ABS_X] = raw_coordinates ? |
256 | MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC; | 248 | MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC; |
257 | mtouch->input.absfuzz[ABS_X] = MTOUCHUSB_XC_FUZZ; | 249 | mtouch->input.absfuzz[ABS_X] = MTOUCHUSB_XC_FUZZ; |
258 | mtouch->input.absflat[ABS_X] = MTOUCHUSB_XC_FLAT; | 250 | mtouch->input.absflat[ABS_X] = MTOUCHUSB_XC_FLAT; |
259 | mtouch->input.absmin[ABS_Y] = MTOUCHUSB_MIN_YC; | 251 | mtouch->input.absmin[ABS_Y] = MTOUCHUSB_MIN_YC; |
260 | mtouch->input.absmax[ABS_Y] = raw_coordinates ? \ | 252 | mtouch->input.absmax[ABS_Y] = raw_coordinates ? |
261 | MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC; | 253 | MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC; |
262 | mtouch->input.absfuzz[ABS_Y] = MTOUCHUSB_YC_FUZZ; | 254 | mtouch->input.absfuzz[ABS_Y] = MTOUCHUSB_YC_FUZZ; |
263 | mtouch->input.absflat[ABS_Y] = MTOUCHUSB_YC_FLAT; | 255 | mtouch->input.absflat[ABS_Y] = MTOUCHUSB_YC_FLAT; |
264 | 256 | ||
265 | if (udev->manufacturer) | 257 | if (udev->manufacturer) |
266 | strcat(mtouch->name, udev->manufacturer); | 258 | strcat(mtouch->name, udev->manufacturer); |
267 | if (udev->product) | 259 | if (udev->product) |
268 | sprintf(mtouch->name, "%s %s", mtouch->name, udev->product); | 260 | sprintf(mtouch->name, "%s %s", mtouch->name, udev->product); |
269 | 261 | ||
270 | if (!strlen(mtouch->name)) | 262 | if (!strlen(mtouch->name)) |
271 | sprintf(mtouch->name, "USB Touchscreen %04x:%04x", | 263 | sprintf(mtouch->name, "USB Touchscreen %04x:%04x", |
272 | mtouch->input.id.vendor, mtouch->input.id.product); | 264 | mtouch->input.id.vendor, mtouch->input.id.product); |
273 | 265 | ||
274 | nRet = usb_control_msg(mtouch->udev, | 266 | nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0), |
275 | usb_rcvctrlpipe(udev, 0), | 267 | MTOUCHUSB_RESET, |
276 | MTOUCHUSB_RESET, | 268 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
277 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 269 | 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); |
278 | 1, | 270 | dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d", |
279 | 0, | 271 | __FUNCTION__, nRet); |
280 | NULL, | 272 | |
281 | 0, | 273 | dbg("%s - usb_alloc_urb: mtouch->irq", __FUNCTION__); |
282 | USB_CTRL_SET_TIMEOUT); | 274 | mtouch->irq = usb_alloc_urb(0, GFP_KERNEL); |
283 | dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d", | 275 | if (!mtouch->irq) { |
284 | __FUNCTION__, nRet); | 276 | dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__); |
285 | 277 | mtouchusb_free_buffers(udev, mtouch); | |
286 | dbg("%s - usb_alloc_urb: mtouch->irq", __FUNCTION__); | 278 | kfree(mtouch); |
287 | mtouch->irq = usb_alloc_urb(0, GFP_KERNEL); | 279 | return -ENOMEM; |
288 | if (!mtouch->irq) { | 280 | } |
289 | dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__); | 281 | |
290 | mtouchusb_free_buffers(udev, mtouch); | 282 | dbg("%s - usb_fill_int_urb", __FUNCTION__); |
291 | kfree(mtouch); | 283 | usb_fill_int_urb(mtouch->irq, mtouch->udev, |
292 | return -ENOMEM; | 284 | usb_rcvintpipe(mtouch->udev, 0x81), |
293 | } | 285 | mtouch->data, MTOUCHUSB_REPORT_DATA_SIZE, |
294 | 286 | mtouchusb_irq, mtouch, endpoint->bInterval); | |
295 | dbg("%s - usb_fill_int_urb", __FUNCTION__); | 287 | |
296 | usb_fill_int_urb(mtouch->irq, | 288 | dbg("%s - input_register_device", __FUNCTION__); |
297 | mtouch->udev, | 289 | input_register_device(&mtouch->input); |
298 | usb_rcvintpipe(mtouch->udev, 0x81), | 290 | |
299 | mtouch->data, | 291 | nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0), |
300 | MTOUCHUSB_REPORT_DATA_SIZE, | 292 | MTOUCHUSB_ASYNC_REPORT, |
301 | mtouchusb_irq, | 293 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
302 | mtouch, | 294 | 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); |
303 | endpoint->bInterval); | 295 | dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d", |
304 | 296 | __FUNCTION__, nRet); | |
305 | dbg("%s - input_register_device", __FUNCTION__); | 297 | |
306 | input_register_device(&mtouch->input); | 298 | printk(KERN_INFO "input: %s on %s\n", mtouch->name, path); |
307 | 299 | usb_set_intfdata(intf, mtouch); | |
308 | nRet = usb_control_msg(mtouch->udev, | 300 | |
309 | usb_rcvctrlpipe(udev, 0), | 301 | return 0; |
310 | MTOUCHUSB_ASYNC_REPORT, | ||
311 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
312 | 1, | ||
313 | 1, | ||
314 | NULL, | ||
315 | 0, | ||
316 | USB_CTRL_SET_TIMEOUT); | ||
317 | dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d", | ||
318 | __FUNCTION__, nRet); | ||
319 | |||
320 | printk(KERN_INFO "input: %s on %s\n", mtouch->name, path); | ||
321 | usb_set_intfdata(intf, mtouch); | ||
322 | |||
323 | return 0; | ||
324 | } | 302 | } |
325 | 303 | ||
326 | static void mtouchusb_disconnect(struct usb_interface *intf) | 304 | static void mtouchusb_disconnect(struct usb_interface *intf) |
327 | { | 305 | { |
328 | struct mtouch_usb *mtouch = usb_get_intfdata (intf); | 306 | struct mtouch_usb *mtouch = usb_get_intfdata(intf); |
329 | 307 | ||
330 | dbg("%s - called", __FUNCTION__); | 308 | dbg("%s - called", __FUNCTION__); |
331 | usb_set_intfdata(intf, NULL); | 309 | usb_set_intfdata(intf, NULL); |
332 | if (mtouch) { | 310 | if (mtouch) { |
333 | dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__); | 311 | dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__); |
334 | usb_kill_urb(mtouch->irq); | 312 | usb_kill_urb(mtouch->irq); |
335 | input_unregister_device(&mtouch->input); | 313 | input_unregister_device(&mtouch->input); |
336 | usb_free_urb(mtouch->irq); | 314 | usb_free_urb(mtouch->irq); |
337 | mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch); | 315 | mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch); |
338 | kfree(mtouch); | 316 | kfree(mtouch); |
339 | } | 317 | } |
340 | } | 318 | } |
341 | 319 | ||
342 | MODULE_DEVICE_TABLE (usb, mtouchusb_devices); | 320 | MODULE_DEVICE_TABLE(usb, mtouchusb_devices); |
343 | 321 | ||
344 | static struct usb_driver mtouchusb_driver = { | 322 | static struct usb_driver mtouchusb_driver = { |
345 | .owner = THIS_MODULE, | 323 | .owner = THIS_MODULE, |
346 | .name = "mtouchusb", | 324 | .name = "mtouchusb", |
347 | .probe = mtouchusb_probe, | 325 | .probe = mtouchusb_probe, |
348 | .disconnect = mtouchusb_disconnect, | 326 | .disconnect = mtouchusb_disconnect, |
349 | .id_table = mtouchusb_devices, | 327 | .id_table = mtouchusb_devices, |
350 | }; | 328 | }; |
351 | 329 | ||
352 | static int __init mtouchusb_init(void) { | 330 | static int __init mtouchusb_init(void) |
353 | dbg("%s - called", __FUNCTION__); | 331 | { |
354 | return usb_register(&mtouchusb_driver); | 332 | dbg("%s - called", __FUNCTION__); |
333 | return usb_register(&mtouchusb_driver); | ||
355 | } | 334 | } |
356 | 335 | ||
357 | static void __exit mtouchusb_cleanup(void) { | 336 | static void __exit mtouchusb_cleanup(void) |
358 | dbg("%s - called", __FUNCTION__); | 337 | { |
359 | usb_deregister(&mtouchusb_driver); | 338 | dbg("%s - called", __FUNCTION__); |
339 | usb_deregister(&mtouchusb_driver); | ||
360 | } | 340 | } |
361 | 341 | ||
362 | module_init(mtouchusb_init); | 342 | module_init(mtouchusb_init); |
363 | module_exit(mtouchusb_cleanup); | 343 | module_exit(mtouchusb_cleanup); |
364 | 344 | ||
365 | MODULE_AUTHOR( DRIVER_AUTHOR ); | 345 | MODULE_AUTHOR(DRIVER_AUTHOR); |
366 | MODULE_DESCRIPTION( DRIVER_DESC ); | 346 | MODULE_DESCRIPTION(DRIVER_DESC); |
367 | MODULE_LICENSE("GPL"); | 347 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index 7fa2f9b9fb69..3975b309d55f 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * back to the host when polled by the USB controller. | 10 | * back to the host when polled by the USB controller. |
11 | * | 11 | * |
12 | * Testing with the knob I have has shown that it measures approximately 94 "clicks" | 12 | * Testing with the knob I have has shown that it measures approximately 94 "clicks" |
13 | * for one full rotation. Testing with my High Speed Rotation Actuator (ok, it was | 13 | * for one full rotation. Testing with my High Speed Rotation Actuator (ok, it was |
14 | * a variable speed cordless electric drill) has shown that the device can measure | 14 | * a variable speed cordless electric drill) has shown that the device can measure |
15 | * speeds of up to 7 clicks either clockwise or anticlockwise between pollings from | 15 | * speeds of up to 7 clicks either clockwise or anticlockwise between pollings from |
16 | * the host. If it counts more than 7 clicks before it is polled, it will wrap back | 16 | * the host. If it counts more than 7 clicks before it is polled, it will wrap back |
@@ -120,9 +120,9 @@ exit: | |||
120 | /* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */ | 120 | /* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */ |
121 | static void powermate_sync_state(struct powermate_device *pm) | 121 | static void powermate_sync_state(struct powermate_device *pm) |
122 | { | 122 | { |
123 | if (pm->requires_update == 0) | 123 | if (pm->requires_update == 0) |
124 | return; /* no updates are required */ | 124 | return; /* no updates are required */ |
125 | if (pm->config->status == -EINPROGRESS) | 125 | if (pm->config->status == -EINPROGRESS) |
126 | return; /* an update is already in progress; it'll issue this update when it completes */ | 126 | return; /* an update is already in progress; it'll issue this update when it completes */ |
127 | 127 | ||
128 | if (pm->requires_update & UPDATE_PULSE_ASLEEP){ | 128 | if (pm->requires_update & UPDATE_PULSE_ASLEEP){ |
@@ -142,7 +142,7 @@ static void powermate_sync_state(struct powermate_device *pm) | |||
142 | 2: multiply the speed | 142 | 2: multiply the speed |
143 | the argument only has an effect for operations 0 and 2, and ranges between | 143 | the argument only has an effect for operations 0 and 2, and ranges between |
144 | 1 (least effect) to 255 (maximum effect). | 144 | 1 (least effect) to 255 (maximum effect). |
145 | 145 | ||
146 | thus, several states are equivalent and are coalesced into one state. | 146 | thus, several states are equivalent and are coalesced into one state. |
147 | 147 | ||
148 | we map this onto a range from 0 to 510, with: | 148 | we map this onto a range from 0 to 510, with: |
@@ -151,7 +151,7 @@ static void powermate_sync_state(struct powermate_device *pm) | |||
151 | 256 -- 510 -- use multiple (510 = fastest). | 151 | 256 -- 510 -- use multiple (510 = fastest). |
152 | 152 | ||
153 | Only values of 'arg' quite close to 255 are particularly useful/spectacular. | 153 | Only values of 'arg' quite close to 255 are particularly useful/spectacular. |
154 | */ | 154 | */ |
155 | if (pm->pulse_speed < 255){ | 155 | if (pm->pulse_speed < 255){ |
156 | op = 0; // divide | 156 | op = 0; // divide |
157 | arg = 255 - pm->pulse_speed; | 157 | arg = 255 - pm->pulse_speed; |
@@ -199,14 +199,14 @@ static void powermate_config_complete(struct urb *urb, struct pt_regs *regs) | |||
199 | 199 | ||
200 | if (urb->status) | 200 | if (urb->status) |
201 | printk(KERN_ERR "powermate: config urb returned %d\n", urb->status); | 201 | printk(KERN_ERR "powermate: config urb returned %d\n", urb->status); |
202 | 202 | ||
203 | spin_lock_irqsave(&pm->lock, flags); | 203 | spin_lock_irqsave(&pm->lock, flags); |
204 | powermate_sync_state(pm); | 204 | powermate_sync_state(pm); |
205 | spin_unlock_irqrestore(&pm->lock, flags); | 205 | spin_unlock_irqrestore(&pm->lock, flags); |
206 | } | 206 | } |
207 | 207 | ||
208 | /* Set the LED up as described and begin the sync with the hardware if required */ | 208 | /* Set the LED up as described and begin the sync with the hardware if required */ |
209 | static void powermate_pulse_led(struct powermate_device *pm, int static_brightness, int pulse_speed, | 209 | static void powermate_pulse_led(struct powermate_device *pm, int static_brightness, int pulse_speed, |
210 | int pulse_table, int pulse_asleep, int pulse_awake) | 210 | int pulse_table, int pulse_asleep, int pulse_awake) |
211 | { | 211 | { |
212 | unsigned long flags; | 212 | unsigned long flags; |
@@ -229,7 +229,7 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne | |||
229 | /* mark state updates which are required */ | 229 | /* mark state updates which are required */ |
230 | if (static_brightness != pm->static_brightness){ | 230 | if (static_brightness != pm->static_brightness){ |
231 | pm->static_brightness = static_brightness; | 231 | pm->static_brightness = static_brightness; |
232 | pm->requires_update |= UPDATE_STATIC_BRIGHTNESS; | 232 | pm->requires_update |= UPDATE_STATIC_BRIGHTNESS; |
233 | } | 233 | } |
234 | if (pulse_asleep != pm->pulse_asleep){ | 234 | if (pulse_asleep != pm->pulse_asleep){ |
235 | pm->pulse_asleep = pulse_asleep; | 235 | pm->pulse_asleep = pulse_asleep; |
@@ -246,7 +246,7 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne | |||
246 | } | 246 | } |
247 | 247 | ||
248 | powermate_sync_state(pm); | 248 | powermate_sync_state(pm); |
249 | 249 | ||
250 | spin_unlock_irqrestore(&pm->lock, flags); | 250 | spin_unlock_irqrestore(&pm->lock, flags); |
251 | } | 251 | } |
252 | 252 | ||
@@ -257,19 +257,19 @@ static int powermate_input_event(struct input_dev *dev, unsigned int type, unsig | |||
257 | struct powermate_device *pm = dev->private; | 257 | struct powermate_device *pm = dev->private; |
258 | 258 | ||
259 | if (type == EV_MSC && code == MSC_PULSELED){ | 259 | if (type == EV_MSC && code == MSC_PULSELED){ |
260 | /* | 260 | /* |
261 | bits 0- 7: 8 bits: LED brightness | 261 | bits 0- 7: 8 bits: LED brightness |
262 | bits 8-16: 9 bits: pulsing speed modifier (0 ... 510); 0-254 = slower, 255 = standard, 256-510 = faster. | 262 | bits 8-16: 9 bits: pulsing speed modifier (0 ... 510); 0-254 = slower, 255 = standard, 256-510 = faster. |
263 | bits 17-18: 2 bits: pulse table (0, 1, 2 valid) | 263 | bits 17-18: 2 bits: pulse table (0, 1, 2 valid) |
264 | bit 19: 1 bit : pulse whilst asleep? | 264 | bit 19: 1 bit : pulse whilst asleep? |
265 | bit 20: 1 bit : pulse constantly? | 265 | bit 20: 1 bit : pulse constantly? |
266 | */ | 266 | */ |
267 | int static_brightness = command & 0xFF; // bits 0-7 | 267 | int static_brightness = command & 0xFF; // bits 0-7 |
268 | int pulse_speed = (command >> 8) & 0x1FF; // bits 8-16 | 268 | int pulse_speed = (command >> 8) & 0x1FF; // bits 8-16 |
269 | int pulse_table = (command >> 17) & 0x3; // bits 17-18 | 269 | int pulse_table = (command >> 17) & 0x3; // bits 17-18 |
270 | int pulse_asleep = (command >> 19) & 0x1; // bit 19 | 270 | int pulse_asleep = (command >> 19) & 0x1; // bit 19 |
271 | int pulse_awake = (command >> 20) & 0x1; // bit 20 | 271 | int pulse_awake = (command >> 20) & 0x1; // bit 20 |
272 | 272 | ||
273 | powermate_pulse_led(pm, static_brightness, pulse_speed, pulse_table, pulse_asleep, pulse_awake); | 273 | powermate_pulse_led(pm, static_brightness, pulse_speed, pulse_table, pulse_asleep, pulse_awake); |
274 | } | 274 | } |
275 | 275 | ||
@@ -378,7 +378,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i | |||
378 | switch (le16_to_cpu(udev->descriptor.idProduct)) { | 378 | switch (le16_to_cpu(udev->descriptor.idProduct)) { |
379 | case POWERMATE_PRODUCT_NEW: pm->input.name = pm_name_powermate; break; | 379 | case POWERMATE_PRODUCT_NEW: pm->input.name = pm_name_powermate; break; |
380 | case POWERMATE_PRODUCT_OLD: pm->input.name = pm_name_soundknob; break; | 380 | case POWERMATE_PRODUCT_OLD: pm->input.name = pm_name_soundknob; break; |
381 | default: | 381 | default: |
382 | pm->input.name = pm_name_soundknob; | 382 | pm->input.name = pm_name_soundknob; |
383 | printk(KERN_WARNING "powermate: unknown product id %04x\n", | 383 | printk(KERN_WARNING "powermate: unknown product id %04x\n", |
384 | le16_to_cpu(udev->descriptor.idProduct)); | 384 | le16_to_cpu(udev->descriptor.idProduct)); |
@@ -402,11 +402,11 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i | |||
402 | usb_make_path(udev, path, 64); | 402 | usb_make_path(udev, path, 64); |
403 | snprintf(pm->phys, 64, "%s/input0", path); | 403 | snprintf(pm->phys, 64, "%s/input0", path); |
404 | printk(KERN_INFO "input: %s on %s\n", pm->input.name, pm->input.phys); | 404 | printk(KERN_INFO "input: %s on %s\n", pm->input.name, pm->input.phys); |
405 | 405 | ||
406 | /* force an update of everything */ | 406 | /* force an update of everything */ |
407 | pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS; | 407 | pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS; |
408 | powermate_pulse_led(pm, 0x80, 255, 0, 1, 0); // set default pulse parameters | 408 | powermate_pulse_led(pm, 0x80, 255, 0, 1, 0); // set default pulse parameters |
409 | 409 | ||
410 | usb_set_intfdata(intf, pm); | 410 | usb_set_intfdata(intf, pm); |
411 | return 0; | 411 | return 0; |
412 | } | 412 | } |
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c index a71f1bbd0a17..386595ee21c0 100644 --- a/drivers/usb/input/touchkitusb.c +++ b/drivers/usb/input/touchkitusb.c | |||
@@ -69,7 +69,6 @@ struct touchkit_usb { | |||
69 | struct urb *irq; | 69 | struct urb *irq; |
70 | struct usb_device *udev; | 70 | struct usb_device *udev; |
71 | struct input_dev input; | 71 | struct input_dev input; |
72 | int open; | ||
73 | char name[128]; | 72 | char name[128]; |
74 | char phys[64]; | 73 | char phys[64]; |
75 | }; | 74 | }; |
@@ -134,15 +133,10 @@ static int touchkit_open(struct input_dev *input) | |||
134 | { | 133 | { |
135 | struct touchkit_usb *touchkit = input->private; | 134 | struct touchkit_usb *touchkit = input->private; |
136 | 135 | ||
137 | if (touchkit->open++) | ||
138 | return 0; | ||
139 | |||
140 | touchkit->irq->dev = touchkit->udev; | 136 | touchkit->irq->dev = touchkit->udev; |
141 | 137 | ||
142 | if (usb_submit_urb(touchkit->irq, GFP_ATOMIC)) { | 138 | if (usb_submit_urb(touchkit->irq, GFP_ATOMIC)) |
143 | touchkit->open--; | ||
144 | return -EIO; | 139 | return -EIO; |
145 | } | ||
146 | 140 | ||
147 | return 0; | 141 | return 0; |
148 | } | 142 | } |
@@ -151,8 +145,7 @@ static void touchkit_close(struct input_dev *input) | |||
151 | { | 145 | { |
152 | struct touchkit_usb *touchkit = input->private; | 146 | struct touchkit_usb *touchkit = input->private; |
153 | 147 | ||
154 | if (!--touchkit->open) | 148 | usb_kill_urb(touchkit->irq); |
155 | usb_kill_urb(touchkit->irq); | ||
156 | } | 149 | } |
157 | 150 | ||
158 | static int touchkit_alloc_buffers(struct usb_device *udev, | 151 | static int touchkit_alloc_buffers(struct usb_device *udev, |
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c index 7038fb9d1ced..f35db1974c42 100644 --- a/drivers/usb/input/usbkbd.c +++ b/drivers/usb/input/usbkbd.c | |||
@@ -9,18 +9,18 @@ | |||
9 | /* | 9 | /* |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2 of the License, or | 12 | * the Free Software Foundation; either version 2 of the License, or |
13 | * (at your option) any later version. | 13 | * (at your option) any later version. |
14 | * | 14 | * |
15 | * This program is distributed in the hope that it will be useful, | 15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | * GNU General Public License for more details. | 18 | * GNU General Public License for more details. |
19 | * | 19 | * |
20 | * You should have received a copy of the GNU General Public License | 20 | * You should have received a copy of the GNU General Public License |
21 | * along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 | * | 23 | * |
24 | * Should you need to contact me, the author, you can do so either by | 24 | * Should you need to contact me, the author, you can do so either by |
25 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: | 25 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: |
26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | 26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic |
@@ -72,7 +72,6 @@ struct usb_kbd { | |||
72 | unsigned char newleds; | 72 | unsigned char newleds; |
73 | char name[128]; | 73 | char name[128]; |
74 | char phys[64]; | 74 | char phys[64]; |
75 | int open; | ||
76 | 75 | ||
77 | unsigned char *new; | 76 | unsigned char *new; |
78 | struct usb_ctrlrequest *cr; | 77 | struct usb_ctrlrequest *cr; |
@@ -166,7 +165,7 @@ static void usb_kbd_led(struct urb *urb, struct pt_regs *regs) | |||
166 | 165 | ||
167 | if (urb->status) | 166 | if (urb->status) |
168 | warn("led urb status %d received", urb->status); | 167 | warn("led urb status %d received", urb->status); |
169 | 168 | ||
170 | if (*(kbd->leds) == kbd->newleds) | 169 | if (*(kbd->leds) == kbd->newleds) |
171 | return; | 170 | return; |
172 | 171 | ||
@@ -180,14 +179,9 @@ static int usb_kbd_open(struct input_dev *dev) | |||
180 | { | 179 | { |
181 | struct usb_kbd *kbd = dev->private; | 180 | struct usb_kbd *kbd = dev->private; |
182 | 181 | ||
183 | if (kbd->open++) | ||
184 | return 0; | ||
185 | |||
186 | kbd->irq->dev = kbd->usbdev; | 182 | kbd->irq->dev = kbd->usbdev; |
187 | if (usb_submit_urb(kbd->irq, GFP_KERNEL)) { | 183 | if (usb_submit_urb(kbd->irq, GFP_KERNEL)) |
188 | kbd->open--; | ||
189 | return -EIO; | 184 | return -EIO; |
190 | } | ||
191 | 185 | ||
192 | return 0; | 186 | return 0; |
193 | } | 187 | } |
@@ -196,8 +190,7 @@ static void usb_kbd_close(struct input_dev *dev) | |||
196 | { | 190 | { |
197 | struct usb_kbd *kbd = dev->private; | 191 | struct usb_kbd *kbd = dev->private; |
198 | 192 | ||
199 | if (!--kbd->open) | 193 | usb_kill_urb(kbd->irq); |
200 | usb_kill_urb(kbd->irq); | ||
201 | } | 194 | } |
202 | 195 | ||
203 | static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd) | 196 | static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd) |
@@ -230,7 +223,7 @@ static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd) | |||
230 | usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma); | 223 | usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma); |
231 | } | 224 | } |
232 | 225 | ||
233 | static int usb_kbd_probe(struct usb_interface *iface, | 226 | static int usb_kbd_probe(struct usb_interface *iface, |
234 | const struct usb_device_id *id) | 227 | const struct usb_device_id *id) |
235 | { | 228 | { |
236 | struct usb_device * dev = interface_to_usbdev(iface); | 229 | struct usb_device * dev = interface_to_usbdev(iface); |
@@ -272,7 +265,7 @@ static int usb_kbd_probe(struct usb_interface *iface, | |||
272 | for (i = 0; i < 255; i++) | 265 | for (i = 0; i < 255; i++) |
273 | set_bit(usb_kbd_keycode[i], kbd->dev.keybit); | 266 | set_bit(usb_kbd_keycode[i], kbd->dev.keybit); |
274 | clear_bit(0, kbd->dev.keybit); | 267 | clear_bit(0, kbd->dev.keybit); |
275 | 268 | ||
276 | kbd->dev.private = kbd; | 269 | kbd->dev.private = kbd; |
277 | kbd->dev.event = usb_kbd_event; | 270 | kbd->dev.event = usb_kbd_event; |
278 | kbd->dev.open = usb_kbd_open; | 271 | kbd->dev.open = usb_kbd_open; |
@@ -294,7 +287,7 @@ static int usb_kbd_probe(struct usb_interface *iface, | |||
294 | sprintf(kbd->phys, "%s/input0", path); | 287 | sprintf(kbd->phys, "%s/input0", path); |
295 | 288 | ||
296 | kbd->dev.name = kbd->name; | 289 | kbd->dev.name = kbd->name; |
297 | kbd->dev.phys = kbd->phys; | 290 | kbd->dev.phys = kbd->phys; |
298 | kbd->dev.id.bustype = BUS_USB; | 291 | kbd->dev.id.bustype = BUS_USB; |
299 | kbd->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); | 292 | kbd->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); |
300 | kbd->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); | 293 | kbd->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); |
@@ -329,7 +322,7 @@ static int usb_kbd_probe(struct usb_interface *iface, | |||
329 | static void usb_kbd_disconnect(struct usb_interface *intf) | 322 | static void usb_kbd_disconnect(struct usb_interface *intf) |
330 | { | 323 | { |
331 | struct usb_kbd *kbd = usb_get_intfdata (intf); | 324 | struct usb_kbd *kbd = usb_get_intfdata (intf); |
332 | 325 | ||
333 | usb_set_intfdata(intf, NULL); | 326 | usb_set_intfdata(intf, NULL); |
334 | if (kbd) { | 327 | if (kbd) { |
335 | usb_kill_urb(kbd->irq); | 328 | usb_kill_urb(kbd->irq); |
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c index 01155bbddd43..1ec41b5effe6 100644 --- a/drivers/usb/input/usbmouse.c +++ b/drivers/usb/input/usbmouse.c | |||
@@ -9,18 +9,18 @@ | |||
9 | /* | 9 | /* |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2 of the License, or | 12 | * the Free Software Foundation; either version 2 of the License, or |
13 | * (at your option) any later version. | 13 | * (at your option) any later version. |
14 | * | 14 | * |
15 | * This program is distributed in the hope that it will be useful, | 15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | * GNU General Public License for more details. | 18 | * GNU General Public License for more details. |
19 | * | 19 | * |
20 | * You should have received a copy of the GNU General Public License | 20 | * You should have received a copy of the GNU General Public License |
21 | * along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 | * | 23 | * |
24 | * Should you need to contact me, the author, you can do so either by | 24 | * Should you need to contact me, the author, you can do so either by |
25 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: | 25 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: |
26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | 26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic |
@@ -51,7 +51,6 @@ struct usb_mouse { | |||
51 | struct usb_device *usbdev; | 51 | struct usb_device *usbdev; |
52 | struct input_dev dev; | 52 | struct input_dev dev; |
53 | struct urb *irq; | 53 | struct urb *irq; |
54 | int open; | ||
55 | 54 | ||
56 | signed char *data; | 55 | signed char *data; |
57 | dma_addr_t data_dma; | 56 | dma_addr_t data_dma; |
@@ -101,14 +100,9 @@ static int usb_mouse_open(struct input_dev *dev) | |||
101 | { | 100 | { |
102 | struct usb_mouse *mouse = dev->private; | 101 | struct usb_mouse *mouse = dev->private; |
103 | 102 | ||
104 | if (mouse->open++) | ||
105 | return 0; | ||
106 | |||
107 | mouse->irq->dev = mouse->usbdev; | 103 | mouse->irq->dev = mouse->usbdev; |
108 | if (usb_submit_urb(mouse->irq, GFP_KERNEL)) { | 104 | if (usb_submit_urb(mouse->irq, GFP_KERNEL)) |
109 | mouse->open--; | ||
110 | return -EIO; | 105 | return -EIO; |
111 | } | ||
112 | 106 | ||
113 | return 0; | 107 | return 0; |
114 | } | 108 | } |
@@ -117,8 +111,7 @@ static void usb_mouse_close(struct input_dev *dev) | |||
117 | { | 111 | { |
118 | struct usb_mouse *mouse = dev->private; | 112 | struct usb_mouse *mouse = dev->private; |
119 | 113 | ||
120 | if (!--mouse->open) | 114 | usb_kill_urb(mouse->irq); |
121 | usb_kill_urb(mouse->irq); | ||
122 | } | 115 | } |
123 | 116 | ||
124 | static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_id * id) | 117 | static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_id * id) |
@@ -132,19 +125,19 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_ | |||
132 | 125 | ||
133 | interface = intf->cur_altsetting; | 126 | interface = intf->cur_altsetting; |
134 | 127 | ||
135 | if (interface->desc.bNumEndpoints != 1) | 128 | if (interface->desc.bNumEndpoints != 1) |
136 | return -ENODEV; | 129 | return -ENODEV; |
137 | 130 | ||
138 | endpoint = &interface->endpoint[0].desc; | 131 | endpoint = &interface->endpoint[0].desc; |
139 | if (!(endpoint->bEndpointAddress & 0x80)) | 132 | if (!(endpoint->bEndpointAddress & 0x80)) |
140 | return -ENODEV; | 133 | return -ENODEV; |
141 | if ((endpoint->bmAttributes & 3) != 3) | 134 | if ((endpoint->bmAttributes & 3) != 3) |
142 | return -ENODEV; | 135 | return -ENODEV; |
143 | 136 | ||
144 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | 137 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); |
145 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | 138 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); |
146 | 139 | ||
147 | if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) | 140 | if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) |
148 | return -ENOMEM; | 141 | return -ENOMEM; |
149 | memset(mouse, 0, sizeof(struct usb_mouse)); | 142 | memset(mouse, 0, sizeof(struct usb_mouse)); |
150 | 143 | ||
@@ -209,7 +202,7 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_ | |||
209 | static void usb_mouse_disconnect(struct usb_interface *intf) | 202 | static void usb_mouse_disconnect(struct usb_interface *intf) |
210 | { | 203 | { |
211 | struct usb_mouse *mouse = usb_get_intfdata (intf); | 204 | struct usb_mouse *mouse = usb_get_intfdata (intf); |
212 | 205 | ||
213 | usb_set_intfdata(intf, NULL); | 206 | usb_set_intfdata(intf, NULL); |
214 | if (mouse) { | 207 | if (mouse) { |
215 | usb_kill_urb(mouse->irq); | 208 | usb_kill_urb(mouse->irq); |
@@ -238,7 +231,7 @@ static struct usb_driver usb_mouse_driver = { | |||
238 | static int __init usb_mouse_init(void) | 231 | static int __init usb_mouse_init(void) |
239 | { | 232 | { |
240 | int retval = usb_register(&usb_mouse_driver); | 233 | int retval = usb_register(&usb_mouse_driver); |
241 | if (retval == 0) | 234 | if (retval == 0) |
242 | info(DRIVER_VERSION ":" DRIVER_DESC); | 235 | info(DRIVER_VERSION ":" DRIVER_DESC); |
243 | return retval; | 236 | return retval; |
244 | } | 237 | } |
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index fec04dda088e..f6b34af66b3d 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * Copyright (c) 2000 Daniel Egger <egger@suse.de> | 9 | * Copyright (c) 2000 Daniel Egger <egger@suse.de> |
10 | * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> | 10 | * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> |
11 | * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> | 11 | * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> |
12 | * Copyright (c) 2002-2004 Ping Cheng <pingc@wacom.com> | 12 | * Copyright (c) 2002-2005 Ping Cheng <pingc@wacom.com> |
13 | * | 13 | * |
14 | * ChangeLog: | 14 | * ChangeLog: |
15 | * v0.1 (vp) - Initial release | 15 | * v0.1 (vp) - Initial release |
@@ -18,7 +18,7 @@ | |||
18 | * v0.4 (sm) - Support for more Intuos models, menustrip | 18 | * v0.4 (sm) - Support for more Intuos models, menustrip |
19 | * relative mode, proximity. | 19 | * relative mode, proximity. |
20 | * v0.5 (vp) - Big cleanup, nifty features removed, | 20 | * v0.5 (vp) - Big cleanup, nifty features removed, |
21 | * they belong in userspace | 21 | * they belong in userspace |
22 | * v1.8 (vp) - Submit URB only when operating, moved to CVS, | 22 | * v1.8 (vp) - Submit URB only when operating, moved to CVS, |
23 | * use input_report_key instead of report_btn and | 23 | * use input_report_key instead of report_btn and |
24 | * other cleanups | 24 | * other cleanups |
@@ -51,6 +51,9 @@ | |||
51 | * - Cleanups here and there | 51 | * - Cleanups here and there |
52 | * v1.30.1 (pi) - Added Graphire3 support | 52 | * v1.30.1 (pi) - Added Graphire3 support |
53 | * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... | 53 | * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... |
54 | * v1.43 (pc) - Added support for Cintiq 21UX | ||
55 | - Fixed a Graphire bug | ||
56 | - Merged wacom_intuos3_irq into wacom_intuos_irq | ||
54 | */ | 57 | */ |
55 | 58 | ||
56 | /* | 59 | /* |
@@ -72,7 +75,7 @@ | |||
72 | /* | 75 | /* |
73 | * Version Information | 76 | * Version Information |
74 | */ | 77 | */ |
75 | #define DRIVER_VERSION "v1.40" | 78 | #define DRIVER_VERSION "v1.43" |
76 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" | 79 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" |
77 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" | 80 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" |
78 | #define DRIVER_LICENSE "GPL" | 81 | #define DRIVER_LICENSE "GPL" |
@@ -83,6 +86,16 @@ MODULE_LICENSE(DRIVER_LICENSE); | |||
83 | 86 | ||
84 | #define USB_VENDOR_ID_WACOM 0x056a | 87 | #define USB_VENDOR_ID_WACOM 0x056a |
85 | 88 | ||
89 | enum { | ||
90 | PENPARTNER = 0, | ||
91 | GRAPHIRE, | ||
92 | PL, | ||
93 | INTUOS, | ||
94 | INTUOS3, | ||
95 | CINTIQ, | ||
96 | MAX_TYPE | ||
97 | }; | ||
98 | |||
86 | struct wacom_features { | 99 | struct wacom_features { |
87 | char *name; | 100 | char *name; |
88 | int pktlen; | 101 | int pktlen; |
@@ -102,7 +115,6 @@ struct wacom { | |||
102 | struct urb *irq; | 115 | struct urb *irq; |
103 | struct wacom_features *features; | 116 | struct wacom_features *features; |
104 | int tool[2]; | 117 | int tool[2]; |
105 | int open; | ||
106 | __u32 serial[2]; | 118 | __u32 serial[2]; |
107 | char phys[32]; | 119 | char phys[32]; |
108 | }; | 120 | }; |
@@ -149,7 +161,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) | |||
149 | prox = data[1] & 0x40; | 161 | prox = data[1] & 0x40; |
150 | 162 | ||
151 | input_regs(dev, regs); | 163 | input_regs(dev, regs); |
152 | 164 | ||
153 | if (prox) { | 165 | if (prox) { |
154 | 166 | ||
155 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); | 167 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); |
@@ -166,8 +178,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) | |||
166 | if (!wacom->tool[0]) { | 178 | if (!wacom->tool[0]) { |
167 | /* Going into proximity select tool */ | 179 | /* Going into proximity select tool */ |
168 | wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | 180 | wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN; |
169 | } | 181 | } else { |
170 | else { | ||
171 | /* was entered with stylus2 pressed */ | 182 | /* was entered with stylus2 pressed */ |
172 | if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) { | 183 | if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) { |
173 | /* report out proximity for previous tool */ | 184 | /* report out proximity for previous tool */ |
@@ -182,16 +193,15 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) | |||
182 | wacom->tool[1] = BTN_TOOL_PEN; | 193 | wacom->tool[1] = BTN_TOOL_PEN; |
183 | } | 194 | } |
184 | input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */ | 195 | input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */ |
185 | input_report_abs(dev, ABS_X, data[3] | ((__u32)data[2] << 7) | ((__u32)(data[1] & 0x03) << 14)); | 196 | input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); |
186 | input_report_abs(dev, ABS_Y, data[6] | ((__u32)data[5] << 7) | ((__u32)(data[4] & 0x03) << 14)); | 197 | input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); |
187 | input_report_abs(dev, ABS_PRESSURE, pressure); | 198 | input_report_abs(dev, ABS_PRESSURE, pressure); |
188 | 199 | ||
189 | input_report_key(dev, BTN_TOUCH, data[4] & 0x08); | 200 | input_report_key(dev, BTN_TOUCH, data[4] & 0x08); |
190 | input_report_key(dev, BTN_STYLUS, data[4] & 0x10); | 201 | input_report_key(dev, BTN_STYLUS, data[4] & 0x10); |
191 | /* Only allow the stylus2 button to be reported for the pen tool. */ | 202 | /* Only allow the stylus2 button to be reported for the pen tool. */ |
192 | input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20)); | 203 | input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20)); |
193 | } | 204 | } else { |
194 | else { | ||
195 | /* report proximity-out of a (valid) tool */ | 205 | /* report proximity-out of a (valid) tool */ |
196 | if (wacom->tool[1] != BTN_TOOL_RUBBER) { | 206 | if (wacom->tool[1] != BTN_TOOL_RUBBER) { |
197 | /* Unknown tool selected default to pen tool */ | 207 | /* Unknown tool selected default to pen tool */ |
@@ -203,7 +213,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) | |||
203 | wacom->tool[0] = prox; /* Save proximity state */ | 213 | wacom->tool[0] = prox; /* Save proximity state */ |
204 | input_sync(dev); | 214 | input_sync(dev); |
205 | 215 | ||
206 | exit: | 216 | exit: |
207 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 217 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
208 | if (retval) | 218 | if (retval) |
209 | err ("%s - usb_submit_urb failed with result %d", | 219 | err ("%s - usb_submit_urb failed with result %d", |
@@ -232,20 +242,16 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs) | |||
232 | goto exit; | 242 | goto exit; |
233 | } | 243 | } |
234 | 244 | ||
235 | if (data[0] != 2) | 245 | if (data[0] != 2) { |
236 | { | ||
237 | printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); | 246 | printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); |
238 | goto exit; | 247 | goto exit; |
239 | } | 248 | } |
240 | 249 | ||
241 | input_regs(dev, regs); | 250 | input_regs(dev, regs); |
242 | if (data[1] & 0x04) | 251 | if (data[1] & 0x04) { |
243 | { | ||
244 | input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20); | 252 | input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20); |
245 | input_report_key(dev, BTN_TOUCH, data[1] & 0x08); | 253 | input_report_key(dev, BTN_TOUCH, data[1] & 0x08); |
246 | } | 254 | } else { |
247 | else | ||
248 | { | ||
249 | input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20); | 255 | input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20); |
250 | input_report_key(dev, BTN_TOUCH, data[1] & 0x01); | 256 | input_report_key(dev, BTN_TOUCH, data[1] & 0x01); |
251 | } | 257 | } |
@@ -257,7 +263,7 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs) | |||
257 | 263 | ||
258 | input_sync(dev); | 264 | input_sync(dev); |
259 | 265 | ||
260 | exit: | 266 | exit: |
261 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 267 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
262 | if (retval) | 268 | if (retval) |
263 | err ("%s - usb_submit_urb failed with result %d", | 269 | err ("%s - usb_submit_urb failed with result %d", |
@@ -300,7 +306,7 @@ static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs) | |||
300 | input_report_key(dev, BTN_STYLUS, (data[5] & 0x40)); | 306 | input_report_key(dev, BTN_STYLUS, (data[5] & 0x40)); |
301 | input_sync(dev); | 307 | input_sync(dev); |
302 | 308 | ||
303 | exit: | 309 | exit: |
304 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 310 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
305 | if (retval) | 311 | if (retval) |
306 | err ("%s - usb_submit_urb failed with result %d", | 312 | err ("%s - usb_submit_urb failed with result %d", |
@@ -340,47 +346,47 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) | |||
340 | 346 | ||
341 | input_regs(dev, regs); | 347 | input_regs(dev, regs); |
342 | 348 | ||
343 | switch ((data[1] >> 5) & 3) { | 349 | if (data[1] & 0x10) { /* in prox */ |
344 | 350 | ||
345 | case 0: /* Pen */ | 351 | switch ((data[1] >> 5) & 3) { |
346 | input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x80); | ||
347 | break; | ||
348 | 352 | ||
349 | case 1: /* Rubber */ | 353 | case 0: /* Pen */ |
350 | input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x80); | 354 | wacom->tool[0] = BTN_TOOL_PEN; |
351 | break; | 355 | break; |
352 | |||
353 | case 2: /* Mouse with wheel */ | ||
354 | input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); | ||
355 | input_report_rel(dev, REL_WHEEL, (signed char) data[6]); | ||
356 | /* fall through */ | ||
357 | 356 | ||
358 | case 3: /* Mouse without wheel */ | 357 | case 1: /* Rubber */ |
359 | input_report_key(dev, BTN_TOOL_MOUSE, data[7] > 24); | 358 | wacom->tool[0] = BTN_TOOL_RUBBER; |
360 | input_report_key(dev, BTN_LEFT, data[1] & 0x01); | 359 | break; |
361 | input_report_key(dev, BTN_RIGHT, data[1] & 0x02); | ||
362 | input_report_abs(dev, ABS_DISTANCE, data[7]); | ||
363 | 360 | ||
364 | input_report_abs(dev, ABS_X, x); | 361 | case 2: /* Mouse with wheel */ |
365 | input_report_abs(dev, ABS_Y, y); | 362 | input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); |
363 | input_report_rel(dev, REL_WHEEL, (signed char) data[6]); | ||
364 | /* fall through */ | ||
366 | 365 | ||
367 | input_sync(dev); | 366 | case 3: /* Mouse without wheel */ |
368 | goto exit; | 367 | wacom->tool[0] = BTN_TOOL_MOUSE; |
368 | input_report_key(dev, BTN_LEFT, data[1] & 0x01); | ||
369 | input_report_key(dev, BTN_RIGHT, data[1] & 0x02); | ||
370 | input_report_abs(dev, ABS_DISTANCE, data[7]); | ||
371 | break; | ||
372 | } | ||
369 | } | 373 | } |
370 | 374 | ||
371 | if (data[1] & 0x80) { | 375 | if (data[1] & 0x80) { |
372 | input_report_abs(dev, ABS_X, x); | 376 | input_report_abs(dev, ABS_X, x); |
373 | input_report_abs(dev, ABS_Y, y); | 377 | input_report_abs(dev, ABS_Y, y); |
374 | } | 378 | } |
379 | if (wacom->tool[0] != BTN_TOOL_MOUSE) { | ||
380 | input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6])); | ||
381 | input_report_key(dev, BTN_TOUCH, data[1] & 0x01); | ||
382 | input_report_key(dev, BTN_STYLUS, data[1] & 0x02); | ||
383 | input_report_key(dev, BTN_STYLUS2, data[1] & 0x04); | ||
384 | } | ||
375 | 385 | ||
376 | input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6])); | 386 | input_report_key(dev, wacom->tool[0], data[1] & 0x10); |
377 | input_report_key(dev, BTN_TOUCH, data[1] & 0x01); | ||
378 | input_report_key(dev, BTN_STYLUS, data[1] & 0x02); | ||
379 | input_report_key(dev, BTN_STYLUS2, data[1] & 0x04); | ||
380 | |||
381 | input_sync(dev); | 387 | input_sync(dev); |
382 | 388 | ||
383 | exit: | 389 | exit: |
384 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 390 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
385 | if (retval) | 391 | if (retval) |
386 | err ("%s - usb_submit_urb failed with result %d", | 392 | err ("%s - usb_submit_urb failed with result %d", |
@@ -398,14 +404,13 @@ static int wacom_intuos_inout(struct urb *urb) | |||
398 | idx = data[1] & 0x01; | 404 | idx = data[1] & 0x01; |
399 | 405 | ||
400 | /* Enter report */ | 406 | /* Enter report */ |
401 | if ((data[1] & 0xfc) == 0xc0) | 407 | if ((data[1] & 0xfc) == 0xc0) { |
402 | { | ||
403 | /* serial number of the tool */ | 408 | /* serial number of the tool */ |
404 | wacom->serial[idx] = ((__u32)(data[3] & 0x0f) << 28) + | 409 | wacom->serial[idx] = ((data[3] & 0x0f) << 28) + |
405 | ((__u32)data[4] << 20) + ((__u32)data[5] << 12) + | 410 | (data[4] << 20) + (data[5] << 12) + |
406 | ((__u32)data[6] << 4) + (data[7] >> 4); | 411 | (data[6] << 4) + (data[7] >> 4); |
407 | 412 | ||
408 | switch (((__u32)data[2] << 4) | (data[3] >> 4)) { | 413 | switch ((data[2] << 4) | (data[3] >> 4)) { |
409 | case 0x812: /* Inking pen */ | 414 | case 0x812: /* Inking pen */ |
410 | case 0x801: /* Intuos3 Inking pen */ | 415 | case 0x801: /* Intuos3 Inking pen */ |
411 | case 0x012: | 416 | case 0x012: |
@@ -449,7 +454,7 @@ static int wacom_intuos_inout(struct urb *urb) | |||
449 | case 0x112: | 454 | case 0x112: |
450 | case 0x913: /* Intuos3 Airbrush */ | 455 | case 0x913: /* Intuos3 Airbrush */ |
451 | wacom->tool[idx] = BTN_TOOL_AIRBRUSH; | 456 | wacom->tool[idx] = BTN_TOOL_AIRBRUSH; |
452 | break; /* Airbrush */ | 457 | break; |
453 | default: /* Unknown tool */ | 458 | default: /* Unknown tool */ |
454 | wacom->tool[idx] = BTN_TOOL_PEN; | 459 | wacom->tool[idx] = BTN_TOOL_PEN; |
455 | } | 460 | } |
@@ -478,9 +483,8 @@ static void wacom_intuos_general(struct urb *urb) | |||
478 | unsigned int t; | 483 | unsigned int t; |
479 | 484 | ||
480 | /* general pen packet */ | 485 | /* general pen packet */ |
481 | if ((data[1] & 0xb8) == 0xa0) | 486 | if ((data[1] & 0xb8) == 0xa0) { |
482 | { | 487 | t = (data[6] << 2) | ((data[7] >> 6) & 3); |
483 | t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3); | ||
484 | input_report_abs(dev, ABS_PRESSURE, t); | 488 | input_report_abs(dev, ABS_PRESSURE, t); |
485 | input_report_abs(dev, ABS_TILT_X, | 489 | input_report_abs(dev, ABS_TILT_X, |
486 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); | 490 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); |
@@ -491,10 +495,9 @@ static void wacom_intuos_general(struct urb *urb) | |||
491 | } | 495 | } |
492 | 496 | ||
493 | /* airbrush second packet */ | 497 | /* airbrush second packet */ |
494 | if ((data[1] & 0xbc) == 0xb4) | 498 | if ((data[1] & 0xbc) == 0xb4) { |
495 | { | ||
496 | input_report_abs(dev, ABS_WHEEL, | 499 | input_report_abs(dev, ABS_WHEEL, |
497 | ((__u32)data[6] << 2) | ((data[7] >> 6) & 3)); | 500 | (data[6] << 2) | ((data[7] >> 6) & 3)); |
498 | input_report_abs(dev, ABS_TILT_X, | 501 | input_report_abs(dev, ABS_TILT_X, |
499 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); | 502 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); |
500 | input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); | 503 | input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); |
@@ -526,7 +529,7 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) | |||
526 | goto exit; | 529 | goto exit; |
527 | } | 530 | } |
528 | 531 | ||
529 | if (data[0] != 2 && data[0] != 5 && data[0] != 6) { | 532 | if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) { |
530 | dbg("wacom_intuos_irq: received unknown report #%d", data[0]); | 533 | dbg("wacom_intuos_irq: received unknown report #%d", data[0]); |
531 | goto exit; | 534 | goto exit; |
532 | } | 535 | } |
@@ -536,107 +539,10 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) | |||
536 | /* tool number */ | 539 | /* tool number */ |
537 | idx = data[1] & 0x01; | 540 | idx = data[1] & 0x01; |
538 | 541 | ||
539 | /* process in/out prox events */ | ||
540 | if (wacom_intuos_inout(urb)) goto exit; | ||
541 | |||
542 | input_report_abs(dev, ABS_X, be16_to_cpu(*(__be16 *) &data[2])); | ||
543 | input_report_abs(dev, ABS_Y, be16_to_cpu(*(__be16 *) &data[4])); | ||
544 | input_report_abs(dev, ABS_DISTANCE, data[9]); | ||
545 | |||
546 | /* process general packets */ | ||
547 | wacom_intuos_general(urb); | ||
548 | |||
549 | if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) { /* 4D mouse or Lens cursor packets */ | ||
550 | |||
551 | if (data[1] & 0x02) { /* Rotation packet */ | ||
552 | |||
553 | t = ((__u32)data[6] << 3) | ((data[7] >> 5) & 7); | ||
554 | input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ? ((t - 1) / 2) : -t / 2); | ||
555 | |||
556 | } else { | ||
557 | |||
558 | if ((data[1] & 0x10) == 0) { /* 4D mouse packets */ | ||
559 | |||
560 | input_report_key(dev, BTN_LEFT, data[8] & 0x01); | ||
561 | input_report_key(dev, BTN_MIDDLE, data[8] & 0x02); | ||
562 | input_report_key(dev, BTN_RIGHT, data[8] & 0x04); | ||
563 | |||
564 | input_report_key(dev, BTN_SIDE, data[8] & 0x20); | ||
565 | input_report_key(dev, BTN_EXTRA, data[8] & 0x10); | ||
566 | t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3); | ||
567 | input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); | ||
568 | |||
569 | } else { | ||
570 | if (wacom->tool[idx] == BTN_TOOL_MOUSE) { /* 2D mouse packets */ | ||
571 | input_report_key(dev, BTN_LEFT, data[8] & 0x04); | ||
572 | input_report_key(dev, BTN_MIDDLE, data[8] & 0x08); | ||
573 | input_report_key(dev, BTN_RIGHT, data[8] & 0x10); | ||
574 | input_report_rel(dev, REL_WHEEL, | ||
575 | (-(__u32)(data[8] & 0x01) + (__u32)((data[8] & 0x02) >> 1))); | ||
576 | } | ||
577 | else { /* Lens cursor packets */ | ||
578 | input_report_key(dev, BTN_LEFT, data[8] & 0x01); | ||
579 | input_report_key(dev, BTN_MIDDLE, data[8] & 0x02); | ||
580 | input_report_key(dev, BTN_RIGHT, data[8] & 0x04); | ||
581 | input_report_key(dev, BTN_SIDE, data[8] & 0x10); | ||
582 | input_report_key(dev, BTN_EXTRA, data[8] & 0x08); | ||
583 | } | ||
584 | } | ||
585 | } | ||
586 | } | ||
587 | |||
588 | input_report_key(dev, wacom->tool[idx], 1); | ||
589 | input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | ||
590 | input_sync(dev); | ||
591 | |||
592 | exit: | ||
593 | retval = usb_submit_urb (urb, GFP_ATOMIC); | ||
594 | if (retval) | ||
595 | err ("%s - usb_submit_urb failed with result %d", | ||
596 | __FUNCTION__, retval); | ||
597 | } | ||
598 | |||
599 | static void wacom_intuos3_irq(struct urb *urb, struct pt_regs *regs) | ||
600 | { | ||
601 | struct wacom *wacom = urb->context; | ||
602 | unsigned char *data = wacom->data; | ||
603 | struct input_dev *dev = &wacom->dev; | ||
604 | unsigned int t; | ||
605 | int idx, retval; | ||
606 | |||
607 | switch (urb->status) { | ||
608 | case 0: | ||
609 | /* success */ | ||
610 | break; | ||
611 | case -ECONNRESET: | ||
612 | case -ENOENT: | ||
613 | case -ESHUTDOWN: | ||
614 | /* this urb is terminated, clean up */ | ||
615 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); | ||
616 | return; | ||
617 | default: | ||
618 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | ||
619 | goto exit; | ||
620 | } | ||
621 | |||
622 | /* check for valid report */ | ||
623 | if (data[0] != 2 && data[0] != 5 && data[0] != 12) | ||
624 | { | ||
625 | printk(KERN_INFO "wacom_intuos3_irq: received unknown report #%d\n", data[0]); | ||
626 | goto exit; | ||
627 | } | ||
628 | |||
629 | input_regs(dev, regs); | ||
630 | |||
631 | /* tool index is always 0 here since there is no dual input tool */ | ||
632 | idx = data[1] & 0x01; | ||
633 | |||
634 | /* pad packets. Works as a second tool and is always in prox */ | 542 | /* pad packets. Works as a second tool and is always in prox */ |
635 | if (data[0] == 12) | 543 | if (data[0] == 12) { |
636 | { | ||
637 | /* initiate the pad as a device */ | 544 | /* initiate the pad as a device */ |
638 | if (wacom->tool[1] != BTN_TOOL_FINGER) | 545 | if (wacom->tool[1] != BTN_TOOL_FINGER) { |
639 | { | ||
640 | wacom->tool[1] = BTN_TOOL_FINGER; | 546 | wacom->tool[1] = BTN_TOOL_FINGER; |
641 | input_report_key(dev, wacom->tool[1], 1); | 547 | input_report_key(dev, wacom->tool[1], 1); |
642 | } | 548 | } |
@@ -656,37 +562,78 @@ static void wacom_intuos3_irq(struct urb *urb, struct pt_regs *regs) | |||
656 | } | 562 | } |
657 | 563 | ||
658 | /* process in/out prox events */ | 564 | /* process in/out prox events */ |
659 | if (wacom_intuos_inout(urb)) goto exit; | 565 | if (wacom_intuos_inout(urb)) |
566 | goto exit; | ||
660 | 567 | ||
661 | input_report_abs(dev, ABS_X, ((__u32)data[2] << 9) | ((__u32)data[3] << 1) | ((data[9] >> 1) & 1)); | 568 | /* Cintiq doesn't send data when RDY bit isn't set */ |
662 | input_report_abs(dev, ABS_Y, ((__u32)data[4] << 9) | ((__u32)data[5] << 1) | (data[9] & 1)); | 569 | if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40)) |
663 | input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); | 570 | return; |
571 | |||
572 | if (wacom->features->type >= INTUOS3) { | ||
573 | input_report_abs(dev, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); | ||
574 | input_report_abs(dev, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); | ||
575 | input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); | ||
576 | } else { | ||
577 | input_report_abs(dev, ABS_X, be16_to_cpu(*(__be16 *) &data[2])); | ||
578 | input_report_abs(dev, ABS_Y, be16_to_cpu(*(__be16 *) &data[4])); | ||
579 | input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); | ||
580 | } | ||
664 | 581 | ||
665 | /* process general packets */ | 582 | /* process general packets */ |
666 | wacom_intuos_general(urb); | 583 | wacom_intuos_general(urb); |
667 | 584 | ||
668 | if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) | 585 | /* 4D mouse, 2D mouse, marker pen rotation, or Lens cursor packets */ |
669 | { | 586 | if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) { |
670 | /* Marker pen rotation packet. Reported as wheel due to valuator limitation */ | 587 | |
671 | if (data[1] & 0x02) | 588 | if (data[1] & 0x02) { |
672 | { | 589 | /* Rotation packet */ |
673 | t = ((__u32)data[6] << 3) | ((data[7] >> 5) & 7); | 590 | if (wacom->features->type >= INTUOS3) { |
674 | t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : | 591 | /* I3 marker pen rotation reported as wheel |
675 | ((t-1) / 2 + 450)) : (450 - t / 2) ; | 592 | * due to valuator limitation |
676 | input_report_abs(dev, ABS_WHEEL, t); | 593 | */ |
677 | } | 594 | t = (data[6] << 3) | ((data[7] >> 5) & 7); |
595 | t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : | ||
596 | ((t-1) / 2 + 450)) : (450 - t / 2) ; | ||
597 | input_report_abs(dev, ABS_WHEEL, t); | ||
598 | } else { | ||
599 | /* 4D mouse rotation packet */ | ||
600 | t = (data[6] << 3) | ((data[7] >> 5) & 7); | ||
601 | input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ? | ||
602 | ((t - 1) / 2) : -t / 2); | ||
603 | } | ||
678 | 604 | ||
679 | /* 2D mouse packets */ | 605 | } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3) { |
680 | if (wacom->tool[idx] == BTN_TOOL_MOUSE) | 606 | /* 4D mouse packet */ |
681 | { | 607 | input_report_key(dev, BTN_LEFT, data[8] & 0x01); |
608 | input_report_key(dev, BTN_MIDDLE, data[8] & 0x02); | ||
609 | input_report_key(dev, BTN_RIGHT, data[8] & 0x04); | ||
610 | |||
611 | input_report_key(dev, BTN_SIDE, data[8] & 0x20); | ||
612 | input_report_key(dev, BTN_EXTRA, data[8] & 0x10); | ||
613 | t = (data[6] << 2) | ((data[7] >> 6) & 3); | ||
614 | input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); | ||
615 | |||
616 | } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { | ||
617 | /* 2D mouse packet */ | ||
682 | input_report_key(dev, BTN_LEFT, data[8] & 0x04); | 618 | input_report_key(dev, BTN_LEFT, data[8] & 0x04); |
683 | input_report_key(dev, BTN_MIDDLE, data[8] & 0x08); | 619 | input_report_key(dev, BTN_MIDDLE, data[8] & 0x08); |
684 | input_report_key(dev, BTN_RIGHT, data[8] & 0x10); | 620 | input_report_key(dev, BTN_RIGHT, data[8] & 0x10); |
685 | input_report_key(dev, BTN_SIDE, data[8] & 0x40); | 621 | input_report_rel(dev, REL_WHEEL, ((data[8] & 0x02) >> 1) |
686 | input_report_key(dev, BTN_EXTRA, data[8] & 0x20); | 622 | - (data[8] & 0x01)); |
687 | /* mouse wheel is positive when rolled backwards */ | 623 | |
688 | input_report_rel(dev, REL_WHEEL, ((__u32)((data[8] & 0x02) >> 1) | 624 | /* I3 2D mouse side buttons */ |
689 | - (__u32)(data[8] & 0x01))); | 625 | if (wacom->features->type == INTUOS3) { |
626 | input_report_key(dev, BTN_SIDE, data[8] & 0x40); | ||
627 | input_report_key(dev, BTN_EXTRA, data[8] & 0x20); | ||
628 | } | ||
629 | |||
630 | } else if (wacom->features->type < INTUOS3) { | ||
631 | /* Lens cursor packets */ | ||
632 | input_report_key(dev, BTN_LEFT, data[8] & 0x01); | ||
633 | input_report_key(dev, BTN_MIDDLE, data[8] & 0x02); | ||
634 | input_report_key(dev, BTN_RIGHT, data[8] & 0x04); | ||
635 | input_report_key(dev, BTN_SIDE, data[8] & 0x10); | ||
636 | input_report_key(dev, BTN_EXTRA, data[8] & 0x08); | ||
690 | } | 637 | } |
691 | } | 638 | } |
692 | 639 | ||
@@ -702,35 +649,36 @@ exit: | |||
702 | } | 649 | } |
703 | 650 | ||
704 | static struct wacom_features wacom_features[] = { | 651 | static struct wacom_features wacom_features[] = { |
705 | { "Wacom Penpartner", 7, 5040, 3780, 255, 32, 0, wacom_penpartner_irq }, | 652 | { "Wacom Penpartner", 7, 5040, 3780, 255, 32, PENPARTNER, wacom_penpartner_irq }, |
706 | { "Wacom Graphire", 8, 10206, 7422, 511, 32, 1, wacom_graphire_irq }, | 653 | { "Wacom Graphire", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_graphire_irq }, |
707 | { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, 1, wacom_graphire_irq }, | 654 | { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_graphire_irq }, |
708 | { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, 1, wacom_graphire_irq }, | 655 | { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_graphire_irq }, |
709 | { "Wacom Graphire3", 8, 10208, 7424, 511, 32, 1, wacom_graphire_irq }, | 656 | { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_graphire_irq }, |
710 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, 1, wacom_graphire_irq }, | 657 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_graphire_irq }, |
711 | { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, 2, wacom_intuos_irq }, | 658 | { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq }, |
712 | { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq }, | 659 | { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq }, |
713 | { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, 2, wacom_intuos_irq }, | 660 | { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq }, |
714 | { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15, 2, wacom_intuos_irq }, | 661 | { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_intuos_irq }, |
715 | { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, 2, wacom_intuos_irq }, | 662 | { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq }, |
716 | { "Wacom PL400", 8, 5408, 4056, 255, 32, 3, wacom_pl_irq }, | 663 | { "Wacom PL400", 8, 5408, 4056, 255, 32, PL, wacom_pl_irq }, |
717 | { "Wacom PL500", 8, 6144, 4608, 255, 32, 3, wacom_pl_irq }, | 664 | { "Wacom PL500", 8, 6144, 4608, 255, 32, PL, wacom_pl_irq }, |
718 | { "Wacom PL600", 8, 6126, 4604, 255, 32, 3, wacom_pl_irq }, | 665 | { "Wacom PL600", 8, 6126, 4604, 255, 32, PL, wacom_pl_irq }, |
719 | { "Wacom PL600SX", 8, 6260, 5016, 255, 32, 3, wacom_pl_irq }, | 666 | { "Wacom PL600SX", 8, 6260, 5016, 255, 32, PL, wacom_pl_irq }, |
720 | { "Wacom PL550", 8, 6144, 4608, 511, 32, 3, wacom_pl_irq }, | 667 | { "Wacom PL550", 8, 6144, 4608, 511, 32, PL, wacom_pl_irq }, |
721 | { "Wacom PL800", 8, 7220, 5780, 511, 32, 3, wacom_pl_irq }, | 668 | { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_pl_irq }, |
722 | { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, 2, wacom_intuos_irq }, | 669 | { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq }, |
723 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq }, | 670 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq }, |
724 | { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, 2, wacom_intuos_irq }, | 671 | { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq }, |
725 | { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, 2, wacom_intuos_irq }, | 672 | { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_intuos_irq }, |
726 | { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, 2, wacom_intuos_irq }, | 673 | { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq }, |
727 | { "Wacom Volito", 8, 5104, 3712, 511, 32, 1, wacom_graphire_irq }, | 674 | { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq }, |
728 | { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, 3, wacom_ptu_irq }, | 675 | { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PL, wacom_ptu_irq }, |
729 | { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, 4, wacom_intuos3_irq }, | 676 | { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_intuos_irq }, |
730 | { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, 4, wacom_intuos3_irq }, | 677 | { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_intuos_irq }, |
731 | { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, 4, wacom_intuos3_irq }, | 678 | { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_intuos_irq }, |
732 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq }, | 679 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_intuos_irq }, |
733 | { } | 680 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq }, |
681 | { } | ||
734 | }; | 682 | }; |
735 | 683 | ||
736 | static struct usb_device_id wacom_ids[] = { | 684 | static struct usb_device_id wacom_ids[] = { |
@@ -761,6 +709,7 @@ static struct usb_device_id wacom_ids[] = { | |||
761 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, | 709 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, |
762 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, | 710 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, |
763 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, | 711 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, |
712 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, | ||
764 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, | 713 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, |
765 | { } | 714 | { } |
766 | }; | 715 | }; |
@@ -771,14 +720,9 @@ static int wacom_open(struct input_dev *dev) | |||
771 | { | 720 | { |
772 | struct wacom *wacom = dev->private; | 721 | struct wacom *wacom = dev->private; |
773 | 722 | ||
774 | if (wacom->open++) | ||
775 | return 0; | ||
776 | |||
777 | wacom->irq->dev = wacom->usbdev; | 723 | wacom->irq->dev = wacom->usbdev; |
778 | if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { | 724 | if (usb_submit_urb(wacom->irq, GFP_KERNEL)) |
779 | wacom->open--; | ||
780 | return -EIO; | 725 | return -EIO; |
781 | } | ||
782 | 726 | ||
783 | return 0; | 727 | return 0; |
784 | } | 728 | } |
@@ -787,8 +731,7 @@ static void wacom_close(struct input_dev *dev) | |||
787 | { | 731 | { |
788 | struct wacom *wacom = dev->private; | 732 | struct wacom *wacom = dev->private; |
789 | 733 | ||
790 | if (!--wacom->open) | 734 | usb_kill_urb(wacom->irq); |
791 | usb_kill_urb(wacom->irq); | ||
792 | } | 735 | } |
793 | 736 | ||
794 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) | 737 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) |
@@ -823,32 +766,33 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
823 | wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS); | 766 | wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS); |
824 | 767 | ||
825 | switch (wacom->features->type) { | 768 | switch (wacom->features->type) { |
826 | case 1: | 769 | case GRAPHIRE: |
827 | wacom->dev.evbit[0] |= BIT(EV_REL); | 770 | wacom->dev.evbit[0] |= BIT(EV_REL); |
828 | wacom->dev.relbit[0] |= BIT(REL_WHEEL); | 771 | wacom->dev.relbit[0] |= BIT(REL_WHEEL); |
829 | wacom->dev.absbit[0] |= BIT(ABS_DISTANCE); | 772 | wacom->dev.absbit[0] |= BIT(ABS_DISTANCE); |
830 | wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); | 773 | wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); |
831 | wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); | 774 | wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); |
832 | break; | 775 | break; |
833 | 776 | ||
834 | case 4: /* new functions for Intuos3 */ | 777 | case INTUOS3: |
778 | case CINTIQ: | ||
835 | wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); | 779 | wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); |
836 | 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); | 780 | 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); |
837 | wacom->dev.absbit[0] |= BIT(ABS_RX) | BIT(ABS_RY); | 781 | wacom->dev.absbit[0] |= BIT(ABS_RX) | BIT(ABS_RY); |
838 | /* fall through */ | 782 | /* fall through */ |
839 | 783 | ||
840 | case 2: | 784 | case INTUOS: |
841 | wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); | 785 | wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); |
842 | wacom->dev.mscbit[0] |= BIT(MSC_SERIAL); | 786 | wacom->dev.mscbit[0] |= BIT(MSC_SERIAL); |
843 | wacom->dev.relbit[0] |= BIT(REL_WHEEL); | 787 | wacom->dev.relbit[0] |= BIT(REL_WHEEL); |
844 | wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); | 788 | wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); |
845 | wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) | 789 | wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) |
846 | | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); | 790 | | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); |
847 | wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE); | 791 | wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE); |
848 | break; | 792 | break; |
849 | 793 | ||
850 | case 3: | 794 | case PL: |
851 | wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER); | 795 | wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER); |
852 | break; | 796 | break; |
853 | } | 797 | } |
854 | 798 | ||
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index d65edb22e545..a7fa1b17dcfe 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c | |||
@@ -104,13 +104,12 @@ MODULE_DEVICE_TABLE (usb, xpad_table); | |||
104 | struct usb_xpad { | 104 | struct usb_xpad { |
105 | struct input_dev dev; /* input device interface */ | 105 | struct input_dev dev; /* input device interface */ |
106 | struct usb_device *udev; /* usb device */ | 106 | struct usb_device *udev; /* usb device */ |
107 | 107 | ||
108 | struct urb *irq_in; /* urb for interrupt in report */ | 108 | struct urb *irq_in; /* urb for interrupt in report */ |
109 | unsigned char *idata; /* input data */ | 109 | unsigned char *idata; /* input data */ |
110 | dma_addr_t idata_dma; | 110 | dma_addr_t idata_dma; |
111 | 111 | ||
112 | char phys[65]; /* physical device path */ | 112 | char phys[65]; /* physical device path */ |
113 | int open_count; /* reference count */ | ||
114 | }; | 113 | }; |
115 | 114 | ||
116 | /* | 115 | /* |
@@ -128,35 +127,35 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d | |||
128 | struct input_dev *dev = &xpad->dev; | 127 | struct input_dev *dev = &xpad->dev; |
129 | 128 | ||
130 | input_regs(dev, regs); | 129 | input_regs(dev, regs); |
131 | 130 | ||
132 | /* left stick */ | 131 | /* left stick */ |
133 | input_report_abs(dev, ABS_X, (__s16) (((__s16)data[13] << 8) | data[12])); | 132 | input_report_abs(dev, ABS_X, (__s16) (((__s16)data[13] << 8) | data[12])); |
134 | input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[15] << 8) | data[14])); | 133 | input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[15] << 8) | data[14])); |
135 | 134 | ||
136 | /* right stick */ | 135 | /* right stick */ |
137 | input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[17] << 8) | data[16])); | 136 | input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[17] << 8) | data[16])); |
138 | input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[19] << 8) | data[18])); | 137 | input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[19] << 8) | data[18])); |
139 | 138 | ||
140 | /* triggers left/right */ | 139 | /* triggers left/right */ |
141 | input_report_abs(dev, ABS_Z, data[10]); | 140 | input_report_abs(dev, ABS_Z, data[10]); |
142 | input_report_abs(dev, ABS_RZ, data[11]); | 141 | input_report_abs(dev, ABS_RZ, data[11]); |
143 | 142 | ||
144 | /* digital pad */ | 143 | /* digital pad */ |
145 | input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); | 144 | input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); |
146 | input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01)); | 145 | input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01)); |
147 | 146 | ||
148 | /* start/back buttons and stick press left/right */ | 147 | /* start/back buttons and stick press left/right */ |
149 | input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4); | 148 | input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4); |
150 | input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5); | 149 | input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5); |
151 | input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6); | 150 | input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6); |
152 | input_report_key(dev, BTN_THUMBR, data[2] >> 7); | 151 | input_report_key(dev, BTN_THUMBR, data[2] >> 7); |
153 | 152 | ||
154 | /* "analog" buttons A, B, X, Y */ | 153 | /* "analog" buttons A, B, X, Y */ |
155 | input_report_key(dev, BTN_A, data[4]); | 154 | input_report_key(dev, BTN_A, data[4]); |
156 | input_report_key(dev, BTN_B, data[5]); | 155 | input_report_key(dev, BTN_B, data[5]); |
157 | input_report_key(dev, BTN_X, data[6]); | 156 | input_report_key(dev, BTN_X, data[6]); |
158 | input_report_key(dev, BTN_Y, data[7]); | 157 | input_report_key(dev, BTN_Y, data[7]); |
159 | 158 | ||
160 | /* "analog" buttons black, white */ | 159 | /* "analog" buttons black, white */ |
161 | input_report_key(dev, BTN_C, data[8]); | 160 | input_report_key(dev, BTN_C, data[8]); |
162 | input_report_key(dev, BTN_Z, data[9]); | 161 | input_report_key(dev, BTN_Z, data[9]); |
@@ -168,7 +167,7 @@ static void xpad_irq_in(struct urb *urb, struct pt_regs *regs) | |||
168 | { | 167 | { |
169 | struct usb_xpad *xpad = urb->context; | 168 | struct usb_xpad *xpad = urb->context; |
170 | int retval; | 169 | int retval; |
171 | 170 | ||
172 | switch (urb->status) { | 171 | switch (urb->status) { |
173 | case 0: | 172 | case 0: |
174 | /* success */ | 173 | /* success */ |
@@ -183,7 +182,7 @@ static void xpad_irq_in(struct urb *urb, struct pt_regs *regs) | |||
183 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | 182 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); |
184 | goto exit; | 183 | goto exit; |
185 | } | 184 | } |
186 | 185 | ||
187 | xpad_process_packet(xpad, 0, xpad->idata, regs); | 186 | xpad_process_packet(xpad, 0, xpad->idata, regs); |
188 | 187 | ||
189 | exit: | 188 | exit: |
@@ -196,25 +195,19 @@ exit: | |||
196 | static int xpad_open (struct input_dev *dev) | 195 | static int xpad_open (struct input_dev *dev) |
197 | { | 196 | { |
198 | struct usb_xpad *xpad = dev->private; | 197 | struct usb_xpad *xpad = dev->private; |
199 | 198 | ||
200 | if (xpad->open_count++) | ||
201 | return 0; | ||
202 | |||
203 | xpad->irq_in->dev = xpad->udev; | 199 | xpad->irq_in->dev = xpad->udev; |
204 | if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) { | 200 | if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) |
205 | xpad->open_count--; | ||
206 | return -EIO; | 201 | return -EIO; |
207 | } | 202 | |
208 | |||
209 | return 0; | 203 | return 0; |
210 | } | 204 | } |
211 | 205 | ||
212 | static void xpad_close (struct input_dev *dev) | 206 | static void xpad_close (struct input_dev *dev) |
213 | { | 207 | { |
214 | struct usb_xpad *xpad = dev->private; | 208 | struct usb_xpad *xpad = dev->private; |
215 | 209 | ||
216 | if (!--xpad->open_count) | 210 | usb_kill_urb(xpad->irq_in); |
217 | usb_kill_urb(xpad->irq_in); | ||
218 | } | 211 | } |
219 | 212 | ||
220 | static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) | 213 | static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) |
@@ -224,19 +217,19 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
224 | struct usb_endpoint_descriptor *ep_irq_in; | 217 | struct usb_endpoint_descriptor *ep_irq_in; |
225 | char path[64]; | 218 | char path[64]; |
226 | int i; | 219 | int i; |
227 | 220 | ||
228 | for (i = 0; xpad_device[i].idVendor; i++) { | 221 | for (i = 0; xpad_device[i].idVendor; i++) { |
229 | if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && | 222 | if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && |
230 | (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct)) | 223 | (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct)) |
231 | break; | 224 | break; |
232 | } | 225 | } |
233 | 226 | ||
234 | if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) { | 227 | if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) { |
235 | err("cannot allocate memory for new pad"); | 228 | err("cannot allocate memory for new pad"); |
236 | return -ENOMEM; | 229 | return -ENOMEM; |
237 | } | 230 | } |
238 | memset(xpad, 0, sizeof(struct usb_xpad)); | 231 | memset(xpad, 0, sizeof(struct usb_xpad)); |
239 | 232 | ||
240 | xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN, | 233 | xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN, |
241 | SLAB_ATOMIC, &xpad->idata_dma); | 234 | SLAB_ATOMIC, &xpad->idata_dma); |
242 | if (!xpad->idata) { | 235 | if (!xpad->idata) { |
@@ -251,18 +244,18 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
251 | kfree(xpad); | 244 | kfree(xpad); |
252 | return -ENOMEM; | 245 | return -ENOMEM; |
253 | } | 246 | } |
254 | 247 | ||
255 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; | 248 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; |
256 | 249 | ||
257 | usb_fill_int_urb(xpad->irq_in, udev, | 250 | usb_fill_int_urb(xpad->irq_in, udev, |
258 | usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), | 251 | usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), |
259 | xpad->idata, XPAD_PKT_LEN, xpad_irq_in, | 252 | xpad->idata, XPAD_PKT_LEN, xpad_irq_in, |
260 | xpad, ep_irq_in->bInterval); | 253 | xpad, ep_irq_in->bInterval); |
261 | xpad->irq_in->transfer_dma = xpad->idata_dma; | 254 | xpad->irq_in->transfer_dma = xpad->idata_dma; |
262 | xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 255 | xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
263 | 256 | ||
264 | xpad->udev = udev; | 257 | xpad->udev = udev; |
265 | 258 | ||
266 | xpad->dev.id.bustype = BUS_USB; | 259 | xpad->dev.id.bustype = BUS_USB; |
267 | xpad->dev.id.vendor = le16_to_cpu(udev->descriptor.idVendor); | 260 | xpad->dev.id.vendor = le16_to_cpu(udev->descriptor.idVendor); |
268 | xpad->dev.id.product = le16_to_cpu(udev->descriptor.idProduct); | 261 | xpad->dev.id.product = le16_to_cpu(udev->descriptor.idProduct); |
@@ -273,21 +266,21 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
273 | xpad->dev.phys = xpad->phys; | 266 | xpad->dev.phys = xpad->phys; |
274 | xpad->dev.open = xpad_open; | 267 | xpad->dev.open = xpad_open; |
275 | xpad->dev.close = xpad_close; | 268 | xpad->dev.close = xpad_close; |
276 | 269 | ||
277 | usb_make_path(udev, path, 64); | 270 | usb_make_path(udev, path, 64); |
278 | snprintf(xpad->phys, 64, "%s/input0", path); | 271 | snprintf(xpad->phys, 64, "%s/input0", path); |
279 | 272 | ||
280 | xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 273 | xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
281 | 274 | ||
282 | for (i = 0; xpad_btn[i] >= 0; i++) | 275 | for (i = 0; xpad_btn[i] >= 0; i++) |
283 | set_bit(xpad_btn[i], xpad->dev.keybit); | 276 | set_bit(xpad_btn[i], xpad->dev.keybit); |
284 | 277 | ||
285 | for (i = 0; xpad_abs[i] >= 0; i++) { | 278 | for (i = 0; xpad_abs[i] >= 0; i++) { |
286 | 279 | ||
287 | signed short t = xpad_abs[i]; | 280 | signed short t = xpad_abs[i]; |
288 | 281 | ||
289 | set_bit(t, xpad->dev.absbit); | 282 | set_bit(t, xpad->dev.absbit); |
290 | 283 | ||
291 | switch (t) { | 284 | switch (t) { |
292 | case ABS_X: | 285 | case ABS_X: |
293 | case ABS_Y: | 286 | case ABS_Y: |
@@ -310,11 +303,11 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
310 | break; | 303 | break; |
311 | } | 304 | } |
312 | } | 305 | } |
313 | 306 | ||
314 | input_register_device(&xpad->dev); | 307 | input_register_device(&xpad->dev); |
315 | 308 | ||
316 | printk(KERN_INFO "input: %s on %s", xpad->dev.name, path); | 309 | printk(KERN_INFO "input: %s on %s", xpad->dev.name, path); |
317 | 310 | ||
318 | usb_set_intfdata(intf, xpad); | 311 | usb_set_intfdata(intf, xpad); |
319 | return 0; | 312 | return 0; |
320 | } | 313 | } |
@@ -322,7 +315,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
322 | static void xpad_disconnect(struct usb_interface *intf) | 315 | static void xpad_disconnect(struct usb_interface *intf) |
323 | { | 316 | { |
324 | struct usb_xpad *xpad = usb_get_intfdata (intf); | 317 | struct usb_xpad *xpad = usb_get_intfdata (intf); |
325 | 318 | ||
326 | usb_set_intfdata(intf, NULL); | 319 | usb_set_intfdata(intf, NULL); |
327 | if (xpad) { | 320 | if (xpad) { |
328 | usb_kill_urb(xpad->irq_in); | 321 | usb_kill_urb(xpad->irq_in); |