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.

McASP On Beaglebone (No sound card)

Hi,

I'm not able to get the McASP.0 up and running on my BeagleBone. When I use 'arecord' then it says "no sound card found".

I want to use McASP.0  I have done pin-muxing correctly (no conflicts) and initialized the mcasp.0 peripheral.

In the davinci_evm.c I have added another
struct snd_soc_dai_link my_dai_link = {
    .name = "McASP0",
    .stream_name = NULL,
    .cpu_dai_name = "davinci-mcasp.0",
    .codec_dai_name = NULL,
    .codec_name = NULL,
    .platform_name = "davinci-pcm-audio",
    .ops = &evm_ops,
};

In my setup I do not have a codec. I want to communicate to another processor over TDM.

Any suggestions what can be a issue?

-Prasant

  • Hi,

    I probed into the soc-core.c and the device fails to instantiate at soc_bind_dai_link().

    The reason is that the ASoC core does not find the codec and cannot only use McASP.

    Can we use ASoC without a codec ?

    Do we have a dummy codec for ASoC?

    -Prasant

  • Assuming that you are using the DVI cape with Beaglebone, please refer the patch in this forum post:

    http://e2e.ti.com/support/dsp/sitara_arm174_microprocessors/f/791/p/184720/671404.aspx#671404

    Thank you!

    Regards, Punya

  • Hi,

    Answering his question on driving the McASP using the ASoC framework without having to require a codec:

    There is a dummy codec that I've noticed in sound/soc/codecs/ that could be of use . grep for dit-hifi

    Joel

  • Hi,

    I faced same problem in our setup which has to send audio stream on mcasp0 as I2S. I am using TFA9882 to convert I2S signal to analog to drive a twitter.

    MCASP0_ACLKX,MCASP0_FSX,MCASP0_AXR0 are our signals so

    static u8 mt_board_iis_serializer_direction0[] = {
          TX_MODE,    INACTIVE_MODE,    INACTIVE_MODE,    INACTIVE_MODE,
    INACTIVE_MODE,    INACTIVE_MODE,    INACTIVE_MODE,    INACTIVE_MODE,
    INACTIVE_MODE,    INACTIVE_MODE,    INACTIVE_MODE,    INACTIVE_MODE,
    INACTIVE_MODE,    INACTIVE_MODE,    INACTIVE_MODE,    INACTIVE_MODE,
    };

    static struct snd_platform_data am335x_evm_snd_data0 = {
            .tx_dma_offset  = 0x46000000,   /* McASP0 */
            /*.rx_dma_offset  = 0x46000000,*/
            .op_mode        = DAVINCI_MCASP_IIS_MODE,
            .num_serializer = ARRAY_SIZE(mt_board_iis_serializer_direction0),
            .tdm_slots      = 2,
            .serial_dir     = mt_board_iis_serializer_direction0,
            .asp_chan_q     = EVENTQ_2,
            .version        = MCASP_VERSION_3,
            .txnumevt       = 1,
            .rxnumevt       = 1,
    };

    static struct pinmux_config mcasp0_pin_mux_delta2[] = {
        {"mcasp0_aclkx.mcasp0_aclkx", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLDOWN},
        {"mcasp0_fsx.mcasp0_fsx", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLDOWN},
        {"mcasp0_axr0.mcasp0_axr0", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLDOWN},
        {NULL, 0},
    };

    and finally I use

    static struct snd_soc_dai_link am335x_evm_dai = {
            .name = "McASP",
            .stream_name = NULL,
            .cpu_dai_name= "davinci-mcasp.0",
            .codec_dai_name = "dit-hifi",
            .codec_name = "dit-hifi",
            .platform_name = "davinci-pcm-audio",
            .ops = &evm_ops,
    };

    but I am getting no sound card found when run aplay?

    please any advice

    Best regard

    Emre

  • Hello all,

    I've recently been working on interfacing an I2S device that isn't a codec to AM335x and was able to get it working with McASP0, so I will share some of what I used.  This is for 3.2 kernel from our 6.00 SDK.  In the future I will be duplicating these efforts on 3.12, though.

    For my configuration, I used an external I2S device that I set up as a master--it was generating the bit clock (ACLK) and the word clock (FSYNC) and sending those signals to AM335x along with the two serial data lines.

    I will create a big patch for all these changes later, but for now I will describe step  by step what I did.

    I'll start with board file changes.  I added some new structures that mirrored what was in place for McASP1:

    static struct snd_platform_data am335x_evm_snd_data0 = {
            .tx_dma_offset  = 0x46000000,   /* McASP0 */
            .rx_dma_offset  = 0x46000000,
            .op_mode        = DAVINCI_MCASP_IIS_MODE,
            .num_serializer = ARRAY_SIZE(am335x_iis_serializer_direction0),
            .tdm_slots      = 2,
            .serial_dir     = am335x_iis_serializer_direction0,
            .asp_chan_q     = EVENTQ_2,
            .version        = MCASP_VERSION_3,
            .txnumevt	= 32,
    	.rxnumevt	= 32,
    	.get_context_loss_count	=
    			omap_pm_get_dev_context_loss_count,
    };
    static u8 am335x_iis_serializer_direction0[] = {
    	TX_MODE,	RX_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
    	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
    	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
    	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
    };
    /* Module pin mux for mcasp0 */
    static struct pinmux_config mcasp0_pin_mux[] = {
    	{"mcasp0_aclkx.mcasp0_aclkx", OMAP_MUX_MODE0 |AM33XX_PIN_INPUT_PULLDOWN},
    	{"mcasp0_fsx.mcasp0_fsx", OMAP_MUX_MODE0   |AM33XX_PIN_INPUT_PULLDOWN},
    	{"mcasp0_axr0.mcasp0_axr0", OMAP_MUX_MODE0 |AM33XX_PIN_OUTPUT_PULLUP},
    	{"mcasp0_axr1.mcasp0_axr1", OMAP_MUX_MODE0 |AM33XX_PIN_INPUT_PULLDOWN},
    	{NULL, 0},
    };
    /* Setup McASP 0 */
    static void mcasp0_init(int evm_id, int profile)
    {
            /* Configure McASP */
            setup_pin_mux(mcasp0_pin_mux);
            am335x_register_mcasp(&am335x_evm_snd_data0, 0);
            return;
    }

    I did this on a AM335x GP EVM, so I added the the following line to the GP EVM dev config structure:

    {mcasp0_init,   DEV_ON_BASEBOARD, PROFILE_ALL},

    Now onto configuring the audio device so that ALSA can use it.  My original intent was to a create a separate "dummy codec" driver that really didn't do much except initialize some basic parameters required by ALSA and also to tell the McASP how I want it to be configured.  In the interest of time, however, it was decided to use some added code from another project that added a "null-codec" structure to sound/soc/soc-core.c.

    The first step was to create a structure for this null codec in sound/soc/soc-core.c.  On line 744 of an unmodified 3.2 kernel source from SDK 6.00, here is what I added:

    static struct snd_soc_dai_ops null_dai_ops = {
    };
    
    static struct snd_soc_codec_driver null_codec_drv = {};
    
    static struct snd_soc_dai_driver null_codec_dai_drv = {
    
              .name = "null-codec-dai",
              .playback = {
                      .channels_min = 1,
                      .channels_max = 2,
                      .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
                                              SNDRV_PCM_RATE_48000,
                      .formats = SNDRV_PCM_FMTBIT_S16_LE,
              },
              .capture = {
                      .channels_min = 1,
                      .channels_max = 2,
                      .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
                                              SNDRV_PCM_RATE_48000,
                      .formats = SNDRV_PCM_FMTBIT_S16_LE,
              },
    
    };

    The values in that structure can be modified to fit your needs.

    Next, I added some new checks in sound/soc/soc-core.c to accommodate the null-codec.  Here is a partial snip from a patch I am creating that shows my changes:

    @@ -2813,7 +2851,7 @@
      */
     int snd_soc_register_card(struct snd_soc_card *card)
     {
    -	int i;
    +	int i, ret;
     
     	if (!card->name || !card->dev)
     		return -EINVAL;
    @@ -2832,7 +2870,21 @@
     	card->rtd_aux = &card->rtd[card->num_links];
     
     	for (i = 0; i < card->num_links; i++)
    +	{
     		card->rtd[i].dai_link = &card->dai_link[i];
    +		if (card->rtd[i].dai_link->no_codec) {
    +			card->rtd[i].dai_link->codec_name = "soc-audio.0";
    +
    +                       ret = snd_soc_register_codec(card->dev, &null_codec_drv,
    +                                       &null_codec_dai_drv, 1);
    +                       if (ret < 0) {
    +                               printk(KERN_ERR "%s: failed to register dynamic DAI link %d\n",
    +                                               __func__, ret);
    +                               goto out;
    +                       }
    +                       continue;
    +        	}	
    +	}
     
     	INIT_LIST_HEAD(&card->list);
     	INIT_LIST_HEAD(&card->dapm_dirty);
    @@ -2845,8 +2897,9 @@
     	mutex_unlock(&client_mutex);
     
     	dev_dbg(card->dev, "Registered card '%s'\n", card->name);
    -
     	return 0;
    +out:
    +      return ret;
     }
     EXPORT_SYMBOL_GPL(snd_soc_register_card);
     

    Furthermore, I had to add one more addition the a header file to complete the null-codec additions.  Here is the patch:

    From 06bb7d909e37883c234082466d35da3de84027f1 Mon Sep 17 00:00:00 2001
    From: Josh Elliott <jelliott@ti.com>
    Date: Wed, 30 Oct 2013 09:22:37 -0500
    Subject: [PATCH 2/3] Added no_codec element to snd_soc_dai_link so Vijay's
     patches would work
    
    ---
     include/sound/soc.h |    2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/include/sound/soc.h b/include/sound/soc.h
    index 11cfb59..ff026db 100644
    --- a/include/sound/soc.h
    +++ b/include/sound/soc.h
    @@ -723,6 +723,8 @@ struct snd_soc_dai_link {
     
     	/* machine stream operations */
     	struct snd_soc_ops *ops;
    +
    +	int no_codec;
     };
     
     struct snd_soc_codec_conf {
    -- 
    1.7.9.5
    

    The final step was to modify the snd_soc_dai_link structure in sound/soc/davinci/davinci-evm.c as you have already mentioned.  Mine looked something like this, although this was just a rough first attempt to see if it would work:

    static struct snd_soc_dai_link am335x_evm_dai = {
     	.name = "TLV320AIC3X",
     	.stream_name = "AIC3X",
    	.cpu_dai_name = "davinci-mcasp.0",
    	.codec_dai_name = "null-codec-dai",
    	.no_codec = 1,
     	.platform_name = "davinci-pcm-audio",
     	.init = evm_aic3x_init,
     	.ops = &evm_ops,
     };

    Anyway, I was able to get my device to work with these modifications.  I apologize for the rough early stage they are in, but I will create a nice patch later on that will be easier to follow.

    Regards,

    Josh

  • Thank you so much Josh,

    I implemented your changes and now ALSA sound card constructed under /dev/snd. As you can predict I get

    [  541.177124] asoc: machine hw_params failed error.

    do you have any advice to play sound without codec?

    Best regards

    Emre

  • Emre,

    It looks like ALSA can't determine how the sound card is supposed to be configured.  How are you trying to play back audio? I was able to play back audio with the changes I listed.  I have only tested with aplay, though.  Are you using a custom application for playback?

    Regards,

    Josh

  • Hi Josh,

    well I was trying to play audio files via aplay but it didnt work

  • Hello,

    Is your external I2S device a master?  Have you used an o-scope to verify it is generating a bit clock and word clock for the McASP?  Do you see any activity on the I2S data and clock lines at all?

    Regards,

    Josh

  • thank you for replying I will try soon

  • Hi josh,

    My evm_hw_params at the below I thing I have to change evm_aic3x_init function because my mcu generating BCLK(24Mhz) and BCLK(800KHz impulse) but there is no DIN data when Iam trying a file.(concole output is here:root@VERA-CP:/crpos# aplay 3.WAV
    Playing WAVE '3.WAV' : Signed 16 bit Little Endian, Rate 22050 Hz, Mono)

    Do you have any idea what I will have to do?


    #define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
                    SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_IB_NF)
    static int evm_hw_params(struct snd_pcm_substream *substream,
                 struct snd_pcm_hw_params *params)
    {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
        int ret = 0;
        unsigned sysclk;

        /* ASP1 on DM355 EVM is clocked by an external oscillator */
        if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm() ||
            machine_is_davinci_dm365_evm())
            sysclk = 27000000;

        /* ASP0 in DM6446 EVM is clocked by U55, as configured by
         * board-dm644x-evm.c using GPIOs from U18.  There are six
         * options; here we "know" we use a 48 KHz sample rate.
         */
        else if (machine_is_davinci_evm())
            sysclk = 12288000;

        else if (machine_is_davinci_da830_evm() ||
                    machine_is_davinci_da850_evm())
            sysclk = 24576000;
        /* On AM335X, CODEC gets MCLK from external Xtal (12MHz). */
        else if (machine_is_am335xevm())
    #ifdef CONFIG_MACH_AM335XEVM
            if (am335x_evm_get_id() == EVM_SK)
                sysclk = 24000000;
            else
    #endif
                sysclk = 12000000;

        else
            return -EINVAL;


        /* set cpu DAI configuration */
        ret = snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
        if (ret < 0)
            return ret;

        return 0;
    }

    Best regards

    Emre

  • Hi josh,

    I have tried below thing but it gives "soc-audio soc-audio.0: Failed to add route SPL->Speaker Jack".

    /* davinci-evm machine dapm widgets */
    static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {

        SND_SOC_DAPM_SPK("Speaker Jack", NULL),

    };

    /* davinci-evm machine audio_mapnections to the codec pins */
    static const struct snd_soc_dapm_route audio_map[] = {
            {"Speaker Jack", NULL, "SPL"},
    };
    static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
    {
        struct snd_soc_codec *codec = rtd->codec;
        struct snd_soc_dapm_context *dapm = &codec->dapm;

        /* Add davinci-evm specific widgets */
        snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
                      ARRAY_SIZE(aic3x_dapm_widgets));

        /* Set up davinci-evm specific audio path audio_map */
        snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));


        snd_soc_dapm_enable_pin(dapm, "Speaker Jack");


        return 0;
    }

    any advice please.

    Thank you

  • Hi Josh, have you already finished the patch?

    do you have any hints on how to do this on 3.8 kernel?

    Thanks a lot

  • Hi Ezequiel,

    I am now in the process of finishing documentation that will go over adding new codecs (or dacs/adcs) to the McASP and then enabling them in linux.


    The guide will be quite similar to what I explained in a previous post in this discussion, although all the board.c modifications will be in the device tree file now.

    I will update this discussion when the documentation is ready.  It will be up by April.

    Josh

  • Hi Ezequiel,

    I finished the guide the demonstrates adding a simple DAC to the kernel.

    http://processors.wiki.ti.com/index.php/Sitara_Linux_SDK_Audio_DAC_Example

    Also, The main Linux SDK Audio page is found here:

    http://processors.wiki.ti.com/index.php/Sitara_SDK_Linux_Audio

    Regards,

    Josh

  • Thanks a lot Josh!!

    This is going to be very helpful...

    Thanks again,

    Ezequiel

  • Hi Josh,

    Thanks for example to write the custom driver using the Device Tree, it really helped us to bring our own driver on BBB using the Kernel 3.8 and *.dts file. All seems working without any issues 

    But we need to do same on the kernel 3.2 so we have to use the board file than dts file. So we did all the changes that you have pointed out above . But we are unable to see the custom codec(dummy) in the ALSA list. Our  intention is to list the driver in the ALSA initially using the board file then we can integrate the above working driver. .

    Is there anything missing from the above steps? i.e we need to edit the kernel code in some other places as well?

    Any help will be appreciated!. Just repeated the steps here for reference. 

     

    Added below code to board file. 

    static struct snd_platform_data am335x_evm_snd_data0 = {

            .tx_dma_offset  = 0x46000000,   /* McASP0 */

            .rx_dma_offset  = 0x46000000,

            .op_mode        = DAVINCI_MCASP_IIS_MODE,

            .num_serializer = ARRAY_SIZE(am335x_iis_serializer_direction0), 

            .tdm_slots      = 2,

            .serial_dir     = am335x_iis_serializer_direction0,

            .asp_chan_q     = EVENTQ_2,

            .version        = MCASP_VERSION_3,

            .txnumevt   = 32,

        .rxnumevt   = 32,

        .get_context_loss_count =

                omap_pm_get_dev_context_loss_count,

    };

    ?

    1

    2

    3

    4

    5

    6

    static u8 am335x_iis_serializer_direction0[] = {

        TX_MODE,    RX_MODE,    INACTIVE_MODE,  INACTIVE_MODE,

        INACTIVE_MODE,  INACTIVE_MODE,  INACTIVE_MODE,  INACTIVE_MODE, 

        INACTIVE_MODE,  INACTIVE_MODE,  INACTIVE_MODE,  INACTIVE_MODE, 

        INACTIVE_MODE,  INACTIVE_MODE,  INACTIVE_MODE,  INACTIVE_MODE, 

    };

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    /* Module pin mux for mcasp0 */

    static struct pinmux_config mcasp0_pin_mux[] = {

        {"mcasp0_aclkx.mcasp0_aclkx", OMAP_MUX_MODE0 |AM33XX_PIN_INPUT_PULLDOWN}, 

        {"mcasp0_fsx.mcasp0_fsx", OMAP_MUX_MODE0   |AM33XX_PIN_INPUT_PULLDOWN},

        {"mcasp0_axr0.mcasp0_axr0", OMAP_MUX_MODE0 |AM33XX_PIN_OUTPUT_PULLUP},

        {"mcasp0_axr1.mcasp0_axr1", OMAP_MUX_MODE0 |AM33XX_PIN_INPUT_PULLDOWN},

        {NULL, 0},

    };

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    /* Setup McASP 0 */

    static void mcasp0_init(int evm_id, int profile)

    {

            /* Configure McASP */

            setup_pin_mux(mcasp0_pin_mux);

            am335x_register_mcasp(&am335x_evm_snd_data0, 0); 

            return;

    }

    Added 

    {mcasp0_init,   DEV_ON_BASEBOARD, PROFILE_ALL},

    Edited the soc-core.c file 

    static struct snd_soc_dai_ops null_dai_ops = {

    };

     

    static struct snd_soc_codec_driver null_codec_drv = {};

     

    static struct snd_soc_dai_driver null_codec_dai_drv = {

     

              .name = "null-codec-dai",

              .playback = {

                      .channels_min = 1,

                      .channels_max = 2,

                      .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |

                                              SNDRV_PCM_RATE_48000,

                      .formats = SNDRV_PCM_FMTBIT_S16_LE,

              },

              .capture = {

                      .channels_min = 1,

                      .channels_max = 2,

                      .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |

                                              SNDRV_PCM_RATE_48000,

                      .formats = SNDRV_PCM_FMTBIT_S16_LE,

              },

     

    };

     

    Added Null codec as you added to the function 

     

    int snd_soc_register_card(struct snd_soc_card *card)

     

    and then linked below code 

     

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    static struct snd_soc_dai_link am335x_evm_dai = { 

        .name = "TLV320AIC3X",

        .stream_name = "AIC3X",

        .cpu_dai_name = "davinci-mcasp.0",

        .codec_dai_name = "null-codec-dai",

        .no_codec = 1,

        .platform_name = "davinci-pcm-audio",

        .init = evm_aic3x_init,

        .ops = &evm_ops,

     };

     

     

    But ALSA unable to find any cards . But if we hook any USB audio card it list and we can issue Aplay and Arecord. 

  • I just tried applying the changes from scratch and tested them on a BeagleBone and it worked.  Maybe there is something wrong with how your are linking the init structure in your board file (to whichever board/evm you are using).


    Here's a full patch--much nicer than that awful mess I posted before.

    7282.dummy_codec_patch.tar

  • Hi Josh,

    Thank you for the quick response. Our code exactly looks like your patch but still we don't have any luck getting the card listed. We tried to list dummy device in /proc/asound/cards, /proc/asound/devices as well as using aplay -l. We are using the custom board with AM335x processor on it. 

    We are using the kernel version 3.2.0 . After reboot we observe snd_soc_evm.ko did not loaded , we need to manually probe it. i.e modprobe snd_soc_evm.ko.

    We did kept some logs in function evm_init() in davanci_evm.c  and soc_core.c file, these are printed only when manually probe the module(but we expected to print these while booting?). Will this explain anything ? i.e we might be missing some configuration to populate the ALSA stuff in config files etc ?  

    --Kishore. 

  • So after you load the module can you see the sound card?  By the way, make sure all the proper modules are inserted.  Look at the SDK 6.0 audio page for a list.

    Also, in your kernel config are you setting all the sound drivers as "built ins" to the kernel?  Look on that same page I just sent for an overview of what needs to be configured.

  • Hi Josh,

    Unfortunately we don't see any cards or devices listed in proc/asound.  we kept the some kernel prints in the code to make sure module has been loaded properly..

    Here is the code snippet of the evm_init function. 

    } else if (machine_is_davinci_da850_evm()) {
    evm_snd_dev_data = &da850_snd_soc_card;
    printk("\ndm355_snd_soc_card_evm 6\n");
    index = 0;
    } else if (machine_is_am335xevm()) {
    evm_snd_dev_data = &am335x_snd_soc_card;
    printk("\ndm355_snd_soc_card_evm 7\n");

    index = 0;
    } else
    return -EINVAL;

    printk("\nplatform_device_alloc\n");

    evm_snd_device = platform_device_alloc("soc-audio", 1);
    if (!evm_snd_device)
    return -ENOMEM;

    //ret = snd_soc_register_card(NULL);

    platform_set_drvdata(evm_snd_device, evm_snd_dev_data);
    printk("\nplatform_device Set \n");
    ret = platform_device_add(evm_snd_device);
    if (ret)
    {
    platform_device_put(evm_snd_device);
    printk("\n Error in adding device \n");
    }
    printk("\nplatform_device added successfully \n");
    return ret;

     

    Also here is some prints we kept in the "snd_soc_register_card()" 

     

    for (i = 0; i < card->num_links; i++)
    {
    printk("SND SOC Register%d \n",i);
    card->rtd[i].dai_link = &card->dai_link[i];
    if (card->rtd[i].dai_link->no_codec) {
    card->rtd[i].dai_link->codec_name = "soc-audio.0";

    ret = snd_soc_register_codec(card->dev, &null_codec_drv,
    &null_codec_dai_drv, 1);
    if (ret < 0) {
    printk(KERN_ERR "%s: failed to register dynamic DAI link %d\n",
    __func__, ret);
    goto out;
    }
    continue;
    } 
    }

    printk("SND SOC Register Done \n");
    INIT_LIST_HEAD(&card->list);
    INIT_LIST_HEAD(&card->dapm_dirty);
    card->instantiated = 0;
    mutex_init(&card->mutex);

    mutex_lock(&client_mutex);
    list_add(&card->list, &card_list);
    snd_soc_instantiate_cards();
    mutex_unlock(&client_mutex);

    dev_dbg(card->dev, "Registered card '%s'\n", card->name);

    printk("SND SOC Register END \n");
    return 0;
    out:
    printk("SND SOC Register ERROR \n");
    return ret;

     

    Here is the configuration of Sound modules in our config file

     

    CONFIG_SOUND=m

    # CONFIG_SOUND_OSS_CORE is not set

    CONFIG_SND=m

    CONFIG_SND_TIMER=m

    CONFIG_SND_PCM=m

    CONFIG_SND_HWDEP=m

    CONFIG_SND_RAWMIDI=m

    CONFIG_SND_JACK=y

    # CONFIG_SND_SEQUENCER is not set

    # CONFIG_SND_MIXER_OSS is not set

    # CONFIG_SND_PCM_OSS is not set

    # CONFIG_SND_HRTIMER is not set

    # CONFIG_SND_DYNAMIC_MINORS is not set

    CONFIG_SND_SUPPORT_OLD_API=y

    # CONFIG_SND_VERBOSE_PROCFS is not set

    # CONFIG_SND_VERBOSE_PRINTK is not set

    # CONFIG_SND_DEBUG is not set

    # CONFIG_SND_RAWMIDI_SEQ is not set

    # CONFIG_SND_OPL3_LIB_SEQ is not set

    # CONFIG_SND_OPL4_LIB_SEQ is not set

    # CONFIG_SND_SBAWE_SEQ is not set

    # CONFIG_SND_EMU10K1_SEQ is not set

    CONFIG_SND_DRIVERS=y

    # CONFIG_SND_DUMMY is not set

    # CONFIG_SND_ALOOP is not set

    # CONFIG_SND_MTPAV is not set

    # CONFIG_SND_SERIAL_U16550 is not set

    # CONFIG_SND_MPU401 is not set

    CONFIG_SND_ARM=y

    CONFIG_SND_SPI=y

    CONFIG_SND_USB=y

    CONFIG_SND_USB_AUDIO=m

    # CONFIG_SND_USB_UA101 is not set

    # CONFIG_SND_USB_CAIAQ is not set

    # CONFIG_SND_USB_6FIRE is not set

    CONFIG_SND_SOC=m

    # CONFIG_SND_SOC_CACHE_LZO is not set

    CONFIG_SND_AM33XX_SOC=m

    CONFIG_SND_DAVINCI_SOC_MCASP=m

    CONFIG_SND_AM335X_SOC_EVM=m

    # CONFIG_SND_OMAP_SOC is not set

    CONFIG_SND_SOC_I2C_AND_SPI=m

    # CONFIG_SND_SOC_ALL_CODECS is not set

    CONFIG_SND_SOC_TLV320AIC3X=m

     

    We don't see any error prints after we manually probe the snd-soc-evm.ko.   

    1. so after manually probing the driver don't we expect the new device to be listed in the proc/asound ? we don't see any devices or cards . 

    2. We also manually loaded all sound kernel modules successfully in the order you have specified in other link. 

    Are we missing any thing else to list the device? 

  • Hi Josh,

    Mean time, Did you repeat the test with kernel 3.2 on Beagle Bone Black? if yes, can you please point us to link where we can get same kernel and rootfs etc , we do have Beagle Bone Black boards with us and we can repeat those tests on our side and compare to see the root cause for why it is not working on our custom board. 

    -- Kishore. 

  • I just tested the patch on SDK 6.0, which is 3.2.  I used BeagleBone White as I don't have BBB on hand.

    I would highly recommend only using the TI provided 3.2 kernel source.  Here is the link to SDK 6.0.

  • Hi Josh,

    We have solved the problem. It turns out that installing all the sound related *.ko did not work, installing  below kos solved the problem.  

    sound/soc/snd-soc-core.ko 
    sound/soc/davinci/snd-soc-davinci.ko
    sound/soc/davinci/snd-soc-evm.ko 

    Now ALSA listed the new card.Thanks and we appreciate your help.

    Best regards,
    Kishore.



     

  • Nice. Glad it worked for you.

  • Dear Josh,

    I came across your support for audio in the link , hope you can kindly address my below issue

    Actually I was using dts was unable to succeeed TI sdk 7 BSP,

    since my reference uda134x.c driver code is already implemented based on board file concept so I switched to ti sdk 6 & did the necessary changes as below hoping should work straight forward,

    I am porting uda134x.c audio codec driver (already ported for mach-mini2440.c & s3c24xx_uda134x.c based on board file) in TI SDK 6 for which I have added the platform data in the board-am335xevm.c & I have done the necessary changes that is to be done in davinci-evm.c as shown below, but the problem is my client driver ie., uda134x.c is not getting invoked, & I have attached the logs also below,

    Could you please kindly do the needful & would appreciate a lot if anybody points out whether am missing any configuration in this board file ie.,board-am335xevm.c or davinci-evm.c file inorder to get my client driver invoked  & get sound card registered & pcm nodes created

    As am struggling from past 4 weeks & stuck with it, still am unable to proceed further

    board-am335xevm.c

    ==================

    #include <sound/uda134x.h>

    struct am335x_uda134x_platform_data {

       int l3_clk;

       int l3_mode;

       int l3_data;

       void (*power) (int);

       int model;

    };

    static struct am335x_uda134x_platform_data am335x_audio_pins = {

       .l3_clk = GPIO_TO_PIN(0, 10), //10,//S3C2410_GPB(4),GPIO_TO_PIN(0, 10)

       .l3_mode = GPIO_TO_PIN(2, 17),//81,//S3C2410_GPB(2),GPIO_TO_PIN(2, 17)

       .l3_data = GPIO_TO_PIN(0, 8),//8,//S3C2410_GPB(3),GPIO_TO_PIN(0, 8)

       .model = UDA134X_UDA1345

    };

    static struct platform_device am335x_audio = {

       .name        = "davinci_evm",

       .id        = 0,

       .dev        = {

           .platform_data    = &am335x_audio_pins,

       },

    };

    static struct platform_device uda1345_codec = {

           .name = "uda134x-codec",

           .id = -1,

    };

    static void am335x_audio_init(int evm_id, int profile)

    {

       int err;

       err = platform_device_register(&am335x_audio);

       if (err) {

           printk("failed to register am335x_audio_init PLATFORM DATA FOR UDA134X IN AM335X BOARD FILE\n");

       }

       else

       {

           printk("SUCCESSFULL am335x_audio_init PLATFORM DATA FOR UDA134X IN AM335X BOARD FILE\n");

       }

    }

    static void uda134x_audio_init(int evm_id, int profile)

    {

       int err;

       err = platform_device_register(&uda1345_codec);

       if (err) {

           printk("failed to register uda134x_audio_init PLATFORM DATA FOR UDA134X IN AM335X BOARD FILE\n");

       }

       else

       {

           printk("SUCCESSFULL uda134x_audio_init PLATFORM DATA FOR UDA134X IN AM335X BOARD FILE\n");

       }

    }

    static u8 am335x_iis_serializer_direction0[] = {
        RX_MODE,    TX_MODE,    INACTIVE_MODE,    INACTIVE_MODE,
        INACTIVE_MODE,    INACTIVE_MODE,    INACTIVE_MODE,    INACTIVE_MODE,
        INACTIVE_MODE,    INACTIVE_MODE,    INACTIVE_MODE,    INACTIVE_MODE,
        INACTIVE_MODE,    INACTIVE_MODE,    INACTIVE_MODE,    INACTIVE_MODE,
    };

    static struct snd_platform_data am335x_evm_snd_data0 = {
        .tx_dma_offset    = 0x46000000,    /* McASP0 */
        .rx_dma_offset    = 0x46000000,
        .op_mode    = DAVINCI_MCASP_IIS_MODE,
        .num_serializer    = ARRAY_SIZE(am335x_iis_serializer_direction0),
        //.tdm_slots    = 2,
        .tdm_slots    = 4,
        .serial_dir    = am335x_iis_serializer_direction0,
        .asp_chan_q    = EVENTQ_2,
        .version    = MCASP_VERSION_3,
        .txnumevt    = 32,
        .rxnumevt    = 32,
        .get_context_loss_count    =
                omap_pm_get_dev_context_loss_count,
    };

    /* Module pin mux for mcasp0 */

    static struct pinmux_config mcasp0_pin_mux[] = {
        {"mcasp0_ahclkx.mcasp0_ahclkx", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLDOWN}, //sysclk / mclk
        {"mcasp0_aclkx.mcasp0_aclkx", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLDOWN}, // bck
        {"mcasp0_fsx.mcasp0_fsx", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLDOWN}, //ws
        {"mcasp0_axr0.mcasp0_axr0", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLDOWN},//datao i/p to processor
        {"mcasp0_axr1.mcasp0_axr1", OMAP_MUX_MODE0 |
                            AM33XX_PIN_OUTPUT_PULLUP}, // datai o/p from processor
        {NULL, 0},
    };

    /* Setup McASP 0 */

    static void mcasp0_init(int evm_id, int profile)

    {

       /* Configure McASP */

       setup_pin_mux(mcasp0_pin_mux);

       switch (evm_id) {

       case EVM_SK:

           am335x_register_mcasp(&am335x_evm_sk_snd_data1, 1);

           break;

       default:

           am335x_register_mcasp(&am335x_evm_snd_data0, 0);

       }

       return;

    }

    /* Beaglebone Black */

    static struct evm_dev_cfg beagleboneblack_dev_cfg[] = {

       {am335x_rtc_init, DEV_ON_BASEBOARD, PROFILE_NONE},

       {clkout2_enable, DEV_ON_BASEBOARD, PROFILE_NONE},

       {mii1_init,    DEV_ON_BASEBOARD, PROFILE_NONE},

       {usb0_init,    DEV_ON_BASEBOARD, PROFILE_NONE},

       {usb1_init,    DEV_ON_BASEBOARD, PROFILE_NONE},

       {mmc1_emmc_init,    DEV_ON_BASEBOARD, PROFILE_NONE},

       {mcasp1_init,    DEV_ON_DGHTR_BRD, PROFILE_NONE},

       {mcasp0_init,    DEV_ON_DGHTR_BRD, PROFILE_NONE},

       {am335x_audio_init, DEV_ON_DGHTR_BRD, PROFILE_NONE},

       {uda134x_audio_init, DEV_ON_DGHTR_BRD, PROFILE_NONE},

       {mmc0_init,    DEV_ON_BASEBOARD, PROFILE_NONE},

       {i2c1_init,    DEV_ON_BASEBOARD, PROFILE_NONE},

       {i2c2_init,    DEV_ON_BASEBOARD, PROFILE_NONE},

       {sgx_init,    DEV_ON_BASEBOARD, PROFILE_NONE},

       {NULL, 0, 0},

    };

    static struct platform_device *audio_devices[] __initdata = {

       &am335x_audio,

       &uda1345_codec,

    };

    /* BeagleBone Black */

    static void setup_beagleboneblack(void)

    {

       pr_info("The board is a AM335x Beaglebone Black.\n");

       /* Beagle Bone has Micro-SD slot which doesn't have Write Protect pin */

       am335x_mmc[0].gpio_wp = -EINVAL;

       platform_add_devices(audio_devices, ARRAY_SIZE(audio_devices));

       _configure_device(BEAGLE_BONE_BLACK, beagleboneblack_dev_cfg,

                   PROFILE_NONE);

       regulator_has_full_constraints();

       am33xx_cpsw_init(AM33XX_CPSW_MODE_MII, NULL, NULL);

    }

    sound/soc/davinci/davinci-evm.c

    ===============================

    #include <linux/gpio.h>

    #include <sound/uda134x.h>

    #include <sound/l3.h>

    //#include "uda134x.h"

    #define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \

           SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)

    struct am335x_uda134x_platform_data {

       int l3_clk;

       int l3_mode;

       int l3_data;

       void (*power) (int);

       int model;

    };

    static struct am335x_uda134x_platform_data *am335x_uda134x_l3_pins;

    /* Common DAPM widgets */

    static const struct snd_soc_dapm_widget uda134x_dapm_widgets[] = {

       SND_SOC_DAPM_INPUT("VINL1"),

       SND_SOC_DAPM_INPUT("VINR1"),

       //SND_SOC_DAPM_INPUT("VINL2"),

       //SND_SOC_DAPM_INPUT("VINR2"),

       SND_SOC_DAPM_OUTPUT("VOUTL"),

       SND_SOC_DAPM_OUTPUT("VOUTR"),

    };

    static const struct snd_soc_dapm_route uda134x_dapm_routes[] = {

       { "ADC", NULL, "VINL1" },

       { "ADC", NULL, "VINR1" },

       //{ "ADC", NULL, "VINL2" },

       //{ "ADC", NULL, "VINR2" },

       { "VOUTL", NULL, "DAC" },

       { "VOUTR", NULL, "DAC" },

    };

    static int evm_uda134x_init(struct snd_soc_pcm_runtime *rtd)

    {

       struct snd_soc_codec *codec = rtd->codec;

       struct snd_soc_dapm_context *dapm = &codec->dapm;

       //struct device_node *np = codec->card->dev->of_node;

       //int ret;

    printk(KERN_ALERT "evm_uda134x_init DAVINCIEVM.C DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);

       snd_soc_dapm_new_controls(dapm, uda134x_dapm_widgets,

                     ARRAY_SIZE(uda134x_dapm_widgets));

           /* Set up davinci-evm specific audio path audio_map */

       printk("DAVINCIIIIIIIIIII UDA134XXXXX  DAPM ROUTING\n");

       snd_soc_dapm_add_routes(dapm, uda134x_dapm_routes, ARRAY_SIZE(uda134x_dapm_routes));

    #if 0

       /* not connected */

       snd_soc_dapm_disable_pin(dapm, "MONO_LOUT");

       snd_soc_dapm_disable_pin(dapm, "HPLCOM");

       snd_soc_dapm_disable_pin(dapm, "HPRCOM");

       /* always connected */

       snd_soc_dapm_enable_pin(dapm, "Headphone Jack");

       snd_soc_dapm_enable_pin(dapm, "Line Out");

       snd_soc_dapm_enable_pin(dapm, "Mic Jack");

       snd_soc_dapm_enable_pin(dapm, "Line In");

    #endif

       return 0;

    }

    static struct snd_soc_dai_link am335x_evm_dai = {

       .name = "UDA134X",

       .stream_name = "UDA134X",

       .codec_name = "uda134x-codec",

       .codec_dai_name = "uda134x-hifi",

       .cpu_dai_name = "davinci-mcasp.0",

       .ops = &evm_ops,

       .platform_name    = "davinci-pcm-audio",

       .init = evm_uda134x_init,

    };

    static void setdat(int v)

    {

       gpio_set_value(am335x_uda134x_l3_pins->l3_data, v > 0);

    }

    static void setclk(int v)

    {

       gpio_set_value(am335x_uda134x_l3_pins->l3_clk, v > 0);

    }

    static void setmode(int v)

    {

       gpio_set_value(am335x_uda134x_l3_pins->l3_mode, v > 0);

    }

    /* FIXME - This must be codec platform data but in which board file ?? */

    static struct uda134x_platform_data am335x_uda134x = {

       .l3 = {

           .setdat = setdat,

           .setclk = setclk,

           .setmode = setmode,

           .data_hold = 1,

           .data_setup = 1,

           .clock_high = 1,

           .mode_hold = 1,

           .mode = 1,

           .mode_setup = 1,

       },

    };

    static int am335x_uda134x_setup_pin(int pin, char *fun)

    {

       if (gpio_request(pin, "am335x_uda134x") < 0) {

           printk(KERN_ERR "AM335X_UDA134X SoC Audio: "

                  "l3 %s pin already in use", fun);

           return -EBUSY;

       }

       gpio_direction_output(pin, 0);

       return 0;

    }

    static int davinci_evm_probe(struct platform_device *pdev)

    {

       struct snd_soc_card *evm_snd_dev_data;

       int index = 0;

       int ret;

       printk(KERN_INFO "DAVINCIIIIIIIII_EVMMM_PROBEEEEEEEEEE SoC Audio driver\n");

       if (machine_is_am335xevm()) {

           printk(KERN_INFO "davinci_evm_probe machine_is_am335xevm SoC Audio driver\n");

           evm_snd_dev_data = &am335x_snd_soc_card;

           index = 0;

       }

       else{

           printk(KERN_INFO "NOTTTTTTTTTTTTT machine_is_am335xevm())))))))))))))))))))))))))))) SoC Audio driver\n");

           return -EINVAL;

       }    

    #if 1

       am335x_uda134x_l3_pins = pdev->dev.platform_data;

       if (am335x_uda134x_l3_pins == NULL) {

           printk(KERN_ERR "AM335X_UDA134X SoC Audio: "

                  "unable to find platform data\n");

           return -ENODEV;

       }

       am335x_uda134x.power = am335x_uda134x_l3_pins->power;

       am335x_uda134x.model = am335x_uda134x_l3_pins->model;

           printk("am335x_uda134x_l3_pins->l3_clk %d\n",am335x_uda134x_l3_pins->l3_clk);

           printk("am335x_uda134x_l3_pins->l3_data %d\n", am335x_uda134x_l3_pins->l3_data);

           printk("am335x_uda134x_l3_pins->l3_mode %d\n", am335x_uda134x_l3_pins->l3_mode);

           printk("am335x_uda134x_l3_pins->power %d\n", am335x_uda134x_l3_pins->power);

           printk("am335x_uda134x_l3_pins->model %d\n", am335x_uda134x_l3_pins->model);

           printk("am335x_uda134x.power %d\n", am335x_uda134x.power);

           printk("am335x_uda134x.model %d\n", am335x_uda134x.model);

       if (am335x_uda134x_setup_pin(am335x_uda134x_l3_pins->l3_data,

                         "data") < 0)

           return -EBUSY;

       if (am335x_uda134x_setup_pin(am335x_uda134x_l3_pins->l3_clk,

                         "clk") < 0) {

           gpio_free(am335x_uda134x_l3_pins->l3_data);

           return -EBUSY;

       }

       if (am335x_uda134x_setup_pin(am335x_uda134x_l3_pins->l3_mode,

                         "mode") < 0) {

           gpio_free(am335x_uda134x_l3_pins->l3_data);

           gpio_free(am335x_uda134x_l3_pins->l3_clk);

           return -EBUSY;

       }

    #endif

       evm_snd_device = platform_device_alloc("soc-audio", -1);

       if (!evm_snd_device)

       {

           printk(KERN_ALERT "FAILUREEEEEE davinci_evm_probe DAVINCIEVM.C DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);

           return -ENOMEM;

       }

       else

       {

           printk(KERN_ALERT "SUCCESSFULLL davinci_evm_probe DAVINCIEVM.C DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__);

       }

       platform_set_drvdata(evm_snd_device, evm_snd_dev_data);

       ret = platform_device_add_data(evm_snd_device, &am335x_uda134x, sizeof(am335x_uda134x));

       printk(KERN_ALERT " davinci_evm_probe platform_device_add_data %d \n",ret);

       ret = platform_device_add(evm_snd_device); /////problemmmmmmmmmmm

       if (ret)

       {

           printk(KERN_ALERT "SUCCESSFULLL davinci_evm_probe platform_device_add %d \n",ret);

           platform_device_put(evm_snd_device);

       }    

       else

       {

           printk(KERN_ALERT "FAILUREEEEEEE davinci_evm_probe platform_device_add %d \n",ret);

       }

       return ret;

    }

    static int davinci_evm_remove(struct platform_device *pdev)

    {

    #if 1

       gpio_free(am335x_uda134x_l3_pins->l3_data);

       gpio_free(am335x_uda134x_l3_pins->l3_clk);

       gpio_free(am335x_uda134x_l3_pins->l3_mode);

    #endif

       return 0;

    }

    static struct platform_driver davinci_evm_driver = {

       .probe        = davinci_evm_probe,

       .remove        = davinci_evm_remove,

       .driver        = {

           .name    = "davinci_evm",

           .owner    = THIS_MODULE,

           .pm    = &snd_soc_pm_ops,

       },

    };

    static int __init evm_init(void)

    {

       struct snd_soc_card *evm_snd_dev_data;

       int index;

       int ret;

       printk(KERN_INFO "DAVINCIIIIIIII_EVMMMMMMM_INITTTTTT_UDA134X SoC Audio driver\n");

         return platform_driver_register(&davinci_evm_driver); // added for uda134x

       if (machine_is_davinci_evm()) {

           evm_snd_dev_data = &dm6446_snd_soc_card_evm;

           index = 0;

       } else if (machine_is_davinci_dm355_evm()) {

           evm_snd_dev_data = &dm355_snd_soc_card_evm;

           index = 1;

       } else if (machine_is_davinci_dm365_evm()) {

           evm_snd_dev_data = &dm365_snd_soc_card_evm;

           index = 0;

       } else if (machine_is_davinci_dm6467_evm()) {

           evm_snd_dev_data = &dm6467_snd_soc_card_evm;

           index = 0;

       } else if (machine_is_davinci_da830_evm()) {

           evm_snd_dev_data = &da830_snd_soc_card;

           index = 1;

       } else if (machine_is_davinci_da850_evm()) {

           evm_snd_dev_data = &da850_snd_soc_card;

           index = 0;

       } else if (machine_is_am335xevm()) {

           evm_snd_dev_data = &am335x_snd_soc_card;

    #ifdef CONFIG_MACH_AM335XEVM

           if (am335x_evm_get_id() == EVM_SK)

               evm_snd_dev_data = &am335x_evm_sk_snd_soc_card;

    #endif

           index = 0;

       } else

           return -EINVAL;

       evm_snd_device = platform_device_alloc("soc-audio", index);

       if (!evm_snd_device)

           return -ENOMEM;

       platform_set_drvdata(evm_snd_device, evm_snd_dev_data);

       ret = platform_device_add(evm_snd_device);

       if (ret)

           platform_device_put(evm_snd_device);

       return ret;

    }

    logs:

    [   13.625000] DAVINCIIIIIIII_EVMMMMMMM_INITTTTTT_UDA134X SoC Audio driver

    [   13.631958] DAVINCIIIIIIIII_EVMMM_PROBEEEEEEEEEE SoC Audio driver

    [   13.638336] davinci_evm_probe machine_is_am335xevm SoC Audio driver

    [   13.644897] am335x_uda134x_l3_pins->l3_clk 10

    [   13.649444] am335x_uda134x_l3_pins->l3_data 8

    [   13.653991] am335x_uda134x_l3_pins->l3_mode 81

    [   13.658630] am335x_uda134x_l3_pins->power 0

    [   13.662994] am335x_uda134x_l3_pins->model 4

    [   13.667388] am335x_uda134x.power 0

    [   13.670928] am335x_uda134x.model 4

    [   13.674499] SUCCESSFULLL davinci_evm_probe DAVINCIEVM.C DEBUG: Passed davinci_evm_probe 524

    [   13.683319]  davinci_evm_probe platform_device_add_data 0

    [   13.689056] SUCCESSFULLLL platform_device_add  if (!pdev) DEBUG: Passed platform_device_add 275

    [   13.698272] pdev->id == -1 platform_device_add DEBUG: Passed platform_device_add 294 0

    [   13.706542] Registering platform device 'soc-audio'. Parent at platform

    [   13.713684] FAILUREEEEEEE davinci_evm_probe platform_device_add 0

    Awaiting for your replies,

    Many Many thanks in advance

  • I would recommend using SDK 7.0 if you can.  I made a comprehensive guide about how to interface a new audio device to the McASP that you can use to guide you.

    If not, there is also an attachment in one of my posts in this thread that has a basic patch that adds a new audio device to SDK 6.0--you could also try starting with that and adding your new stuff in from there.