Hibernation

So, another day, another update. Today I managed to get hibernation working on my Dell XPS13 Plus (9320) running Debian.

So, a quick recap. I’m running Debian testing. I set up the system with Guided – Use entire disk and Setup LVM. This leaves me with an encrypted root partition. What I want to do now, is to put a reasonably sized swap file there, and make the system hibernate to it.

So, first, I created a 35 GB (35840MB) large swapfile as /swapfile. I prefer to create a swapfile slightly larger than RAM, to ensure that everything fits and my machine comes with 32GB of RAM. I used the instructions in the excellent Arch Wiki to set this up. I also edited /etc/fstab, commenting out the swap partition setup by the installer and adding the swapfile.

Then, I followed these instructions to find and set the resume and resume_offset in the /etc/defaults/grub file. I changed the GRUB_CMDLINE_LINUX_DEFAULT parameter.

A quick reboot followed by a sudo swapon --show told me that the swap file was active, so time to hibernate!

sudo systemctl hibernate

This resulted in a lovely Sleep verb "hibernate" not supported error message in bright red. Lovely.

After some poking around I had a look at dmesg and found a reference to kernel lockdown. It turns out that you cannot hibernate if kernel lockdown is active. Being more concerned about battery life than some expert hacker stealing my computer and getting to all my data, I decided to try to get rid of it. Turns out that by disabling secure boot in BIOS does the trick.

So, now this works. Let’s see when I can fix the next issue. I’ve got the audio issue discussed earlier and the web cam left to fix.

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…

fosdem 2022

Yet another virtual fosdem. The organizer team does an amazing job putting it together, but fosdem without the hallway track will never be the same.

Nevertheless, I gave two talks in the Conference Organisation devroom. One on the topic of of the video flow that is used at foss-north, using OBS, Jitsi and Kdenlive. The other talk was about using pgeu-system to run a conference. Here, I was joined by the project author, Magnus Hagander, during the Q&A.

All in all, good fun. But I’m already looking forward to 2023 and a physical event in Brussels. Take care and I’ll see you there!

The Next Step

I recently blogged about my departure from MBition after a four year stint helping to build a software department within Mercedes Benz. Having contemplated various possible paths, I decided to leave my comfort zone and move away from automotive on-board software, which has been my life for the past 11 years.

Instead, I will help Autoliv Research’s ML/AI team to help them build awesome detection tools to help save more lives. This means working with a group of very smart people ranging from domain experts on things such as psychology, bio-mechanics, machine learning, embedded systems, mechatronics and more. I’m really really excited about this – so much fun to learn.

It is still early days and I still have a lot to learn, so I don’t know the details yet. I’ve been meeting people from all around the world for the past week and a half, and will continue to do so until Christmas, but the real fun starts in 2022.

The team is growing, so if you are interested in joining me in a quest to save lives and learning about real life applications of ML/AI in small embedded systems, don’t hesitate to reach out.

Moving on

In the autumn of 2017, me and my family moved down to Berlin for a month to start the infotainment software part of MBition. We were a handful of people at Mindspace in Mitte. I’ve never done so many interviews in my life – and I’ve never had the opportunity to get to know so many great people.

Fast forward to today, and we have grown to over 400 people in the project and are about to deliver an amazing product. The architecture team has grown from a one man team consisting of me, into one of the best groups of engineers I’ve ever worked with.

We wanted to change the world. We could not change everything, but I feel that we are bringing improvements to the project, as well as building a better foundation for future work at Mercedes Benz. I very much want to buy the first car with the MBient platform in it, as I know it will be an amazing product.

This has been a fantastic journey and one of the most challenging, but also rewarding, parts in my career. However, all things must come to an end. I’m sad to leave, but I’m also happy to say that I’m staying with the project as a part of the MBition Advisory Council. I’m happy not to go to Berlin twice a month, but I’m already missing the city, so I’m glad that I know that I will come back.

There are so many I’d like to thank and mention so I cannot begin to try to list you all – I’ll just forget someone. You know who you are! Keep up the great work and let’s meet the next time I’m in town!

Sharing dimensions

Continuing my adventures in FreeCAD, I now had to design a top to my Raspberry Pi enclosure. The FreeCAD people were friendly and told me to checkout spreadsheets.

However, since I already started down another path, I decided to name my constraints. Something I picked up from a random YouTube tutorial I cannot seem to find again.

Having done so, I can then refer to the name in a formula and thus, reuse the old value.

Now, let’s see how the lid will fit. :-)

FreeCAD-ing

I just got myself a 3D printer. It is my second one – I built a reprap back in 2013 – but this one is slightly more convenient to use. I went for the Creality CR6-SE. It works good enough for me out of the box, even though 3D printing is a topic where you can spend infinite time tweaking things.

I used to use OpenSCAD to create my models, as it maps well to my way of thinking (i.e. coding). However, I’ve decided to take some time to learn some new skills and this time around I went for FreeCAD.

FreeCAD is a free, as in freedom, parametric CAD program with a vibrant community. I’m new to CAD – parametric or not – so this is a learning experience for me.

I decided to create a case for my Raspberry Pi and PiTFT based home automation control panel shown in the video below.

To make this happen I first drew the important parts of the Raspberry Pi and the PiTFT hat, to be able to check that the case actually fits the contents. Then I dove into the creation of an enclosure.

The process of sketching, padding, rinse, and repeat is easy and somewhat tedious. I bet there are lots of ways to optimize this. E.g. by parametrize some dimensions to avoid having to “hardcode” them into each sketch. I guess smarter people can share some reference points between sketches too, e.g. to align the holes in the Raspberry Pi to the pegs and peg feet. I’ll learn this the next time around.

Having designed a bottom half, I decided to test fit it, so time to slice it up and then print it. Yes, I use the slicer that came with the printer, as I don’t want to tinker with the printer, but rather with the things I print.

Slicing the bottom of the case

Below, you can see the end result from the first test fitting. Hopefully the picture below shows something that fits as I bravely wrote this while printing. If not, then I really learned something, because I made a mistake.