aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8962.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-01-27 14:54:03 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-17 01:32:03 -0500
commita968d9db3b3a9329587b09bd15f4981473c63a9d (patch)
tree71c89cbe32789a4475c873df29ffec411eb1880a /sound/soc/codecs/wm8962.c
parent5aa9b858ef4ad9dc5551abe62a92d16f9c7a9680 (diff)
ASoC: wm8962: Don't automatically enable and disable FLL
Only enable and disable the FLL when explicitly told to, supporting some additional use cases and making the driver behaviour more standard. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm8962.c')
-rw-r--r--sound/soc/codecs/wm8962.c72
1 files changed, 6 insertions, 66 deletions
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index c36178b3d441..3dba53ace6bd 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -1832,65 +1832,6 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
1832 4, 1, 0, inmix_tlv), 1832 4, 1, 0, inmix_tlv),
1833}; 1833};
1834 1834
1835static int sysclk_event(struct snd_soc_dapm_widget *w,
1836 struct snd_kcontrol *kcontrol, int event)
1837{
1838 struct snd_soc_codec *codec = w->codec;
1839 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
1840 unsigned long timeout;
1841 int src;
1842 int fll;
1843
1844 /* Ignore attempts to run the event during startup */
1845 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
1846 return 0;
1847
1848 src = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_SRC_MASK;
1849
1850 switch (src) {
1851 case 0: /* MCLK */
1852 fll = 0;
1853 break;
1854 case 0x200: /* FLL */
1855 fll = 1;
1856 break;
1857 default:
1858 dev_err(codec->dev, "Unknown SYSCLK source %x\n", src);
1859 return -EINVAL;
1860 }
1861
1862 switch (event) {
1863 case SND_SOC_DAPM_PRE_PMU:
1864 if (fll) {
1865 try_wait_for_completion(&wm8962->fll_lock);
1866
1867 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
1868 WM8962_FLL_ENA, WM8962_FLL_ENA);
1869
1870 timeout = msecs_to_jiffies(5);
1871 timeout = wait_for_completion_timeout(&wm8962->fll_lock,
1872 timeout);
1873
1874 if (wm8962->irq && timeout == 0)
1875 dev_err(codec->dev,
1876 "Timed out starting FLL\n");
1877 }
1878 break;
1879
1880 case SND_SOC_DAPM_POST_PMD:
1881 if (fll)
1882 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
1883 WM8962_FLL_ENA, 0);
1884 break;
1885
1886 default:
1887 BUG();
1888 return -EINVAL;
1889 }
1890
1891 return 0;
1892}
1893
1894static int cp_event(struct snd_soc_dapm_widget *w, 1835static int cp_event(struct snd_soc_dapm_widget *w,
1895 struct snd_kcontrol *kcontrol, int event) 1836 struct snd_kcontrol *kcontrol, int event)
1896{ 1837{
@@ -2176,8 +2117,7 @@ SND_SOC_DAPM_INPUT("DMICDAT"),
2176SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0), 2117SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0),
2177 2118
2178SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0), 2119SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0),
2179SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event, 2120SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, NULL, 0),
2180 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2181SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, 2121SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event,
2182 SND_SOC_DAPM_POST_PMU), 2122 SND_SOC_DAPM_POST_PMU),
2183SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), 2123SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
@@ -2888,8 +2828,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2888 struct _fll_div fll_div; 2828 struct _fll_div fll_div;
2889 unsigned long timeout; 2829 unsigned long timeout;
2890 int ret; 2830 int ret;
2891 int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA; 2831 int fll1 = 0;
2892 int sysclk = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_ENA;
2893 2832
2894 /* Any change? */ 2833 /* Any change? */
2895 if (source == wm8962->fll_src && Fref == wm8962->fll_fref && 2834 if (source == wm8962->fll_src && Fref == wm8962->fll_fref &&
@@ -2912,6 +2851,9 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2912 if (ret != 0) 2851 if (ret != 0)
2913 return ret; 2852 return ret;
2914 2853
2854 /* Parameters good, disable so we can reprogram */
2855 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0);
2856
2915 switch (fll_id) { 2857 switch (fll_id) {
2916 case WM8962_FLL_MCLK: 2858 case WM8962_FLL_MCLK:
2917 case WM8962_FLL_BCLK: 2859 case WM8962_FLL_BCLK:
@@ -2950,12 +2892,10 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2950 2892
2951 try_wait_for_completion(&wm8962->fll_lock); 2893 try_wait_for_completion(&wm8962->fll_lock);
2952 2894
2953 if (sysclk)
2954 fll1 |= WM8962_FLL_ENA;
2955 2895
2956 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, 2896 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
2957 WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK | 2897 WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK |
2958 WM8962_FLL_ENA, fll1); 2898 WM8962_FLL_ENA, fll1 | WM8962_FLL_ENA);
2959 2899
2960 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); 2900 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
2961 2901