Skip to content

HID: apple-mtp-kiwi: the K114c touch screen (needs #1568) - #1605

Draft
joshuaswarren wants to merge 5 commits into
aurora-silicon:integration/aurorafrom
joshuaswarren:w7c/up-k114c-kiwi
Draft

joshuaswarren wants to merge 5 commits into
aurora-silicon:integration/aurorafrom
joshuaswarren:w7c/up-k114c-kiwi

Conversation

@joshuaswarren

@joshuaswarren joshuaswarren commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Adds the touch screen of the 14-inch PROLED MacBook Pro (K114c, M5 Max). The panel's touch controller is a "kiwi" interface on the same dockchannel MTP transport as the trackpad. It has its own reset and power lines and wants a 24 MHz clock pad and a display-sync pad.

What is in the stack, oldest first:

  1. pinctrl: apple: the GPIO mode field is four bits wide. iBoot leaves bit 4 of the touch reset and power pins set; with it set the DATA bit does not latch in output mode, so the reset never took effect. Bits 1-4 are the mode now. Modes 0-7 are unchanged.
  2. HID: apple-mtp-kiwi: add the MTP touch screen driver, with its MAINTAINERS entry and CONFIG_HID_APPLE_MTP_KIWI=m in asahi.config.
  3. HID: dockchannel-hid: bring up the kiwi (touch screen) interface: the reset, power and clock bring-up, and skipping announced GPIOs the device tree does not wire.
  4. dt-bindings: input: apple,dockchannel-hid: document the kiwi interface properties.
  5. arm64: dts: apple: t6050-k114c: enable the kiwi touch screen interface, including the pad functions: clock on NUB pin 22, display sync on AP pin 11, reset on NUB pin 25 (active low), power on NUB pin 26.

It needs #1568 (the report-size clamp for this MTP firmware) underneath it.

Status, measured on the machine: the firmware is accepted, Kiwi interface ready with status:0 appears, /dev/hidraw2 streams 17861-byte frames at about 123 Hz, and the input device "Apple MTP touch screen" registers. Finger events are not verified yet: I have not had a person at the panel since the interface came up. I will update this with a libinput debug-events capture. Marked draft until then.

@RyanTheTide RyanTheTide left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Joshua, this is a big step for the K114c, and the kiwi driver reads well. Two things before it can merge:

  1. integration/aurora now defines ps_nub_gpio in t6050-peripherals.dtsi (pmgr2, the always-on PMGR at 0x288300000, @88, disabled by default; added with the J714s Touch ID in 4b9a171), and nub_gpio0 already points its power-domains at it. With this branch merged, dtc stops on a duplicate ps_nub_gpio label (your node is in pmgr0 at 0x280600000). Please drop the t6050-die0.dtsi node and enable the shared one from t6050-k114c.dts the way J714s does: &ps_nub_gpio { status = "okay"; }; and &nub_gpio0 { status = "okay"; ... }. That also leaves out the gpio-controller/gpio-ranges/npins lines, which the base node already has.
  2. #1603/#1604 are merged, so t6050-k114c.dts conflicts. Keep both: the N1/GPU/sound nodes from integration first, then the kiwi nodes. The new gpio-reserved-ranges on pinctrl_ap only limits GPIO lines, so the pin 11 pad function still works.

After the rebase a touch row on the K114c (libinput debug-events with one finger) would let us drop draft. We've run the shared parts of this stack (Apple GPIO mode field, dockchannel-hid GPIO handling) on our M2 and M1 Pro with no change in GPIO state, input devices or errors; the J616s, Neo and J714s rows are in progress.

On the K114c the NUB GPIO block comes out of iBoot with bit 4 of the
touch-screen reset and power pins set (0x474210, 0x474212 as read through
/dev/mem). With that bit set, the DATA bit does not latch in output mode:
writing 0x474213 reads back 0x474212, writing 0x474203 reads back 0x474203.
direction_output wrote only bits 1-3 of the mode, so the pin stayed in a
state where the driver's output value never took effect.

Treat bits 1-4 as the mode, so that direction_output and direction_input
clear bit 4. Modes 0-7 are unchanged, and a working output (the PERST# pin
of the K114c, register 0x00076a03) has the bit clear.

Signed-off-by: Joshua Warren <816217+joshuaswarren@users.noreply.github.com>
The touch screen of the 14 inch M5 Max MacBook Pro (K114c) sits behind
the kiwi interface of the dockchannel MTP. The interface has a 29-byte
HID descriptor with one opaque input item and no description of the
contacts. The chip reports a raw 82 column by 54 row capacitance image
every 8.3 ms and does no contact detection itself.

Claim the interface by name (hid-apple and hid-magicmouse already refuse
BUS_HOST Apple interfaces that are not a keyboard or mouse), keep the
raw pipe on hidraw, and register a direct multi-touch input device with
10 slots over the 3024x1986 panel. The driver:

 - clamps the Report Size of the descriptor, which is 0x80000 bits and
   above the 16384 that hid-core accepts, in report_fixup,
 - skips the whole-image shift frames the chip sends every 2 s and
   removes a per-row mean from the others,
 - keeps a fixed-point baseline per cell (fast up when a finger left,
   slow drift otherwise),
 - takes 3x3 local maxima 250 counts below baseline, centroids them and
   tracks them frame to frame with a 2 frame miss debounce.

Row 0 of the sensor is the bottom edge of the panel, so y is mirrored;
this is a fixed fact of the hardware, there is no option for it. The grid
and the panel size are K114 only, and frames that are not 17861 bytes
long are ignored.

Tested on a K114c: five taps at the corners and the centre, in that
order, landed at the matching points on a test page, and evtest shows
X/Y changing under a finger. That run used the same parser with a
transport that clamped the descriptor and a module option for the
mirror; the clamp in this patch is checked in a userland test only. The
firmware load and power sequence of the interface are in a separate
patch.

Signed-off-by: Joshua Warren <816217+joshuaswarren@users.noreply.github.com>
The touch screen ("kiwi") of the 14 inch M5 Max MacBook Pro rides the
same dockchannel MTP as the multi-touch interface and announces itself
the same way, but it owns its reset and power lines instead of sharing
the AFE reset, and its 1.3 MB firmware image is written by the MTP
bootloader over the touch IC SPI, which takes seconds rather than the
1 s the comm timeout allows.

- A power method 2 interface may decode its own reset and power lines
  from its device node; without its own reset line it keeps falling back
  to the shared AFE reset, so existing multi-touch boards are unchanged.
- Announced GPIOs are tracked per interface (the MTP announces
  clock_24MHz_enable, display_sync, power and reset for kiwi) instead
  of failing on the second one, and a GPIO command is matched to its
  announced id. The kiwi clock and display_sync pads are pad functions
  in the device tree, not host GPIOs: they are left unset and a command
  for them is refused.
- While the kiwi firmware load is running, comm commands use a 10 s
  timeout, and the kiwi interface waits 10 s for its ready message.
- The kiwi start sequence, taken only when kiwi has a reset line of its
  own, power-cycles the chip with a reset pulse (the reset line is active
  low in the device tree), settles 50 ms, sends the firmware and then runs
  the normal power method 2 transitions. The power line is raised on the
  way up and left alone on the way down. The sequence is fixed code, not
  tunables.

It needs the device tree side (the kiwi node, its reset and power lines
and the two pad functions), which is a separate patch.

The image installed as apple/tpkiwifw-k114c.bin fails to load at its
operations 26, 29 and 30, which are optional property placeholders
(address 0, not required). The verified runs used an image with those
three operations removed, so whatever installs the firmware needs to
drop them.

Compile tested against this tree with W=1. The start sequence, the
timeouts and the pad function settings are verified on hardware on a
7.2.11 based tree.

Booted on a K114c on this base with the first revision of this series: the
interface binds, reports ready with status 0 and streams 17861-byte frames
at about 123 Hz.

Signed-off-by: Joshua Warren <816217+joshuaswarren@users.noreply.github.com>
…e properties

The kiwi (touch screen) interface of the dockchannel MTP owns its power
sequencing lines instead of sharing the multi-touch analog front end
reset. Document apple,power-method, apple,reset-gpios and
apple,power-gpios on the kiwi child node, mirroring how the multi-touch
child documents its power method.

The 24 MHz clock and display sync pads are pad functions selected by the
transport node pinctrl, not GPIO properties, so they need no binding
entries.

Signed-off-by: Joshua Warren <816217+joshuaswarren@users.noreply.github.com>
@joshuaswarren

Copy link
Copy Markdown
Contributor Author

[Joshua's agent] Reworked for both points; the branch is now 81435c7, five commits rebased on integration/aurora de6a8d4.

  1. Duplicate ps_nub_gpio: the t6050-die0.dtsi node is dropped. t6050-k114c.dts now enables the shared one the way J714s does (&ps_nub_gpio { status = "okay"; };) and &nub_gpio0 { status = "okay"; ... }, with no gpio-controller, gpio-ranges or npins lines. The only other lines in that node are /delete-property/ interrupts and the clock pin group. I kept the interrupt delete because the touch result on the K114c was obtained without them; I have no K114c run that covers the base node's seven interrupts, so say so if you would rather inherit them.
  2. Rebase: the N1, GPU and sound nodes from integration come first in t6050-k114c.dts, then the kiwi nodes. The pin 11 pad function is set through the pinctrl_ap pinmux, so the new gpio-reserved-ranges does not touch it.

Checks on this head, run locally: make ARCH=arm64 W=1 builds apple/t6050-k114c.dtb and apple/t6050-j714s.dtb with no warning from these nodes (the unit-address warnings in the gpu and pmp dtsi files were already on integration), and checkpatch --strict reports 0 errors, 0 warnings, 0 checks on all five commits. The dts commit message no longer says it adds the power domain.

Not yet run on this base: a K114c boot with libinput debug-events. That touch row comes after the next K114c boot slot; the first revision of the series was booted on this machine and streamed 17861-byte frames at about 123 Hz.

@RyanTheTide

Copy link
Copy Markdown
Contributor

Thanks Joshua, the rework is what we asked for. The pinctrl, dockchannel-hid and asahi.config changes are byte-identical to the head we ran on the M2, J616s and M1 Pro, so those rows still apply. Only the K114c DT moved, and the die0 node is gone.

On the interrupts: please inherit them and drop the /delete-property/ interrupts. The J714s, same SoC and same base node, enables nub_gpio0 with all seven and runs that way. The kiwi only uses NUB 25 and 26 as outputs, so the touch path doesn't depend on them either way. With the delete, the node still says interrupt-controller but the driver finds no parent IRQs and registers no irqchip, so any later NUB GPIO interrupt user on K114c would fail to map. If the touch row on your next boot comes out the same with them inherited, I'll approve and merge.

The touch screen of the 14 inch MacBook Pro with the M5 Max rides the
dockchannel MTP as its own "kiwi" interface. It sequences its own power:
with power method 2 the host drives the touchscreen reset (nub GPIO 25,
active low) and its optional supply enable (nub GPIO 26), instead of the
shared multi-touch AFE reset on the SMC.

Enable the shared always-on NUB GPIO power domain and controller the way
J714s does, with its seven interrupts, mux the 24 MHz clock (nub pin
22) and display sync (AP pin 11) pads through the transport node pinctrl,
and enable the interface with its k114c firmware name.

The reset polarity, the GPIO numbers and the two pad function values
(pin 22 and pin 11, function 1) are those of the device tree that gave
touch on the hardware on a kernel based on v7.2.11.

Booted on a K114c on an earlier base with the first revision of this
series: the interface binds, reports ready with status 0 and streams
17861-byte frames at about 123 Hz.

Signed-off-by: Joshua Warren <816217+joshuaswarren@users.noreply.github.com>
@DjDeveloperr

Copy link
Copy Markdown
Contributor

J714s (M5 Pro) validation of 81435c7 on top of #1568 (1e06558): PASS.

  • The test kernel is intg3 plus HID: bring up the trackpad of the 14-inch M5 Max MacBook Pro #1568 plus this PR's 5 commits. The one conflict was in the K114c-only dts; I took the PR head's version.
  • The J714s DTB is byte-identical to intg3's.
  • Keyboard binds to hid-apple and trackpad to hid-magicmouse, and Hyprland lists both. There are 0 pinctrl and 0 dockchannel-hid errors.
  • Speaker amp GPIOs 106/107 are in the same state as on intg3. 6/6 SN012776 bound, with 0 fault IRQs in 10 s. Nothing was played.
  • Wi-Fi 5/5 ping, glmark2-es2 4440 (intg3 4464), 0 oops.
  • Not exercised: physical key or touch input, since nobody was at the machine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants