thesofproject / avs-topology-xml

Configuration files for Intel AudioVoiceSpeech (AVS) driver
Apache License 2.0
3 stars 1 forks source link

dmic on chromebooks not working in 2ch mode. #16

Closed WeirdTreeThing closed 1 year ago

WeirdTreeThing commented 1 year ago

I've personally tested this on the cave and snappy chromebooks but the same thing seems to happen on every chromebook using the avs driver. The default NHLT configuration for dmic on MrChromebox's uefi firmware is 2ch, which gives this error in dmesg:

[   19.115046] snd_soc_avs 0000:00:0e.0: no DMIC ep_blob found
[   19.115061] snd_soc_avs 0000:00:0e.0: module-type create failed: -2
[   19.115065] snd_soc_avs 0000:00:0e.0: error creating module -2
[   19.115116] snd_soc_avs 0000:00:0e.0: create path failed: -2
[   19.115120] snd_soc_avs 0000:00:0e.0: ASoC: error at snd_soc_dai_hw_params on DMIC Pin: -2
[   19.115132]  DMIC: ASoC: error at __soc_pcm_hw_params on DMIC: -2
[   19.115136]  Digital Microphone: ASoC: error at dpcm_fe_dai_hw_params on Digital Microphone: -2

If I recompile the firmware with 4ch dmic it is able to load just fine. However, the actual mic hardware is only 2 channels which makes the rear 2 channels very noisy and lowers the quality of the mic recording.

crojewsk-intel commented 1 year ago

Thanks for testing things out, @WeirdTreeThing.

If I recompile the firmware with 4ch dmic

Could you elaborate?

I believe updating the topology so it exposes both 2ch and 4ch formats should do the trick. And then some smart code within the kernel to intersect formats exposed by the topology file with ones exposed by the NHLT. NHLT is an ACPI table that describes hardware capabilities for non-HDAudio devices (the shortcut literally standards for: NonHDAudioLinkTable) which DMIC is example of.

WeirdTreeThing commented 1 year ago

Could you elaborate?

If I wanted to change between 2ch and 4ch on snappy for example, I would need to edit the Kconfig for the reef board and change the included NHLT blob.

cujomalainey commented 1 year ago

On default ChromeOS we consume 4ch and just remap to the correct channels.

WeirdTreeThing commented 1 year ago

I could do something similar to that with UCM but that would still require modifying the firmware.

cujomalainey commented 1 year ago

I could do something similar to that with UCM but that would still require modifying the firmware.

Just to be clear we do the remapping in the audio server, not the dsp

WeirdTreeThing commented 1 year ago

I know, I meant that out of the box MrChromebox's coreboot firmware is set to 2ch which gives the error I showed above. The remapping I could do would be done with UCM macros.

crojewsk-intel commented 1 year ago

Hmm.. if you can enable 4ch DMIC in coreboot firmware, is my assistance required?

WeirdTreeThing commented 1 year ago

It would be preferred if both 2ch and 4ch DMIC worked.

crojewsk-intel commented 1 year ago

@WeirdTreeThing I've checked the DMIC topology XML with intention to add missing formats but it seems everything is already in place i.e.: entries for 2ch are there.

Did you try opening the pcm device while explicitly setting channel count to 2? Example:

arecord -Dhw:0,1 -c 2 -r 48000 -f S32_LE -vv > /dev/null
WeirdTreeThing commented 1 year ago

@crojewsk-intel If I try setting the channel count to 2 in arecord I get this error.

Recording WAVE 'stdin' : Signed 32 bit Little Endian, Rate 48000 Hz, Stereo
arecord: set_params:1416: Unable to install hw params:
ACCESS:  RW_INTERLEAVED
FORMAT:  S32_LE
SUBFORMAT:  STD
SAMPLE_BITS: 32
FRAME_BITS: 64
CHANNELS: 2
RATE: 48000
PERIOD_TIME: 125000
PERIOD_SIZE: 6000
PERIOD_BYTES: 48000
PERIODS: 4
BUFFER_TIME: 500000
BUFFER_SIZE: 24000
BUFFER_BYTES: 192000
TICK_TIME: 0

Along with the same error I initially described in dmesg

[   83.206138] snd_soc_avs 0000:00:0e.0: no DMIC ep_blob found
[   83.206147] snd_soc_avs 0000:00:0e.0: module-type create failed: -2
[   83.206151] snd_soc_avs 0000:00:0e.0: error creating module -2
[   83.206242] snd_soc_avs 0000:00:0e.0: create path failed: -2
[   83.206246] snd_soc_avs 0000:00:0e.0: ASoC: error at snd_soc_dai_hw_params on DMIC Pin: -2
[   83.206259]  DMIC: ASoC: error at __soc_pcm_hw_params on DMIC: -2
[   83.206263]  Digital Microphone: ASoC: error at dpcm_fe_dai_hw_params on Digital Microphone: -2

The same thing happens with 4 channels too

Recording WAVE 'stdin' : Signed 32 bit Little Endian, Rate 48000 Hz, Channels 4
arecord: set_params:1416: Unable to install hw params:
ACCESS:  RW_INTERLEAVED
FORMAT:  S32_LE
SUBFORMAT:  STD
SAMPLE_BITS: 32
FRAME_BITS: 128
CHANNELS: 4
RATE: 48000
PERIOD_TIME: 125000
PERIOD_SIZE: 6000
PERIOD_BYTES: 96000
PERIODS: 4
BUFFER_TIME: 500000
BUFFER_SIZE: 24000
BUFFER_BYTES: 384000
TICK_TIME: 0

Pulseaudio is able to record 4 channels just fine, pipewire gives the same error in dmesg.

crojewsk-intel commented 1 year ago

Could you attach your NHLT here? Also, please dump the entire dmesg from the performed scenario. Before doing so, ensure the dynamic debug for relevant modules is enabled:

// open an existing or create new .conf file in /etc/modprobe.d/
options snd_soc_avs dyndbg==pmf
options snd_soc_core dyndbg==pmf
options snd_intel_dspcfg dyndbg==pmf dsp_driver=4
WeirdTreeThing commented 1 year ago

Sure, the dmesg is in the form of the system journal since the actual dmesg is cut off. I am currently using the stock ChromeOS firmware so the NHLT shouldn't be causing the problem. journal.txt NHLT.txt (NHLT is .txt so that github would let me upload it)

crojewsk commented 1 year ago

The only format I see in your NHLT for DMIC is 4/16/16/48000 as informed by snd_intel_dspcfg:

Apr 05 16:03:18 snappy kernel: snd_intel_dspcfg:nhlt_check_ep_match: snd_soc_avs 0000:00:0e.0: Endpoint: vbus_id=0 link_type=2 dir=1 dev_type = 0
Apr 05 16:03:18 snappy kernel: snd_intel_dspcfg:nhlt_get_specific_cfg: snd_soc_avs 0000:00:0e.0: Endpoint format count=1
Apr 05 16:03:18 snappy kernel: snd_intel_dspcfg:nhlt_get_specific_cfg: snd_soc_avs 0000:00:0e.0: Endpoint format: ch=4 fmt=16/16 rate=48000

whereas the user is attempting either 2/32/32/48000 or 4/32/32/48000. Have you tried with 4/16/16/48000?

WeirdTreeThing commented 1 year ago

That's it, the problem was the audio server would set the format to s32le by default and would fail. Both the 4ch and 2ch NHLT work with s16le.

WeirdTreeThing commented 1 year ago

My solution was to use a wireplumber config file to force pipewire to set the format to S16_LE on dmic. I've been using this for some time now and it has been working perfectly, thanks for all the help.