ASoC: dmaengine-pcm: Add support for platforms which can't report residue
authorLars-Peter Clausen <lars@metafoo.de>
Mon, 15 Apr 2013 17:19:55 +0000 (19:19 +0200)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Wed, 17 Apr 2013 13:25:56 +0000 (14:25 +0100)
Unfortunately there are still quite a few platforms with a dmaengine driver
which do not support reporting the number of bytes left to transfer. If we want
to support these platforms in the generic dmaengine PCM driver we have.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Tested-by: Stephen Warren <swarren@nvidia.com>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
include/sound/dmaengine_pcm.h
sound/soc/soc-generic-dmaengine-pcm.c

index 1a7897a..e705286 100644 (file)
@@ -86,6 +86,11 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
  * makes sense if SND_DMAENGINE_PCM_FLAG_COMPAT is set as well.
  */
 #define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1)
+/*
+ * The platforms dmaengine driver does not support reporting the ammount of
+ * bytes that are still left to transfer.
+ */
+#define SND_DMAENGINE_PCM_FLAG_NO_RESIDUE BIT(2)
 
 /**
  * struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM
index d6e6380..ae0c37e 100644 (file)
@@ -193,6 +193,23 @@ static const struct snd_soc_platform_driver dmaengine_pcm_platform = {
        .probe_order    = SND_SOC_COMP_ORDER_LATE,
 };
 
+static const struct snd_pcm_ops dmaengine_no_residue_pcm_ops = {
+       .open           = dmaengine_pcm_open,
+       .close          = snd_dmaengine_pcm_close,
+       .ioctl          = snd_pcm_lib_ioctl,
+       .hw_params      = dmaengine_pcm_hw_params,
+       .hw_free        = snd_pcm_lib_free_pages,
+       .trigger        = snd_dmaengine_pcm_trigger,
+       .pointer        = snd_dmaengine_pcm_pointer_no_residue,
+};
+
+static const struct snd_soc_platform_driver dmaengine_no_residue_pcm_platform = {
+       .ops            = &dmaengine_no_residue_pcm_ops,
+       .pcm_new        = dmaengine_pcm_new,
+       .pcm_free       = dmaengine_pcm_free,
+       .probe_order    = SND_SOC_COMP_ORDER_LATE,
+};
+
 static const char * const dmaengine_pcm_dma_channel_names[] = {
        [SNDRV_PCM_STREAM_PLAYBACK] = "tx",
        [SNDRV_PCM_STREAM_CAPTURE] = "rx",
@@ -226,7 +243,11 @@ int snd_dmaengine_pcm_register(struct device *dev,
                }
        }
 
-       return snd_soc_add_platform(dev, &pcm->platform,
+       if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE)
+               return snd_soc_add_platform(dev, &pcm->platform,
+                               &dmaengine_no_residue_pcm_platform);
+       else
+               return snd_soc_add_platform(dev, &pcm->platform,
                                &dmaengine_pcm_platform);
 }
 EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_register);