]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Synaptics: code cleanup
authorDmitry Torokhov <dtor_core@ameritech.net>
Thu, 18 Dec 2003 13:32:19 +0000 (05:32 -0800)
committerDmitry Torokhov <dtor_core@ameritech.net>
Thu, 18 Dec 2003 13:32:19 +0000 (05:32 -0800)
Input: Synaptics code cleanup and credit update.

drivers/input/mouse/synaptics.c

index 7f95355ba2ac44e43a32c82390c5dedb540ee3b4..ee52edd79b0f6735a44a1d17f4c9fe7adc2508b0 100644 (file)
@@ -2,7 +2,8 @@
  * Synaptics TouchPad PS/2 mouse driver
  *
  *   2003 Dmitry Torokhov <dtor@mail.ru>
- *     Added support for pass-through port
+ *     Added support for pass-through port. Special thanks to Peter Berg Larsen
+ *     for explaining various Synaptics quirks.
  *
  *   2003 Peter Osterlund <petero2@telia.com>
  *     Ported to 2.5 input device infrastructure.
@@ -419,16 +420,7 @@ void synaptics_disconnect(struct psmouse *psmouse)
 
 static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw)
 {
-       hw->up    = 0;
-       hw->down  = 0;
-       hw->b0    = 0;
-       hw->b1    = 0;
-       hw->b2    = 0;
-       hw->b3    = 0;
-       hw->b4    = 0;
-       hw->b5    = 0;
-       hw->b6    = 0;
-       hw->b7    = 0;
+       memset(hw, 0, sizeof(struct synaptics_hw_state));
 
        if (SYN_MODEL_NEWABS(priv->model_id)) {
                hw->x = (((buf[3] & 0x10) << 8) |
@@ -570,44 +562,29 @@ static void synaptics_process_packet(struct psmouse *psmouse)
        input_sync(dev);
 }
 
+static int synaptics_validate_byte(struct psmouse *psmouse)
+{
+       static unsigned char newabs_mask[] = { 0xC8, 0x00, 0x00, 0xC8, 0x00 };
+       static unsigned char newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 };
+       static unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
+       static unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
+       struct synaptics_data *priv = psmouse->private;
+       int idx = psmouse->pktcnt - 1;
+
+       if (SYN_MODEL_NEWABS(priv->model_id))
+               return (psmouse->packet[idx] & newabs_mask[idx]) == newabs_rslt[idx];
+       else
+               return (psmouse->packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx];
+}
+
 void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
 {
        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);
 
-       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)
-                       break;              /* Wait for full packet */
-
+       if (psmouse->pktcnt >= 6) { /* Full packet received */
                if (priv->out_of_sync) {
                        priv->out_of_sync = 0;
                        printk(KERN_NOTICE "Synaptics driver resynced.\n");
@@ -617,17 +594,15 @@ void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
                        synaptics_pass_pt_packet(priv->ptport, psmouse->packet);
                else
                        synaptics_process_packet(psmouse);
+               psmouse->pktcnt = 0;
 
+       } else if (psmouse->pktcnt && !synaptics_validate_byte(psmouse)) {
+               printk(KERN_WARNING "Synaptics driver lost sync at byte %d\n", psmouse->pktcnt);
                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);
+               if (++priv->out_of_sync == psmouse_resetafter) {
+                       psmouse->state = PSMOUSE_IGNORE;
+                       printk(KERN_NOTICE "synaptics: issuing rescan request\n");
+                       serio_rescan(psmouse->serio);
+               }
        }
 }