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

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: rsnd: tidyup ADG

Merge series from Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>:

Renesas Sound has ADG for clock control. Basically it needs
accurately divisible external input clock. But sometimes
sometimes it doesn't have to be accurate for some reason.

We can use ADG clk_i for such case. It came from CPG as
very high rate clock, but is not accurately divisible for
48kHz/44.1kHz rate, but enough for approximate rate.

This patch set support such use case.

+55 -13
+55 -13
sound/soc/sh/rcar/adg.c
··· 358 358 ckr = 0x80000000; /* BRGB output = 48kHz */ 359 359 360 360 rsnd_mod_bset(adg_mod, BRGCKR, 0x80770000, adg->ckr | ckr); 361 - rsnd_mod_write(adg_mod, BRRA, adg->brga); 362 - rsnd_mod_write(adg_mod, BRRB, adg->brgb); 363 361 364 362 dev_dbg(dev, "CLKOUT is based on BRG%c (= %dHz)\n", 365 363 (ckr) ? 'B' : 'A', ··· 370 372 void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable) 371 373 { 372 374 struct rsnd_adg *adg = rsnd_priv_to_adg(priv); 375 + struct rsnd_mod *adg_mod = rsnd_mod_get(adg); 373 376 struct clk *clk; 374 377 int i; 378 + 379 + if (enable) { 380 + rsnd_mod_bset(adg_mod, BRGCKR, 0x80770000, adg->ckr); 381 + rsnd_mod_write(adg_mod, BRRA, adg->brga); 382 + rsnd_mod_write(adg_mod, BRRB, adg->brgb); 383 + } 375 384 376 385 for_each_rsnd_clkin(clk, adg, i) { 377 386 if (enable) { ··· 490 485 struct device_node *np = dev->of_node; 491 486 struct property *prop; 492 487 u32 ckr, brgx, brga, brgb; 493 - u32 rate, div; 494 488 u32 req_rate[ADG_HZ_SIZE] = {}; 495 489 uint32_t count = 0; 496 490 unsigned long req_Hz[ADG_HZ_SIZE]; 497 491 int clkout_size; 498 492 int i, req_size; 493 + int approximate = 0; 499 494 const char *parent_clk_name = NULL; 500 495 const char * const *clkout_name; 501 496 int brg_table[] = { ··· 506 501 }; 507 502 508 503 ckr = 0; 509 - brga = 2; /* default 1/6 */ 510 - brgb = 2; /* default 1/6 */ 504 + brga = 0xff; /* default */ 505 + brgb = 0xff; /* default */ 511 506 512 507 /* 513 508 * ADG supports BRRA/BRRB output only ··· 542 537 * rsnd_adg_ssi_clk_try_start() 543 538 * rsnd_ssi_master_clk_start() 544 539 */ 540 + 541 + /* 542 + * [APPROXIMATE] 543 + * 544 + * clk_i (internal clock) can't create accurate rate, it will be approximate rate. 545 + * 546 + * <Note> 547 + * 548 + * clk_i needs x2 of required maximum rate. 549 + * see 550 + * - Minimum division of BRRA/BRRB 551 + * - rsnd_ssi_clk_query() 552 + * 553 + * Sample Settings for TDM 8ch, 32bit width 554 + * 555 + * 8(ch) x 32(bit) x 44100(Hz) x 2<Note> = 22579200 556 + * 8(ch) x 32(bit) x 48000(Hz) x 2<Note> = 24576000 557 + * 558 + * clock-frequency = <22579200 24576000>; 559 + */ 545 560 for_each_rsnd_clkin(clk, adg, i) { 561 + u32 rate, div; 562 + 546 563 rate = clk_get_rate(clk); 547 564 548 565 if (0 == rate) /* not used */ 549 566 continue; 550 567 551 568 /* BRGA */ 552 - if (!adg->brg_rate[ADG_HZ_441] && (0 == rate % 44100)) { 553 - div = 6; 554 - if (req_Hz[ADG_HZ_441]) 555 - div = rate / req_Hz[ADG_HZ_441]; 569 + 570 + if (i == CLKI) 571 + /* see [APPROXIMATE] */ 572 + rate = (clk_get_rate(clk) / req_Hz[ADG_HZ_441]) * req_Hz[ADG_HZ_441]; 573 + if (!adg->brg_rate[ADG_HZ_441] && req_Hz[ADG_HZ_441] && (0 == rate % 44100)) { 574 + div = rate / req_Hz[ADG_HZ_441]; 556 575 brgx = rsnd_adg_calculate_brgx(div); 557 576 if (BRRx_MASK(brgx) == brgx) { 558 577 brga = brgx; ··· 584 555 ckr |= brg_table[i] << 20; 585 556 if (req_Hz[ADG_HZ_441]) 586 557 parent_clk_name = __clk_get_name(clk); 558 + if (i == CLKI) 559 + approximate = 1; 587 560 } 588 561 } 589 562 590 563 /* BRGB */ 591 - if (!adg->brg_rate[ADG_HZ_48] && (0 == rate % 48000)) { 592 - div = 6; 593 - if (req_Hz[ADG_HZ_48]) 594 - div = rate / req_Hz[ADG_HZ_48]; 564 + 565 + if (i == CLKI) 566 + /* see [APPROXIMATE] */ 567 + rate = (clk_get_rate(clk) / req_Hz[ADG_HZ_48]) * req_Hz[ADG_HZ_48]; 568 + if (!adg->brg_rate[ADG_HZ_48] && req_Hz[ADG_HZ_48] && (0 == rate % 48000)) { 569 + div = rate / req_Hz[ADG_HZ_48]; 595 570 brgx = rsnd_adg_calculate_brgx(div); 596 571 if (BRRx_MASK(brgx) == brgx) { 597 572 brgb = brgx; ··· 603 570 ckr |= brg_table[i] << 16; 604 571 if (req_Hz[ADG_HZ_48]) 605 572 parent_clk_name = __clk_get_name(clk); 573 + if (i == CLKI) 574 + approximate = 1; 606 575 } 607 576 } 608 577 } 578 + 579 + if (!(adg->brg_rate[ADG_HZ_48] && req_Hz[ADG_HZ_48]) && 580 + !(adg->brg_rate[ADG_HZ_441] && req_Hz[ADG_HZ_441])) 581 + goto rsnd_adg_get_clkout_end; 582 + 583 + if (approximate) 584 + dev_info(dev, "It uses CLK_I as approximate rate"); 609 585 610 586 clkout_name = clkout_name_gen2; 611 587 clkout_size = ARRAY_SIZE(clkout_name_gen2);