mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
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>
This commit is contained in:
parent
09553140c8
commit
4550569bd7
@ -293,6 +293,10 @@ per stream. From ASoC DPCM framework, this stream state maybe linked to
|
|||||||
|
|
||||||
int sdw_alloc_stream(char * stream_name);
|
int sdw_alloc_stream(char * stream_name);
|
||||||
|
|
||||||
|
The SoundWire core provides a sdw_startup_stream() helper function,
|
||||||
|
typically called during a dailink .startup() callback, which performs
|
||||||
|
stream allocation and sets the stream pointer for all DAIs
|
||||||
|
connected to a stream.
|
||||||
|
|
||||||
SDW_STREAM_CONFIGURED
|
SDW_STREAM_CONFIGURED
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -509,7 +513,12 @@ In .shutdown() the data structure maintaining stream state are freed up.
|
|||||||
|
|
||||||
void sdw_release_stream(struct sdw_stream_runtime * stream);
|
void sdw_release_stream(struct sdw_stream_runtime * stream);
|
||||||
|
|
||||||
Not Supported
|
The SoundWire core provides a sdw_shutdown_stream() helper function,
|
||||||
|
typically called during a dailink .shutdown() callback, which clears
|
||||||
|
the stream pointer for all DAIS connected to a stream and releases the
|
||||||
|
memory allocated for the stream.
|
||||||
|
|
||||||
|
Not Supported
|
||||||
=============
|
=============
|
||||||
|
|
||||||
1. A single port with multiple channels supported cannot be used between two
|
1. A single port with multiple channels supported cannot be used between two
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/soundwire/sdw_registers.h>
|
#include <linux/soundwire/sdw_registers.h>
|
||||||
#include <linux/soundwire/sdw.h>
|
#include <linux/soundwire/sdw.h>
|
||||||
|
#include <sound/soc.h>
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1826,3 +1827,100 @@ state_err:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(sdw_deprepare_stream);
|
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);
|
||||||
|
@ -955,10 +955,12 @@ int sdw_stream_remove_master(struct sdw_bus *bus,
|
|||||||
struct sdw_stream_runtime *stream);
|
struct sdw_stream_runtime *stream);
|
||||||
int sdw_stream_remove_slave(struct sdw_slave *slave,
|
int sdw_stream_remove_slave(struct sdw_slave *slave,
|
||||||
struct sdw_stream_runtime *stream);
|
struct sdw_stream_runtime *stream);
|
||||||
|
int sdw_startup_stream(void *sdw_substream);
|
||||||
int sdw_prepare_stream(struct sdw_stream_runtime *stream);
|
int sdw_prepare_stream(struct sdw_stream_runtime *stream);
|
||||||
int sdw_enable_stream(struct sdw_stream_runtime *stream);
|
int sdw_enable_stream(struct sdw_stream_runtime *stream);
|
||||||
int sdw_disable_stream(struct sdw_stream_runtime *stream);
|
int sdw_disable_stream(struct sdw_stream_runtime *stream);
|
||||||
int sdw_deprepare_stream(struct sdw_stream_runtime *stream);
|
int sdw_deprepare_stream(struct sdw_stream_runtime *stream);
|
||||||
|
void sdw_shutdown_stream(void *sdw_substream);
|
||||||
int sdw_bus_prep_clk_stop(struct sdw_bus *bus);
|
int sdw_bus_prep_clk_stop(struct sdw_bus *bus);
|
||||||
int sdw_bus_clk_stop(struct sdw_bus *bus);
|
int sdw_bus_clk_stop(struct sdw_bus *bus);
|
||||||
int sdw_bus_exit_clk_stop(struct sdw_bus *bus);
|
int sdw_bus_exit_clk_stop(struct sdw_bus *bus);
|
||||||
|
Loading…
Reference in New Issue
Block a user