From: Emfox Zhou <emfox@debian.org>
To: Even Xu <even.xu@intel.com>, Xinpeng Sun <xinpeng.sun@intel.com>,
Jiri Kosina <jikos@kernel.org>,
Benjamin Tissoires <bentiss@kernel.org>
Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v2 0/5] HID: intel-thc-hid: intel-ipts: support THC IPTS ports
Date: Sun, 15 Nov 2026 01:07:35 +0800 [thread overview]
Message-ID: <20261114170740.2068179-1-emfox@debian.org> (raw)
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
stays as a 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 v1:
https://lore.kernel.org/r/20261114154611.1683519-1-emfox@debian.org
Changes in v2, from the automated review of v1:
- The recovery work item is initialised where it is introduced.
Patch 2 used it and only patch 3 initialised it, which breaks the
bisect.
- A frame read that finds the ring empty no longer passes an
uninitialised length to the frame decoder.
- The port stays masked while the recovery item resets the engine,
and the handler keeps draining the status registers after an error,
so a queued transmit completion is acknowledged instead of timing
out under the bus lock.
- Teardown stops and quiesces the controller before the DMA memory is
released, and takes req_lock around the release: a send already
inside thc_dma_write finishes, later ones fail on ->stopping.
- SET_REPORT returns the byte count, as hidraw expects; zero was
returned before.
- A late or empty report descriptor no longer overwrites the buffer
being parsed, and an empty one is retried instead of registered.
- Feature reports: empty answers are rejected, and the report ID in
an answer is checked against the request. Verified on hardware,
where GET_FEATURE for reports 5, 6, 9 and 17 echoes its own ID.
- Unchanged: the shared interrupt is still claimed unconditionally.
The cause can only be read from the threaded handler, and returning
IRQ_NONE while this port is masked would let the spurious detector
disable a line that other functions share.
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 | 740 ++++++++++++++++++
drivers/hid/intel-thc-hid/intel-ipts/ipts.h | 191 +++++
.../hid/intel-thc-hid/intel-ipts/pci-ipts.c | 198 +++++
6 files changed, 1241 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
next reply other threads:[~2026-11-14 17:08 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-14 17:07 Emfox Zhou [this message]
2026-11-14 17:07 ` [PATCH v2 1/5] HID: intel-thc-hid: intel-ipts: bring up the port Emfox Zhou
2026-11-14 17:07 ` [PATCH v2 2/5] HID: intel-thc-hid: intel-ipts: receive reports Emfox Zhou
2026-11-14 17:07 ` [PATCH v2 3/5] HID: intel-thc-hid: intel-ipts: register the HID device Emfox Zhou
2026-11-14 17:07 ` [PATCH v2 4/5] HID: intel-thc-hid: intel-ipts: handle system sleep Emfox Zhou
2026-11-14 17:07 ` [PATCH v2 5/5] HID: intel-thc-hid: intel-ipts: document the IPTS mode Emfox Zhou
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261114170740.2068179-1-emfox@debian.org \
--to=emfox@debian.org \
--cc=bentiss@kernel.org \
--cc=even.xu@intel.com \
--cc=jikos@kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=xinpeng.sun@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®