Issues using simple-audio-card driver with Xilinx Audio Formatter
Robert Hancock
robert.hancock at calian.com
Wed Jul 7 02:17:53 CEST 2021
I'm working with a Xilinx UltraScale+ MPSoC platform and trying to get some
drivers working for the Xilinx Audio Formatter, I2S Transmitter and I2S
Receiver FPGA logic cores. The Audio Formatter is what handles audio DMA and
the I2S Transmitter/Receiver handle converting between an AXI stream and I2S.
Right now as a prototype, I just have the I2S Transmitter looped back directly
to the I2S Receiver and both of them connected to the Audio Formatter, with the
idea that audio played back can be immediately recorded in again. The drivers
for these cores are in mainline (sound/soc/xilinx/xlnx_i2s.c and
sound/soc/xilinx/xlnx_formatter_pcm.c), but it's the next step of putting them
together into a functioning audio device which I am having trouble with. It
seems the usual way one would do this is using the simple-audio-card driver and
adding some device tree entries to hook everything up. In this case there is no
real "codec" so I'm using the SPDIF transmitter and receiver codecs for this -
the device tree entries for the simple-audio-card I have look like this:
/* Use S/PDIF transmitter as codec required by simple-audio-card */
playback_codec: playback-codec {
compatible = "linux,spdif-dit";
#sound-dai-cells = <0>;
};
/* Use S/PDIF receiver as codec required by simple-audio-card */
record_codec: record-codec {
compatible = "linux,spdif-dir";
#sound-dai-cells = <0>;
};
irxs-audio {
compatible = "simple-audio-card";
simple-audio-card,name = "IRXS-Audio";
#address-cells = <1>;
#size-cells = <0>;
playback_link: simple-audio-card,dai-link at 0 {
reg = <0>;
format = "i2s";
bitclock-master = <&p_codec_dai>;
frame-master = <&p_codec_dai>;
p_cpu_dai: cpu {
sound-dai = <&test_audio_i2s_transmitter_0>;
};
p_platform_dai: plat {
sound-dai = <&test_audio_audio_formatter_0>;
};
p_codec_dai: codec {
sound-dai = <&playback_codec>;
clocks = <&misc_clk_4>;
};
};
record_link: simple-audio-card,dai-link at 1 {
reg = <1>;
format = "i2s";
bitclock-master = <&r_codec_dai>;
frame-master = <&r_codec_dai>;
r_cpu_dai: cpu {
sound-dai = <&test_audio_i2s_receiver_0>;
};
r_platform_dai: plat {
sound-dai = <&test_audio_audio_formatter_0>;
};
r_codec_dai: codec {
sound-dai = <&record_codec>;
clocks = <&misc_clk_4>;
};
};
};
I _think_ this should be a reasonable setup as far as I can tell? However,
testing this out just results in:
asoc-simple-card irxs-audio: parse error -22
asoc-simple-card: probe of irxs-audio failed with error -22
After adding in a bunch of debug output, it seems that the issue is that
through this sequence of calls:
asoc_simple_probe
simple_parse_of
simple_for_each_link
simple_dai_link_of
asoc_simple_parse_platform (aka asoc_simple_parse_dai)
snd_soc_of_get_dai_name
snd_soc_get_dai_name
Inside snd_soc_get_dai_name, snd_soc_component_of_xlate_dai_name is called and
returns -ENOTSUPP, so we fall into the if block and end up failing out here:
if (id < 0 || id >= pos->num_dai) {
ret = -EINVAL;
continue;
}
That, in turn, seems to be because the Audio Formatter driver doesn't register
any DAIs in its call to devm_snd_soc_register_component in
xlnx_formatter_pcm_probe. I'm a bit unsure whether that is supposed to be the
case, or if not, what should be done to fix it. Can anyone provide some advice?
My tests are on kernel 5.10.45, but there's been no changes in the Xilinx ASoC
drivers since then, and I'm not sure anything relevant to this has changed in
the rest of ASoC either.
--
Robert Hancock
Senior Hardware Designer, Calian Advanced Technologies
www.calian.com
More information about the Alsa-devel
mailing list