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
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>
45 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
48 * Wacom Graphire packet:
52 * byte 0: report ID (2)
53 * byte 1: bit7 mouse/pen/rubber near
54 * bit5-6 0 - pen, 1 - rubber, 2 - mouse
57 * bit2 mouse middle button / pen button2
58 * bit1 mouse right button / pen button1
59 * bit0 mouse left button / pen tip / rubber
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).
73 * (0,0) is upper left corner
75 * Wacom Intuos packet:
77 * byte 0: report ID (2)
79 * bit6 tilt (pressure?) data valid
84 * bit1 first packet (contains other infos)
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)
98 #define USB_VENDOR_ID_WACOM 0x056a
99 #define USB_DEVICE_ID_WACOM_GRAPHIRE 0x0010
100 #define USB_DEVICE_ID_WACOM_INTUOS 0x0021
103 signed char data
[12];
104 struct input_dev dev
;
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;
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) {
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));
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));
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]);
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
;
160 if (urb
->status
) return;
163 dbg("received unknown report #%d", data
[0]);
165 if (data
[1] & 0x02) /* First record, weird data */
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
;
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
))
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
);
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
);
248 if (usb_submit_urb(&wacom
->irq
)) {
253 input_register_device(&wacom
->dev
);
255 printk(KERN_INFO
"input%d: Wacom %s\n", wacom
->dev
.number
, name
);
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
);
268 static struct usb_driver wacom_driver
= {
271 disconnect
: wacom_disconnect
,
274 static int __init
wacom_init(void)
276 usb_register(&wacom_driver
);
280 static void __exit
wacom_exit(void)
282 usb_deregister(&wacom_driver
);
285 module_init(wacom_init
);
286 module_exit(wacom_exit
);