1 // SPDX-License-Identifier: GPL-2.0+
3 // soc-compress.c -- ALSA SoC Compress
5 // Copyright (C) 2012 Intel Corp.
7 // Authors: Namarta Kohli <namartax.kohli@intel.com>
8 // Ramesh Babu K V <ramesh.babu@linux.intel.com>
9 // Vinod Koul <vinod.koul@linux.intel.com>
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/delay.h>
14 #include <linux/slab.h>
15 #include <linux/workqueue.h>
16 #include <sound/core.h>
17 #include <sound/compress_params.h>
18 #include <sound/compress_driver.h>
19 #include <sound/soc.h>
20 #include <sound/initval.h>
21 #include <sound/soc-dpcm.h>
22 #include <linux/pm_runtime.h>
24 static int soc_compr_components_open(struct snd_compr_stream *cstream,
25 struct snd_soc_component **last)
27 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
28 struct snd_soc_component *component;
29 struct snd_soc_rtdcom_list *rtdcom;
32 for_each_rtd_components(rtd, rtdcom, component) {
33 if (!component->driver->compr_ops ||
34 !component->driver->compr_ops->open)
37 ret = component->driver->compr_ops->open(cstream);
39 dev_err(component->dev,
40 "Compress ASoC: can't open platform %s: %d\n",
41 component->name, ret);
52 static int soc_compr_components_free(struct snd_compr_stream *cstream,
53 struct snd_soc_component *last)
55 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
56 struct snd_soc_component *component;
57 struct snd_soc_rtdcom_list *rtdcom;
59 for_each_rtd_components(rtd, rtdcom, component) {
60 if (component == last)
63 if (!component->driver->compr_ops ||
64 !component->driver->compr_ops->free)
67 component->driver->compr_ops->free(cstream);
73 static int soc_compr_open(struct snd_compr_stream *cstream)
75 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
76 struct snd_soc_component *component, *save = NULL;
77 struct snd_soc_rtdcom_list *rtdcom;
78 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
81 for_each_rtd_components(rtd, rtdcom, component) {
82 ret = pm_runtime_get_sync(component->dev);
83 if (ret < 0 && ret != -EACCES) {
84 pm_runtime_put_noidle(component->dev);
90 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
92 if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
93 ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
96 "Compress ASoC: can't open interface %s: %d\n",
102 ret = soc_compr_components_open(cstream, &component);
106 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) {
107 ret = rtd->dai_link->compr_ops->startup(cstream);
110 "Compress ASoC: %s startup failed: %d\n",
111 rtd->dai_link->name, ret);
116 snd_soc_runtime_activate(rtd, cstream->direction);
118 mutex_unlock(&rtd->card->pcm_mutex);
123 soc_compr_components_free(cstream, component);
125 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
126 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
128 mutex_unlock(&rtd->card->pcm_mutex);
130 for_each_rtd_components(rtd, rtdcom, component) {
131 if (component == save)
133 pm_runtime_mark_last_busy(component->dev);
134 pm_runtime_put_autosuspend(component->dev);
140 static int soc_compr_open_fe(struct snd_compr_stream *cstream)
142 struct snd_soc_pcm_runtime *fe = cstream->private_data;
143 struct snd_pcm_substream *fe_substream =
144 fe->pcm->streams[cstream->direction].substream;
145 struct snd_soc_component *component;
146 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
147 struct snd_soc_dpcm *dpcm;
148 struct snd_soc_dapm_widget_list *list;
152 if (cstream->direction == SND_COMPRESS_PLAYBACK)
153 stream = SNDRV_PCM_STREAM_PLAYBACK;
155 stream = SNDRV_PCM_STREAM_CAPTURE;
157 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
158 fe->dpcm[stream].runtime = fe_substream->runtime;
160 ret = dpcm_path_get(fe, stream, &list);
164 dev_dbg(fe->dev, "Compress ASoC: %s no valid %s route\n",
165 fe->dai_link->name, stream ? "capture" : "playback");
166 /* calculate valid and active FE <-> BE dpcms */
167 dpcm_process_paths(fe, stream, &list, 1);
168 fe->dpcm[stream].runtime = fe_substream->runtime;
170 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
172 ret = dpcm_be_dai_startup(fe, stream);
174 /* clean up all links */
175 for_each_dpcm_be(fe, stream, dpcm)
176 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
178 dpcm_be_disconnect(fe, stream);
179 fe->dpcm[stream].runtime = NULL;
183 if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
184 ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
186 dev_err(cpu_dai->dev,
187 "Compress ASoC: can't open interface %s: %d\n",
193 ret = soc_compr_components_open(cstream, &component);
197 if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->startup) {
198 ret = fe->dai_link->compr_ops->startup(cstream);
200 pr_err("Compress ASoC: %s startup failed: %d\n",
201 fe->dai_link->name, ret);
206 dpcm_clear_pending_state(fe, stream);
207 dpcm_path_put(&list);
209 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
210 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
212 snd_soc_runtime_activate(fe, stream);
214 mutex_unlock(&fe->card->mutex);
219 soc_compr_components_free(cstream, component);
221 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
222 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
224 dpcm_path_put(&list);
226 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
227 mutex_unlock(&fe->card->mutex);
232 * Power down the audio subsystem pmdown_time msecs after close is called.
233 * This is to ensure there are no pops or clicks in between any music tracks
234 * due to DAPM power cycling.
236 static void close_delayed_work(struct snd_soc_pcm_runtime *rtd)
238 struct snd_soc_dai *codec_dai = rtd->codec_dai;
240 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
243 "Compress ASoC: pop wq checking: %s status: %s waiting: %s\n",
244 codec_dai->driver->playback.stream_name,
245 codec_dai->playback_active ? "active" : "inactive",
246 rtd->pop_wait ? "yes" : "no");
248 /* are we waiting on this codec DAI stream */
249 if (rtd->pop_wait == 1) {
251 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
252 SND_SOC_DAPM_STREAM_STOP);
255 mutex_unlock(&rtd->card->pcm_mutex);
258 static int soc_compr_free(struct snd_compr_stream *cstream)
260 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
261 struct snd_soc_component *component;
262 struct snd_soc_rtdcom_list *rtdcom;
263 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
264 struct snd_soc_dai *codec_dai = rtd->codec_dai;
267 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
269 if (cstream->direction == SND_COMPRESS_PLAYBACK)
270 stream = SNDRV_PCM_STREAM_PLAYBACK;
272 stream = SNDRV_PCM_STREAM_CAPTURE;
274 snd_soc_runtime_deactivate(rtd, stream);
276 snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
278 if (!cpu_dai->active)
281 if (!codec_dai->active)
284 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown)
285 rtd->dai_link->compr_ops->shutdown(cstream);
287 soc_compr_components_free(cstream, NULL);
289 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
290 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
292 if (cstream->direction == SND_COMPRESS_PLAYBACK) {
293 if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
294 snd_soc_dapm_stream_event(rtd,
295 SNDRV_PCM_STREAM_PLAYBACK,
296 SND_SOC_DAPM_STREAM_STOP);
299 queue_delayed_work(system_power_efficient_wq,
301 msecs_to_jiffies(rtd->pmdown_time));
304 /* capture streams can be powered down now */
305 snd_soc_dapm_stream_event(rtd,
306 SNDRV_PCM_STREAM_CAPTURE,
307 SND_SOC_DAPM_STREAM_STOP);
310 mutex_unlock(&rtd->card->pcm_mutex);
312 for_each_rtd_components(rtd, rtdcom, component) {
313 pm_runtime_mark_last_busy(component->dev);
314 pm_runtime_put_autosuspend(component->dev);
320 static int soc_compr_free_fe(struct snd_compr_stream *cstream)
322 struct snd_soc_pcm_runtime *fe = cstream->private_data;
323 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
324 struct snd_soc_dpcm *dpcm;
327 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
329 if (cstream->direction == SND_COMPRESS_PLAYBACK)
330 stream = SNDRV_PCM_STREAM_PLAYBACK;
332 stream = SNDRV_PCM_STREAM_CAPTURE;
334 snd_soc_runtime_deactivate(fe, stream);
336 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
338 ret = dpcm_be_dai_hw_free(fe, stream);
340 dev_err(fe->dev, "Compressed ASoC: hw_free failed: %d\n", ret);
342 ret = dpcm_be_dai_shutdown(fe, stream);
344 /* mark FE's links ready to prune */
345 for_each_dpcm_be(fe, stream, dpcm)
346 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
348 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
350 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
351 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
353 dpcm_be_disconnect(fe, stream);
355 fe->dpcm[stream].runtime = NULL;
357 if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
358 fe->dai_link->compr_ops->shutdown(cstream);
360 soc_compr_components_free(cstream, NULL);
362 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
363 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
365 mutex_unlock(&fe->card->mutex);
369 static int soc_compr_components_trigger(struct snd_compr_stream *cstream,
372 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
373 struct snd_soc_component *component;
374 struct snd_soc_rtdcom_list *rtdcom;
377 for_each_rtd_components(rtd, rtdcom, component) {
378 if (!component->driver->compr_ops ||
379 !component->driver->compr_ops->trigger)
382 ret = component->driver->compr_ops->trigger(cstream, cmd);
390 static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
392 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
393 struct snd_soc_dai *codec_dai = rtd->codec_dai;
394 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
397 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
399 ret = soc_compr_components_trigger(cstream, cmd);
403 if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger)
404 cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
407 case SNDRV_PCM_TRIGGER_START:
408 snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction);
410 case SNDRV_PCM_TRIGGER_STOP:
411 snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
416 mutex_unlock(&rtd->card->pcm_mutex);
420 static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
422 struct snd_soc_pcm_runtime *fe = cstream->private_data;
423 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
426 if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
427 cmd == SND_COMPR_TRIGGER_DRAIN)
428 return soc_compr_components_trigger(cstream, cmd);
430 if (cstream->direction == SND_COMPRESS_PLAYBACK)
431 stream = SNDRV_PCM_STREAM_PLAYBACK;
433 stream = SNDRV_PCM_STREAM_CAPTURE;
435 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
437 if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger) {
438 ret = cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
443 ret = soc_compr_components_trigger(cstream, cmd);
447 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
449 ret = dpcm_be_dai_trigger(fe, stream, cmd);
452 case SNDRV_PCM_TRIGGER_START:
453 case SNDRV_PCM_TRIGGER_RESUME:
454 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
455 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
457 case SNDRV_PCM_TRIGGER_STOP:
458 case SNDRV_PCM_TRIGGER_SUSPEND:
459 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
461 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
462 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
467 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
468 mutex_unlock(&fe->card->mutex);
472 static int soc_compr_components_set_params(struct snd_compr_stream *cstream,
473 struct snd_compr_params *params)
475 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
476 struct snd_soc_component *component;
477 struct snd_soc_rtdcom_list *rtdcom;
480 for_each_rtd_components(rtd, rtdcom, component) {
481 if (!component->driver->compr_ops ||
482 !component->driver->compr_ops->set_params)
485 ret = component->driver->compr_ops->set_params(cstream, params);
493 static int soc_compr_set_params(struct snd_compr_stream *cstream,
494 struct snd_compr_params *params)
496 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
497 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
500 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
503 * First we call set_params for the CPU DAI, then the component
504 * driver this should configure the SoC side. If the machine has
505 * compressed ops then we call that as well. The expectation is
506 * that these callbacks will configure everything for this compress
507 * path, like configuring a PCM port for a CODEC.
509 if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
510 ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
515 ret = soc_compr_components_set_params(cstream, params);
519 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) {
520 ret = rtd->dai_link->compr_ops->set_params(cstream);
525 if (cstream->direction == SND_COMPRESS_PLAYBACK)
526 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
527 SND_SOC_DAPM_STREAM_START);
529 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
530 SND_SOC_DAPM_STREAM_START);
532 /* cancel any delayed stream shutdown that is pending */
534 mutex_unlock(&rtd->card->pcm_mutex);
536 cancel_delayed_work_sync(&rtd->delayed_work);
541 mutex_unlock(&rtd->card->pcm_mutex);
545 static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
546 struct snd_compr_params *params)
548 struct snd_soc_pcm_runtime *fe = cstream->private_data;
549 struct snd_pcm_substream *fe_substream =
550 fe->pcm->streams[cstream->direction].substream;
551 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
554 if (cstream->direction == SND_COMPRESS_PLAYBACK)
555 stream = SNDRV_PCM_STREAM_PLAYBACK;
557 stream = SNDRV_PCM_STREAM_CAPTURE;
559 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
562 * Create an empty hw_params for the BE as the machine driver must
563 * fix this up to match DSP decoder and ASRC configuration.
564 * I.e. machine driver fixup for compressed BE is mandatory.
566 memset(&fe->dpcm[fe_substream->stream].hw_params, 0,
567 sizeof(struct snd_pcm_hw_params));
569 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
571 ret = dpcm_be_dai_hw_params(fe, stream);
575 ret = dpcm_be_dai_prepare(fe, stream);
579 if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
580 ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
585 ret = soc_compr_components_set_params(cstream, params);
589 if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->set_params) {
590 ret = fe->dai_link->compr_ops->set_params(cstream);
595 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
596 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
599 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
600 mutex_unlock(&fe->card->mutex);
604 static int soc_compr_get_params(struct snd_compr_stream *cstream,
605 struct snd_codec *params)
607 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
608 struct snd_soc_component *component;
609 struct snd_soc_rtdcom_list *rtdcom;
610 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
613 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
615 if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_params) {
616 ret = cpu_dai->driver->cops->get_params(cstream, params, cpu_dai);
621 for_each_rtd_components(rtd, rtdcom, component) {
622 if (!component->driver->compr_ops ||
623 !component->driver->compr_ops->get_params)
626 ret = component->driver->compr_ops->get_params(cstream, params);
631 mutex_unlock(&rtd->card->pcm_mutex);
635 static int soc_compr_get_caps(struct snd_compr_stream *cstream,
636 struct snd_compr_caps *caps)
638 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
639 struct snd_soc_component *component;
640 struct snd_soc_rtdcom_list *rtdcom;
643 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
645 for_each_rtd_components(rtd, rtdcom, component) {
646 if (!component->driver->compr_ops ||
647 !component->driver->compr_ops->get_caps)
650 ret = component->driver->compr_ops->get_caps(cstream, caps);
654 mutex_unlock(&rtd->card->pcm_mutex);
658 static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
659 struct snd_compr_codec_caps *codec)
661 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
662 struct snd_soc_component *component;
663 struct snd_soc_rtdcom_list *rtdcom;
666 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
668 for_each_rtd_components(rtd, rtdcom, component) {
669 if (!component->driver->compr_ops ||
670 !component->driver->compr_ops->get_codec_caps)
673 ret = component->driver->compr_ops->get_codec_caps(cstream,
678 mutex_unlock(&rtd->card->pcm_mutex);
682 static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
684 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
685 struct snd_soc_component *component;
686 struct snd_soc_rtdcom_list *rtdcom;
687 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
690 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
692 if (cpu_dai->driver->cops && cpu_dai->driver->cops->ack) {
693 ret = cpu_dai->driver->cops->ack(cstream, bytes, cpu_dai);
698 for_each_rtd_components(rtd, rtdcom, component) {
699 if (!component->driver->compr_ops ||
700 !component->driver->compr_ops->ack)
703 ret = component->driver->compr_ops->ack(cstream, bytes);
709 mutex_unlock(&rtd->card->pcm_mutex);
713 static int soc_compr_pointer(struct snd_compr_stream *cstream,
714 struct snd_compr_tstamp *tstamp)
716 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
717 struct snd_soc_component *component;
718 struct snd_soc_rtdcom_list *rtdcom;
720 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
722 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
724 if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
725 cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
727 for_each_rtd_components(rtd, rtdcom, component) {
728 if (!component->driver->compr_ops ||
729 !component->driver->compr_ops->pointer)
732 ret = component->driver->compr_ops->pointer(cstream, tstamp);
736 mutex_unlock(&rtd->card->pcm_mutex);
740 static int soc_compr_copy(struct snd_compr_stream *cstream,
741 char __user *buf, size_t count)
743 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
744 struct snd_soc_component *component;
745 struct snd_soc_rtdcom_list *rtdcom;
748 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
750 for_each_rtd_components(rtd, rtdcom, component) {
751 if (!component->driver->compr_ops ||
752 !component->driver->compr_ops->copy)
755 ret = component->driver->compr_ops->copy(cstream, buf, count);
759 mutex_unlock(&rtd->card->pcm_mutex);
763 static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
764 struct snd_compr_metadata *metadata)
766 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
767 struct snd_soc_component *component;
768 struct snd_soc_rtdcom_list *rtdcom;
769 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
772 if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_metadata) {
773 ret = cpu_dai->driver->cops->set_metadata(cstream, metadata, cpu_dai);
778 for_each_rtd_components(rtd, rtdcom, component) {
779 if (!component->driver->compr_ops ||
780 !component->driver->compr_ops->set_metadata)
783 ret = component->driver->compr_ops->set_metadata(cstream,
792 static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
793 struct snd_compr_metadata *metadata)
795 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
796 struct snd_soc_component *component;
797 struct snd_soc_rtdcom_list *rtdcom;
798 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
801 if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_metadata) {
802 ret = cpu_dai->driver->cops->get_metadata(cstream, metadata, cpu_dai);
807 for_each_rtd_components(rtd, rtdcom, component) {
808 if (!component->driver->compr_ops ||
809 !component->driver->compr_ops->get_metadata)
812 return component->driver->compr_ops->get_metadata(cstream,
819 /* ASoC Compress operations */
820 static struct snd_compr_ops soc_compr_ops = {
821 .open = soc_compr_open,
822 .free = soc_compr_free,
823 .set_params = soc_compr_set_params,
824 .set_metadata = soc_compr_set_metadata,
825 .get_metadata = soc_compr_get_metadata,
826 .get_params = soc_compr_get_params,
827 .trigger = soc_compr_trigger,
828 .pointer = soc_compr_pointer,
829 .ack = soc_compr_ack,
830 .get_caps = soc_compr_get_caps,
831 .get_codec_caps = soc_compr_get_codec_caps
834 /* ASoC Dynamic Compress operations */
835 static struct snd_compr_ops soc_compr_dyn_ops = {
836 .open = soc_compr_open_fe,
837 .free = soc_compr_free_fe,
838 .set_params = soc_compr_set_params_fe,
839 .get_params = soc_compr_get_params,
840 .set_metadata = soc_compr_set_metadata,
841 .get_metadata = soc_compr_get_metadata,
842 .trigger = soc_compr_trigger_fe,
843 .pointer = soc_compr_pointer,
844 .ack = soc_compr_ack,
845 .get_caps = soc_compr_get_caps,
846 .get_codec_caps = soc_compr_get_codec_caps
850 * snd_soc_new_compress - create a new compress.
852 * @rtd: The runtime for which we will create compress
853 * @num: the device index number (zero based - shared with normal PCMs)
855 * Return: 0 for success, else error.
857 int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
859 struct snd_soc_component *component;
860 struct snd_soc_rtdcom_list *rtdcom;
861 struct snd_soc_dai *codec_dai = rtd->codec_dai;
862 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
863 struct snd_compr *compr;
864 struct snd_pcm *be_pcm;
866 int ret = 0, direction = 0;
867 int playback = 0, capture = 0;
869 if (rtd->num_codecs > 1) {
870 dev_err(rtd->card->dev,
871 "Compress ASoC: Multicodec not supported\n");
875 /* check client and interface hw capabilities */
876 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
877 snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK))
879 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&
880 snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE))
884 * Compress devices are unidirectional so only one of the directions
885 * should be set, check for that (xor)
887 if (playback + capture != 1) {
888 dev_err(rtd->card->dev,
889 "Compress ASoC: Invalid direction for P %d, C %d\n",
895 direction = SND_COMPRESS_PLAYBACK;
897 direction = SND_COMPRESS_CAPTURE;
899 compr = devm_kzalloc(rtd->card->dev, sizeof(*compr), GFP_KERNEL);
903 compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
908 if (rtd->dai_link->dynamic) {
909 snprintf(new_name, sizeof(new_name), "(%s)",
910 rtd->dai_link->stream_name);
912 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
913 rtd->dai_link->dpcm_playback,
914 rtd->dai_link->dpcm_capture, &be_pcm);
916 dev_err(rtd->card->dev,
917 "Compress ASoC: can't create compressed for %s: %d\n",
918 rtd->dai_link->name, ret);
924 if (rtd->dai_link->dpcm_playback)
925 be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
926 else if (rtd->dai_link->dpcm_capture)
927 be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
928 memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
930 snprintf(new_name, sizeof(new_name), "%s %s-%d",
931 rtd->dai_link->stream_name, codec_dai->name, num);
933 memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
936 for_each_rtd_components(rtd, rtdcom, component) {
937 if (!component->driver->compr_ops ||
938 !component->driver->compr_ops->copy)
941 compr->ops->copy = soc_compr_copy;
945 mutex_init(&compr->lock);
946 ret = snd_compress_new(rtd->card->snd_card, num, direction,
949 component = rtd->codec_dai->component;
950 dev_err(component->dev,
951 "Compress ASoC: can't create compress for codec %s: %d\n",
952 component->name, ret);
956 /* DAPM dai link stream work */
957 rtd->close_delayed_work_func = close_delayed_work;
960 compr->private_data = rtd;
962 dev_info(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n",
963 codec_dai->name, cpu_dai->name);
967 EXPORT_SYMBOL_GPL(snd_soc_new_compress);