Debian on the XPS13 Plus (9320)

TL;DR; Still no sound, but I learned a couple of new things…

So, I finally got around to upgrading my laptop. I decided to go for my fourth XPS13, and this time I opted for a maxed out XPS13 Plus. A really nice machine. However, the driver stack isn’t quite there yet. Yes, I should have read up more before buying, but I didn’t and I know it will be sorted out over time.

As a vim user, the touch Esc key will be a challenge. Perhaps this is where I learn to bind to capslock, but I’ve not come to that point yet.

So, after installing using the netinst image with non-free drivers (and my phone over USB tether for networking since the wifi still didn’t work), I had to move to testing for anything to work. Then I installed firmware-iwlwifi, iwlwifi and firmware-sof-signed from non-free. This got me into a graphical desktop and most things work (I could configure the touch pad for tap-to-click, and so on). I run a KDE desktop, so I installed some Plymouth stuff, breeze for SDDM and such, but that shouldn’t affect the issues described here.

My current issues are the sound, the webcam and hibernation. The two latter items aren’t huge problems, but I do need sound. Both the webcam and sound issues are known. Hibernation is mostly about getting around to configuring it with the encrypted disk setup.

So, let’s start by diving into the audio issue. The early boot process looks like this:

[   20.595666] sof-audio-pci-intel-tgl 0000:00:1f.3: DSP detected with PCI class/subclass/prog-if info 0x040100
[   20.595750] sof-audio-pci-intel-tgl 0000:00:1f.3: SoundWire enabled on CannonLake+ platform, using SOF driver
[   20.595778] sof-audio-pci-intel-tgl 0000:00:1f.3: enabling device (0000 -> 0002)
[   20.596001] sof-audio-pci-intel-tgl 0000:00:1f.3: DSP detected with PCI class/subclass/prog-if 0x040100
[   20.596073] sof-audio-pci-intel-tgl 0000:00:1f.3: bound 0000:00:02.0 (ops i915_audio_component_bind_ops [i915])
[   20.602984] sof-audio-pci-intel-tgl 0000:00:1f.3: use msi interrupt mode
[   20.651283] sof-audio-pci-intel-tgl 0000:00:1f.3: hda codecs found, mask 4
[   20.652476] sof-audio-pci-intel-tgl 0000:00:1f.3: firmware: direct-loading firmware intel/sof/sof-adl.ri
[   20.652482] sof-audio-pci-intel-tgl 0000:00:1f.3: Firmware info: version 2:2:0-57864
[   20.652483] sof-audio-pci-intel-tgl 0000:00:1f.3: Firmware: ABI 3:22:1 Kernel ABI 3:23:0
[   20.652488] sof-audio-pci-intel-tgl 0000:00:1f.3: unknown sof_ext_man header type 3 size 0x30
[   20.747032] sof-audio-pci-intel-tgl 0000:00:1f.3: Firmware info: version 2:2:0-57864
[   20.747036] sof-audio-pci-intel-tgl 0000:00:1f.3: Firmware: ABI 3:22:1 Kernel ABI 3:23:0
[   25.758149] sof_sdw sof_sdw: snd_soc_register_card failed -517
[   25.768995] sof_sdw sof_sdw: snd_soc_register_card failed -517
[   25.799027] sof_sdw sof_sdw: snd_soc_register_card failed -517

If I later force a reload of the module, it all works:

sudo modprobe -r snd-sof-pci-intel-tgl; sudo modprobe snd-sof-pci-intel-tgl

Gives:

[  169.407671] sof-audio-pci-intel-tgl 0000:00:1f.3: DSP detected with PCI class/subclass/prog-if info 0x040100
[  169.407784] sof-audio-pci-intel-tgl 0000:00:1f.3: SoundWire enabled on CannonLake+ platform, using SOF driver
[  169.408027] sof-audio-pci-intel-tgl 0000:00:1f.3: DSP detected with PCI class/subclass/prog-if 0x040100
[  169.408133] sof-audio-pci-intel-tgl 0000:00:1f.3: bound 0000:00:02.0 (ops i915_audio_component_bind_ops [i915])
[  169.414240] sof-audio-pci-intel-tgl 0000:00:1f.3: use msi interrupt mode
[  169.428614] sof-audio-pci-intel-tgl 0000:00:1f.3: hda codecs found, mask 4
[  169.428802] sof-audio-pci-intel-tgl 0000:00:1f.3: firmware: direct-loading firmware intel/sof/sof-adl.ri
[  169.428809] sof-audio-pci-intel-tgl 0000:00:1f.3: Firmware info: version 2:2:0-57864
[  169.428810] sof-audio-pci-intel-tgl 0000:00:1f.3: Firmware: ABI 3:22:1 Kernel ABI 3:23:0
[  169.428814] sof-audio-pci-intel-tgl 0000:00:1f.3: unknown sof_ext_man header type 3 size 0x30
[  169.547087] sof-audio-pci-intel-tgl 0000:00:1f.3: Firmware info: version 2:2:0-57864
[  169.547115] sof-audio-pci-intel-tgl 0000:00:1f.3: Firmware: ABI 3:22:1 Kernel ABI 3:23:0
[  169.563645] sof-audio-pci-intel-tgl 0000:00:1f.3: firmware: direct-loading firmware intel/sof-tplg/sof-adl-rt1316-l12-rt714-l0.tplg
[  169.563665] sof-audio-pci-intel-tgl 0000:00:1f.3: Topology: ABI 3:22:1 Kernel ABI 3:23:0
[  169.564019] sof_sdw sof_sdw: ASoC: Parent card not yet available, widget card binding deferred
[  169.605390] sof_sdw sof_sdw: hda_dsp_hdmi_build_controls: no PCM in topology for HDMI converter 3
[  169.627693] input: sof-soundwire HDMI/DP,pcm=5 as /devices/pci0000:00/0000:00:1f.3/sof_sdw/sound/card0/input26
[  169.627738] input: sof-soundwire HDMI/DP,pcm=6 as /devices/pci0000:00/0000:00:1f.3/sof_sdw/sound/card0/input27
[  169.631375] input: sof-soundwire HDMI/DP,pcm=7 as /devices/pci0000:00/0000:00:1f.3/sof_sdw/sound/card0/input28

So, something happens after sof-adl.ri is loaded. This causes the driver to just stop before loading the sof-adl-rtl316-l12-rt714-l0.tplg firmware, causing the snd_soc_register_card to fail. Let’t have a look at the reasons.

First up, the excellent Arch Linux Wiki says to include the two firmware files and a bunch of modules in the initramfs. However, Arch and Debian uses different tools to build the initramfs, so let’s confirm the issue first:

lsinitramfs -l /boot/initrd.img-6.0.0-5-amd64  | grep 'intel/sof'

This call results in a list of nothing. Just to confirm, grepping for firmware or intel returns long lists of files. So, the firmware is not in the early initramfs image. How do I get the firmware files into the initramfs? Apparently I have to write what is known as an initramfs-tools hook script.

There lives a bunch of them over at /usr/share/initramfs-tools/hooks, so I started a very brute force one called intel-sof-firmware and tried to learn from the surrounding scripts and the manpage linked above. The result can be found in a gist here.

Notice that this is happy code. There is way too few sanity checks in there to make this useful to the general public. Your milage may vary.

So, I added the modules to /etc/initramfs/modules, and then updated the early initramfs images with this command:

sudo update-initramfs -k all -u

And then verified that the files made it to the image (I also had a look at the file listing in general to ensure that the image is ok):

lsinitramfs -l /boot/initrd.img-6.0.0-5-amd64  | grep 'intel/sof'

drwxr-xr-x   2 root     root            0 Dec 11 15:51 usr/lib/firmware/intel/sof
drwxr-xr-x   2 root     root            0 Dec 11 15:51 usr/lib/firmware/intel/sof-tplg
-rw-r--r--   1 root     root        28907 Dec 11 15:51 usr/lib/firmware/intel/sof-tplg/sof-adl-rt1316-l12-rt714-l0.tplg
-rw-r--r--   1 root     root       525056 Dec 11 15:51 usr/lib/firmware/intel/sof/sof-adl.ri

It all seems to work, so let’s reboot and see what comes out the other side. Notice – this can brick your computer if you make a mistake. And if something to do with a computer can brick your computer, you know that it will brick your computer. Don’t say I did not tell you.

Side note: I run an encrypted lvm setup, and if you try to fix this problem by removing all modules (go from many to netbook in the initramfs.conf) you will enjoy re-installing your machine. I’m sure you can unbrick it by booting from a USB stick and fixing stuff, but since I’ve not really installed anything, I don’t really care.

Guess what – after a couple of hours digging at this – I still have no sound…

sudo dmesg | grep sof

Results in this (yay, a new error code – that must mean that I’m doing something):

[    1.760559] sof-audio-pci-intel-tgl 0000:00:1f.3: DSP detected with PCI class/subclass/prog-if info 0x040100
[    1.760629] sof-audio-pci-intel-tgl 0000:00:1f.3: SoundWire enabled on CannonLake+ platform, using SOF driver
[    1.760643] sof-audio-pci-intel-tgl 0000:00:1f.3: enabling device (0000 -> 0002)
[    1.760785] sof-audio-pci-intel-tgl 0000:00:1f.3: DSP detected with PCI class/subclass/prog-if 0x040100
[    3.491343] sof-audio-pci-intel-tgl 0000:00:1f.3: bound 0000:00:02.0 (ops i915_audio_component_bind_ops [i915])
[    3.569000] sof-audio-pci-intel-tgl 0000:00:1f.3: use msi interrupt mode
[    3.585475] sof-audio-pci-intel-tgl 0000:00:1f.3: codec #2 probe error, ret: -2
[    3.585859] sof-audio-pci-intel-tgl 0000:00:1f.3: no hda codecs found!
[    3.585990] sof-audio-pci-intel-tgl 0000:00:1f.3: firmware: direct-loading firmware intel/sof/sof-adl.ri
[    3.585996] sof-audio-pci-intel-tgl 0000:00:1f.3: Firmware info: version 2:2:0-57864
[    3.585998] sof-audio-pci-intel-tgl 0000:00:1f.3: Firmware: ABI 3:22:1 Kernel ABI 3:23:0
[    3.586007] sof-audio-pci-intel-tgl 0000:00:1f.3: unknown sof_ext_man header type 3 size 0x30
[    3.702740] sof-audio-pci-intel-tgl 0000:00:1f.3: Firmware info: version 2:2:0-57864
[    3.702756] sof-audio-pci-intel-tgl 0000:00:1f.3: Firmware: ABI 3:22:1 Kernel ABI 3:23:0
[    3.709727] sof-audio-pci-intel-tgl 0000:00:1f.3: firmware: direct-loading firmware intel/sof-tplg/sof-adl-rt1316-l12-rt714-l0.tplg
[    3.709742] sof-audio-pci-intel-tgl 0000:00:1f.3: Topology: ABI 3:22:1 Kernel ABI 3:23:0
[    3.709825] sof-audio-pci-intel-tgl 0000:00:1f.3: error: can't connect DAI HDA0.OUT stream iDisp1
[    3.709920] sof-audio-pci-intel-tgl 0000:00:1f.3: error: failed to add widget id 0 type 27 name : HDA0.OUT stream iDisp1
[    3.710026] sof_sdw sof_sdw: ASoC: failed to load widget HDA0.OUT
[    3.710086] sof_sdw sof_sdw: ASoC: topology: could not load header: -22
[    3.710162] sof-audio-pci-intel-tgl 0000:00:1f.3: error: tplg component load failed -22
[    3.710247] sof-audio-pci-intel-tgl 0000:00:1f.3: error: failed to load DSP topology -22
[    3.710326] sof-audio-pci-intel-tgl 0000:00:1f.3: ASoC: error at snd_soc_component_probe on 0000:00:1f.3: -22
[    3.710447] sof_sdw sof_sdw: ASoC: failed to instantiate card -22
[    3.710692] sof_sdw sof_sdw: snd_soc_register_card failed -22
[    3.710758] sof_sdw: probe of sof_sdw failed with error -22

I suspect I’m missing another driver in the initramfs. Still, the modprobe trick shown above still fixes sound, so I guess I’ll leave it for today…