All of lore.kernel.org
 help / color / mirror / Atom feed
* Problem with underrun on new CS42448 x2 driver
@ 2010-08-24 19:47 Adam Rosenberg
  2010-08-26 12:47 ` Mark Brown
  0 siblings, 1 reply; 9+ messages in thread
From: Adam Rosenberg @ 2010-08-24 19:47 UTC (permalink / raw)
  To: alsa-devel

I am trying to write a driver for the Blackfin BF537 processor on a custom
board that has two CS42448 CODECs connected to SPORT0.  I am using TDM and
there are 8 channels per frame on each data line (primary and secondary).
My DMA buffer must interleave the data for the two data lines (for a total
of 16 channels of data per frame).  I have completed all of this and the
driver will sometimes work properly but I am having underrun problems.  I
would like to use snd_async_add_pcm_handler as it is used in the /test/pcm.c
example but it seems as though an underrun occurs at regular intervals
causing the PCM prepare function to be called again (this results in a tone
that sounds good but only for a short time before it stops and then starts
again).

There is plenty of time for the data to be transferred.  I feel as though
the driver is not calling snd_pcm_period_elapsed fast enough.  At the
moment, I call snd_pcm_period_elapsed from within a callback function that
occurs every time a DMA period elapse occurs.  I have been working on this
for quite a while now.  Is there someone who can look at the driver code for
me or provide detailed information on when ALSA expects to have
snd_pcm_period_elapsed get called to avoid an underrun?

The other thing that is strange is that I have to explicitly set the period
size for aplay to work.  For example:
aplay --period-size=1024 test.wav
which gives me a period time of 21333 but when I use this period time with
the /test/pcm.c sample that is provided the tone still does not sound right
(although it does seem to improve)

I am about ready to bypass ALSA entirely but I hate the idea of breaking
from standards (not to mention having to rewrite an entire audio
interface).  Any help would be greatly appreciated!

You can check out the driver here:
http://www.alcorn.com/ftp/swap/ami_cs42448.zip

Thank you,
Adam

Adam Rosenberg
Software Engineer

Alcorn McBride Inc.
3300 South Hiawassee
Building 105
Orlando, FL 32835

(407) 296 - 5800 ext. 5490

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problem with underrun on new CS42448 x2 driver
  2010-08-24 19:47 Problem with underrun on new CS42448 x2 driver Adam Rosenberg
@ 2010-08-26 12:47 ` Mark Brown
  2010-08-26 18:06   ` Adam Rosenberg
  0 siblings, 1 reply; 9+ messages in thread
From: Mark Brown @ 2010-08-26 12:47 UTC (permalink / raw)
  To: Adam Rosenberg; +Cc: Mike Frysinger, alsa-devel, Barry Song, Cliff Cai

On Tue, Aug 24, 2010 at 03:47:13PM -0400, Adam Rosenberg wrote:
> I am trying to write a driver for the Blackfin BF537 processor on a custom
> board that has two CS42448 CODECs connected to SPORT0.  I am using TDM and

CCing in the Blackfin guys - this looks like a CPU specific issue.
However, see below...

> there are 8 channels per frame on each data line (primary and secondary).
> My DMA buffer must interleave the data for the two data lines (for a total
> of 16 channels of data per frame).  I have completed all of this and the
> driver will sometimes work properly but I am having underrun problems.  I
> would like to use snd_async_add_pcm_handler as it is used in the /test/pcm.c
> example but it seems as though an underrun occurs at regular intervals
> causing the PCM prepare function to be called again (this results in a tone
> that sounds good but only for a short time before it stops and then starts
> again).
> 
> There is plenty of time for the data to be transferred.  I feel as though
> the driver is not calling snd_pcm_period_elapsed fast enough.  At the
> moment, I call snd_pcm_period_elapsed from within a callback function that
> occurs every time a DMA period elapse occurs.  I have been working on this
> for quite a while now.  Is there someone who can look at the driver code for
> me or provide detailed information on when ALSA expects to have
> snd_pcm_period_elapsed get called to avoid an underrun?
> 
> The other thing that is strange is that I have to explicitly set the period
> size for aplay to work.  For example:
> aplay --period-size=1024 test.wav
> which gives me a period time of 21333 but when I use this period time with
> the /test/pcm.c sample that is provided the tone still does not sound right
> (although it does seem to improve)

If you're needing to set the period size explicitly this probably
indicates a problem with the way the constraints are being exposed to
applicatiohns - normally the constraints would force an appropriate
configuration to be selected.

> I am about ready to bypass ALSA entirely but I hate the idea of breaking
> from standards (not to mention having to rewrite an entire audio
> interface).  Any help would be greatly appreciated!
> 
> You can check out the driver here:
> http://www.alcorn.com/ftp/swap/ami_cs42448.zip

Please post code to the list if you want people to review it.  Looking
at the code there it looks like you've implemented your own custom
driver entirely outside the standard ASoC framework and Blackfin
drivers.  It will be much easier to get community support with the
standard kernel code, if you're not reusing any of the existing CPU
support you're much more on your own.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problem with underrun on new CS42448 x2 driver
  2010-08-26 12:47 ` Mark Brown
@ 2010-08-26 18:06   ` Adam Rosenberg
  2010-08-26 18:52     ` Mark Brown
  2010-08-27 20:37     ` Mike Frysinger
  0 siblings, 2 replies; 9+ messages in thread
From: Adam Rosenberg @ 2010-08-26 18:06 UTC (permalink / raw)
  To: Mark Brown; +Cc: Mike Frysinger, alsa-devel, Barry Song, Cliff Cai

Mark,

Thank you for the reply.  I emailed Barry Song on July 30th to request some
help moving to the new ASoC standards but received no response.

I began writing this driver on the Blackfin uClinux 2009 release and based
it on the AD1836 and AD1938 drivers.  I am now using the Blackfin SVN trunk
and have found that the driver model was changed to ASoC.  It is not
apparent how I would create a driver that supports two chips off of the same
SPORT using the ASoC framework.

The best I could do was use the same SPORT driver that the ASoC code uses
(bf5xx-sport.c) so that I was at least up-to-date in that area.  I had to
modify that driver so that it would support the secondary data lines of the
SPORT.  I found that the driver did not function well in 2D DMA mode so I
have to keep my period size below 64kb.  There is also a problem with
starting Rx and Tx that causes the DMA data to be placed into the SPORT
multichannel window incorrectly.  I added a function to the SPORT driver
yesterday that can work around this problem by starting both Rx and Tx as
normal then stopping the SPORT and restarting it like this:

int sport_start_both(struct sport_device *sport)
{
    sport_tx_start(sport);
    msleep(1);  // is this needed?
    sport_rx_start(sport);
    msleep(1);  // is this needed?
    sport_stop(sport);
    msleep(1);  // is this needed?
    sport_start(sport);
    return 0;
}
EXPORT_SYMBOL(sport_start_both);

This ensures that the data from the DMA buffer is properly loaded into the
SPORT multichannel window for both the Rx and Tx data lines.  If it is not
done this way it seems that one of them is always being filled incorrectly.
This may have sometime to do with the fact that I have to enable the
secondary data lines but there is no clear explanation for why that would
have an effect.

I have not entered any constraints into the driver because there really
should be no need.  The driver just copies whatever PCM data that is
provided directly to the DMA buffer.  It seems that the problem occurs
because the location to copy to is based on the pos suggested by the
callback function.  I am still finding it difficult to tell how ALSA decides
there is an underrun or overrun.  I am definitely trying to read or write
the pcm data fast enough but it seems as though I get these errors anyway.

Questions:
1.  How do I implement an ASoC-style driver that supports multiple chips
when they are connected to the same SPORT but use different SPI chip
selects?
2.  How do I define the proper buffer/period size constraints or should I
ignore the suggested position during copy operations and just keep track of
the position within the DMA buffer myself?
3.  Can you suggest a good way to debug underrun/overrun problems?

Thank you,
Adam

Adam Rosenberg
Software Engineer

Alcorn McBride Inc.
3300 South Hiawassee
Building 105
Orlando, FL 32835

(407) 296 - 5800 ext. 5490

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problem with underrun on new CS42448 x2 driver
  2010-08-26 18:06   ` Adam Rosenberg
@ 2010-08-26 18:52     ` Mark Brown
  2010-08-27 20:11       ` Adam Rosenberg
  2010-08-27 20:37     ` Mike Frysinger
  1 sibling, 1 reply; 9+ messages in thread
From: Mark Brown @ 2010-08-26 18:52 UTC (permalink / raw)
  To: Adam Rosenberg; +Cc: Mike Frysinger, alsa-devel, Barry Song, Cliff Cai

On Thu, Aug 26, 2010 at 02:06:43PM -0400, Adam Rosenberg wrote:

> Thank you for the reply.  I emailed Barry Song on July 30th to request some
> help moving to the new ASoC standards but received no response.

Please don't top post, and remember to include context in your reply so
people can understand the context of your message0.  This is standard
for Linux kernel mailing lists.

> I have not entered any constraints into the driver because there really
> should be no need.  The driver just copies whatever PCM data that is
> provided directly to the DMA buffer.  It seems that the problem occurs
> because the location to copy to is based on the pos suggested by the
> callback function.  I am still finding it difficult to tell how ALSA decides
> there is an underrun or overrun.  I am definitely trying to read or write
> the pcm data fast enough but it seems as though I get these errors anyway.

I've no idea what "the callback function" is?  As far as determining
the overrun and underrun conditions goes the source is available -
obviously and overrun is where you try to write more data than there's
space for and an underrun is when the hardware runs out of data.

This can either mean that the driver is reporting that data is being
consumed at the wrong rate (possibly as a result of hardware
misconfiguration resulting in a misunderstanding about the format of
incoming data, or misconfiguration of clocks) or it can mean that the
application is getting confused.

> Questions:
> 1.  How do I implement an ASoC-style driver that supports multiple chips
> when they are connected to the same SPORT but use different SPI chip
> selects?

Look at current ASoC in -next, I've never tried this multi drop DAI
setup directly myself but it does support multiple CODECs in the system.

> 2.  How do I define the proper buffer/period size constraints or should I
> ignore the suggested position during copy operations and just keep track of
> the position within the DMA buffer myself?

Your constraints will flow from the requirements of the hardware plus
any additional requirements that the driver you've written imposes.  For
example, if you always need a period of data ready to start DMA on which
the application can't touch for coherency reasons then you need to make
sure that there's at least three periods (running, about to run and
updatable), or if your hardware DMAs in blocks you need a minimum period
size for that.

> 3.  Can you suggest a good way to debug underrun/overrun problems?

There's a few settings for XRUN detection diagnostics in the ALSA core
code which can be useful - see pcm_lib.c and the SND_PCM_XRUN_DEBUG
config option.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problem with underrun on new CS42448 x2 driver
  2010-08-26 18:52     ` Mark Brown
@ 2010-08-27 20:11       ` Adam Rosenberg
  2010-08-27 22:04         ` Mark Brown
  0 siblings, 1 reply; 9+ messages in thread
From: Adam Rosenberg @ 2010-08-27 20:11 UTC (permalink / raw)
  To: Mark Brown; +Cc: Mike Frysinger, alsa-devel, Barry Song, Cliff Cai

> Please don't top post, and remember to include context in your reply so
> people can understand the context of your message0.  This is standard
> for Linux kernel mailing lists.


Thanks, no more top posts for me...


>
>> I have not entered any constraints into the driver because there really
>> should be no need.  The driver just copies whatever PCM data that is
>> provided directly to the DMA buffer.  It seems that the problem occurs
>> because the location to copy to is based on the pos suggested by the
>> callback function.  I am still finding it difficult to tell how ALSA decides
>> there is an underrun or overrun.  I am definitely trying to read or write
>> the pcm data fast enough but it seems as though I get these errors anyway.
>
> I've no idea what "the callback function" is?


The callback function is the PCM copy function that I define in struct
snd_pcm_ops


>
>> Questions:
>> 1.  How do I implement an ASoC-style driver that supports multiple chips
>> when they are connected to the same SPORT but use different SPI chip
>> selects?
>
> Look at current ASoC in -next, I've never tried this multi drop DAI
> setup directly myself but it does support multiple CODECs in the system.


I could not find anything in the linux-2.6.x/sound/soc/ directory
called "next" and cannot find any documentation in
linux-2.6.x/Documentation/sound/alsa/soc about "multi drop"


>
>> 2.  How do I define the proper buffer/period size constraints or should I
>> ignore the suggested position during copy operations and just keep track of
>> the position within the DMA buffer myself?
>
> Your constraints will flow from the requirements of the hardware plus
> any additional requirements that the driver you've written imposes.  For
> example, if you always need a period of data ready to start DMA on which
> the application can't touch for coherency reasons then you need to make
> sure that there's at least three periods (running, about to run and
> updatable), or if your hardware DMAs in blocks you need a minimum period
> size for that.


This information was a little cryptic at first.  It turns out it was
the diamond in the rough though.  I set periods_min in struct
snd_pcm_hardware to 3 and it solved quite a few underrun problems.

Question: Is there a way I can force ALSA to always use a period size
that is a multiple of 16?


>
>> 3.  Can you suggest a good way to debug underrun/overrun problems?
>
> There's a few settings for XRUN detection diagnostics in the ALSA core
> code which can be useful - see pcm_lib.c and the SND_PCM_XRUN_DEBUG
> config option.
>


Thank you for this tip.  It turns out you need to enable
SND_VERBOSE_PROCFS to see this option in the kernel configuration.  I
am hoping this additional debug information may help me to figure out
why plughw has never been able to properly convert the sample rate for
me.

Thanks and have a great weekend,
Adam

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problem with underrun on new CS42448 x2 driver
  2010-08-26 18:06   ` Adam Rosenberg
  2010-08-26 18:52     ` Mark Brown
@ 2010-08-27 20:37     ` Mike Frysinger
  2010-08-27 21:20       ` Mark Brown
  1 sibling, 1 reply; 9+ messages in thread
From: Mike Frysinger @ 2010-08-27 20:37 UTC (permalink / raw)
  To: Adam Rosenberg; +Cc: alsa-devel, Mark Brown, Barry Song, Cliff Cai, Sonic Zhang

On Thu, Aug 26, 2010 at 14:06, Adam Rosenberg wrote:
> Thank you for the reply.  I emailed Barry Song on July 30th to request some
> help moving to the new ASoC standards but received no response.

developers shouldnt be e-mailed directly ... it isnt uncommon for them
to simply be punted.  this is why we have mailing lists and forums.

> I began writing this driver on the Blackfin uClinux 2009 release and based
> it on the AD1836 and AD1938 drivers.  I am now using the Blackfin SVN trunk
> and have found that the driver model was changed to ASoC.  It is not
> apparent how I would create a driver that supports two chips off of the same
> SPORT using the ASoC framework.
>
> The best I could do was use the same SPORT driver that the ASoC code uses
> (bf5xx-sport.c) so that I was at least up-to-date in that area.  I had to
> modify that driver so that it would support the secondary data lines of the
> SPORT.  I found that the driver did not function well in 2D DMA mode so I
> have to keep my period size below 64kb.  There is also a problem with
> starting Rx and Tx that causes the DMA data to be placed into the SPORT
> multichannel window incorrectly.  I added a function to the SPORT driver
> yesterday that can work around this problem by starting both Rx and Tx as
> normal then stopping the SPORT and restarting it like this:
>
> int sport_start_both(struct sport_device *sport)
> {
>     sport_tx_start(sport);
>     msleep(1);  // is this needed?
>     sport_rx_start(sport);
>     msleep(1);  // is this needed?
>     sport_stop(sport);
>     msleep(1);  // is this needed?
>     sport_start(sport);
>     return 0;
> }
> EXPORT_SYMBOL(sport_start_both);
>
> This ensures that the data from the DMA buffer is properly loaded into the
> SPORT multichannel window for both the Rx and Tx data lines.  If it is not
> done this way it seems that one of them is always being filled incorrectly.
> This may have sometime to do with the fact that I have to enable the
> secondary data lines but there is no clear explanation for why that would
> have an effect.
>
> I have not entered any constraints into the driver because there really
> should be no need.  The driver just copies whatever PCM data that is
> provided directly to the DMA buffer.  It seems that the problem occurs
> because the location to copy to is based on the pos suggested by the
> callback function.  I am still finding it difficult to tell how ALSA decides
> there is an underrun or overrun.  I am definitely trying to read or write
> the pcm data fast enough but it seems as though I get these errors anyway.
>
> Questions:
> 1.  How do I implement an ASoC-style driver that supports multiple chips
> when they are connected to the same SPORT but use different SPI chip
> selects?
> 2.  How do I define the proper buffer/period size constraints or should I
> ignore the suggested position during copy operations and just keep track of
> the position within the DMA buffer myself?
> 3.  Can you suggest a good way to debug underrun/overrun problems?

i dont really know ASoC/SPORTs, so we'd have to get someone to look into it
-mike
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problem with underrun on new CS42448 x2 driver
  2010-08-27 20:37     ` Mike Frysinger
@ 2010-08-27 21:20       ` Mark Brown
  2010-08-27 23:00         ` Mike Frysinger
  0 siblings, 1 reply; 9+ messages in thread
From: Mark Brown @ 2010-08-27 21:20 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: Adam Rosenberg, alsa-devel, Sonic Zhang, Barry Song, Cliff Cai

On Fri, Aug 27, 2010 at 04:37:45PM -0400, Mike Frysinger wrote:
> On Thu, Aug 26, 2010 at 14:06, Adam Rosenberg wrote:
> > Thank you for the reply.  I emailed Barry Song on July 30th to request some
> > help moving to the new ASoC standards but received no response.

> developers shouldnt be e-mailed directly ... it isnt uncommon for them
> to simply be punted.  this is why we have mailing lists and forums.

That's shouldn't *only* be e-mailed directly (for Linux stuff).  You
should generally keep the relevant folks in the CC as well but also mail
the lists concerned.  The direct mail is there because the lists can be
high volume so it helps people see the mail, while the lists mean that
people other than those you thought of will be able to help and that any
answers will be archived for other people who might need them.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problem with underrun on new CS42448 x2 driver
  2010-08-27 20:11       ` Adam Rosenberg
@ 2010-08-27 22:04         ` Mark Brown
  0 siblings, 0 replies; 9+ messages in thread
From: Mark Brown @ 2010-08-27 22:04 UTC (permalink / raw)
  To: Adam Rosenberg; +Cc: Mike Frysinger, alsa-devel, Barry Song, Cliff Cai

On Fri, Aug 27, 2010 at 04:11:48PM -0400, Adam Rosenberg wrote:

> >> I have not entered any constraints into the driver because there really
> >> should be no need.  The driver just copies whatever PCM data that is
> >> provided directly to the DMA buffer.  It seems that the problem occurs
> >> because the location to copy to is based on the pos suggested by the
> >> callback function.  I am still finding it difficult to tell how ALSA decides
> >> there is an underrun or overrun.  I am definitely trying to read or write
> >> the pcm data fast enough but it seems as though I get these errors anyway.

> > I've no idea what "the callback function" is?

> The callback function is the PCM copy function that I define in struct
> snd_pcm_ops

So, this will be decided based on how much data ALSA thinks is being
consumed and how much it thinks can be 

> >> Questions:
> >> 1.  How do I implement an ASoC-style driver that supports multiple chips
> >> when they are connected to the same SPORT but use different SPI chip
> >> selects?

> > Look at current ASoC in -next, I've never tried this multi drop DAI
> > setup directly myself but it does support multiple CODECs in the system.

> I could not find anything in the linux-2.6.x/sound/soc/ directory
> called "next" and cannot find any documentation in
> linux-2.6.x/Documentation/sound/alsa/soc about "multi drop"

-next is Stephen Rothewell's linux-next tree which contains the latest
development versions of all the trees that are likely to go into Linux
at the next merge window.

The documenation is bitrotted here but you're looking for the recent
multi-component changes.

> >> 2.  How do I define the proper buffer/period size constraints or should I
> >> ignore the suggested position during copy operations and just keep track of
> >> the position within the DMA buffer myself?

> > Your constraints will flow from the requirements of the hardware plus
> > any additional requirements that the driver you've written imposes.  For
> > example, if you always need a period of data ready to start DMA on which
> > the application can't touch for coherency reasons then you need to make
> > sure that there's at least three periods (running, about to run and
> > updatable), or if your hardware DMAs in blocks you need a minimum period
> > size for that.

> This information was a little cryptic at first.  It turns out it was
> the diamond in the rough though.  I set periods_min in struct
> snd_pcm_hardware to 3 and it solved quite a few underrun problems.

Right, so this means that previously you were not getting as much data
as you needed buffered by your application so when the driver ran out of
data to feed to the hardware the application hadn't provided any.

> Question: Is there a way I can force ALSA to always use a period size
> that is a multiple of 16?

You're looking for 

        snd_pcm_hw_constraint_step(runtime, 0,
                                   SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 16);

I suspect but ICBW - it'll be one of the snd_pcm_hw_constraint_()
functions.  Take a look at what other drivers are doing with this sort
of stuff.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problem with underrun on new CS42448 x2 driver
  2010-08-27 21:20       ` Mark Brown
@ 2010-08-27 23:00         ` Mike Frysinger
  0 siblings, 0 replies; 9+ messages in thread
From: Mike Frysinger @ 2010-08-27 23:00 UTC (permalink / raw)
  To: Mark Brown; +Cc: Adam Rosenberg, alsa-devel, Sonic Zhang, Barry Song, Cliff Cai


[-- Attachment #1.1: Type: Text/Plain, Size: 1131 bytes --]

On Friday, August 27, 2010 17:20:25 Mark Brown wrote:
> On Fri, Aug 27, 2010 at 04:37:45PM -0400, Mike Frysinger wrote:
> > On Thu, Aug 26, 2010 at 14:06, Adam Rosenberg wrote:
> > > Thank you for the reply.  I emailed Barry Song on July 30th to request
> > > some help moving to the new ASoC standards but received no response.
> > 
> > developers shouldnt be e-mailed directly ... it isnt uncommon for them
> > to simply be punted.  this is why we have mailing lists and forums.
> 
> That's shouldn't *only* be e-mailed directly (for Linux stuff).  You
> should generally keep the relevant folks in the CC as well but also mail
> the lists concerned.  The direct mail is there because the lists can be
> high volume so it helps people see the mail, while the lists mean that
> people other than those you thought of will be able to help and that any
> answers will be archived for other people who might need them.

right of course.  i meant e-mailing people directly and not including lists.

for Blackfin issues, we have a mailing list that should always be CC-ed 
whenever the Blackfin is involved.
-mike

[-- Attachment #1.2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2010-08-27 23:01 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-24 19:47 Problem with underrun on new CS42448 x2 driver Adam Rosenberg
2010-08-26 12:47 ` Mark Brown
2010-08-26 18:06   ` Adam Rosenberg
2010-08-26 18:52     ` Mark Brown
2010-08-27 20:11       ` Adam Rosenberg
2010-08-27 22:04         ` Mark Brown
2010-08-27 20:37     ` Mike Frysinger
2010-08-27 21:20       ` Mark Brown
2010-08-27 23:00         ` Mike Frysinger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.