@@ -358,8 +358,6 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
358358 ckr = 0x80000000 ; /* BRGB output = 48kHz */
359359
360360 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 );
363361
364362 dev_dbg (dev , "CLKOUT is based on BRG%c (= %dHz)\n" ,
365363 (ckr ) ? 'B' : 'A' ,
@@ -372,9 +370,16 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
372370void rsnd_adg_clk_control (struct rsnd_priv * priv , int enable )
373371{
374372 struct rsnd_adg * adg = rsnd_priv_to_adg (priv );
373+ struct rsnd_mod * adg_mod = rsnd_mod_get (adg );
375374 struct clk * clk ;
376375 int i ;
377376
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+
378383 for_each_rsnd_clkin (clk , adg , i ) {
379384 if (enable ) {
380385 clk_prepare_enable (clk );
@@ -485,12 +490,12 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
485490 struct device_node * np = dev -> of_node ;
486491 struct property * prop ;
487492 u32 ckr , brgx , brga , brgb ;
488- u32 rate , div ;
489493 u32 req_rate [ADG_HZ_SIZE ] = {};
490494 uint32_t count = 0 ;
491495 unsigned long req_Hz [ADG_HZ_SIZE ];
492496 int clkout_size ;
493497 int i , req_size ;
498+ int approximate = 0 ;
494499 const char * parent_clk_name = NULL ;
495500 const char * const * clkout_name ;
496501 int brg_table [] = {
@@ -501,8 +506,8 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
501506 };
502507
503508 ckr = 0 ;
504- brga = 2 ; /* default 1/6 */
505- brgb = 2 ; /* default 1/6 */
509+ brga = 0xff ; /* default */
510+ brgb = 0xff ; /* default */
506511
507512 /*
508513 * ADG supports BRRA/BRRB output only
@@ -537,43 +542,80 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
537542 * rsnd_adg_ssi_clk_try_start()
538543 * rsnd_ssi_master_clk_start()
539544 */
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+ */
540565 for_each_rsnd_clkin (clk , adg , i ) {
566+ u32 rate , div ;
567+
541568 rate = clk_get_rate (clk );
542569
543570 if (0 == rate ) /* not used */
544571 continue ;
545572
546573 /* 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 ];
551580 brgx = rsnd_adg_calculate_brgx (div );
552581 if (BRRx_MASK (brgx ) == brgx ) {
553582 brga = brgx ;
554583 adg -> brg_rate [ADG_HZ_441 ] = rate / div ;
555584 ckr |= brg_table [i ] << 20 ;
556585 if (req_Hz [ADG_HZ_441 ])
557586 parent_clk_name = __clk_get_name (clk );
587+ if (i == CLKI )
588+ approximate = 1 ;
558589 }
559590 }
560591
561592 /* 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 ];
566599 brgx = rsnd_adg_calculate_brgx (div );
567600 if (BRRx_MASK (brgx ) == brgx ) {
568601 brgb = brgx ;
569602 adg -> brg_rate [ADG_HZ_48 ] = rate / div ;
570603 ckr |= brg_table [i ] << 16 ;
571604 if (req_Hz [ADG_HZ_48 ])
572605 parent_clk_name = __clk_get_name (clk );
606+ if (i == CLKI )
607+ approximate = 1 ;
573608 }
574609 }
575610 }
576611
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+
577619 clkout_name = clkout_name_gen2 ;
578620 clkout_size = ARRAY_SIZE (clkout_name_gen2 );
579621 if (rsnd_is_gen4 (priv ))
0 commit comments