Watch
1
0
Fork
You've already forked SouveraineOS
0

task-39: the in-call speaker button is fixed

souveraine-callaudiod routes ENABLE_SPEAKER through the hook, which writes the
amps directly instead of switching a sink port that cannot exist on this card.
Verified over D-Bus: enable -> both amps, disable -> earpiece, not headset.
A real call is the outstanding confirmation.
This commit is contained in:
Fimeg 2026-08-02 08:52:15 -04:00
commit 09e818b4db

View file

@ -192,3 +192,55 @@ and the front-end mixer are **ruled out** (TX5 and TX7 both give peak `0`, and
`MultiMedia2 Mixer SLIMBUS_0_TX` is on in both profiles). What separates working
from silent is the Q6 voice session, which matches the sysclk/SLIM-lifecycle
direction of `mic-fix` rather than the pad-configuration direction.
## FIXED — the in-call speaker button (2026-08-02)
Casey, observed: an inbound call **defaulted to speakerphone**, and tapping the
speaker button (to *turn on* speakerphone) **switched to headset mode**.
**Root cause.** `gnome-calls`' speaker button calls `org.mobian_project.CallAudio`,
a name owned by upstream **`callaudiod`** (`extra` 0.1.99-3, D-Bus activated).
callaudiod moves audio by switching a sink *port* (`cad-pulse.c`,
`set_output_port`), which needs one sink carrying both an earpiece and a speaker
port. blueline has both CS35L36 amps behind a single PCM, so UCM models them as
separate devices and ACP splits them into `Voice Call (Earpiece, Mic)` and
`Voice Call (Mic, Speaker)` — no such sink exists. Disabling the speaker asks
for "the highest priority port that is **not** the speaker", which resolves to
the headset. The call was already on speakerphone, so the tap sent
`EnableSpeaker(FALSE)` and the phone went to headset. Both halves of the report
are one bug.
**Fix: `pkgs/souveraine-callaudiod`.** Upstream 0.1.99 plus one patch routing
`CAD_OPERATION_ENABLE_SPEAKER` through `blueline-callaudio-hook speaker on|off`,
which writes the amplifier controls directly — no profile switch, so the PCM a
live call runs on is never disturbed. Completion mirrors `operation_complete_cb`
so the `speaker-state` property stays truthful. Gated on the hook being
executable, so it is upstream behaviour on any other device. Cross-built on
ArchDev; `provides/conflicts/replaces callaudiod`, which `gnome-calls` and
`phosh` both depend on by name.
**Verified on the device over the same D-Bus interface the button uses** — no
call needed, `callaudiocli` drives it:
earpiece baseline Right AMP Enable Switch = off
callaudiocli --enable-speaker 1 -> on (loudspeaker, both amps)
callaudiocli --enable-speaker 0 -> off (earpiece, NOT headset)
callaudiocli --status -> CALL_AUDIO_SPEAKER_OFF
**Still to confirm on a real call**, the one thing the CLI cannot stand in for:
that the toggle behaves identically while the voice verb is applied. The hook
writes amps rather than profiles, so it should be verb-independent — unproven
until a call happens.
**Three notes worth keeping.** `pacman -U --noconfirm` answers *No* to the
"remove the conflicting package?" prompt, and `replaces=` only applies to repo
syncs — so installing a replacement locally means answering the prompt, not
reaching for `-Rdd`. meson resolves glib's codegen tools from pkg-config
variables, which come back **sysroot-prefixed** under `PKG_CONFIG_SYSROOT_DIR`;
the shared cross file pins `glib-compile-resources`/`gdbus-codegen` but not
`glib-mkenums`, so the package ships a supplementary cross file rather than
editing that shared file, which lives unversioned on the builder and would lose
the change. And neither this package nor the kernel is published to
`souveraine-aarch64`, so both are hand-installed even though the repo is
configured on the phone.