return -EINVAL;
        }
 
+       sdev = widget_to_sdev(w);
+       hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
+
+       /* nothing more to do if the link is already prepared */
+       if (hext_stream && hext_stream->link_prepared)
+               return 0;
+
        /* use HDaudio stream handling */
        ret = hda_dai_hw_params_data(substream, params, cpu_dai, data, flags);
        if (ret < 0) {
                return ret;
        }
 
-       sdev = widget_to_sdev(w);
        if (sdev->dspless_mode_selected)
                return 0;
 
        int ret;
        int i;
 
+       ops = hda_dai_get_ops(substream, cpu_dai);
+       if (!ops) {
+               dev_err(cpu_dai->dev, "DAI widget ops not set\n");
+               return -EINVAL;
+       }
+
+       sdev = widget_to_sdev(w);
+       hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
+
+       /* nothing more to do if the link is already prepared */
+       if (hext_stream && hext_stream->link_prepared)
+               return 0;
+
+       /*
+        * reset the PCMSyCM registers to handle a prepare callback when the PCM is restarted
+        * due to xruns or after a call to snd_pcm_drain/drop()
+        */
+       ret = hdac_bus_eml_sdw_map_stream_ch(sof_to_bus(sdev), link_id, cpu_dai->id,
+                                            0, 0, substream->stream);
+       if (ret < 0) {
+               dev_err(cpu_dai->dev, "%s:  hdac_bus_eml_sdw_map_stream_ch failed %d\n",
+                       __func__, ret);
+               return ret;
+       }
+
        data.dai_index = (link_id << 8) | cpu_dai->id;
        data.dai_node_id = intel_alh_id;
        ret = non_hda_dai_hw_params_data(substream, params, cpu_dai, &data, flags);
                return ret;
        }
 
-       ops = hda_dai_get_ops(substream, cpu_dai);
-       sdev = widget_to_sdev(w);
        hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
-
        if (!hext_stream)
                return -ENODEV;