--- v2
+++ v4
@@ -1,5 +1,3 @@
-From: Daniel Kurtz <djkurtz@chromium.org>
-
Synaptics makes (at least) two kinds of touchpad sensors:
* Older pads use a profile sensor that could only infer the location
of individual fingers based on the projection of their profiles
@@ -15,17 +13,17 @@
The SGM packets have w={0,1} and contain full resolution finger data
Profile sensors try to report the "upper" (larger y value) finger in
- the SGM packet, and the lower (smaller y value) in the AGM packet.
- However, due to the nature of the profile sensor, they easily get
- confused when fingers cross, and can start reporting the x-coordinate
- of one with the y-coordinate of the other. Thus, for profile
- sensors, "semi-mt" was created, which reports a "bounding box"
- created by pairing min and max coordinates of the two pairs of
- reported fingers.
+the SGM packet, and the lower (smaller y value) in the AGM packet.
+However, due to the nature of the profile sensor, they easily get
+confused when fingers cross, and can start reporting the x-coordinate
+of one with the y-coordinate of the other. Thus, for profile
+sensors, "semi-mt" was created, which reports a "bounding box"
+created by pairing min and max coordinates of the two pairs of
+reported fingers.
Image sensors can report the actual coordinates of two of the fingers
- present. This patch detects if the touchpad is an image sensor and
- reports finger data using the MT-B protocol.
+present. This patch detects if the touchpad is an image sensor and
+reports finger data using the MT-B protocol.
NOTE: This patch only adds partial support for 2-finger gestures.
The proper interpretation of the slot contents when more than
@@ -34,12 +32,12 @@
Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
---
- drivers/input/mouse/synaptics.c | 104 +++++++++++++++++++++++++++++++++++++-
+ drivers/input/mouse/synaptics.c | 86 +++++++++++++++++++++++++++++++++++++-
drivers/input/mouse/synaptics.h | 3 +
- 2 files changed, 104 insertions(+), 3 deletions(-)
+ 2 files changed, 86 insertions(+), 3 deletions(-)
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
-index 30d05fd..a9960d2 100644
+index 30d05fd..a49420f 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -304,7 +304,8 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
@@ -63,42 +61,26 @@
synaptics_parse_agm(buf, priv);
return 1;
}
-@@ -543,6 +546,87 @@ static void synaptics_report_semi_mt_data(struct input_dev *dev,
+@@ -543,6 +546,71 @@ static void synaptics_report_semi_mt_data(struct input_dev *dev,
}
}
-+static void synaptics_report_slot_empty(struct input_dev *dev, int slot)
++static void synaptics_report_slot(struct input_dev *dev, int slot,
++ const struct synaptics_hw_state *hw)
+{
+ input_mt_slot(dev, slot);
-+ input_mt_report_slot_state(dev, MT_TOOL_FINGER, false);
++ input_mt_report_slot_state(dev, MT_TOOL_FINGER, (hw != NULL));
++ if (!hw)
++ return;
++
++ input_report_abs(dev, ABS_MT_POSITION_X, hw->x);
++ input_report_abs(dev, ABS_MT_POSITION_Y, invert_y(hw->y));
++ input_report_abs(dev, ABS_MT_PRESSURE, hw->z);
+}
+
-+static void synaptics_report_slot_sgm(struct input_dev *dev, int slot,
-+ const struct synaptics_hw_state *sgm)
-+{
-+ input_mt_slot(dev, slot);
-+ input_mt_report_slot_state(dev, MT_TOOL_FINGER, true);
-+ input_report_abs(dev, ABS_MT_POSITION_X, sgm->x);
-+ input_report_abs(dev, ABS_MT_POSITION_Y, invert_y(sgm->y));
-+ input_report_abs(dev, ABS_MT_PRESSURE, sgm->z);
-+ /* SGM can sometimes contain valid width */
-+ if (sgm->w >= 4)
-+ input_report_abs(dev, ABS_MT_TOUCH_MAJOR, sgm->w);
-+}
-+
-+static void synaptics_report_slot_agm(struct input_dev *dev, int slot,
-+ const struct synaptics_hw_state *agm)
-+{
-+ input_mt_slot(dev, slot);
-+ input_mt_report_slot_state(dev, MT_TOOL_FINGER, true);
-+ input_report_abs(dev, ABS_MT_POSITION_X, agm->x);
-+ input_report_abs(dev, ABS_MT_POSITION_Y, invert_y(agm->y));
-+ input_report_abs(dev, ABS_MT_PRESSURE, agm->z);
-+}
-+
-+static void synaptics_report_mt(struct psmouse *psmouse,
-+ int count,
-+ const struct synaptics_hw_state *sgm)
++static void synaptics_report_mt_data(struct psmouse *psmouse,
++ int count,
++ const struct synaptics_hw_state *sgm)
+{
+ struct input_dev *dev = psmouse->dev;
+ struct synaptics_data *priv = psmouse->private;
@@ -106,17 +88,17 @@
+
+ switch (count) {
+ case 0:
-+ synaptics_report_slot_empty(dev, 0);
-+ synaptics_report_slot_empty(dev, 1);
++ synaptics_report_slot(dev, 0, NULL);
++ synaptics_report_slot(dev, 1, NULL);
+ break;
+ case 1:
-+ synaptics_report_slot_sgm(dev, 0, sgm);
-+ synaptics_report_slot_empty(dev, 1);
++ synaptics_report_slot(dev, 0, sgm);
++ synaptics_report_slot(dev, 1, NULL);
+ break;
+ case 2:
+ case 3: /* Fall-through case */
-+ synaptics_report_slot_sgm(dev, 0, sgm);
-+ synaptics_report_slot_agm(dev, 1, agm);
++ synaptics_report_slot(dev, 0, sgm);
++ synaptics_report_slot(dev, 1, agm);
+ break;
+ }
+
@@ -145,13 +127,13 @@
+ count = 3;
+
+ /* Send resulting input events to user space */
-+ synaptics_report_mt(psmouse, count, sgm);
++ synaptics_report_mt_data(psmouse, count, sgm);
+}
+
/*
* called for each full received packet from the touchpad
*/
-@@ -558,6 +642,11 @@ static void synaptics_process_packet(struct psmouse *psmouse)
+@@ -558,6 +626,11 @@ static void synaptics_process_packet(struct psmouse *psmouse)
if (synaptics_parse_hw_state(psmouse->packet, priv, &hw))
return;
@@ -163,7 +145,7 @@
if (hw.scroll) {
priv->scroll += hw.scroll;
-@@ -739,7 +828,16 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
+@@ -739,7 +812,14 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
set_abs_position_params(dev, priv, ABS_X, ABS_Y);
input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
@@ -174,15 +156,13 @@
+ 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 sometimes report per-contact width */
-+ input_set_abs_params(dev, ABS_MT_TOUCH_MAJOR, 4, 15, 0, 0);
+ } 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);
input_mt_init_slots(dev, 2);
set_abs_position_params(dev, priv, ABS_MT_POSITION_X,
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
-index da8e969..34296b9 100644
+index a9efbf3..0ea7616 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -74,6 +74,8 @@
@@ -195,7 +175,7 @@
*/
#define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */
@@ -82,6 +84,7 @@
- #define SYN_CAP_MIN_DIMENSIONS(ex0c) ((ex0c) & 0x000200)
+ #define SYN_CAP_MIN_DIMENSIONS(ex0c) ((ex0c) & 0x002000)
#define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000)
#define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400)
+#define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800)