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