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