All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Baluta <daniel.baluta@nxp.com>
To: <alsa-devel@alsa-project.org>
Cc: <lgirdwood@gmail.com>, <broonie@kernel.org>, <perex@perex.cz>,
	<tiwai@suse.com>, <linux-kernel@vger.kernel.org>,
	<patches@opensource.wolfsonmicro.com>,
	<ckeepax@opensource.wolfsonmicro.com>, <shengjiu.wang@nxp.com>,
	<viorel.suman@nxp.com>, <mihai.serban@nxp.com>
Subject: [PATCH v2 1/2] ASoC: codec: wm9860: Refactor PLL out freq search
Date: Wed, 5 Apr 2017 16:26:37 +0300	[thread overview]
Message-ID: <1491398798-27829-2-git-send-email-daniel.baluta@nxp.com> (raw)
In-Reply-To: <1491398798-27829-1-git-send-email-daniel.baluta@nxp.com>

Add a separate function for deriving (sysclk, lrclk, bclk)
when the clock is auto or pll.

Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Acked-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/wm8960.c | 97 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 68 insertions(+), 29 deletions(-)

diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index ce159f1..1c973f0 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -672,10 +672,74 @@ int wm8960_configure_sysclk(struct wm8960_priv *wm8960, int mclk,
 	return *bclk_idx;
 }
 
+/**
+ * wm8960_configure_pll - checks if there is a PLL out frequency available
+ *	The PLL out frequency must be chosen such that:
+ *		- sysclk      = lrclk * dac_divs
+ *		- freq_out    = sysclk * sysclk_divs
+ *		- 10 * sysclk = bclk * bclk_divs
+ *
+ * @codec: codec structure
+ * @freq_in: input frequency used to derive freq out via PLL
+ * @sysclk_idx: sysclk_divs index for found sysclk
+ * @dac_idx: dac_divs index for found lrclk
+ * @bclk_idx: bclk_divs index for found bclk
+ *
+ * Returns:
+ *  -1, in case no PLL frequency out available was found
+ * >=0, in case we could derive bclk, lrclk, sysclk from PLL out using
+ *      (@sysclk_idx, @dac_idx, @bclk_idx) dividers
+ */
+static
+int wm8960_configure_pll(struct snd_soc_codec *codec, int freq_in,
+			 int *sysclk_idx, int *dac_idx, int *bclk_idx)
+{
+	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+	int sysclk, bclk, lrclk, freq_out;
+	int diff, best_freq_out = 0;
+	int i, j, k;
+
+	bclk = wm8960->bclk;
+	lrclk = wm8960->lrclk;
+
+	*bclk_idx = *dac_idx = *sysclk_idx = -1;
+
+	for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
+		if (sysclk_divs[i] == -1)
+			continue;
+		for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
+			sysclk = lrclk * dac_divs[j];
+			freq_out = sysclk * sysclk_divs[i];
+
+			for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) {
+				if (!is_pll_freq_available(freq_in, freq_out))
+					continue;
+
+				diff = sysclk - bclk * bclk_divs[k] / 10;
+				if (diff == 0) {
+					*sysclk_idx = i;
+					*dac_idx = j;
+					*bclk_idx = k;
+					best_freq_out = freq_out;
+					break;
+				}
+			}
+			if (k != ARRAY_SIZE(bclk_divs))
+				break;
+		}
+		if (j != ARRAY_SIZE(dac_divs))
+			break;
+	}
+
+	if (*bclk_idx != -1)
+		wm8960_set_pll(codec, freq_in, best_freq_out);
+
+	return *bclk_idx;
+}
 static int wm8960_configure_clocking(struct snd_soc_codec *codec)
 {
 	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-	int sysclk, bclk, lrclk, freq_out, freq_in;
+	int freq_out, freq_in;
 	u16 iface1 = snd_soc_read(codec, WM8960_IFACE1);
 	int i, j, k;
 	int ret;
@@ -692,8 +756,6 @@ static int wm8960_configure_clocking(struct snd_soc_codec *codec)
 	}
 
 	freq_in = wm8960->freq_in;
-	bclk = wm8960->bclk;
-	lrclk = wm8960->lrclk;
 	/*
 	 * If it's sysclk auto mode, check if the MCLK can provide sysclk or
 	 * not. If MCLK can provide sysclk, using MCLK to provide sysclk
@@ -720,33 +782,10 @@ static int wm8960_configure_clocking(struct snd_soc_codec *codec)
 			return -EINVAL;
 		}
 	}
-	/* get a available pll out frequency and set pll */
-	for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
-		if (sysclk_divs[i] == -1)
-			continue;
-		for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
-			sysclk = lrclk * dac_divs[j];
-			freq_out = sysclk * sysclk_divs[i];
-
-			for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) {
-				if (sysclk == bclk * bclk_divs[k] / 10 &&
-				    is_pll_freq_available(freq_in, freq_out)) {
-					wm8960_set_pll(codec,
-						       freq_in, freq_out);
-					break;
-				} else {
-					continue;
-				}
-			}
-			if (k != ARRAY_SIZE(bclk_divs))
-				break;
-		}
-		if (j != ARRAY_SIZE(dac_divs))
-			break;
-	}
 
-	if (i == ARRAY_SIZE(sysclk_divs)) {
-		dev_err(codec->dev, "failed to configure clock\n");
+	ret = wm8960_configure_pll(codec, freq_in, &i, &j, &k);
+	if (ret < 0) {
+		dev_err(codec->dev, "failed to configure clock via PLL\n");
 		return -EINVAL;
 	}
 
-- 
2.7.4

WARNING: multiple messages have this Message-ID (diff)
From: Daniel Baluta <daniel.baluta@nxp.com>
To: alsa-devel@alsa-project.org
Cc: lgirdwood@gmail.com, shengjiu.wang@nxp.com,
	patches@opensource.wolfsonmicro.com,
	linux-kernel@vger.kernel.org, tiwai@suse.com, broonie@kernel.org,
	viorel.suman@nxp.com, mihai.serban@nxp.com,
	ckeepax@opensource.wolfsonmicro.com
Subject: [PATCH v2 1/2] ASoC: codec: wm9860: Refactor PLL out freq search
Date: Wed, 5 Apr 2017 16:26:37 +0300	[thread overview]
Message-ID: <1491398798-27829-2-git-send-email-daniel.baluta@nxp.com> (raw)
In-Reply-To: <1491398798-27829-1-git-send-email-daniel.baluta@nxp.com>

Add a separate function for deriving (sysclk, lrclk, bclk)
when the clock is auto or pll.

Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Acked-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/wm8960.c | 97 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 68 insertions(+), 29 deletions(-)

diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index ce159f1..1c973f0 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -672,10 +672,74 @@ int wm8960_configure_sysclk(struct wm8960_priv *wm8960, int mclk,
 	return *bclk_idx;
 }
 
+/**
+ * wm8960_configure_pll - checks if there is a PLL out frequency available
+ *	The PLL out frequency must be chosen such that:
+ *		- sysclk      = lrclk * dac_divs
+ *		- freq_out    = sysclk * sysclk_divs
+ *		- 10 * sysclk = bclk * bclk_divs
+ *
+ * @codec: codec structure
+ * @freq_in: input frequency used to derive freq out via PLL
+ * @sysclk_idx: sysclk_divs index for found sysclk
+ * @dac_idx: dac_divs index for found lrclk
+ * @bclk_idx: bclk_divs index for found bclk
+ *
+ * Returns:
+ *  -1, in case no PLL frequency out available was found
+ * >=0, in case we could derive bclk, lrclk, sysclk from PLL out using
+ *      (@sysclk_idx, @dac_idx, @bclk_idx) dividers
+ */
+static
+int wm8960_configure_pll(struct snd_soc_codec *codec, int freq_in,
+			 int *sysclk_idx, int *dac_idx, int *bclk_idx)
+{
+	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+	int sysclk, bclk, lrclk, freq_out;
+	int diff, best_freq_out = 0;
+	int i, j, k;
+
+	bclk = wm8960->bclk;
+	lrclk = wm8960->lrclk;
+
+	*bclk_idx = *dac_idx = *sysclk_idx = -1;
+
+	for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
+		if (sysclk_divs[i] == -1)
+			continue;
+		for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
+			sysclk = lrclk * dac_divs[j];
+			freq_out = sysclk * sysclk_divs[i];
+
+			for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) {
+				if (!is_pll_freq_available(freq_in, freq_out))
+					continue;
+
+				diff = sysclk - bclk * bclk_divs[k] / 10;
+				if (diff == 0) {
+					*sysclk_idx = i;
+					*dac_idx = j;
+					*bclk_idx = k;
+					best_freq_out = freq_out;
+					break;
+				}
+			}
+			if (k != ARRAY_SIZE(bclk_divs))
+				break;
+		}
+		if (j != ARRAY_SIZE(dac_divs))
+			break;
+	}
+
+	if (*bclk_idx != -1)
+		wm8960_set_pll(codec, freq_in, best_freq_out);
+
+	return *bclk_idx;
+}
 static int wm8960_configure_clocking(struct snd_soc_codec *codec)
 {
 	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-	int sysclk, bclk, lrclk, freq_out, freq_in;
+	int freq_out, freq_in;
 	u16 iface1 = snd_soc_read(codec, WM8960_IFACE1);
 	int i, j, k;
 	int ret;
@@ -692,8 +756,6 @@ static int wm8960_configure_clocking(struct snd_soc_codec *codec)
 	}
 
 	freq_in = wm8960->freq_in;
-	bclk = wm8960->bclk;
-	lrclk = wm8960->lrclk;
 	/*
 	 * If it's sysclk auto mode, check if the MCLK can provide sysclk or
 	 * not. If MCLK can provide sysclk, using MCLK to provide sysclk
@@ -720,33 +782,10 @@ static int wm8960_configure_clocking(struct snd_soc_codec *codec)
 			return -EINVAL;
 		}
 	}
-	/* get a available pll out frequency and set pll */
-	for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
-		if (sysclk_divs[i] == -1)
-			continue;
-		for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
-			sysclk = lrclk * dac_divs[j];
-			freq_out = sysclk * sysclk_divs[i];
-
-			for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) {
-				if (sysclk == bclk * bclk_divs[k] / 10 &&
-				    is_pll_freq_available(freq_in, freq_out)) {
-					wm8960_set_pll(codec,
-						       freq_in, freq_out);
-					break;
-				} else {
-					continue;
-				}
-			}
-			if (k != ARRAY_SIZE(bclk_divs))
-				break;
-		}
-		if (j != ARRAY_SIZE(dac_divs))
-			break;
-	}
 
-	if (i == ARRAY_SIZE(sysclk_divs)) {
-		dev_err(codec->dev, "failed to configure clock\n");
+	ret = wm8960_configure_pll(codec, freq_in, &i, &j, &k);
+	if (ret < 0) {
+		dev_err(codec->dev, "failed to configure clock via PLL\n");
 		return -EINVAL;
 	}
 
-- 
2.7.4

  reply	other threads:[~2017-04-05 13:27 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-05 13:26 [PATCH v2 0/2] ASoC: codec: wm8960: Relax bit clock computation when using PLL Daniel Baluta
2017-04-05 13:26 ` Daniel Baluta
2017-04-05 13:26 ` Daniel Baluta [this message]
2017-04-05 13:26   ` [PATCH v2 1/2] ASoC: codec: wm9860: Refactor PLL out freq search Daniel Baluta
2017-04-05 13:26 ` [PATCH v2 2/2] ASoC: codec: wm8960: Relax bit clock computation when using PLL Daniel Baluta
2017-04-05 13:26   ` Daniel Baluta

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1491398798-27829-2-git-send-email-daniel.baluta@nxp.com \
    --to=daniel.baluta@nxp.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=ckeepax@opensource.wolfsonmicro.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mihai.serban@nxp.com \
    --cc=patches@opensource.wolfsonmicro.com \
    --cc=perex@perex.cz \
    --cc=shengjiu.wang@nxp.com \
    --cc=tiwai@suse.com \
    --cc=viorel.suman@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.