Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit c899df3e authored by Rander Wang's avatar Rander Wang Committed by Mark Brown
Browse files

ASoC:intel:skl:fix a simultaneous playback & capture issue on hda platform



If playback and capture are enabled concurrently, when the capture stops
the output becomes inaudile. The playback application will become stuck
and underrun after a timeout.

This is caused by mistaken use of the stream_id, which should only be
set for playback and not for capture

Tested on Apollolake and Kabylake with SST driver.

Signed-off-by: default avatarRander Wang <rander.wang@linux.intel.com>
Acked-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 03d0aa4d
Loading
Loading
Loading
Loading
+14 −5
Original line number Original line Diff line number Diff line
@@ -181,6 +181,7 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params)
	struct hdac_stream *hstream;
	struct hdac_stream *hstream;
	struct hdac_ext_stream *stream;
	struct hdac_ext_stream *stream;
	struct hdac_ext_link *link;
	struct hdac_ext_link *link;
	unsigned char stream_tag;


	hstream = snd_hdac_get_stream(bus, params->stream,
	hstream = snd_hdac_get_stream(bus, params->stream,
					params->link_dma_id + 1);
					params->link_dma_id + 1);
@@ -199,10 +200,13 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params)


	snd_hdac_ext_link_stream_setup(stream, format_val);
	snd_hdac_ext_link_stream_setup(stream, format_val);


	stream_tag = hstream->stream_tag;
	if (stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) {
		list_for_each_entry(link, &bus->hlink_list, list) {
		list_for_each_entry(link, &bus->hlink_list, list) {
			if (link->index == params->link_index)
			if (link->index == params->link_index)
				snd_hdac_ext_link_set_stream_id(link,
				snd_hdac_ext_link_set_stream_id(link,
					hstream->stream_tag);
								stream_tag);
		}
	}
	}


	stream->link_prepared = 1;
	stream->link_prepared = 1;
@@ -645,6 +649,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream,
	struct hdac_ext_stream *link_dev =
	struct hdac_ext_stream *link_dev =
				snd_soc_dai_get_dma_data(dai, substream);
				snd_soc_dai_get_dma_data(dai, substream);
	struct hdac_ext_link *link;
	struct hdac_ext_link *link;
	unsigned char stream_tag;


	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);


@@ -654,7 +659,11 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream,
	if (!link)
	if (!link)
		return -EINVAL;
		return -EINVAL;


	snd_hdac_ext_link_clear_stream_id(link, hdac_stream(link_dev)->stream_tag);
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		stream_tag = hdac_stream(link_dev)->stream_tag;
		snd_hdac_ext_link_clear_stream_id(link, stream_tag);
	}

	snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK);
	snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK);
	return 0;
	return 0;
}
}