aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/input/wacom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/input/wacom.c')
-rw-r--r--drivers/usb/input/wacom.c398
1 files changed, 171 insertions, 227 deletions
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
index fec04dda088e..f6b34af66b3d 100644
--- a/drivers/usb/input/wacom.c
+++ b/drivers/usb/input/wacom.c
@@ -9,7 +9,7 @@
9 * Copyright (c) 2000 Daniel Egger <egger@suse.de> 9 * Copyright (c) 2000 Daniel Egger <egger@suse.de>
10 * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> 10 * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com>
11 * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> 11 * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be>
12 * Copyright (c) 2002-2004 Ping Cheng <pingc@wacom.com> 12 * Copyright (c) 2002-2005 Ping Cheng <pingc@wacom.com>
13 * 13 *
14 * ChangeLog: 14 * ChangeLog:
15 * v0.1 (vp) - Initial release 15 * v0.1 (vp) - Initial release
@@ -18,7 +18,7 @@
18 * v0.4 (sm) - Support for more Intuos models, menustrip 18 * v0.4 (sm) - Support for more Intuos models, menustrip
19 * relative mode, proximity. 19 * relative mode, proximity.
20 * v0.5 (vp) - Big cleanup, nifty features removed, 20 * v0.5 (vp) - Big cleanup, nifty features removed,
21 * they belong in userspace 21 * they belong in userspace
22 * v1.8 (vp) - Submit URB only when operating, moved to CVS, 22 * v1.8 (vp) - Submit URB only when operating, moved to CVS,
23 * use input_report_key instead of report_btn and 23 * use input_report_key instead of report_btn and
24 * other cleanups 24 * other cleanups
@@ -51,6 +51,9 @@
51 * - Cleanups here and there 51 * - Cleanups here and there
52 * v1.30.1 (pi) - Added Graphire3 support 52 * v1.30.1 (pi) - Added Graphire3 support
53 * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... 53 * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ...
54 * v1.43 (pc) - Added support for Cintiq 21UX
55 - Fixed a Graphire bug
56 - Merged wacom_intuos3_irq into wacom_intuos_irq
54 */ 57 */
55 58
56/* 59/*
@@ -72,7 +75,7 @@
72/* 75/*
73 * Version Information 76 * Version Information
74 */ 77 */
75#define DRIVER_VERSION "v1.40" 78#define DRIVER_VERSION "v1.43"
76#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" 79#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
77#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" 80#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
78#define DRIVER_LICENSE "GPL" 81#define DRIVER_LICENSE "GPL"
@@ -83,6 +86,16 @@ MODULE_LICENSE(DRIVER_LICENSE);
83 86
84#define USB_VENDOR_ID_WACOM 0x056a 87#define USB_VENDOR_ID_WACOM 0x056a
85 88
89enum {
90 PENPARTNER = 0,
91 GRAPHIRE,
92 PL,
93 INTUOS,
94 INTUOS3,
95 CINTIQ,
96 MAX_TYPE
97};
98
86struct wacom_features { 99struct wacom_features {
87 char *name; 100 char *name;
88 int pktlen; 101 int pktlen;
@@ -102,7 +115,6 @@ struct wacom {
102 struct urb *irq; 115 struct urb *irq;
103 struct wacom_features *features; 116 struct wacom_features *features;
104 int tool[2]; 117 int tool[2];
105 int open;
106 __u32 serial[2]; 118 __u32 serial[2];
107 char phys[32]; 119 char phys[32];
108}; 120};
@@ -149,7 +161,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
149 prox = data[1] & 0x40; 161 prox = data[1] & 0x40;
150 162
151 input_regs(dev, regs); 163 input_regs(dev, regs);
152 164
153 if (prox) { 165 if (prox) {
154 166
155 pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); 167 pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
@@ -166,8 +178,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
166 if (!wacom->tool[0]) { 178 if (!wacom->tool[0]) {
167 /* Going into proximity select tool */ 179 /* Going into proximity select tool */
168 wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN; 180 wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
169 } 181 } else {
170 else {
171 /* was entered with stylus2 pressed */ 182 /* was entered with stylus2 pressed */
172 if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) { 183 if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) {
173 /* report out proximity for previous tool */ 184 /* report out proximity for previous tool */
@@ -182,16 +193,15 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
182 wacom->tool[1] = BTN_TOOL_PEN; 193 wacom->tool[1] = BTN_TOOL_PEN;
183 } 194 }
184 input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */ 195 input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */
185 input_report_abs(dev, ABS_X, data[3] | ((__u32)data[2] << 7) | ((__u32)(data[1] & 0x03) << 14)); 196 input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
186 input_report_abs(dev, ABS_Y, data[6] | ((__u32)data[5] << 7) | ((__u32)(data[4] & 0x03) << 14)); 197 input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
187 input_report_abs(dev, ABS_PRESSURE, pressure); 198 input_report_abs(dev, ABS_PRESSURE, pressure);
188 199
189 input_report_key(dev, BTN_TOUCH, data[4] & 0x08); 200 input_report_key(dev, BTN_TOUCH, data[4] & 0x08);
190 input_report_key(dev, BTN_STYLUS, data[4] & 0x10); 201 input_report_key(dev, BTN_STYLUS, data[4] & 0x10);
191 /* Only allow the stylus2 button to be reported for the pen tool. */ 202 /* Only allow the stylus2 button to be reported for the pen tool. */
192 input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20)); 203 input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));
193 } 204 } else {
194 else {
195 /* report proximity-out of a (valid) tool */ 205 /* report proximity-out of a (valid) tool */
196 if (wacom->tool[1] != BTN_TOOL_RUBBER) { 206 if (wacom->tool[1] != BTN_TOOL_RUBBER) {
197 /* Unknown tool selected default to pen tool */ 207 /* Unknown tool selected default to pen tool */
@@ -203,7 +213,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
203 wacom->tool[0] = prox; /* Save proximity state */ 213 wacom->tool[0] = prox; /* Save proximity state */
204 input_sync(dev); 214 input_sync(dev);
205 215
206exit: 216 exit:
207 retval = usb_submit_urb (urb, GFP_ATOMIC); 217 retval = usb_submit_urb (urb, GFP_ATOMIC);
208 if (retval) 218 if (retval)
209 err ("%s - usb_submit_urb failed with result %d", 219 err ("%s - usb_submit_urb failed with result %d",
@@ -232,20 +242,16 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs)
232 goto exit; 242 goto exit;
233 } 243 }
234 244
235 if (data[0] != 2) 245 if (data[0] != 2) {
236 {
237 printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); 246 printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
238 goto exit; 247 goto exit;
239 } 248 }
240 249
241 input_regs(dev, regs); 250 input_regs(dev, regs);
242 if (data[1] & 0x04) 251 if (data[1] & 0x04) {
243 {
244 input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20); 252 input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20);
245 input_report_key(dev, BTN_TOUCH, data[1] & 0x08); 253 input_report_key(dev, BTN_TOUCH, data[1] & 0x08);
246 } 254 } else {
247 else
248 {
249 input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20); 255 input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20);
250 input_report_key(dev, BTN_TOUCH, data[1] & 0x01); 256 input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
251 } 257 }
@@ -257,7 +263,7 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs)
257 263
258 input_sync(dev); 264 input_sync(dev);
259 265
260exit: 266 exit:
261 retval = usb_submit_urb (urb, GFP_ATOMIC); 267 retval = usb_submit_urb (urb, GFP_ATOMIC);
262 if (retval) 268 if (retval)
263 err ("%s - usb_submit_urb failed with result %d", 269 err ("%s - usb_submit_urb failed with result %d",
@@ -300,7 +306,7 @@ static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs)
300 input_report_key(dev, BTN_STYLUS, (data[5] & 0x40)); 306 input_report_key(dev, BTN_STYLUS, (data[5] & 0x40));
301 input_sync(dev); 307 input_sync(dev);
302 308
303exit: 309 exit:
304 retval = usb_submit_urb (urb, GFP_ATOMIC); 310 retval = usb_submit_urb (urb, GFP_ATOMIC);
305 if (retval) 311 if (retval)
306 err ("%s - usb_submit_urb failed with result %d", 312 err ("%s - usb_submit_urb failed with result %d",
@@ -340,47 +346,47 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
340 346
341 input_regs(dev, regs); 347 input_regs(dev, regs);
342 348
343 switch ((data[1] >> 5) & 3) { 349 if (data[1] & 0x10) { /* in prox */
344 350
345 case 0: /* Pen */ 351 switch ((data[1] >> 5) & 3) {
346 input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x80);
347 break;
348 352
349 case 1: /* Rubber */ 353 case 0: /* Pen */
350 input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x80); 354 wacom->tool[0] = BTN_TOOL_PEN;
351 break; 355 break;
352
353 case 2: /* Mouse with wheel */
354 input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
355 input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
356 /* fall through */
357 356
358 case 3: /* Mouse without wheel */ 357 case 1: /* Rubber */
359 input_report_key(dev, BTN_TOOL_MOUSE, data[7] > 24); 358 wacom->tool[0] = BTN_TOOL_RUBBER;
360 input_report_key(dev, BTN_LEFT, data[1] & 0x01); 359 break;
361 input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
362 input_report_abs(dev, ABS_DISTANCE, data[7]);
363 360
364 input_report_abs(dev, ABS_X, x); 361 case 2: /* Mouse with wheel */
365 input_report_abs(dev, ABS_Y, y); 362 input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
363 input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
364 /* fall through */
366 365
367 input_sync(dev); 366 case 3: /* Mouse without wheel */
368 goto exit; 367 wacom->tool[0] = BTN_TOOL_MOUSE;
368 input_report_key(dev, BTN_LEFT, data[1] & 0x01);
369 input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
370 input_report_abs(dev, ABS_DISTANCE, data[7]);
371 break;
372 }
369 } 373 }
370 374
371 if (data[1] & 0x80) { 375 if (data[1] & 0x80) {
372 input_report_abs(dev, ABS_X, x); 376 input_report_abs(dev, ABS_X, x);
373 input_report_abs(dev, ABS_Y, y); 377 input_report_abs(dev, ABS_Y, y);
374 } 378 }
379 if (wacom->tool[0] != BTN_TOOL_MOUSE) {
380 input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6]));
381 input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
382 input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
383 input_report_key(dev, BTN_STYLUS2, data[1] & 0x04);
384 }
375 385
376 input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6])); 386 input_report_key(dev, wacom->tool[0], data[1] & 0x10);
377 input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
378 input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
379 input_report_key(dev, BTN_STYLUS2, data[1] & 0x04);
380
381 input_sync(dev); 387 input_sync(dev);
382 388
383exit: 389 exit:
384 retval = usb_submit_urb (urb, GFP_ATOMIC); 390 retval = usb_submit_urb (urb, GFP_ATOMIC);
385 if (retval) 391 if (retval)
386 err ("%s - usb_submit_urb failed with result %d", 392 err ("%s - usb_submit_urb failed with result %d",
@@ -398,14 +404,13 @@ static int wacom_intuos_inout(struct urb *urb)
398 idx = data[1] & 0x01; 404 idx = data[1] & 0x01;
399 405
400 /* Enter report */ 406 /* Enter report */
401 if ((data[1] & 0xfc) == 0xc0) 407 if ((data[1] & 0xfc) == 0xc0) {
402 {
403 /* serial number of the tool */ 408 /* serial number of the tool */
404 wacom->serial[idx] = ((__u32)(data[3] & 0x0f) << 28) + 409 wacom->serial[idx] = ((data[3] & 0x0f) << 28) +
405 ((__u32)data[4] << 20) + ((__u32)data[5] << 12) + 410 (data[4] << 20) + (data[5] << 12) +
406 ((__u32)data[6] << 4) + (data[7] >> 4); 411 (data[6] << 4) + (data[7] >> 4);
407 412
408 switch (((__u32)data[2] << 4) | (data[3] >> 4)) { 413 switch ((data[2] << 4) | (data[3] >> 4)) {
409 case 0x812: /* Inking pen */ 414 case 0x812: /* Inking pen */
410 case 0x801: /* Intuos3 Inking pen */ 415 case 0x801: /* Intuos3 Inking pen */
411 case 0x012: 416 case 0x012:
@@ -449,7 +454,7 @@ static int wacom_intuos_inout(struct urb *urb)
449 case 0x112: 454 case 0x112:
450 case 0x913: /* Intuos3 Airbrush */ 455 case 0x913: /* Intuos3 Airbrush */
451 wacom->tool[idx] = BTN_TOOL_AIRBRUSH; 456 wacom->tool[idx] = BTN_TOOL_AIRBRUSH;
452 break; /* Airbrush */ 457 break;
453 default: /* Unknown tool */ 458 default: /* Unknown tool */
454 wacom->tool[idx] = BTN_TOOL_PEN; 459 wacom->tool[idx] = BTN_TOOL_PEN;
455 } 460 }
@@ -478,9 +483,8 @@ static void wacom_intuos_general(struct urb *urb)
478 unsigned int t; 483 unsigned int t;
479 484
480 /* general pen packet */ 485 /* general pen packet */
481 if ((data[1] & 0xb8) == 0xa0) 486 if ((data[1] & 0xb8) == 0xa0) {
482 { 487 t = (data[6] << 2) | ((data[7] >> 6) & 3);
483 t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3);
484 input_report_abs(dev, ABS_PRESSURE, t); 488 input_report_abs(dev, ABS_PRESSURE, t);
485 input_report_abs(dev, ABS_TILT_X, 489 input_report_abs(dev, ABS_TILT_X,
486 ((data[7] << 1) & 0x7e) | (data[8] >> 7)); 490 ((data[7] << 1) & 0x7e) | (data[8] >> 7));
@@ -491,10 +495,9 @@ static void wacom_intuos_general(struct urb *urb)
491 } 495 }
492 496
493 /* airbrush second packet */ 497 /* airbrush second packet */
494 if ((data[1] & 0xbc) == 0xb4) 498 if ((data[1] & 0xbc) == 0xb4) {
495 {
496 input_report_abs(dev, ABS_WHEEL, 499 input_report_abs(dev, ABS_WHEEL,
497 ((__u32)data[6] << 2) | ((data[7] >> 6) & 3)); 500 (data[6] << 2) | ((data[7] >> 6) & 3));
498 input_report_abs(dev, ABS_TILT_X, 501 input_report_abs(dev, ABS_TILT_X,
499 ((data[7] << 1) & 0x7e) | (data[8] >> 7)); 502 ((data[7] << 1) & 0x7e) | (data[8] >> 7));
500 input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); 503 input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f);
@@ -526,7 +529,7 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs)
526 goto exit; 529 goto exit;
527 } 530 }
528 531
529 if (data[0] != 2 && data[0] != 5 && data[0] != 6) { 532 if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) {
530 dbg("wacom_intuos_irq: received unknown report #%d", data[0]); 533 dbg("wacom_intuos_irq: received unknown report #%d", data[0]);
531 goto exit; 534 goto exit;
532 } 535 }
@@ -536,107 +539,10 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs)
536 /* tool number */ 539 /* tool number */
537 idx = data[1] & 0x01; 540 idx = data[1] & 0x01;
538 541
539 /* process in/out prox events */
540 if (wacom_intuos_inout(urb)) goto exit;
541
542 input_report_abs(dev, ABS_X, be16_to_cpu(*(__be16 *) &data[2]));
543 input_report_abs(dev, ABS_Y, be16_to_cpu(*(__be16 *) &data[4]));
544 input_report_abs(dev, ABS_DISTANCE, data[9]);
545
546 /* process general packets */
547 wacom_intuos_general(urb);
548
549 if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) { /* 4D mouse or Lens cursor packets */
550
551 if (data[1] & 0x02) { /* Rotation packet */
552
553 t = ((__u32)data[6] << 3) | ((data[7] >> 5) & 7);
554 input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ? ((t - 1) / 2) : -t / 2);
555
556 } else {
557
558 if ((data[1] & 0x10) == 0) { /* 4D mouse packets */
559
560 input_report_key(dev, BTN_LEFT, data[8] & 0x01);
561 input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
562 input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
563
564 input_report_key(dev, BTN_SIDE, data[8] & 0x20);
565 input_report_key(dev, BTN_EXTRA, data[8] & 0x10);
566 t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3);
567 input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
568
569 } else {
570 if (wacom->tool[idx] == BTN_TOOL_MOUSE) { /* 2D mouse packets */
571 input_report_key(dev, BTN_LEFT, data[8] & 0x04);
572 input_report_key(dev, BTN_MIDDLE, data[8] & 0x08);
573 input_report_key(dev, BTN_RIGHT, data[8] & 0x10);
574 input_report_rel(dev, REL_WHEEL,
575 (-(__u32)(data[8] & 0x01) + (__u32)((data[8] & 0x02) >> 1)));
576 }
577 else { /* Lens cursor packets */
578 input_report_key(dev, BTN_LEFT, data[8] & 0x01);
579 input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
580 input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
581 input_report_key(dev, BTN_SIDE, data[8] & 0x10);
582 input_report_key(dev, BTN_EXTRA, data[8] & 0x08);
583 }
584 }
585 }
586 }
587
588 input_report_key(dev, wacom->tool[idx], 1);
589 input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
590 input_sync(dev);
591
592exit:
593 retval = usb_submit_urb (urb, GFP_ATOMIC);
594 if (retval)
595 err ("%s - usb_submit_urb failed with result %d",
596 __FUNCTION__, retval);
597}
598
599static void wacom_intuos3_irq(struct urb *urb, struct pt_regs *regs)
600{
601 struct wacom *wacom = urb->context;
602 unsigned char *data = wacom->data;
603 struct input_dev *dev = &wacom->dev;
604 unsigned int t;
605 int idx, retval;
606
607 switch (urb->status) {
608 case 0:
609 /* success */
610 break;
611 case -ECONNRESET:
612 case -ENOENT:
613 case -ESHUTDOWN:
614 /* this urb is terminated, clean up */
615 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
616 return;
617 default:
618 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
619 goto exit;
620 }
621
622 /* check for valid report */
623 if (data[0] != 2 && data[0] != 5 && data[0] != 12)
624 {
625 printk(KERN_INFO "wacom_intuos3_irq: received unknown report #%d\n", data[0]);
626 goto exit;
627 }
628
629 input_regs(dev, regs);
630
631 /* tool index is always 0 here since there is no dual input tool */
632 idx = data[1] & 0x01;
633
634 /* pad packets. Works as a second tool and is always in prox */ 542 /* pad packets. Works as a second tool and is always in prox */
635 if (data[0] == 12) 543 if (data[0] == 12) {
636 {
637 /* initiate the pad as a device */ 544 /* initiate the pad as a device */
638 if (wacom->tool[1] != BTN_TOOL_FINGER) 545 if (wacom->tool[1] != BTN_TOOL_FINGER) {
639 {
640 wacom->tool[1] = BTN_TOOL_FINGER; 546 wacom->tool[1] = BTN_TOOL_FINGER;
641 input_report_key(dev, wacom->tool[1], 1); 547 input_report_key(dev, wacom->tool[1], 1);
642 } 548 }
@@ -656,37 +562,78 @@ static void wacom_intuos3_irq(struct urb *urb, struct pt_regs *regs)
656 } 562 }
657 563
658 /* process in/out prox events */ 564 /* process in/out prox events */
659 if (wacom_intuos_inout(urb)) goto exit; 565 if (wacom_intuos_inout(urb))
566 goto exit;
660 567
661 input_report_abs(dev, ABS_X, ((__u32)data[2] << 9) | ((__u32)data[3] << 1) | ((data[9] >> 1) & 1)); 568 /* Cintiq doesn't send data when RDY bit isn't set */
662 input_report_abs(dev, ABS_Y, ((__u32)data[4] << 9) | ((__u32)data[5] << 1) | (data[9] & 1)); 569 if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40))
663 input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); 570 return;
571
572 if (wacom->features->type >= INTUOS3) {
573 input_report_abs(dev, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
574 input_report_abs(dev, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
575 input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
576 } else {
577 input_report_abs(dev, ABS_X, be16_to_cpu(*(__be16 *) &data[2]));
578 input_report_abs(dev, ABS_Y, be16_to_cpu(*(__be16 *) &data[4]));
579 input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 3) & 0x1f));
580 }
664 581
665 /* process general packets */ 582 /* process general packets */
666 wacom_intuos_general(urb); 583 wacom_intuos_general(urb);
667 584
668 if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) 585 /* 4D mouse, 2D mouse, marker pen rotation, or Lens cursor packets */
669 { 586 if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) {
670 /* Marker pen rotation packet. Reported as wheel due to valuator limitation */ 587
671 if (data[1] & 0x02) 588 if (data[1] & 0x02) {
672 { 589 /* Rotation packet */
673 t = ((__u32)data[6] << 3) | ((data[7] >> 5) & 7); 590 if (wacom->features->type >= INTUOS3) {
674 t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : 591 /* I3 marker pen rotation reported as wheel
675 ((t-1) / 2 + 450)) : (450 - t / 2) ; 592 * due to valuator limitation
676 input_report_abs(dev, ABS_WHEEL, t); 593 */
677 } 594 t = (data[6] << 3) | ((data[7] >> 5) & 7);
595 t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
596 ((t-1) / 2 + 450)) : (450 - t / 2) ;
597 input_report_abs(dev, ABS_WHEEL, t);
598 } else {
599 /* 4D mouse rotation packet */
600 t = (data[6] << 3) | ((data[7] >> 5) & 7);
601 input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ?
602 ((t - 1) / 2) : -t / 2);
603 }
678 604
679 /* 2D mouse packets */ 605 } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3) {
680 if (wacom->tool[idx] == BTN_TOOL_MOUSE) 606 /* 4D mouse packet */
681 { 607 input_report_key(dev, BTN_LEFT, data[8] & 0x01);
608 input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
609 input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
610
611 input_report_key(dev, BTN_SIDE, data[8] & 0x20);
612 input_report_key(dev, BTN_EXTRA, data[8] & 0x10);
613 t = (data[6] << 2) | ((data[7] >> 6) & 3);
614 input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
615
616 } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
617 /* 2D mouse packet */
682 input_report_key(dev, BTN_LEFT, data[8] & 0x04); 618 input_report_key(dev, BTN_LEFT, data[8] & 0x04);
683 input_report_key(dev, BTN_MIDDLE, data[8] & 0x08); 619 input_report_key(dev, BTN_MIDDLE, data[8] & 0x08);
684 input_report_key(dev, BTN_RIGHT, data[8] & 0x10); 620 input_report_key(dev, BTN_RIGHT, data[8] & 0x10);
685 input_report_key(dev, BTN_SIDE, data[8] & 0x40); 621 input_report_rel(dev, REL_WHEEL, ((data[8] & 0x02) >> 1)
686 input_report_key(dev, BTN_EXTRA, data[8] & 0x20); 622 - (data[8] & 0x01));
687 /* mouse wheel is positive when rolled backwards */ 623
688 input_report_rel(dev, REL_WHEEL, ((__u32)((data[8] & 0x02) >> 1) 624 /* I3 2D mouse side buttons */
689 - (__u32)(data[8] & 0x01))); 625 if (wacom->features->type == INTUOS3) {
626 input_report_key(dev, BTN_SIDE, data[8] & 0x40);
627 input_report_key(dev, BTN_EXTRA, data[8] & 0x20);
628 }
629
630 } else if (wacom->features->type < INTUOS3) {
631 /* Lens cursor packets */
632 input_report_key(dev, BTN_LEFT, data[8] & 0x01);
633 input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
634 input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
635 input_report_key(dev, BTN_SIDE, data[8] & 0x10);
636 input_report_key(dev, BTN_EXTRA, data[8] & 0x08);
690 } 637 }
691 } 638 }
692 639
@@ -702,35 +649,36 @@ exit:
702} 649}
703 650
704static struct wacom_features wacom_features[] = { 651static struct wacom_features wacom_features[] = {
705 { "Wacom Penpartner", 7, 5040, 3780, 255, 32, 0, wacom_penpartner_irq }, 652 { "Wacom Penpartner", 7, 5040, 3780, 255, 32, PENPARTNER, wacom_penpartner_irq },
706 { "Wacom Graphire", 8, 10206, 7422, 511, 32, 1, wacom_graphire_irq }, 653 { "Wacom Graphire", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_graphire_irq },
707 { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, 1, wacom_graphire_irq }, 654 { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_graphire_irq },
708 { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, 1, wacom_graphire_irq }, 655 { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_graphire_irq },
709 { "Wacom Graphire3", 8, 10208, 7424, 511, 32, 1, wacom_graphire_irq }, 656 { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_graphire_irq },
710 { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, 1, wacom_graphire_irq }, 657 { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_graphire_irq },
711 { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, 2, wacom_intuos_irq }, 658 { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq },
712 { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq }, 659 { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
713 { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, 2, wacom_intuos_irq }, 660 { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq },
714 { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15, 2, wacom_intuos_irq }, 661 { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
715 { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, 2, wacom_intuos_irq }, 662 { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
716 { "Wacom PL400", 8, 5408, 4056, 255, 32, 3, wacom_pl_irq }, 663 { "Wacom PL400", 8, 5408, 4056, 255, 32, PL, wacom_pl_irq },
717 { "Wacom PL500", 8, 6144, 4608, 255, 32, 3, wacom_pl_irq }, 664 { "Wacom PL500", 8, 6144, 4608, 255, 32, PL, wacom_pl_irq },
718 { "Wacom PL600", 8, 6126, 4604, 255, 32, 3, wacom_pl_irq }, 665 { "Wacom PL600", 8, 6126, 4604, 255, 32, PL, wacom_pl_irq },
719 { "Wacom PL600SX", 8, 6260, 5016, 255, 32, 3, wacom_pl_irq }, 666 { "Wacom PL600SX", 8, 6260, 5016, 255, 32, PL, wacom_pl_irq },
720 { "Wacom PL550", 8, 6144, 4608, 511, 32, 3, wacom_pl_irq }, 667 { "Wacom PL550", 8, 6144, 4608, 511, 32, PL, wacom_pl_irq },
721 { "Wacom PL800", 8, 7220, 5780, 511, 32, 3, wacom_pl_irq }, 668 { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_pl_irq },
722 { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, 2, wacom_intuos_irq }, 669 { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq },
723 { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq }, 670 { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
724 { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, 2, wacom_intuos_irq }, 671 { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq },
725 { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, 2, wacom_intuos_irq }, 672 { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
726 { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, 2, wacom_intuos_irq }, 673 { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
727 { "Wacom Volito", 8, 5104, 3712, 511, 32, 1, wacom_graphire_irq }, 674 { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq },
728 { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, 3, wacom_ptu_irq }, 675 { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PL, wacom_ptu_irq },
729 { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, 4, wacom_intuos3_irq }, 676 { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_intuos_irq },
730 { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, 4, wacom_intuos3_irq }, 677 { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_intuos_irq },
731 { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, 4, wacom_intuos3_irq }, 678 { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_intuos_irq },
732 { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq }, 679 { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_intuos_irq },
733 { } 680 { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
681 { }
734}; 682};
735 683
736static struct usb_device_id wacom_ids[] = { 684static struct usb_device_id wacom_ids[] = {
@@ -761,6 +709,7 @@ static struct usb_device_id wacom_ids[] = {
761 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, 709 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) },
762 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, 710 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) },
763 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, 711 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) },
712 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) },
764 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, 713 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
765 { } 714 { }
766}; 715};
@@ -771,14 +720,9 @@ static int wacom_open(struct input_dev *dev)
771{ 720{
772 struct wacom *wacom = dev->private; 721 struct wacom *wacom = dev->private;
773 722
774 if (wacom->open++)
775 return 0;
776
777 wacom->irq->dev = wacom->usbdev; 723 wacom->irq->dev = wacom->usbdev;
778 if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { 724 if (usb_submit_urb(wacom->irq, GFP_KERNEL))
779 wacom->open--;
780 return -EIO; 725 return -EIO;
781 }
782 726
783 return 0; 727 return 0;
784} 728}
@@ -787,8 +731,7 @@ static void wacom_close(struct input_dev *dev)
787{ 731{
788 struct wacom *wacom = dev->private; 732 struct wacom *wacom = dev->private;
789 733
790 if (!--wacom->open) 734 usb_kill_urb(wacom->irq);
791 usb_kill_urb(wacom->irq);
792} 735}
793 736
794static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) 737static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -823,32 +766,33 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
823 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS); 766 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
824 767
825 switch (wacom->features->type) { 768 switch (wacom->features->type) {
826 case 1: 769 case GRAPHIRE:
827 wacom->dev.evbit[0] |= BIT(EV_REL); 770 wacom->dev.evbit[0] |= BIT(EV_REL);
828 wacom->dev.relbit[0] |= BIT(REL_WHEEL); 771 wacom->dev.relbit[0] |= BIT(REL_WHEEL);
829 wacom->dev.absbit[0] |= BIT(ABS_DISTANCE); 772 wacom->dev.absbit[0] |= BIT(ABS_DISTANCE);
830 wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); 773 wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
831 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); 774 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
832 break; 775 break;
833 776
834 case 4: /* new functions for Intuos3 */ 777 case INTUOS3:
778 case CINTIQ:
835 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); 779 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
836 wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); 780 wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
837 wacom->dev.absbit[0] |= BIT(ABS_RX) | BIT(ABS_RY); 781 wacom->dev.absbit[0] |= BIT(ABS_RX) | BIT(ABS_RY);
838 /* fall through */ 782 /* fall through */
839 783
840 case 2: 784 case INTUOS:
841 wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); 785 wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
842 wacom->dev.mscbit[0] |= BIT(MSC_SERIAL); 786 wacom->dev.mscbit[0] |= BIT(MSC_SERIAL);
843 wacom->dev.relbit[0] |= BIT(REL_WHEEL); 787 wacom->dev.relbit[0] |= BIT(REL_WHEEL);
844 wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); 788 wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
845 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) 789 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH)
846 | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); 790 | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2);
847 wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE); 791 wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE);
848 break; 792 break;
849 793
850 case 3: 794 case PL:
851 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER); 795 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
852 break; 796 break;
853 } 797 }
854 798