aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2015-09-10 03:03:48 -0400
committerMark Brown <broonie@kernel.org>2015-09-14 14:47:32 -0400
commiteae6fff4f15a9d1969412bb5aa5a3585f00821fb (patch)
treedc3f227eb9ae719ee7bb6cee4d58ac848199f58d
parent5c6901d98b35c3192336e419344f0f22f86b8845 (diff)
ASoC: rsnd: tidyup ADG clock calculate method
Current ADG clock calculation needs ADG and SSI settings. Thus, SSI side clock request function depends on ADG settings. After reconsideration, we can close this method inside ADG. This function uses new method. And it becomes preparation for AUDIO_CLKOUT support. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/sh/rcar/adg.c77
-rw-r--r--sound/soc/sh/rcar/ssi.c46
2 files changed, 74 insertions, 49 deletions
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 276703ba3e1f..a0b9aaa1af87 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -15,6 +15,8 @@
15#define CLKI 3 15#define CLKI 3
16#define CLKMAX 4 16#define CLKMAX 4
17 17
18#define BRRx_MASK(x) (0x3FF & x)
19
18static struct rsnd_mod_ops adg_ops = { 20static struct rsnd_mod_ops adg_ops = {
19 .name = "adg", 21 .name = "adg",
20}; 22};
@@ -23,8 +25,8 @@ struct rsnd_adg {
23 struct clk *clk[CLKMAX]; 25 struct clk *clk[CLKMAX];
24 struct rsnd_mod mod; 26 struct rsnd_mod mod;
25 27
26 int rbga_rate_for_441khz_div_6; /* RBGA */ 28 int rbga_rate_for_441khz; /* RBGA */
27 int rbgb_rate_for_48khz_div_6; /* RBGB */ 29 int rbgb_rate_for_48khz; /* RBGB */
28}; 30};
29 31
30#define for_each_rsnd_clk(pos, adg, i) \ 32#define for_each_rsnd_clk(pos, adg, i) \
@@ -34,6 +36,21 @@ struct rsnd_adg {
34 i++) 36 i++)
35#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg) 37#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
36 38
39static u32 rsnd_adg_calculate_rbgx(unsigned long div)
40{
41 int i, ratio;
42
43 if (!div)
44 return 0;
45
46 for (i = 3; i >= 0; i--) {
47 ratio = 2 << (i * 2);
48 if (0 == (div % ratio))
49 return (u32)((i << 8) | ((div / ratio) - 1));
50 }
51
52 return ~0;
53}
37 54
38static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io) 55static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
39{ 56{
@@ -146,8 +163,8 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *src_mod,
146 clk_get_rate(adg->clk[CLKA]), /* 0000: CLKA */ 163 clk_get_rate(adg->clk[CLKA]), /* 0000: CLKA */
147 clk_get_rate(adg->clk[CLKB]), /* 0001: CLKB */ 164 clk_get_rate(adg->clk[CLKB]), /* 0001: CLKB */
148 clk_get_rate(adg->clk[CLKC]), /* 0010: CLKC */ 165 clk_get_rate(adg->clk[CLKC]), /* 0010: CLKC */
149 adg->rbga_rate_for_441khz_div_6,/* 0011: RBGA */ 166 adg->rbga_rate_for_441khz, /* 0011: RBGA */
150 adg->rbgb_rate_for_48khz_div_6, /* 0100: RBGB */ 167 adg->rbgb_rate_for_48khz, /* 0100: RBGB */
151 }; 168 };
152 169
153 rsnd_mod_confirm_src(src_mod); 170 rsnd_mod_confirm_src(src_mod);
@@ -228,8 +245,8 @@ int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
228 clk_get_rate(adg->clk[CLKB]), /* 001: CLKB */ 245 clk_get_rate(adg->clk[CLKB]), /* 001: CLKB */
229 clk_get_rate(adg->clk[CLKC]), /* 010: CLKC */ 246 clk_get_rate(adg->clk[CLKC]), /* 010: CLKC */
230 0, /* 011: MLBCLK (not used) */ 247 0, /* 011: MLBCLK (not used) */
231 adg->rbga_rate_for_441khz_div_6,/* 100: RBGA */ 248 adg->rbga_rate_for_441khz, /* 100: RBGA */
232 adg->rbgb_rate_for_48khz_div_6, /* 101: RBGB */ 249 adg->rbgb_rate_for_48khz, /* 101: RBGB */
233 }; 250 };
234 251
235 /* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */ 252 /* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */
@@ -348,14 +365,14 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate)
348 } 365 }
349 366
350 /* 367 /*
351 * find 1/6 clock from BRGA/BRGB 368 * find divided clock from BRGA/BRGB
352 */ 369 */
353 if (rate == adg->rbga_rate_for_441khz_div_6) { 370 if (rate == adg->rbga_rate_for_441khz) {
354 data = 0x10; 371 data = 0x10;
355 goto found_clock; 372 goto found_clock;
356 } 373 }
357 374
358 if (rate == adg->rbgb_rate_for_48khz_div_6) { 375 if (rate == adg->rbgb_rate_for_48khz) {
359 data = 0x20; 376 data = 0x20;
360 goto found_clock; 377 goto found_clock;
361 } 378 }
@@ -380,8 +397,9 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
380{ 397{
381 struct clk *clk; 398 struct clk *clk;
382 struct rsnd_mod *adg_mod = rsnd_mod_get(adg); 399 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
383 unsigned long rate; 400 struct device *dev = rsnd_priv_to_dev(priv);
384 u32 ckr; 401 unsigned long rate, div;
402 u32 ckr, rbgx, rbga, rbgb;
385 int i; 403 int i;
386 int brg_table[] = { 404 int brg_table[] = {
387 [CLKA] = 0x0, 405 [CLKA] = 0x0,
@@ -395,15 +413,15 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
395 * have 44.1kHz or 48kHz base clocks for now. 413 * have 44.1kHz or 48kHz base clocks for now.
396 * 414 *
397 * SSI itself can divide parent clock by 1/1 - 1/16 415 * SSI itself can divide parent clock by 1/1 - 1/16
398 * So, BRGA outputs 44.1kHz base parent clock 1/32,
399 * and, BRGB outputs 48.0kHz base parent clock 1/32 here.
400 * see 416 * see
401 * rsnd_adg_ssi_clk_try_start() 417 * rsnd_adg_ssi_clk_try_start()
402 * rsnd_ssi_master_clk_start() 418 * rsnd_ssi_master_clk_start()
403 */ 419 */
404 ckr = 0; 420 ckr = 0;
405 adg->rbga_rate_for_441khz_div_6 = 0; 421 rbga = 2; /* default 1/6 */
406 adg->rbgb_rate_for_48khz_div_6 = 0; 422 rbgb = 2; /* default 1/6 */
423 adg->rbga_rate_for_441khz = 0;
424 adg->rbgb_rate_for_48khz = 0;
407 for_each_rsnd_clk(clk, adg, i) { 425 for_each_rsnd_clk(clk, adg, i) {
408 rate = clk_get_rate(clk); 426 rate = clk_get_rate(clk);
409 427
@@ -411,21 +429,34 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
411 continue; 429 continue;
412 430
413 /* RBGA */ 431 /* RBGA */
414 if (!adg->rbga_rate_for_441khz_div_6 && (0 == rate % 44100)) { 432 if (!adg->rbga_rate_for_441khz && (0 == rate % 44100)) {
415 adg->rbga_rate_for_441khz_div_6 = rate / 6; 433 div = 6;
416 ckr |= brg_table[i] << 20; 434 rbgx = rsnd_adg_calculate_rbgx(div);
435 if (BRRx_MASK(rbgx) == rbgx) {
436 rbga = rbgx;
437 adg->rbga_rate_for_441khz = rate / div;
438 ckr |= brg_table[i] << 20;
439 }
417 } 440 }
418 441
419 /* RBGB */ 442 /* RBGB */
420 if (!adg->rbgb_rate_for_48khz_div_6 && (0 == rate % 48000)) { 443 if (!adg->rbgb_rate_for_48khz && (0 == rate % 48000)) {
421 adg->rbgb_rate_for_48khz_div_6 = rate / 6; 444 div = 6;
422 ckr |= brg_table[i] << 16; 445 rbgx = rsnd_adg_calculate_rbgx(div);
446 if (BRRx_MASK(rbgx) == rbgx) {
447 rbgb = rbgx;
448 adg->rbgb_rate_for_48khz = rate / div;
449 ckr |= brg_table[i] << 16;
450 }
423 } 451 }
424 } 452 }
425 453
426 rsnd_mod_bset(adg_mod, SSICKR, 0x00FF0000, ckr); 454 rsnd_mod_bset(adg_mod, SSICKR, 0x00FF0000, ckr);
427 rsnd_mod_write(adg_mod, BRRA, 0x00000002); /* 1/6 */ 455 rsnd_mod_write(adg_mod, BRRA, rbga);
428 rsnd_mod_write(adg_mod, BRRB, 0x00000002); /* 1/6 */ 456 rsnd_mod_write(adg_mod, BRRB, rbgb);
457
458 dev_dbg(dev, "SSICKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",
459 ckr, rbga, rbgb);
429} 460}
430 461
431int rsnd_adg_probe(struct platform_device *pdev, 462int rsnd_adg_probe(struct platform_device *pdev,
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 91712e88405d..5e05f9422073 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -129,10 +129,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
129 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 129 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
130 struct device *dev = rsnd_priv_to_dev(priv); 130 struct device *dev = rsnd_priv_to_dev(priv);
131 struct rsnd_mod *mod = rsnd_mod_get(ssi); 131 struct rsnd_mod *mod = rsnd_mod_get(ssi);
132 int i, j, ret; 132 int j, ret;
133 int adg_clk_div_table[] = {
134 1, 6, /* see adg.c */
135 };
136 int ssi_clk_mul_table[] = { 133 int ssi_clk_mul_table[] = {
137 1, 2, 4, 8, 16, 6, 12, 134 1, 2, 4, 8, 16, 6, 12,
138 }; 135 };
@@ -142,28 +139,25 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
142 /* 139 /*
143 * Find best clock, and try to start ADG 140 * Find best clock, and try to start ADG
144 */ 141 */
145 for (i = 0; i < ARRAY_SIZE(adg_clk_div_table); i++) { 142 for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) {
146 for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) { 143
147 144 /*
148 /* 145 * this driver is assuming that
149 * this driver is assuming that 146 * system word is 64fs (= 2 x 32bit)
150 * system word is 64fs (= 2 x 32bit) 147 * see rsnd_ssi_init()
151 * see rsnd_ssi_init() 148 */
152 */ 149 main_rate = rate * 32 * 2 * ssi_clk_mul_table[j];
153 main_rate = rate / adg_clk_div_table[i] 150
154 * 32 * 2 * ssi_clk_mul_table[j]; 151 ret = rsnd_adg_ssi_clk_try_start(mod, main_rate);
155 152 if (0 == ret) {
156 ret = rsnd_adg_ssi_clk_try_start(mod, main_rate); 153 ssi->cr_clk = FORCE | SWL_32 |
157 if (0 == ret) { 154 SCKD | SWSD | CKDV(j);
158 ssi->cr_clk = FORCE | SWL_32 | 155
159 SCKD | SWSD | CKDV(j); 156 dev_dbg(dev, "%s[%d] outputs %u Hz\n",
160 157 rsnd_mod_name(mod),
161 dev_dbg(dev, "%s[%d] outputs %u Hz\n", 158 rsnd_mod_id(mod), rate);
162 rsnd_mod_name(mod), 159
163 rsnd_mod_id(mod), rate); 160 return 0;
164
165 return 0;
166 }
167 } 161 }
168 } 162 }
169 163