aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-09-30 14:31:38 +0100
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-09-30 15:45:25 +0100
commitc36b2fc73a6c0e7b185b17d594b38398ce1f7fff (patch)
tree7e547f591106bf5611c0772917fe127f78560a59 /sound
parent25cbf465207e9616e9b7d362ee166abf296d4c1e (diff)
ASoC: Clean up WM8974 PLL configuration
Don't use a static for WM8974 PLL factors - we don't support more than one device so it won't happen but no sense in leaving the race condition hanging around. Also, pre_div is a single bit and it's a bit simpler if we move the handling of the factor of 4 in the output into the coefficient setup. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/wm8974.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 5104c8aa34f..f30f86b3bda 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -330,36 +330,38 @@ static int wm8974_add_widgets(struct snd_soc_codec *codec)
}
struct pll_ {
- unsigned int pre_div:4; /* prescale - 1 */
+ unsigned int pre_div:1;
unsigned int n:4;
unsigned int k;
};
-static struct pll_ pll_div;
-
/* The size in bits of the pll divide multiplied by 10
* to allow rounding later */
#define FIXED_PLL_SIZE ((1 << 24) * 10)
-static void pll_factors(unsigned int target, unsigned int source)
+static void pll_factors(struct pll_ *pll_div,
+ unsigned int target, unsigned int source)
{
unsigned long long Kpart;
unsigned int K, Ndiv, Nmod;
+ /* There is a fixed divide by 4 in the output path */
+ target *= 4;
+
Ndiv = target / source;
if (Ndiv < 6) {
- source >>= 1;
- pll_div.pre_div = 1;
+ source /= 2;
+ pll_div->pre_div = 1;
Ndiv = target / source;
} else
- pll_div.pre_div = 0;
+ pll_div->pre_div = 0;
if ((Ndiv < 6) || (Ndiv > 12))
printk(KERN_WARNING
"WM8974 N value %u outwith recommended range!\n",
Ndiv);
- pll_div.n = Ndiv;
+ pll_div->n = Ndiv;
Nmod = target % source;
Kpart = FIXED_PLL_SIZE * (long long)Nmod;
@@ -374,13 +376,14 @@ static void pll_factors(unsigned int target, unsigned int source)
/* Move down to proper range now rounding is done */
K /= 10;
- pll_div.k = K;
+ pll_div->k = K;
}
static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai,
int pll_id, unsigned int freq_in, unsigned int freq_out)
{
struct snd_soc_codec *codec = codec_dai->codec;
+ struct pll_ pll_div;
u16 reg;
if (freq_in == 0 || freq_out == 0) {
@@ -394,7 +397,7 @@ static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai,
return 0;
}
- pll_factors(freq_out*4, freq_in);
+ pll_factors(&pll_div, freq_out, freq_in);
wm8974_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n);
wm8974_write(codec, WM8974_PLLK1, pll_div.k >> 18);