PAF becomes saf/device (history kept), STATE.md dissolves into saf/state.md with the dated era archived, the substrate SAF moves up from souveraine, and every agreement points at saf/INDEX.md and nowhere else. one map, nothing to remember
7.6 KiB
PAF · Touch — ST FTS, reset polarity, GPI-DMA, tap-to-wake
Current glass result — 2026-07-11
On kernel 7.1.1-sdm845-g56b0a053bef8, daytime touch works and the FTS
recognizes DBLTAP. The current defect is downstream of gesture recognition:
the first double tap can prepare the panel and then immediately unprepare it
(green flash then black); a second double tap wakes the display. The first
half-wake is kernel-trace confirmed. Treat DT2W as detected but unreliable
until the screen-toggle/DPMS prepare-unprepare ping-pong is fixed. This is not
the old IRQ/FIFO bug.
Status 2026-07-10 (morning): TAP-TO-WAKE WORKS, verified on glass by Casey on kernel d7a8f7dc9. FTS probes clean, gesture mask armed at boot, double-tap wakes from armed sleep, touch alive after wake, hypridle 60s idle screen-off enabled. The one remaining suspend-path defect was the IRQ handler, not the controller — see the closed item below.
Suspend-path doctrine (2026-07-10, learned the hard way)
gesture_enabledMUST be 1 before any DPMS-off. Unarmed suspend takes the SLPI-handoff branch (fts_suspend_work): controller handed to the PARKED sensor island + IRQ disabled → resume races → level IRQ storm (millions on IRQ 148) → kernel kills the IRQ → touch dead until driver rebind or reboot. With SLPI's sar.cc wall unfixed, the handoff target is unavailable — gesture-armed suspend (AP keeps the bus) is the only safe mode.- The compiled gesture_mask sysfs is the STASH-THEN-APPLY variant:
echo "01 20" >stages only; the followingcatapplies (updateGestureMask) and sets gesture_enabled=1. blueline-dt2w.sh does both since de4fe40. - Live recovery from a dead touch IRQ, no reboot:
echo 2-0049 > /sys/bus/i2c/drivers/fts/unbind && echo 2-0049 > .../bind— but Hyprland then holds stale input handles (taps flow at evdev level, UI ignores them); a session restart or reboot is needed after rebind. - VERIFIED 2026-07-10 (clean boot-time arm, Casey on glass): daytime touch works, and touch SURVIVES a full sleep/wake cycle — the regression is closed. Wake was power-button; double-tap did NOT wake.
- CLOSED 2026-07-10 (kernel d7a8f7dc9) — tap-to-wake works on glass. The "controller never enters gesture scan" theory was WRONG: enterGestureMode runs and succeeds at every armed suspend (Sense OFF → gesture mode → enableGesture DONE in dmesg). The real defect was fts_interrupt_handler: during armed sleep bus_refmask==0, so the bus-ref gate refused every IRQ and returned WITHOUT reading the FIFO. Level IRQ line stayed asserted → refired forever (the "582k IRQs" were the unserviced line, not full-rate scanning), gesture events were dropped unread (why double-tap never woke), and a bogus release call in the refusal branch logged one pr_err per IRQ — 85k lines in one screen-off window, enough printk to freeze the phone on long sleeps (2026-07-10 morning freezes). Fix: service the FIFO without taking a bus ref when gesture_enabled && sensor_sleep (taking one would queue a resume per IRQ), drop the bogus release, ratelimit the bus-ref pr_err. The port's 30177cb7e (AP keeps bus in gesture mode) had changed the ownership model without teaching the IRQ path — classic lost-handler.
The hardware truth (settled — do not re-litigate)
- This unit is the LG panel + ST FTS variant: FTS controller at 0x49 on i2c-2 (888000 geni SE). Settled from per-unit persist calibration + LOS init.blueline.rc.
- The Samsung
sec_ts@48nodes in the downstream DTBO (fragment@81,sec,reset_gpio, …) belong to the OTHER hardware variant. Never cite fragment@81 as evidence for our touch config — that mistake shipped ba0620d5c and killed touch for a day. - Pins: reset tlmm 99 (active-low RESETB), IRQ tlmm 125 (level low), AP↔SLPI bus switch tlmm 136.
Reset polarity — the post-mortem
The ported vendor driver (drivers/input/touchscreen/stm/) uses gpiod
logical assert semantics: acquires reset GPIOD_OUT_HIGH ("asserted"),
pulse is set(1) → 20ms → set(0) → 50ms, and its own comment says
"active-low reset" (fts.c ~4320). Therefore the DT flag must be
GPIO_ACTIVE_LOW, so logical assert = physical LOW.
With GPIO_ACTIVE_HIGH (ba0620d5c, 2026-07-09 14:02) deassert drives the
pin physically LOW → RESETB held forever → controller NACKs every I2C
access → probe fails after 3 reset attempts. Signature in dmesg:
gpi ... Error in Transaction: code=0x10 status=0x40 on EVERY read
(including the first 8-byte poll), fts_system_reset: ERROR 80000002,
Probe Failed!. Nobody noticed for a day because every boot in that window
had a black display. f3c5f5a11 reverts to ACTIVE_LOW.
Triage rule: all-reads-fail = controller not out of reset / not powered / bus switch wrong — a dead chip, not a DMA problem. Large-read-only failure = the (historic) GPI-DMA wall below.
GPI-DMA wall (historic — status needs one clean-boot check)
The 888000 SE is GPI-mode-only (its SE firmware has FIFO disabled — no
FIFO fallback exists; verified in i2c-qcom-geni probe). Historically small
reads worked and the first large read (209-byte readSysInfo) died with
MSM_GPI_TCE_UNEXP_ERR. Instrumentation ff6e6e2e8 logs completion status +
error-log register on any recurrence.
ANSWERED 2026-07-10, first clean f3c5f5a11 boot: the wall is GONE.
Zero gpi ... Error in Transaction lines in dmesg; the driver read the
105,140-byte firmware file and ran CX/Panel CRC verification over the bus
(Fw Update Finished! error = 00000000), FTS input device registered.
Large GPI-DMA transfers on the 888000 SE work. Whatever ate the 209-byte
read in the 2026-07-08 era was fixed by the intervening driver/power work
or was reset-state fallout all along; if it ever recurs, the ff6e6e2e8
telemetry will say why. Deep diagnosis archive: ../CLAUDE.md "Touch /
FTS-on-mainline key facts".
Gesture / suspend design (in-tree, working as of 07-09 morning)
- 08687bec9 power+reset sequencing, e31aa9da7 prototype fix, 30177cb7e keep AP bus ownership during gesture mode, 3d9eb1028 sensor_sleep bookkeeping in gesture-mode suspend.
- Gesture mode: on suspend the driver keeps the controller alive for
double-tap;
XF86WakeUp→ Hyprland bind →blueline-screen-toggle(see display.md). dt2w service wiring:blueline-dt2w.servicein rootfs-overlay (uncommitted edits pending as of 2026-07-10). - Proximity gate (2026-07-20):
blueline-screen-togglechecksnet.hadess.SensorProxyProximityNearover D-Bus before dispatching DPMS on; if blocked (phone in pocket) the wake is suppressed and logged, the FTS gesture still fires XF86WakeUp either way. Fails open if the D-Bus query errors, so a dead sensor proxy never permanently blocks wake. Requiresiio-sensor-proxyrunning, which is now always-on (see slpi.md). This closes half the "hot pocket" problem; the other half (screen already on + locked, phone pocketed) isblueline-proximity-lock(overlays/systemd-user/), amonitor-sensor --proximitywatcher that blanks via the sameblueline-screen-toggle offpath when locked.
THE GOAL (unchanged): one FTS driver = daytime touch + tap-to-wake
Like LOS: FTS drives the controller when awake; on suspend it hands the
controller to the SLPI over the tlmm 136 switch, where the
sns_touch_gesture nanoapp (SLPI's own i2c bus 5) watches for double-tap
and wakes the AP. stmfts (mainline driver) can never do this — no switch,
no handoff; it is fallback-only. Two tracks converge:
- FTS daytime path — WORKING modulo the polarity fix verify.
- SLPI-side tap-to-wake — unblocked by the sar.cc fix (see slpi.md), but not required for the current AP-side gesture design.