diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2017-04-18 20:45:52 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-04-19 12:32:46 -0400 |
commit | 25165f79adc76b812bfb4d8f2ab120aafb28d0e6 (patch) | |
tree | f3d49431586d035f8bb281feba0a20f013e7c9ea | |
parent | 9ca5e57d78446c8bd42adff3dcae693703f91d9c (diff) |
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>
-rw-r--r-- | sound/soc/sh/rcar/adg.c | 39 |
1 files 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 { | |||
43 | }; | 43 | }; |
44 | 44 | ||
45 | #define LRCLK_ASYNC (1 << 0) | 45 | #define LRCLK_ASYNC (1 << 0) |
46 | #define AUDIO_OUT_48 (1 << 1) | ||
46 | #define adg_mode_flags(adg) (adg->flags) | 47 | #define adg_mode_flags(adg) (adg->flags) |
47 | 48 | ||
48 | #define for_each_rsnd_clk(pos, adg, i) \ | 49 | #define for_each_rsnd_clk(pos, adg, i) \ |
@@ -364,7 +365,10 @@ found_clock: | |||
364 | 365 | ||
365 | rsnd_adg_set_ssi_clk(ssi_mod, data); | 366 | rsnd_adg_set_ssi_clk(ssi_mod, data); |
366 | 367 | ||
367 | if (!(adg_mode_flags(adg) & LRCLK_ASYNC)) { | 368 | if (adg_mode_flags(adg) & LRCLK_ASYNC) { |
369 | if (adg_mode_flags(adg) & AUDIO_OUT_48) | ||
370 | ckr = 0x80000000; | ||
371 | } else { | ||
368 | if (0 == (rate % 8000)) | 372 | if (0 == (rate % 8000)) |
369 | ckr = 0x80000000; | 373 | ckr = 0x80000000; |
370 | } | 374 | } |
@@ -427,11 +431,14 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, | |||
427 | struct clk *clk; | 431 | struct clk *clk; |
428 | struct device *dev = rsnd_priv_to_dev(priv); | 432 | struct device *dev = rsnd_priv_to_dev(priv); |
429 | struct device_node *np = dev->of_node; | 433 | struct device_node *np = dev->of_node; |
434 | struct property *prop; | ||
430 | u32 ckr, rbgx, rbga, rbgb; | 435 | u32 ckr, rbgx, rbga, rbgb; |
431 | u32 rate, req_rate = 0, div; | 436 | u32 rate, div; |
437 | #define REQ_SIZE 2 | ||
438 | u32 req_rate[REQ_SIZE] = {}; | ||
432 | uint32_t count = 0; | 439 | uint32_t count = 0; |
433 | unsigned long req_48kHz_rate, req_441kHz_rate; | 440 | unsigned long req_48kHz_rate, req_441kHz_rate; |
434 | int i; | 441 | int i, req_size; |
435 | const char *parent_clk_name = NULL; | 442 | const char *parent_clk_name = NULL; |
436 | static const char * const clkout_name[] = { | 443 | static const char * const clkout_name[] = { |
437 | [CLKOUT] = "audio_clkout", | 444 | [CLKOUT] = "audio_clkout", |
@@ -452,13 +459,18 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, | |||
452 | * ADG supports BRRA/BRRB output only | 459 | * ADG supports BRRA/BRRB output only |
453 | * this means all clkout0/1/2/3 will be same rate | 460 | * this means all clkout0/1/2/3 will be same rate |
454 | */ | 461 | */ |
455 | of_property_read_u32(np, "clock-frequency", &req_rate); | 462 | prop = of_find_property(np, "clock-frequency", NULL);; |
463 | req_size = prop->length / sizeof(u32); | ||
464 | |||
465 | of_property_read_u32_array(np, "clock-frequency", req_rate, req_size); | ||
456 | req_48kHz_rate = 0; | 466 | req_48kHz_rate = 0; |
457 | req_441kHz_rate = 0; | 467 | req_441kHz_rate = 0; |
458 | if (0 == (req_rate % 44100)) | 468 | for (i = 0; i < req_size; i++) { |
459 | req_441kHz_rate = req_rate; | 469 | if (0 == (req_rate[i] % 44100)) |
460 | if (0 == (req_rate % 48000)) | 470 | req_441kHz_rate = req_rate[i]; |
461 | req_48kHz_rate = req_rate; | 471 | if (0 == (req_rate[i] % 48000)) |
472 | req_48kHz_rate = req_rate[i]; | ||
473 | } | ||
462 | 474 | ||
463 | /* | 475 | /* |
464 | * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC | 476 | * 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, | |||
505 | rbgb = rbgx; | 517 | rbgb = rbgx; |
506 | adg->rbgb_rate_for_48khz = rate / div; | 518 | adg->rbgb_rate_for_48khz = rate / div; |
507 | ckr |= brg_table[i] << 16; | 519 | ckr |= brg_table[i] << 16; |
508 | if (req_48kHz_rate) { | 520 | if (req_48kHz_rate) |
509 | parent_clk_name = __clk_get_name(clk); | 521 | parent_clk_name = __clk_get_name(clk); |
510 | ckr |= 0x80000000; | ||
511 | } | ||
512 | } | 522 | } |
513 | } | 523 | } |
514 | } | 524 | } |
@@ -523,7 +533,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, | |||
523 | */ | 533 | */ |
524 | if (!count) { | 534 | if (!count) { |
525 | clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT], | 535 | clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT], |
526 | parent_clk_name, 0, req_rate); | 536 | parent_clk_name, 0, req_rate[0]); |
527 | if (!IS_ERR(clk)) { | 537 | if (!IS_ERR(clk)) { |
528 | adg->clkout[CLKOUT] = clk; | 538 | adg->clkout[CLKOUT] = clk; |
529 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 539 | 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, | |||
536 | for (i = 0; i < CLKOUTMAX; i++) { | 546 | for (i = 0; i < CLKOUTMAX; i++) { |
537 | clk = clk_register_fixed_rate(dev, clkout_name[i], | 547 | clk = clk_register_fixed_rate(dev, clkout_name[i], |
538 | parent_clk_name, 0, | 548 | parent_clk_name, 0, |
539 | req_rate); | 549 | req_rate[0]); |
540 | adg->clkout[i] = ERR_PTR(-ENOENT); | 550 | adg->clkout[i] = ERR_PTR(-ENOENT); |
541 | if (!IS_ERR(clk)) | 551 | if (!IS_ERR(clk)) |
542 | adg->clkout[i] = clk; | 552 | adg->clkout[i] = clk; |
@@ -551,6 +561,9 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, | |||
551 | adg->rbga = rbga; | 561 | adg->rbga = rbga; |
552 | adg->rbgb = rbgb; | 562 | adg->rbgb = rbgb; |
553 | 563 | ||
564 | if (req_rate[0] % 48000 == 0) | ||
565 | adg->flags = AUDIO_OUT_48; | ||
566 | |||
554 | for_each_rsnd_clkout(clk, adg, i) | 567 | for_each_rsnd_clkout(clk, adg, i) |
555 | dev_dbg(dev, "clkout %d : %p : %ld\n", i, clk, clk_get_rate(clk)); | 568 | dev_dbg(dev, "clkout %d : %p : %ld\n", i, clk, clk_get_rate(clk)); |
556 | dev_dbg(dev, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n", | 569 | dev_dbg(dev, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n", |