Merge series "ASoC: soc-component: add snd_soc_component_xxx()" from Kuninori Morimot...
[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_open(struct snd_compr_stream *cstream)
26 {
27         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
28         struct snd_soc_component *component = NULL;
29         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
30         int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
31         int ret;
32
33         ret = snd_soc_pcm_component_pm_runtime_get(rtd, cstream);
34         if (ret < 0)
35                 goto pm_err;
36
37         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
38
39         ret = snd_soc_dai_compr_startup(cpu_dai, cstream);
40         if (ret < 0)
41                 goto out;
42
43         ret = snd_soc_component_compr_open(cstream, &component);
44         if (ret < 0)
45                 goto machine_err;
46
47         ret = snd_soc_link_compr_startup(cstream);
48         if (ret < 0)
49                 goto machine_err;
50
51         snd_soc_runtime_activate(rtd, stream);
52
53         mutex_unlock(&rtd->card->pcm_mutex);
54
55         return 0;
56
57 machine_err:
58         snd_soc_component_compr_free(cstream, component);
59
60         snd_soc_dai_compr_shutdown(cpu_dai, cstream);
61 out:
62         mutex_unlock(&rtd->card->pcm_mutex);
63 pm_err:
64         snd_soc_pcm_component_pm_runtime_put(rtd, cstream, 1);
65
66         return ret;
67 }
68
69 static int soc_compr_open_fe(struct snd_compr_stream *cstream)
70 {
71         struct snd_soc_pcm_runtime *fe = cstream->private_data;
72         struct snd_pcm_substream *fe_substream =
73                  fe->pcm->streams[cstream->direction].substream;
74         struct snd_soc_component *component;
75         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
76         struct snd_soc_dpcm *dpcm;
77         struct snd_soc_dapm_widget_list *list;
78         int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
79         int ret;
80
81         mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
82         fe->dpcm[stream].runtime = fe_substream->runtime;
83
84         ret = dpcm_path_get(fe, stream, &list);
85         if (ret < 0)
86                 goto be_err;
87         else if (ret == 0)
88                 dev_dbg(fe->dev, "Compress ASoC: %s no valid %s route\n",
89                         fe->dai_link->name, stream ? "capture" : "playback");
90         /* calculate valid and active FE <-> BE dpcms */
91         dpcm_process_paths(fe, stream, &list, 1);
92         fe->dpcm[stream].runtime = fe_substream->runtime;
93
94         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
95
96         ret = dpcm_be_dai_startup(fe, stream);
97         if (ret < 0) {
98                 /* clean up all links */
99                 for_each_dpcm_be(fe, stream, dpcm)
100                         dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
101
102                 dpcm_be_disconnect(fe, stream);
103                 fe->dpcm[stream].runtime = NULL;
104                 goto out;
105         }
106
107         ret = snd_soc_dai_compr_startup(cpu_dai, cstream);
108         if (ret < 0)
109                 goto out;
110
111         ret = snd_soc_component_compr_open(cstream, &component);
112         if (ret < 0)
113                 goto open_err;
114
115         ret = snd_soc_link_compr_startup(cstream);
116         if (ret < 0)
117                 goto machine_err;
118
119         dpcm_clear_pending_state(fe, stream);
120         dpcm_path_put(&list);
121
122         fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
123         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
124
125         snd_soc_runtime_activate(fe, stream);
126
127         mutex_unlock(&fe->card->mutex);
128
129         return 0;
130
131 machine_err:
132         snd_soc_component_compr_free(cstream, component);
133 open_err:
134         snd_soc_dai_compr_shutdown(cpu_dai, cstream);
135 out:
136         dpcm_path_put(&list);
137 be_err:
138         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
139         mutex_unlock(&fe->card->mutex);
140         return ret;
141 }
142
143 static int soc_compr_free(struct snd_compr_stream *cstream)
144 {
145         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
146         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
147         struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
148         int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
149
150         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
151
152         snd_soc_runtime_deactivate(rtd, stream);
153
154         snd_soc_dai_digital_mute(codec_dai, 1, stream);
155
156         if (!snd_soc_dai_active(cpu_dai))
157                 cpu_dai->rate = 0;
158
159         if (!snd_soc_dai_active(codec_dai))
160                 codec_dai->rate = 0;
161
162         snd_soc_link_compr_shutdown(cstream);
163
164         snd_soc_component_compr_free(cstream, NULL);
165
166         snd_soc_dai_compr_shutdown(cpu_dai, cstream);
167
168         snd_soc_dapm_stream_stop(rtd, stream);
169
170         mutex_unlock(&rtd->card->pcm_mutex);
171
172         snd_soc_pcm_component_pm_runtime_put(rtd, cstream, 0);
173
174         return 0;
175 }
176
177 static int soc_compr_free_fe(struct snd_compr_stream *cstream)
178 {
179         struct snd_soc_pcm_runtime *fe = cstream->private_data;
180         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
181         struct snd_soc_dpcm *dpcm;
182         int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
183         int ret;
184
185         mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
186
187         snd_soc_runtime_deactivate(fe, stream);
188
189         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
190
191         ret = dpcm_be_dai_hw_free(fe, stream);
192         if (ret < 0)
193                 dev_err(fe->dev, "Compressed ASoC: hw_free failed: %d\n", ret);
194
195         ret = dpcm_be_dai_shutdown(fe, stream);
196
197         /* mark FE's links ready to prune */
198         for_each_dpcm_be(fe, stream, dpcm)
199                 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
200
201         dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
202
203         fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
204         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
205
206         dpcm_be_disconnect(fe, stream);
207
208         fe->dpcm[stream].runtime = NULL;
209
210         snd_soc_link_compr_shutdown(cstream);
211
212         snd_soc_component_compr_free(cstream, NULL);
213
214         snd_soc_dai_compr_shutdown(cpu_dai, cstream);
215
216         mutex_unlock(&fe->card->mutex);
217         return 0;
218 }
219
220 static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
221 {
222         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
223         struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
224         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
225         int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
226         int ret;
227
228         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
229
230         ret = snd_soc_component_compr_trigger(cstream, cmd);
231         if (ret < 0)
232                 goto out;
233
234         ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd);
235         if (ret < 0)
236                 goto out;
237
238         switch (cmd) {
239         case SNDRV_PCM_TRIGGER_START:
240                 snd_soc_dai_digital_mute(codec_dai, 0, stream);
241                 break;
242         case SNDRV_PCM_TRIGGER_STOP:
243                 snd_soc_dai_digital_mute(codec_dai, 1, stream);
244                 break;
245         }
246
247 out:
248         mutex_unlock(&rtd->card->pcm_mutex);
249         return ret;
250 }
251
252 static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
253 {
254         struct snd_soc_pcm_runtime *fe = cstream->private_data;
255         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
256         int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
257         int ret;
258
259         if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
260             cmd == SND_COMPR_TRIGGER_DRAIN)
261                 return snd_soc_component_compr_trigger(cstream, cmd);
262
263         mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
264
265         ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd);
266         if (ret < 0)
267                 goto out;
268
269         ret = snd_soc_component_compr_trigger(cstream, cmd);
270         if (ret < 0)
271                 goto out;
272
273         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
274
275         ret = dpcm_be_dai_trigger(fe, stream, cmd);
276
277         switch (cmd) {
278         case SNDRV_PCM_TRIGGER_START:
279         case SNDRV_PCM_TRIGGER_RESUME:
280         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
281                 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
282                 break;
283         case SNDRV_PCM_TRIGGER_STOP:
284         case SNDRV_PCM_TRIGGER_SUSPEND:
285                 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
286                 break;
287         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
288                 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
289                 break;
290         }
291
292 out:
293         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
294         mutex_unlock(&fe->card->mutex);
295         return ret;
296 }
297
298 static int soc_compr_set_params(struct snd_compr_stream *cstream,
299                                 struct snd_compr_params *params)
300 {
301         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
302         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
303         int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
304         int ret;
305
306         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
307
308         /*
309          * First we call set_params for the CPU DAI, then the component
310          * driver this should configure the SoC side. If the machine has
311          * compressed ops then we call that as well. The expectation is
312          * that these callbacks will configure everything for this compress
313          * path, like configuring a PCM port for a CODEC.
314          */
315         ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params);
316         if (ret < 0)
317                 goto err;
318
319         ret = snd_soc_component_compr_set_params(cstream, params);
320         if (ret < 0)
321                 goto err;
322
323         ret = snd_soc_link_compr_set_params(cstream);
324         if (ret < 0)
325                 goto err;
326
327         snd_soc_dapm_stream_event(rtd, stream, SND_SOC_DAPM_STREAM_START);
328
329         /* cancel any delayed stream shutdown that is pending */
330         rtd->pop_wait = 0;
331         mutex_unlock(&rtd->card->pcm_mutex);
332
333         cancel_delayed_work_sync(&rtd->delayed_work);
334
335         return 0;
336
337 err:
338         mutex_unlock(&rtd->card->pcm_mutex);
339         return ret;
340 }
341
342 static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
343                                    struct snd_compr_params *params)
344 {
345         struct snd_soc_pcm_runtime *fe = cstream->private_data;
346         struct snd_pcm_substream *fe_substream =
347                  fe->pcm->streams[cstream->direction].substream;
348         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0);
349         int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
350         int ret;
351
352         mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
353
354         /*
355          * Create an empty hw_params for the BE as the machine driver must
356          * fix this up to match DSP decoder and ASRC configuration.
357          * I.e. machine driver fixup for compressed BE is mandatory.
358          */
359         memset(&fe->dpcm[fe_substream->stream].hw_params, 0,
360                 sizeof(struct snd_pcm_hw_params));
361
362         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
363
364         ret = dpcm_be_dai_hw_params(fe, stream);
365         if (ret < 0)
366                 goto out;
367
368         ret = dpcm_be_dai_prepare(fe, stream);
369         if (ret < 0)
370                 goto out;
371
372         ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params);
373         if (ret < 0)
374                 goto out;
375
376         ret = snd_soc_component_compr_set_params(cstream, params);
377         if (ret < 0)
378                 goto out;
379
380         ret = snd_soc_link_compr_set_params(cstream);
381         if (ret < 0)
382                 goto out;
383
384         dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
385         fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
386
387 out:
388         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
389         mutex_unlock(&fe->card->mutex);
390         return ret;
391 }
392
393 static int soc_compr_get_params(struct snd_compr_stream *cstream,
394                                 struct snd_codec *params)
395 {
396         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
397         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
398         int ret = 0;
399
400         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
401
402         ret = snd_soc_dai_compr_get_params(cpu_dai, cstream, params);
403         if (ret < 0)
404                 goto err;
405
406         ret = snd_soc_component_compr_get_params(cstream, params);
407 err:
408         mutex_unlock(&rtd->card->pcm_mutex);
409         return ret;
410 }
411
412 static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
413 {
414         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
415         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
416         int ret;
417
418         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
419
420         ret = snd_soc_dai_compr_ack(cpu_dai, cstream, bytes);
421         if (ret < 0)
422                 goto err;
423
424         ret = snd_soc_component_compr_ack(cstream, bytes);
425 err:
426         mutex_unlock(&rtd->card->pcm_mutex);
427         return ret;
428 }
429
430 static int soc_compr_pointer(struct snd_compr_stream *cstream,
431                              struct snd_compr_tstamp *tstamp)
432 {
433         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
434         int ret;
435         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
436
437         mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
438
439         ret = snd_soc_dai_compr_pointer(cpu_dai, cstream, tstamp);
440         if (ret < 0)
441                 goto out;
442
443         ret = snd_soc_component_compr_pointer(cstream, tstamp);
444 out:
445         mutex_unlock(&rtd->card->pcm_mutex);
446         return ret;
447 }
448
449 static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
450                                   struct snd_compr_metadata *metadata)
451 {
452         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
453         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
454         int ret;
455
456         ret = snd_soc_dai_compr_set_metadata(cpu_dai, cstream, metadata);
457         if (ret < 0)
458                 return ret;
459
460         return snd_soc_component_compr_set_metadata(cstream, metadata);
461 }
462
463 static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
464                                   struct snd_compr_metadata *metadata)
465 {
466         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
467         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
468         int ret;
469
470         ret = snd_soc_dai_compr_get_metadata(cpu_dai, cstream, metadata);
471         if (ret < 0)
472                 return ret;
473
474         return snd_soc_component_compr_get_metadata(cstream, metadata);
475 }
476
477 /* ASoC Compress operations */
478 static struct snd_compr_ops soc_compr_ops = {
479         .open           = soc_compr_open,
480         .free           = soc_compr_free,
481         .set_params     = soc_compr_set_params,
482         .set_metadata   = soc_compr_set_metadata,
483         .get_metadata   = soc_compr_get_metadata,
484         .get_params     = soc_compr_get_params,
485         .trigger        = soc_compr_trigger,
486         .pointer        = soc_compr_pointer,
487         .ack            = soc_compr_ack,
488         .get_caps       = snd_soc_component_compr_get_caps,
489         .get_codec_caps = snd_soc_component_compr_get_codec_caps,
490 };
491
492 /* ASoC Dynamic Compress operations */
493 static struct snd_compr_ops soc_compr_dyn_ops = {
494         .open           = soc_compr_open_fe,
495         .free           = soc_compr_free_fe,
496         .set_params     = soc_compr_set_params_fe,
497         .get_params     = soc_compr_get_params,
498         .set_metadata   = soc_compr_set_metadata,
499         .get_metadata   = soc_compr_get_metadata,
500         .trigger        = soc_compr_trigger_fe,
501         .pointer        = soc_compr_pointer,
502         .ack            = soc_compr_ack,
503         .get_caps       = snd_soc_component_compr_get_caps,
504         .get_codec_caps = snd_soc_component_compr_get_codec_caps,
505 };
506
507 /**
508  * snd_soc_new_compress - create a new compress.
509  *
510  * @rtd: The runtime for which we will create compress
511  * @num: the device index number (zero based - shared with normal PCMs)
512  *
513  * Return: 0 for success, else error.
514  */
515 int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
516 {
517         struct snd_soc_component *component;
518         struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
519         struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
520         struct snd_compr *compr;
521         struct snd_pcm *be_pcm;
522         char new_name[64];
523         int ret = 0, direction = 0;
524         int playback = 0, capture = 0;
525         int i;
526
527         /*
528          * make sure these are same value,
529          * and then use these as equally
530          */
531         BUILD_BUG_ON((int)SNDRV_PCM_STREAM_PLAYBACK != (int)SND_COMPRESS_PLAYBACK);
532         BUILD_BUG_ON((int)SNDRV_PCM_STREAM_CAPTURE  != (int)SND_COMPRESS_CAPTURE);
533
534         if (rtd->num_cpus > 1 ||
535             rtd->num_codecs > 1) {
536                 dev_err(rtd->card->dev,
537                         "Compress ASoC: Multi CPU/Codec not supported\n");
538                 return -EINVAL;
539         }
540
541         /* check client and interface hw capabilities */
542         if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
543             snd_soc_dai_stream_valid(cpu_dai,   SNDRV_PCM_STREAM_PLAYBACK))
544                 playback = 1;
545         if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&
546             snd_soc_dai_stream_valid(cpu_dai,   SNDRV_PCM_STREAM_CAPTURE))
547                 capture = 1;
548
549         /*
550          * Compress devices are unidirectional so only one of the directions
551          * should be set, check for that (xor)
552          */
553         if (playback + capture != 1) {
554                 dev_err(rtd->card->dev,
555                         "Compress ASoC: Invalid direction for P %d, C %d\n",
556                         playback, capture);
557                 return -EINVAL;
558         }
559
560         if (playback)
561                 direction = SND_COMPRESS_PLAYBACK;
562         else
563                 direction = SND_COMPRESS_CAPTURE;
564
565         compr = devm_kzalloc(rtd->card->dev, sizeof(*compr), GFP_KERNEL);
566         if (!compr)
567                 return -ENOMEM;
568
569         compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
570                                   GFP_KERNEL);
571         if (!compr->ops)
572                 return -ENOMEM;
573
574         if (rtd->dai_link->dynamic) {
575                 snprintf(new_name, sizeof(new_name), "(%s)",
576                         rtd->dai_link->stream_name);
577
578                 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
579                                 rtd->dai_link->dpcm_playback,
580                                 rtd->dai_link->dpcm_capture, &be_pcm);
581                 if (ret < 0) {
582                         dev_err(rtd->card->dev,
583                                 "Compress ASoC: can't create compressed for %s: %d\n",
584                                 rtd->dai_link->name, ret);
585                         return ret;
586                 }
587
588                 rtd->pcm = be_pcm;
589                 rtd->fe_compr = 1;
590                 if (rtd->dai_link->dpcm_playback)
591                         be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
592                 else if (rtd->dai_link->dpcm_capture)
593                         be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
594                 memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
595         } else {
596                 snprintf(new_name, sizeof(new_name), "%s %s-%d",
597                         rtd->dai_link->stream_name, codec_dai->name, num);
598
599                 memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
600         }
601
602         for_each_rtd_components(rtd, i, component) {
603                 if (!component->driver->compress_ops ||
604                     !component->driver->compress_ops->copy)
605                         continue;
606
607                 compr->ops->copy = snd_soc_component_compr_copy;
608                 break;
609         }
610
611         mutex_init(&compr->lock);
612         ret = snd_compress_new(rtd->card->snd_card, num, direction,
613                                 new_name, compr);
614         if (ret < 0) {
615                 component = asoc_rtd_to_codec(rtd, 0)->component;
616                 dev_err(component->dev,
617                         "Compress ASoC: can't create compress for codec %s: %d\n",
618                         component->name, ret);
619                 return ret;
620         }
621
622         /* DAPM dai link stream work */
623         rtd->close_delayed_work_func = snd_soc_close_delayed_work;
624
625         rtd->compr = compr;
626         compr->private_data = rtd;
627
628         dev_dbg(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n",
629                 codec_dai->name, cpu_dai->name);
630
631         return 0;
632 }
633 EXPORT_SYMBOL_GPL(snd_soc_new_compress);