ASoC: arizona: Update handling for input change on an active FLL

Currently, the driver places no restrictions on changes that can be
applied to an active FLL. However, it is only possible to change the
input for an active FLL, to change the output the FLL should be stopped
and then recofigured. This patch disallows changes in output frequency
and adds some additional handling to ensure the output remains
consistent across an input transition.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 7c362cb..be3657a 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -1500,6 +1500,12 @@
 {
 	unsigned int Fvco_min;
 
+	if (fll->fout && Fout != fll->fout) {
+		arizona_fll_err(fll,
+				"Can't change output on active FLL\n");
+		return -EINVAL;
+	}
+
 	if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
 		arizona_fll_err(fll,
 				"Can't scale %dMHz in to <=13.5MHz\n",
@@ -1743,6 +1749,15 @@
 	if (already_enabled < 0)
 		return already_enabled;
 
+	if (already_enabled) {
+		/* Facilitate smooth refclk across the transition */
+		regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x7,
+					 ARIZONA_FLL1_GAIN_MASK, 0);
+		regmap_update_bits_async(fll->arizona->regmap, fll->base + 1,
+					 ARIZONA_FLL1_FREERUN,
+					 ARIZONA_FLL1_FREERUN);
+	}
+
 	/*
 	 * If we have both REFCLK and SYNCCLK then enable both,
 	 * otherwise apply the SYNCCLK settings to REFCLK.
@@ -1798,6 +1813,10 @@
 					 ARIZONA_FLL1_SYNC_ENA,
 					 ARIZONA_FLL1_SYNC_ENA);
 
+	if (already_enabled)
+		regmap_update_bits_async(arizona->regmap, fll->base + 1,
+					 ARIZONA_FLL1_FREERUN, 0);
+
 	ret = wait_for_completion_timeout(&fll->ok,
 					  msecs_to_jiffies(250));
 	if (ret == 0)