@@ -40,6 +40,9 @@ struct rk_i2s_dev {
40
40
struct regmap * regmap ;
41
41
struct regmap * grf ;
42
42
43
+ bool has_capture ;
44
+ bool has_playback ;
45
+
43
46
/*
44
47
* Used to indicate the tx/rx status.
45
48
* I2S controller hopes to start the tx and rx together,
@@ -49,6 +52,7 @@ struct rk_i2s_dev {
49
52
bool rx_start ;
50
53
bool is_master_mode ;
51
54
const struct rk_i2s_pins * pins ;
55
+ unsigned int bclk_ratio ;
52
56
};
53
57
54
58
static int i2s_runtime_suspend (struct device * dev )
@@ -186,7 +190,9 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
186
190
{
187
191
struct rk_i2s_dev * i2s = to_info (cpu_dai );
188
192
unsigned int mask = 0 , val = 0 ;
193
+ int ret = 0 ;
189
194
195
+ pm_runtime_get_sync (cpu_dai -> dev );
190
196
mask = I2S_CKR_MSS_MASK ;
191
197
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK ) {
192
198
case SND_SOC_DAIFMT_CBS_CFS :
@@ -199,21 +205,37 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
199
205
i2s -> is_master_mode = false;
200
206
break ;
201
207
default :
202
- return - EINVAL ;
208
+ ret = - EINVAL ;
209
+ goto err_pm_put ;
203
210
}
204
211
205
212
regmap_update_bits (i2s -> regmap , I2S_CKR , mask , val );
206
213
207
- mask = I2S_CKR_CKP_MASK ;
214
+ mask = I2S_CKR_CKP_MASK | I2S_CKR_TLP_MASK | I2S_CKR_RLP_MASK ;
208
215
switch (fmt & SND_SOC_DAIFMT_INV_MASK ) {
209
216
case SND_SOC_DAIFMT_NB_NF :
210
- val = I2S_CKR_CKP_NEG ;
217
+ val = I2S_CKR_CKP_NORMAL |
218
+ I2S_CKR_TLP_NORMAL |
219
+ I2S_CKR_RLP_NORMAL ;
220
+ break ;
221
+ case SND_SOC_DAIFMT_NB_IF :
222
+ val = I2S_CKR_CKP_NORMAL |
223
+ I2S_CKR_TLP_INVERTED |
224
+ I2S_CKR_RLP_INVERTED ;
211
225
break ;
212
226
case SND_SOC_DAIFMT_IB_NF :
213
- val = I2S_CKR_CKP_POS ;
227
+ val = I2S_CKR_CKP_INVERTED |
228
+ I2S_CKR_TLP_NORMAL |
229
+ I2S_CKR_RLP_NORMAL ;
230
+ break ;
231
+ case SND_SOC_DAIFMT_IB_IF :
232
+ val = I2S_CKR_CKP_INVERTED |
233
+ I2S_CKR_TLP_INVERTED |
234
+ I2S_CKR_RLP_INVERTED ;
214
235
break ;
215
236
default :
216
- return - EINVAL ;
237
+ ret = - EINVAL ;
238
+ goto err_pm_put ;
217
239
}
218
240
219
241
regmap_update_bits (i2s -> regmap , I2S_CKR , mask , val );
@@ -229,14 +251,15 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
229
251
case SND_SOC_DAIFMT_I2S :
230
252
val = I2S_TXCR_IBM_NORMAL ;
231
253
break ;
232
- case SND_SOC_DAIFMT_DSP_A : /* PCM no delay mode */
233
- val = I2S_TXCR_TFS_PCM ;
234
- break ;
235
- case SND_SOC_DAIFMT_DSP_B : /* PCM delay 1 mode */
254
+ case SND_SOC_DAIFMT_DSP_A : /* PCM delay 1 bit mode */
236
255
val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE (1 );
237
256
break ;
257
+ case SND_SOC_DAIFMT_DSP_B : /* PCM no delay mode */
258
+ val = I2S_TXCR_TFS_PCM ;
259
+ break ;
238
260
default :
239
- return - EINVAL ;
261
+ ret = - EINVAL ;
262
+ goto err_pm_put ;
240
263
}
241
264
242
265
regmap_update_bits (i2s -> regmap , I2S_TXCR , mask , val );
@@ -252,19 +275,23 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
252
275
case SND_SOC_DAIFMT_I2S :
253
276
val = I2S_RXCR_IBM_NORMAL ;
254
277
break ;
255
- case SND_SOC_DAIFMT_DSP_A : /* PCM no delay mode */
256
- val = I2S_RXCR_TFS_PCM ;
257
- break ;
258
- case SND_SOC_DAIFMT_DSP_B : /* PCM delay 1 mode */
278
+ case SND_SOC_DAIFMT_DSP_A : /* PCM delay 1 bit mode */
259
279
val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE (1 );
260
280
break ;
281
+ case SND_SOC_DAIFMT_DSP_B : /* PCM no delay mode */
282
+ val = I2S_RXCR_TFS_PCM ;
283
+ break ;
261
284
default :
262
- return - EINVAL ;
285
+ ret = - EINVAL ;
286
+ goto err_pm_put ;
263
287
}
264
288
265
289
regmap_update_bits (i2s -> regmap , I2S_RXCR , mask , val );
266
290
267
- return 0 ;
291
+ err_pm_put :
292
+ pm_runtime_put (cpu_dai -> dev );
293
+
294
+ return ret ;
268
295
}
269
296
270
297
static int rockchip_i2s_hw_params (struct snd_pcm_substream * substream ,
@@ -278,11 +305,11 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
278
305
279
306
if (i2s -> is_master_mode ) {
280
307
mclk_rate = clk_get_rate (i2s -> mclk );
281
- bclk_rate = 2 * 32 * params_rate (params );
282
- if (bclk_rate == 0 || mclk_rate % bclk_rate )
308
+ bclk_rate = i2s -> bclk_ratio * params_rate (params );
309
+ if (! bclk_rate )
283
310
return - EINVAL ;
284
311
285
- div_bclk = mclk_rate / bclk_rate ;
312
+ div_bclk = DIV_ROUND_CLOSEST ( mclk_rate , bclk_rate ) ;
286
313
div_lrck = bclk_rate / params_rate (params );
287
314
regmap_update_bits (i2s -> regmap , I2S_CKR ,
288
315
I2S_CKR_MDIV_MASK ,
@@ -413,6 +440,16 @@ static int rockchip_i2s_trigger(struct snd_pcm_substream *substream,
413
440
return ret ;
414
441
}
415
442
443
+ static int rockchip_i2s_set_bclk_ratio (struct snd_soc_dai * dai ,
444
+ unsigned int ratio )
445
+ {
446
+ struct rk_i2s_dev * i2s = to_info (dai );
447
+
448
+ i2s -> bclk_ratio = ratio ;
449
+
450
+ return 0 ;
451
+ }
452
+
416
453
static int rockchip_i2s_set_sysclk (struct snd_soc_dai * cpu_dai , int clk_id ,
417
454
unsigned int freq , int dir )
418
455
{
@@ -433,43 +470,23 @@ static int rockchip_i2s_dai_probe(struct snd_soc_dai *dai)
433
470
{
434
471
struct rk_i2s_dev * i2s = snd_soc_dai_get_drvdata (dai );
435
472
436
- dai -> capture_dma_data = & i2s -> capture_dma_data ;
437
- dai -> playback_dma_data = & i2s -> playback_dma_data ;
473
+ snd_soc_dai_init_dma_data (dai ,
474
+ i2s -> has_playback ? & i2s -> playback_dma_data : NULL ,
475
+ i2s -> has_capture ? & i2s -> capture_dma_data : NULL );
438
476
439
477
return 0 ;
440
478
}
441
479
442
480
static const struct snd_soc_dai_ops rockchip_i2s_dai_ops = {
443
481
.hw_params = rockchip_i2s_hw_params ,
482
+ .set_bclk_ratio = rockchip_i2s_set_bclk_ratio ,
444
483
.set_sysclk = rockchip_i2s_set_sysclk ,
445
484
.set_fmt = rockchip_i2s_set_fmt ,
446
485
.trigger = rockchip_i2s_trigger ,
447
486
};
448
487
449
488
static struct snd_soc_dai_driver rockchip_i2s_dai = {
450
489
.probe = rockchip_i2s_dai_probe ,
451
- .playback = {
452
- .stream_name = "Playback" ,
453
- .channels_min = 2 ,
454
- .channels_max = 8 ,
455
- .rates = SNDRV_PCM_RATE_8000_192000 ,
456
- .formats = (SNDRV_PCM_FMTBIT_S8 |
457
- SNDRV_PCM_FMTBIT_S16_LE |
458
- SNDRV_PCM_FMTBIT_S20_3LE |
459
- SNDRV_PCM_FMTBIT_S24_LE |
460
- SNDRV_PCM_FMTBIT_S32_LE ),
461
- },
462
- .capture = {
463
- .stream_name = "Capture" ,
464
- .channels_min = 2 ,
465
- .channels_max = 2 ,
466
- .rates = SNDRV_PCM_RATE_8000_192000 ,
467
- .formats = (SNDRV_PCM_FMTBIT_S8 |
468
- SNDRV_PCM_FMTBIT_S16_LE |
469
- SNDRV_PCM_FMTBIT_S20_3LE |
470
- SNDRV_PCM_FMTBIT_S24_LE |
471
- SNDRV_PCM_FMTBIT_S32_LE ),
472
- },
473
490
.ops = & rockchip_i2s_dai_ops ,
474
491
.symmetric_rate = 1 ,
475
492
};
@@ -567,23 +584,101 @@ static const struct rk_i2s_pins rk3399_i2s_pins = {
567
584
};
568
585
569
586
static const struct of_device_id rockchip_i2s_match [] __maybe_unused = {
587
+ { .compatible = "rockchip,px30-i2s" , },
588
+ { .compatible = "rockchip,rk1808-i2s" , },
589
+ { .compatible = "rockchip,rk3036-i2s" , },
570
590
{ .compatible = "rockchip,rk3066-i2s" , },
591
+ { .compatible = "rockchip,rk3128-i2s" , },
571
592
{ .compatible = "rockchip,rk3188-i2s" , },
593
+ { .compatible = "rockchip,rk3228-i2s" , },
572
594
{ .compatible = "rockchip,rk3288-i2s" , },
595
+ { .compatible = "rockchip,rk3308-i2s" , },
596
+ { .compatible = "rockchip,rk3328-i2s" , },
597
+ { .compatible = "rockchip,rk3366-i2s" , },
598
+ { .compatible = "rockchip,rk3368-i2s" , },
573
599
{ .compatible = "rockchip,rk3399-i2s" , .data = & rk3399_i2s_pins },
600
+ { .compatible = "rockchip,rv1126-i2s" , },
574
601
{},
575
602
};
576
603
604
+ static int rockchip_i2s_init_dai (struct rk_i2s_dev * i2s , struct resource * res ,
605
+ struct snd_soc_dai_driver * * dp )
606
+ {
607
+ struct device_node * node = i2s -> dev -> of_node ;
608
+ struct snd_soc_dai_driver * dai ;
609
+ struct property * dma_names ;
610
+ const char * dma_name ;
611
+ unsigned int val ;
612
+
613
+ of_property_for_each_string (node , "dma-names" , dma_names , dma_name ) {
614
+ if (!strcmp (dma_name , "tx" ))
615
+ i2s -> has_playback = true;
616
+ if (!strcmp (dma_name , "rx" ))
617
+ i2s -> has_capture = true;
618
+ }
619
+
620
+ dai = devm_kmemdup (i2s -> dev , & rockchip_i2s_dai ,
621
+ sizeof (* dai ), GFP_KERNEL );
622
+ if (!dai )
623
+ return - ENOMEM ;
624
+
625
+ if (i2s -> has_playback ) {
626
+ dai -> playback .stream_name = "Playback" ;
627
+ dai -> playback .channels_min = 2 ;
628
+ dai -> playback .channels_max = 8 ;
629
+ dai -> playback .rates = SNDRV_PCM_RATE_8000_192000 ;
630
+ dai -> playback .formats = SNDRV_PCM_FMTBIT_S8 |
631
+ SNDRV_PCM_FMTBIT_S16_LE |
632
+ SNDRV_PCM_FMTBIT_S20_3LE |
633
+ SNDRV_PCM_FMTBIT_S24_LE |
634
+ SNDRV_PCM_FMTBIT_S32_LE ;
635
+
636
+ i2s -> playback_dma_data .addr = res -> start + I2S_TXDR ;
637
+ i2s -> playback_dma_data .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES ;
638
+ i2s -> playback_dma_data .maxburst = 8 ;
639
+
640
+ if (!of_property_read_u32 (node , "rockchip,playback-channels" , & val )) {
641
+ if (val >= 2 && val <= 8 )
642
+ dai -> playback .channels_max = val ;
643
+ }
644
+ }
645
+
646
+ if (i2s -> has_capture ) {
647
+ dai -> capture .stream_name = "Capture" ;
648
+ dai -> capture .channels_min = 2 ;
649
+ dai -> capture .channels_max = 8 ;
650
+ dai -> capture .rates = SNDRV_PCM_RATE_8000_192000 ;
651
+ dai -> capture .formats = SNDRV_PCM_FMTBIT_S8 |
652
+ SNDRV_PCM_FMTBIT_S16_LE |
653
+ SNDRV_PCM_FMTBIT_S20_3LE |
654
+ SNDRV_PCM_FMTBIT_S24_LE |
655
+ SNDRV_PCM_FMTBIT_S32_LE ;
656
+
657
+ i2s -> capture_dma_data .addr = res -> start + I2S_RXDR ;
658
+ i2s -> capture_dma_data .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES ;
659
+ i2s -> capture_dma_data .maxburst = 8 ;
660
+
661
+ if (!of_property_read_u32 (node , "rockchip,capture-channels" , & val )) {
662
+ if (val >= 2 && val <= 8 )
663
+ dai -> capture .channels_max = val ;
664
+ }
665
+ }
666
+
667
+ if (dp )
668
+ * dp = dai ;
669
+
670
+ return 0 ;
671
+ }
672
+
577
673
static int rockchip_i2s_probe (struct platform_device * pdev )
578
674
{
579
675
struct device_node * node = pdev -> dev .of_node ;
580
676
const struct of_device_id * of_id ;
581
677
struct rk_i2s_dev * i2s ;
582
- struct snd_soc_dai_driver * soc_dai ;
678
+ struct snd_soc_dai_driver * dai ;
583
679
struct resource * res ;
584
680
void __iomem * regs ;
585
681
int ret ;
586
- int val ;
587
682
588
683
i2s = devm_kzalloc (& pdev -> dev , sizeof (* i2s ), GFP_KERNEL );
589
684
if (!i2s )
@@ -630,13 +725,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
630
725
return PTR_ERR (i2s -> regmap );
631
726
}
632
727
633
- i2s -> playback_dma_data .addr = res -> start + I2S_TXDR ;
634
- i2s -> playback_dma_data .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES ;
635
- i2s -> playback_dma_data .maxburst = 4 ;
636
-
637
- i2s -> capture_dma_data .addr = res -> start + I2S_RXDR ;
638
- i2s -> capture_dma_data .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES ;
639
- i2s -> capture_dma_data .maxburst = 4 ;
728
+ i2s -> bclk_ratio = 64 ;
640
729
641
730
dev_set_drvdata (& pdev -> dev , i2s );
642
731
@@ -647,26 +736,13 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
647
736
goto err_pm_disable ;
648
737
}
649
738
650
- soc_dai = devm_kmemdup (& pdev -> dev , & rockchip_i2s_dai ,
651
- sizeof (* soc_dai ), GFP_KERNEL );
652
- if (!soc_dai ) {
653
- ret = - ENOMEM ;
739
+ ret = rockchip_i2s_init_dai (i2s , res , & dai );
740
+ if (ret )
654
741
goto err_pm_disable ;
655
- }
656
-
657
- if (!of_property_read_u32 (node , "rockchip,playback-channels" , & val )) {
658
- if (val >= 2 && val <= 8 )
659
- soc_dai -> playback .channels_max = val ;
660
- }
661
-
662
- if (!of_property_read_u32 (node , "rockchip,capture-channels" , & val )) {
663
- if (val >= 2 && val <= 8 )
664
- soc_dai -> capture .channels_max = val ;
665
- }
666
742
667
743
ret = devm_snd_soc_register_component (& pdev -> dev ,
668
744
& rockchip_i2s_component ,
669
- soc_dai , 1 );
745
+ dai , 1 );
670
746
671
747
if (ret ) {
672
748
dev_err (& pdev -> dev , "Could not register DAI\n" );
0 commit comments