[alsa-devel] [PATCH] ASoC: rsnd: enable clock-frequency for both 44.1kHz/48kHz
From: Kuninori Morimoto kuninori.morimoto.gx@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@renesas.com Tested-by: Hiroyuki Yokoyama hiroyuki.yokoyama.vx@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",
The patch
ASoC: rsnd: enable clock-frequency for both 44.1kHz/48kHz
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 25165f79adc76b812bfb4d8f2ab120aafb28d0e6 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Date: Wed, 19 Apr 2017 00:45:52 +0000 Subject: [PATCH] ASoC: rsnd: enable clock-frequency for both 44.1kHz/48kHz
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@renesas.com Tested-by: Hiroyuki Yokoyama hiroyuki.yokoyama.vx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org --- 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 214a9ce90bb4..96fef91b480c 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",
participants (2)
-
Kuninori Morimoto
-
Mark Brown