lkml.org 
[lkml]   [2019]   [Apr]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.19 07/53] ASoC:intel:skl:fix a simultaneous playback & capture issue on hda platform
    Date
    From: Rander Wang <rander.wang@linux.intel.com>

    [ Upstream commit c899df3e9b0bf7b76e642aed1a214582ea7012d5 ]

    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: Rander Wang <rander.wang@linux.intel.com>
    Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
    Signed-off-by: Mark Brown <broonie@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    sound/soc/intel/skylake/skl-pcm.c | 19 ++++++++++++++-----
    1 file changed, 14 insertions(+), 5 deletions(-)

    diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
    index 823e39103edd..6b2c8c6e7a00 100644
    --- a/sound/soc/intel/skylake/skl-pcm.c
    +++ b/sound/soc/intel/skylake/skl-pcm.c
    @@ -180,6 +180,7 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params)
    struct hdac_stream *hstream;
    struct hdac_ext_stream *stream;
    struct hdac_ext_link *link;
    + unsigned char stream_tag;

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

    snd_hdac_ext_link_stream_setup(stream, format_val);

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

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

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

    @@ -649,7 +654,11 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream,
    if (!link)
    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);
    return 0;
    }
    --
    2.19.1
    \
     
     \ /
      Last update: 2019-04-27 03:52    [W:4.102 / U:0.192 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site