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