ASoC: Intel: Skylake: Clean up of driver resources in suspend
[deliverable/linux.git] / sound / soc / intel / skylake / skl-pcm.c
index 7c81b31748ffcba2ab7c5d8a8961eb83d4134f55..1590beff644df9d4f03e5ec58dfd8e5e78e76549 100644 (file)
@@ -227,16 +227,25 @@ static int skl_pcm_prepare(struct snd_pcm_substream *substream,
                struct snd_soc_dai *dai)
 {
        struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
+       struct skl *skl = get_skl_ctx(dai->dev);
        unsigned int format_val;
        int err;
+       struct skl_module_cfg *mconfig;
 
        dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
 
+       mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
+
        format_val = skl_get_format(substream, dai);
        dev_dbg(dai->dev, "stream_tag=%d formatvalue=%d\n",
                                hdac_stream(stream)->stream_tag, format_val);
        snd_hdac_stream_reset(hdac_stream(stream));
 
+       /* In case of XRUN recovery, reset the FW pipe to clean state */
+       if (mconfig && (substream->runtime->status->state ==
+                                       SNDRV_PCM_STATE_XRUN))
+               skl_reset_pipe(skl->skl_sst, mconfig->pipe);
+
        err = snd_hdac_stream_set_params(hdac_stream(stream), format_val);
        if (err < 0)
                return err;
@@ -521,6 +530,8 @@ static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
        struct skl_dma_params *dma_params;
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
        struct hdac_ext_link *link;
+       struct skl *skl = get_skl_ctx(dai->dev);
+       struct skl_module_cfg *mconfig = NULL;
 
        dma_params  = (struct skl_dma_params *)
                        snd_soc_dai_get_dma_data(codec_dai, substream);
@@ -535,6 +546,12 @@ static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
 
        snd_hdac_ext_link_stream_reset(link_dev);
 
+       /* In case of XRUN recovery, reset the FW pipe to clean state */
+       mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream);
+       if (mconfig && (substream->runtime->status->state ==
+                                       SNDRV_PCM_STATE_XRUN))
+               skl_reset_pipe(skl->skl_sst, mconfig->pipe);
+
        snd_hdac_ext_link_stream_setup(link_dev, format_val);
 
        snd_hdac_ext_link_set_stream_id(link, hdac_stream(link_dev)->stream_tag);
@@ -1180,9 +1197,17 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
 static int skl_platform_soc_probe(struct snd_soc_platform *platform)
 {
        struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
+       struct skl *skl = ebus_to_skl(ebus);
+       int ret;
 
-       if (ebus->ppcap)
-               return skl_tplg_init(platform, ebus);
+       if (ebus->ppcap) {
+               ret = skl_tplg_init(platform, ebus);
+               if (ret < 0) {
+                       dev_err(platform->dev, "Failed to init topology!\n");
+                       return ret;
+               }
+               skl->platform = platform;
+       }
 
        return 0;
 }
This page took 0.031419 seconds and 5 git commands to generate.