Skip to contentSkip to conversation

Elantech touchpad does not work on Asus

PATCH In review [email protected] 2 participants 8 messages Mar 19, 2015 – Apr 6, 2015

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

Hi all,

I looked at the bugzilla bugreport on
https://bugzilla.kernel.org/show_bug.cgi?id=84491
"Elantech touchpad does not work on Asus TransformerBook Flip 500"

There are problems reported on two variants:
Asus TransformerBook Flip TP500LN
Asus TP500LN

George (in CC:) helped me to investigate on his hardware what happened by trying a few patches and reporting what happens.

It seems that the absolute mode setting somehow gets cancelled after the elantech drivers initializes. This results in relative motion packets coming in, elantech driver not recognizing them and consequentially "lost sync at byte 6" messages.

When one, after the psmouse driver is loaded, does the following:
echo 1 > /sys/devices/platform/i8042/serio4/reg_07
,the touchpad will work like a charm until suspend2ram. After a suspend2ram, another echo is required.

This exact same value is written during initialization of v4 hardware. As a test, I even read it back in elantech_set_absolute_mode after writing and at that moment in the driver the value 1 is read.

But when one performs the read later on the commandline of reg_07, value 0 is read, so probably for a reason unknown to me, the value goes to 0 because of some timeout or serio communiation.

I also tried putting elantech_set_input_params call in front of elantech_set_absolute_mode, but that didn't help either.

Also the suspend2ram seems to result in the same thing.

Anyone an idea why this reg_07 1 value could become a 0 between the time the function elantech_set_absolute_mode during loading of the psmouse module and the time when reading the value from sysfs from the command line ?

Kind regards,
Thanks,
Ulrik

maintainer
#1 lore raw

Hi Ulrik,

Quoted 34 lines · On Thu, Mar 19, 2015 at 11:05:46PM +0100, [email protected] wrote:

Hi all,

I looked at the bugzilla bugreport on
https://bugzilla.kernel.org/show_bug.cgi?id=84491
"Elantech touchpad does not work on Asus TransformerBook Flip 500"

There are problems reported on two variants:
Asus TransformerBook Flip TP500LN
Asus TP500LN

George (in CC:) helped me to investigate on his hardware what happened by trying a few patches and reporting what happens.

It seems that the absolute mode setting somehow gets cancelled after the elantech drivers initializes. This results in relative motion packets coming in, elantech driver not recognizing them and consequentially "lost sync at byte 6" messages.

When one, after the psmouse driver is loaded, does the following:
echo 1 > /sys/devices/platform/i8042/serio4/reg_07
,the touchpad will work like a charm until suspend2ram. After a suspend2ram, another echo is required.

This exact same value is written during initialization of v4 hardware. As a test, I even read it back in elantech_set_absolute_mode after writing and at that moment in the driver the value 1 is read.

But when one performs the read later on the commandline of reg_07, value 0 is read, so probably for a reason unknown to me, the value goes to 0 because of some timeout or serio communiation.

I also tried putting elantech_set_input_params call in front of elantech_set_absolute_mode, but that didn't help either.

Quoted 6 lines

Also the suspend2ram seems to result in the same thing.

Anyone an idea why this reg_07 1 value could become a 0 between the time the function elantech_set_absolute_mode during loading of the psmouse module and the time when reading the value from sysfs from the command line ?

Hmm, so after Elantech code has done with the init you see the correct value in r7? Psmouse driver does [re]set scale, rate and resolution after protocol has been initialized, maybe that confuses Elantech in the same fashion as it does Focaltech?

Thanks.

Signature · 1 line
Dmitry
#2 lore raw

Hi Dmitry,

Quoted 44 lines · Dmitry Torokhov

Hi Ulrik,

Quoted 34 lines · On Thu, Mar 19, 2015 at 11:05:46PM +0100, [email protected] wrote:

Hi all,

I looked at the bugzilla bugreport on
https://bugzilla.kernel.org/show_bug.cgi?id=84491
"Elantech touchpad does not work on Asus TransformerBook Flip 500"

There are problems reported on two variants:
Asus TransformerBook Flip TP500LN
Asus TP500LN

George (in CC:) helped me to investigate on his hardware what happened by trying a few patches and reporting what happens.

It seems that the absolute mode setting somehow gets cancelled after the elantech drivers initializes. This results in relative motion packets coming in, elantech driver not recognizing them and consequentially "lost sync at byte 6" messages.

When one, after the psmouse driver is loaded, does the following:
echo 1 > /sys/devices/platform/i8042/serio4/reg_07
,the touchpad will work like a charm until suspend2ram. After a suspend2ram, another echo is required.

This exact same value is written during initialization of v4 hardware. As a test, I even read it back in elantech_set_absolute_mode after writing and at that moment in the driver the value 1 is read.

But when one performs the read later on the commandline of reg_07, value 0 is read, so probably for a reason unknown to me, the value goes to 0 because of some timeout or serio communiation.

I also tried putting elantech_set_input_params call in front of elantech_set_absolute_mode, but that didn't help either.

Quoted 6 lines

Also the suspend2ram seems to result in the same thing.

Anyone an idea why this reg_07 1 value could become a 0 between the time the function elantech_set_absolute_mode during loading of the psmouse module and the time when reading the value from sysfs from the command line ?

Quoted 4 lines

Hmm, so after Elantech code has done with the init you see the correct value in r7? Psmouse driver does [re]set scale, rate and resolution after protocol has been initialized, maybe that confuses Elantech in the same fashion as it does Focaltech?

Indeed, this time it is specifically the set_rate that resets the value of reg_07 to 0, resulting in the disabling of the absolute mode.

I made a patch on kernel v3.16 that solves the problem and will send it out in like an hour after a final check if it also compiles on kernel v3.19. (The person that tested it is on v3.16 kernel).

Quoted 5 lines

Thanks.

Signature · 1 line
Dmitry

Thanks for once again your valuable input,
Ulrik

#3 lore raw

cover Input: elantech - fix absolute mode setting on some Asus touchpads cover

Just one patch here ...
Patch 1 fixes problems on some Asus touchpads where set_rate sets the register reg_07 to 0, which disables the absolute mode setting and makes the touchpad unusable. This was seen in 3 different scenario's:
1) At startup or module load, the touchpad did not work. Value of reg_07 becomes 0.
2) When writing the content of the sysfs touchpad rate file again to the same file (or any different value most probably), the touchpad does not work anymore.The value of reg_07 in the hardware becomes 0.
3) When returning from suspend to sleep, the touchpad dos not work anymore. The value of reg_07 in the hardware becomes 0.

When writing again a 1 to the sysfs reg_07 file, the touchpad works (again).

Ulrik De Bie (1):
Input: elantech - fix absolute mode setting on some Asus touchpads

 drivers/input/mouse/elantech.c | 22 ++++++++++++++++++++++
 drivers/input/mouse/elantech.h |  1 +
 2 files changed, 23 insertions(+)
Signature · 1 line
2.1.4
#4 lore raw

PATCH 1/1 Input: elantech - fix absolute mode setting on some Asus touchpads

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 perfoms 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

---
 drivers/input/mouse/elantech.c | 22 ++++++++++++++++++++++
 drivers/input/mouse/elantech.h |  1 +
 2 files changed, 23 insertions(+)
drivers/input/mouse/elantech.c +22 -0
index 6e22682..991dc6b 100644
@@ -893,6 +893,21 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
 }
 
 /*
+ * 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
  */
 static int elantech_set_absolute_mode(struct psmouse *psmouse)
@@ -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
@@ -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;
drivers/input/mouse/elantech.h +1 -0
index 6f3afec..f965d15 100644
@@ -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
Signature · 1 line
2.1.4
maintainer
#5 lore raw

Re: [PATCH v1 1/1] Input: elantech - fix absolute mode setting on some Asus touchpads

Hi Ulrik,

Quoted 29 lines · Ulrik De Bie

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 perfoms 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

---
 drivers/input/mouse/elantech.c | 22 ++++++++++++++++++++++
 drivers/input/mouse/elantech.h |  1 +
 2 files changed, 23 insertions(+)
drivers/input/mouse/elantech.c +2 -0
index 6e22682..991dc6b 100644
@@ -893,6 +893,21 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
 }
 
 /*
+ * 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

drivers/input/mouse/elantech.c static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) · line 907

Quoted 10 lines
drivers/input/mouse/elantech.c +10 -0
+ * 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");

I wonder if set rate is useful for Elantech and if it would not be simpler to just have an empty stub for set_rate, maybe even for all Elantech devices?

Thanks.

Signature · 1 line
Dmitry
#6 lore raw

Re: [PATCH v1 1/1] Input: elantech - fix absolute mode setting on some Asus touchpads

Quoted 38 lines · Dmitry Torokhov

Hi Ulrik,

Quoted 35 lines · Ulrik De Bie

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 perfoms 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

---
 drivers/input/mouse/elantech.c | 22 ++++++++++++++++++++++
 drivers/input/mouse/elantech.h |  1 +
 2 files changed, 23 insertions(+)
drivers/input/mouse/elantech.c +8 -0
index 6e22682..991dc6b 100644
@@ -893,6 +893,21 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
 }
 
 /*
+ * 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;
Quoted 8 lines

drivers/input/mouse/elantech.c static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) · line 907

Quoted 4 lines
drivers/input/mouse/elantech.c +4 -0
+
+	etd->original_set_rate(psmouse, rate);
+	if (elantech_write_reg(psmouse, 0x07, etd->reg_07))
+		psmouse_err(psmouse, "restoring reg_07 failed\n");

I wonder if set rate is useful for Elantech and if it would not be simpler to just have an empty stub for set_rate, maybe even for all Elantech devices?

1) all Elantech devices ?
I've considered it for all elantech devices, but I've no idea how this might effect all elantech devices out there.
I did a simple test on my work laptop with elantech. Setting the rate to a value lower than 10 does disable the mouse, setting it to a value higher than 10 enables it again. I would not describe that as 'useful' but not performing a set_rate 100 could give issues on touchpads that do work now. => I think best not all elantech devices because of backwards compatibility issues

2) selectivity of Elantech device
In this patch I used the firmware version, which will probably match with all (and no more than the ) elantech chips out there that have this issue. I could go for dmi table code, but then we will probably have to extend this for a couple of years with more and more rows in the table.
=> preference for firmare version above dmi

3) empty stub instead of set_rate+fixup
Could work, but needs verification because currently set_rate is called with 100 and I don't know what the default is. Of course, ideally the sysfs would then report back that the rate reading/writing is not supported, or the rate sysfs file would not exist at all.
=> small preference for actually performing the set_rate

Kind regards,
Ulrik

maintainer
#7 lore raw

Re: [PATCH v1 1/1] Input: elantech - fix absolute mode setting on some Asus touchpads

Quoted 65 lines · On Thu, Mar 26, 2015 at 06:37:06PM +0100, [email protected] wrote:
Quoted 38 lines · Dmitry Torokhov

Hi Ulrik,

Quoted 35 lines · Ulrik De Bie

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 perfoms 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

---
 drivers/input/mouse/elantech.c | 22 ++++++++++++++++++++++
 drivers/input/mouse/elantech.h |  1 +
 2 files changed, 23 insertions(+)
drivers/input/mouse/elantech.c +8 -0
index 6e22682..991dc6b 100644
@@ -893,6 +893,21 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
 }
 
 /*
+ * 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;
Quoted 8 lines

drivers/input/mouse/elantech.c static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) · line 907

Quoted 4 lines
drivers/input/mouse/elantech.c +4 -0
+
+	etd->original_set_rate(psmouse, rate);
+	if (elantech_write_reg(psmouse, 0x07, etd->reg_07))
+		psmouse_err(psmouse, "restoring reg_07 failed\n");

I wonder if set rate is useful for Elantech and if it would not be simpler to just have an empty stub for set_rate, maybe even for all Elantech devices?

1) all Elantech devices ?
I've considered it for all elantech devices, but I've no idea how this might effect all elantech devices out there.
I did a simple test on my work laptop with elantech. Setting the rate to a value lower than 10 does disable the mouse, setting it to a value higher than 10 enables it again. I would not describe that as 'useful' but not performing a set_rate 100 could give issues on touchpads that do work now. => I think best not all elantech devices because of backwards compatibility issues

2) selectivity of Elantech device
In this patch I used the firmware version, which will probably match with all (and no more than the ) elantech chips out there that have this issue. I could go for dmi table code, but then we will probably have to extend this for a couple of years with more and more rows in the table.
=> preference for firmare version above dmi

Quoted 6 lines

3) empty stub instead of set_rate+fixup
Could work, but needs verification because currently set_rate is called with 100 and I don't know what the default is. Of course, ideally the sysfs would then report back that the rate reading/writing is not supported, or the rate sysfs file would not exist at all.
=> small preference for actually performing the set_rate

OK, fair enough, applied, thank you.

Signature · 1 line
Dmitry