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