My progress on supporting modern Trackpads

As everyone knows already, lot of trackpads/touch screens are not working on Haiku. This happens on modern laptops sporting multitouch trackpads.

Don’t work because most of them are wired through i2c-hid. We do support (most) of this protocol, however we have support only for Intel PCH i2c chipsets, and today a specification known as Designware is broadly used.

On top of that, our HID layer is not well suited for neither multi-touch devices neither Windows 8 compatible trackpads, where a set of hid features must be checked.

I have some contributions to Haiku HID driver, I am maybe not an expert but at least, I feel confident on this topic. But I have no idea about i2c, other than is a kind of low lever serial bus.

I decided anyway, to write a designware i2c driver. The main idea was to take the PCH driver as reference, lookup the bus on ACPI and fill a header with all known registers.

As I started to write this “skeleton” I realized registers were 99% equal to PCH ones so I ended writing all de driver just replacing constants names.

Yeah, it sounds dumb, and maybe it is, but my point was (and still is) to do most of boring plumbing so a real expert on this topic only has to fix some lines to get it working.

The driver is already on gerrit, but meanwhile, I have been trying to determine if the driver works o not, and trying to fix it.

What is working?

As I have access to almost all Slimbook laptops, I currently have a pair of them to develop this so:

  • i2c busses are shown on /dev
  • i2c tool scans the bus and find the trackpad where It is expected to be
  • i2c-hid driver finds a hid device, reads the report descriptor and receives events
  • I can send (at least some) feature reports to device

Does the pointer move? Well… here comes the problem. At first, I was convinced the problem was at HID level, not handling properly multiple x-y each positions report.

On one of the laptops I can switch (via feature report) the trackpad to a mouse-like behaviour and I can use the trackpad without problems (I’ve uploaded a video on telegram). Here we lost any multi-touch gesture, but wasn’t a bad idea as a first milestone.

Anyway, I’ve been trying to get multitouch reports working but after some debugging I realized that I get some corrupted data from i2c.

The funny thing is, I fetch report descriptor from the device, which seems to be ok and well parser by our hid driver. The report weights around 700 bytes. However, input events are ok only the first eight bytes, then, data shows some kind of corruption I have not been able to determine how. That’s why It works well on mouse mode, incoming i2c events have this format:

(2b length) (1b ID) (1b buttons) (2b x) (2b y)

Multitouch events have Y data on bytes 8 and 9, and 9 is always bad. Some times with an unexpected 0x01.

I am reading datasheet (there are tons of concepts to understand here) because it looks like some kind of time shift issue. This does not explain why I am able to fetch a 700 byte report but can fetch input reports no longer than 8 bytes. Driver reports sometimes, a timeout waiting for data, but input reports are constantly wrong.

So… this is where we are. I know there are lot of work to do but I am happy and confident because I already have a pointer moving around, with more or less glitches.

Any help is more than welcome :smiley:

25 Likes

The pch_i2c driver uses a very strange setup for waiting for data which I think is race-prone. I made a change where I tried to fix that, but @X512 tested it and said it made things worse on his hardware. I don’t have any of these devices so I haven’t tried to do much further myself. But maybe seeing that patch will give you some ideas about how the problem might really be fixed, or other things to try.

2 Likes

What I see strange in our pch driver, now that I am starting to understand a bit of what I am doing, is timing configuration. It is non-existent, we just enable the bus and expect all timing parameters to be there. All other operating systems compute those values based on datasheet. In fact, Linux does a small change in the proposed timing formula, based on real experience.

In any case… It is true sometimes I boot and timeouts are very frequent, looks like a race condition that left the driver in some out-of-sync condition. But I have data corruption without timeout messages, and report packets have the expected size.

1 Like

Did you noticed if the corruption is random or seems to obey to some logic? Could it be that to represent that a bit X is set, values are altered in some way? I was thinking of a shift by Y, inversion of representation, etc…

I’ve almost catch the bug. Trackpad has two reports (mouse and trackpad). I request a report ID and getting a different one but truncated to the size of the first.

Don’t know If it is me doing a bad request to i2c-hid or I should be able to handle this situations.

Is it supposed to report the two types of events simultaneously at different addresses or, is there a command to activate one mode or the other? Perhaps you miss that command to make report switch to the right mode?

Yeah, it is almost that way.

It looks like we had some bugs following i2c-hid specification. We request reports in a kind of polling loop pattern, but that is not required, nor recommended, the device sends reports at is own rate (it may change on low power).

On the other hand, there are two “devices”, the multi-touch one and a simple mouse emulation mode. When the device performs a reset (expected at driver initialization) the default is the mouse one (as a fallback for old os/bios). The driver may change to multitouch using a feature report documented on i2c hid specs.

So, the device was sending mouse reports an we were asking for multitouch reports, and we ended mixing all of this. Sometimes it worked because mouse reports are smaller than multitouch. The opposite ended with truncated reports.

The good news:

  • on first laptop (Slimbook ProX), i2c driver seems to work ok, problems were finally at i2c-hid layer.
  • Mouse mode saves the day, tbh. Context button has to be done be pressing the trackpad mechanically, but at least it works.
  • Multitouch events are handled by TabletHandler because fingers use absolute coordinate system. We have to think how to properly handle this. Imho, I would create a MultitouchHandler that sends almost raw data to user space. Other OS allow apps to get multitouch events.
  • The other laptop, a Slimbook Evo (brand new) doesn’t work yet. I can switch from mouse mode to multitouch, but in both cases I always get the same report. but it is not freeze because I get frequent interruptions but the content is always the same. The content report is valid, not garbagge, but always stuck at same coordinates.

And… thats all :smiley:

12 Likes

I would love to test this, where can I get the driver?
I’m on Haiku nightly anyway so I like living on the bleeding edge:)

Strange thing is I have an Intel PCH/i2c-hid chipset and it still doesn’t work.
Will your driver help here?

My touchpad is a

acpi/cid PNP0C50
acpi/handle 18446744071618438656
acpi/hid STAR0001
Device name I2C device
Device paths unknown
device/bus i2c
device/driver bus_managers/i2c/device/driver_v1
device/flags 2
device/pretty name I2C device
Driver used unknown
i2c/slave_addr 44
Manufacturer unknown

PNP0C50 is listed as a “compatible with” device for my “TPD1019” touchpad, at least according to what Win10’s device manager info has to say about it. Not working either. (just to point out that your actual device might be something more specific than the “generic” PNP0C50 Edit: just noticed the “STAR0001”, I need a coffee :smiley: ).

1 Like

Yeah it’s a StarLabs StarBook V with Intel Core 11gen and Intel Xe graphics.
Love that machine, it’s still alive and kicking, but the touchpad doesn’t even work reliably in Linux anymore:(

i2c-hid driver is not on nightly images, I guess it was considered too immature. I’ve modified a bit to get all of this working.

Let me clean up a bit and I will upload it as soon as possible. I’ll be glad to have more testers :smiley:

Anyway, you can build current i2c-hid driver and see what happens.

PNP0C50 is the common ACPI CID all “compliant” (ha!) trackpads share. Under that CID, you can find Elan, Uniwill, …

3 Likes

Please activate it in one of your patches if you have it working :slight_smile:

2 Likes

I certainly will let you know if mine works.
Nice work you are doing. Thank you!

Regards,
RR

Today I have another laptop from Slimbook to test. The designware driver works, the modified i2c-hid works, and in general it works great with a minor detail, the trackpad refuses to work on mouse emulation mode. I’ve been dealing with this trackpad on Linux (my real paid job :D) and it is prone to don’t honour feature reports.

Working in multitouch mode is uncomfortable because our hid driver takes it like a digitizer or touch panel. We would have translate absolute finger positions to relative. But that’s another battle I don’t want to take now.

So, I have a working model in both multitouch and mouse-like mode, a working model in multitouch mode, and a model which I can switch between two modes but I only get one single report, following reports have the same data and to be honest, I don’t know what to do.

With this, I think I am going to clean up all I got right now and push one or two patches to gerrit. I would take a couple of days or so.

Once we got all of this merged we can discuss what to do with multi-touch devices.

12 Likes

IC2 it is a modern serial in inner new embedded devices, it not open source, because many
new electronic programmer use them. I think it’s many time spand to release them (IC2).

Happy to help test if useful? Got an HP that has a multi-input touch screen and a track pad that’s always worked, but curiously requires tapping on the far left to do a right click!