diff options
author | Ulrik De Bie <ulrik.debie-os@e2big.org> | 2015-04-06 18:35:38 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-04-06 18:39:07 -0400 |
commit | bd884149aca61de269fd9bad83fe2a4232ffab21 (patch) | |
tree | 3f97de62459c36712336e1aa7bf1e37f42a81d05 /drivers/input | |
parent | 58d8a3be36cf0fe2eb2609e205bb07a141c29a7c (diff) |
Input: elantech - fix absolute mode setting on some ASUS laptops
On ASUS TP500LN and X750JN, the touchpad absolute mode is reset each
time set_rate is done.
In order to fix this, we will verify the firmware version, and if it
matches the one in those laptops, the set_rate function is overloaded
with a function elantech_set_rate_restore_reg_07 that performs the
set_rate with the original function, followed by a restore of reg_07
(the register that sets the absolute mode on elantech v4 hardware).
Also the ASUS TP500LN and X750JN firmware version, capabilities, and
button constellation is added to elantech.c
Cc: stable@vger.kernel.org
Reported-and-tested-by: George Moutsopoulos <gmoutso@yahoo.co.uk>
Signed-off-by: Ulrik De Bie <ulrik.debie-os@e2big.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/mouse/elantech.c | 22 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.h | 1 |
2 files changed, 23 insertions, 0 deletions
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 6e22682c8255..991dc6b20a58 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -893,6 +893,21 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) | |||
893 | } | 893 | } |
894 | 894 | ||
895 | /* | 895 | /* |
896 | * This writes the reg_07 value again to the hardware at the end of every | ||
897 | * set_rate call because the register loses its value. reg_07 allows setting | ||
898 | * absolute mode on v4 hardware | ||
899 | */ | ||
900 | static void elantech_set_rate_restore_reg_07(struct psmouse *psmouse, | ||
901 | unsigned int rate) | ||
902 | { | ||
903 | struct elantech_data *etd = psmouse->private; | ||
904 | |||
905 | etd->original_set_rate(psmouse, rate); | ||
906 | if (elantech_write_reg(psmouse, 0x07, etd->reg_07)) | ||
907 | psmouse_err(psmouse, "restoring reg_07 failed\n"); | ||
908 | } | ||
909 | |||
910 | /* | ||
896 | * Put the touchpad into absolute mode | 911 | * Put the touchpad into absolute mode |
897 | */ | 912 | */ |
898 | static int elantech_set_absolute_mode(struct psmouse *psmouse) | 913 | static int elantech_set_absolute_mode(struct psmouse *psmouse) |
@@ -1094,6 +1109,8 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse, | |||
1094 | * Asus K53SV 0x450f01 78, 15, 0c 2 hw buttons | 1109 | * Asus K53SV 0x450f01 78, 15, 0c 2 hw buttons |
1095 | * Asus G46VW 0x460f02 00, 18, 0c 2 hw buttons | 1110 | * Asus G46VW 0x460f02 00, 18, 0c 2 hw buttons |
1096 | * Asus G750JX 0x360f00 00, 16, 0c 2 hw buttons | 1111 | * Asus G750JX 0x360f00 00, 16, 0c 2 hw buttons |
1112 | * Asus TP500LN 0x381f17 10, 14, 0e clickpad | ||
1113 | * Asus X750JN 0x381f17 10, 14, 0e clickpad | ||
1097 | * Asus UX31 0x361f00 20, 15, 0e clickpad | 1114 | * Asus UX31 0x361f00 20, 15, 0e clickpad |
1098 | * Asus UX32VD 0x361f02 00, 15, 0e clickpad | 1115 | * Asus UX32VD 0x361f02 00, 15, 0e clickpad |
1099 | * Avatar AVIU-145A2 0x361f00 ? clickpad | 1116 | * Avatar AVIU-145A2 0x361f00 ? clickpad |
@@ -1635,6 +1652,11 @@ int elantech_init(struct psmouse *psmouse) | |||
1635 | goto init_fail; | 1652 | goto init_fail; |
1636 | } | 1653 | } |
1637 | 1654 | ||
1655 | if (etd->fw_version == 0x381f17) { | ||
1656 | etd->original_set_rate = psmouse->set_rate; | ||
1657 | psmouse->set_rate = elantech_set_rate_restore_reg_07; | ||
1658 | } | ||
1659 | |||
1638 | if (elantech_set_input_params(psmouse)) { | 1660 | if (elantech_set_input_params(psmouse)) { |
1639 | psmouse_err(psmouse, "failed to query touchpad range.\n"); | 1661 | psmouse_err(psmouse, "failed to query touchpad range.\n"); |
1640 | goto init_fail; | 1662 | goto init_fail; |
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index 6f3afec02f03..f965d1569cc3 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
@@ -142,6 +142,7 @@ struct elantech_data { | |||
142 | struct finger_pos mt[ETP_MAX_FINGERS]; | 142 | struct finger_pos mt[ETP_MAX_FINGERS]; |
143 | unsigned char parity[256]; | 143 | unsigned char parity[256]; |
144 | int (*send_cmd)(struct psmouse *psmouse, unsigned char c, unsigned char *param); | 144 | int (*send_cmd)(struct psmouse *psmouse, unsigned char c, unsigned char *param); |
145 | void (*original_set_rate)(struct psmouse *psmouse, unsigned int rate); | ||
145 | }; | 146 | }; |
146 | 147 | ||
147 | #ifdef CONFIG_MOUSE_PS2_ELANTECH | 148 | #ifdef CONFIG_MOUSE_PS2_ELANTECH |