summaryrefslogtreecommitdiff
path: root/sound/soc/sh/rcar
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2023-08-22 23:50:31 +0000
committerMark Brown <broonie@kernel.org>2023-08-23 13:53:25 +0100
commitbd4cee2fdf69b56c2bf3e7ec7c2e12b81e08005c (patch)
treef3a615081f7469358aacceded2239700efa01caf /sound/soc/sh/rcar
parent220adc0fda6bbc274fff5825e2fd7d3dcd719e5c (diff)
ASoC: rsnd: enable clk_i approximate rate usage
Basically Renesas sound ADG is assuming that it has accurately divisible input clock. But sometimes / some board might not have it. The clk_i from CPG is used for such case. It can't calculate accurate division, but can be used as approximate rate. This patch enable clk_i for such case. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Acked-by: Adnan Ali <adnan.ali@bp.renesas.com> Tested-by: Vincenzo De Michele <vincenzo.michele@davinci.de> Tested-by: Patrick Keil <patrick.keil@conti-engineering.com> Link: https://lore.kernel.org/r/87msyizlfd.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sh/rcar')
-rw-r--r--sound/soc/sh/rcar/adg.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 0b8926600d90..c490d43aa18c 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -491,6 +491,7 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
unsigned long req_Hz[ADG_HZ_SIZE];
int clkout_size;
int i, req_size;
+ int approximate = 0;
const char *parent_clk_name = NULL;
const char * const *clkout_name;
int brg_table[] = {
@@ -537,6 +538,26 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
* rsnd_adg_ssi_clk_try_start()
* rsnd_ssi_master_clk_start()
*/
+
+ /*
+ * [APPROXIMATE]
+ *
+ * clk_i (internal clock) can't create accurate rate, it will be approximate rate.
+ *
+ * <Note>
+ *
+ * clk_i needs x2 of required maximum rate.
+ * see
+ * - Minimum division of BRRA/BRRB
+ * - rsnd_ssi_clk_query()
+ *
+ * Sample Settings for TDM 8ch, 32bit width
+ *
+ * 8(ch) x 32(bit) x 44100(Hz) x 2<Note> = 22579200
+ * 8(ch) x 32(bit) x 48000(Hz) x 2<Note> = 24576000
+ *
+ * clock-frequency = <22579200 24576000>;
+ */
for_each_rsnd_clkin(clk, adg, i) {
rate = clk_get_rate(clk);
@@ -544,6 +565,10 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
continue;
/* BRGA */
+
+ if (i == CLKI)
+ /* see [APPROXIMATE] */
+ rate = (clk_get_rate(clk) / req_Hz[ADG_HZ_441]) * req_Hz[ADG_HZ_441];
if (!adg->brg_rate[ADG_HZ_441] && (0 == rate % 44100)) {
div = 6;
if (req_Hz[ADG_HZ_441])
@@ -555,10 +580,16 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
ckr |= brg_table[i] << 20;
if (req_Hz[ADG_HZ_441])
parent_clk_name = __clk_get_name(clk);
+ if (i == CLKI)
+ approximate = 1;
}
}
/* BRGB */
+
+ if (i == CLKI)
+ /* see [APPROXIMATE] */
+ rate = (clk_get_rate(clk) / req_Hz[ADG_HZ_48]) * req_Hz[ADG_HZ_48];
if (!adg->brg_rate[ADG_HZ_48] && (0 == rate % 48000)) {
div = 6;
if (req_Hz[ADG_HZ_48])
@@ -570,10 +601,15 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
ckr |= brg_table[i] << 16;
if (req_Hz[ADG_HZ_48])
parent_clk_name = __clk_get_name(clk);
+ if (i == CLKI)
+ approximate = 1;
}
}
}
+ if (approximate)
+ dev_info(dev, "It uses CLK_I as approximate rate");
+
clkout_name = clkout_name_gen2;
clkout_size = ARRAY_SIZE(clkout_name_gen2);
if (rsnd_is_gen4(priv))