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>
38 #include <linux/usb_input.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
;
76 static struct usb_device_id touchkit_devices
[] = {
77 {USB_DEVICE(0x3823, 0x0001)},
78 {USB_DEVICE(0x0eef, 0x0001)},
82 static void touchkit_irq(struct urb
*urb
, struct pt_regs
*regs
)
84 struct touchkit_usb
*touchkit
= urb
->context
;
88 switch (urb
->status
) {
93 /* this urb is timing out */
94 dbg("%s - urb timed out - was the device unplugged?",
100 /* this urb is terminated, clean up */
101 dbg("%s - urb shutting down with status: %d",
102 __FUNCTION__
, urb
->status
);
105 dbg("%s - nonzero urb status received: %d",
106 __FUNCTION__
, urb
->status
);
111 y
= TOUCHKIT_GET_X(touchkit
->data
);
112 x
= TOUCHKIT_GET_Y(touchkit
->data
);
114 x
= TOUCHKIT_GET_X(touchkit
->data
);
115 y
= TOUCHKIT_GET_Y(touchkit
->data
);
118 input_regs(&touchkit
->input
, regs
);
119 input_report_key(&touchkit
->input
, BTN_TOUCH
,
120 TOUCHKIT_GET_TOUCHED(touchkit
->data
));
121 input_report_abs(&touchkit
->input
, ABS_X
, x
);
122 input_report_abs(&touchkit
->input
, ABS_Y
, y
);
123 input_sync(&touchkit
->input
);
126 retval
= usb_submit_urb(urb
, GFP_ATOMIC
);
128 err("%s - usb_submit_urb failed with result: %d",
129 __FUNCTION__
, retval
);
132 static int touchkit_open(struct input_dev
*input
)
134 struct touchkit_usb
*touchkit
= input
->private;
136 touchkit
->irq
->dev
= touchkit
->udev
;
138 if (usb_submit_urb(touchkit
->irq
, GFP_ATOMIC
))
144 static void touchkit_close(struct input_dev
*input
)
146 struct touchkit_usb
*touchkit
= input
->private;
148 usb_kill_urb(touchkit
->irq
);
151 static int touchkit_alloc_buffers(struct usb_device
*udev
,
152 struct touchkit_usb
*touchkit
)
154 touchkit
->data
= usb_buffer_alloc(udev
, TOUCHKIT_REPORT_DATA_SIZE
,
155 SLAB_ATOMIC
, &touchkit
->data_dma
);
163 static void touchkit_free_buffers(struct usb_device
*udev
,
164 struct touchkit_usb
*touchkit
)
167 usb_buffer_free(udev
, TOUCHKIT_REPORT_DATA_SIZE
,
168 touchkit
->data
, touchkit
->data_dma
);
171 static int touchkit_probe(struct usb_interface
*intf
,
172 const struct usb_device_id
*id
)
175 struct touchkit_usb
*touchkit
;
176 struct usb_host_interface
*interface
;
177 struct usb_endpoint_descriptor
*endpoint
;
178 struct usb_device
*udev
= interface_to_usbdev(intf
);
181 interface
= intf
->cur_altsetting
;
182 endpoint
= &interface
->endpoint
[0].desc
;
184 touchkit
= kmalloc(sizeof(struct touchkit_usb
), GFP_KERNEL
);
188 memset(touchkit
, 0, sizeof(struct touchkit_usb
));
189 touchkit
->udev
= udev
;
191 if (touchkit_alloc_buffers(udev
, touchkit
)) {
196 touchkit
->input
.private = touchkit
;
197 touchkit
->input
.open
= touchkit_open
;
198 touchkit
->input
.close
= touchkit_close
;
200 usb_make_path(udev
, path
, 64);
201 sprintf(touchkit
->phys
, "%s/input0", path
);
203 touchkit
->input
.name
= touchkit
->name
;
204 touchkit
->input
.phys
= touchkit
->phys
;
205 usb_to_input_id(udev
, &touchkit
->input
.id
);
206 touchkit
->input
.dev
= &intf
->dev
;
208 touchkit
->input
.evbit
[0] = BIT(EV_KEY
) | BIT(EV_ABS
);
209 touchkit
->input
.absbit
[0] = BIT(ABS_X
) | BIT(ABS_Y
);
210 touchkit
->input
.keybit
[LONG(BTN_TOUCH
)] = BIT(BTN_TOUCH
);
212 /* Used to Scale Compensated Data */
213 touchkit
->input
.absmin
[ABS_X
] = TOUCHKIT_MIN_XC
;
214 touchkit
->input
.absmax
[ABS_X
] = TOUCHKIT_MAX_XC
;
215 touchkit
->input
.absfuzz
[ABS_X
] = TOUCHKIT_XC_FUZZ
;
216 touchkit
->input
.absflat
[ABS_X
] = TOUCHKIT_XC_FLAT
;
217 touchkit
->input
.absmin
[ABS_Y
] = TOUCHKIT_MIN_YC
;
218 touchkit
->input
.absmax
[ABS_Y
] = TOUCHKIT_MAX_YC
;
219 touchkit
->input
.absfuzz
[ABS_Y
] = TOUCHKIT_YC_FUZZ
;
220 touchkit
->input
.absflat
[ABS_Y
] = TOUCHKIT_YC_FLAT
;
222 if (udev
->manufacturer
)
223 strcat(touchkit
->name
, udev
->manufacturer
);
225 sprintf(touchkit
->name
, "%s %s", touchkit
->name
, udev
->product
);
227 if (!strlen(touchkit
->name
))
228 sprintf(touchkit
->name
, "USB Touchscreen %04x:%04x",
229 touchkit
->input
.id
.vendor
, touchkit
->input
.id
.product
);
231 touchkit
->irq
= usb_alloc_urb(0, GFP_KERNEL
);
232 if (!touchkit
->irq
) {
233 dbg("%s - usb_alloc_urb failed: touchkit->irq", __FUNCTION__
);
235 goto out_free_buffers
;
238 usb_fill_int_urb(touchkit
->irq
, touchkit
->udev
,
239 usb_rcvintpipe(touchkit
->udev
, 0x81),
240 touchkit
->data
, TOUCHKIT_REPORT_DATA_SIZE
,
241 touchkit_irq
, touchkit
, endpoint
->bInterval
);
243 input_register_device(&touchkit
->input
);
245 printk(KERN_INFO
"input: %s on %s\n", touchkit
->name
, path
);
246 usb_set_intfdata(intf
, touchkit
);
251 touchkit_free_buffers(udev
, touchkit
);
257 static void touchkit_disconnect(struct usb_interface
*intf
)
259 struct touchkit_usb
*touchkit
= usb_get_intfdata(intf
);
261 dbg("%s - called", __FUNCTION__
);
266 dbg("%s - touchkit is initialized, cleaning up", __FUNCTION__
);
267 usb_set_intfdata(intf
, NULL
);
268 input_unregister_device(&touchkit
->input
);
269 usb_kill_urb(touchkit
->irq
);
270 usb_free_urb(touchkit
->irq
);
271 touchkit_free_buffers(interface_to_usbdev(intf
), touchkit
);
275 MODULE_DEVICE_TABLE(usb
, touchkit_devices
);
277 static struct usb_driver touchkit_driver
= {
278 .owner
= THIS_MODULE
,
279 .name
= "touchkitusb",
280 .probe
= touchkit_probe
,
281 .disconnect
= touchkit_disconnect
,
282 .id_table
= touchkit_devices
,
285 static int __init
touchkit_init(void)
287 return usb_register(&touchkit_driver
);
290 static void __exit
touchkit_cleanup(void)
292 usb_deregister(&touchkit_driver
);
295 module_init(touchkit_init
);
296 module_exit(touchkit_cleanup
);
298 MODULE_AUTHOR(DRIVER_AUTHOR
);
299 MODULE_DESCRIPTION(DRIVER_DESC
);
300 MODULE_LICENSE("GPL");