aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-09-30 09:31:38 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-09-30 10:45:25 -0400
commitc36b2fc73a6c0e7b185b17d594b38398ce1f7fff (patch)
tree7e547f591106bf5611c0772917fe127f78560a59 /sound/soc/codecs
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/soc/codecs')
-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 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
332struct pll_ { 332struct 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
338static 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
344static void pll_factors(unsigned int target, unsigned int source) 342static 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
380static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, 382static 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);