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>
23 static int soc_compr_components_open(struct snd_compr_stream
*cstream
,
24 struct snd_soc_component
**last
)
26 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
27 struct snd_soc_component
*component
;
28 struct snd_soc_rtdcom_list
*rtdcom
;
31 for_each_rtdcom(rtd
, rtdcom
) {
32 component
= rtdcom
->component
;
34 if (!component
->driver
->compr_ops
||
35 !component
->driver
->compr_ops
->open
)
38 ret
= component
->driver
->compr_ops
->open(cstream
);
40 dev_err(component
->dev
,
41 "Compress ASoC: can't open platform %s: %d\n",
42 component
->name
, ret
);
53 static int soc_compr_components_free(struct snd_compr_stream
*cstream
,
54 struct snd_soc_component
*last
)
56 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
57 struct snd_soc_component
*component
;
58 struct snd_soc_rtdcom_list
*rtdcom
;
60 for_each_rtdcom(rtd
, rtdcom
) {
61 component
= rtdcom
->component
;
63 if (component
== last
)
66 if (!component
->driver
->compr_ops
||
67 !component
->driver
->compr_ops
->free
)
70 component
->driver
->compr_ops
->free(cstream
);
76 static int soc_compr_open(struct snd_compr_stream
*cstream
)
78 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
79 struct snd_soc_component
*component
;
80 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
83 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
85 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->startup
) {
86 ret
= cpu_dai
->driver
->cops
->startup(cstream
, cpu_dai
);
89 "Compress ASoC: can't open interface %s: %d\n",
95 ret
= soc_compr_components_open(cstream
, &component
);
99 if (rtd
->dai_link
->compr_ops
&& rtd
->dai_link
->compr_ops
->startup
) {
100 ret
= rtd
->dai_link
->compr_ops
->startup(cstream
);
103 "Compress ASoC: %s startup failed: %d\n",
104 rtd
->dai_link
->name
, ret
);
109 snd_soc_runtime_activate(rtd
, cstream
->direction
);
111 mutex_unlock(&rtd
->pcm_mutex
);
116 soc_compr_components_free(cstream
, component
);
118 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->shutdown
)
119 cpu_dai
->driver
->cops
->shutdown(cstream
, cpu_dai
);
121 mutex_unlock(&rtd
->pcm_mutex
);
125 static int soc_compr_open_fe(struct snd_compr_stream
*cstream
)
127 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
128 struct snd_pcm_substream
*fe_substream
=
129 fe
->pcm
->streams
[cstream
->direction
].substream
;
130 struct snd_soc_component
*component
;
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
);
143 fe
->dpcm
[stream
].runtime
= fe_substream
->runtime
;
145 ret
= dpcm_path_get(fe
, stream
, &list
);
149 dev_dbg(fe
->dev
, "Compress ASoC: %s no valid %s route\n",
150 fe
->dai_link
->name
, stream
? "capture" : "playback");
151 /* calculate valid and active FE <-> BE dpcms */
152 dpcm_process_paths(fe
, stream
, &list
, 1);
153 fe
->dpcm
[stream
].runtime
= fe_substream
->runtime
;
155 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
157 ret
= dpcm_be_dai_startup(fe
, stream
);
159 /* clean up all links */
160 list_for_each_entry(dpcm
, &fe
->dpcm
[stream
].be_clients
, list_be
)
161 dpcm
->state
= SND_SOC_DPCM_LINK_STATE_FREE
;
163 dpcm_be_disconnect(fe
, stream
);
164 fe
->dpcm
[stream
].runtime
= NULL
;
168 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->startup
) {
169 ret
= cpu_dai
->driver
->cops
->startup(cstream
, cpu_dai
);
171 dev_err(cpu_dai
->dev
,
172 "Compress ASoC: can't open interface %s: %d\n",
178 ret
= soc_compr_components_open(cstream
, &component
);
182 if (fe
->dai_link
->compr_ops
&& fe
->dai_link
->compr_ops
->startup
) {
183 ret
= fe
->dai_link
->compr_ops
->startup(cstream
);
185 pr_err("Compress ASoC: %s startup failed: %d\n",
186 fe
->dai_link
->name
, ret
);
191 dpcm_clear_pending_state(fe
, stream
);
192 dpcm_path_put(&list
);
194 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_OPEN
;
195 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
197 snd_soc_runtime_activate(fe
, stream
);
199 mutex_unlock(&fe
->card
->mutex
);
204 soc_compr_components_free(cstream
, component
);
206 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->shutdown
)
207 cpu_dai
->driver
->cops
->shutdown(cstream
, cpu_dai
);
209 dpcm_path_put(&list
);
211 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
212 mutex_unlock(&fe
->card
->mutex
);
217 * Power down the audio subsystem pmdown_time msecs after close is called.
218 * This is to ensure there are no pops or clicks in between any music tracks
219 * due to DAPM power cycling.
221 static void close_delayed_work(struct work_struct
*work
)
223 struct snd_soc_pcm_runtime
*rtd
=
224 container_of(work
, struct snd_soc_pcm_runtime
, delayed_work
.work
);
225 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
227 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
230 "Compress ASoC: pop wq checking: %s status: %s waiting: %s\n",
231 codec_dai
->driver
->playback
.stream_name
,
232 codec_dai
->playback_active
? "active" : "inactive",
233 rtd
->pop_wait
? "yes" : "no");
235 /* are we waiting on this codec DAI stream */
236 if (rtd
->pop_wait
== 1) {
238 snd_soc_dapm_stream_event(rtd
, SNDRV_PCM_STREAM_PLAYBACK
,
239 SND_SOC_DAPM_STREAM_STOP
);
242 mutex_unlock(&rtd
->pcm_mutex
);
245 static int soc_compr_free(struct snd_compr_stream
*cstream
)
247 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
248 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
249 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
252 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
254 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
255 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
257 stream
= SNDRV_PCM_STREAM_CAPTURE
;
259 snd_soc_runtime_deactivate(rtd
, stream
);
261 snd_soc_dai_digital_mute(codec_dai
, 1, cstream
->direction
);
263 if (!cpu_dai
->active
)
266 if (!codec_dai
->active
)
269 if (rtd
->dai_link
->compr_ops
&& rtd
->dai_link
->compr_ops
->shutdown
)
270 rtd
->dai_link
->compr_ops
->shutdown(cstream
);
272 soc_compr_components_free(cstream
, NULL
);
274 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->shutdown
)
275 cpu_dai
->driver
->cops
->shutdown(cstream
, cpu_dai
);
277 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
) {
278 if (snd_soc_runtime_ignore_pmdown_time(rtd
)) {
279 snd_soc_dapm_stream_event(rtd
,
280 SNDRV_PCM_STREAM_PLAYBACK
,
281 SND_SOC_DAPM_STREAM_STOP
);
284 queue_delayed_work(system_power_efficient_wq
,
286 msecs_to_jiffies(rtd
->pmdown_time
));
289 /* capture streams can be powered down now */
290 snd_soc_dapm_stream_event(rtd
,
291 SNDRV_PCM_STREAM_CAPTURE
,
292 SND_SOC_DAPM_STREAM_STOP
);
295 mutex_unlock(&rtd
->pcm_mutex
);
299 static int soc_compr_free_fe(struct snd_compr_stream
*cstream
)
301 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
302 struct snd_soc_dai
*cpu_dai
= fe
->cpu_dai
;
303 struct snd_soc_dpcm
*dpcm
;
306 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
308 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
309 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
311 stream
= SNDRV_PCM_STREAM_CAPTURE
;
313 snd_soc_runtime_deactivate(fe
, stream
);
315 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
317 ret
= dpcm_be_dai_hw_free(fe
, stream
);
319 dev_err(fe
->dev
, "Compressed ASoC: hw_free failed: %d\n", ret
);
321 ret
= dpcm_be_dai_shutdown(fe
, stream
);
323 /* mark FE's links ready to prune */
324 list_for_each_entry(dpcm
, &fe
->dpcm
[stream
].be_clients
, list_be
)
325 dpcm
->state
= SND_SOC_DPCM_LINK_STATE_FREE
;
327 dpcm_dapm_stream_event(fe
, stream
, SND_SOC_DAPM_STREAM_STOP
);
329 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_CLOSE
;
330 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
332 dpcm_be_disconnect(fe
, stream
);
334 fe
->dpcm
[stream
].runtime
= NULL
;
336 if (fe
->dai_link
->compr_ops
&& fe
->dai_link
->compr_ops
->shutdown
)
337 fe
->dai_link
->compr_ops
->shutdown(cstream
);
339 soc_compr_components_free(cstream
, NULL
);
341 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->shutdown
)
342 cpu_dai
->driver
->cops
->shutdown(cstream
, cpu_dai
);
344 mutex_unlock(&fe
->card
->mutex
);
348 static int soc_compr_trigger(struct snd_compr_stream
*cstream
, int cmd
)
351 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
352 struct snd_soc_component
*component
;
353 struct snd_soc_rtdcom_list
*rtdcom
;
354 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
355 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
358 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
360 for_each_rtdcom(rtd
, rtdcom
) {
361 component
= rtdcom
->component
;
363 if (!component
->driver
->compr_ops
||
364 !component
->driver
->compr_ops
->trigger
)
367 __ret
= component
->driver
->compr_ops
->trigger(cstream
, cmd
);
374 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->trigger
)
375 cpu_dai
->driver
->cops
->trigger(cstream
, cmd
, cpu_dai
);
378 case SNDRV_PCM_TRIGGER_START
:
379 snd_soc_dai_digital_mute(codec_dai
, 0, cstream
->direction
);
381 case SNDRV_PCM_TRIGGER_STOP
:
382 snd_soc_dai_digital_mute(codec_dai
, 1, cstream
->direction
);
387 mutex_unlock(&rtd
->pcm_mutex
);
391 static int soc_compr_trigger_fe(struct snd_compr_stream
*cstream
, int cmd
)
393 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
394 struct snd_soc_component
*component
;
395 struct snd_soc_rtdcom_list
*rtdcom
;
396 struct snd_soc_dai
*cpu_dai
= fe
->cpu_dai
;
397 int ret
= 0, __ret
, stream
;
399 if (cmd
== SND_COMPR_TRIGGER_PARTIAL_DRAIN
||
400 cmd
== SND_COMPR_TRIGGER_DRAIN
) {
402 for_each_rtdcom(fe
, rtdcom
) {
403 component
= rtdcom
->component
;
405 if (!component
->driver
->compr_ops
||
406 !component
->driver
->compr_ops
->trigger
)
409 __ret
= component
->driver
->compr_ops
->trigger(cstream
, cmd
);
416 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
417 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
419 stream
= SNDRV_PCM_STREAM_CAPTURE
;
421 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
423 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->trigger
) {
424 ret
= cpu_dai
->driver
->cops
->trigger(cstream
, cmd
, cpu_dai
);
429 for_each_rtdcom(fe
, rtdcom
) {
430 component
= rtdcom
->component
;
432 if (!component
->driver
->compr_ops
||
433 !component
->driver
->compr_ops
->trigger
)
436 __ret
= component
->driver
->compr_ops
->trigger(cstream
, cmd
);
443 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
445 ret
= dpcm_be_dai_trigger(fe
, stream
, cmd
);
448 case SNDRV_PCM_TRIGGER_START
:
449 case SNDRV_PCM_TRIGGER_RESUME
:
450 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
451 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_START
;
453 case SNDRV_PCM_TRIGGER_STOP
:
454 case SNDRV_PCM_TRIGGER_SUSPEND
:
455 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_STOP
;
457 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
458 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_PAUSED
;
463 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
464 mutex_unlock(&fe
->card
->mutex
);
468 static int soc_compr_set_params(struct snd_compr_stream
*cstream
,
469 struct snd_compr_params
*params
)
471 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
472 struct snd_soc_component
*component
;
473 struct snd_soc_rtdcom_list
*rtdcom
;
474 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
477 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
480 * First we call set_params for the CPU DAI, then the component
481 * driver this should configure the SoC side. If the machine has
482 * compressed ops then we call that as well. The expectation is
483 * that these callbacks will configure everything for this compress
484 * path, like configuring a PCM port for a CODEC.
486 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->set_params
) {
487 ret
= cpu_dai
->driver
->cops
->set_params(cstream
, params
, cpu_dai
);
492 for_each_rtdcom(rtd
, rtdcom
) {
493 component
= rtdcom
->component
;
495 if (!component
->driver
->compr_ops
||
496 !component
->driver
->compr_ops
->set_params
)
499 __ret
= component
->driver
->compr_ops
->set_params(cstream
, params
);
506 if (rtd
->dai_link
->compr_ops
&& rtd
->dai_link
->compr_ops
->set_params
) {
507 ret
= rtd
->dai_link
->compr_ops
->set_params(cstream
);
512 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
513 snd_soc_dapm_stream_event(rtd
, SNDRV_PCM_STREAM_PLAYBACK
,
514 SND_SOC_DAPM_STREAM_START
);
516 snd_soc_dapm_stream_event(rtd
, SNDRV_PCM_STREAM_CAPTURE
,
517 SND_SOC_DAPM_STREAM_START
);
519 /* cancel any delayed stream shutdown that is pending */
521 mutex_unlock(&rtd
->pcm_mutex
);
523 cancel_delayed_work_sync(&rtd
->delayed_work
);
528 mutex_unlock(&rtd
->pcm_mutex
);
532 static int soc_compr_set_params_fe(struct snd_compr_stream
*cstream
,
533 struct snd_compr_params
*params
)
535 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
536 struct snd_pcm_substream
*fe_substream
=
537 fe
->pcm
->streams
[cstream
->direction
].substream
;
538 struct snd_soc_component
*component
;
539 struct snd_soc_rtdcom_list
*rtdcom
;
540 struct snd_soc_dai
*cpu_dai
= fe
->cpu_dai
;
541 int ret
= 0, __ret
, stream
;
543 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
544 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
546 stream
= SNDRV_PCM_STREAM_CAPTURE
;
548 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
551 * Create an empty hw_params for the BE as the machine driver must
552 * fix this up to match DSP decoder and ASRC configuration.
553 * I.e. machine driver fixup for compressed BE is mandatory.
555 memset(&fe
->dpcm
[fe_substream
->stream
].hw_params
, 0,
556 sizeof(struct snd_pcm_hw_params
));
558 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
560 ret
= dpcm_be_dai_hw_params(fe
, stream
);
564 ret
= dpcm_be_dai_prepare(fe
, stream
);
568 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->set_params
) {
569 ret
= cpu_dai
->driver
->cops
->set_params(cstream
, params
, cpu_dai
);
574 for_each_rtdcom(fe
, rtdcom
) {
575 component
= rtdcom
->component
;
577 if (!component
->driver
->compr_ops
||
578 !component
->driver
->compr_ops
->set_params
)
581 __ret
= component
->driver
->compr_ops
->set_params(cstream
, params
);
588 if (fe
->dai_link
->compr_ops
&& fe
->dai_link
->compr_ops
->set_params
) {
589 ret
= fe
->dai_link
->compr_ops
->set_params(cstream
);
594 dpcm_dapm_stream_event(fe
, stream
, SND_SOC_DAPM_STREAM_START
);
595 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_PREPARE
;
598 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
599 mutex_unlock(&fe
->card
->mutex
);
603 static int soc_compr_get_params(struct snd_compr_stream
*cstream
,
604 struct snd_codec
*params
)
606 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
607 struct snd_soc_component
*component
;
608 struct snd_soc_rtdcom_list
*rtdcom
;
609 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
612 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
614 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->get_params
) {
615 ret
= cpu_dai
->driver
->cops
->get_params(cstream
, params
, cpu_dai
);
620 for_each_rtdcom(rtd
, rtdcom
) {
621 component
= rtdcom
->component
;
623 if (!component
->driver
->compr_ops
||
624 !component
->driver
->compr_ops
->get_params
)
627 __ret
= component
->driver
->compr_ops
->get_params(cstream
, params
);
633 mutex_unlock(&rtd
->pcm_mutex
);
637 static int soc_compr_get_caps(struct snd_compr_stream
*cstream
,
638 struct snd_compr_caps
*caps
)
640 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
641 struct snd_soc_component
*component
;
642 struct snd_soc_rtdcom_list
*rtdcom
;
645 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
647 for_each_rtdcom(rtd
, rtdcom
) {
648 component
= rtdcom
->component
;
650 if (!component
->driver
->compr_ops
||
651 !component
->driver
->compr_ops
->get_caps
)
654 __ret
= component
->driver
->compr_ops
->get_caps(cstream
, caps
);
659 mutex_unlock(&rtd
->pcm_mutex
);
663 static int soc_compr_get_codec_caps(struct snd_compr_stream
*cstream
,
664 struct snd_compr_codec_caps
*codec
)
666 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
667 struct snd_soc_component
*component
;
668 struct snd_soc_rtdcom_list
*rtdcom
;
671 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
673 for_each_rtdcom(rtd
, rtdcom
) {
674 component
= rtdcom
->component
;
676 if (!component
->driver
->compr_ops
||
677 !component
->driver
->compr_ops
->get_codec_caps
)
680 __ret
= component
->driver
->compr_ops
->get_codec_caps(cstream
, codec
);
685 mutex_unlock(&rtd
->pcm_mutex
);
689 static int soc_compr_ack(struct snd_compr_stream
*cstream
, size_t bytes
)
691 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
692 struct snd_soc_component
*component
;
693 struct snd_soc_rtdcom_list
*rtdcom
;
694 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
697 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
699 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->ack
) {
700 ret
= cpu_dai
->driver
->cops
->ack(cstream
, bytes
, cpu_dai
);
705 for_each_rtdcom(rtd
, rtdcom
) {
706 component
= rtdcom
->component
;
708 if (!component
->driver
->compr_ops
||
709 !component
->driver
->compr_ops
->ack
)
712 __ret
= component
->driver
->compr_ops
->ack(cstream
, bytes
);
718 mutex_unlock(&rtd
->pcm_mutex
);
722 static int soc_compr_pointer(struct snd_compr_stream
*cstream
,
723 struct snd_compr_tstamp
*tstamp
)
725 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
726 struct snd_soc_component
*component
;
727 struct snd_soc_rtdcom_list
*rtdcom
;
729 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
731 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
733 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->pointer
)
734 cpu_dai
->driver
->cops
->pointer(cstream
, tstamp
, cpu_dai
);
736 for_each_rtdcom(rtd
, rtdcom
) {
737 component
= rtdcom
->component
;
739 if (!component
->driver
->compr_ops
||
740 !component
->driver
->compr_ops
->pointer
)
743 __ret
= component
->driver
->compr_ops
->pointer(cstream
, tstamp
);
748 mutex_unlock(&rtd
->pcm_mutex
);
752 static int soc_compr_copy(struct snd_compr_stream
*cstream
,
753 char __user
*buf
, size_t count
)
755 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
756 struct snd_soc_component
*component
;
757 struct snd_soc_rtdcom_list
*rtdcom
;
760 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
762 for_each_rtdcom(rtd
, rtdcom
) {
763 component
= rtdcom
->component
;
765 if (!component
->driver
->compr_ops
||
766 !component
->driver
->compr_ops
->copy
)
769 ret
= component
->driver
->compr_ops
->copy(cstream
, buf
, count
);
773 mutex_unlock(&rtd
->pcm_mutex
);
777 static int soc_compr_set_metadata(struct snd_compr_stream
*cstream
,
778 struct snd_compr_metadata
*metadata
)
780 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
781 struct snd_soc_component
*component
;
782 struct snd_soc_rtdcom_list
*rtdcom
;
783 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
786 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->set_metadata
) {
787 ret
= cpu_dai
->driver
->cops
->set_metadata(cstream
, metadata
, cpu_dai
);
792 for_each_rtdcom(rtd
, rtdcom
) {
793 component
= rtdcom
->component
;
795 if (!component
->driver
->compr_ops
||
796 !component
->driver
->compr_ops
->set_metadata
)
799 __ret
= component
->driver
->compr_ops
->set_metadata(cstream
, metadata
);
807 static int soc_compr_get_metadata(struct snd_compr_stream
*cstream
,
808 struct snd_compr_metadata
*metadata
)
810 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
811 struct snd_soc_component
*component
;
812 struct snd_soc_rtdcom_list
*rtdcom
;
813 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
816 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->get_metadata
) {
817 ret
= cpu_dai
->driver
->cops
->get_metadata(cstream
, metadata
, cpu_dai
);
822 for_each_rtdcom(rtd
, rtdcom
) {
823 component
= rtdcom
->component
;
825 if (!component
->driver
->compr_ops
||
826 !component
->driver
->compr_ops
->get_metadata
)
829 __ret
= component
->driver
->compr_ops
->get_metadata(cstream
, metadata
);
837 /* ASoC Compress operations */
838 static struct snd_compr_ops soc_compr_ops
= {
839 .open
= soc_compr_open
,
840 .free
= soc_compr_free
,
841 .set_params
= soc_compr_set_params
,
842 .set_metadata
= soc_compr_set_metadata
,
843 .get_metadata
= soc_compr_get_metadata
,
844 .get_params
= soc_compr_get_params
,
845 .trigger
= soc_compr_trigger
,
846 .pointer
= soc_compr_pointer
,
847 .ack
= soc_compr_ack
,
848 .get_caps
= soc_compr_get_caps
,
849 .get_codec_caps
= soc_compr_get_codec_caps
852 /* ASoC Dynamic Compress operations */
853 static struct snd_compr_ops soc_compr_dyn_ops
= {
854 .open
= soc_compr_open_fe
,
855 .free
= soc_compr_free_fe
,
856 .set_params
= soc_compr_set_params_fe
,
857 .get_params
= soc_compr_get_params
,
858 .set_metadata
= soc_compr_set_metadata
,
859 .get_metadata
= soc_compr_get_metadata
,
860 .trigger
= soc_compr_trigger_fe
,
861 .pointer
= soc_compr_pointer
,
862 .ack
= soc_compr_ack
,
863 .get_caps
= soc_compr_get_caps
,
864 .get_codec_caps
= soc_compr_get_codec_caps
868 * snd_soc_new_compress - create a new compress.
870 * @rtd: The runtime for which we will create compress
871 * @num: the device index number (zero based - shared with normal PCMs)
873 * Return: 0 for success, else error.
875 int snd_soc_new_compress(struct snd_soc_pcm_runtime
*rtd
, int num
)
877 struct snd_soc_component
*component
;
878 struct snd_soc_rtdcom_list
*rtdcom
;
879 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
880 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
881 struct snd_compr
*compr
;
882 struct snd_pcm
*be_pcm
;
884 int ret
= 0, direction
= 0;
885 int playback
= 0, capture
= 0;
887 if (rtd
->num_codecs
> 1) {
888 dev_err(rtd
->card
->dev
,
889 "Compress ASoC: Multicodec not supported\n");
893 /* check client and interface hw capabilities */
894 if (codec_dai
->driver
->playback
.channels_min
)
896 if (codec_dai
->driver
->capture
.channels_min
)
899 capture
= capture
&& cpu_dai
->driver
->capture
.channels_min
;
900 playback
= playback
&& cpu_dai
->driver
->playback
.channels_min
;
903 * Compress devices are unidirectional so only one of the directions
904 * should be set, check for that (xor)
906 if (playback
+ capture
!= 1) {
907 dev_err(rtd
->card
->dev
,
908 "Compress ASoC: Invalid direction for P %d, C %d\n",
914 direction
= SND_COMPRESS_PLAYBACK
;
916 direction
= SND_COMPRESS_CAPTURE
;
918 compr
= kzalloc(sizeof(*compr
), GFP_KERNEL
);
922 compr
->ops
= devm_kzalloc(rtd
->card
->dev
, sizeof(soc_compr_ops
),
929 if (rtd
->dai_link
->dynamic
) {
930 snprintf(new_name
, sizeof(new_name
), "(%s)",
931 rtd
->dai_link
->stream_name
);
933 ret
= snd_pcm_new_internal(rtd
->card
->snd_card
, new_name
, num
,
934 rtd
->dai_link
->dpcm_playback
,
935 rtd
->dai_link
->dpcm_capture
, &be_pcm
);
937 dev_err(rtd
->card
->dev
,
938 "Compress ASoC: can't create compressed for %s: %d\n",
939 rtd
->dai_link
->name
, ret
);
945 if (rtd
->dai_link
->dpcm_playback
)
946 be_pcm
->streams
[SNDRV_PCM_STREAM_PLAYBACK
].substream
->private_data
= rtd
;
947 else if (rtd
->dai_link
->dpcm_capture
)
948 be_pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
->private_data
= rtd
;
949 memcpy(compr
->ops
, &soc_compr_dyn_ops
, sizeof(soc_compr_dyn_ops
));
951 snprintf(new_name
, sizeof(new_name
), "%s %s-%d",
952 rtd
->dai_link
->stream_name
, codec_dai
->name
, num
);
954 memcpy(compr
->ops
, &soc_compr_ops
, sizeof(soc_compr_ops
));
957 for_each_rtdcom(rtd
, rtdcom
) {
958 component
= rtdcom
->component
;
960 if (!component
->driver
->compr_ops
||
961 !component
->driver
->compr_ops
->copy
)
964 compr
->ops
->copy
= soc_compr_copy
;
968 mutex_init(&compr
->lock
);
969 ret
= snd_compress_new(rtd
->card
->snd_card
, num
, direction
,
972 component
= rtd
->codec_dai
->component
;
973 dev_err(component
->dev
,
974 "Compress ASoC: can't create compress for codec %s: %d\n",
975 component
->name
, ret
);
979 /* DAPM dai link stream work */
980 INIT_DELAYED_WORK(&rtd
->delayed_work
, close_delayed_work
);
983 compr
->private_data
= rtd
;
985 dev_info(rtd
->card
->dev
, "Compress ASoC: %s <-> %s mapping ok\n",
986 codec_dai
->name
, cpu_dai
->name
);
993 EXPORT_SYMBOL_GPL(snd_soc_new_compress
);