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.

J6EVM5777: JAMR3 multiple codec at a time

Part Number: J6EVM5777
Other Parts Discussed in Thread: TLV320AIC3106

Hello Mr/Mrs,

We are trying to make the 3 JAMR3 tlv320aic3106 codecs to be working at the same time. We are facing problems with "jamr3_sound" device-tree definition (dra7xx-jamr3.dtsi).

We are able to manage each one of the 3 codecs, but individually (I mean by generating a different dtb file each time).  To achieve it, what we do it is to change "simple-audio-card,routing" tags and the "sound-dai" of the codec side.

	jamr3_sound {
		compatible = "simple-audio-card";
		simple-audio-card,name = "DRA7xx-JAMR3";
		simple-audio-card,widgets =
			"Line", "Line Out",
			"Line", "Line In";
		simple-audio-card,routing =
			"Line Out",		"J3A LLOUT",
			"Line Out",		"J3A RLOUT",
			"J3A LINE1L",		"Line In",
			"J3A LINE1R",		"Line In";
		simple-audio-card,format = "dsp_b";
		simple-audio-card,bitclock-master = <&jamr3_sound_master>;
		simple-audio-card,frame-master = <&jamr3_sound_master>;
		simple-audio-card,bitclock-inversion;

		jamr3_sound_master: simple-audio-card,cpu {
			sound-dai = <&mcasp6>;
			system-clock-frequency = <11289600>;
		};

		simple-audio-card,codec {
			sound-dai = <&tlv320aic3106a>;
			clocks = <&atl_clkin1_ck>;
		};
	};

But when we try to define a link between CPU and the 3 codecs at a time, we are not succeeding. We have tried:

  • Several dai-links definition:
jamr3_sound {
		compatible = "simple-audio-card";
		simple-audio-card,name = "DRA7xx-JAMR3-CODECA";
		simple-audio-card,widgets =
			"Line", "Line Out B",
			"Line", "Line In B",
			"Line", "Line Out A",
			"Line", "Line In A";
		simple-audio-card,routing =
			"Line Out A",		"J3A LLOUT",
			"Line Out A",		"J3A RLOUT",
			"J3A LINE1L",		"Line In A",
			"J3A LINE1R",		"Line In A",
			"Line Out B",		"J3B LLOUT",
			"Line Out B",		"J3B RLOUT",
			"J3B LINE1L",		"Line In B",
			"J3B LINE1R",		"Line In B";
		simple-audio-card,format = "dsp_b";
		simple-audio-card,bitclock-master = <&jamr3_sound_master>;
		simple-audio-card,frame-master = <&jamr3_sound_master>;
		simple-audio-card,bitclock-inversion;

		//jamr3_sound_master: simple-audio-card,cpu {
		//	sound-dai = <&mcasp6>;
		//	system-clock-frequency = <11289600>;
		//};
		
		simple-audio-card,dai-link@0{
			simple-audio-card,cpu {
				sound-dai = <&mcasp6>;
			};

			simple-audio-card,codec {
				sound-dai = <&tlv320aic3106a>;
				clocks = <&atl_clkin1_ck>;
			};
		};

		simple-audio-card,dai-link@1{
			simple-audio-card,cpu {
				sound-dai = <&mcasp6>;
			};

			simple-audio-card,codec {
				sound-dai = <&tlv320aic3106b>;
				clocks = <&atl_clkin1_ck>;
			};
		};
	};




  • Several codec definition;
jamr3_sound {
		compatible = "simple-audio-card";
		simple-audio-card,name = "DRA7xx-JAMR3-CODECA";
		simple-audio-card,widgets =
			"Line", "Line Out B",
			"Line", "Line In B",
			"Line", "Line Out A",
			"Line", "Line In A";
		simple-audio-card,routing =
			"Line Out A",		"J3A LLOUT",
			"Line Out A",		"J3A RLOUT",
			"J3A LINE1L",		"Line In A",
			"J3A LINE1R",		"Line In A",
			"Line Out B",		"J3B LLOUT",
			"Line Out B",		"J3B RLOUT",
			"J3B LINE1L",		"Line In B",
			"J3B LINE1R",		"Line In B";
		simple-audio-card,format = "dsp_b";
		simple-audio-card,bitclock-master = <&jamr3_sound_master>;
		simple-audio-card,frame-master = <&jamr3_sound_master>;
		simple-audio-card,bitclock-inversion;

		jamr3_sound_master: simple-audio-card,cpu {
			sound-dai = <&mcasp6>;
			system-clock-frequency = <11289600>;
		};

		simple-audio-card,codec@0 {
			sound-dai = <&tlv320aic3106a>;
			clocks = <&atl_clkin1_ck>;
		};

		simple-audio-card,codec@1 {
			sound-dai = <&tlv320aic3106b>;
			clocks = <&atl_clkin1_ck>;
		};
	};



  • Several "cards" definition (if jamr3_sound_b is first defined, DRA7xx-JAMR3_B is mounted. If jamr3_sound_a is first defined, DRA7xx-JAMR3_A is mounted):
jamr3_sound_b {
		compatible = "simple-audio-card";
		simple-audio-card,name = "DRA7xx-JAMR3_B";
		simple-audio-card,widgets =
			"Line", "Line Out",
			"Line", "Line In";
		simple-audio-card,routing =
			"Line Out",		"J3B LLOUT",
			"Line Out",		"J3B RLOUT",
			"J3B LINE1L",		"Line In",
			"J3B LINE1R",		"Line In";
		simple-audio-card,format = "dsp_b";
		simple-audio-card,bitclock-master = <&jamr3_sound_master_b>;
		simple-audio-card,frame-master = <&jamr3_sound_master_b>;
		simple-audio-card,bitclock-inversion;

		jamr3_sound_master_b: simple-audio-card,cpu {
			sound-dai = <&mcasp6>;
			system-clock-frequency = <11289600>;
		};

		simple-audio-card,codec {
			sound-dai = <&tlv320aic3106b>;
			clocks = <&atl_clkin1_ck>;
		};
	};

	jamr3_sound_a {
		compatible = "simple-audio-card";
		simple-audio-card,name = "DRA7xx-JAMR3_A";
		simple-audio-card,widgets =
			"Line", "Line Out",
			"Line", "Line In";
		simple-audio-card,routing =
			"Line Out",		"J3A LLOUT",
			"Line Out",		"J3A RLOUT",
			"J3A LINE1L",		"Line In",
			"J3A LINE1R",		"Line In";
		simple-audio-card,format = "dsp_b";
		simple-audio-card,bitclock-master = <&jamr3_sound_master>;
		simple-audio-card,frame-master = <&jamr3_sound_master>;
		simple-audio-card,bitclock-inversion;

		jamr3_sound_master: simple-audio-card,cpu {
			sound-dai = <&mcasp6>;
			system-clock-frequency = <11289600>;
		};

		simple-audio-card,codec {
			sound-dai = <&tlv320aic3106a>;
			clocks = <&atl_clkin1_ck>;
		};
	};


Anyone could help us to well define the jamr3_sound to be able to manage the 3 codecs at the same time?

Thank you very much!

  • We use to support multi-codec in older Android kernels (3.14), not via simple-card but via custom ASoC machine driver. Looking at newer kernels, it looks like ASoC infrastructure exists but the simple-card (which you tried different variants of) doesn't support it.

  • So you mean that with state-to-the-art technology there is no way of using JAMR3 as it has been designed?

    How must/can we use the McASP?

  • Alejandro,

    simple-card is a generic card and it doesn't seem to support single CPU DAI + multiple CODEC DAIs. One can always write a own machine driver tailored to that specific architecture.

    If you are ok with stereo audio on JAMR3, you can enable JAMR3's McASP6 + single tlv320aic3106 codec using simple-card.

  • Hi ,

    After add support for multichannels codec ti,dra7xx-jamr3-multicodec-evm
    and port sound/soc/davinci/dra7xx-jamr3-card.c

    with this configuration on dts file :

    +       multicodec_sound {
    +               compatible = "ti,dra7xx-jamr3-multicodec-evm";
    +               ti,model = "DRA7xx-JAMR3";
    +               ti,always-on;
    +               clocks = <&atl_clkin1_ck>;
    +               clock-names = "ti,codec-clock";
    +
    +               ti,audio-routing =
    +                       "J3A LINE1L",           "JAMR3 Stereo Aux In",
    +                       "J3A LINE1R",           "JAMR3 Stereo Aux In",
    +                       "J3B LINE1L",           "JAMR3 Mono Mic 1",
    +                       "J3B LINE1R",           "JAMR3 Mono Mic 2",
    +                       "JAMR3 Line Out 1",     "J3A LLOUT",
    +                       "JAMR3 Line Out 1",     "J3A RLOUT",
    +                       "JAMR3 Line Out 2",     "J3B LLOUT",
    +                       "JAMR3 Line Out 2",     "J3B RLOUT",
    +                       "JAMR3 Line Out 3",     "J3C LLOUT",
    +                       "JAMR3 Line Out 3",     "J3C RLOUT";
    +
    +               /* Multichannel DAI link */
    +               ti,multichannel-cpu = <&mcasp6>;
    +               ti,multichannel-codec-a = <&tlv320aic3106a>;
    +               ti,multichannel-codec-b = <&tlv320aic3106b>;
    +               ti,multichannel-codec-c = <&tlv320aic3106c>;
    +               ti,multichannel-slots = <8>;
    +               ti,multichannel-mclk-freq = <11289600>;
    +               ti,multichannel-shared;
            };



            mcasp6: mcasp@48474000 {
                compatible = "ti,dra7-mcasp-audio";
                ti,hwmods = "mcasp6";
                op-mode = <0>;        /* MCASP_IIS_MODE */
                tdm-slots = <8>;
                num-serializer = <4>;
                tx-num-evt = <8>;
                rx-num-evt = <8>;
                reg = <0x48474000 0x2000>,
                      <0x4844c000 0x1000>;
                reg-names = "mpu","dat";
                interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
                         <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "tx", "rx";
                dmas = <&edma_xbar 139 1>, <&edma_xbar 138 1>;
                dma-names = "tx", "rx";
                clocks = <&mcasp6_aux_gfclk_mux>, <&mcasp6_ahclkx_mux>;
                clock-names = "fck", "ahclkx";
                status = "disabled";
            };
            
    the multicodec_sound detected

    [    2.945055] davinci-mcasp 48464000.mcasp: DAI is shared
    [    2.951175] davinci-mcasp 48474000.mcasp: DAI is shared
    [    2.956655] davinci-mcasp 4847c000.mcasp: invalid tdm slots: 0
    [    2.968443] dra7xx-jamr3-multicodec-evm multicodec_sound: multicodec <-> 48474000.mcasp mapping ok
     
    and all mixer ctl are present for J3A,B and C


    inymix -D 2 | grep -i J3 | grep -i  "DACL1 Switch"                            <
    165     BOOL    1       J3A Left Line Mixer DACL1 Switch         On
    171     BOOL    1       J3A Right Line Mixer DACL1 Switch        Off
    177     BOOL    1       J3A Left HP Mixer DACL1 Switch           On
    183     BOOL    1       J3A Right HP Mixer DACL1 Switch          Off
    189     BOOL    1       J3A Left HPCOM Mixer DACL1 Switch        On
    195     BOOL    1       J3A Right HPCOM Mixer DACL1 Switch       Off
    202     BOOL    1       J3A Mono Mixer DACL1 Switch              On
    227     BOOL    1       J3B Left Line Mixer DACL1 Switch         On
    233     BOOL    1       J3B Right Line Mixer DACL1 Switch        Off
    239     BOOL    1       J3B Left HP Mixer DACL1 Switch           On
    245     BOOL    1       J3B Right HP Mixer DACL1 Switch          Off
    251     BOOL    1       J3B Left HPCOM Mixer DACL1 Switch        On
    257     BOOL    1       J3B Right HPCOM Mixer DACL1 Switch       Off
    264     BOOL    1       J3B Mono Mixer DACL1 Switch              On
    289     BOOL    1       J3C Left Line Mixer DACL1 Switch         On
    295     BOOL    1       J3C Right Line Mixer DACL1 Switch        Off
    301     BOOL    1       J3C Left HP Mixer DACL1 Switch           On
    307     BOOL    1       J3C Right HP Mixer DACL1 Switch          Off
    313     BOOL    1       J3C Left HPCOM Mixer DACL1 Switch        On
    319     BOOL    1       J3C Right HPCOM Mixer DACL1 Switch       Off
    326     BOOL    1       J3C Mono Mixer DACL1 Switch              On
    act1000:/ #
    act1000:/ #


    act1000:/ # tinyplay /sdcard/audio.wav -D 2                                    
    Playing sample: 2 ch, 44100 hz, 16 bit


    but Audio routed only to "JAMR3 Line Out 1"

    Could you please review dst changes ?

    Regards,
    Chokri

  • I think that's expected. Audio is played on the line outs as follows:

    • Stereo sample file should be played on "Line Out 1"
    • 4-channel sample file should be played on "Line Out 1" and "Line Out 2"
    • 6-channel sample file should be played on "Line Out 1", "Line Out 2", "Line Out 3"

    Try playing a 4 or 6-channel sample file and check if audio gets rendered on the other line outputs.

  • Hi Misael,

    I tried with wav file 4 and 6 channels and audio not played on Line out 2 and 3

    act1000:/ # tinyplay /sdcard/m.wav -D 2                                        
    Playing sample: 4 ch, 44100 hz, 16 bit

    act1000:/ # tinyplay /sdcard/multi.wav  -D 2                                   
    Playing sample: 6 ch, 44100 hz, 16 bit

    130|act1000:/ # ls -l /sys/kernel/debug/asoc/DRA7xx-JAMR3/
    total 0
    drwxr-xr-x 3 root root 0 1970-01-01 00:00 48474000.mcasp
    drwxr-xr-x 3 root root 0 1970-01-01 00:00 codec:tlv320aic3x-codec.1-0018
    drwxr-xr-x 3 root root 0 1970-01-01 00:00 codec:tlv320aic3x-codec.1-0019
    drwxr-xr-x 3 root root 0 1970-01-01 00:00 codec:tlv320aic3x-codec.1-001a
    drwxr-xr-x 2 root root 0 1970-01-01 00:00 dapm
    -rw-r--r-- 1 root root 0 1970-01-01 00:00 dapm_pop_time
    drwxr-xr-x 3 root root 0 1970-01-01 00:00 platform:48474000.mcasp

    act1000:/ # ls -l /proc/device-tree/multicodec_sound/                          
    total 0
    -r--r--r-- 1 root root  15 2019-07-31 07:35 clock-names
    -r--r--r-- 1 root root   4 2019-07-31 07:35 clocks
    -r--r--r-- 1 root root  31 2019-07-31 07:35 compatible
    -r--r--r-- 1 root root  17 2019-07-31 07:35 name
    -r--r--r-- 1 root root   0 2019-07-31 07:35 ti,always-on
    -r--r--r-- 1 root root 280 2019-07-31 07:35 ti,audio-routing
    -r--r--r-- 1 root root  13 2019-07-31 07:35 ti,model
    -r--r--r-- 1 root root   4 2019-07-31 07:35 ti,multichannel-codec-a
    -r--r--r-- 1 root root   4 2019-07-31 07:35 ti,multichannel-codec-b
    -r--r--r-- 1 root root   4 2019-07-31 07:35 ti,multichannel-codec-c
    -r--r--r-- 1 root root   4 2019-07-31 07:35 ti,multichannel-cpu
    -r--r--r-- 1 root root   4 2019-07-31 07:35 ti,multichannel-mclk-freq
    -r--r--r-- 1 root root   0 2019-07-31 07:35 ti,multichannel-shared
    -r--r--r-- 1 root root   4 2019-07-31 07:35 ti,multichannel-slots
    act1000:/ #

    Do you know please if any other debug tool to check why audio can not be routed ?

    Regards,

    Chokri

  • Chokri,

    There are some options to explore here: http://www.ti.com/lit/an/sprac10/sprac10.pdf

    For instance, please try reading the stream's status procfs entry (section 2 in above app note) and make sure that hw_ptr and appl_ptr are changing. This would indicate that McASP is consuming the samples and probably you are missing amixer control settings.

    Also take a look at section 6 as couple of debug pointers there are applicable for playback.

    BTW, did you hear any audio on JAMR3's "Line Out 1" while playing 4 or 6 channels? Make sure that codec-b and codec-c have the same mixer control settings as codec-c.

  • Thank you so much !

    Got it !  Volume mixer ctrl is not the same :

    act1000:/ # tinymix -D 2 | grep -i "Line DAC Playback Volume"                  
    27      INT     2       J3A Line DAC Playback Volume             118 118
    75      INT     2       J3B Line DAC Playback Volume             71 71
    123     INT     2       J3C Line DAC Playback Volume             71 71
    act1000:/ #
    act1000:/ # tin
    tinycap   tinymix   tinyplay
    act1000:/ # tinymix -D 2 75 118                                                
    act1000:/ # tinymix -D 2 123 118                                               
    act1000:/ #
    130|act1000:/ # tinyplay /sdcard/multi.wav -D 2  
    Playing sample: 6 ch, 44100 hz, 16 bit

    And now the audio if played on the 3 output lines.

    Regards

    Chokri

  • Hi Misael,

    Thank you for your support.

    Now, we are able to play an audio with 6 channels and routed like :
    Channel 1-2 => Line Out1
    Channel 3-4 => Line Out2
    Channel 5-6 => Line Out3

    In order to split multi-audio channels by codec

    Is it possible/supported to create pcm device for each JAMR3 codecs ?

    tinplay test.wav -D 2 -d 1  //codec-a

    tinplay test.wav -D 2 -d 2 //codec-b

    tinplay test.wav -D 2 -d 3 //codec-c

    Regards,

    Chokri

  • In kernel, no. In Android userspace, not possible either. One would have to implement an own "merge streams" logic in the audio HAL.

    In Linux one could create virtual PCM devices using ALSA plugins and have the stereo streams merged in userspace.

  • Hi Misael,

    Thank you !

    I integrated alsa-utils and alsa-lib to android 8.1.1

    And using virtual pcm device, we are able to play an audio for each codec.

    pcm.codec_a {
        type route
        slave.pcm "hw:2,0"
        slave.channels 6
        ttable.0.0 1
        ttable.1.1 1
    }

    pcm.codec_b {
        type route
        slave.pcm "hw:2,0"
        slave.channels 6
        ttable.0.2 1
        ttable.1.3 1
    }

    pcm.codec_c {
        type route
        slave.pcm "hw:2,0"
        slave.channels 6
        ttable.0.4 1
        ttable.1.5 1
    }

    alsa_aplay /sdcard/test.wav  -Dcodec_a
    alsa_aplay /sdcard/test.wav  -Dcodec_b
    alsa_aplay /sdcard/test.wav  -Dcodec_c

    Regards,

    Chokri