]> asedeno.scripts.mit.edu Git - linux.git/blob - sound/soc/soc-compress.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livep...
[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_open(struct snd_compr_stream *cstream)
30 {
31         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
32         struct snd_soc_platform *platform = rtd->platform;
33         struct snd_soc_component *component;
34         struct snd_soc_rtdcom_list *rtdcom;
35         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
36         int ret = 0, __ret;
37
38         mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
39
40         if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
41                 ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
42                 if (ret < 0) {
43                         dev_err(cpu_dai->dev,
44                                 "Compress ASoC: can't open interface %s: %d\n",
45                                 cpu_dai->name, ret);
46                         goto out;
47                 }
48         }
49
50         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->open) {
51                 ret = platform->driver->compr_ops->open(cstream);
52                 if (ret < 0) {
53                         dev_err(platform->dev,
54                                 "Compress ASoC: can't open platform %s: %d\n",
55                                 platform->component.name, ret);
56                         goto plat_err;
57                 }
58         }
59
60         for_each_rtdcom(rtd, rtdcom) {
61                 component = rtdcom->component;
62
63                 /* ignore duplication for now */
64                 if (platform && (component == &platform->component))
65                         continue;
66
67                 if (!component->driver->compr_ops ||
68                     !component->driver->compr_ops->open)
69                         continue;
70
71                 __ret = component->driver->compr_ops->open(cstream);
72                 if (__ret < 0) {
73                         dev_err(component->dev,
74                                 "Compress ASoC: can't open platform %s: %d\n",
75                                 component->name, __ret);
76                         ret = __ret;
77                 }
78         }
79         if (ret < 0)
80                 goto machine_err;
81
82         if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) {
83                 ret = rtd->dai_link->compr_ops->startup(cstream);
84                 if (ret < 0) {
85                         dev_err(rtd->dev,
86                                 "Compress ASoC: %s startup failed: %d\n",
87                                 rtd->dai_link->name, ret);
88                         goto machine_err;
89                 }
90         }
91
92         snd_soc_runtime_activate(rtd, cstream->direction);
93
94         mutex_unlock(&rtd->pcm_mutex);
95
96         return 0;
97
98 machine_err:
99         for_each_rtdcom(rtd, rtdcom) {
100                 component = rtdcom->component;
101
102                 /* ignore duplication for now */
103                 if (platform && (component == &platform->component))
104                         continue;
105
106                 if (!component->driver->compr_ops ||
107                     !component->driver->compr_ops->free)
108                         continue;
109
110                 component->driver->compr_ops->free(cstream);
111         }
112
113         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
114                 platform->driver->compr_ops->free(cstream);
115 plat_err:
116         if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
117                 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
118 out:
119         mutex_unlock(&rtd->pcm_mutex);
120         return ret;
121 }
122
123 static int soc_compr_open_fe(struct snd_compr_stream *cstream)
124 {
125         struct snd_soc_pcm_runtime *fe = cstream->private_data;
126         struct snd_pcm_substream *fe_substream =
127                  fe->pcm->streams[cstream->direction].substream;
128         struct snd_soc_platform *platform = fe->platform;
129         struct snd_soc_component *component;
130         struct snd_soc_rtdcom_list *rtdcom;
131         struct snd_soc_dai *cpu_dai = fe->cpu_dai;
132         struct snd_soc_dpcm *dpcm;
133         struct snd_soc_dapm_widget_list *list;
134         int stream;
135         int ret = 0, __ret;
136
137         if (cstream->direction == SND_COMPRESS_PLAYBACK)
138                 stream = SNDRV_PCM_STREAM_PLAYBACK;
139         else
140                 stream = SNDRV_PCM_STREAM_CAPTURE;
141
142         mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
143
144         if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
145                 ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
146                 if (ret < 0) {
147                         dev_err(cpu_dai->dev,
148                                 "Compress ASoC: can't open interface %s: %d\n",
149                                 cpu_dai->name, ret);
150                         goto out;
151                 }
152         }
153
154         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->open) {
155                 ret = platform->driver->compr_ops->open(cstream);
156                 if (ret < 0) {
157                         dev_err(platform->dev,
158                                 "Compress ASoC: can't open platform %s: %d\n",
159                                 platform->component.name, ret);
160                         goto plat_err;
161                 }
162         }
163
164         for_each_rtdcom(fe, rtdcom) {
165                 component = rtdcom->component;
166
167                 /* ignore duplication for now */
168                 if (platform && (component == &platform->component))
169                         continue;
170
171                 if (!component->driver->compr_ops ||
172                     !component->driver->compr_ops->open)
173                         continue;
174
175                 __ret = component->driver->compr_ops->open(cstream);
176                 if (__ret < 0) {
177                         dev_err(component->dev,
178                                 "Compress ASoC: can't open platform %s: %d\n",
179                                 component->name, __ret);
180                         ret = __ret;
181                 }
182         }
183         if (ret < 0)
184                 goto machine_err;
185
186         if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->startup) {
187                 ret = fe->dai_link->compr_ops->startup(cstream);
188                 if (ret < 0) {
189                         pr_err("Compress ASoC: %s startup failed: %d\n",
190                                fe->dai_link->name, ret);
191                         goto machine_err;
192                 }
193         }
194
195         fe->dpcm[stream].runtime = fe_substream->runtime;
196
197         ret = dpcm_path_get(fe, stream, &list);
198         if (ret < 0)
199                 goto fe_err;
200         else if (ret == 0)
201                 dev_dbg(fe->dev, "Compress ASoC: %s no valid %s route\n",
202                         fe->dai_link->name, stream ? "capture" : "playback");
203
204         /* calculate valid and active FE <-> BE dpcms */
205         dpcm_process_paths(fe, stream, &list, 1);
206
207         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
208
209         ret = dpcm_be_dai_startup(fe, stream);
210         if (ret < 0) {
211                 /* clean up all links */
212                 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
213                         dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
214
215                 dpcm_be_disconnect(fe, stream);
216                 fe->dpcm[stream].runtime = NULL;
217                 goto path_err;
218         }
219
220         dpcm_clear_pending_state(fe, stream);
221         dpcm_path_put(&list);
222
223         fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
224         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
225
226         snd_soc_runtime_activate(fe, stream);
227
228         mutex_unlock(&fe->card->mutex);
229
230         return 0;
231
232 path_err:
233         dpcm_path_put(&list);
234 fe_err:
235         if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
236                 fe->dai_link->compr_ops->shutdown(cstream);
237 machine_err:
238         for_each_rtdcom(fe, rtdcom) {
239                 component = rtdcom->component;
240
241                 /* ignore duplication for now */
242                 if (platform && (component == &platform->component))
243                         continue;
244
245                 if (!component->driver->compr_ops ||
246                     !component->driver->compr_ops->free)
247                         continue;
248
249                 component->driver->compr_ops->free(cstream);
250         }
251
252         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
253                 platform->driver->compr_ops->free(cstream);
254 plat_err:
255         if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
256                 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
257 out:
258         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
259         mutex_unlock(&fe->card->mutex);
260         return ret;
261 }
262
263 /*
264  * Power down the audio subsystem pmdown_time msecs after close is called.
265  * This is to ensure there are no pops or clicks in between any music tracks
266  * due to DAPM power cycling.
267  */
268 static void close_delayed_work(struct work_struct *work)
269 {
270         struct snd_soc_pcm_runtime *rtd =
271                         container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
272         struct snd_soc_dai *codec_dai = rtd->codec_dai;
273
274         mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
275
276         dev_dbg(rtd->dev,
277                 "Compress ASoC: pop wq checking: %s status: %s waiting: %s\n",
278                 codec_dai->driver->playback.stream_name,
279                 codec_dai->playback_active ? "active" : "inactive",
280                 rtd->pop_wait ? "yes" : "no");
281
282         /* are we waiting on this codec DAI stream */
283         if (rtd->pop_wait == 1) {
284                 rtd->pop_wait = 0;
285                 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
286                                           SND_SOC_DAPM_STREAM_STOP);
287         }
288
289         mutex_unlock(&rtd->pcm_mutex);
290 }
291
292 static int soc_compr_free(struct snd_compr_stream *cstream)
293 {
294         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
295         struct snd_soc_platform *platform = rtd->platform;
296         struct snd_soc_component *component;
297         struct snd_soc_rtdcom_list *rtdcom;
298         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
299         struct snd_soc_dai *codec_dai = rtd->codec_dai;
300         int stream;
301
302         mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
303
304         if (cstream->direction == SND_COMPRESS_PLAYBACK)
305                 stream = SNDRV_PCM_STREAM_PLAYBACK;
306         else
307                 stream = SNDRV_PCM_STREAM_CAPTURE;
308
309         snd_soc_runtime_deactivate(rtd, stream);
310
311         snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
312
313         if (!cpu_dai->active)
314                 cpu_dai->rate = 0;
315
316         if (!codec_dai->active)
317                 codec_dai->rate = 0;
318
319         if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown)
320                 rtd->dai_link->compr_ops->shutdown(cstream);
321
322         for_each_rtdcom(rtd, rtdcom) {
323                 component = rtdcom->component;
324
325                 /* ignore duplication for now */
326                 if (platform && (component == &platform->component))
327                         continue;
328
329                 if (!component->driver->compr_ops ||
330                     !component->driver->compr_ops->free)
331                         continue;
332
333                 component->driver->compr_ops->free(cstream);
334         }
335
336         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
337                 platform->driver->compr_ops->free(cstream);
338
339         if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
340                 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
341
342         if (cstream->direction == SND_COMPRESS_PLAYBACK) {
343                 if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
344                         snd_soc_dapm_stream_event(rtd,
345                                         SNDRV_PCM_STREAM_PLAYBACK,
346                                         SND_SOC_DAPM_STREAM_STOP);
347                 } else {
348                         rtd->pop_wait = 1;
349                         queue_delayed_work(system_power_efficient_wq,
350                                            &rtd->delayed_work,
351                                            msecs_to_jiffies(rtd->pmdown_time));
352                 }
353         } else {
354                 /* capture streams can be powered down now */
355                 snd_soc_dapm_stream_event(rtd,
356                         SNDRV_PCM_STREAM_CAPTURE,
357                         SND_SOC_DAPM_STREAM_STOP);
358         }
359
360         mutex_unlock(&rtd->pcm_mutex);
361         return 0;
362 }
363
364 static int soc_compr_free_fe(struct snd_compr_stream *cstream)
365 {
366         struct snd_soc_pcm_runtime *fe = cstream->private_data;
367         struct snd_soc_platform *platform = fe->platform;
368         struct snd_soc_component *component;
369         struct snd_soc_rtdcom_list *rtdcom;
370         struct snd_soc_dai *cpu_dai = fe->cpu_dai;
371         struct snd_soc_dpcm *dpcm;
372         int stream, ret;
373
374         mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
375
376         if (cstream->direction == SND_COMPRESS_PLAYBACK)
377                 stream = SNDRV_PCM_STREAM_PLAYBACK;
378         else
379                 stream = SNDRV_PCM_STREAM_CAPTURE;
380
381         snd_soc_runtime_deactivate(fe, stream);
382
383         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
384
385         ret = dpcm_be_dai_hw_free(fe, stream);
386         if (ret < 0)
387                 dev_err(fe->dev, "Compressed ASoC: hw_free failed: %d\n", ret);
388
389         ret = dpcm_be_dai_shutdown(fe, stream);
390
391         /* mark FE's links ready to prune */
392         list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
393                 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
394
395         dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
396
397         fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
398         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
399
400         dpcm_be_disconnect(fe, stream);
401
402         fe->dpcm[stream].runtime = NULL;
403
404         if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
405                 fe->dai_link->compr_ops->shutdown(cstream);
406
407         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
408                 platform->driver->compr_ops->free(cstream);
409
410         for_each_rtdcom(fe, rtdcom) {
411                 component = rtdcom->component;
412
413                 /* ignore duplication for now */
414                 if (platform && (component == &platform->component))
415                         continue;
416
417                 if (!component->driver->compr_ops ||
418                     !component->driver->compr_ops->free)
419                         continue;
420
421                 component->driver->compr_ops->free(cstream);
422         }
423
424         if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
425                 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
426
427         mutex_unlock(&fe->card->mutex);
428         return 0;
429 }
430
431 static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
432 {
433
434         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
435         struct snd_soc_platform *platform = rtd->platform;
436         struct snd_soc_component *component;
437         struct snd_soc_rtdcom_list *rtdcom;
438         struct snd_soc_dai *codec_dai = rtd->codec_dai;
439         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
440         int ret = 0, __ret;
441
442         mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
443
444         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
445                 ret = platform->driver->compr_ops->trigger(cstream, cmd);
446                 if (ret < 0)
447                         goto out;
448         }
449
450         for_each_rtdcom(rtd, rtdcom) {
451                 component = rtdcom->component;
452
453                 /* ignore duplication for now */
454                 if (platform && (component == &platform->component))
455                         continue;
456
457                 if (!component->driver->compr_ops ||
458                     !component->driver->compr_ops->trigger)
459                         continue;
460
461                 __ret = component->driver->compr_ops->trigger(cstream, cmd);
462                 if (__ret < 0)
463                         ret = __ret;
464         }
465         if (ret < 0)
466                 goto out;
467
468         if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger)
469                 cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
470
471         switch (cmd) {
472         case SNDRV_PCM_TRIGGER_START:
473                 snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction);
474                 break;
475         case SNDRV_PCM_TRIGGER_STOP:
476                 snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
477                 break;
478         }
479
480 out:
481         mutex_unlock(&rtd->pcm_mutex);
482         return ret;
483 }
484
485 static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
486 {
487         struct snd_soc_pcm_runtime *fe = cstream->private_data;
488         struct snd_soc_platform *platform = fe->platform;
489         struct snd_soc_component *component;
490         struct snd_soc_rtdcom_list *rtdcom;
491         struct snd_soc_dai *cpu_dai = fe->cpu_dai;
492         int ret = 0, __ret, stream;
493
494         if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
495                 cmd == SND_COMPR_TRIGGER_DRAIN) {
496
497                 if (platform &&
498                     platform->driver->compr_ops &&
499                     platform->driver->compr_ops->trigger)
500                         return platform->driver->compr_ops->trigger(cstream,
501                                                                     cmd);
502
503                 for_each_rtdcom(fe, rtdcom) {
504                         component = rtdcom->component;
505
506                         /* ignore duplication for now */
507                         if (platform && (component == &platform->component))
508                                 continue;
509
510                         if (!component->driver->compr_ops ||
511                             !component->driver->compr_ops->trigger)
512                                 continue;
513
514                         __ret = component->driver->compr_ops->trigger(cstream, cmd);
515                         if (__ret < 0)
516                                 ret = __ret;
517                 }
518                 return ret;
519         }
520
521         if (cstream->direction == SND_COMPRESS_PLAYBACK)
522                 stream = SNDRV_PCM_STREAM_PLAYBACK;
523         else
524                 stream = SNDRV_PCM_STREAM_CAPTURE;
525
526
527         mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
528
529         if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger) {
530                 ret = cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
531                 if (ret < 0)
532                         goto out;
533         }
534
535         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
536                 ret = platform->driver->compr_ops->trigger(cstream, cmd);
537                 if (ret < 0)
538                         goto out;
539         }
540
541         for_each_rtdcom(fe, rtdcom) {
542                 component = rtdcom->component;
543
544                 /* ignore duplication for now */
545                 if (platform && (component == &platform->component))
546                         continue;
547
548                 if (!component->driver->compr_ops ||
549                     !component->driver->compr_ops->trigger)
550                         continue;
551
552                 __ret = component->driver->compr_ops->trigger(cstream, cmd);
553                 if (__ret < 0)
554                         ret = __ret;
555         }
556         if (ret < 0)
557                 goto out;
558
559         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
560
561         ret = dpcm_be_dai_trigger(fe, stream, cmd);
562
563         switch (cmd) {
564         case SNDRV_PCM_TRIGGER_START:
565         case SNDRV_PCM_TRIGGER_RESUME:
566         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
567                 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
568                 break;
569         case SNDRV_PCM_TRIGGER_STOP:
570         case SNDRV_PCM_TRIGGER_SUSPEND:
571                 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
572                 break;
573         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
574                 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
575                 break;
576         }
577
578 out:
579         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
580         mutex_unlock(&fe->card->mutex);
581         return ret;
582 }
583
584 static int soc_compr_set_params(struct snd_compr_stream *cstream,
585                                         struct snd_compr_params *params)
586 {
587         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
588         struct snd_soc_platform *platform = rtd->platform;
589         struct snd_soc_component *component;
590         struct snd_soc_rtdcom_list *rtdcom;
591         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
592         int ret = 0, __ret;
593
594         mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
595
596         /* first we call set_params for the platform driver
597          * this should configure the soc side
598          * if the machine has compressed ops then we call that as well
599          * expectation is that platform and machine will configure everything
600          * for this compress path, like configuring pcm port for codec
601          */
602         if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
603                 ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
604                 if (ret < 0)
605                         goto err;
606         }
607
608         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
609                 ret = platform->driver->compr_ops->set_params(cstream, params);
610                 if (ret < 0)
611                         goto err;
612         }
613
614         for_each_rtdcom(rtd, rtdcom) {
615                 component = rtdcom->component;
616
617                 /* ignore duplication for now */
618                 if (platform && (component == &platform->component))
619                         continue;
620
621                 if (!component->driver->compr_ops ||
622                     !component->driver->compr_ops->set_params)
623                         continue;
624
625                 __ret = component->driver->compr_ops->set_params(cstream, params);
626                 if (__ret < 0)
627                         ret = __ret;
628         }
629         if (ret < 0)
630                 goto err;
631
632         if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) {
633                 ret = rtd->dai_link->compr_ops->set_params(cstream);
634                 if (ret < 0)
635                         goto err;
636         }
637
638         if (cstream->direction == SND_COMPRESS_PLAYBACK)
639                 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
640                                         SND_SOC_DAPM_STREAM_START);
641         else
642                 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
643                                         SND_SOC_DAPM_STREAM_START);
644
645         /* cancel any delayed stream shutdown that is pending */
646         rtd->pop_wait = 0;
647         mutex_unlock(&rtd->pcm_mutex);
648
649         cancel_delayed_work_sync(&rtd->delayed_work);
650
651         return ret;
652
653 err:
654         mutex_unlock(&rtd->pcm_mutex);
655         return ret;
656 }
657
658 static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
659                                         struct snd_compr_params *params)
660 {
661         struct snd_soc_pcm_runtime *fe = cstream->private_data;
662         struct snd_pcm_substream *fe_substream =
663                  fe->pcm->streams[cstream->direction].substream;
664         struct snd_soc_platform *platform = fe->platform;
665         struct snd_soc_component *component;
666         struct snd_soc_rtdcom_list *rtdcom;
667         struct snd_soc_dai *cpu_dai = fe->cpu_dai;
668         int ret = 0, __ret, stream;
669
670         if (cstream->direction == SND_COMPRESS_PLAYBACK)
671                 stream = SNDRV_PCM_STREAM_PLAYBACK;
672         else
673                 stream = SNDRV_PCM_STREAM_CAPTURE;
674
675         mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
676
677         if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
678                 ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
679                 if (ret < 0)
680                         goto out;
681         }
682
683         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
684                 ret = platform->driver->compr_ops->set_params(cstream, params);
685                 if (ret < 0)
686                         goto out;
687         }
688
689         for_each_rtdcom(fe, rtdcom) {
690                 component = rtdcom->component;
691
692                 /* ignore duplication for now */
693                 if (platform && (component == &platform->component))
694                         continue;
695
696                 if (!component->driver->compr_ops ||
697                     !component->driver->compr_ops->set_params)
698                         continue;
699
700                 __ret = component->driver->compr_ops->set_params(cstream, params);
701                 if (__ret < 0)
702                         ret = __ret;
703         }
704         if (ret < 0)
705                 goto out;
706
707         if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->set_params) {
708                 ret = fe->dai_link->compr_ops->set_params(cstream);
709                 if (ret < 0)
710                         goto out;
711         }
712
713         /*
714          * Create an empty hw_params for the BE as the machine driver must
715          * fix this up to match DSP decoder and ASRC configuration.
716          * I.e. machine driver fixup for compressed BE is mandatory.
717          */
718         memset(&fe->dpcm[fe_substream->stream].hw_params, 0,
719                 sizeof(struct snd_pcm_hw_params));
720
721         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
722
723         ret = dpcm_be_dai_hw_params(fe, stream);
724         if (ret < 0)
725                 goto out;
726
727         ret = dpcm_be_dai_prepare(fe, stream);
728         if (ret < 0)
729                 goto out;
730
731         dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
732         fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
733
734 out:
735         fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
736         mutex_unlock(&fe->card->mutex);
737         return ret;
738 }
739
740 static int soc_compr_get_params(struct snd_compr_stream *cstream,
741                                         struct snd_codec *params)
742 {
743         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
744         struct snd_soc_platform *platform = rtd->platform;
745         struct snd_soc_component *component;
746         struct snd_soc_rtdcom_list *rtdcom;
747         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
748         int ret = 0, __ret;
749
750         mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
751
752         if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_params) {
753                 ret = cpu_dai->driver->cops->get_params(cstream, params, cpu_dai);
754                 if (ret < 0)
755                         goto err;
756         }
757
758         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_params) {
759                 ret = platform->driver->compr_ops->get_params(cstream, params);
760                 if (ret < 0)
761                         goto err;
762         }
763
764         for_each_rtdcom(rtd, rtdcom) {
765                 component = rtdcom->component;
766
767                 /* ignore duplication for now */
768                 if (platform && (component == &platform->component))
769                         continue;
770
771                 if (!component->driver->compr_ops ||
772                     !component->driver->compr_ops->get_params)
773                         continue;
774
775                 __ret = component->driver->compr_ops->get_params(cstream, params);
776                 if (__ret < 0)
777                         ret = __ret;
778         }
779
780 err:
781         mutex_unlock(&rtd->pcm_mutex);
782         return ret;
783 }
784
785 static int soc_compr_get_caps(struct snd_compr_stream *cstream,
786                                 struct snd_compr_caps *caps)
787 {
788         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
789         struct snd_soc_platform *platform = rtd->platform;
790         struct snd_soc_component *component;
791         struct snd_soc_rtdcom_list *rtdcom;
792         int ret = 0, __ret;
793
794         mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
795
796         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_caps) {
797                 ret = platform->driver->compr_ops->get_caps(cstream, caps);
798                 if (ret < 0)
799                         goto err;
800         }
801
802         for_each_rtdcom(rtd, rtdcom) {
803                 component = rtdcom->component;
804
805                 /* ignore duplication for now */
806                 if (platform && (component == &platform->component))
807                         continue;
808
809                 if (!component->driver->compr_ops ||
810                     !component->driver->compr_ops->get_caps)
811                         continue;
812
813                 __ret = component->driver->compr_ops->get_caps(cstream, caps);
814                 if (__ret < 0)
815                         ret = __ret;
816         }
817
818 err:
819         mutex_unlock(&rtd->pcm_mutex);
820         return ret;
821 }
822
823 static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
824                                 struct snd_compr_codec_caps *codec)
825 {
826         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
827         struct snd_soc_platform *platform = rtd->platform;
828         struct snd_soc_component *component;
829         struct snd_soc_rtdcom_list *rtdcom;
830         int ret = 0, __ret;
831
832         mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
833
834         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_codec_caps) {
835                 ret = platform->driver->compr_ops->get_codec_caps(cstream, codec);
836                 if (ret < 0)
837                         goto err;
838         }
839
840         for_each_rtdcom(rtd, rtdcom) {
841                 component = rtdcom->component;
842
843                 /* ignore duplication for now */
844                 if (platform && (component == &platform->component))
845                         continue;
846
847                 if (!component->driver->compr_ops ||
848                     !component->driver->compr_ops->get_codec_caps)
849                         continue;
850
851                 __ret = component->driver->compr_ops->get_codec_caps(cstream, codec);
852                 if (__ret < 0)
853                         ret = __ret;
854         }
855
856 err:
857         mutex_unlock(&rtd->pcm_mutex);
858         return ret;
859 }
860
861 static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
862 {
863         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
864         struct snd_soc_platform *platform = rtd->platform;
865         struct snd_soc_component *component;
866         struct snd_soc_rtdcom_list *rtdcom;
867         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
868         int ret = 0, __ret;
869
870         mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
871
872         if (cpu_dai->driver->cops && cpu_dai->driver->cops->ack) {
873                 ret = cpu_dai->driver->cops->ack(cstream, bytes, cpu_dai);
874                 if (ret < 0)
875                         goto err;
876         }
877
878         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->ack) {
879                 ret = platform->driver->compr_ops->ack(cstream, bytes);
880                 if (ret < 0)
881                         goto err;
882         }
883
884         for_each_rtdcom(rtd, rtdcom) {
885                 component = rtdcom->component;
886
887                 /* ignore duplication for now */
888                 if (platform && (component == &platform->component))
889                         continue;
890
891                 if (!component->driver->compr_ops ||
892                     !component->driver->compr_ops->ack)
893                         continue;
894
895                 __ret = component->driver->compr_ops->ack(cstream, bytes);
896                 if (__ret < 0)
897                         ret = __ret;
898         }
899
900 err:
901         mutex_unlock(&rtd->pcm_mutex);
902         return ret;
903 }
904
905 static int soc_compr_pointer(struct snd_compr_stream *cstream,
906                         struct snd_compr_tstamp *tstamp)
907 {
908         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
909         struct snd_soc_platform *platform = rtd->platform;
910         struct snd_soc_component *component;
911         struct snd_soc_rtdcom_list *rtdcom;
912         int ret = 0, __ret;
913         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
914
915         mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
916
917         if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
918                 cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
919
920         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->pointer) {
921                 ret = platform->driver->compr_ops->pointer(cstream, tstamp);
922                 if (ret < 0)
923                         goto err;
924         }
925
926         for_each_rtdcom(rtd, rtdcom) {
927                 component = rtdcom->component;
928
929                 /* ignore duplication for now */
930                 if (platform && (component == &platform->component))
931                         continue;
932
933                 if (!component->driver->compr_ops ||
934                     !component->driver->compr_ops->pointer)
935                         continue;
936
937                 __ret = component->driver->compr_ops->pointer(cstream, tstamp);
938                 if (__ret < 0)
939                         ret = __ret;
940         }
941
942 err:
943         mutex_unlock(&rtd->pcm_mutex);
944         return ret;
945 }
946
947 static int soc_compr_copy(struct snd_compr_stream *cstream,
948                           char __user *buf, size_t count)
949 {
950         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
951         struct snd_soc_platform *platform = rtd->platform;
952         struct snd_soc_component *component;
953         struct snd_soc_rtdcom_list *rtdcom;
954         int ret = 0;
955
956         mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
957
958         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->copy) {
959                 ret = platform->driver->compr_ops->copy(cstream, buf, count);
960                 if (ret < 0)
961                         goto err;
962         }
963
964         for_each_rtdcom(rtd, rtdcom) {
965                 component = rtdcom->component;
966
967                 /* ignore duplication for now */
968                 if (platform && (component == &platform->component))
969                         continue;
970
971                 if (!component->driver->compr_ops ||
972                     !component->driver->compr_ops->copy)
973                         continue;
974
975                 ret = component->driver->compr_ops->copy(cstream, buf, count);
976                 break;
977         }
978
979 err:
980         mutex_unlock(&rtd->pcm_mutex);
981         return ret;
982 }
983
984 static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
985                                 struct snd_compr_metadata *metadata)
986 {
987         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
988         struct snd_soc_platform *platform = rtd->platform;
989         struct snd_soc_component *component;
990         struct snd_soc_rtdcom_list *rtdcom;
991         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
992         int ret = 0, __ret;
993
994         if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_metadata) {
995                 ret = cpu_dai->driver->cops->set_metadata(cstream, metadata, cpu_dai);
996                 if (ret < 0)
997                         return ret;
998         }
999
1000         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_metadata) {
1001                 ret = platform->driver->compr_ops->set_metadata(cstream, metadata);
1002                 if (ret < 0)
1003                         return ret;
1004         }
1005
1006         for_each_rtdcom(rtd, rtdcom) {
1007                 component = rtdcom->component;
1008
1009                 /* ignore duplication for now */
1010                 if (platform && (component == &platform->component))
1011                         continue;
1012
1013                 if (!component->driver->compr_ops ||
1014                     !component->driver->compr_ops->set_metadata)
1015                         continue;
1016
1017                 __ret = component->driver->compr_ops->set_metadata(cstream, metadata);
1018                 if (__ret < 0)
1019                         ret = __ret;
1020         }
1021
1022         return ret;
1023 }
1024
1025 static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
1026                                 struct snd_compr_metadata *metadata)
1027 {
1028         struct snd_soc_pcm_runtime *rtd = cstream->private_data;
1029         struct snd_soc_platform *platform = rtd->platform;
1030         struct snd_soc_component *component;
1031         struct snd_soc_rtdcom_list *rtdcom;
1032         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1033         int ret = 0, __ret;
1034
1035         if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_metadata) {
1036                 ret = cpu_dai->driver->cops->get_metadata(cstream, metadata, cpu_dai);
1037                 if (ret < 0)
1038                         return ret;
1039         }
1040
1041         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_metadata) {
1042                 ret = platform->driver->compr_ops->get_metadata(cstream, metadata);
1043                 if (ret < 0)
1044                         return ret;
1045         }
1046
1047         for_each_rtdcom(rtd, rtdcom) {
1048                 component = rtdcom->component;
1049
1050                 /* ignore duplication for now */
1051                 if (platform && (component == &platform->component))
1052                         continue;
1053
1054                 if (!component->driver->compr_ops ||
1055                     !component->driver->compr_ops->get_metadata)
1056                         continue;
1057
1058                 __ret = component->driver->compr_ops->get_metadata(cstream, metadata);
1059                 if (__ret < 0)
1060                         ret = __ret;
1061         }
1062
1063         return ret;
1064 }
1065
1066 /* ASoC Compress operations */
1067 static struct snd_compr_ops soc_compr_ops = {
1068         .open           = soc_compr_open,
1069         .free           = soc_compr_free,
1070         .set_params     = soc_compr_set_params,
1071         .set_metadata   = soc_compr_set_metadata,
1072         .get_metadata   = soc_compr_get_metadata,
1073         .get_params     = soc_compr_get_params,
1074         .trigger        = soc_compr_trigger,
1075         .pointer        = soc_compr_pointer,
1076         .ack            = soc_compr_ack,
1077         .get_caps       = soc_compr_get_caps,
1078         .get_codec_caps = soc_compr_get_codec_caps
1079 };
1080
1081 /* ASoC Dynamic Compress operations */
1082 static struct snd_compr_ops soc_compr_dyn_ops = {
1083         .open           = soc_compr_open_fe,
1084         .free           = soc_compr_free_fe,
1085         .set_params     = soc_compr_set_params_fe,
1086         .get_params     = soc_compr_get_params,
1087         .set_metadata   = soc_compr_set_metadata,
1088         .get_metadata   = soc_compr_get_metadata,
1089         .trigger        = soc_compr_trigger_fe,
1090         .pointer        = soc_compr_pointer,
1091         .ack            = soc_compr_ack,
1092         .get_caps       = soc_compr_get_caps,
1093         .get_codec_caps = soc_compr_get_codec_caps
1094 };
1095
1096 /**
1097  * snd_soc_new_compress - create a new compress.
1098  *
1099  * @rtd: The runtime for which we will create compress
1100  * @num: the device index number (zero based - shared with normal PCMs)
1101  *
1102  * Return: 0 for success, else error.
1103  */
1104 int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
1105 {
1106         struct snd_soc_platform *platform = rtd->platform;
1107         struct snd_soc_component *component;
1108         struct snd_soc_rtdcom_list *rtdcom;
1109         struct snd_soc_dai *codec_dai = rtd->codec_dai;
1110         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1111         struct snd_compr *compr;
1112         struct snd_pcm *be_pcm;
1113         char new_name[64];
1114         int ret = 0, direction = 0;
1115         int playback = 0, capture = 0;
1116
1117         if (rtd->num_codecs > 1) {
1118                 dev_err(rtd->card->dev,
1119                         "Compress ASoC: Multicodec not supported\n");
1120                 return -EINVAL;
1121         }
1122
1123         /* check client and interface hw capabilities */
1124         if (codec_dai->driver->playback.channels_min)
1125                 playback = 1;
1126         if (codec_dai->driver->capture.channels_min)
1127                 capture = 1;
1128
1129         capture = capture && cpu_dai->driver->capture.channels_min;
1130         playback = playback && cpu_dai->driver->playback.channels_min;
1131
1132         /*
1133          * Compress devices are unidirectional so only one of the directions
1134          * should be set, check for that (xor)
1135          */
1136         if (playback + capture != 1) {
1137                 dev_err(rtd->card->dev,
1138                         "Compress ASoC: Invalid direction for P %d, C %d\n",
1139                         playback, capture);
1140                 return -EINVAL;
1141         }
1142
1143         if (playback)
1144                 direction = SND_COMPRESS_PLAYBACK;
1145         else
1146                 direction = SND_COMPRESS_CAPTURE;
1147
1148         compr = kzalloc(sizeof(*compr), GFP_KERNEL);
1149         if (!compr)
1150                 return -ENOMEM;
1151
1152         compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
1153                                   GFP_KERNEL);
1154         if (!compr->ops) {
1155                 ret = -ENOMEM;
1156                 goto compr_err;
1157         }
1158
1159         if (rtd->dai_link->dynamic) {
1160                 snprintf(new_name, sizeof(new_name), "(%s)",
1161                         rtd->dai_link->stream_name);
1162
1163                 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
1164                                 rtd->dai_link->dpcm_playback,
1165                                 rtd->dai_link->dpcm_capture, &be_pcm);
1166                 if (ret < 0) {
1167                         dev_err(rtd->card->dev,
1168                                 "Compress ASoC: can't create compressed for %s: %d\n",
1169                                 rtd->dai_link->name, ret);
1170                         goto compr_err;
1171                 }
1172
1173                 rtd->pcm = be_pcm;
1174                 rtd->fe_compr = 1;
1175                 if (rtd->dai_link->dpcm_playback)
1176                         be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
1177                 else if (rtd->dai_link->dpcm_capture)
1178                         be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
1179                 memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
1180         } else {
1181                 snprintf(new_name, sizeof(new_name), "%s %s-%d",
1182                         rtd->dai_link->stream_name, codec_dai->name, num);
1183
1184                 memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
1185         }
1186
1187
1188         /* Add copy callback for not memory mapped DSPs */
1189         if (platform && platform->driver->compr_ops && platform->driver->compr_ops->copy)
1190                 compr->ops->copy = soc_compr_copy;
1191
1192         for_each_rtdcom(rtd, rtdcom) {
1193                 component = rtdcom->component;
1194
1195                 /* ignore duplication for now */
1196                 if (platform && (component == &platform->component))
1197                         continue;
1198
1199                 if (!component->driver->compr_ops ||
1200                     !component->driver->compr_ops->copy)
1201                         continue;
1202
1203                 compr->ops->copy = soc_compr_copy;
1204         }
1205
1206
1207         mutex_init(&compr->lock);
1208         ret = snd_compress_new(rtd->card->snd_card, num, direction,
1209                                 new_name, compr);
1210         if (ret < 0) {
1211                 component = rtd->codec_dai->component;
1212                 dev_err(component->dev,
1213                         "Compress ASoC: can't create compress for codec %s: %d\n",
1214                         component->name, ret);
1215                 goto compr_err;
1216         }
1217
1218         /* DAPM dai link stream work */
1219         INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
1220
1221         rtd->compr = compr;
1222         compr->private_data = rtd;
1223
1224         dev_info(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n",
1225                  codec_dai->name, cpu_dai->name);
1226         return ret;
1227
1228 compr_err:
1229         kfree(compr);
1230         return ret;
1231 }
1232 EXPORT_SYMBOL_GPL(snd_soc_new_compress);