u8 bclk_divider;
        u16 lrck_divider;
        int i;
+       unsigned int clk = es8316->sysclk / 2;
+       bool clk_valid = false;
+
+       /* We will start with halved sysclk and see if we can use it
+        * for proper clocking. This is to minimise the risk of running
+        * the CODEC with a too high frequency. We have an SKU where
+        * the sysclk frequency is 48Mhz and this causes the sound to be
+        * sped up. If we can run with a halved sysclk, we will use it,
+        * if we can't use it, then full sysclk will be used.
+        */
+       do {
+               /* Validate supported sample rates that are autodetected from MCLK */
+               for (i = 0; i < ARRAY_SIZE(supported_mclk_lrck_ratios); i++) {
+                       const unsigned int ratio = supported_mclk_lrck_ratios[i];
+
+                       if (clk % ratio != 0)
+                               continue;
+                       if (clk / ratio == params_rate(params))
+                               break;
+               }
+               if (i == ARRAY_SIZE(supported_mclk_lrck_ratios)) {
+                       if (clk == es8316->sysclk)
+                               return -EINVAL;
+                       clk = es8316->sysclk;
+               } else {
+                       clk_valid = true;
+               }
+       } while (!clk_valid);
 
-       /* Validate supported sample rates that are autodetected from MCLK */
-       for (i = 0; i < ARRAY_SIZE(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 (clk != es8316->sysclk) {
+               snd_soc_component_update_bits(component, ES8316_CLKMGR_CLKSW,
+                                             ES8316_CLKMGR_CLKSW_MCLK_DIV,
+                                             ES8316_CLKMGR_CLKSW_MCLK_DIV);
        }
-       if (i == ARRAY_SIZE(supported_mclk_lrck_ratios))
-               return -EINVAL;
-       lrck_divider = es8316->sysclk / params_rate(params);
+
+       lrck_divider = clk / params_rate(params);
        bclk_divider = lrck_divider / 4;
        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S16_LE: