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