All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage
@ 2014-01-15 16:51 Liam Girdwood
  2014-01-15 16:51 ` [PATCH 2/2] ASoC: compress: Add suport for DPCM into compressed audio Liam Girdwood
  2014-01-16 12:31 ` [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage Mark Brown
  0 siblings, 2 replies; 16+ messages in thread
From: Liam Girdwood @ 2014-01-15 16:51 UTC (permalink / raw)
  To: Mark Brown; +Cc: Vinod Koul, Liam Girdwood, alsa-devel

The ASoC compressed code needs to call the internal DPCM APIs in order to
dynamically route compressed data to different DAIs.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
---
 include/sound/soc-dpcm.h | 22 ++++++++++++++++++++++
 sound/soc/soc-pcm.c      | 29 ++++++++++++-----------------
 2 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/include/sound/soc-dpcm.h b/include/sound/soc-dpcm.h
index 047d657..2883a7a 100644
--- a/include/sound/soc-dpcm.h
+++ b/include/sound/soc-dpcm.h
@@ -11,6 +11,7 @@
 #ifndef __LINUX_SND_SOC_DPCM_H
 #define __LINUX_SND_SOC_DPCM_H
 
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <sound/pcm.h>
 
@@ -135,4 +136,25 @@ int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute);
 int soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd);
 int soc_dpcm_runtime_update(struct snd_soc_card *);
 
+int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
+	int stream, struct snd_soc_dapm_widget_list **list_);
+int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
+	int stream, struct snd_soc_dapm_widget_list **list, int new);
+int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream);
+int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream);
+void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream);
+void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream);
+int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream);
+int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int tream);
+int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd);
+int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream);
+int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
+	int event);
+
+static inline void dpcm_path_put(struct snd_soc_dapm_widget_list **list)
+{
+	kfree(*list);
+}
+
+
 #endif
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 1534115..7023f7e 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -58,7 +58,7 @@ int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
 EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
 
 /* DPCM stream event, send event to FE and all active BEs. */
-static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
+int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
 	int event)
 {
 	struct snd_soc_dpcm *dpcm;
@@ -877,7 +877,7 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe,
 }
 
 /* disconnect a BE and FE */
-static void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
+void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
 {
 	struct snd_soc_dpcm *dpcm, *d;
 
@@ -973,7 +973,7 @@ static int widget_in_list(struct snd_soc_dapm_widget_list *list,
 	return 0;
 }
 
-static int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
+int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
 	int stream, struct snd_soc_dapm_widget_list **list_)
 {
 	struct snd_soc_dai *cpu_dai = fe->cpu_dai;
@@ -995,11 +995,6 @@ static int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
 	return paths;
 }
 
-static inline void dpcm_path_put(struct snd_soc_dapm_widget_list **list)
-{
-	kfree(*list);
-}
-
 static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream,
 	struct snd_soc_dapm_widget_list **list_)
 {
@@ -1069,7 +1064,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,
 			continue;
 
 		/* don't connect if FE is not running */
-		if (!fe->dpcm[stream].runtime)
+		if (!fe->dpcm[stream].runtime && !fe->fe_compr)
 			continue;
 
 		/* newly connected FE and BE */
@@ -1094,7 +1089,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,
  * Find the corresponding BE DAIs that source or sink audio to this
  * FE substream.
  */
-static int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
+int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
 	int stream, struct snd_soc_dapm_widget_list **list, int new)
 {
 	if (new)
@@ -1103,7 +1098,7 @@ static int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
 		return dpcm_prune_paths(fe, stream, list);
 }
 
-static void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream)
+void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream)
 {
 	struct snd_soc_dpcm *dpcm;
 
@@ -1141,7 +1136,7 @@ static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe,
 	}
 }
 
-static int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream)
+int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream)
 {
 	struct snd_soc_dpcm *dpcm;
 	int err, count = 0;
@@ -1293,7 +1288,7 @@ be_err:
 	return ret;
 }
 
-static int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
+int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
 {
 	struct snd_soc_dpcm *dpcm;
 
@@ -1354,7 +1349,7 @@ static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream)
 	return 0;
 }
 
-static int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream)
+int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream)
 {
 	struct snd_soc_dpcm *dpcm;
 
@@ -1419,7 +1414,7 @@ static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream)
 	return 0;
 }
 
-static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream)
+int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream)
 {
 	struct snd_soc_dpcm *dpcm;
 	int ret;
@@ -1549,7 +1544,7 @@ static int dpcm_do_trigger(struct snd_soc_dpcm *dpcm,
 	return ret;
 }
 
-static int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream,
+int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream,
 			       int cmd)
 {
 	struct snd_soc_dpcm *dpcm;
@@ -1717,7 +1712,7 @@ out:
 	return ret;
 }
 
-static int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream)
+int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream)
 {
 	struct snd_soc_dpcm *dpcm;
 	int ret = 0;
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/2] ASoC: compress: Add suport for DPCM into compressed audio
  2014-01-15 16:51 [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage Liam Girdwood
@ 2014-01-15 16:51 ` Liam Girdwood
  2014-01-16 15:59   ` Takashi Iwai
  2014-01-16 18:01   ` Mark Brown
  2014-01-16 12:31 ` [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage Mark Brown
  1 sibling, 2 replies; 16+ messages in thread
From: Liam Girdwood @ 2014-01-15 16:51 UTC (permalink / raw)
  To: Mark Brown; +Cc: Vinod Koul, Liam Girdwood, alsa-devel

Currently compressed audio streams are statically routed from the /dev
to the DAI link. Some DSPs can route compressed data to multiple BE DAIs
like they do for PCM data.

Add support to allow dynamically routed compressed streams using the existing
DPCM infrastructure. This patch adds special FE versions of the compressed ops
that work out the runtime routing.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
---
 include/sound/compress_driver.h |   2 +
 include/sound/soc.h             |   1 +
 sound/soc/soc-compress.c        | 301 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 303 insertions(+), 1 deletion(-)

diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h
index ae6c3b8..2b2d2fb 100644
--- a/include/sound/compress_driver.h
+++ b/include/sound/compress_driver.h
@@ -32,6 +32,7 @@
 #include <sound/pcm.h>
 
 struct snd_compr_ops;
+struct snd_pcm_substream;
 
 /**
  * struct snd_compr_runtime: runtime stream description
@@ -59,6 +60,7 @@ struct snd_compr_runtime {
 	u64 total_bytes_available;
 	u64 total_bytes_transferred;
 	wait_queue_head_t sleep;
+	struct snd_pcm_substream *fe_substream;
 	void *private_data;
 };
 
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 0a600b8d..e0233df 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1035,6 +1035,7 @@ struct snd_soc_pcm_runtime {
 
 	/* Dynamic PCM BE runtime data */
 	struct snd_soc_dpcm_runtime dpcm[2];
+	int fe_compr;
 
 	long pmdown_time;
 	unsigned char pop_wait:1;
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 53c9ecd..bcd4954 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -24,6 +24,7 @@
 #include <sound/compress_driver.h>
 #include <sound/soc.h>
 #include <sound/initval.h>
+#include <sound/soc-dpcm.h>
 
 static int soc_compr_open(struct snd_compr_stream *cstream)
 {
@@ -75,6 +76,98 @@ out:
 	return ret;
 }
 
+static int soc_compr_open_fe(struct snd_compr_stream *cstream)
+{
+	struct snd_soc_pcm_runtime *fe = cstream->private_data;
+	struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
+	struct snd_soc_platform *platform = fe->platform;
+	struct snd_soc_dai *cpu_dai = fe->cpu_dai;
+	struct snd_soc_dai *codec_dai = fe->codec_dai;
+	struct snd_soc_dpcm *dpcm;
+	struct snd_soc_dapm_widget_list *list;
+	int stream;
+	int ret = 0;
+
+	if (cstream->direction == SND_COMPRESS_PLAYBACK)
+		stream = SNDRV_PCM_STREAM_PLAYBACK;
+	else
+		stream = SNDRV_PCM_STREAM_CAPTURE;
+
+	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
+
+	if (platform->driver->compr_ops && platform->driver->compr_ops->open) {
+		ret = platform->driver->compr_ops->open(cstream);
+		if (ret < 0) {
+			pr_err("compress asoc: can't open platform %s\n", platform->name);
+			goto out;
+		}
+	}
+
+	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->startup) {
+		ret = fe->dai_link->compr_ops->startup(cstream);
+		if (ret < 0) {
+			pr_err("compress asoc: %s startup failed\n", fe->dai_link->name);
+			goto machine_err;
+		}
+	}
+
+	fe->dpcm[stream].runtime = fe_substream->runtime;
+
+	if (dpcm_path_get(fe, stream, &list) <= 0) {
+		dev_dbg(fe->dev, "ASoC: %s no valid %s route\n",
+			fe->dai_link->name, stream ? "capture" : "playback");
+	}
+
+	/* calculate valid and active FE <-> BE dpcms */
+	dpcm_process_paths(fe, stream, &list, 1);
+
+	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+
+	ret = dpcm_be_dai_startup(fe, stream);
+	if (ret < 0) {
+		/* clean up all links */
+		list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
+			dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
+
+		dpcm_be_disconnect(fe, stream);
+		fe->dpcm[stream].runtime = NULL;
+		goto fe_err;
+	}
+
+	dpcm_clear_pending_state(fe, stream);
+	dpcm_path_put(&list);
+
+	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
+	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+
+	if (cstream->direction == SND_COMPRESS_PLAYBACK) {
+		cpu_dai->playback_active++;
+		codec_dai->playback_active++;
+	} else {
+		cpu_dai->capture_active++;
+		codec_dai->capture_active++;
+	}
+
+	cpu_dai->active++;
+	codec_dai->active++;
+	fe->codec->active++;
+
+	mutex_unlock(&fe->card->mutex);
+
+	return 0;
+
+fe_err:
+	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
+		fe->dai_link->compr_ops->shutdown(cstream);
+machine_err:
+	if (platform->driver->compr_ops && platform->driver->compr_ops->free)
+		platform->driver->compr_ops->free(cstream);
+out:
+	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+	mutex_unlock(&fe->card->mutex);
+	return ret;
+}
+
 /*
  * Power down the audio subsystem pmdown_time msecs after close is called.
  * This is to ensure there are no pops or clicks in between any music tracks
@@ -164,6 +257,65 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
 	return 0;
 }
 
+static int soc_compr_free_fe(struct snd_compr_stream *cstream)
+{
+	struct snd_soc_pcm_runtime *fe = cstream->private_data;
+	struct snd_soc_platform *platform = fe->platform;
+	struct snd_soc_dai *cpu_dai = fe->cpu_dai;
+	struct snd_soc_dai *codec_dai = fe->codec_dai;
+	struct snd_soc_dpcm *dpcm;
+	int stream, ret;
+
+	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
+
+	if (cstream->direction == SND_COMPRESS_PLAYBACK) {
+		stream = SNDRV_PCM_STREAM_PLAYBACK;
+		cpu_dai->playback_active--;
+		codec_dai->playback_active--;
+	} else {
+		stream = SNDRV_PCM_STREAM_CAPTURE;
+		cpu_dai->capture_active--;
+		codec_dai->capture_active--;
+	}
+
+	cpu_dai->active--;
+	codec_dai->active--;
+	fe->codec->active--;
+
+	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+
+	ret = dpcm_be_dai_hw_free(fe, stream);
+	if (ret < 0)
+		dev_err(fe->dev, "compressed hw_free failed %d\n", ret);
+
+	ret = dpcm_be_dai_shutdown(fe, stream);
+
+	/* mark FE's links ready to prune */
+	list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
+		dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
+
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+		dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
+	else
+		dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
+
+	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
+	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+
+	dpcm_be_disconnect(fe, stream);
+
+	fe->dpcm[stream].runtime = NULL;
+
+	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
+		fe->dai_link->compr_ops->shutdown(cstream);
+
+	if (platform->driver->compr_ops && platform->driver->compr_ops->free)
+		platform->driver->compr_ops->free(cstream);
+
+	mutex_unlock(&fe->card->mutex);
+	return 0;
+}
+
 static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
 {
 
@@ -194,6 +346,59 @@ out:
 	return ret;
 }
 
+static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
+{
+	struct snd_soc_pcm_runtime *fe = cstream->private_data;
+	struct snd_soc_platform *platform = fe->platform;
+	int ret = 0, stream;
+
+	if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
+		cmd == SND_COMPR_TRIGGER_DRAIN) {
+
+		if (platform->driver->compr_ops &&
+			platform->driver->compr_ops->trigger)
+		return platform->driver->compr_ops->trigger(cstream, cmd);
+	}
+
+	if (cstream->direction == SND_COMPRESS_PLAYBACK)
+		stream = SNDRV_PCM_STREAM_PLAYBACK;
+	else
+		stream = SNDRV_PCM_STREAM_CAPTURE;
+
+
+	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
+
+	if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
+		ret = platform->driver->compr_ops->trigger(cstream, cmd);
+		if (ret < 0)
+			goto out;
+	}
+
+	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+
+	ret = dpcm_be_dai_trigger(fe, stream, cmd);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
+		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
+		break;
+	}
+
+out:
+	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+	mutex_unlock(&fe->card->mutex);
+	return ret;
+}
+
 static int soc_compr_set_params(struct snd_compr_stream *cstream,
 					struct snd_compr_params *params)
 {
@@ -241,6 +446,64 @@ err:
 	return ret;
 }
 
+static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
+					struct snd_compr_params *params)
+{
+	struct snd_soc_pcm_runtime *fe = cstream->private_data;
+	struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
+	struct snd_soc_platform *platform = fe->platform;
+	struct snd_pcm_hw_params *hw_params;
+	int ret = 0, stream;
+
+	if (cstream->direction == SND_COMPRESS_PLAYBACK)
+		stream = SNDRV_PCM_STREAM_PLAYBACK;
+	else
+		stream = SNDRV_PCM_STREAM_CAPTURE;
+
+	hw_params = kzalloc(sizeof(*hw_params), GFP_KERNEL);
+	if (hw_params == NULL)
+		return -ENOMEM;
+
+	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
+
+	if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
+		ret = platform->driver->compr_ops->set_params(cstream, params);
+		if (ret < 0)
+			goto out;
+	}
+
+	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->set_params) {
+		ret = fe->dai_link->compr_ops->set_params(cstream);
+		if (ret < 0)
+			goto out;
+	}
+
+	memcpy(&fe->dpcm[fe_substream->stream].hw_params, params,
+			sizeof(struct snd_pcm_hw_params));
+
+	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+
+	ret = dpcm_be_dai_hw_params(fe, stream);
+	if (ret < 0)
+		goto out;
+
+	ret = dpcm_be_dai_prepare(fe, stream);
+	if (ret < 0)
+		goto out;
+
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+		dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
+	else
+		dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
+
+	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
+
+out:
+	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+	mutex_unlock(&fe->card->mutex);
+	return ret;
+}
+
 static int soc_compr_get_params(struct snd_compr_stream *cstream,
 					struct snd_codec *params)
 {
@@ -360,6 +623,7 @@ static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
 
 	return ret;
 }
+
 /* ASoC Compress operations */
 static struct snd_compr_ops soc_compr_ops = {
 	.open		= soc_compr_open,
@@ -375,6 +639,21 @@ static struct snd_compr_ops soc_compr_ops = {
 	.get_codec_caps = soc_compr_get_codec_caps
 };
 
+/* ASoC Dynamic Compress operations */
+static struct snd_compr_ops soc_compr_dyn_ops = {
+	.open		= soc_compr_open_fe,
+	.free		= soc_compr_free_fe,
+	.set_params	= soc_compr_set_params_fe,
+	.get_params	= soc_compr_get_params,
+	.set_metadata   = soc_compr_set_metadata,
+	.get_metadata	= soc_compr_get_metadata,
+	.trigger	= soc_compr_trigger_fe,
+	.pointer	= soc_compr_pointer,
+	.ack		= soc_compr_ack,
+	.get_caps	= soc_compr_get_caps,
+	.get_codec_caps = soc_compr_get_codec_caps
+};
+
 /* create a new compress */
 int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
 {
@@ -383,6 +662,7 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_compr *compr;
+	struct snd_pcm *be_pcm;
 	char new_name[64];
 	int ret = 0, direction = 0;
 
@@ -410,7 +690,26 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
 		ret = -ENOMEM;
 		goto compr_err;
 	}
-	memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
+
+	if (rtd->dai_link->dynamic) {
+		snprintf(new_name, sizeof(new_name), "(%s)",
+			rtd->dai_link->stream_name);
+
+		ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
+				1, 0, &be_pcm);
+		if (ret < 0) {
+			dev_err(rtd->card->dev, "ASoC: can't create compressed for %s\n",
+				rtd->dai_link->name);
+			goto compr_err;
+		}
+
+		rtd->pcm = be_pcm;
+		rtd->fe_compr = 1;
+		be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
+		be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
+		memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
+	} else
+		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)
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage
  2014-01-15 16:51 [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage Liam Girdwood
  2014-01-15 16:51 ` [PATCH 2/2] ASoC: compress: Add suport for DPCM into compressed audio Liam Girdwood
@ 2014-01-16 12:31 ` Mark Brown
  2014-01-16 14:40   ` Vinod Koul
  1 sibling, 1 reply; 16+ messages in thread
From: Mark Brown @ 2014-01-16 12:31 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: Vinod Koul, alsa-devel


[-- Attachment #1.1: Type: text/plain, Size: 330 bytes --]

On Wed, Jan 15, 2014 at 04:51:56PM +0000, Liam Girdwood wrote:
> The ASoC compressed code needs to call the internal DPCM APIs in order to
> dynamically route compressed data to different DAIs.

Applied, thanks.  I'm holding off on the second patch for a little so
Vinod has a chance to say something since it's compressed stuff.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage
  2014-01-16 12:31 ` [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage Mark Brown
@ 2014-01-16 14:40   ` Vinod Koul
  2014-01-16 15:47     ` Liam Girdwood
  2014-01-16 15:55     ` Takashi Iwai
  0 siblings, 2 replies; 16+ messages in thread
From: Vinod Koul @ 2014-01-16 14:40 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Liam Girdwood


[-- Attachment #1.1: Type: text/plain, Size: 733 bytes --]

On Thu, Jan 16, 2014 at 12:31:53PM +0000, Mark Brown wrote:
> On Wed, Jan 15, 2014 at 04:51:56PM +0000, Liam Girdwood wrote:
> > The ASoC compressed code needs to call the internal DPCM APIs in order to
> > dynamically route compressed data to different DAIs.
> 
> Applied, thanks.  I'm holding off on the second patch for a little so
> Vinod has a chance to say something since it's compressed stuff.
Both look good to me, so

Acked-by: Vinod Koul <vinod.koul@intel.com>

The second patch still needs an update for properly copying the hw_params. This
was one of issue reported by qcom folks, but I don't want to hold these now. We
can fix that as it will impact systems not have fixup function for BEs.

--
~Vinod

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage
  2014-01-16 15:47     ` Liam Girdwood
@ 2014-01-16 14:49       ` Vinod Koul
  0 siblings, 0 replies; 16+ messages in thread
From: Vinod Koul @ 2014-01-16 14:49 UTC (permalink / raw)
  Cc: Liam Girdwood, alsa-devel, Mark Brown

On Thu, Jan 16, 2014 at 03:47:43PM +0000, Liam Girdwood wrote:
> On Thu, 2014-01-16 at 20:10 +0530, Vinod Koul wrote:
> > On Thu, Jan 16, 2014 at 12:31:53PM +0000, Mark Brown wrote:
> > > On Wed, Jan 15, 2014 at 04:51:56PM +0000, Liam Girdwood wrote:
> > > > The ASoC compressed code needs to call the internal DPCM APIs in order to
> > > > dynamically route compressed data to different DAIs.
> > > 
> > > Applied, thanks.  I'm holding off on the second patch for a little so
> > > Vinod has a chance to say something since it's compressed stuff.
> > Both look good to me, so
> > 
> > Acked-by: Vinod Koul <vinod.koul@intel.com>
> > 
> > The second patch still needs an update for properly copying the hw_params. This
> > was one of issue reported by qcom folks, but I don't want to hold these now. We
> > can fix that as it will impact systems not have fixup function for BEs.
> 
> I assume you have that fix ? If so, I can add it incrementally ?
Not yet! That's why dont want to hold off this series...

We cna update that a bit later :)

--
~Vinod

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage
  2014-01-16 15:55     ` Takashi Iwai
@ 2014-01-16 14:59       ` Vinod Koul
  2014-01-16 16:02         ` Takashi Iwai
  0 siblings, 1 reply; 16+ messages in thread
From: Vinod Koul @ 2014-01-16 14:59 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Liam Girdwood, alsa-devel, Mark Brown

On Thu, Jan 16, 2014 at 04:55:34PM +0100, Takashi Iwai wrote:
> At Thu, 16 Jan 2014 20:10:42 +0530,
> Vinod Koul wrote:
> > 
> > On Thu, Jan 16, 2014 at 12:31:53PM +0000, Mark Brown wrote:
> > > On Wed, Jan 15, 2014 at 04:51:56PM +0000, Liam Girdwood wrote:
> > > > The ASoC compressed code needs to call the internal DPCM APIs in order to
> > > > dynamically route compressed data to different DAIs.
> > > 
> > > Applied, thanks.  I'm holding off on the second patch for a little so
> > > Vinod has a chance to say something since it's compressed stuff.
> > Both look good to me, so
> > 
> > Acked-by: Vinod Koul <vinod.koul@intel.com>
> > 
> > The second patch still needs an update for properly copying the hw_params. This
> > was one of issue reported by qcom folks, but I don't want to hold these now. We
> > can fix that as it will impact systems not have fixup function for BEs.
> 
> One thing that makes me a bit nervous is that it's accessing the
> actual PCM object.  So far, sound/pcm.h is included there just because
> it's re-using the same enum definitions, etc, but it doesn't mean that
> it allows accessing a PCM object or function.
> 
> If we bind a real PCM instance there, we should add the Kconfig
> selection for SND_PCM from SND_COMPRESS_OFFLOAD.

Makes sense, but is this a practical sceanrios. I dont think we have a sound
card which supports offload only so SND_PCM will always be selected.

This is also ASoC patch, so SND_SOC would be selected, which selects SND_PCM

--
~Vinod

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage
  2014-01-16 14:40   ` Vinod Koul
@ 2014-01-16 15:47     ` Liam Girdwood
  2014-01-16 14:49       ` Vinod Koul
  2014-01-16 15:55     ` Takashi Iwai
  1 sibling, 1 reply; 16+ messages in thread
From: Liam Girdwood @ 2014-01-16 15:47 UTC (permalink / raw)
  To: Vinod Koul; +Cc: Liam Girdwood, alsa-devel, Mark Brown

On Thu, 2014-01-16 at 20:10 +0530, Vinod Koul wrote:
> On Thu, Jan 16, 2014 at 12:31:53PM +0000, Mark Brown wrote:
> > On Wed, Jan 15, 2014 at 04:51:56PM +0000, Liam Girdwood wrote:
> > > The ASoC compressed code needs to call the internal DPCM APIs in order to
> > > dynamically route compressed data to different DAIs.
> > 
> > Applied, thanks.  I'm holding off on the second patch for a little so
> > Vinod has a chance to say something since it's compressed stuff.
> Both look good to me, so
> 
> Acked-by: Vinod Koul <vinod.koul@intel.com>
> 
> The second patch still needs an update for properly copying the hw_params. This
> was one of issue reported by qcom folks, but I don't want to hold these now. We
> can fix that as it will impact systems not have fixup function for BEs.

I assume you have that fix ? If so, I can add it incrementally ?

Thanks

Liam

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage
  2014-01-16 14:40   ` Vinod Koul
  2014-01-16 15:47     ` Liam Girdwood
@ 2014-01-16 15:55     ` Takashi Iwai
  2014-01-16 14:59       ` Vinod Koul
  1 sibling, 1 reply; 16+ messages in thread
From: Takashi Iwai @ 2014-01-16 15:55 UTC (permalink / raw)
  To: Vinod Koul; +Cc: Liam Girdwood, alsa-devel, Mark Brown

At Thu, 16 Jan 2014 20:10:42 +0530,
Vinod Koul wrote:
> 
> On Thu, Jan 16, 2014 at 12:31:53PM +0000, Mark Brown wrote:
> > On Wed, Jan 15, 2014 at 04:51:56PM +0000, Liam Girdwood wrote:
> > > The ASoC compressed code needs to call the internal DPCM APIs in order to
> > > dynamically route compressed data to different DAIs.
> > 
> > Applied, thanks.  I'm holding off on the second patch for a little so
> > Vinod has a chance to say something since it's compressed stuff.
> Both look good to me, so
> 
> Acked-by: Vinod Koul <vinod.koul@intel.com>
> 
> The second patch still needs an update for properly copying the hw_params. This
> was one of issue reported by qcom folks, but I don't want to hold these now. We
> can fix that as it will impact systems not have fixup function for BEs.

One thing that makes me a bit nervous is that it's accessing the
actual PCM object.  So far, sound/pcm.h is included there just because
it's re-using the same enum definitions, etc, but it doesn't mean that
it allows accessing a PCM object or function.

If we bind a real PCM instance there, we should add the Kconfig
selection for SND_PCM from SND_COMPRESS_OFFLOAD.


Takashi

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/2] ASoC: compress: Add suport for DPCM into compressed audio
  2014-01-15 16:51 ` [PATCH 2/2] ASoC: compress: Add suport for DPCM into compressed audio Liam Girdwood
@ 2014-01-16 15:59   ` Takashi Iwai
  2014-01-16 17:08     ` Liam Girdwood
  2014-01-16 18:01   ` Mark Brown
  1 sibling, 1 reply; 16+ messages in thread
From: Takashi Iwai @ 2014-01-16 15:59 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: Vinod Koul, alsa-devel, Mark Brown

At Wed, 15 Jan 2014 16:51:57 +0000,
Liam Girdwood wrote:
> 
> Currently compressed audio streams are statically routed from the /dev
> to the DAI link. Some DSPs can route compressed data to multiple BE DAIs
> like they do for PCM data.
> 
> Add support to allow dynamically routed compressed streams using the existing
> DPCM infrastructure. This patch adds special FE versions of the compressed ops
> that work out the runtime routing.
> 
> Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
> ---
>  include/sound/compress_driver.h |   2 +
>  include/sound/soc.h             |   1 +
>  sound/soc/soc-compress.c        | 301 +++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 303 insertions(+), 1 deletion(-)
> 
> diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h
> index ae6c3b8..2b2d2fb 100644
> --- a/include/sound/compress_driver.h
> +++ b/include/sound/compress_driver.h
> @@ -32,6 +32,7 @@
>  #include <sound/pcm.h>
>  
>  struct snd_compr_ops;
> +struct snd_pcm_substream;
>  
>  /**
>   * struct snd_compr_runtime: runtime stream description
> @@ -59,6 +60,7 @@ struct snd_compr_runtime {
>  	u64 total_bytes_available;
>  	u64 total_bytes_transferred;
>  	wait_queue_head_t sleep;
> +	struct snd_pcm_substream *fe_substream;
>  	void *private_data;
>  };
>  
> diff --git a/include/sound/soc.h b/include/sound/soc.h
> index 0a600b8d..e0233df 100644
> --- a/include/sound/soc.h
> +++ b/include/sound/soc.h
> @@ -1035,6 +1035,7 @@ struct snd_soc_pcm_runtime {
>  
>  	/* Dynamic PCM BE runtime data */
>  	struct snd_soc_dpcm_runtime dpcm[2];
> +	int fe_compr;
>  
>  	long pmdown_time;
>  	unsigned char pop_wait:1;
> diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
> index 53c9ecd..bcd4954 100644
> --- a/sound/soc/soc-compress.c
> +++ b/sound/soc/soc-compress.c
> @@ -24,6 +24,7 @@
>  #include <sound/compress_driver.h>
>  #include <sound/soc.h>
>  #include <sound/initval.h>
> +#include <sound/soc-dpcm.h>
>  
>  static int soc_compr_open(struct snd_compr_stream *cstream)
>  {
> @@ -75,6 +76,98 @@ out:
>  	return ret;
>  }
>  
> +static int soc_compr_open_fe(struct snd_compr_stream *cstream)
> +{
> +	struct snd_soc_pcm_runtime *fe = cstream->private_data;
> +	struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
> +	struct snd_soc_platform *platform = fe->platform;
> +	struct snd_soc_dai *cpu_dai = fe->cpu_dai;
> +	struct snd_soc_dai *codec_dai = fe->codec_dai;
> +	struct snd_soc_dpcm *dpcm;
> +	struct snd_soc_dapm_widget_list *list;
> +	int stream;
> +	int ret = 0;
> +
> +	if (cstream->direction == SND_COMPRESS_PLAYBACK)
> +		stream = SNDRV_PCM_STREAM_PLAYBACK;
> +	else
> +		stream = SNDRV_PCM_STREAM_CAPTURE;
> +
> +	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
> +
> +	if (platform->driver->compr_ops && platform->driver->compr_ops->open) {
> +		ret = platform->driver->compr_ops->open(cstream);
> +		if (ret < 0) {
> +			pr_err("compress asoc: can't open platform %s\n", platform->name);
> +			goto out;
> +		}
> +	}
> +
> +	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->startup) {
> +		ret = fe->dai_link->compr_ops->startup(cstream);
> +		if (ret < 0) {
> +			pr_err("compress asoc: %s startup failed\n", fe->dai_link->name);
> +			goto machine_err;
> +		}
> +	}
> +
> +	fe->dpcm[stream].runtime = fe_substream->runtime;
> +
> +	if (dpcm_path_get(fe, stream, &list) <= 0) {
> +		dev_dbg(fe->dev, "ASoC: %s no valid %s route\n",
> +			fe->dai_link->name, stream ? "capture" : "playback");
> +	}
> +
> +	/* calculate valid and active FE <-> BE dpcms */
> +	dpcm_process_paths(fe, stream, &list, 1);
> +
> +	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
> +
> +	ret = dpcm_be_dai_startup(fe, stream);
> +	if (ret < 0) {
> +		/* clean up all links */
> +		list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
> +			dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
> +
> +		dpcm_be_disconnect(fe, stream);
> +		fe->dpcm[stream].runtime = NULL;
> +		goto fe_err;
> +	}
> +
> +	dpcm_clear_pending_state(fe, stream);
> +	dpcm_path_put(&list);
> +
> +	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
> +	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
> +
> +	if (cstream->direction == SND_COMPRESS_PLAYBACK) {
> +		cpu_dai->playback_active++;
> +		codec_dai->playback_active++;
> +	} else {
> +		cpu_dai->capture_active++;
> +		codec_dai->capture_active++;
> +	}
> +
> +	cpu_dai->active++;
> +	codec_dai->active++;
> +	fe->codec->active++;
> +
> +	mutex_unlock(&fe->card->mutex);
> +
> +	return 0;
> +
> +fe_err:
> +	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
> +		fe->dai_link->compr_ops->shutdown(cstream);
> +machine_err:
> +	if (platform->driver->compr_ops && platform->driver->compr_ops->free)
> +		platform->driver->compr_ops->free(cstream);
> +out:
> +	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
> +	mutex_unlock(&fe->card->mutex);
> +	return ret;
> +}
> +
>  /*
>   * Power down the audio subsystem pmdown_time msecs after close is called.
>   * This is to ensure there are no pops or clicks in between any music tracks
> @@ -164,6 +257,65 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
>  	return 0;
>  }
>  
> +static int soc_compr_free_fe(struct snd_compr_stream *cstream)
> +{
> +	struct snd_soc_pcm_runtime *fe = cstream->private_data;
> +	struct snd_soc_platform *platform = fe->platform;
> +	struct snd_soc_dai *cpu_dai = fe->cpu_dai;
> +	struct snd_soc_dai *codec_dai = fe->codec_dai;
> +	struct snd_soc_dpcm *dpcm;
> +	int stream, ret;
> +
> +	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
> +
> +	if (cstream->direction == SND_COMPRESS_PLAYBACK) {
> +		stream = SNDRV_PCM_STREAM_PLAYBACK;
> +		cpu_dai->playback_active--;
> +		codec_dai->playback_active--;
> +	} else {
> +		stream = SNDRV_PCM_STREAM_CAPTURE;
> +		cpu_dai->capture_active--;
> +		codec_dai->capture_active--;
> +	}
> +
> +	cpu_dai->active--;
> +	codec_dai->active--;
> +	fe->codec->active--;
> +
> +	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
> +
> +	ret = dpcm_be_dai_hw_free(fe, stream);
> +	if (ret < 0)
> +		dev_err(fe->dev, "compressed hw_free failed %d\n", ret);
> +
> +	ret = dpcm_be_dai_shutdown(fe, stream);
> +
> +	/* mark FE's links ready to prune */
> +	list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
> +		dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
> +
> +	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
> +		dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
> +	else
> +		dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
> +
> +	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
> +	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
> +
> +	dpcm_be_disconnect(fe, stream);
> +
> +	fe->dpcm[stream].runtime = NULL;
> +
> +	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
> +		fe->dai_link->compr_ops->shutdown(cstream);
> +
> +	if (platform->driver->compr_ops && platform->driver->compr_ops->free)
> +		platform->driver->compr_ops->free(cstream);
> +
> +	mutex_unlock(&fe->card->mutex);
> +	return 0;
> +}
> +
>  static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
>  {
>  
> @@ -194,6 +346,59 @@ out:
>  	return ret;
>  }
>  
> +static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
> +{
> +	struct snd_soc_pcm_runtime *fe = cstream->private_data;
> +	struct snd_soc_platform *platform = fe->platform;
> +	int ret = 0, stream;
> +
> +	if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
> +		cmd == SND_COMPR_TRIGGER_DRAIN) {
> +
> +		if (platform->driver->compr_ops &&
> +			platform->driver->compr_ops->trigger)
> +		return platform->driver->compr_ops->trigger(cstream, cmd);
> +	}
> +
> +	if (cstream->direction == SND_COMPRESS_PLAYBACK)
> +		stream = SNDRV_PCM_STREAM_PLAYBACK;
> +	else
> +		stream = SNDRV_PCM_STREAM_CAPTURE;
> +
> +
> +	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
> +
> +	if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
> +		ret = platform->driver->compr_ops->trigger(cstream, cmd);
> +		if (ret < 0)
> +			goto out;
> +	}
> +
> +	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
> +
> +	ret = dpcm_be_dai_trigger(fe, stream, cmd);
> +
> +	switch (cmd) {
> +	case SNDRV_PCM_TRIGGER_START:
> +	case SNDRV_PCM_TRIGGER_RESUME:
> +	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
> +		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
> +		break;
> +	case SNDRV_PCM_TRIGGER_STOP:
> +	case SNDRV_PCM_TRIGGER_SUSPEND:
> +		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
> +		break;
> +	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
> +		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
> +		break;
> +	}
> +
> +out:
> +	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
> +	mutex_unlock(&fe->card->mutex);
> +	return ret;
> +}
> +
>  static int soc_compr_set_params(struct snd_compr_stream *cstream,
>  					struct snd_compr_params *params)
>  {
> @@ -241,6 +446,64 @@ err:
>  	return ret;
>  }
>  
> +static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
> +					struct snd_compr_params *params)
> +{
> +	struct snd_soc_pcm_runtime *fe = cstream->private_data;
> +	struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
> +	struct snd_soc_platform *platform = fe->platform;
> +	struct snd_pcm_hw_params *hw_params;
> +	int ret = 0, stream;
> +
> +	if (cstream->direction == SND_COMPRESS_PLAYBACK)
> +		stream = SNDRV_PCM_STREAM_PLAYBACK;
> +	else
> +		stream = SNDRV_PCM_STREAM_CAPTURE;
> +
> +	hw_params = kzalloc(sizeof(*hw_params), GFP_KERNEL);
> +	if (hw_params == NULL)
> +		return -ENOMEM;

I see no kfree() for this.


> +	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
> +
> +	if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
> +		ret = platform->driver->compr_ops->set_params(cstream, params);
> +		if (ret < 0)
> +			goto out;
> +	}
> +
> +	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->set_params) {
> +		ret = fe->dai_link->compr_ops->set_params(cstream);
> +		if (ret < 0)
> +			goto out;
> +	}
> +
> +	memcpy(&fe->dpcm[fe_substream->stream].hw_params, params,
> +			sizeof(struct snd_pcm_hw_params));

Does this really work?  params is snd_compr_params and hw_parmas is
snd_pcm_hw_params, isn't it?

For avoiding such a mistake, you can avoid memcpy:
	*fe->dpcm[fe_substream->stream].hw_params = *params;


Takashi


> +
> +	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
> +
> +	ret = dpcm_be_dai_hw_params(fe, stream);
> +	if (ret < 0)
> +		goto out;
> +
> +	ret = dpcm_be_dai_prepare(fe, stream);
> +	if (ret < 0)
> +		goto out;
> +
> +	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
> +		dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
> +	else
> +		dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
> +
> +	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
> +
> +out:
> +	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
> +	mutex_unlock(&fe->card->mutex);
> +	return ret;
> +}
> +
>  static int soc_compr_get_params(struct snd_compr_stream *cstream,
>  					struct snd_codec *params)
>  {
> @@ -360,6 +623,7 @@ static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
>  
>  	return ret;
>  }
> +
>  /* ASoC Compress operations */
>  static struct snd_compr_ops soc_compr_ops = {
>  	.open		= soc_compr_open,
> @@ -375,6 +639,21 @@ static struct snd_compr_ops soc_compr_ops = {
>  	.get_codec_caps = soc_compr_get_codec_caps
>  };
>  
> +/* ASoC Dynamic Compress operations */
> +static struct snd_compr_ops soc_compr_dyn_ops = {
> +	.open		= soc_compr_open_fe,
> +	.free		= soc_compr_free_fe,
> +	.set_params	= soc_compr_set_params_fe,
> +	.get_params	= soc_compr_get_params,
> +	.set_metadata   = soc_compr_set_metadata,
> +	.get_metadata	= soc_compr_get_metadata,
> +	.trigger	= soc_compr_trigger_fe,
> +	.pointer	= soc_compr_pointer,
> +	.ack		= soc_compr_ack,
> +	.get_caps	= soc_compr_get_caps,
> +	.get_codec_caps = soc_compr_get_codec_caps
> +};
> +
>  /* create a new compress */
>  int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
>  {
> @@ -383,6 +662,7 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
>  	struct snd_soc_dai *codec_dai = rtd->codec_dai;
>  	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
>  	struct snd_compr *compr;
> +	struct snd_pcm *be_pcm;
>  	char new_name[64];
>  	int ret = 0, direction = 0;
>  
> @@ -410,7 +690,26 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
>  		ret = -ENOMEM;
>  		goto compr_err;
>  	}
> -	memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
> +
> +	if (rtd->dai_link->dynamic) {
> +		snprintf(new_name, sizeof(new_name), "(%s)",
> +			rtd->dai_link->stream_name);
> +
> +		ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
> +				1, 0, &be_pcm);
> +		if (ret < 0) {
> +			dev_err(rtd->card->dev, "ASoC: can't create compressed for %s\n",
> +				rtd->dai_link->name);
> +			goto compr_err;
> +		}
> +
> +		rtd->pcm = be_pcm;
> +		rtd->fe_compr = 1;
> +		be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
> +		be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
> +		memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
> +	} else
> +		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)
> -- 
> 1.8.3.2
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage
  2014-01-16 14:59       ` Vinod Koul
@ 2014-01-16 16:02         ` Takashi Iwai
  0 siblings, 0 replies; 16+ messages in thread
From: Takashi Iwai @ 2014-01-16 16:02 UTC (permalink / raw)
  To: Vinod Koul; +Cc: Liam Girdwood, alsa-devel, Mark Brown

At Thu, 16 Jan 2014 20:29:04 +0530,
Vinod Koul wrote:
> 
> On Thu, Jan 16, 2014 at 04:55:34PM +0100, Takashi Iwai wrote:
> > At Thu, 16 Jan 2014 20:10:42 +0530,
> > Vinod Koul wrote:
> > > 
> > > On Thu, Jan 16, 2014 at 12:31:53PM +0000, Mark Brown wrote:
> > > > On Wed, Jan 15, 2014 at 04:51:56PM +0000, Liam Girdwood wrote:
> > > > > The ASoC compressed code needs to call the internal DPCM APIs in order to
> > > > > dynamically route compressed data to different DAIs.
> > > > 
> > > > Applied, thanks.  I'm holding off on the second patch for a little so
> > > > Vinod has a chance to say something since it's compressed stuff.
> > > Both look good to me, so
> > > 
> > > Acked-by: Vinod Koul <vinod.koul@intel.com>
> > > 
> > > The second patch still needs an update for properly copying the hw_params. This
> > > was one of issue reported by qcom folks, but I don't want to hold these now. We
> > > can fix that as it will impact systems not have fixup function for BEs.
> > 
> > One thing that makes me a bit nervous is that it's accessing the
> > actual PCM object.  So far, sound/pcm.h is included there just because
> > it's re-using the same enum definitions, etc, but it doesn't mean that
> > it allows accessing a PCM object or function.
> > 
> > If we bind a real PCM instance there, we should add the Kconfig
> > selection for SND_PCM from SND_COMPRESS_OFFLOAD.
> 
> Makes sense, but is this a practical sceanrios. I dont think we have a sound
> card which supports offload only so SND_PCM will always be selected.
> 
> This is also ASoC patch, so SND_SOC would be selected, which selects SND_PCM

OK, then that's fine.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/2] ASoC: compress: Add suport for DPCM into compressed audio
  2014-01-16 15:59   ` Takashi Iwai
@ 2014-01-16 17:08     ` Liam Girdwood
  2014-01-17  3:53       ` Vinod Koul
  0 siblings, 1 reply; 16+ messages in thread
From: Liam Girdwood @ 2014-01-16 17:08 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Vinod Koul, alsa-devel, Mark Brown

On Thu, 2014-01-16 at 16:59 +0100, Takashi Iwai wrote:
> At Wed, 15 Jan 2014 16:51:57 +0000,
> Liam Girdwood wrote:
> > 

> 
> > +	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
> > +
> > +	if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
> > +		ret = platform->driver->compr_ops->set_params(cstream, params);
> > +		if (ret < 0)
> > +			goto out;
> > +	}
> > +
> > +	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->set_params) {
> > +		ret = fe->dai_link->compr_ops->set_params(cstream);
> > +		if (ret < 0)
> > +			goto out;
> > +	}
> > +
> > +	memcpy(&fe->dpcm[fe_substream->stream].hw_params, params,
> > +			sizeof(struct snd_pcm_hw_params));
> 
> Does this really work?  params is snd_compr_params and hw_parmas is
> snd_pcm_hw_params, isn't it?
> 

Hmmm, no one reported a failure here to me. It is complete nonsense
though so I dont know why the testers didn't run into this. I'll fix it
for V2.

Thanks

Liam

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/2] ASoC: compress: Add suport for DPCM into compressed audio
  2014-01-15 16:51 ` [PATCH 2/2] ASoC: compress: Add suport for DPCM into compressed audio Liam Girdwood
  2014-01-16 15:59   ` Takashi Iwai
@ 2014-01-16 18:01   ` Mark Brown
  2014-01-16 18:12     ` Liam Girdwood
  1 sibling, 1 reply; 16+ messages in thread
From: Mark Brown @ 2014-01-16 18:01 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: Vinod Koul, alsa-devel


[-- Attachment #1.1: Type: text/plain, Size: 263 bytes --]

On Wed, Jan 15, 2014 at 04:51:57PM +0000, Liam Girdwood wrote:
> Currently compressed audio streams are statically routed from the /dev
> to the DAI link. Some DSPs can route compressed data to multiple BE DAIs
> like they do for PCM data.

Applied both, thanks.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/2] ASoC: compress: Add suport for DPCM into compressed audio
  2014-01-16 18:01   ` Mark Brown
@ 2014-01-16 18:12     ` Liam Girdwood
  2014-01-16 18:16       ` Mark Brown
  0 siblings, 1 reply; 16+ messages in thread
From: Liam Girdwood @ 2014-01-16 18:12 UTC (permalink / raw)
  To: Mark Brown; +Cc: Vinod Koul, alsa-devel

On Thu, 2014-01-16 at 18:01 +0000, Mark Brown wrote:
> On Wed, Jan 15, 2014 at 04:51:57PM +0000, Liam Girdwood wrote:
> > Currently compressed audio streams are statically routed from the /dev
> > to the DAI link. Some DSPs can route compressed data to multiple BE DAIs
> > like they do for PCM data.
> 
> Applied both, thanks.

I have a fix for this, I guess you want it incrementally ?

Thanks

Liam

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/2] ASoC: compress: Add suport for DPCM into compressed audio
  2014-01-16 18:12     ` Liam Girdwood
@ 2014-01-16 18:16       ` Mark Brown
  0 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2014-01-16 18:16 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: Vinod Koul, alsa-devel


[-- Attachment #1.1: Type: text/plain, Size: 374 bytes --]

On Thu, Jan 16, 2014 at 06:12:08PM +0000, Liam Girdwood wrote:
> On Thu, 2014-01-16 at 18:01 +0000, Mark Brown wrote:

> > Applied both, thanks.

> I have a fix for this, I guess you want it incrementally ?

Yeah, or I can replace if you like - they're on a branch by themselves
so it's easy to update and start over.  Please carry Vinod's ack if
you resend or I'll forget.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/2] ASoC: compress: Add suport for DPCM into compressed audio
  2014-01-16 17:08     ` Liam Girdwood
@ 2014-01-17  3:53       ` Vinod Koul
  2014-01-17  8:28         ` Liam Girdwood
  0 siblings, 1 reply; 16+ messages in thread
From: Vinod Koul @ 2014-01-17  3:53 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: Takashi Iwai, alsa-devel, Mark Brown

On Thu, Jan 16, 2014 at 05:08:01PM +0000, Liam Girdwood wrote:
> On Thu, 2014-01-16 at 16:59 +0100, Takashi Iwai wrote:
> > At Wed, 15 Jan 2014 16:51:57 +0000,
> > Liam Girdwood wrote:
> > > 
> 
> > 
> > > +	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
> > > +
> > > +	if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
> > > +		ret = platform->driver->compr_ops->set_params(cstream, params);
> > > +		if (ret < 0)
> > > +			goto out;
> > > +	}
> > > +
> > > +	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->set_params) {
> > > +		ret = fe->dai_link->compr_ops->set_params(cstream);
> > > +		if (ret < 0)
> > > +			goto out;
> > > +	}
> > > +
> > > +	memcpy(&fe->dpcm[fe_substream->stream].hw_params, params,
> > > +			sizeof(struct snd_pcm_hw_params));
> > 
> > Does this really work?  params is snd_compr_params and hw_parmas is
> > snd_pcm_hw_params, isn't it?
> > 
> 
> Hmmm, no one reported a failure here to me. It is complete nonsense
> though so I dont know why the testers didn't run into this. I'll fix it
> for V2.
I think that due to the fixup fn noone noticed this. The issue will be seen only
by folks who dont have the fixup function.

--
~Vinod

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/2] ASoC: compress: Add suport for DPCM into compressed audio
  2014-01-17  3:53       ` Vinod Koul
@ 2014-01-17  8:28         ` Liam Girdwood
  0 siblings, 0 replies; 16+ messages in thread
From: Liam Girdwood @ 2014-01-17  8:28 UTC (permalink / raw)
  To: Vinod Koul; +Cc: Takashi Iwai, alsa-devel, Liam Girdwood, Mark Brown

On Fri, 2014-01-17 at 09:23 +0530, Vinod Koul wrote:
> On Thu, Jan 16, 2014 at 05:08:01PM +0000, Liam Girdwood wrote:
> > On Thu, 2014-01-16 at 16:59 +0100, Takashi Iwai wrote:
> > > At Wed, 15 Jan 2014 16:51:57 +0000,
> > > Liam Girdwood wrote:
> > > > 
> > 
> > > 
> > > > +	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
> > > > +
> > > > +	if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
> > > > +		ret = platform->driver->compr_ops->set_params(cstream, params);
> > > > +		if (ret < 0)
> > > > +			goto out;
> > > > +	}
> > > > +
> > > > +	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->set_params) {
> > > > +		ret = fe->dai_link->compr_ops->set_params(cstream);
> > > > +		if (ret < 0)
> > > > +			goto out;
> > > > +	}
> > > > +
> > > > +	memcpy(&fe->dpcm[fe_substream->stream].hw_params, params,
> > > > +			sizeof(struct snd_pcm_hw_params));
> > > 
> > > Does this really work?  params is snd_compr_params and hw_parmas is
> > > snd_pcm_hw_params, isn't it?
> > > 
> > 
> > Hmmm, no one reported a failure here to me. It is complete nonsense
> > though so I dont know why the testers didn't run into this. I'll fix it
> > for V2.
> I think that due to the fixup fn noone noticed this. The issue will be seen only
> by folks who dont have the fixup function.

I now know why we didn't see this on HSW. We have a fixed BE SSP
configuration so we always ignore the BE hw_params. So we ignored the
junk data ;)

Liam

---------------------------------------------------------------------
Intel Corporation (UK) Limited
Registered No. 1134945 (England)
Registered Office: Pipers Way, Swindon SN3 1RJ
VAT No: 860 2173 47

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2014-01-17  8:28 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-15 16:51 [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage Liam Girdwood
2014-01-15 16:51 ` [PATCH 2/2] ASoC: compress: Add suport for DPCM into compressed audio Liam Girdwood
2014-01-16 15:59   ` Takashi Iwai
2014-01-16 17:08     ` Liam Girdwood
2014-01-17  3:53       ` Vinod Koul
2014-01-17  8:28         ` Liam Girdwood
2014-01-16 18:01   ` Mark Brown
2014-01-16 18:12     ` Liam Girdwood
2014-01-16 18:16       ` Mark Brown
2014-01-16 12:31 ` [PATCH 1/2] ASoC: DPCM: make some DPCM API calls non static for compressed usage Mark Brown
2014-01-16 14:40   ` Vinod Koul
2014-01-16 15:47     ` Liam Girdwood
2014-01-16 14:49       ` Vinod Koul
2014-01-16 15:55     ` Takashi Iwai
2014-01-16 14:59       ` Vinod Koul
2014-01-16 16:02         ` Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.