Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am using Buildroot to build an embedded Linux (2.6.39.2) system for the NXP LPC3250 microcontroller.

Right now, I'm trying to get ALSA/ASoC up and running, but I'm having some issues with getting the modules to work together. (I think!)

Some important background:

The board I am testing with is the Embedded Artists 3250 V2 development board. V2 is different from V1 in that it does not have an LCD screen, but does include an I2S audio codec: The NXP UDA1380. Board support for EA3250 V1 is included in the LPCLinux version of the kernel. There is also a different development board, called Phytec 3250, which contains the same UDA1380 codec chip. The LPCLinux distribution also has support for the Phytec board, along with the audio codec chip. From what I have discerned, the Phytec 3250 board has the UDA1380 codec on I2C address 0x18. On my EA3250 V2 board, the audio codec is located at I2C address 0x1a. (I have verified the chip is powered up, and I can communicate to it by using the I2C-tools package. It responds to i2cdetect and I can read registers from the chip correctly using i2cget.)

Modifying the source:

I needed to edit the Phytec 3250 driver files to change the address of the codec chip. I edited this section of lpc3xxx-uda1380.c:

static struct snd_soc_dai_link phy3250_uda1380_dai[] = {
       {
                  .name           = "uda1380",
                  .stream_name    = "UDA1380 Duplex",
  #if defined(CONFIG_SND_LPC32XX_USEI2S1)
                  .cpu_dai_name   = "lpc3xxx-i2s1",
  #else
                  .cpu_dai_name   = "lpc3xxx-i2s0",
  #endif
                  .codec_dai_name = "uda1380-hifi",
                  .init           = phy3250_uda1380_init,
                  .platform_name  = "lpc3xxx-audio.0",
         //EDIT// .codec_name     = "uda1380-codec.0-0018",  //EDIT//
                  .codec_name     = "uda1380-codec.0-001a",
                  .ops            = &phy3250_uda1380_ops,
          },
  };

After I made this change, I went ahead and built the system again and everything compiled OK. After booting into the system, I have the following modules (in addition to the standard core modules) in /lib/modules/2.6.39.2/kernel/sound:

 ./soc/codecs: snd-soc-uda1380.ko          <-- ASoC codec driver
./soc/lpc3xxx: snd-soc-lpc3xxx-i2s.ko      <-- ASoC DAI
               snd-soc-lpc3xxx-uda1380.ko  <-- ASoC machine driver
               snd-soc-lpc3xxx.ko          <-- ASoC platform driver

Now, how do I actually bind all this stuff together?

Just inserting the modules with modprobe doesn't actually give the device to ALSA/ASoC. I am unable to detect the soundcard. Does this mean I must now make a new device called uda1380-codec at address 0x1a and bind it to a driver? I have tried doing the following:
echo uda1380-codec 0x01a > /sys/bus/i2c/devices/i2c-0/new_device
and received:
i2c i2c-0: new_device: Instantiated device uda1380-codec at 0x1a
Then I try to bind a driver to the device:
echo 0x1a > /sys/bus/i2c/drivers/uda1380-codec/bind
and received:
sh: write error: No such device

I get this error for everything I try! I have a feeling I am not creating the device correctly, and then I'm not sure how to bind it to the correct driver.

Nota Bene:

I was playing with this last night and was somehow able to get ASoC to wake up and at least probe for the card. I was playing with different bindings, I guess. It was late and hard to remember my steps, but I was able to at least get the following error somehow:

uda1380-codec 0-001a: asoc: failed to probe CODEC uda1380-codec.0-001a: -22
asoc: failed to instantiate card LPC32XX: -22

I have been unable to recreate this error!

Edit:

I've confirmed my modified code is being compiled, so the driver should be talking to the correct address now. After manually loading the modules, the output of lsmod is:

Module                      Size  Used by    Not tainted
snd_soc_lpc3xxx_uda1380     2087  0 
snd_soc_lpc3xxx             3089  0 
snd_soc_lpc3xxx_i2s         4089  1 
snd_soc_uda1380            10865  0 
snd_soc_core               51549  4 snd_soc_lpc3xxx_uda1380,snd_soc_lpc3xxx,snd_soc_lpc3xxx_i2s,snd_soc_uda1380
snd_pcm                    52098  2 snd_soc_lpc3xxx,snd_soc_core
snd_timer                  15590  1 snd_pcm
snd_page_alloc              3021  1 snd_pcm
snd                        37286  3 snd_soc_core,snd_pcm,snd_timer

Does this look right?

And my device table:

# Audio stuff
/dev/audio      c       666     0       29      14      4       -       -       -
#/dev/audio1    c       666     0       29      14      20      -       -       -
/dev/dsp        c       666     0       29      14      3       -       -       -
#/dev/dsp1      c       666     0       29      14      19      -       -       -
#/dev/sndstat   c       666     0       29      14      6       -       -       -
/dev/mixer      c       666     0       29      14      0       -       -       -
/dev/snd        d       755     0       29      -       -       -       -       -
/dev/snd/controlC0      c       666     0       29      116     0       -       -       -
/dev/snd/pcmC0D0c       c       666     0       29      116     24      -       -       -
/dev/snd/pcmC0D0p       c       666     0       29      116     16      -       -       -
/dev/snd/seq    c       666     0       29      116     1       -       -       -
/dev/snd/timer  c       666     0       29      116     33      -       -       -
share|improve this question
    
You should read the ASoC documentation, and then ask on the alsa-devel list (where you will be told that 2.6.39 is horribly outdated, and that the board vendor is responsible for support). –  CL. Dec 26 '12 at 22:03
    
@CL. Thanks, board vendor does not support UDA1380 codec with LPCLinux (I have already contacted them), which is why I'm trying to hack it in myself. –  dext0rb Dec 26 '12 at 22:14
    
I posted to alsa-devel and nobody responded. (That I can tell - I hate mail-lists, they are the worst to read through.) Now my mailbox is full of ALSA crap and I still have no help. Here I go again, on my own... –  dext0rb Jan 9 '13 at 16:14
add comment

1 Answer

up vote 0 down vote accepted

Need to edit the board's file that defines platform devices. I needed to modify arch/arm/mach-lpc32xx/ea3250.c :

Add this:

/*
 * Platform Data for UDA1380 Audiocodec.
 * As there are no GPIOs for codec power & reset pins,
 * dummy GPIO numbers are used.
 */
static struct uda1380_platform_data uda1380_info = {
    .gpio_power = LPC32XX_GPIO(LPC32XX_GPO_P3_GRP,10),
    .gpio_reset = LPC32XX_GPIO(LPC32XX_GPO_P3_GRP,2),
    .dac_clk    = UDA1380_DAC_CLK_WSPLL,
};

Edit this to include the codec:

static struct i2c_board_info __initdata ea3250_i2c_board_info [] = {
        {   I2C_BOARD_INFO("uda1380", 0x1a),
            .platform_data = &uda1380_info,
        }, 
#if defined (CONFIG_LEDS_PCA9532)
        {
            I2C_BOARD_INFO("pca9532", I2C_PCA9532_ADDR),
            .platform_data = &ea3250_leds,
        },
#endif
#if defined (CONFIG_FB_ARMCLCD)
        {
            /* 8Kb Configuration EEPROM on display board */
            I2C_BOARD_INFO("ea_i2c_disp_cfg", LCDB_CONFIG_EEPROM_I2C_ADDR),
        },
        {
            I2C_BOARD_INFO("ea_i2c_video", LCDB_PCA9532_I2C_ADDR),
        },
#endif
#if defined (CONFIG_EEPROM_AT24)
        {
            I2C_BOARD_INFO("24c256", I2C_24LC256_ADDR),
        },
#endif
    };
#endif

Now I have all the devices:

# cat cards
 0 [LPC32XX        ]:  - LPC32XX
                      LPC32XX
# cat devices
  2: [ 0- 0]: digital audio playback
  3: [ 0- 0]: digital audio capture
  4: [ 0]   : control
 33:        : timer

# cat pcm
00-00: UDA1380 Duplex uda1380-hifi-0 :  : playback 1 : capture 1

I can't get aplay to detect anything yet though, but perhaps that is a different issue.

EDIT: Yes, that was a different issue. The number in front of the devices shown by cat devices should match the Minor device number in your /dev/snd device entries. Everything seems good on ALSA end now, but I have no I2S data coming from the LPC3250...

EDIT2: SOLVED SOLVED SOLVED. If you there's no I2S data/clock, make sure the output mux register is configured correctly to connect the output pins to the I2S peripheral!!!

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.