ASoC: omap-pcm: Prepare to configure the DMA data_type based on stream properties
authorPeter Ujfalusi <peter.ujfalusi@ti.com>
Fri, 14 Sep 2012 12:05:52 +0000 (15:05 +0300)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Sat, 22 Sep 2012 15:12:59 +0000 (11:12 -0400)
Based on the format of the stream the omap-pcm can decide alone what data
type should be used with by the sDMA.
Keep the possibility for OMAP dai drivers to tell omap-pcm if they want to
use different data type. This is needed for the omap-hdmi for example which
needs 32bit data type even if the stream format is S16_LE.

The check if (dma_data->data_type) is safe at the moment since omap-pcm
does not support 8bit samples (OMAP_DMA_DATA_TYPE_S8 == 0x00).

The next step is to redefine the meaning of dma_data->data_type to unblock
this limitation.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Tested-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
sound/soc/omap/omap-pcm.c

index 02eeb2e7cedade0f699345e69dd996f2d320e453..4c13a5f4eebb4456cce635f53eabdc87724cce4c 100644 (file)
@@ -149,6 +149,24 @@ static int omap_pcm_hw_free(struct snd_pcm_substream *substream)
        return 0;
 }
 
+static int omap_pcm_get_dma_type(int num_bits)
+{
+       int data_type;
+
+       switch (num_bits) {
+       case 16:
+               data_type = OMAP_DMA_DATA_TYPE_S16;
+               break;
+       case 32:
+               data_type = OMAP_DMA_DATA_TYPE_S32;
+               break;
+       default:
+               data_type = -EINVAL;
+               break;
+       }
+       return data_type;
+}
+
 static int omap_pcm_prepare(struct snd_pcm_substream *substream)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
@@ -163,7 +181,16 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
                return 0;
 
        memset(&dma_params, 0, sizeof(dma_params));
-       dma_params.data_type                    = dma_data->data_type;
+
+       if (dma_data->data_type)
+               dma_params.data_type = dma_data->data_type;
+       else
+               dma_params.data_type = omap_pcm_get_dma_type(
+                               snd_pcm_format_physical_width(runtime->format));
+
+       if (dma_params.data_type < 0)
+               return dma_params.data_type;
+
        dma_params.trigger                      = dma_data->dma_req;
 
        if (dma_data->packet_size)
@@ -195,7 +222,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
         * still can get an interrupt at each period bounary
         */
        bytes = snd_pcm_lib_period_bytes(substream);
-       dma_params.elem_count   = bytes >> dma_data->data_type;
+       dma_params.elem_count   = bytes >> dma_params.data_type;
        dma_params.frame_count  = runtime->periods;
        omap_set_dma_params(prtd->dma_ch, &dma_params);