static int alps_process_bitmap(struct alps_data *priv,
                               struct alps_fields *fields)
 {
-       int i, fingers_x = 0, fingers_y = 0, fingers;
+       int i, fingers_x = 0, fingers_y = 0, fingers, closest;
        struct alps_bitmap_point x_low = {0,}, x_high = {0,};
        struct alps_bitmap_point y_low = {0,}, y_high = {0,};
+       struct input_mt_pos corner[4];
 
        if (!fields->x_map || !fields->y_map)
                return 0;
                y_high.num_bits = max(i, 1);
        }
 
-       fields->mt[0].x =
+       /* top-left corner */
+       corner[0].x =
                (priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) /
                (2 * (priv->x_bits - 1));
-       fields->mt[0].y =
+       corner[0].y =
                (priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) /
                (2 * (priv->y_bits - 1));
 
-       fields->mt[1].x =
+       /* top-right corner */
+       corner[1].x =
                (priv->x_max * (2 * x_high.start_bit + x_high.num_bits - 1)) /
                (2 * (priv->x_bits - 1));
-       fields->mt[1].y =
+       corner[1].y =
+               (priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) /
+               (2 * (priv->y_bits - 1));
+
+       /* bottom-right corner */
+       corner[2].x =
+               (priv->x_max * (2 * x_high.start_bit + x_high.num_bits - 1)) /
+               (2 * (priv->x_bits - 1));
+       corner[2].y =
+               (priv->y_max * (2 * y_high.start_bit + y_high.num_bits - 1)) /
+               (2 * (priv->y_bits - 1));
+
+       /* bottom-left corner */
+       corner[3].x =
+               (priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) /
+               (2 * (priv->x_bits - 1));
+       corner[3].y =
                (priv->y_max * (2 * y_high.start_bit + y_high.num_bits - 1)) /
                (2 * (priv->y_bits - 1));
 
        /* y-bitmap order is reversed, except on rushmore */
        if (priv->proto_version != ALPS_PROTO_V3_RUSHMORE) {
-               fields->mt[0].y = priv->y_max - fields->mt[0].y;
-               fields->mt[1].y = priv->y_max - fields->mt[1].y;
+               for (i = 0; i < 4; i++)
+                       corner[i].y = priv->y_max - corner[i].y;
+       }
+
+       /*
+        * We only select a corner for the second touch once per 2 finger
+        * touch sequence to avoid the chosen corner (and thus the coordinates)
+        * jumping around when the first touch is in the middle.
+        */
+       if (priv->second_touch == -1) {
+               /* Find corner closest to our st coordinates */
+               closest = 0x7fffffff;
+               for (i = 0; i < 4; i++) {
+                       int dx = fields->st.x - corner[i].x;
+                       int dy = fields->st.y - corner[i].y;
+                       int distance = dx * dx + dy * dy;
+
+                       if (distance < closest) {
+                               priv->second_touch = i;
+                               closest = distance;
+                       }
+               }
+               /* And select the opposite corner to use for the 2nd touch */
+               priv->second_touch = (priv->second_touch + 2) % 4;
        }
 
+       fields->mt[0] = fields->st;
+       fields->mt[1] = corner[priv->second_touch];
+
        return fingers;
 }
 
                f->mt[0].x = f->st.x;
                f->mt[0].y = f->st.y;
                fingers = f->pressure > 0 ? 1 : 0;
+               priv->second_touch = -1;
        }
 
        alps_report_mt_data(psmouse, (fingers <= 2) ? fingers : 2);