View: 629|Reply: 2

orangepi zero 2w/zero 3 H616 SPDIF

[Copy link]

1

threads

6

posts

31

credits

Novice

Rank: 1

credits
31
Published in 2023-11-10 21:39:09 | Show all floors |Read mode
Using a custom dt plugin and re-compiling the 6.1-sun50iw9 kernel to include the sun4i-spdif and spdif-transmitter kernel modules, I got the SPDIF output (pin PH4) available in alsa.
I noticed that only 16 bit sample format was available, which is due to the sun4i-spdif driver using the wrong macros for composing the SUN4I_FORMATS (line 529) SNDRV_FORMAT_XXX should be SNDRV_FMTBIT. After fixing that, the 16 bit and 24 bit formats are available (20 bit isn't supported by the spdif-transmitter module, but that should be easy to fix as well).
When I play a 16 bit sound to SPDIF, the output does turn on and the waveforms look like the biphase-mark signal, but the sound runs 2 times too slow (a 10 second 48K sound takes 20 seconds to play). When playing a 24 bit sound, it runs 4 time too slow. Also the SPDIF signal is not recognised as a valid signal by a SPDIF receiver.

I see that the DMA is configured as a 2-byte buswidth slave, which is insufficient for the 24 bit (and 20 bit) sample format. The DMA engine doesn't support 3-byte slave, so I guess the 20 and 24 bit sample formats must use 32 bit buswidth slave, padding the 20 and 24 bit samples to 32 bits before copying to the DMA buffer. I don't see this handled appropriately in the sun4i-spdif driver.

What can cause the 2 times too slow 16 bit sample format playing? I guess this causes the invalid SPDIF output signal.

Anybody know how to fix the 20 and 24 bit formats so it is compatible with the DMA capabilities?

1

threads

6

posts

31

credits

Novice

Rank: 1

credits
31
 Author| Published in 2023-11-14 19:09:37 | Show all floors
I managed to fix the 24 bit issue, just select DMA_SLAVE_BUSWIDTH_4_BYTES for the 20 and 24 bit sample formats. Apparently, the padding from 3 bytes to 4 bytes is handled correctly automagically.
Now the 2 times too slow issue. This doesn't happen always. I have seen sometimes it works correctly, but only with the 48K (or multiples) rates, not with 44.1K.
When I play some sound at 44.1K to the audiocodec first, the 44.1K works with SPDIF as well. I also notice that playing 24 bit samples to audiocodec plays 2 times too slow as well, so probably the same SLAVE_BUSWIDTH change needs to be applied to the audiocodec driver (or limit to 16 bit samples only).
There is some issue with controlling the PLL_AUDIO through the OWA Clock (CLK_SPDIF).

In principle, the PLL_AUDIO will only ever need to generate either 24.576 MHz (for the 48K rate and friends) or 22.5792 MHz (for the 44.1K rate and friends). All audio peripherals have to either use the one or the other 'set' of rates concurrently. Maybe special-casing this PLL to accept only those frequencies (and switch between them) is the way to go... I'm not sure what would happen if audiocodec plays 44.1K and SPDIF plays 48K... will the latter change the speed for the former or will the PLL change be rejected because it's 'in use'?

1

threads

6

posts

31

credits

Novice

Rank: 1

credits
31
 Author| Published in 2023-11-16 04:13:03 | Show all floors
I enabled ftrace and saw that when starting a sound on audiocodec, the parent pll was configured, while when starting a sound on spdif, it wasn't.
This turns out to be due to a missing flag CLK_SET_RATE_PARENT in the spdif clock defining structure in ccu-sun50i-h616. Adding the flag makes things work like it should.

See pull request #52 in linux-orangepi repo on github.
You need to log in before you can reply login | Register

Points Rule

Quick reply Top Return list