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.

ALSA support of multiple Tx and RX channels on one McASP(McASP0) in DM8148

Other Parts Discussed in Thread: PCM5102A

HI,

I want to configure the McASP0 serializers to have 4 tx and 4 Rx lines. Is it possible to have such a configuration ? Any programming guide to do the same?

Is the McASP driver present in the PSP supports the same?

 

 

 

Thanks and Regards

Ansa

 

 

  • Hi,

    Currently the mcasp driver does not support multiple serializers.

    Regards,

    Vaibhav

  • Hi,

    I am trying to add use multiple serializers (4 TX and 4 RX) in DM8148 McASP0. I am using the PSP release linux-2.6.37-psp04.01.00.05.patch1 that has code for 1 channel (1 TX and 1 RX ) only. I have gotten 1 TX and 1 RX working in my board using DM5148 McASP. But when I add 3 more channels to this framework, I see that DMA IRQ is not coming. Following are the modifications I made to the default architecture. Please tell me if I am missing something.

    1. In arch/arm/mach-omap2/devices.c I have defined that I am using McASP0 as given below.

    static struct resource ti81xx_mcasp_resource[] = {
    {
    .name = "mcasp",
    .start = TI81XX_ASP0_BASE,
    .end = TI81XX_ASP0_BASE + (SZ_1K * 12) - 1,
    .flags = IORESOURCE_MEM,
    },
    /* TX event */
    {
    .start = TI81XX_DMA_MCASP0_AXEVT,
    .end = TI81XX_DMA_MCASP0_AXEVT,
    .flags = IORESOURCE_DMA,
    },
    /* RX event */
    {
    .start = TI81XX_DMA_MCASP0_AREVT,
    .end = TI81XX_DMA_MCASP0_AREVT,
    .flags = IORESOURCE_DMA,
    },
    };
    2. I have defined the serializers I will be using in arch/arm/mach-omap2/board-ti8148evm.c as given below.
    static u8 ti8148_iis_serializer_direction_mcasp0[] = {
    TX_MODE, TX_MODE, TX_MODE, TX_MODE,
    RX_MODE, RX_MODE, RX_MODE, RX_MODE,
    INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
    INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
    };
    static struct snd_platform_data ti8148_evm_snd_data = {
    .tx_dma_offset = 0x46000000,
    .rx_dma_offset = 0x46000000,
    .op_mode = DAVINCI_MCASP_IIS_MODE,
    .num_serializer = ARRAY_SIZE(ti8148_iis_serializer_direction_mcasp0),
    .tdm_slots = 1,
    .serial_dir = ti8148_iis_serializer_direction_mcasp0,
    .asp_chan_q = EVENTQ_2,
    .version = MCASP_VERSION_2,
    .txnumevt = 4,
    .rxnumevt = 4,
    };
    3. I have mentioned that I will use 4 dai's in McASP0 in sound/soc/davinci/davinci-evm.c as given below.
    static struct snd_soc_dai_link grg_dai[] = {
    {
    .name = "PCM3501E.0", /* Codec name */
    .stream_name = "PCM3501EStream.0", /* Stream name */
    .cpu_dai_name = "davinci-mcasp.0", /* McASP instance to be Used */
    .codec_dai_name = "pcm3501e-hifi",
    .codec_name = "pcm3501e-codec.0", /* for multi-codec */
    .platform_name = "davinci-pcm-audio", /* for multi-platform */
    .init = NULL, /* codec/machine specific init - e.g. add machine controls */
    .ops = &grg_snd_soc_ops, /* machine stream operations */
    },
    {
    .name = "PCM3501E.1", /* Codec name */
    .stream_name = "PCM3501EStream.1", /* Stream name */
    .cpu_dai_name = "davinci-mcasp.0", /* McASP instance to be Used */
    .codec_dai_name = "pcm3501e-hifi",
    .codec_name = "pcm3501e-codec.1", /* for multi-codec */
    .platform_name = "davinci-pcm-audio", /* for multi-platform */
    .init = NULL, /* codec/machine specific init - e.g. add machine controls */
    .ops = &grg_snd_soc_ops, /* machine stream operations */
    },
    {
    .name = "PCM3501E.2", /* Codec name */
    .stream_name = "PCM3501EStream.2", /* Stream name */
    .cpu_dai_name = "davinci-mcasp.0", /* McASP instance to be Used */
    .codec_dai_name = "pcm3501e-hifi",
    .codec_name = "pcm3501e-codec.2", /* for multi-codec */
    .platform_name = "davinci-pcm-audio", /* for multi-platform */
    .init = NULL, /* codec/machine specific init - e.g. add machine controls */
    .ops = &grg_snd_soc_ops, /* machine stream operations */
    },
            {
                    .name           = "PCM3501E.3",             /* Codec name */
    .stream_name = "PCM3501EStream.3", /* Stream name */
    .cpu_dai_name = "davinci-mcasp.0", /* McASP instance to be Used */
    .codec_dai_name = "pcm3501e-hifi",
    .codec_name = "pcm3501e-codec.3", /* for multi-codec */
    .platform_name = "davinci-pcm-audio", /* for multi-platform */
    .init = NULL, /* codec/machine specific init - e.g. add machine controls */
    .ops = &grg_snd_soc_ops, /* machine stream operations */
    },
    };
    Note - The codec I am using is PCM3501e and in its driver I have defined 4 codec dais to correspond to this definition.
    4. When the board boots up, I can see that 4 pcm nodes come up as given below.
    controlC0  pcmC0D0p   pcmC0D1p   pcmC0D2p   pcmC0D3p
    pcmC0D0c pcmC0D1c pcmC0D2c pcmC0D3c timer
    5. Also enabling the debug messages I am seeing that each of the codec dai's are getting DMA allocated. See the dump at the end of the post.
    6. When I try to playback a file using aplay, I see that no DMA IRQs are getting generated. The dump is given below.
    ===========================================================================================================
    Register dump with first channel accessed.
    aplay -D"hw:0,0" -r16000 -traw -fS16_LE -c1  sine.wav.raw
    Reg  Value (0x0) : 44307302
    Reg Value (0x10) : 0
    Reg Value (0x14) : b400000f
    Reg Value (0x18) : 0
    Reg Value (0x1c) : 7c000090
    Reg Value (0x20) : 0
    Reg Value (0x44) : 1f00
    Reg Value (0x48) : 0
    Reg Value (0x4c) : 0
    Reg Value (0x50) : 0
    Reg Value (0x60) : 1f00
    Reg Value (0x64) : ffff
    Reg Value (0x68) : 74
    Reg Value (0x6c) : 2
    Reg Value (0x70) : 18009f
    Reg Value (0x74) : 8000
    Reg Value (0x78) : 0
    Reg Value (0x7c) : 0
    Reg Value (0x80) : 104
    Reg Value (0x84) : 0
    Reg Value (0x88) : 0
    Reg Value (0x8c) : 0
    Reg Value (0xa0) : 1f00
    Reg Value (0xa4) : ffff
    Reg Value (0xa8) : 18074
    Reg Value (0xac) : 82
    Reg Value (0xb0) : bf
    Reg Value (0xb4) : 0
    Reg Value (0xb8) : 1
    Reg Value (0xbc) : 0
    Reg Value (0xc0) : 175
    Reg Value (0xc4) : 0
    Reg Value (0xc8) : 85000000
    Reg Value (0xcc) : 0
    Reg Value (0x100) : 0
    Reg Value (0x104) : 0
    Reg Value (0x108) : 0
    Reg Value (0x10c) : 0
    Reg Value (0x110) : 0
    Reg Value (0x114) : 0
    Reg Value (0x118) : 0
    Reg Value (0x11c) : 0
    Reg Value (0x120) : 0
    Reg Value (0x124) : 0
    Reg Value (0x128) : 0
    Reg Value (0x12c) : 0
    Reg Value (0x130) : 0
    Reg Value (0x134) : 0
    Reg Value (0x138) : 0
    Reg Value (0x13c) : 0
    Reg Value (0x140) : 0
    Reg Value (0x144) : 0
    Reg Value (0x148) : 0
    Reg Value (0x14c) : 0
    Reg Value (0x150) : 0
    Reg Value (0x154) : 0
    Reg Value (0x158) : 0
    Reg Value (0x15c) : 0
    Reg Value (0x180) : 11
    Reg Value (0x184) : 11
    Reg Value (0x188) : 11
    Reg Value (0x190) : 2
    Reg Value (0x194) : 2
    Reg Value (0x200) : 0
    Reg Value (0x204) : 0
    Reg Value (0x208) : 0
    Reg Value (0x20c) : 0
    Reg Value (0x210) : 0
    Reg Value (0x214) : 0
    Reg Value (0x280) : 0
    Reg Value (0x284) : 0
    Reg Value (0x288) : 0
    Reg Value (0x28c) : 0
    Reg Value (0x290) : 0
    Reg Value (0x294) : 0
    Reg Value (0x1000) : 11004
    Reg Value (0x1004) : 0
    Reg Value (0x1008) : 1004
    Reg Value (0x100c) : 0
    ===========================================================================
    debug prints when the playback is happening
    
    
    Enter McASP : davinci_mcasp_startup +953
    EDMA: EER0 00000000
    asoc: pcm3501e-hifi <-> davinci-mcasp.0 info:
    asoc: rate mask 0x8
    asoc: min ch 1 max ch 2
    asoc: min rate 16000 max rate 16000
    Enter McASP : davinci_mcasp_set_dai_fmt +518
    Exit : grg_snd_soc_hw_params +65
    Enter: sound/soc/codecs/pcm3501e.c +38
    Enter McASP : davinci_mcasp_hw_params +865
    Enter McASP : davinci_hw_common_param +705
    Enter McASP : davinci_hw_param +766
    Enter McASP : davinci_config_channel_size +621
    davinci_pcm: audio_set_dma_params_play channel = 191 dma_ptr = 872a0000 period_size=fa0
    davinci_pcm: audio_set_dma_params_play channel = 191 dma_ptr = 872a0fa0 period_size=fa0
    EDMA: ER0 00000000
    EDMA: EER0 00000100
    pcm3501e-codec pcm3501e-codec.0: Setting standby bias
    pcm3501e-codec pcm3501e-codec.0: Setting bias prepare
    pcm3501e-codec pcm3501e-codec.0: Setting full bias
    Enter McASP : davinci_mcasp_trigger +915
    Enter McASP : davinci_mcasp_start +463
    Enter McASP : mcasp_start_tx +416
    ALSA sound/core/pcm_lib.c:1765: playback write error (DMA or IRQ trouble?)
    ALSA sound/core/pcm_lib.c:1765: playback write error (DMA or IRQ trouble?)
    Enter McASP : davinci_mcasp_trigger +915
    Enter McASP : davinci_mcasp_stop +498
    Enter McASP : mcasp_stop_tx +489
    EDMA: EER0 00000000
    pop wq checking: PCM3501E Playback status: inactive waiting: yes
    pcm3501e-codec pcm3501e-codec.0: Setting bias prepare
    pcm3501e-codec pcm3501e-codec.0: Setting standby bias
  • Hi,

    I am new to ALSA and sound programming.

    My development platform is  Beagle bone board which is having AM335XX processor and from Beagle bone two I2S channels are interfacing to the  NUVOTON ISD61S00 Voice Corder chips I2S interfaces.

    I2S_SCLK,I2S_WS,I2S0_TXD,I2S0_RXD,I2S1_TXD,I2S1_RXD.

    Both the channels are using same clock and word select pins. Nuvoton sound card is the master which generates the clock and wordselect.

    I am looking into the source code in the following path :

    ocap@ocap-laptop:~$ cd /home/ocap/ti-sdk-am335x-evm-05.03.00.00/board-support/linux-3.0+3.1-rc8-psp04.06.00.01.sdk/sound/soc/davinci/

    -rw-r--r-- 1 ocap ocap  9710 2012-02-24 18:34 davinci-evm.c
    -rw-r--r-- 1 ocap ocap 24366 2012-02-24 12:11 davinci-i2s.c
    -rw-r--r-- 1 ocap ocap   222 2012-02-24 12:27 davinci-i2s.h
    -rw-r--r-- 1 ocap ocap 28416 2012-02-24 14:16 davinci-mcasp.c
    -rw-r--r-- 1 ocap ocap  1378 2011-10-22 17:21 davinci-mcasp.h
    -rw-r--r-- 1 ocap ocap 26412 2012-02-24 22:50 davinci-pcm.c
    -rw-r--r-- 1 ocap ocap  1000 2012-02-23 14:28 davinci-pcm.h
    -rw-r--r-- 1 ocap ocap  3346 2012-02-21 17:49 Kconfig
    -rw-r--r-- 1 ocap ocap   955 2012-02-21 17:50 Makefile

    I have interfaced the ISD61S00 with I2S channels only. ISD61S00 programming is done by other chip(Non-linux based Microcontroller).

    I want to play a 8KHz Sampling Wave file using 'aplay' and stream the Audio on these two channels.(I2S0/I2S1 - McASP ports).

    In AM335XX Schematic I have interfaced the McASP0 and McASP1 I2S pins to Sound card chip's I2S.

    Can you please tel me how shall I start the experiment? Need directions and suggestions about Streaming audio data through these two I2S channels.

    Thanks,

  • Hi Ansa Ahmed and everyone,

    Can anybody give me some pointers regarding creation of Multiple instances of MCASP0/1 for two codecs.

    I am using AM335x processor and wants to use both MCASP0 and MCASP1 for Audio Capture and PLAYBACK at a time.

    In my desgin I am interfacing the MCASP0 CPU DAI to TLV320AIC23 and MCASP1 CPU DAI to TLV320AIC3X.

    I am able to stream out and capture the audio data in MCASP1 and but not on MCASP0.At bootup time I am seeing only "tlv320aic3x-hifi" not tlv320aic23. even though I have made the below changes.

    sound/soc/davinci/davinci-evm.c

    static struct snd_soc_dai_link am335x_evm_dai[ ] = {

    {
    .name = "TLV320AIC3X",
    .stream_name = "AIC3X",
    .cpu_dai_name = "davinci-mcasp.1",
    .codec_dai_name = "tlv320aic3x-hifi",
    .codec_name = "tlv320aic3x-codec.2-001a",
    .platform_name = "davinci-pcm-audio",
    .init = evm_aic3x_init,
    .ops = &evm_ops,

    }.

    {
    .name = "TLV320AIC23",
    .stream_name = "AIC23",
    .cpu_dai_name = "davinci-mcasp.0",
    .codec_dai_name = "tlv320aic23-hifi",
    .codec_name = "tlv320aic23-codec",
    .platform_name = "davinci-pcm-audio",
    .//init = evm_aic3x_init,
    .ops = &evm_ops,

    },
    };

    I havemade the changes for MCASP0 and 1  in devices.c and board-am335-evm.c

    Can you please tel me where I am missing.I am not able to see two devcies at bootup time.

    Waiting for your valuable reply

     

     

     

     

  • Hi anees Ka,

    Did you solve it ? I have same problem.

    My target board is BeagleBone A3 based on am335x-evm-sdk-src-05.03.03.00

    Thanks,

    Kay

  • Similar problem here. I'm trying to create an audio device with 8 output channels for a Beaglebone Black. The device uses 4 PCM5102A DACs, and I want to synchronously transmit 4 stereo streams to them using mcasp0 axr0, axr1, axr2 and axr3. I have a working ALSA version of a 2 output channel DAC using one PCM5102A, by following the tutorial article published by TI (http://processors.wiki.ti.com/index.php/Sitara_Linux_SDK_Audio_DAC_Example).

    I'm not sure how to proceed. Do I need to create 4 DAI's as subdevices? How do I do that?

    /s John Rhoades

  • Hi John,

    I've never attempted this configuration, but it might not be too difficult to get it working.  If I get some time this week, I'll mess around with it on my Beagle Bone.

    I think that you might have to do something along of the lines of:

    1. Set enable 4 tx serializers in your McASP0 node:

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

    2. Modify asound.conf to properly identify the 4 TX elements in McASP0 in user space (this would be up to you how to do based on how you want to playback to work).  The Sitara Linux SDK Audio page has some info on this--look in the ALSA user space interfaces section and the TDM example in the debug section.

  • Wow, this actually works, sort of. There are some issues, which I do not fully understand. However the sound quality seems perfect.


    1)  I would think the correct bit clock for 88200 Hz 16 bit samples would be 2*16*88200 = 28222400, but I actually see 11289600, which is 4x too big. Attached is a oscope shot with 200 ns/division.

    2) With 32 bit samples at 88200 Hz, it still works, but I get occasional xruns. These go away mostly if I renice aplay to highest possible priority. (What I really want is a real-time 3.15.4 kernel or at least low latency one)

    3) Something is fishy with P9-41. The audio signal for axr1 is there, but noisy, and I get sputtering along with the correct music sound.

    output from aplay -v -r 88200 -f S16_LE -c 8 -

    Playing raw data 'stdin' : Signed 16 bit Little Endian, Rate 88200 Hz, Channels 8
    Hardware PCM card 0 'TI PCM5102A' device 0 subdevice 0
    Its setup is:
      stream       : PLAYBACK
      access       : RW_INTERLEAVED
      format       : S16_LE
      subformat    : STD
      channels     : 8
      rate         : 88200
      exact rate   : 88200 (88200/1)
      msbits       : 16
      buffer_size  : 8192
      period_size  : 512
      period_time  : 5804
      tstamp_mode  : NONE
      period_step  : 1
      avail_min    : 512
      period_event : 0
      start_threshold  : 8192
      stop_threshold   : 8192
      silence_threshold: 0
      silence_size : 0
      boundary     : 1073741824
      appl_ptr     : 0
      hw_ptr       : 0

    Debug output from kernel module pcm5102a:

    [  553.856720] PCM5102a hw params
    [  553.856841] sysclk=22579200
    [  553.856860] rate=88200
    [  553.856874] width=16
    [  553.856887] channels=8
    [  553.856900] bclk=11289600
    [  553.856916] set cpu clk to IN

    I used

    in am335x-boneblack.dts:

    &mcasp0 {
            pinctrl-names = "default";
            pinctrl-0 = <&mcasp0_pins>;
            status = "okay";
            op-mode = <0>;          /* MCASP_IIS_MODE */
            tdm-slots = <2>;
            /* 16 serializers */
            serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
                1 1 1 1
            >;
            tx-num-evt = <8> /* was <32>*/;
            rx-num-evt = <8> /* was <32>*/;
    };
     
    / {
     
        pcm5102a: pcm5102a {
            compatible = "ti,pcm5102a";
        };
     
        sound {
            compatible = "ti,pcm5102a-evm-audio";
            ti,model = "TI PCM5102A";
            ti,audio-codec = <&pcm5102a>;
            ti,mcasp-controller = <&mcasp0>;
            ti,codec-clock-rate = <22579200>;
        };
    &am33xx_pinmux {
        mcasp0_pins: mcasp0_pins {
            pinctrl-single,pins = <
                0x190 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* P9-31 mcasp0_aclkx */
                0x194 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* P9-29 mcasp0_fsx*/
                0x198 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* P9-30 mcasp0_axr0 */
                /* 0x1A8 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* P9-41 mcasp0_axr1 something wrong*/
                0x0D8 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* P8-31 mcasp0_axr1 */
                0x19C (PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* P8-28 mcasp0_axr2 */
                0x1A4 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* P8-27 mcasp0_axr3 */
                //0x19C (PIN_INPUT_PULLUP    | MUX_MODE0)    /* P9-28 mcasp0_achlkr */
                0x1AC (PIN_INPUT_PULLUP    | MUX_MODE0)    /* P9-25 mcasp0_achlkx */
            >;
        };
    };

     
    };

    in pcm5102a:

    static struct snd_soc_dai_driver pcm5102a_dai = {
        .name        = "pcm5102a-hifi",
        .playback     = {
            .stream_name    = "Playback",
            .channels_min    = 2,
            .channels_max    = 8,
            .rates        = RATES,
            .formats    = FORMATS,
        },
    };

  • 1) I'm not sure about why it's doing that--I'll think about it and play around with some things and get back to you when I can.

    2) Do you see a high cpu load?  If not, maybe increasing the priority of the McASP in the EMIF class of service could help.

    3) I wonder if you are running into a pin set violation.  Check out this post for some more details.

  • 1) BBB CPU load at (alsa specified) 44100 Hz, 32 bit samples, 8 channels is 32%. Half of that is aplay and half of that is nc (nc is a network socket program that I am using to transfer the audio data from my PC to the BBB.) No xruns. Even though I told alsa to run at 44100, the DAC chips are actually receiving data at 176400! I'm looking at the bit clock on my scope and I see one clock cycle is about 90 ns (11 MHz), and there are 64 bit clocks per LR clock at the DAC chips. So, somehow the mcasp level of Linux sound software is deciding it should run at 176400 Hz, i.e., 4x what alsa thinks the sample rate is. There are 4 DAC chips. Somewhere in the system I guess there is a missing "divide by the number of active serializers." I'm running R. Nelson's Linux 3.15.4-bone4 OS, BTW.

    The PCM5102A is rated up to 384 kHz. If I tell alsa to run at 88.2 kHz, the DAC chips actually receive data at 352.8 kHz. And it all "just works." According to "top" the CPU load is 63%. Once in a while, there is an xrun, maybe every 5-10 minutes. These seem to go away if I "renice" alsa and nc to highest priority. The buffer size is 4096 and the period size is 256. At this rate the CPU has to fetch a new buffer every 11 ms. alsa ignores my attempts to increase the buffer size; it must be hard-coded somewhere.


    2) I think I'm pushing the CPU too hard at an effective sample rate of 352.8 kHz. For my application (a digital crossover for two loudspeakers each having four drivers), a sample rate of 88.2 kHz would be just fine. Extrapolating from the above, I guess the CPU load would only be about 16%. I think this would leave plenty of compute cycles for the digital filter code (currently running on the host PC).

    3) I will check this.


    All in all, the system is working beautifully already, in spite of the quirks. I'll make some noise and distortion measurements when I get my ADC chip up and running, but to my ears it sounds extremely clean and the residual noise level is so low I can barely hear a slight hiss with my ear 2 inches from the speaker at max volume when playing silence. Amazing what you can do for a couple of hundred bucks nowadays. This system is soon to replace my $2000 studio quality DAC.

  • FYI, thanks for the hints and help. For your enjoyment here are some pics of the system. It comprises three units, a transmitter and two receivers.

    The transmitter provides the audio master clock to the BBB. It takes the I2S clock and data signals from the BBB and sends them over two Ethernet cables to the receivers using low voltage differential signalling.

    Each receiver unit contains two DACs. It converts the LVDS clock and data signals from the Ethernet cable back to 3.3v logic levels and sends them on to the DACs.

    The reason for sending the data digitally is so that the DACs can be very close to the amplifiers and speakers. Good quality speaker and analog cables are expensive. Ethernet cable is dirt cheap. Another advantage is avoidance of ground loops. The differential signalling protocol can withstand 3-4 volts of common mode noise and still transfer bit-perfect data over up to 30 feet of cat5 cable. The transmitter and receivers can be on different mains circuits and there is no hum going to the amplifiers.

  • Very cool project!  Besides a few issues, it looks like you're almost there.  I'm gonna add this forum post to the main Sitara Audio page to accompany the Audio DAC tutorial; I've been wanting to test out the simultaneous use of all 4 McASP serializers for a while now.  When I get a chance, I'll take a look at the McASP driver and see if it makes any sense why the sampling rate is being set so high.