diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-09-30 09:31:38 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-09-30 10:45:25 -0400 |
commit | c36b2fc73a6c0e7b185b17d594b38398ce1f7fff (patch) | |
tree | 7e547f591106bf5611c0772917fe127f78560a59 /sound/soc/codecs | |
parent | 25cbf465207e9616e9b7d362ee166abf296d4c1e (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/soc/codecs')
-rw-r--r-- | sound/soc/codecs/wm8974.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 5104c8aa34f6..f30f86b3bda0 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) | |||
330 | } | 330 | } |
331 | 331 | ||
332 | struct pll_ { | 332 | struct pll_ { |
333 | unsigned int pre_div:4; /* prescale - 1 */ | 333 | unsigned int pre_div:1; |
334 | unsigned int n:4; | 334 | unsigned int n:4; |
335 | unsigned int k; | 335 | unsigned int k; |
336 | }; | 336 | }; |
337 | 337 | ||
338 | static struct pll_ pll_div; | ||
339 | |||
340 | /* The size in bits of the pll divide multiplied by 10 | 338 | /* The size in bits of the pll divide multiplied by 10 |
341 | * to allow rounding later */ | 339 | * to allow rounding later */ |
342 | #define FIXED_PLL_SIZE ((1 << 24) * 10) | 340 | #define FIXED_PLL_SIZE ((1 << 24) * 10) |
343 | 341 | ||
344 | static void pll_factors(unsigned int target, unsigned int source) | 342 | static void pll_factors(struct pll_ *pll_div, |
343 | unsigned int target, unsigned int source) | ||
345 | { | 344 | { |
346 | unsigned long long Kpart; | 345 | unsigned long long Kpart; |
347 | unsigned int K, Ndiv, Nmod; | 346 | unsigned int K, Ndiv, Nmod; |
348 | 347 | ||
348 | /* There is a fixed divide by 4 in the output path */ | ||
349 | target *= 4; | ||
350 | |||
349 | Ndiv = target / source; | 351 | Ndiv = target / source; |
350 | if (Ndiv < 6) { | 352 | if (Ndiv < 6) { |
351 | source >>= 1; | 353 | source /= 2; |
352 | pll_div.pre_div = 1; | 354 | pll_div->pre_div = 1; |
353 | Ndiv = target / source; | 355 | Ndiv = target / source; |
354 | } else | 356 | } else |
355 | pll_div.pre_div = 0; | 357 | pll_div->pre_div = 0; |
356 | 358 | ||
357 | if ((Ndiv < 6) || (Ndiv > 12)) | 359 | if ((Ndiv < 6) || (Ndiv > 12)) |
358 | printk(KERN_WARNING | 360 | printk(KERN_WARNING |
359 | "WM8974 N value %u outwith recommended range!\n", | 361 | "WM8974 N value %u outwith recommended range!\n", |
360 | Ndiv); | 362 | Ndiv); |
361 | 363 | ||
362 | pll_div.n = Ndiv; | 364 | pll_div->n = Ndiv; |
363 | Nmod = target % source; | 365 | Nmod = target % source; |
364 | Kpart = FIXED_PLL_SIZE * (long long)Nmod; | 366 | Kpart = FIXED_PLL_SIZE * (long long)Nmod; |
365 | 367 | ||
@@ -374,13 +376,14 @@ static void pll_factors(unsigned int target, unsigned int source) | |||
374 | /* Move down to proper range now rounding is done */ | 376 | /* Move down to proper range now rounding is done */ |
375 | K /= 10; | 377 | K /= 10; |
376 | 378 | ||
377 | pll_div.k = K; | 379 | pll_div->k = K; |
378 | } | 380 | } |
379 | 381 | ||
380 | static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, | 382 | static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, |
381 | int pll_id, unsigned int freq_in, unsigned int freq_out) | 383 | int pll_id, unsigned int freq_in, unsigned int freq_out) |
382 | { | 384 | { |
383 | struct snd_soc_codec *codec = codec_dai->codec; | 385 | struct snd_soc_codec *codec = codec_dai->codec; |
386 | struct pll_ pll_div; | ||
384 | u16 reg; | 387 | u16 reg; |
385 | 388 | ||
386 | if (freq_in == 0 || freq_out == 0) { | 389 | if (freq_in == 0 || freq_out == 0) { |
@@ -394,7 +397,7 @@ static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, | |||
394 | return 0; | 397 | return 0; |
395 | } | 398 | } |
396 | 399 | ||
397 | pll_factors(freq_out*4, freq_in); | 400 | pll_factors(&pll_div, freq_out, freq_in); |
398 | 401 | ||
399 | wm8974_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n); | 402 | wm8974_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n); |
400 | wm8974_write(codec, WM8974_PLLK1, pll_div.k >> 18); | 403 | wm8974_write(codec, WM8974_PLLK1, pll_div.k >> 18); |