diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-07-07 22:25:43 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-07-08 19:50:12 -0400 |
commit | 66b47fdb851924956b6e4696fb43a3496ae2c462 (patch) | |
tree | 6f15ecb7e2254dfe53339457adbd372dfee81621 | |
parent | e88ff1e6db0ae6462e881d9f10776f7bdfd32e64 (diff) |
ASoC: Implement WM8994 OPCLK support
The WM8994 can output a clock derived from its internal SYSCLK, called
OPCLK. The rate can be selected as a sysclk, with a division from the
SYSCLK rate specified (multiplied by 10 since a division of 5.5 is
supported) and the clock can be disabled by specifying a divisor of
zero.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
-rw-r--r-- | sound/soc/codecs/wm8994.c | 23 | ||||
-rw-r--r-- | sound/soc/codecs/wm8994.h | 3 |
2 files changed, 26 insertions, 0 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index ed8be9db2b02..c41cf47f4009 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -2492,6 +2492,7 @@ static const struct snd_kcontrol_new aif3adc_mux = | |||
2492 | static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { | 2492 | static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { |
2493 | SND_SOC_DAPM_INPUT("DMIC1DAT"), | 2493 | SND_SOC_DAPM_INPUT("DMIC1DAT"), |
2494 | SND_SOC_DAPM_INPUT("DMIC2DAT"), | 2494 | SND_SOC_DAPM_INPUT("DMIC2DAT"), |
2495 | SND_SOC_DAPM_INPUT("Clock"), | ||
2495 | 2496 | ||
2496 | SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, | 2497 | SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, |
2497 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 2498 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
@@ -2966,11 +2967,14 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src, | |||
2966 | return 0; | 2967 | return 0; |
2967 | } | 2968 | } |
2968 | 2969 | ||
2970 | static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 }; | ||
2971 | |||
2969 | static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, | 2972 | static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, |
2970 | int clk_id, unsigned int freq, int dir) | 2973 | int clk_id, unsigned int freq, int dir) |
2971 | { | 2974 | { |
2972 | struct snd_soc_codec *codec = dai->codec; | 2975 | struct snd_soc_codec *codec = dai->codec; |
2973 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2976 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2977 | int i; | ||
2974 | 2978 | ||
2975 | switch (dai->id) { | 2979 | switch (dai->id) { |
2976 | case 1: | 2980 | case 1: |
@@ -3008,6 +3012,25 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, | |||
3008 | dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id); | 3012 | dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id); |
3009 | break; | 3013 | break; |
3010 | 3014 | ||
3015 | case WM8994_SYSCLK_OPCLK: | ||
3016 | /* Special case - a division (times 10) is given and | ||
3017 | * no effect on main clocking. | ||
3018 | */ | ||
3019 | if (freq) { | ||
3020 | for (i = 0; i < ARRAY_SIZE(opclk_divs); i++) | ||
3021 | if (opclk_divs[i] == freq) | ||
3022 | break; | ||
3023 | if (i == ARRAY_SIZE(opclk_divs)) | ||
3024 | return -EINVAL; | ||
3025 | snd_soc_update_bits(codec, WM8994_CLOCKING_2, | ||
3026 | WM8994_OPCLK_DIV_MASK, i); | ||
3027 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2, | ||
3028 | WM8994_OPCLK_ENA, WM8994_OPCLK_ENA); | ||
3029 | } else { | ||
3030 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2, | ||
3031 | WM8994_OPCLK_ENA, 0); | ||
3032 | } | ||
3033 | |||
3011 | default: | 3034 | default: |
3012 | return -EINVAL; | 3035 | return -EINVAL; |
3013 | } | 3036 | } |
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index 7072dc539354..2e0ca67a8df7 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h | |||
@@ -20,6 +20,9 @@ extern struct snd_soc_dai wm8994_dai[]; | |||
20 | #define WM8994_SYSCLK_FLL1 3 | 20 | #define WM8994_SYSCLK_FLL1 3 |
21 | #define WM8994_SYSCLK_FLL2 4 | 21 | #define WM8994_SYSCLK_FLL2 4 |
22 | 22 | ||
23 | /* OPCLK is also configured with set_dai_sysclk, specify division*10 as rate. */ | ||
24 | #define WM8994_SYSCLK_OPCLK 5 | ||
25 | |||
23 | #define WM8994_FLL1 1 | 26 | #define WM8994_FLL1 1 |
24 | #define WM8994_FLL2 2 | 27 | #define WM8994_FLL2 2 |
25 | 28 | ||