aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8994.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-03-29 09:49:27 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-04-01 06:28:29 -0400
commite413ba88044db34b3fc9aa1b432a4579db9072b3 (patch)
tree5bd74e36c96fd4b7f0b689f09db43f6cf26dea28 /sound/soc/codecs/wm8994.c
parent95cd98f9a6dcf112d2abf724ac07c56ec745180f (diff)
ASoC: wm8994: Don't allow reconfiguration of FLL when it provides SYSCLK
Rather than trying to work around machine drivers which try to reprogram the FLL while it is providing SYSCLK just return an error if they try. This will avoid audio glitches during FLL reconfiguration, or at least move the introduction of the glitches to the machine driver. Since disabling the source for an active SYSCLK is not supported in the first place systems shouldn't be doing this in the first place. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm8994.c')
-rw-r--r--sound/soc/codecs/wm8994.c35
1 files changed, 17 insertions, 18 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index fbcaf499b0ff..317159eec44c 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -1900,24 +1900,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1900 struct wm8994 *control = wm8994->wm8994; 1900 struct wm8994 *control = wm8994->wm8994;
1901 int reg_offset, ret; 1901 int reg_offset, ret;
1902 struct fll_div fll; 1902 struct fll_div fll;
1903 u16 reg, aif1, aif2; 1903 u16 reg, clk1, aif_reg, aif_src;
1904 unsigned long timeout; 1904 unsigned long timeout;
1905 bool was_enabled; 1905 bool was_enabled;
1906 1906
1907 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
1908 & WM8994_AIF1CLK_ENA;
1909
1910 aif2 = snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
1911 & WM8994_AIF2CLK_ENA;
1912
1913 switch (id) { 1907 switch (id) {
1914 case WM8994_FLL1: 1908 case WM8994_FLL1:
1915 reg_offset = 0; 1909 reg_offset = 0;
1916 id = 0; 1910 id = 0;
1911 aif_src = 0x10;
1917 break; 1912 break;
1918 case WM8994_FLL2: 1913 case WM8994_FLL2:
1919 reg_offset = 0x20; 1914 reg_offset = 0x20;
1920 id = 1; 1915 id = 1;
1916 aif_src = 0x18;
1921 break; 1917 break;
1922 default: 1918 default:
1923 return -EINVAL; 1919 return -EINVAL;
@@ -1959,11 +1955,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1959 if (ret < 0) 1955 if (ret < 0)
1960 return ret; 1956 return ret;
1961 1957
1962 /* Gate the AIF clocks while we reclock */ 1958 /* Make sure that we're not providing SYSCLK right now */
1963 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, 1959 clk1 = snd_soc_read(codec, WM8994_CLOCKING_1);
1964 WM8994_AIF1CLK_ENA, 0); 1960 if (clk1 & WM8994_SYSCLK_SRC)
1965 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, 1961 aif_reg = WM8994_AIF2_CLOCKING_1;
1966 WM8994_AIF2CLK_ENA, 0); 1962 else
1963 aif_reg = WM8994_AIF1_CLOCKING_1;
1964 reg = snd_soc_read(codec, aif_reg);
1965
1966 if ((reg & WM8994_AIF1CLK_ENA) &&
1967 (reg & WM8994_AIF1CLK_SRC_MASK) == aif_src) {
1968 dev_err(codec->dev, "FLL%d is currently providing SYSCLK\n",
1969 id + 1);
1970 return -EBUSY;
1971 }
1967 1972
1968 /* We always need to disable the FLL while reconfiguring */ 1973 /* We always need to disable the FLL while reconfiguring */
1969 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, 1974 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
@@ -2049,12 +2054,6 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
2049 wm8994->fll[id].out = freq_out; 2054 wm8994->fll[id].out = freq_out;
2050 wm8994->fll[id].src = src; 2055 wm8994->fll[id].src = src;
2051 2056
2052 /* Enable any gated AIF clocks */
2053 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
2054 WM8994_AIF1CLK_ENA, aif1);
2055 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
2056 WM8994_AIF2CLK_ENA, aif2);
2057
2058 configure_clock(codec); 2057 configure_clock(codec);
2059 2058
2060 return 0; 2059 return 0;