ASoC: omap-mcbsp: Use DMA packet mode for non mono streams on OMAP3+
authorPeter Ujfalusi <peter.ujfalusi@ti.com>
Thu, 15 Mar 2012 10:20:32 +0000 (12:20 +0200)
committerLiam Girdwood <lrg@ti.com>
Tue, 22 May 2012 16:33:18 +0000 (17:33 +0100)
Take the DMA packet mode into use when the McBSP is configured in element
dma_op_mode if the stream is not mono.
In this way we transfer one sample from/to McBSP FIFO upon DMA request.
This change only affects OMAP3+ versions, where the McBSP ports have FIFO.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Jarkko Nikula <jarkko.nikula@bitmer.com>
Signed-off-by: Liam Girdwood <lrg@ti.com>
sound/soc/omap/omap-mcbsp.c

index 6912ac7cb6250ae8cf30b886d507e0ffdfe2df9a..418dc3cebdeca59720b69cd88b6ae14fd77f93a6 100644 (file)
@@ -71,18 +71,17 @@ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
 
        dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 
-       /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
-       if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
-               /*
-                * Configure McBSP threshold based on either:
-                * packet_size, when the sDMA is in packet mode, or
-                * based on the period size.
-                */
-               if (dma_data->packet_size)
-                       words = dma_data->packet_size;
-               else
-                       words = snd_pcm_lib_period_bytes(substream) /
-                                                       (mcbsp->wlen / 8);
+       /*
+        * Configure McBSP threshold based on either:
+        * packet_size, when the sDMA is in packet mode, or based on the
+        * period size in THRESHOLD mode, otherwise use McBSP threshold = 1
+        * for mono streams.
+        */
+       if (dma_data->packet_size)
+               words = dma_data->packet_size;
+       else if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
+               words = snd_pcm_lib_period_bytes(substream) /
+                                               (mcbsp->wlen / 8);
        else
                words = 1;
 
@@ -230,6 +229,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
        unsigned int format, div, framesize, master;
 
        dma_data = &mcbsp->dma_data[substream->stream];
+       channels = params_channels(params);
 
        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S16_LE:
@@ -283,6 +283,10 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
                        } else {
                                sync_mode = OMAP_DMA_SYNC_FRAME;
                        }
+               } else if (channels > 1) {
+                       /* Use packet mode for non mono streams */
+                       pkt_size = channels;
+                       sync_mode = OMAP_DMA_SYNC_PACKET;
                }
        }
 
@@ -301,7 +305,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
        regs->rcr1      &= ~(RFRLEN1(0x7f) | RWDLEN1(7));
        regs->xcr1      &= ~(XFRLEN1(0x7f) | XWDLEN1(7));
        format = mcbsp->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
-       wpf = channels = params_channels(params);
+       wpf = channels;
        if (channels == 2 && (format == SND_SOC_DAIFMT_I2S ||
                              format == SND_SOC_DAIFMT_LEFT_J)) {
                /* Use dual-phase frames */