tlv320aic3x on TX2: only noise while playback

Hello,

I am trying to connect tlv320aic3104 audio codec on TX2 board.
Refer to https://devtalk.nvidia.com/default/topic/1027508/jetson-tx2/tlv320aic32x4-evaluation-board-with-tx2/, I add the device tree and set the registers for my tlv320aic3104 in tlv320aic3x.c.

According to the reference above, I adjust the following files:

  1. tegra_t186ref_mobile_rt565x.c
  2. tegra_asoc_utils_alt.c
  3. tegra186-quill-common.dtsi
  4. tegra186-super-module-e2614-p2597-1000-a00.dtsi
  5. tegra186-quill-power-tree-p3310-1000-a00-00.dtsi
  6. kernel configuration to enable tlv320aic3x

The audio codec is probed successful.
But there is only noise sound when I played wav files on the TX2 board.

Below is device tree for tlv320aic3x in tegra186-quill-common.dtsi:

tegra_sound: sound {
		compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x";
		nvidia,model = "tegra-snd-t186ref-mobile-rt565x";
		nvidia,num-codec-link = <13>;
		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 LINE1RP",	"z IN",
			"z LINE1RM",	"z IN",
			"z LINE1R",		"z IN",
			"z LINE1L",		"z IN",
			"z OUT",		"z HPLOUT",
			"z OUT",		"z HPLCOM",
			"z OUT",		"z RLOUT",
			"x Headphone",	"x OUT",
			"x IN",			"x Mic",
			"y Headphone",	"y OUT",
			"y IN",			"y Mic",
			"z Headphone",	"z OUT",
			"z IN",			"z Mic",
			"m Headphone",	"m OUT",
			"m IN",			"m Mic",
			"n Headphone",	"n OUT",
			"n IN",			"n Mic",
			"o Headphone",	"o OUT",
			"o IN",			"o Mic",
			"a IN",			"a Mic",
			"b IN",			"b Mic",
			"c IN",			"c Mic",
			"d IN",			"d Mic",
			"e Headphone",	"e OUT",
			"e IN",			"e Mic",
			"d1 Headphone",	"d1 OUT",
			"d2 Headphone",	"d2 OUT";


		nvidia,xbar = <&tegra_axbar>;

		rt565x_dai_link: nvidia,dai-link-1 {
			link-name = "rt565x-playback";
			cpu-dai = <&tegra_i2s3>;
			codec-dai = <&spdif_dit0>;
			cpu-dai-name = "I2S3";
			codec-dai-name = "dit-hifi";
			format = "i2s";
			bitclock-slave;
			frame-slave;
			bitclock-noninversion;
			frame-noninversion;
			bit-format = "s16_le";
			bclk_ratio = <0>;
			srate = <48000>;
			num-channel = <2>;
			ignore_suspend;
			name-prefix = "x";
			status = "disabled";
		};
		nvidia,dai-link-2 {
			link-name = "spdif-dit-1";
			cpu-dai = <&tegra_i2s2>;
			codec-dai = <&spdif_dit1>;
			cpu-dai-name = "I2S2";
			codec-dai-name = "dit-hifi";
			format = "i2s";
			bitclock-slave;
			frame-slave;
			bitclock-noninversion;
			frame-noninversion;
			bit-format = "s16_le";
			bclk_ratio = <1>;
			srate = <48000>;
			num-channel = <2>;
			ignore_suspend;
			name-prefix = "y";
			status = "disabled";
		};
		tlv320aic3104_dai_link: nvidia,dai-link-3 {
			link-name = "ti-playback";
			cpu-dai = <&tegra_i2s1>;
			codec-dai = <&aic3x>;
			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 = <2>;
			ignore_suspend;
			name-prefix = "z";
			status = "okay";
		};
		...

and

i2c@31c0000 {
		status = "okay";
		aic3x: tlv320aic3x-codec.6-0018@18 {
			compatible = "ti,tlv320aic3104";
			status = "okay";
			reg = <0x18>;
			gpio-reset = <&tegra_main_gpio TEGRA_MAIN_GPIO(J , 6) GPIO_ACTIVE_LOW>;
			clocks = <&tegra_car TEGRA186_CLK_AUD_MCLK>;
			clock-names = "mclk";

			AVDD-supply = <&vdd_3v3>;
			IOVDD-supply = <&vdd_1v8_ap>;
			DRVDD-supply = <&vdd_3v3>;
			DVDD-supply = <&vdd_1v8_ap>;
		};
	};

Here is the log when I tried to play a wav file:

nvidia@tegra-ubuntu:~$ aplay -D hw:tegrasndt186ref,0 my.wav
Playing WAVE 'my.wav' : Signed 16 bit Li[ 1866.129000] tegra-snd-t186ref-mobile-rt565x sound: tegra_t186ref_hw_params: set Playback
ttle Endian, Rate 48000 Hz, Mono[ 1866.140272] tegra-snd-t186ref-mobile-rt565x sound: [CTTest] rate = 48000 Hz, formats = 4, is_playback = 1, machine->rate_via_kcontrol=0

[ 1866.155128] tegra-snd-t186ref-mobile-rt565x sound: [CTTest] alt asoc set rate, argument, srate = 48000, mclk=0, clk_out_rate=0, data->mclk_scale=256
[ 1866.168609] tegra-snd-t186ref-mobile-rt565x sound: [CTTest] pll_a_out0 = 49152000 Hz, aud_mclk = 12288000 Hz, codec rate = 48000 Hz
[ 1866.180649] !!!!!!!!!!!!!!!!!!! aic3x_set_dai_sysclk : freq=24000000, AIC3X_CLKGEN_CTRL_REG=2!!!!!!!!!!!!!!!!!!
[ 1866.180649] 
[ 1866.180649] 
[ 1866.180649] 
[ 1866.195226] tegra-snd-t186ref-mobile-rt565x sound: [ti-playback] codec_dai clock set at id 160 
[ 1866.206745] !!!!!!!!!!!!!!!!!!! aic3x_hw_params !!!!!!!!!!!!!!!!!!
[ 1866.206745] 
[ 1866.206745] 
[ 1866.206745] 
[ 1866.217401] [CTTest-hw_param] AIC3X_ASD_INTF_CTRLB, width=16, data=0
[ 1866.217401] 
[ 1866.225391] [CTTest-hw_param] Use PLL
[ 1866.225391] 
[ 1866.230576] [CTTest-hw_param] AIC3X_GPIOB_REG=0
[ 1866.230576] 
[ 1866.236736] [CTTest-hw_param] AIC3X_CODEC_DATAPATH_REG=10
[ 1866.236736] 
[ 1866.243769] [CTTest-hw_param] AIC3X_SAMPLE_RATE_SEL_REG=0
[ 1866.243769] 
[ 1866.250879] [CTTest-hw_param] PLL: p=1, r=1, j=4, d=960, fsref=48000
[ 1866.250879] 
[ 1866.258731] [CTTest-hw_param] AIC3X_OVRF_STATUS_AND_PLLR_REG=1
[ 1866.258731] 
[ 1866.266058] [CTTest-hw_param] AIC3X_PLL_PROGB_REG=16
[ 1866.266058] 
[ 1866.272502] [CTTest-hw_param] AIC3X_PLL_PROGC_REG=15
[ 1866.272502] 
[ 1866.278943] [CTTest-hw_param] AIC3X_PLL_PROGD_REG=0
[ 1866.278943] 
[ 1866.285779] !!!!!!!!!!!!!!!!!!! aic3x_mute : No !!!!!!!!!!!!!!!!!!
[ 1866.285779] 
[ 1866.285779] 
[ 1866.285779] 
[ 1869.365602] !!!!!!!!!!!!!!!!!!! aic3x_mute : Yes !!!!!!!!!!!!!!!!!!
[ 1869.365602] 
[ 1869.365602] 
[ 1869.365602] 
nvidia@tegra-ubuntu:~$

What can I do to fix this?

Thanks,
C.T.

Hello!

I assume that you have followed all the steps that Igal mentioned here …

https://devtalk.nvidia.com/default/topic/1027508/jetson-tx2/tlv320aic32x4-evaluation-board-with-tx2/post/5275966/#5275966

If so, can you confirm what L4T release you are using?

Regards,
Jon

Hello Jon,

Thanks for your reply.
The L4T release I am using is R28.2.1.

Thanks,
C.T.

Hello!

Thanks. Can you confirm that you following all of Igal’s steps in the following post? He has detailed everything that needs to be done.

https://devtalk.nvidia.com/default/topic/1027508/jetson-tx2/tlv320aic32x4-evaluation-board-with-tx2/post/5275966/#5275966

Thanks!
Jon

Hello Jon,

The audio codec I used is tlv320aic3104 instead the one which Igal was using.
Moreover, there related source files are different.
(mine is tlv320aic3x.c and Igal’s is tlv320aic32x4.c)

Therefore, I could try my best to follow the Igal’s steps.

Below is the diff of my modifications:

  1. tlv320aic3x.c
diff --git a/kernel/kernel-4.4/sound/soc/codecs/tlv320aic3x.c b/kernel/kernel-4.4/sound/soc/codecs/tlv320aic3x.c
index a564759..baeda3e 100644
--- a/kernel/kernel-4.4/sound/soc/codecs/tlv320aic3x.c
+++ b/kernel/kernel-4.4/sound/soc/codecs/tlv320aic3x.c
@@ -50,6 +50,7 @@
 #include <sound/initval.h>
 #include <sound/tlv.h>
 #include <sound/tlv320aic3x.h>
+#include <dt-bindings/gpio/tegra186-gpio.h>
 
 #include "tlv320aic3x.h"
 
@@ -93,6 +94,8 @@ struct aic3x_priv {
 
 	/* Selects the micbias voltage */
 	enum aic3x_micbias_voltage micbias_vg;
+	/* Output Common-Mode Voltage */
+	u8 ocmv;
 };
 
 static const struct reg_default aic3x_reg[] = {
@@ -126,6 +129,16 @@ static const struct reg_default aic3x_reg[] = {
 	{ 108, 0x00 }, { 109, 0x00 },
 };
 
+static bool aic3x_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case AIC3X_RESET:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static const struct regmap_config aic3x_regmap = {
 	.reg_bits = 8,
 	.val_bits = 8,
@@ -133,6 +146,9 @@ static const struct regmap_config aic3x_regmap = {
 	.max_register = DAC_ICC_ADJ,
 	.reg_defaults = aic3x_reg,
 	.num_reg_defaults = ARRAY_SIZE(aic3x_reg),
+
+	.volatile_reg = aic3x_volatile_reg,
+
 	.cache_type = REGCACHE_RBTREE,
 };
 
@@ -157,7 +173,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
 	unsigned int mask = (1 << fls(max)) - 1;
 	unsigned int invert = mc->invert;
 	unsigned short val;
-	struct snd_soc_dapm_update update;
+	struct snd_soc_dapm_update update = {};
 	int connect, change;
 
 	val = (ucontrol->value.integer.value[0] & mask);
@@ -615,7 +631,7 @@ SOC_DAPM_ENUM("Route", aic3x_line2r_2_rdac_enum);
 
 static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
 	/* Left DAC to Left Outputs */
-	SND_SOC_DAPM_DAC("Left DAC", "Left Playback", DAC_PWR, 7, 0),
+	SND_SOC_DAPM_DAC("Left DAC", "Playback", DAC_PWR, 7, 0),
 	SND_SOC_DAPM_MUX("Left DAC Mux", SND_SOC_NOPM, 0, 0,
 			 &aic3x_left_dac_mux_controls),
 	SND_SOC_DAPM_MUX("Left HPCOM Mux", SND_SOC_NOPM, 0, 0,
@@ -625,7 +641,7 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
 	SND_SOC_DAPM_PGA("Left HP Com", HPLCOM_CTRL, 0, 0, NULL, 0),
 
 	/* Right DAC to Right Outputs */
-	SND_SOC_DAPM_DAC("Right DAC", "Right Playback", DAC_PWR, 6, 0),
+	SND_SOC_DAPM_DAC("Right DAC", "Playback", DAC_PWR, 6, 0),
 	SND_SOC_DAPM_MUX("Right DAC Mux", SND_SOC_NOPM, 0, 0,
 			 &aic3x_right_dac_mux_controls),
 	SND_SOC_DAPM_MUX("Right HPCOM Mux", SND_SOC_NOPM, 0, 0,
@@ -635,14 +651,14 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
 	SND_SOC_DAPM_PGA("Right HP Com", HPRCOM_CTRL, 0, 0, NULL, 0),
 
 	/* Inputs to Left ADC */
-	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0),
+	SND_SOC_DAPM_ADC("Left ADC", "Capture", LINE1L_2_LADC_CTRL, 2, 0),
 	SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0,
 			 &aic3x_left_line1l_mux_controls),
 	SND_SOC_DAPM_MUX("Left Line1R Mux", SND_SOC_NOPM, 0, 0,
 			 &aic3x_left_line1r_mux_controls),
 
 	/* Inputs to Right ADC */
-	SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
+	SND_SOC_DAPM_ADC("Right ADC", "Capture",
 			 LINE1R_2_RADC_CTRL, 2, 0),
 	SND_SOC_DAPM_MUX("Right Line1L Mux", SND_SOC_NOPM, 0, 0,
 			 &aic3x_right_line1l_mux_controls),
@@ -1020,6 +1036,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 			   struct snd_pcm_hw_params *params,
 			   struct snd_soc_dai *dai)
 {
+#if 1
 	struct snd_soc_codec *codec = dai->codec;
 	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
 	int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
@@ -1027,10 +1044,12 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 	u16 d, pll_d = 1;
 	int clk;
 	int width = aic3x->slot_width;
+	printk(KERN_ERR "!!!!!!!!!!!!!!!!!!! %s !!!!!!!!!!!!!!!!!!\n\n\n\n", __func__);
 
 	if (!width)
 		width = params_width(params);
 
+
 	/* select data word length */
 	data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
 	switch (width) {
@@ -1046,6 +1065,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 		data |= (0x03 << 4);
 		break;
 	}
+	printk(KERN_ERR "[CTTest-hw_param] AIC3X_ASD_INTF_CTRLB, width=%d, data=%d\n\n", width, data);
 	snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, data);
 
 	/* Fsref can be 44100 or 48000 */
@@ -1060,13 +1080,18 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 		}
 
 	if (bypass_pll) {
+		printk(KERN_ERR "Bypass PLL\n\n\n\n");
 		pll_q &= 0xf;
+		printk(KERN_ERR "[CTTest-hw_param] AIC3X_PLL_PROGA_REG=%d\n\n", pll_q << PLLQ_SHIFT);
+		printk(KERN_ERR "[CTTest-hw_param] AIC3X_GPIOB_REG=%d\n\n", CODEC_CLKIN_CLKDIV);
 		snd_soc_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
 		snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
 		/* disable PLL if it is bypassed */
 		snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLL_ENABLE, 0);
 
 	} else {
+		printk(KERN_ERR "[CTTest-hw_param] Use PLL\n\n");
+		printk(KERN_ERR "[CTTest-hw_param] AIC3X_GPIOB_REG=%d\n\n", CODEC_CLKIN_PLLDIV);
 		snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
 		/* enable PLL when it is used */
 		snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
@@ -1079,6 +1104,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 	data |= (fsref == 44100) ? FSREF_44100 : FSREF_48000;
 	if (params_rate(params) >= 64000)
 		data |= DUAL_RATE_MODE;
+	printk(KERN_ERR "[CTTest-hw_param] AIC3X_CODEC_DATAPATH_REG=%d\n\n", data);
 	snd_soc_write(codec, AIC3X_CODEC_DATAPATH_REG, data);
 
 	/* codec sample rate select */
@@ -1088,6 +1114,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 	data /= 5;
 	data -= 2;
 	data |= (data << 4);
+	printk(KERN_ERR "[CTTest-hw_param] AIC3X_SAMPLE_RATE_SEL_REG=%d\n\n", data);
 	snd_soc_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, data);
 
 	if (bypass_pll)
@@ -1157,7 +1184,12 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 	}
 
 found:
+	printk(KERN_ERR "[CTTest-hw_param] PLL: p=%d, r=%d, j=%d, d=%d, fsref=%d\n\n", pll_p, pll_r, pll_j, pll_d, fsref);
 	snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLLP_MASK, pll_p);
+	printk(KERN_ERR "[CTTest-hw_param] AIC3X_OVRF_STATUS_AND_PLLR_REG=%d\n\n", pll_r << PLLR_SHIFT);
+	printk(KERN_ERR "[CTTest-hw_param] AIC3X_PLL_PROGB_REG=%d\n\n", pll_j << PLLJ_SHIFT);
+	printk(KERN_ERR "[CTTest-hw_param] AIC3X_PLL_PROGC_REG=%d\n\n", (pll_d >> 6) << PLLD_MSB_SHIFT);
+	printk(KERN_ERR "[CTTest-hw_param] AIC3X_PLL_PROGD_REG=%d\n\n", (pll_d & 0x3F) << PLLD_LSB_SHIFT);
 	snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG,
 		      pll_r << PLLR_SHIFT);
 	snd_soc_write(codec, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT);
@@ -1165,7 +1197,7 @@ found:
 		      (pll_d >> 6) << PLLD_MSB_SHIFT);
 	snd_soc_write(codec, AIC3X_PLL_PROGD_REG,
 		      (pll_d & 0x3F) << PLLD_LSB_SHIFT);
-
+#endif
 	return 0;
 }
 
@@ -1188,7 +1220,7 @@ static int aic3x_prepare(struct snd_pcm_substream *substream,
 
 	/* Configure data delay */
 	snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
-
+	printk(KERN_ERR "[CTTest] AIC3X_ASD_INTF_CTRLC:%d\n\n", snd_soc_read(codec, AIC3X_ASD_INTF_CTRLC));
 	return 0;
 }
 
@@ -1197,7 +1229,7 @@ static int aic3x_mute(struct snd_soc_dai *dai, int mute)
 	struct snd_soc_codec *codec = dai->codec;
 	u8 ldac_reg = snd_soc_read(codec, LDAC_VOL) & ~MUTE_ON;
 	u8 rdac_reg = snd_soc_read(codec, RDAC_VOL) & ~MUTE_ON;
-
+	printk(KERN_ERR "!!!!!!!!!!!!!!!!!!! %s : %s !!!!!!!!!!!!!!!!!!\n\n\n\n", __func__, mute?"Yes":"No");
 	if (mute) {
 		snd_soc_write(codec, LDAC_VOL, ldac_reg | MUTE_ON);
 		snd_soc_write(codec, RDAC_VOL, rdac_reg | MUTE_ON);
@@ -1214,13 +1246,13 @@ static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 {
 	struct snd_soc_codec *codec = codec_dai->codec;
 	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
-
 	/* set clock on MCLK or GPIO2 or BCLK */
-	snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, PLLCLK_IN_MASK,
-				clk_id << PLLCLK_IN_SHIFT);
-	snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, CLKDIV_IN_MASK,
-				clk_id << CLKDIV_IN_SHIFT);
-
+	 snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, PLLCLK_IN_MASK,
+						clk_id << PLLCLK_IN_SHIFT);
+	 snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, CLKDIV_IN_MASK,
+						clk_id << CLKDIV_IN_SHIFT);
+	printk(KERN_ERR "!!!!!!!!!!!!!!!!!!! %s : freq=%d, AIC3X_CLKGEN_CTRL_REG=%d!!!!!!!!!!!!!!!!!!\n\n\n\n",
+		__func__, freq, snd_soc_read(codec, AIC3X_CLKGEN_CTRL_REG));
 	aic3x->sysclk = freq;
 	return 0;
 }
@@ -1231,7 +1263,7 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	struct snd_soc_codec *codec = codec_dai->codec;
 	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
 	u8 iface_areg, iface_breg;
-
+	printk(KERN_ERR "!!!!!!!!!!!!!!!!!!! %s !!!!!!!!!!!!!!!!!!\n\n\n\n", __func__);
 	iface_areg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f;
 	iface_breg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f;
 
@@ -1245,6 +1277,16 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		aic3x->master = 0;
 		iface_areg &= ~(BIT_CLK_MASTER | WORD_CLK_MASTER);
 		break;
+	case SND_SOC_DAIFMT_CBM_CFS:
+		aic3x->master = 1;
+		iface_areg |= BIT_CLK_MASTER;
+		iface_areg &= ~WORD_CLK_MASTER;
+		break;
+	case SND_SOC_DAIFMT_CBS_CFM:
+		aic3x->master = 1;
+		iface_areg |= WORD_CLK_MASTER;
+		iface_areg &= ~BIT_CLK_MASTER;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -1276,7 +1318,8 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	/* set iface */
 	snd_soc_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg);
 	snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg);
-
+	printk(KERN_ERR "[CTTest-fmt] AIC3X_ASD_INTF_CTRLA:%d\n\n", iface_areg);
+	printk(KERN_ERR "[CTTest-fmt] AIC3X_ASD_INTF_CTRLB:%d\n\n", iface_breg);
 	return 0;
 }
 
@@ -1380,6 +1423,12 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
 			snd_soc_write(codec, AIC3X_PLL_PROGC_REG, pll_c);
 			snd_soc_write(codec, AIC3X_PLL_PROGD_REG, pll_d);
 		}
+
+		/*
+		 * Delay is needed to reduce pop-noise after syncing back the
+		 * registers
+		 */
+		mdelay(50);
 	} else {
 		/*
 		 * Do soft reset to this codec instance in order to clear
@@ -1553,6 +1602,10 @@ static int aic3x_init(struct snd_soc_codec *codec)
 		break;
 	}
 
+	/*  Output common-mode voltage = 1.5 V */
+	snd_soc_update_bits(codec, HPOUT_SC, HPOUT_SC_OCMV_MASK,
+			    aic3x->ocmv << HPOUT_SC_OCMV_SHIFT);
+
 	return 0;
 }
 
@@ -1571,10 +1624,20 @@ static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x)
 
 static int aic3x_probe(struct snd_soc_codec *codec)
 {
+	printk(KERN_ERR "!!!!!!!!!!!!!!!!!!! %s !!!!!!!!!!!!!!!!!!\n\n\n\n", __func__);
+	
+
 	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
 	int ret, i;
+	u32 tmp_reg;
+
+	if (gpio_is_valid(aic3x->gpio_reset)) {
+		ndelay(10);
+		tmp_reg = gpio_get_value(aic3x->gpio_reset);
+		gpio_set_value(aic3x->gpio_reset, 1);
+		printk(KERN_ERR "[CTTest] gpio reset:%d to %d\n\n", tmp_reg, gpio_get_value(aic3x->gpio_reset));
+	}
 
-	INIT_LIST_HEAD(&aic3x->list);
 	aic3x->codec = codec;
 
 	for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) {
@@ -1586,7 +1649,7 @@ static int aic3x_probe(struct snd_soc_codec *codec)
 			dev_err(codec->dev,
 				"Failed to request regulator notifier: %d\n",
 				 ret);
-			goto err_notif;
+			return ret;
 		}
 	}
 
@@ -1640,27 +1703,73 @@ static int aic3x_probe(struct snd_soc_codec *codec)
 		 */
 		break;
 	}
+#if 1
+	snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, 0x0);
+
+	//Bit clock of data offset before the valid data
+	tmp_reg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLC);
+	snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, 0x1);
+	printk(KERN_ERR "[CTTest] AIC3X_ASD_INTF_CTRLC:%d to %d\n\n", tmp_reg, snd_soc_read(codec, AIC3X_ASD_INTF_CTRLC));
+
+	//CLK source settings for PLLCLK_IN and CLKDIV_IN
+	tmp_reg = snd_soc_read(codec, AIC3X_CLKGEN_CTRL_REG);
+	tmp_reg = (tmp_reg & ~0xff) | 0x02;
+	snd_soc_write(codec, AIC3X_CLKGEN_CTRL_REG, tmp_reg);
+	printk(KERN_ERR "[CTTest] AIC3X_CLKGEN_CTRL_REG:%d = %d\n\n", tmp_reg, snd_soc_read(codec, AIC3X_CLKGEN_CTRL_REG));
+
+#if 0
+	//PLL settings
+	tmp_reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
+	tmp_reg = (tmp_reg & (~0xff)) | 0x92;
+	snd_soc_write(codec, AIC3X_PLL_PROGA_REG, tmp_reg);
+	printk(KERN_ERR "[CTTest] AIC3X_PLL_PROGA_REG:%d = %d\n\n", tmp_reg, snd_soc_read(codec, AIC3X_PLL_PROGA_REG));
+	snd_soc_write(codec, AIC3X_PLL_PROGB_REG, 0x7 << 2);
+	printk(KERN_ERR "[CTTest] AIC3X_PLL_PROGB_REG:%d = %d\n\n", 0x7 << 2, snd_soc_read(codec, AIC3X_PLL_PROGB_REG));
+
+	snd_soc_write(codec, AIC3X_PLL_PROGC_REG, 0x52);
+	printk(KERN_ERR "[CTTest] AIC3X_PLL_PROGC_REG:%d = %d\n\n", 0x82, snd_soc_read(codec, AIC3X_PLL_PROGC_REG));
+	snd_soc_write(codec, AIC3X_PLL_PROGD_REG, 0x40);
+	printk(KERN_ERR "[CTTest] AIC3X_PLL_PROGD_REG:%d = %d\n\n", 0x10, snd_soc_read(codec, AIC3X_PLL_PROGD_REG));
+#endif
 
-	aic3x_add_widgets(codec);
+	//Connect DAC to output HPLOUT and HPLCOM
+	tmp_reg = snd_soc_read(codec, DACL1_2_HPLOUT_VOL);
+	snd_soc_update_bits(codec, DACL1_2_HPLOUT_VOL, ROUTE_ON, ROUTE_ON);
+	printk(KERN_ERR "[CTTest] reg47 DACL1_2_HPLOUT_VOL:%d to %d\n\n", tmp_reg, snd_soc_read(codec, DACL1_2_HPLOUT_VOL));
+	tmp_reg = snd_soc_read(codec, DACL1_2_HPLCOM_VOL);
+	snd_soc_update_bits(codec, DACL1_2_HPLCOM_VOL, ROUTE_ON, ROUTE_ON);
+	printk(KERN_ERR "[CTTest] reg54 DACL1_2_HPLCOM_VOL:%d to %d\n\n", tmp_reg, snd_soc_read(codec, DACL1_2_HPLCOM_VOL));
 
-	return 0;
+	//Umute
+	snd_soc_update_bits(codec, HPLOUT_CTRL, UNMUTE, UNMUTE);
+	printk(KERN_ERR "[CTTest] HPLOUT_CTRL:%d = %d\n\n", UNMUTE, snd_soc_read(codec, HPLOUT_CTRL));
+	snd_soc_update_bits(codec, HPLCOM_CTRL, UNMUTE, UNMUTE);
+	printk(KERN_ERR "[CTTest] HPLCOM_CTRL:%d = %d\n\n", UNMUTE, snd_soc_read(codec, HPLCOM_CTRL));
 
-err_notif:
-	while (i--)
-		regulator_unregister_notifier(aic3x->supplies[i].consumer,
-					      &aic3x->disable_nb[i].nb);
-	return ret;
-}
+	tmp_reg = snd_soc_read(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG);
+	//snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, 0x0);
+	printk(KERN_ERR "[CTTest] AIC3X_OVRF_STATUS_AND_PLLR_REG:%d = %d\n\n", tmp_reg, snd_soc_read(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG));
+	/* Route Left DAC to left channel input and
+	 * right DAC to right channel input */
+	//snd_soc_write(codec, AIC3X_CODEC_DATAPATH_REG, 0x8a);
+	printk(KERN_ERR "[CTTest] AIC3X_CODEC_DATAPATH_REG:%d = %d\n\n", 0x8a, snd_soc_read(codec, AIC3X_CODEC_DATAPATH_REG));
 
-static int aic3x_remove(struct snd_soc_codec *codec)
-{
-	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
-	int i;
+	//snd_soc_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, 0x0);
+	printk(KERN_ERR "[CTTest] AIC3X_SAMPLE_RATE_SEL_REG:%d = %d\n\n", 0x0, snd_soc_read(codec, AIC3X_SAMPLE_RATE_SEL_REG));
 
-	list_del(&aic3x->list);
-	for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
-		regulator_unregister_notifier(aic3x->supplies[i].consumer,
-					      &aic3x->disable_nb[i].nb);
+#endif
+
+	//DAC power setting
+	snd_soc_write(codec, DAC_PWR, 0xC0);
+	printk(KERN_ERR "[CTTest] DAC_PWR:%d = %d\n\n", 0xC0, snd_soc_read(codec, DAC_PWR));
+
+	//HPLOUT and HPLCOM power setting
+	snd_soc_update_bits(codec, HPLOUT_CTRL, HPLOUT_PWR_ON, HPLOUT_PWR_ON);
+	printk(KERN_ERR "[CTTest] HPLOUT_CTRL:%d = %d\n\n", HPLOUT_PWR_ON, snd_soc_read(codec, HPLOUT_CTRL));
+	snd_soc_update_bits(codec, HPLCOM_CTRL, HPLCOM_PWR_ON, HPLCOM_PWR_ON);
+	printk(KERN_ERR "[CTTest] HPLCOM_CTRL:%d = %d\n\n", HPLCOM_PWR_ON, snd_soc_read(codec, HPLCOM_CTRL));
+
+	aic3x_add_widgets(codec);
 
 	return 0;
 }
@@ -1669,7 +1778,6 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
 	.set_bias_level = aic3x_set_bias_level,
 	.idle_bias_off = true,
 	.probe = aic3x_probe,
-	.remove = aic3x_remove,
 	.controls = aic3x_snd_controls,
 	.num_controls = ARRAY_SIZE(aic3x_snd_controls),
 	.dapm_widgets = aic3x_dapm_widgets,
@@ -1678,6 +1786,44 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
 	.num_dapm_routes = ARRAY_SIZE(intercon),
 };
 
+static void aic3x_configure_ocmv(struct i2c_client *client)
+{
+	struct device_node *np = client->dev.of_node;
+	struct aic3x_priv *aic3x = i2c_get_clientdata(client);
+	u32 value;
+	int dvdd, avdd;
+
+	if (np && !of_property_read_u32(np, "ai3x-ocmv", &value)) {
+		/* OCMV setting is forced by DT */
+		if (value <= 3) {
+			aic3x->ocmv = value;
+			return;
+		}
+	}
+
+	dvdd = regulator_get_voltage(aic3x->supplies[1].consumer);
+	avdd = regulator_get_voltage(aic3x->supplies[2].consumer);
+
+	if (avdd > 3600000 || dvdd > 1950000) {
+		dev_warn(&client->dev,
+			 "Too high supply voltage(s) AVDD: %d, DVDD: %d\n",
+			 avdd, dvdd);
+	} else if (avdd == 3600000 && dvdd == 1950000) {
+		aic3x->ocmv = HPOUT_SC_OCMV_1_8V;
+	} else if (avdd > 3300000 && dvdd > 1800000) {
+		aic3x->ocmv = HPOUT_SC_OCMV_1_65V;
+	} else if (avdd > 3000000 && dvdd > 1650000) {
+		aic3x->ocmv = HPOUT_SC_OCMV_1_5V;
+	} else if (avdd >= 2700000 && dvdd >= 1525000) {
+		aic3x->ocmv = HPOUT_SC_OCMV_1_35V;
+	} else {
+		dev_warn(&client->dev,
+			 "Invalid supply voltage(s) AVDD: %d, DVDD: %d\n",
+			 avdd, dvdd);
+	}
+}
+
+
 /*
  * AIC3X 2 wire address can be up to 4 devices with device addresses
  * 0x18, 0x19, 0x1A, 0x1B
@@ -1717,6 +1863,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
 	int ret, i;
 	u32 value;
 
+	dev_err(&i2c->dev, "!!!!!!!!!!!!!! aic3x_i2c_probe !!!!!!!!!!!!!!!!!\n\n\n\n");
+
 	aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL);
 	if (!aic3x)
 		return -ENOMEM;
@@ -1740,11 +1888,18 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
 		if (!ai3x_setup)
 			return -ENOMEM;
 
-		ret = of_get_named_gpio(np, "gpio-reset", 0);
-		if (ret >= 0)
+		ret = of_get_named_gpio(np, "reset-gpios", 0);
+		if (ret >= 0) {
 			aic3x->gpio_reset = ret;
-		else
-			aic3x->gpio_reset = -1;
+		} else {
+			ret = of_get_named_gpio(np, "gpio-reset", 0);
+			if (ret > 0) {
+				dev_warn(&i2c->dev, "Using deprecated property \"gpio-reset\", please update your DT");
+				aic3x->gpio_reset = ret;
+			} else {
+				aic3x->gpio_reset = -1;
+			}
+		}
 
 		if (of_property_read_u32_array(np, "ai3x-gpio-func",
 					ai3x_setup->gpio_func, 2) >= 0) {
@@ -1795,6 +1950,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
 		goto err_gpio;
 	}
 
+	aic3x_configure_ocmv(i2c);
+
 	if (aic3x->model == AIC3X_MODEL_3007) {
 		ret = regmap_register_patch(aic3x->regmap, aic3007_class_d,
 					    ARRAY_SIZE(aic3007_class_d));
@@ -1809,6 +1966,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
 	if (ret != 0)
 		goto err_gpio;
 
+	INIT_LIST_HEAD(&aic3x->list);
 	list_add(&aic3x->list, &reset_list);
 
 	return 0;
@@ -1825,7 +1983,8 @@ static int aic3x_i2c_remove(struct i2c_client *client)
 {
 	struct aic3x_priv *aic3x = i2c_get_clientdata(client);
 
-	snd_soc_unregister_codec(&client->dev);
+	list_del(&aic3x->list);
+
 	if (gpio_is_valid(aic3x->gpio_reset) &&
 	    !aic3x_is_shared_reset(aic3x)) {
 		gpio_set_value(aic3x->gpio_reset, 0);
  1. tegra_t186ref_mobile_rt565x.c
diff --git a/kernel/t18x/sound/soc/tegra-alt/tegra_t186ref_mobile_rt565x.c b/kernel/t18x/sound/soc/tegra-alt/tegra_t186ref_mobile_rt565x.c
index ebd6702..8eada05 100644
--- a/kernel/t18x/sound/soc/tegra-alt/tegra_t186ref_mobile_rt565x.c
+++ b/kernel/t18x/sound/soc/tegra-alt/tegra_t186ref_mobile_rt565x.c
@@ -44,7 +44,7 @@
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include "../codecs/rt5659.h"
-
+#include "../codecs/tlv320aic3x.h"
 #include "tegra_asoc_utils_alt.h"
 #include "tegra_asoc_machine_alt.h"
 #include "tegra_asoc_machine_alt_t18x.h"
@@ -69,7 +69,7 @@
 		.channels_min = channels,		\
 		.channels_max = channels,		\
 	}
-
+ 
 struct tegra_t186ref {
 	struct tegra_asoc_platform_data *pdata;
 	struct tegra_asoc_audio_clock_info audio_clock;
@@ -132,7 +132,9 @@ static int tegra_t186ref_jack_notifier(struct notifier_block *self,
 	idx = tegra_machine_get_codec_dai_link_idx_t18x("rt565x-playback");
 	/* check if idx has valid number */
 	if (idx == -EINVAL)
+	{
 		return idx;
+	}
 
 	dev_dbg(card->dev, "jack status = %d", jack->status);
 	if (jack->status & (SND_JACK_BTN_0 | SND_JACK_BTN_1 |
@@ -277,6 +279,8 @@ static int tegra_t186ref_dai_init(struct snd_soc_pcm_runtime *rtd,
 	unsigned int idx, clk_out_rate;
 	int err, codec_rate, clk_rate;
 
+	dev_err(card->dev, "[CTTest] rate = %d Hz, formats = %llx, is_playback = %d, machine->rate_via_kcontrol=%d\n",
+		rate, formats, is_playback, machine->rate_via_kcontrol);
 	codec_rate = tegra_t186ref_srate_values[machine->rate_via_kcontrol];
 	clk_rate = (machine->rate_via_kcontrol) ? codec_rate : rate;
 
@@ -289,12 +293,13 @@ static int tegra_t186ref_dai_init(struct snd_soc_pcm_runtime *rtd,
 
 	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",
+	pr_debug("[CTTest] pll_a_out0 = %d Hz, aud_mclk = %d Hz, codec rate = %d Hz\n",
+		machine->audio_clock.set_mclk, clk_out_rate, clk_rate);
+	dev_err(card->dev, "[CTTest] 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("rt565x-playback");
+	idx = tegra_machine_get_codec_dai_link_idx_t18x("ti-playback");
 	/* check if idx has valid number */
 	if (idx != -EINVAL) {
 		dai_params =
@@ -306,83 +311,14 @@ static int tegra_t186ref_dai_init(struct snd_soc_pcm_runtime *rtd,
 
 		if (!machine->is_codec_dummy) {
 			err = snd_soc_dai_set_sysclk(card->rtd[idx].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");
+				dev_err(card->dev, "[ti-playback] codec_dai clock not set\n");
 				return err;
 			}
-		}
-	}
-
-	/* set clk rate for i2s3 dai link*/
-	idx = tegra_machine_get_codec_dai_link_idx_t18x("spdif-dit-2");
-	if (idx != -EINVAL) {
-		dai_params =
-		(struct snd_soc_pcm_stream *)card->rtd[idx].dai_link->params;
-
-		dai_params->rate_min = clk_rate;
-	}
-
-	idx = tegra_machine_get_codec_dai_link_idx_t18x("dspk-playback-r");
-	if (idx != -EINVAL) {
-		dai_params =
-		(struct snd_soc_pcm_stream *)card->rtd[idx].dai_link->params;
-
-		if (!machine->is_codec_dummy) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
-			err = snd_soc_dai_set_sysclk(card->rtd[idx].codec_dai,
-				0, clk_out_rate, SND_SOC_CLOCK_IN);
-#else
-			err = snd_soc_dai_set_sysclk(card->rtd[idx].codec_dai,
-				TAS2552_PDM_CLK_IVCLKIN, clk_out_rate,
-				SND_SOC_CLOCK_IN);
-#endif
-			if (err < 0) {
-				dev_err(card->dev, "codec_dai clock not set\n");
-				return err;
-			}
-		}
-	}
-
-	idx = tegra_machine_get_codec_dai_link_idx_t18x("dspk-playback-l");
-	if (idx != -EINVAL) {
-		dai_params =
-		(struct snd_soc_pcm_stream *)card->rtd[idx].dai_link->params;
-
-		if (!machine->is_codec_dummy) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
-			err = snd_soc_dai_set_sysclk(card->rtd[idx].codec_dai,
-				0, clk_out_rate, SND_SOC_CLOCK_IN);
-#else
-			err = snd_soc_dai_set_sysclk(card->rtd[idx].codec_dai,
-				TAS2552_PDM_CLK_IVCLKIN, clk_out_rate,
-				SND_SOC_CLOCK_IN);
-#endif
-			if (err < 0) {
-				dev_err(card->dev, "codec_dai clock not set\n");
-				return err;
-			}
-		}
-	}
-
-	idx = tegra_machine_get_codec_dai_link_idx_t18x("spdif-playback");
-	if ((idx != -EINVAL) && (clk_rate >= 32000)) {
-		dai_params =
-		(struct snd_soc_pcm_stream *)card->rtd[idx].dai_link->params;
-
-		if (is_playback) {
-			err = snd_soc_dai_set_sysclk(card->rtd[idx].cpu_dai, 0,
-						clk_rate, SND_SOC_CLOCK_OUT);
-			if (err < 0) {
-				dev_err(card->dev, "cpu_dai out clock not set\n");
-				return err;
-			}
-		} else {
-			err = snd_soc_dai_set_sysclk(card->rtd[idx].cpu_dai, 0,
-						clk_rate, SND_SOC_CLOCK_IN);
-			if (err < 0) {
-				dev_err(card->dev, "cpu_dai in clock not set\n");
-				return err;
+			else
+			{
+				dev_err(card->dev, "[ti-playback] codec_dai clock set at id %d \n", idx);
 			}
 		}
 	}
@@ -399,9 +335,15 @@ static int tegra_t186ref_hw_params(struct snd_pcm_substream *substream,
 	bool is_playback;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+	{
+		dev_err(card->dev, "tegra_t186ref_hw_params: set Playback\n");
 		is_playback = true;
+	}
 	else
+	{
+		dev_err(card->dev, "tegra_t186ref_hw_params: not set Playback\n");
 		is_playback = false;
+	}
 
 	err = tegra_t186ref_dai_init(rtd, params_rate(params),
 			params_channels(params),
@@ -460,16 +402,15 @@ static int tegra_t186ref_dspk_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_soc_card *card = rtd->card;
 	struct snd_soc_dapm_context *dapm = &card->dapm;
-	struct tegra_t186ref *machine = snd_soc_card_get_drvdata(card);
-	int err;
-
+	//struct tegra_t186ref *machine = snd_soc_card_get_drvdata(card);
+#if 0	//request by Jon
 	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");
-
+#endif
 	snd_soc_dapm_sync(dapm);
-	return err;
+	return 0;
 }
 
 static int tegra_t186ref_compr_set_params(struct snd_compr_stream *cstream)
@@ -513,20 +454,20 @@ static int tegra_t186ref_compr_set_params(struct snd_compr_stream *cstream)
 static int tegra_t186ref_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_soc_card *card = rtd->card;
-	struct tegra_t186ref *machine = snd_soc_card_get_drvdata(card);
+	//struct tegra_t186ref *machine = snd_soc_card_get_drvdata(card);
 	int err;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
 	struct snd_soc_codec *codec = codec_dai->codec;
 #endif
-
+#if 0	//request by Jon
 	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;
 	}
-
+#endif
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
 	snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
 		&tegra_t186ref_hp_jack);
@@ -708,6 +649,8 @@ static const struct snd_soc_dapm_widget tegra_t186ref_dapm_widgets[] = {
 	SND_SOC_DAPM_MIC("e Mic", NULL),
 	SND_SOC_DAPM_SPK("d1 Headphone", NULL),
 	SND_SOC_DAPM_SPK("d2 Headphone", NULL),
+	SND_SOC_DAPM_LINE(	"z IN", 			NULL),
+	SND_SOC_DAPM_LINE(	"z OUT", 			NULL),
 };
 
 static int tegra_t186ref_suspend_pre(struct snd_soc_card *card)
@@ -933,6 +876,8 @@ static void dai_link_setup(struct platform_device *pdev)
 			if (strstr(tegra_t186ref_codec_links[i].name,
 				"rt565x-playback"))
 				tegra_t186ref_codec_links[i].init = tegra_t186ref_init;
+			else if (strstr(tegra_t186ref_codec_links[i].name, "ti-playback"))
+				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;
@@ -1018,9 +963,9 @@ static int tegra_t186ref_driver_probe(struct platform_device *pdev)
 	struct snd_soc_card *card = &snd_soc_tegra_t186ref;
 	struct tegra_t186ref *machine;
 	struct tegra_asoc_platform_data *pdata = NULL;
+	int ret = 0;
 	struct snd_soc_codec *codec = NULL;
 	int idx = 0;
-	int ret = 0;
 	const char *codec_dai_name;
 
 	if (!np) {
@@ -1103,6 +1048,14 @@ static int tegra_t186ref_driver_probe(struct platform_device *pdev)
 	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",
@@ -1110,7 +1063,7 @@ static int tegra_t186ref_driver_probe(struct platform_device *pdev)
 		goto err_fini_utils;
 	}
 
-	idx = tegra_machine_get_codec_dai_link_idx_t18x("rt565x-playback");
+	idx = tegra_machine_get_codec_dai_link_idx_t18x("ti-playback");
 	/* check if idx has valid number */
 	if (idx == -EINVAL)
 		dev_warn(&pdev->dev, "codec link not defined - codec not part of sound card");
@@ -1120,6 +1073,7 @@ static int tegra_t186ref_driver_probe(struct platform_device *pdev)
 
 		dev_info(&pdev->dev,
 			"codec-dai \"%s\" registered\n", codec_dai_name);
+		#if 0
 		if (!strcmp("dit-hifi", codec_dai_name)) {
 			dev_info(&pdev->dev, "This is a dummy codec\n");
 			machine->is_codec_dummy = 1;
@@ -1129,8 +1083,10 @@ static int tegra_t186ref_driver_probe(struct platform_device *pdev)
 			/* setup for jack detection only in non-dummy case */
 			rt5659_set_jack_detect(codec, &tegra_t186ref_hp_jack);
 		}
+		#endif
 	}
 
+
 	return 0;
 
 err_fini_utils:
  1. tegra_asoc_utils_alt.c
diff --git a/kernel/kernel-4.4/sound/soc/tegra-alt/tegra_asoc_utils_alt.c b/kernel/kernel-4.4/sound/soc/tegra-alt/tegra_asoc_utils_alt.c
index 92418bc..9f20202 100644
--- a/kernel/kernel-4.4/sound/soc/tegra-alt/tegra_asoc_utils_alt.c
+++ b/kernel/kernel-4.4/sound/soc/tegra-alt/tegra_asoc_utils_alt.c
@@ -160,6 +160,8 @@ int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data,
 	bool clk_change;
 	int err;
 
+	dev_err(data->dev, "[CTTest] alt asoc set rate, argument, srate = %d, mclk=%d, clk_out_rate=%d, data->mclk_scale=%d\n",
+		srate, mclk, clk_out_rate, data->mclk_scale);
 	switch (srate) {
 	case 11025:
 	case 22050:
@@ -259,17 +261,19 @@ int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data,
 			return err;
 		}
 	}
-
+#if 0
 	err = clk_set_rate(data->clk_cdev1, clk_out_rate);
 	if (err) {
 		dev_err(data->dev, "Can't set clk_cdev1 rate: %d\n", err);
 		return err;
 	}
-
+#endif
 	data->set_baseclock = new_baseclock;
 	data->set_mclk = mclk;
 	data->set_clk_out_rate = clk_out_rate;
 
+	dev_err(data->dev, "[CTTest] alt asoc set rate, set_mclk=%d, set_clk_out_rate=%d, set_baseclock=%d\n",
+		mclk, clk_out_rate, new_baseclock);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_set_rate);
@@ -353,6 +357,7 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
 		return -EINVAL;
 
 	/* pll_p_out1 is not used for ahub for T210,T186 */
+	#if 0
 	if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210) {
 		data->clk_pll_p_out1 = clk_get_sys(NULL, "pll_p_out1");
 		if (IS_ERR(data->clk_pll_p_out1)) {
@@ -361,6 +366,14 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
 			goto err;
 		}
 	}
+	#else
+	data->clk_pll_p_out1 = tegra_alt_asoc_utils_get_clk(dev, false, "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;
+	} 
+	#endif
 
 	data->clk_m = tegra_alt_asoc_utils_get_clk(dev, false, "clk_m");
 	if (IS_ERR(data->clk_m)) {
@@ -418,6 +431,8 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
 #endif
 	}
 
+	dev_err(dev, "[CTTest] A-set clk, set_mclk=%d, clk_out_rate=%d\n",
+		data->set_mclk, data->clk_out_rate);
 	if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210) {
 		ret = tegra_alt_asoc_utils_set_rate(data, 48000,
 					256 * 48000, 256 * 48000);
@@ -425,6 +440,9 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
 			goto err_put_ahub;
 	}
 
+
+	dev_err(dev, "[CTTest] B-set clk, set_mclk=%d, clk_out_rate=%d\n",
+		data->set_mclk, data->clk_out_rate);
 #if !defined(CONFIG_ARCH_TEGRA_18x_SOC)
 	ret = clk_prepare_enable(data->clk_cdev1);
 	if (ret) {
@@ -445,7 +463,7 @@ err_put_pll_a_out0:
 err_put_pll_a:
 	tegra_alt_asoc_utils_clk_put(dev, data->clk_pll_a);
 err_put_pll_p_out1:
-	if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210)
+	//if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210)
 		clk_put(data->clk_pll_p_out1);
 err:
 	return ret;
@@ -467,13 +485,14 @@ int tegra_alt_asoc_utils_set_parent(struct tegra_asoc_audio_clock_info *data,
 			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);
+		ret = clk_set_rate(data->clk_cdev1, 12000000);
 		if (ret) {
 			dev_err(data->dev, "Can't set clk rate");
 			return ret;
@@ -533,7 +552,7 @@ void tegra_alt_asoc_utils_fini(struct tegra_asoc_audio_clock_info *data)
 	if (!IS_ERR(data->clk_pll_a))
 		tegra_alt_asoc_utils_clk_put(data->dev, data->clk_pll_a);
 
-	if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210)
+	//if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210)
 		if (!IS_ERR(data->clk_pll_p_out1))
 			clk_put(data->clk_pll_p_out1);
 }

Do I miss some settings?

Thanks,
C.T.

Hello Jon,

Is the noise issue due to the amixer settings?
Or which registers should I set for tlv320aic3104 audio codec?

Below is my amixer settings:

amixer -c tegrasndt186ref sset 'ADMAIF1 Mux' 'I2S1'
amixer -c tegrasndt186ref sset 'I2S1 Mux' 'ADMAIF1'
amixer -c tegrasndt186ref cset name='MVC1 Mute' 0
amixer -c tegrasndt186ref cset name='MVC2 Mute' 0
amixer -c tegrasndt186ref cset name='z HPCOM Playback Switch' 1
amixer -c tegrasndt186ref cset name='z Line Playback Switch' 1
amixer -c tegrasndt186ref cset name='z HP Playback Switch' 1
amixer -c tegrasndt186ref cset name='z PCM Playback Volume' 95%
amixer -c tegrasndt186ref cset name='z HP DAC Playback Volume' 95%
amixer -c tegrasndt186ref cset name='z HPCOM DAC Playback Volume' 80%
amixer -c tegrasndt186ref cset name='z Left HP Mixer DACR1 Playback Volume' 90%
amixer -c tegrasndt186ref cset name='z Left HPCOM Mixer DACR1 Playback Volume' 90%
aplay -D hw:tegrasndt186ref,0 my.wav

The my.wav is copied from “/usr/shared/sound/alsa/Front_Left.wav”.

Hello!

Thanks for the information. So I cannot help too much with the codec specific because I am not familiar with the TI codecs, but I can help with the Tegra aspects.

So to start with we need to get the codec clocking correct.

In the DT you have Tegra as the bit-clock and frame master and the codec MCLK as clocked by the Tegra AUD_MCLK. Can you confirm that the codec MCLK is connected to the Tegra AUD_MCLK on the 40-pin header?
If this is the case then we can greatly simplify the changes to the Tegra tegra_t186ref_mobile_rt565x.c driver.

In Igal’s case the AIC32x4 codec driver only supported a fixed MCLK (12MHz, 24MHz or 25MHz). The AIC3104 driver does not have this limitation and so we do not need to make all the changes to tegra_t186ref_mobile_rt565x.c to set the sysclk to 12MHz.

So please confirm you are using the AUD_MCLK to drive the codec clock.

Regards,
Jon

Hello Jon,

Thanks for your reply.

I don’t use the evaluation board with which TX2 board is used to connect but our own evaluation board.
The MCLK is connected to the Tegra AUD_MCLK directly on GPIO3_PJ.04.

I’ll rollback the modification which is followed by Igal’s steps.

If the HPLOUT and HPLCOM are the only audio output, what registers should be set?

Regards,
C.T.

Hello!

Sorry for the delay. To use the AUD_MCLK to drive the codecs MCLK, you should make the following changes to Tegra machine driver (based upon your DT changes) …

diff --git a/sound/soc/tegra-alt/tegra_t186ref_mobile_rt565x.c b/sound/soc/tegra-alt/tegra_t186ref_mobile_rt565x.c
index 2bbb22e60b21..f43c115459cd 100644
--- a/sound/soc/tegra-alt/tegra_t186ref_mobile_rt565x.c
+++ b/sound/soc/tegra-alt/tegra_t186ref_mobile_rt565x.c
@@ -43,6 +43,7 @@
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
+#include "../codecs/tlv320aic3x.h"
 #include "../codecs/rt5659.h"
 
 #include "tegra_asoc_utils_alt.h"
@@ -314,6 +315,25 @@ static int tegra_t186ref_dai_init(struct snd_soc_pcm_runtime *rtd,
                }
        }
 
+       idx = tegra_machine_get_codec_dai_link_idx_t18x("ti-playback");
+       /* 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;
+
+               err = snd_soc_dai_set_sysclk(card->rtd[idx].codec_dai,
+                                            CLKIN_MCLK, clk_out_rate,
+                                            SND_SOC_CLOCK_IN);
+               if (err < 0) {
+                       dev_err(card->dev, "codec_dai clock not set\n");
+                       return err;
+               }
+       }
+
        /* set clk rate for i2s3 dai link*/
        idx = tegra_machine_get_codec_dai_link_idx_t18x("spdif-dit-2");
        if (idx != -EINVAL) {
@@ -515,6 +535,22 @@ static int tegra_t186ref_compr_set_params(struct snd_compr_stream *cstream)
 }
 #endif
 
+static int tegra_t186ref_ti_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_soc_card *card = rtd->card;
+       struct tegra_t186ref *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;
+}
+
 static int tegra_t186ref_init(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_soc_card *card = rtd->card;
@@ -941,6 +977,9 @@ static void dai_link_setup(struct platform_device *pdev)
                                "rt565x-playback"))
                                tegra_t186ref_codec_links[i].init = tegra_t186ref_init;
                        else if (strstr(tegra_t186ref_codec_links[i].name,
+                               "ti-playback"))
+                               tegra_t186ref_codec_links[i].init = tegra_t186ref_ti_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,

Can you see if this helps?

Please note that while we can assist with customising the Tegra drivers and device-tree, configuring the actual audio codec is often the challenging part, because we are not familiar with these codecs. Typically, we recommend you contact the codec vendor for assistance with that, but we can take a look.

Regards,
Jon

Hi Jon,

Thanks for your help and sorry for the delay.
After rollback my code base and making the changes that you advised, there is no signal from Dout and MCLK when I try to play a wav file.

After applying the following changes, there are signals from Dout and MCLK when I try to play a wav file.

--- a/kernel/kernel-4.4/sound/soc/codecs/tlv320aic3x.c
+++ b/kernel/kernel-4.4/sound/soc/codecs/tlv320aic3x.c
@@ -615,7 +618,7 @@ SOC_DAPM_ENUM("Route", aic3x_line2r_2_rdac_enum);
 
 static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
 	/* Left DAC to Left Outputs */
-	SND_SOC_DAPM_DAC("Left DAC", "Left Playback", DAC_PWR, 7, 0),
+	SND_SOC_DAPM_DAC("Left DAC", "Playback", DAC_PWR, 7, 0),
 	SND_SOC_DAPM_MUX("Left DAC Mux", SND_SOC_NOPM, 0, 0,
 			 &aic3x_left_dac_mux_controls),
 	SND_SOC_DAPM_MUX("Left HPCOM Mux", SND_SOC_NOPM, 0, 0,
@@ -625,7 +628,7 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
 	SND_SOC_DAPM_PGA("Left HP Com", HPLCOM_CTRL, 0, 0, NULL, 0),
 
 	/* Right DAC to Right Outputs */
-	SND_SOC_DAPM_DAC("Right DAC", "Right Playback", DAC_PWR, 6, 0),
+	SND_SOC_DAPM_DAC("Right DAC", "Playback", DAC_PWR, 6, 0),
 	SND_SOC_DAPM_MUX("Right DAC Mux", SND_SOC_NOPM, 0, 0,
 			 &aic3x_right_dac_mux_controls),
 	SND_SOC_DAPM_MUX("Right HPCOM Mux", SND_SOC_NOPM, 0, 0,

The device only plays very small sound which is like a noise but not a real sound.

I know that some register settings should be asked from TI team, which I also did.
But there is still some details which would be needed a help from you.

Is there anything I should check for the settings of the data format if I use I2S mode for transferring digital data?

Regards,
C.T.

Hi Jon,

Why do you use “pll_a_out0” as the extern parent rather using “clk_m”?

Regards,
C.T.

Hello!

We use pll_a_out0 because this is scaled with the sampling rate. By using this clock the codec MCLK will be 256 * fs. For example, for 48kHz, this would yield a MCLK is 48000 * 256 = 12.288MHz. Hopefully, in this mode the AIC3104 driver will bypass the PLL (see aic3x_hw_params()).

The ‘clk_m’ on Tegra is a fixed frequency clock of 19.2MHz and so if you use this then the codec would need to use its PLL to generate its clocks and then the codec would need to be configured as the bitclock and frame master. In genernal it is simpler to use the pll_a_out0 clock to drive the codec MCLK.

Have you also verified that the bitclock and frame sync and toggling as expected? If you see all of theh I2S signals (SCLK, FS and DOUT) and AUD_MCLK toggling at the expected frequencies, then there is probably still some codec setting missing.

TI have a ‘programming made easy’ for these codec on their webpage and so this could be a good guide to see if the codec is configured as necessary …

http://www.ti.com/lit/pdf/slaa403

Please note that you can dump the codec registers while playback is active via the /sys/kerne/debug/regmap/ directory. There should be an entry for the codec under this directory.

Regards,
Jon

Hi Jon,

Thanks for your reply.
The webpage which you provided is easy to understand!
I am just doing the same thing, checking the register settings of audio codec.
And I change some register settings.

When I use the following command in console:

amixer -c tegrasndt186ref cset name='z HP DAC Playback Volume' 100%
amixer -c tegrasndt186ref cset name='z HPCOM DAC Playback Volume' 100%
aplay -D hw:tegrasndt186ref,0 -c 2 -F S16_LE -t wav /usr/share/sounds/alsa/Front_Left.wav

When I play the wav file, the sound sounds very small and like a electric current sound.
But there is no sound when I finish playing the wav file.

Is there anything I should configure?

Hello!

The Front_Left.wav should be a 48kHz sample rate. So I would expect that the …

  • MCLK is 12.228MHz (48000 * 256)
  • I2S bit-clock is 1.536MHz (48000 * 16 * 2)
  • I2S frame sync is 48kHz.

Can you confirm that the above signals are toggling at the above frequencies? If so and you see data on the I2S DOUT then it appears that the Tegra I2S interface is operating correctly.

If that is the case, then I would review the codec register settings and use the programming guide to figure out if the codec configuration needs correcting.

Regards,
Jon

Hi Jon,

I check the three signals …

  • MCLK is close to 12.228M Hz
  • I2S bit-clock is close to 1.536M Hz

But the I2S frame sync (WCLK) is only 24k Hz.
I also checked the register (page 0, register 2) which is set to 0x0.
Please refer to the TLV320AIC3x document: http://www.ti.com/lit/ds/symlink/tlv320aic3104.pdf

According to the I2S mode, I also set 1 bit-clock offset for data output.
And I did confirm this on oscilloscope.

So, I am confused why the frame sync is half of fsref?

Hello!

Can you check the frame sync width?

$ amixer -c tegrasndt186ref cget name='I2S1 fsync width'
numid=854,iface=MIXER,name='I2S1 fsync width'
  ; type=INTEGER,access=rw------,values=1,min=0,max=255,step=0
  : values=31

If you have 31 as indicated above, can you change to 15 (for 16 bits per channel) …

$ amixer -c tegrasndt186ref cset name='I2S1 fsync width' 15

Regards,
Jon

Hi Jon,

Thanks for your reply.

But I am not able to run the following command:

The result of the command is:

root@tegra-ubuntu:~# amixer -c tegrasndt186ref cget name='I2S1'
amixer: Cannot find the given element from control hw:1

Is there anything else I can do to check?

Regards,
C.T.

Hello!

The command should be …

root@tegra-ubuntu:~# amixer -c tegrasndt186ref cget name='I2S1 fsync width'

However, maybe this command is only available for rel32 and not rel28. Otherwise, you can check …

$ sudo grep "a0:" /sys/kernel/debug/regmap/tegra186-i2s.0/registers                                                                                                                                                      
a0: 1f000400

The upper byte tells you the frame-sync width. So above the 0x1f implies an fsync width of 32 bits. This is set in device-tree under the I2S node.

Regards,
Jon

Hi Jon,

Thanks for your reply.

Sorry, it was a copy-paste problem.
The command I tried is:

amixer -c tegrasndt186ref cget name='I2S1 fsync width'

There is no ‘tegra186-i2s.0’ in the path:

root@tegra-ubuntu:~# sudo grep "a0:" /sys/kernel/debug/regmap/tegra
tegra186-asrc/        tegra210-afc.5/       tegra210-i2s.4/
tegra186-dspk.0/      tegra210-amx.0/       tegra210-i2s.5/
tegra186-dspk.1/      tegra210-amx.1/       tegra210-mixer/
tegra210-admaif/      tegra210-amx.2/       tegra210-mvc.0/
tegra210-adx.0/       tegra210-amx.3/       tegra210-mvc.1/
tegra210-adx.1/       tegra210-dmic.0/      tegra210-ope.0/
tegra210-adx.2/       tegra210-dmic.1/      tegra210-ope.0-mbdrc/
tegra210-adx.3/       tegra210-dmic.2/      tegra210-ope.0-peq/
tegra210-afc.0/       tegra210-dmic.3/      tegra210-sfc.0/
tegra210-afc.1/       tegra210-i2s.0/       tegra210-sfc.1/
tegra210-afc.2/       tegra210-i2s.1/       tegra210-sfc.2/
tegra210-afc.3/       tegra210-i2s.2/       tegra210-sfc.3/
tegra210-afc.4/       tegra210-i2s.3/       tegra210-spdif/

I try the two of them:

  1. 6-0018 is my audio codec.
root@tegra-ubuntu:~# sudo grep "a0:" /sys/kernel/debug/regmap/6-0018/registers
root@tegra-ubuntu:~#

Nothing in this.

root@tegra-ubuntu:~# sudo grep "a0:" /sys/kernel/debug/regmap/tegra210-i2s.0/registers
a0: 1f000403
root@tegra-ubuntu:~#

In this case, the framsync width is 32 bits?
But why there is no ‘tegra186-i2s.0’?

Hello!

OK, yes I believe that this is something else that has changed from rel28 to rel32. However, tegra210-i2s.0 is what you want.

OK, so the frame-sync width is 32 bits. Please update the frame-sync width in the device-tree source for i2s@2901000 to be 15.

Regards,
Jon