Keep the DSPs out of the initramfs, and let the headphone port be chosen
Some checks failed
build image / build (push) Has been cancelled
Some checks failed
build image / build (push) Has been cancelled
Rebuilding the initramfs on the machine rather than in the build container pulled qcom_q6v5_pas into it. There it probes while the initramfs is still the root filesystem, asks for qcadsp850.mbn, gets -2, and never retries — the same race 10-c630.conf already documents for the Adreno firmware. The ADSP hosts the whole audio path, so the machine comes up with no sound card and a sound device deferring on "error getting cpu dai name", which points nowhere near firmware. The blobs cannot go in the initramfs to fix it: they are ~20 MiB and are extracted from Windows, so they need not exist at build time. Omitting the driver instead means it loads once the real root is there. The modem driver goes with it, since it is not needed early either. Separately, the WCD9340 decides what is plugged in by measuring impedance, so an amplifier on the headphone socket reads as an open circuit and the jack control never leaves 'off'. PipeWire marks the port not available, will not keep it as the default sink, and GNOME hides it — an output that works when driven directly becomes unreachable from the desktop. Dropping JackControl from the Headphones device leaves availability unknown rather than no, and the port becomes permanently selectable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011XgGF5wfxLDAybVnNz6eNQ
This commit is contained in:
@@ -620,6 +620,41 @@ suspend/resume or per-stream volumes, all of which look guilty and are not.
|
||||
built-in card to S16_LE, which fixes every client. The underlying q6asm
|
||||
format bug is worth a report to alsa-devel.
|
||||
|
||||
**The DSPs have to load after the switch to the real root.** `qcom_q6v5_pas`
|
||||
boots the ADSP, CDSP and SLPI as soon as it probes. If it is in the initramfs
|
||||
it probes while the initramfs is still the root filesystem, asks for
|
||||
`qcom/sdm850/LENOVO/81JL/qcadsp850.mbn`, gets `-2`, and never retries — the
|
||||
same race the Adreno firmware loses, and the reason
|
||||
`overlay/etc/dracut.conf.d/10-c630.conf` omits both remoteproc drivers. The
|
||||
symptom points nowhere near firmware: the ADSP hosts the entire audio path, so
|
||||
what you see is no sound card at all and a sound device stuck in deferred
|
||||
probe complaining `msm-snd-sdm845: MultiMedia1: error getting cpu dai name`,
|
||||
because the q6 DAIs it wants to bind to were never registered. `dmesg` is no
|
||||
help either if the modem is crash-looping, since 80-odd crashes will have
|
||||
pushed the early firmware failures out of the ring buffer — use
|
||||
`journalctl -b -k`. To confirm the diagnosis in one step:
|
||||
|
||||
```sh
|
||||
cat /sys/class/remoteproc/remoteproc0/state # 'offline' when this has bitten
|
||||
echo start | sudo tee /sys/class/remoteproc/remoteproc0/state
|
||||
cat /proc/asound/cards # card appears within seconds
|
||||
```
|
||||
|
||||
**Headphone detection does not work with an amplifier.** The WCD9340 decides
|
||||
what is in the socket by measuring impedance, which suits headphones (16-32
|
||||
ohm) and not a line input — an amplifier looks like an open circuit, so
|
||||
`Headphone Jack` (numid=108) never leaves `off`. PipeWire takes that as
|
||||
authoritative, marks the port `not available`, refuses to keep it as the
|
||||
default sink, and GNOME hides it from Settings, so a perfectly working output
|
||||
becomes unreachable. The output itself is fine: `speaker-test -D plughw:0,2`
|
||||
(the headphone PCM, MultiMedia3 — the speakers are `hw:0,0`) plays through it.
|
||||
`overlay/usr/share/alsa/ucm2/Qualcomm/sdm845/HiFi-MM1.conf` is a copy of the
|
||||
alsa-ucm file with the Headphones device's `JackControl` line removed, which
|
||||
leaves availability `unknown` instead of `no` and makes the port permanently
|
||||
selectable. The trade is that real headphones no longer switch automatically.
|
||||
Since it shadows a packaged file, an `alsa-ucm` update puts the stock one back
|
||||
and the port vanishes from Settings again.
|
||||
|
||||
Unrelated to the hardware, two pieces of routing politics are worth knowing
|
||||
on a machine like this: PipeWire's RAOP discovery will happily make a
|
||||
neighbour's AirPlay speaker the default sink, and a newly connected
|
||||
|
||||
@@ -23,3 +23,27 @@ add_drivers+=" nvmem_qfprom qcom_scm rtc-pm8xxx "
|
||||
# of kilobytes in the initramfs fixes it. The model-signed zap shader is a
|
||||
# separate problem; see docs/firmware.md.
|
||||
install_items+=" /usr/lib/firmware/qcom/a630_sqe.fw.xz /usr/lib/firmware/qcom/a630_gmu.bin.xz /usr/lib/firmware/qcom/sdm845/a630_zap.mbn.xz "
|
||||
|
||||
# The DSPs lose the same race, and cannot be fixed the same way. qcom_q6v5_pas
|
||||
# auto-boots the ADSP, CDSP and SLPI the moment it probes; if that happens in
|
||||
# the initramfs the per-model firmware on the real root is not there yet:
|
||||
#
|
||||
# remoteproc remoteproc0: Direct firmware load for
|
||||
# qcom/sdm850/LENOVO/81JL/qcadsp850.mbn failed with error -2
|
||||
#
|
||||
# and, as with the GPU, nothing retries. The ADSP hosts the whole audio path,
|
||||
# so the result is a machine with no sound card at all — the sound driver sits
|
||||
# in deferred probe reporting "error getting cpu dai name", which says nothing
|
||||
# about firmware and sends you looking in the wrong place.
|
||||
#
|
||||
# Putting these blobs in the initramfs is not an option: they are ~20 MiB, and
|
||||
# unlike the Adreno firmware they are not in any package — they are extracted
|
||||
# from Windows by c630-firmware, so at build time they may not exist. Keeping
|
||||
# the driver out of the initramfs instead means it loads after the switch to
|
||||
# the real root, where the firmware is plainly visible. Nothing needs a DSP to
|
||||
# get that far.
|
||||
#
|
||||
# The modem driver goes too. It is not needed early either, and leaving it out
|
||||
# keeps it from crash-looping (see docs/firmware.md) before the rmtfs drop-in
|
||||
# that tames it has had a chance to start.
|
||||
omit_drivers+=" qcom_q6v5_pas qcom_q6v5_mss "
|
||||
|
||||
100
overlay/usr/share/alsa/ucm2/Qualcomm/sdm845/HiFi-MM1.conf
Normal file
100
overlay/usr/share/alsa/ucm2/Qualcomm/sdm845/HiFi-MM1.conf
Normal file
@@ -0,0 +1,100 @@
|
||||
# Use case configuration for LenovoYOGAC6301.
|
||||
# Author: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
#
|
||||
# Local copy of the file from alsa-ucm, with one line removed: the Headphones
|
||||
# device no longer declares
|
||||
#
|
||||
# JackControl "Headphone Jack"
|
||||
#
|
||||
# The WCD9340 detects what is in the socket by measuring its impedance, which
|
||||
# works for headphones (16-32 ohm) and not for a line input — an amplifier
|
||||
# presents something close to an open circuit, so the jack control stays 'off'
|
||||
# and nothing is ever detected as plugged in. PipeWire then marks the port
|
||||
# "not available", refuses to keep it as the default sink, and GNOME hides it
|
||||
# from Settings entirely, so there is no way to select an output that works
|
||||
# perfectly well.
|
||||
#
|
||||
# Without JackControl the port's availability is "unknown" rather than "no",
|
||||
# which makes it permanently selectable. The cost is that plugging in real
|
||||
# headphones no longer switches to them automatically; you pick the output by
|
||||
# hand. On a machine wired to an amplifier that is the better trade, and the
|
||||
# detection it gives up was never working for that case anyway.
|
||||
#
|
||||
# Only Qualcomm/sdm845/Lenovo-YOGA-C630-13Q50.conf includes this file, so the
|
||||
# override cannot affect any other card. It does shadow an alsa-ucm file, and
|
||||
# rpm will put the stock one back when that package updates — after which the
|
||||
# headphone port disappears from Settings again until this is reapplied.
|
||||
|
||||
SectionVerb {
|
||||
|
||||
EnableSequence [
|
||||
cset "name='SLIMBUS_0_RX Audio Mixer MultiMedia1' 1"
|
||||
cset "name='SLIMBUS_1_RX Audio Mixer MultiMedia3' 1"
|
||||
cset "name='MultiMedia2 Mixer SLIMBUS_0_TX' 1"
|
||||
]
|
||||
|
||||
Include.wcde.File "/codecs/wcd934x/DefaultEnableSeq.conf"
|
||||
Include.wsae.File "/codecs/wsa881x/DefaultEnableSeq.conf"
|
||||
|
||||
Include.wcdd {
|
||||
File "/codecs/wcd934x/DefaultDisableSeq.conf"
|
||||
Before.DisableSequence "0"
|
||||
}
|
||||
|
||||
DisableSequence [
|
||||
cset "name='SLIMBUS_0_RX Audio Mixer MultiMedia1' 0"
|
||||
cset "name='SLIMBUS_1_RX Audio Mixer MultiMedia3' 0"
|
||||
cset "name='MultiMedia2 Mixer SLIMBUS_0_TX' 0"
|
||||
]
|
||||
|
||||
Value {
|
||||
TQ "HiFi"
|
||||
}
|
||||
}
|
||||
|
||||
SectionDevice."Speaker" {
|
||||
Comment "Speaker playback"
|
||||
|
||||
Include.wcdspke.File "/codecs/wcd934x/SpeakerEnableSeq.conf"
|
||||
Include.wcdspkd.File "/codecs/wcd934x/SpeakerDisableSeq.conf"
|
||||
Include.wsaspke.File "/codecs/wsa881x/SpeakerEnableSeq.conf"
|
||||
Include.wsaspkd.File "/codecs/wsa881x/SpeakerDisableSeq.conf"
|
||||
|
||||
Value {
|
||||
PlaybackPriority 100
|
||||
PlaybackPCM "hw:${CardId},0"
|
||||
PlaybackMixer "default:${CardId}"
|
||||
PlaybackMixerElem "Speaker"
|
||||
}
|
||||
}
|
||||
|
||||
SectionDevice."Headphones" {
|
||||
Comment "Headphones playback"
|
||||
|
||||
Include.wcdhpe.File "/codecs/wcd934x/HeadphoneEnableSeq.conf"
|
||||
Include.wcdhpd.File "/codecs/wcd934x/HeadphoneDisableSeq.conf"
|
||||
|
||||
Value {
|
||||
PlaybackPriority 200
|
||||
PlaybackPCM "hw:${CardId},2"
|
||||
PlaybackMixer "default:${CardId}"
|
||||
PlaybackMixerElem "HP"
|
||||
}
|
||||
}
|
||||
|
||||
SectionDevice."Mic" {
|
||||
Comment "Mic"
|
||||
|
||||
Include.wcdmice.File "/codecs/wcd934x/HeadphoneMicEnableSeq.conf"
|
||||
Include.wcdmicd.File "/codecs/wcd934x/HeadphoneMicDisableSeq.conf"
|
||||
|
||||
DisableSequence [
|
||||
cset "name='AMIC MUX0' ZERO"
|
||||
]
|
||||
|
||||
Value {
|
||||
CapturePriority 100
|
||||
CapturePCM "hw:${CardId},1"
|
||||
CaptureMixerElem "ADC2"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user