@@ -35,6 +35,7 @@ struct rsnd_src {
35
35
struct rsnd_mod * dma ;
36
36
struct rsnd_kctrl_cfg_s sen ; /* sync convert enable */
37
37
struct rsnd_kctrl_cfg_s sync ; /* sync convert */
38
+ u32 current_sync_rate ;
38
39
int irq ;
39
40
};
40
41
@@ -100,7 +101,7 @@ static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io,
100
101
if (!rsnd_src_sync_is_enabled (mod ))
101
102
return rsnd_io_converted_rate (io );
102
103
103
- convert_rate = src -> sync . val ;
104
+ convert_rate = src -> current_sync_rate ;
104
105
105
106
if (!convert_rate )
106
107
convert_rate = rsnd_io_converted_rate (io );
@@ -201,13 +202,73 @@ static const u32 chan222222[] = {
201
202
static void rsnd_src_set_convert_rate (struct rsnd_dai_stream * io ,
202
203
struct rsnd_mod * mod )
203
204
{
205
+ struct snd_pcm_runtime * runtime = rsnd_io_to_runtime (io );
204
206
struct rsnd_priv * priv = rsnd_mod_to_priv (mod );
205
- struct device * dev = rsnd_priv_to_dev (priv );
207
+ struct rsnd_src * src = rsnd_mod_to_src (mod );
208
+ u32 fin , fout , new_rate ;
209
+ int inc , cnt , rate ;
210
+ u64 base , val ;
211
+
212
+ if (!runtime )
213
+ return ;
214
+
215
+ if (!rsnd_src_sync_is_enabled (mod ))
216
+ return ;
217
+
218
+ fin = rsnd_src_get_in_rate (priv , io );
219
+ fout = rsnd_src_get_out_rate (priv , io );
220
+
221
+ new_rate = src -> sync .val ;
222
+
223
+ if (!new_rate )
224
+ new_rate = fout ;
225
+
226
+ /* Do nothing if no diff */
227
+ if (new_rate == src -> current_sync_rate )
228
+ return ;
229
+
230
+ /*
231
+ * SRCm_IFSVR::INTIFS can change within 1%
232
+ * see
233
+ * SRCm_IFSVR::INTIFS Note
234
+ */
235
+ inc = fout / 100 ;
236
+ cnt = abs (new_rate - fout ) / inc ;
237
+ if (fout > new_rate )
238
+ inc *= -1 ;
239
+
240
+ /*
241
+ * After start running SRC, we can update only SRC_IFSVR
242
+ * for Synchronous Mode
243
+ */
244
+ base = (u64 )0x0400000 * fin ;
245
+ rate = fout ;
246
+ for (int i = 0 ; i < cnt ; i ++ ) {
247
+ val = base ;
248
+ rate += inc ;
249
+ do_div (val , rate );
250
+
251
+ rsnd_mod_write (mod , SRC_IFSVR , val );
252
+ }
253
+ val = base ;
254
+ do_div (val , new_rate );
255
+
256
+ rsnd_mod_write (mod , SRC_IFSVR , val );
257
+
258
+ /* update current_sync_rate */
259
+ src -> current_sync_rate = new_rate ;
260
+ }
261
+
262
+ static void rsnd_src_init_convert_rate (struct rsnd_dai_stream * io ,
263
+ struct rsnd_mod * mod )
264
+ {
206
265
struct snd_pcm_runtime * runtime = rsnd_io_to_runtime (io );
266
+ struct rsnd_priv * priv = rsnd_mod_to_priv (mod );
267
+ struct device * dev = rsnd_priv_to_dev (priv );
207
268
int is_play = rsnd_io_is_play (io );
208
269
int use_src = 0 ;
209
270
u32 fin , fout ;
210
- u32 ifscr , fsrate , adinr ;
271
+ u32 ifscr , adinr ;
211
272
u32 cr , route ;
212
273
u32 i_busif , o_busif , tmp ;
213
274
const u32 * bsdsr_table ;
@@ -245,26 +306,15 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
245
306
adinr = rsnd_get_adinr_bit (mod , io ) | chan ;
246
307
247
308
/*
248
- * SRC_IFSCR / SRC_IFSVR
249
- */
250
- ifscr = 0 ;
251
- fsrate = 0 ;
252
- if (use_src ) {
253
- u64 n ;
254
-
255
- ifscr = 1 ;
256
- n = (u64 )0x0400000 * fin ;
257
- do_div (n , fout );
258
- fsrate = n ;
259
- }
260
-
261
- /*
309
+ * SRC_IFSCR
262
310
* SRC_SRCCR / SRC_ROUTE_MODE0
263
311
*/
312
+ ifscr = 0 ;
264
313
cr = 0x00011110 ;
265
314
route = 0x0 ;
266
315
if (use_src ) {
267
316
route = 0x1 ;
317
+ ifscr = 0x1 ;
268
318
269
319
if (rsnd_src_sync_is_enabled (mod )) {
270
320
cr |= 0x1 ;
@@ -335,7 +385,6 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
335
385
rsnd_mod_write (mod , SRC_SRCIR , 1 ); /* initialize */
336
386
rsnd_mod_write (mod , SRC_ADINR , adinr );
337
387
rsnd_mod_write (mod , SRC_IFSCR , ifscr );
338
- rsnd_mod_write (mod , SRC_IFSVR , fsrate );
339
388
rsnd_mod_write (mod , SRC_SRCCR , cr );
340
389
rsnd_mod_write (mod , SRC_BSDSR , bsdsr_table [idx ]);
341
390
rsnd_mod_write (mod , SRC_BSISR , bsisr_table [idx ]);
@@ -348,6 +397,9 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
348
397
349
398
rsnd_adg_set_src_timesel_gen2 (mod , io , fin , fout );
350
399
400
+ /* update SRC_IFSVR */
401
+ rsnd_src_set_convert_rate (io , mod );
402
+
351
403
return ;
352
404
353
405
convert_rate_err :
@@ -467,15 +519,16 @@ static int rsnd_src_init(struct rsnd_mod *mod,
467
519
int ret ;
468
520
469
521
/* reset sync convert_rate */
470
- src -> sync .val = 0 ;
522
+ src -> sync .val =
523
+ src -> current_sync_rate = 0 ;
471
524
472
525
ret = rsnd_mod_power_on (mod );
473
526
if (ret < 0 )
474
527
return ret ;
475
528
476
529
rsnd_src_activation (mod );
477
530
478
- rsnd_src_set_convert_rate (io , mod );
531
+ rsnd_src_init_convert_rate (io , mod );
479
532
480
533
rsnd_src_status_clear (mod );
481
534
@@ -493,7 +546,8 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
493
546
rsnd_mod_power_off (mod );
494
547
495
548
/* reset sync convert_rate */
496
- src -> sync .val = 0 ;
549
+ src -> sync .val =
550
+ src -> current_sync_rate = 0 ;
497
551
498
552
return 0 ;
499
553
}
@@ -531,6 +585,22 @@ static irqreturn_t rsnd_src_interrupt(int irq, void *data)
531
585
return IRQ_HANDLED ;
532
586
}
533
587
588
+ static int rsnd_src_kctrl_accept_runtime (struct rsnd_dai_stream * io )
589
+ {
590
+ struct snd_pcm_runtime * runtime = rsnd_io_to_runtime (io );
591
+
592
+ if (!runtime ) {
593
+ struct rsnd_priv * priv = rsnd_io_to_priv (io );
594
+ struct device * dev = rsnd_priv_to_dev (priv );
595
+
596
+ dev_warn (dev , "\"SRC Out Rate\" can use during running\n" );
597
+
598
+ return 0 ;
599
+ }
600
+
601
+ return 1 ;
602
+ }
603
+
534
604
static int rsnd_src_probe_ (struct rsnd_mod * mod ,
535
605
struct rsnd_dai_stream * io ,
536
606
struct rsnd_priv * priv )
@@ -585,7 +655,7 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
585
655
"SRC Out Rate Switch" :
586
656
"SRC In Rate Switch" ,
587
657
rsnd_kctrl_accept_anytime ,
588
- rsnd_src_set_convert_rate ,
658
+ rsnd_src_init_convert_rate ,
589
659
& src -> sen , 1 );
590
660
if (ret < 0 )
591
661
return ret ;
@@ -594,7 +664,7 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
594
664
rsnd_io_is_play (io ) ?
595
665
"SRC Out Rate" :
596
666
"SRC In Rate" ,
597
- rsnd_kctrl_accept_runtime ,
667
+ rsnd_src_kctrl_accept_runtime ,
598
668
rsnd_src_set_convert_rate ,
599
669
& src -> sync , 192000 );
600
670
0 commit comments