|
@@ -629,10 +629,61 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
|
|
((buf[0] & 0x04) >> 1) |
|
|
((buf[0] & 0x04) >> 1) |
|
|
((buf[3] & 0x04) >> 2));
|
|
((buf[3] & 0x04) >> 2));
|
|
|
|
|
|
|
|
+ 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, hw);
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ 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->left = (buf[0] & 0x01) ? 1 : 0;
|
|
hw->left = (buf[0] & 0x01) ? 1 : 0;
|
|
hw->right = (buf[0] & 0x02) ? 1 : 0;
|
|
hw->right = (buf[0] & 0x02) ? 1 : 0;
|
|
|
|
|
|
- if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
|
|
|
|
|
|
+ if (SYN_CAP_FORCEPAD(priv->ext_cap_0c)) {
|
|
|
|
+ /*
|
|
|
|
+ * ForcePads, like Clickpads, use middle button
|
|
|
|
+ * bits to report primary button clicks.
|
|
|
|
+ * Unfortunately they report primary button not
|
|
|
|
+ * only when user presses on the pad above certain
|
|
|
|
+ * threshold, but also when there are more than one
|
|
|
|
+ * finger on the touchpad, which interferes with
|
|
|
|
+ * out multi-finger gestures.
|
|
|
|
+ */
|
|
|
|
+ if (hw->z == 0) {
|
|
|
|
+ /* No contacts */
|
|
|
|
+ priv->press = priv->report_press = false;
|
|
|
|
+ } else if (hw->w >= 4 && ((buf[0] ^ buf[3]) & 0x01)) {
|
|
|
|
+ /*
|
|
|
|
+ * Single-finger touch with pressure above
|
|
|
|
+ * the threshold. If pressure stays long
|
|
|
|
+ * enough, we'll start reporting primary
|
|
|
|
+ * button. We rely on the device continuing
|
|
|
|
+ * sending data even if finger does not
|
|
|
|
+ * move.
|
|
|
|
+ */
|
|
|
|
+ if (!priv->press) {
|
|
|
|
+ priv->press_start = jiffies;
|
|
|
|
+ priv->press = true;
|
|
|
|
+ } else if (time_after(jiffies,
|
|
|
|
+ priv->press_start +
|
|
|
|
+ msecs_to_jiffies(50))) {
|
|
|
|
+ priv->report_press = true;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ priv->press = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ hw->left = priv->report_press;
|
|
|
|
+
|
|
|
|
+ } else if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
|
|
/*
|
|
/*
|
|
* Clickpad's button is transmitted as middle button,
|
|
* Clickpad's button is transmitted as middle button,
|
|
* however, since it is primary button, we will report
|
|
* however, since it is primary button, we will report
|
|
@@ -651,21 +702,6 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
|
|
hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0;
|
|
hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0;
|
|
}
|
|
}
|
|
|
|
|
|
- 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, hw);
|
|
|
|
- return 1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- 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];
|
|
|
|
-
|
|
|
|
if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
|
|
if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
|
|
((buf[0] ^ buf[3]) & 0x02)) {
|
|
((buf[0] ^ buf[3]) & 0x02)) {
|
|
switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
|
|
switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
|