IMX6 SSI Clock Slave

Hi community

We want to connected a Colibri IMX6DL 512MB Module to a Audio DSP ADAU1467, so we can play and record audio to/from this Audio DSP.

Our Goal is to use the TDM Signals like described in this Blog, to transmit 8 Channels and receive 8 Channels from the Audio DSP. The DSP works as clock master, as there are many other ADC’s and DAC’s connected to it. So the DSP provides the Bitclock and Frameclock to the imx6

The existing audio codec on the colibri module (sgtl15000) should be deactivated and only the DSP connection should appear as a soundcard on linux.

So we deactivated the sgtl15000 and route the ssi2 to the AUD4 and use the simple-audio-card with a dummy codec. The Input clock is configured for 48kHz sampling rate and 8 Channels with Slot width 32 Bit. This leads to a frequency of 12288000Hz.

I used the device-tree from imx6dl-colibri-eval-v3.dts and added following changes:

&iomuxc {

	/* remove existing sgtl15000 pinctrl */
	/delete-node/ pinctrl_audmux;
	/* add pinctrl to use AUD4 */
	pinctrl_audmux: audmuxgrp {
		fsl,pins = <
			MX6QDL_PAD_DISP0_DAT18__AUD4_RXFS 0x130b0
			MX6QDL_PAD_DISP0_DAT19__AUD4_RXC  0x130b0
			MX6QDL_PAD_DISP0_DAT20__AUD4_TXC  0x130b0
			MX6QDL_PAD_DISP0_DAT21__AUD4_TXD  0x130b0
			MX6QDL_PAD_DISP0_DAT22__AUD4_TXFS 0x130b0
			MX6QDL_PAD_DISP0_DAT23__AUD4_RXD  0x130b0

#define AUD_PORT_2 1
#define AUD_PORT_4 3

&audmux {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_audmux>;
	status = "okay";

	 * SSI2 on AUDMUX Port 2
	 * PTCR1:
	 *  - TFS_DIR 1	// TXFS is an output
	 *  - TFSEL 3	// TSFS Source Port 4
	 *  - TCLKDIR 1	// TCLK is an output
	 *  - TCSEL 3	// TCLK Source Port 4
	 *  - RFS_DIR 1	// RXFS is an output
	 *  - RFSEL 3	// RXFS Source Port 4
	 *  - RCLKDIR 1	// RCLK is an output
	 *  - RCSEL	3	// RCLK Source Port 4
	 *  - SYN 1		// Synchronous mode (4-wire interface)
	 * PDCR1:
	 *  - RXDSEL 4
	 *  - TXRXEN 0
	 *  - MODE 0
	 *  - INMMASK 0
	 * AUD4 on AUDMUX Port 4
	 *  - TFS_DIR 0	// TXFS as input
	 *  - TFSEL 0 	// will be ignored when TFS_DIR = 0
	 *  - TCLKDIR 0	// TCLK as Input
	 *  - TCSEL 0	// will be ignored when TCLKDIR = 0
	 *  - RFS_DIR 0	// RFS as Input
	 *  - RFSEL 0   // will be ignored when RFS_DIR = 0
	 *  - RCLKDIR 0	// RCLK as Input
	 *  - RCSEL	0	// will be ignored when RCLKDIR = 0
	 *  - SYN 1		// Synchronous mode (4-wire interface)
	 * PDCR4: 0x0000 0000
	 *  - RXDSEL 0
	 *  - TXRXEN 0
	 *  - MODE 0
	 *  - INMMASK 0
	ssi2 {
		fsl,audmux-port = <AUD_PORT_1>;
		fsl,port-config = <
	aud4 {
		fsl,audmux-port = <AUD_PORT_4>;
		fsl,port-config = <

&i2c2 {
	/delete-node/ sgtl5000@a;

&ssi2 {
	status = "okay";

	/delete-node/ sound;
	codec_test: codec_test {
		compatible = "linux,snd-soc-dummy";
		#sound-dai-cells = <0>;
		status = "okay";

	sound@2 {
		compatible = "simple-audio-card";
		model = "ssi-test";
		ssi-controller = <&ssi2>;
		simple-audio-card,name = "ssi-test";
		simple-audio-card,frame-master = <&codec_test>;
		simple-audio-card,bitclock-master = <&codec_test>;
		sound2_ssi: simple-audio-card,cpu {
			sound-dai = <&ssi2>;
			system-clock-frequency = <12288000>;
			dai-tdm-slot-num = <8>;
			dai-tdm-slot-width = <16>;
		sound2codec: simple-audio-card,codec {
			sound-dai = <&codec_test>;

When play some sound through the ssi-test soundcard i can see some data on the aud4 TXD output pin with a logic analyzer. But the Data is not synced to the input clock instead it look’s like it is synced to another clock (maybe 44100 from the sgtl1500 driver?).

I have tried several different combinations with different data format (dsp_a, dsp_b, left_justified) and configure the ssi port for i2s-master or i2s-slave with the same result. As the dsp is quite flexible for the input format i just want to see some audio data synced to the input clock.

Do you have any suggestions, what i have missed or wrongly configured?

Best regards

Dear @mme, how are you?

Thanks for reaching us. Can you please share with us a bit more information about your issue?

  • Which exact image and version are you using? For example, BSP 5.6.0 - Reference Minimal Image
  • Did you check if the ADAU drivers are enabled? From what I understand, they are not enabled by default in our images:
$ zcat /proc/config.gz | grep -i adau
# CONFIG_SND_SOC_ADAU1701 is not set
# CONFIG_SND_SOC_ADAU1761_I2C is not set
# CONFIG_SND_SOC_ADAU1761_SPI is not set
# CONFIG_SND_SOC_ADAU7002 is not set
  • I suppose you’re using your own carrier board, right?

Best regards,

Hi @gclaudino.tx, thanks i’m fine and you?

Which exact image and version are you using? For example, BSP 5.6.0 - Reference Minimal Image

Thank you for the fast response.
Im not totally sure about, how to get the correct version, we are using a custom image based on Poky (Yocto Project Reference Distro)

DISTRO = "poky"
DISTRO_NAME = "Poky (Yocto Project Reference Distro)"

Did you check if the ADAU drivers are enabled? From what I understand, they are not enabled by default in our images:

Yes you are right. They are deactivated by default. I will activate them. So should i use them instead of the simple-audio-card? As a sidenote: The ADAU1467 is configured via SPI, but this SPI ist not connected to the Colibri Module, instead it is configured by another independent controller. We would just use the Audio interface.

Dear @mme, thanks for the update.

We had a quick chat about it internally and as you’re using another interface to connect it to the module you wouldn’t need them at all. We’d like, however, to suggest one change on the following part of your device tree:

Could you please test using the following fields:

simple-audio-card,frame-master = <&sound2_ssi>;
simple-audio-card,bitclock-master = <&sound2_ssi>;

As your clock is defined on the simple-audio-card, CPU side referencing the codec as you were trying to do may be responsible for the syncing problem. Can you please give it a try?

In addition, which command are you using to build your image? How are you doing it?

Could you also please share with us the output of a dmesg command?

Best regards,

Dear @gclaudino.tx

I have tested to use &sound2_ssi as bitclock-master and frame-master with the same result.

Here you will find the dmesg output:
dmesg.txt (21.9 KB)

We have setup the build repository with kas. The image is build with bitbake bitbake <custom-image-name>. Kas does basicly the same.

For testing the device-tree modifications i did it like described here:

  1. Open Kerne dev shell bitbake virtual/kernel -c devshell
  2. Compile device-tree files make dtbs
  3. Modify device-tree source file custom.dts
  4. Compile custom device-tree file make custom.dtb
  5. Copy compiled device-tree file from $KBUILD_OUTPUT to /boot/ directory of target
  6. Reboot target

If i have a working version, i will then have to include it into my custom layer. But that’s the problem for tomorrow :wink:

Best regards

Dear @mme,

We had another look at your device tree and a few things came to our attention. As you said, you used the Evaluation Board Device Tree as a reference for your project. On it, you can see the following includes:

#include "imx6dl.dtsi"
#include "imx6qdl-colibri.dtsi"

If we take a closer look on the device-trees that have been included we have:

  • on the imx6dl.dtsi we have a include to imx6qdl.dtsi. This file on its time has the definition of the ssi2 interface:
                                ssi2: ssi@202c000 {
                                        #sound-dai-cells = <0>;
                                        compatible = "fsl,imx6q-ssi",
                                        reg = <0x0202c000 0x4000>;
                                        interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6QDL_CLK_SSI2_IPG>,
                                                 <&clks IMX6QDL_CLK_SSI2>;
                                        clock-names = "ipg", "baud";
                                        dmas = <&sdma 41 1 0>,
                                               <&sdma 42 1 0>;
                                        dma-names = "rx", "tx";
                                        fsl,fifo-depth = <15>;
                                        status = "disabled";

Therefore, if you have the same includes of the evaluation board, you may run into a few problems while using your device tree.

The first thing that you can see is a label to ssi@202c000 (Device Tree Customization | Toradex Developer Center) where it sets the compatible drivers and a few more things. Therefore, when you use &ssi2, you point to this node. On your device tree, you create a new node named ssi2. With this, these configurations are not transferred to the original node. You should instead use &ssi2 as the node was already created and included.

Can you please have a look at it and check how this affects your issue?

In addition, looking at your dmesg, it seems that the ssi-test device is being loaded without any major errors. Can you see this interface when you run cat /proc/asound/cards?

Lastly, may I ask you why do you use kas? Are there any particular benefits from that approach that we usually don’t have on our base Yocto settings? You’re using our reference images as a base in any case, right? Do you have our meta-layers?

Best regards,

Hi @gclaudino.tx

So if i unserstood you correctly, i created a new label ssi2 inside the audmux which overrides the &ssi2 label from the imx6qdl.dtsi.

To fix it, i have renamed the ssi2 label inside the audmux to audmuxssi2 so the configuration should now apply to the ssi@202c000 node.

But with these change, the Data output is still out of sync with the provided clock.

Yes i can see the interface.

$ cat /proc/asound/cards
 0 [ssitest        ]: ssi-test - ssi-test

About kas:
Actually we started with your base Yocto settings using repo. We have brought in an external expert to setup the u-boot configuration for Firmware Updates and he recommendet us to switch over to kas. As he already setup the kas with the same layers and same configuration, we are quite happy with it so far. Main advantage, it inclused the build/conf/local.conf changes directly within the yaml and so can be checked in our source control.

Yes we have a custom image based on your reference images.
Your meta layers are included:

    url : ""
    refspec : dunfell-5.x.y
    url : ""
    refspec : dunfell-5.x.y
    url : ""
    refspec : dunfell-5.x.y

Dear @mme,

Just to get it clear, are the fsl,audmux-port and the fsl,portconfig intended to be on a separate node? And just as a final check, you now have something like this: audmuxssi2: ssi2? If so, I’d suggest you to give another try and change it to something like: audmuxssi2: not_named_as_ssi2.

If the above doesn’t help you at all, what I’d suggest you right now would be to test it with one of our reference images without any customization.

You can find the recipes to build them under OpenEmbedded Layer Index - meta-toradex-demos.

This way we can try to remove any kernel modification/package modification as a possible problem source. Could you please give it a try using for instance: bitbake tdx-reference-multimedia-image?

Also, thanks for the explanation about kas!

Best regards,

Hi @gclaudino.tx

Sorry for the late reply. It took me some time to setup the environment and adapt all changes to test it.

Now i’m using the tdx-reference-minimal-image where i added
IMAGE_INSTALL += " alsa-utils"

and in the kernel menuconfig activate:


But i still have the same issue, that the AUD4 Data is not in sync with the provided input clock.

Attached you will find the actual device-tree file and also the dmesg output.

imx6dl-colibri-custom-board.dts (7.0 KB)
dmesg.txt (18.8 KB)

One thing i found was the message:
[ 2.708275] debugfs: Directory '202c000.ssi' with parent 'ssi-test' already present!

I don’t know exactly what is the reason for this, but maybe it is a hint, that something is not correctly configured.

Best regards.

Dear @mme,

Thanks for the update. Just a small feedback, if you use the tdx-reference-multimedia-image you’d have alsa-utils by default and could also have a folder called sound on your root directory with some samples for you to test. There may be other modules or packages necessary for the sound to work properly.

Would you please also give this a try with the simple card configuration enabled with the tdx-reference-multimedia-image?

If you have a look on the imx6dl.dtsi file you can find that 202c000 is the register address for the SSI2 interface. I’ll check more information about this message.

Best regards,

Hi @gclaudino.tx

I have now used the tdx-reference-multimedia-image for testing with the same result.

If you are interested, here is the Picture of the Logic Analyzer, when playing sound or use the speaker-test command:

Where the Bitclock and LRClock (Frameclock) are generated from the DSP, the Output Signal SDO is far to slow and completly out of sync.

The Error debugfs: Directory '202c000.ssi' with parent 'ssi-test' already present! is still in the dmesg output. Do you have any news for that?
dmesg.txt (19.9 KB)

Best regards

Hello @mme,
I’ve looked through the thread, and although I don’t have a solution I would like to add some suggestions of what you could look into.
It seems to me that what’s missing is the configuration of the ssi in “network mode” with the correct format that selects external clock and external FS. Here’s an excerpt of the fsl_ssi.c file:

        /* DAI clock master masks */                                                                                                                           
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {                                                                                                            
        case SND_SOC_DAIFMT_CBS_CFS:                                                                                                                           
                /* Output bit and frame sync clocks */                                                                                                         
                strcr |= SSI_STCR_TFDIR | SSI_STCR_TXDIR;                                                                                                      
                scr |= SSI_SCR_SYS_CLK_EN;                                                                                                                     
        case SND_SOC_DAIFMT_CBM_CFM:                                                                                                                           
                /* Input bit or frame sync clocks */                                                                                                           
        case SND_SOC_DAIFMT_CBM_CFS:                                                                                                                           
                /* Input bit clock but output frame sync clock */                                                                                              
                strcr |= SSI_STCR_TFDIR;                                                                                                                       
                return -EINVAL;                                                                                                                                

And the definition of SND_SOC_DAIFMT_CBM_CFS in soc-dai.h:

 * DAI hardware clock masters.                                                                                                                                 
 * This is wrt the codec, the inverse is true for the interface                                                                                                
 * i.e. if the codec is clk and FRM master then the interface is                                                                                               
 * clk and frame slave.                                                                                                                                        
#define SND_SOC_DAIFMT_CBM_CFM          (1 << 12) /* codec clk & FRM master */                                                                                 
#define SND_SOC_DAIFMT_CBS_CFM          (2 << 12) /* codec clk slave & FRM master */                                                                           
#define SND_SOC_DAIFMT_CBM_CFS          (3 << 12) /* codec clk master & frame slave */                                                                         
#define SND_SOC_DAIFMT_CBS_CFS          (4 << 12) /* codec clk & FRM slave */

Unfortunately I couldn’t find how to properly set it up using the device tree. I assume there’s a missing “format” parameter that needs to be setup somewhere to make the ssi be properly configured. It seems that the audmux should be properly setup with the settings that you have in your device tree.
Also, it can be helpful to enable the debug functionality in the sound/soc/generic/simple-card.c by applying the following patch:

diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 58c200c27ba1..75d8beb451fa 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -5,6 +5,9 @@
 // Copyright (C) 2012 Renesas Solutions Corp.
 // Kuninori Morimoto <>
+#define DEBUG
 #include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/module.h>

After recompiling / installing the kernel, you should get the following output on the kernel boot (please note that I tested this in another module, but you should have a similar output on yours):

root@verdin-imx8mm-06827736:~# dmesg|grep simple
[    1.312682] usbcore: registered new interface driver usb_serial_simple
[    1.734071] asoc-simple-card sound-card: link 1, dais 2, ccnf 0
[    1.734151] asoc-simple-card sound-card: link_of (/sound-card)
[    2.542609] asoc-simple-card sound-card: link 1, dais 2, ccnf 0
[    2.542688] asoc-simple-card sound-card: link_of (/sound-card)
[    2.598530] asoc-simple-card sound-card: link 1, dais 2, ccnf 0
[    2.598609] asoc-simple-card sound-card: link_of (/sound-card)
[    2.679071] asoc-simple-card sound-card: link 1, dais 2, ccnf 0
[    2.679137] asoc-simple-card sound-card: link_of (/sound-card)
[    2.690458] asoc-simple-card sound-card: link 1, dais 2, ccnf 0
[    2.690522] asoc-simple-card sound-card: link_of (/sound-card)
[    4.642577] asoc-simple-card sound-card: link 1, dais 2, ccnf 0
[    4.642644] asoc-simple-card sound-card: link_of (/sound-card)
[    4.664298] asoc-simple-card sound-card: link 1, dais 2, ccnf 0
[    4.664372] asoc-simple-card sound-card: link_of (/sound-card)
[    4.673068] asoc-simple-card sound-card: link 1, dais 2, ccnf 0
[    4.673136] asoc-simple-card sound-card: link_of (/sound-card)
[    4.673201] asoc-simple-card sound-card: Card Name: imx8mm-nau8822
[    4.673205] asoc-simple-card sound-card: DAI0
[    4.673210] asoc-simple-card sound-card: cpu sysclk = 400000000
[    4.673213] asoc-simple-card sound-card: cpu direction = IN
[    4.673217] asoc-simple-card sound-card: codec sysclk = 24576000
[    4.673220] asoc-simple-card sound-card: codec direction = IN
[    4.673224] asoc-simple-card sound-card: codec clk 24576000Hz
[    4.673228] asoc-simple-card sound-card: dai name = 30020000.sai-nau8822-hifi
[    4.673231] asoc-simple-card sound-card: dai format = 1001
[    4.700210] asoc-simple-card sound-card: nau8822-hifi <-> 30020000.sai mapping ok
[    4.707830] asoc-simple-card sound-card: ASoC: no DMI vendor name!

You can see that there is a format bitmask that I assume is what we need to change:

[    4.673231] asoc-simple-card sound-card: dai format = 1001

If I understood the thread correctly, you started with an older kernel and then updated your setup at some point to work with our BSP 5 reference image, is that right? Could you share your updated device tree?

Additionally, as this is a very specific functionality that you are trying to achieve I would also suggest:

  1. Try to find a similar setup with an external DSP in another board that’s currently supported on the linux kernel code;
  2. Try to contact the NXP community directly (, maybe they can help you move a little bit forward with this setup;

Please let us know of any progress,
Rafael Beims

1 Like

Hi @rafael.tx

I have activated the debug functionality and i see the following output:

root@colibri-imx6-10866214:~# dmesg | grep simple
[    1.897435] asoc-simple-card sound@2: link 1, dais 2, ccnf 0
[    1.897484] asoc-simple-card sound@2: link_of (/sound@2)
[    2.695269] asoc-simple-card sound@2: link 1, dais 2, ccnf 0
[    2.695312] asoc-simple-card sound@2: link_of (/sound@2)
[    2.695389] asoc-simple-card sound@2: Card Name: ssi-test
[    2.695395] asoc-simple-card sound@2: DAI0
[    2.695402] asoc-simple-card sound@2: cpu sysclk = 12288000
[    2.695408] asoc-simple-card sound@2: cpu direction = IN
[    2.695413] asoc-simple-card sound@2: cpu slots = 8
[    2.695418] asoc-simple-card sound@2: cpu slot width = 16
[    2.695423] asoc-simple-card sound@2: codec direction = IN
[    2.695428] asoc-simple-card sound@2: dai name = 202c000.ssi-snd-soc-dummy-dai
[    2.695434] asoc-simple-card sound@2: dai format = 4004
[    2.706143] asoc-simple-card sound@2: snd-soc-dummy-dai <-> 202c000.ssi mapping ok

So the dai format is 4004 which I interpret as clock slave and frame slave. Which is the behavior i expected. Or have i mixed up something here?

If I understood the thread correctly, you started with an older kernel and then updated your setup at some point to work with our BSP 5 reference image, is that right? Could you share your updated device tree?

Not at all. I started with another setup which used the same BSP and a custom image based on the reference image. To be shure, that the problem, does not depend on our changes, i switched to the BSP5 reference image.

Here is the device tree i actually use:
imx6dl-colibri-custom-board.dts (7.0 KB)

Thanks for the Inputs: I will have a look into linux kernel code for a similar setup. Otherwise i try to contact the nxp community.

Hi @mme,

Thanks for the update. About your question on the dai format, I could find this commit online: kernel/git/broonie/sound.git - ASoC. There are some differencies on the structure of the device tree they propose and the one you have currently. Maybe this can help you figure out.

It makes reference to this previous patch: kernel/git/broonie/sound.git - ASoC where they mention a wrong configuration on the Dai Format.

Best regards,

Hi @gclaudino.tx

I think you point me to the right direction. I missinterpreted the dai format prevously, because i did not read the comment carefully enough.

 * DAI hardware clock masters.                                                                                                                                 
 * This is wrt the codec, the inverse is true for the interface                                                                                                
 * i.e. if the codec is clk and FRM master then the interface is                                                                                               
 * clk and frame slave.                                                                                                                                        
#define SND_SOC_DAIFMT_CBM_CFM          (1 << 12) /* codec clk & FRM master */                                                                                 
#define SND_SOC_DAIFMT_CBS_CFM          (2 << 12) /* codec clk slave & FRM master */                                                                           
#define SND_SOC_DAIFMT_CBM_CFS          (3 << 12) /* codec clk master & frame slave */                                                                         
#define SND_SOC_DAIFMT_CBS_CFS          (4 << 12) /* codec clk & FRM slave */

As my DSP is clock master i have to configure the DAI as clock master (SND_SOC_DAIFMT_CBM_CFM ). The dai format should be 1004!

After following you first link i changed the device tree modification from

		simple-audio-card,frame-master = <&sound2_ssi>;
		simple-audio-card,bitclock-master = <&sound2_ssi>;


		simple-audio-card,frame-master = <&sound2codec>;
		simple-audio-card,bitclock-master = <&sound2codec>;

Now the dai format is exactly 1004 and also the logic analyzer output look’s like it is synced with the bitclock and frameclock from the DSP.

So it looks like the problem is solved for our. We just need to adapt the configuration from the DSP but as the signals looks correct, it should just take some minor changes on the device tree.

Many thanks @gclaudino.tx and @rafael.tx for your support.

Best regards

Hi @mme,

That’s good to hear! I’m glad the links did help you.

Please tell us if you’d still need help with that part or if we can tag your answer as the solution.

Best regards,

Hi @gclaudino.tx

You can tag my response as the solution. If i have any more questions, i will reach out to you again.

Best regards

Hi @mme,

Thanks for the update. Please feel free to come back anytime.