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. */