*     Functions to interpret the absolute mode packets
  ****************************************************************************/
 
+static void synaptics_mt_state_set(struct synaptics_mt_state *state, int count,
+                                  int sgm, int agm)
+{
+       state->count = count;
+       state->sgm = sgm;
+       state->agm = agm;
+}
+
 static void synaptics_parse_agm(const unsigned char buf[],
-                               struct synaptics_data *priv)
+                               struct synaptics_data *priv,
+                               struct synaptics_hw_state *hw)
 {
        struct synaptics_hw_state *agm = &priv->agm;
+       int agm_packet_type;
+
+       agm_packet_type = (buf[5] & 0x30) >> 4;
+       switch (agm_packet_type) {
+       case 1:
+               /* Gesture packet: (x, y, z) half resolution */
+               agm->w = hw->w;
+               agm->x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1;
+               agm->y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1;
+               agm->z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1;
+               break;
 
-       /* Gesture packet: (x, y, z) at half resolution */
-       agm->x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1;
-       agm->y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1;
-       agm->z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1;
+       case 2:
+               /* AGM-CONTACT packet: (count, sgm, agm) */
+               synaptics_mt_state_set(&agm->mt_state, buf[1], buf[2], buf[4]);
+               break;
+
+       default:
+               break;
+       }
 }
 
 static int synaptics_parse_hw_state(const unsigned char buf[],
                if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) ||
                        SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) &&
                    hw->w == 2) {
-                       synaptics_parse_agm(buf, priv);
+                       synaptics_parse_agm(buf, priv, hw);
                        return 1;
                }
 
 
 #define SYN_REDUCED_FILTER_FUZZ                8
 
 /*
- * A structure to describe the state of the touchpad hardware (buttons and pad)
+ * A structure to describe which internal touchpad finger slots are being
+ * reported in raw packets.
  */
+struct synaptics_mt_state {
+       int count;                      /* num fingers being tracked */
+       int sgm;                        /* which slot is reported by sgm pkt */
+       int agm;                        /* which slot is reported by agm pkt*/
+};
 
+/*
+ * A structure to describe the state of the touchpad hardware (buttons and pad)
+ */
 struct synaptics_hw_state {
        int x;
        int y;
        unsigned int down:1;
        unsigned char ext_buttons;
        signed char scroll;
+
+       /* As reported in last AGM-CONTACT packets */
+       struct synaptics_mt_state mt_state;
 };
 
 struct synaptics_data {