McASP dual serializers and codecs - cannot figure out device tree mappings

From: Arvid Brodin
Date: Wed Jan 04 2023 - 07:56:18 EST


Hi,

I'm trying to create a four-channel "audio-graph-card" consisting of two
TI PCM512X codecs, each connected to its own serializer on one of the McASP
peripherals on a Beaglebone Black. (For context, we can call the channels
"MainL", "MainR", "Sub1", and "Sub2".)

What is the device tree syntax for this? After reading the bindings
documentation (e.g. "Multi DAI with DPCM" example) and searching for working
examples (which I have not been able to find any, only people asking how to
do this) it is still unclear to me how to map cpu endpoints to mcasp
serializers and slots.

So far I have two channel sound from either codec working fine, but I cannot
seem to get both working simultaneously; I'm obviously missing something.
(I've also tried using only one serializer and 4 TDM slots, adding different
combinations of convert-channels, as well as using a "simple-audio-card"
instead, among many other unsuccessful things.)

Kernel is linux-5.10.145-ti-r55; source at
https://github.com/beagleboard/linux/tree/5.10.145-ti-r55.

Below dts works for either codec individually after (un)commenting the
relevant sections:

--- code ---

&mcasp0 {
#sound-dai-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&mcasp0_pins>;
status = "okay";
op-mode = <0>; /* MCASP_IIS_MODE */
tdm-slots = <2>;
serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
0 0 1 0 // Pi DAC+
// 1 0 0 0 // Pi DAC Pro
// 1 0 1 0 // Both
>;
tx-num-evt = <32>;
rx-num-evt = <32>;

mcasp0_port: port@0 {
#address-cells = <1>;
#size-cells = <0>;

cpu_dai0: endpoint@0 {
reg = <0>;
dai-format = "i2s";
frame-master = <&mcasp0_port>;
bitclock-master = <&mcasp0_port>;
remote-endpoint = <&codec_dai0>;
clocks = <&clk_mcasp0>;
};
/*
cpu_dai1: endpoint@1 {
reg = <1>;
dai-format = "i2s";
frame-master = <&mcasp0_port>;
bitclock-master = <&mcasp0_port>;
remote-endpoint = <&codec_dai1>;
clocks = <&clk_mcasp0>;
};
*/
};
};


&{/} {
sound {
compatible = "audio-graph-card";
label = "AmazingDAC"; // Indulge me ;)
dais = <&mcasp0_port>;
};
};

&i2c2 {
#address-cells = <1>;
#size-cells = <0>;
audio_codec1: pcm5122@4c {
#sound-dai-cells = <0>;
compatible = "ti,pcm5122";
reg = <0x4c>;

// AVDD created on-board Pi-DAC+ from RPi pin 2 = 5 V.
AVDD-supply = <&avdd_3v3>;
// DVDD fed directly from RPi pin 1 = 3.3 V.
DVDD-supply = <&vdd_3v3exp>;
// CPVDD fed directly from RPi pin 1 = 3.3 V.
CPVDD-supply = <&vdd_3v3exp>;

port {
codec_dai0: endpoint {
remote-endpoint = <&cpu_dai0>;
};
};
};
pcm5142@4e {
#sound-dai-cells = <0>;
compatible = "ti,pcm5142";
reg = <0x4e>;

// AVDD created on-board Pi-DAC+ from RPi pin 2 = 5 V.
AVDD-supply = <&avdd_3v3>;
// DVDD fed directly from RPi pin 1 = 3.3 V.
DVDD-supply = <&vdd_3v3exp>;
// CPVDD fed directly from RPi pin 1 = 3.3 V.
CPVDD-supply = <&vdd_3v3exp>;
/*
port {
codec_dai1: endpoint {
remote-endpoint = <&cpu_dai1>;
};
};
*/
};
};

--- /code ---

... but if I enable both, and boot with

setenv dtb_overlay "/lib/firmware/BB-GRAPH-AUDIO-PCM5XXX-00A0.dtbo"
setenv optargs 'snd_soc_davinci_mcasp.dyndbg=+plf snd_soc_audio_graph_card.dyndbg=+plf snd_soc_pcm512x.dyndbg=+plf snd_soc_core.dyndbg=+plf'
run bootcmd

I get this output from the kernel:

kernel: snd_soc_register_dai:2308: snd-soc-dummy snd-soc-dummy: ASoC: dynamically register DAI snd-soc-dummy
kernel: snd_soc_register_dai:2345: snd-soc-dummy snd-soc-dummy: ASoC: Registered DAI 'snd-soc-dummy-dai'
kernel: snd_soc_register_dai:2308: pcm512x 2-004e: ASoC: dynamically register DAI 2-004e
kernel: snd_soc_register_dai:2345: pcm512x 2-004e: ASoC: Registered DAI 'pcm512x-hifi'
kernel: snd_soc_register_dai:2308: pcm512x 2-004c: ASoC: dynamically register DAI 2-004c
kernel: snd_soc_register_dai:2345: pcm512x 2-004c: ASoC: Registered DAI 'pcm512x-hifi'
kernel: davinci-mcasp 48038000.mcasp: IRQ common not found
kernel: snd_soc_register_dai:2308: davinci-mcasp 48038000.mcasp: ASoC: dynamically register DAI 48038000.mcasp
kernel: snd_soc_register_dai:2345: davinci-mcasp 48038000.mcasp: ASoC: Registered DAI '48038000.mcasp'
kernel: davinci_mcasp_get_dma_type:1917: davinci-mcasp 48038000.mcasp: DMA controller compatible = "ti,edma3-tpcc"
kernel: graph_count_noml:527: asoc-audio-graph-card sound: Count As Normal
kernel: graph_count_noml:527: asoc-audio-graph-card sound: Count As Normal
kernel: graph_get_dais_count:609: asoc-audio-graph-card sound: link 2, dais 4, ccnf 0
kernel: graph_dai_link_of:351: asoc-audio-graph-card sound: link_of (/ocp/interconnect@48000000/segment@0/target-module@38000/mcasp@0/port/endpoint@1)
kernel: asoc-audio-graph-card sound: parse error -22
kernel: asoc-audio-graph-card: probe of sound failed with error -22

I have tried to trace this to figure out what's missing/wrong but have been
generally unsuccessful. (The call to asoc_simple_parse_cpu() in
audio-graph-card.c:369 fails with -EINVAL but that is as far as I got.)

Thank you for your time.

--
Arvid Brodin