public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Wacom USB driver patch
@ 2004-02-11  1:23 Ping Cheng
  2004-02-11  8:24 ` Vojtech Pavlik
  2004-03-08  9:05 ` Vojtech Pavlik
  0 siblings, 2 replies; 13+ messages in thread
From: Ping Cheng @ 2004-02-11  1:23 UTC (permalink / raw)
  To: 'linux-kernel@vger.kernel.org'
  Cc: ''vojtech@suse.cz' ', 'Greg KH '

[-- Attachment #1: Type: text/plain, Size: 903 bytes --]

 <<linuxwacom.patch>> 
Attached is a wacom driver patch for kernel 2.6. I have sent my patch to
Vojtech last year. But, he didn't commit it. I bet he's busy. So, hope
someone in this list can help me check the code in.

Please reply to me directly since I am not in linux-kernel mailing list. 

Thanks!

Ping

-----Original Message-----
From: Greg KH
To: Ping Cheng
Sent: 2/10/04 4:54 PM
Subject: Re: Wacom USB driver patch

On Tue, Feb 10, 2004 at 04:48:32PM -0800, Ping Cheng wrote:
> Can someone in the To list commit my patch? The patch is based on
wacom.c
> 1.32 and hid-core.c 1.72 at http://linux.bkbits.net:8080/linux-2.5. 

So this is for the 2.6 kernel?

Your patch is line-wrapped, and can't be applied by using 'patch -p1'
from the main kernel directory.

Vojtech would be the one to ACK this patch or not, but you also might
want to CC: the linux-usb-devel mailing list.

thanks,

greg k-h

[-- Attachment #2: linuxwacom.patch --]
[-- Type: application/octet-stream, Size: 16020 bytes --]

diff -purN wacom.c@1.32 wacom.c
--- wacom.c@1.32	2004-02-10 14:32:01.000000000 -0800
+++ wacom.c	2004-02-10 15:34:00.000000000 -0800
@@ -8,7 +8,7 @@
  *  Copyright (c) 2000 James E. Blair		<corvus@gnu.org>
  *  Copyright (c) 2000 Daniel Egger		<egger@suse.de>
  *  Copyright (c) 2001 Frederic Lepied		<flepied@mandrakesoft.com>
- *  Copyright (c) 2002 Ping Cheng		<pingc@wacom.com>
+ *  Copyright (c) 2002-2004 Ping Cheng		<pingc@wacom.com>
  *
  *  ChangeLog:
  *      v0.1 (vp)  - Initial release
@@ -137,14 +137,12 @@ static void wacom_pl_irq(struct urb *urb
 	}
 
 	if (data[0] != 2)
-		dbg("received unknown report #%d", data[0]);
+		dbg("wacom_pl_irq: received unknown report #%d", data[0]);
 
 	prox = data[1] & 0x40;
 
 	input_regs(dev, regs);
 	
-	input_report_key(dev, BTN_TOOL_PEN, prox);
-	
 	if (prox) {
 
 		pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
@@ -152,15 +150,103 @@ static void wacom_pl_irq(struct urb *urb
 			pressure = (pressure << 1) | ((data[4] >> 6) & 1);
 		pressure += (wacom->features->pressure_max + 1) / 2;
 
+		/*
+		 * if going from out of proximity into proximity select between the eraser
+		 * and the pen based on the state of the stylus2 button, choose eraser if
+		 * pressed else choose pen. if not a proximity change from out to in, send
+		 * an out of proximity for previous tool then a in for new tool.
+		 */
+		if (!wacom->tool[0]) {
+			/* Going into proximity select tool */
+			wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+		}
+		else {
+			/* was entered with stylus2 pressed */
+			if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) {
+				/* report out proximity for previous tool */
+				input_report_key(dev, wacom->tool[1], 0);
+				input_sync(dev);
+				wacom->tool[1] = BTN_TOOL_PEN;
+				return;
+			}
+		}
+		if (wacom->tool[1] != BTN_TOOL_RUBBER) {
+			/* Unknown tool selected default to pen tool */
+			wacom->tool[1] = BTN_TOOL_PEN;
+		}
+		input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */
 		input_report_abs(dev, ABS_X, data[3] | ((__u32)data[2] << 7) | ((__u32)(data[1] & 0x03) << 14));
 		input_report_abs(dev, ABS_Y, data[6] | ((__u32)data[5] << 7) | ((__u32)(data[4] & 0x03) << 14));
 		input_report_abs(dev, ABS_PRESSURE, pressure);
 
 		input_report_key(dev, BTN_TOUCH, data[4] & 0x08);
 		input_report_key(dev, BTN_STYLUS, data[4] & 0x10);
-		input_report_key(dev, BTN_STYLUS2, data[4] & 0x20);
+		/* Only allow the stylus2 button to be reported for the pen tool. */
+		input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));
 	}
-	
+	else {
+		/* report proximity-out of a (valid) tool */
+		if (wacom->tool[1] != BTN_TOOL_RUBBER) {
+			/* Unknown tool selected default to pen tool */
+			wacom->tool[1] = BTN_TOOL_PEN;
+		}
+		input_report_key(dev, wacom->tool[1], prox);
+	}
+
+	wacom->tool[0] = prox; /* Save proximity state */
+	input_sync(dev);
+
+exit:
+	retval = usb_submit_urb (urb, GFP_ATOMIC);
+	if (retval)
+		err ("%s - usb_submit_urb failed with result %d",
+		     __FUNCTION__, retval);
+}
+
+static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs)
+{
+	struct wacom *wacom = urb->context;
+	unsigned char *data = wacom->data;
+	struct input_dev *dev = &wacom->dev;
+	int retval;
+
+	switch (urb->status) {
+	case 0:
+		/* success */
+		break;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		/* this urb is terminated, clean up */
+		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+		return;
+	default:
+		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+		goto exit;
+	}
+
+	if (data[0] != 2)
+	{
+		printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
+	}
+
+	input_regs(dev, regs);
+	if (data[1] & 0x04)
+	{
+		input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20);
+		input_report_key(dev, BTN_TOUCH, data[1] & 0x08);
+	}
+	else
+	{
+		input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20);
+		input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
+	}
+	input_report_abs(dev, ABS_X, data[3] << 8 | data[2]);
+	input_report_abs(dev, ABS_Y, data[5] << 8 | data[4]);
+	input_report_abs(dev, ABS_PRESSURE, (data[6]|data[7] << 8));
+	input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
+	input_report_key(dev, BTN_STYLUS2, data[1] & 0x10);
+
 	input_sync(dev);
 
 exit:
@@ -231,8 +317,12 @@ static void wacom_graphire_irq(struct ur
 		goto exit;
 	}
 
+	/* check if we can handle the data */
+	if (data[0] == 99)
+		return;
+
 	if (data[0] != 2)
-		dbg("received unknown report #%d", data[0]);
+		dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
 
 	x = data[2] | ((__u32)data[3] << 8);
 	y = data[4] | ((__u32)data[5] << 8);
@@ -249,13 +339,16 @@ static void wacom_graphire_irq(struct ur
 			input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x80);
 			break;
 
-		case 2: /* Mouse */
+		case 2: /* Mouse with wheel */
+			input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
+			input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
+			/* fall through */
+
+                case 3: /* Mouse without wheel */
 			input_report_key(dev, BTN_TOOL_MOUSE, data[7] > 24);
 			input_report_key(dev, BTN_LEFT, data[1] & 0x01);
 			input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
-			input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
 			input_report_abs(dev, ABS_DISTANCE, data[7]);
-			input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
 
 			input_report_abs(dev, ABS_X, x);
 			input_report_abs(dev, ABS_Y, y);
@@ -308,7 +401,7 @@ static void wacom_intuos_irq(struct urb 
 	}
 
 	if (data[0] != 2)
-		dbg("received unknown report #%d", data[0]);
+		dbg("wacom_intuos_irq: received unknown report #%d", data[0]);
 
 	input_regs(dev, regs);
 
@@ -317,18 +410,18 @@ static void wacom_intuos_irq(struct urb 
 
 	if ((data[1] & 0xfc) == 0xc0) {						/* Enter report */
 
-		wacom->serial[idx] = ((__u32)(data[3] & 0x0f) << 4) +		/* serial number of the tool */
-			((__u32)data[4] << 16) + ((__u32)data[5] << 12) +
+		wacom->serial[idx] = ((__u32)(data[3] & 0x0f) << 28) +		/* serial number of the tool */
+			((__u32)data[4] << 20) + ((__u32)data[5] << 12) +
 			((__u32)data[6] << 4) + (data[7] >> 4);
 
 		switch (((__u32)data[2] << 4) | (data[3] >> 4)) {
-			case 0x832:
+			case 0x812:
 			case 0x012: wacom->tool[idx] = BTN_TOOL_PENCIL;		break;	/* Inking pen */
 			case 0x822:
 			case 0x842:
 			case 0x852:
 			case 0x022: wacom->tool[idx] = BTN_TOOL_PEN;		break;	/* Pen */
-			case 0x812:
+			case 0x832:
 			case 0x032: wacom->tool[idx] = BTN_TOOL_BRUSH;		break;	/* Stroke pen */
 			case 0x007:
 		        case 0x09c:
@@ -337,7 +430,10 @@ static void wacom_intuos_irq(struct urb 
 			case 0x82a:
 			case 0x85a:
 		        case 0x91a:
+			case 0xd1a:
 			case 0x0fa: wacom->tool[idx] = BTN_TOOL_RUBBER;		break;	/* Eraser */
+			case 0xd12:
+			case 0x912:
 			case 0x112: wacom->tool[idx] = BTN_TOOL_AIRBRUSH;	break;	/* Airbrush */
 			default:    wacom->tool[idx] = BTN_TOOL_PEN;		break;	/* Unknown tool */
 		}
@@ -350,13 +446,14 @@ static void wacom_intuos_irq(struct urb 
 
 	if ((data[1] & 0xfe) == 0x80) {						/* Exit report */
 		input_report_key(dev, wacom->tool[idx], 0);
+		input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
 		input_sync(dev);
 		goto exit;
 	}
 
 	input_report_abs(dev, ABS_X, ((__u32)data[2] << 8) | data[3]);
 	input_report_abs(dev, ABS_Y, ((__u32)data[4] << 8) | data[5]);
-	input_report_abs(dev, ABS_DISTANCE, data[9] >> 4);
+	input_report_abs(dev, ABS_DISTANCE, data[9]);
 
 	if ((data[1] & 0xb8) == 0xa0) {						/* general pen packet */
 		input_report_abs(dev, ABS_PRESSURE, t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3));
@@ -378,8 +475,8 @@ static void wacom_intuos_irq(struct urb 
 		if (data[1] & 0x02) {						/* Rotation packet */
 
 			input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ?
-					 ((__u32)data[6] << 2) | ((data[7] >> 6) & 3):
-					 (-(((__u32)data[6] << 2) | ((data[7] >> 6) & 3))) - 1);
+					 ((__u32)data[6] << 3) | ((data[7] >> 5) & 7):
+					 (-(((__u32)data[6] << 3) | ((data[7] >> 5) & 7))) - 1);
 
 		} else {
 
@@ -391,17 +488,17 @@ static void wacom_intuos_irq(struct urb 
 
 				input_report_key(dev, BTN_SIDE,   data[8] & 0x20);
 				input_report_key(dev, BTN_EXTRA,  data[8] & 0x10);
-				input_report_abs(dev, ABS_THROTTLE,  (data[8] & 0x08) ?
+				input_report_abs(dev, ABS_THROTTLE,  -((data[8] & 0x08) ?
 						 ((__u32)data[6] << 2) | ((data[7] >> 6) & 3) :
-						 -((__u32)data[6] << 2) | ((data[7] >> 6) & 3));
+						 -((__u32)data[6] << 2) | ((data[7] >> 6) & 3)));
 
 			} else {
 				if (wacom->tool[idx] == BTN_TOOL_MOUSE) {	/* 2D mouse packets */	
 					input_report_key(dev, BTN_LEFT,   data[8] & 0x04);
 					input_report_key(dev, BTN_MIDDLE, data[8] & 0x08);
 					input_report_key(dev, BTN_RIGHT,  data[8] & 0x10);
-					input_report_abs(dev, REL_WHEEL, 
-					    ((__u32)(data[8] & 0x01) - (__u32)((data[8] & 0x02) >> 1)));
+					input_report_rel(dev, REL_WHEEL, 
+					    (-(__u32)(data[8] & 0x01) + (__u32)((data[8] & 0x02) >> 1)));
 				}
 				else {     /* Lens cursor packets */
 					input_report_key(dev, BTN_LEFT,   data[8] & 0x01);
@@ -414,6 +511,8 @@ static void wacom_intuos_irq(struct urb 
 		}
 	}
 	
+	input_report_key(dev, wacom->tool[idx], 1);
+	input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
 	input_sync(dev);
 
 exit:
@@ -429,22 +528,26 @@ struct wacom_features wacom_features[] =
 	{ "Wacom Graphire2 4x5", 8,  10206,  7422,  511, 32, 1, wacom_graphire_irq },
  	{ "Wacom Graphire2 5x7", 8,  13918, 10206,  511, 32, 1, wacom_graphire_irq },
 	{ "Wacom Graphire3",     8,  10208,  7424,  511, 32, 1, wacom_graphire_irq },
-  	{ "Wacom Intuos 4x5",   10,  12700, 10360, 1023, 15, 2, wacom_intuos_irq },
- 	{ "Wacom Intuos 6x8",   10,  20600, 16450, 1023, 15, 2, wacom_intuos_irq },
- 	{ "Wacom Intuos 9x12",  10,  30670, 24130, 1023, 15, 2, wacom_intuos_irq },
- 	{ "Wacom Intuos 12x12", 10,  30670, 31040, 1023, 15, 2, wacom_intuos_irq },
- 	{ "Wacom Intuos 12x18", 10,  45860, 31040, 1023, 15, 2, wacom_intuos_irq },
+	{ "Wacom Graphire3 6x8", 8,  16704, 12064,  511, 32, 1, wacom_graphire_irq },
+  	{ "Wacom Intuos 4x5",   10,  12700, 10600, 1023, 15, 2, wacom_intuos_irq },
+ 	{ "Wacom Intuos 6x8",   10,  20320, 16240, 1023, 15, 2, wacom_intuos_irq },
+ 	{ "Wacom Intuos 9x12",  10,  30480, 24060, 1023, 15, 2, wacom_intuos_irq },
+ 	{ "Wacom Intuos 12x12", 10,  30480, 31680, 1023, 15, 2, wacom_intuos_irq },
+ 	{ "Wacom Intuos 12x18", 10,  45720, 31680, 1023, 15, 2, wacom_intuos_irq },
  	{ "Wacom PL400",         8,   5408,  4056,  255, 32, 3, wacom_pl_irq },
  	{ "Wacom PL500",         8,   6144,  4608,  255, 32, 3, wacom_pl_irq },
  	{ "Wacom PL600",         8,   6126,  4604,  255, 32, 3, wacom_pl_irq },
  	{ "Wacom PL600SX",       8,   6260,  5016,  255, 32, 3, wacom_pl_irq },
  	{ "Wacom PL550",         8,   6144,  4608,  511, 32, 3, wacom_pl_irq },
  	{ "Wacom PL800",         8,   7220,  5780,  511, 32, 3, wacom_pl_irq },
-	{ "Wacom Intuos2 4x5",   10, 12700, 10360, 1023, 15, 2, wacom_intuos_irq },
-	{ "Wacom Intuos2 6x8",   10, 20600, 16450, 1023, 15, 2, wacom_intuos_irq },
-	{ "Wacom Intuos2 9x12",  10, 30670, 24130, 1023, 15, 2, wacom_intuos_irq },
-	{ "Wacom Intuos2 12x12", 10, 30670, 31040, 1023, 15, 2, wacom_intuos_irq },
-	{ "Wacom Intuos2 12x18", 10, 45860, 31040, 1023, 15, 2, wacom_intuos_irq },
+	{ "Wacom Intuos2 4x5",   10, 12700, 10600, 1023, 15, 2, wacom_intuos_irq },
+	{ "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq },
+	{ "Wacom Intuos2 9x12",  10, 30480, 24060, 1023, 15, 2, wacom_intuos_irq },
+	{ "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, 2, wacom_intuos_irq },
+	{ "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, 2, wacom_intuos_irq },
+	{ "Wacom Volito",        8,   5104,  3712,  511, 32, 1, wacom_graphire_irq },
+	{ "Wacom Cintiq Partner",8,  20480, 15360,  511, 32, 3, wacom_ptu_irq },
+	{ "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq },
  	{ }
 };
 
@@ -454,6 +557,7 @@ struct usb_device_id wacom_ids[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) },
@@ -470,6 +574,9 @@ struct usb_device_id wacom_ids[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) },
+        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) },
+        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) },
+        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
 	{ }
 };
 
@@ -538,8 +645,9 @@ static int wacom_probe(struct usb_interf
 			break;
 
 		case 2:
-			wacom->dev.evbit[0] |= BIT(EV_MSC);
+			wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
 			wacom->dev.mscbit[0] |= BIT(MSC_SERIAL);
+			wacom->dev.relbit[0] |= BIT(REL_WHEEL);
 			wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
  			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE)	| BIT(BTN_TOOL_BRUSH)
 							  | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2);

diff -purN hid-core.c@1.72 hid-core.c
--- hid-core.c@1.72	2004-02-10 11:59:31.000000000 -0800
+++ hid-core.c	2004-02-10 12:30:33.000000000 -0800
@@ -1313,6 +1313,8 @@ void hid_init_reports(struct hid_device 
 #define USB_DEVICE_ID_WACOM_INTUOS	0x0020
 #define USB_DEVICE_ID_WACOM_PL		0x0030
 #define USB_DEVICE_ID_WACOM_INTUOS2	0x0040
+#define USB_DEVICE_ID_WACOM_VOLITO      0x0060
+#define USB_DEVICE_ID_WACOM_PTU         0x0003
 
 #define USB_VENDOR_ID_KBGEAR            0x084e
 #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO  0x1001
@@ -1372,6 +1374,7 @@ struct hid_blacklist {
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 2, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 3, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 4, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 1, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 2, HID_QUIRK_IGNORE },
@@ -1383,11 +1386,14 @@ struct hid_blacklist {
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 3, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 4, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 5, HID_QUIRK_IGNORE },
-	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 1, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 2, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 4, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 5, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_6000, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Wacom USB driver patch
  2004-02-11  1:23 Wacom USB driver patch Ping Cheng
@ 2004-02-11  8:24 ` Vojtech Pavlik
  2004-03-08  9:05 ` Vojtech Pavlik
  1 sibling, 0 replies; 13+ messages in thread
From: Vojtech Pavlik @ 2004-02-11  8:24 UTC (permalink / raw)
  To: Ping Cheng; +Cc: 'linux-kernel@vger.kernel.org', 'Greg KH '

On Tue, Feb 10, 2004 at 05:23:11PM -0800, Ping Cheng wrote:

>  <<linuxwacom.patch>> 
> Attached is a wacom driver patch for kernel 2.6. I have sent my patch to
> Vojtech last year. But, he didn't commit it. I bet he's busy. So, hope
> someone in this list can help me check the code in.
> 
> Please reply to me directly since I am not in linux-kernel mailing list. 

I'll take a look at it.

> Thanks!
> 
> Ping
> 
> -----Original Message-----
> From: Greg KH
> To: Ping Cheng
> Sent: 2/10/04 4:54 PM
> Subject: Re: Wacom USB driver patch
> 
> On Tue, Feb 10, 2004 at 04:48:32PM -0800, Ping Cheng wrote:
> > Can someone in the To list commit my patch? The patch is based on
> wacom.c
> > 1.32 and hid-core.c 1.72 at http://linux.bkbits.net:8080/linux-2.5. 
> 
> So this is for the 2.6 kernel?
> 
> Your patch is line-wrapped, and can't be applied by using 'patch -p1'
> from the main kernel directory.
> 
> Vojtech would be the one to ACK this patch or not, but you also might
> want to CC: the linux-usb-devel mailing list.
> 
> thanks,
> 
> greg k-h



-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Wacom USB driver patch
       [not found] <mailman.1076463721.27289.linux-kernel2news@redhat.com>
@ 2004-02-11 19:04 ` Pete Zaitcev
  0 siblings, 0 replies; 13+ messages in thread
From: Pete Zaitcev @ 2004-02-11 19:04 UTC (permalink / raw)
  To: Ping Cheng; +Cc: linux-kernel, vojtech

On Tue, 10 Feb 2004 17:23:11 -0800
Ping Cheng <pingc@wacom.com> wrote:

>  <<linuxwacom.patch>> 

This looks much better, it's not line-wrapped.

I have one question though, about this part:

@@ -152,15 +150,103 @@ static void wacom_pl_irq(struct urb *urb

+                       /* was entered with stylus2 pressed */
+                       if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) {
+                               /* report out proximity for previous tool */
+                               input_report_key(dev, wacom->tool[1], 0);
+                               input_sync(dev);
+                               wacom->tool[1] = BTN_TOOL_PEN;
+                               return;
+                       }

Is it safe to just return without resubmitting the urb here?

@@ -231,8 +317,12 @@ static void wacom_graphire_irq(struct ur
+       /* check if we can handle the data */
+       if (data[0] == 99)
+               return;
+
        if (data[0] != 2)

Same here.

Also, please add the path to the patch, e.g. always use recursive diff.

-- Pete

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: Wacom USB driver patch
@ 2004-02-11 19:47 Ping Cheng
  2004-02-11 20:04 ` Vojtech Pavlik
  0 siblings, 1 reply; 13+ messages in thread
From: Ping Cheng @ 2004-02-11 19:47 UTC (permalink / raw)
  To: 'Pete Zaitcev'; +Cc: linux-kernel, vojtech

Nice catch, Pete. The Two "return"s should be replaced by "goto exit". 

Vojtech, should I make another patch or you can handle it with my previous
one?

Thanks, both of you!

Ping

-----Original Message-----
From: Pete Zaitcev [mailto:zaitcev@redhat.com] 
Sent: Wednesday, February 11, 2004 11:05 AM
To: Ping Cheng
Cc: linux-kernel@vger.kernel.org; vojtech@suse.cz
Subject: Re: Wacom USB driver patch


On Tue, 10 Feb 2004 17:23:11 -0800
Ping Cheng <pingc@wacom.com> wrote:

>  <<linuxwacom.patch>>

This looks much better, it's not line-wrapped.

I have one question though, about this part:

@@ -152,15 +150,103 @@ static void wacom_pl_irq(struct urb *urb

+                       /* was entered with stylus2 pressed */
+                       if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] &
0x20) ) {
+                               /* report out proximity for previous tool */
+                               input_report_key(dev, wacom->tool[1], 0);
+                               input_sync(dev);
+                               wacom->tool[1] = BTN_TOOL_PEN;
+                               return;
+                       }

Is it safe to just return without resubmitting the urb here?

@@ -231,8 +317,12 @@ static void wacom_graphire_irq(struct ur
+       /* check if we can handle the data */
+       if (data[0] == 99)
+               return;
+
        if (data[0] != 2)

Same here.

Also, please add the path to the patch, e.g. always use recursive diff.

-- Pete

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Wacom USB driver patch
  2004-02-11 19:47 Ping Cheng
@ 2004-02-11 20:04 ` Vojtech Pavlik
  0 siblings, 0 replies; 13+ messages in thread
From: Vojtech Pavlik @ 2004-02-11 20:04 UTC (permalink / raw)
  To: Ping Cheng; +Cc: 'Pete Zaitcev', linux-kernel

On Wed, Feb 11, 2004 at 11:47:19AM -0800, Ping Cheng wrote:
> Nice catch, Pete. The Two "return"s should be replaced by "goto exit". 
> 
> Vojtech, should I make another patch or you can handle it with my previous
> one?

It's okay, you don't need to make another patch.

> 
> Thanks, both of you!
> 
> Ping
> 
> -----Original Message-----
> From: Pete Zaitcev [mailto:zaitcev@redhat.com] 
> Sent: Wednesday, February 11, 2004 11:05 AM
> To: Ping Cheng
> Cc: linux-kernel@vger.kernel.org; vojtech@suse.cz
> Subject: Re: Wacom USB driver patch
> 
> 
> On Tue, 10 Feb 2004 17:23:11 -0800
> Ping Cheng <pingc@wacom.com> wrote:
> 
> >  <<linuxwacom.patch>>
> 
> This looks much better, it's not line-wrapped.
> 
> I have one question though, about this part:
> 
> @@ -152,15 +150,103 @@ static void wacom_pl_irq(struct urb *urb
> 
> +                       /* was entered with stylus2 pressed */
> +                       if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] &
> 0x20) ) {
> +                               /* report out proximity for previous tool */
> +                               input_report_key(dev, wacom->tool[1], 0);
> +                               input_sync(dev);
> +                               wacom->tool[1] = BTN_TOOL_PEN;
> +                               return;
> +                       }
> 
> Is it safe to just return without resubmitting the urb here?
> 
> @@ -231,8 +317,12 @@ static void wacom_graphire_irq(struct ur
> +       /* check if we can handle the data */
> +       if (data[0] == 99)
> +               return;
> +
>         if (data[0] != 2)
> 
> Same here.
> 
> Also, please add the path to the patch, e.g. always use recursive diff.
> 
> -- Pete
> 

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: Wacom USB driver patch
@ 2004-02-13  0:55 Ping Cheng
  2004-02-13  3:28 ` Pete Zaitcev
  0 siblings, 1 reply; 13+ messages in thread
From: Ping Cheng @ 2004-02-13  0:55 UTC (permalink / raw)
  To: 'Vojtech Pavlik'; +Cc: 'Pete Zaitcev', linux-kernel

The wacom.c at http://linux.bkbits.net:8080/linux-2.4 is way out of date and
people are still working on/using 2.4 releases. Should I make a patch for
2.4?

Ping

-----Original Message-----
From: Vojtech Pavlik [mailto:vojtech@suse.cz] 
Sent: Wednesday, February 11, 2004 12:05 PM
To: Ping Cheng
Cc: 'Pete Zaitcev'; linux-kernel@vger.kernel.org
Subject: Re: Wacom USB driver patch


On Wed, Feb 11, 2004 at 11:47:19AM -0800, Ping Cheng wrote:
> Nice catch, Pete. The Two "return"s should be replaced by "goto exit".
> 
> Vojtech, should I make another patch or you can handle it with my 
> previous one?

It's okay, you don't need to make another patch.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Wacom USB driver patch
  2004-02-13  0:55 Ping Cheng
@ 2004-02-13  3:28 ` Pete Zaitcev
  2004-02-13  8:13   ` Vojtech Pavlik
  0 siblings, 1 reply; 13+ messages in thread
From: Pete Zaitcev @ 2004-02-13  3:28 UTC (permalink / raw)
  To: Ping Cheng; +Cc: vojtech, linux-kernel

On Thu, 12 Feb 2004 16:55:47 -0800
Ping Cheng <pingc@wacom.com> wrote:

> The wacom.c at http://linux.bkbits.net:8080/linux-2.4 is way out of date and
> people are still working on/using 2.4 releases. Should I make a patch for
> 2.4?

We plan to support 2.4 based releases for several years yet. If Vojtech
approves what you did for 2.6, I am all for a backport to Marcelo tree.
Marcelo is not very forthcoming with approvals these days, but perhaps
it may be folded into some update. But as usual I would like to avoid
carrying a patch in Red Hat tree, if at all possible.

-- Pete

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Wacom USB driver patch
  2004-02-13  3:28 ` Pete Zaitcev
@ 2004-02-13  8:13   ` Vojtech Pavlik
  0 siblings, 0 replies; 13+ messages in thread
From: Vojtech Pavlik @ 2004-02-13  8:13 UTC (permalink / raw)
  To: Pete Zaitcev; +Cc: Ping Cheng, linux-kernel

On Thu, Feb 12, 2004 at 07:28:09PM -0800, Pete Zaitcev wrote:
> On Thu, 12 Feb 2004 16:55:47 -0800
> Ping Cheng <pingc@wacom.com> wrote:
> 
> > The wacom.c at http://linux.bkbits.net:8080/linux-2.4 is way out of date and
> > people are still working on/using 2.4 releases. Should I make a patch for
> > 2.4?
> 
> We plan to support 2.4 based releases for several years yet. If Vojtech
> approves what you did for 2.6, I am all for a backport to Marcelo tree.
> Marcelo is not very forthcoming with approvals these days, but perhaps
> it may be folded into some update. But as usual I would like to avoid
> carrying a patch in Red Hat tree, if at all possible.

Agreed. Same for us at SUSE.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: Wacom USB driver patch
@ 2004-02-20 22:29 Ping Cheng
  0 siblings, 0 replies; 13+ messages in thread
From: Ping Cheng @ 2004-02-20 22:29 UTC (permalink / raw)
  To: 'Vojtech Pavlik ', 'Pete Zaitcev '
  Cc: 'linux-kernel@vger.kernel.org '

[-- Attachment #1: Type: text/plain, Size: 1048 bytes --]

 <<wacom_2.4.patch>> 
The attached patch is against the latest versions of wacom.c and hid-core.c
at  http://linux.bkbits.net:8080/linux-2.4.

Ping

-----Original Message-----
From: Vojtech Pavlik
To: Pete Zaitcev
Cc: Ping Cheng; linux-kernel@vger.kernel.org
Sent: 2/13/04 12:13 AM
Subject: Re: Wacom USB driver patch

On Thu, Feb 12, 2004 at 07:28:09PM -0800, Pete Zaitcev wrote:
> On Thu, 12 Feb 2004 16:55:47 -0800
> Ping Cheng <pingc@wacom.com> wrote:
> 
> > The wacom.c at http://linux.bkbits.net:8080/linux-2.4 is way out of
date and
> > people are still working on/using 2.4 releases. Should I make a
patch for
> > 2.4?
> 
> We plan to support 2.4 based releases for several years yet. If
Vojtech
> approves what you did for 2.6, I am all for a backport to Marcelo
tree.
> Marcelo is not very forthcoming with approvals these days, but perhaps
> it may be folded into some update. But as usual I would like to avoid
> carrying a patch in Red Hat tree, if at all possible.

Agreed. Same for us at SUSE.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

[-- Attachment #2: wacom_2.4.patch --]
[-- Type: application/octet-stream, Size: 25372 bytes --]

--- linux-2.4/drivers/usb/hid-core.c@1.27	2004-02-18 16:30:18.000000000 -0800
+++ linux-2.4/drivers/usb/hid-core.c	2004-02-18 16:47:49.000000000 -0800
@@ -1135,7 +1135,9 @@ void hid_init_reports(struct hid_device 
 #define USB_DEVICE_ID_WACOM_GRAPHIRE	0x0010
 #define USB_DEVICE_ID_WACOM_INTUOS	0x0020
 #define USB_DEVICE_ID_WACOM_PL		0x0030
-#define USB_DEVICE_ID_WACOM_INTUOS2	0x0041
+#define USB_DEVICE_ID_WACOM_INTUOS2	0x0040
+#define USB_DEVICE_ID_WACOM_VOLITO	0x0060
+#define USB_DEVICE_ID_WACOM_PTU		0x0003
 
 #define USB_VENDOR_ID_KBGEAR		0x084e
 #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO	0x1001
@@ -1203,11 +1205,16 @@ struct hid_blacklist {
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 3, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 4, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 5, HID_QUIRK_IGNORE },
-	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 1, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 2, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 4, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 5, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 3, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 4, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
--- linux-2.4/drivers/usb/wacom.c@1.9	2004-02-17 15:46:42.000000000 -0800
+++ linux-2.4/drivers/usb/wacom.c	2004-02-18 15:07:30.000000000 -0800
@@ -1,13 +1,15 @@
 /*
  * $Id: wacom.c,v 1.23 2001/05/29 12:57:18 vojtech Exp $
  *
- *  Copyright (c) 2000-2001 Vojtech Pavlik	<vojtech@suse.cz>
+ *  Copyright (c) 2000-2004 Vojtech Pavlik	<vojtech@suse.cz>
  *  Copyright (c) 2000 Andreas Bach Aaen	<abach@stofanet.dk>
  *  Copyright (c) 2000 Clifford Wolf		<clifford@clifford.at>
  *  Copyright (c) 2000 Sam Mosel		<sam.mosel@computer.org>
  *  Copyright (c) 2000 James E. Blair		<corvus@gnu.org>
  *  Copyright (c) 2000 Daniel Egger		<egger@suse.de>
  *  Copyright (c) 2001 Frederic Lepied		<flepied@mandrakesoft.com>
+ *  Copyright (c) 2002-2004 Ping Cheng		<pingc@wacom.com>
+ *  Copyright (c) 2002-2003 John Joganic	<john@joganic.com>
  *
  *  USB Wacom Graphire and Wacom Intuos tablet support
  *
@@ -74,6 +76,8 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb.h>
+#include <linux/smp_lock.h>
+#include <linux/list.h>
 
 /*
  * Version Information
@@ -88,6 +92,12 @@ MODULE_LICENSE("GPL");
 
 #define USB_VENDOR_ID_WACOM	0x056a
 
+static int kwacomd_pid = 0;			/* PID of kwacomd */
+static DECLARE_COMPLETION(kwacomd_exited);
+static DECLARE_WAIT_QUEUE_HEAD(kwacomd_wait);
+static LIST_HEAD(wacom_event_list);   /* List of tablets needing servicing */
+static spinlock_t wacom_event_lock = SPIN_LOCK_UNLOCKED;
+
 struct wacom_features {
 	char *name;
 	int pktlen;
@@ -112,36 +122,124 @@ struct wacom {
 	int tool[2];
 	int open;
 	__u32 serial[2];
+	struct list_head event_list;
+	struct semaphore kwacomd_sem;
+	unsigned int ifnum;
 };
 
+static void wacom_request_reset(struct wacom* wacom)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&wacom_event_lock, flags);
+	if (list_empty(&wacom->event_list))
+	{
+		list_add(&wacom->event_list, &wacom_event_list);
+		wake_up(&kwacomd_wait);
+	}
+	spin_unlock_irqrestore(&wacom_event_lock, flags);
+}
+
 static void wacom_pl_irq(struct urb *urb)
 {
 	struct wacom *wacom = urb->context;
 	unsigned char *data = wacom->data;
 	struct input_dev *dev = &wacom->dev;
-	int prox;
+	int prox, pressure;
 
 	if (urb->status) return;
 
 	if (data[0] != 2) {
-		printk(KERN_ERR "wacom_pl_irq: received unknown report #%d\n", data[0]);
+		printk(KERN_INFO "wacom_pl_irq: received unknown report #%d\n", data[0]);
+		wacom_request_reset(wacom);
 		return;
 	}
 	
-	prox = data[1] & 0x20;
-	
-	input_report_key(dev, BTN_TOOL_PEN, prox);
-	
+	prox = data[1] & 0x40;
+
 	if (prox) {
-		int pressure = (data[4] & 0x04) >> 2 | ((__u32)(data[7] & 0x7f) << 1);
+		pressure = (signed char) ((data[7] <<1 ) | ((data[4] >> 2) & 1));
+		if ( wacom->features->pressure_max > 350 ) {
+			pressure = (pressure << 1) | ((data[4] >> 6) & 1);
+                } 
+		pressure += (( wacom->features->pressure_max + 1 )/ 2);
+
+		/*
+		 * if going from out of proximity into proximity select between the eraser
+		 * and the pen based on the state of the stylus2 button, choose eraser if
+		 * pressed else choose pen. if not a proximity change from out to in, send
+		 * an out of proximity for previous tool then a in for new tool.
+		 */
+		if (!wacom->tool[0]) {
+			/* Going into proximity select tool */
+			wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+		}
+		else {
+			/* was entered with stylus2 pressed */
+			if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) {
+				/* report out proximity for previous tool */
+				input_report_key(dev, wacom->tool[1], 0);
+				input_event(dev, EV_MSC, MSC_SERIAL, 0);
+				wacom->tool[1] = BTN_TOOL_PEN;
+				return;
+			}
+		}
+		if (wacom->tool[1] != BTN_TOOL_RUBBER) {
+			/* Unknown tool selected default to pen tool */
+			wacom->tool[1] = BTN_TOOL_PEN;
+		}
+		input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */
 
-		input_report_abs(dev, ABS_X, data[3] | ((__u32)data[2] << 8) | ((__u32)(data[1] & 0x03) << 16));
-		input_report_abs(dev, ABS_Y, data[6] | ((__u32)data[5] << 8) | ((__u32)(data[4] & 0x03) << 8));
-		input_report_abs(dev, ABS_PRESSURE, (data[7] & 0x80) ? (255 - pressure) : (pressure + 255));
+		input_report_abs(dev, ABS_X, data[3] | ((__u32)data[2] << 7) | ((__u32)(data[1] & 0x03) << 14));
+		input_report_abs(dev, ABS_Y, data[6] | ((__u32)data[5] << 7) | ((__u32)(data[4] & 0x03) << 14));
+		input_report_abs(dev, ABS_PRESSURE, pressure);
 		input_report_key(dev, BTN_TOUCH, data[4] & 0x08);
 		input_report_key(dev, BTN_STYLUS, data[4] & 0x10);
-		input_report_key(dev, BTN_STYLUS2, data[4] & 0x20);
+		/* Only allow the stylus2 button to be reported for the pen tool. */
+		input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));
 	}
+	else {
+		/* report proximity-out of a (valid) tool */
+		if (wacom->tool[1] != BTN_TOOL_RUBBER) {
+			/* Unknown tool selected default to pen tool */
+			wacom->tool[1] = BTN_TOOL_PEN;
+		}
+		input_report_key(dev, wacom->tool[1], prox);
+	}
+	wacom->tool[0] = prox; /* Save proximity state */
+	
+	input_event(dev, EV_MSC, MSC_SERIAL, 0);
+}
+
+static void wacom_ptu_irq(struct urb *urb)
+{
+	struct wacom *wacom = urb->context;
+	unsigned char *data = wacom->data;
+	struct input_dev *dev = &wacom->dev;
+
+	if (urb->status) return;
+
+	if (data[0] != 2)
+	{
+		printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
+		wacom_request_reset(wacom);
+		return;
+	}
+	
+	if (data[1] & 0x04) 
+	{
+		input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20);
+		input_report_key(dev, BTN_TOUCH, data[1] & 0x08);
+	}
+	else
+	{
+		input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20);
+		input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
+	}
+	input_report_abs(dev, ABS_X, data[3] << 8 | data[2]);
+	input_report_abs(dev, ABS_Y, data[5] << 8 | data[4]);
+	input_report_abs(dev, ABS_PRESSURE, (data[6]|data[7] << 8));
+	input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
+	input_report_key(dev, BTN_STYLUS2, data[1] & 0x10);
 	
 	input_event(dev, EV_MSC, MSC_SERIAL, 0);
 }
@@ -152,7 +250,7 @@ static void wacom_penpartner_irq(struct 
 	unsigned char *data = wacom->data;
 	struct input_dev *dev = &wacom->dev;
 	int x, y; 
-	char pressure; 
+	signed char pressure; 
 	int leftmb;
 
 	if (urb->status) return;
@@ -160,15 +258,15 @@ static void wacom_penpartner_irq(struct 
 	x = data[2] << 8 | data[1];
 	y = data[4] << 8 | data[3];
 	pressure = data[6];
-	leftmb = ((pressure > -80) && !(data[5] &20));
+	leftmb = ((pressure > -80) && !(data[5] & 0x20));
 
 	input_report_key(dev, BTN_TOOL_PEN, 1);
 
 	input_report_abs(dev, ABS_X, x);
 	input_report_abs(dev, ABS_Y, y);
 	input_report_abs(dev, ABS_PRESSURE, pressure+127);
-	input_report_key(dev, BTN_LEFT, leftmb);
-	input_report_key(dev, BTN_RIGHT, (data[5] & 0x40));
+	input_report_key(dev, BTN_TOUCH, leftmb);
+	input_report_key(dev, BTN_STYLUS, (data[5] & 0x40));
 	
 	input_event(dev, EV_MSC, MSC_SERIAL, leftmb);
 }
@@ -182,8 +280,13 @@ static void wacom_graphire_irq(struct ur
 
 	if (urb->status) return;
 
+	/* check if we can handle the data */
+	if (data[0] == 99) /* for Volito */
+		return;
+
 	if (data[0] != 2) {
-		printk(KERN_ERR "wacom_graphire_irq: received unknown report #%d\n", data[0]);
+		printk(KERN_INFO "wacom_graphire_irq: received unknown report #%d\n", data[0]);
+		wacom_request_reset(wacom);
 		return;
 	}
 	
@@ -200,14 +303,15 @@ static void wacom_graphire_irq(struct ur
 			input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x80);
 			break;
 
-		case 2: /* Mouse */
+		case 2: /* Mouse with wheel */
+			input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
+			input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
+
+		case 3: /* Mouse without wheel */
 			input_report_key(dev, BTN_TOOL_MOUSE, data[7] > 24);
 			input_report_key(dev, BTN_LEFT, data[1] & 0x01);
 			input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
-			input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
 			input_report_abs(dev, ABS_DISTANCE, data[7]);
-			input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
-
 			input_report_abs(dev, ABS_X, x);
 			input_report_abs(dev, ABS_Y, y);
 
@@ -238,8 +342,10 @@ static void wacom_intuos_irq(struct urb 
 
 	if (urb->status) return;
 
+	/* check for valid report */
 	if (data[0] != 2) {
-		printk(KERN_ERR "wacom_intuos_irq: received unknown report #%d\n", data[0]);
+		printk(KERN_INFO "wacom_intuos_irq: received unknown report #%d\n", data[0]);
+		wacom_request_reset(wacom);
 		return;
 	}
 	
@@ -248,17 +354,18 @@ static void wacom_intuos_irq(struct urb 
 
 	if ((data[1] & 0xfc) == 0xc0) {						/* Enter report */
 
-		wacom->serial[idx] = ((__u32)(data[3] & 0x0f) << 4) +		/* serial number of the tool */
-			((__u32)data[4] << 16) + ((__u32)data[5] << 12) +
-			((__u32)data[6] << 4) + (data[7] >> 4);
+		wacom->serial[idx] = ((__u32)(data[3] & 0x0f) << 28) +		/* serial number of the tool */
+			((__u32)data[4] << 20) + ((__u32)data[5] << 12) +
+			((__u32)data[6] << 4) + ((__u32)data[7] >> 4);
 
 		switch (((__u32)data[2] << 4) | (data[3] >> 4)) {
-			case 0x832:
+			case 0x812:
 			case 0x012: wacom->tool[idx] = BTN_TOOL_PENCIL;		break;	/* Inking pen */
 			case 0x822:
 		        case 0x852:
+			case 0x842:
 			case 0x022: wacom->tool[idx] = BTN_TOOL_PEN;		break;	/* Pen */
-			case 0x812:
+			case 0x832:
 			case 0x032: wacom->tool[idx] = BTN_TOOL_BRUSH;		break;	/* Stroke pen */
 		        case 0x09c:
 		        case 0x007:
@@ -267,12 +374,14 @@ static void wacom_intuos_irq(struct urb 
 			case 0x82a:
 		        case 0x85a:
 		        case 0x91a:
+			case 0xd1a:
 			case 0x0fa: wacom->tool[idx] = BTN_TOOL_RUBBER;		break;	/* Eraser */
+			case 0x912:
+			case 0xd12:
 			case 0x112: wacom->tool[idx] = BTN_TOOL_AIRBRUSH;	break;	/* Airbrush */
 			default:    wacom->tool[idx] = BTN_TOOL_PEN;		break;	/* Unknown tool */
 		}
 
-		input_report_key(dev, wacom->tool[idx], 1);
 		input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
 		return;
 	}
@@ -285,7 +394,7 @@ static void wacom_intuos_irq(struct urb 
 
 	input_report_abs(dev, ABS_X, ((__u32)data[2] << 8) | data[3]);
 	input_report_abs(dev, ABS_Y, ((__u32)data[4] << 8) | data[5]);
-	input_report_abs(dev, ABS_DISTANCE, data[9] >> 4);
+	input_report_abs(dev, ABS_DISTANCE, data[9]);
 	
 	if ((data[1] & 0xb8) == 0xa0) {						/* general pen packet */
 		input_report_abs(dev, ABS_PRESSURE, t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3));
@@ -307,31 +416,37 @@ static void wacom_intuos_irq(struct urb 
 		if (data[1] & 0x02) {						/* Rotation packet */
 
 			input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ?
-					 ((__u32)data[6] << 2) | ((data[7] >> 6) & 3):
-					 (-(((__u32)data[6] << 2) | ((data[7] >> 6) & 3))) - 1);
+					 ((__u32)data[6] << 3) | ((data[7] >> 5) & 7):
+					 (-(((__u32)data[6] << 3) | ((data[7] >> 5) & 7))) - 1);
 
-		} else {
+		} else if ((data[1] & 0x10) == 0) {				/* 4D mouse packets */
 
 			input_report_key(dev, BTN_LEFT,   data[8] & 0x01);
 			input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
 			input_report_key(dev, BTN_RIGHT,  data[8] & 0x04);
+			input_report_key(dev, BTN_SIDE,   data[8] & 0x20);
+			input_report_key(dev, BTN_EXTRA,  data[8] & 0x10);
+			input_report_abs(dev, ABS_THROTTLE,  (data[8] & 0x08) ?
+					 ((__u32)data[6] << 2) | ((data[7] >> 6) & 3) :
+					 -((__u32)data[6] << 2) | ((data[7] >> 6) & 3));
+
+		} else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {		/* 2D mouse packets */
+			input_report_key(dev, BTN_LEFT,   data[8] & 0x04);
+			input_report_key(dev, BTN_MIDDLE, data[8] & 0x08);
+			input_report_key(dev, BTN_RIGHT,  data[8] & 0x10);
+			input_report_rel(dev, REL_WHEEL, - (((__u32)(data[8] & 0x01)) -
+					((__u32)((data[8] & 0x02) >> 1))));
+		} else {							/* Lens cursor packets */
 
-	 		if ((data[1] & 0x10) == 0) {				/* 4D mouse packets */
-
-				input_report_key(dev, BTN_SIDE,   data[8] & 0x20);
-				input_report_key(dev, BTN_EXTRA,  data[8] & 0x10);
-				input_report_abs(dev, ABS_THROTTLE,  (data[8] & 0x08) ?
-						 ((__u32)data[6] << 2) | ((data[7] >> 6) & 3) :
-						 -((__u32)data[6] << 2) | ((data[7] >> 6) & 3));
-
-			} else {						/* Lens cursor packets */
-
-				input_report_key(dev, BTN_SIDE,   data[8] & 0x10);
-				input_report_key(dev, BTN_EXTRA,  data[8] & 0x08);
-			}
+			input_report_key(dev, BTN_LEFT,   data[8] & 0x01);
+			input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
+			input_report_key(dev, BTN_RIGHT,  data[8] & 0x04);
+			input_report_key(dev, BTN_SIDE,   data[8] & 0x10);
+			input_report_key(dev, BTN_EXTRA,  data[8] & 0x08);
 		}
 	}
 	
+	input_report_key(dev, wacom->tool[idx], 1);
 	input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
 }
 
@@ -344,42 +459,43 @@ struct wacom_features wacom_features[] =
 		0, 0, 0, 0 },
 	{ "Wacom Graphire",      8, 10206,  7422,  511, 32, wacom_graphire_irq,
 		BIT(EV_REL), 0, BIT(REL_WHEEL), 0 },
-	{ "Wacom Graphire2 4x5",     8, 10206,  7422,  511, 32, wacom_graphire_irq,
+	{ "Wacom Graphire2 4x5", 8, 10206,  7422,  511, 32, wacom_graphire_irq,
+		BIT(EV_REL), 0, BIT(REL_WHEEL), 0 },
+	{ "Wacom Graphire2 5x7", 8, 13918,  10206,  511, 32, wacom_graphire_irq,
+		BIT(EV_REL), 0, BIT(REL_WHEEL), 0 },
+	{ "Wacom Intuos 4x5",   10, 12700, 10600, 1023, 15, wacom_intuos_irq, BIT(EV_REL), 
+		WACOM_INTUOS_ABS, BIT(REL_WHEEL), WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom Intuos 6x8",   10, 20320, 16240, 1023, 15, wacom_intuos_irq, BIT(EV_REL), 
+		WACOM_INTUOS_ABS, BIT(REL_WHEEL), WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom Intuos 9x12",  10, 30480, 24060, 1023, 15, wacom_intuos_irq, BIT(EV_REL), 
+		WACOM_INTUOS_ABS, BIT(REL_WHEEL), WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15, wacom_intuos_irq, BIT(EV_REL), 
+		WACOM_INTUOS_ABS, BIT(REL_WHEEL), WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, wacom_intuos_irq, BIT(EV_REL), 
+		WACOM_INTUOS_ABS, BIT(REL_WHEEL), WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom PL400",         8,  5408,  4056,  255, 32, wacom_pl_irq, 0,  0, 0, 0 },
+	{ "Wacom PL500",         8,  6144,  4608,  255, 32, wacom_pl_irq, 0,  0, 0, 0 },
+	{ "Wacom PL600",         8,  6126,  4604,  255, 32, wacom_pl_irq, 0,  0, 0, 0 },
+	{ "Wacom PL600SX",       8,  6260,  5016,  255, 32, wacom_pl_irq, 0,  0, 0, 0 },
+	{ "Wacom PL550",         8,  6144,  4608,  511, 32, wacom_pl_irq, 0,  0, 0, 0 },
+	{ "Wacom PL800",         8,  7220,  5780,  511, 32, wacom_pl_irq, 0,  0, 0, 0 },
+	{ "Wacom Intuos2 4x5",  10, 12700, 10600, 1023, 15, wacom_intuos_irq, BIT(EV_REL), 
+		WACOM_INTUOS_ABS, BIT(REL_WHEEL), WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom Intuos2 6x8",  10, 20320, 16240, 1023, 15, wacom_intuos_irq, BIT(EV_REL), 
+		WACOM_INTUOS_ABS, BIT(REL_WHEEL), WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, wacom_intuos_irq, BIT(EV_REL), 
+		WACOM_INTUOS_ABS, BIT(REL_WHEEL), WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom Intuos2 12x12",10, 30480, 31680, 1023, 15, wacom_intuos_irq, BIT(EV_REL), 
+		WACOM_INTUOS_ABS, BIT(REL_WHEEL), WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom Intuos2 12x18",10, 45720, 31680, 1023, 15, wacom_intuos_irq, BIT(EV_REL), 
+		WACOM_INTUOS_ABS, BIT(REL_WHEEL), WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom Volito",        8,  5104,  3712,  511, 32, wacom_graphire_irq,
+		BIT(EV_REL), 0, 0, 0 },
+	{ "Wacom Graphire3 4x5", 8, 10208,  7424,  511, 32, wacom_graphire_irq,
 		BIT(EV_REL), 0, BIT(REL_WHEEL), 0 },
-	{ "Wacom Graphire2 5x7",     8, 10206,  7422,  511, 32, wacom_graphire_irq,
+	{ "Wacom Graphire3 6x8", 8, 16704, 12064,  511, 32, wacom_graphire_irq,
 		BIT(EV_REL), 0, BIT(REL_WHEEL), 0 },
-	{ "Wacom Intuos 4x5",   10, 12700, 10360, 1023, 15, wacom_intuos_irq,
-		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
-	{ "Wacom Intuos 6x8",   10, 20320, 15040, 1023, 15, wacom_intuos_irq,
-		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
-	{ "Wacom Intuos 9x12",  10, 30480, 23060, 1023, 15, wacom_intuos_irq,
-		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
-	{ "Wacom Intuos 12x12", 10, 30480, 30480, 1023, 15, wacom_intuos_irq,
-		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
-	{ "Wacom Intuos 12x18", 10, 47720, 30480, 1023, 15, wacom_intuos_irq,
-		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
-	{ "Wacom PL400",        8,  12328, 9256,   511, 32, wacom_pl_irq,
-		0,  0, 0, 0 },
-	{ "Wacom PL500",        8,  12328, 9256,   511, 32, wacom_pl_irq,
-		0,  0, 0, 0 },
-	{ "Wacom PL600",        8,  12328, 9256,   511, 32, wacom_pl_irq,
-		0,  0, 0, 0 },
-	{ "Wacom PL600SX",        8,  12328, 9256,   511, 32, wacom_pl_irq,
-		0,  0, 0, 0 },
-	{ "Wacom PL550",        8,  12328, 9256,   511, 32, wacom_pl_irq,
-		0,  0, 0, 0 },
-	{ "Wacom PL800",        8,  12328, 9256,   511, 32, wacom_pl_irq,
-		0,  0, 0, 0 },
-	{ "Wacom Intuos2 4x5",   10, 12700, 10360, 1023, 15, wacom_intuos_irq,
-		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
-	{ "Wacom Intuos2 6x8",   10, 20320, 15040, 1023, 15, wacom_intuos_irq,
-		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
-	{ "Wacom Intuos2 9x12",  10, 30480, 23060, 1023, 15, wacom_intuos_irq,
-		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
-	{ "Wacom Intuos2 12x12", 10, 30480, 30480, 1023, 15, wacom_intuos_irq,
-		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
-	{ "Wacom Intuos2 12x18", 10, 47720, 30480, 1023, 15, wacom_intuos_irq,
-		0, WACOM_INTUOS_ABS, 0, WACOM_INTUOS_BUTTONS, WACOM_INTUOS_TOOLS },
+	{ "Wacom Cintiq Partner",8, 20480, 15360,  511, 32, wacom_ptu_irq, 0,  0, 0, 0 },
 	{ NULL , 0 }
 };
 
@@ -404,6 +520,13 @@ struct usb_device_id wacom_ids[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43), driver_info: 17 },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44), driver_info: 18 },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45), driver_info: 19 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60), driver_info: 20 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13), driver_info: 21 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14), driver_info: 22 },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03), driver_info: 23 },
+
+	/* some Intuos2 6x8's erroneously report as 0x47 */
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47), driver_info: 16 },
 	{ }
 };
 
@@ -431,11 +554,24 @@ static void wacom_close(struct input_dev
 		usb_unlink_urb(&wacom->irq);
 }
 
+static void wacom_reset(struct wacom* wacom)
+{
+	char rep_data[2] = {0x02, 0x02};
+
+	#ifdef __JEJ_DEBUG
+	printk(KERN_INFO __FILE__ ": Setting tablet report for tablet data\n");
+	#endif
+
+	/* ask the tablet to report tablet data */
+	usb_set_report(wacom->usbdev, wacom->ifnum, 3, 2, rep_data, 2);
+	usb_set_report(wacom->usbdev, wacom->ifnum, 3, 5, rep_data, 0);
+	usb_set_report(wacom->usbdev, wacom->ifnum, 3, 6, rep_data, 0);
+}
+
 static void *wacom_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)
 {
 	struct usb_endpoint_descriptor *endpoint;
 	struct wacom *wacom;
-	char rep_data[2] = {0x02, 0x02};
 	
 	if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) return NULL;
 	memset(wacom, 0, sizeof(struct wacom));
@@ -476,6 +612,10 @@ static void *wacom_probe(struct usb_devi
 	wacom->dev.idproduct = dev->descriptor.idProduct;
 	wacom->dev.idversion = dev->descriptor.bcdDevice;
 	wacom->usbdev = dev;
+	wacom->ifnum = ifnum;
+
+	INIT_LIST_HEAD(&wacom->event_list);
+	init_MUTEX(&wacom->kwacomd_sem);
 
 	endpoint = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0;
 
@@ -485,12 +625,9 @@ static void *wacom_probe(struct usb_devi
 		     wacom->data, wacom->features->pktlen, wacom->features->irq, wacom, endpoint->bInterval);
 
 	input_register_device(&wacom->dev);
-
-	/* ask the tablet to report tablet data */
-	usb_set_report(dev, ifnum, 3, 2, rep_data, 2);
-	usb_set_report(dev, ifnum, 3, 5, rep_data, 0);
-	usb_set_report(dev, ifnum, 3, 6, rep_data, 0);
 	
+	wacom_reset(wacom);
+
 	printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n",
 	       wacom->dev.number, wacom->features->name, dev->bus->busnum, dev->devnum, ifnum);
 
@@ -499,10 +636,73 @@ static void *wacom_probe(struct usb_devi
 
 static void wacom_disconnect(struct usb_device *dev, void *ptr)
 {
+	unsigned int flags;
 	struct wacom *wacom = ptr;
-	usb_unlink_urb(&wacom->irq);
-	input_unregister_device(&wacom->dev);
-	kfree(wacom);
+	if (wacom)
+	{
+    		spin_lock_irqsave(&wacom_event_lock, flags);
+		list_del(&wacom->event_list);
+		INIT_LIST_HEAD(&wacom->event_list);
+		spin_unlock_irqrestore(&wacom_event_lock, flags);
+
+		/* Wait for kwacomd to leave this tablet alone. */
+		down(&wacom->kwacomd_sem);
+		up(&wacom->kwacomd_sem);
+
+		usb_unlink_urb(&wacom->irq);
+		input_unregister_device(&wacom->dev);
+		kfree(wacom);
+	}
+}
+
+static void wacom_events(void)
+{
+	struct wacom* wacom;
+	unsigned int flags;
+	struct list_head *tmp;
+
+	printk(KERN_INFO "wacom_events\n");
+
+	while (1)
+	{
+		spin_lock_irqsave(&wacom_event_lock, flags);
+
+		if (list_empty(&wacom_event_list))
+			break;
+
+		/* Grab the next entry from the beginning of the list */
+		tmp = wacom_event_list.next;
+		wacom = list_entry(tmp, struct wacom, event_list);
+
+		list_del(tmp); /* dequeue tablet */
+		INIT_LIST_HEAD(tmp);
+
+		if (down_trylock(&wacom->kwacomd_sem) != 0) BUG(); /* never blocks */
+		spin_unlock_irqrestore(&wacom_event_lock, flags);
+
+		wacom_reset(wacom);
+
+		up(&wacom->kwacomd_sem); /* mark tablet free */
+	}
+	spin_unlock_irqrestore(&wacom_event_lock, flags);
+}
+
+static int wacom_thread(void* pv)
+{
+	daemonize();
+	reparent_to_init();
+
+	/* Setup a nice name */
+	strcpy(current->comm, "kwacomd");
+
+	/* Send me a signal to get me die (for debugging) */
+	while (!signal_pending(current))
+	{
+		wacom_events();
+		wait_event_interruptible(kwacomd_wait, !list_empty(&wacom_event_list));
+	}
+
+	complete_and_exit(&kwacomd_exited, 0);
 }
 
 static struct usb_driver wacom_driver = {
@@ -512,16 +712,33 @@ static struct usb_driver wacom_driver = 
 	id_table:	wacom_ids,
 };
 
-static int __init wacom_init(void)
+static int __init wacom_init(void) 
 {
+	int pid;
 	usb_register(&wacom_driver);
 	info(DRIVER_VERSION " " DRIVER_AUTHOR);
 	info(DRIVER_DESC);
-	return 0;
+	pid = kernel_thread(wacom_thread, NULL,
+			CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+	if (pid >= 0) {
+		kwacomd_pid = pid;
+		return 0;
+	}
+
+	/* Fall through if kernel_thread failed */
+	usb_deregister(&wacom_driver);
+	err("failed to start wacom_thread");
+
+	return -1;
 }
 
 static void __exit wacom_exit(void)
 {
+	int ret;
+
+	/* Kill the thread */
+	ret = kill_proc(kwacomd_pid, SIGTERM, 1);
+	wait_for_completion(&kwacomd_exited);
 	usb_deregister(&wacom_driver);
 }
 


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Wacom USB driver patch
  2004-02-11  1:23 Wacom USB driver patch Ping Cheng
  2004-02-11  8:24 ` Vojtech Pavlik
@ 2004-03-08  9:05 ` Vojtech Pavlik
  1 sibling, 0 replies; 13+ messages in thread
From: Vojtech Pavlik @ 2004-03-08  9:05 UTC (permalink / raw)
  To: Ping Cheng; +Cc: 'linux-kernel@vger.kernel.org', 'Greg KH '

On Tue, Feb 10, 2004 at 05:23:11PM -0800, Ping Cheng wrote:
>  <<linuxwacom.patch>> 
> Attached is a wacom driver patch for kernel 2.6. I have sent my patch to
> Vojtech last year. But, he didn't commit it. I bet he's busy. So, hope
> someone in this list can help me check the code in.
> 
> Please reply to me directly since I am not in linux-kernel mailing list. 
> 
> Thanks!

Sorry for the delay, I merged your patch (with fixes for bugs found by
Pete) today.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Wacom USB driver patch
       [not found] <Pine.LNX.4.58L.0402262354190.1653@logos.cnet>
@ 2004-03-17 17:29 ` Pete Zaitcev
  2004-03-17 20:36   ` Vojtech Pavlik
  0 siblings, 1 reply; 13+ messages in thread
From: Pete Zaitcev @ 2004-03-17 17:29 UTC (permalink / raw)
  To: pingc; +Cc: vojtech, zaitcev, linux-kernel

Dear Ping,

Vojtech posted your 2.6 patch to linux-kernel yesterday, so I examined it
(Subject: [PATCH 32/44] Update of Wacom driver from Ping Cheng (from Wacom)).
Unlike the 2.4 version, it does not feature a reset thread. Please tell
me why that thread was required in 2.4.

Or perhaps it was present in your original submission which I lost and
Vojtech removed that element of the patch?

Yours truly,
-- Pete

> Date: Fri, 20 Feb 2004 14:29:04 -0800
> From: Ping Cheng <pingc@wacom.com>
> To: 'Vojtech Pavlik ' <vojtech@suse.cz>, 'Pete Zaitcev ' <zaitcev@redhat.com>
> Cc: "'linux-kernel@vger.kernel.org '" <linux-kernel@vger.kernel.org>
> Subject: RE: Wacom USB driver patch
> 
>  <<wacom_2.4.patch>>
> The attached patch is against the latest versions of wacom.c and hid-core.c
> at  http://linux.bkbits.net:8080/linux-2.4.
> 
> Ping
> 
> -----Original Message-----
> From: Vojtech Pavlik
> To: Pete Zaitcev
> Cc: Ping Cheng; linux-kernel@vger.kernel.org
> Sent: 2/13/04 12:13 AM
> Subject: Re: Wacom USB driver patch
> 
> On Thu, Feb 12, 2004 at 07:28:09PM -0800, Pete Zaitcev wrote:
> > On Thu, 12 Feb 2004 16:55:47 -0800
> > Ping Cheng <pingc@wacom.com> wrote:
> >
> > > The wacom.c at http://linux.bkbits.net:8080/linux-2.4 is way out of date and
> > > people are still working on/using 2.4 releases. Should I make a patch for
> > > 2.4?
> >
> > We plan to support 2.4 based releases for several years yet. If Vojtech
> > approves what you did for 2.6, I am all for a backport to Marcelo tree.
> > Marcelo is not very forthcoming with approvals these days, but perhaps
> > it may be folded into some update. But as usual I would like to avoid
> > carrying a patch in Red Hat tree, if at all possible.
> 
> Agreed. Same for us at SUSE.
> 
> -- 
> Vojtech Pavlik
> SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Wacom USB driver patch
  2004-03-17 17:29 ` Pete Zaitcev
@ 2004-03-17 20:36   ` Vojtech Pavlik
  0 siblings, 0 replies; 13+ messages in thread
From: Vojtech Pavlik @ 2004-03-17 20:36 UTC (permalink / raw)
  To: Pete Zaitcev; +Cc: pingc, linux-kernel

On Wed, Mar 17, 2004 at 09:29:59AM -0800, Pete Zaitcev wrote:

> Dear Ping,
> 
> Vojtech posted your 2.6 patch to linux-kernel yesterday, so I examined it
> (Subject: [PATCH 32/44] Update of Wacom driver from Ping Cheng (from Wacom)).
> Unlike the 2.4 version, it does not feature a reset thread. Please tell
> me why that thread was required in 2.4.
> 
> Or perhaps it was present in your original submission which I lost and
> Vojtech removed that element of the patch?

I didn't remove it - it was not present in the 2.6 patch.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: Wacom USB driver patch
@ 2004-03-17 22:24 Ping Cheng
  0 siblings, 0 replies; 13+ messages in thread
From: Ping Cheng @ 2004-03-17 22:24 UTC (permalink / raw)
  To: 'Vojtech Pavlik', Pete Zaitcev; +Cc: linux-kernel

Here is the history. Patches for wacom.c in 2.4 was majorly modified by John
Joganic. Specially, the reset thread was added by John to deal with the case
when the tablet is set/reset to HID mode. Otherwise the driver will have to
be reloaded. The code was tested by users. Patches for wacom.c in 2.6 was
made by myself.

The reason I didn't add the reset thread to 2.6 patch was because I don't
know exactly how to do it in 2.6 and I didn't find proper examples from
other device drivers in 2.6. Basically, I don't want to introduce any new
"feature" before I can convince myself.

The reason I didn't remove the reset thread code in 2.4 was because it was
tested by many users and there are no negative feedbacks. 

So, we need the reset thread. Please let me know the proper approach to
implement this feature in 2.4 and 2.6. I'll update the patches accordingly.

Ping

-----Original Message-----
From: Vojtech Pavlik [mailto:vojtech@suse.cz] 
Sent: Wednesday, March 17, 2004 12:37 PM
To: Pete Zaitcev
Cc: Ping Cheng; linux-kernel@vger.kernel.org
Subject: Re: Wacom USB driver patch


On Wed, Mar 17, 2004 at 09:29:59AM -0800, Pete Zaitcev wrote:

> Dear Ping,
> 
> Vojtech posted your 2.6 patch to linux-kernel yesterday, so I examined 
> it
> (Subject: [PATCH 32/44] Update of Wacom driver from Ping Cheng (from
Wacom)).
> Unlike the 2.4 version, it does not feature a reset thread. Please tell
> me why that thread was required in 2.4.
> 
> Or perhaps it was present in your original submission which I lost and 
> Vojtech removed that element of the patch?

I didn't remove it - it was not present in the 2.6 patch.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2004-03-17 22:27 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-02-11  1:23 Wacom USB driver patch Ping Cheng
2004-02-11  8:24 ` Vojtech Pavlik
2004-03-08  9:05 ` Vojtech Pavlik
     [not found] <mailman.1076463721.27289.linux-kernel2news@redhat.com>
2004-02-11 19:04 ` Pete Zaitcev
  -- strict thread matches above, loose matches on Subject: below --
2004-02-11 19:47 Ping Cheng
2004-02-11 20:04 ` Vojtech Pavlik
2004-02-13  0:55 Ping Cheng
2004-02-13  3:28 ` Pete Zaitcev
2004-02-13  8:13   ` Vojtech Pavlik
2004-02-20 22:29 Ping Cheng
     [not found] <Pine.LNX.4.58L.0402262354190.1653@logos.cnet>
2004-03-17 17:29 ` Pete Zaitcev
2004-03-17 20:36   ` Vojtech Pavlik
2004-03-17 22:24 Ping Cheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox