ASoC: wm8994: Implement support for self-oscillation mode in the FLL
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Mon, 23 Jul 2012 19:14:43 +0000 (20:14 +0100)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Fri, 3 Aug 2012 22:03:55 +0000 (23:03 +0100)
The FLLs in the WM8994 series devices can be started without any reference
being supplied, mainly for use in analogue bypass cases. Implement support
for this mode.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm8994.h

index 04ef03175c5182c2eb9ed26edc3e58a1d9130550..2c9b8b7fdf3d07970e0c6fcb3a694e1d1ac1c18e 100644 (file)
@@ -2102,6 +2102,10 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
        case WM8994_FLL_SRC_LRCLK:
        case WM8994_FLL_SRC_BCLK:
                break;
+       case WM8994_FLL_SRC_INTERNAL:
+               freq_in = 12000000;
+               freq_out = 12000000;
+               break;
        default:
                return -EINVAL;
        }
@@ -2164,9 +2168,11 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
                                    fll.n << WM8994_FLL1_N_SHIFT);
 
        snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
-                           WM8958_FLL1_BYP |
+                           WM8994_FLL1_FRC_NCO | WM8958_FLL1_BYP |
                            WM8994_FLL1_REFCLK_DIV_MASK |
                            WM8994_FLL1_REFCLK_SRC_MASK,
+                           ((src == WM8994_FLL_SRC_INTERNAL)
+                            << WM8994_FLL1_FRC_NCO_SHIFT) |
                            (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) |
                            (src - 1));
 
@@ -2192,13 +2198,16 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
                        }
                }
 
+               reg = WM8994_FLL1_ENA;
+
                if (fll.k)
-                       reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC;
-               else
-                       reg = WM8994_FLL1_ENA;
+                       reg |= WM8994_FLL1_FRAC;
+               if (src == WM8994_FLL_SRC_INTERNAL)
+                       reg |= WM8994_FLL1_OSC_ENA;
+
                snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
-                                   WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
-                                   reg);
+                                   WM8994_FLL1_ENA | WM8994_FLL1_OSC_ENA |
+                                   WM8994_FLL1_FRAC, reg);
 
                if (wm8994->fll_locked_irq) {
                        timeout = wait_for_completion_timeout(&wm8994->fll_locked[id],
index d77e06f0a6751f7a1d4394b90324916b6085a34d..19068d8fa3016ebf893ddd0bca3be9bdec346d22 100644 (file)
 #define WM8994_FLL1 1
 #define WM8994_FLL2 2
 
-#define WM8994_FLL_SRC_MCLK1  1
-#define WM8994_FLL_SRC_MCLK2  2
-#define WM8994_FLL_SRC_LRCLK  3
-#define WM8994_FLL_SRC_BCLK   4
+#define WM8994_FLL_SRC_MCLK1    1
+#define WM8994_FLL_SRC_MCLK2    2
+#define WM8994_FLL_SRC_LRCLK    3
+#define WM8994_FLL_SRC_BCLK     4
+#define WM8994_FLL_SRC_INTERNAL 5
 
 enum wm8994_vmid_mode {
        WM8994_VMID_NORMAL,