On 27/12/2024 11:21 pm, Stephen Gordon wrote:
On 23/12/2024 1:01 pm, Kuninori Morimoto wrote:
[ 27.333830] asoc-audio-graph-card2 soc@107c000000:sound: probe with
driver asoc-audio-graph-card2 failed with error -12
However, when graph_get_next_multi_ep() is called to get the next
endpoint, it returns null.
Hello Morimoto-san.
I reproduced this using the test components with the attached DTS.
I found that this is because the sibling field of the
/soc@107c000000/sound/multi/ports@0/port@0 node is null, which means
that of_graph_get_next_child returns null.
In turn, this is because the linked list of siblings is actually in
reverse order due to the way populate_node() (drivers/of/fdt.c) adds
them. This means that when the driver uses remote-endpoint to navigate
from the endpoint in the cpu node to the endpoint in the multi node, it
is actually arriving at the last child (with address 0). When calling
next_child(), it gets null.
[ 30.196250] asoc-audio-graph-card2 soc@107c000000:sound: ports
parent:/soc@107c000000/sound/multi
child:/soc@107c000000/sound/multi/ports@0/port@2
[ 30.196256] asoc-audio-graph-card2 soc@107c000000:sound: sib #0:
/soc@107c000000/sound/multi/ports@0/port@2
[ 30.196260] asoc-audio-graph-card2 soc@107c000000:sound: sib #1:
/soc@107c000000/sound/multi/ports@0/port@1
[ 30.196264] asoc-audio-graph-card2 soc@107c000000:sound: sib #2:
/soc@107c000000/sound/multi/ports@0/port@0
After finding this, I reversed the order of the port nodes inside
multi/ports (i.e. the cpu link is now last) and the overlay loads
without errors.
I get a playback DAI visible in aplay, however the capture DAI is not
visible in arecord. If I swap the order of the codec ports in
multi/ports, then I get a capture DAI visible in arecord, but the
playback DAI is missing :)
I will keep experimenting to see if I can find a way to make them both
work, but I think some changes are needed to ensure all of the nodes get
processed.
Regards
Stephen
//Device tree overlay for multi-channel I2S in clock consumer mode
/dts-v1/;
/plugin/;
/ {
// Pi5 only
compatible = "brcm,bcm2712";
fragment@2 {
target = <&sound>;
__overlay__ {
compatible = "audio-graph-card2";
label = "ezsound";
status = "okay";
links = <&link0>;
multi {
#address-cells = <1>;
#size-cells = <0>;
/*
* +---+
* cpu_i2s <-@------->|X A|-> codec_dac
* | B|-> codec_adc
* +---+
*/
ports@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
port@0 { reg = <0>; link_cpu: endpoint { remote-endpoint = <&cpu_i2s>; };};
port@1 { reg = <1>; link_dac: endpoint { remote-endpoint = <&codec_dac>; };};
port@2 { reg = <2>; link_adc: endpoint { remote-endpoint = <&codec_adc>; };};
};
};
};
};
// Bring the I2S clock consumer block up
fragment@4 {
target-path = "/";
__overlay__ {
test-cpu {
compatible = "test-cpu-verbose";
#sound-dai-cells = <0>;
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
link0: port@0 {
reg = <0>;
cpu_i2s: endpoint {
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
remote-endpoint = <&link_cpu>;
};
};
};
};
};
};
fragment@5 {
target-path = "/";
__overlay__ {
test-codec {
compatible = "test-codec-verbose";
#sound-dai-cells = <1>;
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
prefix = "pcm3168a";
port@0 {
reg = <0>;
codec_dac: endpoint {
playback-only;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
remote-endpoint = <&link_dac>;
};
};
port@1 {
reg = <1>;
codec_adc: endpoint {
bitclock-master;
frame-master;
capture-only;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
remote-endpoint = <&link_adc>;
};
};
};
};
};
};
};
[Index of Archives]
[Pulseaudio]
[Linux Audio Users]
[ALSA Devel]
[Fedora Desktop]
[Fedora SELinux]
[Big List of Linux Books]
[Yosemite News]
[KDE Users]