]> asedeno.scripts.mit.edu Git - linux.git/blob - sound/soc/soc-compress.c
Merge tag 'sdw_interfaces_5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul...
[linux.git] / sound / soc / soc-compress.c
1 // SPDX-License-Identifier: GPL-2.0+
2 //
3 // soc-compress.c  --  ALSA SoC Compress
4 //
5 // Copyright (C) 2012 Intel Corp.
6 //
7 // Authors: Namarta Kohli <namartax.kohli@intel.com>
8 //          Ramesh Babu K V <ramesh.babu@linux.intel.com>
9 //          Vinod Koul <vinod.koul@linux.intel.com>
10
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/delay.h>
14 #include <linux/slab.h>
15 #include <linux/workqueue.h>
16 #include <sound/core.h>
17 #include <sound/compress_params.h>
18 #include <sound/compress_driver.h>
19 #include <sound/soc.h>
20 #include <sound/initval.h>
21 #include <sound/soc-dpcm.h>
22 #include <linux/pm_runtime.h>
23
24 static int soc_compr_components_open(struct snd_compr_stream *cstream,
25                                      struct snd_soc_component **last)
26 {
27         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
28         struct snd_soc_component *component;
29         struct snd_soc_rtdcom_list *rtdcom;
30         int ret;
31
32         for_each_rtd_components(rtd, rtdcom, component) {
33                 if (!component->driver->compr_ops ||
34                     !component->driver->compr_ops->open)
35                         continue;
36
37                 ret = component->driver->compr_ops->open(cstream);
38                 if (ret < 0) {
39                         dev_err(component->dev,
40                                 "Compress ASoC: can't open platform %s: %d\n",
41                                 component->name, ret);
42
43                         *last = component;
44                         return ret;
45                 }
46         }
47
48         *last = NULL;
49         return 0;
50 }
51
52 static int soc_compr_components_free(struct snd_compr_stream *cstream,
53                                      struct snd_soc_component *last)
54 {
55         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
56         struct snd_soc_component *component;
57         struct snd_soc_rtdcom_list *rtdcom;
58
59         for_each_rtd_components(rtd, rtdcom, component) {
60                 if (component == last)
61                         break;
62
63                 if (!component->driver->compr_ops ||
64                     !component->driver->compr_ops->free)
65                         continue;
66
67                 component->driver->compr_ops->free(cstream);
68         }
69
70         return 0;
71 }
72
73 static int soc_compr_open(struct snd_compr_stream *cstream)
74 {
75         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
76         struct snd_soc_component *component, *save = NULL;
77         struct snd_soc_rtdcom_list *rtdcom;
78         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
79         int ret;
80
81         for_each_rtd_components(rtd, rtdcom, component) {
82                 ret = pm_runtime_get_sync(component->dev);
83                 if (ret < 0 && ret != -EACCES) {
84                         pm_runtime_put_noidle(component->dev);
85                         save = component;
86                         goto pm_err;
87                 }
88         }
89
90         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
91
92         if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
93                 ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
94                 if (ret < 0) {
95                         dev_err(cpu_dai->dev,
96                                 "Compress ASoC: can't open interface %s: %d\n",
97                                 cpu_dai->name, ret);
98                         goto out;
99                 }
100         }
101
102         ret = soc_compr_components_open(cstream, &component);
103         if (ret < 0)
104                 goto machine_err;
105
106         if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) {
107                 ret = rtd->dai_link->compr_ops->startup(cstream);
108                 if (ret < 0) {
109                         dev_err(rtd->dev,
110                                 "Compress ASoC: %s startup failed: %d\n",
111                                 rtd->dai_link->name, ret);
112                         goto machine_err;
113                 }
114         }
115
116         snd_soc_runtime_activate(rtd, cstream->direction);
117
118         mutex_unlock(&rtd->card->pcm_mutex);
119
120         return 0;
121
122 machine_err:
123         soc_compr_components_free(cstream, component);
124
125         if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
126                 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
127 out:
128         mutex_unlock(&rtd->card->pcm_mutex);
129 pm_err:
130         for_each_rtd_components(rtd, rtdcom, component) {
131                 if (component == save)
132                         break;
133                 pm_runtime_mark_last_busy(component->dev);
134                 pm_runtime_put_autosuspend(component->dev);
135         }
136
137         return ret;
138 }
139
140 static int soc_compr_open_fe(struct snd_compr_stream *cstream)
141 {
142         struct snd_soc_pcm_runtime *fe = cstream->private_data;
143         struct snd_pcm_substream *fe_substream =
144                  fe->pcm->streams[cstream->direction].substream;
145         struct snd_soc_component *component;
146         struct snd_soc_dai *cpu_dai = fe->cpu_dai;
147         struct snd_soc_dpcm *dpcm;
148         struct snd_soc_dapm_widget_list *list;
149         int stream;
150         int ret;
151
152         if (cstream->direction == SND_COMPRESS_PLAYBACK)
153                 stream = SNDRV_PCM_STREAM_PLAYBACK;
154         else
155                 stream = SNDRV_PCM_STREAM_CAPTURE;
156
157         mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
158         fe->dpcm[stream].runtime = fe_substream->runtime;
159
160         ret = dpcm_path_get(fe, stream, &list);
161         if (ret < 0)
162                 goto be_err;
163         else if (ret == 0)
164                 dev_dbg(fe->dev, "Compress ASoC: %s no valid %s route\n",
165                         fe->dai_link->name, stream ? "capture" : "playback");
166         /* calculate valid and active FE <-> BE dpcms */
167         dpcm_process_paths(fe, stream, &list, 1);
168         fe->dpcm[stream].runtime = fe_substream->runtime;
169
170         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
171
172         ret = dpcm_be_dai_startup(fe, stream);
173         if (ret < 0) {
174                 /* clean up all links */
175                 for_each_dpcm_be(fe, stream, dpcm)
176                         dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
177
178                 dpcm_be_disconnect(fe, stream);
179                 fe->dpcm[stream].runtime = NULL;
180                 goto out;
181         }
182
183         if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
184                 ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
185                 if (ret < 0) {
186                         dev_err(cpu_dai->dev,
187                                 "Compress ASoC: can't open interface %s: %d\n",
188                                 cpu_dai->name, ret);
189                         goto out;
190                 }
191         }
192
193         ret = soc_compr_components_open(cstream, &component);
194         if (ret < 0)
195                 goto open_err;
196
197         if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->startup) {
198                 ret = fe->dai_link->compr_ops->startup(cstream);
199                 if (ret < 0) {
200                         pr_err("Compress ASoC: %s startup failed: %d\n",
201                                fe->dai_link->name, ret);
202                         goto machine_err;
203                 }
204         }
205
206         dpcm_clear_pending_state(fe, stream);
207         dpcm_path_put(&list);
208
209         fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
210         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
211
212         snd_soc_runtime_activate(fe, stream);
213
214         mutex_unlock(&fe->card->mutex);
215
216         return 0;
217
218 machine_err:
219         soc_compr_components_free(cstream, component);
220 open_err:
221         if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
222                 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
223 out:
224         dpcm_path_put(&list);
225 be_err:
226         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
227         mutex_unlock(&fe->card->mutex);
228         return ret;
229 }
230
231 /*
232  * Power down the audio subsystem pmdown_time msecs after close is called.
233  * This is to ensure there are no pops or clicks in between any music tracks
234  * due to DAPM power cycling.
235  */
236 static void close_delayed_work(struct snd_soc_pcm_runtime *rtd)
237 {
238         struct snd_soc_dai *codec_dai = rtd->codec_dai;
239
240         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
241
242         dev_dbg(rtd->dev,
243                 "Compress ASoC: pop wq checking: %s status: %s waiting: %s\n",
244                 codec_dai->driver->playback.stream_name,
245                 codec_dai->playback_active ? "active" : "inactive",
246                 rtd->pop_wait ? "yes" : "no");
247
248         /* are we waiting on this codec DAI stream */
249         if (rtd->pop_wait == 1) {
250                 rtd->pop_wait = 0;
251                 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
252                                           SND_SOC_DAPM_STREAM_STOP);
253         }
254
255         mutex_unlock(&rtd->card->pcm_mutex);
256 }
257
258 static int soc_compr_free(struct snd_compr_stream *cstream)
259 {
260         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
261         struct snd_soc_component *component;
262         struct snd_soc_rtdcom_list *rtdcom;
263         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
264         struct snd_soc_dai *codec_dai = rtd->codec_dai;
265         int stream;
266
267         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
268
269         if (cstream->direction == SND_COMPRESS_PLAYBACK)
270                 stream = SNDRV_PCM_STREAM_PLAYBACK;
271         else
272                 stream = SNDRV_PCM_STREAM_CAPTURE;
273
274         snd_soc_runtime_deactivate(rtd, stream);
275
276         snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
277
278         if (!cpu_dai->active)
279                 cpu_dai->rate = 0;
280
281         if (!codec_dai->active)
282                 codec_dai->rate = 0;
283
284         if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown)
285                 rtd->dai_link->compr_ops->shutdown(cstream);
286
287         soc_compr_components_free(cstream, NULL);
288
289         if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
290                 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
291
292         if (cstream->direction == SND_COMPRESS_PLAYBACK) {
293                 if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
294                         snd_soc_dapm_stream_event(rtd,
295                                                   SNDRV_PCM_STREAM_PLAYBACK,
296                                                   SND_SOC_DAPM_STREAM_STOP);
297                 } else {
298                         rtd->pop_wait = 1;
299                         queue_delayed_work(system_power_efficient_wq,
300                                            &rtd->delayed_work,
301                                            msecs_to_jiffies(rtd->pmdown_time));
302                 }
303         } else {
304                 /* capture streams can be powered down now */
305                 snd_soc_dapm_stream_event(rtd,
306                                           SNDRV_PCM_STREAM_CAPTURE,
307                                           SND_SOC_DAPM_STREAM_STOP);
308         }
309
310         mutex_unlock(&rtd->card->pcm_mutex);
311
312         for_each_rtd_components(rtd, rtdcom, component) {
313                 pm_runtime_mark_last_busy(component->dev);
314                 pm_runtime_put_autosuspend(component->dev);
315         }
316
317         return 0;
318 }
319
320 static int soc_compr_free_fe(struct snd_compr_stream *cstream)
321 {
322         struct snd_soc_pcm_runtime *fe = cstream->private_data;
323         struct snd_soc_dai *cpu_dai = fe->cpu_dai;
324         struct snd_soc_dpcm *dpcm;
325         int stream, ret;
326
327         mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
328
329         if (cstream->direction == SND_COMPRESS_PLAYBACK)
330                 stream = SNDRV_PCM_STREAM_PLAYBACK;
331         else
332                 stream = SNDRV_PCM_STREAM_CAPTURE;
333
334         snd_soc_runtime_deactivate(fe, stream);
335
336         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
337
338         ret = dpcm_be_dai_hw_free(fe, stream);
339         if (ret < 0)
340                 dev_err(fe->dev, "Compressed ASoC: hw_free failed: %d\n", ret);
341
342         ret = dpcm_be_dai_shutdown(fe, stream);
343
344         /* mark FE's links ready to prune */
345         for_each_dpcm_be(fe, stream, dpcm)
346                 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
347
348         dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
349
350         fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
351         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
352
353         dpcm_be_disconnect(fe, stream);
354
355         fe->dpcm[stream].runtime = NULL;
356
357         if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
358                 fe->dai_link->compr_ops->shutdown(cstream);
359
360         soc_compr_components_free(cstream, NULL);
361
362         if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
363                 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
364
365         mutex_unlock(&fe->card->mutex);
366         return 0;
367 }
368
369 static int soc_compr_components_trigger(struct snd_compr_stream *cstream,
370                                         int cmd)
371 {
372         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
373         struct snd_soc_component *component;
374         struct snd_soc_rtdcom_list *rtdcom;
375         int ret;
376
377         for_each_rtd_components(rtd, rtdcom, component) {
378                 if (!component->driver->compr_ops ||
379                     !component->driver->compr_ops->trigger)
380                         continue;
381
382                 ret = component->driver->compr_ops->trigger(cstream, cmd);
383                 if (ret < 0)
384                         return ret;
385         }
386
387         return 0;
388 }
389
390 static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
391 {
392         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
393         struct snd_soc_dai *codec_dai = rtd->codec_dai;
394         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
395         int ret;
396
397         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
398
399         ret = soc_compr_components_trigger(cstream, cmd);
400         if (ret < 0)
401                 goto out;
402
403         if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger)
404                 cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
405
406         switch (cmd) {
407         case SNDRV_PCM_TRIGGER_START:
408                 snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction);
409                 break;
410         case SNDRV_PCM_TRIGGER_STOP:
411                 snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
412                 break;
413         }
414
415 out:
416         mutex_unlock(&rtd->card->pcm_mutex);
417         return ret;
418 }
419
420 static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
421 {
422         struct snd_soc_pcm_runtime *fe = cstream->private_data;
423         struct snd_soc_dai *cpu_dai = fe->cpu_dai;
424         int ret, stream;
425
426         if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
427             cmd == SND_COMPR_TRIGGER_DRAIN)
428                 return soc_compr_components_trigger(cstream, cmd);
429
430         if (cstream->direction == SND_COMPRESS_PLAYBACK)
431                 stream = SNDRV_PCM_STREAM_PLAYBACK;
432         else
433                 stream = SNDRV_PCM_STREAM_CAPTURE;
434
435         mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
436
437         if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger) {
438                 ret = cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
439                 if (ret < 0)
440                         goto out;
441         }
442
443         ret = soc_compr_components_trigger(cstream, cmd);
444         if (ret < 0)
445                 goto out;
446
447         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
448
449         ret = dpcm_be_dai_trigger(fe, stream, cmd);
450
451         switch (cmd) {
452         case SNDRV_PCM_TRIGGER_START:
453         case SNDRV_PCM_TRIGGER_RESUME:
454         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
455                 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
456                 break;
457         case SNDRV_PCM_TRIGGER_STOP:
458         case SNDRV_PCM_TRIGGER_SUSPEND:
459                 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
460                 break;
461         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
462                 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
463                 break;
464         }
465
466 out:
467         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
468         mutex_unlock(&fe->card->mutex);
469         return ret;
470 }
471
472 static int soc_compr_components_set_params(struct snd_compr_stream *cstream,
473                                            struct snd_compr_params *params)
474 {
475         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
476         struct snd_soc_component *component;
477         struct snd_soc_rtdcom_list *rtdcom;
478         int ret;
479
480         for_each_rtd_components(rtd, rtdcom, component) {
481                 if (!component->driver->compr_ops ||
482                     !component->driver->compr_ops->set_params)
483                         continue;
484
485                 ret = component->driver->compr_ops->set_params(cstream, params);
486                 if (ret < 0)
487                         return ret;
488         }
489
490         return 0;
491 }
492
493 static int soc_compr_set_params(struct snd_compr_stream *cstream,
494                                 struct snd_compr_params *params)
495 {
496         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
497         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
498         int ret;
499
500         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
501
502         /*
503          * First we call set_params for the CPU DAI, then the component
504          * driver this should configure the SoC side. If the machine has
505          * compressed ops then we call that as well. The expectation is
506          * that these callbacks will configure everything for this compress
507          * path, like configuring a PCM port for a CODEC.
508          */
509         if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
510                 ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
511                 if (ret < 0)
512                         goto err;
513         }
514
515         ret = soc_compr_components_set_params(cstream, params);
516         if (ret < 0)
517                 goto err;
518
519         if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) {
520                 ret = rtd->dai_link->compr_ops->set_params(cstream);
521                 if (ret < 0)
522                         goto err;
523         }
524
525         if (cstream->direction == SND_COMPRESS_PLAYBACK)
526                 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
527                                           SND_SOC_DAPM_STREAM_START);
528         else
529                 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
530                                           SND_SOC_DAPM_STREAM_START);
531
532         /* cancel any delayed stream shutdown that is pending */
533         rtd->pop_wait = 0;
534         mutex_unlock(&rtd->card->pcm_mutex);
535
536         cancel_delayed_work_sync(&rtd->delayed_work);
537
538         return 0;
539
540 err:
541         mutex_unlock(&rtd->card->pcm_mutex);
542         return ret;
543 }
544
545 static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
546                                    struct snd_compr_params *params)
547 {
548         struct snd_soc_pcm_runtime *fe = cstream->private_data;
549         struct snd_pcm_substream *fe_substream =
550                  fe->pcm->streams[cstream->direction].substream;
551         struct snd_soc_dai *cpu_dai = fe->cpu_dai;
552         int ret, stream;
553
554         if (cstream->direction == SND_COMPRESS_PLAYBACK)
555                 stream = SNDRV_PCM_STREAM_PLAYBACK;
556         else
557                 stream = SNDRV_PCM_STREAM_CAPTURE;
558
559         mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
560
561         /*
562          * Create an empty hw_params for the BE as the machine driver must
563          * fix this up to match DSP decoder and ASRC configuration.
564          * I.e. machine driver fixup for compressed BE is mandatory.
565          */
566         memset(&fe->dpcm[fe_substream->stream].hw_params, 0,
567                 sizeof(struct snd_pcm_hw_params));
568
569         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
570
571         ret = dpcm_be_dai_hw_params(fe, stream);
572         if (ret < 0)
573                 goto out;
574
575         ret = dpcm_be_dai_prepare(fe, stream);
576         if (ret < 0)
577                 goto out;
578
579         if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
580                 ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
581                 if (ret < 0)
582                         goto out;
583         }
584
585         ret = soc_compr_components_set_params(cstream, params);
586         if (ret < 0)
587                 goto out;
588
589         if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->set_params) {
590                 ret = fe->dai_link->compr_ops->set_params(cstream);
591                 if (ret < 0)
592                         goto out;
593         }
594
595         dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
596         fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
597
598 out:
599         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
600         mutex_unlock(&fe->card->mutex);
601         return ret;
602 }
603
604 static int soc_compr_get_params(struct snd_compr_stream *cstream,
605                                 struct snd_codec *params)
606 {
607         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
608         struct snd_soc_component *component;
609         struct snd_soc_rtdcom_list *rtdcom;
610         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
611         int ret = 0;
612
613         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
614
615         if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_params) {
616                 ret = cpu_dai->driver->cops->get_params(cstream, params, cpu_dai);
617                 if (ret < 0)
618                         goto err;
619         }
620
621         for_each_rtd_components(rtd, rtdcom, component) {
622                 if (!component->driver->compr_ops ||
623                     !component->driver->compr_ops->get_params)
624                         continue;
625
626                 ret = component->driver->compr_ops->get_params(cstream, params);
627                 break;
628         }
629
630 err:
631         mutex_unlock(&rtd->card->pcm_mutex);
632         return ret;
633 }
634
635 static int soc_compr_get_caps(struct snd_compr_stream *cstream,
636                               struct snd_compr_caps *caps)
637 {
638         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
639         struct snd_soc_component *component;
640         struct snd_soc_rtdcom_list *rtdcom;
641         int ret = 0;
642
643         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
644
645         for_each_rtd_components(rtd, rtdcom, component) {
646                 if (!component->driver->compr_ops ||
647                     !component->driver->compr_ops->get_caps)
648                         continue;
649
650                 ret = component->driver->compr_ops->get_caps(cstream, caps);
651                 break;
652         }
653
654         mutex_unlock(&rtd->card->pcm_mutex);
655         return ret;
656 }
657
658 static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
659                                     struct snd_compr_codec_caps *codec)
660 {
661         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
662         struct snd_soc_component *component;
663         struct snd_soc_rtdcom_list *rtdcom;
664         int ret = 0;
665
666         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
667
668         for_each_rtd_components(rtd, rtdcom, component) {
669                 if (!component->driver->compr_ops ||
670                     !component->driver->compr_ops->get_codec_caps)
671                         continue;
672
673                 ret = component->driver->compr_ops->get_codec_caps(cstream,
674                                                                    codec);
675                 break;
676         }
677
678         mutex_unlock(&rtd->card->pcm_mutex);
679         return ret;
680 }
681
682 static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
683 {
684         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
685         struct snd_soc_component *component;
686         struct snd_soc_rtdcom_list *rtdcom;
687         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
688         int ret = 0;
689
690         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
691
692         if (cpu_dai->driver->cops && cpu_dai->driver->cops->ack) {
693                 ret = cpu_dai->driver->cops->ack(cstream, bytes, cpu_dai);
694                 if (ret < 0)
695                         goto err;
696         }
697
698         for_each_rtd_components(rtd, rtdcom, component) {
699                 if (!component->driver->compr_ops ||
700                     !component->driver->compr_ops->ack)
701                         continue;
702
703                 ret = component->driver->compr_ops->ack(cstream, bytes);
704                 if (ret < 0)
705                         goto err;
706         }
707
708 err:
709         mutex_unlock(&rtd->card->pcm_mutex);
710         return ret;
711 }
712
713 static int soc_compr_pointer(struct snd_compr_stream *cstream,
714                              struct snd_compr_tstamp *tstamp)
715 {
716         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
717         struct snd_soc_component *component;
718         struct snd_soc_rtdcom_list *rtdcom;
719         int ret = 0;
720         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
721
722         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
723
724         if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
725                 cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
726
727         for_each_rtd_components(rtd, rtdcom, component) {
728                 if (!component->driver->compr_ops ||
729                     !component->driver->compr_ops->pointer)
730                         continue;
731
732                 ret = component->driver->compr_ops->pointer(cstream, tstamp);
733                 break;
734         }
735
736         mutex_unlock(&rtd->card->pcm_mutex);
737         return ret;
738 }
739
740 static int soc_compr_copy(struct snd_compr_stream *cstream,
741                           char __user *buf, size_t count)
742 {
743         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
744         struct snd_soc_component *component;
745         struct snd_soc_rtdcom_list *rtdcom;
746         int ret = 0;
747
748         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
749
750         for_each_rtd_components(rtd, rtdcom, component) {
751                 if (!component->driver->compr_ops ||
752                     !component->driver->compr_ops->copy)
753                         continue;
754
755                 ret = component->driver->compr_ops->copy(cstream, buf, count);
756                 break;
757         }
758
759         mutex_unlock(&rtd->card->pcm_mutex);
760         return ret;
761 }
762
763 static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
764                                   struct snd_compr_metadata *metadata)
765 {
766         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
767         struct snd_soc_component *component;
768         struct snd_soc_rtdcom_list *rtdcom;
769         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
770         int ret;
771
772         if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_metadata) {
773                 ret = cpu_dai->driver->cops->set_metadata(cstream, metadata, cpu_dai);
774                 if (ret < 0)
775                         return ret;
776         }
777
778         for_each_rtd_components(rtd, rtdcom, component) {
779                 if (!component->driver->compr_ops ||
780                     !component->driver->compr_ops->set_metadata)
781                         continue;
782
783                 ret = component->driver->compr_ops->set_metadata(cstream,
784                                                                  metadata);
785                 if (ret < 0)
786                         return ret;
787         }
788
789         return 0;
790 }
791
792 static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
793                                   struct snd_compr_metadata *metadata)
794 {
795         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
796         struct snd_soc_component *component;
797         struct snd_soc_rtdcom_list *rtdcom;
798         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
799         int ret;
800
801         if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_metadata) {
802                 ret = cpu_dai->driver->cops->get_metadata(cstream, metadata, cpu_dai);
803                 if (ret < 0)
804                         return ret;
805         }
806
807         for_each_rtd_components(rtd, rtdcom, component) {
808                 if (!component->driver->compr_ops ||
809                     !component->driver->compr_ops->get_metadata)
810                         continue;
811
812                 return component->driver->compr_ops->get_metadata(cstream,
813                                                                   metadata);
814         }
815
816         return 0;
817 }
818
819 /* ASoC Compress operations */
820 static struct snd_compr_ops soc_compr_ops = {
821         .open           = soc_compr_open,
822         .free           = soc_compr_free,
823         .set_params     = soc_compr_set_params,
824         .set_metadata   = soc_compr_set_metadata,
825         .get_metadata   = soc_compr_get_metadata,
826         .get_params     = soc_compr_get_params,
827         .trigger        = soc_compr_trigger,
828         .pointer        = soc_compr_pointer,
829         .ack            = soc_compr_ack,
830         .get_caps       = soc_compr_get_caps,
831         .get_codec_caps = soc_compr_get_codec_caps
832 };
833
834 /* ASoC Dynamic Compress operations */
835 static struct snd_compr_ops soc_compr_dyn_ops = {
836         .open           = soc_compr_open_fe,
837         .free           = soc_compr_free_fe,
838         .set_params     = soc_compr_set_params_fe,
839         .get_params     = soc_compr_get_params,
840         .set_metadata   = soc_compr_set_metadata,
841         .get_metadata   = soc_compr_get_metadata,
842         .trigger        = soc_compr_trigger_fe,
843         .pointer        = soc_compr_pointer,
844         .ack            = soc_compr_ack,
845         .get_caps       = soc_compr_get_caps,
846         .get_codec_caps = soc_compr_get_codec_caps
847 };
848
849 /**
850  * snd_soc_new_compress - create a new compress.
851  *
852  * @rtd: The runtime for which we will create compress
853  * @num: the device index number (zero based - shared with normal PCMs)
854  *
855  * Return: 0 for success, else error.
856  */
857 int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
858 {
859         struct snd_soc_component *component;
860         struct snd_soc_rtdcom_list *rtdcom;
861         struct snd_soc_dai *codec_dai = rtd->codec_dai;
862         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
863         struct snd_compr *compr;
864         struct snd_pcm *be_pcm;
865         char new_name[64];
866         int ret = 0, direction = 0;
867         int playback = 0, capture = 0;
868
869         if (rtd->num_codecs > 1) {
870                 dev_err(rtd->card->dev,
871                         "Compress ASoC: Multicodec not supported\n");
872                 return -EINVAL;
873         }
874
875         /* check client and interface hw capabilities */
876         if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
877             snd_soc_dai_stream_valid(cpu_dai,   SNDRV_PCM_STREAM_PLAYBACK))
878                 playback = 1;
879         if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&
880             snd_soc_dai_stream_valid(cpu_dai,   SNDRV_PCM_STREAM_CAPTURE))
881                 capture = 1;
882
883         /*
884          * Compress devices are unidirectional so only one of the directions
885          * should be set, check for that (xor)
886          */
887         if (playback + capture != 1) {
888                 dev_err(rtd->card->dev,
889                         "Compress ASoC: Invalid direction for P %d, C %d\n",
890                         playback, capture);
891                 return -EINVAL;
892         }
893
894         if (playback)
895                 direction = SND_COMPRESS_PLAYBACK;
896         else
897                 direction = SND_COMPRESS_CAPTURE;
898
899         compr = devm_kzalloc(rtd->card->dev, sizeof(*compr), GFP_KERNEL);
900         if (!compr)
901                 return -ENOMEM;
902
903         compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
904                                   GFP_KERNEL);
905         if (!compr->ops)
906                 return -ENOMEM;
907
908         if (rtd->dai_link->dynamic) {
909                 snprintf(new_name, sizeof(new_name), "(%s)",
910                         rtd->dai_link->stream_name);
911
912                 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
913                                 rtd->dai_link->dpcm_playback,
914                                 rtd->dai_link->dpcm_capture, &be_pcm);
915                 if (ret < 0) {
916                         dev_err(rtd->card->dev,
917                                 "Compress ASoC: can't create compressed for %s: %d\n",
918                                 rtd->dai_link->name, ret);
919                         return ret;
920                 }
921
922                 rtd->pcm = be_pcm;
923                 rtd->fe_compr = 1;
924                 if (rtd->dai_link->dpcm_playback)
925                         be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
926                 else if (rtd->dai_link->dpcm_capture)
927                         be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
928                 memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
929         } else {
930                 snprintf(new_name, sizeof(new_name), "%s %s-%d",
931                         rtd->dai_link->stream_name, codec_dai->name, num);
932
933                 memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
934         }
935
936         for_each_rtd_components(rtd, rtdcom, component) {
937                 if (!component->driver->compr_ops ||
938                     !component->driver->compr_ops->copy)
939                         continue;
940
941                 compr->ops->copy = soc_compr_copy;
942                 break;
943         }
944
945         mutex_init(&compr->lock);
946         ret = snd_compress_new(rtd->card->snd_card, num, direction,
947                                 new_name, compr);
948         if (ret < 0) {
949                 component = rtd->codec_dai->component;
950                 dev_err(component->dev,
951                         "Compress ASoC: can't create compress for codec %s: %d\n",
952                         component->name, ret);
953                 return ret;
954         }
955
956         /* DAPM dai link stream work */
957         rtd->close_delayed_work_func = close_delayed_work;
958
959         rtd->compr = compr;
960         compr->private_data = rtd;
961
962         dev_info(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n",
963                  codec_dai->name, cpu_dai->name);
964
965         return 0;
966 }
967 EXPORT_SYMBOL_GPL(snd_soc_new_compress);