Casey Tunturi

August 1, 2026

August 1, 2026

41 public commits · 5 public repos · 261 private commits

Work threads
qseecom8input6sessiond5task-495task-443arm642blueline-fingerprintdtools
  • Private work 5 repos sealed

    261 commits count toward the day. Names, subjects, and links stay private.

    • 4:59 p.m. · 08e9db5

      The sensor works now, and that is what exposed this. Once the TrustZone app arms finger-detect the FPC1020 interrupts continuously - 1444 in 25 s on the phone - and the driver was reporting KEY_WAKEUP for every one. hyprland.lua binds XF86WakeUp to blueline-screen-toggle, so that is 1444 wake requests: 132 DPMS transitions in the journal and the ambient-light sensor oscillating because the panel was strobing. Casey spotted it as 'that's the screen powering on and off?' before I did.

    • 4:59 p.m. · 10cbed9

      The sensor works now, and that is what exposed this. Once the TrustZone app arms finger-detect the FPC1020 interrupts continuously - 1444 in 25 s on the phone - and the driver was reporting KEY_WAKEUP for every one. hyprland.lua binds XF86WakeUp to blueline-screen-toggle, so that is 1444 wake requests: 132 DPMS transitions in the journal and the ambient-light sensor oscillating because the panel was strobing. Casey spotted it as 'that's the screen powering on and off?' before I did.

    • 4:48 p.m. · ac9a4dd

      The FPC sensor commands do not carry their arguments in the request. The request is a descriptor - { u32 aux_len; void *aux } - and the real payload { group=0xa, cmd } lives in a buffer whose address is patched in at offset 4. Recovered from the vendor HAL: sym.sensor_command writes the pair with 'stp w8, w19, [x22]' (w8=0xa) into the shared allocation, and sym.fpc_tac_transfer_platform passes ion_fd_info {fd, offset=4} to QSEECom_send_modified_cmd alongside a 64-byte req/rsp pair.

    • 4:48 p.m. · 6fb5501

      The FPC sensor commands do not carry their arguments in the request. The request is a descriptor - { u32 aux_len; void *aux } - and the real payload { group=0xa, cmd } lives in a buffer whose address is patched in at offset 4. Recovered from the vendor HAL: sym.sensor_command writes the pair with 'stp w8, w19, [x22]' (w8=0xa) into the shared allocation, and sym.fpc_tac_transfer_platform passes ion_fd_info {fd, offset=4} to QSEECom_send_modified_cmd alongside a 64-byte req/rsp pair.

    • 4:35 p.m. · 4d52867

      The image was assembled correctly - mdt_len=7208 matched the .mdt, img_len=777653 matched the sum of the set - and TZ still returned -EINVAL: 'qcom_scm firmware:scm: qseecom: scm call failed with error -22'.

    • 4:35 p.m. · a8bac15

      The image was assembled correctly - mdt_len=7208 matched the .mdt, img_len=777653 matched the sum of the set - and TZ still returned -EINVAL: 'qcom_scm firmware:scm: qseecom: scm call failed with error -22'.

    • 4:19 p.m. · 329737a

      Dropping the vendor sysfs was right when nothing could load a TA. It is wrong now that we can: the FPC stack reaches the sensor through it. The HAL's TAC library calls fpc_irq_init()/fpc_sysfs_node_write() against /sys/bus/platform/devices/soc:fp_fpc1020, poll()s 'irq', and drives 'hw_reset' and 'device_prepare' around each transaction (strings in android.hardware.biometrics.fingerprint@2.1-service.fpc, which links libQSEEComAPI and calls QSEECom_start_app/send_modified_cmd).

    • 4:19 p.m. · 9ddf93c

      Dropping the vendor sysfs was right when nothing could load a TA. It is wrong now that we can: the FPC stack reaches the sensor through it. The HAL's TAC library calls fpc_irq_init()/fpc_sysfs_node_write() against /sys/bus/platform/devices/soc:fp_fpc1020, poll()s 'irq', and drives 'hw_reset' and 'device_prepare' around each transaction (strings in android.hardware.biometrics.fingerprint@2.1-service.fpc, which links libQSEEComAPI and calls QSEECom_start_app/send_modified_cmd).

    • 4:15 p.m. · cb150d7

      The first load returned EINVAL for two reasons, both now measured against the real blob. fpctzappfingerprint.mdt is ELFCLASS64 and was being read through elf32_hdr, so e_phnum and e_phoff were garbage. And the layout was wrong: downstream does not place segments at p_paddr-relative offsets, it *concatenates* - mdt, then b00, b01, ... in index order - with mdt_len naming how much of the front is the header blob (__qseecom_get_fw_data, qseecom.c:4165-4230). TZ places the segments itself from the headers.

    • 4:15 p.m. · b792455

      The first load returned EINVAL for two reasons, both now measured against the real blob. fpctzappfingerprint.mdt is ELFCLASS64 and was being read through elf32_hdr, so e_phnum and e_phoff were garbage. And the layout was wrong: downstream does not place segments at p_paddr-relative offsets, it *concatenates* - mdt, then b00, b01, ... in index order - with mdt_len naming how much of the front is the header blob (__qseecom_get_fw_data, qseecom.c:4165-4230). TZ places the segments itself from the headers.

    • 4:06 p.m. · d7d2e12

      Every GET_APP_ID on this device returns -ENOENT - fpctzappfingerprint, keymaster, widevine, cmnlib, all of them - because TZ only resolves apps something already started, and on Android that something is qseecomd. Nothing on a mainline userspace loads one, so the lookup verb had nothing to find and the whole QSEECOM client could not reach a single app.

    • 4:06 p.m. · f3864af

      Every GET_APP_ID on this device returns -ENOENT - fpctzappfingerprint, keymaster, widevine, cmnlib, all of them - because TZ only resolves apps something already started, and on Android that something is qseecomd. Nothing on a mainline userspace loads one, so the lookup verb had nothing to find and the whole QSEECOM client could not reach a single app.

    • 1:56 p.m. · 8fc7623

      0x10 was beryllium's address for the same sensor and the only candidate the downstream DTBO could confirm - it carries no slave-addr, and neither does the eeprom node cam-sensor@0 points at. On glass it NACKs:

    • 1:56 p.m. · 254f8dd

      0x10 was beryllium's address for the same sensor and the only candidate the downstream DTBO could confirm - it carries no slave-addr, and neither does the eeprom node cam-sensor@0 points at. On glass it NACKs:

    • 9:05 a.m. · 8eebcaf

      blueline carries an FPC1020 under the rear reader. Its SPI image path belongs to a TrustZone application, so the AP only ever owns reset, the pad rail and the interrupt line. The vendor's fpc1020_platform_tee.c is that half and nothing more - there is no capture and no matching in it.

    • 9:05 a.m. · 6f637c4

      blueline carries an FPC1020 under the rear reader. Its SPI image path belongs to a TrustZone application, so the AP only ever owns reset, the pad rail and the interrupt line. The vendor's fpc1020_platform_tee.c is that half and nothing more - there is no capture and no matching in it.

    • 7:27 p.m. · 499dc5e

      KEY_WAKEUP lands on event4 at the same timestamp as the hardware edge, so the existing XF86WakeUp bind can already see it. arm generates its own edge, which means re-arm-on-interrupt feeds itself - that was the 1444 events, not the sensor. wakeup_enable takes enable/disable, not 1.

    • 7:01 p.m. · be4ceed

      fpctzappfingerprint loads from cold boot and answers; init/idle/arm all 0x0. gpio121 goes idle-low after the sequence - the latch that killed piece 1 is cleared, so a rising edge is possible for the first time. init accounts for 68 of the edges; armed and untouched is a flat 0 over 15s, so the 1444-event run was the re-arm loop. Open: whether a finger raises an edge.

    • 2:59 p.m. · 55a4423

      home_ssids needs a list: Samaritan Solutions and TheTholianWeb both lease from [host]/24 (.234 and .245). Three defects only hardware showed: reapply clat wipes the CLAT daemon's routes including the MMS /32; the gsm connection is the wrong lever because the v4 carrier default comes from the clat tun at 2048; and wg show needs CAP_NET_ADMIN that a user unit will never have.

    • 2:37 p.m. · 0737387

      [host] was ipv4.addresses [host]/24, which is [host]'s; [host] is [host], the phone's. Not near-copies - bringing [host] up would have put two devices on one WireGuard address. [host] also carried the dns-priority 10 fix; [host] was still at 0. Deleted, backed up to ~/nm-profile-backup/ on the device.

    • 2:21 p.m. · 6b4e4fd

      bearer.rs plus PreferLink/PinTunnelUnderlay and a bearer verb. Decision layer tested (settling window, no re-emit, dead network); nothing has run on the phone. home_ssids still unset and the [host]/[host] duplicate still unresolved.

    • 1:57 p.m. · 11668f0

      And the lesson that cost the front camera: camss creates all sensor->csiphy links in the async notifier's .complete, which needs every declared subdev to bind. One non-probing sensor leaves the working front pair registered with zero links. Never leave a failing sensor node enabled; a rear-disabled DTB is parked on the device for one-cp recovery.

    • 1:21 p.m. · 7b96c94

      Found still installed 2026-08-01, in no repo and no repo's history. Three defects, all traps the state-machine version can repeat:

    • 1:16 p.m. · 8b9edae

      This repo has no delivery path; rootfs-overlay does. Files were byte-identical.

    • 12:39 p.m. · 2e06421

      sdm845_domains[] carries mpss_root_pd and mpss_wlan_pd, so wifi and cellular share the modem's PD broker on this SoC. A broker that stops serving explains a no-attach that only a reboot clears.

    • 9:16 a.m. · c614b3a

      The staged vendor driver is the fpc_fingerprint variant, which blueline does not build (b1c1_defconfig sets CONFIG_FPR_FPC=y, the other copy). The shipping one has an empty vreg_conf[] and manages no regulators at all.

    • 7:49 p.m. · e300973

      The sensor asserts once per arm then latches, so it has to be re-armed after every event - but arm makes its own edge, which is what turned the naive loop into 1444 interrupts. Shut the driver's wake gate around the re-arm and drain that edge by counter, not by clock.

    • 7:27 p.m. · 2e1f0fe

      The windowed rigs kept missing because the touch prompt only reaches the human after the window has started counting. This one arms once and waits, timestamps every edge, and watches event4 so KEY_WAKEUP is visible alongside the interrupt.

    • 7:01 p.m. · 94cf267

      A cold boot leaves the initramfs gadget's usb0 linkdown, still holding [host] and a competing route, so replies to the laptop egress a dead interface while usb1 answers ARP - the phone reads as a hung boot. always-up defaulted IgnoreCarrierLoss to yes; set it to 5s instead of flushing by hand.

    • 1:16 p.m. · 3090440

      blueline-wifi-bringup.{service,sh} and blueline-wifi-defer.conf were only on the phone and in SouveraineOS/blueline/, which reaches no device. Meanwhile the overlay still shipped and enabled blueline-wifi-load.service, retired 2026-07-20 for incomplete ordering, and provision enabled blueline-wifi-retry which the device has had disabled just as long.

    • 9:16 a.m. · 6b914aa
    • 9:07 a.m. · 85fa372

      Eight patches generated from the blueline branch's own commits, not from kernel/patches/ (which is stale reference material the PKGBUILD already marks do-not-apply). Six apply clean to the codeberg sdm845 tree; 0006 and 0007 conflict on blueline.dts context and need a rebase before send. Not sent.

    • 9:07 a.m. · 1fc31a3

      CONFIG_INPUT_FPC1020=m. Driver and DT land on the linux-blueline fingerprint-fpc1020 branch; survives olddefconfig in place, so the PKGBUILD's config-drift guard stays quiet.

    • 3:10 p.m. · d2f51e9

      Both executors recorded success via record_error, so the daemon's own working actions landed in the trail's error channel - visible on the phone as {"event":{"error":{"component":"bearer","error":"preferred wifi"}}}. That makes the one signal a reader scans for useless.

    • 2:58 p.m. · 7e91de1

      Measured on the phone. After one PreferLink the clat device was up with its 192.0.0.1/32 address and *zero* routes: no default, and no 205.151.11.13/32, which is the only path to the MMS proxy. ip route get 205.151.11.13 went out wlan0. Restored by restarting blueline-clat.service.

    • 2:44 p.m. · ac084b4

      Found on the phone: the bearer verb reported tunnel "off" while [host] was up and handshaking (4.11 KiB received). wg show needs CAP_NET_ADMIN for WG_CMD_GET_DEVICE and sessiond is a systemd *user* unit, so it gets "Unable to access interface [host]: Operation not permitted" and every tunnel reads off, forever. A daemon that cannot see the instrument it is built around.

    • 2:21 p.m. · 0f7fe27
    • 2:09 p.m. · f6479c9

      A policy field with no verb behind it is unreachable. set_policy takes both, get_policy reports both, and a zero settling window is refused the same way a zero lock-ack budget is - it is the event-speed controller by another name.

    • 2:05 p.m. · 4fd3d24

      Nothing owned which link carries traffic. It was the residue of a DHCP metric, a NetworkManager penalty and a shell script's assumption, and when those disagreed the phone silently lost the network - every IPv4 destination leaving over a degraded clat while wifi sat associated.

    • 8:25 a.m. · 77f69a7

      The kms feature links libseat/libinput/libudev/gbm/EGL, so a bare --target makes pkg-config answer with the host's libraries and libseat-sys dies in its build script. Give it the sysroot, the aarch64 linker, and the explicit -L that --sysroot alone does not cover.

    • 8:20 a.m. · 77b5882

      Presentation is driven by vblank and a vblank only arrives for a crtc with a flip in flight, so a frame that came back empty ended the loop with no clock left to notice the next commit. Rendered once, then looked frozen.