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 <sound/soc-link.h>
23 #include <linux/pm_runtime.h>
25 static int soc_compr_components_open(struct snd_compr_stream
*cstream
,
26 struct snd_soc_component
**last
)
28 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
29 struct snd_soc_component
*component
;
32 for_each_rtd_components(rtd
, i
, component
) {
33 if (!component
->driver
->compress_ops
||
34 !component
->driver
->compress_ops
->open
)
37 ret
= component
->driver
->compress_ops
->open(component
, 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
;
59 for_each_rtd_components(rtd
, i
, component
) {
60 if (component
== last
)
63 if (!component
->driver
->compress_ops
||
64 !component
->driver
->compress_ops
->free
)
67 component
->driver
->compress_ops
->free(component
, 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
= NULL
, *save
= NULL
;
77 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(rtd
, 0);
80 for_each_rtd_components(rtd
, i
, component
) {
81 ret
= pm_runtime_get_sync(component
->dev
);
82 if (ret
< 0 && ret
!= -EACCES
) {
83 pm_runtime_put_noidle(component
->dev
);
89 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
91 ret
= snd_soc_dai_compr_startup(cpu_dai
, cstream
);
95 ret
= soc_compr_components_open(cstream
, &component
);
99 ret
= snd_soc_link_compr_startup(cstream
);
103 snd_soc_runtime_activate(rtd
, cstream
->direction
);
105 mutex_unlock(&rtd
->card
->pcm_mutex
);
110 soc_compr_components_free(cstream
, component
);
112 snd_soc_dai_compr_shutdown(cpu_dai
, cstream
);
114 mutex_unlock(&rtd
->card
->pcm_mutex
);
116 for_each_rtd_components(rtd
, i
, component
) {
117 if (component
== save
)
119 pm_runtime_mark_last_busy(component
->dev
);
120 pm_runtime_put_autosuspend(component
->dev
);
126 static int soc_compr_open_fe(struct snd_compr_stream
*cstream
)
128 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
129 struct snd_pcm_substream
*fe_substream
=
130 fe
->pcm
->streams
[cstream
->direction
].substream
;
131 struct snd_soc_component
*component
;
132 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(fe
, 0);
133 struct snd_soc_dpcm
*dpcm
;
134 struct snd_soc_dapm_widget_list
*list
;
138 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
139 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
141 stream
= SNDRV_PCM_STREAM_CAPTURE
;
143 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
144 fe
->dpcm
[stream
].runtime
= fe_substream
->runtime
;
146 ret
= dpcm_path_get(fe
, stream
, &list
);
150 dev_dbg(fe
->dev
, "Compress ASoC: %s no valid %s route\n",
151 fe
->dai_link
->name
, stream
? "capture" : "playback");
152 /* calculate valid and active FE <-> BE dpcms */
153 dpcm_process_paths(fe
, stream
, &list
, 1);
154 fe
->dpcm
[stream
].runtime
= fe_substream
->runtime
;
156 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
158 ret
= dpcm_be_dai_startup(fe
, stream
);
160 /* clean up all links */
161 for_each_dpcm_be(fe
, stream
, dpcm
)
162 dpcm
->state
= SND_SOC_DPCM_LINK_STATE_FREE
;
164 dpcm_be_disconnect(fe
, stream
);
165 fe
->dpcm
[stream
].runtime
= NULL
;
169 ret
= snd_soc_dai_compr_startup(cpu_dai
, cstream
);
173 ret
= soc_compr_components_open(cstream
, &component
);
177 ret
= snd_soc_link_compr_startup(cstream
);
181 dpcm_clear_pending_state(fe
, stream
);
182 dpcm_path_put(&list
);
184 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_OPEN
;
185 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
187 snd_soc_runtime_activate(fe
, stream
);
189 mutex_unlock(&fe
->card
->mutex
);
194 soc_compr_components_free(cstream
, component
);
196 snd_soc_dai_compr_shutdown(cpu_dai
, cstream
);
198 dpcm_path_put(&list
);
200 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
201 mutex_unlock(&fe
->card
->mutex
);
205 static int soc_compr_free(struct snd_compr_stream
*cstream
)
207 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
208 struct snd_soc_component
*component
;
209 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(rtd
, 0);
210 struct snd_soc_dai
*codec_dai
= asoc_rtd_to_codec(rtd
, 0);
213 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
215 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
216 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
218 stream
= SNDRV_PCM_STREAM_CAPTURE
;
220 snd_soc_runtime_deactivate(rtd
, stream
);
222 snd_soc_dai_digital_mute(codec_dai
, 1, cstream
->direction
);
224 if (!snd_soc_dai_active(cpu_dai
))
227 if (!snd_soc_dai_active(codec_dai
))
230 snd_soc_link_compr_shutdown(cstream
);
232 soc_compr_components_free(cstream
, NULL
);
234 snd_soc_dai_compr_shutdown(cpu_dai
, cstream
);
236 snd_soc_dapm_stream_stop(rtd
, stream
);
238 mutex_unlock(&rtd
->card
->pcm_mutex
);
240 for_each_rtd_components(rtd
, i
, component
) {
241 pm_runtime_mark_last_busy(component
->dev
);
242 pm_runtime_put_autosuspend(component
->dev
);
248 static int soc_compr_free_fe(struct snd_compr_stream
*cstream
)
250 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
251 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(fe
, 0);
252 struct snd_soc_dpcm
*dpcm
;
255 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
257 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
258 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
260 stream
= SNDRV_PCM_STREAM_CAPTURE
;
262 snd_soc_runtime_deactivate(fe
, stream
);
264 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
266 ret
= dpcm_be_dai_hw_free(fe
, stream
);
268 dev_err(fe
->dev
, "Compressed ASoC: hw_free failed: %d\n", ret
);
270 ret
= dpcm_be_dai_shutdown(fe
, stream
);
272 /* mark FE's links ready to prune */
273 for_each_dpcm_be(fe
, stream
, dpcm
)
274 dpcm
->state
= SND_SOC_DPCM_LINK_STATE_FREE
;
276 dpcm_dapm_stream_event(fe
, stream
, SND_SOC_DAPM_STREAM_STOP
);
278 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_CLOSE
;
279 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
281 dpcm_be_disconnect(fe
, stream
);
283 fe
->dpcm
[stream
].runtime
= NULL
;
285 snd_soc_link_compr_shutdown(cstream
);
287 soc_compr_components_free(cstream
, NULL
);
289 snd_soc_dai_compr_shutdown(cpu_dai
, cstream
);
291 mutex_unlock(&fe
->card
->mutex
);
295 static int soc_compr_components_trigger(struct snd_compr_stream
*cstream
,
298 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
299 struct snd_soc_component
*component
;
302 for_each_rtd_components(rtd
, i
, component
) {
303 if (!component
->driver
->compress_ops
||
304 !component
->driver
->compress_ops
->trigger
)
307 ret
= component
->driver
->compress_ops
->trigger(
308 component
, cstream
, cmd
);
316 static int soc_compr_trigger(struct snd_compr_stream
*cstream
, int cmd
)
318 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
319 struct snd_soc_dai
*codec_dai
= asoc_rtd_to_codec(rtd
, 0);
320 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(rtd
, 0);
323 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
325 ret
= soc_compr_components_trigger(cstream
, cmd
);
329 ret
= snd_soc_dai_compr_trigger(cpu_dai
, cstream
, cmd
);
334 case SNDRV_PCM_TRIGGER_START
:
335 snd_soc_dai_digital_mute(codec_dai
, 0, cstream
->direction
);
337 case SNDRV_PCM_TRIGGER_STOP
:
338 snd_soc_dai_digital_mute(codec_dai
, 1, cstream
->direction
);
343 mutex_unlock(&rtd
->card
->pcm_mutex
);
347 static int soc_compr_trigger_fe(struct snd_compr_stream
*cstream
, int cmd
)
349 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
350 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(fe
, 0);
353 if (cmd
== SND_COMPR_TRIGGER_PARTIAL_DRAIN
||
354 cmd
== SND_COMPR_TRIGGER_DRAIN
)
355 return soc_compr_components_trigger(cstream
, cmd
);
357 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
358 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
360 stream
= SNDRV_PCM_STREAM_CAPTURE
;
362 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
364 ret
= snd_soc_dai_compr_trigger(cpu_dai
, cstream
, cmd
);
368 ret
= soc_compr_components_trigger(cstream
, cmd
);
372 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
374 ret
= dpcm_be_dai_trigger(fe
, stream
, cmd
);
377 case SNDRV_PCM_TRIGGER_START
:
378 case SNDRV_PCM_TRIGGER_RESUME
:
379 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
380 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_START
;
382 case SNDRV_PCM_TRIGGER_STOP
:
383 case SNDRV_PCM_TRIGGER_SUSPEND
:
384 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_STOP
;
386 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
387 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_PAUSED
;
392 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
393 mutex_unlock(&fe
->card
->mutex
);
397 static int soc_compr_components_set_params(struct snd_compr_stream
*cstream
,
398 struct snd_compr_params
*params
)
400 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
401 struct snd_soc_component
*component
;
404 for_each_rtd_components(rtd
, i
, component
) {
405 if (!component
->driver
->compress_ops
||
406 !component
->driver
->compress_ops
->set_params
)
409 ret
= component
->driver
->compress_ops
->set_params(
410 component
, cstream
, params
);
418 static int soc_compr_set_params(struct snd_compr_stream
*cstream
,
419 struct snd_compr_params
*params
)
421 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
422 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(rtd
, 0);
425 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
428 * First we call set_params for the CPU DAI, then the component
429 * driver this should configure the SoC side. If the machine has
430 * compressed ops then we call that as well. The expectation is
431 * that these callbacks will configure everything for this compress
432 * path, like configuring a PCM port for a CODEC.
434 ret
= snd_soc_dai_compr_set_params(cpu_dai
, cstream
, params
);
438 ret
= soc_compr_components_set_params(cstream
, params
);
442 ret
= snd_soc_link_compr_set_params(cstream
);
446 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
447 snd_soc_dapm_stream_event(rtd
, SNDRV_PCM_STREAM_PLAYBACK
,
448 SND_SOC_DAPM_STREAM_START
);
450 snd_soc_dapm_stream_event(rtd
, SNDRV_PCM_STREAM_CAPTURE
,
451 SND_SOC_DAPM_STREAM_START
);
453 /* cancel any delayed stream shutdown that is pending */
455 mutex_unlock(&rtd
->card
->pcm_mutex
);
457 cancel_delayed_work_sync(&rtd
->delayed_work
);
462 mutex_unlock(&rtd
->card
->pcm_mutex
);
466 static int soc_compr_set_params_fe(struct snd_compr_stream
*cstream
,
467 struct snd_compr_params
*params
)
469 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
470 struct snd_pcm_substream
*fe_substream
=
471 fe
->pcm
->streams
[cstream
->direction
].substream
;
472 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(fe
, 0);
475 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
476 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
478 stream
= SNDRV_PCM_STREAM_CAPTURE
;
480 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
483 * Create an empty hw_params for the BE as the machine driver must
484 * fix this up to match DSP decoder and ASRC configuration.
485 * I.e. machine driver fixup for compressed BE is mandatory.
487 memset(&fe
->dpcm
[fe_substream
->stream
].hw_params
, 0,
488 sizeof(struct snd_pcm_hw_params
));
490 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
492 ret
= dpcm_be_dai_hw_params(fe
, stream
);
496 ret
= dpcm_be_dai_prepare(fe
, stream
);
500 ret
= snd_soc_dai_compr_set_params(cpu_dai
, cstream
, params
);
504 ret
= soc_compr_components_set_params(cstream
, params
);
508 ret
= snd_soc_link_compr_set_params(cstream
);
512 dpcm_dapm_stream_event(fe
, stream
, SND_SOC_DAPM_STREAM_START
);
513 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_PREPARE
;
516 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
517 mutex_unlock(&fe
->card
->mutex
);
521 static int soc_compr_get_params(struct snd_compr_stream
*cstream
,
522 struct snd_codec
*params
)
524 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
525 struct snd_soc_component
*component
;
526 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(rtd
, 0);
529 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
531 ret
= snd_soc_dai_compr_get_params(cpu_dai
, cstream
, params
);
535 for_each_rtd_components(rtd
, i
, component
) {
536 if (!component
->driver
->compress_ops
||
537 !component
->driver
->compress_ops
->get_params
)
540 ret
= component
->driver
->compress_ops
->get_params(
541 component
, cstream
, params
);
546 mutex_unlock(&rtd
->card
->pcm_mutex
);
550 static int soc_compr_get_caps(struct snd_compr_stream
*cstream
,
551 struct snd_compr_caps
*caps
)
553 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
554 struct snd_soc_component
*component
;
557 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
559 for_each_rtd_components(rtd
, i
, component
) {
560 if (!component
->driver
->compress_ops
||
561 !component
->driver
->compress_ops
->get_caps
)
564 ret
= component
->driver
->compress_ops
->get_caps(
565 component
, cstream
, caps
);
569 mutex_unlock(&rtd
->card
->pcm_mutex
);
573 static int soc_compr_get_codec_caps(struct snd_compr_stream
*cstream
,
574 struct snd_compr_codec_caps
*codec
)
576 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
577 struct snd_soc_component
*component
;
580 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
582 for_each_rtd_components(rtd
, i
, component
) {
583 if (!component
->driver
->compress_ops
||
584 !component
->driver
->compress_ops
->get_codec_caps
)
587 ret
= component
->driver
->compress_ops
->get_codec_caps(
588 component
, cstream
, codec
);
592 mutex_unlock(&rtd
->card
->pcm_mutex
);
596 static int soc_compr_ack(struct snd_compr_stream
*cstream
, size_t bytes
)
598 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
599 struct snd_soc_component
*component
;
600 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(rtd
, 0);
603 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
605 ret
= snd_soc_dai_compr_ack(cpu_dai
, cstream
, bytes
);
609 for_each_rtd_components(rtd
, i
, component
) {
610 if (!component
->driver
->compress_ops
||
611 !component
->driver
->compress_ops
->ack
)
614 ret
= component
->driver
->compress_ops
->ack(
615 component
, cstream
, bytes
);
621 mutex_unlock(&rtd
->card
->pcm_mutex
);
625 static int soc_compr_pointer(struct snd_compr_stream
*cstream
,
626 struct snd_compr_tstamp
*tstamp
)
628 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
629 struct snd_soc_component
*component
;
631 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(rtd
, 0);
633 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
635 ret
= snd_soc_dai_compr_pointer(cpu_dai
, cstream
, tstamp
);
639 for_each_rtd_components(rtd
, i
, component
) {
640 if (!component
->driver
->compress_ops
||
641 !component
->driver
->compress_ops
->pointer
)
644 ret
= component
->driver
->compress_ops
->pointer(
645 component
, cstream
, tstamp
);
649 mutex_unlock(&rtd
->card
->pcm_mutex
);
653 static int soc_compr_copy(struct snd_compr_stream
*cstream
,
654 char __user
*buf
, size_t count
)
656 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
657 struct snd_soc_component
*component
;
660 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
662 for_each_rtd_components(rtd
, i
, component
) {
663 if (!component
->driver
->compress_ops
||
664 !component
->driver
->compress_ops
->copy
)
667 ret
= component
->driver
->compress_ops
->copy(
668 component
, cstream
, buf
, count
);
672 mutex_unlock(&rtd
->card
->pcm_mutex
);
676 static int soc_compr_set_metadata(struct snd_compr_stream
*cstream
,
677 struct snd_compr_metadata
*metadata
)
679 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
680 struct snd_soc_component
*component
;
681 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(rtd
, 0);
684 ret
= snd_soc_dai_compr_set_metadata(cpu_dai
, cstream
, metadata
);
688 for_each_rtd_components(rtd
, i
, component
) {
689 if (!component
->driver
->compress_ops
||
690 !component
->driver
->compress_ops
->set_metadata
)
693 ret
= component
->driver
->compress_ops
->set_metadata(
694 component
, cstream
, metadata
);
702 static int soc_compr_get_metadata(struct snd_compr_stream
*cstream
,
703 struct snd_compr_metadata
*metadata
)
705 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
706 struct snd_soc_component
*component
;
707 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(rtd
, 0);
710 ret
= snd_soc_dai_compr_get_metadata(cpu_dai
, cstream
, metadata
);
714 for_each_rtd_components(rtd
, i
, component
) {
715 if (!component
->driver
->compress_ops
||
716 !component
->driver
->compress_ops
->get_metadata
)
719 return component
->driver
->compress_ops
->get_metadata(
720 component
, cstream
, metadata
);
726 /* ASoC Compress operations */
727 static struct snd_compr_ops soc_compr_ops
= {
728 .open
= soc_compr_open
,
729 .free
= soc_compr_free
,
730 .set_params
= soc_compr_set_params
,
731 .set_metadata
= soc_compr_set_metadata
,
732 .get_metadata
= soc_compr_get_metadata
,
733 .get_params
= soc_compr_get_params
,
734 .trigger
= soc_compr_trigger
,
735 .pointer
= soc_compr_pointer
,
736 .ack
= soc_compr_ack
,
737 .get_caps
= soc_compr_get_caps
,
738 .get_codec_caps
= soc_compr_get_codec_caps
741 /* ASoC Dynamic Compress operations */
742 static struct snd_compr_ops soc_compr_dyn_ops
= {
743 .open
= soc_compr_open_fe
,
744 .free
= soc_compr_free_fe
,
745 .set_params
= soc_compr_set_params_fe
,
746 .get_params
= soc_compr_get_params
,
747 .set_metadata
= soc_compr_set_metadata
,
748 .get_metadata
= soc_compr_get_metadata
,
749 .trigger
= soc_compr_trigger_fe
,
750 .pointer
= soc_compr_pointer
,
751 .ack
= soc_compr_ack
,
752 .get_caps
= soc_compr_get_caps
,
753 .get_codec_caps
= soc_compr_get_codec_caps
757 * snd_soc_new_compress - create a new compress.
759 * @rtd: The runtime for which we will create compress
760 * @num: the device index number (zero based - shared with normal PCMs)
762 * Return: 0 for success, else error.
764 int snd_soc_new_compress(struct snd_soc_pcm_runtime
*rtd
, int num
)
766 struct snd_soc_component
*component
;
767 struct snd_soc_dai
*codec_dai
= asoc_rtd_to_codec(rtd
, 0);
768 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(rtd
, 0);
769 struct snd_compr
*compr
;
770 struct snd_pcm
*be_pcm
;
772 int ret
= 0, direction
= 0;
773 int playback
= 0, capture
= 0;
776 if (rtd
->num_cpus
> 1 ||
777 rtd
->num_codecs
> 1) {
778 dev_err(rtd
->card
->dev
,
779 "Compress ASoC: Multi CPU/Codec not supported\n");
783 /* check client and interface hw capabilities */
784 if (snd_soc_dai_stream_valid(codec_dai
, SNDRV_PCM_STREAM_PLAYBACK
) &&
785 snd_soc_dai_stream_valid(cpu_dai
, SNDRV_PCM_STREAM_PLAYBACK
))
787 if (snd_soc_dai_stream_valid(codec_dai
, SNDRV_PCM_STREAM_CAPTURE
) &&
788 snd_soc_dai_stream_valid(cpu_dai
, SNDRV_PCM_STREAM_CAPTURE
))
792 * Compress devices are unidirectional so only one of the directions
793 * should be set, check for that (xor)
795 if (playback
+ capture
!= 1) {
796 dev_err(rtd
->card
->dev
,
797 "Compress ASoC: Invalid direction for P %d, C %d\n",
803 direction
= SND_COMPRESS_PLAYBACK
;
805 direction
= SND_COMPRESS_CAPTURE
;
807 compr
= devm_kzalloc(rtd
->card
->dev
, sizeof(*compr
), GFP_KERNEL
);
811 compr
->ops
= devm_kzalloc(rtd
->card
->dev
, sizeof(soc_compr_ops
),
816 if (rtd
->dai_link
->dynamic
) {
817 snprintf(new_name
, sizeof(new_name
), "(%s)",
818 rtd
->dai_link
->stream_name
);
820 ret
= snd_pcm_new_internal(rtd
->card
->snd_card
, new_name
, num
,
821 rtd
->dai_link
->dpcm_playback
,
822 rtd
->dai_link
->dpcm_capture
, &be_pcm
);
824 dev_err(rtd
->card
->dev
,
825 "Compress ASoC: can't create compressed for %s: %d\n",
826 rtd
->dai_link
->name
, ret
);
832 if (rtd
->dai_link
->dpcm_playback
)
833 be_pcm
->streams
[SNDRV_PCM_STREAM_PLAYBACK
].substream
->private_data
= rtd
;
834 else if (rtd
->dai_link
->dpcm_capture
)
835 be_pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
->private_data
= rtd
;
836 memcpy(compr
->ops
, &soc_compr_dyn_ops
, sizeof(soc_compr_dyn_ops
));
838 snprintf(new_name
, sizeof(new_name
), "%s %s-%d",
839 rtd
->dai_link
->stream_name
, codec_dai
->name
, num
);
841 memcpy(compr
->ops
, &soc_compr_ops
, sizeof(soc_compr_ops
));
844 for_each_rtd_components(rtd
, i
, component
) {
845 if (!component
->driver
->compress_ops
||
846 !component
->driver
->compress_ops
->copy
)
849 compr
->ops
->copy
= soc_compr_copy
;
853 mutex_init(&compr
->lock
);
854 ret
= snd_compress_new(rtd
->card
->snd_card
, num
, direction
,
857 component
= asoc_rtd_to_codec(rtd
, 0)->component
;
858 dev_err(component
->dev
,
859 "Compress ASoC: can't create compress for codec %s: %d\n",
860 component
->name
, ret
);
864 /* DAPM dai link stream work */
865 rtd
->close_delayed_work_func
= snd_soc_close_delayed_work
;
868 compr
->private_data
= rtd
;
870 dev_dbg(rtd
->card
->dev
, "Compress ASoC: %s <-> %s mapping ok\n",
871 codec_dai
->name
, cpu_dai
->name
);
875 EXPORT_SYMBOL_GPL(snd_soc_new_compress
);