1 /******************************************************************************
2 * touchkitusb.c -- Driver for eGalax TouchKit USB Touchscreens
4 * Copyright (C) 2004 by Daniel Ritz
5 * Copyright (C) by Todd E. Johnson (mtouchusb.c)
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * Based upon mtouchusb.c
23 *****************************************************************************/
27 #include <linux/config.h>
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>
34 #if !defined(DEBUG) && defined(CONFIG_USB_DEBUG)
37 #include <linux/usb.h>
40 #define TOUCHKIT_MIN_XC 0x0
41 #define TOUCHKIT_MAX_XC 0x07ff
42 #define TOUCHKIT_XC_FUZZ 0x0
43 #define TOUCHKIT_XC_FLAT 0x0
44 #define TOUCHKIT_MIN_YC 0x0
45 #define TOUCHKIT_MAX_YC 0x07ff
46 #define TOUCHKIT_YC_FUZZ 0x0
47 #define TOUCHKIT_YC_FLAT 0x0
48 #define TOUCHKIT_REPORT_DATA_SIZE 8
50 #define TOUCHKIT_DOWN 0x01
51 #define TOUCHKIT_POINT_TOUCH 0x81
52 #define TOUCHKIT_POINT_NOTOUCH 0x80
54 #define TOUCHKIT_GET_TOUCHED(dat) ((((dat)[0]) & TOUCHKIT_DOWN) ? 1 : 0)
55 #define TOUCHKIT_GET_X(dat) (((dat)[3] << 7) | (dat)[4])
56 #define TOUCHKIT_GET_Y(dat) (((dat)[1] << 7) | (dat)[2])
58 #define DRIVER_VERSION "v0.1"
59 #define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>"
60 #define DRIVER_DESC "eGalax TouchKit USB HID Touchscreen Driver"
63 module_param(swap_xy
, bool, 0644);
64 MODULE_PARM_DESC(swap_xy
, "If set X and Y axes are swapped.");
70 struct usb_device
*udev
;
71 struct input_dev input
;
77 static struct usb_device_id touchkit_devices
[] = {
78 {USB_DEVICE(0x3823, 0x0001)},
79 {USB_DEVICE(0x0eef, 0x0001)},
83 static void touchkit_irq(struct urb
*urb
, struct pt_regs
*regs
)
85 struct touchkit_usb
*touchkit
= urb
->context
;
89 switch (urb
->status
) {
94 /* this urb is timing out */
95 dbg("%s - urb timed out - was the device unplugged?",
101 /* this urb is terminated, clean up */
102 dbg("%s - urb shutting down with status: %d",
103 __FUNCTION__
, urb
->status
);
106 dbg("%s - nonzero urb status received: %d",
107 __FUNCTION__
, urb
->status
);
112 y
= TOUCHKIT_GET_X(touchkit
->data
);
113 x
= TOUCHKIT_GET_Y(touchkit
->data
);
115 x
= TOUCHKIT_GET_X(touchkit
->data
);
116 y
= TOUCHKIT_GET_Y(touchkit
->data
);
119 input_regs(&touchkit
->input
, regs
);
120 input_report_key(&touchkit
->input
, BTN_TOUCH
,
121 TOUCHKIT_GET_TOUCHED(touchkit
->data
));
122 input_report_abs(&touchkit
->input
, ABS_X
, x
);
123 input_report_abs(&touchkit
->input
, ABS_Y
, y
);
124 input_sync(&touchkit
->input
);
127 retval
= usb_submit_urb(urb
, GFP_ATOMIC
);
129 err("%s - usb_submit_urb failed with result: %d",
130 __FUNCTION__
, retval
);
133 static int touchkit_open(struct input_dev
*input
)
135 struct touchkit_usb
*touchkit
= input
->private;
137 if (touchkit
->open
++)
140 touchkit
->irq
->dev
= touchkit
->udev
;
142 if (usb_submit_urb(touchkit
->irq
, GFP_ATOMIC
)) {
150 static void touchkit_close(struct input_dev
*input
)
152 struct touchkit_usb
*touchkit
= input
->private;
154 if (!--touchkit
->open
)
155 usb_kill_urb(touchkit
->irq
);
158 static int touchkit_alloc_buffers(struct usb_device
*udev
,
159 struct touchkit_usb
*touchkit
)
161 touchkit
->data
= usb_buffer_alloc(udev
, TOUCHKIT_REPORT_DATA_SIZE
,
162 SLAB_ATOMIC
, &touchkit
->data_dma
);
170 static void touchkit_free_buffers(struct usb_device
*udev
,
171 struct touchkit_usb
*touchkit
)
174 usb_buffer_free(udev
, TOUCHKIT_REPORT_DATA_SIZE
,
175 touchkit
->data
, touchkit
->data_dma
);
178 static int touchkit_probe(struct usb_interface
*intf
,
179 const struct usb_device_id
*id
)
182 struct touchkit_usb
*touchkit
;
183 struct usb_host_interface
*interface
;
184 struct usb_endpoint_descriptor
*endpoint
;
185 struct usb_device
*udev
= interface_to_usbdev(intf
);
188 interface
= intf
->cur_altsetting
;
189 endpoint
= &interface
->endpoint
[0].desc
;
191 touchkit
= kmalloc(sizeof(struct touchkit_usb
), GFP_KERNEL
);
195 memset(touchkit
, 0, sizeof(struct touchkit_usb
));
196 touchkit
->udev
= udev
;
198 if (touchkit_alloc_buffers(udev
, touchkit
)) {
203 touchkit
->input
.private = touchkit
;
204 touchkit
->input
.open
= touchkit_open
;
205 touchkit
->input
.close
= touchkit_close
;
207 usb_make_path(udev
, path
, 64);
208 sprintf(touchkit
->phys
, "%s/input0", path
);
210 touchkit
->input
.name
= touchkit
->name
;
211 touchkit
->input
.phys
= touchkit
->phys
;
212 touchkit
->input
.id
.bustype
= BUS_USB
;
213 touchkit
->input
.id
.vendor
= le16_to_cpu(udev
->descriptor
.idVendor
);
214 touchkit
->input
.id
.product
= le16_to_cpu(udev
->descriptor
.idProduct
);
215 touchkit
->input
.id
.version
= le16_to_cpu(udev
->descriptor
.bcdDevice
);
216 touchkit
->input
.dev
= &intf
->dev
;
218 touchkit
->input
.evbit
[0] = BIT(EV_KEY
) | BIT(EV_ABS
);
219 touchkit
->input
.absbit
[0] = BIT(ABS_X
) | BIT(ABS_Y
);
220 touchkit
->input
.keybit
[LONG(BTN_TOUCH
)] = BIT(BTN_TOUCH
);
222 /* Used to Scale Compensated Data */
223 touchkit
->input
.absmin
[ABS_X
] = TOUCHKIT_MIN_XC
;
224 touchkit
->input
.absmax
[ABS_X
] = TOUCHKIT_MAX_XC
;
225 touchkit
->input
.absfuzz
[ABS_X
] = TOUCHKIT_XC_FUZZ
;
226 touchkit
->input
.absflat
[ABS_X
] = TOUCHKIT_XC_FLAT
;
227 touchkit
->input
.absmin
[ABS_Y
] = TOUCHKIT_MIN_YC
;
228 touchkit
->input
.absmax
[ABS_Y
] = TOUCHKIT_MAX_YC
;
229 touchkit
->input
.absfuzz
[ABS_Y
] = TOUCHKIT_YC_FUZZ
;
230 touchkit
->input
.absflat
[ABS_Y
] = TOUCHKIT_YC_FLAT
;
232 if (udev
->manufacturer
)
233 strcat(touchkit
->name
, udev
->manufacturer
);
235 sprintf(touchkit
->name
, "%s %s", touchkit
->name
, udev
->product
);
237 if (!strlen(touchkit
->name
))
238 sprintf(touchkit
->name
, "USB Touchscreen %04x:%04x",
239 touchkit
->input
.id
.vendor
, touchkit
->input
.id
.product
);
241 touchkit
->irq
= usb_alloc_urb(0, GFP_KERNEL
);
242 if (!touchkit
->irq
) {
243 dbg("%s - usb_alloc_urb failed: touchkit->irq", __FUNCTION__
);
245 goto out_free_buffers
;
248 usb_fill_int_urb(touchkit
->irq
, touchkit
->udev
,
249 usb_rcvintpipe(touchkit
->udev
, 0x81),
250 touchkit
->data
, TOUCHKIT_REPORT_DATA_SIZE
,
251 touchkit_irq
, touchkit
, endpoint
->bInterval
);
253 input_register_device(&touchkit
->input
);
255 printk(KERN_INFO
"input: %s on %s\n", touchkit
->name
, path
);
256 usb_set_intfdata(intf
, touchkit
);
261 touchkit_free_buffers(udev
, touchkit
);
267 static void touchkit_disconnect(struct usb_interface
*intf
)
269 struct touchkit_usb
*touchkit
= usb_get_intfdata(intf
);
271 dbg("%s - called", __FUNCTION__
);
276 dbg("%s - touchkit is initialized, cleaning up", __FUNCTION__
);
277 usb_set_intfdata(intf
, NULL
);
278 input_unregister_device(&touchkit
->input
);
279 usb_kill_urb(touchkit
->irq
);
280 usb_free_urb(touchkit
->irq
);
281 touchkit_free_buffers(interface_to_usbdev(intf
), touchkit
);
285 MODULE_DEVICE_TABLE(usb
, touchkit_devices
);
287 static struct usb_driver touchkit_driver
= {
288 .owner
= THIS_MODULE
,
289 .name
= "touchkitusb",
290 .probe
= touchkit_probe
,
291 .disconnect
= touchkit_disconnect
,
292 .id_table
= touchkit_devices
,
295 static int __init
touchkit_init(void)
297 return usb_register(&touchkit_driver
);
300 static void __exit
touchkit_cleanup(void)
302 usb_deregister(&touchkit_driver
);
305 module_init(touchkit_init
);
306 module_exit(touchkit_cleanup
);
308 MODULE_AUTHOR(DRIVER_AUTHOR
);
309 MODULE_DESCRIPTION(DRIVER_DESC
);
310 MODULE_LICENSE("GPL");