Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: rsnd: add AUDIO_CLKOUT support

Renesas sound has AUDIO_CLKOUT (in Gen1/Gen2) AUDIO_CLKOUT1/2/3 (in Gen3)
This patch support these patches as clock provider.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Kuninori Morimoto and committed by
Mark Brown
2a46db4a 248e88c2

+97 -4
+3
Documentation/devicetree/bindings/sound/renesas,rsnd.txt
··· 34 34 see below for detail. 35 35 - #sound-dai-cells : it must be 0 if your system is using single DAI 36 36 it must be 1 if your system is using multi DAI 37 + - #clock-cells : it must be 0 if your system has audio_clkout 38 + it must be 1 if your system has audio_clkout0/1/2/3 39 + - clock-frequency : for all audio_clkout0/1/2/3 37 40 38 41 SSI subnode properties: 39 42 - interrupts : Should contain SSI interrupt for PIO transfer
+94 -4
sound/soc/sh/rcar/adg.c
··· 7 7 * License. See the file "COPYING" in the main directory of this archive 8 8 * for more details. 9 9 */ 10 + #include <linux/clk-provider.h> 10 11 #include "rsnd.h" 11 12 12 13 #define CLKA 0 ··· 15 14 #define CLKC 2 16 15 #define CLKI 3 17 16 #define CLKMAX 4 17 + 18 + #define CLKOUT 0 19 + #define CLKOUT1 1 20 + #define CLKOUT2 2 21 + #define CLKOUT3 3 22 + #define CLKOUTMAX 4 18 23 19 24 #define BRRx_MASK(x) (0x3FF & x) 20 25 ··· 30 23 31 24 struct rsnd_adg { 32 25 struct clk *clk[CLKMAX]; 26 + struct clk *clkout[CLKOUTMAX]; 27 + struct clk_onecell_data onecell; 33 28 struct rsnd_mod mod; 34 29 35 30 int rbga_rate_for_441khz; /* RBGA */ ··· 42 33 for (i = 0; \ 43 34 (i < CLKMAX) && \ 44 35 ((pos) = adg->clk[i]); \ 36 + i++) 37 + #define for_each_rsnd_clkout(pos, adg, i) \ 38 + for (i = 0; \ 39 + (i < CLKOUTMAX) && \ 40 + ((pos) = adg->clkout[i]); \ 45 41 i++) 46 42 #define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg) 47 43 ··· 430 416 dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk)); 431 417 } 432 418 433 - static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg) 419 + static void rsnd_adg_get_clkout(struct rsnd_priv *priv, 420 + struct rsnd_adg *adg) 434 421 { 435 422 struct clk *clk; 436 423 struct rsnd_mod *adg_mod = rsnd_mod_get(adg); 437 424 struct device *dev = rsnd_priv_to_dev(priv); 438 - unsigned long rate, div; 425 + struct device_node *np = dev->of_node; 439 426 u32 ckr, rbgx, rbga, rbgb; 427 + u32 rate, req_rate, div; 428 + uint32_t count = 0; 429 + unsigned long req_48kHz_rate, req_441kHz_rate; 440 430 int i; 431 + const char *parent_clk_name = NULL; 432 + static const char * const clkout_name[] = { 433 + [CLKOUT] = "audio_clkout", 434 + [CLKOUT1] = "audio_clkout1", 435 + [CLKOUT2] = "audio_clkout2", 436 + [CLKOUT3] = "audio_clkout3", 437 + }; 441 438 int brg_table[] = { 442 439 [CLKA] = 0x0, 443 440 [CLKB] = 0x1, 444 441 [CLKC] = 0x4, 445 442 [CLKI] = 0x2, 446 443 }; 444 + 445 + of_property_read_u32(np, "#clock-cells", &count); 446 + 447 + /* 448 + * ADG supports BRRA/BRRB output only 449 + * this means all clkout0/1/2/3 will be same rate 450 + */ 451 + of_property_read_u32(np, "clock-frequency", &req_rate); 452 + req_48kHz_rate = 0; 453 + req_441kHz_rate = 0; 454 + if (0 == (req_rate % 44100)) 455 + req_441kHz_rate = req_rate; 456 + if (0 == (req_rate % 48000)) 457 + req_48kHz_rate = req_rate; 447 458 448 459 /* 449 460 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC ··· 493 454 /* RBGA */ 494 455 if (!adg->rbga_rate_for_441khz && (0 == rate % 44100)) { 495 456 div = 6; 457 + if (req_441kHz_rate) 458 + div = rate / req_441kHz_rate; 496 459 rbgx = rsnd_adg_calculate_rbgx(div); 497 460 if (BRRx_MASK(rbgx) == rbgx) { 498 461 rbga = rbgx; 499 462 adg->rbga_rate_for_441khz = rate / div; 500 463 ckr |= brg_table[i] << 20; 464 + if (req_441kHz_rate) 465 + parent_clk_name = __clk_get_name(clk); 501 466 } 502 467 } 503 468 504 469 /* RBGB */ 505 470 if (!adg->rbgb_rate_for_48khz && (0 == rate % 48000)) { 506 471 div = 6; 472 + if (req_48kHz_rate) 473 + div = rate / req_48kHz_rate; 507 474 rbgx = rsnd_adg_calculate_rbgx(div); 508 475 if (BRRx_MASK(rbgx) == rbgx) { 509 476 rbgb = rbgx; 510 477 adg->rbgb_rate_for_48khz = rate / div; 511 478 ckr |= brg_table[i] << 16; 479 + if (req_48kHz_rate) { 480 + parent_clk_name = __clk_get_name(clk); 481 + ckr |= 0x80000000; 482 + } 483 + } 484 + } 485 + } 486 + 487 + /* 488 + * ADG supports BRRA/BRRB output only. 489 + * this means all clkout0/1/2/3 will be * same rate 490 + */ 491 + 492 + /* 493 + * for clkout 494 + */ 495 + if (!count) { 496 + clk = clk_register_fixed_rate(dev, clkout_name[i], 497 + parent_clk_name, 498 + (parent_clk_name) ? 499 + 0 : CLK_IS_ROOT, req_rate); 500 + if (!IS_ERR(clk)) { 501 + adg->clkout[CLKOUT] = clk; 502 + of_clk_add_provider(np, of_clk_src_simple_get, clk); 503 + } 504 + } 505 + /* 506 + * for clkout0/1/2/3 507 + */ 508 + else { 509 + for (i = 0; i < CLKOUTMAX; i++) { 510 + clk = clk_register_fixed_rate(dev, clkout_name[i], 511 + parent_clk_name, 512 + (parent_clk_name) ? 513 + 0 : CLK_IS_ROOT, 514 + req_rate); 515 + if (!IS_ERR(clk)) { 516 + adg->onecell.clks = adg->clkout; 517 + adg->onecell.clk_num = CLKOUTMAX; 518 + 519 + adg->clkout[i] = clk; 520 + 521 + of_clk_add_provider(np, of_clk_src_onecell_get, 522 + &adg->onecell); 512 523 } 513 524 } 514 525 } ··· 567 478 rsnd_mod_write(adg_mod, BRRA, rbga); 568 479 rsnd_mod_write(adg_mod, BRRB, rbgb); 569 480 481 + for_each_rsnd_clkout(clk, adg, i) 482 + dev_dbg(dev, "clkout %d : %p : %ld\n", i, clk, clk_get_rate(clk)); 570 483 dev_dbg(dev, "SSICKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n", 571 484 ckr, rbga, rbgb); 572 485 } ··· 595 504 adg->mod.priv = priv; 596 505 597 506 rsnd_adg_get_clkin(priv, adg); 598 - 599 - rsnd_adg_ssi_clk_init(priv, adg); 507 + rsnd_adg_get_clkout(priv, adg); 600 508 601 509 priv->adg = adg; 602 510