OpenSDE Packages Database (without history before r20070)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1131 lines
41 KiB

  1. # --- SDE-COPYRIGHT-NOTE-BEGIN ---
  2. # This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  3. #
  4. # Filename: package/.../linuxwacom/wacom_24.diff
  5. # Copyright (C) 2004 - 2006 The T2 SDE Project
  6. #
  7. # More information can be found in the files COPYING and README.
  8. #
  9. # This patch file is dual-licensed. It is available under the license the
  10. # patched project is licensed under, as long as it is an OpenSource license
  11. # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
  12. # of the GNU General Public License as published by the Free Software
  13. # Foundation; either version 2 of the License, or (at your option) any later
  14. # version.
  15. # --- SDE-COPYRIGHT-NOTE-END ---
  16. diff -Naur linux-2.4.30_orig/drivers/usb/wacom.c linux-2.4.30/drivers/usb/wacom.c
  17. --- linux-2.4.30_orig/drivers/usb/wacom.c 2002-11-29 00:53:15.000000000 +0100
  18. +++ linux-2.4.30/drivers/usb/wacom.c 2005-03-29 00:52:09.000000000 +0200
  19. @@ -1,15 +1,18 @@
  20. /*
  21. - * $Id: wacom.c,v 1.23 2001/05/29 12:57:18 vojtech Exp $
  22. + * $Id: wacom.c,v 1.12 2005/03/18 18:17:44 pingc Exp $
  23. *
  24. - * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@suse.cz>
  25. - * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk>
  26. - * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at>
  27. - * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org>
  28. - * Copyright (c) 2000 James E. Blair <corvus@gnu.org>
  29. - * Copyright (c) 2000 Daniel Egger <egger@suse.de>
  30. - * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com>
  31. + * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@suse.cz>
  32. + * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk>
  33. + * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at>
  34. + * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org>
  35. + * Copyright (c) 2000 James E. Blair <corvus@gnu.org>
  36. + * Copyright (c) 2000 Daniel Egger <egger@suse.de>
  37. + * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com>
  38. + * Copyright (c) 2002 Christer Nilsson <christer.nilsson@kretskompaniet.se>
  39. + * Copyright (c) 2002-2005 Ping Cheng <pingc@wacom.com>
  40. + * Copyright (c) 2002 John Joganic <john@joganic.com>
  41. *
  42. - * USB Wacom Graphire and Wacom Intuos tablet support
  43. + * USB Wacom Graphire and Intuos tablet support
  44. *
  45. * Sponsored by SuSE
  46. *
  47. @@ -46,6 +49,41 @@
  48. * - added smooth filter for Graphire from Peri Hankey
  49. * - added PenPartner support from Olaf van Es
  50. * - new tool ids from Ole Martin Bjoerndalen
  51. + * v1.29 (pc) - Add support for more tablets
  52. + * - Fix pressure reporting
  53. + * v1.30 (vp) - Merge 2.4 and 2.5 drivers
  54. + * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse
  55. + * - Cleanups here and there
  56. + *
  57. + * WARNING: THIS IS NOT PART OF THE OFFICIAL KERNEL TREE
  58. + * THIS IS FOR TESTING PURPOSES
  59. + *
  60. + * v1.21.3-j0 - fixed absolute x and y for intuos by John Joganic
  61. + * v1.21.3-j1 - applied Christer Nilsson's patches for 2.4.20
  62. + * v1.30.1-j0 - applied Ping Cheng's patches for device ranges and caps
  63. + * v1.30.1-j1 - updated device ranges for Intuos2 12x12 (0x44)
  64. + * v1.30.1-j2 - updated device ranges for Intuos2 6x8 (0x42)
  65. + * v1.30-j0.3.1 - fixed pen identifers, 2D mouse handling
  66. + * v1.30-j0.3.3 - added volito, thanks to Pasi Savolainen; fixed wheel sign
  67. + * v1.30-j0.3.4 - added Ping Cheng's new tool IDs
  68. + * v1.30-j0.3.5 - thread for resetting tablet on bad report
  69. + * v1.30-j0.3.6 - fixed volito ranges, thanks to Pasi Savolainen
  70. + * v1.30-j0.3.7 - unknown reports are now info, rather than error
  71. + * v1.30-j0.3.8 - fixed I2 4x5 Y max value, thanks to John New
  72. + * fixed Intuos and Intuos2 sizes, values from Wacom
  73. + * v1.30-j0.5.0 - new release
  74. + * v1.30-j0.5.1 - fixed serial number code for Intuos and Intuos2
  75. + * v1.30-j0.5.2 - applied Ping Cheng's eraser patch for PL
  76. + * v1.30-j0.5.3 - reapplied patch for Intuos2 6x8's reportings as (0x47)
  77. + * v1.30-j0.6.0 - new release
  78. + * v1.30-j0.6.1 - new release
  79. + * v1.30-j0.6.2 - new release
  80. + * v1.30-j0.6.3 - new release
  81. + * v1.30-j0.6.4 - new release
  82. + * v1.30-j0.6.5 - added Intuos3
  83. + * v1.30-j0.6.6 - new release
  84. + * v1.30-j0.6.7 - fixed a Graphire bug
  85. + * v1.30-j0.6.8 - added Cintiq 21UX
  86. */
  87. /*
  88. @@ -53,41 +91,49 @@
  89. * it under the terms of the GNU General Public License as published by
  90. * the Free Software Foundation; either version 2 of the License, or
  91. * (at your option) any later version.
  92. - *
  93. - * This program is distributed in the hope that it will be useful,
  94. - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  95. - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  96. - * GNU General Public License for more details.
  97. - *
  98. - * You should have received a copy of the GNU General Public License
  99. - * along with this program; if not, write to the Free Software
  100. - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  101. - *
  102. - * Should you need to contact me, the author, you can do so either by
  103. - * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  104. - * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  105. */
  106. +#include <linux/autoconf.h>
  107. +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
  108. +# define MODVERSIONS
  109. +#endif
  110. +
  111. +#ifdef MODVERSIONS
  112. +#include <linux/modversions.h>
  113. +#endif
  114. +
  115. #include <linux/kernel.h>
  116. #include <linux/slab.h>
  117. #include <linux/input.h>
  118. #include <linux/module.h>
  119. #include <linux/init.h>
  120. #include <linux/usb.h>
  121. +#include <linux/smp_lock.h>
  122. +#include <linux/list.h>
  123. /*
  124. * Version Information
  125. */
  126. -#define DRIVER_VERSION "v1.21.3"
  127. +#define DRIVER_VERSION "v1.30-j0.6.8"
  128. #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@suse.cz>"
  129. -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
  130. +#ifndef __JEJ_DEBUG
  131. +#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver (LINUXWACOM)"
  132. +#else
  133. +#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver (LINUXWACOM-DEBUG)"
  134. +#endif
  135. -MODULE_AUTHOR( DRIVER_AUTHOR );
  136. -MODULE_DESCRIPTION( DRIVER_DESC );
  137. +MODULE_AUTHOR(DRIVER_AUTHOR);
  138. +MODULE_DESCRIPTION(DRIVER_DESC);
  139. MODULE_LICENSE("GPL");
  140. #define USB_VENDOR_ID_WACOM 0x056a
  141. +static int kwacomd_pid = 0; /* PID of kwacomd */
  142. +static DECLARE_COMPLETION(kwacomd_exited);
  143. +static DECLARE_WAIT_QUEUE_HEAD(kwacomd_wait);
  144. +static LIST_HEAD(wacom_event_list); /* List of tablets needing servicing */
  145. +static spinlock_t wacom_event_lock = SPIN_LOCK_UNLOCKED;
  146. +
  147. struct wacom_features {
  148. char *name;
  149. int pktlen;
  150. @@ -112,64 +158,157 @@
  151. int tool[2];
  152. int open;
  153. __u32 serial[2];
  154. +
  155. + struct list_head event_list;
  156. + struct semaphore kwacomd_sem;
  157. + unsigned int ifnum;
  158. };
  159. +static void wacom_request_reset(struct wacom* wacom)
  160. +{
  161. + unsigned long flags;
  162. + spin_lock_irqsave(&wacom_event_lock, flags);
  163. + if (list_empty(&wacom->event_list))
  164. + {
  165. + list_add(&wacom->event_list, &wacom_event_list);
  166. + wake_up(&kwacomd_wait);
  167. + }
  168. + spin_unlock_irqrestore(&wacom_event_lock, flags);
  169. +}
  170. +
  171. static void wacom_pl_irq(struct urb *urb)
  172. {
  173. struct wacom *wacom = urb->context;
  174. unsigned char *data = wacom->data;
  175. struct input_dev *dev = &wacom->dev;
  176. - int prox;
  177. + int prox, pressure;
  178. if (urb->status) return;
  179. - if (data[0] != 2) {
  180. - printk(KERN_ERR "wacom_pl_irq: received unknown report #%d\n", data[0]);
  181. + if (data[0] != 2 && data[0] != 5)
  182. + {
  183. + printk(KERN_INFO "wacom_pl_irq: received unknown report #%d\n", data[0]);
  184. + wacom_request_reset(wacom);
  185. return;
  186. }
  187. - prox = data[1] & 0x20;
  188. -
  189. - input_report_key(dev, BTN_TOOL_PEN, prox);
  190. -
  191. + /* proximity and pressure */
  192. + prox = data[1] & 0x40;
  193. +
  194. if (prox) {
  195. - int pressure = (data[4] & 0x04) >> 2 | ((__u32)(data[7] & 0x7f) << 1);
  196. + pressure = (signed char) ((data[7] <<1 ) | ((data[4] >> 2) & 1));
  197. + if ( wacom->features->pressure_max > 350 ) {
  198. + pressure = (pressure << 1) | ((data[4] >> 6) & 1);
  199. + }
  200. + pressure += (( wacom->features->pressure_max + 1 )/ 2);
  201. +
  202. + /*
  203. + * if going from out of proximity into proximity select between the eraser
  204. + * and the pen based on the state of the stylus2 button, choose eraser if
  205. + * pressed else choose pen. if not a proximity change from out to in, send
  206. + * an out of proximity for previous tool then a in for new tool.
  207. + */
  208. + if (!wacom->tool[0]) {
  209. + /* Going into proximity select tool */
  210. + wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
  211. + }
  212. + else {
  213. + /* was entered with stylus2 pressed */
  214. + if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) {
  215. + /* report out proximity for previous tool */
  216. + input_report_key(dev, wacom->tool[1], 0);
  217. + input_event(dev, EV_MSC, MSC_SERIAL, 0);
  218. + wacom->tool[1] = BTN_TOOL_PEN;
  219. + return;
  220. + }
  221. + }
  222. + if (wacom->tool[1] != BTN_TOOL_RUBBER) {
  223. + /* Unknown tool selected default to pen tool */
  224. + wacom->tool[1] = BTN_TOOL_PEN;
  225. + }
  226. + input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */
  227. - input_report_abs(dev, ABS_X, data[3] | ((__u32)data[2] << 8) | ((__u32)(data[1] & 0x03) << 16));
  228. - input_report_abs(dev, ABS_Y, data[6] | ((__u32)data[5] << 8) | ((__u32)(data[4] & 0x03) << 8));
  229. - input_report_abs(dev, ABS_PRESSURE, (data[7] & 0x80) ? (255 - pressure) : (pressure + 255));
  230. + input_report_abs(dev, ABS_X, data[3] | ((__u32)data[2] << 7) | ((__u32)(data[1] & 0x03) << 14));
  231. + input_report_abs(dev, ABS_Y, data[6] | ((__u32)data[5] << 7) | ((__u32)(data[4] & 0x03) << 14));
  232. + input_report_abs(dev, ABS_PRESSURE, pressure);
  233. input_report_key(dev, BTN_TOUCH, data[4] & 0x08);
  234. input_report_key(dev, BTN_STYLUS, data[4] & 0x10);
  235. - input_report_key(dev, BTN_STYLUS2, data[4] & 0x20);
  236. + /* Only allow the stylus2 button to be reported for the pen tool. */
  237. + input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));
  238. + }
  239. + else {
  240. + /* report proximity-out of a (valid) tool */
  241. + if (wacom->tool[1] != BTN_TOOL_RUBBER) {
  242. + /* Unknown tool selected default to pen tool */
  243. + wacom->tool[1] = BTN_TOOL_PEN;
  244. + }
  245. + input_report_key(dev, wacom->tool[1], prox);
  246. }
  247. +
  248. + wacom->tool[0] = prox; /* Save proximity state */
  249. + /* end of proximity code */
  250. input_event(dev, EV_MSC, MSC_SERIAL, 0);
  251. }
  252. +static void wacom_ptu_irq(struct urb *urb)
  253. +{
  254. + struct wacom *wacom = urb->context;
  255. + unsigned char *data = wacom->data;
  256. + struct input_dev *dev = &wacom->dev;
  257. +
  258. + if (urb->status) return;
  259. +
  260. + if (data[0] != 2 && data[0] != 5)
  261. + {
  262. + printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
  263. + wacom_request_reset(wacom);
  264. + return;
  265. + }
  266. +
  267. + if (data[1] & 0x04)
  268. + {
  269. + input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20);
  270. + input_report_key(dev, BTN_TOUCH, data[1] & 0x08);
  271. + }
  272. + else
  273. + {
  274. + input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20);
  275. + input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
  276. + }
  277. + input_report_abs(dev, ABS_X, data[3] << 8 | data[2]);
  278. + input_report_abs(dev, ABS_Y, data[5] << 8 | data[4]);
  279. + input_report_abs(dev, ABS_PRESSURE, (data[6]|data[7] << 8));
  280. + input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
  281. + input_report_key(dev, BTN_STYLUS2, data[1] & 0x10);
  282. +
  283. + input_event(dev, EV_MSC, MSC_SERIAL, 0);
  284. +}
  285. +
  286. +
  287. static void wacom_penpartner_irq(struct urb *urb)
  288. {
  289. struct wacom *wacom = urb->context;
  290. unsigned char *data = wacom->data;
  291. struct input_dev *dev = &wacom->dev;
  292. - int x, y;
  293. - char pressure;
  294. - int leftmb;
  295. + int leftmb = (((signed char)data[6] > -80) && !(data[5] &0x20));
  296. if (urb->status) return;
  297. - x = data[2] << 8 | data[1];
  298. - y = data[4] << 8 | data[3];
  299. - pressure = data[6];
  300. - leftmb = ((pressure > -80) && !(data[5] &20));
  301. + if (data[0] != 2 && data[0] != 5)
  302. + {
  303. + printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]);
  304. + wacom_request_reset(wacom);
  305. + return;
  306. + }
  307. input_report_key(dev, BTN_TOOL_PEN, 1);
  308. + input_report_abs(dev, ABS_X, data[2] << 8 | data[1]);
  309. + input_report_abs(dev, ABS_Y, data[4] << 8 | data[3]);
  310. + input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127);
  311. + input_report_key(dev, BTN_TOUCH, leftmb);
  312. + input_report_key(dev, BTN_STYLUS, (data[5] & 0x40));
  313. - input_report_abs(dev, ABS_X, x);
  314. - input_report_abs(dev, ABS_Y, y);
  315. - input_report_abs(dev, ABS_PRESSURE, pressure+127);
  316. - input_report_key(dev, BTN_LEFT, leftmb);
  317. - input_report_key(dev, BTN_RIGHT, (data[5] & 0x40));
  318. -
  319. input_event(dev, EV_MSC, MSC_SERIAL, leftmb);
  320. }
  321. @@ -182,204 +321,412 @@
  322. if (urb->status) return;
  323. - if (data[0] != 2) {
  324. - printk(KERN_ERR "wacom_graphire_irq: received unknown report #%d\n", data[0]);
  325. + if (data[0] != 2)
  326. + {
  327. + printk(KERN_INFO "wacom_graphire_irq: received unknown report #%d\n", data[0]);
  328. + wacom_request_reset(wacom);
  329. return;
  330. }
  331. -
  332. - x = data[2] | ((__u32)data[3] << 8);
  333. - y = data[4] | ((__u32)data[5] << 8);
  334. -
  335. - switch ((data[1] >> 5) & 3) {
  336. -
  337. - case 0: /* Pen */
  338. - input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x80);
  339. - break;
  340. -
  341. - case 1: /* Rubber */
  342. - input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x80);
  343. - break;
  344. -
  345. - case 2: /* Mouse */
  346. - input_report_key(dev, BTN_TOOL_MOUSE, data[7] > 24);
  347. - input_report_key(dev, BTN_LEFT, data[1] & 0x01);
  348. - input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
  349. - input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
  350. - input_report_abs(dev, ABS_DISTANCE, data[7]);
  351. - input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
  352. -
  353. - input_report_abs(dev, ABS_X, x);
  354. - input_report_abs(dev, ABS_Y, y);
  355. - input_event(dev, EV_MSC, MSC_SERIAL, data[1] & 0x01);
  356. - return;
  357. + if ( data[1] & 0x10 ) /* in prox */
  358. + {
  359. + switch ((data[1] >> 5) & 3) {
  360. +
  361. + case 0: /* Pen */
  362. + wacom->tool[0] = BTN_TOOL_PEN;
  363. + break;
  364. +
  365. + case 1: /* Rubber */
  366. + wacom->tool[0] = BTN_TOOL_RUBBER;
  367. + break;
  368. +
  369. + case 2: /* Mouse with wheel */
  370. + input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
  371. + input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
  372. + /* fall through */
  373. +
  374. + case 3: /* Mouse without wheel */
  375. + wacom->tool[0] = BTN_TOOL_MOUSE;
  376. + input_report_key(dev, BTN_LEFT, data[1] & 0x01);
  377. + input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
  378. + input_report_abs(dev, ABS_DISTANCE, data[7]);
  379. + break;
  380. + }
  381. }
  382. if (data[1] & 0x80) {
  383. + x = data[2] | ((__u32)data[3] << 8);
  384. + y = data[4] | ((__u32)data[5] << 8);
  385. input_report_abs(dev, ABS_X, x);
  386. input_report_abs(dev, ABS_Y, y);
  387. }
  388. -
  389. - input_report_abs(dev, ABS_PRESSURE, data[6] | ((__u32)data[7] << 8));
  390. - input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
  391. - input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
  392. - input_report_key(dev, BTN_STYLUS2, data[1] & 0x04);
  393. -
  394. + if (wacom->tool[0] != BTN_TOOL_MOUSE) {
  395. + input_report_abs(dev, ABS_PRESSURE, data[6] | ((__u32)data[7] << 8));
  396. + input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
  397. + input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
  398. + input_report_key(dev, BTN_STYLUS2, data[1] & 0x04);
  399. + }
  400. + input_report_key(dev, wacom->tool[0], data[1] & 0x10);
  401. input_event(dev, EV_MSC, MSC_SERIAL, data[1] & 0x01);
  402. }
  403. -static void wacom_intuos_irq(struct urb *urb)
  404. +static int wacom_intuos_inout(struct urb *urb)
  405. {
  406. struct wacom *wacom = urb->context;
  407. unsigned char *data = wacom->data;
  408. struct input_dev *dev = &wacom->dev;
  409. - unsigned int t;
  410. int idx;
  411. - if (urb->status) return;
  412. -
  413. - if (data[0] != 2) {
  414. - printk(KERN_ERR "wacom_intuos_irq: received unknown report #%d\n", data[0]);
  415. - return;
  416. - }
  417. -
  418. /* tool number */
  419. idx = data[1] & 0x01;
  420. - if ((data[1] & 0xfc) == 0xc0) { /* Enter report */
  421. + /* Enter report */
  422. + if ((data[1] & 0xfc) == 0xc0)
  423. + {
  424. + /* serial number of the tool */
  425. + wacom->serial[idx] = ((__u32)(data[3] & 0x0f) << 28) +
  426. + ((__u32)data[4] << 20) + ((__u32)data[5] << 12) +
  427. + ((__u32)data[6] << 4) + ((__u32)data[7] >> 4);
  428. +
  429. + #ifdef __JEJ_DEBUG
  430. + printk(KERN_INFO "wacom_intuos_irq: tool change 0x%03X\n",
  431. + (((__u32)data[2] << 4) | (data[3] >> 4)));
  432. + #endif
  433. +
  434. + switch ((((__u32)data[2] << 4) | (data[3] >> 4)))
  435. + {
  436. + case 0x812: /* Intuos2 ink pen XP-110-00A */
  437. + case 0x801: /* Intuos3 Inking pen */
  438. + case 0x012: /* Inking pen */
  439. + wacom->tool[idx] = BTN_TOOL_PENCIL; break;
  440. +
  441. + case 0x822: /* Intuos Pen GP-300E-01H */
  442. + case 0x852: /* Intuos2 Grip Pen XP-501E-00A */
  443. + case 0x842: /* Designer Pen */
  444. + case 0x823: /* Intuos3 Grip Pen */
  445. + case 0x813: /* Intuos3 Classic Pen */
  446. + case 0x885: /* Intuos3 Marker Pen */
  447. + case 0x022:
  448. + wacom->tool[idx] = BTN_TOOL_PEN; break;
  449. +
  450. + case 0x832: /* Intuos2 stroke pen XP-120-00A */
  451. + case 0x032: /* Stroke pen */
  452. + wacom->tool[idx] = BTN_TOOL_BRUSH; break;
  453. +
  454. + case 0x007: /* 2D Mouse */
  455. + case 0x09C: /* ?? Mouse - not a valid code according to Wacom */
  456. + case 0x094: /* 4D Mouse */
  457. + case 0x017: /* Intuos3 2D Mouse */
  458. + wacom->tool[idx] = BTN_TOOL_MOUSE; break;
  459. +
  460. + case 0x096: /* Lens cursor */
  461. + case 0x097: /* Intuos3 Lens cursor */
  462. + wacom->tool[idx] = BTN_TOOL_LENS; break;
  463. +
  464. + case 0x82A:
  465. + case 0x85A:
  466. + case 0x91A:
  467. + case 0xD1A:
  468. + case 0x0FA: /* Eraser */
  469. + case 0x82B: /* Intuos3 Grip Pen Eraser */
  470. + case 0x81B: /* Intuos3 Classic Pen Eraser */
  471. + case 0x91B: /* Intuos3 Airbrush Eraser */
  472. + wacom->tool[idx] = BTN_TOOL_RUBBER; break;
  473. +
  474. + case 0x112: /* Airbrush */
  475. + case 0x912: /* Intuos2 Airbrush */
  476. + case 0xD12: /* Intuos Airbrush */
  477. + case 0x913: /* Intuos3 Airbrush */
  478. + wacom->tool[idx] = BTN_TOOL_AIRBRUSH; break;
  479. - wacom->serial[idx] = ((__u32)(data[3] & 0x0f) << 4) + /* serial number of the tool */
  480. - ((__u32)data[4] << 16) + ((__u32)data[5] << 12) +
  481. - ((__u32)data[6] << 4) + (data[7] >> 4);
  482. -
  483. - switch (((__u32)data[2] << 4) | (data[3] >> 4)) {
  484. - case 0x832:
  485. - case 0x012: wacom->tool[idx] = BTN_TOOL_PENCIL; break; /* Inking pen */
  486. - case 0x822:
  487. - case 0x852:
  488. - case 0x022: wacom->tool[idx] = BTN_TOOL_PEN; break; /* Pen */
  489. - case 0x812:
  490. - case 0x032: wacom->tool[idx] = BTN_TOOL_BRUSH; break; /* Stroke pen */
  491. - case 0x09c:
  492. - case 0x007:
  493. - case 0x094: wacom->tool[idx] = BTN_TOOL_MOUSE; break; /* Mouse 4D */
  494. - case 0x096: wacom->tool[idx] = BTN_TOOL_LENS; break; /* Lens cursor */
  495. - case 0x82a:
  496. - case 0x85a:
  497. - case 0x91a:
  498. - case 0x0fa: wacom->tool[idx] = BTN_TOOL_RUBBER; break; /* Eraser */
  499. - case 0x112: wacom->tool[idx] = BTN_TOOL_AIRBRUSH; break; /* Airbrush */
  500. - default: wacom->tool[idx] = BTN_TOOL_PEN; break; /* Unknown tool */
  501. + default: /* Unknown tool */
  502. + wacom->tool[idx] = BTN_TOOL_PEN; break;
  503. }
  504. -
  505. - input_report_key(dev, wacom->tool[idx], 1);
  506. input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
  507. - return;
  508. + return 1;
  509. }
  510. - if ((data[1] & 0xfe) == 0x80) { /* Exit report */
  511. + /* Exit report */
  512. + if ((data[1] & 0xfe) == 0x80)
  513. + {
  514. input_report_key(dev, wacom->tool[idx], 0);
  515. input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
  516. - return;
  517. + return 1;
  518. }
  519. - input_report_abs(dev, ABS_X, ((__u32)data[2] << 8) | data[3]);
  520. - input_report_abs(dev, ABS_Y, ((__u32)data[4] << 8) | data[5]);
  521. - input_report_abs(dev, ABS_DISTANCE, data[9] >> 4);
  522. -
  523. - if ((data[1] & 0xb8) == 0xa0) { /* general pen packet */
  524. - input_report_abs(dev, ABS_PRESSURE, t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3));
  525. - input_report_abs(dev, ABS_TILT_X, ((data[7] << 1) & 0x7e) | (data[8] >> 7));
  526. + return 0;
  527. +}
  528. +
  529. +static void wacom_intuos_general(struct urb *urb)
  530. +{
  531. + struct wacom *wacom = urb->context;
  532. + unsigned char *data = wacom->data;
  533. + struct input_dev *dev = &wacom->dev;
  534. + unsigned int t;
  535. +
  536. + /* general pen packet */
  537. + if ((data[1] & 0xb8) == 0xa0)
  538. + {
  539. + t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3);
  540. + input_report_abs(dev, ABS_PRESSURE, t);
  541. + input_report_abs(dev, ABS_TILT_X,
  542. + ((data[7] << 1) & 0x7e) | (data[8] >> 7));
  543. input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f);
  544. input_report_key(dev, BTN_STYLUS, data[1] & 2);
  545. input_report_key(dev, BTN_STYLUS2, data[1] & 4);
  546. input_report_key(dev, BTN_TOUCH, t > 10);
  547. }
  548. - if ((data[1] & 0xbc) == 0xb4) { /* airbrush second packet */
  549. - input_report_abs(dev, ABS_WHEEL, ((__u32)data[6] << 2) | ((data[7] >> 6) & 3));
  550. - input_report_abs(dev, ABS_TILT_X, ((data[7] << 1) & 0x7e) | (data[8] >> 7));
  551. + /* airbrush second packet */
  552. + if ((data[1] & 0xbc) == 0xb4)
  553. + {
  554. + input_report_abs(dev, ABS_WHEEL,
  555. + ((__u32)data[6] << 2) | ((data[7] >> 6) & 3));
  556. + input_report_abs(dev, ABS_TILT_X,
  557. + ((data[7] << 1) & 0x7e) | (data[8] >> 7));
  558. input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f);
  559. }
  560. + return;
  561. +}
  562. +
  563. +static void wacom_intuos_irq(struct urb *urb)
  564. +{
  565. + struct wacom *wacom = urb->context;
  566. + unsigned char *data = wacom->data;
  567. + struct input_dev *dev = &wacom->dev;
  568. + unsigned int t;
  569. + int idx;
  570. +
  571. + if (urb->status) return;
  572. +
  573. + /* check for valid report */
  574. + if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12)
  575. + {
  576. + printk(KERN_INFO "wacom_intuos_irq: received unknown report #%d\n", data[0]);
  577. + wacom_request_reset(wacom);
  578. + return;
  579. + }
  580. - if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) { /* 4D mouse or Lens cursor packets */
  581. + /* tool index */
  582. + idx = data[1] & 0x01;
  583. - if (data[1] & 0x02) { /* Rotation packet */
  584. + /* pad packets. Works as a second tool and is alway in prox */
  585. + if (data[0] == 12)
  586. + {
  587. + /* initiate the pad as a device */
  588. + if (wacom->tool[1] != BTN_TOOL_FINGER)
  589. + {
  590. + wacom->tool[1] = BTN_TOOL_FINGER;
  591. + input_report_key(dev, wacom->tool[1], 1);
  592. + }
  593. + input_report_key(dev, BTN_0, (data[5] & 0x01));
  594. + input_report_key(dev, BTN_1, (data[5] & 0x02));
  595. + input_report_key(dev, BTN_2, (data[5] & 0x04));
  596. + input_report_key(dev, BTN_3, (data[5] & 0x08));
  597. + input_report_key(dev, BTN_4, (data[6] & 0x01));
  598. + input_report_key(dev, BTN_5, (data[6] & 0x02));
  599. + input_report_key(dev, BTN_6, (data[6] & 0x04));
  600. + input_report_key(dev, BTN_7, (data[6] & 0x08));
  601. + input_report_abs(dev, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
  602. + input_report_abs(dev, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
  603. + input_event(dev, EV_MSC, MSC_SERIAL, 0xffffffff);
  604. + return;
  605. + }
  606. - input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ?
  607. - ((__u32)data[6] << 2) | ((data[7] >> 6) & 3):
  608. - (-(((__u32)data[6] << 2) | ((data[7] >> 6) & 3))) - 1);
  609. + /* process in/out prox events */
  610. + if (wacom_intuos_inout(urb)) return;
  611. - } else {
  612. + /* Cintiq doesn't send data when RDY bit isn't set */
  613. + if (strstr(wacom->features->name, "Cintiq") && !(data[1] & 0x40)) return;
  614. +
  615. + if(strstr(wacom->features->name, "Intuos3") || strstr(wacom->features->name, "Cintiq"))
  616. + {
  617. + input_report_abs(dev, ABS_X, ((__u32)data[2] << 9) | ((__u32)data[3] << 1) | ((data[9] >> 1) & 1));
  618. + input_report_abs(dev, ABS_Y, ((__u32)data[4] << 9) | ((__u32)data[5] << 1) | (data[9] & 1));
  619. + input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
  620. + }
  621. + else
  622. + {
  623. + input_report_abs(dev, ABS_X, ((__u32)data[2] << 8) | data[3]);
  624. + input_report_abs(dev, ABS_Y, ((__u32)data[4] << 8) | data[5]);
  625. + input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 3) & 0x1f));
  626. + }
  627. +
  628. + /* process general packets */
  629. + wacom_intuos_general(urb);
  630. +
  631. + /* 4D mouse, 2D mouse, marker pen rotation, or Lens cursor packets */
  632. + if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0)
  633. + {
  634. + /* Rotation packet */
  635. + if (data[1] & 0x02)
  636. + {
  637. + if(strstr(wacom->features->name, "Intuos3") ||
  638. + strstr(wacom->features->name, "Cintiq"))
  639. + {
  640. + /* I3 marker pen rotation reported as wheel
  641. + * due to valuator limitation
  642. + */
  643. + t = ((__u32)data[6] << 3) | ((data[7] >> 5) & 7);
  644. + t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
  645. + ((t-1) / 2 + 450)) : (450 - t / 2) ;
  646. + input_report_abs(dev, ABS_WHEEL, t);
  647. + }
  648. + else
  649. + {
  650. + /* 4D mouse rotation packet */
  651. + t = ((__u32)data[6] << 3) | ((data[7] >> 5) & 7);
  652. + input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ?
  653. + ((t - 1) / 2) : -t / 2);
  654. + }
  655. + }
  656. + /* 4D mouse packets */
  657. + else if ( !(data[1] & 0x10) && !strstr(wacom->features->name, "Intuos3"))
  658. + {
  659. input_report_key(dev, BTN_LEFT, data[8] & 0x01);
  660. input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
  661. input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
  662. + input_report_key(dev, BTN_SIDE, data[8] & 0x20);
  663. + input_report_key(dev, BTN_EXTRA, data[8] & 0x10);
  664. + /* throttle is positive when rolled backwards */
  665. + t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3);
  666. + input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
  667. + }
  668. - if ((data[1] & 0x10) == 0) { /* 4D mouse packets */
  669. -
  670. - input_report_key(dev, BTN_SIDE, data[8] & 0x20);
  671. - input_report_key(dev, BTN_EXTRA, data[8] & 0x10);
  672. - input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ?
  673. - ((__u32)data[6] << 2) | ((data[7] >> 6) & 3) :
  674. - -((__u32)data[6] << 2) | ((data[7] >> 6) & 3));
  675. -
  676. - } else { /* Lens cursor packets */
  677. -
  678. - input_report_key(dev, BTN_SIDE, data[8] & 0x10);
  679. - input_report_key(dev, BTN_EXTRA, data[8] & 0x08);
  680. + /* 2D mouse packets */
  681. + else if (wacom->tool[idx] == BTN_TOOL_MOUSE)
  682. + {
  683. + input_report_key(dev, BTN_LEFT, data[8] & 0x04);
  684. + input_report_key(dev, BTN_MIDDLE, data[8] & 0x08);
  685. + input_report_key(dev, BTN_RIGHT, data[8] & 0x10);
  686. + /* mouse wheel is positive when rolled backwards */
  687. + input_report_rel(dev, REL_WHEEL, (__u32)((data[8] & 0x02) >> 1)
  688. + - (__u32)(data[8] & 0x01));
  689. +
  690. + /* I3 2D mouse side buttons */
  691. + if (strstr(wacom->features->name, "Intuos3"))
  692. + {
  693. + input_report_key(dev, BTN_SIDE, data[8] & 0x40);
  694. + input_report_key(dev, BTN_EXTRA, data[8] & 0x20);
  695. }
  696. }
  697. + /* lens cursor packets */
  698. + else if ( !strstr(wacom->features->name, "Intuos3") )
  699. + {
  700. + input_report_key(dev, BTN_LEFT, data[8] & 0x01);
  701. + input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
  702. + input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
  703. + input_report_key(dev, BTN_SIDE, data[8] & 0x10);
  704. + input_report_key(dev, BTN_EXTRA, data[8] & 0x08);
  705. + }
  706. }
  707. -
  708. +
  709. + input_report_key(dev, wacom->tool[idx], 1);
  710. input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
  711. }
  712. +#define WACOM_GRAPHIRE_BITS (BIT(EV_REL))
  713. +#define WACOM_GRAPHIRE_REL (BIT(REL_WHEEL))
  714. #define WACOM_INTUOS_TOOLS (BIT(BTN_TOOL_BRUSH) | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS))
  715. +#define WACOM_INTUOS3_TOOLS (WACOM_INTUOS_TOOLS | BIT(BTN_TOOL_FINGER))
  716. #define WACOM_INTUOS_BUTTONS (BIT(BTN_SIDE) | BIT(BTN_EXTRA))
  717. +#define WACOM_INTUOS3_BUTTONS (WACOM_INTUOS_BUTTONS | BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7))
  718. +#define WACOM_INTUOS_BITS (BIT(EV_REL))
  719. +#define WACOM_INTUOS_REL (BIT(REL_WHEEL))
  720. #define WACOM_INTUOS_ABS (BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE))
  721. +#define WACOM_INTUOS3_ABS (WACOM_INTUOS_ABS | BIT(ABS_RX) | BIT(ABS_RY))
  722. struct wacom_features wacom_features[] = {
  723. - { "Wacom Penpartner", 7, 5040, 3780, 255, 32, wacom_penpartner_irq,
  724. - 0, 0, 0, 0 },
  725. - { "Wacom Graphire", 8, 10206, 7422, 511, 32, wacom_graphire_irq,
  726. - BIT(EV_REL), 0, BIT(REL_WHEEL), 0 },
  727. - { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, wacom_graphire_irq,
  728. - BIT(EV_REL), 0, BIT(REL_WHEEL), 0 },
  729. - { "Wacom Graphire2 5x7", 8, 10206, 7422, 511, 32, wacom_graphire_irq,
  730. - BIT(EV_REL), 0, BIT(REL_WHEEL), 0 },
  731. - { "Wacom Intuos 4x5", 10, 12700, 10360, 1023, 15, wacom_intuos_irq,
  732. - 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  733. - { "Wacom Intuos 6x8", 10, 20320, 15040, 1023, 15, wacom_intuos_irq,
  734. - 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  735. - { "Wacom Intuos 9x12", 10, 30480, 23060, 1023, 15, wacom_intuos_irq,
  736. - 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  737. - { "Wacom Intuos 12x12", 10, 30480, 30480, 1023, 15, wacom_intuos_irq,
  738. - 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  739. - { "Wacom Intuos 12x18", 10, 47720, 30480, 1023, 15, wacom_intuos_irq,
  740. - 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  741. - { "Wacom PL400", 8, 12328, 9256, 511, 32, wacom_pl_irq,
  742. - 0, 0, 0, 0 },
  743. - { "Wacom PL500", 8, 12328, 9256, 511, 32, wacom_pl_irq,
  744. - 0, 0, 0, 0 },
  745. - { "Wacom PL600", 8, 12328, 9256, 511, 32, wacom_pl_irq,
  746. - 0, 0, 0, 0 },
  747. - { "Wacom PL600SX", 8, 12328, 9256, 511, 32, wacom_pl_irq,
  748. - 0, 0, 0, 0 },
  749. - { "Wacom PL550", 8, 12328, 9256, 511, 32, wacom_pl_irq,
  750. - 0, 0, 0, 0 },
  751. - { "Wacom PL800", 8, 12328, 9256, 511, 32, wacom_pl_irq,
  752. - 0, 0, 0, 0 },
  753. - { "Wacom Intuos2 4x5", 10, 12700, 10360, 1023, 15, wacom_intuos_irq,
  754. - 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  755. - { "Wacom Intuos2 6x8", 10, 20320, 15040, 1023, 15, wacom_intuos_irq,
  756. - 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  757. - { "Wacom Intuos2 9x12", 10, 30480, 23060, 1023, 15, wacom_intuos_irq,
  758. - 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  759. - { "Wacom Intuos2 12x12", 10, 30480, 30480, 1023, 15, wacom_intuos_irq,
  760. - 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  761. - { "Wacom Intuos2 12x18", 10, 47720, 30480, 1023, 15, wacom_intuos_irq,
  762. - 0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  763. +
  764. + /* PenPartner */
  765. + /* 0 */ { "Wacom Penpartner", 7, 5040, 3780, 255, 32,
  766. + wacom_penpartner_irq, 0, 0, 0, 0 },
  767. +
  768. + /* Graphire */
  769. + /* 1 */ { "Wacom Graphire", 8, 10206, 7422, 511, 32,
  770. + wacom_graphire_irq, WACOM_GRAPHIRE_BITS, 0, WACOM_GRAPHIRE_REL, 0 },
  771. + /* 2 */ { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32,
  772. + wacom_graphire_irq, WACOM_GRAPHIRE_BITS, 0, WACOM_GRAPHIRE_REL, 0 },
  773. + /* 3 */ { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32,
  774. + wacom_graphire_irq, WACOM_GRAPHIRE_BITS, 0, WACOM_GRAPHIRE_REL, 0 },
  775. +
  776. + /* Intuos */
  777. + /* 4 */ { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15,
  778. + wacom_intuos_irq, WACOM_INTUOS_BITS, WACOM_INTUOS_ABS,
  779. + WACOM_INTUOS_REL, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  780. + /* JEJ - confirmed X and Y range from test tablet */
  781. + /* 5 */ { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15,
  782. + wacom_intuos_irq, WACOM_INTUOS_BITS, WACOM_INTUOS_ABS,
  783. + WACOM_INTUOS_REL, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  784. + /* 6 */ { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15,
  785. + wacom_intuos_irq, WACOM_INTUOS_BITS, WACOM_INTUOS_ABS,
  786. + WACOM_INTUOS_REL, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  787. + /* 7 */ { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15,
  788. + wacom_intuos_irq, WACOM_INTUOS_BITS, WACOM_INTUOS_ABS,
  789. + WACOM_INTUOS_REL, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  790. + /* 8 */ { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15,
  791. + wacom_intuos_irq, WACOM_INTUOS_BITS, WACOM_INTUOS_ABS,
  792. + WACOM_INTUOS_REL, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  793. +
  794. + /* PL - Cintiq */
  795. + /* 9 */ { "Wacom PL400", 8, 5408, 4056, 255, 32,
  796. + wacom_pl_irq, 0, 0, 0, 0 },
  797. + /* 10 */ { "Wacom PL500", 8, 6144, 4608, 255, 32,
  798. + wacom_pl_irq, 0, 0, 0, 0 },
  799. + /* 11 */ { "Wacom PL600", 8, 6126, 4604, 255, 32,
  800. + wacom_pl_irq, 0, 0, 0, 0 },
  801. + /* 12 */ { "Wacom PL600SX", 8, 6260, 5016, 255, 32,
  802. + wacom_pl_irq, 0, 0, 0, 0 },
  803. + /* 13 */ { "Wacom PL550", 8, 6144, 4608, 511, 32,
  804. + wacom_pl_irq, 0, 0, 0, 0 },
  805. + /* 14 */ { "Wacom PL800", 8, 7220, 5780, 511, 32,
  806. + wacom_pl_irq, 0, 0, 0, 0 },
  807. +
  808. + /* Intuos2 */
  809. + /* JEJ - confirmed X and Y range from J.N. tablet */
  810. + /* 15 */ { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15,
  811. + wacom_intuos_irq, WACOM_INTUOS_BITS, WACOM_INTUOS_ABS,
  812. + WACOM_INTUOS_REL, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  813. + /* JEJ - confirmed X and Y range from R.T. and J.S. tablets */
  814. + /* 16 */ { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15,
  815. + wacom_intuos_irq, WACOM_INTUOS_BITS, WACOM_INTUOS_ABS,
  816. + WACOM_INTUOS_REL, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  817. + /* JEJ - values from serial 9x12 */
  818. + /* 17 */ { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15,
  819. + wacom_intuos_irq, WACOM_INTUOS_BITS, WACOM_INTUOS_ABS,
  820. + WACOM_INTUOS_REL, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  821. + /* JEJ - confirmed X and Y range from J.J. tablet */
  822. + /* 18 */ { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15,
  823. + wacom_intuos_irq, WACOM_INTUOS_BITS, WACOM_INTUOS_ABS,
  824. + WACOM_INTUOS_REL, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  825. + /* 19 */ { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15,
  826. + wacom_intuos_irq, WACOM_INTUOS_BITS, WACOM_INTUOS_ABS,
  827. + WACOM_INTUOS_REL, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
  828. + /* Volito - (Graphire2 4x5 no mouse wheel) */
  829. + /* 20 */ { "Wacom Volito", 8, 5104, 3712, 511, 32,
  830. + wacom_graphire_irq, WACOM_GRAPHIRE_BITS, 0, 0, 0 },
  831. + /* 21 */ { "Wacom Graphire3 4x5", 8, 10208, 7424, 511, 32,
  832. + wacom_graphire_irq, WACOM_GRAPHIRE_BITS, 0, WACOM_GRAPHIRE_REL, 0 },
  833. + /* 22 */ { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32,
  834. + wacom_graphire_irq, WACOM_GRAPHIRE_BITS, 0, WACOM_GRAPHIRE_REL, 0 },
  835. + /* 23 */ { "Wacom Cintiq Partner", 8, 20480, 15360, 511, 32,
  836. + wacom_ptu_irq, 0, 0, 0, 0 },
  837. + /* Intuos3 */
  838. + /* 24 */ { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15,
  839. + wacom_intuos_irq, WACOM_INTUOS_BITS, WACOM_INTUOS3_ABS,
  840. + WACOM_INTUOS_REL, WACOM_INTUOS3_BUTTONS, WACOM_INTUOS3_TOOLS },
  841. + /* 25 */ { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15,
  842. + wacom_intuos_irq, WACOM_INTUOS_BITS, WACOM_INTUOS3_ABS,
  843. + WACOM_INTUOS_REL, WACOM_INTUOS3_BUTTONS, WACOM_INTUOS3_TOOLS },
  844. + /* 26 */ { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15,
  845. + wacom_intuos_irq, WACOM_INTUOS_BITS, WACOM_INTUOS3_ABS,
  846. + WACOM_INTUOS_REL, WACOM_INTUOS3_BUTTONS, WACOM_INTUOS3_TOOLS },
  847. + /* Protocol 5 Cintiq */
  848. + /* 27 */ { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15,
  849. + wacom_intuos_irq, WACOM_INTUOS_BITS, WACOM_INTUOS3_ABS,
  850. + WACOM_INTUOS_REL, WACOM_INTUOS3_BUTTONS, WACOM_INTUOS3_TOOLS },
  851. +
  852. { NULL , 0 }
  853. };
  854. @@ -404,6 +751,19 @@
  855. { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43), driver_info: 17 },
  856. { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44), driver_info: 18 },
  857. { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45), driver_info: 19 },
  858. + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60), driver_info: 20 },
  859. + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13), driver_info: 21 },
  860. + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14), driver_info: 22 },
  861. + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03), driver_info: 23 },
  862. + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0), driver_info: 24 },
  863. + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1), driver_info: 25 },
  864. + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2), driver_info: 26 },
  865. + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F), driver_info: 27 },
  866. +
  867. + /* some Intuos2 6x8's erroneously report as 0x47;
  868. + * multiple confirmed examples exist. */
  869. + { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47), driver_info: 16 },
  870. +
  871. { }
  872. };
  873. @@ -431,25 +791,50 @@
  874. usb_unlink_urb(&wacom->irq);
  875. }
  876. +static void wacom_reset(struct wacom* wacom)
  877. +{
  878. + unsigned char edata[2], limit=0;
  879. + #ifdef __JEJ_DEBUG
  880. + printk(KERN_INFO __FILE__ ": Setting tablet report for tablet data\n");
  881. + #endif
  882. +
  883. + /* ask the tablet to report tablet data. repeats until it succeeds */
  884. + do {
  885. + edata[0] = 2;
  886. + edata[1] = 2;
  887. + usb_set_report(wacom->usbdev, wacom->ifnum, 3, 2, edata, 2);
  888. + usb_get_report(wacom->usbdev, wacom->ifnum, 3, 2, edata, 2);
  889. + } while (edata[1] != 2 && limit++ < 5);
  890. +}
  891. +
  892. static void *wacom_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)
  893. {
  894. struct usb_endpoint_descriptor *endpoint;
  895. struct wacom *wacom;
  896. - char rep_data[2] = {0x02, 0x02};
  897. -
  898. +
  899. if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) return NULL;
  900. memset(wacom, 0, sizeof(struct wacom));
  901. wacom->features = wacom_features + id->driver_info;
  902. - wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC) | wacom->features->evbit;
  903. - wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | wacom->features->absbit;
  904. + wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC) |
  905. + wacom->features->evbit;
  906. + wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) |
  907. + BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | wacom->features->absbit;
  908. wacom->dev.relbit[0] |= wacom->features->relbit;
  909. - wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | wacom->features->btnbit;
  910. - wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) |
  911. - BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2) | wacom->features->digibit;
  912. + wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) |
  913. + BIT(BTN_MIDDLE) | wacom->features->btnbit;
  914. + wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) |
  915. + BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) |
  916. + BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2) |
  917. + wacom->features->digibit;
  918. wacom->dev.mscbit[0] |= BIT(MSC_SERIAL);
  919. + #ifdef __JEJ_DEBUG
  920. + printk(KERN_INFO __FILE__ ": Reporting max %d, %d\n",
  921. + wacom->features->x_max, wacom->features->y_max);
  922. + #endif
  923. +
  924. wacom->dev.absmax[ABS_X] = wacom->features->x_max;
  925. wacom->dev.absmax[ABS_Y] = wacom->features->y_max;
  926. wacom->dev.absmax[ABS_PRESSURE] = wacom->features->pressure_max;
  927. @@ -458,6 +843,8 @@
  928. wacom->dev.absmax[ABS_TILT_Y] = 127;
  929. wacom->dev.absmax[ABS_WHEEL] = 1023;
  930. + wacom->dev.absmax[ABS_RX] = 4097;
  931. + wacom->dev.absmax[ABS_RY] = 4097;
  932. wacom->dev.absmin[ABS_RZ] = -900;
  933. wacom->dev.absmax[ABS_RZ] = 899;
  934. wacom->dev.absmin[ABS_THROTTLE] = -1023;
  935. @@ -476,35 +863,102 @@
  936. wacom->dev.idproduct = dev->descriptor.idProduct;
  937. wacom->dev.idversion = dev->descriptor.bcdDevice;
  938. wacom->usbdev = dev;
  939. + wacom->ifnum = ifnum;
  940. +
  941. + INIT_LIST_HEAD(&wacom->event_list);
  942. + init_MUTEX(&wacom->kwacomd_sem);
  943. endpoint = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0;
  944. usb_set_idle(dev, dev->config[0].interface[ifnum].altsetting[0].bInterfaceNumber, 0, 0);
  945. - FILL_INT_URB(&wacom->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress),
  946. - wacom->data, wacom->features->pktlen, wacom->features->irq, wacom, endpoint->bInterval);
  947. + FILL_INT_URB(&wacom->irq, dev, usb_rcvintpipe(dev,
  948. + endpoint->bEndpointAddress), wacom->data, wacom->features->pktlen,
  949. + wacom->features->irq, wacom, endpoint->bInterval);
  950. input_register_device(&wacom->dev);
  951. - /* ask the tablet to report tablet data */
  952. - usb_set_report(dev, ifnum, 3, 2, rep_data, 2);
  953. - usb_set_report(dev, ifnum, 3, 5, rep_data, 0);
  954. - usb_set_report(dev, ifnum, 3, 6, rep_data, 0);
  955. -
  956. - printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n",
  957. - wacom->dev.number, wacom->features->name, dev->bus->busnum, dev->devnum, ifnum);
  958. + wacom_reset(wacom);
  959. +
  960. + printk(KERN_INFO __FILE__ ": input%d: %s on usb%d:%d.%d\n",
  961. + wacom->dev.number, wacom->features->name, dev->bus->busnum,
  962. + dev->devnum, ifnum);
  963. return wacom;
  964. }
  965. static void wacom_disconnect(struct usb_device *dev, void *ptr)
  966. {
  967. + unsigned int flags;
  968. struct wacom *wacom = ptr;
  969. - usb_unlink_urb(&wacom->irq);
  970. - input_unregister_device(&wacom->dev);
  971. - kfree(wacom);
  972. + if (wacom)
  973. + {
  974. + spin_lock_irqsave(&wacom_event_lock, flags);
  975. + list_del(&wacom->event_list);
  976. + INIT_LIST_HEAD(&wacom->event_list);
  977. + spin_unlock_irqrestore(&wacom_event_lock, flags);
  978. +
  979. + /* Wait for kwacomd to leave this tablet alone. */
  980. + down(&wacom->kwacomd_sem);
  981. + up(&wacom->kwacomd_sem);
  982. +
  983. + usb_unlink_urb(&wacom->irq);
  984. + input_unregister_device(&wacom->dev);
  985. + kfree(wacom);
  986. + }
  987. +}
  988. +
  989. +static void wacom_events(void)
  990. +{
  991. + struct wacom* wacom;
  992. + unsigned int flags;
  993. + struct list_head *tmp;
  994. +
  995. + printk(KERN_INFO "wacom_events\n");
  996. +
  997. + while (1)
  998. + {
  999. + spin_lock_irqsave(&wacom_event_lock, flags);
  1000. +
  1001. + if (list_empty(&wacom_event_list))
  1002. + break;
  1003. +
  1004. + /* Grab the next entry from the beginning of the list */
  1005. + tmp = wacom_event_list.next;
  1006. + wacom = list_entry(tmp, struct wacom, event_list);
  1007. +
  1008. + list_del(tmp); /* dequeue tablet */
  1009. + INIT_LIST_HEAD(tmp);
  1010. +
  1011. + if (down_trylock(&wacom->kwacomd_sem) != 0) BUG(); /* never blocks */
  1012. + spin_unlock_irqrestore(&wacom_event_lock, flags);
  1013. +
  1014. + wacom_reset(wacom);
  1015. +
  1016. + up(&wacom->kwacomd_sem); /* mark tablet free */
  1017. + }
  1018. + spin_unlock_irqrestore(&wacom_event_lock, flags);
  1019. }
  1020. +static int wacom_thread(void* pv)
  1021. +{
  1022. + daemonize();
  1023. + reparent_to_init();
  1024. +
  1025. + /* Setup a nice name */
  1026. + strcpy(current->comm, "kwacomd");
  1027. +
  1028. + /* Send me a signal to get me die (for debugging) */
  1029. + while (!signal_pending(current))
  1030. + {
  1031. + wacom_events();
  1032. + wait_event_interruptible(kwacomd_wait, !list_empty(&wacom_event_list));
  1033. + }
  1034. +
  1035. + complete_and_exit(&kwacomd_exited, 0);
  1036. +}
  1037. +
  1038. +
  1039. static struct usb_driver wacom_driver = {
  1040. name: "wacom",
  1041. probe: wacom_probe,
  1042. @@ -514,14 +968,36 @@
  1043. static int __init wacom_init(void)
  1044. {
  1045. + int pid;
  1046. +
  1047. usb_register(&wacom_driver);
  1048. info(DRIVER_VERSION " " DRIVER_AUTHOR);
  1049. info(DRIVER_DESC);
  1050. - return 0;
  1051. +
  1052. + pid = kernel_thread(wacom_thread, NULL,
  1053. + CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
  1054. +
  1055. + if (pid >= 0)
  1056. + {
  1057. + kwacomd_pid = pid;
  1058. + return 0;
  1059. + }
  1060. +
  1061. + /* Fall through if kernel_thread failed */
  1062. + usb_deregister(&wacom_driver);
  1063. + err("failed to start wacom_thread");
  1064. +
  1065. + return -1;
  1066. }
  1067. static void __exit wacom_exit(void)
  1068. {
  1069. + int ret;
  1070. +
  1071. + /* Kill the thread */
  1072. + ret = kill_proc(kwacomd_pid, SIGTERM, 1);
  1073. + wait_for_completion(&kwacomd_exited);
  1074. +
  1075. usb_deregister(&wacom_driver);
  1076. }