diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-09-30 10:48:38 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-09-30 10:48:38 -0400 |
commit | 4c0bccbe66ffe34f7bc88d29c345f9a7888656eb (patch) | |
tree | 9f1a76c0cabf40505f5c719fb1df615e6e28865a /sound/soc/codecs/wm8974.c | |
parent | 4fa9c1a5953441e06dbde7b6a655cbf6618e61dd (diff) | |
parent | c36b2fc73a6c0e7b185b17d594b38398ce1f7fff (diff) |
Merge branch 'upstream/wm8974' into for-2.6.33
Diffstat (limited to 'sound/soc/codecs/wm8974.c')
-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 93d66e30f109..eff29331235b 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c | |||
@@ -281,36 +281,38 @@ static int wm8974_add_widgets(struct snd_soc_codec *codec) | |||
281 | } | 281 | } |
282 | 282 | ||
283 | struct pll_ { | 283 | struct pll_ { |
284 | unsigned int pre_div:4; /* prescale - 1 */ | 284 | unsigned int pre_div:1; |
285 | unsigned int n:4; | 285 | unsigned int n:4; |
286 | unsigned int k; | 286 | unsigned int k; |
287 | }; | 287 | }; |
288 | 288 | ||
289 | static struct pll_ pll_div; | ||
290 | |||
291 | /* The size in bits of the pll divide multiplied by 10 | 289 | /* The size in bits of the pll divide multiplied by 10 |
292 | * to allow rounding later */ | 290 | * to allow rounding later */ |
293 | #define FIXED_PLL_SIZE ((1 << 24) * 10) | 291 | #define FIXED_PLL_SIZE ((1 << 24) * 10) |
294 | 292 | ||
295 | static void pll_factors(unsigned int target, unsigned int source) | 293 | static void pll_factors(struct pll_ *pll_div, |
294 | unsigned int target, unsigned int source) | ||
296 | { | 295 | { |
297 | unsigned long long Kpart; | 296 | unsigned long long Kpart; |
298 | unsigned int K, Ndiv, Nmod; | 297 | unsigned int K, Ndiv, Nmod; |
299 | 298 | ||
299 | /* There is a fixed divide by 4 in the output path */ | ||
300 | target *= 4; | ||
301 | |||
300 | Ndiv = target / source; | 302 | Ndiv = target / source; |
301 | if (Ndiv < 6) { | 303 | if (Ndiv < 6) { |
302 | source >>= 1; | 304 | source /= 2; |
303 | pll_div.pre_div = 1; | 305 | pll_div->pre_div = 1; |
304 | Ndiv = target / source; | 306 | Ndiv = target / source; |
305 | } else | 307 | } else |
306 | pll_div.pre_div = 0; | 308 | pll_div->pre_div = 0; |
307 | 309 | ||
308 | if ((Ndiv < 6) || (Ndiv > 12)) | 310 | if ((Ndiv < 6) || (Ndiv > 12)) |
309 | printk(KERN_WARNING | 311 | printk(KERN_WARNING |
310 | "WM8974 N value %u outwith recommended range!\n", | 312 | "WM8974 N value %u outwith recommended range!\n", |
311 | Ndiv); | 313 | Ndiv); |
312 | 314 | ||
313 | pll_div.n = Ndiv; | 315 | pll_div->n = Ndiv; |
314 | Nmod = target % source; | 316 | Nmod = target % source; |
315 | Kpart = FIXED_PLL_SIZE * (long long)Nmod; | 317 | Kpart = FIXED_PLL_SIZE * (long long)Nmod; |
316 | 318 | ||
@@ -325,13 +327,14 @@ static void pll_factors(unsigned int target, unsigned int source) | |||
325 | /* Move down to proper range now rounding is done */ | 327 | /* Move down to proper range now rounding is done */ |
326 | K /= 10; | 328 | K /= 10; |
327 | 329 | ||
328 | pll_div.k = K; | 330 | pll_div->k = K; |
329 | } | 331 | } |
330 | 332 | ||
331 | static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | 333 | static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, |
332 | int source, unsigned int freq_in, unsigned int freq_out) | 334 | int source, unsigned int freq_in, unsigned int freq_out) |
333 | { | 335 | { |
334 | struct snd_soc_codec *codec = codec_dai->codec; | 336 | struct snd_soc_codec *codec = codec_dai->codec; |
337 | struct pll_ pll_div; | ||
335 | u16 reg; | 338 | u16 reg; |
336 | 339 | ||
337 | if (freq_in == 0 || freq_out == 0) { | 340 | if (freq_in == 0 || freq_out == 0) { |
@@ -345,7 +348,7 @@ static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
345 | return 0; | 348 | return 0; |
346 | } | 349 | } |
347 | 350 | ||
348 | pll_factors(freq_out*4, freq_in); | 351 | pll_factors(&pll_div, freq_out, freq_in); |
349 | 352 | ||
350 | snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n); | 353 | snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n); |
351 | snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18); | 354 | snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18); |