25-akpm/drivers/input/mouse/synaptics.c |  174 ++++++++++++++++++--------------
 1 files changed, 100 insertions(+), 74 deletions(-)

diff -puN drivers/input/mouse/synaptics.c~p00007_synaptics-old-proto drivers/input/mouse/synaptics.c
--- 25/drivers/input/mouse/synaptics.c~p00007_synaptics-old-proto	Tue Jul 29 14:57:07 2003
+++ 25-akpm/drivers/input/mouse/synaptics.c	Tue Jul 29 14:57:07 2003
@@ -394,20 +394,6 @@ void synaptics_disconnect(struct psmouse
 
 static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw)
 {
-	hw->x = (((buf[3] & 0x10) << 8) |
-		 ((buf[1] & 0x0f) << 8) |
-		 buf[4]);
-	hw->y = (((buf[3] & 0x20) << 7) |
-		 ((buf[1] & 0xf0) << 4) |
-		 buf[5]);
-
-	hw->z = buf[2];
-	hw->w = (((buf[0] & 0x30) >> 2) |
-		 ((buf[0] & 0x04) >> 1) |
-		 ((buf[3] & 0x04) >> 2));
-
-	hw->left  = (buf[0] & 0x01) ? 1 : 0;
-	hw->right = (buf[0] & 0x02) ? 1 : 0;
 	hw->up    = 0;
 	hw->down  = 0;
 	hw->b0    = 0;
@@ -418,32 +404,58 @@ static void synaptics_parse_hw_state(uns
 	hw->b5    = 0;
 	hw->b6    = 0;
 	hw->b7    = 0;
-	if (SYN_CAP_EXTENDED(priv->capabilities) &&
-	    (SYN_CAP_FOUR_BUTTON(priv->capabilities))) {
-		hw->up = ((buf[3] & 0x01)) ? 1 : 0;
-		if (hw->left)
-			hw->up = !hw->up;
-		hw->down = ((buf[3] & 0x02)) ? 1 : 0;
-		if (hw->right)
-			hw->down = !hw->down;
-	}
-	if (buf[3] == 0xC2 && SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) {
-		switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
-		default:
-			; /* we did comment while initialising... */
-		case 8:
-			hw->b7 = ((buf[5] & 0x08)) ? 1 : 0;
-			hw->b6 = ((buf[4] & 0x08)) ? 1 : 0;
-		case 6:
-			hw->b5 = ((buf[5] & 0x04)) ? 1 : 0;
-			hw->b4 = ((buf[4] & 0x04)) ? 1 : 0;
-		case 4:
-			hw->b3 = ((buf[5] & 0x02)) ? 1 : 0;
-			hw->b2 = ((buf[4] & 0x02)) ? 1 : 0;
-		case 2:
-			hw->b1 = ((buf[5] & 0x01)) ? 1 : 0;
-			hw->b0 = ((buf[4] & 0x01)) ? 1 : 0;
+
+	if (SYN_MODEL_NEWABS(priv->model_id)) {
+		hw->x = (((buf[3] & 0x10) << 8) |
+			 ((buf[1] & 0x0f) << 8) |
+			 buf[4]);
+		hw->y = (((buf[3] & 0x20) << 7) |
+			 ((buf[1] & 0xf0) << 4) |
+			 buf[5]);
+
+		hw->z = buf[2];
+		hw->w = (((buf[0] & 0x30) >> 2) |
+			 ((buf[0] & 0x04) >> 1) |
+			 ((buf[3] & 0x04) >> 2));
+
+		hw->left  = (buf[0] & 0x01) ? 1 : 0;
+		hw->right = (buf[0] & 0x02) ? 1 : 0;
+		if (SYN_CAP_EXTENDED(priv->capabilities) &&
+		    (SYN_CAP_FOUR_BUTTON(priv->capabilities))) {
+			hw->up = ((buf[3] & 0x01)) ? 1 : 0;
+			if (hw->left)
+				hw->up = !hw->up;
+			hw->down = ((buf[3] & 0x02)) ? 1 : 0;
+			if (hw->right)
+				hw->down = !hw->down;
+		}
+		if (buf[3] == 0xC2 && SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) {
+			switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
+			default:
+				; /* we did comment while initialising... */
+			case 8:
+				hw->b7 = ((buf[5] & 0x08)) ? 1 : 0;
+				hw->b6 = ((buf[4] & 0x08)) ? 1 : 0;
+			case 6:
+				hw->b5 = ((buf[5] & 0x04)) ? 1 : 0;
+				hw->b4 = ((buf[4] & 0x04)) ? 1 : 0;
+			case 4:
+				hw->b3 = ((buf[5] & 0x02)) ? 1 : 0;
+				hw->b2 = ((buf[4] & 0x02)) ? 1 : 0;
+			case 2:
+				hw->b1 = ((buf[5] & 0x01)) ? 1 : 0;
+				hw->b0 = ((buf[4] & 0x01)) ? 1 : 0;
+			}
 		}
+	} else {
+		hw->x = (((buf[1] & 0x1f) << 8) | buf[2]);
+		hw->y = (((buf[4] & 0x1f) << 8) | buf[5]);
+
+		hw->z = (((buf[0] & 0x30) << 2) | (buf[3] & 0x3F));
+		hw->w = (((buf[1] & 0x80) >> 4) | ((buf[0] & 0x04) >> 1));
+
+		hw->left  = (buf[0] & 0x01) ? 1 : 0;
+		hw->right = (buf[0] & 0x02) ? 1 : 0;
 	}
 }
 
@@ -522,44 +534,58 @@ void synaptics_process_byte(struct psmou
 	struct input_dev *dev = &psmouse->dev;
 	struct synaptics_data *priv = psmouse->private;
 	unsigned char data = psmouse->packet[psmouse->pktcnt - 1];
+	int newabs = SYN_MODEL_NEWABS(priv->model_id);
 
 	input_regs(dev, regs);
 
-	/* check first byte */
-	if (psmouse->pktcnt == 1 && (data & 0xC8) != 0x80) {
-		printk(KERN_WARNING "Synaptics driver lost sync at 1st byte\n");
-		priv->out_of_sync++;
-		psmouse->pktcnt = 0;
-	        if (psmouse_resetafter > 0 && priv->out_of_sync	== psmouse_resetafter) {
-			psmouse->state = PSMOUSE_IGNORE;
-			serio_rescan(psmouse->serio);
-		}
-		return;
-	}
-
-	/* check 4th byte */
-	if (psmouse->pktcnt == 4 && (data & 0xC8) != 0xC0) {
-		printk(KERN_WARNING "Synaptics driver lost sync at 4th byte\n");
-		priv->out_of_sync++;
-		psmouse->pktcnt = 0;
-	        if (psmouse_resetafter > 0 && priv->out_of_sync	== psmouse_resetafter) {
-			psmouse->state = PSMOUSE_IGNORE;
-			serio_rescan(psmouse->serio);
-		}
-		return;
-	}
-
-	if (psmouse->pktcnt >= 6) { /* Full packet received */
-		if (priv->out_of_sync) {
-			priv->out_of_sync = 0;
-			printk(KERN_NOTICE "Synaptics driver resynced.\n");
-		}
-
-		if (priv->ptport && synaptics_is_pt_packet(psmouse->packet))
-			synaptics_pass_pt_packet(priv->ptport, psmouse->packet);
-		else
-			synaptics_process_packet(psmouse);
+	switch (psmouse->pktcnt) {
+	case 1:
+		if (newabs ? ((data & 0xC8) != 0x80) : ((data & 0xC0) != 0xC0)) {
+			printk(KERN_WARNING "Synaptics driver lost sync at 1st byte\n");
+			goto bad_sync;
+		}
+		break;
+	case 2:
+		if (!newabs && ((data & 0x60) != 0x00)) {
+			printk(KERN_WARNING "Synaptics driver lost sync at 2nd byte\n");
+			goto bad_sync;
+		}
+		break;
+	case 4:
+		if (newabs ? ((data & 0xC8) != 0xC0) : ((data & 0xC0) != 0x80)) {
+			printk(KERN_WARNING "Synaptics driver lost sync at 4th byte\n");
+			goto bad_sync;
+		}
+		break;
+	case 5:
+		if (!newabs && ((data & 0x60) != 0x00)) {
+			printk(KERN_WARNING "Synaptics driver lost sync at 5th byte\n");
+			goto bad_sync;
+		}
+		break;
+	default:
+		if (psmouse->pktcnt >= 6) { /* Full packet received */
+			if (priv->out_of_sync) {
+				priv->out_of_sync = 0;
+				printk(KERN_NOTICE "Synaptics driver resynced.\n");
+			}
 
-		psmouse->pktcnt = 0;
+			if (priv->ptport && synaptics_is_pt_packet(psmouse->packet))
+				synaptics_pass_pt_packet(priv->ptport, psmouse->packet);
+			else
+				synaptics_process_packet(psmouse);
+
+			psmouse->pktcnt = 0;
+		}
+		break;
+	}
+	return;
+
+ bad_sync:
+	priv->out_of_sync++;
+	psmouse->pktcnt = 0;
+	if (psmouse_resetafter > 0 && priv->out_of_sync	== psmouse_resetafter) {
+		psmouse->state = PSMOUSE_IGNORE;
+		serio_rescan(psmouse->serio);
 	}
 }

_