[PATCH synaptics] Implement a workaround for Elantech touchpads

Peter Hutterer peter.hutterer at who-t.net
Thu Mar 1 17:21:36 PST 2012


From: Peter Zotov <whitequark at whitequark.org>

All Elantech touchpads report the number of fingers explicitly,
and at least the v3 version of the hardware can report any
pressure values down to zero. This interferes with the tap
detection hysteresis, which is required for dumb touchpads.

This commit implements a vendor-specific workaround for Elantech
touchpads which sets the FingerLow and FingerHigh options to 1
by default, effectively disabling the hysteresis mechanism.

Signed-off-by: Peter Zotov <whitequark at whitequark.org>
Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/eventcomm.c    |    1 +
 src/synaptics.c    |   24 +++++++++++++++++++++---
 src/synapticsstr.h |    3 ++-
 3 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/src/eventcomm.c b/src/eventcomm.c
index 6147e41..2556fcb 100644
--- a/src/eventcomm.c
+++ b/src/eventcomm.c
@@ -293,6 +293,7 @@ static model_lookup_t model_lookup_table[] = {
 	{0x0002, 0x0007, MODEL_SYNAPTICS},
 	{0x0002, 0x0008, MODEL_ALPS},
 	{0x05ac, PRODUCT_ANY, MODEL_APPLETOUCH},
+	{0x0002, 0x000e, MODEL_ELANTECH},
 	{0x0, 0x0, 0x0}
 };
 
diff --git a/src/synaptics.c b/src/synaptics.c
index 4784157..719e810 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -386,6 +386,25 @@ calculate_edge_widths(SynapticsPrivate *priv, int *l, int *r, int *t, int *b)
     *b = priv->maxy - eheight;
 }
 
+static void
+calculate_tap_hysteresis(SynapticsPrivate *priv, int range,
+                         int *fingerLow, int *fingerHigh, int *fingerPress)
+{
+    if (priv->model == MODEL_ELANTECH) {
+        /* All Elantech touchpads don't need the Z filtering to get the
+         * number of fingers correctly. See Documentation/elantech.txt
+         * in the kernel.
+         */
+        *fingerLow  = priv->minp + 1;
+        *fingerHigh = priv->minp + 1;
+    } else {
+        *fingerLow  = priv->minp + range * (25.0/256);
+        *fingerHigh = priv->minp + range * (30.0/256);
+    }
+
+    *fingerPress = priv->minp + range * 1.000;
+}
+
 /* Area options support both percent values and absolute values. This is
  * awkward. The xf86Set* calls will print to the log, but they'll
  * also print an error if we request a percent value but only have an
@@ -471,10 +490,9 @@ static void set_default_parameters(InputInfoPtr pInfo)
 
     range = priv->maxp - priv->minp + 1;
 
+    calculate_tap_hysteresis(priv, range, &fingerLow, &fingerHigh, &fingerPress);
+
     /* scaling based on defaults and a pressure of 256 */
-    fingerLow = priv->minp + range * (25.0/256);
-    fingerHigh = priv->minp + range * (30.0/256);
-    fingerPress = priv->minp + range * 1.000;
     emulateTwoFingerMinZ = priv->minp + range * (282.0/256);
     edgeMotionMinZ = priv->minp + range * (30.0/256);
     edgeMotionMaxZ = priv->minp + range * (160.0/256);
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index ba1eb13..d4daeba 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -112,7 +112,8 @@ enum TouchpadModel {
     MODEL_UNKNOWN = 0,
     MODEL_SYNAPTICS,
     MODEL_ALPS,
-    MODEL_APPLETOUCH
+    MODEL_APPLETOUCH,
+    MODEL_ELANTECH
 };
 
 typedef struct _SynapticsParameters
-- 
1.7.9


More information about the xorg-devel mailing list