Problem seeing i2c device on my carrier Please look over my dts changes

Hello!

I downloaded the latest pinmux spreadsheet for TX2, I configured the AUD_MCLK as follows …

Customer Usage: AUD_MCLK
Pin Direction: Output
Req. Initial State: N/A

In the pinmux.dtsi file generated I see …

aud_mclk_pj4 {
				nvidia,pins = "aud_mclk_pj4";
				nvidia,function = "aud";
				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
				nvidia,tristate = <TEGRA_PIN_ENABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
				nvidia,lpdr = <TEGRA_PIN_DISABLE>;
			};

Which looks good. So I don’t see any bugs with the spreadsheet itself. I ran this through the pinmux-dts2cfg.py and get …

$ python pinmux-dts2cfg.py --pinmux addr_info.txt gpio_addr_info.txt por_val.txt --mandatory_pinmux_file mandatory_pinmux.txt tegra18x-jetson-tx2i-tx2-4gb-template-pinmux.dtsi tegra18x-jetson-tx2i-tx2-4gb-template-gpio-default.dtsi 1.0 | grep aud_mclk
pinmux.0x02431020 = 0x00000400; # aud_mclk_pj4: aud, tristate-disable, input-disable, lpdr-disable

Which also looks good. However, I am using the latest version of the pinmux-dts2cfg.py. Which version of L4T are you using? Maybe there is a problem with this script.

With regard to the clock what do you currently have in DT for the sgtl5000 codec? Previously you had the following …

+        /* i2c@31e0000 { */
+       i2c@31e0000 {
+                status = "okay";
+
+               sgtl5000: sgtl5000@0a {
+                       compatible = "fsl,sgtl5000";
+                       reg = <0x0a>;
+                       clocks = <&extern1>;  /* maybe extern1 ? */
+                       micbias-resistor-k-ohms = <2>;
+                       micbias-voltage-m-volts = <3000>;
+                       VDDA-supply = <&vdd_3v3>;
+                       VDDIO-supply = <&vdd_1v8_ap>;
+                       status = "okay";
+               };
+        };

This will definitely not work, because you have defined ‘extern1’ as a essentially a pseudo clock. In other words, it does not actually turn on any clock. What you want is …

+        /* i2c@31e0000 { */
+       i2c@31e0000 {
+                status = "okay";
+
+               sgtl5000: sgtl5000@0a {
+                       compatible = "fsl,sgtl5000";
+                       reg = <0x0a>;
+                       clocks = <&tegra_car TEGRA186_CLK_AUD_MCLK>;
+                       micbias-resistor-k-ohms = <2>;
+                       micbias-voltage-m-volts = <3000>;
+                       VDDA-supply = <&vdd_3v3>;
+                       VDDIO-supply = <&vdd_1v8_ap>;
+                       status = "okay";
+               };
+        };

Also when the codec is active you can check if the clock is enabled and what frequency it is operating at by …

$ sudo grep "clock\|aud_mclk" /sys/kernel/debug/clk/clk_summary
   clock                                           enable_cnt  prepare_cnt        rate    req_rate   accuracy   phase
             aud_mclk                                       1            1    12287998    12288000          0 0

Regards,
Jon

Thanks that should be a great help! It looks like I got part of that fixed - probably when looking at the recent Xavier or other sgtl5000 posts.

i2c@31e0000 {
		sgtl5000: sgtl5000.8-000a@0a {
		       compatible = "fsl,sgtl5000";
		       reg = <0x0a>;
		       clocks = <&tegra_car TEGRA186_CLK_AUD_MCLK>;
		       clock-names = "extern1";
                       micbias-resistor-k-ohms = <2>;
                       micbias-voltage-m-volts = <3000>;
                       VDDA-supply = <&vdd_3v3>;
                       VDDIO-supply = <&vdd_1v8_ap>;
                       status = "okay";
               };
        };

I have changed the sgtl5000.8-000a@0a to sgtl5000@0a and remove the clock-names line and to see
if that improves the result.
Then I am get this in the clk_summary: aud_mclk 0 0 19200000 19200000
So it appears I have an error. I will go over your example and my code again to see if I can find the error. As always, if you have suggestions they will be very welcome. I’ll put all my in a new post soon.

Here my current code It appears I followed a couple discussions you were involved with about xavier and sgtl5000 as this has some similarities with the code found there
(

and

)

It seems like a good idea to keep the clock-name lines as they are.

Do you see any reason this would be leaving the clock disabled?
(I’m looking for my sgtl5000.8-000 reference elsewhere to see if that was actually correct.)

NOTE: I just noticed that the area I built in was missing the changes to the driver - I will try again and post the patch for the driver if adding that into the kernel does not fix it.

i2c@31e0000 {
		sgtl5000: sgtl5000@0a { /* was sgtl5000.8-000a@0a */
		       compatible = "fsl,sgtl5000";
		       reg = <0x0a>;
		       clocks = <&tegra_car TEGRA186_CLK_AUD_MCLK>;
		       clock-names = "extern1";
                       micbias-resistor-k-ohms = <2>;
                       micbias-voltage-m-volts = <3000>;
                       VDDA-supply = <&vdd_3v3>;
                       VDDIO-supply = <&vdd_1v8_ap>;
                       status = "okay";
               };
        };

tegra_sound: sound {
		compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x";
		nvidia,model = "tegra-snd-t186ref-mobile-rt565x";
		nvidia,num-codec-link = <12>;
		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 =
			"x Headphone",		"x HP_OUT",
			"x MIC_IN",		"x Mic",
			"y Headphone",		"y HP_OUT",
			"y MIC_IN",		"y Mic",
			"z Headphone",		"z OUT",
			"z IN",			"z Mic",

So I tried a number of changes to tegra_machine_driver_mobile.c trying to get the clock initialized without success.
It makes me wonder if this is because the clock is not running so the sgtl5000 cannot acknowledge the
initial query on i2c and is not detected so the clock initialization is never run.

Any suggestions on where I went wrong?
Any suggestions on how to initialize the clock before the first i2c access to the sgtl5000?

Thanks for your comments!

/* in tegra_machine_driver_mobile.c */
static int tegra_machine_dai_init(struct
...

       rtd = snd_soc_get_pcm_runtime(card, "sgtl5000-playback");
       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;

	       dev_err(card->dev, "Preparing to set extern1 for SGTL5000 sysclk\n");
               /*so I can see if this is getting called. */

	       /* err = snd_soc_dai_set_sysclk(rtd->codec_dai, SGTL5000_SYSCLK, 12288000,
				     SND_SOC_CLOCK_IN);  I believe this is the psuedo-clock
                                                         so not needed, right? */

	       /* err = tegra_alt_asoc_utils_set_extern_parent(&machine->audio_clock,
	           "pll_a_out0");  The xavier example used this */

               /* so I tried thhis... */
               err = tegra_alt_asoc_utils_set_extern_parent(&machine->audio_clock,
                                                    "extern1");
               if (err < 0) {
                       /* dev_err(card->dev, "codec_dai clock not set\n"); */
		       dev_err(card->dev, "failed to set extern1 for SGTL5000 sysclk\n");
                       return err;
               }
       }
...

static int tegra_machine_sgtl5000_init(struct snd_soc_pcm_runtime *rtd)
{
       struct tegra_machine *machine = snd_soc_card_get_drvdata(rtd->card);
       int err;

       err = tegra_alt_asoc_utils_set_extern_parent(&machine->audio_clock,
                                                    "extern1");
       if (err < 0) {
               dev_err(rtd->card->dev, "Failed to set extern clk parent for SGTL5000\n");
               return err;
       }

       return 0;
}

Hello!

The clock-name in the sgtl5000 device-tree binding can be whatever you want as the sgtl5000 driver does not look for a particular name. Looking at the sgtl5000 driver (sound/soc/codecs/sgtl5000.c) the clock should be enabled during the sgtl5000_i2c_probe() function. So if it is not enabled, then I would check to see if the sgtl5000_i2c_probe() function is failing in some way. Do you see any error messages on boot?

Regards,
Jon

Last night I took a quick look and did not see an error message - but it is possible I missed it. I will look at sgtl5000_i2c_probe and see if I can do something there. The sgtl500 will need at least 8 clock cycles to prepare before the i2c probe. Thanks for the quick reply.

I added some messages to sgtl5000_i2c_probe() and to the init code in tegra-alt/machine/tegra_machine_driver_mobile.c (tegra_machine_dai_init() tegra_machine_sgtl5000_init fepi_init and etc.) The rest of the code remains as shown in previous posts.

I need to learn more about using regmap in drivers. I am reading “Linux Driver Development for Embedded Processors” but the section on i2c does not cover any sound driver examples or regmap in any depth.

Thanks for the comments so far. Hope you can give me a few more pointers as I work my way through this.

At this point there appears to be some set up for tegra-alt/machine/tegra_machine_driver_mobile.c that has been missed. (you may have better insight)

Anyway this is what I have now, lets start with the relevant part of sgtl5000_i2c_probe():

dev_err(&client->dev, "sgtl5000_i2c_probe: at 4\n");
	sgtl5000->regmap = devm_regmap_init_i2c(client, &sgtl5000_regmap);
	if (IS_ERR(sgtl5000->regmap)) {
		ret = PTR_ERR(sgtl5000->regmap);
		dev_err(&client->dev, "Failed to allocate regmap: %d\n", ret);
		goto disable_regs;
	}
	
       	dev_err(&client->dev, "sgtl5000_i2c_probe: at 5\n");
	sgtl5000->mclk = devm_clk_get(&client->dev, NULL);
	if (IS_ERR(sgtl5000->mclk)) {
		ret = PTR_ERR(sgtl5000->mclk);
		dev_err(&client->dev, "Failed to get mclock: %d\n", ret);
		/* Defer the probe to see if the clk will be provided later */
		if (ret == -ENOENT)
			ret = -EPROBE_DEFER;
		goto disable_regs;
	}

       	dev_err(&client->dev, "sgtl5000_i2c_probe: at 6\n");
	ret = clk_prepare_enable(sgtl5000->mclk);
	if (ret) {
		dev_err(&client->dev, "Error enabling clock %d\n", ret);
		goto disable_regs;
	}

	/* Need 8 clocks before I2C accesses */
	udelay(1);

       	dev_err(&client->dev, "sgtl5000_i2c_probe: at 7\n");
	/* read chip information */
	ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, &reg);
	if (ret) {
		dev_err(&client->dev, "Error reading chip id %d\n", ret);
		goto disable_clk;
	}

       	dev_err(&client->dev, "sgtl5000_i2c_probe: at 8\n");
	if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
	    SGTL5000_PARTID_PART_ID) {
		dev_err(&client->dev,
			"Device with ID register %x is not a sgtl5000\n", reg);
		ret = -ENODEV;
		goto disable_clk;
	}

Here is the dmesg log. Note the error after message 7. The clock does not get set up but the clock code at 5 does not emit an error. I believe I should have seen messages I added from tegra_machine_driver_mobile.c (in either dai_init() or sgtl5000_init() or both around message 4.
Note that the messages I added in the tegra-alt/machine area never are emitted by dmesg.

Am I misunderstanding what I think I should see?

What did I miss setting up to cause the sgtl5000 driver to not use the correct sgtl5000 i2c interface?

Here are the lines of interest from dmesg:

[    4.277465] trusty_ipc virtio0: is online
[    4.278767] mmc0: SDHCI controller on 3460000.sdhci [3460000.sdhci] using ADM
A 64-bit with 64 bit addr
[    4.278929] usbcore: registered new interface driver snd-usb-audio
[    4.279445] sgtl5000 8-000a: Entered sgtl5000_i2c_probe
[    4.279448] sgtl5000 8-000a: sgtl5000_i2c_probe: at 2
[    4.279450] sgtl5000 8-000a: sgtl5000_i2c_probe: at 3
[    4.279739] sgtl5000 8-000a: sgtl5000_i2c_probe: at 4
[    4.279781] sgtl5000 8-000a: sgtl5000_i2c_probe: at 5
[    4.280056] sgtl5000 8-000a: sgtl5000_i2c_probe: at 6
[    4.280131] sgtl5000 8-000a: sgtl5000_i2c_probe: at 7
[    4.280197] tegra-i2c 31e0000.i2c: no acknowledge from address 0xa
[    4.280219] sgtl5000 8-000a: Error reading chip id -121
[    4.280354] sgtl5000: probe of 8-000a failed with error -121
[    4.290723] mmc1: SDHCI controller on 3440000.sdhci [3440000.sdhci] using ADMA 64-bit with 64 bit addr
[    4.294829] gpio tegra-gpio wake71 for gpio=125(P:5)

And in case something is misconfigured, here is my kernel config (just the sound codec part)

#
# SoC Audio for Freescale CPUs
#

#
# Common SoC Audio options for Freescale CPUs:
#
# CONFIG_SND_SOC_FSL_ASRC is not set
# CONFIG_SND_SOC_FSL_SAI is not set
# CONFIG_SND_SOC_FSL_SSI is not set
# CONFIG_SND_SOC_FSL_SPDIF is not set
# CONFIG_SND_SOC_FSL_ESAI is not set
# CONFIG_SND_SOC_IMX_AUDMUX is not set
# CONFIG_SND_SOC_IMG is not set
# CONFIG_SND_SOC_TEGRA is not set
# CONFIG_SND_SOC_XTFPGA_I2S is not set
CONFIG_SND_SOC_I2C_AND_SPI=y

#
# CODEC drivers
#
# CONFIG_SND_SOC_AC97_CODEC is not set
# CONFIG_SND_SOC_AD193X_I2C is not set
# CONFIG_SND_SOC_ADAU1701 is not set
# CONFIG_SND_SOC_ADAU7002 is not set
# CONFIG_SND_SOC_AK4104 is not set
# CONFIG_SND_SOC_AK4554 is not set
# CONFIG_SND_SOC_AK4613 is not set
# CONFIG_SND_SOC_AK4642 is not set
# CONFIG_SND_SOC_AK5386 is not set
# CONFIG_SND_SOC_ALC5623 is not set
# CONFIG_SND_SOC_BT_SCO is not set
# CONFIG_SND_SOC_CS35L32 is not set
# CONFIG_SND_SOC_CS35L33 is not set
# CONFIG_SND_SOC_CS42L51_I2C is not set
# CONFIG_SND_SOC_CS42L52 is not set
# CONFIG_SND_SOC_CS42L56 is not set
# CONFIG_SND_SOC_CS42L73 is not set
# CONFIG_SND_SOC_CS4265 is not set
# CONFIG_SND_SOC_CS4270 is not set
# CONFIG_SND_SOC_CS4271_I2C is not set
# CONFIG_SND_SOC_CS4271_SPI is not set
# CONFIG_SND_SOC_CS42XX8_I2C is not set
# CONFIG_SND_SOC_CS4349 is not set
CONFIG_SND_SOC_CS53L30=y
# CONFIG_SND_SOC_ES8328 is not set
# CONFIG_SND_SOC_GTM601 is not set
# CONFIG_SND_SOC_INNO_RK3036 is not set
# CONFIG_SND_SOC_MAX98504 is not set
# CONFIG_SND_SOC_MAX9860 is not set
# CONFIG_SND_SOC_PCM1681 is not set
# CONFIG_SND_SOC_PCM179X_I2C is not set
# CONFIG_SND_SOC_PCM179X_SPI is not set
# CONFIG_SND_SOC_PCM3168A_I2C is not set
# CONFIG_SND_SOC_PCM3168A_SPI is not set
# CONFIG_SND_SOC_PCM512x_I2C is not set
# CONFIG_SND_SOC_PCM512x_SPI is not set
CONFIG_SND_SOC_RL6231=y
CONFIG_SND_SOC_RL6231=y
# CONFIG_SND_SOC_RT5616 is not set
# CONFIG_SND_SOC_RT5631 is not set
CONFIG_SND_SOC_RT5640=y
CONFIG_SND_SOC_RT5659=y
# CONFIG_SND_SOC_RT5677_SPI is not set
CONFIG_SND_SOC_SGTL5000=y
# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set
CONFIG_SND_SOC_SPDIF=y
# CONFIG_SND_SOC_SSM2602_SPI is not set
# CONFIG_SND_SOC_SSM2602_I2C is not set
# CONFIG_SND_SOC_SSM4567 is not set
# CONFIG_SND_SOC_STA32X is not set
# CONFIG_SND_SOC_STA350 is not set
# CONFIG_SND_SOC_STI_SAS is not set
CONFIG_SND_SOC_TAS2552=y
# CONFIG_SND_SOC_TAS5086 is not set
# CONFIG_SND_SOC_TAS571X is not set
# CONFIG_SND_SOC_TAS5720 is not set
# CONFIG_SND_SOC_TFA9879 is not set
# CONFIG_SND_SOC_TLV320AIC23_I2C is not set
# CONFIG_SND_SOC_TLV320AIC23_SPI is not set
# CONFIG_SND_SOC_TLV320AIC31XX is not set
# CONFIG_SND_SOC_TLV320AIC3X is not set
# CONFIG_SND_SOC_TS3A227E is not set
# CONFIG_SND_SOC_WM8510 is not set
# CONFIG_SND_SOC_WM8523 is not set
# CONFIG_SND_SOC_WM8580 is not set
# CONFIG_SND_SOC_WM8711 is not set
# CONFIG_SND_SOC_WM8728 is not set
# CONFIG_SND_SOC_WM8731 is not set
# CONFIG_SND_SOC_WM8737 is not set
# CONFIG_SND_SOC_WM8741 is not set
# CONFIG_SND_SOC_WM8750 is not set
# CONFIG_SND_SOC_WM8753 is not set
# CONFIG_SND_SOC_WM8770 is not set
# CONFIG_SND_SOC_WM8776 is not set
# CONFIG_SND_SOC_WM8804_I2C is not set
# CONFIG_SND_SOC_WM8804_SPI is not set
# CONFIG_SND_SOC_WM8903 is not set
# CONFIG_SND_SOC_WM8960 is not set
# CONFIG_SND_SOC_WM8962 is not set
# CONFIG_SND_SOC_WM8974 is not set
# CONFIG_SND_SOC_WM8978 is not set
# CONFIG_SND_SOC_WM8985 is not set
# CONFIG_SND_SOC_NAU8810 is not set
# CONFIG_SND_SOC_TPA6130A2 is not set
# CONFIG_SND_SOC_TAS2557_STEREO is not set
CONFIG_SND_SIMPLE_CARD_UTILS=y
CONFIG_SND_SIMPLE_CARD=y
# CONFIG_SND_SIMPLE_SCU_CARD is not set
CONFIG_SND_SOC_TEGRA_ALT_186=y
CONFIG_SND_SOC_TEGRA186_DSPK_ALT=y
CONFIG_SND_SOC_TEGRA186_ASRC_ALT=y
CONFIG_SND_SOC_TEGRA186_ARAD_ALT=y
# CONFIG_SND_SOC_TEGRA_ALT_FORCE_CARD_REG is not set
CONFIG_SND_SOC_TEGRA_T186REF_P4573_ALT=y
# CONFIG_SND_SOC_TEGRA_T186REF_AUTO_ALT is not set
CONFIG_TEGRA186_ASRC_INT_CLEAR_WAR=y
CONFIG_SND_SOC_TEGRA_ALT=y
CONFIG_SND_SOC_TEGRA_ALT_210=y
CONFIG_SND_SOC_TEGRA210_XBAR_ALT=y
CONFIG_SND_SOC_TEGRA210_ADMAIF_ALT=y
CONFIG_SND_SOC_TEGRA210_I2S_ALT=y
CONFIG_SND_SOC_TEGRA210_DMIC_ALT=y
CONFIG_SND_SOC_TEGRA210_AMX_ALT=y
CONFIG_SND_SOC_TEGRA210_ADX_ALT=y
CONFIG_SND_SOC_TEGRA210_MIXER_ALT=y
CONFIG_SND_SOC_TEGRA210_SFC_ALT=y
CONFIG_SND_SOC_TEGRA210_AFC_ALT=y
CONFIG_SND_SOC_TEGRA210_MVC_ALT=y
# CONFIG_SND_SOC_TEGRA210_IQC_ALT is not set
CONFIG_SND_SOC_TEGRA210_OPE_ALT=y
CONFIG_SND_SOC_TEGRA_ASOC_MACHINE_ALT=y
CONFIG_SND_SOC_TEGRA_T210REF_MOBILE_ALT=y
# CONFIG_SND_SOC_TEGRA_T210REF_ALT is not set
CONFIG_SND_SOC_TEGRA_T186REF_ALT=y
CONFIG_SND_SOC_TEGRA_T186REF_MOBILE_ALT=y
# CONFIG_SND_SOC_TEGRA_T210REF_P2382_ALT is not set
# CONFIG_SOUND_PRIME is not set
CONFIG_AC97_BUS=m

#

Hello!

So the probe for the codec is failing and in this case once it fails to read the chip ID, then it will goto ‘disable_clk’ and turn off the clock again. So you may see the clock turn on for a short period and then turn off again. For debugging you could comment out the call to clk_disable_unprepare() and then after boot it should be on …

disable_clk:
        //clk_disable_unprepare(sgtl5000->mclk);

If you dump the clocks what do you see if the default parent for the aud_mclk? It should be pll_a_out0 and be something like …

$ sudo cat /sys/kernel/debug/clk/clk_summary
...
    pll_a_vco                                               1            1   258000000   258000000          0 0  
    *[        default_freq                                       0]
       pll_a                                                1            1   245759960   245760000          0 0  
       *[        default_freq                                       0]
          pll_a_out0                                        3            3    49151992    49152000          0 0  
          *[        default_freq                                       0]
             aud_mclk                                       1            1    12287998    12288000          0 0

Regards,
Jon

From a previous response, I can see that the aud_mclk is running at 19.2MHz in your case and so must be configured so that the clk_m is the parent. This should be fine as the SGTL5000 can support a MCLK between 8 and 27MHz. So try removing the call to disable the aud_mclk from the SGTL5000 driver and see if it remains on and you see a clock on the pin.

Regards,
Jon

Thanks Jon, That is a great suggestion. I will report a result tomorrow.

Regards,
Curtis

Hi Jon,
Commenting the clock disable gave a clock with a parent m_clk. That allowed me to get a response from the sgtl5000 with i2cdetect. Looks like that and whatever other fixes we’ve made in the recent past has the clock working. I discovered that the chip which was supposed to be at 0a was actually at 2a. Fixing the address then gave me the following:

pll_a_vco                                               1            1   258000000   258000000          0 0  
    *[        default_freq                                       0]
       pll_a                                                1            1   270950390   270950400          0 0  
       *[        default_freq                                       0]
          pll_a_out0                                        1            1    45158398    45158400          0 0  
          *[        default_freq                                       0]
             aud_mclk                                       1            1    11289599    11289599          0 0  
             *[        default_freq                                       0]

The driver does not produce any sound but does correctly access the chip. I will have some time tomorrow to see if I can figure out what is failing. (I will post the dmesg log in case you have tips to speed me up.

Thanks so much for the help! I was unfamiliar with this and would have had difficulty getting this far.
I suspect the rest is at least a little easier. I will reread some of the other conversations you have had about this chip. I suspect the answer is there if I look. (Note that the driver keeps trying to set up the clock I’ve named extern1 even though I am now set at the correct clock rate. I must be missing something that will let it move on to do the rest of the initialization. Might just be because I need to clean up a bit after the various edits.)
I’ll post the final driver changes after they are working so the complete reference will be in one place.

Best regards,
Curtis

[    4.239562] trusty_ipc virtio0: is online
[    4.241060] usbcore: registered new interface driver snd-usb-audio
[    4.241500] sgtl5000 8-002a: Entered sgtl5000_i2c_probe
[    4.241502] sgtl5000 8-002a: sgtl5000_i2c_probe: at 2
[    4.241504] sgtl5000 8-002a: sgtl5000_i2c_probe: at 3
[    4.241747] sgtl5000 8-002a: sgtl5000_i2c_probe: at 4
[    4.241787] sgtl5000 8-002a: sgtl5000_i2c_probe: at 5
[    4.242096] sgtl5000 8-002a: sgtl5000_i2c_probe: at 6
[    4.242171] sgtl5000 8-002a: sgtl5000_i2c_probe: at 7
[    4.242356] sgtl5000 8-002a: sgtl5000_i2c_probe: at 8
[    4.242358] sgtl5000 8-002a: sgtl5000_i2c_probe: at 9
[    4.242360] sgtl5000 8-002a: sgtl5000 revision 0x11
[    4.242362] sgtl5000 8-002a: sgtl5000_i2c_probe: at 10
[    4.242511] sgtl5000 8-002a: sgtl5000_i2c_probe: at 11
[    4.242512] sgtl5000 8-002a: sgtl5000_i2c_probe: at 12
[    4.242837] sgtl5000 8-002a: Using internal LDO instead of VDDD: check ER1
[    4.242984] sgtl5000 8-002a: sgtl5000_i2c_probe: at 14 
[    4.243369] mmc1: SDHCI controller on 3440000.sdhci [3440000.sdhci] using ADMA 64-bit with 64 bit addr
[    4.255543] gpio tegra-gpio wake71 for gpio=125(P:5)
[    4.255597] mmc2: SDHCI controller on 3400000.sdhci [3400000.sdhci] using ADMA 64-bit with 64 bit addr
[    4.255655] input: tegra-hda HDMI/DP,pcm=3 as /devices/3510000.hda/sound/card0/input0
[    4.255787] input: tegra-hda HDMI/DP,pcm=7 as /devices/3510000.hda/sound/card0/input1
[    4.284959] mmc0: mmc_decode_ext_csd: CMDQ supported: depth: 31, cmdq_support: 1
[    4.299077] mmc0: periodic cache flush enabled
[    4.299091] mmc0: new HS400 Enhanced strobe MMC card at address 0001
[    4.299593] mmcblk0: mmc0:0001 032G34 29.1 GiB 
[    4.303842] mmcblk0boot0: mmc0:0001 032G34 partition 1 8.00 MiB
[    4.304059] mmcblk0boot1: mmc0:0001 032G34 partition 2 8.00 MiB
[    4.304284] mmcblk0rpmb: mmc0:0001 032G34 partition 3 4.00 MiB
[    4.307595]  mmcblk0: p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 p18 p19 p20 p21 p22 p23 p24 p25 p26 p27 p28 p29 p30 p31
[    4.355647] OPE platform probe
[    4.355761] OPE platform probe successful
[    4.437275] tegra-asoc: sound: ADMAIF1 <-> ADMAIF1 mapping ok
[    4.437450] tegra-asoc: sound: ADMAIF2 <-> ADMAIF2 mapping ok
[    4.437577] tegra-asoc: sound: ADMAIF3 <-> ADMAIF3 mapping ok
[    4.437698] tegra-asoc: sound: ADMAIF4 <-> ADMAIF4 mapping ok
[    4.437786] tegra-asoc: sound: ADMAIF5 <-> ADMAIF5 mapping ok
[    4.437873] tegra-asoc: sound: ADMAIF6 <-> ADMAIF6 mapping ok
[    4.437961] tegra-asoc: sound: ADMAIF7 <-> ADMAIF7 mapping ok
[    4.438045] tegra-asoc: sound: ADMAIF8 <-> ADMAIF8 mapping ok
[    4.438134] tegra-asoc: sound: ADMAIF9 <-> ADMAIF9 mapping ok
[    4.438221] tegra-asoc: sound: ADMAIF10 <-> ADMAIF10 mapping ok
[    4.438306] tegra-asoc: sound: ADMAIF11 <-> ADMAIF11 mapping ok
[    4.438395] tegra-asoc: sound: ADMAIF12 <-> ADMAIF12 mapping ok
[    4.438481] tegra-asoc: sound: ADMAIF13 <-> ADMAIF13 mapping ok
[    4.438577] tegra-asoc: sound: ADMAIF14 <-> ADMAIF14 mapping ok
[    4.438718] tegra-asoc: sound: ADMAIF15 <-> ADMAIF15 mapping ok
[    4.438804] tegra-asoc: sound: ADMAIF16 <-> ADMAIF16 mapping ok
[    4.438890] tegra-asoc: sound: ADMAIF17 <-> ADMAIF17 mapping ok
[    4.438979] tegra-asoc: sound: ADMAIF18 <-> ADMAIF18 mapping ok
[    4.439065] tegra-asoc: sound: ADMAIF19 <-> ADMAIF19 mapping ok
[    4.439154] tegra-asoc: sound: ADMAIF20 <-> ADMAIF20 mapping ok
[    4.442165] tegra-asoc: sound: Entered tegra_machine_sgtl5000_init
[    4.451126] tegra-asoc: sound: ASoC: no source widget found for x HP_OUT
[    4.451133] tegra-asoc: sound: ASoC: Failed to add route x HP_OUT -> direct -> x Headphone
[    4.451162] tegra-asoc: sound: ASoC: no sink widget found for x MIC_IN
[    4.451165] tegra-asoc: sound: ASoC: Failed to add route x Mic -> direct -> x MIC_IN
[    4.469027] u32 classifier
[    4.469030]     Actions configured
[    4.469110] Initializing XFRM netlink socket
...
[    4.560075] ALSA device list:
[    4.560079]   #0: tegra-hda at 0x3518000 irq 383
[    4.560081]   #1: tegra-snd-t186ref-mobile-rt565x
[    4.932572] tegra-pcie 10003000.pcie-controller: link 2 down, retrying
...
[  248.003598] IPv6: ADDRCONF(NETDEV_UP): usb0: link is not ready
[  249.045811] tegra-asoc: sound: Entered tegra_machine_dai_init
[  249.057041] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  249.064864] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  250.057633] tegra-asoc: sound: Entered tegra_machine_dai_init
[  250.063848] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  250.071480] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  251.043500] tegra-asoc: sound: Entered tegra_machine_dai_init
[  251.049618] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  251.057057] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  251.601599] tegra-asoc: sound: Entered tegra_machine_dai_init
[  251.607500] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  251.614920] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  252.451381] tegra-asoc: sound: Entered tegra_machine_dai_init
[  252.457708] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  252.466823] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  253.734501] tegra-asoc: sound: Entered tegra_machine_dai_init
[  253.740994] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  253.748502] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  254.280337] tegra-asoc: sound: Entered tegra_machine_dai_init
[  254.286223] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  254.293635] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  255.139510] tegra-asoc: sound: Entered tegra_machine_dai_init
[  255.145673] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  255.153256] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  256.434070] tegra-asoc: sound: Entered tegra_machine_dai_init
[  256.440092] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  256.447529] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  257.044258] tegra-asoc: sound: Entered tegra_machine_dai_init
[  257.050168] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  257.057595] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  323.937029] tegradc 15210000.nvdisplay: blank - powerdown
[  323.994490] extcon-disp-state external-connection:disp-state: cable 47 state 0
[  323.994493] Extcon AUX1(HDMI) disable
[  324.016435] tegra_nvdisp_handle_pd_disable: Powergated Head2 pd
[  324.016519] tegra_nvdisp_handle_pd_disable: Powergated Head1 pd
[  324.017146] tegra_nvdisp_handle_pd_disable: Powergated Head0 pd
[  324.143267] tegradc 15210000.nvdisplay: blank - powerdown
[  324.143288] tegradc 15210000.nvdisplay: unblank
[  324.144416] tegra_nvdisp_handle_pd_enable: Unpowergated Head0 pd
[  324.144519] tegra_nvdisp_handle_pd_enable: Unpowergated Head1 pd
[  324.144613] tegra_nvdisp_handle_pd_enable: Unpowergated Head2 pd
[  324.146046] Parent Clock set for DC plld2
[  324.148833] tegradc 15210000.nvdisplay: hdmi: tmds rate:148500K prod-setting:prod_c_hdmi_111m_223m
[  324.150071] tegradc 15210000.nvdisplay: hdmi: get RGB quant from EDID.
[  324.150078] tegradc 15210000.nvdisplay: hdmi: get YCC quant from EDID.
[  324.189504] extcon-disp-state external-connection:disp-state: cable 47 state 1
[  324.189506] Extcon AUX1(HDMI) enable
[  324.189556] tegradc 15210000.nvdisplay: unblank
[  328.827931] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[  328.827942] Bluetooth: BNEP socket layer initialized
[  329.195327] tegradc 15210000.nvdisplay: unblank
[  329.311681] tegra-asoc: sound: Entered tegra_machine_dai_init
[  329.317869] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  329.325513] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  330.370707] tegra-asoc: sound: Entered tegra_machine_dai_init
[  330.376637] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  330.385355] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  331.361207] tegra-asoc: sound: Entered tegra_machine_dai_init
[  331.367108] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  331.374519] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  331.922964] tegra-asoc: sound: Entered tegra_machine_dai_init
[  331.929040] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  331.936557] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  332.767095] tegra-asoc: sound: Entered tegra_machine_dai_init
[  332.773278] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  332.781261] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  334.062322] tegra-asoc: sound: Entered tegra_machine_dai_init
[  334.068808] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  334.076936] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  334.603696] tegra-asoc: sound: Entered tegra_machine_dai_init
[  334.609603] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  334.617129] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  335.466490] tegra-asoc: sound: Entered tegra_machine_dai_init
[  335.473006] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  335.480503] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  336.756914] tegra-asoc: sound: Entered tegra_machine_dai_init
[  336.762827] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  336.770351] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  337.359523] tegra-asoc: sound: Entered tegra_machine_dai_init
[  337.365420] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  337.372853] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  474.389655] tegra-asoc: sound: Entered tegra_machine_dai_init
[  474.395677] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  474.404543] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  616.387680] usb 2-2.2: new SuperSpeed USB device number 4 using tegra-xusb
[  616.409974] usb 2-2.2: New USB device found, idVendor=154b, idProduct=00ed
[  616.410004] usb 2-2.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3

Hello!

Thanks for the update. I see you have already made the necessary changes to set the codec sysclk frequency in the machine driver. So hopefully now we should be able to get this working.

Regards,
Jon

Hi Jon, I’m hopping you can weigh in on the current state of my audio effort.

I was having the typical issue where dmesg reports something like:

 tegra-asoc: sound: ASoC: no source widget found for  ...

I did an earlier version of the following in the dts file and finally got HP_OUT to connect.
The problem here is that we do not actually have the headphone out connected in our implementation.

I have been searching all the ASoC docs I can find and the sgtl5000 related kernel code but still seem to be failing to get the needed connections.

Can you give me any guidance or examples?

Our carrier has the sgtl5000 connections: Line out (right and left in a single jack, Line in (R & L in a jack), and monophonic mic jack on the mic input. headphones are not connected.

My last rev of code gave the following in dmesg

[    3.978801] sgtl5000 8-000a: sgtl5000_i2c_probe: at 9
[    3.978803] sgtl5000 8-000a: sgtl5000 revision 0x11
[    3.978804] sgtl5000 8-000a: sgtl5000_i2c_probe: at 10
[    3.978955] sgtl5000 8-000a: sgtl5000_i2c_probe: at 11
[    3.978956] sgtl5000 8-000a: sgtl5000_i2c_probe: at 12
[    3.979280] sgtl5000 8-000a: Using internal LDO instead of VDDD: check ER1
[    3.979427] sgtl5000 8-000a: sgtl5000_i2c_probe: at 14 
[    3.995742] input: tegra-hda HDMI/DP,pcm=3 as /devices/3510000.hda/sound/card
0/input0
[    3.995981] input: tegra-hda HDMI/DP,pcm=7 as /devices/3510000.hda/sound/card
0/input1

...

[    4.038396] tegra-asoc: sound: Property 'name-prefix' missing or invalid
[    4.039112] tegra-asoc: sound: ASoC: no source widget found for Lineout jack
[    4.039117] tegra-asoc: sound: ASoC: Failed to add route Lineout jack -> direct -> LINE_OUT
[    4.039121] tegra-asoc: sound: ASoC: no source widget found for Linein jack
[    4.039124] tegra-asoc: sound: ASoC: Failed to add route Linein jack -> direct -> LINE_IN
[    4.039128] tegra-asoc: sound: ASoC: no source widget found for Mic jack
[    4.039131] tegra-asoc: sound: ASoC: Failed to add route Mic jack -> direct -> MIC_IN

You can see that I have some of the names in the wrong place.
I am just deploying a fix with the following code:

i2c@31e0000 {
                sgtl5000: sgtl5000a@0a { /* had sgtl5000.8-000a@0a */
                       compatible = "fsl,sgtl5000";
                       reg = <0x0a>;
                       clocks = <&tegra_car TEGRA186_CLK_AUD_MCLK>;
                       clock-names = "extern1";
                       micbias-resistor-k-ohms = <2>;
                       micbias-voltage-m-volts = <3000>;
                       VDDA-supply = <&vdd_3v3>;
                       VDDIO-supply = <&vdd_1v8_ap>;
                       status = "okay";
               };

       tegra_sound: sound {
                compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x";
                nvidia,model = "tegra-snd-t186ref-mobile-rt565x";
                nvidia,num-codec-link = <1>; /* 12 */
                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 =
                        "Headphone",            "HP_OUT",
                        "MIC_IN",               "Mic",
                        "Lineout",              "LINE_OUT",
                        "LINE_IN",              "Linein",

                nvidia,xbar = <&tegra_axbar>;

                rt565x_dai_link: nvidia,dai-link-1 {
                        link-name = "sgtl5000-playback";
                        /* link-name = "spdif-dit-1"; */
                        cpu-dai = <&tegra_i2s2>;
                        codec-dai = <&sgtl5000>;
                        /* codec-dai = <&spdif_dit1>; */
                        cpu-dai-name = "I2S2";
                        codec-dai-name = "sgtl5000";
                        format = "i2s";  /* "dsp_a";  or  "i2s"; ? */
                        bitclock-slave;
                        frame-slave;
                        bitclock-noninversion;
                        frame-noninversion;
                        bit-format = "s16_le";
                        bclk_ratio = <1>;
                        srate = <48000>;
                        num-channel = <2>;
                        ignore_suspend;
                        status = "okay";
                };

What names should I use in the audio-routing section for Linein and Lineout? I seem to be
drawing a blank.

As with all engineering projects I was scheduled to be done yesterday so any other tips to speed up the final development would be greatly appreciated.

Note that the LINE_IN and LINE_OUT designations were found in the imx related sgtl5000 kernel documentation and may or may not be right for tegra ASoC but even if that is right I am not certain what the other end of those connections should be named. I seem to find few if any references in other sgtl5000 docs.

Result from the code above failed. I just realized that I should have used a name prefix as it is complaining (but still tries to work).

I expected to see the HP_OUT connection succeed but see no messages on that one. The others all fail.
and call the connections “Linout jack” “Linein jack” and Mic jack" so I am changing the one side of the definitions to match that. In the meantime any comments are very welcome!

Thanks!

Hello!

In your device-tree you want to have something like the followings …

nvidia,audio-routing =
                        "x MIC_IN",               "x Mic",
                        "x ADC",                  "x Mic Bias",
                        "x Lineout",              "x LINE_OUT",
                        "x LINE_IN",              "x Linein",

                nvidia,xbar = <&tegra_axbar>;

                rt565x_dai_link: nvidia,dai-link-1 {
                        link-name = "sgtl5000-playback";
                        /* link-name = "spdif-dit-1"; */
                        cpu-dai = <&tegra_i2s2>;
                        codec-dai = <&sgtl5000>;
                        /* codec-dai = <&spdif_dit1>; */
                        cpu-dai-name = "I2S2";
                        codec-dai-name = "sgtl5000";
                        format = "i2s";  /* "dsp_a";  or  "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 = "x";
                        status = "okay";
                };

Note make sure you have the ‘name-prefix’ property under the DAI link node. The following widgets need to be specified in the Tegra machine driver …

“x Mic”
“x Lineout”
“x Linein”

The ‘x Mic’ already exists, but the others don’t and need to be added like follows …

diff --git a/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c b/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c
index fbca4699d353..f70d50b6722c 100644
--- a/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c
+++ b/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c
@@ -150,6 +150,8 @@ static const struct snd_soc_dapm_widget tegra_machine_dapm_widgets[] = {
        SND_SOC_DAPM_HP("o Headphone", NULL),
        SND_SOC_DAPM_HP("s Headphone", NULL),
 
+       SND_SOC_DAPM_HP("x Lineout", NULL),
+
        SND_SOC_DAPM_MIC("Int Mic", NULL),
        SND_SOC_DAPM_MIC("w Mic", NULL),
        SND_SOC_DAPM_MIC("x Mic", NULL),
@@ -164,6 +166,8 @@ static const struct snd_soc_dapm_widget tegra_machine_dapm_widgets[] = {
        SND_SOC_DAPM_MIC("c Mic", NULL),
        SND_SOC_DAPM_MIC("d Mic", NULL),
        SND_SOC_DAPM_MIC("s Mic", NULL),
+
+       SND_SOC_DAPM_HP("x Linein", NULL),
 };

Let me know if this helps.

Regards,
Jon

Hi Jon,

I tried a few variations before I got all the widget related error to go away. I am still a little confused by way some of the widgets are declared. I see SND_SOC_DAPM_HP, SND_SOC_DAPM_LINE, SND_SOC_DAPM_SPK, SND_SOC_DAPM_PCM and others in various drivers. I have had the widget related messages disappear when I define Lineout with either “_HP” or “_LINE” I’ve looked at quite a bit of ASoC related documentation and knowing what to use is still eluding me. Can you point me to anything that might help or share any insights?

So now I am left looping through the initialization routines. My error that is causing this is still eluding me. Can you share any pointer that will help?

Dmesg log (Note that I have added a kernel message reporting success but that the initialization is
still entered over and over)

[    4.809242] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[    4.809334] sgtl5000 8-000a: Entered sgtl5000_i2c_probe
[    4.809338] sgtl5000 8-000a: sgtl5000_i2c_probe: at 2
[    4.809340] sgtl5000 8-000a: sgtl5000_i2c_probe: at 3
[    4.809644] sgtl5000 8-000a: sgtl5000_i2c_probe: at 4
[    4.809723] sgtl5000 8-000a: sgtl5000_i2c_probe: at 5
[    4.810075] sgtl5000 8-000a: sgtl5000_i2c_probe: at 6
[    4.810168] sgtl5000 8-000a: sgtl5000_i2c_probe: at 7
[    4.810369] sgtl5000 8-000a: sgtl5000_i2c_probe: at 8
[    4.810372] sgtl5000 8-000a: sgtl5000_i2c_probe: at 9
[    4.810376] sgtl5000 8-000a: sgtl5000 revision 0x11
[    4.810378] sgtl5000 8-000a: sgtl5000_i2c_probe: at 10
[    4.810545] sgtl5000 8-000a: sgtl5000_i2c_probe: at 11
[    4.810548] sgtl5000 8-000a: sgtl5000_i2c_probe: at 12
[    4.810922] sgtl5000 8-000a: Using internal LDO instead of VDDD: check ER1
[    4.811104] sgtl5000 8-000a: sgtl5000_i2c_probe: at 14 
[    4.815841]  sda: sda1
[    4.816408] sd 0:0:0:0: [sda] Attached SCSI disk
[    4.823480] random: crng init done

...

[    4.944141] extcon-disp-state external-connection:disp-state: cable 47 state 1
[    4.944144] Extcon AUX1(HDMI) enable
[    5.009832] tegra-asoc: sound: ADMAIF1 <-> ADMAIF1 mapping ok
[    5.009926] tegra-asoc: sound: ADMAIF2 <-> ADMAIF2 mapping ok
[    5.010009] tegra-asoc: sound: ADMAIF3 <-> ADMAIF3 mapping ok
[    5.010099] tegra-asoc: sound: ADMAIF4 <-> ADMAIF4 mapping ok
[    5.010180] tegra-asoc: sound: ADMAIF5 <-> ADMAIF5 mapping ok
[    5.010273] tegra-asoc: sound: ADMAIF6 <-> ADMAIF6 mapping ok
[    5.010356] tegra-asoc: sound: ADMAIF7 <-> ADMAIF7 mapping ok
[    5.010437] tegra-asoc: sound: ADMAIF8 <-> ADMAIF8 mapping ok
[    5.010545] tegra-asoc: sound: ADMAIF9 <-> ADMAIF9 mapping ok
[    5.010653] tegra-asoc: sound: ADMAIF10 <-> ADMAIF10 mapping ok
[    5.010743] tegra-asoc: sound: ADMAIF11 <-> ADMAIF11 mapping ok
[    5.010862] tegra-asoc: sound: ADMAIF12 <-> ADMAIF12 mapping ok
[    5.010951] tegra-asoc: sound: ADMAIF13 <-> ADMAIF13 mapping ok
[    5.011039] tegra-asoc: sound: ADMAIF14 <-> ADMAIF14 mapping ok
[    5.011129] tegra-asoc: sound: ADMAIF15 <-> ADMAIF15 mapping ok
[    5.011217] tegra-asoc: sound: ADMAIF16 <-> ADMAIF16 mapping ok
[    5.011304] tegra-asoc: sound: ADMAIF17 <-> ADMAIF17 mapping ok
[    5.011419] tegra-asoc: sound: ADMAIF18 <-> ADMAIF18 mapping ok
[    5.011529] tegra-asoc: sound: ADMAIF19 <-> ADMAIF19 mapping ok
[    5.011630] tegra-asoc: sound: ADMAIF20 <-> ADMAIF20 mapping ok
[    5.014673] tegra-asoc: sound: Entered tegra_machine_sgtl5000_init
[    5.035429] input: tegra-snd-t186ref-mobile-rt565x Headset Jack as /devices/sound/sound/card1/input2
[    5.036490] u32 classifier
[    5.036493]     Actions configured
[    5.036581] Initializing XFRM netlink socket
[    5.038381] NET: Registered protocol family 10

...

[  404.036839] tegra-xudc-new 3550000.xudc: ep 8 (type: 2, dir: out) enabled
[  404.036947] IPv6: ADDRCONF(NETDEV_CHANGE): usb0: link becomes ready
[  404.930256] tegra-asoc: sound: Entered tegra_machine_dai_init
[  404.936100] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  404.943929] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  404.954821] tegra-asoc: sound: SUCCESS setting extern1 for SGTL5000 sysclk out=11289600 in=0
[  405.876428] tegra-asoc: sound: Entered tegra_machine_dai_init
[  405.882319] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  405.889815] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  405.897195] tegra-asoc: sound: SUCCESS setting extern1 for SGTL5000 sysclk out=11289600 in=0
[  406.419856] tegra-asoc: sound: Entered tegra_machine_dai_init
[  406.425778] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
[  406.433195] tegra-asoc: sound: Preparing to set extern1 for SGTL5000 sysclk
[  406.440369] tegra-asoc: sound: SUCCESS setting extern1 for SGTL5000 sysclk out=11289600 in=0
[  407.259523] tegra-asoc: sound: Entered tegra_machine_dai_init
[  407.265370] tegra-asoc: sound: Entered tegra_machine_dai_init: sgtl5000-playback
 ...

Here is the block of code I am executing in tegra_machine_dai_init

rtd = snd_soc_get_pcm_runtime(card, "sgtl5000-playback");
	if (rtd) {
	       dev_err(card->dev,"Entered tegra_machine_dai_init: sgtl5000-playback\n");
               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;

               /* err = snd_soc_dai_set_sysclk(rtd->codec_dai, RT5659_SCLK_S_MCLK, */
	       dev_err(card->dev, "Preparing to set extern1 for SGTL5000 sysclk\n");
	       err = snd_soc_dai_set_sysclk(rtd->codec_dai, SGTL5000_SYSCLK, 12288000,
				     SND_SOC_CLOCK_IN);
               if (err < 0) {
                       /* dev_err(card->dev, "codec_dai clock not set\n"); */
		       dev_err(card->dev, "failed to set sgtl5000 sysclk\n");
                       return err;
		}

               /* err = snd_soc_dai_set_sysclk(rtd->codec_dai, SGTL5000_SYSCLK,
		  clk_out_rate, SND_SOC_CLOCK_IN); */
	       /* err = tegra_alt_asoc_utils_set_extern_parent(&machine->audio_clock,
	           "pll_a_out0"); */
               err = tegra_alt_asoc_utils_set_extern_parent(&machine->audio_clock,
                                                    "extern1");
	       
               if (err < 0) {
                       /* dev_err(card->dev, "codec_dai clock not set\n"); */
		       dev_err(card->dev, "failed to set extern1 for SGTL5000 sysclk\n");
                       return err;
               }
	       dev_err(card->dev, "SUCCESS setting extern1 for SGTL5000 sysclk out=%d in=%d\n",clk_out_rate, SND_SOC_CLOCK_IN);
       }

I notice that the clk_out_rate that the original routine uses is different than the 12Mhz clok setting I actually use. (Changing that did not fix it.)
Any ideas about what I need to do to fix this? (I’ve been going back through the clock examples to see if I can find anything related, but so far I am coming up blank.)

Best regards,
Curtis

Hi Curtis,

The widgets in the machine driver are typically endpoint widgets, meaning that they represent an audio input or output jacks on the board. We need to connect the appropriate widgets in the codec to these endpoint widgets so that the ASoC core knows that this audio path is being used and so the inputs/outputs on the codec are powered up appropriately during playback/capture. If we don’t use this endpoint widgets (HP, SPK, LINE, etc) then the audio path will not be complete and appear unused.

Yes this initialisation will occur everytime that hw_params callback is called. Basically everytime that audio playback/capture starts. My understanding is that you are using the AUD_MCLK to drive the MCLK on the sgtl5000. By default the AUD_MCLK will operate at 256*fs. So it is not a fixed rate. Therefore, we should be passing ‘clk_out_rate’ in the snd_soc_dai_set_sysclk() call …

https://nv-tegra.nvidia.com/gitweb/?p=linux-nvidia.git;a=blob;f=sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c;h=cbe8c5ff3c6a40584f70b050da3c1b5405a62acd;hb=5ce7e219fa2764b829a480389dec90c57a0c1eda#l537

Regards,
Jon

Thanks for the quick response. I switched the clock in the call to “clk_out_rate” yesterday after posting. Thanks for the confirmation on that. Unfortunately, I don’t see any improvement in the behavior.
(broke and fixed the mclk hierarchy. I was hoping that the mclk losing its parent was the problem but I still am getting looping on the tegra_machine_dai_init. But at least I have the mclk set up correctly again.)

I could use a little more explanation on two topics:

  1. Do you have any idea why the tegra_machine_dai_init gets called over and over?
    I’m not sure what the calling code is looking for when it decides to make the call again.
    It seems obvious that I have left something unconfigured that it will need to be satisfied.
    (This is called by tegra_machine_pcm_hw_params() and tegra_machine_compr_set_params()
    (sorry still working on tracing back the rest of the way…)
    I suspect that there is an indirect call into this code from elsewhere in the kernel and
    that will be what I need to find to understand. Perhaps you can help me shortcut to that location?

  2. How do you know which endpoint widget to use? (_HP _LINE or something else)
    Are the Widgets in sound/soc/codecs/sgtl5000.c available to me or do I need to place all needed
    definitions (see below) in the tegra_machine_driver_mobile.c file?
    also…Does the file kernel-4.9/sound/soc/tegra/tegra_sgtl5000.c get used when using the
    tegra_machine_driver…?

static const struct snd_soc_dapm_widget tegra_machine_dapm_widgets[] = {

        SND_SOC_DAPM_LINE("x Linein", NULL),

  	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_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),

	SND_SOC_DAPM_INPUT("x LINE_IN"),
	SND_SOC_DAPM_INPUT("x MIC_IN"),

	SND_SOC_DAPM_OUTPUT("x HP_OUT"),
	SND_SOC_DAPM_OUTPUT("x LINE_OUT"),
	SND_SOC_DAPM_LINE("x Lineout", NULL),
	};

According to the Embedded Linux talks I’ve been watching on youtube I should only need to make changes to the machine driver code. Although it looks like the tegra machine driver may be defining some things that are usually in the codec or platform drivers (although I am new to working with the ASoC subsystem so I could be wrong).

I know your time is limited for answering questions please feel free to point me to any useful documents I may have missed. Most of the docs I’ve found are in the kernel Documentation tree or are talks and slides from various Embedded Linux conferences. Most of my kernel books do not seem to mention the ASoC subsystem. In the meantime I am going back over all the sgtl5000 related threads here in how of finding something I missed.

Hello!

Yes. Everytime playback/capture is started the various ->hw_params() callbacks are called. The codec drivers and machine driver all have a ->hw_params() callback to configure audio for the current configuration (sample-rate, sample-size, etc). The function tegra_machine_dai_init() is called by the Tegra machine driver ->hw_params() callback and so it is expected that this will be called everytime playback/capture starts. Please note that on boot, it is common for userspace (pulseaudio, etc) to invoke audio playback a few times and so what you are seeing is normal/expected.

I would use the widget that matches the audio output. So if you are using Line-out on the codec use the LINE widgets and if you are using the Headphones use the HP widget. That said, to be honest, I am not sure it actually matters, but I think it is good practice.

My understanding is that the codec driver defines various widgets including those for its input and output pins using the INPUT and OUTPUT widgets, respectively. However, it is the machine driver that defines the widgets for the physical audio jacks (LINE, HP, SPK, etc) on the board. So it is the machine driver that defines which of the codec input and output pins are being used on a particular platform. This is why the codec INPUT/OUTPUT widgets are routed to the machine driver widgets to complete the audio path.

The Tegra machine driver is design to support all the different audio interfaces on the SoC. So there are lots of widgets that are used for I2S, Digital MIC, Digital Speaker, etc. However, if you are just interfacing with the sgtl5000 codec, then no you do not need all of these. You only need the widgets that are used in the ‘nvidia,audio-routing’ property, the rest can be removed.

Yes you should only need to customise the machine (or platform) driver and device-tree. There should not be anything that we are doing in the machine driver that should be handled by the codec driver. The machine driver does need to tell the codec driver the sysclk frequency as only it knows this, but that is normal.

By the way, we are working to improve the audio documentation and so there should be some updates coming soon that should help with this.

Regards,
Jon

Thanks for the quick reply. I am still assimilating the info in your post but the number of times the init gets called seems to continue forever (I am to 900 seconds after my last boot and am still getting the init calls.) I just set up with the headphones and mic only to see if that would get rid of the looping, but it still retried the init continually. (So this is probably not related to the Widget setup.)
If I attempt to play something throught the headphones I should be able to catch it on the device pins with a scope but the playback seems to hang.

I think I must have missed configuring something that must be configured to move forward. I’ll keep working at it but if you think of anything that I may have missed please let me know.

I am starting to go through your post now to see if it brings anything to light.

Thanks for the great support Jon!

Best regards,
Curtis

OK, yes that is not normal indeed. Maybe share a diff of all the changes you have made to the machine driver.

Alternatively, save all the changes you have made and gradually re-introduce them to see what is causing this to happen.

Thanks
Jon