Skip to content

Instantly share code, notes, and snippets.

@crojewsk
Last active April 3, 2024 08:21
Show Gist options
  • Save crojewsk/4e6382bfb0dbfaaf60513174211f29cb to your computer and use it in GitHub Desktop.
Save crojewsk/4e6382bfb0dbfaaf60513174211f29cb to your computer and use it in GitHub Desktop.
Enabling HDA (dsp) plus DMIC audio configuration on Skylake and Kabylake platforms

Linux: HDA+DMIC with skylake driver

Table of Contents


Audience

This document targets Skylake, Kabylake, Kabylake-refresh, Amberlake and some other platforms where audio is of SPT (PCH) type. HDA (with DSP capabilities) plus DMIC configuration is supported on these with skylake driver. Throughout this document said driver will also be refered to as snd_soc_skl. To see if your device matches the type, navigate to: /sys/devices/pci0000\:00/0000\:00\:1f.3/ and do: cat device. PCI device ids: 0x9d70 or 0x9d71 denote that indeed this doc is what you're looking for.

Requirements

Make sure your kernel is at least v5.4 before continuing. Several problems that had previously existed with skylake were addressed and merged with v5.7-rc1 sound PR. These fixes were then backported to v5.4 LTS kernel. Additional updates were provided later on to address issues troubling DMIC. Older kernels do not come with these fixes applied so HDA+DMIC configuration is unsupported.

For some of the steps it's best if you have your git at the ready. Configuration files may not be present by default on your machine. alsatplg tool, which will be handy for creating topology binaries should be installed by default but you can always follow official alsa-lib and alsa-utils guides to compile these by your own if available version does not suffice.

Limitations

skylake driver supports Realtek and HDMI (Intel) HDA codecs. Other vendors, such as Conexant are not supported.

Advanced users

Feel free to backport mentioned patches to earlier kernels. When doing so, please note commits which initially introduced hda-dsp machine driver came with v4.20. So, going below v4.20 requires extra work.

When compiling kernel yourself, remember to select kernel configuration options listed below. make menuconfig should help you with that.

Device Drivers
  Sound card support
    Advanced Linux Sound Architecture
      HD-Audio
        <M> HD Audio PCI
        <M> Build Realtek HD-audio codec support
        <M> Build HDMI/DisplayPort HD-audio codec support

      ALSA for SoC audio support
        [*] Intel ASoC SST drivers
          <M> Skylake Platforms
          <M> Kabylake Platforms
          [*] HDAudio codec support

        Intel Machine drivers
          <M> SKL/KBL/BXT/APL with HDA Codecs

With these, both skylake driver and skl_hda_dsp_generic machine board driver will be compiled and able to interact with each other during runtime.

Enabling the configuration

First check the device type, if indeed your audio DSP is of SPT-type as mentioned in Audience.

Topology

Topologies are stored in alsa-topology-conf repo and once compiled, should be moved to /lib/firmware/ directory. Their naming also needs to be precise. Default, exact name is complicated so it's recommended that you use a more friendly option. Topology search algorithm present in skl_tplg_init() fetches for topology binary three times before giving up:

  • Exact name: based on OEM and revision ids, plus PCI device id
  • Friendly name: <machine_driver_name>-tplg.bin. For HDA+DMIC configuration that's always: skl_hda_dsp_generic-tplg.bin
  • Fallback, static name: dfw_sst.bin

To manually install topology, clone alsa-topology-conf and navigate to /topology/hda-dsp subdirectory. Then, make use of alsatplg tool:

alsatplg -c skl_hda_dsp_generic-tplg.conf -o skl_hda_dsp_generic-tplg.bin

and move generated output to /lib/firmware/ so it can be consumed by skylake driver later on.

Kernel modules

While two drivers can support audio on our platforms of interest, only one, HDA legacy or HDA DSP driver may be running at a time. These are represented by snd_hda_intel and snd_soc_skl respectively. For HDA+DMIC you need the latter. Selection is performed with help of snd_intel_dspcfg module. See the source for more info regarding selection mechanism, especially the FLAG_XXX macros. Said module exposes dsp_driver parameter which influences driver selecting during runtime. To force skylake driver selection, append:

options snd_intel_dspcfg dsp_driver=2

within any or new file within /etc/modprobe.d/<file> directory. Value of 2 stands for SST - skylake. This needs to be done only once. To see if the selection succeeded, after reboot, navigate to: /sys/module/snd_intel_dspcfg/parameters/ and see the output of: cat dsp_driver.

NHLT overridding

This ACPI table takes part in configuring DMIC portion of our HDA+DMIC setup. Default table should be sufficient for supporting basic audio cases. Unfortunatelly, should is not always. Please, refer to initrd_table_override guide in order to override onboard NHLT with new one. You will also need acpi-overrides scripts. As currently no public tools are available to edit NHLT manually, it's best if you ask intel developers for help to obtain correct NHLT binary. You may also checkout NLHT speficication if you want to try to fix the problems yourself.

UseCaseManagement

Sometimes sound card's behaviour may be dummy or lackluster. Usually this comes from missing or incorrect use-case configuration. This is where UseCaseManagement (ucm) files come into play. These are officially available at alsa-ucm-conf and should be installed under /usr/share/alsa/ucm2. Each separate file or package targets concrete configuration. Here, we're looking for HDA+DMIC one: /ucm2/hda-dsp. Chances are, you already have plenty of these present so adding new or updating existing should be straightforward. Refer to alsaucm manual for additional information.

DSP Firmware (optional)

While proper DSP firmware binaries should already be present, it's worth noting these are located in /lib/firmware/intel/. You should notice pattern in their naming, only suffix gets changed: kbl goes for 0x9d71 devices, while release for 0x9d70 ones. Multiple firmware versions may be present, skylake driver loads only generically-named onces though. These are often symbolic links. If you ever need to update firmware file manually, checkout linux-firmware repo and simply backup and remove existing, generically-named file and create new symbolic link targeting your new file, e.g.:

ln -s dsp_fw_spt_release_vNewVersion.bin dsp_fw_release.bin

Do's when filing a ticket

When everything fails, feel free to send Intel a ticket. When doing so, it's worth remembering couple of important steps. These will help us in fixing your issue quicker so you can enjoy smooth audio experience sooner.

  • Provide dmesg output. dmesg > log.txt suffices. It's appreciated if said log contains early boot information i.e. dumped right after boot. If problem occurs later, you can provide two dmesg(s) instead: one from boot and one from runtime, once the problem presents itself. Please note that the default log level may not be sufficient. To enable debug logs, navigate to /etc/modprobe.d/ and similarly to snd_intel_dspcfg case, append within any or new file:
options snd_hda_core dyndbg==pmf
options snd_hda_codec dyndbg==pmf
options snd_soc_core dyndbg==pmf
options snd_soc_skl dyndbg==pmf

These ensure dmesg will be rich with audio related logs.

  • Attach kconfig, that is kernel config file which your kernel image is based on. These should be available in /boot/ directory. For exact match, check output of uname -r and select file matching: config-<uname -r> pattern.
  • Don't forget to add topology binary for HDA+DMIC configuration If your /lib/firmware/ directory contains it.
  • Dump NHLT table. To do that, do: cat /sys/firmware/acpi/tables/NLHT > ~/nhlt.dat
  • General ALSA information, output of: alsa-info.sh --no-upload
  • List of sound modules loaded: lsmod | grep snd
  • PCI device ID of hda bus: cat /sys/devices/pci0000\:00/0000\:00\:1f.3/device
@Gnoenk
Copy link

Gnoenk commented Oct 3, 2022

Thank you for this instruction how to enable under Linux a Digitial Microphone "D-Mic" with Intel SmartSoundTechnology (SST) on Machines with Skylake-Processor and SunrisePoint-LP (Low Power) chipset!
As Linux SOF explicitly does not support Skylake/KabyLake processors your fine instruction is the first solution I could find offering a targeted solution.

Your instruction explicitly covers two hardware-ids - which are a combination of the Skylake processors and its Platform Controller Hub (PCH) "SunrisePoint" chipset.
However there is a distinction within the processor family towards high-performance and energy-saving lines.
This article describes the differences:
https://www.anandtech.com/show/10303/choosing-the-right-ssd-for-a-skylakeu-system

While the high-performance H-, S- and K- CPUs need a separate Intel 100 Series platform controller hub (Sunrise Point PCH), the Skylake-U and Skylake-Y are Multi-Chip Packages (MCP) that have the Sunrise Point-LP PCH die integrated with the CPU in a single package.

So this solution covers many Notebooks with low-power oriented Skylake-Processers combined with low-power SunrisePoint (which is hardware id 0x9d70) but it misses the other ones (like H-Series which is 0xa170).

As many others I am suffering from this issue as well as my Notebook (Acer VN7-792 G) contains a Skylake i7-6700 HQ processer and Mobile Intel® HM170 Chipset ( https://ark.intel.com/content/www/us/en/ark/products/90584/mobile-intel-hm170-chipset.html ). Unfortunately your description does not work for this processor-chipset combination.
The ids of my system are

vendor: 8086 ("Intel Corporation"), device: a170 ("100 Series/C230 Series Chipset Family HD Audio Controller").

so for this particular Skylake processor the PCI device id is 0xa170.

As power-consumption is the reason for the different details in the chipsets I researched further and found this article showing a "Skylake U/Y Processor Platform Overview"
https://www.anandtech.com/show/10121/intel-nuc6i5syk-skylake-ucff-pc-review
containing a feature mapping table of the "SKL PCH-LP" versus the "100 Series PCH". The row "Audio" shows in both cases the same entry with respect to DMic - so I assume that there are no differences in the underlying logic, target hardware functionality (like number of mics in the array etc.).

This gave me hope that your solution approach can be expanded to include the other Skylake Processors as well and I continued my search.

Therefore I updated my Notebook to run under Linux Mint 21 - so it does contain all program versions/libraries as stated in your instruction. Having these installed I did some further research in the relevant linux source files for "0x9d70" and came to following results:

Firstly in linux/sound/pci/hda/hda_intel.c and in https://github.com/torvalds/linux/blob/master/sound/pci/hda/hda_intel.c

	/* Sunrise Point */
	{ PCI_DEVICE(0x8086, 0xa170),
	  .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
	/* Sunrise Point-LP */
	{ PCI_DEVICE(0x8086, 0x9d70),
	  .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
	/* Kabylake */
	{ PCI_DEVICE(0x8086, 0xa171),
	  .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
	/* Kabylake-LP */
	{ PCI_DEVICE(0x8086, 0x9d71),
	  .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },

here are no differences for "0x9d70" versus "0xa170".

Secondly in linux/sound/soc/intel/skylake/skl.c and in https://github.com/torvalds/linux/blob/master/sound/soc/intel/skylake/skl.c
Herein again I searched for "0x9d70" and could find two passages which define certain actions for this PCI-ID (and "0x9d71") but nothing for "0xa170". Could this be the right place to add "something" to enable "0xa170" D-Mic as well?

I am neither a Linux expert nor a programmer - only a googling amateur trying to enable my fine notebook to be fully operable under Linux. So from hereon I have no idea what to do next.

Now my question is what to try next and whether you can help in this.

Note: It seems that all other functions controlled by the SunrisePoint PCH do work fine under Linux - only the D-Mic functionality does not.

@crojewsk
Copy link
Author

crojewsk commented Oct 3, 2022

Even if what you say about yourself @Gnoenk is true, you did an exceptional job navigating through all the hardware and kernel mysteries.

Given your input, I assume you'd like to enable DMIC configuration on a non-U/Y Skylake platform. If I'm correct about this, I'd suggest putting this on hold for a week or two. The reasoning is as follows:

  • skylake-driver is deprecated in professional environment (and is about to in end-to-end one); Its successor, the avs-driver is already present in the kernel and is located in the very same parent directory. SKL-H is covered by it too, although the relevant ID is not present in Linus tree yet.
  • configuration files for said driver should land in github.com/thesofproject umbrella within a week. Lots of examples of audio stream topologies (including DMIC one)
  • tools for compiling such topology files (and more) should either the same day or a week later under the same umbrella
  • this doc is going to be updated to highlight all the changes e.g.: how to transfer to the avs-driver. This does not mean current content is getting removed - not until the skylake-driver is completely removed from Linus' tree

Without clearance from the company side I cannot fully assist you in this endeavor. But this is about to change, as mentioned above. You'll be hearing from me soon enough.

@Gnoenk
Copy link

Gnoenk commented Oct 16, 2022

Thank you very much for your response!

Indeed your assumption is correct: I am looking for a working DMIC configuration on a Skylake non U/Y platform - this had me searching the internet again and again for a solution.
I am very happy to hear that the Skylake processor line does not get forgotten under Linux and that a successor driver is on its way.
So far the Skylake and KabyLake are not supported by SOF according to
https://thesofproject.github.io/latest/getting_started/intel_debug/introduction.html#pci-devices-introduced-after-2016
Do I understand correctly that the successor, the avs-driver, will become an element of SOF?

Hoping that you can assist in including this particular hardware configuration in the future setup I will stay patient. Looking forward for news from you!

@crojewsk
Copy link
Author

Hello @Gnoenk,

Think of the SOF as an umbrella for projects. And many are part of it. The avs-driver is tasked with covering older platforms, times when open-source firmware was not yet available.

Now, as there are several semi-connected subjects ongoing simultaneously (e.g.: thesofproject/linux/issues/3840), some of the changes required to enable configuration of yours have been already merged. Tooling and example topology configuration files are now available to the community as well, see thesofproject/avsdk and thesofproject/avs-topology-xml.

Updated AudioDSP firmware for SKL-based devices can be found here but will be soon sent to the official linux-firmware repository.

Due all of this ongoing work I've not been update to complete the docs, though the avsdk and the avs-topology-xml show quite a bit already. While the PR I'd mentioned earlier contains a link to a candidate branch for KBL+ES8336 support, it should also work for the configuration of yours. Once all the remaining patches pass the upstream review, will prepare linux-stable equivalent on either 5.19 or 6.0 so users (like you) have a reference to work with.

@paulhart
Copy link

Hi there, like some others I'm running Skylake device (the HP G1 13 "CHELL" Chromebook) and am curious about the state of things around audio - the instructions provided above and the updated ucm2 settings have caused the latest kernel to do different things, but it doesn't appear that we're much closer to a working sound solution.

Thanks for your efforts on this and the time you've spent answering our questions!

@crojewsk
Copy link
Author

crojewsk commented May 9, 2023

Hello @paulhart, could you open a new issue for avs-topology-xml. I'd like this gist not to become an issue-tracker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment