return true;
 }
 
+static int aif_mclk_set(struct snd_soc_component *component, int aif, bool enable)
+{
+       struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
+       unsigned int offset, val, clk_idx;
+       int ret;
+
+       if (aif)
+               offset = 4;
+       else
+               offset = 0;
+
+       val = snd_soc_component_read32(component, WM8994_AIF1_CLOCKING_1 + offset);
+       val &= WM8994_AIF1CLK_SRC_MASK;
+
+       switch (val) {
+       case 0:
+               clk_idx = WM8994_MCLK1;
+               break;
+       case 1:
+               clk_idx = WM8994_MCLK2;
+               break;
+       default:
+               return 0;
+       }
+
+       if (enable) {
+               ret = clk_prepare_enable(wm8994->mclk[clk_idx].clk);
+               if (ret < 0) {
+                       dev_err(component->dev, "Failed to enable MCLK%d\n",
+                               clk_idx);
+                       return ret;
+               }
+       } else {
+               clk_disable_unprepare(wm8994->mclk[clk_idx].clk);
+       }
+
+       return 0;
+}
+
 static int aif1clk_ev(struct snd_soc_dapm_widget *w,
                      struct snd_kcontrol *kcontrol, int event)
 {
        struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
        struct wm8994 *control = wm8994->wm8994;
        int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA;
-       int i;
+       int ret, i;
        int dac;
        int adc;
        int val;
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
+               ret = aif_mclk_set(component, 0, true);
+               if (ret < 0)
+                       return ret;
+
                /* Don't enable timeslot 2 if not in use */
                if (wm8994->channels[0] <= 2)
                        mask &= ~(WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
                break;
        }
 
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMD:
+               aif_mclk_set(component, 0, false);
+               break;
+       }
+
        return 0;
 }
 
                      struct snd_kcontrol *kcontrol, int event)
 {
        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
-       int i;
+       int ret, i;
        int dac;
        int adc;
        int val;
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
+               ret = aif_mclk_set(component, 1, true);
+               if (ret < 0)
+                       return ret;
+
                val = snd_soc_component_read32(component, WM8994_AIF2_CONTROL_1);
                if ((val & WM8994_AIF2ADCL_SRC) &&
                    (val & WM8994_AIF2ADCR_SRC))
                break;
        }
 
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMD:
+               aif_mclk_set(component, 1, false);
+               break;
+       }
+
        return 0;
 }
 
 static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = {
 SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, aif1clk_ev,
                    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
-                   SND_SOC_DAPM_PRE_PMD),
+                   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, aif2clk_ev,
                    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
-                   SND_SOC_DAPM_PRE_PMD),
+                   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
                   left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
        u16 reg, clk1, aif_reg, aif_src;
        unsigned long timeout;
        bool was_enabled;
+       struct clk *mclk;
 
        switch (id) {
        case WM8994_FLL1:
        snd_soc_component_update_bits(component, WM8994_FLL1_CONTROL_1 + reg_offset,
                            WM8994_FLL1_ENA, 0);
 
+       /* Disable MCLK if needed before we possibly change to new clock parent */
+       if (was_enabled) {
+               reg = snd_soc_component_read32(component, WM8994_FLL1_CONTROL_5
+                                                       + reg_offset);
+               reg = ((reg & WM8994_FLL1_REFCLK_SRC_MASK)
+                       >> WM8994_FLL1_REFCLK_SRC_SHIFT) + 1;
+
+               switch (reg) {
+               case WM8994_FLL_SRC_MCLK1:
+                       mclk = wm8994->mclk[WM8994_MCLK1].clk;
+                       break;
+               case WM8994_FLL_SRC_MCLK2:
+                       mclk = wm8994->mclk[WM8994_MCLK2].clk;
+                       break;
+               default:
+                       mclk = NULL;
+               }
+
+               clk_disable_unprepare(mclk);
+       }
+
        if (wm8994->fll_byp && src == WM8994_FLL_SRC_BCLK &&
            freq_in == freq_out && freq_out) {
                dev_dbg(component->dev, "Bypassing FLL%d\n", id + 1);
        /* Clear any pending completion from a previous failure */
        try_wait_for_completion(&wm8994->fll_locked[id]);
 
+       switch (src) {
+       case WM8994_FLL_SRC_MCLK1:
+               mclk = wm8994->mclk[WM8994_MCLK1].clk;
+               break;
+       case WM8994_FLL_SRC_MCLK2:
+               mclk = wm8994->mclk[WM8994_MCLK2].clk;
+               break;
+       default:
+               mclk = NULL;
+       }
+
        /* Enable (with fractional mode if required) */
        if (freq_out) {
+               ret = clk_prepare_enable(mclk);
+               if (ret < 0) {
+                       dev_err(component->dev, "Failed to enable MCLK for FLL%d\n",
+                               id + 1);
+                       return ret;
+               }
+
                /* Enable VMID if we need it */
                if (!was_enabled) {
+
                        active_reference(component);
 
                        switch (control->type) {