2 * soc-compress.c -- ALSA SoC Compress
4 * Copyright (C) 2012 Intel Corp.
6 * Authors: Namarta Kohli <namartax.kohli@intel.com>
7 * Ramesh Babu K V <ramesh.babu@linux.intel.com>
8 * Vinod Koul <vinod.koul@linux.intel.com>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/delay.h>
20 #include <linux/slab.h>
21 #include <linux/workqueue.h>
22 #include <sound/core.h>
23 #include <sound/compress_params.h>
24 #include <sound/compress_driver.h>
25 #include <sound/soc.h>
26 #include <sound/initval.h>
27 #include <sound/soc-dpcm.h>
29 static int soc_compr_open(struct snd_compr_stream
*cstream
)
31 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
32 struct snd_soc_platform
*platform
= rtd
->platform
;
33 struct snd_soc_component
*component
;
34 struct snd_soc_rtdcom_list
*rtdcom
;
35 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
38 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
40 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->startup
) {
41 ret
= cpu_dai
->driver
->cops
->startup(cstream
, cpu_dai
);
43 dev_err(cpu_dai
->dev
, "Compress ASoC: can't open interface %s: %d\n",
49 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->open
) {
50 ret
= platform
->driver
->compr_ops
->open(cstream
);
52 pr_err("compress asoc: can't open platform %s\n",
53 platform
->component
.name
);
58 for_each_rtdcom(rtd
, rtdcom
) {
59 component
= rtdcom
->component
;
61 /* ignore duplication for now */
62 if (platform
&& (component
== &platform
->component
))
65 if (!component
->driver
->compr_ops
||
66 !component
->driver
->compr_ops
->open
)
69 __ret
= component
->driver
->compr_ops
->open(cstream
);
71 pr_err("compress asoc: can't open platform %s\n",
79 if (rtd
->dai_link
->compr_ops
&& rtd
->dai_link
->compr_ops
->startup
) {
80 ret
= rtd
->dai_link
->compr_ops
->startup(cstream
);
82 pr_err("compress asoc: %s startup failed\n", rtd
->dai_link
->name
);
87 snd_soc_runtime_activate(rtd
, cstream
->direction
);
89 mutex_unlock(&rtd
->pcm_mutex
);
94 for_each_rtdcom(rtd
, rtdcom
) {
95 component
= rtdcom
->component
;
97 /* ignore duplication for now */
98 if (platform
&& (component
== &platform
->component
))
101 if (!component
->driver
->compr_ops
||
102 !component
->driver
->compr_ops
->free
)
105 component
->driver
->compr_ops
->free(cstream
);
108 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->free
)
109 platform
->driver
->compr_ops
->free(cstream
);
111 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->shutdown
)
112 cpu_dai
->driver
->cops
->shutdown(cstream
, cpu_dai
);
114 mutex_unlock(&rtd
->pcm_mutex
);
118 static int soc_compr_open_fe(struct snd_compr_stream
*cstream
)
120 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
121 struct snd_pcm_substream
*fe_substream
=
122 fe
->pcm
->streams
[cstream
->direction
].substream
;
123 struct snd_soc_platform
*platform
= fe
->platform
;
124 struct snd_soc_component
*component
;
125 struct snd_soc_rtdcom_list
*rtdcom
;
126 struct snd_soc_dai
*cpu_dai
= fe
->cpu_dai
;
127 struct snd_soc_dpcm
*dpcm
;
128 struct snd_soc_dapm_widget_list
*list
;
132 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
133 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
135 stream
= SNDRV_PCM_STREAM_CAPTURE
;
137 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
139 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->startup
) {
140 ret
= cpu_dai
->driver
->cops
->startup(cstream
, cpu_dai
);
142 dev_err(cpu_dai
->dev
, "Compress ASoC: can't open interface %s: %d\n",
149 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->open
) {
150 ret
= platform
->driver
->compr_ops
->open(cstream
);
152 pr_err("compress asoc: can't open platform %s\n",
153 platform
->component
.name
);
158 for_each_rtdcom(fe
, rtdcom
) {
159 component
= rtdcom
->component
;
161 /* ignore duplication for now */
162 if (platform
&& (component
== &platform
->component
))
165 if (!component
->driver
->compr_ops
||
166 !component
->driver
->compr_ops
->open
)
169 __ret
= component
->driver
->compr_ops
->open(cstream
);
171 pr_err("compress asoc: can't open platform %s\n",
179 if (fe
->dai_link
->compr_ops
&& fe
->dai_link
->compr_ops
->startup
) {
180 ret
= fe
->dai_link
->compr_ops
->startup(cstream
);
182 pr_err("compress asoc: %s startup failed\n", fe
->dai_link
->name
);
187 fe
->dpcm
[stream
].runtime
= fe_substream
->runtime
;
189 ret
= dpcm_path_get(fe
, stream
, &list
);
193 dev_dbg(fe
->dev
, "ASoC: %s no valid %s route\n",
194 fe
->dai_link
->name
, stream
? "capture" : "playback");
196 /* calculate valid and active FE <-> BE dpcms */
197 dpcm_process_paths(fe
, stream
, &list
, 1);
199 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
201 ret
= dpcm_be_dai_startup(fe
, stream
);
203 /* clean up all links */
204 list_for_each_entry(dpcm
, &fe
->dpcm
[stream
].be_clients
, list_be
)
205 dpcm
->state
= SND_SOC_DPCM_LINK_STATE_FREE
;
207 dpcm_be_disconnect(fe
, stream
);
208 fe
->dpcm
[stream
].runtime
= NULL
;
212 dpcm_clear_pending_state(fe
, stream
);
213 dpcm_path_put(&list
);
215 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_OPEN
;
216 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
218 snd_soc_runtime_activate(fe
, stream
);
220 mutex_unlock(&fe
->card
->mutex
);
225 dpcm_path_put(&list
);
227 if (fe
->dai_link
->compr_ops
&& fe
->dai_link
->compr_ops
->shutdown
)
228 fe
->dai_link
->compr_ops
->shutdown(cstream
);
230 for_each_rtdcom(fe
, rtdcom
) {
231 component
= rtdcom
->component
;
233 /* ignore duplication for now */
234 if (platform
&& (component
== &platform
->component
))
237 if (!component
->driver
->compr_ops
||
238 !component
->driver
->compr_ops
->free
)
241 component
->driver
->compr_ops
->free(cstream
);
244 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->free
)
245 platform
->driver
->compr_ops
->free(cstream
);
247 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->shutdown
)
248 cpu_dai
->driver
->cops
->shutdown(cstream
, cpu_dai
);
250 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
251 mutex_unlock(&fe
->card
->mutex
);
256 * Power down the audio subsystem pmdown_time msecs after close is called.
257 * This is to ensure there are no pops or clicks in between any music tracks
258 * due to DAPM power cycling.
260 static void close_delayed_work(struct work_struct
*work
)
262 struct snd_soc_pcm_runtime
*rtd
=
263 container_of(work
, struct snd_soc_pcm_runtime
, delayed_work
.work
);
264 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
266 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
268 dev_dbg(rtd
->dev
, "ASoC: pop wq checking: %s status: %s waiting: %s\n",
269 codec_dai
->driver
->playback
.stream_name
,
270 codec_dai
->playback_active
? "active" : "inactive",
271 rtd
->pop_wait
? "yes" : "no");
273 /* are we waiting on this codec DAI stream */
274 if (rtd
->pop_wait
== 1) {
276 snd_soc_dapm_stream_event(rtd
, SNDRV_PCM_STREAM_PLAYBACK
,
277 SND_SOC_DAPM_STREAM_STOP
);
280 mutex_unlock(&rtd
->pcm_mutex
);
283 static int soc_compr_free(struct snd_compr_stream
*cstream
)
285 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
286 struct snd_soc_platform
*platform
= rtd
->platform
;
287 struct snd_soc_component
*component
;
288 struct snd_soc_rtdcom_list
*rtdcom
;
289 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
290 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
293 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
295 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
296 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
298 stream
= SNDRV_PCM_STREAM_CAPTURE
;
300 snd_soc_runtime_deactivate(rtd
, stream
);
302 snd_soc_dai_digital_mute(codec_dai
, 1, cstream
->direction
);
304 if (!cpu_dai
->active
)
307 if (!codec_dai
->active
)
311 if (rtd
->dai_link
->compr_ops
&& rtd
->dai_link
->compr_ops
->shutdown
)
312 rtd
->dai_link
->compr_ops
->shutdown(cstream
);
314 for_each_rtdcom(rtd
, rtdcom
) {
315 component
= rtdcom
->component
;
317 /* ignore duplication for now */
318 if (platform
&& (component
== &platform
->component
))
321 if (!component
->driver
->compr_ops
||
322 !component
->driver
->compr_ops
->free
)
325 component
->driver
->compr_ops
->free(cstream
);
328 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->free
)
329 platform
->driver
->compr_ops
->free(cstream
);
331 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->shutdown
)
332 cpu_dai
->driver
->cops
->shutdown(cstream
, cpu_dai
);
334 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
) {
335 if (snd_soc_runtime_ignore_pmdown_time(rtd
)) {
336 snd_soc_dapm_stream_event(rtd
,
337 SNDRV_PCM_STREAM_PLAYBACK
,
338 SND_SOC_DAPM_STREAM_STOP
);
341 queue_delayed_work(system_power_efficient_wq
,
343 msecs_to_jiffies(rtd
->pmdown_time
));
346 /* capture streams can be powered down now */
347 snd_soc_dapm_stream_event(rtd
,
348 SNDRV_PCM_STREAM_CAPTURE
,
349 SND_SOC_DAPM_STREAM_STOP
);
352 mutex_unlock(&rtd
->pcm_mutex
);
356 static int soc_compr_free_fe(struct snd_compr_stream
*cstream
)
358 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
359 struct snd_soc_platform
*platform
= fe
->platform
;
360 struct snd_soc_component
*component
;
361 struct snd_soc_rtdcom_list
*rtdcom
;
362 struct snd_soc_dai
*cpu_dai
= fe
->cpu_dai
;
363 struct snd_soc_dpcm
*dpcm
;
366 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
368 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
369 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
371 stream
= SNDRV_PCM_STREAM_CAPTURE
;
373 snd_soc_runtime_deactivate(fe
, stream
);
375 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
377 ret
= dpcm_be_dai_hw_free(fe
, stream
);
379 dev_err(fe
->dev
, "compressed hw_free failed %d\n", ret
);
381 ret
= dpcm_be_dai_shutdown(fe
, stream
);
383 /* mark FE's links ready to prune */
384 list_for_each_entry(dpcm
, &fe
->dpcm
[stream
].be_clients
, list_be
)
385 dpcm
->state
= SND_SOC_DPCM_LINK_STATE_FREE
;
387 dpcm_dapm_stream_event(fe
, stream
, SND_SOC_DAPM_STREAM_STOP
);
389 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_CLOSE
;
390 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
392 dpcm_be_disconnect(fe
, stream
);
394 fe
->dpcm
[stream
].runtime
= NULL
;
396 if (fe
->dai_link
->compr_ops
&& fe
->dai_link
->compr_ops
->shutdown
)
397 fe
->dai_link
->compr_ops
->shutdown(cstream
);
399 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->free
)
400 platform
->driver
->compr_ops
->free(cstream
);
402 for_each_rtdcom(fe
, rtdcom
) {
403 component
= rtdcom
->component
;
405 /* ignore duplication for now */
406 if (platform
&& (component
== &platform
->component
))
409 if (!component
->driver
->compr_ops
||
410 !component
->driver
->compr_ops
->free
)
413 component
->driver
->compr_ops
->free(cstream
);
416 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->shutdown
)
417 cpu_dai
->driver
->cops
->shutdown(cstream
, cpu_dai
);
419 mutex_unlock(&fe
->card
->mutex
);
423 static int soc_compr_trigger(struct snd_compr_stream
*cstream
, int cmd
)
426 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
427 struct snd_soc_platform
*platform
= rtd
->platform
;
428 struct snd_soc_component
*component
;
429 struct snd_soc_rtdcom_list
*rtdcom
;
430 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
431 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
434 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
436 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->trigger
) {
437 ret
= platform
->driver
->compr_ops
->trigger(cstream
, cmd
);
442 for_each_rtdcom(rtd
, rtdcom
) {
443 component
= rtdcom
->component
;
445 /* ignore duplication for now */
446 if (platform
&& (component
== &platform
->component
))
449 if (!component
->driver
->compr_ops
||
450 !component
->driver
->compr_ops
->trigger
)
453 __ret
= component
->driver
->compr_ops
->trigger(cstream
, cmd
);
460 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->trigger
)
461 cpu_dai
->driver
->cops
->trigger(cstream
, cmd
, cpu_dai
);
465 case SNDRV_PCM_TRIGGER_START
:
466 snd_soc_dai_digital_mute(codec_dai
, 0, cstream
->direction
);
468 case SNDRV_PCM_TRIGGER_STOP
:
469 snd_soc_dai_digital_mute(codec_dai
, 1, cstream
->direction
);
474 mutex_unlock(&rtd
->pcm_mutex
);
478 static int soc_compr_trigger_fe(struct snd_compr_stream
*cstream
, int cmd
)
480 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
481 struct snd_soc_platform
*platform
= fe
->platform
;
482 struct snd_soc_component
*component
;
483 struct snd_soc_rtdcom_list
*rtdcom
;
484 struct snd_soc_dai
*cpu_dai
= fe
->cpu_dai
;
485 int ret
= 0, __ret
, stream
;
487 if (cmd
== SND_COMPR_TRIGGER_PARTIAL_DRAIN
||
488 cmd
== SND_COMPR_TRIGGER_DRAIN
) {
491 platform
->driver
->compr_ops
&&
492 platform
->driver
->compr_ops
->trigger
)
493 return platform
->driver
->compr_ops
->trigger(cstream
,
496 for_each_rtdcom(fe
, rtdcom
) {
497 component
= rtdcom
->component
;
499 /* ignore duplication for now */
500 if (platform
&& (component
== &platform
->component
))
503 if (!component
->driver
->compr_ops
||
504 !component
->driver
->compr_ops
->trigger
)
507 __ret
= component
->driver
->compr_ops
->trigger(cstream
, cmd
);
514 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
515 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
517 stream
= SNDRV_PCM_STREAM_CAPTURE
;
520 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
522 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->trigger
) {
523 ret
= cpu_dai
->driver
->cops
->trigger(cstream
, cmd
, cpu_dai
);
528 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->trigger
) {
529 ret
= platform
->driver
->compr_ops
->trigger(cstream
, cmd
);
534 for_each_rtdcom(fe
, rtdcom
) {
535 component
= rtdcom
->component
;
537 /* ignore duplication for now */
538 if (platform
&& (component
== &platform
->component
))
541 if (!component
->driver
->compr_ops
||
542 !component
->driver
->compr_ops
->trigger
)
545 __ret
= component
->driver
->compr_ops
->trigger(cstream
, cmd
);
552 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
554 ret
= dpcm_be_dai_trigger(fe
, stream
, cmd
);
557 case SNDRV_PCM_TRIGGER_START
:
558 case SNDRV_PCM_TRIGGER_RESUME
:
559 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
560 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_START
;
562 case SNDRV_PCM_TRIGGER_STOP
:
563 case SNDRV_PCM_TRIGGER_SUSPEND
:
564 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_STOP
;
566 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
567 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_PAUSED
;
572 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
573 mutex_unlock(&fe
->card
->mutex
);
577 static int soc_compr_set_params(struct snd_compr_stream
*cstream
,
578 struct snd_compr_params
*params
)
580 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
581 struct snd_soc_platform
*platform
= rtd
->platform
;
582 struct snd_soc_component
*component
;
583 struct snd_soc_rtdcom_list
*rtdcom
;
584 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
587 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
589 /* first we call set_params for the platform driver
590 * this should configure the soc side
591 * if the machine has compressed ops then we call that as well
592 * expectation is that platform and machine will configure everything
593 * for this compress path, like configuring pcm port for codec
595 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->set_params
) {
596 ret
= cpu_dai
->driver
->cops
->set_params(cstream
, params
, cpu_dai
);
601 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->set_params
) {
602 ret
= platform
->driver
->compr_ops
->set_params(cstream
, params
);
607 for_each_rtdcom(rtd
, rtdcom
) {
608 component
= rtdcom
->component
;
610 /* ignore duplication for now */
611 if (platform
&& (component
== &platform
->component
))
614 if (!component
->driver
->compr_ops
||
615 !component
->driver
->compr_ops
->set_params
)
618 __ret
= component
->driver
->compr_ops
->set_params(cstream
, params
);
625 if (rtd
->dai_link
->compr_ops
&& rtd
->dai_link
->compr_ops
->set_params
) {
626 ret
= rtd
->dai_link
->compr_ops
->set_params(cstream
);
631 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
632 snd_soc_dapm_stream_event(rtd
, SNDRV_PCM_STREAM_PLAYBACK
,
633 SND_SOC_DAPM_STREAM_START
);
635 snd_soc_dapm_stream_event(rtd
, SNDRV_PCM_STREAM_CAPTURE
,
636 SND_SOC_DAPM_STREAM_START
);
638 /* cancel any delayed stream shutdown that is pending */
640 mutex_unlock(&rtd
->pcm_mutex
);
642 cancel_delayed_work_sync(&rtd
->delayed_work
);
647 mutex_unlock(&rtd
->pcm_mutex
);
651 static int soc_compr_set_params_fe(struct snd_compr_stream
*cstream
,
652 struct snd_compr_params
*params
)
654 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
655 struct snd_pcm_substream
*fe_substream
=
656 fe
->pcm
->streams
[cstream
->direction
].substream
;
657 struct snd_soc_platform
*platform
= fe
->platform
;
658 struct snd_soc_component
*component
;
659 struct snd_soc_rtdcom_list
*rtdcom
;
660 struct snd_soc_dai
*cpu_dai
= fe
->cpu_dai
;
661 int ret
= 0, __ret
, stream
;
663 if (cstream
->direction
== SND_COMPRESS_PLAYBACK
)
664 stream
= SNDRV_PCM_STREAM_PLAYBACK
;
666 stream
= SNDRV_PCM_STREAM_CAPTURE
;
668 mutex_lock_nested(&fe
->card
->mutex
, SND_SOC_CARD_CLASS_RUNTIME
);
670 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->set_params
) {
671 ret
= cpu_dai
->driver
->cops
->set_params(cstream
, params
, cpu_dai
);
676 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->set_params
) {
677 ret
= platform
->driver
->compr_ops
->set_params(cstream
, params
);
682 for_each_rtdcom(fe
, rtdcom
) {
683 component
= rtdcom
->component
;
685 /* ignore duplication for now */
686 if (platform
&& (component
== &platform
->component
))
689 if (!component
->driver
->compr_ops
||
690 !component
->driver
->compr_ops
->set_params
)
693 __ret
= component
->driver
->compr_ops
->set_params(cstream
, params
);
700 if (fe
->dai_link
->compr_ops
&& fe
->dai_link
->compr_ops
->set_params
) {
701 ret
= fe
->dai_link
->compr_ops
->set_params(cstream
);
707 * Create an empty hw_params for the BE as the machine driver must
708 * fix this up to match DSP decoder and ASRC configuration.
709 * I.e. machine driver fixup for compressed BE is mandatory.
711 memset(&fe
->dpcm
[fe_substream
->stream
].hw_params
, 0,
712 sizeof(struct snd_pcm_hw_params
));
714 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
716 ret
= dpcm_be_dai_hw_params(fe
, stream
);
720 ret
= dpcm_be_dai_prepare(fe
, stream
);
724 dpcm_dapm_stream_event(fe
, stream
, SND_SOC_DAPM_STREAM_START
);
725 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_PREPARE
;
728 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
729 mutex_unlock(&fe
->card
->mutex
);
733 static int soc_compr_get_params(struct snd_compr_stream
*cstream
,
734 struct snd_codec
*params
)
736 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
737 struct snd_soc_platform
*platform
= rtd
->platform
;
738 struct snd_soc_component
*component
;
739 struct snd_soc_rtdcom_list
*rtdcom
;
740 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
743 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
745 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->get_params
) {
746 ret
= cpu_dai
->driver
->cops
->get_params(cstream
, params
, cpu_dai
);
751 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->get_params
) {
752 ret
= platform
->driver
->compr_ops
->get_params(cstream
, params
);
757 for_each_rtdcom(rtd
, rtdcom
) {
758 component
= rtdcom
->component
;
760 /* ignore duplication for now */
761 if (platform
&& (component
== &platform
->component
))
764 if (!component
->driver
->compr_ops
||
765 !component
->driver
->compr_ops
->get_params
)
768 __ret
= component
->driver
->compr_ops
->get_params(cstream
, params
);
774 mutex_unlock(&rtd
->pcm_mutex
);
778 static int soc_compr_get_caps(struct snd_compr_stream
*cstream
,
779 struct snd_compr_caps
*caps
)
781 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
782 struct snd_soc_platform
*platform
= rtd
->platform
;
783 struct snd_soc_component
*component
;
784 struct snd_soc_rtdcom_list
*rtdcom
;
787 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
789 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->get_caps
) {
790 ret
= platform
->driver
->compr_ops
->get_caps(cstream
, caps
);
795 for_each_rtdcom(rtd
, rtdcom
) {
796 component
= rtdcom
->component
;
798 /* ignore duplication for now */
799 if (platform
&& (component
== &platform
->component
))
802 if (!component
->driver
->compr_ops
||
803 !component
->driver
->compr_ops
->get_caps
)
806 __ret
= component
->driver
->compr_ops
->get_caps(cstream
, caps
);
812 mutex_unlock(&rtd
->pcm_mutex
);
816 static int soc_compr_get_codec_caps(struct snd_compr_stream
*cstream
,
817 struct snd_compr_codec_caps
*codec
)
819 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
820 struct snd_soc_platform
*platform
= rtd
->platform
;
821 struct snd_soc_component
*component
;
822 struct snd_soc_rtdcom_list
*rtdcom
;
825 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
827 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->get_codec_caps
) {
828 ret
= platform
->driver
->compr_ops
->get_codec_caps(cstream
, codec
);
833 for_each_rtdcom(rtd
, rtdcom
) {
834 component
= rtdcom
->component
;
836 /* ignore duplication for now */
837 if (platform
&& (component
== &platform
->component
))
840 if (!component
->driver
->compr_ops
||
841 !component
->driver
->compr_ops
->get_codec_caps
)
844 __ret
= component
->driver
->compr_ops
->get_codec_caps(cstream
, codec
);
850 mutex_unlock(&rtd
->pcm_mutex
);
854 static int soc_compr_ack(struct snd_compr_stream
*cstream
, size_t bytes
)
856 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
857 struct snd_soc_platform
*platform
= rtd
->platform
;
858 struct snd_soc_component
*component
;
859 struct snd_soc_rtdcom_list
*rtdcom
;
860 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
863 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
865 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->ack
) {
866 ret
= cpu_dai
->driver
->cops
->ack(cstream
, bytes
, cpu_dai
);
871 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->ack
) {
872 ret
= platform
->driver
->compr_ops
->ack(cstream
, bytes
);
877 for_each_rtdcom(rtd
, rtdcom
) {
878 component
= rtdcom
->component
;
880 /* ignore duplication for now */
881 if (platform
&& (component
== &platform
->component
))
884 if (!component
->driver
->compr_ops
||
885 !component
->driver
->compr_ops
->ack
)
888 __ret
= component
->driver
->compr_ops
->ack(cstream
, bytes
);
894 mutex_unlock(&rtd
->pcm_mutex
);
898 static int soc_compr_pointer(struct snd_compr_stream
*cstream
,
899 struct snd_compr_tstamp
*tstamp
)
901 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
902 struct snd_soc_platform
*platform
= rtd
->platform
;
903 struct snd_soc_component
*component
;
904 struct snd_soc_rtdcom_list
*rtdcom
;
906 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
908 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
910 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->pointer
)
911 cpu_dai
->driver
->cops
->pointer(cstream
, tstamp
, cpu_dai
);
913 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->pointer
) {
914 ret
= platform
->driver
->compr_ops
->pointer(cstream
, tstamp
);
919 for_each_rtdcom(rtd
, rtdcom
) {
920 component
= rtdcom
->component
;
922 /* ignore duplication for now */
923 if (platform
&& (component
== &platform
->component
))
926 if (!component
->driver
->compr_ops
||
927 !component
->driver
->compr_ops
->pointer
)
930 __ret
= component
->driver
->compr_ops
->pointer(cstream
, tstamp
);
936 mutex_unlock(&rtd
->pcm_mutex
);
940 static int soc_compr_copy(struct snd_compr_stream
*cstream
,
941 char __user
*buf
, size_t count
)
943 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
944 struct snd_soc_platform
*platform
= rtd
->platform
;
945 struct snd_soc_component
*component
;
946 struct snd_soc_rtdcom_list
*rtdcom
;
949 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
951 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->copy
) {
952 ret
= platform
->driver
->compr_ops
->copy(cstream
, buf
, count
);
957 for_each_rtdcom(rtd
, rtdcom
) {
958 component
= rtdcom
->component
;
960 /* ignore duplication for now */
961 if (platform
&& (component
== &platform
->component
))
964 if (!component
->driver
->compr_ops
||
965 !component
->driver
->compr_ops
->copy
)
968 __ret
= component
->driver
->compr_ops
->copy(cstream
, buf
, count
);
973 mutex_unlock(&rtd
->pcm_mutex
);
977 static int soc_compr_set_metadata(struct snd_compr_stream
*cstream
,
978 struct snd_compr_metadata
*metadata
)
980 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
981 struct snd_soc_platform
*platform
= rtd
->platform
;
982 struct snd_soc_component
*component
;
983 struct snd_soc_rtdcom_list
*rtdcom
;
984 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
987 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->set_metadata
) {
988 ret
= cpu_dai
->driver
->cops
->set_metadata(cstream
, metadata
, cpu_dai
);
993 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->set_metadata
) {
994 ret
= platform
->driver
->compr_ops
->set_metadata(cstream
, metadata
);
999 for_each_rtdcom(rtd
, rtdcom
) {
1000 component
= rtdcom
->component
;
1002 /* ignore duplication for now */
1003 if (platform
&& (component
== &platform
->component
))
1006 if (!component
->driver
->compr_ops
||
1007 !component
->driver
->compr_ops
->set_metadata
)
1010 __ret
= component
->driver
->compr_ops
->set_metadata(cstream
, metadata
);
1018 static int soc_compr_get_metadata(struct snd_compr_stream
*cstream
,
1019 struct snd_compr_metadata
*metadata
)
1021 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
1022 struct snd_soc_platform
*platform
= rtd
->platform
;
1023 struct snd_soc_component
*component
;
1024 struct snd_soc_rtdcom_list
*rtdcom
;
1025 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
1028 if (cpu_dai
->driver
->cops
&& cpu_dai
->driver
->cops
->get_metadata
) {
1029 ret
= cpu_dai
->driver
->cops
->get_metadata(cstream
, metadata
, cpu_dai
);
1034 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->get_metadata
) {
1035 ret
= platform
->driver
->compr_ops
->get_metadata(cstream
, metadata
);
1040 for_each_rtdcom(rtd
, rtdcom
) {
1041 component
= rtdcom
->component
;
1043 /* ignore duplication for now */
1044 if (platform
&& (component
== &platform
->component
))
1047 if (!component
->driver
->compr_ops
||
1048 !component
->driver
->compr_ops
->get_metadata
)
1051 __ret
= component
->driver
->compr_ops
->get_metadata(cstream
, metadata
);
1059 /* ASoC Compress operations */
1060 static struct snd_compr_ops soc_compr_ops
= {
1061 .open
= soc_compr_open
,
1062 .free
= soc_compr_free
,
1063 .set_params
= soc_compr_set_params
,
1064 .set_metadata
= soc_compr_set_metadata
,
1065 .get_metadata
= soc_compr_get_metadata
,
1066 .get_params
= soc_compr_get_params
,
1067 .trigger
= soc_compr_trigger
,
1068 .pointer
= soc_compr_pointer
,
1069 .ack
= soc_compr_ack
,
1070 .get_caps
= soc_compr_get_caps
,
1071 .get_codec_caps
= soc_compr_get_codec_caps
1074 /* ASoC Dynamic Compress operations */
1075 static struct snd_compr_ops soc_compr_dyn_ops
= {
1076 .open
= soc_compr_open_fe
,
1077 .free
= soc_compr_free_fe
,
1078 .set_params
= soc_compr_set_params_fe
,
1079 .get_params
= soc_compr_get_params
,
1080 .set_metadata
= soc_compr_set_metadata
,
1081 .get_metadata
= soc_compr_get_metadata
,
1082 .trigger
= soc_compr_trigger_fe
,
1083 .pointer
= soc_compr_pointer
,
1084 .ack
= soc_compr_ack
,
1085 .get_caps
= soc_compr_get_caps
,
1086 .get_codec_caps
= soc_compr_get_codec_caps
1090 * snd_soc_new_compress - create a new compress.
1092 * @rtd: The runtime for which we will create compress
1093 * @num: the device index number (zero based - shared with normal PCMs)
1095 * Return: 0 for success, else error.
1097 int snd_soc_new_compress(struct snd_soc_pcm_runtime
*rtd
, int num
)
1099 struct snd_soc_codec
*codec
= rtd
->codec
;
1100 struct snd_soc_platform
*platform
= rtd
->platform
;
1101 struct snd_soc_component
*component
;
1102 struct snd_soc_rtdcom_list
*rtdcom
;
1103 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
1104 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
1105 struct snd_compr
*compr
;
1106 struct snd_pcm
*be_pcm
;
1108 int ret
= 0, direction
= 0;
1109 int playback
= 0, capture
= 0;
1111 if (rtd
->num_codecs
> 1) {
1112 dev_err(rtd
->card
->dev
, "Multicodec not supported for compressed stream\n");
1116 /* check client and interface hw capabilities */
1117 if (codec_dai
->driver
->playback
.channels_min
)
1119 if (codec_dai
->driver
->capture
.channels_min
)
1122 capture
= capture
&& cpu_dai
->driver
->capture
.channels_min
;
1123 playback
= playback
&& cpu_dai
->driver
->playback
.channels_min
;
1126 * Compress devices are unidirectional so only one of the directions
1127 * should be set, check for that (xor)
1129 if (playback
+ capture
!= 1) {
1130 dev_err(rtd
->card
->dev
, "Invalid direction for compress P %d, C %d\n",
1136 direction
= SND_COMPRESS_PLAYBACK
;
1138 direction
= SND_COMPRESS_CAPTURE
;
1140 compr
= kzalloc(sizeof(*compr
), GFP_KERNEL
);
1144 compr
->ops
= devm_kzalloc(rtd
->card
->dev
, sizeof(soc_compr_ops
),
1151 if (rtd
->dai_link
->dynamic
) {
1152 snprintf(new_name
, sizeof(new_name
), "(%s)",
1153 rtd
->dai_link
->stream_name
);
1155 ret
= snd_pcm_new_internal(rtd
->card
->snd_card
, new_name
, num
,
1156 rtd
->dai_link
->dpcm_playback
,
1157 rtd
->dai_link
->dpcm_capture
, &be_pcm
);
1159 dev_err(rtd
->card
->dev
, "ASoC: can't create compressed for %s\n",
1160 rtd
->dai_link
->name
);
1166 if (rtd
->dai_link
->dpcm_playback
)
1167 be_pcm
->streams
[SNDRV_PCM_STREAM_PLAYBACK
].substream
->private_data
= rtd
;
1168 else if (rtd
->dai_link
->dpcm_capture
)
1169 be_pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
->private_data
= rtd
;
1170 memcpy(compr
->ops
, &soc_compr_dyn_ops
, sizeof(soc_compr_dyn_ops
));
1172 snprintf(new_name
, sizeof(new_name
), "%s %s-%d",
1173 rtd
->dai_link
->stream_name
, codec_dai
->name
, num
);
1175 memcpy(compr
->ops
, &soc_compr_ops
, sizeof(soc_compr_ops
));
1179 /* Add copy callback for not memory mapped DSPs */
1180 if (platform
&& platform
->driver
->compr_ops
&& platform
->driver
->compr_ops
->copy
)
1181 compr
->ops
->copy
= soc_compr_copy
;
1183 for_each_rtdcom(rtd
, rtdcom
) {
1184 component
= rtdcom
->component
;
1186 /* ignore duplication for now */
1187 if (platform
&& (component
== &platform
->component
))
1190 if (!component
->driver
->compr_ops
||
1191 !component
->driver
->compr_ops
->copy
)
1194 compr
->ops
->copy
= soc_compr_copy
;
1198 mutex_init(&compr
->lock
);
1199 ret
= snd_compress_new(rtd
->card
->snd_card
, num
, direction
,
1202 pr_err("compress asoc: can't create compress for codec %s\n",
1203 codec
->component
.name
);
1207 /* DAPM dai link stream work */
1208 INIT_DELAYED_WORK(&rtd
->delayed_work
, close_delayed_work
);
1211 compr
->private_data
= rtd
;
1213 printk(KERN_INFO
"compress asoc: %s <-> %s mapping ok\n", codec_dai
->name
,
1221 EXPORT_SYMBOL_GPL(snd_soc_new_compress
);