TLV320aic34 audio codec

Hi,
I’m working on a custom board based on TX2-4GB, and I’m struggling to configure TLV320aic34 audio codec.
I’m using this post as a reference (https://devtalk.nvidia.com/default/topic/1053652/jetson-tx2/tlv320aic3x-on-tx2-only-noise-while-playback/1) since I’m using the same codec driver (TLV320aic34 is actually seen as two sapareted TLV320aic3106). Unfortunately my problem seems a little bit different because when I try to play a sound the aplay command ends immediately and nothing is played on the output lines.

This is my codec node:

{
	i2c@3180000 {
  		aic34_a: tlv320aic34_a@1a {
			staus = "okay";
  			compatible = "ti,tlv320aic3106";
  			reg = <0x1a>;
			clocks = <&tegra_car TEGRA186_CLK_AUD_MCLK>;
			clock-names = "aud_mclk"; 			

			/* Regulators */
        		AVDD-supply = <&spmic_ldo2>; //3.3
        		DRVDD-supply = <&spmic_ldo2>; //v3.3
        		IOVDD-supply = <&spmic_sd2>; //v 1.8
        		DVDD-supply = <&spmic_sd2>; //v1.8
  		};

  		aic34_b: tlv320aic34_b@1b {
			staus = "okay";
  			compatible = "ti,tlv320aic3106";
  			reg = <0x1b>;
			clocks = <&tegra_car TEGRA186_CLK_AUD_MCLK>;
			clock-names = "aud_mclk";

			/* Regulators */
        		AVDD-supply = <&spmic_ldo2>; //3.3
        		DRVDD-supply = <&spmic_ldo2>; //v3.3
        		IOVDD-supply = <&spmic_sd2>; //v 1.8
        		DVDD-supply = <&spmic_sd2>; //v1.8
  		};
	};
};

Please note that the reset is done with an external FPGA.
The codec driver probe functions are called during system startup: first aic3x_i2c_probe and then aic3x_probe without any errors.

My sound node looks like this:

tegra_sound: sound {
		compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x";
		nvidia,model = "tegra-sound";
                nvidia,num-codec-link = <2>;
		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 =
                	"a LINE1L",    "a Mic",
                	"a LINE2L",    "a Mic",
                	"a Headphone", "a HPLOUT",
                	"a Headphone", "a HPROUT",
                	"b LINE1L",    "b Mic",
                	"b LINE2L",    "b Mic",
                	"b Headphone", "b HPLOUT",
                	"b Headphone", "b HPROUT";

                nvidia,xbar = <&tegra_axbar>;

		nvidia,dai-link-1 {
                        link-name = "ti-playback-a";
			status = "okay";
                        cpu-dai = <&tegra_i2s1>;
                        codec-dai = <&aic34_a>;
                        cpu-dai-name = "I2S1";
                        codec-dai-name = "tlv320aic3x-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 = <4>;  /* max 2 input/ 2 output */
			name-prefix = "a";
                };

		nvidia,dai-link-2 {
                        link-name = "ti-playback-b";
			status = "okay";
                       	cpu-dai = <&tegra_i2s2>;
                       	codec-dai = <&aic34_b>;
                       	cpu-dai-name = "I2S2";
                       	codec-dai-name = "tlv320aic3x-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 = <4>;  /* max 2 input/ 4 output */
			name-prefix = "b";
               	};
	};

The additional sound card is listed in the ALSA devices, and the codec widgets are listed correctly.

The tegra machine driver has been patched to generate a MLCK of 12Mhz:

diff --git a/tegra_machine_driver_mobile.c.ori b/tegra_machine_driver_mobile.c
old mode 100644
new mode 100755
index 048007f..3500ccf
--- a/tegra_machine_driver_mobile.c.ori
+++ b/tegra_machine_driver_mobile.c
@@ -97,7 +97,8 @@ static int tegra_machine_driver_remove(struct platform_device *);
 static int tegra_machine_driver_probe(struct platform_device *);
 static void dai_link_setup(struct platform_device *);
 static int tegra_machine_sfc_init(struct snd_soc_pcm_runtime *);
-static int tegra_machine_rt565x_init(struct snd_soc_pcm_runtime *);
+//static int tegra_machine_rt565x_init(struct snd_soc_pcm_runtime *);
+static int tegra_machine_t186ref_init(struct snd_soc_pcm_runtime *);
 
 #if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT)
 static int tegra_machine_compr_set_params(struct snd_compr_stream *);
@@ -527,7 +528,7 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
 	if (machine->soc_data->is_clk_rate_via_dt)
 		clk_out_rate = machine->audio_clock.set_clk_out_rate;
 
-	pr_debug("pll_a_out0 = %d Hz, aud_mclk = %d Hz, codec rate = %d Hz\n",
+	printk(KERN_ERR "pll_a_out0 = %d Hz, aud_mclk = %d Hz, codec rate = %d Hz\n",
 		machine->audio_clock.set_mclk,
 		machine->audio_clock.set_clk_out_rate, clk_rate);
 
@@ -535,8 +536,9 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
 	err = tegra_machine_set_params(card, machine, rate, channels, formats);
 	if (err < 0)
 		return err;
-
-	rtd = snd_soc_get_pcm_runtime(card, "rt565x-playback");
+	
+	rtd = snd_soc_get_pcm_runtime(card, "ti-playback-a");
+	printk(KERN_ERR "SOUND tegra_machine_dai_init:====ti-playback-a I2S1 =====\n");
 	if (rtd) {
 		dai_params =
 		(struct snd_soc_pcm_stream *)rtd->dai_link->params;
@@ -547,15 +549,16 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
 
 		if (machine->is_hs_supported) {
 			err = snd_soc_dai_set_sysclk(rtd->codec_dai,
-			RT5659_SCLK_S_MCLK, clk_out_rate, SND_SOC_CLOCK_IN);
+			0, 12000000, SND_SOC_CLOCK_IN);
 			if (err < 0) {
 				dev_err(card->dev, "codec_dai clock not set\n");
 				return err;
 			}
 		}
 	}
-
-	rtd = snd_soc_get_pcm_runtime(card, "rt565x-codec-sysclk-bclk1");
+	
+	rtd = snd_soc_get_pcm_runtime(card, "ti-playback-b");
+	printk(KERN_ERR "SOUND tegra_machine_dai_init:====ti-playback-b I2S2 =====\n");
 	if (rtd) {
 		dai_params =
 		(struct snd_soc_pcm_stream *)rtd->dai_link->params;
@@ -564,78 +567,9 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
 		dai_params->formats = (machine->fmt_via_kcontrol == 2) ?
 			(1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats;
 
-		err = rt565x_manage_codec_sysclk(dai_params, rtd->codec_dai,
-						 RT5659_PLL1_S_BCLK1);
-		if (err < 0) {
-			dev_err(card->dev, "codec_dai clock not set\n");
-			return err;
-		}
-	}
-
-	/* TODO: remove below spdif links if clk_rate is passed
-	 *	in tegra_machine_set_params
-	 */
-	rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-1");
-	if (rtd) {
-		dai_params =
-		(struct snd_soc_pcm_stream *)rtd->dai_link->params;
-
-		dai_params->rate_min = clk_rate;
-	}
-
-	/* set clk rate for i2s3 dai link*/
-	rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-2");
-	if (rtd) {
-		dai_params =
-		(struct snd_soc_pcm_stream *)rtd->dai_link->params;
-
-		dai_params->rate_min = clk_rate;
-	}
-
-	rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-3");
-	if (rtd) {
-		dai_params =
-		(struct snd_soc_pcm_stream *)rtd->dai_link->params;
-
-		dai_params->rate_min = clk_rate;
-	}
-
-	rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-5");
-	if (rtd) {
-		dai_params =
-		(struct snd_soc_pcm_stream *)rtd->dai_link->params;
-
-		/* update link_param to update hw_param for DAPM */
-		dai_params->rate_min = clk_rate;
-		dai_params->channels_min = channels;
-		dai_params->formats = formats;
-	}
-
-	rtd = snd_soc_get_pcm_runtime(card, "dspk-playback-r");
-	if (rtd) {
-		dai_params =
-		(struct snd_soc_pcm_stream *)rtd->dai_link->params;
-
-		if (!strcmp(rtd->codec_dai->name, "tas2552-amplifier")) {
-			err = snd_soc_dai_set_sysclk(rtd->codec_dai,
-				TAS2552_PDM_CLK_IVCLKIN, clk_out_rate,
-				SND_SOC_CLOCK_IN);
-			if (err < 0) {
-				dev_err(card->dev, "codec_dai clock not set\n");
-				return err;
-			}
-		}
-	}
-
-	rtd = snd_soc_get_pcm_runtime(card, "dspk-playback-l");
-	if (rtd) {
-		dai_params =
-		(struct snd_soc_pcm_stream *)rtd->dai_link->params;
-
-		if (!strcmp(rtd->codec_dai->name, "tas2552-amplifier")) {
+		if (machine->is_hs_supported) {
 			err = snd_soc_dai_set_sysclk(rtd->codec_dai,
-				TAS2552_PDM_CLK_IVCLKIN, clk_out_rate,
-				SND_SOC_CLOCK_IN);
+			0, 12000000, SND_SOC_CLOCK_IN);
 			if (err < 0) {
 				dev_err(card->dev, "codec_dai clock not set\n");
 				return err;
@@ -643,16 +577,7 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
 		}
 	}
 
-	rtd = snd_soc_get_pcm_runtime(card, "fe-pi-audio-z-v2");
-	if (rtd) {
-		dai_params =
-		(struct snd_soc_pcm_stream *)rtd->dai_link->params;
-
-		dai_params->rate_min = clk_rate;
-		dai_params->channels_min = channels;
-		dai_params->formats = formats;
-	}
-
+	printk(KERN_ERR "SOUND tegra_machine_dai_init:==== OK =====\n");
 	return 0;
 }
 
@@ -810,6 +735,22 @@ static int tegra_machine_fepi_init(struct snd_soc_pcm_runtime *rtd)
 	return 0;
 }
 
+static int tegra_machine_t186ref_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_card *card = rtd->card;
+	struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
+	int err;
+
+	err = tegra_alt_asoc_utils_set_extern_parent(&machine->audio_clock,
+							"pll_a_out0");
+	if (err < 0) {
+		dev_err(card->dev, "Failed to set extern clk parent\n");
+		return err;
+	}
+
+	return 0;
+}
+#if 0
 static int tegra_machine_rt565x_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_soc_card *card = rtd->card;
@@ -859,7 +800,7 @@ static int tegra_machine_rt565x_init(struct snd_soc_pcm_runtime *rtd)
 
 	return 0;
 }
-
+#endif
 static int tegra_machine_sfc_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
@@ -899,9 +840,9 @@ static void dai_link_setup(struct platform_device *pdev)
 	for (i = 0; i < machine->num_codec_links; i++) {
 		if (tegra_machine_codec_links[i].name) {
 			if (strstr(tegra_machine_codec_links[i].name,
-				"rt565x-playback") ||
+				"ti-playback-a") ||
 			    strstr(tegra_machine_codec_links[i].name,
-				"rt565x-codec-sysclk-bclk1")) {
+				"ti-playback-b")) {
 				codec_dai_name =
 				 tegra_machine_codec_links[i].codec_dai_name;
 				if (!strcmp("dit-hifi", codec_dai_name)) {
@@ -910,7 +851,7 @@ static void dai_link_setup(struct platform_device *pdev)
 				} else {
 					machine->is_hs_supported = true;
 					tegra_machine_codec_links[i].init =
-						tegra_machine_rt565x_init;
+						tegra_machine_t186ref_init;
 				}
 			} else if (strstr(tegra_machine_codec_links[i].name,
 				"dspk-playback-r")) {
@@ -1107,6 +1048,13 @@ static int tegra_machine_driver_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_alloc_dai_link;
 
+	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_alloc_dai_link;
+	}
+
 	ret = snd_soc_register_card(card);
 	if (ret) {
 		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
diff --git a/tegra_asoc_utils_alt.c.ori b/tegra_asoc_utils_alt.c
old mode 100644
new mode 100755
index f18c24b..e02c86f
--- a/tegra_asoc_utils_alt.c.ori
+++ b/tegra_asoc_utils_alt.c
@@ -135,12 +135,12 @@ int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data,
 		}
 	}
 
-	err = clk_set_rate(data->clk_cdev1, clk_out_rate);
+	err = clk_set_rate(data->clk_cdev1, 12000000);
 	if (err) {
 		dev_err(data->dev, "Can't set clk_cdev1 rate: %d\n", err);
 		return err;
 	}
-
+	
 	data->set_baseclock = new_baseclock;
 	data->set_mclk = mclk;
 	data->set_clk_out_rate = clk_out_rate;
@@ -212,6 +212,13 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
 		goto err;
 	}
 
+	data->clk_pll_p_out1 = devm_clk_get(dev, "pll_p_out1");
+        if (IS_ERR(data->clk_pll_p_out1)) {
+                dev_err(data->dev, "Can't retrieve clk pll_p_out1\n");
+                ret = PTR_ERR(data->clk_pll_p_out1);
+                goto err;
+        }
+
 	data->clk_pll_a = devm_clk_get(dev, "pll_a");
 	if (IS_ERR(data->clk_pll_a)) {
 		dev_err(data->dev, "Can't retrieve clk pll_a\n");
@@ -275,19 +282,21 @@ int tegra_alt_asoc_utils_set_parent(struct tegra_asoc_audio_clock_info *data,
 	int ret = -ENODEV;
 
 	if (is_i2s_master) {
-		ret = clk_set_parent(data->clk_cdev1, data->clk_pll_a_out0);
+		ret = clk_set_parent(data->clk_cdev1, data->clk_pll_p_out1);
 		if (ret) {
 			dev_err(data->dev, "Can't set clk cdev1/extern1 parent");
 			return ret;
 		}
 	} else {
-		ret = clk_set_parent(data->clk_cdev1, data->clk_m);
+		ret = clk_set_parent(data->clk_cdev1, data->clk_pll_p_out1);
 		if (ret) {
 			dev_err(data->dev, "Can't set clk cdev1/extern1 parent");
 			return ret;
 		}
 
-		ret = clk_set_rate(data->clk_cdev1, 13000000);
+//		ret = clk_set_rate(data->clk_cdev1, 13000000);
+		printk(KERN_ERR "SOUND MACHINE DRIVER Set master clock 12Mhz\n");	
+		ret = clk_set_rate(data->clk_cdev1, 12000000);
 		if (ret) {
 			dev_err(data->dev, "Can't set clk rate");
 			return ret;
@@ -317,7 +326,15 @@ int tegra_alt_asoc_utils_set_extern_parent(
 		return err;
 	}
 
-	err = clk_set_rate(data->clk_cdev1, rate);
+	err = clk_set_parent(data->clk_cdev1, data->clk_pll_p_out1);
+	if (err) {
+		dev_err(data->dev, "Can't set clk cdev1/extern1 parent");
+		return err;
+	}
+
+	printk(KERN_ERR "SOUND MACHINE DRIVER Set master clock 12Mhz\n");	
+	err = clk_set_rate(data->clk_cdev1, 12000000);
+	//err = clk_set_rate(data->clk_cdev1, rate);
 	if (err) {
 		dev_err(data->dev, "Can't set clk rate");
 		return err;

But unfortunately I’ve never seen the aic3x_hw_params been called.

When I try to play a sound I use the following script:

#!/bin/bash
amixer -c tegrasound sset 'ADMAIF3 Mux' 'I2S1'
amixer -c tegrasound sset 'I2S1 Mux' 'ADMAIF3'
amixer -c tegrasound cset name='MVC1 Mute' 0
amixer -c tegrasound cset name='MVC2 Mute' 0
amixer -c tegrasound cset name='a HPCOM Playback Switch' 1
amixer -c tegrasound cset name='a Line Playback Switch' 1
amixer -c tegrasound cset name='a HP Playback Switch' 1
amixer -c tegrasound cset name='a PCM Playback Volume' 95%
amixer -c tegrasound cset name='a HP DAC Playback Volume' 95%
amixer -c tegrasound cset name='a HPCOM DAC Playback Volume' 80%
amixer -c tegrasound cset name='a Left HP Mixer DACR1 Playback Volume' 90%
amixer -c tegrasound cset name='a Left HPCOM Mixer DACR1 Playback Volume' 90%
amixer -c tegrasound sset 'ADMAIF4 Mux' 'I2S2'
amixer -c tegrasound sset 'I2S2 Mux' 'ADMAIF4'
amixer -c tegrasound cset name='MVC1 Mute' 0
amixer -c tegrasound cset name='MVC2 Mute' 0
amixer -c tegrasound cset name='b HPCOM Playback Switch' 1
amixer -c tegrasound cset name='b Line Playback Switch' 1
amixer -c tegrasound cset name='b HP Playback Switch' 1
amixer -c tegrasound cset name='b PCM Playback Volume' 95%
amixer -c tegrasound cset name='b HP DAC Playback Volume' 95%
amixer -c tegrasound cset name='b HPCOM DAC Playback Volume' 80%
amixer -c tegrasound cset name='b Left HP Mixer DACR1 Playback Volume' 90%
amixer -c tegrasound cset name='b Left HPCOM Mixer DACR1 Playback Volume' 90%
aplay -D hw:tegrasound,10 ../Music/piano2.wav
aplay -D hw:tegrasound,11 ../Music/piano2.wav

this is the command output:

Simple mixer control 'ADMAIF3 Mux',0
  Capabilities: enum
  Items: 'None' 'ADMAIF1' 'ADMAIF2' 'ADMAIF3' 'ADMAIF4' 'ADMAIF5' 'ADMAIF6' 'ADMAIF7' 'ADMAIF8' 'ADMAIF9' 'ADMAIF10' 'ADMAIF11' 'ADMAIF12' 'ADMAIF13' 'ADMAIF14' 'ADMAIF15' 'ADMAIF16' 'I2S1' 'I2S2' 'I2S3' 'I2S4' 'I2S5' 'I2S6' 'SFC1' 'SFC2' 'SFC3' 'SFC4' 'MIXER1-1' 'MIXER1-2' 'MIXER1-3' 'MIXER1-4' 'MIXER1-5' 'AMX1' 'AMX2' 'AMX3' 'AMX4' 'ARAD1' 'AFC1' 'AFC2' 'AFC3' 'AFC4' 'AFC5' 'AFC6' 'OPE1' 'SPKPROT1' 'MVC1' 'MVC2' 'IQC1-1' 'IQC1-2' 'IQC2-1' 'IQC2-2' 'DMIC1' 'DMIC2' 'DMIC3' 'DMIC4' 'ADX1-1' 'ADX1-2' 'ADX1-3' 'ADX1-4' 'ADX2-1' 'ADX2-2' 'ADX2-3' 'ADX2-4' 'ADX3-1' 'ADX3-2' 'ADX3-3' 'ADX3-4' 'ADX4-1' 'ADX4-2' 'ADX4-3' 'ADX4-4' 'ADMAIF17' 'ADMAIF18' 'ADMAIF19' 'ADMAIF20' 'ASRC1-1' 'ASRC1-2' 'ASRC1-3' 'ASRC1-4' 'ASRC1-5' 'ASRC1-6'
  Item0: 'I2S1'
Simple mixer control 'I2S1 Mux',0
  Capabilities: enum
  Items: 'None' 'ADMAIF1' 'ADMAIF2' 'ADMAIF3' 'ADMAIF4' 'ADMAIF5' 'ADMAIF6' 'ADMAIF7' 'ADMAIF8' 'ADMAIF9' 'ADMAIF10' 'ADMAIF11' 'ADMAIF12' 'ADMAIF13' 'ADMAIF14' 'ADMAIF15' 'ADMAIF16' 'I2S1' 'I2S2' 'I2S3' 'I2S4' 'I2S5' 'I2S6' 'SFC1' 'SFC2' 'SFC3' 'SFC4' 'MIXER1-1' 'MIXER1-2' 'MIXER1-3' 'MIXER1-4' 'MIXER1-5' 'AMX1' 'AMX2' 'AMX3' 'AMX4' 'ARAD1' 'AFC1' 'AFC2' 'AFC3' 'AFC4' 'AFC5' 'AFC6' 'OPE1' 'SPKPROT1' 'MVC1' 'MVC2' 'IQC1-1' 'IQC1-2' 'IQC2-1' 'IQC2-2' 'DMIC1' 'DMIC2' 'DMIC3' 'DMIC4' 'ADX1-1' 'ADX1-2' 'ADX1-3' 'ADX1-4' 'ADX2-1' 'ADX2-2' 'ADX2-3' 'ADX2-4' 'ADX3-1' 'ADX3-2' 'ADX3-3' 'ADX3-4' 'ADX4-1' 'ADX4-2' 'ADX4-3' 'ADX4-4' 'ADMAIF17' 'ADMAIF18' 'ADMAIF19' 'ADMAIF20' 'ASRC1-1' 'ASRC1-2' 'ASRC1-3' 'ASRC1-4' 'ASRC1-5' 'ASRC1-6'
  Item0: 'ADMAIF3'
numid=683,iface=MIXER,name='MVC1 Mute'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=689,iface=MIXER,name='MVC2 Mute'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=896,iface=MIXER,name='a HPCOM Playback Switch'
  ; type=BOOLEAN,access=rw------,values=2
  : values=on,on
numid=894,iface=MIXER,name='a Line Playback Switch'
  ; type=BOOLEAN,access=rw------,values=2
  : values=on,on
numid=895,iface=MIXER,name='a HP Playback Switch'
  ; type=BOOLEAN,access=rw------,values=2
  : values=on,on
numid=875,iface=MIXER,name='a PCM Playback Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=127,step=0
  : values=121,121
  | dBscale-min=-63.50dB,step=0.50dB,mute=0
numid=891,iface=MIXER,name='a HP DAC Playback Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=118,step=0
  : values=113,113
  | dBscale-min=-59.00dB,step=0.50dB,mute=1
numid=893,iface=MIXER,name='a HPCOM DAC Playback Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=118,step=0
  : values=95,95
  | dBscale-min=-59.00dB,step=0.50dB,mute=1
numid=881,iface=MIXER,name='a Left HP Mixer DACR1 Playback Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=118,step=0
  : values=107
  | dBscale-min=-59.00dB,step=0.50dB,mute=1
numid=885,iface=MIXER,name='a Left HPCOM Mixer DACR1 Playback Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=118,step=0
  : values=107
  | dBscale-min=-59.00dB,step=0.50dB,mute=1
Simple mixer control 'ADMAIF4 Mux',0
  Capabilities: enum
  Items: 'None' 'ADMAIF1' 'ADMAIF2' 'ADMAIF3' 'ADMAIF4' 'ADMAIF5' 'ADMAIF6' 'ADMAIF7' 'ADMAIF8' 'ADMAIF9' 'ADMAIF10' 'ADMAIF11' 'ADMAIF12' 'ADMAIF13' 'ADMAIF14' 'ADMAIF15' 'ADMAIF16' 'I2S1' 'I2S2' 'I2S3' 'I2S4' 'I2S5' 'I2S6' 'SFC1' 'SFC2' 'SFC3' 'SFC4' 'MIXER1-1' 'MIXER1-2' 'MIXER1-3' 'MIXER1-4' 'MIXER1-5' 'AMX1' 'AMX2' 'AMX3' 'AMX4' 'ARAD1' 'AFC1' 'AFC2' 'AFC3' 'AFC4' 'AFC5' 'AFC6' 'OPE1' 'SPKPROT1' 'MVC1' 'MVC2' 'IQC1-1' 'IQC1-2' 'IQC2-1' 'IQC2-2' 'DMIC1' 'DMIC2' 'DMIC3' 'DMIC4' 'ADX1-1' 'ADX1-2' 'ADX1-3' 'ADX1-4' 'ADX2-1' 'ADX2-2' 'ADX2-3' 'ADX2-4' 'ADX3-1' 'ADX3-2' 'ADX3-3' 'ADX3-4' 'ADX4-1' 'ADX4-2' 'ADX4-3' 'ADX4-4' 'ADMAIF17' 'ADMAIF18' 'ADMAIF19' 'ADMAIF20' 'ASRC1-1' 'ASRC1-2' 'ASRC1-3' 'ASRC1-4' 'ASRC1-5' 'ASRC1-6'
  Item0: 'I2S2'
Simple mixer control 'I2S2 Mux',0
  Capabilities: enum
  Items: 'None' 'ADMAIF1' 'ADMAIF2' 'ADMAIF3' 'ADMAIF4' 'ADMAIF5' 'ADMAIF6' 'ADMAIF7' 'ADMAIF8' 'ADMAIF9' 'ADMAIF10' 'ADMAIF11' 'ADMAIF12' 'ADMAIF13' 'ADMAIF14' 'ADMAIF15' 'ADMAIF16' 'I2S1' 'I2S2' 'I2S3' 'I2S4' 'I2S5' 'I2S6' 'SFC1' 'SFC2' 'SFC3' 'SFC4' 'MIXER1-1' 'MIXER1-2' 'MIXER1-3' 'MIXER1-4' 'MIXER1-5' 'AMX1' 'AMX2' 'AMX3' 'AMX4' 'ARAD1' 'AFC1' 'AFC2' 'AFC3' 'AFC4' 'AFC5' 'AFC6' 'OPE1' 'SPKPROT1' 'MVC1' 'MVC2' 'IQC1-1' 'IQC1-2' 'IQC2-1' 'IQC2-2' 'DMIC1' 'DMIC2' 'DMIC3' 'DMIC4' 'ADX1-1' 'ADX1-2' 'ADX1-3' 'ADX1-4' 'ADX2-1' 'ADX2-2' 'ADX2-3' 'ADX2-4' 'ADX3-1' 'ADX3-2' 'ADX3-3' 'ADX3-4' 'ADX4-1' 'ADX4-2' 'ADX4-3' 'ADX4-4' 'ADMAIF17' 'ADMAIF18' 'ADMAIF19' 'ADMAIF20' 'ASRC1-1' 'ASRC1-2' 'ASRC1-3' 'ASRC1-4' 'ASRC1-5' 'ASRC1-6'
  Item0: 'ADMAIF4'
numid=683,iface=MIXER,name='MVC1 Mute'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=689,iface=MIXER,name='MVC2 Mute'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=955,iface=MIXER,name='b HPCOM Playback Switch'
  ; type=BOOLEAN,access=rw------,values=2
  : values=on,on
numid=953,iface=MIXER,name='b Line Playback Switch'
  ; type=BOOLEAN,access=rw------,values=2
  : values=on,on
numid=954,iface=MIXER,name='b HP Playback Switch'
  ; type=BOOLEAN,access=rw------,values=2
  : values=on,on
numid=934,iface=MIXER,name='b PCM Playback Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=127,step=0
  : values=121,121
  | dBscale-min=-63.50dB,step=0.50dB,mute=0
numid=950,iface=MIXER,name='b HP DAC Playback Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=118,step=0
  : values=113,113
  | dBscale-min=-59.00dB,step=0.50dB,mute=1
numid=952,iface=MIXER,name='b HPCOM DAC Playback Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=118,step=0
  : values=95,95
  | dBscale-min=-59.00dB,step=0.50dB,mute=1
numid=940,iface=MIXER,name='b Left HP Mixer DACR1 Playback Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=118,step=0
  : values=107
  | dBscale-min=-59.00dB,step=0.50dB,mute=1
numid=944,iface=MIXER,name='b Left HPCOM Mixer DACR1 Playback Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=118,step=0
  : values=107
  | dBscale-min=-59.00dB,step=0.50dB,mute=1
Playing WAVE '../Music/piano2.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Playing WAVE '../Music/piano2.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo

kernel log:

[  893.347770] pll_a_out0 = 45158400 Hz, aud_mclk = 11289600 Hz, codec rate = 44100 Hz
[  893.355720] SOUND tegra_machine_dai_init:====ti-playback-a I2S1 =====
[  893.363372] aic3x: SOUND DAI system clock frequency 12000000 clk_id: 0
[  893.370421] SOUND tegra_machine_dai_init:====ti-playback-b I2S2 =====
[  893.377418] aic3x: SOUND DAI system clock frequency 12000000 clk_id: 0
[  893.384532] SOUND tegra_machine_dai_init:==== OK =====
[  896.849855] pll_a_out0 = 45158400 Hz, aud_mclk = 11289600 Hz, codec rate = 44100 Hz
[  896.857773] SOUND tegra_machine_dai_init:====ti-playback-a I2S1 =====
[  896.864251] aic3x: SOUND DAI system clock frequency 12000000 clk_id: 0
[  896.870878] SOUND tegra_machine_dai_init:====ti-playback-b I2S2 =====
[  896.877430] aic3x: SOUND DAI system clock frequency 12000000 clk_id: 0
[  896.883974] SOUND tegra_machine_dai_init:==== OK =====

and the trace pipe:

aplay-12059 [002] ....  8123.672800: snd_soc_dapm_start: card=tegra-sound
           aplay-12059 [002] ....  8123.672951: snd_soc_dapm_walk_done: tegra-sound: checks 2 power, 2 path, 0 neighbour
           aplay-12059 [002] ....  8123.672974: snd_soc_dapm_done: card=tegra-sound
           aplay-12059 [002] ....  8123.872978: snd_soc_dapm_start: card=tegra-sound
           aplay-12059 [002] ....  8123.873234: snd_soc_dapm_path: *ADMAIF3 Receive <- (direct) <- Playback 3
           aplay-12059 [002] ....  8123.873261: snd_soc_dapm_path: *ADMAIF3 Receive <- (direct) <- ADMAIF3 CIF Receive-ADMAIF3 Receive
           aplay-12059 [002] ....  8123.873470: snd_soc_dapm_walk_done: tegra-sound: checks 2 power, 2 path, 2 neighbour
           aplay-12059 [002] ....  8123.873516: snd_soc_dapm_done: card=tegra-sound
           aplay-12060 [001] ....  8123.969349: snd_soc_dapm_start: card=tegra-sound
           aplay-12060 [001] ....  8123.969542: snd_soc_dapm_walk_done: tegra-sound: checks 2 power, 2 path, 0 neighbour
           aplay-12060 [001] ....  8123.969561: snd_soc_dapm_done: card=tegra-sound
           aplay-12060 [001] ....  8124.170077: snd_soc_dapm_start: card=tegra-sound
           aplay-12060 [001] ....  8124.170914: snd_soc_dapm_path: *ADMAIF4 Receive <- (direct) <- Playback 4
           aplay-12060 [001] ....  8124.171419: snd_soc_dapm_path: *ADMAIF4 Receive <- (direct) <- ADMAIF4 CIF Receive-ADMAIF4 Receive
           aplay-12060 [001] ....  8124.171998: snd_soc_dapm_walk_done: tegra-sound: checks 2 power, 2 path, 2 neighbour
           aplay-12060 [004] ....  8124.172869: snd_soc_dapm_done: card=tegra-sound

Note that in the DAPM trace I dont’ see any reference to the codec widgets.
Please let me know if I’m missing something, folder /sys/kernel/debug/asoc/tegra-sound/ is full of additional debug information but I’m a little bit lost and I don’t know exactly what to search for.

Thanks,
Davide

Quick update:
It seems that the routing path is wrong, I’ve changed the sound node mapping between the machine driver and the codec driver to the following:

nvidia,audio-routing =
“a LINE1L”, “a Mic”,
“a LINE2L”, “a Mic”,
“a Headphone”, “a Playback”,
“b LINE1L”, “b Mic”,
“b LINE2L”, “b Mic”,
“b Headphone”, “b Playback”;

And now I actually see the aic3x_hw_params function being called and the aplay command lasts as long as the sound duration.
MCLK , BCLK and WCLK are now working correctly during the playback.
There is something I do not understand though, the stream_name is the actual widget exposed by the codec driver?

static struct snd_soc_dai_driver aic3x_dai = {
	.name = "tlv320aic3x-hifi",
	.playback = {
		.stream_name = "Playback",
		.channels_min = 2,
		.channels_max = 2,
		.rates = AIC3X_RATES,
		.formats = AIC3X_FORMATS,},
	.capture = {
		.stream_name = "Capture",
		.channels_min = 2,
		.channels_max = 2,
		.rates = AIC3X_RATES,
		.formats = AIC3X_FORMATS,},
	.ops = &aic3x_dai_ops,
	.symmetric_rates = 1,
};

I thought they were these:

SND_SOC_DAPM_OUTPUT("LLOUT"),
	SND_SOC_DAPM_OUTPUT("RLOUT"),
	SND_SOC_DAPM_OUTPUT("HPLOUT"),
	SND_SOC_DAPM_OUTPUT("HPROUT"),
	SND_SOC_DAPM_OUTPUT("HPLCOM"),
	SND_SOC_DAPM_OUTPUT("HPRCOM"),

	SND_SOC_DAPM_INPUT("LINE1L"),
	SND_SOC_DAPM_INPUT("LINE1R"),

I still don’t hear any sound anyway but I have to double check my physical connections now…

Hello!

If you have not defined widgets for ‘a Mic’, ‘a Headphone’, etc in the Tegra machine driver you need to add these to the tegra_machine_dapm_widgets structure. Then see if the original routing you posted works.

Regards,
Jon

Hi Jonathan,

My machine driver looks good, I’ve just added “b Headphone” there (I think it was the only missing widget).
It’s the codec driver side that I don’t understand at all.
If I use ‘a HPLOUT’ (as the original routing) it does not seems to work but if I use ‘a Playback’ ‘b Playback’ at least it seems that the audio path is complete, but I don’t understand where that ‘Playback’ comes from.
Also is this suggesting to use ‘a Capture’,‘b Capture’ instead of LINE1L,LINE2L?

This is my current machine driver widget structure:

static const struct snd_soc_dapm_widget tegra_machine_dapm_widgets[] = {
	SND_SOC_DAPM_SPK("x Int Spk", NULL),
	SND_SOC_DAPM_HP("x Headphone Jack", NULL),
	SND_SOC_DAPM_MIC("x Int Mic", NULL),
	SND_SOC_DAPM_MIC("x Mic Jack", NULL),

	SND_SOC_DAPM_SPK("d1 Headphone", NULL),
	SND_SOC_DAPM_SPK("d2 Headphone", NULL),

	SND_SOC_DAPM_HP("w Headphone", NULL),
	SND_SOC_DAPM_HP("x Headphone", NULL),
	SND_SOC_DAPM_HP("y Headphone", NULL),
	SND_SOC_DAPM_HP("z Headphone", NULL),
	SND_SOC_DAPM_HP("l Headphone", NULL),
	SND_SOC_DAPM_HP("m Headphone", NULL),
	SND_SOC_DAPM_HP("n Headphone", NULL),
	SND_SOC_DAPM_HP("o Headphone", NULL),
	SND_SOC_DAPM_HP("s Headphone", NULL),
	SND_SOC_DAPM_HP("a Headphone", NULL),
	SND_SOC_DAPM_HP("b Headphone", NULL),

	SND_SOC_DAPM_MIC("Int Mic", NULL),
	SND_SOC_DAPM_MIC("w Mic", NULL),
	SND_SOC_DAPM_MIC("x Mic", NULL),
	SND_SOC_DAPM_MIC("y Mic", NULL),
	SND_SOC_DAPM_MIC("z Mic", NULL),
	SND_SOC_DAPM_MIC("l Mic", NULL),
	SND_SOC_DAPM_MIC("m Mic", NULL),
	SND_SOC_DAPM_MIC("n Mic", NULL),
	SND_SOC_DAPM_MIC("o Mic", NULL),
	SND_SOC_DAPM_MIC("a Mic", NULL),
	SND_SOC_DAPM_MIC("b Mic", NULL),
	SND_SOC_DAPM_MIC("c Mic", NULL),
	SND_SOC_DAPM_MIC("d Mic", NULL),
	SND_SOC_DAPM_MIC("s Mic", NULL),
};

Quick update:

it’s the codec driver that is missing the ‘Playback’ route, because it is using ‘Left Playback’ and ‘Right Playback’ instead.
I’ve modified the codec driver to use ‘Playback’ and ‘Capture’ and now I can use the original routes in the tegra-sound node.