@@ -61,7 +61,36 @@ static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream)
6161{
6262 struct snd_pcm_runtime * runtime = substream -> runtime ;
6363 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+ }
6594
6695 snd_soc_set_runtime_hwparams (substream , & lpass_platform_pcm_hardware );
6796
@@ -72,11 +101,39 @@ static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream)
72101 if (ret < 0 ) {
73102 dev_err (soc_runtime -> dev , "%s() setting constraints failed: %d\n" ,
74103 __func__ , ret );
75- return - EINVAL ;
104+ goto err ;
76105 }
77106
78107 snd_pcm_set_runtime_buffer (substream , & substream -> dma_buffer );
79108
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+
80137 return 0 ;
81138}
82139
@@ -374,6 +431,7 @@ static int lpass_platform_pcmops_mmap(struct snd_pcm_substream *substream,
374431
375432static struct snd_pcm_ops lpass_platform_pcm_ops = {
376433 .open = lpass_platform_pcmops_open ,
434+ .close = lpass_platform_pcmops_close ,
377435 .ioctl = snd_pcm_lib_ioctl ,
378436 .hw_params = lpass_platform_pcmops_hw_params ,
379437 .hw_free = lpass_platform_pcmops_hw_free ,
@@ -471,14 +529,12 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
471529 struct snd_pcm * pcm = soc_runtime -> pcm ;
472530 struct snd_pcm_substream * psubstream , * csubstream ;
473531 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 ;
532+ struct device * dev = soc_runtime -> platform -> dev ;
478533 struct lpass_pcm_data * data ;
479534 size_t size = lpass_platform_pcm_hardware .buffer_bytes_max ;
535+ int ret = - EINVAL ;
480536
481- data = devm_kzalloc (soc_runtime -> dev , sizeof (* data ), GFP_KERNEL );
537+ data = devm_kzalloc (dev , sizeof (* data ), GFP_KERNEL );
482538 if (!data )
483539 return - ENOMEM ;
484540
@@ -487,100 +543,37 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
487543
488544 psubstream = pcm -> streams [SNDRV_PCM_STREAM_PLAYBACK ].substream ;
489545 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- 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 );
546+ ret = snd_dma_alloc_pages (SNDRV_DMA_TYPE_DEV , dev , size ,
547+ & psubstream -> dma_buffer );
507548 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 ;
549+ dev_err (dev , "can't alloc playback dma buffer\n" );
550+ return ret ;
512551 }
513552 }
514553
515554 csubstream = pcm -> streams [SNDRV_PCM_STREAM_CAPTURE ].substream ;
516555 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- 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 );
556+ ret = snd_dma_alloc_pages (SNDRV_DMA_TYPE_DEV , dev , size ,
557+ & csubstream -> dma_buffer );
536558 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 ;
559+ dev_err (dev , "can't alloc capture dma buffer\n" );
560+ if ( psubstream )
561+ snd_dma_free_pages ( & psubstream -> dma_buffer );
562+ return ret ;
541563 }
542564 }
543565
544566 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 ;
558567}
559568
560569static void lpass_platform_pcm_free (struct snd_pcm * pcm )
561570{
562- struct snd_soc_pcm_runtime * rt ;
563- struct lpass_data * drvdata ;
564- struct lpass_pcm_data * data ;
565- struct lpass_variant * v ;
566571 struct snd_pcm_substream * substream ;
567- int ch , i ;
572+ int i ;
568573
569574 for (i = 0 ; i < ARRAY_SIZE (pcm -> streams ); i ++ ) {
570575 substream = pcm -> streams [i ].substream ;
571576 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-
584577 snd_dma_free_pages (& substream -> dma_buffer );
585578 substream -> dma_buffer .area = NULL ;
586579 substream -> dma_buffer .addr = 0 ;
0 commit comments