@@ -61,7 +61,36 @@ static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream)
61
61
{
62
62
struct snd_pcm_runtime * runtime = substream -> runtime ;
63
63
struct snd_soc_pcm_runtime * soc_runtime = substream -> private_data ;
64
- int ret ;
64
+ struct lpass_pcm_data * pcm_data = snd_soc_pcm_get_drvdata (soc_runtime );
65
+ struct lpass_data * drvdata =
66
+ snd_soc_platform_get_drvdata (soc_runtime -> platform );
67
+ struct lpass_variant * v = drvdata -> variant ;
68
+ int ch = -1 , reg , ret ;
69
+
70
+ if (v -> alloc_dma_channel ) {
71
+ ch = v -> alloc_dma_channel (drvdata , substream -> stream );
72
+
73
+ if (ch < 0 )
74
+ return ch ;
75
+
76
+ drvdata -> substream [ch ] = substream ;
77
+
78
+ if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK ) {
79
+ pcm_data -> rdma_ch = ch ;
80
+ reg = LPAIF_RDMACTL_REG (v , ch );
81
+ } else {
82
+ pcm_data -> wrdma_ch = ch ;
83
+ reg = LPAIF_WRDMACTL_REG (v , ch );
84
+ }
85
+
86
+ ret = regmap_write (drvdata -> lpaif_map , reg , 0 );
87
+ if (ret ) {
88
+ dev_err (soc_runtime -> dev ,
89
+ "%s() error writing to dmactl reg: %d\n" ,
90
+ __func__ , ret );
91
+ goto err ;
92
+ }
93
+ }
65
94
66
95
snd_soc_set_runtime_hwparams (substream , & lpass_platform_pcm_hardware );
67
96
@@ -72,11 +101,41 @@ static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream)
72
101
if (ret < 0 ) {
73
102
dev_err (soc_runtime -> dev , "%s() setting constraints failed: %d\n" ,
74
103
__func__ , ret );
75
- return - EINVAL ;
104
+ goto err ;
76
105
}
77
106
78
107
snd_pcm_set_runtime_buffer (substream , & substream -> dma_buffer );
79
108
109
+ return 0 ;
110
+
111
+ err :
112
+ if (ch >= 0 && v -> free_dma_channel )
113
+ v -> free_dma_channel (drvdata , ch );
114
+
115
+ return ret ;
116
+ }
117
+
118
+ static int lpass_platform_pcmops_close (struct snd_pcm_substream * substream )
119
+ {
120
+ struct snd_soc_pcm_runtime * soc_runtime = substream -> private_data ;
121
+ struct lpass_pcm_data * pcm_data = snd_soc_pcm_get_drvdata (soc_runtime );
122
+ struct lpass_data * drvdata =
123
+ snd_soc_platform_get_drvdata (soc_runtime -> platform );
124
+ struct lpass_variant * v = drvdata -> variant ;
125
+ int ch ;
126
+
127
+ if (v -> free_dma_channel ) {
128
+ if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
129
+ ch = pcm_data -> rdma_ch ;
130
+ else
131
+ ch = pcm_data -> wrdma_ch ;
132
+
133
+ if (ch >= 0 )
134
+ v -> free_dma_channel (drvdata , ch );
135
+
136
+ drvdata -> substream [ch ] = NULL ;
137
+ }
138
+
80
139
return 0 ;
81
140
}
82
141
@@ -374,6 +433,7 @@ static int lpass_platform_pcmops_mmap(struct snd_pcm_substream *substream,
374
433
375
434
static struct snd_pcm_ops lpass_platform_pcm_ops = {
376
435
.open = lpass_platform_pcmops_open ,
436
+ .close = lpass_platform_pcmops_close ,
377
437
.ioctl = snd_pcm_lib_ioctl ,
378
438
.hw_params = lpass_platform_pcmops_hw_params ,
379
439
.hw_free = lpass_platform_pcmops_hw_free ,
@@ -471,12 +531,9 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
471
531
struct snd_pcm * pcm = soc_runtime -> pcm ;
472
532
struct snd_pcm_substream * psubstream , * csubstream ;
473
533
struct snd_soc_dai * cpu_dai = soc_runtime -> cpu_dai ;
474
- struct lpass_data * drvdata =
475
- snd_soc_platform_get_drvdata (soc_runtime -> platform );
476
- struct lpass_variant * v = drvdata -> variant ;
477
- int ret = - EINVAL ;
478
534
struct lpass_pcm_data * data ;
479
535
size_t size = lpass_platform_pcm_hardware .buffer_bytes_max ;
536
+ int ret = - EINVAL ;
480
537
481
538
data = devm_kzalloc (soc_runtime -> dev , sizeof (* data ), GFP_KERNEL );
482
539
if (!data )
@@ -487,100 +544,41 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
487
544
488
545
psubstream = pcm -> streams [SNDRV_PCM_STREAM_PLAYBACK ].substream ;
489
546
if (psubstream ) {
490
- if (v -> alloc_dma_channel )
491
- data -> rdma_ch = v -> alloc_dma_channel (drvdata ,
492
- SNDRV_PCM_STREAM_PLAYBACK );
493
-
494
- if (data -> rdma_ch < 0 )
495
- return data -> rdma_ch ;
496
-
497
- drvdata -> substream [data -> rdma_ch ] = psubstream ;
498
-
499
547
ret = snd_dma_alloc_pages (SNDRV_DMA_TYPE_DEV ,
500
- soc_runtime -> platform -> dev ,
501
- size , & psubstream -> dma_buffer );
502
- if (ret )
503
- goto playback_alloc_err ;
504
-
505
- ret = regmap_write (drvdata -> lpaif_map ,
506
- LPAIF_RDMACTL_REG (v , data -> rdma_ch ), 0 );
548
+ soc_runtime -> platform -> dev ,
549
+ size , & psubstream -> dma_buffer );
507
550
if (ret ) {
508
- dev_err (soc_runtime -> dev ,
509
- "%s() error writing to rdmactl reg: %d\n" ,
510
- __func__ , ret );
511
- goto capture_alloc_err ;
551
+ dev_err (soc_runtime -> platform -> dev ,
552
+ "can't alloc playback dma buffer (%d)\n" , ret );
553
+ return ret ;
512
554
}
513
555
}
514
556
515
557
csubstream = pcm -> streams [SNDRV_PCM_STREAM_CAPTURE ].substream ;
516
558
if (csubstream ) {
517
- if (v -> alloc_dma_channel )
518
- data -> wrdma_ch = v -> alloc_dma_channel (drvdata ,
519
- SNDRV_PCM_STREAM_CAPTURE );
520
-
521
- if (data -> wrdma_ch < 0 ) {
522
- ret = data -> wrdma_ch ;
523
- goto capture_alloc_err ;
524
- }
525
-
526
- drvdata -> substream [data -> wrdma_ch ] = csubstream ;
527
-
528
559
ret = snd_dma_alloc_pages (SNDRV_DMA_TYPE_DEV ,
529
- soc_runtime -> platform -> dev ,
530
- size , & csubstream -> dma_buffer );
531
- if (ret )
532
- goto capture_alloc_err ;
533
-
534
- ret = regmap_write (drvdata -> lpaif_map ,
535
- LPAIF_WRDMACTL_REG (v , data -> wrdma_ch ), 0 );
560
+ soc_runtime -> platform -> dev ,
561
+ size , & csubstream -> dma_buffer );
536
562
if (ret ) {
537
- dev_err (soc_runtime -> dev ,
538
- "%s() error writing to wrdmactl reg: %d\n" ,
539
- __func__ , ret );
540
- goto capture_reg_err ;
563
+ dev_err (soc_runtime -> platform -> dev ,
564
+ "can't alloc capture dma buffer (%d)\n" , ret );
565
+ if (psubstream )
566
+ snd_dma_free_pages (& psubstream -> dma_buffer );
567
+ return ret ;
541
568
}
542
569
}
543
570
544
571
return 0 ;
545
-
546
- capture_reg_err :
547
- if (csubstream )
548
- snd_dma_free_pages (& csubstream -> dma_buffer );
549
-
550
- capture_alloc_err :
551
- if (psubstream )
552
- snd_dma_free_pages (& psubstream -> dma_buffer );
553
-
554
- playback_alloc_err :
555
- dev_err (soc_runtime -> dev , "Cannot allocate buffer(s)\n" );
556
-
557
- return ret ;
558
572
}
559
573
560
574
static void lpass_platform_pcm_free (struct snd_pcm * pcm )
561
575
{
562
- struct snd_soc_pcm_runtime * rt ;
563
- struct lpass_data * drvdata ;
564
- struct lpass_pcm_data * data ;
565
- struct lpass_variant * v ;
566
576
struct snd_pcm_substream * substream ;
567
- int ch , i ;
577
+ int i ;
568
578
569
579
for (i = 0 ; i < ARRAY_SIZE (pcm -> streams ); i ++ ) {
570
580
substream = pcm -> streams [i ].substream ;
571
581
if (substream ) {
572
- rt = substream -> private_data ;
573
- data = snd_soc_pcm_get_drvdata (rt );
574
- drvdata = snd_soc_platform_get_drvdata (rt -> platform );
575
-
576
- ch = (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
577
- ? data -> rdma_ch
578
- : data -> wrdma_ch ;
579
- v = drvdata -> variant ;
580
- drvdata -> substream [ch ] = NULL ;
581
- if (v -> free_dma_channel )
582
- v -> free_dma_channel (drvdata , ch );
583
-
584
582
snd_dma_free_pages (& substream -> dma_buffer );
585
583
substream -> dma_buffer .area = NULL ;
586
584
substream -> dma_buffer .addr = 0 ;
0 commit comments