aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/omap/omap-mcbsp.c
diff options
context:
space:
mode:
authorJarkko Nikula <jhnikula@gmail.com>2009-08-07 02:59:47 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-07 05:57:42 -0400
commitc12abc012e18b362204345c323536f228d65c4db (patch)
tree105552bd558076eb3206ce5f4026af60921dc27f /sound/soc/omap/omap-mcbsp.c
parent06c71282a90470184a78f7f0ab0f7ce0fc1f69c8 (diff)
ARM: OMAP: McBSP: Fix ASoC on OMAP1510 by fixing API of omap_mcbsp_start/stop
Simultaneous audio playback and capture on OMAP1510 can cause that second stream is stalled if there is enough delay between startup of the audio streams. Current implementation of the omap_mcbsp_start is starting both transmitter and receiver at the same time and it is called only for firstly started audio stream from the OMAP McBSP based ASoC DAI driver. Since DMA request lines on OMAP1510 are edge sensitive, the DMA request is missed if there is no DMA transfer set up at that time when the first word after McBSP startup is transmitted. The problem hasn't noted before since later OMAPs are using level sensitive DMA request lines. Fix the problem by changing API of omap_mcbsp_start and omap_mcbsp_stop by allowing to start and stop individually McBSP transmitter and receiver logics. Then call those functions individually for both audio playback and capture streams. This ensures that DMA transfer is setup before transmitter or receiver is started. Thanks to Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> for detailed problem analysis and Peter Ujfalusi <peter.ujfalusi@nokia.com> for info about DMA request line behavior differences between the OMAP generations. Reported-and-tested-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Signed-off-by: Jarkko Nikula <jhnikula@gmail.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/omap/omap-mcbsp.c')
-rw-r--r--sound/soc/omap/omap-mcbsp.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index a5d46a7b196a..6a837ffd5d0b 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -183,21 +183,21 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
183 struct snd_soc_pcm_runtime *rtd = substream->private_data; 183 struct snd_soc_pcm_runtime *rtd = substream->private_data;
184 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 184 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
185 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 185 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
186 int err = 0; 186 int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
187 187
188 switch (cmd) { 188 switch (cmd) {
189 case SNDRV_PCM_TRIGGER_START: 189 case SNDRV_PCM_TRIGGER_START:
190 case SNDRV_PCM_TRIGGER_RESUME: 190 case SNDRV_PCM_TRIGGER_RESUME:
191 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 191 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
192 if (!mcbsp_data->active++) 192 mcbsp_data->active++;
193 omap_mcbsp_start(mcbsp_data->bus_id); 193 omap_mcbsp_start(mcbsp_data->bus_id, play, !play);
194 break; 194 break;
195 195
196 case SNDRV_PCM_TRIGGER_STOP: 196 case SNDRV_PCM_TRIGGER_STOP:
197 case SNDRV_PCM_TRIGGER_SUSPEND: 197 case SNDRV_PCM_TRIGGER_SUSPEND:
198 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 198 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
199 if (!--mcbsp_data->active) 199 omap_mcbsp_stop(mcbsp_data->bus_id, play, !play);
200 omap_mcbsp_stop(mcbsp_data->bus_id); 200 mcbsp_data->active--;
201 break; 201 break;
202 default: 202 default:
203 err = -EINVAL; 203 err = -EINVAL;