Audio Driver (with bounty!)


I've already spent most of it on "fixing" a stupid bug with the network card on the devboard so it doesn't get a random MAC address every boot.
Remember being down that rabbit hole too...
 
Yes, I've seen the release mails, but I can never find the actual commits I find interesting.
For example, the release you linked mentions "some fixes for soc_component_driver for aess", so I wanted to check that code. I followed the git download link (https://git.goldelico.com/?p=letux-kernel.git;a=shortlog;h=letux-6.2-rc4), but there was only a ton of merge commits. I didn't really feel like trudging through 50 other merged branches to find this 1 commit, so I entered the commit message in the search bar but it came up empty. I could of course clone the repo, but the Linux repo is big!
Yes, that is a little unfortunate with the Linux development model which finally wants to see a cleaned up set pf patches which does not favour collaboration on a single feature. This means that it is not the "pile up changes by everyone even if they undo something" model, but involves rebasing and merging patches that had been there in the previous version. So what are options: indeed cloning the repo. Or looking into the feature branch: https://git.goldelico.com/?p=letux-kernel.git;a=shortlog;h=refs/heads/letux/aess-v11 with a focus on the "important" stuff (everything else is also important but not for AESS). In the long run this will be squashed into roughly 5 to 10 patches when we try to get it upstream.
 
I can take a look :) unfortunately, time is running out this weekend so don't expect much :( I've already spent most of it on "fixing" a stupid bug with the network card on the devboard so it doesn't get a random MAC address every boot. Kinda annoying, but I have a workaround now. I also have nfsroot working, which will hopefully save me time in the long run :)
You could also add something to /etc/network/interfaces to set a fixed MAC or IP address.
 
You could also add something to /etc/network/interfaces to set a fixed MAC or IP address.
That unfortunately doesn't work with NFS boot since the kernel does DHCP before mounting the file system. Thanks for the suggestion though :)
 
I wonder how many people have invented this wheel?

An alternative is to actually solder in the eeprom missing at U17
 
  • Like
Reactions: hns
Some progress after another handful of testing hours: the mcbsp widgets are now defined. Will become part of the pending letux-6.2.0 release after some code consolidation.
But I still do not have the aess bubble picture as with 3.15. Next bug to trace down. Sadly there are no error messages...
A first hint is that the missing components are defined in the firmware source code. So something is not initialized properly during firmware load (which had to be significantly reworked for a modern kernel).
 
Last edited:
And after two days hunting the next bug, there is again progress. I can now get the same bubbles from vizdapm (or/sys/kernel/debug/asoc/omap5-uevm/401f1000.aess/dapm/) as by Risca. Well, the bug was a missing translation from old platform devices to component drivers which did lead to a duplication of some kernel-internal registration. This had the effect that no new entries could be added to the above mentioned debug directory. So everything was in place but not accessible for vizdapm.
Unfortunately the AESS subsystem still does not work and reports that it can't access the subschannels. Except the Legacy interface.
So I will consolidate this a little so that it is included in the new letux-6.2.0 kernel (binary and tree).

aess6.png
root6.png
twl6040-codec6.png
 
I took some time today to parse the omap4_abe_new firmware blob from here: https://git.ti.com/cgit/glsdk/abefw-omap4plus/
That's the firmware that is being used with the TI GLSDK 6.03.00.01. Looks like it contains much of the things that make up the graphs above, plus some vendor blobs as well.

This blob was made for Linux-3.8 and, if I understand correctly, it fails to load on the latest Pyra kernels. I know @hns has successfully recompiled the abefw blob for later kernel and managed to load it. I just wanted to try and verify that everything was converted correctly. I've come so far that I'm able to fully parse the old firmware.

Firmware parser available here: https://github.com/Risca/abefw_mangler
 
Firmware creation and loading the blobs with 6.3-rc2 seems to be ok. Note that the file format has significantly changed since 3.8 or 3.15 which was the major part of work to create a firmware blob in the format a modern kernel can read (sound/soc-topology). So trying to understand or modify the old binary blobs is IMHO a little pointless since the source code for building them from source is on github (https://github.com/omap-audio). Yes, such a blob contains mixer definitions, path definitions and the real firmware binary for the Audio Engine processor.

I am currently hunting why
amixer set "DL1 PDM" "on"
tells it is "on" but a following "amixer get" says it is still (or again) "off" on 6.3-rc2.
This works on 3.15 kernel and seems to be the reason why I get no backend DAIs enabled:
[ 284.203735] OMAP ABE Media LP: ASoC: no backend DAIs enabled for OMAP ABE Media LP
This can either be a firmware generation bug or setting up the mixer properly on reading. Or setting this mixer should go through the AE firmware (which must be up and running but I wasn't able to find out yet). There are multiple potential locations for the reason of this failure...
 
Last edited:
Latest news: I just had commented out the operational code in aess_put_switch(). So it was a NO-OP. Firmware generation and loading is good and doing what is expected.
Now the "ASoC: no backend DAIs enabled for OMAP ABE Media LP" error is gone, but aplay is stuck at 00:00:00.00 until some timeout occurs.
So a little progress after several hours of searching and analyzing deepest details. Just another onion shell around the final bug removed.

Edit: I can now also get "green" bubbles :)

aess6.png
root6.png
 
Last edited:
Firmware creation and loading the blobs with 6.3-rc2 seems to be ok. Note that the file format has significantly changed since 3.8 or 3.15 which was the major part of work to create a firmware blob in the format a modern kernel can read (sound/soc-topology). So trying to understand or modify the old binary blobs is IMHO a little pointless since the source code for building them from source is on github (https://github.com/omap-audio). Yes, such a blob contains mixer definitions, path definitions and the real firmware binary for the Audio Engine processor.
It was also a lot of fun :D never really worked with binary data in python before so I thought I'd give it a try. I also wanted to understand how things used to work before, so that I can compare it with today. I figured I would do a similar exercise on a modern firmware to see if I could find any bugs.

All in all: great work!

EDIT: I did note the distinct lack of green bubble around BE_OUT. Not sure what that means though, but looks like it's super close to getting audio out!
 
EDIT: I did note the distinct lack of green bubble around BE_OUT. Not sure what that means though, but looks like it's super close to getting audio out!
Yes, that was a great hint!

I've spent some time to analyse what makes the bubbles red or green (BTW on a Pyra now. Just to see if it makes a difference): the Red/Green bubble color represents the "DAPM Widget" power state (a single bit in struct snd_soc_dapm_widget).

But that is only the symptom, not the reason why BE_OUT stays red. From other searches through the code and some wild guess I think "BE_OUT" means "Backend Out" or in other words: the PCM connection between the OMAP and the twl6040 audio codec chip. So we are now no longer checking for firmware load issues or getting the sound links and graphs right, but getting all components powered on demand.

Well, I have not yet any idea how and where in the code the PCM should be powered on... Needs some more hours to find out... Only the observed result is very reasonable: if the McPDM interface is not powered up, the kernel or ALSA play tool waits until some timeout for the sound data going out. Which never happens.

But maybe this are things I can compare to the Pandaboard 3.15 kernel and see what that one would do or really does. Either by looking into the code or by adding some printk at the right positions.
 
Yes, that was a great hint!

I've spent some time to analyse what makes the bubbles red or green (BTW on a Pyra now. Just to see if it makes a difference): the Red/Green bubble color represents the "DAPM Widget" power state (a single bit in struct snd_soc_dapm_widget).

But that is only the symptom, not the reason why BE_OUT stays red. From other searches through the code and some wild guess I think "BE_OUT" means "Backend Out" or in other words: the PCM connection between the OMAP and the twl6040 audio codec chip. So we are now no longer checking for firmware load issues or getting the sound links and graphs right, but getting all components powered on demand.

Well, I have not yet any idea how and where in the code the PCM should be powered on... Needs some more hours to find out... Only the observed result is very reasonable: if the McPDM interface is not powered up, the kernel or ALSA play tool waits until some timeout for the sound data going out. Which never happens.

But maybe this are things I can compare to the Pandaboard 3.15 kernel and see what that one would do or really does. Either by looking into the code or by adding some printk at the right positions.
Maybe if you put a dumpstack on the pandaboard where the McPDM gets turned on?
 
Yes, dump_stack() and printk() are your friends :)
Well, it turned out that the initialisation is basically right, except that powering BE_OUT addresses the legacy codec path and not the abe path.
This may (or may not) be a bug in converting abe_be_mcpdm_dai[] to some new macros...
At least I see a difference in the stream name which is tried to be powered on.

Edit: has already helped to fix the macros for the stream name and some other bugs, but BE_OUT remains a "red" bubble.
 
Last edited:
Latest insights after some more hours of searching: is_connected_output_ep() is returning 0 for the BE_OUT widget in the v6.3 kernel while it returns 1 on v3.15. This makes the bubble in the graph stay red. Unfortunately, the code has been significantly reworked and it is not yet obvious why this return value is different. Can have a lot of reasons. And it is difficult to compare what the code is doing (or not doing and why not).

If you want to inspect:
https://elixir.bootlin.com/linux/v6.3-rc4/source/sound/soc/soc-dapm.c#L1248
https://elixir.bootlin.com/linux/v3.15/source/sound/soc/soc-dapm.c#L885

Note that it is a recursive function walking through the widget graph. So it might depend on the exact data in the widget graph. Which may be initialized wrongly somewhere else.
 
And a little progress: the BE_OUT bubble now turns green.
Well, it wasn't really a bug, but a 10 years old function of the twl6040 driver that didn't play a significant role before adding the AESS code. Just a single line of code needed to be changed. In fact a sufficient workaround is changing a constant from 1 to 0 but I am not sure it is really a good solution that works in all situations...
Still a 'play' command hangs. Maybe, because the Audio Engine signal processor isn't running and fetching the provided audio stream data blocks.
 
Still a 'play' command hangs. Maybe, because the Audio Engine signal processor isn't running and fetching the provided audio stream data blocks.
It might be some clocks are not turned on properly? Or power turned off for some subsystem in the audio path
 
Back
Top