Skip to content

Commit

Permalink
Input: elantech - fix absolute mode setting on some ASUS laptops
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ulrik De Bie authored and Dmitry Torokhov committed Apr 6, 2015
1 parent 58d8a3b commit bd88414
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
22 changes: 22 additions & 0 deletions drivers/input/mouse/elantech.c
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,21 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
return PSMOUSE_FULL_PACKET;
}

/*
* This writes the reg_07 value again to the hardware at the end of every
* set_rate call because the register loses its value. reg_07 allows setting
* absolute mode on v4 hardware
*/
static void elantech_set_rate_restore_reg_07(struct psmouse *psmouse,
unsigned int rate)
{
struct elantech_data *etd = psmouse->private;

etd->original_set_rate(psmouse, rate);
if (elantech_write_reg(psmouse, 0x07, etd->reg_07))
psmouse_err(psmouse, "restoring reg_07 failed\n");
}

/*
* Put the touchpad into absolute mode
*/
Expand Down Expand Up @@ -1094,6 +1109,8 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse,
* Asus K53SV 0x450f01 78, 15, 0c 2 hw buttons
* Asus G46VW 0x460f02 00, 18, 0c 2 hw buttons
* Asus G750JX 0x360f00 00, 16, 0c 2 hw buttons
* Asus TP500LN 0x381f17 10, 14, 0e clickpad
* Asus X750JN 0x381f17 10, 14, 0e clickpad
* Asus UX31 0x361f00 20, 15, 0e clickpad
* Asus UX32VD 0x361f02 00, 15, 0e clickpad
* Avatar AVIU-145A2 0x361f00 ? clickpad
Expand Down Expand Up @@ -1635,6 +1652,11 @@ int elantech_init(struct psmouse *psmouse)
goto init_fail;
}

if (etd->fw_version == 0x381f17) {
etd->original_set_rate = psmouse->set_rate;
psmouse->set_rate = elantech_set_rate_restore_reg_07;
}

if (elantech_set_input_params(psmouse)) {
psmouse_err(psmouse, "failed to query touchpad range.\n");
goto init_fail;
Expand Down
1 change: 1 addition & 0 deletions drivers/input/mouse/elantech.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ struct elantech_data {
struct finger_pos mt[ETP_MAX_FINGERS];
unsigned char parity[256];
int (*send_cmd)(struct psmouse *psmouse, unsigned char c, unsigned char *param);
void (*original_set_rate)(struct psmouse *psmouse, unsigned int rate);
};

#ifdef CONFIG_MOUSE_PS2_ELANTECH
Expand Down

0 comments on commit bd88414

Please sign in to comment.