diff options
Diffstat (limited to 'sound/soc/omap/omap-pcm.c')
-rw-r--r-- | sound/soc/omap/omap-pcm.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index e6a6b99..a2a464f 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -198,6 +198,14 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); else if (!substream->runtime->no_period_wakeup) omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); + else { + /* + * No period wakeup: + * we need to disable BLOCK_IRQ, which is enabled by the omap + * dma core at request dma time. + */ + omap_disable_dma_irq(prtd->dma_ch, OMAP_DMA_BLOCK_IRQ); + } if (!(cpu_class_is_omap1())) { omap_set_dma_src_burst_mode(prtd->dma_ch, @@ -235,6 +243,11 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_PUSH: prtd->period_index = -1; omap_stop_dma(prtd->dma_ch); + /* Since we are using self linking, there is a + chance that the DMA as re-enabled the channel + just after disabling it */ + while (omap_get_dma_active_status(prtd->dma_ch)) + omap_stop_dma(prtd->dma_ch); break; default: ret = -EINVAL; @@ -280,6 +293,15 @@ static int omap_pcm_open(struct snd_pcm_substream *substream) SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) goto out; + if (cpu_is_omap44xx()) { + /* ABE needs a step of 24 * 4 data bits, and HDMI 32 * 4 + * Ensure buffer size satisfies both constraints. + */ + ret = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 384); + if (ret < 0) + goto out; + } prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); if (prtd == NULL) { @@ -366,9 +388,10 @@ static void omap_pcm_free_dma_buffers(struct snd_pcm *pcm) } } -static int omap_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, - struct snd_pcm *pcm) +static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd) { + struct snd_card *card = rtd->card->snd_card; + struct snd_pcm *pcm = rtd->pcm; int ret = 0; if (!card->dev->dma_mask) @@ -376,14 +399,14 @@ static int omap_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = DMA_BIT_MASK(64); - if (dai->driver->playback.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = omap_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) goto out; } - if (dai->driver->capture.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { ret = omap_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) |