#include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
+#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
        struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES];
        struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES];
        struct snd_soc_jack *jack;
+       u32 sysclk_id;
        unsigned int sysclk;
        u8 p_div;
        int rate_div_line;
                             struct snd_soc_dai *dai)
 {
        struct snd_soc_component *component = dai->component;
+       struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
        u8 data = 0;
 
        dev_dbg(component->dev, "## %s: width %d rate %d\n",
                            AIC31XX_IFACE1_DATALEN_MASK,
                            data);
 
+       /*
+        * If BCLK is used as PLL input, the sysclk is determined by the hw
+        * params. So it must be updated here to match the input frequency.
+        */
+       if (aic31xx->sysclk_id == AIC31XX_PLL_CLKIN_BCLK) {
+               aic31xx->sysclk = params_rate(params) * params_width(params) *
+                                 params_channels(params);
+               aic31xx->p_div = 1;
+       }
+
        return aic31xx_setup_pll(component, params);
 }
 
        snd_soc_component_update_bits(component, AIC31XX_CLKMUX, AIC31XX_PLL_CLKIN_MASK,
                            clk_id << AIC31XX_PLL_CLKIN_SHIFT);
 
+       aic31xx->sysclk_id = clk_id;
        aic31xx->sysclk = freq;
 
        return 0;