diff options
author | JJ Ding <jj_ding@emc.com.tw> | 2011-09-21 01:42:51 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-09-21 01:46:27 -0400 |
commit | 84a90b610a1473d732818ec5d041ab18eae77f14 (patch) | |
tree | 23826221db7299bcce38f3ad35d4c42bd46531ad /drivers/input/mouse | |
parent | 1dc6edec127e1fdb89d246189c232fe635d2f921 (diff) |
Input: elantech - better support all those v2 variants
V2 hardware has many variants. This patch adddresses two issues:
- some model also has debounce packets, but with a different signature
than v3. Now we just check debounce for all v2 hardware.
- due to different scanning methods the hardware uses, x and y ranges have
to be calculated differently. And for some specific versions, we can just
see them as custom-made, so set {x, y} the same values as Windows driver
does.
Signed-off-by: JJ Ding <jj_ding@emc.com.tw>
Tested-by: Richard Schütz <r.schtz@t-online.de>
Reviewed-by: Éric Piel <eric.piel@tremplin-utc.net>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r-- | drivers/input/mouse/elantech.c | 46 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.h | 1 |
2 files changed, 42 insertions, 5 deletions
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index b8733b377266..c2d91ebbadf4 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -613,6 +613,18 @@ static int elantech_packet_check_v1(struct psmouse *psmouse) | |||
613 | etd->parity[packet[3]] == p3; | 613 | etd->parity[packet[3]] == p3; |
614 | } | 614 | } |
615 | 615 | ||
616 | static int elantech_debounce_check_v2(struct psmouse *psmouse) | ||
617 | { | ||
618 | /* | ||
619 | * When we encounter packet that matches this exactly, it means the | ||
620 | * hardware is in debounce status. Just ignore the whole packet. | ||
621 | */ | ||
622 | const u8 debounce_packet[] = { 0x84, 0xff, 0xff, 0x02, 0xff, 0xff }; | ||
623 | unsigned char *packet = psmouse->packet; | ||
624 | |||
625 | return !memcmp(packet, debounce_packet, sizeof(debounce_packet)); | ||
626 | } | ||
627 | |||
616 | static int elantech_packet_check_v2(struct psmouse *psmouse) | 628 | static int elantech_packet_check_v2(struct psmouse *psmouse) |
617 | { | 629 | { |
618 | struct elantech_data *etd = psmouse->private; | 630 | struct elantech_data *etd = psmouse->private; |
@@ -708,6 +720,10 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) | |||
708 | break; | 720 | break; |
709 | 721 | ||
710 | case 2: | 722 | case 2: |
723 | /* ignore debounce */ | ||
724 | if (elantech_debounce_check_v2(psmouse)) | ||
725 | return PSMOUSE_FULL_PACKET; | ||
726 | |||
711 | if (etd->paritycheck && !elantech_packet_check_v2(psmouse)) | 727 | if (etd->paritycheck && !elantech_packet_check_v2(psmouse)) |
712 | return PSMOUSE_BAD_DATA; | 728 | return PSMOUSE_BAD_DATA; |
713 | 729 | ||
@@ -825,7 +841,6 @@ static int elantech_set_range(struct psmouse *psmouse, | |||
825 | struct elantech_data *etd = psmouse->private; | 841 | struct elantech_data *etd = psmouse->private; |
826 | unsigned char param[3]; | 842 | unsigned char param[3]; |
827 | unsigned char traces; | 843 | unsigned char traces; |
828 | int i; | ||
829 | 844 | ||
830 | switch (etd->hw_version) { | 845 | switch (etd->hw_version) { |
831 | case 1: | 846 | case 1: |
@@ -844,12 +859,33 @@ static int elantech_set_range(struct psmouse *psmouse, | |||
844 | *x_max = ETP_XMAX_V2; | 859 | *x_max = ETP_XMAX_V2; |
845 | *y_max = ETP_YMAX_V2; | 860 | *y_max = ETP_YMAX_V2; |
846 | } else { | 861 | } else { |
862 | int i; | ||
863 | int fixed_dpi; | ||
864 | |||
847 | i = (etd->fw_version > 0x020800 && | 865 | i = (etd->fw_version > 0x020800 && |
848 | etd->fw_version < 0x020900) ? 1 : 2; | 866 | etd->fw_version < 0x020900) ? 1 : 2; |
849 | *x_min = 0; | 867 | |
850 | *y_min = 0; | 868 | if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param)) |
851 | *x_max = (etd->capabilities[1] - i) * 64; | 869 | return -1; |
852 | *y_max = (etd->capabilities[2] - i) * 64; | 870 | |
871 | fixed_dpi = param[1] & 0x10; | ||
872 | |||
873 | if (((etd->fw_version >> 16) == 0x14) && fixed_dpi) { | ||
874 | if (synaptics_send_cmd(psmouse, ETP_SAMPLE_QUERY, param)) | ||
875 | return -1; | ||
876 | |||
877 | *x_max = (etd->capabilities[1] - i) * param[1] / 2; | ||
878 | *y_max = (etd->capabilities[2] - i) * param[2] / 2; | ||
879 | } else if (etd->fw_version == 0x040216) { | ||
880 | *x_max = 819; | ||
881 | *y_max = 405; | ||
882 | } else if (etd->fw_version == 0x040219 || etd->fw_version == 0x040215) { | ||
883 | *x_max = 900; | ||
884 | *y_max = 500; | ||
885 | } else { | ||
886 | *x_max = (etd->capabilities[1] - i) * 64; | ||
887 | *y_max = (etd->capabilities[2] - i) * 64; | ||
888 | } | ||
853 | } | 889 | } |
854 | break; | 890 | break; |
855 | 891 | ||
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index 7ecaef0c07c4..9e5f1aabea7e 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #define ETP_FW_ID_QUERY 0x00 | 19 | #define ETP_FW_ID_QUERY 0x00 |
20 | #define ETP_FW_VERSION_QUERY 0x01 | 20 | #define ETP_FW_VERSION_QUERY 0x01 |
21 | #define ETP_CAPABILITIES_QUERY 0x02 | 21 | #define ETP_CAPABILITIES_QUERY 0x02 |
22 | #define ETP_SAMPLE_QUERY 0x03 | ||
22 | 23 | ||
23 | /* | 24 | /* |
24 | * Command values for register reading or writing | 25 | * Command values for register reading or writing |