]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.drivers/elousb.patch
Disable build of xen kernel.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / elousb.patch
1 From: Jiri Kosina <jkosina@suse.cz>
2 Subject: Elo USB touchscreen driver
3 Patch-mainline: will be submitted for 2.6.28
4 References: FATE#304972
5
6 This is a driver for Elo USB touchscreen devices.
7
8 Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
9 Acked-by: Jiri Kosina <jkosina@suse.cz>
10
11 ---
12 drivers/hid/usbhid/hid-quirks.c | 4
13 drivers/input/touchscreen/Kconfig | 12 +
14 drivers/input/touchscreen/Makefile | 1
15 drivers/input/touchscreen/elousb.c | 305 +++++++++++++++++++++++++++++++++++++
16 4 files changed, 322 insertions(+)
17
18 --- a/drivers/hid/usbhid/hid-quirks.c
19 +++ b/drivers/hid/usbhid/hid-quirks.c
20 @@ -138,7 +138,9 @@
21 #define USB_DEVICE_ID_DMI_ENC 0x5fab
22
23 #define USB_VENDOR_ID_ELO 0x04E7
24 +#define USB_DEVICE_ID_ELO_4000U 0x0009
25 #define USB_DEVICE_ID_ELO_TS2700 0x0020
26 +#define USB_DEVICE_ID_ELO_4500U 0x0030
27
28 #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
29 #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
30 @@ -485,6 +487,8 @@ static const struct hid_blacklist {
31 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE, HID_QUIRK_IGNORE },
32 { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE },
33 { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE },
34 + { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_4000U, HID_QUIRK_IGNORE },
35 + { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_4500U, HID_QUIRK_IGNORE },
36 { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE },
37 { USB_VENDOR_ID_GENERAL_TOUCH, 0x0001, HID_QUIRK_IGNORE },
38 { USB_VENDOR_ID_GENERAL_TOUCH, 0x0002, HID_QUIRK_IGNORE },
39 --- /dev/null
40 +++ b/drivers/input/touchscreen/elousb.c
41 @@ -0,0 +1,305 @@
42 +/*
43 + * Copyright (c) 1999-2001 Vojtech Pavlik
44 + *
45 + * Elo USB touchscreen support
46 + */
47 +
48 +/*
49 + * This program is free software; you can redistribute it and/or modify
50 + * it under the terms of the GNU General Public License as published by
51 + * the Free Software Foundation; either version 2 of the License.
52 + *
53 + * This program is distributed in the hope that it will be useful,
54 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
55 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56 + * GNU General Public License for more details.
57 + *
58 + * You should have received a copy of the GNU General Public License
59 + * along with this program; if not, write to the Free Software
60 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
61 + *
62 + * Should you need to contact me, the author, you can do so either by
63 + * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
64 + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
65 + */
66 +
67 +#include <linux/kernel.h>
68 +#include <linux/slab.h>
69 +#include <linux/module.h>
70 +#include <linux/init.h>
71 +#include <linux/usb.h>
72 +#include <linux/usb/input.h>
73 +#include <linux/hid.h>
74 +#include <linux/input.h>
75 +
76 +/*
77 + * Version Information
78 + */
79 +#define DRIVER_VERSION "v1.1"
80 +#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@suse.cz>"
81 +#define DRIVER_DESC "Elo USB touchscreen driver"
82 +#define DRIVER_LICENSE "GPL"
83 +
84 +MODULE_AUTHOR(DRIVER_AUTHOR);
85 +MODULE_DESCRIPTION(DRIVER_DESC);
86 +MODULE_LICENSE(DRIVER_LICENSE);
87 +
88 +struct elousb {
89 + char name[128];
90 + char phys[64];
91 + struct usb_device *usbdev;
92 + struct input_dev *dev;
93 + struct urb *irq;
94 +
95 + unsigned char *data;
96 + dma_addr_t data_dma;
97 +};
98 +
99 +static void elousb_irq(struct urb *urb)
100 +{
101 + struct elousb *elo = urb->context;
102 + unsigned char *data = elo->data;
103 + struct input_dev *dev = elo->dev;
104 + int status;
105 +
106 + switch (urb->status) {
107 + case 0: /* success */
108 + break;
109 + case -ECONNRESET: /* unlink */
110 + case -ENOENT:
111 + case -ESHUTDOWN:
112 + return;
113 + /* -EPIPE: should clear the halt */
114 + default: /* error */
115 + goto resubmit;
116 + }
117 +
118 + if (data[0] != 'T') /* Mandatory ELO packet marker */
119 + return;
120 +
121 +
122 + input_report_abs(dev, ABS_X, ((u32)data[3] << 8) | data[2]);
123 + input_report_abs(dev, ABS_Y, ((u32)data[5] << 8) | data[4]);
124 +
125 + input_report_abs(dev, ABS_PRESSURE,
126 + (data[1] & 0x80) ? (((u32)data[7] << 8) | data[6]): 0);
127 +
128 + if (data[1] & 0x03) {
129 + input_report_key(dev, BTN_TOUCH, 1);
130 + input_sync(dev);
131 + }
132 +
133 + if (data[1] & 0x04)
134 + input_report_key(dev, BTN_TOUCH, 0);
135 +
136 + input_sync(dev);
137 +
138 +resubmit:
139 + status = usb_submit_urb (urb, GFP_ATOMIC);
140 + if (status)
141 + err ("can't resubmit intr, %s-%s/input0, status %d",
142 + elo->usbdev->bus->bus_name,
143 + elo->usbdev->devpath, status);
144 +}
145 +
146 +static int elousb_open(struct input_dev *dev)
147 +{
148 + struct elousb *elo = input_get_drvdata(dev);
149 +
150 + elo->irq->dev = elo->usbdev;
151 + if (usb_submit_urb(elo->irq, GFP_KERNEL))
152 + return -EIO;
153 +
154 + return 0;
155 +}
156 +
157 +static void elousb_close(struct input_dev *dev)
158 +{
159 + struct elousb *elo = input_get_drvdata(dev);
160 +
161 + usb_kill_urb(elo->irq);
162 +}
163 +
164 +static int elousb_probe(struct usb_interface *intf, const struct usb_device_id *id)
165 +{
166 + struct usb_device *dev = interface_to_usbdev(intf);
167 + struct usb_host_interface *interface;
168 + struct usb_endpoint_descriptor *endpoint;
169 + struct hid_descriptor *hdesc;
170 + struct elousb *elo;
171 + struct input_dev *input_dev;
172 + int pipe, i;
173 + unsigned int rsize = 0;
174 + int error = -ENOMEM;
175 + char *rdesc;
176 +
177 + interface = intf->cur_altsetting;
178 +
179 + if (interface->desc.bNumEndpoints != 1)
180 + return -ENODEV;
181 +
182 + endpoint = &interface->endpoint[0].desc;
183 + if (!(endpoint->bEndpointAddress & USB_DIR_IN))
184 + return -ENODEV;
185 + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
186 + return -ENODEV;
187 +
188 + if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
189 + (!interface->desc.bNumEndpoints ||
190 + usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
191 + err("HID class descriptor not present");
192 + return -ENODEV;
193 + }
194 +
195 + for (i = 0; i < hdesc->bNumDescriptors; i++)
196 + if (hdesc->desc[i].bDescriptorType == HID_DT_REPORT)
197 + rsize = le16_to_cpu(hdesc->desc[i].wDescriptorLength);
198 +
199 + if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
200 + err("weird size of report descriptor (%u)", rsize);
201 + return -ENODEV;
202 + }
203 +
204 +
205 + pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
206 +
207 + elo = kzalloc(sizeof(struct elousb), GFP_KERNEL);
208 + input_dev = input_allocate_device();
209 + if (!elo || !input_dev)
210 + goto fail1;
211 +
212 + elo->data = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &elo->data_dma);
213 + if (!elo->data)
214 + goto fail1;
215 +
216 + elo->irq = usb_alloc_urb(0, GFP_KERNEL);
217 + if (!elo->irq)
218 + goto fail2;
219 +
220 + if (!(rdesc = kmalloc(rsize, GFP_KERNEL)))
221 + goto fail3;
222 +
223 + elo->usbdev = dev;
224 + elo->dev = input_dev;
225 +
226 + if ((error = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
227 + HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0,
228 + interface->desc.bInterfaceNumber,
229 + NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) {
230 + err("setting HID idle timeout failed, error %d", error);
231 + error = -ENODEV;
232 + goto fail4;
233 + }
234 +
235 + if ((error = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
236 + USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
237 + HID_DT_REPORT << 8, interface->desc.bInterfaceNumber,
238 + rdesc, rsize, USB_CTRL_GET_TIMEOUT)) < rsize) {
239 + err("reading HID report descriptor failed, error %d", error);
240 + error = -ENODEV;
241 + goto fail4;
242 + }
243 +
244 + if (dev->manufacturer)
245 + strlcpy(elo->name, dev->manufacturer, sizeof(elo->name));
246 +
247 + if (dev->product) {
248 + if (dev->manufacturer)
249 + strlcat(elo->name, " ", sizeof(elo->name));
250 + strlcat(elo->name, dev->product, sizeof(elo->name));
251 + }
252 +
253 + if (!strlen(elo->name))
254 + snprintf(elo->name, sizeof(elo->name),
255 + "Elo touchscreen %04x:%04x",
256 + le16_to_cpu(dev->descriptor.idVendor),
257 + le16_to_cpu(dev->descriptor.idProduct));
258 +
259 + usb_make_path(dev, elo->phys, sizeof(elo->phys));
260 + strlcat(elo->phys, "/input0", sizeof(elo->phys));
261 +
262 + input_dev->name = elo->name;
263 + input_dev->phys = elo->phys;
264 + usb_to_input_id(dev, &input_dev->id);
265 + input_dev->dev.parent = &intf->dev;
266 +
267 + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
268 + set_bit(BTN_TOUCH, input_dev->keybit);
269 + input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
270 + set_bit(ABS_PRESSURE, input_dev->absbit);
271 +
272 + input_set_abs_params(input_dev, ABS_X, 0, 4000, 0, 0);
273 + input_set_abs_params(input_dev, ABS_Y, 0, 3840, 0, 0);
274 + input_set_abs_params(input_dev, ABS_PRESSURE, 0, 256, 0, 0);
275 +
276 + input_set_drvdata(input_dev, elo);
277 +
278 + input_dev->open = elousb_open;
279 + input_dev->close = elousb_close;
280 +
281 + usb_fill_int_urb(elo->irq, dev, pipe, elo->data, 8,
282 + elousb_irq, elo, endpoint->bInterval);
283 + elo->irq->transfer_dma = elo->data_dma;
284 + elo->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
285 +
286 + input_register_device(elo->dev);
287 +
288 + usb_set_intfdata(intf, elo);
289 + return 0;
290 +
291 +fail4:
292 + kfree(rdesc);
293 +fail3:
294 + usb_free_urb(elo->irq);
295 +fail2:
296 + usb_buffer_free(dev, 8, elo->data, elo->data_dma);
297 +fail1:
298 + input_free_device(input_dev);
299 + kfree(elo);
300 + return -ENOMEM;
301 +}
302 +
303 +static void elousb_disconnect(struct usb_interface *intf)
304 +{
305 + struct elousb *elo = usb_get_intfdata (intf);
306 +
307 + usb_set_intfdata(intf, NULL);
308 + if (elo) {
309 + usb_kill_urb(elo->irq);
310 + input_unregister_device(elo->dev);
311 + usb_free_urb(elo->irq);
312 + usb_buffer_free(interface_to_usbdev(intf), 8, elo->data, elo->data_dma);
313 + kfree(elo);
314 + }
315 +}
316 +
317 +static struct usb_device_id elousb_id_table [] = {
318 + { USB_DEVICE(0x04e7, 0x0009) }, /* CarrolTouch 4000U */
319 + { USB_DEVICE(0x04e7, 0x0030) }, /* CarrolTouch 4500U */
320 + { } /* Terminating entry */
321 +};
322 +
323 +MODULE_DEVICE_TABLE (usb, elousb_id_table);
324 +
325 +static struct usb_driver elousb_driver = {
326 + .name = "elousb",
327 + .probe = elousb_probe,
328 + .disconnect = elousb_disconnect,
329 + .id_table = elousb_id_table,
330 +};
331 +
332 +static int __init elousb_init(void)
333 +{
334 + int retval = usb_register(&elousb_driver);
335 + if (retval == 0)
336 + info(DRIVER_VERSION ":" DRIVER_DESC);
337 + return retval;
338 +}
339 +
340 +static void __exit elousb_exit(void)
341 +{
342 + usb_deregister(&elousb_driver);
343 +}
344 +
345 +module_init(elousb_init);
346 +module_exit(elousb_exit);
347 --- a/drivers/input/touchscreen/Kconfig
348 +++ b/drivers/input/touchscreen/Kconfig
349 @@ -91,6 +91,18 @@ config TOUCHSCREEN_ELO
350 To compile this driver as a module, choose M here: the
351 module will be called elo.
352
353 +config TOUCHSCREEN_ELOUSB
354 + tristate "Elo USB touchscreens"
355 + select USB
356 + help
357 + Say Y here if you have an Elo USB touchscreen connected to
358 + your system.
359 +
360 + If unsure, say N.
361 +
362 + To compile this driver as a module, choose M here: the
363 + module will be called elousb.
364 +
365 config TOUCHSCREEN_MTOUCH
366 tristate "MicroTouch serial touchscreens"
367 select SERIO
368 --- a/drivers/input/touchscreen/Makefile
369 +++ b/drivers/input/touchscreen/Makefile
370 @@ -12,6 +12,7 @@ obj-$(CONFIG_TOUCHSCREEN_BITSY) += h360
371 obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
372 obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
373 obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
374 +obj-$(CONFIG_TOUCHSCREEN_ELOUSB) += elousb.o
375 obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
376 obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
377 obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o