Skip to content

Building Usage and Troubleshooting

Syax89 edited this page Jul 8, 2026 · 5 revisions

Building, Usage and Troubleshooting

Building

make LLVM=1 -C /lib/modules/$(uname -r)/build M=$PWD/driver modules

LLVM=1 is required — this codebase relies on clang-only build flags; a plain gcc build fails.

Loading

Manually:

sudo rmmod spi_hid spi_amd 2>/dev/null
sudo insmod driver/spi-amd.ko
sudo insmod driver/spi-hid.ko

Or, for auto-load at every boot (recommended for daily use — loads standard mode, raw_mode=0), install driver/sl4a-touch.service as a systemd unit:

sudo cp driver/sl4a-touch.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now sl4a-touch.service

After loading successfully, the touchscreen appears as:

  • /dev/input/eventNspi 045E:0C19 (ABS_X, ABS_Y, BTN_TOUCH) for touch
  • /dev/input/eventNspi 045E:0C19 Stylus for the pen

Check with dmesg | grep -E "SEQ|spi-hid|hid-generic" — a successful load ends with a line like hid-generic ...: input,hidraw3: SPI HID v1.00 Device [spi 045E:0C19] on spi-MSHW0231:00.

Rebuilding after driver changes or a kernel update

Out-of-tree modules like these are built against one specific kernel version — after a kernel update, sl4a-touch.service will fail to load the (now stale) .ko files until they're rebuilt. tools/rebuild_and_install.sh automates this: it rebuilds both modules for the currently running kernel, re-syncs the systemd unit file if it changed, and reloads via the service.

./tools/rebuild_and_install.sh

Pass extra arguments to do a one-off manual load with module parameters instead (e.g. to try raw_mode=1) — this bypasses the systemd service for that single run only; the service itself always loads with no parameters:

./tools/rebuild_and_install.sh raw_mode=1 debug_coords=1

Module parameters (spi-hid.ko)

Parameter Default Meaning
raw_mode 0 (off) 1 = experimental raw heatmap multi-touch mode. See Multi-touch Experimental
debug_coords 0 (off) Log blob grid coordinates/weights (raw_mode=1 only)
invert_x, invert_y, swap_xy 0 (off) Axis calibration knobs for the blob detector
setfeat_speed_hz 0 (bus default, 33.33MHz) Override SPI clock speed for the SET_FEATURE write only — an experiment, no known effect (see Multi-touch Experimental)
setfeat_no_double 0 (off) Send SET_FEATURE without the opcode-doubling quirk — makes things worse, kept only for future experiments

Pass at insmod time, e.g.: sudo insmod driver/spi-hid.ko raw_mode=1 debug_coords=1. Most are also runtime-writable via /sys/module/spi_hid/parameters/<name> (0644), though several (like raw_mode) only take effect on the next device bind, not retroactively.

Debugging

sudo dmesg -w | grep "SEQ\|spi-hid"

The state machine logs its own state transitions (SEQ: thread seq_state=N) and every header/type it decodes (SEQ[state=N] type=T hdr=[...]) — very verbose by design, since this device's behavior is still not fully understood (see Further Reading for the deep investigation history).

Recovery tools

  • tools/reset_touch.sh — power-cycles just the touchscreen via the ACPI \M010 GPIO method, without touching the loaded modules or requiring a full reboot. Useful any time the device seems stuck (in particular, some raw_mode=1 recovery scenarios).

    sudo ./tools/reset_touch.sh
  • Full reboot — the only reliable way back to standard mode once raw_mode=1 has actually switched the device into raw streaming (see Multi-touch Experimental).

Common issues

  • hid-generic never binds / no input devices appear — check dmesg for SEQ: ll_parse lines; if it says "device-read report descriptor failed to parse", the driver should automatically retry with the hardcoded fallback (see Report Descriptor) — if it doesn't, that's a real bug worth reporting.
  • raw_mode=1 never streams data — expected some of the time; see Multi-touch Experimental for the known reliability issue and what the built-in watchdog does about it.
  • Touch stopped working after testing raw_mode=1 — reboot. See the warning at the top of Multi-touch Experimental.

Clone this wiki locally