Page MenuHomeFreeBSD

First draft HID over I2C support (Mouse only)
Needs ReviewPublic

Authored by marc.priggemeyer_gmail.com on Aug 12 2018, 10:51 PM.

Details

Reviewers
KOT_MATPOCKuH.Ru
Summary

Support for Human Interface Devices over I2C.

There are a couple of points to keep in mind:

Important notes:

  1. Currently iichid only supports mouse devices and therefore creates /dev/ims*.
  2. I use moused with settings in rc.conf like this: moused_port="/dev/ims0"
  3. I tried a few approaches to identify and attach an iichid device by querying ACPI directly from the iichid module. That failed on two details: parent association (in general HID over I2C devices appear below ACPI0 in NewBus but it is necessary to have them below the iicbus*/iic* nodes, moving these node in NewBus failed for me with a panic) and also interrupt handling (apparently, interrupts must be handled by the nodes the IRQs are assigned to (i.e. the node below ACPI0). Trying to attach to an IRQ from another node (i.e. a node below iicbus*/i2c*) fails)
  4. acpi_iichid creates a iichid node below the identifiable iicbus
  5. acpi_iichid enques a task either on interrupt or timeout and delegates retrieval of reports to iichid by callback
  6. iichid_load="YES" and acpi_iichid_load="YES" in loader.conf should work now without crash.

Stalled:

  1. Please refer to the changes I made to usbhid.h and usbhid.c, since I moved the generic hid functionality out of those files into two new ones. The long term aim would be to create a HID abstraction layer (called HID Caps) that will provide a general interface to HID capabilities and functions through the device tree. It will help to make it easier to use Human Interface Devices on different busses without the need of pulling USB into the kernel configuration. This is work in progress and, for now, independent of the I2C over HID support.
Test Plan

Load acpi_iichid and make sure to have an I2C controller driver (e.g. ig4) loaded beforehand. acpi_iichid should require iicbus and iichid as dependencies.

After loading you should see something like this (That is the output on my Dell Latitude 5480):
iichid_acpi0: <HID over I2C (ACPI)> irq 51 on acpi0
iichid_acpi0: descriptor register address is 20
iichid_acpi0: parent device is "\134_SB_.PCI0.I2C1"
iichid0: <HID over I2C> at addr 0x2c on iicbus1
iichid0: ADDR 0x2c REG 0x20
iichid0: 3 buttons and [XYZT] coordinates ID=1
iichid0: 3 buttons and [XYZT] coordinates ID=1
iichid0: determined (len=81) and described (len=83) input report lengths mismatch
iichid_acpi0: added iichid0 ADDR 0x2c REG 0x20 to iicbus1
iichid_acpi0: allocated irq at 0xfffff80004a46600 and rid 0
iichid_acpi0: successfully setup interrupt

vmstat -i should show statistics on interrupt handling.

Since interrupt resource acquisition is not always possible (in case of GPIO interrupts) acpi_iichid now supports a sampling_mode.
Set dev.acpi_iichid.#.sampling_rate to a value greater then 0 to activate sampling. A value of 0 is possible but will not reset the callout and, thereby, disable further report requests.
Do not set the sampling_rate value too high as it may result in periodical lags of cursor motion

  • e.g. 100 is the achievable rate in interrupt mode on my laptop, but is too high in sampling mode
  • rates between 30 and 60 samples per second appear to be a good tradeoff on my system.
  • 20 is too low on my machine

Another minor addition is a sysctl to invert the mouse wheel direction. Set dev.iichid.#.invert_scroll to test.

Diff Detail

Repository
rS FreeBSD src repository
Lint
Lint Skipped
Unit
Unit Tests Skipped

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

driver bug: Unable to set devclass (class: ppc devname: (unknown))
driver bug: Unable to set devclass (class: ppc devname: (unknown))
ig4iic_acpi0: <Designware I2C Controller> iomem 0xe1122000-0xe1122fff irq 7 on acpi0
ig4iic_acpi0: controller error during attach-1
driver bug: Unable to set devclass (class: ppc devname: (unknown))
ig4iic_acpi1: <Designware I2C Controller> iomem 0xe1124000-0xe1124fff irq 7 on acpi0
ig4iic_acpi1: controller error during attach-1
iicbus0: <Philips I2C bus> on ig4iic_acpi0
iic0: <I2C generic I/O> on iicbus0
iicbus1: <Philips I2C bus> on ig4iic_acpi1
iic1: <I2C generic I/O> on iicbus1
driver bug: Unable to set devclass (class: ppc devname: (unknown))
wlan0: Ethernet address: 6c:29:95:4e:a3:68

Looks like acpi_iichid isn't attaching to anything acpi..hmmmm.

Id Refs Address Size Name
1 107 0xffffffff80200000 24528e0 kernel
2 1 0xffffffff82653000 940c8 linux64.ko
3 5 0xffffffff826e8000 8a10 linux_common.ko
4 1 0xffffffff826f1000 2be8 coretemp.ko
5 1 0xffffffff826f4000 1011a8 iwm7260fw.ko
6 1 0xffffffff827f6000 a6780 linux.ko
7 1 0xffffffff8289d000 10be0 tmpfs.ko
8 1 0xffffffff828ae000 3a86f0 zfs.ko
9 2 0xffffffff82c57000 a4f0 opensolaris.ko
10 1 0xffffffff82c63000 166f8 fuse.ko
11 1 0xffffffff82c7a000 2a138 if_iwm.ko
12 1 0xffffffff835fa000 19e0 fdescfs.ko
13 1 0xffffffff835fc000 490c linprocfs.ko
14 1 0xffffffff83601000 194c linsysfs.ko
15 1 0xffffffff83603000 120040 i915kms.ko
16 1 0xffffffff83724000 74810 drm.ko
17 4 0xffffffff83799000 104b0 linuxkpi.ko
18 3 0xffffffff837aa000 11300 linuxkpi_gplv2.ko
19 2 0xffffffff837bc000 6c0 debugfs.ko
20 1 0xffffffff837bd000 f98 iic.ko
21 5 0xffffffff837be000 2020 iicbus.ko
22 1 0xffffffff837c1000 35e8 ig4.ko
25 1 0xffffffff837c9000 3aa0 ng_ubt.ko
26 5 0xffffffff837cd000 a020 netgraph.ko
27 1 0xffffffff837d8000 9608 ng_hci.ko
28 3 0xffffffff837e2000 9c0 ng_bluetooth.ko
29 1 0xffffffff837e3000 cd40 ng_l2cap.ko
30 1 0xffffffff837f0000 1b9c0 ng_btsocket.ko
31 1 0xffffffff8380c000 2190 ng_socket.ko
32 1 0xffffffff8380f000 acf mac_ntpd.ko
33 1 0xffffffff83810000 2120 acpi_wmi.ko
34 1 0xffffffff83813000 2b98 acpi_video.ko
35 1 0xffffffff837c5000 1470 acpi_iichid.ko
36 1 0xffffffff837c7000 1d30 iichid.ko

Let's see what a debug boot shows...this box is strange and running an odd coreboot.

Table 'FACP' at 0x78f10960
FACP: Found table at 0x78f10960
ppc: ppc-1 already exists; skipping it
driver bug: Unable to set devclass (class: ppc devname: (unknown))
Table 'FACP' at 0x78f10960
FACP: Found table at 0x78f10960
Table 'FACP' at 0x78f10960
FACP: Found table at 0x78f10960
Table 'FACP' at 0x78f10960
FACP: Found table at 0x78f10960
Table 'FACP' at 0x78f10960
FACP: Found table at 0x78f10960
Table 'FACP' at 0x78f10960
FACP: Found table at 0x78f10960
Table 'FACP' at 0x78f10960
FACP: Found table at 0x78f10960
Table 'FACP' at 0x78f10960
FACP: Found table at 0x78f10960
Table 'FACP' at 0x78f10960
FACP: Found table at 0x78f10960
Table 'FACP' at 0x78f10960
FACP: Found table at 0x78f10960
Table 'FACP' at 0x78f10960
FACP: Found table at 0x78f10960
Table 'FACP' at 0x78f10960
FACP: Found table at 0x78f10960

Hmmm. Does my ACPI table not _know_ there should be an i2c mouse?

KOT_MATPOCKuH.Ru accepted this revision.Oct 10 2018, 8:34 PM
KOT_MATPOCKuH.Ru added a subscriber: KOT_MATPOCKuH.Ru.

I'm applied this patch to my FreeBSD 12 r338342 box on Dell Latitude 5290 and applied this configuration to rc.conf:
kld_list="/boot/modules/i915kms.ko /boot/modules/iichid.ko /boot/modules/acpi_iichid.ko"
moused_port="/dev/ims0"

Also I changed device for mouse driver in xorg.conf:
Option "Device" "/dev/ims0"

I'm got this messages in /var/run/dmesg.boot:
iichid_acpi0: <HID over I2C (ACPI)> irq 51 on acpi0
iichid_acpi0: descriptor register address is 20
iichid_acpi0: parent device is "\134_SB_.PCI0.I2C1"
iichid0: <HID over I2C> at addr 0x2c on iicbus1
iichid0: ADDR 0x2c REG 0x20
iichid0: 3 buttons and [XYZT] coordinates ID=1
iichid0: 3 buttons and [XYZT] coordinates ID=1
iichid0: determined (len=28) and described (len=30) input report lengths mismatch
iichid_acpi0: added iichid0 ADDR 0x2c REG 0x20 to iicbus1
iichid_acpi0: allocated irq at 0xfffff8001ee9d300 and rid 0
iichid_acpi0: successfully setup interrupt

And got working touchpad in console and X.

Some problems:

  1. Without started moused X.org hangs on start
  2. Kernel panic occurs after enabling to load this modules on boot time from loader.conf
This revision is now accepted and ready to land.Oct 10 2018, 8:34 PM

Hmmm. Does my ACPI table not _know_ there should be an i2c mouse?

ig4 does not attach on your system, even though the iicbus and iic devices are created (which is weird imo). So you could try enumerating devices on iic0 or iic1, but I believe you won't have any successful communication on the I2C bus. You could try the following tool (don't remember where it's from, not mine though). Compile and run with full path of iic# device as first argument (enumerates devices on an I2C bus):

#include <sys/cdefs.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <unistd.h>
#include <dev/iicbus/iic.h>

int main(int argc, char** argv)
{
	int i ,fd;

	if (argc < 2)
	{
		perror("usage: ./a.out device");
		return -1;
	}

	const char* dev = argv[1];
	uint8_t buf[2] = {0, 0};
	struct iic_msg msg[2];
	struct iic_rdwr_data rdwr;

	msg[0].flags = !IIC_M_RD;
	msg[0].len = sizeof(buf);
	msg[0].buf = buf;

	msg[1].flags = IIC_M_RD;
	msg[1].len = sizeof(buf);
	msg[1].buf = buf;

	rdwr.nmsgs = 2;

	if( (fd = open(dev, O_RDWR)) < 0 ) {
		perror("open");
		exit(-1);
	}

	setbuf(stdout, 0);
	for(i=1; i<128; i++) {
		msg[0].slave = i;
		msg[1].slave = i;
		rdwr.msgs = msg;

		if( ioctl(fd, I2CRDWR, &rdwr) >= 0 )
			printf(" 0x%02x ", i);
		else
			printf(".");
	}
	printf("\n");
	close(fd);
	exit(0);
}

Besides that, I think you really will have to fix your ig4 problem first (https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=221777). By the way, the ACPI information you provided there suggests that the HID device is a trackpad. That is not supported yet, since iichid only searches for mouse information in the descriptor.

Besides that, I think you really will have to fix your ig4 problem first (https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=221777). By the way, the ACPI information you provided there suggests that the HID device is a trackpad. That is not supported yet, since iichid only searches for mouse information in the descriptor.

Considering the firmware is slightly-custom, that might just be a human-readable reference. I am not entirely sure.

I just uploaded a new diff that lacks the changes to usb. iichid for now depends on usb but should be easier to test.

This revision now requires review to proceed.Oct 12 2018, 8:02 PM

I got some open questions that someone actually reviewing this code or just stumbling by might be able to answer:

  1. is PI_TTY the preferred thread priority, or should it be something else?
  2. I read locking(9), mutex(9), bus_setup_intr(9) and a paper on locking mechanisms in FreeBSD and think that I got a fair idea about the basic principles, but I think I still didn't get a grasp on when sleeping is allowed when using an interrupt routine. From what I understand, I almost always need to create a task queue due to the fact that almost all bus implementations call mtx_sleep at some point. Is that correct? Then again I think I saw some modules calling bus operations (that possibly call mtx_sleep) during interrupt handling directly from the associated ithread routine. Are they doing it wrong?
  3. If I use a task queue to handle interrupts and retrieve data from a device and that retrieval method goes to sleep eventually. From my understanding I should release my locks before and reacquire them after the bus operation. What is the preferred method to prevent another thread trying to detach the sleeping module? Possible solutions I figured that might be applicable are flag and condition variable or nested mutex. But what is the right way to do it, or is it even unnecessary because some internal mechanism prevents detaching (device busy msg)?

Thanks for your help.

Best,
Marc

markj added a subscriber: markj.Oct 13 2018, 10:17 PM

I was able to use this on a Dell latitude 7480 to get a working trackpad. Thank you!

I haven't spent any significant amount of time looking at the diff yet, but I'll take a stab at answering these.

I got some open questions that someone actually reviewing this code or just stumbling by might be able to answer:

  1. is PI_TTY the preferred thread priority, or should it be something else?

I don't yet understand the code well enough to say. PI_TTY is for the TTY subsystem and thus probably doesn't quite make sense here. PI_DULL strikes me as a reasonable priority to use here.

  1. I read locking(9), mutex(9), bus_setup_intr(9) and a paper on locking mechanisms in FreeBSD and think that I got a fair idea about the basic principles, but I think I still didn't get a grasp on when sleeping is allowed when using an interrupt routine. From what I understand, I almost always need to create a task queue due to the fact that almost all bus implementations call mtx_sleep at some point. Is that correct? Then again I think I saw some modules calling bus operations (that possibly call mtx_sleep) during interrupt handling directly from the associated ithread routine. Are they doing it wrong?

It's never correct to sleep (e.g., by calling mtx_sleep()) in an ithread context. Could you point out the code you're referring to? In general it seems quite odd to me to call sleepable bus methods from an ithread handler.

  1. If I use a task queue to handle interrupts and retrieve data from a device and that retrieval method goes to sleep eventually. From my understanding I should release my locks before and reacquire them after the bus operation. What is the preferred method to prevent another thread trying to detach the sleeping module? Possible solutions I figured that might be applicable are flag and condition variable or nested mutex. But what is the right way to do it, or is it even unnecessary because some internal mechanism prevents detaching (device busy msg)?

Driver detach code should ensure that all taskqueues associated with the driver are stopped by calling taskqueue_drain(). This function may sleep while waiting for a taskqueue handler to complete. See the taskqueue(9) man page for more details.

There are indeed mechanisms which can block unload of a busy module, e.g., by calling device_busy() when a device file is opened.

sys/dev/iicbus/input/acpi_iichid.c
2

This file is missing a license header.

sys/dev/iicbus/input/iichid.c
2

This file is missing a license header.

sys/modules/acpi/acpi_iichid/Makefile
5

Don't forget to add this to the Makefile in the parent acpi/ directory.

First, good job!

I have an Acer Aspire E 11 (E3-112-P579).
In the BIOS I can set the touchpad to either "Basic" or "Advanced", meaning it functions as a PS/2 or I2C device.
I belive it is a Synaptics device, since with the sysctl hw.psm.synaptics_support=1 two finger scrolling works.
(And hardware ID seems to be "SYN1B7D")

I set the BIOS to "Advanced" and tested this patch. It attaches;

kernel: acpi_iichid0: <HID over I2C (ACPI)> irq 67 on acpi
0
kernel: acpi_iichid0: descriptor register address is 20
kernel: acpi_iichid0: - irq: 67
kernel: acpi_iichid0: parent device is "\_SB_.I2C1"
kernel: iichid0: <HID over I2C> at addr 0x2c on iicbus0
kernel: iichid0: ADDR 0x2c REG 0x20
kernel: iichid0: 2 buttons and [XY] coordinates ID=2
syslogd: last message repeated 1 times
kernel: acpi_iichid0: added iichid0 ADDR 0x2c REG 0x20 to iicbus0
kernel: acpi_iichid0: allocated irq at 0xfffff8000a2f7400 and rid 0
kernel: acpi_iichid0: successfully setup interrupt
kernel: iichid0: no data received
syslogd: last message repeated 1 times
kernel: iichid0: no blocks available
syslogd: last message repeated 61 times
syslogd: last message repeated 12 times

It works, but there is only one button and no two finger scrolling, whereas with psm I have 3 buttons (one, two and three finger taps) and two finger scrolling.

...
I haven't spent any significant amount of time looking at the diff yet, but I'll take a stab at answering these.
...

Your answers were very helpful, thanks alot. I can build upon that and fix some obvious errors I made in my implementation.

...
I set the BIOS to "Advanced" and tested this patch. It attaches;
...
kernel: iichid0: 2 buttons and [XY] coordinates ID=2
...
It works, but there is only one button and no two finger scrolling, whereas with psm I have 3 buttons (one, two and three finger taps) and two finger scrolling.

Thanks for testing. That your two finger scroll does not work is apparent from the descriptor line identifying only two axis, namely X and Y. For scrolling to work, there should be a Z axis as well. I believe that your touchpad does not only support the mouse reports but also multitouch trackpad reports, but they are not yet considered by iichid. Nevertheless you should be able to use two buttons.

It works, but there is only one button and no two finger scrolling, whereas with psm I have 3 buttons (one, two and three finger taps) and two finger scrolling.

Thanks for testing. That your two finger scroll does not work is apparent from the descriptor line identifying only two axis, namely X and Y. For scrolling to work, there should be a Z axis as well. I believe that your touchpad does not only support the mouse reports but also multitouch trackpad reports, but they are not yet considered by iichid. Nevertheless you should be able to use two buttons.

I did some more testing. I can only get button 1 events, by tapping with one finger. This is one of those I think are called clickpad, pushing down on the pad it clicks a physical button. That does not generate an event. However, it doesn't generate a button event in PS/2 mode either.

@marc.priggemeyer_gmail.com hello sir can you be so kind to help me out, when I try to kldload acpi_iichid.ko it says 'parent is not attached', what should I kldload beforehand or something should be done?

@marc.priggemeyer_gmail.com
sorry for bothering you guys
I have managed to kldload acpi_iicbus.ko
but my mosuepad doesn't work
here is my latest FreeBSD dmesg output:
ig4iic_pci0: <Intel Sunrise Point-LP I2C Controller-0> mem 0xd2336000-0xd2336fff at device 21.0 on pci0
ig4iic_pci0: Using MSI
iicbus0: <Philips I2C bus> on ig4iic_pci0
acpi_iichid0: <HID over I2C (ACPI)> irq 51 on acpi0
acpi_iichid0: descriptor register address is 1
acpi_iichid0: - irq: 51
acpi_iichid0: parent device is "\134_SB_.PCI0.I2C0"
iichid0: <HID over I2C> at addr 0x15 on iicbus0
iichid0: ADDR 0x15 REG 0x1
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
iichid0: 3 buttons and [XY] coordinates ID=1
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
iichid0: 3 buttons and [XY] coordinates ID=1
hid_get_item: Number of items(256) truncated to 255
hid_get_item: Number of items(672) truncated to 255
acpi_iichid0: added iichid0 ADDR 0x15 REG 0x1 to iicbus0
acpi_iichid0: allocated irq at 0xfffff801088b6780 and rid 0
acpi_iichid0: successfully setup interrupt

besides that function iichid_event in iichid.c keep printing "no data received\n"
can you be so kind to take a sight

Awesome Mark.
It works on my Huawei Matebook X Pro. Sorry for comming back so late.
I had 10 minutes to test and here are my initial findings.

Notes:

  • tested on FreeBSD ALPHA-10
  • loaded ig4 from /boot/loader.conf
  • loading iichid and acpi_iichid from /boot/loader.conf leads to panic. Adding it to /etc/rc.conf works
  • moused_port="/dev/ims1" set in /etc/rc.conf
  • moused_enable="YES" set in /etc/rc.conf
  • /usr/local/etc/X11/xorg.conf.d/mouse.conf created and ' Option "Device" "/dev/ims1" ' added
  • in /etc/sysctl.conf -> dev.acpi_iichid.1.sampling_rate=20
  • Moving the cursor works. Once its moving, it will only stop when I tap the touchpad.
  • holding the touchpad down with one finger and moving a second finger to select text works
  • Suspend/Resume does not work. However this is still an issue with ig4 I guess.

Thanks for doing this! Works great on my Dell 7490.
Suspend/resume not tested. Please also add EVDEV to this driver so we can get things like horizontal scrolling :)

/etc/rc.conf

kld_list="ig4 acpi_iichid"
moused_port="/dev/ims0"
moused_enable="YES"

/etc/X11/xorg.d/mouse.conf

Section "InputClass"
	Identifier "Touchpad"
	Option "Device" "/dev/ims0"
EndSection

Many thanks for these files and patches.
Now my Asus Vivobook S15 touchpad is working running FreeBSD 12.RC1, kernel source revision 340904.

Norice that setting iichid_load="YES" and acpi_iichid_load="YES" in either /boot/loader.conf or /etc/rc.conf lead to crash, have to be set in /etc/rc.conf kld_list variable.

dmesg

[ ... ]
iicbus0: <Philips I2C bus> on ig4iic_pci0
iicbus1: <Philips I2C bus> on ig4iic_pci1
iic0: <I2C generic I/O> on iicbus0
iic1: <I2C generic I/O> on iicbus1
iicsmb0: <SMBus over I2C bridge> on iicbus0
iicsmb1: <SMBus over I2C bridge> on iicbus1
smbus0: <System Management Bus> on iicsmb0
smbus1: <System Management Bus> on iicsmb1
acpi_iichid0: <HID over I2C (ACPI)> irq 109 on acpi0
acpi_iichid0: descriptor register address is 1
acpi_iichid0: - irq: 109
acpi_iichid0: parent device is "\134_SB_.PCI0.I2C1"
iichid0: <HID over I2C> at addr 0x15 on iicbus1
iichid0: ADDR 0x15 REG 0x1
iichid0: 2 buttons and [XYZT] coordinates ID=1
iichid0: 2 buttons and [XYZT] coordinates ID=1
acpi_iichid0: added iichid0 ADDR 0x15 REG 0x1 to iicbus1
acpi_iichid0: allocated irq at 0xfffff80009ea2a80 and rid 0
acpi_iichid0: successfully setup interrupt
iichid0: could not retrieve input report (3)
iichid0: an error occured
iichid0: could not retrieve input report (3)
iichid0: an error occured

arrowd added a subscriber: arrowd.Dec 10 2018, 2:09 PM

Builds on 12.0-STABLE r343501 sources and works fine with Dell Latitude 5590. Thank you!

kwm added a subscriber: kwm.Feb 3 2019, 11:24 AM
Scoobi_doo_yahoo.com added a comment.EditedFeb 15 2019, 7:01 PM

I'm working on adding support for the Intel DesignWare I2C controllers that are connected to my touchpad and my touchscreen, also to the touchpad of another user (who originally requested my help on this issue for his laptop). I think I have a working I2C device(running 'i2c -s -v -f /dev/iic0' kills my working PS/2-connected touchpad). I would like to use your iichid module to instantly add support for these HID devices, but when I build & load iichid I see no new HID device nodes.

What is the general procedure (using iichid) for adding a given I2C HID device that resides on a particular I2C bus attached to a particular I2C controller? I don't think my ACPI tables define the I2C addresses or control registers of the HID devices.

Thanks,
Anthony Jenkins

justus_sutsuj.com added a comment.EditedMar 31 2019, 12:32 AM

Thank you very much Marc. I have been waiting for this and really appreciate your work.

It works almost for me on an ASUS UX310. Sometimes after boot I need to load the iic kernel module and scan the bus using i2c -s -f /dev/iic1.
Furthermore two finger scrolling does not work but it seems to be recognized. At least the cursor does not move during scrolling. The middle mouse button does not work as well.

Here is my dmesg output:

Mar 30 23:59:49 maerz kernel: ig4iic_pci0: <Intel Sunrise Point-LP I2C Controller-0> mem 0xef137000-0xef137fff at device 21.0 on pci0
Mar 30 23:59:49 maerz kernel: ig4iic_pci0: Using MSI
Mar 30 23:59:49 maerz kernel: iicbus0: <Philips I2C bus> on ig4iic_pci0
Mar 30 23:59:49 maerz kernel: ig4iic_pci1: <Intel Sunrise Point-LP I2C Controller-1> mem 0xef136000-0xef136fff at device 21.1 on pci0
Mar 30 23:59:49 maerz kernel: ig4iic_pci1: Using MSI
Mar 30 23:59:49 maerz kernel: iicbus1: <Philips I2C bus> on ig4iic_pci1
Mar 30 23:59:49 maerz kernel: acpi_iichid0: <HID over I2C (ACPI)> irq 109 on acpi0
Mar 30 23:59:49 maerz kernel: acpi_iichid0: descriptor register address is 1
Mar 30 23:59:49 maerz kernel: acpi_iichid0:  - irq: 109
Mar 30 23:59:49 maerz kernel: acpi_iichid0: parent device is "\_SB_.PCI0.I2C1"
Mar 30 23:59:49 maerz kernel: iichid0: <HID over I2C> at addr 0x15 on iicbus1
Mar 30 23:59:49 maerz kernel: iichid0: ADDR 0x15 REG 0x1
Mar 30 23:59:49 maerz kernel: iichid0: 2 buttons and [XYZT] coordinates ID=1
Mar 30 23:59:49 maerz syslogd: last message repeated 1 times
Mar 30 23:59:49 maerz kernel: acpi_iichid0: added iichid0 ADDR 0x15 REG 0x1 to iicbus1
Mar 30 23:59:49 maerz kernel: acpi_iichid0: allocated irq at 0xfffff8002b1dab00 and rid 0
Mar 30 23:59:49 maerz kernel: acpi_iichid0: successfully setup interrupt
Mar 30 23:59:58 maerz kernel: iichid0: no data received
Mar 31 00:00:00 maerz syslogd: last message repeated 271 times
Mar 31 00:00:00 maerz kernel: iichid0: no data received
Mar 31 00:00:13 maerz syslogd: last message repeated 607 times
Mar 31 00:00:38 maerz kernel: iic0: <I2C generic I/O> on iicbus0
Mar 31 00:00:38 maerz kernel: iic1: <I2C generic I/O> on iicbus1
Mar 31 00:00:39 maerz kernel: iichid0: no data received
Mar 31 00:00:52 maerz syslogd: last message repeated 477 times
Mar 31 00:00:59 maerz kernel: iichid0: no data received
Mar 31 00:01:09 maerz syslogd: last message repeated 124 times

Justus

Here's preliminary evdev support. Can you please incorporate it into your patch?
https://gist.github.com/johalun/3c67a678e740b82512cec52bfe926092

Another thing, I'm having trouble with horizontal scrolling. If I do two finger horizontal scroll I don't get any event callbacks at all while I do for vertical. Could this be something that has to be enabled by sending some command to the device? I haven't tested any other OS but I assume that this (two finger horizontal scroll) would work in Windows....

seanc added a subscriber: seanc.Apr 27 2019, 6:12 PM
seanc added a comment.Apr 27 2019, 6:15 PM

Can someone summarize what's left or preventing this from being committed?

Driver does not work after resume. I had to reboot to get working touchpad again.

Can someone summarize what's left or preventing this from being committed?

  • merge evdev support
  • add support for suspend/resume
  • supposedly a crash when loading in loader.conf
  • mouse support only

Should further tests be done on current, or is it sufficient to stay on stable/12?

Thank you very much Marc. I have been waiting for this and really appreciate your work.
It works almost for me on an ASUS UX310. Sometimes after boot I need to load the iic kernel module and scan the bus using i2c -s -f /dev/iic1.
Furthermore two finger scrolling does not work but it seems to be recognized. At least the cursor does not move during scrolling. The middle mouse button does not work as well.
...

I, too, appreciate your work, Marc.

I am trying this on an ASUS S150UQ. I get similar results to Justus.

I also get a panic if loading the modules from loader.conf. But it works if I load them from rc.conf or manually.
I need to initiate load of modules iic, ig4 and acpi_iichid. The modules iicbus and iichid are then auto-loaded.

Here is then my dmesg:

Jun 23 15:53:49 susauq kernel: ig4iic_pci0: <Intel Sunrise Point-LP I2C Controller-0> mem 0xef239000-0xef239fff at device 21.0 on pci0
Jun 23 15:53:49 susauq kernel: ig4iic_pci0: Using MSI
Jun 23 15:53:49 susauq kernel: iicbus0: <Philips I2C bus> on ig4iic_pci0
Jun 23 15:53:49 susauq kernel: iic0: <I2C generic I/O> on iicbus0
Jun 23 15:53:49 susauq kernel: ig4iic_pci1: <Intel Sunrise Point-LP I2C Controller-1> mem 0xef238000-0xef238fff at device 21.1 on pci0
Jun 23 15:53:49 susauq kernel: ig4iic_pci1: Using MSI
Jun 23 15:53:49 susauq kernel: iicbus1: <Philips I2C bus> on ig4iic_pci1
Jun 23 15:53:49 susauq kernel: iic1: <I2C generic I/O> on iicbus1
Jun 23 15:53:57 susauq kernel: acpi_iichid0: <HID over I2C (ACPI)> irq 109 on acpi0
Jun 23 15:53:57 susauq kernel: acpi_iichid0: descriptor register address is 1
Jun 23 15:53:57 susauq kernel: acpi_iichid0: - irq: 109
Jun 23 15:53:57 susauq kernel: acpi_iichid0: parent device is "\_SB_.PCI0.I2C1"
Jun 23 15:53:57 susauq kernel: iichid0: <HID over I2C> at addr 0x15 on iicbus1
Jun 23 15:53:57 susauq kernel: iichid0: ADDR 0x15 REG 0x1
Jun 23 15:53:57 susauq kernel: iichid0: 2 buttons and [XYZT] coordinates ID=1
Jun 23 15:53:57 susauq syslogd: last message repeated 1 times
Jun 23 15:53:57 susauq kernel: acpi_iichid0: added iichid0 ADDR 0x15 REG 0x1 to iicbus1
Jun 23 15:53:57 susauq kernel: acpi_iichid0: allocated irq at 0xfffff8007f8c6580 and rid 0
Jun 23 15:53:57 susauq kernel: acpi_iichid0: successfully setup interrupt
Jun 23 15:53:57 susauq kernel: iichid0: no data received
Jun 23 15:54:28 susauq syslogd: last message repeated 30528 times

The "no data received" messages repeat rapidly until I perform a scan of the bus:

i2c -v -s -f /dev/iic1
dev: /dev/iic1, addr: 0x0, r/w: r, offset: 0x00, width: 8, count: 1
Hardware may not support START/STOP scanning; trying less-reliable read method.
Scanning I2C devices on /dev/iic1: 15

after which they stop and the ims0 mouse then works fine!

After suspend/resume, all input broken (ims mouse, ums mouse and also keyboard), so need hard reboot to resolve.

fbsd_opal.com added a comment.EditedSun, Jun 23, 6:13 PM

After suspend/resume, all input broken (ims mouse, ums mouse and also keyboard), so need hard reboot to resolve.

There is a comment in sys/dev/ichiic/ig4_pci.c:

/*
 * Loading this module breaks suspend/resume on laptops
 * Do not add MODULE_PNP_INFO until it's impleneted
 */

It appears that this has been fixed in HEAD, so I will merge those diffs and retest.

I've been playing around with it here https://gist.github.com/johalun/ffc271a07a0cf50d0bc816138c4eec81 but still no success. Basically there are no interrupts from the device after resume. I don't know if this is because ig4 or the i2c device missing some kind of reset command. I found something in MS docs about sending an i2c reset command which you can see in the resume function but it doesn't do anything which makes me think that ig4 is the problem. Here I simply copy/paste the routine from the attach function to resume but not sure that's enough. Probably need to spend some times reading reference manual for the devices.

I've been playing around with it here https://gist.github.com/johalun/ffc271a07a0cf50d0bc816138c4eec81 but still no success. Basically there are no interrupts from the device after resume. I don't know if this is because ig4 or the i2c device missing some kind of reset command. I found something in MS docs about sending an i2c reset command which you can see in the resume function but it doesn't do anything which makes me think that ig4 is the problem. Here I simply copy/paste the routine from the attach function to resume but not sure that's enough. Probably need to spend some times reading reference manual for the devices.

I didn't say before, but I am testing on 12-stable. It may be easier to test devel code on head, but here I am on 12.

OK, so I have applied commits r342170, r342178 and r342180 which allows the ig4 module to autoload on boot, which is a step forwards. I thought this would also fix suspend/resume, but it hasn't yet. Maybe I didn't include all the commits I should have...?

I still have two problems:

  • the iic bus doesn't always init properly, but it works after doing the "i2c -s" scan (which does an ioctl( I2CRSTCARD) and then probes the bus, after which it's ok).
  • all my input devices (ims mouse, ums mouse and keyboard) are all dead after the resume

The init problem suggests the init sequence isn't quite complete in one of these layers. I see that in ig4_iic.c, the reset code is commented out with a note that it "blows up the PCI config", although a reset is done for Skylake (which is what I have) under certain conditions. I'll have to study this more to see if it is being done in my case.

The resume problem may be related, but I suspect that it is more complex given what those other patches do. I suspect that the suspend/resume is wiping the PCI config and we are not setting it back up again. Or maybe, in fact we are calling that Skylake reset when we should not be and that is what is "blow[ing] up the PCI config"!?

markj added a comment.Sun, Jun 23, 7:47 PM

Could anyone affected by the issue give the patch here a try? https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=238037

Could anyone affected by the issue give the patch here a try? https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=238037

Yes, indeed it does fix suspend/resume for me! Thanks for the pointer to that PR. So that's on 12-stable with additional commits from head r342170, r342178 and r342180 applied too.

However, the initial need to scan the bus "i2c -s -f /dev/iic1" was needed again after the resume.

But ums0 and keyboard worked immediately and ims0 works again after that scan. Great!

By the way, there is an error in the diff of sys/conf/files in this D16698 patch:

# diff -u sys/conf/files.orig sys/conf/files
--- sys/conf/files.orig 2019-06-24 10:21:56.282212000 +0200
+++ sys/conf/files      2019-06-23 14:03:36.690297000 +0200
@@ -1847,7 +1847,7 @@
 dev/iicbus/iicbb_if.m          optional iicbb
 dev/iicbus/iicbus.c            optional iicbus
 dev/iicbus/iicbus_if.m         optional iicbus
-dev/iicubs/iichid.c            optional iichid acpi iicbus
+dev/iicbus/iichid.c            optional iichid acpi iicbus
 dev/iicbus/iiconf.c            optional iicbus
 dev/iicbus/iicsmb.c            optional iicsmb                         \
        dependency      "iicbus_if.h"
seanc added a comment.Sat, Jul 6, 7:02 AM

@marc.priggemeyer_gmail.com or @markj, is what's here sufficient for now, or do the edev fixes need to go in, too? It looked like suspend/resume was the biggest issue. I'm worried about this review being a casualty of perfection vs making incremental, usable progress. Given the successes reported so far, I'm trying to gauge what's mandatory vs what should be done next post-commit.

sys/conf/files
1849

Per @fbsd_opal.com , this line needs: s/iicubs/iicbus/

@marc.priggemeyer_gmail.com or @markj, is what's here sufficient for now, or do the edev fixes need to go in, too? It looked like suspend/resume was the biggest issue. I'm worried about this review being a casualty of perfection vs making incremental, usable progress. Given the successes reported so far, I'm trying to gauge what's mandatory vs what should be done next post-commit.

The actual driver works well once you have it initialized properly.

From discussion on the ig4 suspend/resume PR, It seems that the ACPI driver may also need some re-initialization after a suspend/resume. Also, I was thinking that the non-acpi driver may need a flag in its softc for the ACPI side to to tell it that the ACPI isn't ready (because the re-initialization after resume is in newbus tree order which means the ACPI driver will be done after the main driver).

The initialization after boot is also not right. You can get it to work by forcing the module load in the right order. But if you load just this driver, things are loaded in the wrong order and so it suffers the same initialization problems as on resume.

I have played around with these a bit, but do not have a solution yet.

It also causes a panic if the modules are loaded from /boot/loader.conf. At the very least, I'd think that needs fixing before commit.

We might also want to rename the driver files to "ims" following FreeBSD conventions, and similar to OpenBSD. "kldload ims" should get you the ims driver, not "kldload acpi_iichid".

markj added a comment.Sat, Jul 6, 3:41 PM

@marc.priggemeyer_gmail.com or @markj, is what's here sufficient for now, or do the edev fixes need to go in, too? It looked like suspend/resume was the biggest issue. I'm worried about this review being a casualty of perfection vs making incremental, usable progress. Given the successes reported so far, I'm trying to gauge what's mandatory vs what should be done next post-commit.

The acpi_iichid driver needs to be rewritten. It should be a child of the iic bus, not the acpi bus. I've started working on this.

iichid.c needs a license header.

#1

The acpi_iichid driver needs to be rewritten. It should be a child of the iic bus, not the acpi bus. I've started working on this.

I will submit to the more experienced developers on this point, for completeness I would still like to include my findings here:

  • The I2C Bus is not enumerable, which means that the driver won't be attached automatically if it is a child of iicbus.
  • The specification of HID over I2C explicitly states that devices should be included in the ACPI tables for proper identification, therefore a driver implemented as a child of ACPI will be attached.
  • My workaround was to implement the driver as part of the ACPI structure that identifies the relevant parameters and attaches the actual device below the iicbus.
  • A more elaborate explanation to the why is included in point 3 under the important notes in my initial description.
  • Thanks for picking this issue up, I am looking forward to see the correct implementation.

#2
One major issue I still see here is a structural one: HID code is currently maintained as part of the USB implementation (since it was initially specified to be part of USB).

#3
The crash people are experiencing during boot with acpi_iichid_load="YES" in /boot/loader.conf:
Do you also include iichid_load="YES"? I don't experience crashes on my system, but I will try this evening to replicate that.

Unfortunately I do not have much time to spend on this at the moment.

markj added a comment.Sat, Jul 6, 8:11 PM

#1

The acpi_iichid driver needs to be rewritten. It should be a child of the iic bus, not the acpi bus. I've started working on this.

I will submit to the more experienced developers on this point, for completeness I would still like to include my findings here:

  • The I2C Bus is not enumerable, which means that the driver won't be attached automatically if it is a child of iicbus.

The trick is to use the DEVICE_IDENTIFY(9) method to walk the child nodes of the ACPI node associated with the iicbus device. This can be done with AcpiWalkNamespace(), for instance. Then you can force the instantiation of a acpi_iicbus device.

I'm not sure yet about the interrupt problem you described in the code review description, I'll try to get that bit working this coming week.

  • The specification of HID over I2C explicitly states that devices should be included in the ACPI tables for proper identification, therefore a driver implemented as a child of ACPI will be attached.
  • My workaround was to implement the driver as part of the ACPI structure that identifies the relevant parameters and attaches the actual device below the iicbus.
  • A more elaborate explanation to the why is included in point 3 under the important notes in my initial description.
  • Thanks for picking this issue up, I am looking forward to see the correct implementation.

#2
One major issue I still see here is a structural one: HID code is currently maintained as part of the USB implementation (since it was initially specified to be part of USB).

Yes, they will require some work to merge. However, I don't think it should block this driver from being committed.

Do you have a license header for iichid.c?

Do you have a license header for iichid.c?

Actually, no. What would be the source for the default for FreeBSD? 2-clause from here (https://www.freebsd.org/internal/software-license.html)?

The trick is to use the DEVICE_IDENTIFY(9) method to walk the child nodes of the ACPI node associated with the iicbus device. This can be done with AcpiWalkNamespace(), for instance. Then you can force the instantiation of a acpi_iicbus device.

Sounds right. Acutally, I fumbled through that acpica code and collected what looked right. Do you have any pointer to the handbook or other documentation suitable as reference material?

I just looked into Microsoft's HID over I2C specification document again. Section 8.2 deals with "Host Initiated Power Optimizations" (HIPO). There, sleep and on are explicitly stated as modes that the host should take care of:
Quote: [1]

The HOST is responsible for optimizing the power of the overall system and the DEVICE. This method of power optimization is to be used when the HOST wishes to provide power optimization notifications to devices.
The following power states are defined for HIPO and are not to be confused with vendor specific DIPO states.

• ON
• SLEEP

Section 7.2.8 specifies the SET_POWER command, so the DEVMETHODs device_suspend and device_resume should implement sleep and wakeup transitions for the human interface device. In addition, the device is not required to respond to the SET_POWER command, so it could be implemented fairly easy. Probably something like this (untested):

static int
iichid_write_register(device_t dev, uint8_t* cmd, int cmdlen)
{
	uint16_t addr = iicbus_get_addr(dev);
	struct iic_msg msgs[] = {
	     { addr << 1, IIC_M_WR, cmdlen, cmd },
	};

	return (iicbus_transfer(dev, msgs, nitems(msgs)));
}

static int
iichid_set_power(device_t dev, struct i2c_hid_desc* hid_desc, bool sleep)
{
	struct iichid_softc* sc;
	sc = device_get_softc(dev);

	mtx_assert(&sc->lock, MA_OWNED);

	uint16_t cmdreg = htole16(hid_desc->wCommandRegister);

	uint8_t power_state = 0; //default on
	if( sleep )
		power_state = 1; //sleep	

	uint8_t cmd[] = {cmdreg & 0xff, cmdreg >> 8, power_state, 0x08};  //0x08, 4 reserved bits plus opcode (4 bit)
	int cmdlen    = 4;

	mtx_unlock(&sc->lock);

	int error = iichid_write_register(dev, cmd, cmdlen);

	mtx_lock(&sc->lock);

	return error;
}

[1] http://download.microsoft.com/download/7/d/d/7dd44bb7-2a7a-4505-ac1c-7227d3d96d5b/hid-over-i2c-protocol-spec-v1-0.docx

marc.priggemeyer_gmail.com marked an inline comment as done.Sat, Jul 6, 9:55 PM
marc.priggemeyer_gmail.com updated this revision to Diff 59484.

Hmm, I think I did not intend to create a new diff. Should I reupload, or can it be merged?

sys/modules/acpi/acpi_iichid/Makefile
5

Will the acpi module be removed and code integrated into sys/modules/i2c?

markj added a comment.Sun, Jul 7, 4:12 PM

Hmm, I think I did not intend to create a new diff. Should I reupload, or can it be merged?

Please reupload the full diff.

Do you have a license header for iichid.c?

Actually, no. What would be the source for the default for FreeBSD? 2-clause from here (https://www.freebsd.org/internal/software-license.html)?

FreeBSD 2-clause is the preferred license for new files. I noticed that iichid.h appears to be from OpenBSD (which is perfectly fine), so it wasn't clear to me if iichid.c was also derived from OpenBSD or if it was written from scratch.

I just looked into Microsoft's HID over I2C specification document again. Section 8.2 deals with "Host Initiated Power Optimizations" (HIPO). There, sleep and on are explicitly stated as modes that the host should take care of:
Quote: [1]

The HOST is responsible for optimizing the power of the overall system and the DEVICE. This method of power optimization is to be used when the HOST wishes to provide power optimization notifications to devices.
The following power states are defined for HIPO and are not to be confused with vendor specific DIPO states.

• ON
• SLEEP

Section 7.2.8 specifies the SET_POWER command, so the DEVMETHODs device_suspend and device_resume should implement sleep and wakeup transitions for the human interface device. In addition, the device is not required to respond to the SET_POWER command, so it could be implemented fairly easy. Probably something like this (untested):

static int
iichid_write_register(device_t dev, uint8_t* cmd, int cmdlen)
static int
iichid_set_power(device_t dev, struct i2c_hid_desc* hid_desc, bool sleep)

I put in that code and added suspend and resume functions to invoke it.

Firstly, the mtx_assert() fails and causes a panic.

Removing the mtx_assert() and so also the mtx_unlock() and mtx_lock() runs ok, but doesn't help with the problem of the mouse still needing resetting after resume.

I reuploaded the full patch with a sysctl (power_state) added.
Setting

sysctl dev.iichid.0.power_state=1

or any other value not 0, will send the human interface device to sleep. Setting

sysctl dev.iichid.0.power_state=0

will wake it up again.

device_suspend and device_resume was also added, but I could not test it sufficiently, because suspend/resume does not work on my laptop as of yet.

wulf added a subscriber: wulf.Mon, Jul 8, 10:06 PM

I wrote a driver for I2C MT touchscreens https://github.com/wulf7/iichid which is heavily based on the code in this review.
It does not require dedicated ACPI module at all and has some I2C/HID layers separation which is missed in current review.
So I think it may have sense to join efforts and codebases

markj added a comment.Mon, Jul 8, 10:19 PM
In D16698#452631, @wulf wrote:

I wrote a driver for I2C MT touchscreens https://github.com/wulf7/iichid which is heavily based on the code in this review.
It does not require dedicated ACPI module at all and has some I2C/HID layers separation which is missed in current review.
So I think it may have sense to join efforts and codebases

Oh, nice. Your iichid_identify() method is basically identical to what I wrote. You're right, it does not strictly require a separate module, it just seemed cleaner to have a generic acpi_iichid bus.

I think it would be best to try and base the ims driver on top of your code. Are you interested in trying to integrate them?

wulf added a comment.Mon, Jul 8, 11:15 PM

Oh, nice. Your iichid_identify() method is basically identical to what I wrote. You're right, it does not strictly require a separate module, it just seemed cleaner to have a generic acpi_iichid bus.

I don't object to acpi_iichid module existence. It just adds an extra requirements for module load order which I was not able to solve quickly.

I think it would be best to try and base the ims driver on top of your code. Are you interested in trying to integrate them?

Yes, I am going to submit this code to the project when it will be ready, so it is better to have it insync with ims

Many thanks for your efforts! My laptop: Asus Zenbook 14 UX410UFR with 12.0-RELEASE. After kldload ig4 iic acpi_iichid the device works after being probed with i2c -v -s -f /dev/iic1 (thanks fbsd_opal.com). My /var/log/messages:

Jul 15 01:55:03 thorium kernel: ig4iic_pci0: <Intel Sunrise Point-LP I2C Controller-0> mem 0xef238000-0xef238fff at device 21.0 on pci0
Jul 15 01:55:03 thorium kernel: ig4iic_pci0: Using MSI
Jul 15 01:55:03 thorium kernel: iicbus0: <Philips I2C bus> on ig4iic_pci0
Jul 15 01:55:03 thorium kernel: ig4iic_pci1: <Intel Sunrise Point-LP I2C Controller-1> mem 0xef237000-0xef237fff at device 21.1 on pci0
Jul 15 01:55:03 thorium kernel: ig4iic_pci1: Using MSI
Jul 15 01:55:03 thorium kernel: iicbus1: <Philips I2C bus> on ig4iic_pci1
Jul 15 01:55:03 thorium kernel: ig4iic_pci2: <Intel Sunrise Point-LP I2C Controller-2> mem 0xef236000-0xef236fff at device 21.2 on pci0
Jul 15 01:55:03 thorium kernel: ig4iic_pci2: Using MSI
Jul 15 01:55:03 thorium kernel: iicbus2: <Philips I2C bus> on ig4iic_pci2
Jul 15 01:55:03 thorium kernel: warning: KLD '/boot/kernel/iic.ko' is newer than the linker.hints file
Jul 15 01:55:03 thorium kernel: iic0: <I2C generic I/O> on iicbus0
Jul 15 01:55:03 thorium kernel: iic1: <I2C generic I/O> on iicbus1
Jul 15 01:55:03 thorium kernel: iic2: <I2C generic I/O> on iicbus2
Jul 15 01:55:03 thorium kernel: acpi_iichid0: <HID over I2C (ACPI)> irq 109 on acpi0
Jul 15 01:55:03 thorium kernel: acpi_iichid0: descriptor register address is 1
Jul 15 01:55:03 thorium kernel: acpi_iichid0:  - irq: 109
Jul 15 01:55:03 thorium kernel: acpi_iichid0: parent device is "\_SB_.PCI0.I2C1"
Jul 15 01:55:03 thorium kernel: iichid0: <HID over I2C> at addr 0x15 on iicbus1
Jul 15 01:55:03 thorium kernel: iichid0: ADDR 0x15 REG 0x1
Jul 15 01:55:03 thorium kernel: iichid0: 2 buttons and [XYZT] coordinates ID=1
Jul 15 01:55:03 thorium syslogd: last message repeated 1 times
Jul 15 01:55:03 thorium kernel: acpi_iichid0: added iichid0 ADDR 0x15 REG 0x1 to iicbus1
Jul 15 01:55:03 thorium kernel: acpi_iichid0: allocated irq at 0xfffff80107e06500 and rid 0
Jul 15 01:55:03 thorium kernel: acpi_iichid0: successfully setup interrupt

ig4 breaks suspend for me (which works just fine without it). After acpiconf -s3 laptop hangs on ttyv1 with quickly blinking mouse cursor and these lines:

<6>[drm] GPU HANG: ecode 9:1:0xfffffffe, reason: Hang on bcs0, action: reset 
drmn0: Failed to idle engines, declaring wedged!

For now, I solved this problem by adding kldunload ig4 in /etc/rc.suspend and all commands activating touchpad in /etc/rc.resume. With this hack, I have working touchpad after resume, which is very nice.

My questions:

  1. I compiled this driver with EVDEV support (https://gist.github.com/johalun/3c67a678e740b82512cec52bfe926092). How can I make use of it? I see no difference with and without this patch.
  1. With this in /etc/rc.conf:
moused_flags=" -V -a 0.8 -A 1.0 -U 4 -L 1.5"
moused_port="/dev/ims0"

and this in /etc/X11/xorg.d/mouse.conf:

Section "InputClass"
    Identifier "Touchpad"
    Option "Device" "/dev/ims0"
EndSection

I have only left button working (no right click, no two-finger scrolling). Any suggestions?

  1. moused_flags=" -V -a 0.8 -A 1.0 -U 4 -L 1.5" gives horrible results; it's almost impossible to click on the right place, and drag-and-drop is very hard to achieve. Any suggestions how to improve these flags?
  1. Does anybody have better solution to ig4 problem? Update: deprecated question. I missed https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=238037.
marc.priggemeyer_gmail.com marked 3 inline comments as done.Tue, Jul 16, 3:16 PM

Many thanks for your efforts! My laptop: Asus Zenbook 14 UX410UFR with 12.0-RELEASE. After kldload ig4 iic acpi_iichid the device works after being probed with i2c -v -s -f /dev/iic1 (thanks fbsd_opal.com). My /var/log/messages:

Could you post the full output of the i2c -v -s -f /dev/iic1 command? I just checked the implementation and i2c either uses START/STOP or reads a byte to perform a scan per address. On my laptop (using ig4), I get the following output and I think it looks similar on yours.

dev: /dev/iic1, addr: 0x0, r/w: r, offset: 0x00, width: 8, count: 1
Hardware may not support START/STOP scanning; trying less-reliable read method.
Scanning I2C devices on /dev/iic1: 2c

Since ig4 does not implement iicbus_start and iicbus_stop functions, it issues a write on the bus. Question is: does running i2c trigger an event (that results in the touchpad working again) on the device itself or within ig4.
Possibility 1: Controller reset helps.
I2CRSTCARD is issued to the iicbus driver.

Possibility 2: Testing if START/STOP works will trigger said event (thats basically the same as possibility 1 with another configuration if iicbus_start is not implemented)
Within iicioctl() the I2CSTART command issues iicbus_request_bus and iicbus_release_bus once iicbus_start returned an error.

Possibility 3: reading from the device helps
I2CRDWR is issued and reads one byte from the devices address.

I would like to ask you to test all of them (suspend does not work on my computer):
You can download the attached file {F4862417}and just compile it cc main.cpp, afterwards run the program a.out with the path to the iic device (e.g. /dev/iic1) as the first parameter, the test to run as the second parameter (decimal) and the address of your touchpad on the i2c bus as the third parameter (hex), so basically something like this (given your dmesg output indicates the address of you touchpad is 0x15 and it's located on iicbus1):

#test 1: reset controller (I2CRSTCARD)
./a.out /dev/iic1 1 0x15

#test 2: issue start and stop conditions (I2CSTART)
./a.out /dev/iic1 2 0x15

#test 3: issue a read of 1 byte (I2CRDWR)
./a.out /dev/iic1 3 0x15

#scan (just like i2c -v -l -f /dev/iic1)
./a.out /dev/iic1 0 0x15

So after resume, when your touchpad does not work, run the above commands in that order and verify in between if the touchpad works again.

sys/dev/iicbus/input/iichid.c
2

I took some code form sys/dev/usb/input/ums.c that handles the HID reports, how to take that into account?

Many thanks for your efforts! My laptop: Asus Zenbook 14 UX410UFR with 12.0-RELEASE. After kldload ig4 iic acpi_iichid the device works after being probed with i2c -v -s -f /dev/iic1 (thanks fbsd_opal.com). My /var/log/messages:

Could you post the full output of the i2c -v -s -f /dev/iic1 command? I just checked the implementation and i2c either uses START/STOP or reads a byte to perform a scan per address. On my laptop (using ig4), I get the following output and I think it looks similar on yours.

dev: /dev/iic1, addr: 0x0, r/w: r, offset: 0x00, width: 8, count: 1
Hardware may not support START/STOP scanning; trying less-reliable read method.
Scanning I2C devices on /dev/iic1: 2c

Here it is:

# i2c -v -s -f /dev/iic1
dev: /dev/iic1, addr: 0x0, r/w: r, offset: 0x00, width: 8, count: 1
Hardware may not support START/STOP scanning; trying less-reliable read method.
Scanning I2C devices on /dev/iic1: 15 77

Since ig4 does not implement iicbus_start and iicbus_stop functions, it issues a write on the bus. Question is: does running i2c trigger an event (that results in the touchpad working again) on the device itself or within ig4.
Possibility 1: Controller reset helps.
I2CRSTCARD is issued to the iicbus driver.
Possibility 2: Testing if START/STOP works will trigger said event (thats basically the same as possibility 1 with another configuration if iicbus_start is not implemented)
Within iicioctl() the I2CSTART command issues iicbus_request_bus and iicbus_release_bus once iicbus_start returned an error.
Possibility 3: reading from the device helps
I2CRDWR is issued and reads one byte from the devices address.
I would like to ask you to test all of them (suspend does not work on my computer):
You can download the attached file {F4862417}and just compile it cc main.cpp, afterwards run the program a.out with the path to the iic device (e.g. /dev/iic1) as the first parameter, the test to run as the second parameter (decimal) and the address of your touchpad on the i2c bus as the third parameter (hex), so basically something like this (given your dmesg output indicates the address of you touchpad is 0x15 and it's located on iicbus1):

#test 1: reset controller (I2CRSTCARD)
./a.out /dev/iic1 1 0x15
#test 2: issue start and stop conditions (I2CSTART)
./a.out /dev/iic1 2 0x15
#test 3: issue a read of 1 byte (I2CRDWR)
./a.out /dev/iic1 3 0x15
#scan (just like i2c -v -l -f /dev/iic1)
./a.out /dev/iic1 0 0x15

So after resume, when your touchpad does not work, run the above commands in that order and verify in between if the touchpad works again.

The touchpad needs scan to start working not just after resume, but on boot as well (after loading all necessary modules). Here is the output. Suspend done, with ig4 kldunload'ed. Resumed. kldload ig4 by hand. Touchpad doesn't work, any movement produces

Jul 16 19:34:56 thorium kernel: iichid0: no data received

The a.out output:

# ./a.out /dev/iic1 1 0x15
reset returned 0
test finished
# ./a.out /dev/iic1 2 0x15
I2CSTART failed, will not I2CSTOP (-1)
test finished
# ./a.out /dev/iic1 3 0x15
read: 0x0
test finished

At this moment, after third test, touchpad is working again.

# ./a.out /dev/iic1 0 0x15
.................... 0x15 ................................................................................................. 0x77  0x78 ......
#

And please tell me if it's possible at all at this moment to get this touchpad behave like a normal touchpad? Some people reported that synaptics driver does some job for them, but not in my case. In other words -- is there any xorg driver for it, or we are doomed to moused and it's crude functionality for now?

... please note that I edited my last post; touchpad is working again after test #3.

  1. I compiled this driver with EVDEV support (https://gist.github.com/johalun/3c67a678e740b82512cec52bfe926092). How can I make use of it? I see no difference with and without this patch.

If there's a new device in /dev/input, it is working. You can run libinput debug-events to see the input events. To consume evdev devices from xorg, use xf86-input-libinput. There were patches for autodetection (one adding evdev autodetection to the devd backend, another switching to the udev backend with libudev-devd). The devd one might have been merged?? (I don't follow Xorg, I use Wayland exclusively)

  1. I compiled this driver with EVDEV support (https://gist.github.com/johalun/3c67a678e740b82512cec52bfe926092). How can I make use of it? I see no difference with and without this patch.

If there's a new device in /dev/input, it is working. You can run libinput debug-events to see the input events. To consume evdev devices from xorg, use xf86-input-libinput. There were patches for autodetection (one adding evdev autodetection to the devd backend, another switching to the udev backend with libudev-devd). The devd one might have been merged?? (I don't follow Xorg, I use Wayland exclusively)

Thanks; I thought that kldload evdev was enough; but kernel with EVDEV_SUPPORT was needed. Now I have /dev/input, but two-finger tapping, two-finger scrolling etc. still don't generate any events. And, obviously, the device is recognized as a mouse. Does anyone have ideas/knowledge about the cause of this situation? Is it possible to get full touchpad functionality with this hardware? In details:

# sysctl -a | grep evdev
kern.features.evdev_support: 1
kern.features.evdev: 1
device  evdev
kern.evdev.sysmouse_t_axis: 1
kern.evdev.rcpt_mask: 12

(last two parameters changed by me; with rcpt_mask=24 mouse touchpad doesn't work under xorg).

% libinput debug-events
-event0   DEVICE_ADDED     System keyboard multiplexer       seat0 default group1  cap:k
-event1   DEVICE_ADDED     System mouse                      seat0 default group2  cap:p left scroll-nat scroll-button
-event2   DEVICE_ADDED     AT keyboard                       seat0 default group3  cap:k
-event3   DEVICE_ADDED     HID over I2C                      seat0 default group4  cap:p left scroll-nat scroll-button
...

and

# libinput list-devices
Device:           System keyboard multiplexer
Kernel:           /dev/input/event0
[...]

Device:           System mouse
Kernel:           /dev/input/event1
[...]

Device:           AT keyboard
Kernel:           /dev/input/event2
[...]

Device:           HID over I2C
Kernel:           /dev/input/event3
Group:            4
Seat:             seat0, default
Capabilities:     pointer 
Tap-to-click:     n/a
Tap-and-drag:     n/a
Tap drag lock:    n/a
Left-handed:      disabled
Nat.scrolling:    disabled
Middle emulation: n/a
Calibration:      n/a
Scroll methods:   button
Click methods:    none
Disable-w-typing: n/a
Accel profiles:   flat *adaptive
Rotation:         n/a

However, only movements and simple clicks generate events. Anyway, I added this to xorg.conf:

Section "InputDevice"
    Identifier      "Touchpad1"
    Driver          "libinput"
    Option          "Device" "/dev/input/event3"
    Option          "Tapping" "on"
    Option "ClickMethod" "clickfinger"
    Option "NaturalScrolling" "true"
    Option "ScrollMethod" "twofinger"
EndSection

From Xorg.0.log:

[ 10809.080] (II) Using input driver 'libinput' for 'Touchpad1'
[ 10809.080] (**) Option "CorePointer"
[ 10809.080] (**) Touchpad1: always reports core events
[ 10809.080] (**) Option "Device" "/dev/input/event3"
[ 10809.081] (II) event3  - HID over I2C: is tagged by udev as: Mouse
[ 10809.082] (II) event3  - HID over I2C: device is a pointer
[ 10809.082] (II) event3  - HID over I2C: device removed
[ 10809.082] (**) Option "NaturalScrolling" "true"
[ 10809.082] (**) Option "ScrollMethod" "twofinger"
[ 10809.082] (II) XINPUT: Adding extended input device "Touchpad1" (type: MOUSE, id 7)
[ 10809.082] (EE) libinput: Touchpad1: Failed to set scroll to twofinger
[ 10809.082] (**) Option "AccelerationScheme" "none"
[ 10809.082] (**) Touchpad1: (accel) selected scheme none/0
[ 10809.082] (**) Touchpad1: (accel) acceleration factor: 2.000
[ 10809.082] (**) Touchpad1: (accel) acceleration threshold: 4
[ 10809.082] (II) event3  - HID over I2C: is tagged by udev as: Mouse
[ 10809.082] (II) event3  - HID over I2C: device is a pointer
[ 10809.082] (EE) libinput: Touchpad1: Failed to set scroll to twofinger
  1. I compiled this driver with EVDEV support (https://gist.github.com/johalun/3c67a678e740b82512cec52bfe926092). How can I make use of it? I see no difference with and without this patch.

If there's a new device in /dev/input, it is working. You can run libinput debug-events to see the input events. To consume evdev devices from xorg, use xf86-input-libinput. There were patches for autodetection (one adding evdev autodetection to the devd backend, another switching to the udev backend with libudev-devd). The devd one might have been merged?? (I don't follow Xorg, I use Wayland exclusively)

Thanks; I thought that kldload evdev was enough; but kernel with EVDEV_SUPPORT was needed.

hm. EVDEV_SUPPORT enables evdev in "legacy" drivers like psm, ums, ukbd etc. I'm not sure why @johalun added ifdefs for that here, this is a new driver :)

Now I have /dev/input, but two-finger tapping, two-finger scrolling etc. still don't generate any events. And, obviously, the device is recognized as a mouse. Does anyone have ideas/knowledge about the cause of this situation? Is it possible to get full touchpad functionality with this hardware? In details:

It's possible, just not done — looks like the patch is called "… (Mouse only)" for a reason.

What these touchpads use for actual touchpad functionality over HID is (most likely) the Microsoft Precision protocol.

We have the wmt driver but right now it's *touchscreen*-only and (of course) USB-only.

hm. EVDEV_SUPPORT enables evdev in "legacy" drivers like psm, ums, ukbd etc. I'm not sure why @johalun added ifdefs for that here, this is a new driver :)

Well, without EVDEV_SUPPORT enabled kernel there is no /dev/input. And libinput driver obviously communicates with this touchpad.

It's possible, just not done — looks like the patch is called "… (Mouse only)" for a reason.
What these touchpads use for actual touchpad functionality over HID is (most likely) the Microsoft Precision protocol.
We have the wmt driver but right now it's *touchscreen*-only and (of course) USB-only.

I see. Sigh. Anyway, some people from this thread reported that two finger scrolling *does* work, including @johalun himself in his announcement:

If I do two finger horizontal scroll I don't get any event callbacks at all while I do for vertical. Could this be something that has to be enabled by sending some command to the device?

hm. EVDEV_SUPPORT enables evdev in "legacy" drivers like psm, ums, ukbd etc. I'm not sure why @johalun added ifdefs for that here, this is a new driver :)

EVDEV is still optional and the driver won't compile without the #ifdefs if it's not enabled. Just recently I think it has been enabled by default.

EVDEV is still optional and the driver won't compile without the #ifdefs if it's not enabled. Just recently I think it has been enabled by default.

@johalun, would you be kind to scroll three posts up and give your verdict about Asus Zenbook 14's touchpad? I posted a lot of output there. Is iichid driver with your evdev patch capable of making it fully functional touchpad, or I'm doomed to simple mouse functionality for now? It would be nice to have at least two finger scrolling; you mentioned earlier that it's possible.

wulf added a comment.Thu, Jul 18, 9:34 PM

We have the wmt driver but right now it's *touchscreen*-only and (of course) USB-only.

I have half-completed (it is working for me!) WIP port of wmt for i2c bus https://github.com/wulf7/iichid.
It is relatively easy (~20-30 LOC) to add support for MS-precision protocol touchpads to it but according to some docs enclosed with Darwin driver https://github.com/alexandred/VoodooI2C/blob/master/Documentation/Satellites.md it wont help as many models of touchpads uses proprietary protocol in absolute mode.

wulf added a comment.Thu, Jul 18, 9:45 PM

I see. Sigh. Anyway, some people from this thread reported that two finger scrolling *does* work, including @johalun himself in his announcement:

If I do two finger horizontal scroll I don't get any event callbacks at all while I do for vertical. Could this be something that has to be enabled by sending some command to the device?

This driver like ums supports only relative mouse protocol. So it is up to touchpad firmware to support any gestures. OS driver or userland applications just do not have enough information as finger coords or count to support doublefinger scroll or multifinger taps.

wulf added a comment.Thu, Jul 18, 9:59 PM

OS driver or userland applications just do not have enough information as finger coords or count to support doublefinger scroll or multifinger taps.

I wrote a simple util to dump report descriptor from I2C HID device

.
It accepts 3 input parameters: iic device path, i2c bus address and i2c HID register and prints report descriptor of given I2C device on stdout. This report descriptor can be further analyzed with any tool (e.g. web-based http://eleccelerator.com/usbdescreqparser/) to examine HID device capabilities.

In D16698#455403, @wulf wrote:

OS driver or userland applications just do not have enough information as finger coords or count to support doublefinger scroll or multifinger taps.

I wrote a simple util to dump report descriptor from I2C HID device

.
It accepts 3 input parameters: iic device path, i2c bus address and i2c HID register and prints report descriptor of given I2C device on stdout. This report descriptor can be further analyzed with any tool (e.g. web-based http://eleccelerator.com/usbdescreqparser/) to examine HID device capabilities.

Great! In my case (Asus Zenbook 14):

# ./fetchdesc /dev/iic1 0x15 1
HID descriptor:

wHIDDescLength:      30
bcdVersion:          0x0100
wReportDescLength:   356
wReportDescRegister: 0x0002
wInputRegister:      0x0003
wMaxInputLength:     16
wOutputRegister:     0x0004
wMaxOutputLength:    0
wCommandRegister:    0x0005
wDataRegister:       0x0006
wVendorID:           0x04f3
wProductID:          0x309c
wVersionID:          0x0001

Report descriptor:

05 01 09 02 A1 01 85 01  09 01 A1 00 05 09 19 01  
29 02 15 00 25 01 75 01  95 02 81 02 95 06 81 03  
05 01 09 30 09 31 09 38  15 81 25 7F 75 08 95 03  
81 06 05 0C 0A 38 02 95  01 81 06 75 08 95 03 81  
03 C0 C0 05 0D 09 05 A1  01 85 04 09 22 A1 02 15  
00 25 01 09 47 09 42 95  02 75 01 81 02 75 01 95  
02 81 03 95 01 75 04 25  0F 09 51 81 02 05 01 15  
00 26 80 0C 75 10 55 0E  65 13 09 30 35 00 46 90  
01 95 01 81 02 46 13 01  26 96 08 26 96 08 09 31  
81 02 05 0D 15 00 25 64  95 03 C0 55 0C 66 01 10  
47 FF FF 00 00 27 FF FF  00 00 75 10 95 01 09 56  
81 02 09 54 25 7F 95 01  75 08 81 02 05 09 09 01  
25 01 75 01 95 01 81 02  95 07 81 03 09 C5 75 08  
95 04 81 03 05 0D 85 02  09 55 09 59 75 04 95 02  
25 0F B1 02 85 07 09 60  75 01 95 01 15 00 25 01  
B1 02 95 0F B1 03 06 00  FF 06 00 FF 85 06 09 C5  
15 00 26 FF 00 75 08 96  00 01 B1 02 85 0D 09 C4  
15 00 26 FF 00 75 08 95  04 B1 02 85 0C 09 C6 96  
8A 02 75 08 B1 02 85 0B  09 C7 95 80 75 08 B1 02  
C0 05 0D 09 0E A1 01 85  03 09 22 A1 00 09 52 15  
00 25 0A 75 10 95 01 B1  02 C0 09 22 A1 00 85 05  
09 57 09 58 15 00 75 01  95 02 25 03 B1 02 95 0E  
B1 03 C0 C0

Parsed:

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x02,        // Usage (Mouse)
0xA1, 0x01,        // Collection (Application)
0x85, 0x01,        //   Report ID (1)
0x09, 0x01,        //   Usage (Pointer)
0xA1, 0x00,        //   Collection (Physical)
0x05, 0x09,        //     Usage Page (Button)
0x19, 0x01,        //     Usage Minimum (0x01)
0x29, 0x02,        //     Usage Maximum (0x02)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x75, 0x01,        //     Report Size (1)
0x95, 0x02,        //     Report Count (2)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x06,        //     Report Count (6)
0x81, 0x03,        //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x09, 0x30,        //     Usage (X)
0x09, 0x31,        //     Usage (Y)
0x09, 0x38,        //     Usage (Wheel)
0x15, 0x81,        //     Logical Minimum (-127)
0x25, 0x7F,        //     Logical Maximum (127)
0x75, 0x08,        //     Report Size (8)
0x95, 0x03,        //     Report Count (3)
0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x0C,        //     Usage Page (Consumer)
0x0A, 0x38, 0x02,  //     Usage (AC Pan)
0x95, 0x01,        //     Report Count (1)
0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x75, 0x08,        //     Report Size (8)
0x95, 0x03,        //     Report Count (3)
0x81, 0x03,        //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0xC0,              // End Collection
0x05, 0x0D,        // Usage Page (Digitizer)
0x09, 0x05,        // Usage (Touch Pad)
0xA1, 0x01,        // Collection (Application)
0x85, 0x04,        //   Report ID (4)
0x09, 0x22,        //   Usage (Finger)
0xA1, 0x02,        //   Collection (Logical)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x09, 0x47,        //     Usage (0x47)
0x09, 0x42,        //     Usage (Tip Switch)
0x95, 0x02,        //     Report Count (2)
0x75, 0x01,        //     Report Size (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x75, 0x01,        //     Report Size (1)
0x95, 0x02,        //     Report Count (2)
0x81, 0x03,        //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01,        //     Report Count (1)
0x75, 0x04,        //     Report Size (4)
0x25, 0x0F,        //     Logical Maximum (15)
0x09, 0x51,        //     Usage (0x51)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x15, 0x00,        //     Logical Minimum (0)
0x26, 0x80, 0x0C,  //     Logical Maximum (3200)
0x75, 0x10,        //     Report Size (16)
0x55, 0x0E,        //     Unit Exponent (-2)
0x65, 0x13,        //     Unit (System: English Linear, Length: Centimeter)
0x09, 0x30,        //     Usage (X)
0x35, 0x00,        //     Physical Minimum (0)
0x46, 0x90, 0x01,  //     Physical Maximum (400)
0x95, 0x01,        //     Report Count (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x46, 0x13, 0x01,  //     Physical Maximum (275)
0x26, 0x96, 0x08,  //     Logical Maximum (2198)
0x26, 0x96, 0x08,  //     Logical Maximum (2198)
0x09, 0x31,        //     Usage (Y)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x0D,        //     Usage Page (Digitizer)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x64,        //     Logical Maximum (100)
0x95, 0x03,        //     Report Count (3)
0xC0,              //   End Collection
0x55, 0x0C,        //   Unit Exponent (-4)
0x66, 0x01, 0x10,  //   Unit (System: SI Linear, Time: Seconds)
0x47, 0xFF, 0xFF, 0x00, 0x00,  //   Physical Maximum (65534)
0x27, 0xFF, 0xFF, 0x00, 0x00,  //   Logical Maximum (65534)
0x75, 0x10,        //   Report Size (16)
0x95, 0x01,        //   Report Count (1)
0x09, 0x56,        //   Usage (0x56)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x54,        //   Usage (0x54)
0x25, 0x7F,        //   Logical Maximum (127)
0x95, 0x01,        //   Report Count (1)
0x75, 0x08,        //   Report Size (8)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x09,        //   Usage Page (Button)
0x09, 0x01,        //   Usage (0x01)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x01,        //   Report Count (1)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x07,        //   Report Count (7)
0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0xC5,        //   Usage (0xC5)
0x75, 0x08,        //   Report Size (8)
0x95, 0x04,        //   Report Count (4)
0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x0D,        //   Usage Page (Digitizer)
0x85, 0x02,        //   Report ID (2)
0x09, 0x55,        //   Usage (0x55)
0x09, 0x59,        //   Usage (0x59)
0x75, 0x04,        //   Report Size (4)
0x95, 0x02,        //   Report Count (2)
0x25, 0x0F,        //   Logical Maximum (15)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x07,        //   Report ID (7)
0x09, 0x60,        //   Usage (0x60)
0x75, 0x01,        //   Report Size (1)
0x95, 0x01,        //   Report Count (1)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x0F,        //   Report Count (15)
0xB1, 0x03,        //   Feature (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x06, 0x00, 0xFF,  //   Usage Page (Vendor Defined 0xFF00)
0x06, 0x00, 0xFF,  //   Usage Page (Vendor Defined 0xFF00)
0x85, 0x06,        //   Report ID (6)
0x09, 0xC5,        //   Usage (0xC5)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x96, 0x00, 0x01,  //   Report Count (256)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x0D,        //   Report ID (13)
0x09, 0xC4,        //   Usage (0xC4)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x04,        //   Report Count (4)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x0C,        //   Report ID (12)
0x09, 0xC6,        //   Usage (0xC6)
0x96, 0x8A, 0x02,  //   Report Count (650)
0x75, 0x08,        //   Report Size (8)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x0B,        //   Report ID (11)
0x09, 0xC7,        //   Usage (0xC7)
0x95, 0x80,        //   Report Count (-128)
0x75, 0x08,        //   Report Size (8)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection
0x05, 0x0D,        // Usage Page (Digitizer)
0x09, 0x0E,        // Usage (0x0E)
0xA1, 0x01,        // Collection (Application)
0x85, 0x03,        //   Report ID (3)
0x09, 0x22,        //   Usage (Finger)
0xA1, 0x00,        //   Collection (Physical)
0x09, 0x52,        //     Usage (0x52)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x0A,        //     Logical Maximum (10)
0x75, 0x10,        //     Report Size (16)
0x95, 0x01,        //     Report Count (1)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0x09, 0x22,        //   Usage (Finger)
0xA1, 0x00,        //   Collection (Physical)
0x85, 0x05,        //     Report ID (5)
0x09, 0x57,        //     Usage (0x57)
0x09, 0x58,        //     Usage (0x58)
0x15, 0x00,        //     Logical Minimum (0)
0x75, 0x01,        //     Report Size (1)
0x95, 0x02,        //     Report Count (2)
0x25, 0x03,        //     Logical Maximum (3)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x0E,        //     Report Count (14)
0xB1, 0x03,        //     Feature (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xC0,              // End Collection

// 356 bytes
In D16698#455371, @wulf wrote:

We have the wmt driver but right now it's *touchscreen*-only and (of course) USB-only.

I have half-completed (it is working for me!) WIP port of wmt for i2c bus https://github.com/wulf7/iichid.

@wulf, please explain how to test this driver. Should I just compile new iichid.ko (running make in the input directory), leaving all other modules built from the source of this thread? Should I remove evdev support from the kernel? Can you please share your xorg configuration?

wulf added a comment.Fri, Jul 19, 9:13 PM

Parsed:

0x05, 0x0D,        // Usage Page (Digitizer)
0x09, 0x05,        // Usage (Touch Pad)
0xA1, 0x01,        // Collection (Application)
0x85, 0x04,        //   Report ID (4)
0x09, 0x22,        //   Usage (Finger)
0xA1, 0x02,        //   Collection (Logical)

It looks like multitouch HID report descriptor.
I am not sure if your touchpad sends such reports out of box.
You can uncomment line 609 from iichid.c

//      device_printf(sc->dev, "id: %d\n", id);

and than look at ids it printfing.
For your touchpad "1" means relative mouse report and "4" means absolute touchpad report
"4" is required for "MS precission touchpad" to work

wulf added a comment.Fri, Jul 19, 9:31 PM

@wulf, please explain how to test this driver. Should I just compile new iichid.ko (running make in the input directory),

just unpack it at your $HOME. Than

make && sudo kldload ./iichid.ko

leaving all other modules built from the source of this thread?

drivers from this review should be at least unloaded from kernel. There is no need to revert D16698 patch. Just don't try to kldload both modules in between reboots.

Should I remove evdev support from the kernel?

No need. It links with evdev unconditionally

Can you please share your xorg configuration?

I do not have any specific xorg.conf options. Any evdev-awared autoconfiguration backend should work out of box. See https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=196678 for example.

In D16698#455669, @wulf wrote:

@wulf, please explain how to test this driver. Should I just compile new iichid.ko (running make in the input directory),

just unpack it at your $HOME. Than

make && sudo kldload ./iichid.ko

[...]

@wulf, thanks! Ok, after kldloading new iichid.ko (with just ig4 already loaded) I got this:

Jul 20 16:15:25 thorium kernel: acpi_iichid0: <HID over I2C (ACPI)> irq 109 on acpi0
Jul 20 16:15:25 thorium kernel: imt0:   ACPI Hardware ID  : ELAN1200
Jul 20 16:15:25 thorium kernel: imt0:   IICbus addr       : 0x15
Jul 20 16:15:25 thorium kernel: imt0:   HID descriptor reg: 0x01
Jul 20 16:15:25 thorium kernel: imt0: HID command I2C_HID_CMD_SET_POWER(0)
Jul 20 16:15:25 thorium kernel: imt0: HID command I2C_HID_CMD_RESET
Jul 20 16:15:25 thorium kernel: imt0: HID command I2C_HID_REPORT_DESCR at 0x2 with size 356
Jul 20 16:15:25 thorium kernel: imt0: HID report descriptor: 05 01 09 02 a1 01 85 01 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 75 01 95 02 81 02 95 06 81 03 05 01 09 30 09 31 09 38 15 81 25 7f 75 08 95 03 81 06 05 0c 0a 38 02 95 01 81 06 75 08 95 03 81 03 c0 c0 05 0d 09 05 a1 01 85 04 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 75 01 95 02 81 03 95 01 75 04 25 0f 09 51 81 02 05 01 15 00 26 80 0c 75 10 55 0e 65 13 09 30 35 00 46 90 01 95 01 81 02 46 13 01 26 96 08 26 96 08 09 31 81 02 05 0d 15 00 25 64 95 03 c0 55 0c 66 01 10 47 ff ff 00 00 27 ff ff 00 00 75 10 95 01 09 56 81 02 09 54 25 7f 95 01 75 08 81 02 05 09 09 01 25 01 75 01 95 01 81 02 95 07 81 03 09 c5 75 08 95 04 81 03 05 0d 85 02 09 55 09 59 75 04 95 02 25 0f b1 02 85 07 09 60 75 01 95 01 15 00 25 01 b1 02 95 0f b1 03 06 00 ff 06 00 ff 85 06 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 85 0d 09 c4 15 00 26 ff 00 75 08 95 04 b1 02 85 0c 09 c6 96 8a 02 75 08 b1 02 85 0b 09 c7 95 80 75 08 b1 02 c0 05 0d 09 0e a1 01 85 03 09 22 a1 00 09 52 15 00 25 0a 75 10 95 01 b1 02 c0 09 22 a1 00 85 05 09 57 09 58 15 00 75 01 95 02 25 03 b1 02 95 0e b1 03 c0 c0
Jul 20 16:15:25 thorium kernel: imt0: HID command I2C_HID_CMD_SET_POWER(1)
Jul 20 16:15:25 thorium kernel: iicbus1: <unknown card> at addr 0x15

Unlike with previous driver, I don't see /dev/input/event3 (HID over IIC) anymore. Just this:

Device:           System mouse
Kernel:           /dev/input/event1
Group:            2
Seat:             seat0, default
Capabilities:     pointer 
Tap-to-click:     n/a
Tap-and-drag:     n/a
Tap drag lock:    n/a
Left-handed:      disabled
Nat.scrolling:    disabled
Middle emulation: disabled
Calibration:      n/a
Scroll methods:   button
Click methods:    none
Disable-w-typing: n/a
Accel profiles:   flat *adaptive
Rotation:         n/a

You can uncomment line 609 from iichid.c

//      device_printf(sc->dev, "id: %d\n", id);

and than look at ids it printfing.
For your touchpad "1" means relative mouse report and "4" means absolute touchpad report
"4" is required for "MS precission touchpad" to work

Hm, I don't see such a line anywhere.

Any evdev-awared autoconfiguration backend should work out of box.

Sorry for my xorg illiteracy, but I couldn't get touchpad working after kldload ./iichid.ko in any way... :(

How to proceed? New iichid.ko dmesg looks promising, I'd say. :)

wulf added a comment.Sun, Jul 21, 12:56 PM

Unlike with previous driver, I don't see /dev/input/event3 (HID over IIC) anymore.

That is expected as it ignored any touchpads

I added some basic touchpad support (surface touches only, no buttons) so you can try it again
Unfortunately, it is untested.

In D16698#455907, @wulf wrote:

Unlike with previous driver, I don't see /dev/input/event3 (HID over IIC) anymore.

That is expected as it ignored any touchpads
I added some basic touchpad support (surface touches only, no buttons) so you can try it again
Unfortunately, it is untested.

Great, it's now seen as a touchpad; its capabilities detected. Here are my new dmesg/logs etc. The only problem -- the device is still dead; it generates nothing with libinput debug-events, and no events in xev.

Jul 21 16:03:55 thorium kernel: acpi_iichid0: <HID over I2C (ACPI)> on acpi0
Jul 21 16:03:55 thorium kernel: imt0:   ACPI Hardware ID  : ELAN1200
Jul 21 16:03:55 thorium kernel: imt0:   IICbus addr       : 0x15
Jul 21 16:03:55 thorium kernel: imt0:   HID descriptor reg: 0x01
Jul 21 16:03:55 thorium kernel: imt0: HID command I2C_HID_CMD_SET_POWER(0)
Jul 21 16:03:55 thorium kernel: imt0: HID command I2C_HID_CMD_RESET
Jul 21 16:03:55 thorium kernel: imt0: HID command I2C_HID_REPORT_DESCR at 0x2 with size 356
Jul 21 16:03:55 thorium kernel: imt0: HID report descriptor: 05 01 09 02 a1 01 85 01 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 75 01 95 02 81 02 95 06 81 03 05 01 09 30 09 31 09 38 15 81 25 7f 75 08 95 03 81 06 05 0c 0a 38 02 95 01 81 06 75 08 95 03 81 03 c0 c0 05 0d 09 05 a1 01 85 04 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 75 01 95 02 81 03 95 01 75 04 25 0f 09 51 81 02 05 01 15 00 26 80 0c 75 10 55 0e 65 13 09 30 35 00 46 90 01 95 01 81 02 46 13 01 26 96 08 26 96 08 09 31 81 02 05 0d 15 00 25 64 95 03 c0 55 0c 66 01 10 47 ff ff 00 00 27 ff ff 00 00 75 10 95 01 09 56 81 02 09 54 25 7f 95 01 75 08 81 02 05 09 09 01 25 01 75 01 95 01 81 02 95 07 81 03 09 c5 75 08 95 04 81 03 05 0d 85 02 09 55 09 59 75 04 95 02 25 0f b1 02 85 07 09 60 75 01 95 01 15 00 25 01 b1 02 95 0f b1 03 06 00 ff 06 00 ff 85 06 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 85 0d 09 c4 15 00 26 ff 00 75 08 95 04 b1 02 85 0c 09 c6 96 8a 02 75 08 b1 02 85 0b 09 c7 95 80 75 08 b1 02 c0 05 0d 09 0e a1 01 85 03 09 22 a1 00 09 52 15 00 25 0a 75 10 95 01 b1 02 c0 09 22 a1 00 85 05 09 57 09 58 15 00 75 01 95 02 25 03 b1 02 95 0e b1 03 c0 c0
Jul 21 16:03:55 thorium kernel: imt0: HID command I2C_HID_REPORT_DESCR at 0x2 with size 356
Jul 21 16:03:55 thorium kernel: imt0: HID report descriptor: 05 01 09 02 a1 01 85 01 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 75 01 95 02 81 02 95 06 81 03 05 01 09 30 09 31 09 38 15 81 25 7f 75 08 95 03 81 06 05 0c 0a 38 02 95 01 81 06 75 08 95 03 81 03 c0 c0 05 0d 09 05 a1 01 85 04 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 75 01 95 02 81 03 95 01 75 04 25 0f 09 51 81 02 05 01 15 00 26 80 0c 75 10 55 0e 65 13 09 30 35 00 46 90 01 95 01 81 02 46 13 01 26 96 08 26 96 08 09 31 81 02 05 0d 15 00 25 64 95 03 c0 55 0c 66 01 10 47 ff ff 00 00 27 ff ff 00 00 75 10 95 01 09 56 81 02 09 54 25 7f 95 01 75 08 81 02 05 09 09 01 25 01 75 01 95 01 81 02 95 07 81 03 09 c5 75 08 95 04 81 03 05 0d 85 02 09 55 09 59 75 04 95 02 25 0f b1 02 85 07 09 60 75 01 95 01 15 00 25 01 b1 02 95 0f b1 03 06 00 ff 06 00 ff 85 06 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 85 0d 09 c4 15 00 26 ff 00 75 08 95 04 b1 02 85 0c 09 c6 96 8a 02 75 08 b1 02 85 0b 09 c7 95 80 75 08 b1 02 c0 05 0d 09 0e a1 01 85 03 09 22 a1 00 09 52 15 00 25 0a 75 10 95 01 b1 02 c0 09 22 a1 00 85 05 09 57 09 58 15 00 75 01 95 02 25 03 b1 02 95 0e b1 03 c0 c0
Jul 21 16:03:55 thorium kernel: imt0: <ELAN1200> at addr 0x15 irq 109 on iicbus1
Jul 21 16:03:55 thorium kernel: imt0: HID command I2C_HID_REPORT_DESCR at 0x2 with size 356
Jul 21 16:03:55 thorium kernel: imt0: HID report descriptor: 05 01 09 02 a1 01 85 01 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 75 01 95 02 81 02 95 06 81 03 05 01 09 30 09 31 09 38 15 81 25 7f 75 08 95 03 81 06 05 0c 0a 38 02 95 01 81 06 75 08 95 03 81 03 c0 c0 05 0d 09 05 a1 01 85 04 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 75 01 95 02 81 03 95 01 75 04 25 0f 09 51 81 02 05 01 15 00 26 80 0c 75 10 55 0e 65 13 09 30 35 00 46 90 01 95 01 81 02 46 13 01 26 96 08 26 96 08 09 31 81 02 05 0d 15 00 25 64 95 03 c0 55 0c 66 01 10 47 ff ff 00 00 27 ff ff 00 00 75 10 95 01 09 56 81 02 09 54 25 7f 95 01 75 08 81 02 05 09 09 01 25 01 75 01 95 01 81 02 95 07 81 03 09 c5 75 08 95 04 81 03 05 0d 85 02 09 55 09 59 75 04 95 02 25 0f b1 02 85 07 09 60 75 01 95 01 15 00 25 01 b1 02 95 0f b1 03 06 00 ff 06 00 ff 85 06 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 85 0d 09 c4 15 00 26 ff 00 75 08 95 04 b1 02 85 0c 09 c6 96 8a 02 75 08 b1 02 85 0b 09 c7 95 80 75 08 b1 02 c0 05 0d 09 0e a1 01 85 03 09 22 a1 00 09 52 15 00 25 0a 75 10 95 01 b1 02 c0 09 22 a1 00 85 05 09 57 09 58 15 00 75 01 95 02 25 03 b1 02 95 0e b1 03 c0 c0
Jul 21 16:03:55 thorium kernel: imt0: 15 contacts and [C]. Report range [0:0] - [3200:2198]
Jul 21 16:03:55 thorium kernel: imt0: HID command I2C_HID_CMD_GET_REPORT 2 (type 3, len 1)
Jul 21 16:03:55 thorium kernel: imt0: response: 04 00 02 05
Jul 21 16:03:55 thorium kernel: imt0: 5 feature report contactsimt0: HID command I2C_HID_CMD_GET_REPORT 6 (type 3, len 256)
Jul 21 16:03:55 thorium kernel: imt0: response: 03 01 06 fc 28 fe 84 40 cb 9a 87 0d be 57 3c b6 70 09 88 07 97 2d 2b e3 38 34 b6 6c ed b0 f7 e5 9c f6 c2 2e 84 1b e8 b4 51 78 43 1f 28 4b 7c 2d 53 af fc 47 70 1b 59 6f 74 43 c4 f3 47 18 53 1a a2 a1 71 c7 95 0e 31 55 21 d3 b5 1e e9 0c ba ec b8 89 19 3e b3 af 75 81 9d 53 b9 41 57 f4 6d 39 25 29 7c 87 d9 b4 98 45 7d a7 26 9c 65 3b 85 68 89 d7 3b bd ff 14 67 f2 2b f0 2a 41 54 f0 fd 2c 66 7c f8 c0 8f 33 13 03 f1 d3 c1 0b 89 d9 1b 62 cd 51 b7 80 b8 af 3a 10 c1 8a 5b e8 8a 56 f0 8c aa fa 35 e9 42 c4 d8 55 c3 38 cc 2b 53 5c 69 52 d5 c8 73 02 38 7c 73 b6 41 e7 ff 05 d8 2b 79 9a e2 34 60 8f a3 32 1f 09 78 62 bc 80 e3 0f bd 65 20 08 13 c1 e2 ee 53 2d 86 7e a7 5a c5 d3 7d 98 be 31 48 1f fb da af a2 a8 6a 89 d6 bf f2 d3 32 2a 9a e4 cf 17 b7 b8 f4 e1 33 08 24 8b c4 43 a5 e5 24 c2
Jul 21 16:03:55 thorium kernel: imt0: HID command I2C_HID_CMD_SET_POWER(1)
Jul 21 16:03:55 thorium kernel: imt0: IRQ allocation failed. Fallback to sampling.
...
Jul 21 16:06:11 thorium kernel: imt0: iichid device open
Jul 21 16:06:11 thorium kernel: imt0: imt0: HID command I2C_HID_CMD_SET_POWER(0)
Jul 21 16:06:11 thorium kernel: iichid device close
Jul 21 16:06:11 thorium kernel: imt0: iichid device open
Jul 21 16:06:11 thorium kernel: imt0: successfully setup callout
...

Jul 21 16:07:08 thorium kernel: imt0: iichid device close
Jul 21 16:07:08 thorium kernel: imt0: HID command I2C_HID_CMD_SET_POWER(1)
Jul 21 16:07:08 thorium kernel: imt0: tore callout down

sysctl's:

# sysctl -a | grep iic
irq17: ig4iic_pci1:33 @cpu0(domain0): 479263
irq18: ig4iic_pci2:35 @cpu0(domain0): 0
dev.iic.2.%parent: iicbus2
dev.iic.2.%pnpinfo:
dev.iic.2.%location: addr=0
dev.iic.2.%driver: iic
dev.iic.2.%desc: I2C generic I/O
dev.iic.1.%parent: iicbus1
dev.iic.1.%pnpinfo:
dev.iic.1.%location: addr=0
dev.iic.1.%driver: iic
dev.iic.1.%desc: I2C generic I/O
dev.iic.0.%parent: iicbus0
dev.iic.0.%pnpinfo:
dev.iic.0.%location: addr=0
dev.iic.0.%driver: iic
dev.iic.0.%desc: I2C generic I/O
dev.iic.%parent:
dev.imt.0.%parent: iicbus1
dev.acpi_iichid.0.%parent: acpi0
dev.acpi_iichid.0.%pnpinfo: _HID=ELAN1200 _UID=1
dev.acpi_iichid.0.%location: handle=\_SB_.PCI0.I2C1.ETPD
dev.acpi_iichid.0.%driver: acpi_iichid
dev.acpi_iichid.0.%desc: HID over I2C (ACPI)
dev.acpi_iichid.%parent:
dev.iicbus.2.frequency: 100000
dev.iicbus.2.%parent: ig4iic_pci2
dev.iicbus.2.%pnpinfo:
dev.iicbus.2.%location:
dev.iicbus.2.%driver: iicbus
dev.iicbus.2.%desc: Philips I2C bus
dev.iicbus.1.frequency: 100000
dev.iicbus.1.%parent: ig4iic_pci1
dev.iicbus.1.%pnpinfo:
dev.iicbus.1.%location:
dev.iicbus.1.%driver: iicbus
dev.iicbus.1.%desc: Philips I2C bus
dev.iicbus.0.frequency: 100000
dev.iicbus.0.%parent: ig4iic_pci0
dev.iicbus.0.%pnpinfo:
dev.iicbus.0.%location:
dev.iicbus.0.%driver: iicbus
dev.iicbus.0.%desc: Philips I2C bus
dev.iicbus.%parent:
dev.ig4iic_pci.2.%parent: pci0
dev.ig4iic_pci.2.%pnpinfo: vendor=0x8086 device=0x9d62 subvendor=0x1043 subdevice=0x1e30 class=0x118000
dev.ig4iic_pci.2.%location: slot=21 function=2 dbsf=pci0:0:21:2 handle=\_SB_.PCI0.I2C2
dev.ig4iic_pci.2.%driver: ig4iic_pci
dev.ig4iic_pci.2.%desc: Intel Sunrise Point-LP I2C Controller-2
dev.ig4iic_pci.1.%parent: pci0
dev.ig4iic_pci.1.%pnpinfo: vendor=0x8086 device=0x9d61 subvendor=0x1043 subdevice=0x1e30 class=0x118000
dev.ig4iic_pci.1.%location: slot=21 function=1 dbsf=pci0:0:21:1 handle=\_SB_.PCI0.I2C1
dev.ig4iic_pci.1.%driver: ig4iic_pci
dev.ig4iic_pci.1.%desc: Intel Sunrise Point-LP I2C Controller-1
dev.ig4iic_pci.0.%parent: pci0
dev.ig4iic_pci.0.%pnpinfo: vendor=0x8086 device=0x9d60 subvendor=0x1043 subdevice=0x1e30 class=0x118000
dev.ig4iic_pci.0.%location: slot=21 function=0 dbsf=pci0:0:21:0 handle=\_SB_.PCI0.I2C0
dev.ig4iic_pci.0.%driver: ig4iic_pci
dev.ig4iic_pci.0.%desc: Intel Sunrise Point-LP I2C Controller-0
dev.ig4iic_pci.%parent:

libinput says:

-event0   DEVICE_ADDED     System keyboard multiplexer       seat0 default group1  cap:k
-event1   DEVICE_ADDED     System mouse                      seat0 default group2  cap:p left scroll-nat scroll-button
-event2   DEVICE_ADDED     AT keyboard                       seat0 default group3  cap:k
-event3   DEVICE_ADDED     ELAN1200                          seat0 default group4  cap:pg  size 103x71mm tap(dl off) left scroll-nat scroll-2fg-edge dwt-on

and

Device:           ELAN1200
Kernel:           /dev/input/event3
Group:            4
Seat:             seat0, default
Size:             103x71mm
Capabilities:     pointer gesture
Tap-to-click:     enabled
Tap-and-drag:     enabled
Tap drag lock:    disabled
Left-handed:      disabled
Nat.scrolling:    disabled
Middle emulation: n/a
Calibration:      n/a
Scroll methods:   *two-finger edge
Click methods:    none
Disable-w-typing: enabled
Accel profiles:   none
Rotation:         n/a

Xorg log:

[   506.771] (II) Using input driver 'libinput' for 'Touchpad1'
[   506.771] (**) Option "CorePointer"
[   506.771] (**) Touchpad1: always reports core events
[   506.771] (**) Option "Device" "/dev/input/event3"
[   506.773] (II) event3  - ELAN1200: is tagged by udev as: Mouse Touchpad
[   506.773] (II) event3  - ELAN1200: device is a touchpad
[   506.773] (II) event3  - ELAN1200: device removed
[   506.773] (**) Option "Tapping" "on"
[   506.773] (**) Option "TappingDrag" "true"
[   506.773] (**) Option "NaturalScrolling" "true"
[   506.773] (**) Option "ScrollMethod" "twofinger"
[   506.773] (**) Option "HorizontalScrolling" "true"
[   506.773] (II) XINPUT: Adding extended input device "Touchpad1" (type: TOUCHPAD, id 6)
[   506.773] (**) Option "AccelerationScheme" "none"
[   506.773] (**) Touchpad1: (accel) selected scheme none/0
[   506.773] (**) Touchpad1: (accel) acceleration factor: 2.000
[   506.773] (**) Touchpad1: (accel) acceleration threshold: 4
[   506.774] (II) event3  - ELAN1200: is tagged by udev as: Mouse Touchpad
[   506.774] (II) event3  - ELAN1200: device is a touchpad

xinput:

⎡ Virtual core pointer                          id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ Touchpad1                                 id=6    [slave  pointer  (2)]
⎜   ↳ sysmouse                                  id=8    [slave  pointer  (2)]
⎣ Virtual core keyboard                         id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ kbdmux                                    id=7    [slave  keyboard (3)]