jackhumbert / pinebook-pro-keyboard-updater

A keyboard/touchpad firmware and updater for the Pinebook Pro
78 stars 11 forks source link

Trackpad inputs are displaced in time #12

Open SolraBizna opened 4 years ago

SolraBizna commented 4 years ago

It seems like trackpad movement reports are 1-3 "frames" behind my actual inputs. For example, if I rapidly swipe my finger right across the trackpad, then very slowly move it left, I get a few more large rightward jumps in cursor position before it starts moving in the correct direction and speed. This makes precise input nearly impossible, especially for someone with wrist and motor issues (like me). If I provide no inputs for an arbitrarily long time in between, the effect still occurs in just the same way.

At least one other person has also experienced this issue, but it seems clear that the vast majority of PBP users aren't experiencing anything like this. (I can't believe that anyone could find this experience usable, and most PBP users clearly regard their trackpads as usable, so... QED.)

I have flashed the new firmware multiple times, and every time it flashed successfully. The problem also existed with the original firmware. I even disconnected the battery to make sure it wasn't some kind of strange latchup condition.

I'm fairly certain that the issue is some kind of trivial queue management bug—maybe a queue that doesn't empty fully, or one whose start/end pointers are going skewumpus some how.

tnyeanderson commented 4 years ago

If I'm not mistaken, the trackpad firmware has not been reverse engineered yet. So the version you get here is the same as upstream.

Correct me if I am not up to date... Is anybody working on the trackpad currently?

SolraBizna commented 4 years ago

As far as I know, you're correct. By "new firmware" I meant "the one included with the first updater", which is the same as the one currently included with this one.

SolraBizna commented 4 years ago

I've been doing a little research on how trackpads communicate with the host system, and I have another hypothesis as to the cause of my problem. The problem is most obvious when my inputs are very slow, or after a very "dramatic" input. I suspect that it's happening because the trackpad immediately stops sending reports if it doesn't detect finger motion, rather than sending a report of zero motion. I believe that the other trackpads I've used send one or more reports of zero motion before going silent. [Edit: libinput debug-events suggests that neither the PBP trackpad nor the other I have access to ever sends a zero-motion report, so scratch that.]

I searched and searched through synclient and the Xorg "synaptics" driver to see if there was anything I could tune to test this and couldn't find anything. I did find that the driver seems to depend on a pretty specific number of reports per second in order to function perfectly, but I don't know if that is useful information.

I'm going to keep doing as much investigation on the host side as I can about this.

tnyeanderson commented 4 years ago

@SolraBizna Thank you for taking the time to investigate! I created a bounty to track progress on reverse engineering the firmware, but it might be a while before it is implemented. Hopefully with the help of people like you, we can start making progress :)

16

akirakyle commented 4 years ago

I've been trying to dig into this and I've found a few things which may be causing the trackpad performance to be less than ideal. The most immediate is that the trackpad reports incorrect dimensions. Running libinput record tells us that udev reports trackpad dimensions of 30mm height and 48mm width which is off by a factor of two. This causes the trackpad resolution to be double what it should be for the ABS_MT_POSITION events. This is easily fixable in by adding the following entry to the evdev hwdb as a local rule (/etc/udev/hwdb.d/99-local.hwdb)

 evdev:input:b0003v258Ap001E*
    EVDEV_ABS_00=::15
    EVDEV_ABS_01=::15
    EVDEV_ABS_35=::15
    EVDEV_ABS_36=::15

This can either be upstreamed to the systemd evdev hwdb or perhaps we can modify the hid usage tables in firmware so it isn't necessary? The relevant hid usage page is here.

It seems this may also solve the palm detection issues people were reporting where the touchpad was not being disabled while typing even with the libinput config Option "DisableWhileTyping" "on" set as libinput seems to hard code disabling palm detection on touchpads <= 55mm high.

However it seems the underlying issue reported here which I also experience is more fundamental. While debugging this issue I noticed that libinput record reported a SYN_REPORT every 8ms always containing at least a MSC_TIMESTAMP with a value of 0 whenever a touch was present. This seemed wrong and indeed the kernel documentation advises that " If the device does not provide this information, the driver must not provide it to user space". I patched the hid_multitouch kernel module to force it to not report these events by commenting out the lines pertaining to the MSC_TIMESTAMP code. Although this shouldn't have really made a difference since libinput ignores this code, it actually made the pointer a little bit better, perhaps because libinput wasn't being spammed with useless reports so latency was reduced a little bit. In any case this led me to believe that the touchpad firmware was also not correctly reporting the hid scan time usage field. Perhaps this is also something that can be fixed in firmware as I doubt this warrants a kernel patch.

In order to completely rule out libinput as the culprit for this pointer time displacement issue I ended up writing this little python script using libevdev:

import libevdev
import sys

fd = open('/dev/input/event4', 'rb')
d = libevdev.Device(fd)

x, sec, usec = 0, 0, 0
while True:
    for e in d.events():
        if not e.matches(libevdev.EV_ABS.ABS_X): continue
        diff = e.value-x
        tdiff = (e.sec - sec)*1000000 + (e.usec - usec)
        print("{:5d}u {:5d}ms".format(diff, tdiff//1000))
        x, sec, usec = e.value, e.sec, e.usec

This is able to quantify the issue reported. When I move my finger to the right then stop for more than a second then move it to the left it shows something like the following:

    4u    15ms
    4u    23ms
    3u    96ms
    3u    88ms
    2u  1767ms
    2u    15ms
    1u    48ms
    1u     7ms
    1u    24ms
    1u    15ms
    1u     7ms
    1u     7ms
   -1u    72ms
   -1u   128ms
   -1u   112ms
   -1u    47ms

This clearly shows the hid multitouch kernel module sending reports that my finger started moving right then left after my 1.7 sec pause when in reality I only moved it left after the long pause. I think this pretty much rules out libinput or any other userspace touchpad library as a culprit (although I think the adaptive profile's nonlinear behavior may magnify the issue (as one can observe with libinput debug-gui).

I doubt that the issue is fundamentally with the kernel's hid_multitouch module as my skimming through the code leads me to believe events are propagated to userspace pretty much immediately when they happen and I would suspect some issue there would affect other touchpads rather than just the pinebook pro's. Unfortunately that just leaves the firmware to blame. Perhaps it is just more incorrect hid usage pages as we've now seen two which are incorrect in the existing firmware and perhaps those are easier to correct than fully reverse engineering the firmware? I'm not knowledgable enough to say but perhaps @jackhumbert has some input here. Otherwise it may be some event queue in firmware which isn't being flushed when it should be as @SolraBizna speculated.

akirakyle commented 4 years ago

I thought I'd post a link to my fork of this repo, specifically the README.org in the firmware/disassembly folder where I've been documenting my progress in trying to understand this issue and more broadly the firmware itself.

Izaic commented 3 years ago

Is this still an issue?

SolraBizna commented 3 years ago

As far as I know, there haven't been any new developments on this front in the last 10 months. @akirakyle 's heroic reverse engineering effort appears to have stalled.

To be completely honest, I've stopped regularly using my PBP because of this problem. Every few months, it comes out of my closet for some brief long-battery-life computing, and I re-experience the joy of actively fighting my trackpad over every precise click. It's a shame; I really like my PBP, except that this one issue makes it unusable for me.

I have heard from friends that other cheap laptops from around the same time period have a trackpad with nearly identical physical specifications and problems. Our assumption is that it's the same buggy trackpad underlying them all.

cobratbq commented 3 years ago

This is still an issue for me. I have not heard of any further efforts to remediate this. The touchpad is certainly functional, but it is very hard to be pixel-perfect, e.g. grabbing windows at the border.

Izaic commented 3 years ago

Hopefully Pine64 remediates this problem, but it doesn't look like a lot of the community is taking it that seriously. I think for quite a few people it's a huge turnoff though.

mpodshivalin commented 3 years ago

You know what's funny? I have a PineTab with a cover and it doesn't have this problem. Surely PineTab cover has an even cheaper touchpad, but it works more or less ok - I don't find myself fighting with every click. So actually if I use only touchpad, PineTab is a better "laptop" than Pinebook. So I hope that Pine64 will take this touchpad issue seriously, especially if this is just a firmware issue