ASoC: Intel: avs: Handle SUSPEND and RESUME triggers
commit 8e097f9a55
upstream.
With power management operations added, service SUSPEND and RESUME
trigger commands for running streams.
Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20221027124702.1761002-5-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
9d90994abd
commit
026aa0946e
|
@ -208,30 +208,43 @@ static int avs_dai_nonhda_be_prepare(struct snd_pcm_substream *substream, struct
|
|||
static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
|
||||
struct avs_dma_data *data;
|
||||
int ret = 0;
|
||||
|
||||
data = snd_soc_dai_get_dma_data(dai, substream);
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
if (rtd->dai_link->ignore_suspend)
|
||||
break;
|
||||
fallthrough;
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
ret = avs_path_pause(data->path);
|
||||
if (ret < 0) {
|
||||
dev_err(dai->dev, "pause BE path failed: %d\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
|
||||
if (ret < 0)
|
||||
dev_err(dai->dev, "run BE path failed: %d\n", ret);
|
||||
break;
|
||||
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
if (rtd->dai_link->ignore_suspend)
|
||||
break;
|
||||
fallthrough;
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
ret = avs_path_pause(data->path);
|
||||
if (ret < 0)
|
||||
dev_err(dai->dev, "pause BE path failed: %d\n", ret);
|
||||
|
||||
if (cmd == SNDRV_PCM_TRIGGER_STOP) {
|
||||
ret = avs_path_reset(data->path);
|
||||
if (ret < 0)
|
||||
dev_err(dai->dev, "reset BE path failed: %d\n", ret);
|
||||
}
|
||||
ret = avs_path_reset(data->path);
|
||||
if (ret < 0)
|
||||
dev_err(dai->dev, "reset BE path failed: %d\n", ret);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -351,6 +364,7 @@ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct sn
|
|||
static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
|
||||
struct hdac_ext_stream *link_stream;
|
||||
struct avs_dma_data *data;
|
||||
int ret = 0;
|
||||
|
@ -361,15 +375,29 @@ static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
|
|||
link_stream = substream->runtime->private_data;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
if (rtd->dai_link->ignore_suspend)
|
||||
break;
|
||||
fallthrough;
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
snd_hdac_ext_stream_start(link_stream);
|
||||
|
||||
ret = avs_path_pause(data->path);
|
||||
if (ret < 0) {
|
||||
dev_err(dai->dev, "pause BE path failed: %d\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
|
||||
if (ret < 0)
|
||||
dev_err(dai->dev, "run BE path failed: %d\n", ret);
|
||||
break;
|
||||
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
if (rtd->dai_link->ignore_suspend)
|
||||
break;
|
||||
fallthrough;
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
ret = avs_path_pause(data->path);
|
||||
|
@ -378,11 +406,9 @@ static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
|
|||
|
||||
snd_hdac_ext_stream_clear(link_stream);
|
||||
|
||||
if (cmd == SNDRV_PCM_TRIGGER_STOP) {
|
||||
ret = avs_path_reset(data->path);
|
||||
if (ret < 0)
|
||||
dev_err(dai->dev, "reset BE path failed: %d\n", ret);
|
||||
}
|
||||
ret = avs_path_reset(data->path);
|
||||
if (ret < 0)
|
||||
dev_err(dai->dev, "reset BE path failed: %d\n", ret);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -600,6 +626,7 @@ static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_so
|
|||
|
||||
static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
|
||||
struct avs_dma_data *data;
|
||||
struct hdac_ext_stream *host_stream;
|
||||
struct hdac_bus *bus;
|
||||
|
@ -611,17 +638,36 @@ static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, stru
|
|||
bus = hdac_stream(host_stream)->bus;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
if (rtd->dai_link->ignore_suspend)
|
||||
break;
|
||||
fallthrough;
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
spin_lock_irqsave(&bus->reg_lock, flags);
|
||||
snd_hdac_stream_start(hdac_stream(host_stream), true);
|
||||
spin_unlock_irqrestore(&bus->reg_lock, flags);
|
||||
|
||||
/* Timeout on DRSM poll shall not stop the resume so ignore the result. */
|
||||
if (cmd == SNDRV_PCM_TRIGGER_RESUME)
|
||||
snd_hdac_stream_wait_drsm(hdac_stream(host_stream));
|
||||
|
||||
ret = avs_path_pause(data->path);
|
||||
if (ret < 0) {
|
||||
dev_err(dai->dev, "pause FE path failed: %d\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
|
||||
if (ret < 0)
|
||||
dev_err(dai->dev, "run FE path failed: %d\n", ret);
|
||||
|
||||
break;
|
||||
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
if (rtd->dai_link->ignore_suspend)
|
||||
break;
|
||||
fallthrough;
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
ret = avs_path_pause(data->path);
|
||||
|
@ -632,11 +678,9 @@ static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, stru
|
|||
snd_hdac_stream_stop(hdac_stream(host_stream));
|
||||
spin_unlock_irqrestore(&bus->reg_lock, flags);
|
||||
|
||||
if (cmd == SNDRV_PCM_TRIGGER_STOP) {
|
||||
ret = avs_path_reset(data->path);
|
||||
if (ret < 0)
|
||||
dev_err(dai->dev, "reset FE path failed: %d\n", ret);
|
||||
}
|
||||
ret = avs_path_reset(data->path);
|
||||
if (ret < 0)
|
||||
dev_err(dai->dev, "reset FE path failed: %d\n", ret);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -987,6 +1031,7 @@ static int avs_component_open(struct snd_soc_component *component,
|
|||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_PAUSE |
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP;
|
||||
|
||||
hwparams.formats = SNDRV_PCM_FMTBIT_S16_LE |
|
||||
|
|
Loading…
Reference in New Issue