This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/PROCESSOR-SDK-AM335X: Multiple McASP I2S Audio Input Serializers

Part Number: PROCESSOR-SDK-AM335X


Tool/software: Linux

Hello,

I have been fighting with this for awhile now, i know it am probably just forgetting something simple but can't seem to put my finger on it.  I thought maybe it was related to one of my prior posts (https://e2e.ti.com/support/processors/f/791/t/313430), but messing with the num-evt properties doesn't seem to help : /.

Anyways, my setup is i am using McASP0 and the AM335x is a slave and the master is only capable of I2S.  I have 1 output serializer (2 channels) and 3 input serializers (6 channels).  The 1 output channel works great, i can play audio via my codec no problem.  The issue is with the capture channels.  When i record from the any of the capture channels everything is all messed up.  For example Serializer 1 it seems to be putting both left and right channels together on channel 0 and for serializer 2 one of the channels is on channel 3 and the other is on channel 5?  That is why i thought it might be a similar issue to my other post because it seems like everything is all out of order : /.

Here is the related code:

Device Tree:

sound {
	compatible = "ti,am335x-hoho";
	ti,model = "QRS WM8580";
	ti,audio-codec = <&wm8580 &wm8580>;
	ti,mcasp-controller = <&mcasp0 &mcasp0>;
	ti,codec-clock-rate = <12000000>;
	ti,codec-num-links = <2>;
	ti,audio-routing =
		"Front",      "VOUT1L",
		"Front",      "VOUT1R",
		"DREAML", 	  "DreamIn",
		"DREAMR", 	  "DreamIn",
		"MICL", 	  "MicIn",
		"MICR", 	  "MicIn",
		"AINL",       "LineIn",
		"AINR",       "LineIn";
};


mcasp0_audio_pins: mcasp0_audio_pins {
	pinctrl-single,pins = <
		AM33XX_IOPAD(0x990, PIN_INPUT_PULLDOWN | MUX_MODE0) 	/* mcasp0_aclkx.mcasp0_aclkx 	- MCASP BCLK*/
		AM33XX_IOPAD(0x994, PIN_INPUT_PULLDOWN | MUX_MODE0) 	/* mcasp0_fsx.mcasp0_fsx     	- MCASP FRAME SYNC*/
		AM33XX_IOPAD(0x998, PIN_OUTPUT_PULLDOWN | MUX_MODE0) 	/* mcasp0_axr0.mcasp0_axr0   	- MCASP DATA OUT*/
		AM33XX_IOPAD(0x9A8, PIN_INPUT_PULLDOWN | MUX_MODE0) 	/* mcasp0_axr1.mcasp0_axr1   	- MCASP DATA IN CODEC*/
		AM33XX_IOPAD(0x9A0, PIN_INPUT_PULLDOWN | MUX_MODE2) 	/* mcasp0_aclkr.mcasp0_axr2   	- MCASP DATA IN MIC*/
		AM33XX_IOPAD(0x9A4, PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mcasp0_fsr.mcasp0_axr3 	- MCASP DATA IN DREAM*/
	>;
};

&mcasp0 {
	#sound-dai-cells = <0>;
	pinctrl-names = "default";
	pinctrl-0 = <&mcasp0_audio_pins>;
	status = "okay";
	op-mode = <0>;         /* MCASP_IIS_MODE */ 
	tdm-slots = <2>;
	/* 16 serializers */
	/* 0: INACTIVE, 1: TX, 2: RX */
	serial-dir = <  
		1 2 2 2
		0 0 0 0
		0 0 0 0
		0 0 0 0
	>;
	tx-num-evt = <32>;
	rx-num-evt = <32>;
};

Then the setup in the codec driver:

static struct snd_soc_dai_driver wm8580_dai[] = {
	{
		.name = "wm8580-hifi-playback",
		.id	= WM8580_DAI_PAIFRX,
		.playback = {
			.stream_name = "Playback",
			.channels_min = 2,
			.channels_max = 2,
			.rates = SNDRV_PCM_RATE_8000_192000,
			.formats = WM8580_FORMATS,
		},
		.ops = &wm8580_dai_ops_playback,
	},
	{
		.name = "wm8580-hifi-capture",
		.id	=	WM8580_DAI_PAIFTX,
		.capture = {
			.stream_name = "Capture",
			.channels_min = 2,
			.channels_max = 6,	
			.rates = SNDRV_PCM_RATE_8000_192000,
			.formats = WM8580_FORMATS,
		},
		.ops = &wm8580_dai_ops_capture,
	},
};

And finally my asound.conf:

#Our main 6 channel input mixer/controller
pcm.imixed {
    type dsnoop
    ipc_key 3025
    ipc_perm 0666
    slave {
        pcm "hw:0,1"
        channels 6
        format S32_LE
        rate 48000
    }
    bindings {
        0 0
        1 1
        2 2
        3 3
        4 4
        5 5
    }
}

#Define the 2 channel line-in
pcm.lineinx {
    type plug
    slave {
        pcm "imixed"
        channels 6
    }
    ttable.0.0 1
    ttable.1.1 1
}

#Define the 2 channel dream-in
pcm.dreaminx {
    type plug
    slave {
        pcm "imixed"
        channels 6
    }
    ttable.0.2 1
    ttable.1.3 1
}

#Define the 2 channel mic-in
pcm.micinx {
    type plug
    slave {
        pcm "imixed"
        channels 6
    }
    ttable.0.4 1
    ttable.1.5 1
}

I will keep working at it, but i am just hoping maybe a someone else has done something similar with multiple input serializers on McASP using I2S and has some information that may be helpful!

  • Jarrod,

    Our expert on this is out today, but we should be able to give you some feedback early next week.

    Could you please share what version of the SDK you are working with?

    Thanks.

  • Ron,

    Alright, that sounds great!  Thank you.  I started with the latest (05_01_00_11), so the kernel version 4.14.

    Thanks,

    Jarrod

  • Hi Jarrod,

    Could you please directly open the PCM (not via ALSA plugins) and check the recorded audio if it is matching? Also, I was looking at the datasheet for wm8580 and it does not support 6 channel capture (1 Stereo ADC).

    Regards,
    Krunal
  • Jarrod,

    one thing to note when using multiple serializers to achieve multichannel audio:
    In your case you have 3 serializers, all configured in i2s (stereo) -> 3*2 = maximum of 6 channels.

    If the PCM is opened in stereo:
    slot0 -> arx1 ch0 (left)
    slot1 -> arx1 ch1 (right)

    If the PCM is opened in 3/4 channel mode:
    slot0 -> arx1 ch0 (left)
    slot1 -> arx2 ch0 (left)
    slot2 -> arx1 ch1 (right)
    slot3 -> arx2 ch1 (right)

    If the PCM is opened in 5/6 channel mode:
    slot0 -> arx1 ch0 (left)
    slot1 -> arx2 ch0 (left)
    slot2 -> arx3 ch0 (left)
    slot3 -> arx1 ch1 (right)
    slot4 -> arx2 ch1 (right)
    slot5 -> arx3 ch1 (right)

    If you open the PCM directly via hw or plughw and record audio you should have the channels in different order depending on how many channels are you recording.

    The reason for this is that we must have the data ready for _all_ serializers at the same time since they are running in parallel.

    Regards,
    Peter
  • Peter,

    Thank you very much for the reply!  Sorry for the delay i was caught up into some other things.  Anyways the information you gave me has pointed me in the correct direction I think.  I didn't realize the channels were organized in the slots in that way, which is why i though everything was all mixed up!  I recorded from the raw PCM and opened the file and everything was on the correct channel for the 6 channel configuration you presented above, i will just have to redo my asound.conf to map them correctly. 

    The other problems i am having that prevented me from realizing the channels are simply ordered different was a manufacturing issue with the microphones and something with the WM8580 ADC settings.  I thought the slots were messed up causing the garbled audio with the 2 channels for the ADC of the WM8580 but turns out something must be wrong in the WM8580 setup because it is not putting the data on the I2S bus properly, I verified by tieing the I2S data line from the ADC directly to a DAC output data line and sure enough the same garbled up audio, so nothing with the McASP setup.  I haven't been able to figure out the problem quite yet with the WM8580 setup, but i will keep working at it.  As for the microphones they were accidentally washed during manufacture and it damaged them, they just needed replaced.  I have multiple devices on the I2S bus so my setup is rather weird, as you pointed out the WM8580 only has 1 stereo capture, i actually have a couple I2S Mics and a Synthesizer chip (generates I2S audio data from MIDI input) providing the other inputs.  Here is a very simplified block diagram of what I have going on:

    The Synthesizer chip and Microphones need no configuration and they are working properly now, the synthesizer chip has to be the master so my setup is rather strange, pretending the WM8580 has 3 stereo captures so i can expose as 6 channels. 

    Anyway i think you have given me the information to point me in the right direction.  I will keep working at the WM8580 ADC setup issue and post back my final asound.conf changes once i get everything working fully!  Thanks Peter!

    Thanks,

    Jarrod

  • Jarrod,

    Thank you for the details of your setup. Sure enough it is not something I see frequently!

    I'm glad that the slot/channel placement from/to a captured stream in case of multiple serializers working in parallel cleared things up, it is not obvious for the first glance and it makes things (channels) moving here and there depending on the channels.

    Thanks again for the background information!

    Kind regards,
    Peter
  • Hi Jarrod,

    Thank you for your the updates. I will be closing the ticket and if you are still experiencing issues, feel free to open the ticket in the future.

    Regards,
    Krunal
  • Krunal,

    Thanks for the help!  Here is the corrected asound.conf in case anyone stumbling across was curious:

    #Our output mixer/controller
    pcm.dmixed {
        type dmix
        ipc_key 2048
        ipc_perm 0666
        slave {
            pcm "hw:0,0"
            format S32_LE
            channels 2
            rate 48000
            period_size 682
            buffer_size 10912
        }
        bindings {
           0 0
           1 1
        }
    }
    
    #Our main 6 channel input mixer/controller
    pcm.imixed {
        type dsnoop
        ipc_key 3025
        ipc_perm 0666
        slave {
            pcm "hw:0,1"
            channels 6
            format S32_LE
            rate 48000
        }
        bindings {
            0 0
            1 1
            2 2
            3 3
            4 4
            5 5
        }
    }
    
    #This puts stereo out on just the "front"(VOUT1) jack
    pcm.frontx {
        type plug
        slave {
            pcm "dmixed"
            channels 2
        }
        ttable.0.0 1
        ttable.1.1 1
    }
    
    #Define the 2 channel line-in
    pcm.lineinx {
        type plug
        slave {
            pcm "imixed"
            channels 6
        }
        ttable.0.0 1
        ttable.1.3 1
    }
    
    #Define the 2 channel mic-in
    pcm.micinx {
        type plug
        slave {
            pcm "imixed"
            channels 6
        }
        ttable.0.1 1
        ttable.1.4 1
    }
    
    #Define the 2 channel dream-in
    pcm.dreaminx {
        type plug
        slave {
            pcm "imixed"
            channels 6
        }
        ttable.0.2 1
        ttable.1.5 1
    }

    The channel alignment was my big problem with using the multiple serializers and there were just other issues confusing it.  I still have an issue with my WM8580 codec ADC not behaving properly as a slave, it seems to be an MCLK issue, but since the master is not the AM335x either but another chip entirely this is not an issue for this forum, so yeah all solved from the AM335x side of things : ).

    Thanks!

    Jarrod