|
@@ -762,6 +762,10 @@ static void synaptics_image_sensor_1f(struct synaptics_data *priv,
|
|
|
synaptics_mt_state_set(mt_state, 1, -1, -1);
|
|
|
priv->mt_state_lost = true;
|
|
|
break;
|
|
|
+ case 4:
|
|
|
+ case 5:
|
|
|
+ /* mt_state was updated by AGM-CONTACT packet */
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -816,6 +820,10 @@ static void synaptics_image_sensor_2f(struct synaptics_data *priv,
|
|
|
synaptics_mt_state_set(mt_state, 2, -1, -1);
|
|
|
priv->mt_state_lost = true;
|
|
|
break;
|
|
|
+ case 4:
|
|
|
+ case 5:
|
|
|
+ /* mt_state was updated by AGM-CONTACT packet */
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -843,6 +851,22 @@ static void synaptics_image_sensor_3f(struct synaptics_data *priv,
|
|
|
synaptics_mt_state_set(mt_state, 3, 0, 2);
|
|
|
break;
|
|
|
case 2:
|
|
|
+ /*
|
|
|
+ * If the AGM previously contained slot 3 or higher, then the
|
|
|
+ * newly touching finger is in the lowest available slot.
|
|
|
+ *
|
|
|
+ * If SGM was previously 1 or higher, then the new SGM is
|
|
|
+ * now slot 0 (with a new finger), otherwise, the new finger
|
|
|
+ * is now in a hidden slot between 0 and AGM's slot.
|
|
|
+ *
|
|
|
+ * In all such cases, the SGM now contains slot 0, and the AGM
|
|
|
+ * continues to contain the same slot as before.
|
|
|
+ */
|
|
|
+ if (old->agm >= 3) {
|
|
|
+ synaptics_mt_state_set(mt_state, 3, 0, old->agm);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* After some 3->1 and all 3->2 transitions, we lose track
|
|
|
* of which slot is reported by SGM and AGM.
|
|
@@ -883,9 +907,22 @@ static void synaptics_image_sensor_3f(struct synaptics_data *priv,
|
|
|
* received AGM-CONTACT packet.
|
|
|
*/
|
|
|
break;
|
|
|
+
|
|
|
+ case 4:
|
|
|
+ case 5:
|
|
|
+ /* mt_state was updated by AGM-CONTACT packet */
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/* Handle case where mt_state->count = 4, or = 5 */
|
|
|
+static void synaptics_image_sensor_45f(struct synaptics_data *priv,
|
|
|
+ struct synaptics_mt_state *mt_state)
|
|
|
+{
|
|
|
+ /* mt_state was updated correctly by AGM-CONTACT packet */
|
|
|
+ priv->mt_state_lost = false;
|
|
|
+}
|
|
|
+
|
|
|
static void synaptics_image_sensor_process(struct psmouse *psmouse,
|
|
|
struct synaptics_hw_state *sgm)
|
|
|
{
|
|
@@ -905,8 +942,10 @@ static void synaptics_image_sensor_process(struct psmouse *psmouse,
|
|
|
synaptics_image_sensor_1f(priv, &mt_state);
|
|
|
else if (sgm->w == 0)
|
|
|
synaptics_image_sensor_2f(priv, &mt_state);
|
|
|
- else if (sgm->w == 1)
|
|
|
+ else if (sgm->w == 1 && mt_state.count <= 3)
|
|
|
synaptics_image_sensor_3f(priv, &mt_state);
|
|
|
+ else
|
|
|
+ synaptics_image_sensor_45f(priv, &mt_state);
|
|
|
|
|
|
/* Send resulting input events to user space */
|
|
|
synaptics_report_mt_data(psmouse, &mt_state, sgm);
|
|
@@ -1110,6 +1149,10 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
|
|
|
ABS_MT_POSITION_Y);
|
|
|
/* Image sensors can report per-contact pressure */
|
|
|
input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
|
|
|
+
|
|
|
+ /* Image sensors can signal 4 and 5 finger clicks */
|
|
|
+ __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
|
|
|
+ __set_bit(BTN_TOOL_QUINTTAP, dev->keybit);
|
|
|
} else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) {
|
|
|
/* Non-image sensors with AGM use semi-mt */
|
|
|
__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
|