[alsa-devel] [PATCH] ASoC: rsnd: enable clock-frequency for both 44.1kHz/48kHz

Kuninori Morimoto kuninori.morimoto.gx at renesas.com
Wed Apr 19 02:45:52 CEST 2017


From: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>

Current clock-frequency allows only 1 clock, but ADG can
handle both 44.1kHz/48kHz base clocks. This patch enables these.

On Salvator-X board, AUDIO_CLKOUT which is generated by ADG
is connected to ak4613 MCKI, and it should be synchronized with
LRCK. Thus, we need both 44.1kHz/48kHz base clock-frequency.
Otherwise, either one sounds strange in high frequency sound.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
Tested-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx at renesas.com>
---
 sound/soc/sh/rcar/adg.c | 39 ++++++++++++++++++++++++++-------------
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 214a9ce..96fef91 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -43,6 +43,7 @@ struct rsnd_adg {
 };
 
 #define LRCLK_ASYNC	(1 << 0)
+#define AUDIO_OUT_48	(1 << 1)
 #define adg_mode_flags(adg)	(adg->flags)
 
 #define for_each_rsnd_clk(pos, adg, i)		\
@@ -364,7 +365,10 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
 
 	rsnd_adg_set_ssi_clk(ssi_mod, data);
 
-	if (!(adg_mode_flags(adg) & LRCLK_ASYNC)) {
+	if (adg_mode_flags(adg) & LRCLK_ASYNC) {
+		if (adg_mode_flags(adg) & AUDIO_OUT_48)
+			ckr = 0x80000000;
+	} else {
 		if (0 == (rate % 8000))
 			ckr = 0x80000000;
 	}
@@ -427,11 +431,14 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
 	struct clk *clk;
 	struct device *dev = rsnd_priv_to_dev(priv);
 	struct device_node *np = dev->of_node;
+	struct property *prop;
 	u32 ckr, rbgx, rbga, rbgb;
-	u32 rate, req_rate = 0, div;
+	u32 rate, div;
+#define REQ_SIZE 2
+	u32 req_rate[REQ_SIZE] = {};
 	uint32_t count = 0;
 	unsigned long req_48kHz_rate, req_441kHz_rate;
-	int i;
+	int i, req_size;
 	const char *parent_clk_name = NULL;
 	static const char * const clkout_name[] = {
 		[CLKOUT]  = "audio_clkout",
@@ -452,13 +459,18 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
 	 * ADG supports BRRA/BRRB output only
 	 * this means all clkout0/1/2/3 will be same rate
 	 */
-	of_property_read_u32(np, "clock-frequency", &req_rate);
+	prop = of_find_property(np, "clock-frequency", NULL);;
+	req_size = prop->length / sizeof(u32);
+
+	of_property_read_u32_array(np, "clock-frequency", req_rate, req_size);
 	req_48kHz_rate = 0;
 	req_441kHz_rate = 0;
-	if (0 == (req_rate % 44100))
-		req_441kHz_rate = req_rate;
-	if (0 == (req_rate % 48000))
-		req_48kHz_rate = req_rate;
+	for (i = 0; i < req_size; i++) {
+		if (0 == (req_rate[i] % 44100))
+			req_441kHz_rate = req_rate[i];
+		if (0 == (req_rate[i] % 48000))
+			req_48kHz_rate = req_rate[i];
+	}
 
 	/*
 	 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
@@ -505,10 +517,8 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
 				rbgb = rbgx;
 				adg->rbgb_rate_for_48khz = rate / div;
 				ckr |= brg_table[i] << 16;
-				if (req_48kHz_rate) {
+				if (req_48kHz_rate)
 					parent_clk_name = __clk_get_name(clk);
-					ckr |= 0x80000000;
-				}
 			}
 		}
 	}
@@ -523,7 +533,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
 	 */
 	if (!count) {
 		clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT],
-					      parent_clk_name, 0, req_rate);
+					      parent_clk_name, 0, req_rate[0]);
 		if (!IS_ERR(clk)) {
 			adg->clkout[CLKOUT] = clk;
 			of_clk_add_provider(np, of_clk_src_simple_get, clk);
@@ -536,7 +546,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
 		for (i = 0; i < CLKOUTMAX; i++) {
 			clk = clk_register_fixed_rate(dev, clkout_name[i],
 						      parent_clk_name, 0,
-						      req_rate);
+						      req_rate[0]);
 			adg->clkout[i] = ERR_PTR(-ENOENT);
 			if (!IS_ERR(clk))
 				adg->clkout[i] = clk;
@@ -551,6 +561,9 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
 	adg->rbga = rbga;
 	adg->rbgb = rbgb;
 
+	if (req_rate[0] % 48000 == 0)
+		adg->flags = AUDIO_OUT_48;
+
 	for_each_rsnd_clkout(clk, adg, i)
 		dev_dbg(dev, "clkout %d : %p : %ld\n", i, clk, clk_get_rate(clk));
 	dev_dbg(dev, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",
-- 
1.9.1



More information about the Alsa-devel mailing list