diff options
author | Eliot Blennerhassett <eblennerhassett@audioscience.com> | 2011-04-05 04:55:43 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-04-05 05:47:08 -0400 |
commit | 0b7ce9e2bd2d9dbc8f4797b0cd5e0d138cb529e1 (patch) | |
tree | cefa6f59f25f536b0f1f84bd161297ed02729b12 /sound | |
parent | a6477134db119a22aa30911ff18e440b8db9df65 (diff) |
ALSA: asihpi: Handle playback drained status better
Use the card drained status reporting for playback,
but allow it to persist for a few timer cycles before
signalling XRUN, to allow card to recover by itself.
Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/asihpi/asihpi.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 434342f874ff..a5226e3af3d7 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c | |||
@@ -165,6 +165,7 @@ struct snd_card_asihpi_pcm { | |||
165 | unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */ | 165 | unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */ |
166 | unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */ | 166 | unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */ |
167 | unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */ | 167 | unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */ |
168 | unsigned int drained_count; | ||
168 | struct snd_pcm_substream *substream; | 169 | struct snd_pcm_substream *substream; |
169 | u32 h_stream; | 170 | u32 h_stream; |
170 | struct hpi_format format; | 171 | struct hpi_format format; |
@@ -592,6 +593,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
592 | if (substream->stream != s->stream) | 593 | if (substream->stream != s->stream) |
593 | continue; | 594 | continue; |
594 | 595 | ||
596 | ds->drained_count = 0; | ||
595 | if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && | 597 | if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && |
596 | (card->support_mmap)) { | 598 | (card->support_mmap)) { |
597 | /* How do I know how much valid data is present | 599 | /* How do I know how much valid data is present |
@@ -771,12 +773,18 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
771 | (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { | 773 | (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { |
772 | hpi_handle_error(hpi_stream_start(ds->h_stream)); | 774 | hpi_handle_error(hpi_stream_start(ds->h_stream)); |
773 | snd_printdd("P%d start\n", s->number); | 775 | snd_printdd("P%d start\n", s->number); |
776 | ds->drained_count = 0; | ||
774 | } | 777 | } |
775 | } else if (state == HPI_STATE_DRAINED) { | 778 | } else if (state == HPI_STATE_DRAINED) { |
776 | snd_printd(KERN_WARNING "P%d drained\n", | 779 | snd_printd(KERN_WARNING "P%d drained\n", |
777 | s->number); | 780 | s->number); |
778 | /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); | 781 | ds->drained_count++; |
779 | continue; */ | 782 | if (ds->drained_count > 2) { |
783 | snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); | ||
784 | continue; | ||
785 | } | ||
786 | } else { | ||
787 | ds->drained_count = 0; | ||
780 | } | 788 | } |
781 | } else | 789 | } else |
782 | pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs; | 790 | pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs; |