es8316->sysclk = freq;
 
-       if (freq == 0)
+       if (freq == 0) {
+               es8316->sysclk_constraints.list = NULL;
+               es8316->sysclk_constraints.count = 0;
+
                return 0;
+       }
 
        ret = clk_set_rate(es8316->mclk, freq);
        if (ret)
        struct snd_soc_component *component = dai->component;
        struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
 
-       if (es8316->sysclk == 0) {
-               dev_err(component->dev, "No sysclk provided\n");
-               return -EINVAL;
-       }
-
-       /* The set of sample rates that can be supported depends on the
-        * MCLK supplied to the CODEC.
-        */
-       snd_pcm_hw_constraint_list(substream->runtime, 0,
-                                  SNDRV_PCM_HW_PARAM_RATE,
-                                  &es8316->sysclk_constraints);
+       if (es8316->sysclk_constraints.list)
+               snd_pcm_hw_constraint_list(substream->runtime, 0,
+                                          SNDRV_PCM_HW_PARAM_RATE,
+                                          &es8316->sysclk_constraints);
 
        return 0;
 }
        struct snd_soc_component *component = dai->component;
        struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
        u8 wordlen = 0;
+       int i;
 
-       if (!es8316->sysclk) {
-               dev_err(component->dev, "No MCLK configured\n");
-               return -EINVAL;
+       /* Validate supported sample rates that are autodetected from MCLK */
+       for (i = 0; i < NR_SUPPORTED_MCLK_LRCK_RATIOS; i++) {
+               const unsigned int ratio = supported_mclk_lrck_ratios[i];
+
+               if (es8316->sysclk % ratio != 0)
+                       continue;
+               if (es8316->sysclk / ratio == params_rate(params))
+                       break;
        }
+       if (i == NR_SUPPORTED_MCLK_LRCK_RATIOS)
+               return -EINVAL;
 
        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S16_LE: