Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.12-rc2 951 lines 30 kB view raw
1/* 2 * USB Wacom Graphire and Wacom Intuos tablet support 3 * 4 * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> 5 * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> 6 * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at> 7 * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org> 8 * Copyright (c) 2000 James E. Blair <corvus@gnu.org> 9 * Copyright (c) 2000 Daniel Egger <egger@suse.de> 10 * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> 11 * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> 12 * Copyright (c) 2002-2004 Ping Cheng <pingc@wacom.com> 13 * 14 * ChangeLog: 15 * v0.1 (vp) - Initial release 16 * v0.2 (aba) - Support for all buttons / combinations 17 * v0.3 (vp) - Support for Intuos added 18 * v0.4 (sm) - Support for more Intuos models, menustrip 19 * relative mode, proximity. 20 * v0.5 (vp) - Big cleanup, nifty features removed, 21 * they belong in userspace 22 * v1.8 (vp) - Submit URB only when operating, moved to CVS, 23 * use input_report_key instead of report_btn and 24 * other cleanups 25 * v1.11 (vp) - Add URB ->dev setting for new kernels 26 * v1.11 (jb) - Add support for the 4D Mouse & Lens 27 * v1.12 (de) - Add support for two more inking pen IDs 28 * v1.14 (vp) - Use new USB device id probing scheme. 29 * Fix Wacom Graphire mouse wheel 30 * v1.18 (vp) - Fix mouse wheel direction 31 * Make mouse relative 32 * v1.20 (fl) - Report tool id for Intuos devices 33 * - Multi tools support 34 * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...) 35 * - Add PL models support 36 * - Fix Wacom Graphire mouse wheel again 37 * v1.21 (vp) - Removed protocol descriptions 38 * - Added MISC_SERIAL for tool serial numbers 39 * (gb) - Identify version on module load. 40 * v1.21.1 (fl) - added Graphire2 support 41 * v1.21.2 (fl) - added Intuos2 support 42 * - added all the PL ids 43 * v1.21.3 (fl) - added another eraser id from Neil Okamoto 44 * - added smooth filter for Graphire from Peri Hankey 45 * - added PenPartner support from Olaf van Es 46 * - new tool ids from Ole Martin Bjoerndalen 47 * v1.29 (pc) - Add support for more tablets 48 * - Fix pressure reporting 49 * v1.30 (vp) - Merge 2.4 and 2.5 drivers 50 * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse 51 * - Cleanups here and there 52 * v1.30.1 (pi) - Added Graphire3 support 53 * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... 54 */ 55 56/* 57 * This program is free software; you can redistribute it and/or modify 58 * it under the terms of the GNU General Public License as published by 59 * the Free Software Foundation; either version 2 of the License, or 60 * (at your option) any later version. 61 */ 62 63#include <linux/kernel.h> 64#include <linux/slab.h> 65#include <linux/input.h> 66#include <linux/module.h> 67#include <linux/init.h> 68#include <linux/usb.h> 69#include <asm/unaligned.h> 70#include <asm/byteorder.h> 71 72/* 73 * Version Information 74 */ 75#define DRIVER_VERSION "v1.40" 76#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" 77#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" 78#define DRIVER_LICENSE "GPL" 79 80MODULE_AUTHOR(DRIVER_AUTHOR); 81MODULE_DESCRIPTION(DRIVER_DESC); 82MODULE_LICENSE(DRIVER_LICENSE); 83 84#define USB_VENDOR_ID_WACOM 0x056a 85 86struct wacom_features { 87 char *name; 88 int pktlen; 89 int x_max; 90 int y_max; 91 int pressure_max; 92 int distance_max; 93 int type; 94 usb_complete_t irq; 95}; 96 97struct wacom { 98 signed char *data; 99 dma_addr_t data_dma; 100 struct input_dev dev; 101 struct usb_device *usbdev; 102 struct urb *irq; 103 struct wacom_features *features; 104 int tool[2]; 105 int open; 106 __u32 serial[2]; 107 char phys[32]; 108}; 109 110#define USB_REQ_SET_REPORT 0x09 111static int usb_set_report(struct usb_interface *intf, unsigned char type, 112 unsigned char id, void *buf, int size) 113{ 114 return usb_control_msg(interface_to_usbdev(intf), 115 usb_sndctrlpipe(interface_to_usbdev(intf), 0), 116 USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 117 (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, 118 buf, size, 1000); 119} 120 121static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs) 122{ 123 struct wacom *wacom = urb->context; 124 unsigned char *data = wacom->data; 125 struct input_dev *dev = &wacom->dev; 126 int prox, pressure; 127 int retval; 128 129 switch (urb->status) { 130 case 0: 131 /* success */ 132 break; 133 case -ECONNRESET: 134 case -ENOENT: 135 case -ESHUTDOWN: 136 /* this urb is terminated, clean up */ 137 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 138 return; 139 default: 140 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); 141 goto exit; 142 } 143 144 if (data[0] != 2) { 145 dbg("wacom_pl_irq: received unknown report #%d", data[0]); 146 goto exit; 147 } 148 149 prox = data[1] & 0x40; 150 151 input_regs(dev, regs); 152 153 if (prox) { 154 155 pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); 156 if (wacom->features->pressure_max > 255) 157 pressure = (pressure << 1) | ((data[4] >> 6) & 1); 158 pressure += (wacom->features->pressure_max + 1) / 2; 159 160 /* 161 * if going from out of proximity into proximity select between the eraser 162 * and the pen based on the state of the stylus2 button, choose eraser if 163 * pressed else choose pen. if not a proximity change from out to in, send 164 * an out of proximity for previous tool then a in for new tool. 165 */ 166 if (!wacom->tool[0]) { 167 /* Going into proximity select tool */ 168 wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN; 169 } 170 else { 171 /* was entered with stylus2 pressed */ 172 if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) { 173 /* report out proximity for previous tool */ 174 input_report_key(dev, wacom->tool[1], 0); 175 input_sync(dev); 176 wacom->tool[1] = BTN_TOOL_PEN; 177 goto exit; 178 } 179 } 180 if (wacom->tool[1] != BTN_TOOL_RUBBER) { 181 /* Unknown tool selected default to pen tool */ 182 wacom->tool[1] = BTN_TOOL_PEN; 183 } 184 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)); 186 input_report_abs(dev, ABS_Y, data[6] | ((__u32)data[5] << 7) | ((__u32)(data[4] & 0x03) << 14)); 187 input_report_abs(dev, ABS_PRESSURE, pressure); 188 189 input_report_key(dev, BTN_TOUCH, data[4] & 0x08); 190 input_report_key(dev, BTN_STYLUS, data[4] & 0x10); 191 /* 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)); 193 } 194 else { 195 /* report proximity-out of a (valid) tool */ 196 if (wacom->tool[1] != BTN_TOOL_RUBBER) { 197 /* Unknown tool selected default to pen tool */ 198 wacom->tool[1] = BTN_TOOL_PEN; 199 } 200 input_report_key(dev, wacom->tool[1], prox); 201 } 202 203 wacom->tool[0] = prox; /* Save proximity state */ 204 input_sync(dev); 205 206exit: 207 retval = usb_submit_urb (urb, GFP_ATOMIC); 208 if (retval) 209 err ("%s - usb_submit_urb failed with result %d", 210 __FUNCTION__, retval); 211} 212 213static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs) 214{ 215 struct wacom *wacom = urb->context; 216 unsigned char *data = wacom->data; 217 struct input_dev *dev = &wacom->dev; 218 int retval; 219 220 switch (urb->status) { 221 case 0: 222 /* success */ 223 break; 224 case -ECONNRESET: 225 case -ENOENT: 226 case -ESHUTDOWN: 227 /* this urb is terminated, clean up */ 228 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 229 return; 230 default: 231 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); 232 goto exit; 233 } 234 235 if (data[0] != 2) 236 { 237 printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); 238 goto exit; 239 } 240 241 input_regs(dev, regs); 242 if (data[1] & 0x04) 243 { 244 input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20); 245 input_report_key(dev, BTN_TOUCH, data[1] & 0x08); 246 } 247 else 248 { 249 input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20); 250 input_report_key(dev, BTN_TOUCH, data[1] & 0x01); 251 } 252 input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[2])); 253 input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[4])); 254 input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6])); 255 input_report_key(dev, BTN_STYLUS, data[1] & 0x02); 256 input_report_key(dev, BTN_STYLUS2, data[1] & 0x10); 257 258 input_sync(dev); 259 260exit: 261 retval = usb_submit_urb (urb, GFP_ATOMIC); 262 if (retval) 263 err ("%s - usb_submit_urb failed with result %d", 264 __FUNCTION__, retval); 265} 266 267static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs) 268{ 269 struct wacom *wacom = urb->context; 270 unsigned char *data = wacom->data; 271 struct input_dev *dev = &wacom->dev; 272 int retval; 273 274 switch (urb->status) { 275 case 0: 276 /* success */ 277 break; 278 case -ECONNRESET: 279 case -ENOENT: 280 case -ESHUTDOWN: 281 /* this urb is terminated, clean up */ 282 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 283 return; 284 default: 285 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); 286 goto exit; 287 } 288 289 if (data[0] != 2) { 290 printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]); 291 goto exit; 292 } 293 294 input_regs(dev, regs); 295 input_report_key(dev, BTN_TOOL_PEN, 1); 296 input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1])); 297 input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3])); 298 input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127); 299 input_report_key(dev, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20)); 300 input_report_key(dev, BTN_STYLUS, (data[5] & 0x40)); 301 input_sync(dev); 302 303exit: 304 retval = usb_submit_urb (urb, GFP_ATOMIC); 305 if (retval) 306 err ("%s - usb_submit_urb failed with result %d", 307 __FUNCTION__, retval); 308} 309 310static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) 311{ 312 struct wacom *wacom = urb->context; 313 unsigned char *data = wacom->data; 314 struct input_dev *dev = &wacom->dev; 315 int x, y; 316 int retval; 317 318 switch (urb->status) { 319 case 0: 320 /* success */ 321 break; 322 case -ECONNRESET: 323 case -ENOENT: 324 case -ESHUTDOWN: 325 /* this urb is terminated, clean up */ 326 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 327 return; 328 default: 329 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); 330 goto exit; 331 } 332 333 if (data[0] != 2) { 334 dbg("wacom_graphire_irq: received unknown report #%d", data[0]); 335 goto exit; 336 } 337 338 x = le16_to_cpu(*(__le16 *) &data[2]); 339 y = le16_to_cpu(*(__le16 *) &data[4]); 340 341 input_regs(dev, regs); 342 343 switch ((data[1] >> 5) & 3) { 344 345 case 0: /* Pen */ 346 input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x80); 347 break; 348 349 case 1: /* Rubber */ 350 input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x80); 351 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 358 case 3: /* Mouse without wheel */ 359 input_report_key(dev, BTN_TOOL_MOUSE, data[7] > 24); 360 input_report_key(dev, BTN_LEFT, data[1] & 0x01); 361 input_report_key(dev, BTN_RIGHT, data[1] & 0x02); 362 input_report_abs(dev, ABS_DISTANCE, data[7]); 363 364 input_report_abs(dev, ABS_X, x); 365 input_report_abs(dev, ABS_Y, y); 366 367 input_sync(dev); 368 goto exit; 369 } 370 371 if (data[1] & 0x80) { 372 input_report_abs(dev, ABS_X, x); 373 input_report_abs(dev, ABS_Y, y); 374 } 375 376 input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6])); 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); 382 383exit: 384 retval = usb_submit_urb (urb, GFP_ATOMIC); 385 if (retval) 386 err ("%s - usb_submit_urb failed with result %d", 387 __FUNCTION__, retval); 388} 389 390static int wacom_intuos_inout(struct urb *urb) 391{ 392 struct wacom *wacom = urb->context; 393 unsigned char *data = wacom->data; 394 struct input_dev *dev = &wacom->dev; 395 int idx; 396 397 /* tool number */ 398 idx = data[1] & 0x01; 399 400 /* Enter report */ 401 if ((data[1] & 0xfc) == 0xc0) 402 { 403 /* serial number of the tool */ 404 wacom->serial[idx] = ((__u32)(data[3] & 0x0f) << 28) + 405 ((__u32)data[4] << 20) + ((__u32)data[5] << 12) + 406 ((__u32)data[6] << 4) + (data[7] >> 4); 407 408 switch (((__u32)data[2] << 4) | (data[3] >> 4)) { 409 case 0x812: /* Inking pen */ 410 case 0x801: /* Intuos3 Inking pen */ 411 case 0x012: 412 wacom->tool[idx] = BTN_TOOL_PENCIL; 413 break; 414 case 0x822: /* Pen */ 415 case 0x842: 416 case 0x852: 417 case 0x823: /* Intuos3 Grip Pen */ 418 case 0x813: /* Intuos3 Classic Pen */ 419 case 0x885: /* Intuos3 Marker Pen */ 420 case 0x022: 421 wacom->tool[idx] = BTN_TOOL_PEN; 422 break; 423 case 0x832: /* Stroke pen */ 424 case 0x032: 425 wacom->tool[idx] = BTN_TOOL_BRUSH; 426 break; 427 case 0x007: /* Mouse 4D and 2D */ 428 case 0x09c: 429 case 0x094: 430 case 0x017: /* Intuos3 2D Mouse */ 431 wacom->tool[idx] = BTN_TOOL_MOUSE; 432 break; 433 case 0x096: /* Lens cursor */ 434 case 0x097: /* Intuos3 Lens cursor */ 435 wacom->tool[idx] = BTN_TOOL_LENS; 436 break; 437 case 0x82a: /* Eraser */ 438 case 0x85a: 439 case 0x91a: 440 case 0xd1a: 441 case 0x0fa: 442 case 0x82b: /* Intuos3 Grip Pen Eraser */ 443 case 0x81b: /* Intuos3 Classic Pen Eraser */ 444 case 0x91b: /* Intuos3 Airbrush Eraser */ 445 wacom->tool[idx] = BTN_TOOL_RUBBER; 446 break; 447 case 0xd12: 448 case 0x912: 449 case 0x112: 450 case 0x913: /* Intuos3 Airbrush */ 451 wacom->tool[idx] = BTN_TOOL_AIRBRUSH; 452 break; /* Airbrush */ 453 default: /* Unknown tool */ 454 wacom->tool[idx] = BTN_TOOL_PEN; 455 } 456 input_report_key(dev, wacom->tool[idx], 1); 457 input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); 458 input_sync(dev); 459 return 1; 460 } 461 462 /* Exit report */ 463 if ((data[1] & 0xfe) == 0x80) { 464 input_report_key(dev, wacom->tool[idx], 0); 465 input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); 466 input_sync(dev); 467 return 1; 468 } 469 470 return 0; 471} 472 473static void wacom_intuos_general(struct urb *urb) 474{ 475 struct wacom *wacom = urb->context; 476 unsigned char *data = wacom->data; 477 struct input_dev *dev = &wacom->dev; 478 unsigned int t; 479 480 /* general pen packet */ 481 if ((data[1] & 0xb8) == 0xa0) 482 { 483 t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3); 484 input_report_abs(dev, ABS_PRESSURE, t); 485 input_report_abs(dev, ABS_TILT_X, 486 ((data[7] << 1) & 0x7e) | (data[8] >> 7)); 487 input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); 488 input_report_key(dev, BTN_STYLUS, data[1] & 2); 489 input_report_key(dev, BTN_STYLUS2, data[1] & 4); 490 input_report_key(dev, BTN_TOUCH, t > 10); 491 } 492 493 /* airbrush second packet */ 494 if ((data[1] & 0xbc) == 0xb4) 495 { 496 input_report_abs(dev, ABS_WHEEL, 497 ((__u32)data[6] << 2) | ((data[7] >> 6) & 3)); 498 input_report_abs(dev, ABS_TILT_X, 499 ((data[7] << 1) & 0x7e) | (data[8] >> 7)); 500 input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); 501 } 502 return; 503} 504 505static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs) 506{ 507 struct wacom *wacom = urb->context; 508 unsigned char *data = wacom->data; 509 struct input_dev *dev = &wacom->dev; 510 unsigned int t; 511 int idx; 512 int retval; 513 514 switch (urb->status) { 515 case 0: 516 /* success */ 517 break; 518 case -ECONNRESET: 519 case -ENOENT: 520 case -ESHUTDOWN: 521 /* this urb is terminated, clean up */ 522 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 523 return; 524 default: 525 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); 526 goto exit; 527 } 528 529 if (data[0] != 2 && data[0] != 5 && data[0] != 6) { 530 dbg("wacom_intuos_irq: received unknown report #%d", data[0]); 531 goto exit; 532 } 533 534 input_regs(dev, regs); 535 536 /* tool number */ 537 idx = data[1] & 0x01; 538 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 */ 635 if (data[0] == 12) 636 { 637 /* initiate the pad as a device */ 638 if (wacom->tool[1] != BTN_TOOL_FINGER) 639 { 640 wacom->tool[1] = BTN_TOOL_FINGER; 641 input_report_key(dev, wacom->tool[1], 1); 642 } 643 input_report_key(dev, BTN_0, (data[5] & 0x01)); 644 input_report_key(dev, BTN_1, (data[5] & 0x02)); 645 input_report_key(dev, BTN_2, (data[5] & 0x04)); 646 input_report_key(dev, BTN_3, (data[5] & 0x08)); 647 input_report_key(dev, BTN_4, (data[6] & 0x01)); 648 input_report_key(dev, BTN_5, (data[6] & 0x02)); 649 input_report_key(dev, BTN_6, (data[6] & 0x04)); 650 input_report_key(dev, BTN_7, (data[6] & 0x08)); 651 input_report_abs(dev, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); 652 input_report_abs(dev, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); 653 input_event(dev, EV_MSC, MSC_SERIAL, 0xffffffff); 654 input_sync(dev); 655 goto exit; 656 } 657 658 /* process in/out prox events */ 659 if (wacom_intuos_inout(urb)) goto exit; 660 661 input_report_abs(dev, ABS_X, ((__u32)data[2] << 9) | ((__u32)data[3] << 1) | ((data[9] >> 1) & 1)); 662 input_report_abs(dev, ABS_Y, ((__u32)data[4] << 9) | ((__u32)data[5] << 1) | (data[9] & 1)); 663 input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); 664 665 /* process general packets */ 666 wacom_intuos_general(urb); 667 668 if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) 669 { 670 /* Marker pen rotation packet. Reported as wheel due to valuator limitation */ 671 if (data[1] & 0x02) 672 { 673 t = ((__u32)data[6] << 3) | ((data[7] >> 5) & 7); 674 t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : 675 ((t-1) / 2 + 450)) : (450 - t / 2) ; 676 input_report_abs(dev, ABS_WHEEL, t); 677 } 678 679 /* 2D mouse packets */ 680 if (wacom->tool[idx] == BTN_TOOL_MOUSE) 681 { 682 input_report_key(dev, BTN_LEFT, data[8] & 0x04); 683 input_report_key(dev, BTN_MIDDLE, data[8] & 0x08); 684 input_report_key(dev, BTN_RIGHT, data[8] & 0x10); 685 input_report_key(dev, BTN_SIDE, data[8] & 0x40); 686 input_report_key(dev, BTN_EXTRA, data[8] & 0x20); 687 /* mouse wheel is positive when rolled backwards */ 688 input_report_rel(dev, REL_WHEEL, ((__u32)((data[8] & 0x02) >> 1) 689 - (__u32)(data[8] & 0x01))); 690 } 691 } 692 693 input_report_key(dev, wacom->tool[idx], 1); 694 input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); 695 input_sync(dev); 696 697exit: 698 retval = usb_submit_urb (urb, GFP_ATOMIC); 699 if (retval) 700 err ("%s - usb_submit_urb failed with result %d", 701 __FUNCTION__, retval); 702} 703 704static struct wacom_features wacom_features[] = { 705 { "Wacom Penpartner", 7, 5040, 3780, 255, 32, 0, wacom_penpartner_irq }, 706 { "Wacom Graphire", 8, 10206, 7422, 511, 32, 1, wacom_graphire_irq }, 707 { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, 1, wacom_graphire_irq }, 708 { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, 1, wacom_graphire_irq }, 709 { "Wacom Graphire3", 8, 10208, 7424, 511, 32, 1, wacom_graphire_irq }, 710 { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, 1, wacom_graphire_irq }, 711 { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, 2, wacom_intuos_irq }, 712 { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq }, 713 { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, 2, wacom_intuos_irq }, 714 { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15, 2, wacom_intuos_irq }, 715 { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, 2, wacom_intuos_irq }, 716 { "Wacom PL400", 8, 5408, 4056, 255, 32, 3, wacom_pl_irq }, 717 { "Wacom PL500", 8, 6144, 4608, 255, 32, 3, wacom_pl_irq }, 718 { "Wacom PL600", 8, 6126, 4604, 255, 32, 3, wacom_pl_irq }, 719 { "Wacom PL600SX", 8, 6260, 5016, 255, 32, 3, wacom_pl_irq }, 720 { "Wacom PL550", 8, 6144, 4608, 511, 32, 3, wacom_pl_irq }, 721 { "Wacom PL800", 8, 7220, 5780, 511, 32, 3, wacom_pl_irq }, 722 { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, 2, wacom_intuos_irq }, 723 { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq }, 724 { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, 2, wacom_intuos_irq }, 725 { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, 2, wacom_intuos_irq }, 726 { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, 2, wacom_intuos_irq }, 727 { "Wacom Volito", 8, 5104, 3712, 511, 32, 1, wacom_graphire_irq }, 728 { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, 3, wacom_ptu_irq }, 729 { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, 4, wacom_intuos3_irq }, 730 { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, 4, wacom_intuos3_irq }, 731 { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, 4, wacom_intuos3_irq }, 732 { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq }, 733 { } 734}; 735 736static struct usb_device_id wacom_ids[] = { 737 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00) }, 738 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10) }, 739 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) }, 740 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) }, 741 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) }, 742 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) }, 743 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, 744 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, 745 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, 746 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23) }, 747 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24) }, 748 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30) }, 749 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31) }, 750 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32) }, 751 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) }, 752 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) }, 753 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) }, 754 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, 755 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, 756 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) }, 757 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) }, 758 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) }, 759 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, 760 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, 761 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) }, 762 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) }, 763 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) }, 764 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, 765 { } 766}; 767 768MODULE_DEVICE_TABLE(usb, wacom_ids); 769 770static int wacom_open(struct input_dev *dev) 771{ 772 struct wacom *wacom = dev->private; 773 774 if (wacom->open++) 775 return 0; 776 777 wacom->irq->dev = wacom->usbdev; 778 if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { 779 wacom->open--; 780 return -EIO; 781 } 782 783 return 0; 784} 785 786static void wacom_close(struct input_dev *dev) 787{ 788 struct wacom *wacom = dev->private; 789 790 if (!--wacom->open) 791 usb_kill_urb(wacom->irq); 792} 793 794static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) 795{ 796 struct usb_device *dev = interface_to_usbdev(intf); 797 struct usb_endpoint_descriptor *endpoint; 798 char rep_data[2] = {0x02, 0x02}; 799 struct wacom *wacom; 800 char path[64]; 801 802 if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) 803 return -ENOMEM; 804 memset(wacom, 0, sizeof(struct wacom)); 805 806 wacom->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); 807 if (!wacom->data) { 808 kfree(wacom); 809 return -ENOMEM; 810 } 811 812 wacom->irq = usb_alloc_urb(0, GFP_KERNEL); 813 if (!wacom->irq) { 814 usb_buffer_free(dev, 10, wacom->data, wacom->data_dma); 815 kfree(wacom); 816 return -ENOMEM; 817 } 818 819 wacom->features = wacom_features + (id - wacom_ids); 820 821 wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); 822 wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); 823 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS); 824 825 switch (wacom->features->type) { 826 case 1: 827 wacom->dev.evbit[0] |= BIT(EV_REL); 828 wacom->dev.relbit[0] |= BIT(REL_WHEEL); 829 wacom->dev.absbit[0] |= BIT(ABS_DISTANCE); 830 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); 832 break; 833 834 case 4: /* new functions for Intuos3 */ 835 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); 837 wacom->dev.absbit[0] |= BIT(ABS_RX) | BIT(ABS_RY); 838 /* fall through */ 839 840 case 2: 841 wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); 842 wacom->dev.mscbit[0] |= BIT(MSC_SERIAL); 843 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); 845 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); 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); 848 break; 849 850 case 3: 851 wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER); 852 break; 853 } 854 855 wacom->dev.absmax[ABS_X] = wacom->features->x_max; 856 wacom->dev.absmax[ABS_Y] = wacom->features->y_max; 857 wacom->dev.absmax[ABS_PRESSURE] = wacom->features->pressure_max; 858 wacom->dev.absmax[ABS_DISTANCE] = wacom->features->distance_max; 859 wacom->dev.absmax[ABS_TILT_X] = 127; 860 wacom->dev.absmax[ABS_TILT_Y] = 127; 861 wacom->dev.absmax[ABS_WHEEL] = 1023; 862 863 wacom->dev.absmax[ABS_RX] = 4097; 864 wacom->dev.absmax[ABS_RY] = 4097; 865 wacom->dev.absmin[ABS_RZ] = -900; 866 wacom->dev.absmax[ABS_RZ] = 899; 867 wacom->dev.absmin[ABS_THROTTLE] = -1023; 868 wacom->dev.absmax[ABS_THROTTLE] = 1023; 869 870 wacom->dev.absfuzz[ABS_X] = 4; 871 wacom->dev.absfuzz[ABS_Y] = 4; 872 873 wacom->dev.private = wacom; 874 wacom->dev.open = wacom_open; 875 wacom->dev.close = wacom_close; 876 877 usb_make_path(dev, path, 64); 878 sprintf(wacom->phys, "%s/input0", path); 879 880 wacom->dev.name = wacom->features->name; 881 wacom->dev.phys = wacom->phys; 882 wacom->dev.id.bustype = BUS_USB; 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; 887 wacom->usbdev = dev; 888 889 endpoint = &intf->cur_altsetting->endpoint[0].desc; 890 891 if (wacom->features->pktlen > 10) 892 BUG(); 893 894 usb_fill_int_urb(wacom->irq, dev, 895 usb_rcvintpipe(dev, endpoint->bEndpointAddress), 896 wacom->data, wacom->features->pktlen, 897 wacom->features->irq, wacom, endpoint->bInterval); 898 wacom->irq->transfer_dma = wacom->data_dma; 899 wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 900 901 input_register_device(&wacom->dev); 902 903 /* ask the tablet to report tablet data */ 904 usb_set_report(intf, 3, 2, rep_data, 2); 905 /* repeat once (not sure why the first call often fails) */ 906 usb_set_report(intf, 3, 2, rep_data, 2); 907 908 printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path); 909 910 usb_set_intfdata(intf, wacom); 911 912 return 0; 913} 914 915static void wacom_disconnect(struct usb_interface *intf) 916{ 917 struct wacom *wacom = usb_get_intfdata (intf); 918 919 usb_set_intfdata(intf, NULL); 920 if (wacom) { 921 usb_kill_urb(wacom->irq); 922 input_unregister_device(&wacom->dev); 923 usb_free_urb(wacom->irq); 924 usb_buffer_free(interface_to_usbdev(intf), 10, wacom->data, wacom->data_dma); 925 kfree(wacom); 926 } 927} 928 929static struct usb_driver wacom_driver = { 930 .owner = THIS_MODULE, 931 .name = "wacom", 932 .probe = wacom_probe, 933 .disconnect = wacom_disconnect, 934 .id_table = wacom_ids, 935}; 936 937static int __init wacom_init(void) 938{ 939 int result = usb_register(&wacom_driver); 940 if (result == 0) 941 info(DRIVER_VERSION ":" DRIVER_DESC); 942 return result; 943} 944 945static void __exit wacom_exit(void) 946{ 947 usb_deregister(&wacom_driver); 948} 949 950module_init(wacom_init); 951module_exit(wacom_exit);