diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-07-08 11:25:43 +0900 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-07-09 08:50:12 +0900 |
commit | 66b47fdb851924956b6e4696fb43a3496ae2c462 (patch) | |
tree | 6f15ecb7e2254dfe53339457adbd372dfee81621 /sound/soc/codecs/wm8994.c | |
parent | e88ff1e6db0ae6462e881d9f10776f7bdfd32e64 (diff) | |
download | op-kernel-dev-66b47fdb851924956b6e4696fb43a3496ae2c462.zip op-kernel-dev-66b47fdb851924956b6e4696fb43a3496ae2c462.tar.gz |
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>
Diffstat (limited to 'sound/soc/codecs/wm8994.c')
-rw-r--r-- | sound/soc/codecs/wm8994.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index ed8be9d..c41cf47 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 = static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { SND_SOC_DAPM_INPUT("DMIC1DAT"), SND_SOC_DAPM_INPUT("DMIC2DAT"), +SND_SOC_DAPM_INPUT("Clock"), SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, 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, return 0; } +static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 }; + static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_codec *codec = dai->codec; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + int i; switch (dai->id) { case 1: @@ -3008,6 +3012,25 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id); break; + case WM8994_SYSCLK_OPCLK: + /* Special case - a division (times 10) is given and + * no effect on main clocking. + */ + if (freq) { + for (i = 0; i < ARRAY_SIZE(opclk_divs); i++) + if (opclk_divs[i] == freq) + break; + if (i == ARRAY_SIZE(opclk_divs)) + return -EINVAL; + snd_soc_update_bits(codec, WM8994_CLOCKING_2, + WM8994_OPCLK_DIV_MASK, i); + snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2, + WM8994_OPCLK_ENA, WM8994_OPCLK_ENA); + } else { + snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2, + WM8994_OPCLK_ENA, 0); + } + default: return -EINVAL; } |