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:

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:

Create a new file /etc/udev/hwdb.d/90-libinput-x220-fw8.1.hwdb

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.

Verify the tag shows up with sudo udevadm test /sys/class/input/event4 (adjust the event node if necessary)

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.

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: 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.

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.