#define MICFIL_OSR_DEFAULT     16
 
+#define MICFIL_NUM_RATES       7
+#define MICFIL_CLK_SRC_NUM     3
+/* clock source ids */
+#define MICFIL_AUDIO_PLL1      0
+#define MICFIL_AUDIO_PLL2      1
+#define MICFIL_CLK_EXT3                2
+
 enum quality {
        QUALITY_HIGH,
        QUALITY_MEDIUM,
        struct clk *mclk;
        struct clk *pll8k_clk;
        struct clk *pll11k_clk;
+       struct clk *clk_src[MICFIL_CLK_SRC_NUM];
        struct snd_dmaengine_dai_dma_data dma_params_rx;
        struct sdma_peripheral_config sdmacfg;
        struct snd_soc_card *card;
+       struct snd_pcm_hw_constraint_list constraint_rates;
+       unsigned int constraint_rates_list[MICFIL_NUM_RATES];
        unsigned int dataline;
        char name[32];
        int irq[MICFIL_IRQ_LINES];
                              struct snd_soc_dai *dai)
 {
        struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
+       unsigned int rates[MICFIL_NUM_RATES] = {8000, 11025, 16000, 22050, 32000, 44100, 48000};
+       int i, j, k = 0;
+       u64 clk_rate;
 
        if (!micfil) {
                dev_err(dai->dev, "micfil dai priv_data not set\n");
                return -EINVAL;
        }
 
+       micfil->constraint_rates.list = micfil->constraint_rates_list;
+       micfil->constraint_rates.count = 0;
+
+       for (j = 0; j < MICFIL_NUM_RATES; j++) {
+               for (i = 0; i < MICFIL_CLK_SRC_NUM; i++) {
+                       clk_rate = clk_get_rate(micfil->clk_src[i]);
+                       if (clk_rate != 0 && do_div(clk_rate, rates[j]) == 0) {
+                               micfil->constraint_rates_list[k++] = rates[j];
+                               micfil->constraint_rates.count++;
+                               break;
+                       }
+               }
+       }
+
+       if (micfil->constraint_rates.count > 0)
+               snd_pcm_hw_constraint_list(substream->runtime, 0,
+                                          SNDRV_PCM_HW_PARAM_RATE,
+                                          &micfil->constraint_rates);
+
        return 0;
 }
 
        fsl_asoc_get_pll_clocks(&pdev->dev, &micfil->pll8k_clk,
                                &micfil->pll11k_clk);
 
+       micfil->clk_src[MICFIL_AUDIO_PLL1] = micfil->pll8k_clk;
+       micfil->clk_src[MICFIL_AUDIO_PLL2] = micfil->pll11k_clk;
+       micfil->clk_src[MICFIL_CLK_EXT3] = devm_clk_get(&pdev->dev, "clkext3");
+       if (IS_ERR(micfil->clk_src[MICFIL_CLK_EXT3]))
+               micfil->clk_src[MICFIL_CLK_EXT3] = NULL;
+
        /* init regmap */
        regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
        if (IS_ERR(regs))