alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/9] Update FLL calculations on Arizona devices
@ 2014-03-07 16:34 Charles Keepax
  2014-03-07 16:34 ` [PATCH 1/9] ASoC: arizona: An OUTDIV of 1 is not valid, avoid this Charles Keepax
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: Charles Keepax @ 2014-03-07 16:34 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lee.jones, lgirdwood, sameo

Newer versions of the Arizona IP have several differences
in the FLL configuration. The reference and synchroniser
paths have slightly difference FRATIO encodings and the
expanded encoding on the reference path should be used to
avoid integer mode operation.

This series of patches does some refactoring on the FLL
configuration code, previously calculation of the FLL
configuration was done before we knew whether this would be
applied to reference or synchroniser path. These patches
add some checks to make sure the requested clock can be
accomodated and then does the calculations once we knew
where they will be applied. Additionally, we add support for
the encodings on the newer IP.

Thanks,
Charles

Charles Keepax (9):
  ASoC: arizona: An OUTDIV of 1 is not valid, avoid this
  ASoC: arizona: Add defines for FLL configuration constants
  ASoC: arizona: Move set of OUTDIV in to arizona_apply_fll
  ASoC: arizona: Move calculation of FLL configuration
  ASoC: arizona: Don't pass Fout into arizona_calc_fll
  ASoC: arizona: Calculate OUTDIV first
  ASoC: arizona: Calculate FLL gain last
  mfd: arizona: Add support for new fratio encoding
  ASoC: arizona: Support new fratio encoding on the wm5110 rev D

 include/linux/mfd/arizona/registers.h |    6 +-
 sound/soc/codecs/arizona.c            |  254 ++++++++++++++++++++++-----------
 2 files changed, 171 insertions(+), 89 deletions(-)

-- 
1.7.2.5

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/9] ASoC: arizona: An OUTDIV of 1 is not valid, avoid this
  2014-03-07 16:34 [PATCH 0/9] Update FLL calculations on Arizona devices Charles Keepax
@ 2014-03-07 16:34 ` Charles Keepax
  2014-03-07 16:34 ` [PATCH 2/9] ASoC: arizona: Add defines for FLL configuration constants Charles Keepax
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2014-03-07 16:34 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lee.jones, lgirdwood, sameo

One is not a valid value for the OUTDIV start searching at 2 instead.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/arizona.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index a32b84a..e4c1c9e 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -1415,7 +1415,7 @@ static int arizona_calc_fll(struct arizona_fll *fll,
 	Fref /= div;
 
 	/* Fvco should be over the targt; don't check the upper bound */
-	div = 1;
+	div = 2;
 	while (Fout * div < 90000000 * fll->vco_mult) {
 		div++;
 		if (div > 7) {
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/9] ASoC: arizona: Add defines for FLL configuration constants
  2014-03-07 16:34 [PATCH 0/9] Update FLL calculations on Arizona devices Charles Keepax
  2014-03-07 16:34 ` [PATCH 1/9] ASoC: arizona: An OUTDIV of 1 is not valid, avoid this Charles Keepax
@ 2014-03-07 16:34 ` Charles Keepax
  2014-03-07 16:34 ` [PATCH 3/9] ASoC: arizona: Move set of OUTDIV in to arizona_apply_fll Charles Keepax
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2014-03-07 16:34 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lee.jones, lgirdwood, sameo

Improve readability by adding defines for some of the constants
associated with FLL configuration.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/arizona.c |   16 +++++++++++-----
 1 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index e4c1c9e..e6f8290 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -53,6 +53,12 @@
 #define ARIZONA_AIF_RX_ENABLES                  0x1A
 #define ARIZONA_AIF_FORCE_WRITE                 0x1B
 
+#define ARIZONA_FLL_MAX_FREF   13500000
+#define ARIZONA_FLL_MIN_FVCO   90000000
+#define ARIZONA_FLL_MAX_REFDIV 8
+#define ARIZONA_FLL_MIN_OUTDIV 2
+#define ARIZONA_FLL_MAX_OUTDIV 7
+
 #define arizona_fll_err(_fll, fmt, ...) \
 	dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
 #define arizona_fll_warn(_fll, fmt, ...) \
@@ -1399,11 +1405,11 @@ static int arizona_calc_fll(struct arizona_fll *fll,
 	/* Fref must be <=13.5MHz */
 	div = 1;
 	cfg->refdiv = 0;
-	while ((Fref / div) > 13500000) {
+	while ((Fref / div) > ARIZONA_FLL_MAX_FREF) {
 		div *= 2;
 		cfg->refdiv++;
 
-		if (div > 8) {
+		if (div > ARIZONA_FLL_MAX_REFDIV) {
 			arizona_fll_err(fll,
 					"Can't scale %dMHz in to <=13.5MHz\n",
 					Fref);
@@ -1415,10 +1421,10 @@ static int arizona_calc_fll(struct arizona_fll *fll,
 	Fref /= div;
 
 	/* Fvco should be over the targt; don't check the upper bound */
-	div = 2;
-	while (Fout * div < 90000000 * fll->vco_mult) {
+	div = ARIZONA_FLL_MIN_OUTDIV;
+	while (Fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
 		div++;
-		if (div > 7) {
+		if (div > ARIZONA_FLL_MAX_OUTDIV) {
 			arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
 					Fout);
 			return -EINVAL;
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/9] ASoC: arizona: Move set of OUTDIV in to arizona_apply_fll
  2014-03-07 16:34 [PATCH 0/9] Update FLL calculations on Arizona devices Charles Keepax
  2014-03-07 16:34 ` [PATCH 1/9] ASoC: arizona: An OUTDIV of 1 is not valid, avoid this Charles Keepax
  2014-03-07 16:34 ` [PATCH 2/9] ASoC: arizona: Add defines for FLL configuration constants Charles Keepax
@ 2014-03-07 16:34 ` Charles Keepax
  2014-03-07 16:34 ` [PATCH 4/9] ASoC: arizona: Move calculation of FLL configuration Charles Keepax
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2014-03-07 16:34 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lee.jones, lgirdwood, sameo

Since we know in arizona_apply_fll if we are setting the sync or ref
path there is no need to set the outdiv seperately anymore. This patch
moves this from arizona_enable_fll to arizona_apply_fll.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/arizona.c |   28 ++++++++++++----------------
 1 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index e6f8290..6b53c3c 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -1511,14 +1511,18 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
 				 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
 				 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
 
-	if (sync)
-		regmap_update_bits_async(arizona->regmap, base + 0x7,
-					 ARIZONA_FLL1_GAIN_MASK,
-					 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
-	else
-		regmap_update_bits_async(arizona->regmap, base + 0x9,
-					 ARIZONA_FLL1_GAIN_MASK,
-					 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
+	if (sync) {
+		regmap_update_bits(arizona->regmap, base + 0x7,
+				   ARIZONA_FLL1_GAIN_MASK,
+				   cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
+	} else {
+		regmap_update_bits(arizona->regmap, base + 0x5,
+				   ARIZONA_FLL1_OUTDIV_MASK,
+				   cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
+		regmap_update_bits(arizona->regmap, base + 0x9,
+				   ARIZONA_FLL1_GAIN_MASK,
+				   cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
+	}
 
 	regmap_update_bits_async(arizona->regmap, base + 2,
 				 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
@@ -1555,10 +1559,6 @@ static void arizona_enable_fll(struct arizona_fll *fll,
 	 */
 	if (fll->ref_src >= 0 && fll->ref_freq &&
 	    fll->ref_src != fll->sync_src) {
-		regmap_update_bits_async(arizona->regmap, fll->base + 5,
-					 ARIZONA_FLL1_OUTDIV_MASK,
-					 ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
-
 		arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
 				  false);
 		if (fll->sync_src >= 0) {
@@ -1567,10 +1567,6 @@ static void arizona_enable_fll(struct arizona_fll *fll,
 			use_sync = true;
 		}
 	} else if (fll->sync_src >= 0) {
-		regmap_update_bits_async(arizona->regmap, fll->base + 5,
-					 ARIZONA_FLL1_OUTDIV_MASK,
-					 sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
-
 		arizona_apply_fll(arizona, fll->base, sync,
 				  fll->sync_src, false);
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/9] ASoC: arizona: Move calculation of FLL configuration
  2014-03-07 16:34 [PATCH 0/9] Update FLL calculations on Arizona devices Charles Keepax
                   ` (2 preceding siblings ...)
  2014-03-07 16:34 ` [PATCH 3/9] ASoC: arizona: Move set of OUTDIV in to arizona_apply_fll Charles Keepax
@ 2014-03-07 16:34 ` Charles Keepax
  2014-03-09  8:26   ` Mark Brown
  2014-03-07 16:34 ` [PATCH 5/9] ASoC: arizona: Don't pass Fout into arizona_calc_fll Charles Keepax
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Charles Keepax @ 2014-03-07 16:34 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lee.jones, lgirdwood, sameo

Currently the FLL configuration is calculated before it is known which
FLL path the configuration will be applied to. Newer versions of the IP
have differences in the configuration required for each FLL path, which
makes it complicated to calculate the FLL configuration in advance.

This patch simply checks the validity of a requested input and output
frequency before we know which FLL path they will be applied to and
saves the actual calculation of the configuration until we know where
the settings will be applied.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/arizona.c |   79 ++++++++++++++++++++++++-------------------
 1 files changed, 44 insertions(+), 35 deletions(-)

diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 6b53c3c..c9cae8e 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -1392,6 +1392,29 @@ struct arizona_fll_cfg {
 	int gain;
 };
 
+static int arizona_validate_fll(struct arizona_fll *fll,
+				unsigned int Fref,
+				unsigned int Fout)
+{
+	unsigned int Fvco_min;
+
+	if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
+		arizona_fll_err(fll,
+				"Can't scale %dMHz in to <=13.5MHz\n",
+				Fref);
+		return -EINVAL;
+	}
+
+	Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult;
+	if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) {
+		arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
+				Fout);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int arizona_calc_fll(struct arizona_fll *fll,
 			    struct arizona_fll_cfg *cfg,
 			    unsigned int Fref,
@@ -1409,12 +1432,8 @@ static int arizona_calc_fll(struct arizona_fll *fll,
 		div *= 2;
 		cfg->refdiv++;
 
-		if (div > ARIZONA_FLL_MAX_REFDIV) {
-			arizona_fll_err(fll,
-					"Can't scale %dMHz in to <=13.5MHz\n",
-					Fref);
+		if (div > ARIZONA_FLL_MAX_REFDIV)
 			return -EINVAL;
-		}
 	}
 
 	/* Apply the division for our remaining calculations */
@@ -1424,11 +1443,8 @@ static int arizona_calc_fll(struct arizona_fll *fll,
 	div = ARIZONA_FLL_MIN_OUTDIV;
 	while (Fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
 		div++;
-		if (div > ARIZONA_FLL_MAX_OUTDIV) {
-			arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
-					Fout);
+		if (div > ARIZONA_FLL_MAX_OUTDIV)
 			return -EINVAL;
-		}
 	}
 	target = Fout * div / fll->vco_mult;
 	cfg->outdiv = div;
@@ -1545,13 +1561,12 @@ static bool arizona_is_enabled_fll(struct arizona_fll *fll)
 	return reg & ARIZONA_FLL1_ENA;
 }
 
-static void arizona_enable_fll(struct arizona_fll *fll,
-			      struct arizona_fll_cfg *ref,
-			      struct arizona_fll_cfg *sync)
+static void arizona_enable_fll(struct arizona_fll *fll)
 {
 	struct arizona *arizona = fll->arizona;
 	int ret;
 	bool use_sync = false;
+	struct arizona_fll_cfg cfg;
 
 	/*
 	 * If we have both REFCLK and SYNCCLK then enable both,
@@ -1559,15 +1574,21 @@ static void arizona_enable_fll(struct arizona_fll *fll,
 	 */
 	if (fll->ref_src >= 0 && fll->ref_freq &&
 	    fll->ref_src != fll->sync_src) {
-		arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
+		arizona_calc_fll(fll, &cfg, fll->ref_freq, fll->fout);
+
+		arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
 				  false);
 		if (fll->sync_src >= 0) {
-			arizona_apply_fll(arizona, fll->base + 0x10, sync,
+			arizona_calc_fll(fll, &cfg, fll->sync_freq, fll->fout);
+
+			arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
 					  fll->sync_src, true);
 			use_sync = true;
 		}
 	} else if (fll->sync_src >= 0) {
-		arizona_apply_fll(arizona, fll->base, sync,
+		arizona_calc_fll(fll, &cfg, fll->sync_freq, fll->fout);
+
+		arizona_apply_fll(arizona, fll->base, &cfg,
 				  fll->sync_src, false);
 
 		regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
@@ -1629,32 +1650,22 @@ static void arizona_disable_fll(struct arizona_fll *fll)
 int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
 			   unsigned int Fref, unsigned int Fout)
 {
-	struct arizona_fll_cfg ref, sync;
 	int ret;
 
 	if (fll->ref_src == source && fll->ref_freq == Fref)
 		return 0;
 
-	if (fll->fout) {
-		if (Fref > 0) {
-			ret = arizona_calc_fll(fll, &ref, Fref, fll->fout);
-			if (ret != 0)
-				return ret;
-		}
-
-		if (fll->sync_src >= 0) {
-			ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
-					       fll->fout);
-			if (ret != 0)
-				return ret;
-		}
+	if (fll->fout && Fref > 0) {
+		ret = arizona_validate_fll(fll, Fref, fll->fout);
+		if (ret != 0)
+			return ret;
 	}
 
 	fll->ref_src = source;
 	fll->ref_freq = Fref;
 
 	if (fll->fout && Fref > 0) {
-		arizona_enable_fll(fll, &ref, &sync);
+		arizona_enable_fll(fll);
 	}
 
 	return 0;
@@ -1664,7 +1675,6 @@ EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
 int arizona_set_fll(struct arizona_fll *fll, int source,
 		    unsigned int Fref, unsigned int Fout)
 {
-	struct arizona_fll_cfg ref, sync;
 	int ret;
 
 	if (fll->sync_src == source &&
@@ -1673,13 +1683,12 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
 
 	if (Fout) {
 		if (fll->ref_src >= 0) {
-			ret = arizona_calc_fll(fll, &ref, fll->ref_freq,
-					       Fout);
+			ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
 			if (ret != 0)
 				return ret;
 		}
 
-		ret = arizona_calc_fll(fll, &sync, Fref, Fout);
+		ret = arizona_validate_fll(fll, Fref, Fout);
 		if (ret != 0)
 			return ret;
 	}
@@ -1689,7 +1698,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
 	fll->fout = Fout;
 
 	if (Fout) {
-		arizona_enable_fll(fll, &ref, &sync);
+		arizona_enable_fll(fll);
 	} else {
 		arizona_disable_fll(fll);
 	}
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 5/9] ASoC: arizona: Don't pass Fout into arizona_calc_fll
  2014-03-07 16:34 [PATCH 0/9] Update FLL calculations on Arizona devices Charles Keepax
                   ` (3 preceding siblings ...)
  2014-03-07 16:34 ` [PATCH 4/9] ASoC: arizona: Move calculation of FLL configuration Charles Keepax
@ 2014-03-07 16:34 ` Charles Keepax
  2014-03-07 16:34 ` [PATCH 6/9] ASoC: arizona: Calculate OUTDIV first Charles Keepax
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2014-03-07 16:34 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lee.jones, lgirdwood, sameo

As we now calculate the FLL configuration at a later stage in the
process the fout member of the FLL structure will contain the desired
Fout frequency so no need to pass this in seperately.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/arizona.c |   15 +++++++--------
 1 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index c9cae8e..e9488cd 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -1417,13 +1417,12 @@ static int arizona_validate_fll(struct arizona_fll *fll,
 
 static int arizona_calc_fll(struct arizona_fll *fll,
 			    struct arizona_fll_cfg *cfg,
-			    unsigned int Fref,
-			    unsigned int Fout)
+			    unsigned int Fref)
 {
 	unsigned int target, div, gcd_fll;
 	int i, ratio;
 
-	arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
+	arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
 
 	/* Fref must be <=13.5MHz */
 	div = 1;
@@ -1441,12 +1440,12 @@ static int arizona_calc_fll(struct arizona_fll *fll,
 
 	/* Fvco should be over the targt; don't check the upper bound */
 	div = ARIZONA_FLL_MIN_OUTDIV;
-	while (Fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
+	while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
 		div++;
 		if (div > ARIZONA_FLL_MAX_OUTDIV)
 			return -EINVAL;
 	}
-	target = Fout * div / fll->vco_mult;
+	target = fll->fout * div / fll->vco_mult;
 	cfg->outdiv = div;
 
 	arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
@@ -1574,19 +1573,19 @@ static void arizona_enable_fll(struct arizona_fll *fll)
 	 */
 	if (fll->ref_src >= 0 && fll->ref_freq &&
 	    fll->ref_src != fll->sync_src) {
-		arizona_calc_fll(fll, &cfg, fll->ref_freq, fll->fout);
+		arizona_calc_fll(fll, &cfg, fll->ref_freq);
 
 		arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
 				  false);
 		if (fll->sync_src >= 0) {
-			arizona_calc_fll(fll, &cfg, fll->sync_freq, fll->fout);
+			arizona_calc_fll(fll, &cfg, fll->sync_freq);
 
 			arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
 					  fll->sync_src, true);
 			use_sync = true;
 		}
 	} else if (fll->sync_src >= 0) {
-		arizona_calc_fll(fll, &cfg, fll->sync_freq, fll->fout);
+		arizona_calc_fll(fll, &cfg, fll->sync_freq);
 
 		arizona_apply_fll(arizona, fll->base, &cfg,
 				  fll->sync_src, false);
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 6/9] ASoC: arizona: Calculate OUTDIV first
  2014-03-07 16:34 [PATCH 0/9] Update FLL calculations on Arizona devices Charles Keepax
                   ` (4 preceding siblings ...)
  2014-03-07 16:34 ` [PATCH 5/9] ASoC: arizona: Don't pass Fout into arizona_calc_fll Charles Keepax
@ 2014-03-07 16:34 ` Charles Keepax
  2014-03-07 16:34 ` [PATCH 7/9] ASoC: arizona: Calculate FLL gain last Charles Keepax
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2014-03-07 16:34 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lee.jones, lgirdwood, sameo

OUTDIV will remain unchanged whilst the rest of the FLL configuration is
calculated so do this first.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/arizona.c |   24 ++++++++++++------------
 1 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index e9488cd..175e230 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -1424,6 +1424,18 @@ static int arizona_calc_fll(struct arizona_fll *fll,
 
 	arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
 
+	/* Fvco should be over the targt; don't check the upper bound */
+	div = ARIZONA_FLL_MIN_OUTDIV;
+	while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
+		div++;
+		if (div > ARIZONA_FLL_MAX_OUTDIV)
+			return -EINVAL;
+	}
+	target = fll->fout * div / fll->vco_mult;
+	cfg->outdiv = div;
+
+	arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
+
 	/* Fref must be <=13.5MHz */
 	div = 1;
 	cfg->refdiv = 0;
@@ -1438,18 +1450,6 @@ static int arizona_calc_fll(struct arizona_fll *fll,
 	/* Apply the division for our remaining calculations */
 	Fref /= div;
 
-	/* Fvco should be over the targt; don't check the upper bound */
-	div = ARIZONA_FLL_MIN_OUTDIV;
-	while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
-		div++;
-		if (div > ARIZONA_FLL_MAX_OUTDIV)
-			return -EINVAL;
-	}
-	target = fll->fout * div / fll->vco_mult;
-	cfg->outdiv = div;
-
-	arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
-
 	/* Find an appropraite FLL_FRATIO and factor it out of the target */
 	for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
 		if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 7/9] ASoC: arizona: Calculate FLL gain last
  2014-03-07 16:34 [PATCH 0/9] Update FLL calculations on Arizona devices Charles Keepax
                   ` (5 preceding siblings ...)
  2014-03-07 16:34 ` [PATCH 6/9] ASoC: arizona: Calculate OUTDIV first Charles Keepax
@ 2014-03-07 16:34 ` Charles Keepax
  2014-03-07 16:34 ` [PATCH 8/9] mfd: arizona: Add support for new fratio encoding Charles Keepax
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2014-03-07 16:34 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lee.jones, lgirdwood, sameo

No part of the FLL calculation depends on the value determined for the
gain but the gain does depend on other values. In preparation for future
updates this patch moves the gain to be the last thing calculated.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/arizona.c |   24 ++++++++++++------------
 1 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 175e230..24ea6ed 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -1464,18 +1464,6 @@ static int arizona_calc_fll(struct arizona_fll *fll,
 		return -EINVAL;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
-		if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
-			cfg->gain = fll_gains[i].gain;
-			break;
-		}
-	}
-	if (i == ARRAY_SIZE(fll_gains)) {
-		arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
-				Fref);
-		return -EINVAL;
-	}
-
 	cfg->n = target / (ratio * Fref);
 
 	if (target % (ratio * Fref)) {
@@ -1499,6 +1487,18 @@ static int arizona_calc_fll(struct arizona_fll *fll,
 		cfg->lambda >>= 1;
 	}
 
+	for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
+		if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
+			cfg->gain = fll_gains[i].gain;
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(fll_gains)) {
+		arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
+				Fref);
+		return -EINVAL;
+	}
+
 	arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
 			cfg->n, cfg->theta, cfg->lambda);
 	arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 8/9] mfd: arizona: Add support for new fratio encoding
  2014-03-07 16:34 [PATCH 0/9] Update FLL calculations on Arizona devices Charles Keepax
                   ` (6 preceding siblings ...)
  2014-03-07 16:34 ` [PATCH 7/9] ASoC: arizona: Calculate FLL gain last Charles Keepax
@ 2014-03-07 16:34 ` Charles Keepax
  2014-03-07 16:34 ` [PATCH 9/9] ASoC: arizona: Support new fratio encoding on the wm5110 rev D Charles Keepax
  2014-03-09  8:28 ` [PATCH 0/9] Update FLL calculations on Arizona devices Mark Brown
  9 siblings, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2014-03-07 16:34 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lee.jones, lgirdwood, sameo

Newer IP has an expanded encoding for the fratio bits. As the additional
used bits are unused on older IP simply expand the field to the new
size.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 include/linux/mfd/arizona/registers.h |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h
index fdf3aa3..3ddaa63 100644
--- a/include/linux/mfd/arizona/registers.h
+++ b/include/linux/mfd/arizona/registers.h
@@ -1702,9 +1702,9 @@
 /*
  * R373 (0x175) - FLL1 Control 5
  */
-#define ARIZONA_FLL1_FRATIO_MASK                 0x0700  /* FLL1_FRATIO - [10:8] */
-#define ARIZONA_FLL1_FRATIO_SHIFT                     8  /* FLL1_FRATIO - [10:8] */
-#define ARIZONA_FLL1_FRATIO_WIDTH                     3  /* FLL1_FRATIO - [10:8] */
+#define ARIZONA_FLL1_FRATIO_MASK                 0x0F00  /* FLL1_FRATIO - [11:8] */
+#define ARIZONA_FLL1_FRATIO_SHIFT                     8  /* FLL1_FRATIO - [11:8] */
+#define ARIZONA_FLL1_FRATIO_WIDTH                     4  /* FLL1_FRATIO - [11:8] */
 #define ARIZONA_FLL1_OUTDIV_MASK                 0x000E  /* FLL1_OUTDIV - [3:1] */
 #define ARIZONA_FLL1_OUTDIV_SHIFT                     1  /* FLL1_OUTDIV - [3:1] */
 #define ARIZONA_FLL1_OUTDIV_WIDTH                     3  /* FLL1_OUTDIV - [3:1] */
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 9/9] ASoC: arizona: Support new fratio encoding on the wm5110 rev D
  2014-03-07 16:34 [PATCH 0/9] Update FLL calculations on Arizona devices Charles Keepax
                   ` (7 preceding siblings ...)
  2014-03-07 16:34 ` [PATCH 8/9] mfd: arizona: Add support for new fratio encoding Charles Keepax
@ 2014-03-07 16:34 ` Charles Keepax
  2014-03-09  8:28 ` [PATCH 0/9] Update FLL calculations on Arizona devices Mark Brown
  9 siblings, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2014-03-07 16:34 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lee.jones, lgirdwood, sameo

The reference clock path on newer IP FLLs requires a different
configuration, and should avoid integer mode operation. This patch adds
support for both the new encoding and updates the calculation.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/arizona.c |  130 ++++++++++++++++++++++++++++++++++----------
 1 files changed, 101 insertions(+), 29 deletions(-)

diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 24ea6ed..29e198f 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -53,8 +53,10 @@
 #define ARIZONA_AIF_RX_ENABLES                  0x1A
 #define ARIZONA_AIF_FORCE_WRITE                 0x1B
 
+#define ARIZONA_FLL_VCO_CORNER 141900000
 #define ARIZONA_FLL_MAX_FREF   13500000
 #define ARIZONA_FLL_MIN_FVCO   90000000
+#define ARIZONA_FLL_MAX_FRATIO 16
 #define ARIZONA_FLL_MAX_REFDIV 8
 #define ARIZONA_FLL_MIN_OUTDIV 2
 #define ARIZONA_FLL_MAX_OUTDIV 7
@@ -1415,9 +1417,99 @@ static int arizona_validate_fll(struct arizona_fll *fll,
 	return 0;
 }
 
+static int arizona_find_fratio(unsigned int Fref, int *fratio)
+{
+	int i;
+
+	/* Find an appropriate FLL_FRATIO */
+	for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
+		if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
+			if (fratio)
+				*fratio = fll_fratios[i].fratio;
+			return fll_fratios[i].ratio;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int arizona_calc_fratio(struct arizona_fll *fll,
+			       struct arizona_fll_cfg *cfg,
+			       unsigned int target,
+			       unsigned int Fref, bool sync)
+{
+	int init_ratio, ratio;
+	int refdiv, div;
+
+	/* Fref must be <=13.5MHz, find initial refdiv */
+	div = 1;
+	cfg->refdiv = 0;
+	while (Fref > ARIZONA_FLL_MAX_FREF) {
+		div *= 2;
+		Fref /= 2;
+		cfg->refdiv++;
+
+		if (div > ARIZONA_FLL_MAX_REFDIV)
+			return -EINVAL;
+	}
+
+	/* Find an appropriate FLL_FRATIO */
+	init_ratio = arizona_find_fratio(Fref, &cfg->fratio);
+	if (init_ratio < 0) {
+		arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
+				Fref);
+		return init_ratio;
+	}
+
+	switch (fll->arizona->type) {
+	case WM5110:
+		if (fll->arizona->rev < 3 || sync)
+			return init_ratio;
+		break;
+	default:
+		return init_ratio;
+	}
+
+	cfg->fratio = init_ratio - 1;
+
+	/* Adjust FRATIO/refdiv to avoid integer mode if possible */
+	refdiv = cfg->refdiv;
+
+	while (div <= ARIZONA_FLL_MAX_REFDIV) {
+		for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO;
+		     ratio++) {
+			if (target % (ratio * Fref)) {
+				cfg->refdiv = refdiv;
+				cfg->fratio = ratio - 1;
+				return ratio;
+			}
+		}
+
+		for (ratio = init_ratio - 1; ratio >= 0; ratio--) {
+			if (ARIZONA_FLL_VCO_CORNER / (fll->vco_mult * ratio) <
+			    Fref)
+				break;
+
+			if (target % (ratio * Fref)) {
+				cfg->refdiv = refdiv;
+				cfg->fratio = ratio - 1;
+				return ratio;
+			}
+		}
+
+		div *= 2;
+		Fref /= 2;
+		refdiv++;
+		init_ratio = arizona_find_fratio(Fref, NULL);
+	}
+
+	arizona_fll_warn(fll, "Falling back to integer mode operation\n");
+	return cfg->fratio + 1;
+}
+
 static int arizona_calc_fll(struct arizona_fll *fll,
 			    struct arizona_fll_cfg *cfg,
-			    unsigned int Fref)
+			    unsigned int Fref, bool sync)
 {
 	unsigned int target, div, gcd_fll;
 	int i, ratio;
@@ -1436,33 +1528,13 @@ static int arizona_calc_fll(struct arizona_fll *fll,
 
 	arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
 
-	/* Fref must be <=13.5MHz */
-	div = 1;
-	cfg->refdiv = 0;
-	while ((Fref / div) > ARIZONA_FLL_MAX_FREF) {
-		div *= 2;
-		cfg->refdiv++;
-
-		if (div > ARIZONA_FLL_MAX_REFDIV)
-			return -EINVAL;
-	}
+	/* Find an appropriate FLL_FRATIO and refdiv */
+	ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync);
+	if (ratio < 0)
+		return ratio;
 
 	/* Apply the division for our remaining calculations */
-	Fref /= div;
-
-	/* Find an appropraite FLL_FRATIO and factor it out of the target */
-	for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
-		if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
-			cfg->fratio = fll_fratios[i].fratio;
-			ratio = fll_fratios[i].ratio;
-			break;
-		}
-	}
-	if (i == ARRAY_SIZE(fll_fratios)) {
-		arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
-				Fref);
-		return -EINVAL;
-	}
+	Fref = Fref / (1 << cfg->refdiv);
 
 	cfg->n = target / (ratio * Fref);
 
@@ -1573,19 +1645,19 @@ static void arizona_enable_fll(struct arizona_fll *fll)
 	 */
 	if (fll->ref_src >= 0 && fll->ref_freq &&
 	    fll->ref_src != fll->sync_src) {
-		arizona_calc_fll(fll, &cfg, fll->ref_freq);
+		arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
 
 		arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
 				  false);
 		if (fll->sync_src >= 0) {
-			arizona_calc_fll(fll, &cfg, fll->sync_freq);
+			arizona_calc_fll(fll, &cfg, fll->sync_freq, true);
 
 			arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
 					  fll->sync_src, true);
 			use_sync = true;
 		}
 	} else if (fll->sync_src >= 0) {
-		arizona_calc_fll(fll, &cfg, fll->sync_freq);
+		arizona_calc_fll(fll, &cfg, fll->sync_freq, false);
 
 		arizona_apply_fll(arizona, fll->base, &cfg,
 				  fll->sync_src, false);
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/9] ASoC: arizona: Move calculation of FLL configuration
  2014-03-07 16:34 ` [PATCH 4/9] ASoC: arizona: Move calculation of FLL configuration Charles Keepax
@ 2014-03-09  8:26   ` Mark Brown
  2014-03-10  9:11     ` Charles Keepax
  2014-03-10 13:27     ` Charles Keepax
  0 siblings, 2 replies; 14+ messages in thread
From: Mark Brown @ 2014-03-09  8:26 UTC (permalink / raw)
  To: Charles Keepax; +Cc: alsa-devel, patches, lee.jones, lgirdwood, sameo


[-- Attachment #1.1: Type: text/plain, Size: 871 bytes --]

On Fri, Mar 07, 2014 at 04:34:20PM +0000, Charles Keepax wrote:
> Currently the FLL configuration is calculated before it is known which
> FLL path the configuration will be applied to. Newer versions of the IP
> have differences in the configuration required for each FLL path, which
> makes it complicated to calculate the FLL configuration in advance.
> 
> This patch simply checks the validity of a requested input and output
> frequency before we know which FLL path they will be applied to and
> saves the actual calculation of the configuration until we know where
> the settings will be applied.

I'll apply this but are you sure that this validity check is actually
accurate?  For some of the devices there were input/output
configurations that couldn't be reached due to constraints in the system
even though both input and output were in range.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 0/9] Update FLL calculations on Arizona devices
  2014-03-07 16:34 [PATCH 0/9] Update FLL calculations on Arizona devices Charles Keepax
                   ` (8 preceding siblings ...)
  2014-03-07 16:34 ` [PATCH 9/9] ASoC: arizona: Support new fratio encoding on the wm5110 rev D Charles Keepax
@ 2014-03-09  8:28 ` Mark Brown
  9 siblings, 0 replies; 14+ messages in thread
From: Mark Brown @ 2014-03-09  8:28 UTC (permalink / raw)
  To: Charles Keepax; +Cc: alsa-devel, patches, lee.jones, lgirdwood, sameo


[-- Attachment #1.1: Type: text/plain, Size: 355 bytes --]

On Fri, Mar 07, 2014 at 04:34:16PM +0000, Charles Keepax wrote:
> Newer versions of the Arizona IP have several differences
> in the FLL configuration. The reference and synchroniser
> paths have slightly difference FRATIO encodings and the
> expanded encoding on the reference path should be used to
> avoid integer mode operation.

Applied all, thanks.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/9] ASoC: arizona: Move calculation of FLL configuration
  2014-03-09  8:26   ` Mark Brown
@ 2014-03-10  9:11     ` Charles Keepax
  2014-03-10 13:27     ` Charles Keepax
  1 sibling, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2014-03-10  9:11 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, patches, lee.jones, lgirdwood, sameo

On Sun, Mar 09, 2014 at 08:26:49AM +0000, Mark Brown wrote:
> On Fri, Mar 07, 2014 at 04:34:20PM +0000, Charles Keepax wrote:
> > Currently the FLL configuration is calculated before it is known which
> > FLL path the configuration will be applied to. Newer versions of the IP
> > have differences in the configuration required for each FLL path, which
> > makes it complicated to calculate the FLL configuration in advance.
> > 
> > This patch simply checks the validity of a requested input and output
> > frequency before we know which FLL path they will be applied to and
> > saves the actual calculation of the configuration until we know where
> > the settings will be applied.
> 
> I'll apply this but are you sure that this validity check is actually
> accurate?  For some of the devices there were input/output
> configurations that couldn't be reached due to constraints in the system
> even though both input and output were in range.

I will look over it again to make sure.

Thanks,
Charles

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/9] ASoC: arizona: Move calculation of FLL configuration
  2014-03-09  8:26   ` Mark Brown
  2014-03-10  9:11     ` Charles Keepax
@ 2014-03-10 13:27     ` Charles Keepax
  1 sibling, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2014-03-10 13:27 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, patches, lee.jones, lgirdwood, sameo

On Sun, Mar 09, 2014 at 08:26:49AM +0000, Mark Brown wrote:
> On Fri, Mar 07, 2014 at 04:34:20PM +0000, Charles Keepax wrote:
> > Currently the FLL configuration is calculated before it is known which
> > FLL path the configuration will be applied to. Newer versions of the IP
> > have differences in the configuration required for each FLL path, which
> > makes it complicated to calculate the FLL configuration in advance.
> > 
> > This patch simply checks the validity of a requested input and output
> > frequency before we know which FLL path they will be applied to and
> > saves the actual calculation of the configuration until we know where
> > the settings will be applied.
> 
> I'll apply this but are you sure that this validity check is actually
> accurate?  For some of the devices there were input/output
> configurations that couldn't be reached due to constraints in the system
> even though both input and output were in range.

Only thing I can find directly is sub 5kHz as an input clock
would be a problem  on some parts but that is unlikely to ever happen
in practice. Naturally there is the granularity of the multipliers
as well but the step on that appears small enough that I wouldn't
be overly concerned about the error, given there is ~46-bits
worth of options there.

Also the error checking matches what was there before the patch,
ie. anything that pass here would also have passed the old
implementation. So even if I am missing something it should be as
robust as the old solution.

Thanks,
Charles

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2014-03-10 13:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-07 16:34 [PATCH 0/9] Update FLL calculations on Arizona devices Charles Keepax
2014-03-07 16:34 ` [PATCH 1/9] ASoC: arizona: An OUTDIV of 1 is not valid, avoid this Charles Keepax
2014-03-07 16:34 ` [PATCH 2/9] ASoC: arizona: Add defines for FLL configuration constants Charles Keepax
2014-03-07 16:34 ` [PATCH 3/9] ASoC: arizona: Move set of OUTDIV in to arizona_apply_fll Charles Keepax
2014-03-07 16:34 ` [PATCH 4/9] ASoC: arizona: Move calculation of FLL configuration Charles Keepax
2014-03-09  8:26   ` Mark Brown
2014-03-10  9:11     ` Charles Keepax
2014-03-10 13:27     ` Charles Keepax
2014-03-07 16:34 ` [PATCH 5/9] ASoC: arizona: Don't pass Fout into arizona_calc_fll Charles Keepax
2014-03-07 16:34 ` [PATCH 6/9] ASoC: arizona: Calculate OUTDIV first Charles Keepax
2014-03-07 16:34 ` [PATCH 7/9] ASoC: arizona: Calculate FLL gain last Charles Keepax
2014-03-07 16:34 ` [PATCH 8/9] mfd: arizona: Add support for new fratio encoding Charles Keepax
2014-03-07 16:34 ` [PATCH 9/9] ASoC: arizona: Support new fratio encoding on the wm5110 rev D Charles Keepax
2014-03-09  8:28 ` [PATCH 0/9] Update FLL calculations on Arizona devices Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).