Skip to content

Commit

Permalink
ALSA: lola - Add sync in loop implementation
Browse files Browse the repository at this point in the history
For assuring the synchronized state with the pause operation,
loop over the all linked streams and waits until all get ready
in a loop.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed May 3, 2011
1 parent 7e79f22 commit c7aad3c
Showing 1 changed file with 59 additions and 17 deletions.
76 changes: 59 additions & 17 deletions sound/pci/lola/lola_pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,27 +121,69 @@ static int lola_stream_wait_for_fifo(struct lola *chip,
return -EIO;
}

static void lola_stream_reset(struct lola *chip, struct lola_stream *str)
/* sync for FIFO ready/empty for all linked streams;
* clear paused flag when FIFO gets ready again
*/
static int lola_sync_wait_for_fifo(struct lola *chip,
struct snd_pcm_substream *substream,
bool ready)
{
if (str->prepared) {
str->prepared = 0;
unsigned int val = ready ? LOLA_DSD_STS_FIFORDY : 0;
unsigned long end_time = jiffies + msecs_to_jiffies(200);
struct snd_pcm_substream *s;
int pending = 0;

while (time_before(jiffies, end_time)) {
pending = 0;
snd_pcm_group_for_each_entry(s, substream) {
struct lola_stream *str;
if (s->pcm->card != substream->pcm->card)
continue;
str = lola_get_stream(s);
if (str->prepared && str->paused) {
unsigned int reg;
reg = lola_dsd_read(chip, str->dsd, STS);
if ((reg & LOLA_DSD_STS_FIFORDY) != val) {
pending = str->dsd + 1;
break;
}
if (ready)
str->paused = 0;
}
}
if (!pending)
return 0;
msleep(1);
}
printk(KERN_WARNING SFX "FIFO not ready (pending %d)\n", pending - 1);
return -EIO;
}

if (str->paused) {
/* finish pause - prepare for a new resume
* move this code later to trigger function,
* as this is also needed when resuming from pause
*/
str->paused = 0;
/* implement later loop for all streams */
lola_stream_wait_for_fifo(chip, str, false);
/* finish pause - prepare for a new resume */
static void lola_sync_pause(struct lola *chip,
struct snd_pcm_substream *substream)
{
struct snd_pcm_substream *s;

lola_sync_wait_for_fifo(chip, substream, false);
snd_pcm_group_for_each_entry(s, substream) {
struct lola_stream *str;
if (s->pcm->card != substream->pcm->card)
continue;
str = lola_get_stream(s);
if (str->paused && str->prepared)
lola_dsd_write(chip, str->dsd, CTL, LOLA_DSD_CTL_SRUN |
LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE);
/* end loop */
/* implement later once more loop for all streams */
lola_stream_wait_for_fifo(chip, str, true);
/* end loop */
/* end finish pause */
}
}
lola_sync_wait_for_fifo(chip, substream, true);
}

static void lola_stream_reset(struct lola *chip, struct lola_stream *str)
{
if (str->prepared) {
if (str->paused)
lola_sync_pause(chip, str->substream);
str->prepared = 0;
lola_dsd_write(chip, str->dsd, CTL,
LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE);
lola_stream_wait_for_fifo(chip, str, false);
Expand Down

0 comments on commit c7aad3c

Please sign in to comment.