diff options
-rw-r--r-- | sound/soc/codecs/wm8804.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 40e5067e8246..b23c57ca7c26 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c | |||
@@ -390,36 +390,41 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id, | |||
390 | int source, unsigned int freq_in, | 390 | int source, unsigned int freq_in, |
391 | unsigned int freq_out) | 391 | unsigned int freq_out) |
392 | { | 392 | { |
393 | int ret; | ||
394 | struct snd_soc_codec *codec; | 393 | struct snd_soc_codec *codec; |
395 | struct pll_div pll_div = { 0 }; | ||
396 | 394 | ||
397 | codec = dai->codec; | 395 | codec = dai->codec; |
398 | if (freq_in && freq_out) { | 396 | if (!freq_in || !freq_out) { |
397 | /* disable the PLL */ | ||
398 | snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0); | ||
399 | return 0; | ||
400 | } else { | ||
401 | int ret; | ||
402 | struct pll_div pll_div; | ||
403 | |||
399 | ret = pll_factors(&pll_div, freq_out, freq_in); | 404 | ret = pll_factors(&pll_div, freq_out, freq_in); |
400 | if (ret) | 405 | if (ret) |
401 | return ret; | 406 | return ret; |
402 | } | ||
403 | 407 | ||
404 | /* power down the PLL before reprogramming it */ | 408 | /* power down the PLL before reprogramming it */ |
405 | snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0); | 409 | snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0); |
406 | 410 | ||
407 | if (!freq_in || !freq_out) | 411 | if (!freq_in || !freq_out) |
408 | return 0; | 412 | return 0; |
409 | 413 | ||
410 | /* set PLLN and PRESCALE */ | 414 | /* set PLLN and PRESCALE */ |
411 | snd_soc_update_bits(codec, WM8804_PLL4, 0xf | 0x10, | 415 | snd_soc_update_bits(codec, WM8804_PLL4, 0xf | 0x10, |
412 | pll_div.n | (pll_div.prescale << 4)); | 416 | pll_div.n | (pll_div.prescale << 4)); |
413 | /* set mclkdiv and freqmode */ | 417 | /* set mclkdiv and freqmode */ |
414 | snd_soc_update_bits(codec, WM8804_PLL5, 0x3 | 0x8, | 418 | snd_soc_update_bits(codec, WM8804_PLL5, 0x3 | 0x8, |
415 | pll_div.freqmode | (pll_div.mclkdiv << 3)); | 419 | pll_div.freqmode | (pll_div.mclkdiv << 3)); |
416 | /* set PLLK */ | 420 | /* set PLLK */ |
417 | snd_soc_write(codec, WM8804_PLL1, pll_div.k & 0xff); | 421 | snd_soc_write(codec, WM8804_PLL1, pll_div.k & 0xff); |
418 | snd_soc_write(codec, WM8804_PLL2, (pll_div.k >> 8) & 0xff); | 422 | snd_soc_write(codec, WM8804_PLL2, (pll_div.k >> 8) & 0xff); |
419 | snd_soc_write(codec, WM8804_PLL3, pll_div.k >> 16); | 423 | snd_soc_write(codec, WM8804_PLL3, pll_div.k >> 16); |
420 | 424 | ||
421 | /* power up the PLL */ | 425 | /* power up the PLL */ |
422 | snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1); | 426 | snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1); |
427 | } | ||
423 | 428 | ||
424 | return 0; | 429 | return 0; |
425 | } | 430 | } |