I am working on a carrier board for my employer which uses an ADV7481 to convert HDMI to CSI2 for the Jetson Xavier NX. I have managed to adapt a driver by Renesas for the ADV7482 to capture the video but I am now trying to handle audio.
I have registered the snd_soc_dai_ops structure with the driver and can see from the kernel logs that it is binding, but I receive an I/O error when running arecord.
The device tree include and driver source are attached.
The device-tree ‘nvidia,audio-routing’ defines a route between the I2S interface and codec. However, I don’t see any DAPM widget defined in the codec driver. Typically, codec drivers define DAPM widgets like these. There are probably some messages in the dmesg output about the widgets no being found. Please attach the dmesg output.
Do you call snd_soc_dai_set_sysclk() anywhere to set the sysclk frequency?
Thank you; I have actually been experimenting with widgets but have had no luck so far. I have attached copy of my current experimental source. adv7482.c (90.9 KB)
This is the kernel log from dmesg: dmesg-210908-1127.log (87.4 KB)
I do not currently call snd_soc_dai_set_sysclk.
To call snd_soc_dai_set_sysclk() you would typically add an ‘init’ function like this to the Tegra machine driver. Then check for the presence of the DAI link for your codec in codec_init to register your init function with the appropriate DAI link.
I always recommend tracing the DAPM widgets when running arecord/aplay to see that the I2S is being enabled.
$ echo 0 | sudo tee /sys/kernel/debug/tracing/trace
$ echo 0 | sudo tee /sys/kernel/debug/tracing/events/enable
$ echo 1 | sudo tee /sys/kernel/debug/tracing/tracing_on
$ echo 1 | sudo tee /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_widget_power/enable
$ arecord <params>
$ sudo cat /sys/kernel/debug/tracing/trace
You need to make sure that the I2S5 is mapped to the appropriate DMA interface. By default I2S5 should be mapped to ADMAIF0 and so you should use something like the following command …
The ‘-c 2’ just indicates 2 channels which is common for standard I2S, but not sure how many channels you are need to capture and if it is standard I2S signalling or something like TDM.
I have tried enabling the dynamic debug in /sys/kernel/debug/dynamic_debug/control
for soc-core.c, tegra_machine_driver_mobile.c, soc-pcm.c, soc-dapm.c and pcm.c to see if it sheds any light on the matter. I have attached a log. dmesg-210909-0922.log (171.2 KB)
The reason for amixer not working seems to be related to the entry in adv7482_snd_controls; commenting it out gives me this:
Something that I have noticed this morning is that I have been calling devm_snd_soc_register_component to register the driver; should I actually be calling snd_soc_register_codec?
I have reimplemented the driver as a snd_soc_codec_driver and added an initialisation function to the machine driver. However, I am finding that the mclk_hw pointer is coming back as NULL, which causes the set_sysclk function to crash. I have by-passed this for now and I still see the same Input/output error message.
I now see the following in dmesg when I reun arecord but still no errors:
I have been using the patch from the following post on the mailing list as a reference: https://lore.kernel.org/driverdev-devel/20200323084011.GC4298@pflmari/T/
I can’t see exactly what is going on with the mclk_hw pointer but I’m assuming that it’s identifying the MCLK output from the ADV748x as a clock source.
It is interesting that the trace still does not show the I2S interface or the codec widgets. Can you run the following script and send the output …
outfile="${HOME}/tegra-audio-debug.txt"
if [ -f "${outfile}" ]; then
rm "${outfile}"
fi
alsactl store -f "${outfile}"
dapm_dirs=$(sudo find /sys/kernel/debug/asoc -type d -name dapm)
for dir in ${dapm_dirs}; do
sudo find ${dir} -type f -exec echo {} \; -exec cat {} \; >> "${outfile}"
done
echo "Tegra audio debug info written to ${outfile}"