snd_soc_dai_set_stream(codec_dai, hstream, substream->stream);
 }
 
+static unsigned int hda_calc_stream_format(struct snd_sof_dev *sdev,
+                                          struct snd_pcm_substream *substream,
+                                          struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+       struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+       unsigned int link_bps;
+       unsigned int format_val;
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               link_bps = codec_dai->driver->playback.sig_bits;
+       else
+               link_bps = codec_dai->driver->capture.sig_bits;
+
+       format_val = snd_hdac_calc_stream_format(params_rate(params), params_channels(params),
+                                                params_format(params), link_bps, 0);
+
+       dev_dbg(sdev->dev, "format_val=%#x, rate=%d, ch=%d, format=%d\n", format_val,
+               params_rate(params), params_channels(params), params_format(params));
+
+       return format_val;
+}
+
 static int hda_ipc4_pre_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai,
                                struct snd_pcm_substream *substream, int cmd)
 {
        .trigger = hda_trigger,
        .post_trigger = hda_ipc4_post_trigger,
        .codec_dai_set_stream = hda_codec_dai_set_stream,
+       .calc_stream_format = hda_calc_stream_format,
 };
 
 static const struct hda_dai_widget_dma_ops hda_ipc4_chain_dma_ops = {
        .reset_hext_stream = hda_reset_hext_stream,
        .trigger = hda_trigger,
        .codec_dai_set_stream = hda_codec_dai_set_stream,
+       .calc_stream_format = hda_calc_stream_format,
 };
 
 static int hda_ipc3_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai,
        .trigger = hda_trigger,
        .post_trigger = hda_ipc3_post_trigger,
        .codec_dai_set_stream = hda_codec_dai_set_stream,
+       .calc_stream_format = hda_calc_stream_format,
 };
 
 static struct hdac_ext_stream *
        .get_hext_stream = hda_dspless_get_hext_stream,
        .setup_hext_stream = hda_dspless_setup_hext_stream,
        .codec_dai_set_stream = hda_codec_dai_set_stream,
+       .calc_stream_format = hda_calc_stream_format,
 };
 
 #endif
 
        struct hdac_ext_link *hlink;
        struct snd_sof_dev *sdev;
        struct hdac_bus *bus;
-       unsigned int format_val;
-       unsigned int link_bps;
        int stream_tag;
 
        if (!ops) {
        if (ops->codec_dai_set_stream)
                ops->codec_dai_set_stream(sdev, substream, hstream);
 
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               link_bps = codec_dai->driver->playback.sig_bits;
-       else
-               link_bps = codec_dai->driver->capture.sig_bits;
-
        if (ops->reset_hext_stream)
                ops->reset_hext_stream(sdev, hext_stream);
 
-       format_val = snd_hdac_calc_stream_format(params_rate(params), params_channels(params),
-                                                params_format(params), link_bps, 0);
-
-       dev_dbg(bus->dev, "format_val=%#x, rate=%d, ch=%d, format=%d\n", format_val,
-               params_rate(params), params_channels(params), params_format(params));
+       if (ops->calc_stream_format && ops->setup_hext_stream) {
+               unsigned int format_val = ops->calc_stream_format(sdev, substream, params);
 
-       if (ops->setup_hext_stream)
                ops->setup_hext_stream(sdev, hext_stream, format_val);
+       }
 
        hext_stream->link_prepared = 1;
 
 
  * @trigger: Function pointer for DAI DMA trigger actions
  * @post_trigger: Function pointer for DAI DMA post-trigger actions
  * @codec_dai_set_stream: Function pointer to set codec-side stream information
+ * @calc_stream_format: Function pointer to determine stream format from hw_params and
+ * for HDaudio codec DAI from the .sig bits
  */
 struct hda_dai_widget_dma_ops {
        struct hdac_ext_stream *(*get_hext_stream)(struct snd_sof_dev *sdev,
        void (*codec_dai_set_stream)(struct snd_sof_dev *sdev,
                                     struct snd_pcm_substream *substream,
                                     struct hdac_stream *hstream);
+       unsigned int (*calc_stream_format)(struct snd_sof_dev *sdev,
+                                          struct snd_pcm_substream *substream,
+                                          struct snd_pcm_hw_params *params);
 };
 
 const struct hda_dai_widget_dma_ops *