Tool/software:
Hello everyone.
We are using an AM3352 SoC on a TQMA335x SoM, and we have successfully set up one McASP serializer as I2S slave by using simple-audio-card in the devicetree and a minimal snd_soc_dai_driver in the kernel (Linux 5.4).
This is the relevant part of our devicetree:
/ { wssdsp1: wssdsp1 { #sound-dai-cells = <0>; compatible = "dwe,wssdsp1"; status = "okay"; }; sound { compatible = "simple-audio-card"; simple-audio-card,name = "WSSDSP1"; simple-audio-card,format = "i2s"; simple-audio-card,bitclock-master = <&sound_master>; simple-audio-card,frame-master = <&sound_master>; simple-audio-card,cpu { sound-dai = <&mcasp0>; }; sound_master: simple-audio-card,codec { #sound-dai-cells = <0>; sound-dai = <&wssdsp1>; /* codec name */ system-clock-frequency = <24000000>; }; }; &am33xx_pinmux { mcasp0_pins_adsp: mcasp0_pins_adsp { pinctrl-single,pins = < 0x194 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */ 0x190 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */ 0x198 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_axr0.mcasp0_axr0 */ 0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_axr1.mcasp0_axr1 */ 0x19c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2 */ 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkx.mcasp0_axr3 */ 0x1a0 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkr.mcasp0_aclkr */ 0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_fsr.mcasp0_fsr */ >; }; }; &mcasp0 { #sound-dai-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&mcasp0_pins_adsp>; status = "okay"; op-mode = <0>; /* MCASP_IIS_MODE */ tdm-slots = <2>; /* 4 serializers */ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ 1 0 0 0 >; /* bit depth for tx and rx */ tx-num-evt = <32>; rx-num-evt = <32>; };
This is the driver:
#include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <sound/soc.h> static struct snd_soc_dai_driver wssdsp1_dai = { .name = "wssdsp1-hifi", .playback = { .stream_name = "Playback", .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_384000, .formats = SNDRV_PCM_FMTBIT_S32_LE }, }; static struct snd_soc_component_driver soc_component_dev_wssdsp1 = { }; static int wssdsp1_probe(struct platform_device *pdev) { int ret; ret = devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_wssdsp1, &wssdsp1_dai, 1); if (ret) { printk("failed to register component wssdsp1: %d\n", ret); return ret; } else { printk("successfully registered component wssdsp1: %d\n", ret); } return 0; } static const struct of_device_id wssdsp1_of_match[] = { { .compatible = "dwe,wssdsp1", }, { } }; MODULE_DEVICE_TABLE(of, wssdsp1_of_match); static struct platform_driver wssdsp1_codec_driver = { .probe = wssdsp1_probe, .driver = { .name = "wssdsp1-codec", .of_match_table = wssdsp1_of_match, }, }; module_platform_driver(wssdsp1_codec_driver); MODULE_DESCRIPTION("ASoC WSSDSP1 codec driver"); MODULE_AUTHOR("Rolf Anderegg <rolf.anderegg@weiss.ch>"); MODULE_LICENSE("GPL");
There is no noise during playback. However, whenever playback stops, there is random noise on the left I2S channel!
It's as if the I2S data pin (mcasp0_axr0) was not pulled down anymore.
When trying to measure the I2S data pin with the scope, the noise goes away, which suggests that the pin is indeed floating.
The noise changes based on the CPU load of the AM3352, suggesting crosstalk.
We have the same exact hardware running fine on kernel 3.x with no noise whatsoever, so this has to be a software issue.
Any help will be greatly appreciated.
Kind regards,
Michele