2 * soc-compress.c -- ALSA SoC Compress
4 * Copyright (C) 2012 Intel Corp.
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>
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.
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>
29 static int soc_compr_open(struct snd_compr_stream *cstream)
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;
38 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
40 if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
41 ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
44 "Compress ASoC: can't open interface %s: %d\n",
50 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->open) {
51 ret = platform->driver->compr_ops->open(cstream);
53 dev_err(platform->dev,
54 "Compress ASoC: can't open platform %s: %d\n",
55 platform->component.name, ret);
60 for_each_rtdcom(rtd, rtdcom) {
61 component = rtdcom->component;
63 /* ignore duplication for now */
64 if (platform && (component == &platform->component))
67 if (!component->driver->compr_ops ||
68 !component->driver->compr_ops->open)
71 __ret = component->driver->compr_ops->open(cstream);
73 dev_err(component->dev,
74 "Compress ASoC: can't open platform %s: %d\n",
75 component->name, __ret);
82 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) {
83 ret = rtd->dai_link->compr_ops->startup(cstream);
86 "Compress ASoC: %s startup failed: %d\n",
87 rtd->dai_link->name, ret);
92 snd_soc_runtime_activate(rtd, cstream->direction);
94 mutex_unlock(&rtd->pcm_mutex);
99 for_each_rtdcom(rtd, rtdcom) {
100 component = rtdcom->component;
102 /* ignore duplication for now */
103 if (platform && (component == &platform->component))
106 if (!component->driver->compr_ops ||
107 !component->driver->compr_ops->free)
110 component->driver->compr_ops->free(cstream);
113 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
114 platform->driver->compr_ops->free(cstream);
116 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
117 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
119 mutex_unlock(&rtd->pcm_mutex);
123 static int soc_compr_open_fe(struct snd_compr_stream *cstream)
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;
137 if (cstream->direction == SND_COMPRESS_PLAYBACK)
138 stream = SNDRV_PCM_STREAM_PLAYBACK;
140 stream = SNDRV_PCM_STREAM_CAPTURE;
142 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
144 if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
145 ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
147 dev_err(cpu_dai->dev,
148 "Compress ASoC: can't open interface %s: %d\n",
154 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->open) {
155 ret = platform->driver->compr_ops->open(cstream);
157 dev_err(platform->dev,
158 "Compress ASoC: can't open platform %s: %d\n",
159 platform->component.name, ret);
164 for_each_rtdcom(fe, rtdcom) {
165 component = rtdcom->component;
167 /* ignore duplication for now */
168 if (platform && (component == &platform->component))
171 if (!component->driver->compr_ops ||
172 !component->driver->compr_ops->open)
175 __ret = component->driver->compr_ops->open(cstream);
177 dev_err(component->dev,
178 "Compress ASoC: can't open platform %s: %d\n",
179 component->name, __ret);
186 if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->startup) {
187 ret = fe->dai_link->compr_ops->startup(cstream);
189 pr_err("Compress ASoC: %s startup failed: %d\n",
190 fe->dai_link->name, ret);
195 fe->dpcm[stream].runtime = fe_substream->runtime;
197 ret = dpcm_path_get(fe, stream, &list);
201 dev_dbg(fe->dev, "Compress ASoC: %s no valid %s route\n",
202 fe->dai_link->name, stream ? "capture" : "playback");
204 /* calculate valid and active FE <-> BE dpcms */
205 dpcm_process_paths(fe, stream, &list, 1);
207 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
209 ret = dpcm_be_dai_startup(fe, stream);
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;
215 dpcm_be_disconnect(fe, stream);
216 fe->dpcm[stream].runtime = NULL;
220 dpcm_clear_pending_state(fe, stream);
221 dpcm_path_put(&list);
223 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
224 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
226 snd_soc_runtime_activate(fe, stream);
228 mutex_unlock(&fe->card->mutex);
233 dpcm_path_put(&list);
235 if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
236 fe->dai_link->compr_ops->shutdown(cstream);
238 for_each_rtdcom(fe, rtdcom) {
239 component = rtdcom->component;
241 /* ignore duplication for now */
242 if (platform && (component == &platform->component))
245 if (!component->driver->compr_ops ||
246 !component->driver->compr_ops->free)
249 component->driver->compr_ops->free(cstream);
252 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
253 platform->driver->compr_ops->free(cstream);
255 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
256 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
258 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
259 mutex_unlock(&fe->card->mutex);
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.
268 static void close_delayed_work(struct work_struct *work)
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;
274 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
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");
282 /* are we waiting on this codec DAI stream */
283 if (rtd->pop_wait == 1) {
285 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
286 SND_SOC_DAPM_STREAM_STOP);
289 mutex_unlock(&rtd->pcm_mutex);
292 static int soc_compr_free(struct snd_compr_stream *cstream)
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;
302 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
304 if (cstream->direction == SND_COMPRESS_PLAYBACK)
305 stream = SNDRV_PCM_STREAM_PLAYBACK;
307 stream = SNDRV_PCM_STREAM_CAPTURE;
309 snd_soc_runtime_deactivate(rtd, stream);
311 snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
313 if (!cpu_dai->active)
316 if (!codec_dai->active)
319 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown)
320 rtd->dai_link->compr_ops->shutdown(cstream);
322 for_each_rtdcom(rtd, rtdcom) {
323 component = rtdcom->component;
325 /* ignore duplication for now */
326 if (platform && (component == &platform->component))
329 if (!component->driver->compr_ops ||
330 !component->driver->compr_ops->free)
333 component->driver->compr_ops->free(cstream);
336 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
337 platform->driver->compr_ops->free(cstream);
339 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
340 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
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);
349 queue_delayed_work(system_power_efficient_wq,
351 msecs_to_jiffies(rtd->pmdown_time));
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);
360 mutex_unlock(&rtd->pcm_mutex);
364 static int soc_compr_free_fe(struct snd_compr_stream *cstream)
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;
374 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
376 if (cstream->direction == SND_COMPRESS_PLAYBACK)
377 stream = SNDRV_PCM_STREAM_PLAYBACK;
379 stream = SNDRV_PCM_STREAM_CAPTURE;
381 snd_soc_runtime_deactivate(fe, stream);
383 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
385 ret = dpcm_be_dai_hw_free(fe, stream);
387 dev_err(fe->dev, "Compressed ASoC: hw_free failed: %d\n", ret);
389 ret = dpcm_be_dai_shutdown(fe, stream);
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;
395 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
397 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
398 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
400 dpcm_be_disconnect(fe, stream);
402 fe->dpcm[stream].runtime = NULL;
404 if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
405 fe->dai_link->compr_ops->shutdown(cstream);
407 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
408 platform->driver->compr_ops->free(cstream);
410 for_each_rtdcom(fe, rtdcom) {
411 component = rtdcom->component;
413 /* ignore duplication for now */
414 if (platform && (component == &platform->component))
417 if (!component->driver->compr_ops ||
418 !component->driver->compr_ops->free)
421 component->driver->compr_ops->free(cstream);
424 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
425 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
427 mutex_unlock(&fe->card->mutex);
431 static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
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;
442 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
444 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
445 ret = platform->driver->compr_ops->trigger(cstream, cmd);
450 for_each_rtdcom(rtd, rtdcom) {
451 component = rtdcom->component;
453 /* ignore duplication for now */
454 if (platform && (component == &platform->component))
457 if (!component->driver->compr_ops ||
458 !component->driver->compr_ops->trigger)
461 __ret = component->driver->compr_ops->trigger(cstream, cmd);
468 if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger)
469 cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
472 case SNDRV_PCM_TRIGGER_START:
473 snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction);
475 case SNDRV_PCM_TRIGGER_STOP:
476 snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
481 mutex_unlock(&rtd->pcm_mutex);
485 static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
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;
494 if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
495 cmd == SND_COMPR_TRIGGER_DRAIN) {
498 platform->driver->compr_ops &&
499 platform->driver->compr_ops->trigger)
500 return platform->driver->compr_ops->trigger(cstream,
503 for_each_rtdcom(fe, rtdcom) {
504 component = rtdcom->component;
506 /* ignore duplication for now */
507 if (platform && (component == &platform->component))
510 if (!component->driver->compr_ops ||
511 !component->driver->compr_ops->trigger)
514 __ret = component->driver->compr_ops->trigger(cstream, cmd);
521 if (cstream->direction == SND_COMPRESS_PLAYBACK)
522 stream = SNDRV_PCM_STREAM_PLAYBACK;
524 stream = SNDRV_PCM_STREAM_CAPTURE;
527 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
529 if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger) {
530 ret = cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
535 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
536 ret = platform->driver->compr_ops->trigger(cstream, cmd);
541 for_each_rtdcom(fe, rtdcom) {
542 component = rtdcom->component;
544 /* ignore duplication for now */
545 if (platform && (component == &platform->component))
548 if (!component->driver->compr_ops ||
549 !component->driver->compr_ops->trigger)
552 __ret = component->driver->compr_ops->trigger(cstream, cmd);
559 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
561 ret = dpcm_be_dai_trigger(fe, stream, 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;
569 case SNDRV_PCM_TRIGGER_STOP:
570 case SNDRV_PCM_TRIGGER_SUSPEND:
571 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
573 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
574 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
579 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
580 mutex_unlock(&fe->card->mutex);
584 static int soc_compr_set_params(struct snd_compr_stream *cstream,
585 struct snd_compr_params *params)
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;
594 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
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
602 if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
603 ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
608 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
609 ret = platform->driver->compr_ops->set_params(cstream, params);
614 for_each_rtdcom(rtd, rtdcom) {
615 component = rtdcom->component;
617 /* ignore duplication for now */
618 if (platform && (component == &platform->component))
621 if (!component->driver->compr_ops ||
622 !component->driver->compr_ops->set_params)
625 __ret = component->driver->compr_ops->set_params(cstream, params);
632 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) {
633 ret = rtd->dai_link->compr_ops->set_params(cstream);
638 if (cstream->direction == SND_COMPRESS_PLAYBACK)
639 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
640 SND_SOC_DAPM_STREAM_START);
642 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
643 SND_SOC_DAPM_STREAM_START);
645 /* cancel any delayed stream shutdown that is pending */
647 mutex_unlock(&rtd->pcm_mutex);
649 cancel_delayed_work_sync(&rtd->delayed_work);
654 mutex_unlock(&rtd->pcm_mutex);
658 static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
659 struct snd_compr_params *params)
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;
670 if (cstream->direction == SND_COMPRESS_PLAYBACK)
671 stream = SNDRV_PCM_STREAM_PLAYBACK;
673 stream = SNDRV_PCM_STREAM_CAPTURE;
675 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
677 if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
678 ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
683 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
684 ret = platform->driver->compr_ops->set_params(cstream, params);
689 for_each_rtdcom(fe, rtdcom) {
690 component = rtdcom->component;
692 /* ignore duplication for now */
693 if (platform && (component == &platform->component))
696 if (!component->driver->compr_ops ||
697 !component->driver->compr_ops->set_params)
700 __ret = component->driver->compr_ops->set_params(cstream, params);
707 if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->set_params) {
708 ret = fe->dai_link->compr_ops->set_params(cstream);
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.
718 memset(&fe->dpcm[fe_substream->stream].hw_params, 0,
719 sizeof(struct snd_pcm_hw_params));
721 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
723 ret = dpcm_be_dai_hw_params(fe, stream);
727 ret = dpcm_be_dai_prepare(fe, stream);
731 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
732 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
735 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
736 mutex_unlock(&fe->card->mutex);
740 static int soc_compr_get_params(struct snd_compr_stream *cstream,
741 struct snd_codec *params)
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;
750 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
752 if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_params) {
753 ret = cpu_dai->driver->cops->get_params(cstream, params, cpu_dai);
758 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_params) {
759 ret = platform->driver->compr_ops->get_params(cstream, params);
764 for_each_rtdcom(rtd, rtdcom) {
765 component = rtdcom->component;
767 /* ignore duplication for now */
768 if (platform && (component == &platform->component))
771 if (!component->driver->compr_ops ||
772 !component->driver->compr_ops->get_params)
775 __ret = component->driver->compr_ops->get_params(cstream, params);
781 mutex_unlock(&rtd->pcm_mutex);
785 static int soc_compr_get_caps(struct snd_compr_stream *cstream,
786 struct snd_compr_caps *caps)
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;
794 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
796 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_caps) {
797 ret = platform->driver->compr_ops->get_caps(cstream, caps);
802 for_each_rtdcom(rtd, rtdcom) {
803 component = rtdcom->component;
805 /* ignore duplication for now */
806 if (platform && (component == &platform->component))
809 if (!component->driver->compr_ops ||
810 !component->driver->compr_ops->get_caps)
813 __ret = component->driver->compr_ops->get_caps(cstream, caps);
819 mutex_unlock(&rtd->pcm_mutex);
823 static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
824 struct snd_compr_codec_caps *codec)
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;
832 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
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);
840 for_each_rtdcom(rtd, rtdcom) {
841 component = rtdcom->component;
843 /* ignore duplication for now */
844 if (platform && (component == &platform->component))
847 if (!component->driver->compr_ops ||
848 !component->driver->compr_ops->get_codec_caps)
851 __ret = component->driver->compr_ops->get_codec_caps(cstream, codec);
857 mutex_unlock(&rtd->pcm_mutex);
861 static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
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;
870 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
872 if (cpu_dai->driver->cops && cpu_dai->driver->cops->ack) {
873 ret = cpu_dai->driver->cops->ack(cstream, bytes, cpu_dai);
878 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->ack) {
879 ret = platform->driver->compr_ops->ack(cstream, bytes);
884 for_each_rtdcom(rtd, rtdcom) {
885 component = rtdcom->component;
887 /* ignore duplication for now */
888 if (platform && (component == &platform->component))
891 if (!component->driver->compr_ops ||
892 !component->driver->compr_ops->ack)
895 __ret = component->driver->compr_ops->ack(cstream, bytes);
901 mutex_unlock(&rtd->pcm_mutex);
905 static int soc_compr_pointer(struct snd_compr_stream *cstream,
906 struct snd_compr_tstamp *tstamp)
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;
913 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
915 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
917 if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
918 cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
920 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->pointer) {
921 ret = platform->driver->compr_ops->pointer(cstream, tstamp);
926 for_each_rtdcom(rtd, rtdcom) {
927 component = rtdcom->component;
929 /* ignore duplication for now */
930 if (platform && (component == &platform->component))
933 if (!component->driver->compr_ops ||
934 !component->driver->compr_ops->pointer)
937 __ret = component->driver->compr_ops->pointer(cstream, tstamp);
943 mutex_unlock(&rtd->pcm_mutex);
947 static int soc_compr_copy(struct snd_compr_stream *cstream,
948 char __user *buf, size_t count)
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;
956 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
958 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->copy) {
959 ret = platform->driver->compr_ops->copy(cstream, buf, count);
964 for_each_rtdcom(rtd, rtdcom) {
965 component = rtdcom->component;
967 /* ignore duplication for now */
968 if (platform && (component == &platform->component))
971 if (!component->driver->compr_ops ||
972 !component->driver->compr_ops->copy)
975 ret = component->driver->compr_ops->copy(cstream, buf, count);
980 mutex_unlock(&rtd->pcm_mutex);
984 static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
985 struct snd_compr_metadata *metadata)
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;
994 if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_metadata) {
995 ret = cpu_dai->driver->cops->set_metadata(cstream, metadata, cpu_dai);
1000 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_metadata) {
1001 ret = platform->driver->compr_ops->set_metadata(cstream, metadata);
1006 for_each_rtdcom(rtd, rtdcom) {
1007 component = rtdcom->component;
1009 /* ignore duplication for now */
1010 if (platform && (component == &platform->component))
1013 if (!component->driver->compr_ops ||
1014 !component->driver->compr_ops->set_metadata)
1017 __ret = component->driver->compr_ops->set_metadata(cstream, metadata);
1025 static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
1026 struct snd_compr_metadata *metadata)
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;
1035 if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_metadata) {
1036 ret = cpu_dai->driver->cops->get_metadata(cstream, metadata, cpu_dai);
1041 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_metadata) {
1042 ret = platform->driver->compr_ops->get_metadata(cstream, metadata);
1047 for_each_rtdcom(rtd, rtdcom) {
1048 component = rtdcom->component;
1050 /* ignore duplication for now */
1051 if (platform && (component == &platform->component))
1054 if (!component->driver->compr_ops ||
1055 !component->driver->compr_ops->get_metadata)
1058 __ret = component->driver->compr_ops->get_metadata(cstream, metadata);
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
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
1097 * snd_soc_new_compress - create a new compress.
1099 * @rtd: The runtime for which we will create compress
1100 * @num: the device index number (zero based - shared with normal PCMs)
1102 * Return: 0 for success, else error.
1104 int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
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;
1114 int ret = 0, direction = 0;
1115 int playback = 0, capture = 0;
1117 if (rtd->num_codecs > 1) {
1118 dev_err(rtd->card->dev,
1119 "Compress ASoC: Multicodec not supported\n");
1123 /* check client and interface hw capabilities */
1124 if (codec_dai->driver->playback.channels_min)
1126 if (codec_dai->driver->capture.channels_min)
1129 capture = capture && cpu_dai->driver->capture.channels_min;
1130 playback = playback && cpu_dai->driver->playback.channels_min;
1133 * Compress devices are unidirectional so only one of the directions
1134 * should be set, check for that (xor)
1136 if (playback + capture != 1) {
1137 dev_err(rtd->card->dev,
1138 "Compress ASoC: Invalid direction for P %d, C %d\n",
1144 direction = SND_COMPRESS_PLAYBACK;
1146 direction = SND_COMPRESS_CAPTURE;
1148 compr = kzalloc(sizeof(*compr), GFP_KERNEL);
1152 compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
1159 if (rtd->dai_link->dynamic) {
1160 snprintf(new_name, sizeof(new_name), "(%s)",
1161 rtd->dai_link->stream_name);
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);
1167 dev_err(rtd->card->dev,
1168 "Compress ASoC: can't create compressed for %s: %d\n",
1169 rtd->dai_link->name, ret);
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));
1181 snprintf(new_name, sizeof(new_name), "%s %s-%d",
1182 rtd->dai_link->stream_name, codec_dai->name, num);
1184 memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
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;
1192 for_each_rtdcom(rtd, rtdcom) {
1193 component = rtdcom->component;
1195 /* ignore duplication for now */
1196 if (platform && (component == &platform->component))
1199 if (!component->driver->compr_ops ||
1200 !component->driver->compr_ops->copy)
1203 compr->ops->copy = soc_compr_copy;
1207 mutex_init(&compr->lock);
1208 ret = snd_compress_new(rtd->card->snd_card, num, direction,
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);
1218 /* DAPM dai link stream work */
1219 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
1222 compr->private_data = rtd;
1224 dev_info(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n",
1225 codec_dai->name, cpu_dai->name);
1232 EXPORT_SYMBOL_GPL(snd_soc_new_compress);