I2C_HID touchpad issues

What version of Parrot are you running? (Parrot 4.5 x64)

What method did you use to install Parrot? (Debian GTK)

Configured to multiboot with other systems? (yes)

If there are any similar issues or solutions, link to them below:

If there are any error messages or relevant logs, post them below: 

Hello guys. Recetly I tried to fix my touchpad lags with firmware update, but it crushed my whole touchpad. Now movement is inverted, and right click doesn’t work.

My touchpad is ELAN1200 04F3:304E, one of the worst supported touchpad’s ever.

However, I still have a hope.

I know that touchpad is being recognized as I2C-HID device, and if I could upgrade it’s firmware with a programm, it’s possible to read data and write data to toucpad’s chip.

So i’m trying to lookup for i2c devices connected but have no luck with i2cdetect -l.
My lsusb doesn’t show touchpad either:

$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 005: ID 0b05:1869 ASUSTek Computer, Inc. 
Bus 001 Device 004: ID 13d3:5666 IMC Networks 
Bus 001 Device 003: ID 8087:0a2b Intel Corp. 
Bus 001 Device 002: ID 09da:7dc8 A4Tech Co., Ltd. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Though xinput recognizes it:

$ xinput
⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ COMPANY USB Device                      	id=13	[slave  pointer  (2)]
⎜   ↳ COMPANY USB Device Consumer Control     	id=16	[slave  pointer  (2)]
⎜   ↳ ITE Tech. Inc. ITE Device(8910) Consumer Control	id=19	[slave  pointer  (2)]
⎜   ↳ ELAN1200:00 04F3:304E Touchpad          	id=22	[slave  pointer  (2)]
⎣ Virtual core keyboard                   	id=3	[master keyboard (2)]
    ↳ Virtual core XTEST keyboard             	id=5	[slave  keyboard (3)]
    ↳ Power Button                            	id=6	[slave  keyboard (3)]
    ↳ Asus Wireless Radio Control             	id=7	[slave  keyboard (3)]
    ↳ Video Bus                               	id=8	[slave  keyboard (3)]
    ↳ Video Bus                               	id=9	[slave  keyboard (3)]
    ↳ Power Button                            	id=10	[slave  keyboard (3)]
    ↳ Sleep Button                            	id=11	[slave  keyboard (3)]
    ↳ COMPANY USB Device                      	id=12	[slave  keyboard (3)]
    ↳ COMPANY USB Device Keyboard             	id=14	[slave  keyboard (3)]
    ↳ COMPANY USB Device System Control       	id=15	[slave  keyboard (3)]
    ↳ USB2.0 HD UVC WebCam: USB2.0 HD         	id=17	[slave  keyboard (3)]
    ↳ ITE Tech. Inc. ITE Device(8910) Keyboard	id=18	[slave  keyboard (3)]
    ↳ ITE Tech. Inc. ITE Device(8910) Wireless Radio Control	id=20	[slave  keyboard (3)]
    ↳ ITE Tech. Inc. ITE Device(8910) System Control	id=21	[slave  keyboard (3)]
    ↳ Asus WMI hotkeys                        	id=23	[slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard            	id=24	[slave  keyboard (3)]
    ↳ COMPANY USB Device Consumer Control     	id=25	[slave  keyboard (3)]
    ↳ ITE Tech. Inc. ITE Device(8910) Consumer Control	id=26	[slave  keyboard (3)]

What you guys think I can do?

1 Like

Tried Kernel 4.20 ? It should fix it, more or less. Random disconnects seem to persist. But this is just hearsay because I was a tiny little bit involved in patching my own Laptops Touchpad and I remember the Asus lads kept showing up.
https://bugzilla.kernel.org/show_bug.cgi?id=199911#c68

P.S. works for GL703GE but not for GL503VS. Still worth a try, imho. Since I know the woes of AsusTPs, I will never again swear and curse against this malayan Touchpad of mine from a company noone has ever heard of. At least they published a proper documentation.
If all that doesn’t work you will have to debug the TP on Windows eg which I/O pins are used what happens when I press a certain button and compare that to Linux. A mighty hardware hacker once told me: “there are only about 3 people in the world that enjoy hardware debugging, the rest of us cries a little”

Thanks for the info. I think it would be easier to send my laptop to the service center.

I also am having issues with it. Randomly stops responding and sometimes when scrolling it stays stuck in “scrolling” mode. My outputs are the same as yours. I am on a GL503VS . The 4.20 kernel seems to have improved things but still I consider it unreliable. Is there anything I could try to work with?

EDIT: forgot to mention that I read somewhere that pressing Alt+F1 and then Alt+F7 instantly fixes the “unresponsiveness” however I can do this twice on average, then my whole GUI seems to freeze.

1 Like

UPDATE:

ELANTECH send me a patch, where setting correct IRQ flag seems to fix all the problems.
If you are using ParrotOS you can patch it by this diff: https://nest.parrotsec.org/h0tw4t3r/linux/compare/06bac60e4df4eec3ed400e420fa7d27d67287450...36eb22cfe5e5fb49a383e0907f187cc209b56051, or just fork my kernel and compile it.

Though atm I’m working with RedHat specialist’s on this problem, so hopefully we will roll a patch and this issue will be fixed in the future kernel.

Here are reveleant links:
https://bugzilla.redhat.com/show_bug.cgi?id=1543769#c130

1 Like

First of all thanks for your reply!
I am using latest Parrot but have not been with Linux long enough to even pretend I understand how to patch the fix or fork your kernel. The link you provided is from what seems to be a repo but not sure what to do or what to look for as I am not familiar with that. Just now started understanding how github works. I am one of those who is happy to experiment and try things however. Could you assist with a tip or two?

Also, is there a way to take a backup of my whole distro so I can have a safe restore point if something goes wrong? I don’t think trying through a VM would be a good idea for these kinds of things. I will be searching extensively tonight for ways to do this but asking in case you have a proven-to-work way of doing it.

I searched the forum for a couple of issues associated with my laptop model and found none so I was thinking of starting a couple of different threads for the touchpad, key-backlight and Fn button functionality. I am currently doing some research on those and would like to archive it in the forum for the community.

I will be happy to contribute stats and testing if that helps in any way, just tell me if you need anything.

Thanks again for your time @hotwater!

1 Like

Hi. I am also having struggles with my ASUS FX503VD FN keys, keyboard backlight. Though I found some commit’s in 5.0.0 kernel that show’s that this issue was fixed specially for my laptop, but as you have almost the same model (you have a more powerful one), they can share the same keyboard (as I googled the images they look pretty similar, so hopefully hid driver will catch it up).

Though, I spoke to @palinuro and he applied my touchpad patch to the kernel, though I’m still working on it to apply it to kernel mainline.

You can either wait, because new kernel is coming soon, or try to compile kernel.

You need to do next things:

  1. Clone my parrot-kernel fork: git clone git@git.parrotsec.org:h0tw4t3r/linux.git;
  2. Enter cloned repo: cd linux;
  3. Do a git pull as I may do some changes while you are reding this post: git pull;
  4. Make kernel config: make menuconfig, choose <Save> button and save it to .config;
  5. Compile kernel (this can take a while, and can ask passwords): sudo make -j 4 && sudo make modules_install -j 4 && sudo make install -j 4
  6. Update grub: sudo update-grub2

Now you can find a new kernel in your grub list. If something went wrong, simply go to Advanced Options and choose a stable kernel.

But still I recommend you to wait for Parrot 4.6, as this patch will be included.

1 Like

Hi and thanks for that.

So you are to thanks for making the touchpad stabler than the previous version?Thank you!!:smiley:

Sure I could wait but then I wouldn’t have a chance to play around and compile my first kernel!

I will try this tonight and get back to you with my results. If it doesn;t work, then I will simply look elsewhere or wait to be included.

1 Like

So I tried your steps and here is what happened :

I couldn’t use got to clone your repo, it was asking for a pwd.

I manually download the master git, Cs in and ran the steps fro 4. to finish.

It took a long time then hang. I restarted, kernel was untouched so I repeated the steps. It finished faster but would but in a login screen with no GUI. TTY1 it said at the top.

I booted with a stable kernel, again repeated the steps and now I was able to boot. My fn keys do not work still and the touchpad seems to behave pretty much. The back-light is always what I last had in Windows.

Is there a way to check if everything ran properly. I lack knowledge in kernels and how they are shown in grub so I will read on that a bit more.

Are fn shortcuts working for you or just the backlight controls?

Thanks!

Full keyboard support was applied in 5.0.0 kernel which is going to release. I didn’t apply any patches related to this issue.

My patch help’s the touchpad only.

1 Like

I see. Well wait it is for me. When is version 5.0 released anyway? (roughly even)

Well, I can’t say you that precisely, but it will be released after debianizing 5.0.0 kernel.

To keep you guys in touch, what’s happening atm.

Me and i2c_hid team are still working on the solution, at the moment there is a patch for touchpad but there is suspend problem which is still present.

BTW I’ve installed experimental kernel version and every FN+Key combo works, except FN+F6 (Screen off). FN+F5 is not programmed yet.

Hey @hotwater, thanks for the update! ICan I ask if can provide more info or a ref link to the “suspend problem” you mentioned?

Is there a way to build the beta kernel and try it out? I would love to try things out on my machine!

Well, the problem is for some reason touchpad works good when interupt level is set to edge-triggered. I suggested a patch which was setting IRQ level to edge-triggered by adding additional quirk for especially ELAN touchpad.

But it actually influenced a lot of people (you may see many touchpad problems on the forum), and right now guys came with another reveal - it is a problem of GPIO driver callback.

And it was tested by me, by deleting the callback and masking it, touchpad worked good. Right now they are finishing the patch and I will post it here asap.

The suspend problem is - touchpad looses edge-triggered mode and becomes stupid and laggy again, with massive flooding in dmsg about uncomplete report.
After suspend touchpad doesn’t reset’s but powers on. Though after adding additional quirk and forcing touchpad to reset nothing changed.
So atm this problem stays unsolved. But there is a fix, you need to change suspend mode from deep to s2mode. It only fixes touchpad reset, so before applying it you need to patch kernel.

I will keep you in touch.

Commit a939bb57cd47 ("pinctrl: intel: implement gpio_irq_enable") was
added because clearing interrupt status bit is required to avoid
unexpected behavior.

Turns out the unmask callback also needs the fix, which can solve weird
IRQ triggering issues on I2C touchpad ELAN1200.

Signed-off-by: Kai-Heng Feng <[kai.heng.feng@canonical.com](mailto:kai.heng.feng@canonical.com)>
---
v2:
- Clear interrupt status for both mask/umask cases.
- Reduce calculation under irq spinlock.

drivers/pinctrl/intel/pinctrl-intel.c | 37 +++++----------------------
1 file changed, 6 insertions(+), 31 deletions(-)

diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
index 3b1818184207..717148d2818c 100644
--- a/drivers/pinctrl/intel/pinctrl-intel.c
+++ b/drivers/pinctrl/intel/pinctrl-intel.c
@@ -913,35 +913,6 @@ static void intel_gpio_irq_ack(struct irq_data *d)
}
}

-static void intel_gpio_irq_enable(struct irq_data *d)
-{
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
- const struct intel_community *community;
- const struct intel_padgroup *padgrp;
- int pin;
-
- pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp);
- if (pin >= 0) {
- unsigned int gpp, gpp_offset, is_offset;
- unsigned long flags;
- u32 value;
-
- gpp = padgrp->reg_num;
- gpp_offset = padgroup_offset(padgrp, pin);
- is_offset = community->is_offset + gpp * 4;
-
- raw_spin_lock_irqsave(&pctrl->lock, flags);
- /* Clear interrupt status first to avoid unexpected interrupt */
- writel(BIT(gpp_offset), community->regs + is_offset);
-
- value = readl(community->regs + community->ie_offset + gpp * 4);
- value |= BIT(gpp_offset);
- writel(value, community->regs + community->ie_offset + gpp * 4);
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
- }
-}
-
static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
@@ -954,15 +925,20 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
if (pin >= 0) {
unsigned int gpp, gpp_offset;
unsigned long flags;
- void __iomem *reg;
+ void __iomem *reg, *is;
u32 value;

gpp = padgrp->reg_num;
gpp_offset = padgroup_offset(padgrp, pin);

reg = community->regs + community->ie_offset + gpp * 4;
+ is = community->regs + community->is_offset + gpp * 4;

raw_spin_lock_irqsave(&pctrl->lock, flags);
+
+ /* Clear interrupt status first to avoid unexpected interrupt */
+ writel(BIT(gpp_offset), is);
+
value = readl(reg);
if (mask)
value &= ~BIT(gpp_offset);
@@ -1106,7 +1082,6 @@ static irqreturn_t intel_gpio_irq(int irq, void *data)

static struct irq_chip intel_gpio_irqchip = {
.name = "intel-gpio",
- .irq_enable = intel_gpio_irq_enable,
.irq_ack = intel_gpio_irq_ack,
.irq_mask = intel_gpio_irq_mask,
.irq_unmask = intel_gpio_irq_unmask,
--
2.17.1

Wow, thanks so much for all the info! I just did a clean install, that contains kernel v 4.19. 0 parrot28t . That wouldn’t be the beta right? Is there a place where I can compile from and try this for myself?

Also, I have very limited knowledge but admire your efforts and would like to help however I can. How does one become better at this? e,g. logging and testing and applying fixes? I have some C knowledge so not anything looks alien , but that;s about it xD

Notice that this patch is for upstream kernel, that means that you can’t apply it with some automated tool like git.

So you have to clone parrot-kernel repo from the nest nest.parrotsec.org, and apply changes by hands - by looking for a correct row in a file and putting this info.

After that compile and install kernel by the way I described before.

Tools to checkout module work: dmesg, journalctl with using grep i2c_hid. For example:

sudo dmesg | grep i2c_hid

show’s you debug output of that module. Basically journalctl does the same.
Main bugs was that there was a flood of i2c_hid incomplete report messages,
Also if touchpad dies, restart it with next command:

sudo rmmod i2c_hid && sudo modprobe i2c_hid

I’ve also tried to make a patch but it gave nothing. Probably you will figure it out. Here’s example link which I’ve used to create it: https://lore.kernel.org/lkml/20190211070040.4569-1-jbroadus@gmail.com/

Here’s my not-working patch:

From 87d02fd122b76d4b8960bbed2f6ffb1ef00392b4 Mon Sep 17 00:00:00 2001
From: h0tw4t3r <hotwater438@tutanota.com>
Date: Fri, 26 Apr 2019 01:20:53 +0300
Subject: [PATCH] i2c-hid-core.c: ELAN suspend issue possible fix

---
drivers/hid/i2c-hid/i2c-hid-core.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index 4d1f24ee249c..c651e072b8cc 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -51,6 +51,8 @@
#define I2C_HID_QUIRK_NO_RUNTIME_PM BIT(2)
#define I2C_HID_QUIRK_DELAY_AFTER_SLEEP BIT(3)
#define I2C_HID_QUIRK_BOGUS_IRQ BIT(4)
+#define I2C_HID_QUIRK_RESET_AFTER_RESUME BIT(4)
+

/* flags */
#define I2C_HID_STARTED 0
@@ -186,6 +188,8 @@ static const struct i2c_hid_quirks {
I2C_HID_QUIRK_BOGUS_IRQ },
{ USB_VENDOR_ID_SYNAPTICS, I2C_DEVICE_ID_SYNAPTICS_7E7E,
I2C_HID_QUIRK_NO_RUNTIME_PM },
+ { USB_VENDOR_ID_ELAN, HID_ANY_ID,
+ I2C_HID_QUIRK_RESET_AFTER_RESUME },
{ 0, 0 }
};

@@ -1290,12 +1294,17 @@ static int i2c_hid_resume(struct device *dev)

enable_irq(client->irq);

- /* Instead of resetting device, simply powers the device on. This
- * solves "incomplete reports" on Raydium devices 2386:3118 and
- * 2386:4B33 and fixes various SIS touchscreens no longer sending
- * data after a suspend/resume.
- */
- ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
+ if (ihid->quirks & I2C_HID_QUIRK_RESET_AFTER_RESUME) {
+ ret = i2c_hid_hwreset(client);
+ } else {
+ /* Instead of resetting device, simply powers the device on. This
+ * solves "incomplete reports" on Raydium devices 2386:3118 and
+ * 2386:4B33 and fixes various SIS touchscreens no longer sending
+ * data after a suspend/resume.
+ */
+ ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
+ }
+
if (ret)
return ret;

--
2.20.1
1 Like