Revert "Input: wacom - merge out and in prox events"

This reverts commit 776943fd6f104a6e8457dc95a17282e69e963666 as it
causes issues with ISDv4 E3 touchscreens:

	https://bugzilla.kernel.org/show_bug.cgi?id=15670

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index b3ba343..4a852d8 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -155,19 +155,19 @@
 {
 	struct wacom_features *features = &wacom->features;
 	unsigned char *data = wacom->data;
-	int x, y, prox;
-	int rw = 0;
-	int retval = 0;
+	int x, y, rw;
+	static int penData = 0;
 
 	if (data[0] != WACOM_REPORT_PENABLED) {
 		dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
-		goto exit;
+		return 0;
 	}
 
-	prox = data[1] & 0x80;
-	if (prox || wacom->id[0]) {
-		if (prox) {
-			switch ((data[1] >> 5) & 3) {
+	if (data[1] & 0x80) {
+		/* in prox and not a pad data */
+		penData = 1;
+
+		switch ((data[1] >> 5) & 3) {
 
 			case 0:	/* Pen */
 				wacom->tool[0] = BTN_TOOL_PEN;
@@ -181,13 +181,23 @@
 
 			case 2: /* Mouse with wheel */
 				wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04);
+				if (features->type == WACOM_G4 || features->type == WACOM_MO) {
+					rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
+					wacom_report_rel(wcombo, REL_WHEEL, -rw);
+				} else
+					wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]);
 				/* fall through */
 
 			case 3: /* Mouse without wheel */
 				wacom->tool[0] = BTN_TOOL_MOUSE;
 				wacom->id[0] = CURSOR_DEVICE_ID;
+				wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
+				wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
+				if (features->type == WACOM_G4 || features->type == WACOM_MO)
+					wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
+				else
+					wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
 				break;
-			}
 		}
 		x = wacom_le16_to_cpu(&data[2]);
 		y = wacom_le16_to_cpu(&data[4]);
@@ -198,32 +208,36 @@
 			wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01);
 			wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
 			wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
-		} else {
-			wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
-			wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
-			if (features->type == WACOM_G4 ||
-					features->type == WACOM_MO) {
-				wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
-				rw = (signed)(data[7] & 0x04) - (data[7] & 0x03);
-			} else {
-				wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
-				rw = -(signed)data[6];
-			}
-			wacom_report_rel(wcombo, REL_WHEEL, rw);
 		}
-
-		if (!prox)
-			wacom->id[0] = 0;
 		wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
-		wacom_report_key(wcombo, wacom->tool[0], prox);
-		wacom_input_sync(wcombo); /* sync last event */
+		wacom_report_key(wcombo, wacom->tool[0], 1);
+	} else if (wacom->id[0]) {
+		wacom_report_abs(wcombo, ABS_X, 0);
+		wacom_report_abs(wcombo, ABS_Y, 0);
+		if (wacom->tool[0] == BTN_TOOL_MOUSE) {
+			wacom_report_key(wcombo, BTN_LEFT, 0);
+			wacom_report_key(wcombo, BTN_RIGHT, 0);
+			wacom_report_abs(wcombo, ABS_DISTANCE, 0);
+		} else {
+			wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+			wacom_report_key(wcombo, BTN_TOUCH, 0);
+			wacom_report_key(wcombo, BTN_STYLUS, 0);
+			wacom_report_key(wcombo, BTN_STYLUS2, 0);
+		}
+		wacom->id[0] = 0;
+		wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
+		wacom_report_key(wcombo, wacom->tool[0], 0);
 	}
 
 	/* send pad data */
 	switch (features->type) {
 	    case WACOM_G4:
-		prox = data[7] & 0xf8;
-		if (prox || wacom->id[1]) {
+		if (data[7] & 0xf8) {
+			if (penData) {
+				wacom_input_sync(wcombo); /* sync last event */
+				if (!wacom->id[0])
+					penData = 0;
+			}
 			wacom->id[1] = PAD_DEVICE_ID;
 			wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
 			wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
@@ -231,16 +245,29 @@
 			wacom_report_rel(wcombo, REL_WHEEL, rw);
 			wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
 			wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
-			if (!prox)
-				wacom->id[1] = 0;
-			wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
+			wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+		} else if (wacom->id[1]) {
+			if (penData) {
+				wacom_input_sync(wcombo); /* sync last event */
+				if (!wacom->id[0])
+					penData = 0;
+			}
+			wacom->id[1] = 0;
+			wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
+			wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
+			wacom_report_rel(wcombo, REL_WHEEL, 0);
+			wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
+			wacom_report_abs(wcombo, ABS_MISC, 0);
 			wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
 		}
-		retval = 1;
 		break;
 	    case WACOM_MO:
-		prox = (data[7] & 0xf8) || data[8];
-		if (prox || wacom->id[1]) {
+		if ((data[7] & 0xf8) || (data[8] & 0xff)) {
+			if (penData) {
+				wacom_input_sync(wcombo); /* sync last event */
+				if (!wacom->id[0])
+					penData = 0;
+			}
 			wacom->id[1] = PAD_DEVICE_ID;
 			wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
 			wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
@@ -248,16 +275,27 @@
 			wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
 			wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
 			wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
-			if (!prox)
-				wacom->id[1] = 0;
 			wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
 			wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+		} else if (wacom->id[1]) {
+			if (penData) {
+				wacom_input_sync(wcombo); /* sync last event */
+				if (!wacom->id[0])
+					penData = 0;
+			}
+			wacom->id[1] = 0;
+			wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
+			wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
+			wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
+			wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
+			wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
+			wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
+			wacom_report_abs(wcombo, ABS_MISC, 0);
+			wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
 		}
-		retval = 1;
 		break;
 	}
-exit:
-	return retval;
+	return 1;
 }
 
 static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
@@ -598,9 +636,9 @@
 static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx)
 {
 	wacom_report_abs(wcombo, ABS_X,
-		data[2 + idx * 2] | ((data[3 + idx * 2] & 0x7f) << 8));
+		(data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8));
 	wacom_report_abs(wcombo, ABS_Y,
-		data[6 + idx * 2] | ((data[7 + idx * 2] & 0x7f) << 8));
+		(data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8));
 	wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
 	wacom_report_key(wcombo, wacom->tool[idx], 1);
 	if (idx)
@@ -744,24 +782,31 @@
 
 		touchInProx = 0;
 
-		if (!wacom->id[0]) { /* first in prox */
-			/* Going into proximity select tool */
-			wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
-			if (wacom->tool[0] == BTN_TOOL_PEN)
-				wacom->id[0] = STYLUS_DEVICE_ID;
-			else
-				wacom->id[0] = ERASER_DEVICE_ID;
-		}
-		wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
-		wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
-		wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
-		wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
-		pressure = ((data[7] & 0x01) << 8) | data[6];
-		if (pressure < 0)
-			pressure = features->pressure_max + pressure + 1;
-		wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
-		wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
-		if (!prox) { /* out-prox */
+		if (prox) { /* in prox */
+			if (!wacom->id[0]) {
+				/* Going into proximity select tool */
+				wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+				if (wacom->tool[0] == BTN_TOOL_PEN)
+					wacom->id[0] = STYLUS_DEVICE_ID;
+				else
+					wacom->id[0] = ERASER_DEVICE_ID;
+			}
+			wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
+			wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
+			wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
+			wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
+			pressure = ((data[7] & 0x01) << 8) | data[6];
+			if (pressure < 0)
+				pressure = features->pressure_max + pressure + 1;
+			wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
+			wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
+		} else {
+			wacom_report_abs(wcombo, ABS_X, 0);
+			wacom_report_abs(wcombo, ABS_Y, 0);
+			wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+			wacom_report_key(wcombo, BTN_STYLUS, 0);
+			wacom_report_key(wcombo, BTN_STYLUS2, 0);
+			wacom_report_key(wcombo, BTN_TOUCH, 0);
 			wacom->id[0] = 0;
 			/* pen is out so touch can be enabled now */
 			touchInProx = 1;