Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9a09de4
ASoC: fix for_rtd_codec_dai_rollback() macro
plbossart Feb 18, 2020
af255e9
ASoC: Add initial support for multiple CPU DAIs
shreyasnc1 Jan 20, 2020
1e044e5
ASoC: Add multiple CPU DAI support for PCM ops
shreyasnc1 Jan 20, 2020
ab98fab
ASoC: Add dapm_add_valid_dai_widget helper
shreyasnc1 Jan 20, 2020
5005d58
ASoC: Add multiple CPU DAI support in DAPM
shreyasnc1 Jan 20, 2020
d514a91
ASoC: Return error if the function does not support multi-cpu
bardliao Jan 20, 2020
4097910
ASoC: pcm: check if cpu-dai supports a given stream
bardliao Jan 20, 2020
0d5413a
ASoC: SOF: topology: connect dai widget to all cpu-dais
bardliao Feb 18, 2020
c2e38f1
soundwire: cadence: remove useless prototypes
plbossart Feb 20, 2020
b3359e6
soundwire: stream: only change state if needed
plbossart Feb 19, 2020
b27f0d8
ASoC: soc-dai: add get_sdw_stream() callback
plbossart Feb 20, 2020
eeef703
soundwire: intel: implement get_sdw_stream() operations
plbossart Feb 20, 2020
216ebe4
soundwire: stream: add helper to startup/shutdown streams
plbossart Feb 20, 2020
f8914ba
soundwire: intel: remove stream allocation/free
plbossart Feb 20, 2020
b5c329a
soundwire: cadence: allocate/free dma_data in set_sdw_stream
plbossart Feb 20, 2020
47b4921
soundwire: intel: don't free dma_data in DAI shutdown
plbossart Feb 20, 2020
4476a47
ASoC: Intel: sdw_rt700: handle SoundWire stream creation in dailink
plbossart Feb 20, 2020
fced860
ASoC: Intel: sdw_rt711_rt1308_rt715: handle SoundWire stream creation…
plbossart Feb 20, 2020
352771c
Revert "ASoC: pcm: check if cpu-dai supports a given stream"
plbossart Feb 20, 2020
3578aae
[SQUASHME] ASoC: soc-generic-dmaengine-pcm: fix integer/pointer
plbossart Feb 21, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 38 additions & 14 deletions drivers/soundwire/cadence_master.c
Original file line number Diff line number Diff line change
Expand Up @@ -1445,25 +1445,49 @@ int cdns_set_sdw_stream(struct snd_soc_dai *dai,
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
struct sdw_cdns_dma_data *dma;

dma = kzalloc(sizeof(*dma), GFP_KERNEL);
if (!dma)
return -ENOMEM;
if (stream) {
/* first paranoia check */
if (direction == SNDRV_PCM_STREAM_PLAYBACK)
dma = dai->playback_dma_data;
else
dma = dai->capture_dma_data;

if (dma) {
dev_err(dai->dev,
"dma_data already allocated for dai %s\n",
dai->name);
return -EINVAL;
}

if (pcm)
dma->stream_type = SDW_STREAM_PCM;
else
dma->stream_type = SDW_STREAM_PDM;
/* allocate and set dma info */
dma = kzalloc(sizeof(*dma), GFP_KERNEL);
if (!dma)
return -ENOMEM;

dma->bus = &cdns->bus;
dma->link_id = cdns->instance;
if (pcm)
dma->stream_type = SDW_STREAM_PCM;
else
dma->stream_type = SDW_STREAM_PDM;

dma->stream = stream;
dma->bus = &cdns->bus;
dma->link_id = cdns->instance;

if (direction == SNDRV_PCM_STREAM_PLAYBACK)
dai->playback_dma_data = dma;
else
dai->capture_dma_data = dma;
dma->stream = stream;

if (direction == SNDRV_PCM_STREAM_PLAYBACK)
dai->playback_dma_data = dma;
else
dai->capture_dma_data = dma;
} else {
/* for NULL stream we release allocated dma_data */
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
kfree(dai->playback_dma_data);
dai->playback_dma_data = NULL;
} else {
kfree(dai->capture_dma_data);
dai->capture_dma_data = NULL;
}
}
return 0;
}
EXPORT_SYMBOL(cdns_set_sdw_stream);
Expand Down
8 changes: 0 additions & 8 deletions drivers/soundwire/cadence_master.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,20 +163,12 @@ int sdw_cdns_clock_restart(struct sdw_cdns *cdns, bool bus_reset);
void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
#endif

int sdw_cdns_get_stream(struct sdw_cdns *cdns,
struct sdw_cdns_streams *stream,
u32 ch, u32 dir);
struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns,
struct sdw_cdns_streams *stream,
u32 ch, u32 dir, int dai_id);
void sdw_cdns_config_stream(struct sdw_cdns *cdns,
u32 ch, u32 dir, struct sdw_cdns_pdi *pdi);

int sdw_cdns_pcm_set_stream(struct snd_soc_dai *dai,
void *stream, int direction);
int sdw_cdns_pdm_set_stream(struct snd_soc_dai *dai,
void *stream, int direction);

enum sdw_command_response
cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num);

Expand Down
83 changes: 20 additions & 63 deletions drivers/soundwire/intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -869,57 +869,6 @@ static int intel_post_bank_switch(struct sdw_bus *bus)
* DAI routines
*/

static int sdw_stream_setup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct sdw_stream_runtime *sdw_stream = NULL;
char *name;
int i, ret;

if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
name = kasprintf(GFP_KERNEL, "%s-Playback", dai->name);
else
name = kasprintf(GFP_KERNEL, "%s-Capture", dai->name);

if (!name)
return -ENOMEM;

sdw_stream = sdw_alloc_stream(name);
if (!sdw_stream) {
dev_err(dai->dev, "alloc stream failed for DAI %s", dai->name);
ret = -ENOMEM;
goto error;
}

/* Set stream pointer on CPU DAI */
ret = snd_soc_dai_set_sdw_stream(dai, sdw_stream, substream->stream);
if (ret < 0) {
dev_err(dai->dev, "failed to set stream pointer on cpu dai %s",
dai->name);
goto release_stream;
}

/* Set stream pointer on all CODEC DAIs */
for (i = 0; i < rtd->num_codecs; i++) {
ret = snd_soc_dai_set_sdw_stream(rtd->codec_dais[i], sdw_stream,
substream->stream);
if (ret < 0) {
dev_err(dai->dev, "failed to set stream pointer on codec dai %s",
rtd->codec_dais[i]->name);
goto release_stream;
}
}

return 0;

release_stream:
sdw_release_stream(sdw_stream);
error:
kfree(name);
return ret;
}

static int intel_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
Expand All @@ -932,9 +881,9 @@ static int intel_startup(struct snd_pcm_substream *substream,
"pm_runtime_get_sync failed in %s, ret %d\n",
__func__, ret);
pm_runtime_put_noidle(cdns->dev);
return ret;
}

return sdw_stream_setup(substream, dai);
return 0;
}

static int intel_hw_params(struct snd_pcm_substream *substream,
Expand Down Expand Up @@ -1147,25 +1096,15 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)

dma->hw_params = NULL;
dma->pdi = NULL;
kfree(dma->stream->name);
sdw_release_stream(dma->stream);

return 0;
}

static void intel_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct sdw_cdns_dma_data *dma;
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);

dma = snd_soc_dai_get_dma_data(dai, substream);
if (!dma)
return;

snd_soc_dai_set_dma_data(dai, substream, NULL);
kfree(dma);

pm_runtime_mark_last_busy(cdns->dev);
pm_runtime_put_autosuspend(cdns->dev);
}
Expand Down Expand Up @@ -1206,6 +1145,22 @@ static int intel_pdm_set_sdw_stream(struct snd_soc_dai *dai,
return cdns_set_sdw_stream(dai, stream, false, direction);
}

static void *intel_get_sdw_stream(struct snd_soc_dai *dai,
int direction)
{
struct sdw_cdns_dma_data *dma;

if (direction == SNDRV_PCM_STREAM_PLAYBACK)
dma = dai->playback_dma_data;
else
dma = dai->capture_dma_data;

if (!dma)
return NULL;

return dma->stream;
}

static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
.startup = intel_startup,
.hw_params = intel_hw_params,
Expand All @@ -1214,6 +1169,7 @@ static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
.hw_free = intel_hw_free,
.shutdown = intel_shutdown,
.set_sdw_stream = intel_pcm_set_sdw_stream,
.get_sdw_stream = intel_get_sdw_stream,
};

static const struct snd_soc_dai_ops intel_pdm_dai_ops = {
Expand All @@ -1224,6 +1180,7 @@ static const struct snd_soc_dai_ops intel_pdm_dai_ops = {
.hw_free = intel_hw_free,
.shutdown = intel_shutdown,
.set_sdw_stream = intel_pdm_set_sdw_stream,
.get_sdw_stream = intel_get_sdw_stream,
};

static const struct snd_soc_component_driver dai_component = {
Expand Down
121 changes: 121 additions & 0 deletions drivers/soundwire/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#include <linux/slab.h>
#include <linux/soundwire/sdw_registers.h>
#include <linux/soundwire/sdw.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include "bus.h"

/*
Expand Down Expand Up @@ -1578,6 +1581,7 @@ int sdw_prepare_stream(struct sdw_stream_runtime *stream)
sdw_acquire_bus_lock(stream);

if (stream->state == SDW_STREAM_PREPARED) {
/* nothing to do */
ret = 0;
goto state_err;
}
Expand Down Expand Up @@ -1667,6 +1671,12 @@ int sdw_enable_stream(struct sdw_stream_runtime *stream)

sdw_acquire_bus_lock(stream);

if (stream->state == SDW_STREAM_ENABLED) {
/* nothing to do */
ret = 0;
goto state_err;
}

if (stream->state != SDW_STREAM_PREPARED &&
stream->state != SDW_STREAM_DISABLED) {
pr_err("%s: %s: inconsistent state state %d\n",
Expand Down Expand Up @@ -1750,6 +1760,12 @@ int sdw_disable_stream(struct sdw_stream_runtime *stream)

sdw_acquire_bus_lock(stream);

if (stream->state == SDW_STREAM_DISABLED) {
/* nothing to do */
ret = 0;
goto state_err;
}

if (stream->state != SDW_STREAM_ENABLED) {
pr_err("%s: %s: inconsistent state state %d\n",
__func__, stream->name, stream->state);
Expand Down Expand Up @@ -1825,6 +1841,12 @@ int sdw_deprepare_stream(struct sdw_stream_runtime *stream)

sdw_acquire_bus_lock(stream);

if (stream->state == SDW_STREAM_DEPREPARED) {
/* nothing to do */
ret = 0;
goto state_err;
}

if (stream->state != SDW_STREAM_PREPARED &&
stream->state != SDW_STREAM_DISABLED) {
pr_err("%s: %s: inconsistent state state %d\n",
Expand All @@ -1840,3 +1862,102 @@ int sdw_deprepare_stream(struct sdw_stream_runtime *stream)
return ret;
}
EXPORT_SYMBOL(sdw_deprepare_stream);

static int set_stream(struct snd_pcm_substream *substream,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sdw_set_stream?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static -> no prefix
And sdw_set_stream is already used for something else

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 CPU DAIs */
for (i = 0; i < rtd->num_cpus; i++) {
dai = rtd->cpu_dais[i];
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 cpu dai %s",
dai->name);
goto err_stream;
}
}

/* Set stream pointer on all CODEC DAIs */
for (i = 0; i < rtd->num_codecs; i++) {
dai = rtd->codec_dais[i];
ret = snd_soc_dai_set_sdw_stream(dai, sdw_stream,
substream->stream);
if (ret < 0) {
dev_err(dai->dev, "failed to set stream pointer on codec dai %s",
dai->name);
goto err_stream;
}
}

err_stream:
return ret;
}

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);

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 = rtd->cpu_dais[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);
2 changes: 2 additions & 0 deletions include/linux/soundwire/sdw.h
Original file line number Diff line number Diff line change
Expand Up @@ -941,10 +941,12 @@ int sdw_stream_remove_master(struct sdw_bus *bus,
struct sdw_stream_runtime *stream);
int sdw_stream_remove_slave(struct sdw_slave *slave,
struct sdw_stream_runtime *stream);
int sdw_startup_stream(void *sdw_substream);
int sdw_prepare_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_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_clk_stop(struct sdw_bus *bus);
int sdw_bus_exit_clk_stop(struct sdw_bus *bus);
Expand Down
Loading