diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-05-03 11:02:35 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-05-03 11:02:35 -0400 |
commit | c7aad3c317afc05418414c95e877173799145d0b (patch) | |
tree | d091d02fdbd48f6b38207149aa7c07719d7d2b9c /sound/pci/lola | |
parent | 7e79f2267605e59492fef92b966dddc3c6a68b41 (diff) |
ALSA: lola - Add sync in loop implementation
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>
Diffstat (limited to 'sound/pci/lola')
-rw-r--r-- | sound/pci/lola/lola_pcm.c | 76 |
1 files changed, 59 insertions, 17 deletions
diff --git a/sound/pci/lola/lola_pcm.c b/sound/pci/lola/lola_pcm.c index 6be6b7e8f567..5c0014cbff07 100644 --- a/sound/pci/lola/lola_pcm.c +++ b/sound/pci/lola/lola_pcm.c | |||
@@ -121,27 +121,69 @@ static int lola_stream_wait_for_fifo(struct lola *chip, | |||
121 | return -EIO; | 121 | return -EIO; |
122 | } | 122 | } |
123 | 123 | ||
124 | static void lola_stream_reset(struct lola *chip, struct lola_stream *str) | 124 | /* sync for FIFO ready/empty for all linked streams; |
125 | * clear paused flag when FIFO gets ready again | ||
126 | */ | ||
127 | static int lola_sync_wait_for_fifo(struct lola *chip, | ||
128 | struct snd_pcm_substream *substream, | ||
129 | bool ready) | ||
125 | { | 130 | { |
126 | if (str->prepared) { | 131 | unsigned int val = ready ? LOLA_DSD_STS_FIFORDY : 0; |
127 | str->prepared = 0; | 132 | unsigned long end_time = jiffies + msecs_to_jiffies(200); |
133 | struct snd_pcm_substream *s; | ||
134 | int pending = 0; | ||
135 | |||
136 | while (time_before(jiffies, end_time)) { | ||
137 | pending = 0; | ||
138 | snd_pcm_group_for_each_entry(s, substream) { | ||
139 | struct lola_stream *str; | ||
140 | if (s->pcm->card != substream->pcm->card) | ||
141 | continue; | ||
142 | str = lola_get_stream(s); | ||
143 | if (str->prepared && str->paused) { | ||
144 | unsigned int reg; | ||
145 | reg = lola_dsd_read(chip, str->dsd, STS); | ||
146 | if ((reg & LOLA_DSD_STS_FIFORDY) != val) { | ||
147 | pending = str->dsd + 1; | ||
148 | break; | ||
149 | } | ||
150 | if (ready) | ||
151 | str->paused = 0; | ||
152 | } | ||
153 | } | ||
154 | if (!pending) | ||
155 | return 0; | ||
156 | msleep(1); | ||
157 | } | ||
158 | printk(KERN_WARNING SFX "FIFO not ready (pending %d)\n", pending - 1); | ||
159 | return -EIO; | ||
160 | } | ||
128 | 161 | ||
129 | if (str->paused) { | 162 | /* finish pause - prepare for a new resume */ |
130 | /* finish pause - prepare for a new resume | 163 | static void lola_sync_pause(struct lola *chip, |
131 | * move this code later to trigger function, | 164 | struct snd_pcm_substream *substream) |
132 | * as this is also needed when resuming from pause | 165 | { |
133 | */ | 166 | struct snd_pcm_substream *s; |
134 | str->paused = 0; | 167 | |
135 | /* implement later loop for all streams */ | 168 | lola_sync_wait_for_fifo(chip, substream, false); |
136 | lola_stream_wait_for_fifo(chip, str, false); | 169 | snd_pcm_group_for_each_entry(s, substream) { |
170 | struct lola_stream *str; | ||
171 | if (s->pcm->card != substream->pcm->card) | ||
172 | continue; | ||
173 | str = lola_get_stream(s); | ||
174 | if (str->paused && str->prepared) | ||
137 | lola_dsd_write(chip, str->dsd, CTL, LOLA_DSD_CTL_SRUN | | 175 | lola_dsd_write(chip, str->dsd, CTL, LOLA_DSD_CTL_SRUN | |
138 | LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE); | 176 | LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE); |
139 | /* end loop */ | 177 | } |
140 | /* implement later once more loop for all streams */ | 178 | lola_sync_wait_for_fifo(chip, substream, true); |
141 | lola_stream_wait_for_fifo(chip, str, true); | 179 | } |
142 | /* end loop */ | 180 | |
143 | /* end finish pause */ | 181 | static void lola_stream_reset(struct lola *chip, struct lola_stream *str) |
144 | } | 182 | { |
183 | if (str->prepared) { | ||
184 | if (str->paused) | ||
185 | lola_sync_pause(chip, str->substream); | ||
186 | str->prepared = 0; | ||
145 | lola_dsd_write(chip, str->dsd, CTL, | 187 | lola_dsd_write(chip, str->dsd, CTL, |
146 | LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE); | 188 | LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE); |
147 | lola_stream_wait_for_fifo(chip, str, false); | 189 | lola_stream_wait_for_fifo(chip, str, false); |