Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH v4 0/5] HID: intel-thc-hid: intel-ipts: support THC IPTS ports
@ 2026-11-14 21:40 Emfox Zhou
  2026-11-14 21:40 ` [PATCH v4 1/5] HID: intel-thc-hid: intel-ipts: bring up the port Emfox Zhou
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Emfox Zhou @ 2026-11-14 21:40 UTC (permalink / raw)
  To: Even Xu, Xinpeng Sun, Jiri Kosina, Benjamin Tissoires
  Cc: linux-input, linux-kernel

The THC ports on Tiger Lake, Lakefield, Alder Lake and Raptor Lake run in
IPTS mode: plain SPI with a private framing instead of HIDSPI, which is
all intel-thc-hid handles today. This adds a backend for them next to
intel-quickspi and intel-quicki2c, on top of the same core, and is based
on v7.4-rc2, the first tag with the hid_safe_input_report() it uses.

Register, DMA and interrupt work goes through the exported intel-thc API,
except in four places where the core has no call for it: the reset,
port-supported and quiesce-state bits of THC_M_PRT_CONTROL are accessed
directly. Nothing outside the new directory changes except Kconfig and
Makefile.

The hardware facts - port IDs, configuration block layout, frame codes
and header sizes - come from the ithc driver linux-surface ships, at
https://github.com/quo/ithc-linux 6d53c9c (dual licensed GPL-2.0 /
BSD-2-Clause); no code is taken from it. The layout, the frame format and
the ordering between quiesce, interrupt configuration and the DMA engines
are the parts most likely to need scrutiny; each is argued in the commit
message that relies on it. All of it was confirmed on a Surface Pro 8 with
a 045e:0c37 controller.

The first four patches each leave a state that builds and loads: port
bring-up, DMA and interrupts, HID registration, system sleep. The fifth
documents the controller behaviour the driver relies on, none of which is
written down anywhere else.

On that machine the touchscreen and the pen work through hidraw and iptsd
after patch 3, and three suspend/resume cycles (pm_test=devices) bring
them back after patch 4, with the daemon restarting on its own.

The interrupt is the legacy pin: these ports put requester ID 01:05.0 in
their MSI messages, which is neither their own function nor expressible
as a DMA alias, so with interrupt remapping on the MSI is rejected and the
port stays silent. The pin is shared on the PCH, hence IRQF_SHARED; MSI
is the fallback where no pin is routed.

Ports are matched by PCI ID. These four generations are not in the HIDSPI
ID table, so nothing else claims them, and a port that firmware drives as
HIDSPI has no driver today: this driver gives up with -EIO when the $TIC
tag never appears.

Report handling stops at HID core on purpose: the controller is the one
declaring itself a HID device, so the descriptor comes from it, Windows
exposes the same port the same way, and turning the heatmap into contacts
is user space work that already exists.

Some concerns:

  - Runtime PM is not implemented, and only the Tiger Lake ports were
    tested; Lakefield, Alder Lake and Raptor Lake share the code path but
    have not been run. LTR configuration comes with runtime PM.

  - The SPI clock is one of ten gears the core can program, 7.8 to
    50 MHz, and the core rounds the request down. A controller that asks
    for less than the slowest gear is raised to 7.8 MHz, warned about
    once and carried on with.

  - System sleep takes the HID device down and brings it back, so the
    daemon restarts and asks for the report stream again: the controller
    does not keep that state, and replaying one set feature would not
    cover the several the daemon sends. It also means the touchscreen
    cannot wake the machine.

Link to v3:
https://lore.kernel.org/r/20261114183624.2379573-1-emfox@debian.org

Changes in v4:

  - Divisor 3 asked for 41666666 Hz, 34 Hz below the 41 MHz gear the core
    compares against, so the controller was clocked from the 35 MHz gear
    instead; divisor 12 asked for 10416666 Hz, 42 Hz below the 10 MHz gear,
    and fell two gears to 7 MHz. The division is now rounded the way the
    core's table is.

  - A request that started during a recovery waited out its one second
    timeout on a masked port, holding the bus lock the reset needs. Such a
    request is refused now.

  - Teardown masks the line again once synchronize_irq() and
    cancel_work_sync() have returned: a handler that read ->stopping
    before it was set could unmask after the first mask.

  - An interrupt that arrives while a reset is in flight is reported as not
    handled. The port is masked at that point, so the interrupt belongs to
    another function on the line; claiming it also meant that a reset which
    failed would claim every interrupt on the shared pin from then on.

  - The recovery item masks the port before it resets the engine. A handler
    that was already running could have unmasked the port after the error,
    and the reset has to run with the engine quiet.

  - A feature answer is matched to its request by a serial number. The
    same report asked for twice in a row gave the second request nothing
    to tell a late answer of the first one from its own: the report ID
    matched, so the request could complete with the previous payload.
    The payload is copied out under the same lock now.

Emfox Zhou (5):
  HID: intel-thc-hid: intel-ipts: bring up the port
  HID: intel-thc-hid: intel-ipts: receive reports
  HID: intel-thc-hid: intel-ipts: register the HID device
  HID: intel-thc-hid: intel-ipts: handle system sleep
  HID: intel-thc-hid: intel-ipts: document the IPTS mode

 Documentation/hid/intel-thc-hid.rst           |  95 ++-
 drivers/hid/intel-thc-hid/Kconfig             |  14 +
 drivers/hid/intel-thc-hid/Makefile            |   4 +
 drivers/hid/intel-thc-hid/intel-ipts/ipts.c   | 805 ++++++++++++++++++
 drivers/hid/intel-thc-hid/intel-ipts/ipts.h   | 200 +++++
 .../hid/intel-thc-hid/intel-ipts/pci-ipts.c   | 203 +++++
 6 files changed, 1320 insertions(+), 1 deletion(-)
 create mode 100644 drivers/hid/intel-thc-hid/intel-ipts/ipts.c
 create mode 100644 drivers/hid/intel-thc-hid/intel-ipts/ipts.h
 create mode 100644 drivers/hid/intel-thc-hid/intel-ipts/pci-ipts.c


base-commit: 7475ea8b58616b33c04afb976cf0fbaad9dd63fb

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-11-14 22:00 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-14 21:40 [PATCH v4 0/5] HID: intel-thc-hid: intel-ipts: support THC IPTS ports Emfox Zhou
2026-11-14 21:40 ` [PATCH v4 1/5] HID: intel-thc-hid: intel-ipts: bring up the port Emfox Zhou
2026-11-14 21:40 ` [PATCH v4 2/5] HID: intel-thc-hid: intel-ipts: receive reports Emfox Zhou
2026-11-14 22:00   ` sashiko-bot
2026-11-14 21:40 ` [PATCH v4 3/5] HID: intel-thc-hid: intel-ipts: register the HID device Emfox Zhou
2026-11-14 21:54   ` sashiko-bot
2026-11-14 21:40 ` [PATCH v4 4/5] HID: intel-thc-hid: intel-ipts: handle system sleep Emfox Zhou
2026-11-14 21:40 ` [PATCH v4 5/5] HID: intel-thc-hid: intel-ipts: document the IPTS mode Emfox Zhou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox