* RT1015 audio amplifier
  */
 
+static const struct {
+       unsigned int tx;
+       unsigned int rx;
+} rt1015_tdm_mask[] = {
+       {.tx = 0x0, .rx = 0x1},
+       {.tx = 0x0, .rx = 0x2},
+};
+
 static int rt1015_hw_params(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_link *dai_link = rtd->dai_link;
        struct snd_soc_dai *codec_dai;
-       int i, fs = 64, ret;
+       int i, clk_freq, ret;
 
-       for_each_rtd_codec_dais(rtd, i, codec_dai) {
-               ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK,
-                                         params_rate(params) * fs,
-                                         params_rate(params) * 256);
-               if (ret)
-                       return ret;
+       clk_freq = sof_dai_get_bclk(rtd);
 
-               ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL,
-                                            params_rate(params) * 256,
-                                            SND_SOC_CLOCK_IN);
-               if (ret)
-                       return ret;
+       if (clk_freq <= 0) {
+               dev_err(rtd->dev, "fail to get bclk freq, ret %d\n", clk_freq);
+               return -EINVAL;
        }
 
-       return 0;
-}
-
-static int rt1015_hw_params_pll_and_tdm(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;
-       int i, fs = 100, ret;
-
        for_each_rtd_codec_dais(rtd, i, codec_dai) {
                ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK,
-                                         params_rate(params) * fs,
+                                         clk_freq,
                                          params_rate(params) * 256);
-               if (ret)
+               if (ret) {
+                       dev_err(codec_dai->dev, "fail to set pll, ret %d\n",
+                               ret);
                        return ret;
+               }
 
                ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL,
                                             params_rate(params) * 256,
                                             SND_SOC_CLOCK_IN);
-               if (ret)
+               if (ret) {
+                       dev_err(codec_dai->dev, "fail to set sysclk, ret %d\n",
+                               ret);
                        return ret;
-       }
-       /* rx slot 1 for RT1015_DEV0_NAME */
-       ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0),
-                                      0x0, 0x1, 4, 24);
-       if (ret)
-               return ret;
+               }
 
-       /* rx slot 2 for RT1015_DEV1_NAME */
-       ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 1),
-                                      0x0, 0x2, 4, 24);
-       if (ret)
-               return ret;
+               switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+               case SND_SOC_DAIFMT_DSP_A:
+               case SND_SOC_DAIFMT_DSP_B:
+                       /* 4-slot TDM */
+                       ret = snd_soc_dai_set_tdm_slot(codec_dai,
+                                                      rt1015_tdm_mask[i].tx,
+                                                      rt1015_tdm_mask[i].rx,
+                                                      4,
+                                                      params_width(params));
+                       if (ret < 0) {
+                               dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
+                                       ret);
+                               return ret;
+                       }
+                       break;
+               default:
+                       dev_dbg(codec_dai->dev, "codec is in I2S mode\n");
+                       break;
+               }
+       }
 
-       return 0;
+       return ret;
 }
 
 static struct snd_soc_ops rt1015_ops = {
 }
 EXPORT_SYMBOL_NS(sof_rt1015_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON);
 
-void sof_rt1015_dai_link(struct snd_soc_dai_link *link, unsigned int fs)
+void sof_rt1015_dai_link(struct snd_soc_dai_link *link)
 {
        link->codecs = rt1015_components;
        link->num_codecs = ARRAY_SIZE(rt1015_components);
        link->init = speaker_codec_init_lr;
        link->ops = &rt1015_ops;
-
-       if (fs == 100)
-               rt1015_ops.hw_params = rt1015_hw_params_pll_and_tdm;
 }
 EXPORT_SYMBOL_NS(sof_rt1015_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
 
 
        ((quirk << SOF_RT5682_NUM_HDMIDEV_SHIFT) & SOF_RT5682_NUM_HDMIDEV_MASK)
 #define SOF_RT1011_SPEAKER_AMP_PRESENT         BIT(13)
 #define SOF_RT1015_SPEAKER_AMP_PRESENT         BIT(14)
-#define SOF_RT1015_SPEAKER_AMP_100FS           BIT(15)
 #define SOF_RT1015P_SPEAKER_AMP_PRESENT                BIT(16)
 #define SOF_MAX98373_SPEAKER_AMP_PRESENT       BIT(17)
 #define SOF_MAX98360A_SPEAKER_AMP_PRESENT      BIT(18)
                                        SOF_RT5682_SSP_CODEC(0) |
                                        SOF_SPEAKER_AMP_PRESENT |
                                        SOF_RT1015_SPEAKER_AMP_PRESENT |
-                                       SOF_RT1015_SPEAKER_AMP_100FS |
                                        SOF_RT5682_SSP_AMP(1)),
        },
        {
 
                links[id].id = id;
                if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT) {
-                       sof_rt1015_dai_link(&links[id], (sof_rt5682_quirk &
-                                       SOF_RT1015_SPEAKER_AMP_100FS) ? 100 : 64);
+                       sof_rt1015_dai_link(&links[id]);
                } else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) {
                        sof_rt1015p_dai_link(&links[id]);
                } else if (sof_rt5682_quirk & SOF_RT1019_SPEAKER_AMP_PRESENT) {
                                        SOF_RT5682_SSP_CODEC(0) |
                                        SOF_SPEAKER_AMP_PRESENT |
                                        SOF_RT1015_SPEAKER_AMP_PRESENT |
-                                       SOF_RT1015_SPEAKER_AMP_100FS |
                                        SOF_RT5682_SSP_AMP(1)),
        },
        {