Wednesday, December 16, 2015

libinput and the Lenovo x220 touchpad - after a firmware update to version 8.1

This post only applies to users of the Lenovo x220 laptop experiencing issues when using the touchpad. Specifically, the touchpad is imprecise and "jumpy" after a firmware update, as outlined in Fedora bug 1264453. The cause is buggy touchpad firmware, identifiable by the string "fw: 8.1" in the dmesg output for the touchpad:

[  +0.005261] psmouse serio1: synaptics: Touchpad model: 1, fw: 8.1, 
id: 0x1e2b1, caps: 0xd002a3/0x940300/0x123800, board id: 1611, fw id: 1099905
If you are experiencing these touchpad issues and your dmesg shows the 8.1 firmware version, please read on for a solution. By default, the x220 shipped with version 8.0 so unless you updated the firmware as part of a Lenovo update, you are not affected by this bug.

The touchpad issues seem identical as the ones seen on the Lenovo x230 model which has the same physical hardware and also ships with a firmware version 8.1. The root cause as seen by libinput is that the touchpad only sends events once the finger moves approximately 50 device units in either direction. The touchpad advertises a resolution of 65 units/mm horizontally and 136 units/mm vertically, but the effective resolution is reduced by roughly 75% and 30% This bugzilla attachment 1082925 shows the recording, you can easily see that while the pressure is upgraded with high granularity, the motion coordinates jump from one position to the next. From what we know this was introduced by the touchpad firmware v8.1, presumably as part of a filter to reduce the jitter some x230 users saw.

libinput automatically detects the x230 and enables a custom acceleration function for just that model. That same acceleration function works for the x220 v8.1, but unfortunately we cannot automatically detect it. As of libinput 1.1.3, libinput recognises a special udev tag, LIBINPUT_MODEL_LENOVO_X220_TOUCHPAD_FW81, to mark such an updated x220 and enable a better pointer behaviour. To apply this tag, please do the following:

  1. Create a new file /etc/udev/hwdb.d/90-libinput-x220-fw8.1.hwdb
  2. Look for X220 in the 90-libinput-model-quirks.hwdb file, copy the match and the property assignment into the file. As of the time of writing, the two lines are as below, but make sure you take the latest from your locally installed libinput version or the link above.
    libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPadX220*
     LIBINPUT_MODEL_LENOVO_X220_TOUCHPAD_FW81=1
    
  3. Update the udev hwdb with sudo udevadm hwdb --update
  4. Verify the tag shows up with sudo udevadm test /sys/class/input/event4 (adjust the event node if necessary)
  5. Reboot
The touchpad is now marked as requiring special treatment and libinput will apply a different pointer acceleration for this touchpad.

Note that any udev property starting with LIBINPUT_MODEL_ is private API and subject to change at any time. We will never break the meaning of the LIBINPUT_MODEL_LENOVO_X220_TOUCHPAD_FW81 property, but the exact behaviour of the property is implementation-dependent and may change at any time. Do not use it for any other purpose than marking the touchpad on a Lenovo x220 with an updated touchpad firmware version v8.1.

6 comments:

Josh Triplett said...

Given that the kernel knows the firmware version, could the kernel expose that version to userspace such that hwdb could use it for a quirk?

Peter Hutterer said...

Josh: some touchpad drivers do this in the evdev version field, but the synaptics one doesn't. Right now the information is only available in a printk and is then discarded by the kernel. Having this information would be useful, but for this bug the ship's sailed (and it's a very niche case with hardware older than 3 years). If you can expose that information, I'm sure it'll come in handy. See this line for an example on other touchpads where we use the firmware version to set some properties:
http://cgit.freedesktop.org/wayland/libinput/tree/udev/90-libinput-model-quirks.hwdb#n25

Calvin Walton said...

Huh, I've been seeing the same problem on a different laptop, and was wondering what's up. I'll give this quirk a try.

I'm using a ThinkPad T440p with an aftermarket (eBay) touchpad similar to a Tx50-series model. It's also showing the same firmware version "8.1":

[ 2.829201] localhost kernel: psmouse serio1: synaptics: Touchpad model: 1, fw: 8.1, id: 0x1e2b1, caps: 0xf003a3/0x943300/0x12e800/0x10000, board id: 3053, fw id: 2560

I don't expect this combination makes sense to autodetect, but it's good to know that there's a quirk I can try.

Peter Hutterer said...

Calvin: this is a different problem I think. I have a T440s with v8.1 as well and it works fine, it's a different physical touchpad. I think only the x220/x230 hardware was affected by this, so it's better if you file a separate bug for this.

Clinton said...

Hi I found this blog post when searching for solutions to my jumpy touchpad on my Lenovo X220 laptop. My cursor is still jumpy when trying to make precision movements especially when moving slowly. I have tried following these steps in both Ubuntu 15.10 and Manjaro 15.12, both 64 bit.
I will walk through what exactly I did so maybe you can point out something wrong I am doing.

1) First I ran dmesg to confirm my trackpad has the "fw: 8.1".

2) Then I opened a terminal and entered "sudo touch /etc/udev/hwdb.d/90-libinput-x220-fw8.1.hwdb" to create the new 90-libinput-x220-fw8.1.hwdb file.

3) I opened the /lib/udev/hwdb.d/90-libinput-model-quirks.hwdb file and copied the lines "libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPadX220*
LIBINPUT_MODEL_LENOVO_X220_TOUCHPAD_FW81=1"

4) I then did "sudo nano /etc/udev/hwdb.d/90-libinput-x220-fw8.1.hwdb" to open the new file created on step 2 and pasted in the lines from step 3 then used ctrl x to exit nano (I saved the file on exit).

5) "sudo udevadm hwdb --update"

6) "sudo udevadm test /sys/class/input/event14"

7) Verified the line LIBINPUT_MODEL_LENOVO_X220_TOUCHPAD_FW81=1 is there after doing step 6.

8) Rebooted and now still seem to have same poor touchpad performance.

I did notice there is also LIBINPUT_MODEL_SYNAPTICS_SERIAL_TOUCHPAD=1 below LIBINPUT_MODEL_LENOVO_X220_TOUCHPAD_FW81=1 after doing step 6.

Any help you may be able to provide would be greatly appreciated.

Warren said...

also can't get this fix working.

there are no X220 entries in my /lib/udev/hwdb.d/90-libinput-model-quirks.hwdb

I added the ones here and they show up but its still jumpy with pause just after I click.

Using F23