wulf7/iichid: Generic HID layer for FreeBSD. Including I2C and USB backends.
Driver on

wulf7/iichid: Generic HID layer for FreeBSD. Including I2C and USB backends.

iichid is a set of summary HID drivers for FreeBSD. All of the drivers use evdev
protocol to speak with userland functions like libinput and
xf86-input-evdev. hidbus is used to attach HID drivers with transport
backends (usbhid for USB and iichid for I2C) and permits a number of HID drivers
to connect to a single bodily system.

Present drivers and respective HID units supported by them are following:

  • hms – HID mouses. Bodily relative units with curler or optical sensor
    are supported in addition to digital absolute units like VBox, Bhyve and VMWare
  • hmt – MS Home windows 7+ suitable Multi-touch units like touchscreens
    and precission touchpads.
  • hconf – Mouse/touchpad mode switches on precission touchpads.
  • hkbd – HID keyboards. AT-key subset.
  • hskbd – Easy evdev-only HID keyboard driver.
  • hpen – Generic / MS Home windows suitable HID pen tablets.
  • hcons – Client web page AKA Multimedia keys.
  • hsctrl – System Controls web page (Energy/Sleep keys).
  • hgame – Recreation controllers together with Xbox360-compatible and joysticks.
  • hidraw – Export uncooked HID knowledge in uhid(4) and Linux hidraw-compatible approach.

System necessities

FreeBSD 12.1+. Latest (any from 2020) CURRENT or 12-STABLE are most popular.


This venture doesn’t have a particular dwelling web page. The supply code and the
situation tracker are hosted on the Github:



To construct driver, cd in to extracted archive listing and sort

$ make

You want the sources of the working working system underneath /usr/src

Putting in

To put in file already constructed simply sort:

$ sudo make set up

and you’ll get the compiled module put in in /boot/modules

To load the module at a boot time, add each I2C driver module (it’s normally
an ig4) and HID module iichid to kld_list variable in
/and so on/rc.conf.

To deal with keyboards in single consumer mode and on the early levels
of booting course of, iichid ought to be loaded at kernel startup.
Add following traces to /boot/loader.conf in that case:


Configure Xorg

Usually talking, it’s a unhealthy thought to make use of static Xorg configuration for
evdev units as a result of dynamic unit quantity task. The best approach
to get new units acknowledged by Xorg-server is to rebuild it with DEVD
(since 1.20.7) or UDEV autoconfiguration backend enabled.

Static configuration remains to be doable. Add following snippet to a file underneath
/usr/native/and so on/X11/xorg.conf.d/

Part "InputDevice"
	Identifier "HID system"
	Driver "libinput"
	Possibility "Machine" "/dev/enter/event6"
	Possibility "AutoServerLayout" "true"

Chances are you’ll have to run sudo libinput list-devices to seek out out unit quantity
belonging to given system. Notice that it could actually change throughout reboots.


USB transport backend can (and normally does) intervene with OS built-in USB
HID drivers like uhid, ukbd, ums and wmt. Which one will likely be
energetic is depend upon the order of loading, so genarally you must load
iichid.ko from bootloader. Within the case if the module is loaded
with kldload it’s essential to situation

$ sudo usbconfig -d ugenX.X reset

command to drive ugenX.X system reprobe at working system run time. ugenX.X
to reprobe could be discovered with issuing of straightforward usbconfig command:

$ sudo usbconfig

It’s doable to construct iichid with USB assist disabled with following


I2C transport backend sampling (polling) mode

Presently iichid is unable to make the most of GPIO interrupts on i386 and amd64
platforms as a result of absence of INTRNG assist in PIC drivers and can’t use any
interrupts on 12.1-RELEASE as a result of lack of ability of ig4 driver to work in
ithread context in 12.1. On this case it fallbacks to so known as sampling
mode with periodic polling of {hardware} by driver. It’s doable to examine
mode with following command:

$ sysctl dev.iichid.0.sampling_rate_slow

Any constructive quantity returned signifies that sampling mode is enabled.

Unfortunatelly, utilizing of sampling mode results in lose of some knowledge and
usually ends in glitches. Most identified are “drift of inactive mouse pointer”
and “caught of single finger contact”. iichid has some inner hacks to
workaround them however they don’t seem to be dependable.

Selecting of optimum sampling charge for I2C transport.

Sampling charge is about to 60Hz by default. Though principally it simply works, in
some circumstances e.g. if system inner scan charge decrease than polling frequence
it ends in studying of empty studies, doubling of them or different undesirable

Sometimes driver polling frequency ought to be set to about 0.9 of system
inner scan charge. The best approach to measure it’s to run a Linux stay
distro from USB flash than execute evemu-record utility and select your I2C
system. Than you must convert inter-report interval length to Hz and
set 0.9 of that worth as sampling_rate_fast parameter with following command

$ sudo sysctl dev.iichid.0.sampling_rate_fast=

In case your system is supported by hmt driver, scan charge could be obtained by
analyze of {hardware} timestamps. To allow them HQ_MT_TIMESTAMP quirk ought to
be set for HID system. At first get vendor and product IDs with following

$ devinfo -rv | grep 'hmt.* bus=0x18'

It’s going to return one thing like:
hmt0 pnpinfo web page=0x000d utilization=0x0004 bus=0x18 vendor=0x06cb product=0x1941 …

Then add following line to /boot/loader.conf changing 0x6cb and 0x1941
with vendor and product values from earlier command output.

hw.hid.quirk.0="0x18 **0x6cb** **0x1941** Zero 0xffff HQ_MT_TIMESTAMP"

That can allow output of {hardware} timestamps in hmt driver after reboot.
Reboot than connect evemu-record to correct node and contact system floor.
You willl see one thing like this on stdout:

E: 33.569577 0004 0005 1152000	# EV_MSC / MSC_TIMESTAMP        1152000
E: 33.569577 0000 0000 0001	# ------------ SYN_REPORT (1) ---------- +18ms
E: 33.587771 0004 0005 1161000	# EV_MSC / MSC_TIMESTAMP        1161000
E: 33.587771 0000 0000 0001	# ------------ SYN_REPORT (1) ---------- +18ms
E: 33.605326 0004 0005 1170000	# EV_MSC / MSC_TIMESTAMP        1170000
E: 33.605326 0000 0000 0001	# ------------ SYN_REPORT (1) ---------- +18ms

Scan charge could be calculated with easy method:

scan_rate = 1000000 / (MSC_TIMESTAMP(X) - MSC_TIMESTAMP(X-1))

the place MSC_TIMESTAMP(X) and MSC_TIMESTAMP(X-1) are values taken from two
consecutive occasions.
In aforementioned instance, optimum polling frequency is anticipated to be

sampling_rate_fast = 0.9 × 1000000 ÷ (1161000 − 1152000) = 100 (Hz)

It’s doable to make use of double of scan_rate as sampling charge with rising
of dev.iichid.0.sampling_hysteresis to three or Four to filter out lacking samples.
Tuning of this worth requires enabling of debug output in I2C transport
and lies out of scope of this README. Usually, sampling_hysteresis ought to
be left as 1 if sampling frequency decrease or equal 0.9 of system scan charge.

Bug reporting

You possibly can report bugs at ‘Mission Points’ web page
It is strongly recommended to surround console output of ‘kldload iichid.ko’ command
along with your report.

Some extra info that may be useful particularly if system has not
been detected in any respect could be obtained with following instructions:

$ devinfo -rv	# Very verbose
$ pciconf -lv
$ sudo usbconfig
$ dmesg

Leave a Reply

Your email address will not be published. Required fields are marked *