Sound Card Not showing in NX

I am trying to add a new codec over SPI interface and send audio data over I2S. AUD_MCLK for SYSCLK. I have taken the /boot/tegra194-p3668-all-p3509-0000-user-custom.dtb from the Xavier NX and made the following changes to its dts file:

spi@3210000 {
		...
		cs47l35_spi: spi@0 {
			compatible = "cirrus,cs47l35";
			spi-max-frequency = <0x5b8d80>;
			reg = <0x00>;
		};
....
sound {
		...
		nvidia,audio-routing = "x Headphone\0x OUT\0x IN\0x Mic\0y Headphone\0y OUT\0y IN\0y Mic\0z Headphone\0z OUT\0z IN\0z Mic\0m Headphone\0m OUT\0m IN\0m Mic\0n Headphone\0n OUT\0n IN\0n Mic\0o Headphone\0o OUT\0o IN\0o Mic\0a IN\0a Mic\0b IN\0b Mic\0c IN\0c Mic\0d IN\0d Mic\0[78 00] Headphone\0[78 00] HPOUTL\0[78 00] Headphone\0[78 00] HPOUTR";
		assigned-clock-rates = <0>, <12288000>;
		mclk-fs = <0x100>;
		...
nvidia,dai-link-5 {
			link-name = "cs47l35-codec";
			cpu-dai = <&tegra_i2s5_cs47l35>;
			codec-dai = <&cs47l35_spi>;
			cpu-dai-name = "I2S5";
			codec-dai-name = "cs47l35-aif1";
			format = "i2s";
			bit-format = "s16_le";
			srate = <0xbb80>;
			num-channel = <0x02>;
			ignore_suspend;
			name-prefix = [78 00];
			status = "okay";
			#linux,phandle = <0xc3>;
			#phandle = <0xc3>;
		};
...
ahub {
         ...
   tegra_i2s5_cs47l35: i2s@2901400 {
	  ...
	    };
}

And the following changes to the machine driver:

...
#define DRV_NAME "tegra-asoc:cs47l35"
...
static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
				  unsigned int rate, unsigned int channels,
				  u64 formats)
{
...
rtd = snd_soc_get_pcm_runtime(card, "cs47l35-codec");
	if (rtd) {
		dai_params =
		(struct snd_soc_pcm_stream *)rtd->dai_link->params;

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

		err = snd_soc_dai_set_sysclk(rtd->codec_dai, RT5659_SCLK_S_MCLK,
					     aud_mclk, SND_SOC_CLOCK_IN);
		if (err < 0) {
			dev_err(card->dev, "codec_dai clock not set\n");
			return err;
		}
	}
...


static int tegra_machine_cs47l35_init(struct snd_soc_pcm_runtime *rtd)
{
	struct device *dev = rtd->card->dev;
	int err;

	err = snd_soc_dai_set_sysclk(rtd->codec_dai, 1, 12288000,
				     SND_SOC_CLOCK_IN);
	if (err) {
		dev_err(dev, "failed to set cs47l35 sysclk!\n");
		return err;
	}

	return 0;
}
...

static int codec_init(struct tegra_machine *machine)
{
	struct snd_soc_dai_link *dai_links = machine->asoc->dai_links;
	unsigned int num_links = machine->asoc->num_links, i;

	if (!dai_links || !num_links)
		return -EINVAL;

	for (i = 0; i < num_links; i++) {
		if (!dai_links[i].name)
			continue;

		if (strstr(dai_links[i].name, "rt565x-playback") ||
		    strstr(dai_links[i].name, "rt565x-codec-sysclk-bclk1"))
			dai_links[i].init = tegra_machine_rt565x_init;
		else if (strstr(dai_links[i].name, "cs47l35-codec"))
			dai_links[i].init = tegra_machine_cs47l35_init;
	}

	return 0;
}

But I don’t see the codec under /sys/kernel/debug/asoc/codecs. Also the dmesg shows the following error message:

[ 9261.679122] tegra-asoc:cs47l35 sound: ASoC: CODEC DAI cs47l35-aif1 not registered
[ 9261.679331] tegra-asoc:cs47l35 sound: snd_soc_register_card failed (-517)

So can anybody please help me understand where the problem is?

Thanks in advance.

Sorry for the late response, our team will do the investigation and provide suggestions soon. Thanks

Hi, I have been able to make some progress since then and now my codec is showing under /sys/kernel/debug/asoc/codecs. So now, I need to add a ‘interrupts’ and ‘interrupt-parent’ property to the spi device node. So can you please help me on how I can choose the interrupts and interrupt-parent? I see quite many nodes with interrupt-controller properties. This is my current spi node:

spi@3210000 {
		compatible = "nvidia,tegra186-spi";
		reg = <0x00 0x3210000 0x00 0x10000>;
		interrupts = <0x00 0x24 0x04>;
		#address-cells = <0x01>;
		#size-cells = <0x00>;
		iommus = <0x02 0x20>;
		dma-coherent;
		dmas = <0x19 0x0f 0x19 0x0f>;
		dma-names = "rx\0tx";
		spi-max-frequency = <0x3dfd240>;
		nvidia,clk-parents = "pll_p\0clk_m";
		clocks = <0x04 0x87 0x04 0x66 0x04 0x0e>;
		clock-names = "spi\0pll_p\0clk_m";
		resets = <0x05 0x5b>;
		reset-names = "spi";
		status = "okay";
		linux,phandle = <0xf2>;
		phandle = <0xf2>;

		cs47l35_spi: spi@0 {
			compatible = "cirrus,cs47l35";
			spi-max-frequency = <0x5b8d80>; //Maximum SPI clocking speed of device in Hz.
			reg = <0x00>;

			AVDD-supply = <&dummyreg>;
			DBVDD1-supply = <&dummyreg>;
			DBVDD2-supply = <&dummyreg>;
			CPVDD1-supply = <&dummyreg>;
			SPKVDD-supply = <&dummyreg>;
			DCVDD-supply = <&dummyreg>;
			interrupt-parent = <0x24>;
			interrupts = <0x00 0xd2 0x00>;

		};

and my dmesg reads:

[   56.151491] madera_spi_probe
[   56.151890] madera spi0.0: Running without reset GPIO is not recommended
[   56.158835] madera spi0.0: CS47L35 silicon revision 1
[   56.163746] madera_irq_probe
[   56.170778] gpiochip_setup_dev: registered GPIOs 224 to 239 on device: gpiochip3 (madera)
[   56.170805] Adding alias for supply MICVDD,(null) -> MICVDD,spi0.0
[   56.171015] Adding alias for supply MICVDD,(null) -> MICVDD,spi0.0
[   56.171025] Adding alias for supply DBVDD2,(null) -> DBVDD2,spi0.0
[   56.171033] Adding alias for supply CPVDD1,(null) -> CPVDD1,spi0.0
[   56.171042] Adding alias for supply CPVDD2,(null) -> CPVDD2,spi0.0
[   56.171048] Adding alias for supply SPKVDD,(null) -> SPKVDD,spi0.0
[   56.171195] cs47l35_probe
[   56.213828] pinctrl madera probe
[   56.213841] madera-pinctrl madera-pinctrl: madera_pin_probe
[   56.213902] madera-pinctrl madera-pinctrl: pinctrl registered
[   56.277458] cs47l35-codec cs47l35-codec: ASoC: Failed to request CPVDD2: -19
[   56.277661] cs47l35-codec cs47l35-codec: ASoC: Failed to create DAPM control CPVDD2
[   56.277801] cs47l35-codec cs47l35-codec: Failed to create new controls -12
[   56.277969] tegra-asoc: sound: ASoC: failed to instantiate card -12
[   56.280356] tegra-asoc: sound: snd_soc_register_card failed (-12)
[   56.280551] tegra-asoc:: probe of sound failed with error -12
[   56.363852] cs47l35-codec cs47l35-codec: ASoC: Failed to request CPVDD2: -19
[   56.364018] cs47l35-codec cs47l35-codec: ASoC: Failed to create DAPM control CPVDD2
[   56.364156] cs47l35-codec cs47l35-codec: Failed to create new controls -12
[   56.364320] tegra-asoc:cs47l35 sound: ASoC: failed to instantiate card -12
[   56.367018] tegra-asoc:cs47l35 sound: snd_soc_register_card failed (-12)
[   56.367225] tegra-asoc:cs47l35: probe of sound failed with error -12
[   56.451230] cs47l35-codec cs47l35-codec: ASoC: Failed to request CPVDD2: -19
[   56.451428] cs47l35-codec cs47l35-codec: ASoC: Failed to create DAPM control CPVDD2
[   56.451569] cs47l35-codec cs47l35-codec: Failed to create new controls -12
[   56.451737] tegra-asoc:cs47l35 sound: ASoC: failed to instantiate card -12
[   56.454283] tegra-asoc:cs47l35 sound: snd_soc_register_card failed (-12)
[   56.455554] tegra-asoc:cs47l35: probe of sound failed with error -12
[   95.911337] madera spi0.0: BOOT_DONE
[  108.496452] irq 810: nobody cared (try booting with the "irqpoll" option)
[  108.496766] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.9.140-tegra #1
[  108.496773] Hardware name: NVIDIA Jetson Xavier NX Developer Kit (DT)
[  108.496784] Call trace:
[  108.496837] [<ffffff800808bdb8>] dump_backtrace+0x0/0x198
[  108.496851] [<ffffff800808c37c>] show_stack+0x24/0x30
[  108.496872] [<ffffff800845c7a0>] dump_stack+0x98/0xc0
[  108.496895] [<ffffff800812547c>] __report_bad_irq+0x3c/0xf8
[  108.496903] [<ffffff80081258e0>] note_interrupt+0x2c8/0x318
[  108.496914] [<ffffff8008122778>] handle_irq_event_percpu+0x50/0x60
[  108.496926] [<ffffff80081227d8>] handle_irq_event+0x50/0x80
[  108.496936] [<ffffff80081265a0>] handle_fasteoi_irq+0xc8/0x1b8
[  108.496943] [<ffffff80081214f4>] generic_handle_irq+0x34/0x50
[  108.496950] [<ffffff8008121bd8>] __handle_domain_irq+0x68/0xc0
[  108.496960] [<ffffff8008080d44>] gic_handle_irq+0x5c/0xb0
[  108.496967] [<ffffff8008082c28>] el1_irq+0xe8/0x194
[  108.496993] [<ffffff8008ba5ef8>] cpuidle_enter_state+0xb8/0x380
[  108.497001] [<ffffff8008ba6234>] cpuidle_enter+0x34/0x48
[  108.497016] [<ffffff8008111cc4>] call_cpuidle+0x44/0x70
[  108.497023] [<ffffff8008112040>] cpu_startup_entry+0x1b0/0x200
[  108.497043] [<ffffff8008f5965c>] rest_init+0x84/0x90
[  108.497071] [<ffffff8009600b64>] start_kernel+0x370/0x384
[  108.497079] [<ffffff8009600204>] __primary_switched+0x80/0x94
[  108.497086] handlers:
[  108.497160] [<ffffff8008122878>] irq_default_primary_handler threaded [<ffffff80087afe58>] regmap_irq_thread
[  108.497395] Disabling IRQ #810
[  316.757569] EXT4-fs (mmcblk0p1): error count since last fsck: 1
[  316.757958] EXT4-fs (mmcblk0p1): initial error at time 1517155107: ext4_find_entry:1441: inode 524551
[  316.758209] EXT4-fs (mmcblk0p1): last error at time 1517155107: ext4_find_entry:1441: inode 524551

Here tegra-asoc is the in-built default machine driver and tegra-asoc:cs47l35 is the same machine driver to which I made modifications to add the new codec.

Thanks.

Hi abhigyanborah95

At this point do you see sound card is registered fine? (Check with cat /proc/asound/cards).
In other words, without the addition of interrupt properties sound card is available? Please confirm this.

Next you can try interrupts. Please describe what the interrupt is used for and share reference to the Codec driver.

Thanks,
Sameer.

Hi,

In other words, without the addition of interrupt properties sound card is available? Please confirm this.

Without the interrupt properties, I see the following errors:

[   86.053318] madera-irq madera-irq: Invalid IRQ: 0
[   86.053460] madera-irq: probe of madera-irq failed with error -22

and in this case I don’t see the codec even under /sys/kernel/debug/asoc/codecs.

Please describe what the interrupt is used for and share reference to the Codec driver.

The interrupt-parent is the “tegra194-pm-irq” and I put the “interrupt-parent” and “interrupts” property just out of guess work to see what happens, as I am new in this field.

cs47l35.c (58.1 KB) is the codec driver.

Thanks

Without the schematic details and correct interrupt line that is required to be used, you will end up facing issues with arbitrary choice of interrupt number.

The probe is expected to fail without interrupt properties because the driver expects some mapping. See probe() function of the codec driver you attached.

You need to find the details on why the interrupt is required and what is the purpose of it. If this is not really essential for your application, you can avoid using interrupt properties for now. However you need to fix the driver in this case to not cause probe failures. Then you can see if sound card registers fine.

Can you please tell me where I should look to find the values of these properties? And apologies for my naive question, but do I have to connect the interrupt pin of my codec with some GPIO on the Xavier?

Thanks.

Usage of interrupt pin in your case is not clear to me. Like I mentioned before, you need to find out why it is required. If it is very much essential to your codec functionality, then it has to be added. Can you please share the schematics or mention the pin which you want to configure for interrupts?