Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
37ea566
ALSA: HDA: hdac_ext_stream: use consistent prefixes for variables
plbossart Sep 14, 2021
67787ed
ASoC: SOF: Intel: hdac_ext_stream: consistent prefixes for variables/…
plbossart Sep 14, 2021
1e300e7
ASoC/SoundWire: dai: expand 'stream' concept beyond SoundWire
plbossart Aug 31, 2021
c18456e
ASoC: Intel/SOF: use set_stream() instead of set_tdm_slots() for HDAudio
plbossart Aug 31, 2021
2fa550d
ASOC: SOF: Intel: use snd_soc_dai_get_widget()
plbossart Aug 31, 2021
c2656d1
ASoC: SOF: Intel: hda-dai: remove support for TRIGGER_RESUME
plbossart Aug 31, 2021
fb422e7
ASOC: SOF: Intel: hda-dai: consistent naming for HDA DAI and HDA link…
plbossart Aug 31, 2021
3c6ad2c
ASoC: SOF: Intel: hda-dai: simplify hda_dai_widget_update() prototype
plbossart Aug 31, 2021
72330f9
ASoC: SOF: Intel: hda-dai: split dailink and dai operations
plbossart Aug 31, 2021
5fd0931
ASoC: SOF: Intel: hda-dai: regroup dai and dailink operations
plbossart Sep 8, 2021
9ebf97b
soundwire: intel: remove unnecessary initialization
plbossart Sep 9, 2021
f35a506
soundwire: stream: remove unused parameter in sdw_stream_add_slave
plbossart Aug 27, 2021
b028f65
soundwire: stream: add slave runtime to list earlier
plbossart Aug 27, 2021
2a546d4
soundwire: stream: simplify check on port range
plbossart Sep 9, 2021
62fd00f
soundwire: stream: add alloc/config/free helpers for ports
plbossart Sep 8, 2021
191e7f1
soundwire: stream: split port allocation and configuration loops
plbossart Sep 9, 2021
528ed46
soundwire: stream: split alloc and config in two functions
plbossart Sep 9, 2021
1f7c030
soundwire: stream: add 'slave' prefix for port range checks
plbossart Sep 9, 2021
a7addd1
soundwire: stream: group sdw_port and sdw_master/slave_port functions
plbossart Sep 9, 2021
e674f47
soundwire: stream: simplify sdw_alloc_master_rt()
plbossart Sep 9, 2021
d0cb229
soundwire: stream: split sdw_alloc_master_rt() in alloc and config
plbossart Sep 9, 2021
a375efc
soundwire: stream: move sdw_alloc_slave_rt() before 'master' helpers
plbossart Sep 9, 2021
cc1a16e
soundwire: stream: split sdw_alloc_slave_rt() in alloc and config
plbossart Sep 9, 2021
bc54f16
soundwire: stream: group sdw_stream_ functions
plbossart Sep 9, 2021
2332f41
soundwire: stream: rename and move master/slave_rt_free routines
plbossart Sep 9, 2021
71d2c27
soundwire: stream: move list addition to sdw_slave_alloc_rt()
plbossart Sep 9, 2021
a19f191
soundwire: stream: separate alloc and config within sdw_stream_add_xxx()
plbossart Sep 9, 2021
88c2376
soundwire: stream: introduce sdw_slave_rt_find() helper
plbossart Sep 9, 2021
c645243
soundwire: stream: sdw_stream_add_ functions can be called multiple t…
plbossart Sep 9, 2021
ad0cab2
soundwire: stream: make enable/disable/deprepare idempotent
plbossart Aug 13, 2021
4a0a02e
ASoC/soundwire: intel: simplify callbacks for params/hw_free
plbossart Aug 25, 2021
f8ae301
Revert "soundwire: intel: trap TRIGGER_SUSPEND in .trigger callback"
plbossart Sep 9, 2021
a52031b
soundwire: intel: improve suspend flows
ranj063 Jun 30, 2021
5b7fe99
ASoC: soc-pcm: protect BE dailink state changes in trigger
plbossart Aug 13, 2021
e2ce216
ASoC: soc-pcm: test refcount before triggering
plbossart Aug 16, 2021
2a3f977
ASoC: soc-pcm: fix BE handling of PAUSE_RELEASE
plbossart Aug 24, 2021
b99224c
ASoC: SOF: sof-audio: flag errors on pipeline teardown
plbossart Aug 17, 2021
5e9c753
ASOC: SOF: Intel: hda-dai: add hda_dai_hw_free_ipc() helper
plbossart Sep 14, 2021
22e8209
ASoC: SOF: Intel: hda-dai: move code to deal with hda dai/dailink sus…
plbossart Sep 14, 2021
929aeaa
ASoC: SOF: Intel: hda-dai: reset dma_data and release stream
plbossart Sep 16, 2021
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
2 changes: 2 additions & 0 deletions drivers/soundwire/cadence_master.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ struct sdw_cdns_stream_config {
* @link_id: Master link id
* @hw_params: hw_params to be applied in .prepare step
* @suspended: status set when suspended, to be used in .prepare
* @paused: status set in .trigger, to be used in suspend
*/
struct sdw_cdns_dma_data {
char *name;
Expand All @@ -96,6 +97,7 @@ struct sdw_cdns_dma_data {
int link_id;
struct snd_pcm_hw_params *hw_params;
bool suspended;
bool paused;
};

/**
Expand Down
106 changes: 83 additions & 23 deletions drivers/soundwire/intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -711,15 +711,15 @@ intel_pdi_alh_configure(struct sdw_intel *sdw, struct sdw_cdns_pdi *pdi)
}

static int intel_params_stream(struct sdw_intel *sdw,
struct snd_pcm_substream *substream,
int stream,
struct snd_soc_dai *dai,
struct snd_pcm_hw_params *hw_params,
int link_id, int alh_stream_id)
{
struct sdw_intel_link_res *res = sdw->link_res;
struct sdw_intel_stream_params_data params_data;

params_data.substream = substream;
params_data.stream = stream; /* direction */
params_data.dai = dai;
params_data.hw_params = hw_params;
params_data.link_id = link_id;
Expand All @@ -732,14 +732,14 @@ static int intel_params_stream(struct sdw_intel *sdw,
}

static int intel_free_stream(struct sdw_intel *sdw,
struct snd_pcm_substream *substream,
int stream,
struct snd_soc_dai *dai,
int link_id)
{
struct sdw_intel_link_res *res = sdw->link_res;
struct sdw_intel_stream_free_data free_data;

free_data.substream = substream;
free_data.stream = stream; /* direction */
free_data.dai = dai;
free_data.link_id = link_id;

Expand Down Expand Up @@ -871,12 +871,13 @@ static int intel_hw_params(struct snd_pcm_substream *substream,
sdw_cdns_config_stream(cdns, ch, dir, pdi);

/* store pdi and hw_params, may be needed in prepare step */
dma->paused = false;
dma->suspended = false;
dma->pdi = pdi;
dma->hw_params = params;

/* Inform DSP about PDI stream number */
ret = intel_params_stream(sdw, substream, dai, params,
ret = intel_params_stream(sdw, substream->stream, dai, params,
sdw->instance,
pdi->intel_alh_id);
if (ret)
Expand Down Expand Up @@ -953,7 +954,7 @@ static int intel_prepare(struct snd_pcm_substream *substream,
sdw_cdns_config_stream(cdns, ch, dir, dma->pdi);

/* Inform DSP about PDI stream number */
ret = intel_params_stream(sdw, substream, dai,
ret = intel_params_stream(sdw, substream->stream, dai,
dma->hw_params,
sdw->instance,
dma->pdi->intel_alh_id);
Expand Down Expand Up @@ -987,7 +988,7 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
return ret;
}

ret = intel_free_stream(sdw, substream, dai, sdw->instance);
ret = intel_free_stream(sdw, substream->stream, dai, sdw->instance);
if (ret < 0) {
dev_err(dai->dev, "intel_free_stream: failed %d\n", ret);
return ret;
Expand Down Expand Up @@ -1041,15 +1042,7 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, struct sn
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
struct sdw_intel *sdw = cdns_to_intel(cdns);
struct sdw_cdns_dma_data *dma;

/*
* The .prepare callback is used to deal with xruns and resume operations. In the case
* of xruns, the DMAs and SHIM registers cannot be touched, but for resume operations the
* DMAs and SHIM registers need to be initialized.
* the .trigger callback is used to track the suspend case only.
*/
if (cmd != SNDRV_PCM_TRIGGER_SUSPEND)
return 0;
int ret;

dma = snd_soc_dai_get_dma_data(dai, substream);
if (!dma) {
Expand All @@ -1058,9 +1051,75 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, struct sn
return -EIO;
}

dma->suspended = true;
switch (cmd) {
case SNDRV_PCM_TRIGGER_SUSPEND:

/*
* The .prepare callback is used to deal with xruns and resume operations.
* In the case of xruns, the DMAs and SHIM registers cannot be touched,
* but for resume operations the DMAs and SHIM registers need to be initialized.
* the .trigger callback is used to track the suspend case only.
*/

dma->suspended = true;

return intel_free_stream(sdw, substream, dai, sdw->instance);
ret = intel_free_stream(sdw, substream->stream, dai, sdw->instance);
break;

case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
dma->paused = true;
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
dma->paused = false;
break;
default:
break;
}

return ret;
}

static int intel_component_dais_suspend(struct snd_soc_component *component)
{
struct snd_soc_dai *dai;

/*
* In the corner case where a SUSPEND happens during a PAUSE, the ALSA core
* does not throw the TRIGGER_SUSPEND. This leaves the DAIs in an unbalanced state.
* Since the component suspend is called last, we can trap this corner case
* and force the DAIs to release their resources.
*/
for_each_component_dais(component, dai) {
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
struct sdw_intel *sdw = cdns_to_intel(cdns);
struct sdw_cdns_dma_data *dma;
int stream;
int ret;

dma = dai->playback_dma_data;
stream = SNDRV_PCM_STREAM_PLAYBACK;
if (!dma) {
dma = dai->capture_dma_data;
stream = SNDRV_PCM_STREAM_CAPTURE;
}

if (!dma)
continue;

if (dma->suspended)
continue;

if (dma->paused) {
dma->suspended = true;

ret = intel_free_stream(sdw, stream, dai, sdw->instance);
if (ret < 0)
return ret;
}
}

return 0;
}

static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
Expand All @@ -1070,8 +1129,8 @@ static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
.hw_free = intel_hw_free,
.trigger = intel_trigger,
.shutdown = intel_shutdown,
.set_sdw_stream = intel_pcm_set_sdw_stream,
.get_sdw_stream = intel_get_sdw_stream,
.set_stream = intel_pcm_set_sdw_stream,
.get_stream = intel_get_sdw_stream,
};

static const struct snd_soc_dai_ops intel_pdm_dai_ops = {
Expand All @@ -1081,12 +1140,13 @@ static const struct snd_soc_dai_ops intel_pdm_dai_ops = {
.hw_free = intel_hw_free,
.trigger = intel_trigger,
.shutdown = intel_shutdown,
.set_sdw_stream = intel_pdm_set_sdw_stream,
.get_sdw_stream = intel_get_sdw_stream,
.set_stream = intel_pdm_set_sdw_stream,
.get_stream = intel_get_sdw_stream,
};

static const struct snd_soc_component_driver dai_component = {
.name = "soundwire",
.suspend = intel_component_dais_suspend,
};

static int intel_create_dai(struct sdw_cdns *cdns,
Expand Down Expand Up @@ -1554,7 +1614,7 @@ static int __maybe_unused intel_pm_prepare(struct device *dev)
struct sdw_intel *sdw = cdns_to_intel(cdns);
struct sdw_bus *bus = &cdns->bus;
u32 clock_stop_quirks;
int ret = 0;
int ret;

if (bus->prop.hw_disabled || !sdw->startup_done) {
dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n",
Expand Down
8 changes: 4 additions & 4 deletions drivers/soundwire/qcom.c
Original file line number Diff line number Diff line change
Expand Up @@ -1019,8 +1019,8 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
ctrl->sruntime[dai->id] = sruntime;

for_each_rtd_codec_dais(rtd, i, codec_dai) {
ret = snd_soc_dai_set_sdw_stream(codec_dai, sruntime,
substream->stream);
ret = snd_soc_dai_set_stream(codec_dai, sruntime,
substream->stream);
if (ret < 0 && ret != -ENOTSUPP) {
dev_err(dai->dev, "Failed to set sdw stream on %s\n",
codec_dai->name);
Expand All @@ -1046,8 +1046,8 @@ static const struct snd_soc_dai_ops qcom_swrm_pdm_dai_ops = {
.hw_free = qcom_swrm_hw_free,
.startup = qcom_swrm_startup,
.shutdown = qcom_swrm_shutdown,
.set_sdw_stream = qcom_swrm_set_sdw_stream,
.get_sdw_stream = qcom_swrm_get_sdw_stream,
.set_stream = qcom_swrm_set_sdw_stream,
.get_stream = qcom_swrm_get_sdw_stream,
};

static const struct snd_soc_component_driver qcom_swrm_dai_component = {
Expand Down
Loading