Hi,

there might be a problem. The Linux driver for that touchpad type also
accepts "debounce packets", which have the same format as for the
non-crc version. I have no idea whether that is correct and if those
packets do occur in practice, but if they do they wouldn't pass this
version of sync() (byte 3 would be 0x02 then).

On 04/01/2015 05:44 PM, Fasse wrote:
This diff adds support for Elantech v3 touchpads using the "crc_enabled"
integrity check. I tested this patch with my Elantech v3 touchpad using
firmware version 0x454f00, it now works correctly.
Other hardware versions should not be affected by this change. I could
not check if this introduces regression with other firmware versions.
If you have an elantech touchpad, particularly v3, could you please try
this diff and see if it causes any issues.

Index: sys/dev/pckbc/pms.c
===================================================================
RCS file: /cvs/src/sys/dev/pckbc/pms.c,v
retrieving revision 1.58
diff -u -p -r1.58 pms.c
--- sys/dev/pckbc/pms.c 26 Mar 2015 01:30:22 -0000      1.58
+++ sys/dev/pckbc/pms.c 1 Apr 2015 14:22:10 -0000
@@ -137,6 +137,7 @@ struct elantech_softc {
  #define ELANTECH_F_HAS_ROCKER         0x02
  #define ELANTECH_F_2FINGER_PACKET     0x04
  #define ELANTECH_F_HW_V1_OLD          0x08
+#define ELANTECH_F_CRC_ENABLED         0x10
        int fw_version;

        int min_x, min_y;
@@ -1812,6 +1813,9 @@ elantech_get_hwinfo_v3(struct pms_softc
        elantech->fw_version = fw_version;
        elantech->flags |= ELANTECH_F_REPORTS_PRESSURE;

+       if ((fw_version&  0x4000) == 0x4000)
+               elantech->flags |= ELANTECH_F_CRC_ENABLED;
+
        if (elantech_set_absolute_mode_v3(sc))
                return (-1);

@@ -2164,14 +2168,23 @@ pms_sync_elantech_v2(struct pms_softc *s
  int
  pms_sync_elantech_v3(struct pms_softc *sc, int data)
  {
+       struct elantech_softc *elantech = sc->elantech;
+
        switch (sc->inputstate) {
        case 0:
+               if (elantech->flags&  ELANTECH_F_CRC_ENABLED)
+                       break;
                if ((data&  0x0c) != 0x04&&  (data&  0x0c) != 0x0c)
                        return (-1);
                break;
        case 3:
-               if ((data&  0xcf) != 0x02&&  (data&  0xce) != 0x0c)
-                       return (-1);
+               if (elantech->flags&  ELANTECH_F_CRC_ENABLED) {
+                       if ((data&  0x09) != 0x08&&  (data&  0x09) != 0x09)
+                               return (-1);
+               } else {
+                       if ((data&  0xcf) != 0x02&&  (data&  0xce) != 0x0c)
+                               return (-1);
+               }
                break;
        }

@@ -2271,11 +2284,18 @@ pms_proc_elantech_v3(struct pms_softc *s
                 * and a tail packet. We report a single event and ignore
                 * the tail packet.
                 */
-               if ((sc->packet[0]&  0x0c) != 0x04&&
-                   (sc->packet[3]&  0xcf) != 0x02) {
-                       /* not the head packet -- ignore */
-                       return;
+               switch (elantech->flags&  ELANTECH_F_CRC_ENABLED) {
+               case 0:
+                       if ((sc->packet[0]&  0x0c) != 0x04&&
+                       (sc->packet[3]&  0xcf) != 0x02) {
+                               /* not the head packet -- ignore */
+                               return;
+                       }
+               case ELANTECH_F_CRC_ENABLED:
+                       if ((sc->packet[3]&  0x09) != 0x08)
+                               return;
                }
+                       
        }

        /* Prevent juming cursor if pad isn't touched or reports garbage. */



Reply via email to