Static configuration and small boot-time services that make the TB323FU hardware work: audio, sensors,
Bluetooth, USB-C routing, the emergency way back to Android. They are distribution- and desktop-neutral
(systemd, udev, ALSA/PipeWire only), always installed, and work without the tb323fu helper and without a
desktop. The helper (layer 2, helper/) adds user-facing settings on top; nothing here depends on it.
See docs/helper.md for the layer model.
Install with install.sh (DESTDIR, PREFIX, SYSCONFDIR, CC, OPTIONAL; no package manager
calls), then enable the services it prints. Distribution recipes can call it or copy the same files.
These files come from the development image (Debian 13). The Fedora and SteamOS builders in rootfs/ install
them with install.sh; the Debian, Arch and Nix packages in packaging/ carry the same files.
replaces feedbackd's packaged rules: drops its LED rules (they would take over the torch and RGB ring), adds the two haptic motors as vibra devices (LGPL-2.1-or-later, from feedbackd)
once per install: derive a Bluetooth address (/etc/tb323fu/bt-address) and a fixed Wi-Fi MAC (/etc/systemd/network/10-tb323fu-wlan-mac.link) from /etc/machine-id; the Wi-Fi firmware otherwise invents a new MAC every boot. Existing files are kept
tb323fu-btaddr.service
the Bluetooth controller starts without an address; give it /etc/tb323fu/bt-address before bluetoothd starts
tb323fu-dsp.service
start the audio and compute DSPs once the root filesystem (with their firmware) is mounted
tb323fu-audio.service + tb323fu-audio-defaults
speaker/microphone mixer defaults again after alsa-restore, so a saved mixer state never leaves the amplifiers unattenuated
tb323fu-usb-port.service + tb323fu-usb-port
route USB to the connector in use at boot (bottom USB 3 + DP or side USB 2; one controller, a GPIO switches the lines), and recover a stuck gadget
hold volume up + down (10 s by default) → back to Android via back-to-android, even with a frozen desktop. Config /etc/tb323fu/emergency-key.conf (ENABLED, HOLD_SECONDS), Android image hash /etc/tb323fu/android-boot.sha256; needs keyhold (src/keyhold.c) and back-to-android (android/)
hexagonrpcd.service.d/tb323fu.conf
point hexagonrpcd at the secure ADSP fastrpc node and the sensor file tree; order it after the DSPs
kernel updates: 90 s after the system reached graphical.target (or multi-user.target), confirm a kernel on trial — boot_a becomes linux-good.img on the state root, so the initramfs stops counting its starts. Testing-channel kernels wait for Keep; a hand-flashed kernel is recorded as good the same way. Works without the helper (docs/helper-reference.md); test-kernel-confirm.sh runs it offline
open the speaker amplifiers up only while PipeWire's protecting filter chain runs; safe attenuation otherwise (safety: there is no DSP speaker protection)
only without the helper: lets UPower/GNOME's "Preserve battery health" switch manage the charge limit. With the helper installed the helper owns it (two writers would fight)
led-group
optional/udev/74-tb323fu-leds.rules
only without the helper: video group may write the torch and RGB ring directly
logind
optional/logind.conf.d/tb323fu-powerkey.conf
ignore short power-key presses in logind (logind's default powers off); for desktops that handle the key themselves
Torch, RGB ring charge indicator, GPU profile, charge limit, refresh-rate policy, switch to Android —
user-facing settings owned by the helper (layer 2); the development image's scripts for them are replaced by it.
Development conveniences (serial console and tty autologin, USB network gadget, NetworkManager tweaks,
hostname, fstab, first-boot script) — belong to a development image, not to the platform.
Desktop extensions — layer 3, provided with the helper.
bootmac (qcom-phone-utils): its bootmac-bluetooth.service generates a random Bluetooth address and brings the controller up through the legacy hciconfig path, which hides it from the management interface; tb323fu-btaddr then cannot set the real address and Bluetooth ends up with a random address or unusable. Mask it: systemctl mask bootmac-bluetooth.service.
rmtfs.service (Debian/Ubuntu rmtfs package): runs rmtfs -r -P -s, and -s starts the modem. The tablet has no GNSS antenna and no cellular, so the modem has no use, and a modem crash currently resets the whole SoC. Mask rmtfs and tqftpserv (systemctl mask), so no other unit pulls them in.