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
->card
->pcm_mutex
, rtd
->card
->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
->card
->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
->card
->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 for_each_dpcm_be(fe
, stream
, dpcm
)
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
->card
->pcm_mutex
, rtd
->card
->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
->card
->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
->card
->pcm_mutex
, rtd
->card
->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
->card
->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 for_each_dpcm_be(fe
, stream
, dpcm
)
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_components_trigger(struct snd_compr_stream
*cstream
,
351 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
352 struct snd_soc_component
*component
;
353 struct snd_soc_rtdcom_list
*rtdcom
;
356 for_each_rtdcom(rtd
, rtdcom
) {
357 component
= rtdcom
->component
;
359 if (!component
->driver
->compr_ops
||
360 !component
->driver
->compr_ops
->trigger
)
363 ret
= component
->driver
->compr_ops
->trigger(cstream
, cmd
);
371 static int soc_compr_trigger(struct snd_compr_stream
*cstream
, int cmd
)
373 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
374 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
375 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
378 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
380 ret
= soc_compr_components_trigger(cstream
, cmd
);
384 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->trigger
)
385 cpu_dai
->driver
->cops
->trigger(cstream
, cmd
, cpu_dai
);
388 case SNDRV_PCM_TRIGGER_START
:
389 snd_soc_dai_digital_mute(codec_dai
, 0, cstream
->direction
);
391 case SNDRV_PCM_TRIGGER_STOP
:
392 snd_soc_dai_digital_mute(codec_dai
, 1, cstream
->direction
);
397 mutex_unlock(&rtd
->card
->pcm_mutex
);
401 static int soc_compr_trigger_fe(struct snd_compr_stream
*cstream
, int cmd
)
403 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
404 struct snd_soc_dai
*cpu_dai
= fe
->cpu_dai
;
407 if (cmd
== SND_COMPR_TRIGGER_PARTIAL_DRAIN
||
408 cmd
== SND_COMPR_TRIGGER_DRAIN
)
409 return soc_compr_components_trigger(cstream
, cmd
);
411 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
412 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
414 stream
= SNDRV_PCM_STREAM_CAPTURE
;
416 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
418 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->trigger
) {
419 ret
= cpu_dai
->driver
->cops
->trigger(cstream
, cmd
, cpu_dai
);
424 ret
= soc_compr_components_trigger(cstream
, cmd
);
428 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
430 ret
= dpcm_be_dai_trigger(fe
, stream
, cmd
);
433 case SNDRV_PCM_TRIGGER_START
:
434 case SNDRV_PCM_TRIGGER_RESUME
:
435 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
436 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_START
;
438 case SNDRV_PCM_TRIGGER_STOP
:
439 case SNDRV_PCM_TRIGGER_SUSPEND
:
440 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_STOP
;
442 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
443 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_PAUSED
;
448 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
449 mutex_unlock(&fe
->card
->mutex
);
453 static int soc_compr_components_set_params(struct snd_compr_stream
*cstream
,
454 struct snd_compr_params
*params
)
456 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
457 struct snd_soc_component
*component
;
458 struct snd_soc_rtdcom_list
*rtdcom
;
461 for_each_rtdcom(rtd
, rtdcom
) {
462 component
= rtdcom
->component
;
464 if (!component
->driver
->compr_ops
||
465 !component
->driver
->compr_ops
->set_params
)
468 ret
= component
->driver
->compr_ops
->set_params(cstream
, params
);
476 static int soc_compr_set_params(struct snd_compr_stream
*cstream
,
477 struct snd_compr_params
*params
)
479 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
480 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
483 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
486 * First we call set_params for the CPU DAI, then the component
487 * driver this should configure the SoC side. If the machine has
488 * compressed ops then we call that as well. The expectation is
489 * that these callbacks will configure everything for this compress
490 * path, like configuring a PCM port for a CODEC.
492 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->set_params
) {
493 ret
= cpu_dai
->driver
->cops
->set_params(cstream
, params
, cpu_dai
);
498 ret
= soc_compr_components_set_params(cstream
, params
);
502 if (rtd
->dai_link
->compr_ops
&& rtd
->dai_link
->compr_ops
->set_params
) {
503 ret
= rtd
->dai_link
->compr_ops
->set_params(cstream
);
508 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
509 snd_soc_dapm_stream_event(rtd
, SNDRV_PCM_STREAM_PLAYBACK
,
510 SND_SOC_DAPM_STREAM_START
);
512 snd_soc_dapm_stream_event(rtd
, SNDRV_PCM_STREAM_CAPTURE
,
513 SND_SOC_DAPM_STREAM_START
);
515 /* cancel any delayed stream shutdown that is pending */
517 mutex_unlock(&rtd
->card
->pcm_mutex
);
519 cancel_delayed_work_sync(&rtd
->delayed_work
);
524 mutex_unlock(&rtd
->card
->pcm_mutex
);
528 static int soc_compr_set_params_fe(struct snd_compr_stream
*cstream
,
529 struct snd_compr_params
*params
)
531 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
532 struct snd_pcm_substream
*fe_substream
=
533 fe
->pcm
->streams
[cstream
->direction
].substream
;
534 struct snd_soc_dai
*cpu_dai
= fe
->cpu_dai
;
537 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
538 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
540 stream
= SNDRV_PCM_STREAM_CAPTURE
;
542 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
545 * Create an empty hw_params for the BE as the machine driver must
546 * fix this up to match DSP decoder and ASRC configuration.
547 * I.e. machine driver fixup for compressed BE is mandatory.
549 memset(&fe
->dpcm
[fe_substream
->stream
].hw_params
, 0,
550 sizeof(struct snd_pcm_hw_params
));
552 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
554 ret
= dpcm_be_dai_hw_params(fe
, stream
);
558 ret
= dpcm_be_dai_prepare(fe
, stream
);
562 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->set_params
) {
563 ret
= cpu_dai
->driver
->cops
->set_params(cstream
, params
, cpu_dai
);
568 ret
= soc_compr_components_set_params(cstream
, params
);
572 if (fe
->dai_link
->compr_ops
&& fe
->dai_link
->compr_ops
->set_params
) {
573 ret
= fe
->dai_link
->compr_ops
->set_params(cstream
);
578 dpcm_dapm_stream_event(fe
, stream
, SND_SOC_DAPM_STREAM_START
);
579 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_PREPARE
;
582 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
583 mutex_unlock(&fe
->card
->mutex
);
587 static int soc_compr_get_params(struct snd_compr_stream
*cstream
,
588 struct snd_codec
*params
)
590 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
591 struct snd_soc_component
*component
;
592 struct snd_soc_rtdcom_list
*rtdcom
;
593 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
596 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
598 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->get_params
) {
599 ret
= cpu_dai
->driver
->cops
->get_params(cstream
, params
, cpu_dai
);
604 for_each_rtdcom(rtd
, rtdcom
) {
605 component
= rtdcom
->component
;
607 if (!component
->driver
->compr_ops
||
608 !component
->driver
->compr_ops
->get_params
)
611 ret
= component
->driver
->compr_ops
->get_params(cstream
, params
);
616 mutex_unlock(&rtd
->card
->pcm_mutex
);
620 static int soc_compr_get_caps(struct snd_compr_stream
*cstream
,
621 struct snd_compr_caps
*caps
)
623 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
624 struct snd_soc_component
*component
;
625 struct snd_soc_rtdcom_list
*rtdcom
;
628 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
630 for_each_rtdcom(rtd
, rtdcom
) {
631 component
= rtdcom
->component
;
633 if (!component
->driver
->compr_ops
||
634 !component
->driver
->compr_ops
->get_caps
)
637 ret
= component
->driver
->compr_ops
->get_caps(cstream
, caps
);
641 mutex_unlock(&rtd
->card
->pcm_mutex
);
645 static int soc_compr_get_codec_caps(struct snd_compr_stream
*cstream
,
646 struct snd_compr_codec_caps
*codec
)
648 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
649 struct snd_soc_component
*component
;
650 struct snd_soc_rtdcom_list
*rtdcom
;
653 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
655 for_each_rtdcom(rtd
, rtdcom
) {
656 component
= rtdcom
->component
;
658 if (!component
->driver
->compr_ops
||
659 !component
->driver
->compr_ops
->get_codec_caps
)
662 ret
= component
->driver
->compr_ops
->get_codec_caps(cstream
,
667 mutex_unlock(&rtd
->card
->pcm_mutex
);
671 static int soc_compr_ack(struct snd_compr_stream
*cstream
, size_t bytes
)
673 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
674 struct snd_soc_component
*component
;
675 struct snd_soc_rtdcom_list
*rtdcom
;
676 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
679 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
681 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->ack
) {
682 ret
= cpu_dai
->driver
->cops
->ack(cstream
, bytes
, cpu_dai
);
687 for_each_rtdcom(rtd
, rtdcom
) {
688 component
= rtdcom
->component
;
690 if (!component
->driver
->compr_ops
||
691 !component
->driver
->compr_ops
->ack
)
694 ret
= component
->driver
->compr_ops
->ack(cstream
, bytes
);
700 mutex_unlock(&rtd
->card
->pcm_mutex
);
704 static int soc_compr_pointer(struct snd_compr_stream
*cstream
,
705 struct snd_compr_tstamp
*tstamp
)
707 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
708 struct snd_soc_component
*component
;
709 struct snd_soc_rtdcom_list
*rtdcom
;
711 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
713 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
715 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->pointer
)
716 cpu_dai
->driver
->cops
->pointer(cstream
, tstamp
, cpu_dai
);
718 for_each_rtdcom(rtd
, rtdcom
) {
719 component
= rtdcom
->component
;
721 if (!component
->driver
->compr_ops
||
722 !component
->driver
->compr_ops
->pointer
)
725 ret
= component
->driver
->compr_ops
->pointer(cstream
, tstamp
);
729 mutex_unlock(&rtd
->card
->pcm_mutex
);
733 static int soc_compr_copy(struct snd_compr_stream
*cstream
,
734 char __user
*buf
, size_t count
)
736 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
737 struct snd_soc_component
*component
;
738 struct snd_soc_rtdcom_list
*rtdcom
;
741 mutex_lock_nested(&rtd
->card
->pcm_mutex
, rtd
->card
->pcm_subclass
);
743 for_each_rtdcom(rtd
, rtdcom
) {
744 component
= rtdcom
->component
;
746 if (!component
->driver
->compr_ops
||
747 !component
->driver
->compr_ops
->copy
)
750 ret
= component
->driver
->compr_ops
->copy(cstream
, buf
, count
);
754 mutex_unlock(&rtd
->card
->pcm_mutex
);
758 static int soc_compr_set_metadata(struct snd_compr_stream
*cstream
,
759 struct snd_compr_metadata
*metadata
)
761 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
762 struct snd_soc_component
*component
;
763 struct snd_soc_rtdcom_list
*rtdcom
;
764 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
767 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->set_metadata
) {
768 ret
= cpu_dai
->driver
->cops
->set_metadata(cstream
, metadata
, cpu_dai
);
773 for_each_rtdcom(rtd
, rtdcom
) {
774 component
= rtdcom
->component
;
776 if (!component
->driver
->compr_ops
||
777 !component
->driver
->compr_ops
->set_metadata
)
780 ret
= component
->driver
->compr_ops
->set_metadata(cstream
,
789 static int soc_compr_get_metadata(struct snd_compr_stream
*cstream
,
790 struct snd_compr_metadata
*metadata
)
792 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
793 struct snd_soc_component
*component
;
794 struct snd_soc_rtdcom_list
*rtdcom
;
795 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
798 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->get_metadata
) {
799 ret
= cpu_dai
->driver
->cops
->get_metadata(cstream
, metadata
, cpu_dai
);
804 for_each_rtdcom(rtd
, rtdcom
) {
805 component
= rtdcom
->component
;
807 if (!component
->driver
->compr_ops
||
808 !component
->driver
->compr_ops
->get_metadata
)
811 return component
->driver
->compr_ops
->get_metadata(cstream
,
818 /* ASoC Compress operations */
819 static struct snd_compr_ops soc_compr_ops
= {
820 .open
= soc_compr_open
,
821 .free
= soc_compr_free
,
822 .set_params
= soc_compr_set_params
,
823 .set_metadata
= soc_compr_set_metadata
,
824 .get_metadata
= soc_compr_get_metadata
,
825 .get_params
= soc_compr_get_params
,
826 .trigger
= soc_compr_trigger
,
827 .pointer
= soc_compr_pointer
,
828 .ack
= soc_compr_ack
,
829 .get_caps
= soc_compr_get_caps
,
830 .get_codec_caps
= soc_compr_get_codec_caps
833 /* ASoC Dynamic Compress operations */
834 static struct snd_compr_ops soc_compr_dyn_ops
= {
835 .open
= soc_compr_open_fe
,
836 .free
= soc_compr_free_fe
,
837 .set_params
= soc_compr_set_params_fe
,
838 .get_params
= soc_compr_get_params
,
839 .set_metadata
= soc_compr_set_metadata
,
840 .get_metadata
= soc_compr_get_metadata
,
841 .trigger
= soc_compr_trigger_fe
,
842 .pointer
= soc_compr_pointer
,
843 .ack
= soc_compr_ack
,
844 .get_caps
= soc_compr_get_caps
,
845 .get_codec_caps
= soc_compr_get_codec_caps
849 * snd_soc_new_compress - create a new compress.
851 * @rtd: The runtime for which we will create compress
852 * @num: the device index number (zero based - shared with normal PCMs)
854 * Return: 0 for success, else error.
856 int snd_soc_new_compress(struct snd_soc_pcm_runtime
*rtd
, int num
)
858 struct snd_soc_component
*component
;
859 struct snd_soc_rtdcom_list
*rtdcom
;
860 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
861 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
862 struct snd_compr
*compr
;
863 struct snd_pcm
*be_pcm
;
865 int ret
= 0, direction
= 0;
866 int playback
= 0, capture
= 0;
868 if (rtd
->num_codecs
> 1) {
869 dev_err(rtd
->card
->dev
,
870 "Compress ASoC: Multicodec not supported\n");
874 /* check client and interface hw capabilities */
875 if (snd_soc_dai_stream_valid(codec_dai
, SNDRV_PCM_STREAM_PLAYBACK
) &&
876 snd_soc_dai_stream_valid(cpu_dai
, SNDRV_PCM_STREAM_PLAYBACK
))
878 if (snd_soc_dai_stream_valid(codec_dai
, SNDRV_PCM_STREAM_CAPTURE
) &&
879 snd_soc_dai_stream_valid(cpu_dai
, SNDRV_PCM_STREAM_CAPTURE
))
883 * Compress devices are unidirectional so only one of the directions
884 * should be set, check for that (xor)
886 if (playback
+ capture
!= 1) {
887 dev_err(rtd
->card
->dev
,
888 "Compress ASoC: Invalid direction for P %d, C %d\n",
894 direction
= SND_COMPRESS_PLAYBACK
;
896 direction
= SND_COMPRESS_CAPTURE
;
898 compr
= devm_kzalloc(rtd
->card
->dev
, sizeof(*compr
), GFP_KERNEL
);
902 compr
->ops
= devm_kzalloc(rtd
->card
->dev
, sizeof(soc_compr_ops
),
907 if (rtd
->dai_link
->dynamic
) {
908 snprintf(new_name
, sizeof(new_name
), "(%s)",
909 rtd
->dai_link
->stream_name
);
911 ret
= snd_pcm_new_internal(rtd
->card
->snd_card
, new_name
, num
,
912 rtd
->dai_link
->dpcm_playback
,
913 rtd
->dai_link
->dpcm_capture
, &be_pcm
);
915 dev_err(rtd
->card
->dev
,
916 "Compress ASoC: can't create compressed for %s: %d\n",
917 rtd
->dai_link
->name
, ret
);
923 if (rtd
->dai_link
->dpcm_playback
)
924 be_pcm
->streams
[SNDRV_PCM_STREAM_PLAYBACK
].substream
->private_data
= rtd
;
925 else if (rtd
->dai_link
->dpcm_capture
)
926 be_pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
->private_data
= rtd
;
927 memcpy(compr
->ops
, &soc_compr_dyn_ops
, sizeof(soc_compr_dyn_ops
));
929 snprintf(new_name
, sizeof(new_name
), "%s %s-%d",
930 rtd
->dai_link
->stream_name
, codec_dai
->name
, num
);
932 memcpy(compr
->ops
, &soc_compr_ops
, sizeof(soc_compr_ops
));
935 for_each_rtdcom(rtd
, rtdcom
) {
936 component
= rtdcom
->component
;
938 if (!component
->driver
->compr_ops
||
939 !component
->driver
->compr_ops
->copy
)
942 compr
->ops
->copy
= soc_compr_copy
;
946 mutex_init(&compr
->lock
);
947 ret
= snd_compress_new(rtd
->card
->snd_card
, num
, direction
,
950 component
= rtd
->codec_dai
->component
;
951 dev_err(component
->dev
,
952 "Compress ASoC: can't create compress for codec %s: %d\n",
953 component
->name
, ret
);
957 /* DAPM dai link stream work */
958 INIT_DELAYED_WORK(&rtd
->delayed_work
, close_delayed_work
);
961 compr
->private_data
= rtd
;
963 dev_info(rtd
->card
->dev
, "Compress ASoC: %s <-> %s mapping ok\n",
964 codec_dai
->name
, cpu_dai
->name
);
968 EXPORT_SYMBOL_GPL(snd_soc_new_compress
);