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
;
31 for_each_rtd_components(rtd
, i
, component
) {
32 if (!component
->driver
->compr_ops
||
33 !component
->driver
->compr_ops
->open
)
36 ret
= component
->driver
->compr_ops
->open(cstream
);
38 dev_err(component
->dev
,
39 "Compress ASoC: can't open platform %s: %d\n",
40 component
->name
, ret
);
51 static int soc_compr_components_free(struct snd_compr_stream
*cstream
,
52 struct snd_soc_component
*last
)
54 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
55 struct snd_soc_component
*component
;
58 for_each_rtd_components(rtd
, i
, component
) {
59 if (component
== last
)
62 if (!component
->driver
->compr_ops
||
63 !component
->driver
->compr_ops
->free
)
66 component
->driver
->compr_ops
->free(cstream
);
72 static int soc_compr_open(struct snd_compr_stream
*cstream
)
74 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
75 struct snd_soc_component
*component
, *save
= NULL
;
76 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
79 for_each_rtd_components(rtd
, i
, component
) {
80 ret
= pm_runtime_get_sync(component
->dev
);
81 if (ret
< 0 && ret
!= -EACCES
) {
82 pm_runtime_put_noidle(component
->dev
);
88 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
90 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->startup
) {
91 ret
= cpu_dai
->driver
->cops
->startup(cstream
, cpu_dai
);
94 "Compress ASoC: can't open interface %s: %d\n",
100 ret
= soc_compr_components_open(cstream
, &component
);
104 if (rtd
->dai_link
->compr_ops
&& rtd
->dai_link
->compr_ops
->startup
) {
105 ret
= rtd
->dai_link
->compr_ops
->startup(cstream
);
108 "Compress ASoC: %s startup failed: %d\n",
109 rtd
->dai_link
->name
, ret
);
114 snd_soc_runtime_activate(rtd
, cstream
->direction
);
116 mutex_unlock(&rtd
->card
->pcm_mutex
);
121 soc_compr_components_free(cstream
, component
);
123 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->shutdown
)
124 cpu_dai
->driver
->cops
->shutdown(cstream
, cpu_dai
);
126 mutex_unlock(&rtd
->card
->pcm_mutex
);
128 for_each_rtd_components(rtd
, i
, component
) {
129 if (component
== save
)
131 pm_runtime_mark_last_busy(component
->dev
);
132 pm_runtime_put_autosuspend(component
->dev
);
138 static int soc_compr_open_fe(struct snd_compr_stream
*cstream
)
140 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
141 struct snd_pcm_substream
*fe_substream
=
142 fe
->pcm
->streams
[cstream
->direction
].substream
;
143 struct snd_soc_component
*component
;
144 struct snd_soc_dai
*cpu_dai
= fe
->cpu_dai
;
145 struct snd_soc_dpcm
*dpcm
;
146 struct snd_soc_dapm_widget_list
*list
;
150 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
151 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
153 stream
= SNDRV_PCM_STREAM_CAPTURE
;
155 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
156 fe
->dpcm
[stream
].runtime
= fe_substream
->runtime
;
158 ret
= dpcm_path_get(fe
, stream
, &list
);
162 dev_dbg(fe
->dev
, "Compress ASoC: %s no valid %s route\n",
163 fe
->dai_link
->name
, stream
? "capture" : "playback");
164 /* calculate valid and active FE <-> BE dpcms */
165 dpcm_process_paths(fe
, stream
, &list
, 1);
166 fe
->dpcm
[stream
].runtime
= fe_substream
->runtime
;
168 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
170 ret
= dpcm_be_dai_startup(fe
, stream
);
172 /* clean up all links */
173 for_each_dpcm_be(fe
, stream
, dpcm
)
174 dpcm
->state
= SND_SOC_DPCM_LINK_STATE_FREE
;
176 dpcm_be_disconnect(fe
, stream
);
177 fe
->dpcm
[stream
].runtime
= NULL
;
181 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->startup
) {
182 ret
= cpu_dai
->driver
->cops
->startup(cstream
, cpu_dai
);
184 dev_err(cpu_dai
->dev
,
185 "Compress ASoC: can't open interface %s: %d\n",
191 ret
= soc_compr_components_open(cstream
, &component
);
195 if (fe
->dai_link
->compr_ops
&& fe
->dai_link
->compr_ops
->startup
) {
196 ret
= fe
->dai_link
->compr_ops
->startup(cstream
);
198 pr_err("Compress ASoC: %s startup failed: %d\n",
199 fe
->dai_link
->name
, ret
);
204 dpcm_clear_pending_state(fe
, stream
);
205 dpcm_path_put(&list
);
207 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_OPEN
;
208 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
210 snd_soc_runtime_activate(fe
, stream
);
212 mutex_unlock(&fe
->card
->mutex
);
217 soc_compr_components_free(cstream
, component
);
219 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->shutdown
)
220 cpu_dai
->driver
->cops
->shutdown(cstream
, cpu_dai
);
222 dpcm_path_put(&list
);
224 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
225 mutex_unlock(&fe
->card
->mutex
);
229 static int soc_compr_free(struct snd_compr_stream
*cstream
)
231 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
232 struct snd_soc_component
*component
;
233 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
234 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
237 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
239 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
240 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
242 stream
= SNDRV_PCM_STREAM_CAPTURE
;
244 snd_soc_runtime_deactivate(rtd
, stream
);
246 snd_soc_dai_digital_mute(codec_dai
, 1, cstream
->direction
);
248 if (!cpu_dai
->active
)
251 if (!codec_dai
->active
)
254 if (rtd
->dai_link
->compr_ops
&& rtd
->dai_link
->compr_ops
->shutdown
)
255 rtd
->dai_link
->compr_ops
->shutdown(cstream
);
257 soc_compr_components_free(cstream
, NULL
);
259 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->shutdown
)
260 cpu_dai
->driver
->cops
->shutdown(cstream
, cpu_dai
);
262 snd_soc_dapm_stream_stop(rtd
, stream
);
264 mutex_unlock(&rtd
->card
->pcm_mutex
);
266 for_each_rtd_components(rtd
, i
, component
) {
267 pm_runtime_mark_last_busy(component
->dev
);
268 pm_runtime_put_autosuspend(component
->dev
);
274 static int soc_compr_free_fe(struct snd_compr_stream
*cstream
)
276 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
277 struct snd_soc_dai
*cpu_dai
= fe
->cpu_dai
;
278 struct snd_soc_dpcm
*dpcm
;
281 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
283 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
284 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
286 stream
= SNDRV_PCM_STREAM_CAPTURE
;
288 snd_soc_runtime_deactivate(fe
, stream
);
290 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
292 ret
= dpcm_be_dai_hw_free(fe
, stream
);
294 dev_err(fe
->dev
, "Compressed ASoC: hw_free failed: %d\n", ret
);
296 ret
= dpcm_be_dai_shutdown(fe
, stream
);
298 /* mark FE's links ready to prune */
299 for_each_dpcm_be(fe
, stream
, dpcm
)
300 dpcm
->state
= SND_SOC_DPCM_LINK_STATE_FREE
;
302 snd_soc_dapm_stream_stop(fe
, stream
);
304 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_CLOSE
;
305 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
307 dpcm_be_disconnect(fe
, stream
);
309 fe
->dpcm
[stream
].runtime
= NULL
;
311 if (fe
->dai_link
->compr_ops
&& fe
->dai_link
->compr_ops
->shutdown
)
312 fe
->dai_link
->compr_ops
->shutdown(cstream
);
314 soc_compr_components_free(cstream
, NULL
);
316 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->shutdown
)
317 cpu_dai
->driver
->cops
->shutdown(cstream
, cpu_dai
);
319 mutex_unlock(&fe
->card
->mutex
);
323 static int soc_compr_components_trigger(struct snd_compr_stream
*cstream
,
326 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
327 struct snd_soc_component
*component
;
330 for_each_rtd_components(rtd
, i
, component
) {
331 if (!component
->driver
->compr_ops
||
332 !component
->driver
->compr_ops
->trigger
)
335 ret
= component
->driver
->compr_ops
->trigger(cstream
, cmd
);
343 static int soc_compr_trigger(struct snd_compr_stream
*cstream
, int cmd
)
345 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
346 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
347 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
350 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
352 ret
= soc_compr_components_trigger(cstream
, cmd
);
356 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->trigger
)
357 cpu_dai
->driver
->cops
->trigger(cstream
, cmd
, cpu_dai
);
360 case SNDRV_PCM_TRIGGER_START
:
361 snd_soc_dai_digital_mute(codec_dai
, 0, cstream
->direction
);
363 case SNDRV_PCM_TRIGGER_STOP
:
364 snd_soc_dai_digital_mute(codec_dai
, 1, cstream
->direction
);
369 mutex_unlock(&rtd
->card
->pcm_mutex
);
373 static int soc_compr_trigger_fe(struct snd_compr_stream
*cstream
, int cmd
)
375 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
376 struct snd_soc_dai
*cpu_dai
= fe
->cpu_dai
;
379 if (cmd
== SND_COMPR_TRIGGER_PARTIAL_DRAIN
||
380 cmd
== SND_COMPR_TRIGGER_DRAIN
)
381 return soc_compr_components_trigger(cstream
, cmd
);
383 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
384 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
386 stream
= SNDRV_PCM_STREAM_CAPTURE
;
388 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
390 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->trigger
) {
391 ret
= cpu_dai
->driver
->cops
->trigger(cstream
, cmd
, cpu_dai
);
396 ret
= soc_compr_components_trigger(cstream
, cmd
);
400 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
402 ret
= dpcm_be_dai_trigger(fe
, stream
, cmd
);
405 case SNDRV_PCM_TRIGGER_START
:
406 case SNDRV_PCM_TRIGGER_RESUME
:
407 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
408 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_START
;
410 case SNDRV_PCM_TRIGGER_STOP
:
411 case SNDRV_PCM_TRIGGER_SUSPEND
:
412 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_STOP
;
414 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
415 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_PAUSED
;
420 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
421 mutex_unlock(&fe
->card
->mutex
);
425 static int soc_compr_components_set_params(struct snd_compr_stream
*cstream
,
426 struct snd_compr_params
*params
)
428 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
429 struct snd_soc_component
*component
;
432 for_each_rtd_components(rtd
, i
, component
) {
433 if (!component
->driver
->compr_ops
||
434 !component
->driver
->compr_ops
->set_params
)
437 ret
= component
->driver
->compr_ops
->set_params(cstream
, params
);
445 static int soc_compr_set_params(struct snd_compr_stream
*cstream
,
446 struct snd_compr_params
*params
)
448 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
449 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
452 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
455 * First we call set_params for the CPU DAI, then the component
456 * driver this should configure the SoC side. If the machine has
457 * compressed ops then we call that as well. The expectation is
458 * that these callbacks will configure everything for this compress
459 * path, like configuring a PCM port for a CODEC.
461 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->set_params
) {
462 ret
= cpu_dai
->driver
->cops
->set_params(cstream
, params
, cpu_dai
);
467 ret
= soc_compr_components_set_params(cstream
, params
);
471 if (rtd
->dai_link
->compr_ops
&& rtd
->dai_link
->compr_ops
->set_params
) {
472 ret
= rtd
->dai_link
->compr_ops
->set_params(cstream
);
477 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
478 snd_soc_dapm_stream_event(rtd
, SNDRV_PCM_STREAM_PLAYBACK
,
479 SND_SOC_DAPM_STREAM_START
);
481 snd_soc_dapm_stream_event(rtd
, SNDRV_PCM_STREAM_CAPTURE
,
482 SND_SOC_DAPM_STREAM_START
);
484 /* cancel any delayed stream shutdown that is pending */
486 mutex_unlock(&rtd
->card
->pcm_mutex
);
488 cancel_delayed_work_sync(&rtd
->delayed_work
);
493 mutex_unlock(&rtd
->card
->pcm_mutex
);
497 static int soc_compr_set_params_fe(struct snd_compr_stream
*cstream
,
498 struct snd_compr_params
*params
)
500 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
501 struct snd_pcm_substream
*fe_substream
=
502 fe
->pcm
->streams
[cstream
->direction
].substream
;
503 struct snd_soc_dai
*cpu_dai
= fe
->cpu_dai
;
506 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
507 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
509 stream
= SNDRV_PCM_STREAM_CAPTURE
;
511 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
514 * Create an empty hw_params for the BE as the machine driver must
515 * fix this up to match DSP decoder and ASRC configuration.
516 * I.e. machine driver fixup for compressed BE is mandatory.
518 memset(&fe
->dpcm
[fe_substream
->stream
].hw_params
, 0,
519 sizeof(struct snd_pcm_hw_params
));
521 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
523 ret
= dpcm_be_dai_hw_params(fe
, stream
);
527 ret
= dpcm_be_dai_prepare(fe
, stream
);
531 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->set_params
) {
532 ret
= cpu_dai
->driver
->cops
->set_params(cstream
, params
, cpu_dai
);
537 ret
= soc_compr_components_set_params(cstream
, params
);
541 if (fe
->dai_link
->compr_ops
&& fe
->dai_link
->compr_ops
->set_params
) {
542 ret
= fe
->dai_link
->compr_ops
->set_params(cstream
);
547 dpcm_dapm_stream_event(fe
, stream
, SND_SOC_DAPM_STREAM_START
);
548 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_PREPARE
;
551 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
552 mutex_unlock(&fe
->card
->mutex
);
556 static int soc_compr_get_params(struct snd_compr_stream
*cstream
,
557 struct snd_codec
*params
)
559 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
560 struct snd_soc_component
*component
;
561 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
564 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
566 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->get_params
) {
567 ret
= cpu_dai
->driver
->cops
->get_params(cstream
, params
, cpu_dai
);
572 for_each_rtd_components(rtd
, i
, component
) {
573 if (!component
->driver
->compr_ops
||
574 !component
->driver
->compr_ops
->get_params
)
577 ret
= component
->driver
->compr_ops
->get_params(cstream
, params
);
582 mutex_unlock(&rtd
->card
->pcm_mutex
);
586 static int soc_compr_get_caps(struct snd_compr_stream
*cstream
,
587 struct snd_compr_caps
*caps
)
589 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
590 struct snd_soc_component
*component
;
593 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
595 for_each_rtd_components(rtd
, i
, component
) {
596 if (!component
->driver
->compr_ops
||
597 !component
->driver
->compr_ops
->get_caps
)
600 ret
= component
->driver
->compr_ops
->get_caps(cstream
, caps
);
604 mutex_unlock(&rtd
->card
->pcm_mutex
);
608 static int soc_compr_get_codec_caps(struct snd_compr_stream
*cstream
,
609 struct snd_compr_codec_caps
*codec
)
611 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
612 struct snd_soc_component
*component
;
615 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
617 for_each_rtd_components(rtd
, i
, component
) {
618 if (!component
->driver
->compr_ops
||
619 !component
->driver
->compr_ops
->get_codec_caps
)
622 ret
= component
->driver
->compr_ops
->get_codec_caps(cstream
,
627 mutex_unlock(&rtd
->card
->pcm_mutex
);
631 static int soc_compr_ack(struct snd_compr_stream
*cstream
, size_t bytes
)
633 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
634 struct snd_soc_component
*component
;
635 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
638 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
640 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->ack
) {
641 ret
= cpu_dai
->driver
->cops
->ack(cstream
, bytes
, cpu_dai
);
646 for_each_rtd_components(rtd
, i
, component
) {
647 if (!component
->driver
->compr_ops
||
648 !component
->driver
->compr_ops
->ack
)
651 ret
= component
->driver
->compr_ops
->ack(cstream
, bytes
);
657 mutex_unlock(&rtd
->card
->pcm_mutex
);
661 static int soc_compr_pointer(struct snd_compr_stream
*cstream
,
662 struct snd_compr_tstamp
*tstamp
)
664 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
665 struct snd_soc_component
*component
;
667 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
669 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
671 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->pointer
)
672 cpu_dai
->driver
->cops
->pointer(cstream
, tstamp
, cpu_dai
);
674 for_each_rtd_components(rtd
, i
, component
) {
675 if (!component
->driver
->compr_ops
||
676 !component
->driver
->compr_ops
->pointer
)
679 ret
= component
->driver
->compr_ops
->pointer(cstream
, tstamp
);
683 mutex_unlock(&rtd
->card
->pcm_mutex
);
687 static int soc_compr_copy(struct snd_compr_stream
*cstream
,
688 char __user
*buf
, size_t count
)
690 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
691 struct snd_soc_component
*component
;
694 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
696 for_each_rtd_components(rtd
, i
, component
) {
697 if (!component
->driver
->compr_ops
||
698 !component
->driver
->compr_ops
->copy
)
701 ret
= component
->driver
->compr_ops
->copy(cstream
, buf
, count
);
705 mutex_unlock(&rtd
->card
->pcm_mutex
);
709 static int soc_compr_set_metadata(struct snd_compr_stream
*cstream
,
710 struct snd_compr_metadata
*metadata
)
712 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
713 struct snd_soc_component
*component
;
714 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
717 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->set_metadata
) {
718 ret
= cpu_dai
->driver
->cops
->set_metadata(cstream
, metadata
, cpu_dai
);
723 for_each_rtd_components(rtd
, i
, component
) {
724 if (!component
->driver
->compr_ops
||
725 !component
->driver
->compr_ops
->set_metadata
)
728 ret
= component
->driver
->compr_ops
->set_metadata(cstream
,
737 static int soc_compr_get_metadata(struct snd_compr_stream
*cstream
,
738 struct snd_compr_metadata
*metadata
)
740 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
741 struct snd_soc_component
*component
;
742 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
745 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->get_metadata
) {
746 ret
= cpu_dai
->driver
->cops
->get_metadata(cstream
, metadata
, cpu_dai
);
751 for_each_rtd_components(rtd
, i
, component
) {
752 if (!component
->driver
->compr_ops
||
753 !component
->driver
->compr_ops
->get_metadata
)
756 return component
->driver
->compr_ops
->get_metadata(cstream
,
763 /* ASoC Compress operations */
764 static struct snd_compr_ops soc_compr_ops
= {
765 .open
= soc_compr_open
,
766 .free
= soc_compr_free
,
767 .set_params
= soc_compr_set_params
,
768 .set_metadata
= soc_compr_set_metadata
,
769 .get_metadata
= soc_compr_get_metadata
,
770 .get_params
= soc_compr_get_params
,
771 .trigger
= soc_compr_trigger
,
772 .pointer
= soc_compr_pointer
,
773 .ack
= soc_compr_ack
,
774 .get_caps
= soc_compr_get_caps
,
775 .get_codec_caps
= soc_compr_get_codec_caps
778 /* ASoC Dynamic Compress operations */
779 static struct snd_compr_ops soc_compr_dyn_ops
= {
780 .open
= soc_compr_open_fe
,
781 .free
= soc_compr_free_fe
,
782 .set_params
= soc_compr_set_params_fe
,
783 .get_params
= soc_compr_get_params
,
784 .set_metadata
= soc_compr_set_metadata
,
785 .get_metadata
= soc_compr_get_metadata
,
786 .trigger
= soc_compr_trigger_fe
,
787 .pointer
= soc_compr_pointer
,
788 .ack
= soc_compr_ack
,
789 .get_caps
= soc_compr_get_caps
,
790 .get_codec_caps
= soc_compr_get_codec_caps
794 * snd_soc_new_compress - create a new compress.
796 * @rtd: The runtime for which we will create compress
797 * @num: the device index number (zero based - shared with normal PCMs)
799 * Return: 0 for success, else error.
801 int snd_soc_new_compress(struct snd_soc_pcm_runtime
*rtd
, int num
)
803 struct snd_soc_component
*component
;
804 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
805 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
806 struct snd_compr
*compr
;
807 struct snd_pcm
*be_pcm
;
809 int ret
= 0, direction
= 0;
810 int playback
= 0, capture
= 0;
813 if (rtd
->num_codecs
> 1) {
814 dev_err(rtd
->card
->dev
,
815 "Compress ASoC: Multicodec not supported\n");
819 /* check client and interface hw capabilities */
820 if (snd_soc_dai_stream_valid(codec_dai
, SNDRV_PCM_STREAM_PLAYBACK
) &&
821 snd_soc_dai_stream_valid(cpu_dai
, SNDRV_PCM_STREAM_PLAYBACK
))
823 if (snd_soc_dai_stream_valid(codec_dai
, SNDRV_PCM_STREAM_CAPTURE
) &&
824 snd_soc_dai_stream_valid(cpu_dai
, SNDRV_PCM_STREAM_CAPTURE
))
828 * Compress devices are unidirectional so only one of the directions
829 * should be set, check for that (xor)
831 if (playback
+ capture
!= 1) {
832 dev_err(rtd
->card
->dev
,
833 "Compress ASoC: Invalid direction for P %d, C %d\n",
839 direction
= SND_COMPRESS_PLAYBACK
;
841 direction
= SND_COMPRESS_CAPTURE
;
843 compr
= devm_kzalloc(rtd
->card
->dev
, sizeof(*compr
), GFP_KERNEL
);
847 compr
->ops
= devm_kzalloc(rtd
->card
->dev
, sizeof(soc_compr_ops
),
852 if (rtd
->dai_link
->dynamic
) {
853 snprintf(new_name
, sizeof(new_name
), "(%s)",
854 rtd
->dai_link
->stream_name
);
856 ret
= snd_pcm_new_internal(rtd
->card
->snd_card
, new_name
, num
,
857 rtd
->dai_link
->dpcm_playback
,
858 rtd
->dai_link
->dpcm_capture
, &be_pcm
);
860 dev_err(rtd
->card
->dev
,
861 "Compress ASoC: can't create compressed for %s: %d\n",
862 rtd
->dai_link
->name
, ret
);
868 if (rtd
->dai_link
->dpcm_playback
)
869 be_pcm
->streams
[SNDRV_PCM_STREAM_PLAYBACK
].substream
->private_data
= rtd
;
870 else if (rtd
->dai_link
->dpcm_capture
)
871 be_pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
->private_data
= rtd
;
872 memcpy(compr
->ops
, &soc_compr_dyn_ops
, sizeof(soc_compr_dyn_ops
));
874 snprintf(new_name
, sizeof(new_name
), "%s %s-%d",
875 rtd
->dai_link
->stream_name
, codec_dai
->name
, num
);
877 memcpy(compr
->ops
, &soc_compr_ops
, sizeof(soc_compr_ops
));
880 for_each_rtd_components(rtd
, i
, component
) {
881 if (!component
->driver
->compr_ops
||
882 !component
->driver
->compr_ops
->copy
)
885 compr
->ops
->copy
= soc_compr_copy
;
889 mutex_init(&compr
->lock
);
890 ret
= snd_compress_new(rtd
->card
->snd_card
, num
, direction
,
893 component
= rtd
->codec_dai
->component
;
894 dev_err(component
->dev
,
895 "Compress ASoC: can't create compress for codec %s: %d\n",
896 component
->name
, ret
);
900 /* DAPM dai link stream work */
901 rtd
->close_delayed_work_func
= snd_soc_close_delayed_work
;
904 compr
->private_data
= rtd
;
906 dev_info(rtd
->card
->dev
, "Compress ASoC: %s <-> %s mapping ok\n",
907 codec_dai
->name
, cpu_dai
->name
);
911 EXPORT_SYMBOL_GPL(snd_soc_new_compress
);