Add two sound card drivers on TX2

I want to realize two sound cards working at the same time on TX2. Now I2S1 and I2S2 of TX2 are connected with two audio codec chips TLV320AIC32X4, I2S1 is used for recording, I2S2 is used for audio playback.
tegra_t186ref_mobile_rt565x_i2s1.c

#define DRV_NAME_I2S1 "tegra-snd-t186ref-mobile-rt565x-i2s1"

static int tegra_t186ref_dai_init(struct snd_soc_pcm_runtime *rtd,
					int rate,
					int channels,
					u64 formats,
					bool is_playback)
{
	struct snd_soc_card *card = rtd->card;
	struct tegra_t186ref *machine = snd_soc_card_get_drvdata(card);
	struct snd_soc_pcm_stream *dai_params;
	unsigned int idx, clk_out_rate;
	int err, codec_rate, clk_rate;

	codec_rate = tegra_t186ref_srate_values[machine->rate_via_kcontrol];
	clk_rate = (machine->rate_via_kcontrol) ? codec_rate : rate;

	err = tegra_alt_asoc_utils_set_rate(&machine->audio_clock, clk_rate,
						0, 0);
	if (err < 0) {
		dev_err(card->dev, "Can't configure clocks\n");
		return err;
	}

	clk_out_rate = machine->audio_clock.clk_out_rate;

	pr_debug("pll_a_out0 = %d Hz, aud_mclk = %d Hz, codec rate = %d Hz\n",
		machine->audio_clock.set_mclk, clk_out_rate, clk_rate);

	tegra_t186ref_set_params(card, machine, rate, channels, formats);

	idx = tegra_machine_get_codec_dai_link_idx_t18x("ti-playback-i2s1");
	//printk(KERN_ERR "tegra_t186ref_dai_init:====ti-playback-i2s1-idx = %d \n",idx);
	/* check if idx has valid number */
	if (idx != -EINVAL) {
		dai_params =
		(struct snd_soc_pcm_stream *)card->rtd[idx].dai_link->params;

		dai_params->rate_min = clk_rate;
		dai_params->formats = (machine->fmt_via_kcontrol == 2) ?
                                (1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats;

		if (!machine->is_codec_dummy) {
			err = snd_soc_dai_set_sysclk(card->rtd[idx].codec_dai,
			0, 12000000, SND_SOC_CLOCK_IN);
			if (err < 0) {
				dev_err(card->dev, "codec_dai clock not set\n");
				return err;
			}
		}
	}
	return 0;
}

static int tegra_t186ref_driver_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct snd_soc_card *card = &snd_soc_tegra_t186ref;
	struct tegra_t186ref *machine;
	struct tegra_asoc_platform_data *pdata = NULL;
	struct snd_soc_codec *codec = NULL;
	int idx = 0;
	int ret = 0;
	const char *codec_dai_name;

	if (!np) {
		dev_err(&pdev->dev, "No device tree node for t186ref driver");
		return -ENODEV;
	}

	machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_t186ref),
			       GFP_KERNEL);
	if (!machine) {
		dev_err(&pdev->dev, "Can't allocate t186ref struct\n");
		ret = -ENOMEM;
		goto err;
	}

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, machine);
	machine->is_codec_dummy = 0;
	machine->audio_clock.clk_cdev1_state = 0;
	machine->digital_reg = NULL;
	machine->spk_reg = NULL;
	machine->dmic_reg = NULL;
	card->dapm.idle_bias_off = true;

	ret = snd_soc_of_parse_card_name(card, "nvidia,model");
	if (ret)
		goto err;

	ret = snd_soc_of_parse_audio_routing(card,
				"nvidia,audio-routing");
	if (ret)
		goto err;

	if (of_property_read_u32(np, "nvidia,num-clk",
			       &machine->audio_clock.num_clk) < 0) {
		dev_err(&pdev->dev,
			"Missing property nvidia,num-clk\n");
		ret = -ENODEV;
		goto err;
	}

	if (of_property_read_u32_array(np, "nvidia,clk-rates",
				(u32 *)&machine->audio_clock.clk_rates,
				machine->audio_clock.num_clk) < 0) {
		dev_err(&pdev->dev,
			"Missing property nvidia,clk-rates\n");
		ret = -ENODEV;
		goto err;
	}

	dai_link_setup(pdev);

#ifdef CONFIG_SWITCH
	/* Addd h2w swith class support */
	ret = tegra_alt_asoc_switch_register(&tegra_t186ref_headset_switch);
	if (ret < 0)
		goto err_alloc_dai_link;
#endif

	pdata = devm_kzalloc(&pdev->dev,
				sizeof(struct tegra_asoc_platform_data),
				GFP_KERNEL);
	if (!pdata) {
		dev_err(&pdev->dev,
			"Can't allocate tegra_asoc_platform_data struct\n");
		return -ENOMEM;
	}

	pdata->gpio_codec1 = pdata->gpio_codec2 = pdata->gpio_codec3 =
	pdata->gpio_spkr_en = pdata->gpio_hp_mute =
	pdata->gpio_int_mic_en = pdata->gpio_ext_mic_en = -1;

	machine->pdata = pdata;
	machine->pcard = card;

	ret = tegra_alt_asoc_utils_init(&machine->audio_clock,
					&pdev->dev,
					card);
	if (ret)
		goto err_switch_unregister;

#if 1
	ret = tegra_alt_asoc_utils_set_parent(&machine->audio_clock, false);
	if (ret){
		dev_err(&pdev->dev, "tegra_alt_asoc_utils_set_parent failed (%d)\n",
			ret);
		goto err_switch_unregister;
	}
#endif

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err_fini_utils;
	}


    printk(KERN_ERR "aic32x4-idx:===========ti-playback-i2s1-idx=====================");
    idx = tegra_machine_get_codec_dai_link_idx_t18x("ti-playback-i2s1");
    printk(KERN_ERR "ti-playback-i2s1-idx = %d \n",idx);
	/* check if idx has valid number */
	if (idx == -EINVAL)
		dev_warn(&pdev->dev, "codec link not defined - codec not part of sound card --i2s1");
	else {
		codec = card->rtd[idx].codec;
		codec_dai_name = card->rtd[idx].dai_link->codec_dai_name;

		dev_info(&pdev->dev,
			"codec-dai \"%s\" registered\n", codec_dai_name);
		if (!strcmp("tlv320aic32x4-hifi", codec_dai_name)) {
			dev_info(&pdev->dev, "This is a dummy codec\n");
			machine->is_codec_dummy = 2;
		}
	}	

	return 0;

err_fini_utils:
	tegra_alt_asoc_utils_fini(&machine->audio_clock);
err_switch_unregister:
#ifdef CONFIG_SWITCH
	tegra_alt_asoc_switch_unregister(&tegra_t186ref_headset_switch);
#endif
err_alloc_dai_link:
	tegra_machine_remove_dai_link();
	tegra_machine_remove_codec_conf();
err:

	return ret;
}

static const struct of_device_id tegra_t186ref_of_match[] = {
	{ .compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x-i2s1", },
};

MODULE_AUTHOR("Mohan Kumar <mkumard@nvidia.com>");
MODULE_DESCRIPTION("Tegra+t186ref machine ASoC driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRV_NAME_I2S1);
MODULE_DEVICE_TABLE(of, tegra_t186ref_of_match);

tegra186-quill-common.dtsi

i2c@3180000 {
		status = "okay";

        aic32x4_1: tlv320aic32x4.2-0018@18 {
			compatible = "ti,tlv320aic32x4";
			status = "okay";
			reg = <0x18>;
			clocks = <&tegra_car TEGRA186_CLK_AUD_MCLK>;
			clock-names = "mclk";			
		};

	};

i2c@3160000 {
		status = "okay";
		aic32x4: tlv320aic32x4.0-0018@18 {
			compatible = "ti,tlv320aic32x4";
			status = "okay";
			reg = <0x18>;
			clocks = <&tegra_car TEGRA186_CLK_AUD_MCLK>;
			clock-names = "mclk";			
		};
       };

rt565x_dai_link: nvidia,dai-link-1 {
			link-name = "ti-playback-i2s2";
			cpu-dai = <&tegra_i2s2>;
			codec-dai = <&aic32x4_1>;
			cpu-dai-name = "I2S2";
			codec-dai-name = "tlv320aic32x4-hifi";
			tx-mask = <0xFF>;
			rx-mask = <0xFF>; 
			format = "i2s";
			bitclock-slave;
			frame-slave;
			bitclock-noninversion;
			frame-noninversion;
			bit-format = "s16_le";
			bclk_ratio = <0>;
			srate = <48000>;
			num-channel = <1>;
			ignore_suspend;
			name-prefix = "z";
			status = "okay"; 
		};


       nvidia,dai-link-2 {
			link-name = "ti-playback-i2s1";
			cpu-dai = <&tegra_i2s1>;
			codec-dai = <&aic32x4>;
			cpu-dai-name = "I2S1";
			codec-dai-name = "tlv320aic32x4-hifi";
			tx-mask = <0xFF>;
			rx-mask = <0xFF>; 
			format = "i2s";
			bitclock-slave;
			frame-slave;
			bitclock-noninversion;
			frame-noninversion;
			bit-format = "s16_le";
			bclk_ratio = <0>;
			srate = <48000>;
			num-channel = <1>;
			ignore_suspend;
			name-prefix = "z";
			status = "okay";
		};

However, both sound cards failed to drive and no sound card device was displayed. How can I successfully add the drivers of two sound card devices to TX2?

thanks

Hi,

Nvidia Audio drivers can support both codecs with single sound card itself (via multiple DAI Links in sound node). i.e. No need to have two instances of machine drivers. It requires DTS change (similar to done in tegra186-quill-common.dtsi above) + Codec Sysclock callbacks in existing machine driver (tegra_t186ref_mobile_rt565x.c) for each codec link (depends on the codec).

From the topic “Add two sound card drivers on TX2” looks like you are trying to have two separate ALSA sound cards, each one for a specific codec. This is not supported by our BSP.

Thanks,
Sharad

Thanks Sharad,

The function I want to achieve is to start recording and playing at the same time after the device is turned on. The way I used before was to use only one hardware sound card device(tlv320aic32x4), because the recording and playback clocks have different sampling rates, so I can’t simultaneously record and play on a hardware sound card device (codec tlv320aic32x4), so I designed the hardware. A codec tlv320aic32x4 has been added. One codec tlv320aic32x4 I2S connects to I2S1, and another codec tlv320aic32x4 I2S connects to I2S2 to realize simultaneous recording and playback functions after the device is powered on.

The kernel version is 28.2.1

I2C nodes and sound nodes (sound@0 and sound@1) were added to the device tree, but the sound card device was not recognized. If only the sound node is used, one of the sound card devices can be recognized and can be recorded or played.

tegra_sound: sound {
        #address-cells=<1>;
        #size-cells=<0>;
        sound@0{
                compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x-i2s2";
                reg=<0>;
		nvidia,model = "tegra-snd-t186ref-mobile-rt565x-i2s2";
		nvidia,num-codec-link = <4>;
                nvidia,num-clk = <8>;
		nvidia,clk-rates = < 270950400	/* PLLA_x11025_RATE */
				     11289600	/* AUD_MCLK_x11025_RATE */
				     45158400	/* PLLA_OUT0_x11025_RATE */
				     45158400	/* AHUB_x11025_RATE */
				     245760000  /* PLLA_x8000_RATE */
				     12288000	/* AUD_MCLK_x8000_RATE */
				     49152000	/* PLLA_OUT0_x8000_RATE */
				     49152000 >;/* AHUB_x8000_RATE */
		clocks = <&tegra_car TEGRA186_CLK_PLLP_OUT0>,
			<&tegra_car TEGRA186_CLK_PLLA>,
			<&tegra_car TEGRA186_CLK_PLL_A_OUT0>,
			<&tegra_car TEGRA186_CLK_AHUB>,
			<&tegra_car TEGRA186_CLK_CLK_M>,
			<&tegra_car TEGRA186_CLK_AUD_MCLK>;
		clock-names = "pll_p_out1", "pll_a", "pll_a_out0", "ahub",
				"clk_m", "extern1";
		resets = <&tegra_car TEGRA186_RESET_AUD_MCLK>;
		reset-names = "extern1_rst";

		status = "okay";
		nvidia,audio-routing =
			"z IN2_R", "z IN",
			"z IN2_L", "z IN",
			"z OUT", "z LOR",
			"z OUT", "z LOL";

		nvidia,xbar = <&tegra_axbar>;

                rt565x_dai_link: nvidia,dai-link-1 {
			link-name = "ti-playback-i2s2";
			cpu-dai = <&tegra_i2s2>;
			codec-dai = <&aic32x4_1>;
			cpu-dai-name = "I2S2";
			codec-dai-name = "tlv320aic32x4-hifi";
			tx-mask = <0xFF>;
			rx-mask = <0xFF>; 
			format = "i2s";
			bitclock-slave;
			frame-slave;
			bitclock-noninversion;
			frame-noninversion;
			bit-format = "s16_le";
			bclk_ratio = <0>;
			srate = <48000>;
			num-channel = <1>;
			ignore_suspend;
			name-prefix = "z";
			status = "okay"; 
		};
                spdif_dai_link: nvidia,dai-link-2 {
			link-name = "spdif-playback";
			cpu-dai = <&tegra_spdif>;
			codec-dai = <&spdif_dit11>;
			cpu-dai-name = "SPDIF1-1";
			codec-dai-name = "dit-hifi";
			format = "i2s";
			bit-format = "s16_le";
			srate = <48000>;
			num-channel = <2>;
			ignore_suspend;
			name-prefix = "e";
			status = "disabled";
		};
		dspk_1_dai_link: nvidia,dai-link-3 {
			link-name = "dspk-playback-r";
			cpu-dai = <&tegra_dspk1>;
			codec-dai = <&spdif_dit12>;
			cpu-dai-name = "DSPK1";
			codec-dai-name = "dit-hifi";
			format = "i2s";
			bit-format = "s16_le";
			srate = <48000>;
			num-channel = <2>;
			ignore_suspend;
			name-prefix = "d1";
			status = "disabled";
		};
		dspk_2_dai_link: nvidia,dai-link-4 {
			link-name = "dspk-playback-l";
			cpu-dai = <&tegra_dspk2>;
			codec-dai = <&spdif_dit13>;
			cpu-dai-name = "DSPK2";
			codec-dai-name = "dit-hifi";
			format = "i2s";
			bit-format = "s16_le";
			srate = <48000>;
			num-channel = <2>;
			ignore_suspend;
			name-prefix = "d2";
			status = "disabled";
                };
      };

      sound@1{
                compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x-i2s1";
                reg=<1>;
	        nvidia,model = "tegra-snd-t186ref-mobile-rt565x-i2s1";
	        nvidia,num-codec-link = <1>;
                nvidia,num-clk = <8>;
		nvidia,clk-rates = < 270950400	
				     11289600	
				     45158400	
				     45158400	
				     245760000  
				     12288000	
				     49152000	
				     49152000 >;
		clocks = <&tegra_car TEGRA186_CLK_PLLP_OUT0>,
			<&tegra_car TEGRA186_CLK_PLLA>,
			<&tegra_car TEGRA186_CLK_PLL_A_OUT0>,
			<&tegra_car TEGRA186_CLK_AHUB>,
			<&tegra_car TEGRA186_CLK_CLK_M>,
			<&tegra_car TEGRA186_CLK_AUD_MCLK>;
		clock-names = "pll_p_out1", "pll_a", "pll_a_out0", "ahub",
				"clk_m", "extern1";
		resets = <&tegra_car TEGRA186_RESET_AUD_MCLK>;
		reset-names = "extern1_rst";

		status = "okay";
		nvidia,audio-routing =
			"z IN2_R", "z IN",
			"z IN2_L", "z IN",
			"z OUT", "z LOR",
			"z OUT", "z LOL";

		nvidia,xbar = <&tegra_axbar>;

                nvidia,dai-link-1 {
			link-name = "ti-playback-i2s1";
			cpu-dai = <&tegra_i2s1>;
			codec-dai = <&aic32x4>;
			cpu-dai-name = "I2S1";
			codec-dai-name = "tlv320aic32x4-hifi";
			tx-mask = <0xFF>;
			rx-mask = <0xFF>; 
			format = "i2s";
			bitclock-slave;
			frame-slave;
			bitclock-noninversion;
			frame-noninversion;
			bit-format = "s16_le";
			bclk_ratio = <0>;
			srate = <48000>;
			num-channel = <1>;
			ignore_suspend;
			name-prefix = "z";
			status = "okay"; 
		    };      
            };
     
};

If i use two codecs tlv320aic32x4 how to achieve TX2 simultaneous recording and playback. Or TX2 only use a codec tlv320aic32x4 how to achieve TX2 simultaneous recording and playback function?

Thanks

Hi,

We don’t recommend to use multiple sound cards for this purpose with Nvidia Audio drivers.

What are the sampling rates you want to support for Capture and Playback? Depending on that, we will analyze at our end and help you further.

Thanks,
Sharad

Hi,Sharad

I want to support the recording sample rate is 16K, 48K sampling rate playback. However,the sampling rate for playback in actual applications may be 16K/44K/48K.

How can I achieve TX2 playback and recording at the same time when the sampling rate of recording and playback is different?

Thanks

Hi, Thanks for the info.

Even Sampling rates: 8K/16K/32K/48K…
Odd Sampling rates: 11.025K/22.5K/44.1K…

We can achieve recording and playback at either even sampling rate combinations or odd sampling rate combinations i.e. “Record @16K, Playback @48K” / “Record @11.025K, Playback @44.1K”…

The reason is, both I2S interfaces are using same clock parent source and hence it can drive either even rates or odd rates at a time (irrespective of having single/dual sound cards).

Have follow up question: Is it must to have 44.1K playback support? A conversion from 44.1K to 48K/16K (in the HW/SW) and then rendering at 48K/16K won’t suffice?

Thanks,
Sharad

Hi,Sharad

1、I used the NVIDIA audio driver to add the dai_link node to the device tree file tegra186-quill-Common.dtsi. In order to support two codecs for the single sound card, some error messages will be prompted after the system starts.

tegra-snd-t186ref-mobile-rt565x sound: control 2:0:0:z PCM Playback Volume:0 is already present
tlv320aic32x4 0-0018: ASoC: Failed to add PCM Playback Volume: -16

tegra-snd-t186ref-mobile-rt565x sound: control 2:0:0:z HPL Output Mixer L_DAC Switch:0 is already present
tlv320aic32x4 0-0018: ASoC: Failed to add widget z HPL Output Mixer dapm kcontrol HPL Output L_DAC Switch: -16
tegra-snd-t186ref-mobile-rt565x sound: control 2:0:0:z LOL Output Mixer L_DAC Switch:0 is already present
tlv320aic32x4 0-0018: ASoC: Failed to add widget z LOL Output Mixer dapm kcontrol LOL Output L_DAC Switch: -16
tegra-snd-t186ref-mobile-rt565x sound: control 2:0:0:z HPR Output Mixer R_DAC Switch:0 is already present
tlv320aic32x4 0-0018: ASoC: Failed to add widget z HPR Output Mixer dapm kcontrol HPR Output R_DAC Switch: -16
tegra-snd-t186ref-mobile-rt565x sound: control 2:0:0:z LOR Output Mixer R_DAC Switch:0 is already present
tlv320aic32x4 0-0018: ASoC: Failed to add widget z LOR Output Mixer dapm kcontrol LOR Output R_DAC Switch: -16

What are the problems with my code?

tegra186-quill-common.dtsi

i2c@3180000 {
		status = "okay";

        aic32x4_1: tlv320aic32x4.2-0018@18 {
			compatible = "ti,tlv320aic32x4";
			status = "okay";
			reg = <0x18>;
			clocks = <&tegra_car TEGRA186_CLK_AUD_MCLK>;
			clock-names = "mclk";			
		};

	};

	i2c@3160000 {
		status = "okay";
		aic32x4: tlv320aic32x4.0-0018@18 {
			compatible = "ti,tlv320aic32x4";
			status = "okay";
			reg = <0x18>;
			clocks = <&tegra_car TEGRA186_CLK_AUD_MCLK>;
			clock-names = "mclk";			
		};
        };
tegra_sound: sound {
                compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x";
		nvidia,model = "tegra-snd-t186ref-mobile-rt565x";
		nvidia,num-codec-link = <5>;
                nvidia,num-clk = <8>;
		nvidia,clk-rates = < 270950400	/* PLLA_x11025_RATE */
				     11289600	/* AUD_MCLK_x11025_RATE */
				     45158400	/* PLLA_OUT0_x11025_RATE */
				     45158400	/* AHUB_x11025_RATE */
				     245760000  /* PLLA_x8000_RATE */
				     12288000	/* AUD_MCLK_x8000_RATE */
				     49152000	/* PLLA_OUT0_x8000_RATE */
				     49152000 >;/* AHUB_x8000_RATE */
		clocks = <&tegra_car TEGRA186_CLK_PLLP_OUT0>,
			<&tegra_car TEGRA186_CLK_PLLA>,
			<&tegra_car TEGRA186_CLK_PLL_A_OUT0>,
			<&tegra_car TEGRA186_CLK_AHUB>,
			<&tegra_car TEGRA186_CLK_CLK_M>,
			<&tegra_car TEGRA186_CLK_AUD_MCLK>;
		clock-names = "pll_p_out1", "pll_a", "pll_a_out0", "ahub",
				"clk_m", "extern1";
		resets = <&tegra_car TEGRA186_RESET_AUD_MCLK>;
		reset-names = "extern1_rst";

		status = "okay";
		nvidia,audio-routing =
			"z IN2_R", "z IN",
			"z IN2_L", "z IN",
			"z OUT", "z LOR",
			"z OUT", "z LOL";

		nvidia,xbar = <&tegra_axbar>;

        rt565x_dai_link: nvidia,dai-link-1 {
			link-name = "ti-playback-i2s2";
			cpu-dai = <&tegra_i2s2>;
			codec-dai = <&aic32x4_1>;
			cpu-dai-name = "I2S2";
			codec-dai-name = "tlv320aic32x4-hifi";
			tx-mask = <0xFF>;
			rx-mask = <0xFF>; 
			format = "i2s";
			bitclock-slave;
			frame-slave;
			bitclock-noninversion;
			frame-noninversion;
			bit-format = "s16_le";
			bclk_ratio = <0>;
			srate = <48000>;
			num-channel = <1>;
			ignore_suspend;
			name-prefix = "z";
			status = "okay"; 
		};
        nvidia,dai-link-2 {
			link-name = "ti-playback-i2s1";
			cpu-dai = <&tegra_i2s1>;
			codec-dai = <&aic32x4>;
			cpu-dai-name = "I2S1";
			codec-dai-name = "tlv320aic32x4-hifi";
			tx-mask = <0xFF>;
			rx-mask = <0xFF>; 
			format = "i2s";
			bitclock-slave;
			frame-slave;
			bitclock-noninversion;
			frame-noninversion;
			bit-format = "s16_le";
			bclk_ratio = <0>;
			srate = <48000>;
			num-channel = <1>;
			ignore_suspend;
			name-prefix = "z";
			status = "okay"; 
		    };
        spdif_dai_link: nvidia,dai-link-3 {
			link-name = "spdif-playback";
			cpu-dai = <&tegra_spdif>;
			codec-dai = <&spdif_dit11>;
			cpu-dai-name = "SPDIF1-1";
			codec-dai-name = "dit-hifi";
			format = "i2s";
			bit-format = "s16_le";
			srate = <48000>;
			num-channel = <2>;
			ignore_suspend;
			name-prefix = "e";
			status = "disabled";
		};
	dspk_1_dai_link: nvidia,dai-link-4 {
			link-name = "dspk-playback-r";
			cpu-dai = <&tegra_dspk1>;
			codec-dai = <&spdif_dit12>;
			cpu-dai-name = "DSPK1";
			codec-dai-name = "dit-hifi";
			format = "i2s";
			bit-format = "s16_le";
			srate = <48000>;
			num-channel = <2>;
			ignore_suspend;
			name-prefix = "d1";
			status = "disabled";
		};
	dspk_2_dai_link: nvidia,dai-link-5 {
			link-name = "dspk-playback-l";
			cpu-dai = <&tegra_dspk2>;
			codec-dai = <&spdif_dit13>;
			cpu-dai-name = "DSPK2";
			codec-dai-name = "dit-hifi";
			format = "i2s";
			bit-format = "s16_le";
			srate = <48000>;
			num-channel = <2>;
			ignore_suspend;
			name-prefix = "d2";
			status = "disabled";
               };

tegra_t186ref_mobile_rt565x.c

static int tegra_t186ref_driver_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct snd_soc_card *card = &snd_soc_tegra_t186ref;
	struct tegra_t186ref *machine;
	struct tegra_asoc_platform_data *pdata = NULL;
	struct snd_soc_codec *codec = NULL;
	int idx = 0;
	int ret = 0;
	const char *codec_dai_name;

	if (!np) {
		dev_err(&pdev->dev, "No device tree node for t186ref driver");
		return -ENODEV;
	}

	machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_t186ref),
			       GFP_KERNEL);
	if (!machine) {
		dev_err(&pdev->dev, "Can't allocate t186ref struct\n");
		ret = -ENOMEM;
		goto err;
	}

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, machine);
	machine->is_codec_dummy = 0;
	machine->audio_clock.clk_cdev1_state = 0;
	machine->digital_reg = NULL;
	machine->spk_reg = NULL;
	machine->dmic_reg = NULL;
	card->dapm.idle_bias_off = true;

	ret = snd_soc_of_parse_card_name(card, "nvidia,model");
	if (ret)
		goto err;

	ret = snd_soc_of_parse_audio_routing(card,
				"nvidia,audio-routing");
	if (ret)
		goto err;

	if (of_property_read_u32(np, "nvidia,num-clk",
			       &machine->audio_clock.num_clk) < 0) {
		dev_err(&pdev->dev,
			"Missing property nvidia,num-clk\n");
		ret = -ENODEV;
		goto err;
	}

	if (of_property_read_u32_array(np, "nvidia,clk-rates",
				(u32 *)&machine->audio_clock.clk_rates,
				machine->audio_clock.num_clk) < 0) {
		dev_err(&pdev->dev,
			"Missing property nvidia,clk-rates\n");
		ret = -ENODEV;
		goto err;
	}

	dai_link_setup(pdev);

#ifdef CONFIG_SWITCH
	/* Addd h2w swith class support */
	ret = tegra_alt_asoc_switch_register(&tegra_t186ref_headset_switch);
	if (ret < 0)
		goto err_alloc_dai_link;
#endif

	pdata = devm_kzalloc(&pdev->dev,
				sizeof(struct tegra_asoc_platform_data),
				GFP_KERNEL);
	if (!pdata) {
		dev_err(&pdev->dev,
			"Can't allocate tegra_asoc_platform_data struct\n");
		return -ENOMEM;
	}

	pdata->gpio_codec1 = pdata->gpio_codec2 = pdata->gpio_codec3 =
	pdata->gpio_spkr_en = pdata->gpio_hp_mute =
	pdata->gpio_int_mic_en = pdata->gpio_ext_mic_en = -1;

	machine->pdata = pdata;
	machine->pcard = card;

	ret = tegra_alt_asoc_utils_init(&machine->audio_clock,
					&pdev->dev,
					card);
	if (ret)
		goto err_switch_unregister;

	ret = tegra_alt_asoc_utils_set_parent(&machine->audio_clock, false);
	if (ret){
		dev_err(&pdev->dev, "tegra_alt_asoc_utils_set_parent failed (%d)\n",
			ret);
		goto err_switch_unregister;
	}

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err_fini_utils;
	}

	idx = tegra_machine_get_codec_dai_link_idx_t18x("ti-playback-i2s1");
	/* check if idx has valid number */
	if (idx == -EINVAL)
		dev_warn(&pdev->dev, "codec link not defined - codec not part of sound card --i2s1");
	else {
		codec = card->rtd[idx].codec;
		codec_dai_name = card->rtd[idx].dai_link->codec_dai_name;

		dev_info(&pdev->dev,
			"codec-dai \"%s\" registered\n", codec_dai_name);
		if (!strcmp("tlv320aic32x4-hifi", codec_dai_name)) {
			dev_info(&pdev->dev, "This is a dummy codec\n");
			machine->is_codec_dummy = 1;
		}
	}
    
    idx = tegra_machine_get_codec_dai_link_idx_t18x("ti-playback-i2s2");
	/* check if idx has valid number */
	if (idx == -EINVAL)
		dev_warn(&pdev->dev, "codec link not defined - codec not part of sound card --i2s2");
	else {
		codec = card->rtd[idx].codec;
		codec_dai_name = card->rtd[idx].dai_link->codec_dai_name;

		dev_info(&pdev->dev,
			"codec-dai \"%s\" registered\n", codec_dai_name);
		if (!strcmp("tlv320aic32x4-hifi", codec_dai_name)) {
			dev_info(&pdev->dev, "This is a dummy codec\n");
			machine->is_codec_dummy = 2;
		}
	}	
#endif

	return 0;

err_fini_utils:
	tegra_alt_asoc_utils_fini(&machine->audio_clock);
err_switch_unregister:
#ifdef CONFIG_SWITCH
	tegra_alt_asoc_switch_unregister(&tegra_t186ref_headset_switch);
#endif
err_alloc_dai_link:
	tegra_machine_remove_dai_link();
	tegra_machine_remove_codec_conf();
err:

	return ret;
}
static void dai_link_setup(struct platform_device *pdev)
{
	struct snd_soc_card *card = platform_get_drvdata(pdev);
	struct tegra_t186ref *machine = snd_soc_card_get_drvdata(card);
	struct snd_soc_codec_conf *tegra_machine_codec_conf = NULL;
	struct snd_soc_codec_conf *tegra_t186ref_codec_conf = NULL;
	struct snd_soc_dai_link *tegra_machine_dai_links = NULL;
	struct snd_soc_dai_link *tegra_t186ref_codec_links = NULL;
	int i;

	/* set new codec links and conf */
	tegra_t186ref_codec_links = tegra_machine_new_codec_links(pdev,
		tegra_t186ref_codec_links,
		&machine->num_codec_links);
	if (!tegra_t186ref_codec_links)
		goto err_alloc_dai_link;

	/* set codec init */
	for (i = 0; i < machine->num_codec_links; i++) {
		if (tegra_t186ref_codec_links[i].name) {
			if (strstr(tegra_t186ref_codec_links[i].name,
				"rt565x-playback"))
				tegra_t186ref_codec_links[i].init = tegra_t186ref_init;
			// crengby lee add 2019.2.20 for aic32x4	
			else if (strstr(tegra_t186ref_codec_links[i].name, "ti-playback-i2s1"))
				tegra_t186ref_codec_links[i].init = tegra_t186ref_init;
            else if (strstr(tegra_t186ref_codec_links[i].name, "ti-playback-i2s2"))
				tegra_t186ref_codec_links[i].init = tegra_t186ref_init;
			else if (strstr(tegra_t186ref_codec_links[i].name,
				"dspk-playback-r"))
				tegra_t186ref_codec_links[i].init = tegra_t186ref_dspk_init;
			else if (strstr(tegra_t186ref_codec_links[i].name,
				"dspk-playback-l"))
				tegra_t186ref_codec_links[i].init = tegra_t186ref_dspk_init;
		}
	}

	tegra_t186ref_codec_conf = tegra_machine_new_codec_conf(pdev,
		tegra_t186ref_codec_conf,
		&machine->num_codec_links);
	if (!tegra_t186ref_codec_conf)
		goto err_alloc_dai_link;

	/* get the xbar dai link/codec conf structure */
	tegra_machine_dai_links = tegra_machine_get_dai_link_t18x();
	if (!tegra_machine_dai_links)
		goto err_alloc_dai_link;

	tegra_machine_codec_conf = tegra_machine_get_codec_conf_t18x();
	if (!tegra_machine_codec_conf)
		goto err_alloc_dai_link;

	/* set ADMAIF dai_ops */
	for (i = TEGRA186_DAI_LINK_ADMAIF1;
		i <= TEGRA186_DAI_LINK_ADMAIF20; i++)
		tegra_machine_set_dai_ops(i, &tegra_t186ref_ops);

	/* set sfc dai_init */
	tegra_machine_set_dai_init(TEGRA186_DAI_LINK_SFC1_RX,
		&tegra_t186ref_sfc_init);
#if defined(CONFIG_SND_SOC_TEGRA210_ADSP_ALT)
	/* set ADSP PCM/COMPR */
	for (i = TEGRA186_DAI_LINK_ADSP_PCM1;
		i <= TEGRA186_DAI_LINK_ADSP_PCM2; i++) {
		tegra_machine_set_dai_ops(i, &tegra_t186ref_ops);
	}

	/* set ADSP COMPR */
	for (i = TEGRA186_DAI_LINK_ADSP_COMPR1;
		i <= TEGRA186_DAI_LINK_ADSP_COMPR2; i++) {
		tegra_machine_set_dai_compr_ops(i,
			&tegra_t186ref_compr_ops);
	}
#endif

	/* set ASRC params. The default is 2 channels */
	for (i = 0; i < 6; i++) {
		tegra_machine_set_dai_params(TEGRA186_DAI_LINK_ASRC1_TX1 + i,
			(struct snd_soc_pcm_stream *)
				&tegra_t186ref_asrc_link_params[i]);
		tegra_machine_set_dai_params(TEGRA186_DAI_LINK_ASRC1_RX1 + i,
			(struct snd_soc_pcm_stream *)
				&tegra_t186ref_asrc_link_params[i]);
	}

	/* append t186ref specific dai_links */
	card->num_links =
		tegra_machine_append_dai_link_t18x(tegra_t186ref_codec_links,
			2 * machine->num_codec_links);
	tegra_machine_dai_links = tegra_machine_get_dai_link_t18x();
	card->dai_link = tegra_machine_dai_links;

	/* append t186ref specific codec_conf */
	card->num_configs =
		tegra_machine_append_codec_conf_t18x(tegra_t186ref_codec_conf,
			machine->num_codec_links);
	tegra_machine_codec_conf = tegra_machine_get_codec_conf_t18x();
	card->codec_conf = tegra_machine_codec_conf;

	return;

err_alloc_dai_link:
	tegra_machine_remove_dai_link();
	tegra_machine_remove_codec_conf();
	return;
}
static int tegra_t186ref_dai_init(struct snd_soc_pcm_runtime *rtd,
					int rate,
					int channels,
					u64 formats,
					bool is_playback)
{
	struct snd_soc_card *card = rtd->card;
	struct tegra_t186ref *machine = snd_soc_card_get_drvdata(card);
	struct snd_soc_pcm_stream *dai_params;
	unsigned int idx, clk_out_rate;
	int err, codec_rate, clk_rate;

	codec_rate = tegra_t186ref_srate_values[machine->rate_via_kcontrol];
	clk_rate = (machine->rate_via_kcontrol) ? codec_rate : rate;

	err = tegra_alt_asoc_utils_set_rate(&machine->audio_clock, clk_rate,
						0, 0);
	if (err < 0) {
		dev_err(card->dev, "Can't configure clocks\n");
		return err;
	}

	clk_out_rate = machine->audio_clock.clk_out_rate;

	pr_debug("pll_a_out0 = %d Hz, aud_mclk = %d Hz, codec rate = %d Hz\n",
		machine->audio_clock.set_mclk, clk_out_rate, clk_rate);

	tegra_t186ref_set_params(card, machine, rate, channels, formats);

	idx = tegra_machine_get_codec_dai_link_idx_t18x("ti-playback-i2s1");
	/* check if idx has valid number */
    if (idx != -EINVAL) {
		dai_params =
		(struct snd_soc_pcm_stream *)card->rtd[idx].dai_link->params;
		dai_params->rate_min = clk_rate;
		dai_params->formats = (machine->fmt_via_kcontrol == 2) ?
                                (1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats;

		if (!machine->is_codec_dummy) {
			err = snd_soc_dai_set_sysclk(card->rtd[idx].codec_dai,
			0, 12000000, SND_SOC_CLOCK_IN);
			if (err < 0) {
				dev_err(card->dev, "codec_dai clock not set\n");
				return err;
			}
		}
	}

	
	idx = tegra_machine_get_codec_dai_link_idx_t18x("ti-playback-i2s2");
	/* check if idx has valid number */
	if (idx != -EINVAL) {
		dai_params =
		(struct snd_soc_pcm_stream *)card->rtd[idx].dai_link->params;

		dai_params->rate_min = clk_rate;
		dai_params->formats = (machine->fmt_via_kcontrol == 2) ?
                                (1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats;

		if (!machine->is_codec_dummy) {
			err = snd_soc_dai_set_sysclk(card->rtd[idx].codec_dai,
			0, 12000000, SND_SOC_CLOCK_IN);
			if (err < 0) {
				dev_err(card->dev, "codec_dai clock not set\n");
				return err;
			}
		}
	}

	return 0;
}

2、If the audio is combined with an even sampling rate (recording @16K, playback @48K), how to solve the noise interference problem, because there is noise interference in the first version of the design(a codec TLV320AIC32X4, an I2S interface,recording @16K, playback @48K)?

3、How to correctly use two I2S interfaces in the software?

Thanks

1、 One obvious issue is name-prefix. You need to have different prefix for each link. Please use:

dai-link-1 : name-prefix=x
dai-link-2 : name-prefix=y

Also update audio routing to:

nvidia,audio-routing =
			"x IN2_R", "x Mic",
			"x IN2_L", "x Mic",
			"x Headphone", "x LOR",
			"x Headphone", "x LOL",
			"y IN2_R", "y Mic",
			"y IN2_L", "y Mic",
			"y Headphone", "y LOR",
			"y Headphone", "y LOL";

2、For different sampling rates, 2 different I2S interfaces will be required.

3、Please make corrections as mentioned in point “1” and provide logs if you encounter issues further.

Thanks,
Sharad

Thanks Sharad,

I modified the code according to your method, the previous problem was solved, and a new problem appeared.

dmesg.log

[    4.658397] aic32x4: =================probe===============1.2
[    4.679007] aic32x4: =================probe===============1.2
[    4.679008] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF1 <-> ADMAIF1 mapping ok
[    4.679109] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF2 <-> ADMAIF2 mapping ok
[    4.679230] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF3 <-> ADMAIF3 mapping ok
[    4.679327] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF4 <-> ADMAIF4 mapping ok
[    4.679430] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF5 <-> ADMAIF5 mapping ok
[    4.679535] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF6 <-> ADMAIF6 mapping ok
[    4.679651] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF7 <-> ADMAIF7 mapping ok
[    4.679779] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF8 <-> ADMAIF8 mapping ok
[    4.679902] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF9 <-> ADMAIF9 mapping ok
[    4.680021] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF10 <-> ADMAIF10 mapping ok
[    4.680120] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF11 <-> ADMAIF11 mapping ok
[    4.680222] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF12 <-> ADMAIF12 mapping ok
[    4.680327] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF13 <-> ADMAIF13 mapping ok
[    4.680451] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF14 <-> ADMAIF14 mapping ok
[    4.680559] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF15 <-> ADMAIF15 mapping ok
[    4.680664] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF16 <-> ADMAIF16 mapping ok
[    4.680775] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF17 <-> ADMAIF17 mapping ok
[    4.680878] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF18 <-> ADMAIF18 mapping ok
[    4.681012] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF19 <-> ADMAIF19 mapping ok
[    4.681110] tegra-snd-t186ref-mobile-rt565x sound: ADMAIF20 <-> ADMAIF20 mapping ok
[    4.685460] tegra-snd-t186ref-mobile-rt565x sound: ADSP-FE1 <-> ADSP PCM1 mapping ok
[    4.685561] tegra-snd-t186ref-mobile-rt565x sound: ADSP-FE2 <-> ADSP PCM2 mapping ok
[    4.685591] compress asoc: ADSP-FE3 <-> ADSP COMPR1 mapping ok
[    4.685619] compress asoc: ADSP-FE4 <-> ADSP COMPR2 mapping ok
[    4.739799] input: tegra-snd-t186ref-mobile-rt565x Headphone Jack as /devices/sound/sound/card1/input2
[    4.739966] input: tegra-snd-t186ref-mobile-rt565x Headphone Jack as /devices/sound/sound/card1/input3
[    4.740584] aic32x4-idx:===========ti-playback-i2s-idx=====================
[    4.740584] ti-playback-i2s1-idx = 159 
[    4.740591] tegra-snd-t186ref-mobile-rt565x sound: codec-dai "tlv320aic32x4-hifi" registered
[    4.740594] tegra-snd-t186ref-mobile-rt565x sound: This is a dummy codec
[    4.740596] ti-playback-i2s2-idx = 158 
[    4.740599] tegra-snd-t186ref-mobile-rt565x sound: codec-dai "tlv320aic32x4-hifi" registered
[    4.740601] tegra-snd-t186ref-mobile-rt565x sound: This is a dummy codec

[   17.423091] ===========set_params==============ti-playback-i2s1-idx = 159 
[   17.429994] ===========set_params==============ti-playback-i2s2-idx = 158 
[   17.437300] aic32x4: master clock and sample rate is not supported
[   17.443565] aic32x4: mclk[0] rate[44100]
[   17.447549] aic32x4: sampling rate not supported
[   17.452191] tlv320aic32x4 0-0018: ASoC: can't set tlv320aic32x4-hifi hw params: -22
[   17.459921] tegra-snd-t186ref-mobile-rt565x sound: ASoC: PRE_PMU: y Capture-I2S1 DAP Receive event failed: -22
[   17.614812] ===========set_params==============ti-playback-i2s1-idx = 159 
[   17.621824] ===========set_params==============ti-playback-i2s2-idx = 158 
[   17.629205] aic32x4: master clock and sample rate is not supported
[   17.635522] aic32x4: mclk[0] rate[44100]
[   17.639598] aic32x4: sampling rate not supported
[   17.644317] tlv320aic32x4 0-0018: ASoC: can't set tlv320aic32x4-hifi hw params: -22
[   17.652051] tegra-snd-t186ref-mobile-rt565x sound: ASoC: PRE_PMU: y Capture-I2S1 DAP Receive event failed: -22
[   17.764624] ===========set_params==============ti-playback-i2s1-idx = 159 
[   17.771575] ===========set_params==============ti-playback-i2s2-idx = 158 
[   17.779896] aic32x4: master clock and sample rate is not supported
[   17.786105] aic32x4: mclk[0] rate[44100]
[   17.790082] aic32x4: sampling rate not supported
[   17.794783] tlv320aic32x4 0-0018: ASoC: can't set tlv320aic32x4-hifi hw params: -22
[   17.802461] tegra-snd-t186ref-mobile-rt565x sound: ASoC: PRE_PMU: I2S1 DAP Transmit-y Playback event failed: -22
[   17.812705] aic32x4: mute[0]
[   17.930664] ===========set_params==============ti-playback-i2s1-idx = 159 
[   17.937569] ===========set_params==============ti-playback-i2s2-idx = 158 
[   17.944839] aic32x4: master clock and sample rate is not supported
[   17.951048] aic32x4: mclk[0] rate[44100]
[   17.955004] aic32x4: sampling rate not supported
[   17.959656] tlv320aic32x4 0-0018: ASoC: can't set tlv320aic32x4-hifi hw params: -22
[   17.967391] tegra-snd-t186ref-mobile-rt565x sound: ASoC: PRE_PMU: y Capture-I2S1 DAP Receive event failed: -22
[   17.980879] ===========set_params==============ti-playback-i2s1-idx = 159 
[   17.987807] ===========set_params==============ti-playback-i2s2-idx = 158 
[   17.995061] aic32x4: master clock and sample rate is not supported
[   18.001292] aic32x4: mclk[0] rate[44100]
[   18.005247] aic32x4: sampling rate not supported
[   18.009897] tlv320aic32x4 0-0018: ASoC: can't set tlv320aic32x4-hifi hw params: -22
[   18.017645] tegra-snd-t186ref-mobile-rt565x sound: ASoC: PRE_PMU: y Capture-I2S1 DAP Receive event failed: -22
[   18.031158] aic32x4: mute[1]
[   18.038846] ===========set_params==============ti-playback-i2s1-idx = 159 
[   18.045783] ===========set_params==============ti-playback-i2s2-idx = 158 
[   18.053567] aic32x4: master clock and sample rate is not supported
[   18.060141] aic32x4: mclk[0] rate[44100]
[   18.064396] aic32x4: sampling rate not supported
[   18.069268] tlv320aic32x4 0-0018: ASoC: can't set tlv320aic32x4-hifi hw params: -22
[   18.077210] tegra-snd-t186ref-mobile-rt565x sound: ASoC: PRE_PMU: I2S1 DAP Transmit-y Playback event failed: -22
[   18.087567] aic32x4: mute[0]
[   18.208083] ===========set_params==============ti-playback-i2s1-idx = 159 
[   18.215010] ===========set_params==============ti-playback-i2s2-idx = 158 
[   18.222282] aic32x4: master clock and sample rate is not supported
[   18.228534] aic32x4: mclk[0] rate[44100]
[   18.232496] aic32x4: sampling rate not supported
[   18.237159] tlv320aic32x4 0-0018: ASoC: can't set tlv320aic32x4-hifi hw params: -22
[   18.244861] tegra-snd-t186ref-mobile-rt565x sound: ASoC: PRE_PMU: y Capture-I2S1 DAP Receive event failed: -22
[   18.259277] ===========set_params==============ti-playback-i2s1-idx = 159 
[   18.266347] ===========set_params==============ti-playback-i2s2-idx = 158 
[   18.273601] aic32x4: master clock and sample rate is not supported
[   18.279955] aic32x4: mclk[0] rate[44100]
[   18.283938] aic32x4: sampling rate not supported
[   18.288593] tlv320aic32x4 0-0018: ASoC: can't set tlv320aic32x4-hifi hw params: -22
[   18.296333] tegra-snd-t186ref-mobile-rt565x sound: ASoC: PRE_PMU: y Capture-I2S1 DAP Receive event failed: -22
[   18.313423] aic32x4: mute[1]
[   18.343910] ===========set_params==============ti-playback-i2s1-idx = 159 
[   18.350855] ===========set_params==============ti-playback-i2s2-idx = 158 
[   18.359623] aic32x4: master clock and sample rate is not supported
[   18.365896] aic32x4: mclk[0] rate[44100]
[   18.369887] aic32x4: sampling rate not supported
[   18.374578] tlv320aic32x4 0-0018: ASoC: can't set tlv320aic32x4-hifi hw params: -22
[   18.382425] tegra-snd-t186ref-mobile-rt565x sound: ASoC: PRE_PMU: I2S1 DAP Transmit-y Playback event failed: -22
[   18.392690] aic32x4: mute[0]
[   18.530297] ===========set_params==============ti-playback-i2s1-idx = 159 
[   18.537554] ===========set_params==============ti-playback-i2s2-idx = 158 
[   18.546292] aic32x4: master clock and sample rate is not supported
[   18.552524] aic32x4: mclk[0] rate[44100]
[   18.556506] aic32x4: sampling rate not supported
[   18.561205] tlv320aic32x4 0-0018: ASoC: can't set tlv320aic32x4-hifi hw params: -22
[   18.568884] tegra-snd-t186ref-mobile-rt565x sound: ASoC: PRE_PMU: y Capture-I2S1 DAP Receive event failed: -22
[   18.884872] IPVS: Creating netns size=1424 id=3
[   23.739424] aic32x4: mute[1]
[   24.614374] l4tbr0: port 1(usb0) entered forwarding state
[  123.895329] IPVS: Creating netns size=1424 id=4

Thanks

“[ 4.740594] tegra-snd-t186ref-mobile-rt565x sound: This is a dummy codec” is the problem here.

In probe, please modified the code as below:

idx = tegra_machine_get_codec_dai_link_idx_t18x("ti-playback-i2s1");
	/* check if idx has valid number */
	if (idx == -EINVAL)
		dev_warn(&pdev->dev, "codec link not defined - codec not part of sound card --i2s1");
	else {
		codec = card->rtd[idx].codec;
		codec_dai_name = card->rtd[idx].dai_link->codec_dai_name;

		dev_info(&pdev->dev,
			"codec-dai \"%s\" registered\n", codec_dai_name);
		if (!strcmp("dit-hifi", codec_dai_name)) {
			dev_info(&pdev->dev, "This is a dummy codec\n");
			machine->is_codec_dummy = 1;
		}
	}
    
    idx = tegra_machine_get_codec_dai_link_idx_t18x("ti-playback-i2s2");
	/* check if idx has valid number */
	if (idx == -EINVAL)
		dev_warn(&pdev->dev, "codec link not defined - codec not part of sound card --i2s2");
	else {
		codec = card->rtd[idx].codec;
		codec_dai_name = card->rtd[idx].dai_link->codec_dai_name;

		dev_info(&pdev->dev,
			"codec-dai \"%s\" registered\n", codec_dai_name);
		if (!strcmp("dit-hifi", codec_dai_name)) {
			dev_info(&pdev->dev, "This is a dummy codec\n");
			machine->is_codec_dummy = machine->is_codec_dummy|2;
		}
	}

This will fix dummy codec logs. I suggest to enable one codec at a time and make sure functionality is up with that …and then enable another one.

Thanks Sharad.

I modified the code according to your suggestions and tips. After debugging, TX2 can recording and playback at the same time.

Thanks

Glad to hear that!