diff options
author | JJ Ding <jj_ding@emc.com.tw> | 2011-09-09 13:28:04 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-09-09 13:34:50 -0400 |
commit | 7894f21b109848130be7547448af89dc33d0f268 (patch) | |
tree | 430abd74d0ffc9006fd2bdf350418482378fe043 /drivers/input | |
parent | 8a360d09b14514139b883d970cd3a1b0b63e6717 (diff) |
Input: elantech - packet checking for v2 hardware
For v2 hardware, there is no real parity check, but we can still check
some constant bits for data integrity.
Also rename elantech_check_parity_v1 to elantech_packet_check_v1 to make
these packet checking function names consistent.
Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
Acked-by: Daniel Kurtz <djkurtz@chromium.org>
Acked-by: Éric Piel <eric.piel@tremplin-utc.net>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/mouse/elantech.c | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 296b6a6250fd..f2e3a2be041c 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -350,7 +350,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
350 | input_sync(dev); | 350 | input_sync(dev); |
351 | } | 351 | } |
352 | 352 | ||
353 | static int elantech_check_parity_v1(struct psmouse *psmouse) | 353 | static int elantech_packet_check_v1(struct psmouse *psmouse) |
354 | { | 354 | { |
355 | struct elantech_data *etd = psmouse->private; | 355 | struct elantech_data *etd = psmouse->private; |
356 | unsigned char *packet = psmouse->packet; | 356 | unsigned char *packet = psmouse->packet; |
@@ -374,6 +374,34 @@ static int elantech_check_parity_v1(struct psmouse *psmouse) | |||
374 | etd->parity[packet[3]] == p3; | 374 | etd->parity[packet[3]] == p3; |
375 | } | 375 | } |
376 | 376 | ||
377 | static int elantech_packet_check_v2(struct psmouse *psmouse) | ||
378 | { | ||
379 | struct elantech_data *etd = psmouse->private; | ||
380 | unsigned char *packet = psmouse->packet; | ||
381 | |||
382 | /* | ||
383 | * V2 hardware has two flavors. Older ones that do not report pressure, | ||
384 | * and newer ones that reports pressure and width. With newer ones, all | ||
385 | * packets (1, 2, 3 finger touch) have the same constant bits. With | ||
386 | * older ones, 1/3 finger touch packets and 2 finger touch packets | ||
387 | * have different constant bits. | ||
388 | * With all three cases, if the constant bits are not exactly what I | ||
389 | * expected, I consider them invalid. | ||
390 | */ | ||
391 | if (etd->reports_pressure) | ||
392 | return (packet[0] & 0x0c) == 0x04 && | ||
393 | (packet[3] & 0x0f) == 0x02; | ||
394 | |||
395 | if ((packet[0] & 0xc0) == 0x80) | ||
396 | return (packet[0] & 0x0c) == 0x0c && | ||
397 | (packet[3] & 0x0e) == 0x08; | ||
398 | |||
399 | return (packet[0] & 0x3c) == 0x3c && | ||
400 | (packet[1] & 0xf0) == 0x00 && | ||
401 | (packet[3] & 0x3e) == 0x38 && | ||
402 | (packet[4] & 0xf0) == 0x00; | ||
403 | } | ||
404 | |||
377 | /* | 405 | /* |
378 | * Process byte stream from mouse and handle complete packets | 406 | * Process byte stream from mouse and handle complete packets |
379 | */ | 407 | */ |
@@ -389,14 +417,16 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) | |||
389 | 417 | ||
390 | switch (etd->hw_version) { | 418 | switch (etd->hw_version) { |
391 | case 1: | 419 | case 1: |
392 | if (etd->paritycheck && !elantech_check_parity_v1(psmouse)) | 420 | if (etd->paritycheck && !elantech_packet_check_v1(psmouse)) |
393 | return PSMOUSE_BAD_DATA; | 421 | return PSMOUSE_BAD_DATA; |
394 | 422 | ||
395 | elantech_report_absolute_v1(psmouse); | 423 | elantech_report_absolute_v1(psmouse); |
396 | break; | 424 | break; |
397 | 425 | ||
398 | case 2: | 426 | case 2: |
399 | /* We don't know how to check parity in protocol v2 */ | 427 | if (etd->paritycheck && !elantech_packet_check_v2(psmouse)) |
428 | return PSMOUSE_BAD_DATA; | ||
429 | |||
400 | elantech_report_absolute_v2(psmouse); | 430 | elantech_report_absolute_v2(psmouse); |
401 | break; | 431 | break; |
402 | } | 432 | } |
@@ -795,8 +825,7 @@ int elantech_init(struct psmouse *psmouse) | |||
795 | etd->hw_version = 2; | 825 | etd->hw_version = 2; |
796 | /* For now show extra debug information */ | 826 | /* For now show extra debug information */ |
797 | etd->debug = 1; | 827 | etd->debug = 1; |
798 | /* Don't know how to do parity checking for version 2 */ | 828 | etd->paritycheck = 1; |
799 | etd->paritycheck = 0; | ||
800 | 829 | ||
801 | if (etd->fw_version >= 0x020800) | 830 | if (etd->fw_version >= 0x020800) |
802 | etd->reports_pressure = true; | 831 | etd->reports_pressure = true; |