2008-03-24 01:00:02     Are the code in linux-2.6.x/sound/soc OK?

Document created by Aaronwu Employee on Aug 5, 2013
Version 1Show Document
  • View in full screen mode

2008-03-24 01:00:02     Are the code in linux-2.6.x/sound/soc OK?

Zhi Qiang Zhang (CHINA)

Message: 52953    Hi,

 

I built a WM8731soc audio driver, and then play a audio file, such as,

 

mplay a.mp3

 

the mplay did not return until CTRL+C. Here is some information about the audio card,

 

root:/proc/asound/card0/pcm0p/sub0> cat status

state: PREPARED

trigger_time: 0.000000000

tstamp      : 1097170815.508000000

delay       : 0

avail       : 0

avail_max   : 0

-----

hw_ptr      : 0

appl_ptr    : 12288

 

the state is always "PREPARED"

 

I want to know, are the code in linux-2.6.x/sound/soc OK? Thanks

 

 

Regards,

ZhangZQ

QuoteReplyEditDelete

 

 

2008-03-24 01:43:17     Re: Are the code in linux-2.6.x/sound/soc OK?

Mike Frysinger (UNITED STATES)

Message: 52954    yes, the code is "OK" ... we're already using it on the BF537/BF54x

QuoteReplyEditDelete

 

 

2008-03-24 02:05:25     Re: Are the code in linux-2.6.x/sound/soc OK?

Zhi Qiang Zhang (CHINA)

Message: 52956    Mike,

 

Thank for your reply, can you tell me which codec did you try? I am using PCM1742, the SPORT configuration is, it uses the internally generated TCLK and TFS.

 

What is your suggestion?

 

 

Regards,

ZhangZQ

QuoteReplyEditDelete

 

 

2008-03-24 02:45:44     Re: Are the code in linux-2.6.x/sound/soc OK?

Mike Frysinger (UNITED STATES)

Message: 52957    we've tested the AD1980 quite extensively

QuoteReplyEditDelete

 

 

2008-03-24 03:26:44     Re: Are the code in linux-2.6.x/sound/soc OK?

Zhi Qiang Zhang (CHINA)

Message: 52958    Mike,

 

I found no AD1980 source in soc source, can you send me that source for reference? can you tell me which is the TCLK source, from SPORT or from AD1980?

 

 

Regards,

ZhangZQ

QuoteReplyEditDelete

 

 

2008-03-24 03:37:59     Re: Are the code in linux-2.6.x/sound/soc OK?

Zhi Qiang Zhang (CHINA)

Message: 52959    Mike,

 

There is a definition in bf5xx-i2s.c

struct snd_soc_cpu_dai bf5xx_i2s_dai[NUM_SPORT_I2S] = {

{

        .name = "bf5xx-i2s-0",

        .id = 0,

        .type = SND_SOC_DAI_I2S,

        .suspend = bf5xx_i2s_suspend,

        .resume = bf5xx_i2s_resume,

        .playback = {

                .channels_min = 1,

                .channels_max = 2,

                .rates = BF5XX_I2S_RATES,

                .formats = BF5XX_I2S_FORMATS,},

        .capture = {

                .channels_min = 1,

                .channels_max = 2,

                .rates = BF5XX_I2S_RATES,

                .formats = BF5XX_I2S_FORMATS,},

        .ops = {

                .startup = bf5xx_i2s_startup,

                .shutdown = bf5xx_i2s_shutdown,

                .trigger = bf5xx_i2s_trigger,

                .hw_params = bf5xx_i2s_hw_params,

                .prepare = bf5xx_i2s_prepare,},

        .dai_ops = {

                .set_fmt = bf5xx_i2s_set_dai_fmt,

        },

},

 

and there is anothere trigger defined in bf5xx-pcm.c

struct snd_pcm_ops bf5xx_pcm_ops = {

        .open           = bf5xx_pcm_open,

        .close          = bf5xx_pcm_close,

        .ioctl          = snd_pcm_lib_ioctl,

        .hw_params      = bf5xx_pcm_hw_params,

        .hw_free        = bf5xx_pcm_hw_free,

        .prepare        = bf5xx_pcm_prepare,

        .trigger        = bf5xx_pcm_trigger,

        .pointer        = bf5xx_pcm_pointer,

#ifdef CONFIG_SND_MMAP_SUPPORT

        .mmap           = bf5xx_pcm_mmap,

#else

        .copy           = bf5xx_pcm_copy,

#endif

};

 

struct snd_soc_platform bf5xx_soc_platform = {

        .name           = "bf5xx-audio",

        .pcm_ops        = &bf5xx_pcm_ops,

        .pcm_new        = bf5xx_pcm_new,

        .pcm_free       = bf5xx_pcm_free_dma_buffers,

};

 

And my PCM1742 driver is based on bf5xx-wm731.c, in bf5xx-wm8731.c

 

static struct snd_soc_device bf5xx_wm8731_snd_devdata = {

        .machine = &bf5xx_wm8731,

        .platform = &bf5xx_soc_platform,

        .codec_dev = &soc_codec_dev_wm8731,

        .codec_data = &bf5xx_wm8731_setup,

};

 

static struct snd_soc_dai_link bf5xx_wm8731_dai = {

        .name = "wm8731",

        .stream_name = "WM8731",

        .cpu_dai = &bf5xx_i2s_dai[CONFIG_SND_BF5XX_SPORT_NUM],

        .codec_dai = &wm8731_dai,

        .init = bf5xx_wm8731_init_dev,

        .ops = &bf5xx_wm8731_ops,

};

 

This definition will cause the trigger will be called twice, is there something wrong in bf5xx-wm8731.c or in bf5xx-i2s.c or bf5xx-pcm.c?

 

 

 

Regards,

ZhangZQ

QuoteReplyEditDelete

 

 

2008-03-24 04:00:40     Re: Are the code in linux-2.6.x/sound/soc OK?

Mike Frysinger (UNITED STATES)

Message: 52960    i dont know where you're looking, but there is def a codec driver for the AD1980 in the codecs directory

 

you can find the datasheet on analog.com or just by googling for it

QuoteReplyEditDelete

 

 

2008-03-24 04:39:52     Re: Are the code in linux-2.6.x/sound/soc OK?

Zhi Qiang Zhang (CHINA)

Message: 52963    Mike,

 

Sorry, there is a ad1980 codec driver, but found no ad1980 dai driver.

 

I used a logic analyser to check if the I2S output, the SCLK of my board is 86400000,  I set the SPORT by

 

bf5xx_i2s[cpu_dai->id].tclkdiv = 28;

bf5xx_i2s[cpu_dai->id].tfsdiv = 16;

 

using I2S

bf5xx_i2s[cpu_dai->id].tcr1 |= TFSR | TCKFE;

bf5xx_i2s[cpu_dai->id].tcr2 |= TSFSE;

 

using internally generated clock

bf5xx_i2s[cpu_dai->id].tcr1 |= ITCLK | ITFS;

 

SLEN

bf5xx_i2s[cpu_dai->id].tcr2 |= 15;

 

Do you think that setting is OK? it seems only the TFS is ok, please check the attached photo.

 

 

 

Regards,

ZhangZQ

logic_1.jpg

logic_2.jpg

QuoteReplyEditDelete

 

 

2008-03-24 07:25:07     Re: Are the code in linux-2.6.x/sound/soc OK?

Mike Frysinger (UNITED STATES)

Message: 52968    the AD1980 doesnt speak I2S, it does AC97

 

regardless, the way the alsa soc works is that you have a codec driver for the codec and you have a driver for the transport layer ... the two are not intermingled

QuoteReplyEditDelete

 

 

2008-03-24 08:41:43     回复: Re: Are the code in linux-2.6.x/sound/soc OK?

Cliff Cai (CHINA)

Message: 52970    I think the two trigger callbacks have different  meanings.one for  alsa soc layer,is a member of snd_soc_ops;the other for  pcm layer,is a member of snd_pcm_ops.Blackfin use ac97 to talk with ad1980,so the snd_soc_cpu_dai is defined in bf5xx-ac97.c.The trigger for PCM layer is a must,but for asoc layer is an option,it depends what the trigger for PCM layer does.

 

Cliff

QuoteReplyEditDelete

 

 

2008-03-24 08:47:22     回复: Re: Are the code in linux-2.6.x/sound/soc OK?

Cliff Cai (CHINA)

Message: 52971    Sorry ,should be "depends on",I mean if the trigger in PCM layer does all the thing ,then there is no need for the asoc one.

 

Cliff

QuoteReplyEditDelete

 

 

2008-03-24 09:42:47     Re: 回复: Re: Are the code in linux-2.6.x/sound/soc OK?

Zhi Qiang Zhang (CHINA)

Message: 52972    Cliff,

 

I have to mark the trigger definition in bf5xx-i2s.c, otherwise, the driver can't run. I have not tried to mark the trigger definition in bf5xx-pcm.c. And I traced the code, when

static int snd_pcm_do_start(struct snd_pcm_substream *substream, int state)

{

        if (substream->runtime->trigger_master != substream)

                return 0;

        return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);

}

the ops->trigger was called, that 2 triggers would be called if none had been marked, so the driver can't work.

 

After the driver can work, I attached the PCM1742 codec, and play a media file, what I can hear is only the noise.

 

What is your suggestion? Thanks.

 

 

Regards,

ZhangZQ

QuoteReplyEditDelete

 

 

2008-03-24 23:16:21     回复: Re: 回复: Re: Are the code in linux-2.6.x/sound/soc OK?

Cliff Cai (CHINA)

Message: 52986    Hi Zhi Qiang,

 

I have no PCM1742 at hand ,so I guess if you can:

1.check if the chip is configured properly.

2.check if the SPORT works in I2S mode.

3.check if the DMA  is configured properly.

 

I just had a look of the code ,and found that the two triggers almost do the same thing.

so it's right to mark one.there are also two "prepare" callbacks ,the one in bf5xx-pcm.c is used to configure DMA,

the one in bf5xx-i2s.c is used to set SPORT mode.

 

Best Regards

 

Cliff

QuoteReplyEditDelete

 

 

2008-03-25 00:24:06     Re: 回复: Re: 回复: Re: Are the code in linux-2.6.x/sound/soc OK?

Zhi Qiang Zhang (CHINA)

Message: 52987    Cliff,

 

> 1.check if the chip is configured properly.

It must be set properly, because I captured the SPI output, and checked it is correct.

 

> 2.check if the SPORT works in I2S mode.

here is the SPORT setting

using I2S

bf5xx_i2s[cpu_dai->id].tcr1 |= TFSR | TCKFE;

bf5xx_i2s[cpu_dai->id].tcr2 |= TSFSE;

 

using internally generated clock

bf5xx_i2s[cpu_dai->id].tcr1 |= ITCLK | ITFS;

 

DATALEN

bf5xx_i2s[cpu_dai->id].tcr2 |= 15;

 

the clock setting, my SCLK is 86400000

bf5xx_i2s[cpu_dai->id].tclkdiv = 28;

bf5xx_i2s[cpu_dai->id].tfsdiv = 16;

 

So I think the SPORT setting is correct.

 

> 3.check if the DMA  is configured properly.

That is a problem, as you said, you found two 'prepare' in bf5xx-i2s.c & bf5xx-pcm.c, the 'prepare' in bf5xx-i2s.c is to setting the SPORT, here is code.

static int bf5xx_i2s_tx_prepare(struct snd_pcm_substream *substream)

{

        struct snd_soc_pcm_runtime *rtd = substream->private_data;

        struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;

        struct sport_device *sport =

                (struct sport_device *)cpu_dai->private_data;

 

        i2s_printd("%s : sport %d, addr %x\n", __func__, cpu_dai->id, sport);

 

        return sport_config_tx(sport, bf5xx_i2s[cpu_dai->id].tcr1,

                bf5xx_i2s[cpu_dai->id].tcr2,

                bf5xx_i2s[cpu_dai->id].tclkdiv,

                bf5xx_i2s[cpu_dai->id].tfsdiv);

}

 

the 'prepare' in bf5xx-pcm.c is to setting up the DMA, I think, but it allocates the DMA buffer to ac97_frame, I just wonder, if the blackfin also soc driver only work for ac97 protocol? I found this code too,

void bf5xx_ac97_pcm32_to_frame(struct ac97_frame *dst, const __u32 *src, \

                size_t count)

{

        while (count--) {

                dst->ac97_tag = TAG_VALID | TAG_PCM;

                (dst++)->ac97_pcm = *src++;

        }

}

This code transmit the audio following the ac97 protocol, but I am using I2S, should I modify something to make it work for I2S? or there is something I don't know?

 

 

Regards,

ZhangZQ

QuoteReplyEditDelete

 

 

2008-03-25 22:52:09     回复: Re: 回复: Re: 回复: Re: Are the code in linux-2.6.x/sound/soc OK?

Cliff Cai (CHINA)

Message: 53020    Hi Zhi Qiang,

 

Yes , bf5xx-pcm.c is based on AC97,so you need to replace every ac97 related struct to  original  PCM  struct.

 

Cliff

QuoteReplyEditDelete

 

 

2008-03-26 22:54:30     Re: 回复: Re: 回复: Re: 回复: Re: Are the code in linux-2.6.x/sound/soc OK?

Zhi Qiang Zhang (CHINA)

Message: 53087    With the help from Cliff.Cai, the PCM1742 ASOC driver can work now. CHEERS!

 

 

Regards,

ZhangZQ

QuoteReplyEditDelete

 

 

2008-03-27 05:10:14     Re: 回复: Re: 回复: Re: 回复: Re: Are the code in linux-2.6.x/sound/soc OK?

C.C Lu (TAIWAN)

Message: 53120    Hi Zhi Qiang,

 

Can you post the modified code?

I want to do same thing with you. But I get some error in sport pointer.

Attachments

Outcomes