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.c404
1 files changed, 173 insertions, 231 deletions
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
index fec04dda088e..02412e31a46b 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/*
@@ -66,13 +69,14 @@
66#include <linux/module.h> 69#include <linux/module.h>
67#include <linux/init.h> 70#include <linux/init.h>
68#include <linux/usb.h> 71#include <linux/usb.h>
72#include <linux/usb_input.h>
69#include <asm/unaligned.h> 73#include <asm/unaligned.h>
70#include <asm/byteorder.h> 74#include <asm/byteorder.h>
71 75
72/* 76/*
73 * Version Information 77 * Version Information
74 */ 78 */
75#define DRIVER_VERSION "v1.40" 79#define DRIVER_VERSION "v1.43"
76#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" 80#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
77#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" 81#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
78#define DRIVER_LICENSE "GPL" 82#define DRIVER_LICENSE "GPL"
@@ -83,6 +87,16 @@ MODULE_LICENSE(DRIVER_LICENSE);
83 87
84#define USB_VENDOR_ID_WACOM 0x056a 88#define USB_VENDOR_ID_WACOM 0x056a
85 89
90enum {
91 PENPARTNER = 0,
92 GRAPHIRE,
93 PL,
94 INTUOS,
95 INTUOS3,
96 CINTIQ,
97 MAX_TYPE
98};
99
86struct wacom_features { 100struct wacom_features {
87 char *name; 101 char *name;
88 int pktlen; 102 int pktlen;
@@ -102,7 +116,6 @@ struct wacom {
102 struct urb *irq; 116 struct urb *irq;
103 struct wacom_features *features; 117 struct wacom_features *features;
104 int tool[2]; 118 int tool[2];
105 int open;
106 __u32 serial[2]; 119 __u32 serial[2];
107 char phys[32]; 120 char phys[32];
108}; 121};
@@ -149,7 +162,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
149 prox = data[1] & 0x40; 162 prox = data[1] & 0x40;
150 163
151 input_regs(dev, regs); 164 input_regs(dev, regs);
152 165
153 if (prox) { 166 if (prox) {
154 167
155 pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); 168 pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
@@ -166,8 +179,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
166 if (!wacom->tool[0]) { 179 if (!wacom->tool[0]) {
167 /* Going into proximity select tool */ 180 /* Going into proximity select tool */
168 wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN; 181 wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
169 } 182 } else {
170 else {
171 /* was entered with stylus2 pressed */ 183 /* was entered with stylus2 pressed */
172 if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) { 184 if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) {
173 /* report out proximity for previous tool */ 185 /* report out proximity for previous tool */
@@ -182,16 +194,15 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
182 wacom->tool[1] = BTN_TOOL_PEN; 194 wacom->tool[1] = BTN_TOOL_PEN;
183 } 195 }
184 input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */ 196 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)); 197 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)); 198 input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
187 input_report_abs(dev, ABS_PRESSURE, pressure); 199 input_report_abs(dev, ABS_PRESSURE, pressure);
188 200
189 input_report_key(dev, BTN_TOUCH, data[4] & 0x08); 201 input_report_key(dev, BTN_TOUCH, data[4] & 0x08);
190 input_report_key(dev, BTN_STYLUS, data[4] & 0x10); 202 input_report_key(dev, BTN_STYLUS, data[4] & 0x10);
191 /* Only allow the stylus2 button to be reported for the pen tool. */ 203 /* 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)); 204 input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));
193 } 205 } else {
194 else {
195 /* report proximity-out of a (valid) tool */ 206 /* report proximity-out of a (valid) tool */
196 if (wacom->tool[1] != BTN_TOOL_RUBBER) { 207 if (wacom->tool[1] != BTN_TOOL_RUBBER) {
197 /* Unknown tool selected default to pen tool */ 208 /* Unknown tool selected default to pen tool */
@@ -203,7 +214,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
203 wacom->tool[0] = prox; /* Save proximity state */ 214 wacom->tool[0] = prox; /* Save proximity state */
204 input_sync(dev); 215 input_sync(dev);
205 216
206exit: 217 exit:
207 retval = usb_submit_urb (urb, GFP_ATOMIC); 218 retval = usb_submit_urb (urb, GFP_ATOMIC);
208 if (retval) 219 if (retval)
209 err ("%s - usb_submit_urb failed with result %d", 220 err ("%s - usb_submit_urb failed with result %d",
@@ -232,20 +243,16 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs)
232 goto exit; 243 goto exit;
233 } 244 }
234 245
235 if (data[0] != 2) 246 if (data[0] != 2) {
236 {
237 printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); 247 printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
238 goto exit; 248 goto exit;
239 } 249 }
240 250
241 input_regs(dev, regs); 251 input_regs(dev, regs);
242 if (data[1] & 0x04) 252 if (data[1] & 0x04) {
243 {
244 input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20); 253 input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20);
245 input_report_key(dev, BTN_TOUCH, data[1] & 0x08); 254 input_report_key(dev, BTN_TOUCH, data[1] & 0x08);
246 } 255 } else {
247 else
248 {
249 input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20); 256 input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20);
250 input_report_key(dev, BTN_TOUCH, data[1] & 0x01); 257 input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
251 } 258 }
@@ -257,7 +264,7 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs)
257 264
258 input_sync(dev); 265 input_sync(dev);
259 266
260exit: 267 exit:
261 retval = usb_submit_urb (urb, GFP_ATOMIC); 268 retval = usb_submit_urb (urb, GFP_ATOMIC);
262 if (retval) 269 if (retval)
263 err ("%s - usb_submit_urb failed with result %d", 270 err ("%s - usb_submit_urb failed with result %d",
@@ -300,7 +307,7 @@ static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs)
300 input_report_key(dev, BTN_STYLUS, (data[5] & 0x40)); 307 input_report_key(dev, BTN_STYLUS, (data[5] & 0x40));
301 input_sync(dev); 308 input_sync(dev);
302 309
303exit: 310 exit:
304 retval = usb_submit_urb (urb, GFP_ATOMIC); 311 retval = usb_submit_urb (urb, GFP_ATOMIC);
305 if (retval) 312 if (retval)
306 err ("%s - usb_submit_urb failed with result %d", 313 err ("%s - usb_submit_urb failed with result %d",
@@ -340,47 +347,47 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
340 347
341 input_regs(dev, regs); 348 input_regs(dev, regs);
342 349
343 switch ((data[1] >> 5) & 3) { 350 if (data[1] & 0x10) { /* in prox */
344 351
345 case 0: /* Pen */ 352 switch ((data[1] >> 5) & 3) {
346 input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x80);
347 break;
348 353
349 case 1: /* Rubber */ 354 case 0: /* Pen */
350 input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x80); 355 wacom->tool[0] = BTN_TOOL_PEN;
351 break; 356 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 357
358 case 3: /* Mouse without wheel */ 358 case 1: /* Rubber */
359 input_report_key(dev, BTN_TOOL_MOUSE, data[7] > 24); 359 wacom->tool[0] = BTN_TOOL_RUBBER;
360 input_report_key(dev, BTN_LEFT, data[1] & 0x01); 360 break;
361 input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
362 input_report_abs(dev, ABS_DISTANCE, data[7]);
363 361
364 input_report_abs(dev, ABS_X, x); 362 case 2: /* Mouse with wheel */
365 input_report_abs(dev, ABS_Y, y); 363 input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
364 input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
365 /* fall through */
366 366
367 input_sync(dev); 367 case 3: /* Mouse without wheel */
368 goto exit; 368 wacom->tool[0] = BTN_TOOL_MOUSE;
369 input_report_key(dev, BTN_LEFT, data[1] & 0x01);
370 input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
371 input_report_abs(dev, ABS_DISTANCE, data[7]);
372 break;
373 }
369 } 374 }
370 375
371 if (data[1] & 0x80) { 376 if (data[1] & 0x80) {
372 input_report_abs(dev, ABS_X, x); 377 input_report_abs(dev, ABS_X, x);
373 input_report_abs(dev, ABS_Y, y); 378 input_report_abs(dev, ABS_Y, y);
374 } 379 }
380 if (wacom->tool[0] != BTN_TOOL_MOUSE) {
381 input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6]));
382 input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
383 input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
384 input_report_key(dev, BTN_STYLUS2, data[1] & 0x04);
385 }
375 386
376 input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6])); 387 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); 388 input_sync(dev);
382 389
383exit: 390 exit:
384 retval = usb_submit_urb (urb, GFP_ATOMIC); 391 retval = usb_submit_urb (urb, GFP_ATOMIC);
385 if (retval) 392 if (retval)
386 err ("%s - usb_submit_urb failed with result %d", 393 err ("%s - usb_submit_urb failed with result %d",
@@ -398,14 +405,13 @@ static int wacom_intuos_inout(struct urb *urb)
398 idx = data[1] & 0x01; 405 idx = data[1] & 0x01;
399 406
400 /* Enter report */ 407 /* Enter report */
401 if ((data[1] & 0xfc) == 0xc0) 408 if ((data[1] & 0xfc) == 0xc0) {
402 {
403 /* serial number of the tool */ 409 /* serial number of the tool */
404 wacom->serial[idx] = ((__u32)(data[3] & 0x0f) << 28) + 410 wacom->serial[idx] = ((data[3] & 0x0f) << 28) +
405 ((__u32)data[4] << 20) + ((__u32)data[5] << 12) + 411 (data[4] << 20) + (data[5] << 12) +
406 ((__u32)data[6] << 4) + (data[7] >> 4); 412 (data[6] << 4) + (data[7] >> 4);
407 413
408 switch (((__u32)data[2] << 4) | (data[3] >> 4)) { 414 switch ((data[2] << 4) | (data[3] >> 4)) {
409 case 0x812: /* Inking pen */ 415 case 0x812: /* Inking pen */
410 case 0x801: /* Intuos3 Inking pen */ 416 case 0x801: /* Intuos3 Inking pen */
411 case 0x012: 417 case 0x012:
@@ -449,7 +455,7 @@ static int wacom_intuos_inout(struct urb *urb)
449 case 0x112: 455 case 0x112:
450 case 0x913: /* Intuos3 Airbrush */ 456 case 0x913: /* Intuos3 Airbrush */
451 wacom->tool[idx] = BTN_TOOL_AIRBRUSH; 457 wacom->tool[idx] = BTN_TOOL_AIRBRUSH;
452 break; /* Airbrush */ 458 break;
453 default: /* Unknown tool */ 459 default: /* Unknown tool */
454 wacom->tool[idx] = BTN_TOOL_PEN; 460 wacom->tool[idx] = BTN_TOOL_PEN;
455 } 461 }
@@ -478,9 +484,8 @@ static void wacom_intuos_general(struct urb *urb)
478 unsigned int t; 484 unsigned int t;
479 485
480 /* general pen packet */ 486 /* general pen packet */
481 if ((data[1] & 0xb8) == 0xa0) 487 if ((data[1] & 0xb8) == 0xa0) {
482 { 488 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); 489 input_report_abs(dev, ABS_PRESSURE, t);
485 input_report_abs(dev, ABS_TILT_X, 490 input_report_abs(dev, ABS_TILT_X,
486 ((data[7] << 1) & 0x7e) | (data[8] >> 7)); 491 ((data[7] << 1) & 0x7e) | (data[8] >> 7));
@@ -491,10 +496,9 @@ static void wacom_intuos_general(struct urb *urb)
491 } 496 }
492 497
493 /* airbrush second packet */ 498 /* airbrush second packet */
494 if ((data[1] & 0xbc) == 0xb4) 499 if ((data[1] & 0xbc) == 0xb4) {
495 {
496 input_report_abs(dev, ABS_WHEEL, 500 input_report_abs(dev, ABS_WHEEL,
497 ((__u32)data[6] << 2) | ((data[7] >> 6) & 3)); 501 (data[6] << 2) | ((data[7] >> 6) & 3));
498 input_report_abs(dev, ABS_TILT_X, 502 input_report_abs(dev, ABS_TILT_X,
499 ((data[7] << 1) & 0x7e) | (data[8] >> 7)); 503 ((data[7] << 1) & 0x7e) | (data[8] >> 7));
500 input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); 504 input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f);
@@ -526,7 +530,7 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs)
526 goto exit; 530 goto exit;
527 } 531 }
528 532
529 if (data[0] != 2 && data[0] != 5 && data[0] != 6) { 533 if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) {
530 dbg("wacom_intuos_irq: received unknown report #%d", data[0]); 534 dbg("wacom_intuos_irq: received unknown report #%d", data[0]);
531 goto exit; 535 goto exit;
532 } 536 }
@@ -536,107 +540,10 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs)
536 /* tool number */ 540 /* tool number */
537 idx = data[1] & 0x01; 541 idx = data[1] & 0x01;
538 542
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 */ 543 /* pad packets. Works as a second tool and is always in prox */
635 if (data[0] == 12) 544 if (data[0] == 12) {
636 {
637 /* initiate the pad as a device */ 545 /* initiate the pad as a device */
638 if (wacom->tool[1] != BTN_TOOL_FINGER) 546 if (wacom->tool[1] != BTN_TOOL_FINGER) {
639 {
640 wacom->tool[1] = BTN_TOOL_FINGER; 547 wacom->tool[1] = BTN_TOOL_FINGER;
641 input_report_key(dev, wacom->tool[1], 1); 548 input_report_key(dev, wacom->tool[1], 1);
642 } 549 }
@@ -656,37 +563,78 @@ static void wacom_intuos3_irq(struct urb *urb, struct pt_regs *regs)
656 } 563 }
657 564
658 /* process in/out prox events */ 565 /* process in/out prox events */
659 if (wacom_intuos_inout(urb)) goto exit; 566 if (wacom_intuos_inout(urb))
567 goto exit;
660 568
661 input_report_abs(dev, ABS_X, ((__u32)data[2] << 9) | ((__u32)data[3] << 1) | ((data[9] >> 1) & 1)); 569 /* 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)); 570 if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40))
663 input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); 571 return;
572
573 if (wacom->features->type >= INTUOS3) {
574 input_report_abs(dev, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
575 input_report_abs(dev, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
576 input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
577 } else {
578 input_report_abs(dev, ABS_X, be16_to_cpu(*(__be16 *) &data[2]));
579 input_report_abs(dev, ABS_Y, be16_to_cpu(*(__be16 *) &data[4]));
580 input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 3) & 0x1f));
581 }
664 582
665 /* process general packets */ 583 /* process general packets */
666 wacom_intuos_general(urb); 584 wacom_intuos_general(urb);
667 585
668 if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) 586 /* 4D mouse, 2D mouse, marker pen rotation, or Lens cursor packets */
669 { 587 if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) {
670 /* Marker pen rotation packet. Reported as wheel due to valuator limitation */ 588
671 if (data[1] & 0x02) 589 if (data[1] & 0x02) {
672 { 590 /* Rotation packet */
673 t = ((__u32)data[6] << 3) | ((data[7] >> 5) & 7); 591 if (wacom->features->type >= INTUOS3) {
674 t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : 592 /* I3 marker pen rotation reported as wheel
675 ((t-1) / 2 + 450)) : (450 - t / 2) ; 593 * due to valuator limitation
676 input_report_abs(dev, ABS_WHEEL, t); 594 */
677 } 595 t = (data[6] << 3) | ((data[7] >> 5) & 7);
596 t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
597 ((t-1) / 2 + 450)) : (450 - t / 2) ;
598 input_report_abs(dev, ABS_WHEEL, t);
599 } else {
600 /* 4D mouse rotation packet */
601 t = (data[6] << 3) | ((data[7] >> 5) & 7);
602 input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ?
603 ((t - 1) / 2) : -t / 2);
604 }
678 605
679 /* 2D mouse packets */ 606 } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3) {
680 if (wacom->tool[idx] == BTN_TOOL_MOUSE) 607 /* 4D mouse packet */
681 { 608 input_report_key(dev, BTN_LEFT, data[8] & 0x01);
609 input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
610 input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
611
612 input_report_key(dev, BTN_SIDE, data[8] & 0x20);
613 input_report_key(dev, BTN_EXTRA, data[8] & 0x10);
614 t = (data[6] << 2) | ((data[7] >> 6) & 3);
615 input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
616
617 } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
618 /* 2D mouse packet */
682 input_report_key(dev, BTN_LEFT, data[8] & 0x04); 619 input_report_key(dev, BTN_LEFT, data[8] & 0x04);
683 input_report_key(dev, BTN_MIDDLE, data[8] & 0x08); 620 input_report_key(dev, BTN_MIDDLE, data[8] & 0x08);
684 input_report_key(dev, BTN_RIGHT, data[8] & 0x10); 621 input_report_key(dev, BTN_RIGHT, data[8] & 0x10);
685 input_report_key(dev, BTN_SIDE, data[8] & 0x40); 622 input_report_rel(dev, REL_WHEEL, ((data[8] & 0x02) >> 1)
686 input_report_key(dev, BTN_EXTRA, data[8] & 0x20); 623 - (data[8] & 0x01));
687 /* mouse wheel is positive when rolled backwards */ 624
688 input_report_rel(dev, REL_WHEEL, ((__u32)((data[8] & 0x02) >> 1) 625 /* I3 2D mouse side buttons */
689 - (__u32)(data[8] & 0x01))); 626 if (wacom->features->type == INTUOS3) {
627 input_report_key(dev, BTN_SIDE, data[8] & 0x40);
628 input_report_key(dev, BTN_EXTRA, data[8] & 0x20);
629 }
630
631 } else if (wacom->features->type < INTUOS3) {
632 /* Lens cursor packets */
633 input_report_key(dev, BTN_LEFT, data[8] & 0x01);
634 input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
635 input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
636 input_report_key(dev, BTN_SIDE, data[8] & 0x10);
637 input_report_key(dev, BTN_EXTRA, data[8] & 0x08);
690 } 638 }
691 } 639 }
692 640
@@ -702,35 +650,36 @@ exit:
702} 650}
703 651
704static struct wacom_features wacom_features[] = { 652static struct wacom_features wacom_features[] = {
705 { "Wacom Penpartner", 7, 5040, 3780, 255, 32, 0, wacom_penpartner_irq }, 653 { "Wacom Penpartner", 7, 5040, 3780, 255, 32, PENPARTNER, wacom_penpartner_irq },
706 { "Wacom Graphire", 8, 10206, 7422, 511, 32, 1, wacom_graphire_irq }, 654 { "Wacom Graphire", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_graphire_irq },
707 { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, 1, wacom_graphire_irq }, 655 { "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 }, 656 { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_graphire_irq },
709 { "Wacom Graphire3", 8, 10208, 7424, 511, 32, 1, wacom_graphire_irq }, 657 { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_graphire_irq },
710 { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, 1, wacom_graphire_irq }, 658 { "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 }, 659 { "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 }, 660 { "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 }, 661 { "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 }, 662 { "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 }, 663 { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
716 { "Wacom PL400", 8, 5408, 4056, 255, 32, 3, wacom_pl_irq }, 664 { "Wacom PL400", 8, 5408, 4056, 255, 32, PL, wacom_pl_irq },
717 { "Wacom PL500", 8, 6144, 4608, 255, 32, 3, wacom_pl_irq }, 665 { "Wacom PL500", 8, 6144, 4608, 255, 32, PL, wacom_pl_irq },
718 { "Wacom PL600", 8, 6126, 4604, 255, 32, 3, wacom_pl_irq }, 666 { "Wacom PL600", 8, 6126, 4604, 255, 32, PL, wacom_pl_irq },
719 { "Wacom PL600SX", 8, 6260, 5016, 255, 32, 3, wacom_pl_irq }, 667 { "Wacom PL600SX", 8, 6260, 5016, 255, 32, PL, wacom_pl_irq },
720 { "Wacom PL550", 8, 6144, 4608, 511, 32, 3, wacom_pl_irq }, 668 { "Wacom PL550", 8, 6144, 4608, 511, 32, PL, wacom_pl_irq },
721 { "Wacom PL800", 8, 7220, 5780, 511, 32, 3, wacom_pl_irq }, 669 { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_pl_irq },
722 { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, 2, wacom_intuos_irq }, 670 { "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 }, 671 { "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 }, 672 { "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 }, 673 { "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 }, 674 { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
727 { "Wacom Volito", 8, 5104, 3712, 511, 32, 1, wacom_graphire_irq }, 675 { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq },
728 { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, 3, wacom_ptu_irq }, 676 { "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 }, 677 { "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 }, 678 { "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 }, 679 { "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 }, 680 { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_intuos_irq },
733 { } 681 { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
682 { }
734}; 683};
735 684
736static struct usb_device_id wacom_ids[] = { 685static struct usb_device_id wacom_ids[] = {
@@ -761,6 +710,7 @@ static struct usb_device_id wacom_ids[] = {
761 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, 710 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) },
762 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, 711 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) },
763 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, 712 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) },
713 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) },
764 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, 714 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
765 { } 715 { }
766}; 716};
@@ -771,14 +721,9 @@ static int wacom_open(struct input_dev *dev)
771{ 721{
772 struct wacom *wacom = dev->private; 722 struct wacom *wacom = dev->private;
773 723
774 if (wacom->open++)
775 return 0;
776
777 wacom->irq->dev = wacom->usbdev; 724 wacom->irq->dev = wacom->usbdev;
778 if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { 725 if (usb_submit_urb(wacom->irq, GFP_KERNEL))
779 wacom->open--;
780 return -EIO; 726 return -EIO;
781 }
782 727
783 return 0; 728 return 0;
784} 729}
@@ -787,8 +732,7 @@ static void wacom_close(struct input_dev *dev)
787{ 732{
788 struct wacom *wacom = dev->private; 733 struct wacom *wacom = dev->private;
789 734
790 if (!--wacom->open) 735 usb_kill_urb(wacom->irq);
791 usb_kill_urb(wacom->irq);
792} 736}
793 737
794static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) 738static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -823,32 +767,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); 767 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
824 768
825 switch (wacom->features->type) { 769 switch (wacom->features->type) {
826 case 1: 770 case GRAPHIRE:
827 wacom->dev.evbit[0] |= BIT(EV_REL); 771 wacom->dev.evbit[0] |= BIT(EV_REL);
828 wacom->dev.relbit[0] |= BIT(REL_WHEEL); 772 wacom->dev.relbit[0] |= BIT(REL_WHEEL);
829 wacom->dev.absbit[0] |= BIT(ABS_DISTANCE); 773 wacom->dev.absbit[0] |= BIT(ABS_DISTANCE);
830 wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); 774 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); 775 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
832 break; 776 break;
833 777
834 case 4: /* new functions for Intuos3 */ 778 case INTUOS3:
779 case CINTIQ:
835 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); 780 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); 781 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); 782 wacom->dev.absbit[0] |= BIT(ABS_RX) | BIT(ABS_RY);
838 /* fall through */ 783 /* fall through */
839 784
840 case 2: 785 case INTUOS:
841 wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); 786 wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
842 wacom->dev.mscbit[0] |= BIT(MSC_SERIAL); 787 wacom->dev.mscbit[0] |= BIT(MSC_SERIAL);
843 wacom->dev.relbit[0] |= BIT(REL_WHEEL); 788 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); 789 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) 790 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); 791 | 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); 792 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; 793 break;
849 794
850 case 3: 795 case PL:
851 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER); 796 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
852 break; 797 break;
853 } 798 }
854 799
@@ -879,10 +824,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
879 824
880 wacom->dev.name = wacom->features->name; 825 wacom->dev.name = wacom->features->name;
881 wacom->dev.phys = wacom->phys; 826 wacom->dev.phys = wacom->phys;
882 wacom->dev.id.bustype = BUS_USB; 827 usb_to_input_id(dev, &wacom->dev.id);
883 wacom->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
884 wacom->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
885 wacom->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
886 wacom->dev.dev = &intf->dev; 828 wacom->dev.dev = &intf->dev;
887 wacom->usbdev = dev; 829 wacom->usbdev = dev;
888 830