[alsa-devel] [PATCH v3] ASoC: soc-compress: Add support for not memory mapped DSPs

Charles Keepax ckeepax at opensource.wolfsonmicro.com
Tue Feb 5 11:41:47 CET 2013


The ASoC compressed API did not implement the copy callback in its
compressed ops which is required for DSPs that are not memory mapped.

This patch creates a local copy of the compress ops for each runtime and
modifies them with a copy callback as appropriate.

Signed-off-by: Charles Keepax <ckeepax at opensource.wolfsonmicro.com>
---
 sound/soc/soc-compress.c |   38 +++++++++++++++++++++++++++++++++++---
 1 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 3ea7956..c81aeec 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -302,6 +302,22 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
 	return 0;
 }
 
+static int soc_compr_copy(struct snd_compr_stream *cstream,
+			  const char __user *buf, size_t count)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct snd_soc_platform *platform = rtd->platform;
+	int ret = 0;
+
+	mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+
+	if (platform->driver->compr_ops && platform->driver->compr_ops->copy)
+		ret = platform->driver->compr_ops->copy(cstream, buf, count);
+
+	mutex_unlock(&rtd->pcm_mutex);
+	return ret;
+}
+
 /* ASoC Compress operations */
 static struct snd_compr_ops soc_compr_ops = {
 	.open		= soc_compr_open,
@@ -319,6 +335,7 @@ static struct snd_compr_ops soc_compr_ops = {
 int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
 {
 	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_platform *platform = rtd->platform;
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_compr *compr;
@@ -335,14 +352,25 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
 		return -ENOMEM;
 	}
 
-	compr->ops = &soc_compr_ops;
+	compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
+				  GFP_KERNEL);
+	if (compr->ops == NULL) {
+		dev_err(rtd->card->dev, "Cannot allocate compressed ops\n");
+		ret = -ENOMEM;
+		goto compr_err;
+	}
+	memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
+
+	/* Add copy callback for not memory mapped DSPs */
+	if (platform->driver->compr_ops && platform->driver->compr_ops->copy)
+		compr->ops->copy = soc_compr_copy;
+
 	mutex_init(&compr->lock);
 	ret = snd_compress_new(rtd->card->snd_card, num, direction, compr);
 	if (ret < 0) {
 		pr_err("compress asoc: can't create compress for codec %s\n",
 			codec->name);
-		kfree(compr);
-		return ret;
+		goto compr_err;
 	}
 
 	/* DAPM dai link stream work */
@@ -354,4 +382,8 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
 	printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name,
 		cpu_dai->name);
 	return ret;
+
+compr_err:
+	kfree(compr);
+	return ret;
 }
-- 
1.7.2.5



More information about the Alsa-devel mailing list