diff options
author | Daniel Baluta <daniel.baluta@nxp.com> | 2017-03-21 11:03:24 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-03-24 14:53:04 -0400 |
commit | 3ddc97211cbb61a5f59882c26f8e3158c86e34bb (patch) | |
tree | 8466a8ffcbddff2d0e79f3c2f392846c315fe3be | |
parent | a5de5b74a50113564a1e0850e2da96c37c35e55d (diff) |
ASoC: codec: wm8960: Refactor sysclk freq search
Add a separate function for finding (sysclk, lrclk, bclk)
when the clock is auto or mclk. This makes code easier to
read and reduces the indentation level in wm8960_configure_clocking.
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Acked-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/codecs/wm8960.c | 80 |
1 files changed, 61 insertions, 19 deletions
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 3bf081a7e450..25a4a11929fe 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
@@ -604,12 +604,71 @@ static const int bclk_divs[] = { | |||
604 | 120, 160, 220, 240, 320, 320, 320 | 604 | 120, 160, 220, 240, 320, 320, 320 |
605 | }; | 605 | }; |
606 | 606 | ||
607 | /** | ||
608 | * wm8960_configure_sysclk - checks if there is a sysclk frequency available | ||
609 | * The sysclk must be chosen such that: | ||
610 | * - sysclk = MCLK / sysclk_divs | ||
611 | * - lrclk = sysclk / dac_divs | ||
612 | * - 10 * bclk = sysclk / bclk_divs | ||
613 | * | ||
614 | * @wm8960_priv: wm8960 codec private data | ||
615 | * @mclk: MCLK used to derive sysclk | ||
616 | * @sysclk_idx: sysclk_divs index for found sysclk | ||
617 | * @dac_idx: dac_divs index for found lrclk | ||
618 | * @bclk_idx: bclk_divs index for found bclk | ||
619 | * | ||
620 | * Returns: | ||
621 | * -1, in case no sysclk frequency available found | ||
622 | * 0, in case an exact (@sysclk_idx, @dac_idx, @bclk_idx) match is found | ||
623 | */ | ||
624 | static | ||
625 | int wm8960_configure_sysclk(struct wm8960_priv *wm8960, int mclk, | ||
626 | int *sysclk_idx, int *dac_idx, int *bclk_idx) | ||
627 | { | ||
628 | int sysclk, bclk, lrclk; | ||
629 | int i, j, k; | ||
630 | int diff; | ||
631 | |||
632 | bclk = wm8960->bclk; | ||
633 | lrclk = wm8960->lrclk; | ||
634 | |||
635 | /* check if the sysclk frequency is available. */ | ||
636 | for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) { | ||
637 | if (sysclk_divs[i] == -1) | ||
638 | continue; | ||
639 | sysclk = mclk / sysclk_divs[i]; | ||
640 | for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) { | ||
641 | if (sysclk != dac_divs[j] * lrclk) | ||
642 | continue; | ||
643 | for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) { | ||
644 | diff = sysclk - bclk * bclk_divs[k] / 10; | ||
645 | if (diff == 0) { | ||
646 | *sysclk_idx = i; | ||
647 | *dac_idx = j; | ||
648 | *bclk_idx = k; | ||
649 | break; | ||
650 | } | ||
651 | } | ||
652 | if (k != ARRAY_SIZE(bclk_divs)) | ||
653 | break; | ||
654 | } | ||
655 | if (j != ARRAY_SIZE(dac_divs)) | ||
656 | break; | ||
657 | } | ||
658 | |||
659 | if (i != ARRAY_SIZE(sysclk_divs)) | ||
660 | return 0; | ||
661 | |||
662 | return -1; | ||
663 | } | ||
664 | |||
607 | static int wm8960_configure_clocking(struct snd_soc_codec *codec) | 665 | static int wm8960_configure_clocking(struct snd_soc_codec *codec) |
608 | { | 666 | { |
609 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); | 667 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); |
610 | int sysclk, bclk, lrclk, freq_out, freq_in; | 668 | int sysclk, bclk, lrclk, freq_out, freq_in; |
611 | u16 iface1 = snd_soc_read(codec, WM8960_IFACE1); | 669 | u16 iface1 = snd_soc_read(codec, WM8960_IFACE1); |
612 | int i, j, k; | 670 | int i, j, k; |
671 | int ret; | ||
613 | 672 | ||
614 | if (!(iface1 & (1<<6))) { | 673 | if (!(iface1 & (1<<6))) { |
615 | dev_dbg(codec->dev, | 674 | dev_dbg(codec->dev, |
@@ -643,25 +702,8 @@ static int wm8960_configure_clocking(struct snd_soc_codec *codec) | |||
643 | } | 702 | } |
644 | 703 | ||
645 | if (wm8960->clk_id != WM8960_SYSCLK_PLL) { | 704 | if (wm8960->clk_id != WM8960_SYSCLK_PLL) { |
646 | /* check if the sysclk frequency is available. */ | 705 | ret = wm8960_configure_sysclk(wm8960, freq_out, &i, &j, &k); |
647 | for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) { | 706 | if (ret == 0) { |
648 | if (sysclk_divs[i] == -1) | ||
649 | continue; | ||
650 | sysclk = freq_out / sysclk_divs[i]; | ||
651 | for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) { | ||
652 | if (sysclk != dac_divs[j] * lrclk) | ||
653 | continue; | ||
654 | for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) | ||
655 | if (sysclk == bclk * bclk_divs[k] / 10) | ||
656 | break; | ||
657 | if (k != ARRAY_SIZE(bclk_divs)) | ||
658 | break; | ||
659 | } | ||
660 | if (j != ARRAY_SIZE(dac_divs)) | ||
661 | break; | ||
662 | } | ||
663 | |||
664 | if (i != ARRAY_SIZE(sysclk_divs)) { | ||
665 | goto configure_clock; | 707 | goto configure_clock; |
666 | } else if (wm8960->clk_id != WM8960_SYSCLK_AUTO) { | 708 | } else if (wm8960->clk_id != WM8960_SYSCLK_AUTO) { |
667 | dev_err(codec->dev, "failed to configure clock\n"); | 709 | dev_err(codec->dev, "failed to configure clock\n"); |