raspberrypi / linux

Kernel source tree for Raspberry Pi-provided kernel builds. Issues unrelated to the linux kernel should be posted on the community forum at https://forums.raspberrypi.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Pi 5 and soundcards - problems and solutions

pelwell opened this issue · comments

Describe the bug

This issue is meant to be a common place to discuss the changes required for I2S support on Pi 5. Existing issues that cover this area are #5724 and #5741, and some of the content below is copied from them.

Pi 5 (specifically RP1) has slightly different I2S capabilities than those found on the BCM2835 family of processors. It gains the ability to do dual- and quad-lane I2S, but it has separate clock producer (master) and clock consumer (slave) blocks. This means that each overlay has to specify the correct I2S controller - producer or consumer. For most soundcards this is a fixed property, but a few of them can operate in either mode, which causes a problem.

The addition of a "slave" property was a way to solve the problem, but this requires user intervention (and knowledge). A better solution might be to give the overlays for those flexible cards two different i2s-controller properties (or a single property with two label references) - one for each scenario - and modify the driver to choose the correct one at runtime.

There can also be problems for Audio HATs with EEPROMs that have embedded overlays, rather than just including the name of an overlay. By counting how many cards use the I2S interface in producer mode and how many in consumer mode, the old label i2s was added as an alias for the clock producer block, but for some of the cards this is the wrong choice. If this is wrong for a soundcard with an embedded overlay then there is no choice but to suppress the embedded overlay and load one from the OS image instead (unless the EEPROM can be rewritten).

Putting dtoverlay= in config.txt before any other dt settings disables the loading of the overlay from the HAT EEPROM. The preferred overlay can then be loaded in the usual way. Alternatively, if all the instances of a soundcard have been programmed with the same UUID then a rule can be added to the hat_map, an example of which can be seen in #5742.

@gtrainavicius @j-schambacher This is a more open and more efficient place to discuss the required changes than individual issues or private emails.

@pelwell Thanks Phil, for aligning things here. I will summarize our findings and post here.

Full duplex mode is not working with Pisound, for example, starting audio output in one terminal:

speaker-test -c2 -D hw:pisound -r 48000 -t sine

Then starting arecord:

arecord -D hw:pisound -r 48000 -f s16_le > /dev/null

Cuts audio output off immediately, speaker-test gets stuck, and eventually gives -5 (-EIO) error. dmesg does not log anything at all at the moment this happens. Eventually I see these messages after stopping the audio commands, not sure if they're relevant:

[323831.447683] dma dma2chan2: dma2chan2 failed to stop
[323905.772971] dma dma2chan2: dma2chan2 is non-idle!
[323922.367335] dma dma2chan2: dma2chan2 failed to stop

The Jack backend does not manage to start in full duplex mode:

pi@raspberrypi:~ $ JACK_NO_AUDIO_RESERVATION=1 sudo -E /usr/bin/jackd -t 2000 -R -P 95 -d alsa -d hw:pisound -r 48000 -p 128 -n 2 -X seq -s -S

...

ALSA: poll time out, polled for 3998998 usecs, Retrying with a recovery, retry cnt = 1
ALSA: poll time out, polled for 3999003 usecs, Retrying with a recovery, retry cnt = 2
ALSA: poll time out, polled for 3998998 usecs, Retrying with a recovery, retry cnt = 3
ALSA: poll time out, polled for 3998998 usecs, Retrying with a recovery, retry cnt = 4
ALSA: poll time out, polled for 3999003 usecs, Retrying with a recovery, retry cnt = 5
ALSA: poll time out, polled for 3999001 usecs, Reached max retry cnt = 5, Exiting
JackAudioDriver::ProcessAsync: read error, stopping...

Does this issue fall under this umbrella, or should I create a dedicated one?

You've been beaten to it: #5747

#5757 is a potential fix for #5747.

@pelwell

  1. Sorry for the delay, I was beaten up with other stuff. I was wondering how we should approach the correct controller/target setup for the new I2S module. It's a 'first come, first wins' solution. It means the first DT definition loads the respective module and pin configuration. Any later module or DT definition fails, especially the former technique where the driver switched BCLK/LRCLK between controller/target. Without additional code for the PI5 this 'autodetect' will never work. Do you agree?
    This means (w/o driver change), the potentially best way is your suggestion to use different DT-overlay definitions, which still is a 'challenge' for the existing HATs w/o UUID. But I wonder, why it seems sometimes the controller-module/DT is loaded before the card-DT is loaded requiring the target-module and fails. Is there any DT config which loads the I2S controller module per se?

  2. Meanwhile I got the 8 channels running on the DAC side but I need to continue work on the driver side. It somehow interferes with 1) as we need to use again a different DT-overlay including additional pin configs.

@pelwell I know -off topic, but I don't know where to place it best. It's not a bug or solely related to PI5. You may remember we are working on an amplifier which uses TAS575x in controller mode. Meanwhile, we have the necessary patches in the upstream kernel.
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git/commit/?id=736b884a7b68c4eeb66dbf75b97c8ec9b9eeff7f
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git/commit/?id=1f817805262c2c34142291da376d4932d3c493bc
It has been merged into the 6.7-rc1. What do you suggest how and when we can pull it into the raspberry Linux?

We're very happy to take back-ports. Just cut-and-paste that into a new issue and it will be dealt with promptly.

I hope to put together some answers and suggestions in the next day or two, but I agree that setting the pinmux is the main hurdle to choosing the I2S controller at runtime.

Just cut-and-paste that into a new issue and it will be dealt with promptly.

On second thoughts, don't - I'll just do it

Done.

Done.

@pelwell Thanks Phil!

And I'll dig next week into the I2S issues while continuing work on the 8 channel driver.
Maybe using of_changesets_ like I've done on the optional headphone amp in the dacplus driver code could be an option and allow DT changes during runtime. Just thoughts so far.