summaryrefslogtreecommitdiff
path: root/drivers/soundwire/stream.c
diff options
context:
space:
mode:
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>2020-07-01 02:43:53 +0800
committerVinod Koul <vkoul@kernel.org>2020-07-15 10:10:05 +0530
commit4550569bd779f25398503ad5556f8dc7c1f216c2 (patch)
treecb6633f440fcacea3f6190d88606d0647f18a550 /drivers/soundwire/stream.c
parent09553140c8d7be7d74e2e39796f644cc085ab273 (diff)
soundwire: stream: add helper to startup/shutdown streams
To handle streams at the dailink level, expose two helpers that will be called from machine drivers. Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://lore.kernel.org/r/20200630184356.24939-3-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/soundwire/stream.c')
-rw-r--r--drivers/soundwire/stream.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
index a9a72574b34a..6bc2ff29c202 100644
--- a/drivers/soundwire/stream.c
+++ b/drivers/soundwire/stream.c
@@ -13,6 +13,7 @@
#include <linux/slab.h>
#include <linux/soundwire/sdw_registers.h>
#include <linux/soundwire/sdw.h>
+#include <sound/soc.h>
#include "bus.h"
/*
@@ -1826,3 +1827,100 @@ state_err:
return ret;
}
EXPORT_SYMBOL(sdw_deprepare_stream);
+
+static int set_stream(struct snd_pcm_substream *substream,
+ struct sdw_stream_runtime *sdw_stream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *dai;
+ int ret = 0;
+ int i;
+
+ /* Set stream pointer on all DAIs */
+ for_each_rtd_dais(rtd, i, dai) {
+ ret = snd_soc_dai_set_sdw_stream(dai, sdw_stream, substream->stream);
+ if (ret < 0) {
+ dev_err(rtd->dev, "failed to set stream pointer on dai %s", dai->name);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * sdw_startup_stream() - Startup SoundWire stream
+ *
+ * @stream: Soundwire stream
+ *
+ * Documentation/driver-api/soundwire/stream.rst explains this API in detail
+ */
+int sdw_startup_stream(void *sdw_substream)
+{
+ struct snd_pcm_substream *substream = sdw_substream;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct sdw_stream_runtime *sdw_stream;
+ char *name;
+ int ret;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ name = kasprintf(GFP_KERNEL, "%s-Playback", substream->name);
+ else
+ name = kasprintf(GFP_KERNEL, "%s-Capture", substream->name);
+
+ if (!name)
+ return -ENOMEM;
+
+ sdw_stream = sdw_alloc_stream(name);
+ if (!sdw_stream) {
+ dev_err(rtd->dev, "alloc stream failed for substream DAI %s", substream->name);
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ ret = set_stream(substream, sdw_stream);
+ if (ret < 0)
+ goto release_stream;
+ return 0;
+
+release_stream:
+ sdw_release_stream(sdw_stream);
+ set_stream(substream, NULL);
+error:
+ kfree(name);
+ return ret;
+}
+EXPORT_SYMBOL(sdw_startup_stream);
+
+/**
+ * sdw_shutdown_stream() - Shutdown SoundWire stream
+ *
+ * @stream: Soundwire stream
+ *
+ * Documentation/driver-api/soundwire/stream.rst explains this API in detail
+ */
+void sdw_shutdown_stream(void *sdw_substream)
+{
+ struct snd_pcm_substream *substream = sdw_substream;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct sdw_stream_runtime *sdw_stream;
+ struct snd_soc_dai *dai;
+
+ /* Find stream from first CPU DAI */
+ dai = asoc_rtd_to_cpu(rtd, 0);
+
+ sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
+
+ if (!sdw_stream) {
+ dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
+ return;
+ }
+
+ /* release memory */
+ kfree(sdw_stream->name);
+ sdw_release_stream(sdw_stream);
+
+ /* clear DAI data */
+ set_stream(substream, NULL);
+}
+EXPORT_SYMBOL(sdw_shutdown_stream);