Import 2.3.49pre2
[davej-history.git] / drivers / usb / wacom.c
blobc67d30a602b351b2fb00c1292f8cd32f6890a12b
1 /*
2 * wacom.c Version 0.3
4 * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz>
5 * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk>
6 * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at>
8 * USB Wacom Graphire and Wacom Intuos tablet support
10 * Sponsored by SuSE
12 * ChangeLog:
13 * v0.1 (vp) - Initial release
14 * v0.2 (aba) - Support for all buttons / combinations
15 * v0.3 (vp) - Support for Intuos added
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 * Should you need to contact me, the author, you can do so either by
34 * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
35 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
38 #include <linux/kernel.h>
39 #include <linux/malloc.h>
40 #include <linux/input.h>
41 #include <linux/module.h>
42 #include <linux/init.h>
43 #include "usb.h"
45 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
48 * Wacom Graphire packet:
50 * The input report:
52 * byte 0: report ID (2)
53 * byte 1: bit7 mouse/pen/rubber near
54 * bit5-6 0 - pen, 1 - rubber, 2 - mouse
55 * bit4 1 ?
56 * bit3 0 ?
57 * bit2 mouse middle button / pen button2
58 * bit1 mouse right button / pen button1
59 * bit0 mouse left button / pen tip / rubber
60 * byte 2: X low bits
61 * byte 3: X high bits
62 * byte 4: Y low bits
63 * byte 5: Y high bits
64 * byte 6: pen pressure low bits / mouse wheel
65 * byte 7: pen presure high bits / mouse distance
67 * There are also two single-byte feature reports (2 and 3).
69 * Resolution:
70 * X: 0 - 10206
71 * Y: 0 - 7422
73 * (0,0) is upper left corner
75 * Wacom Intuos packet:
77 * byte 0: report ID (2)
78 * byte 1: bit7 1 ?
79 * bit6 tilt (pressure?) data valid
80 * bit5 near
81 * bit4 0 ?
82 * bit3 0 ?
83 * bit2 pen button
84 * bit1 first packet (contains other infos)
85 * bit0 0 ?
86 * byte 2: X high bits
87 * byte 3: X low bits
88 * byte 4: Y high bits
89 * byte 5: Y low bits
90 * byte 6: bits 0-7: pressure (bits 2-9)
91 * byte 7: bits 6-7: pressure (bits 0-1)
92 * byte 7: bits 0-5: X tilt (bits 1-6)
93 * byte 8: bit 7: X tilt (bit 0)
94 * byte 8: bits 0-6: Y tilt (bits 0-6)
95 * byte 9: ?
98 #define USB_VENDOR_ID_WACOM 0x056a
99 #define USB_DEVICE_ID_WACOM_GRAPHIRE 0x0010
100 #define USB_DEVICE_ID_WACOM_INTUOS 0x0021
102 struct wacom {
103 signed char data[12];
104 struct input_dev dev;
105 struct urb irq;
108 static void wacom_graphire_irq(struct urb *urb)
110 struct wacom *wacom = urb->context;
111 unsigned char *data = wacom->data;
112 struct input_dev *dev = &wacom->dev;
114 if (urb->status) return;
116 if (data[0] != 2)
117 dbg("received unknown report #%d", data[0]);
119 if ( data[1] & 0x80 ) {
120 input_report_abs(dev, ABS_X, data[2] | ((__u32)data[3] << 8));
121 input_report_abs(dev, ABS_Y, 7422 - (data[4] | ((__u32)data[5] << 8)));
124 switch ((data[1] >> 5) & 3) {
126 case 0: /* Pen */
127 input_report_btn(dev, BTN_TOOL_PEN, data[1] & 0x80);
128 input_report_btn(dev, BTN_TOUCH, data[1] & 0x01);
129 input_report_btn(dev, BTN_STYLUS, data[1] & 0x02);
130 input_report_btn(dev, BTN_STYLUS2, data[1] & 0x04);
131 input_report_abs(dev, ABS_PRESSURE, data[6] | ((__u32)data[7] << 8));
132 break;
134 case 1: /* Rubber */
135 input_report_btn(dev, BTN_TOOL_RUBBER, data[1] & 0x80);
136 input_report_btn(dev, BTN_TOUCH, data[1] & 0x01);
137 input_report_btn(dev, BTN_STYLUS, data[1] & 0x02);
138 input_report_btn(dev, BTN_STYLUS2, data[1] & 0x04);
139 input_report_abs(dev, ABS_PRESSURE, data[6] | ((__u32)data[7] << 8));
140 break;
142 case 2: /* Mouse */
143 input_report_btn(dev, BTN_TOOL_MOUSE, data[7] > 24);
144 input_report_btn(dev, BTN_LEFT, data[1] & 0x01);
145 input_report_btn(dev, BTN_RIGHT, data[1] & 0x02);
146 input_report_btn(dev, BTN_MIDDLE, data[1] & 0x04);
147 input_report_abs(dev, ABS_DISTANCE, data[7]);
148 input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
149 break;
153 static void wacom_intuos_irq(struct urb *urb)
155 struct wacom *wacom = urb->context;
156 unsigned char *data = wacom->data;
157 struct input_dev *dev = &wacom->dev;
158 unsigned int t;
160 if (urb->status) return;
162 if (data[0] != 2)
163 dbg("received unknown report #%d", data[0]);
165 if (data[1] & 0x02) /* First record, weird data */
166 return;
168 if (data[1] & 0x20) { /* Near */
169 input_report_abs(dev, ABS_X, (((unsigned int) data[2]) << 8) | data[3]);
170 input_report_abs(dev, ABS_Y, 16240 - ((((unsigned int) data[4]) << 8) | data[5]));
173 input_report_btn(dev, BTN_TOOL_PEN, data[1] & 0x20);
174 input_report_btn(dev, BTN_STYLUS, data[1] & 0x04);
176 t = (((unsigned int) data[6]) << 2) | ((data[7] & 0xC0) >> 6);
178 input_report_btn(dev, BTN_TOUCH, t > 10);
179 input_report_abs(dev, ABS_PRESSURE, t);
181 if (data[1] & 0x40) { /* Tilt data */
182 input_report_abs(dev, ABS_TILT_X, ((((unsigned int) data[7]) & 0x3f) << 1) | ((data[8] & 0x80) >> 7));
183 input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f);
187 static void *wacom_probe(struct usb_device *dev, unsigned int ifnum)
189 struct usb_endpoint_descriptor *endpoint;
190 struct wacom *wacom;
191 char *name;
193 if (dev->descriptor.idVendor != USB_VENDOR_ID_WACOM ||
194 (dev->descriptor.idProduct != USB_DEVICE_ID_WACOM_GRAPHIRE &&
195 dev->descriptor.idProduct != USB_DEVICE_ID_WACOM_INTUOS))
196 return NULL;
198 endpoint = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0;
200 if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) return NULL;
201 memset(wacom, 0, sizeof(struct wacom));
203 switch (dev->descriptor.idProduct) {
205 case USB_DEVICE_ID_WACOM_GRAPHIRE:
207 wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
208 wacom->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
209 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE);
210 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
211 wacom->dev.relbit[0] |= BIT(REL_WHEEL);
212 wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_DISTANCE);
214 wacom->dev.absmax[ABS_X] = 10206;
215 wacom->dev.absmax[ABS_Y] = 7422;
216 wacom->dev.absmax[ABS_PRESSURE] = 511;
217 wacom->dev.absmax[ABS_DISTANCE] = 32;
219 FILL_INT_URB(&wacom->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress),
220 wacom->data, 8, wacom_graphire_irq, wacom, endpoint->bInterval);
222 name = "Graphire";
223 break;
225 case USB_DEVICE_ID_WACOM_INTUOS:
227 wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
228 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
229 wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
230 wacom->dev.absbit[0] |= BIT(ABS_TILT_X) | BIT(ABS_TILT_Y);
232 wacom->dev.absmax[ABS_X] = 20320;
233 wacom->dev.absmax[ABS_Y] = 16240;
234 wacom->dev.absmax[ABS_PRESSURE] = 1024;
235 wacom->dev.absmax[ABS_TILT_X] = 127;
236 wacom->dev.absmax[ABS_TILT_Y] = 127;
238 FILL_INT_URB(&wacom->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress),
239 wacom->data, 8, wacom_intuos_irq, wacom, endpoint->bInterval);
241 name = "Intuos";
242 break;
244 default:
245 return NULL;
248 if (usb_submit_urb(&wacom->irq)) {
249 kfree(wacom);
250 return NULL;
253 input_register_device(&wacom->dev);
255 printk(KERN_INFO "input%d: Wacom %s\n", wacom->dev.number, name);
257 return wacom;
260 static void wacom_disconnect(struct usb_device *dev, void *ptr)
262 struct wacom *wacom = ptr;
263 usb_unlink_urb(&wacom->irq);
264 input_unregister_device(&wacom->dev);
265 kfree(wacom);
268 static struct usb_driver wacom_driver = {
269 name: "wacom",
270 probe: wacom_probe,
271 disconnect: wacom_disconnect,
274 static int __init wacom_init(void)
276 usb_register(&wacom_driver);
277 return 0;
280 static void __exit wacom_exit(void)
282 usb_deregister(&wacom_driver);
285 module_init(wacom_init);
286 module_exit(wacom_exit);