1 // SPDX-License-Identifier: GPL-2.0+
3 // soc-compress.c -- ALSA SoC Compress
5 // Copyright (C) 2012 Intel Corp.
7 // Authors: Namarta Kohli <namartax.kohli@intel.com>
8 // Ramesh Babu K V <ramesh.babu@linux.intel.com>
9 // Vinod Koul <vinod.koul@linux.intel.com>
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/delay.h>
14 #include <linux/slab.h>
15 #include <linux/workqueue.h>
16 #include <sound/core.h>
17 #include <sound/compress_params.h>
18 #include <sound/compress_driver.h>
19 #include <sound/soc.h>
20 #include <sound/initval.h>
21 #include <sound/soc-dpcm.h>
22 #include <sound/soc-link.h>
24 static int snd_soc_compr_components_open(struct snd_compr_stream
*cstream
)
26 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
27 struct snd_soc_component
*component
;
31 for_each_rtd_components(rtd
, i
, component
) {
32 ret
= snd_soc_component_module_get_when_open(component
, cstream
);
36 ret
= snd_soc_component_compr_open(component
, cstream
);
44 static void snd_soc_compr_components_free(struct snd_compr_stream
*cstream
,
47 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
48 struct snd_soc_component
*component
;
51 for_each_rtd_components(rtd
, i
, component
) {
52 snd_soc_component_compr_free(component
, cstream
, rollback
);
53 snd_soc_component_module_put_when_close(component
, cstream
, rollback
);
57 static int soc_compr_clean(struct snd_compr_stream
*cstream
, int rollback
)
59 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
60 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
61 struct snd_soc_dai
*codec_dai
= snd_soc_rtd_to_codec(rtd
, 0);
62 int stream
= cstream
->direction
; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
64 snd_soc_dpcm_mutex_lock(rtd
);
67 snd_soc_runtime_deactivate(rtd
, stream
);
69 snd_soc_dai_digital_mute(codec_dai
, 1, stream
);
71 if (!snd_soc_dai_active(cpu_dai
))
72 cpu_dai
->symmetric_rate
= 0;
74 if (!snd_soc_dai_active(codec_dai
))
75 codec_dai
->symmetric_rate
= 0;
77 snd_soc_link_compr_shutdown(cstream
, rollback
);
79 snd_soc_compr_components_free(cstream
, rollback
);
81 snd_soc_dai_compr_shutdown(cpu_dai
, cstream
, rollback
);
84 snd_soc_dapm_stream_stop(rtd
, stream
);
86 snd_soc_dpcm_mutex_unlock(rtd
);
88 snd_soc_pcm_component_pm_runtime_put(rtd
, cstream
, rollback
);
93 static int soc_compr_free(struct snd_compr_stream
*cstream
)
95 return soc_compr_clean(cstream
, 0);
98 static int soc_compr_open(struct snd_compr_stream
*cstream
)
100 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
101 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
102 int stream
= cstream
->direction
; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
105 ret
= snd_soc_pcm_component_pm_runtime_get(rtd
, cstream
);
109 snd_soc_dpcm_mutex_lock(rtd
);
111 ret
= snd_soc_dai_compr_startup(cpu_dai
, cstream
);
115 ret
= snd_soc_compr_components_open(cstream
);
119 ret
= snd_soc_link_compr_startup(cstream
);
123 snd_soc_runtime_activate(rtd
, stream
);
125 snd_soc_dpcm_mutex_unlock(rtd
);
128 soc_compr_clean(cstream
, 1);
133 static int soc_compr_open_fe(struct snd_compr_stream
*cstream
)
135 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
136 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(fe
, 0);
137 struct snd_soc_dpcm
*dpcm
;
138 struct snd_soc_dapm_widget_list
*list
;
139 int stream
= cstream
->direction
; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
142 snd_soc_card_mutex_lock(fe
->card
);
144 ret
= dpcm_path_get(fe
, stream
, &list
);
148 snd_soc_dpcm_mutex_lock(fe
);
150 /* calculate valid and active FE <-> BE dpcms */
151 dpcm_process_paths(fe
, stream
, &list
, 1);
153 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
155 ret
= dpcm_be_dai_startup(fe
, stream
);
157 /* clean up all links */
158 for_each_dpcm_be(fe
, stream
, dpcm
)
159 dpcm
->state
= SND_SOC_DPCM_LINK_STATE_FREE
;
161 dpcm_be_disconnect(fe
, stream
);
165 ret
= snd_soc_dai_compr_startup(cpu_dai
, cstream
);
169 ret
= snd_soc_compr_components_open(cstream
);
173 ret
= snd_soc_link_compr_startup(cstream
);
177 dpcm_clear_pending_state(fe
, stream
);
178 dpcm_path_put(&list
);
180 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_OPEN
;
181 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
183 snd_soc_runtime_activate(fe
, stream
);
184 snd_soc_dpcm_mutex_unlock(fe
);
186 snd_soc_card_mutex_unlock(fe
->card
);
191 snd_soc_compr_components_free(cstream
, 1);
193 snd_soc_dai_compr_shutdown(cpu_dai
, cstream
, 1);
195 dpcm_path_put(&list
);
196 snd_soc_dpcm_mutex_unlock(fe
);
198 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
199 snd_soc_card_mutex_unlock(fe
->card
);
203 static int soc_compr_free_fe(struct snd_compr_stream
*cstream
)
205 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
206 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(fe
, 0);
207 struct snd_soc_dpcm
*dpcm
;
208 int stream
= cstream
->direction
; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
210 snd_soc_card_mutex_lock(fe
->card
);
212 snd_soc_dpcm_mutex_lock(fe
);
213 snd_soc_runtime_deactivate(fe
, stream
);
215 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
217 dpcm_be_dai_hw_free(fe
, stream
);
219 dpcm_be_dai_shutdown(fe
, stream
);
221 /* mark FE's links ready to prune */
222 for_each_dpcm_be(fe
, stream
, dpcm
)
223 dpcm
->state
= SND_SOC_DPCM_LINK_STATE_FREE
;
225 dpcm_dapm_stream_event(fe
, stream
, SND_SOC_DAPM_STREAM_STOP
);
227 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_CLOSE
;
228 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
230 dpcm_be_disconnect(fe
, stream
);
232 snd_soc_dpcm_mutex_unlock(fe
);
234 snd_soc_link_compr_shutdown(cstream
, 0);
236 snd_soc_compr_components_free(cstream
, 0);
238 snd_soc_dai_compr_shutdown(cpu_dai
, cstream
, 0);
240 snd_soc_card_mutex_unlock(fe
->card
);
244 static int soc_compr_trigger(struct snd_compr_stream
*cstream
, int cmd
)
246 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
247 struct snd_soc_dai
*codec_dai
= snd_soc_rtd_to_codec(rtd
, 0);
248 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
249 int stream
= cstream
->direction
; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
252 snd_soc_dpcm_mutex_lock(rtd
);
254 ret
= snd_soc_component_compr_trigger(cstream
, cmd
);
258 ret
= snd_soc_dai_compr_trigger(cpu_dai
, cstream
, cmd
);
263 case SNDRV_PCM_TRIGGER_START
:
264 snd_soc_dai_digital_mute(codec_dai
, 0, stream
);
266 case SNDRV_PCM_TRIGGER_STOP
:
267 snd_soc_dai_digital_mute(codec_dai
, 1, stream
);
272 snd_soc_dpcm_mutex_unlock(rtd
);
276 static int soc_compr_trigger_fe(struct snd_compr_stream
*cstream
, int cmd
)
278 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
279 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(fe
, 0);
280 int stream
= cstream
->direction
; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
283 if (cmd
== SND_COMPR_TRIGGER_PARTIAL_DRAIN
||
284 cmd
== SND_COMPR_TRIGGER_DRAIN
)
285 return snd_soc_component_compr_trigger(cstream
, cmd
);
287 snd_soc_card_mutex_lock(fe
->card
);
289 ret
= snd_soc_dai_compr_trigger(cpu_dai
, cstream
, cmd
);
293 ret
= snd_soc_component_compr_trigger(cstream
, cmd
);
297 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
299 ret
= dpcm_be_dai_trigger(fe
, stream
, cmd
);
302 case SNDRV_PCM_TRIGGER_START
:
303 case SNDRV_PCM_TRIGGER_RESUME
:
304 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
305 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_START
;
307 case SNDRV_PCM_TRIGGER_STOP
:
308 case SNDRV_PCM_TRIGGER_SUSPEND
:
309 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_STOP
;
311 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
312 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_PAUSED
;
317 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
318 snd_soc_card_mutex_unlock(fe
->card
);
322 static int soc_compr_set_params(struct snd_compr_stream
*cstream
,
323 struct snd_compr_params
*params
)
325 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
326 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
327 int stream
= cstream
->direction
; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
330 snd_soc_dpcm_mutex_lock(rtd
);
333 * First we call set_params for the CPU DAI, then the component
334 * driver this should configure the SoC side. If the machine has
335 * compressed ops then we call that as well. The expectation is
336 * that these callbacks will configure everything for this compress
337 * path, like configuring a PCM port for a CODEC.
339 ret
= snd_soc_dai_compr_set_params(cpu_dai
, cstream
, params
);
343 ret
= snd_soc_component_compr_set_params(cstream
, params
);
347 ret
= snd_soc_link_compr_set_params(cstream
);
351 snd_soc_dapm_stream_event(rtd
, stream
, SND_SOC_DAPM_STREAM_START
);
353 /* cancel any delayed stream shutdown that is pending */
355 snd_soc_dpcm_mutex_unlock(rtd
);
357 cancel_delayed_work_sync(&rtd
->delayed_work
);
362 snd_soc_dpcm_mutex_unlock(rtd
);
366 static int soc_compr_set_params_fe(struct snd_compr_stream
*cstream
,
367 struct snd_compr_params
*params
)
369 struct snd_soc_pcm_runtime
*fe
= cstream
->private_data
;
370 struct snd_pcm_substream
*fe_substream
=
371 fe
->pcm
->streams
[cstream
->direction
].substream
;
372 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(fe
, 0);
373 int stream
= cstream
->direction
; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */
376 snd_soc_card_mutex_lock(fe
->card
);
379 * Create an empty hw_params for the BE as the machine driver must
380 * fix this up to match DSP decoder and ASRC configuration.
381 * I.e. machine driver fixup for compressed BE is mandatory.
383 memset(&fe
->dpcm
[fe_substream
->stream
].hw_params
, 0,
384 sizeof(struct snd_pcm_hw_params
));
386 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_FE
;
388 snd_soc_dpcm_mutex_lock(fe
);
389 ret
= dpcm_be_dai_hw_params(fe
, stream
);
390 snd_soc_dpcm_mutex_unlock(fe
);
394 snd_soc_dpcm_mutex_lock(fe
);
395 ret
= dpcm_be_dai_prepare(fe
, stream
);
396 snd_soc_dpcm_mutex_unlock(fe
);
400 ret
= snd_soc_dai_compr_set_params(cpu_dai
, cstream
, params
);
404 ret
= snd_soc_component_compr_set_params(cstream
, params
);
408 ret
= snd_soc_link_compr_set_params(cstream
);
411 snd_soc_dpcm_mutex_lock(fe
);
412 dpcm_dapm_stream_event(fe
, stream
, SND_SOC_DAPM_STREAM_START
);
413 snd_soc_dpcm_mutex_unlock(fe
);
414 fe
->dpcm
[stream
].state
= SND_SOC_DPCM_STATE_PREPARE
;
417 fe
->dpcm
[stream
].runtime_update
= SND_SOC_DPCM_UPDATE_NO
;
418 snd_soc_card_mutex_unlock(fe
->card
);
422 static int soc_compr_get_params(struct snd_compr_stream
*cstream
,
423 struct snd_codec
*params
)
425 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
426 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
429 snd_soc_dpcm_mutex_lock(rtd
);
431 ret
= snd_soc_dai_compr_get_params(cpu_dai
, cstream
, params
);
435 ret
= snd_soc_component_compr_get_params(cstream
, params
);
437 snd_soc_dpcm_mutex_unlock(rtd
);
441 static int soc_compr_ack(struct snd_compr_stream
*cstream
, size_t bytes
)
443 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
444 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
447 snd_soc_dpcm_mutex_lock(rtd
);
449 ret
= snd_soc_dai_compr_ack(cpu_dai
, cstream
, bytes
);
453 ret
= snd_soc_component_compr_ack(cstream
, bytes
);
455 snd_soc_dpcm_mutex_unlock(rtd
);
459 static int soc_compr_pointer(struct snd_compr_stream
*cstream
,
460 struct snd_compr_tstamp
*tstamp
)
462 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
464 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
466 snd_soc_dpcm_mutex_lock(rtd
);
468 ret
= snd_soc_dai_compr_pointer(cpu_dai
, cstream
, tstamp
);
472 ret
= snd_soc_component_compr_pointer(cstream
, tstamp
);
474 snd_soc_dpcm_mutex_unlock(rtd
);
478 static int soc_compr_set_metadata(struct snd_compr_stream
*cstream
,
479 struct snd_compr_metadata
*metadata
)
481 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
482 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
485 ret
= snd_soc_dai_compr_set_metadata(cpu_dai
, cstream
, metadata
);
489 return snd_soc_component_compr_set_metadata(cstream
, metadata
);
492 static int soc_compr_get_metadata(struct snd_compr_stream
*cstream
,
493 struct snd_compr_metadata
*metadata
)
495 struct snd_soc_pcm_runtime
*rtd
= cstream
->private_data
;
496 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
499 ret
= snd_soc_dai_compr_get_metadata(cpu_dai
, cstream
, metadata
);
503 return snd_soc_component_compr_get_metadata(cstream
, metadata
);
506 /* ASoC Compress operations */
507 static struct snd_compr_ops soc_compr_ops
= {
508 .open
= soc_compr_open
,
509 .free
= soc_compr_free
,
510 .set_params
= soc_compr_set_params
,
511 .set_metadata
= soc_compr_set_metadata
,
512 .get_metadata
= soc_compr_get_metadata
,
513 .get_params
= soc_compr_get_params
,
514 .trigger
= soc_compr_trigger
,
515 .pointer
= soc_compr_pointer
,
516 .ack
= soc_compr_ack
,
517 .get_caps
= snd_soc_component_compr_get_caps
,
518 .get_codec_caps
= snd_soc_component_compr_get_codec_caps
,
521 /* ASoC Dynamic Compress operations */
522 static struct snd_compr_ops soc_compr_dyn_ops
= {
523 .open
= soc_compr_open_fe
,
524 .free
= soc_compr_free_fe
,
525 .set_params
= soc_compr_set_params_fe
,
526 .get_params
= soc_compr_get_params
,
527 .set_metadata
= soc_compr_set_metadata
,
528 .get_metadata
= soc_compr_get_metadata
,
529 .trigger
= soc_compr_trigger_fe
,
530 .pointer
= soc_compr_pointer
,
531 .ack
= soc_compr_ack
,
532 .get_caps
= snd_soc_component_compr_get_caps
,
533 .get_codec_caps
= snd_soc_component_compr_get_codec_caps
,
537 * snd_soc_new_compress - create a new compress.
539 * @rtd: The runtime for which we will create compress
541 * Return: 0 for success, else error.
543 int snd_soc_new_compress(struct snd_soc_pcm_runtime
*rtd
)
545 struct snd_soc_component
*component
;
546 struct snd_soc_dai
*codec_dai
= snd_soc_rtd_to_codec(rtd
, 0);
547 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
548 struct snd_compr
*compr
;
549 struct snd_pcm
*be_pcm
;
551 int ret
= 0, direction
= 0;
552 int playback
= 0, capture
= 0;
556 * make sure these are same value,
557 * and then use these as equally
559 BUILD_BUG_ON((int)SNDRV_PCM_STREAM_PLAYBACK
!= (int)SND_COMPRESS_PLAYBACK
);
560 BUILD_BUG_ON((int)SNDRV_PCM_STREAM_CAPTURE
!= (int)SND_COMPRESS_CAPTURE
);
562 if (rtd
->dai_link
->num_cpus
> 1 ||
563 rtd
->dai_link
->num_codecs
> 1) {
564 dev_err(rtd
->card
->dev
,
565 "Compress ASoC: Multi CPU/Codec not supported\n");
570 dev_err(rtd
->card
->dev
, "Missing codec\n");
574 /* check client and interface hw capabilities */
575 if (snd_soc_dai_stream_valid(codec_dai
, SNDRV_PCM_STREAM_PLAYBACK
) &&
576 snd_soc_dai_stream_valid(cpu_dai
, SNDRV_PCM_STREAM_PLAYBACK
))
578 if (snd_soc_dai_stream_valid(codec_dai
, SNDRV_PCM_STREAM_CAPTURE
) &&
579 snd_soc_dai_stream_valid(cpu_dai
, SNDRV_PCM_STREAM_CAPTURE
))
583 * Compress devices are unidirectional so only one of the directions
584 * should be set, check for that (xor)
586 if (playback
+ capture
!= 1) {
587 dev_err(rtd
->card
->dev
,
588 "Compress ASoC: Invalid direction for P %d, C %d\n",
594 direction
= SND_COMPRESS_PLAYBACK
;
596 direction
= SND_COMPRESS_CAPTURE
;
598 compr
= devm_kzalloc(rtd
->card
->dev
, sizeof(*compr
), GFP_KERNEL
);
602 compr
->ops
= devm_kzalloc(rtd
->card
->dev
, sizeof(soc_compr_ops
),
607 if (rtd
->dai_link
->dynamic
) {
611 if (rtd
->dai_link
->capture_only
)
613 if (rtd
->dai_link
->playback_only
)
616 snprintf(new_name
, sizeof(new_name
), "(%s)",
617 rtd
->dai_link
->stream_name
);
619 ret
= snd_pcm_new_internal(rtd
->card
->snd_card
, new_name
, rtd
->id
,
620 playback
, capture
, &be_pcm
);
622 dev_err(rtd
->card
->dev
,
623 "Compress ASoC: can't create compressed for %s: %d\n",
624 rtd
->dai_link
->name
, ret
);
628 /* inherit atomicity from DAI link */
629 be_pcm
->nonatomic
= rtd
->dai_link
->nonatomic
;
634 be_pcm
->streams
[SNDRV_PCM_STREAM_PLAYBACK
].substream
->private_data
= rtd
;
636 be_pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
->private_data
= rtd
;
637 memcpy(compr
->ops
, &soc_compr_dyn_ops
, sizeof(soc_compr_dyn_ops
));
639 snprintf(new_name
, sizeof(new_name
), "%s %s-%d",
640 rtd
->dai_link
->stream_name
, codec_dai
->name
, rtd
->id
);
642 memcpy(compr
->ops
, &soc_compr_ops
, sizeof(soc_compr_ops
));
645 for_each_rtd_components(rtd
, i
, component
) {
646 if (!component
->driver
->compress_ops
||
647 !component
->driver
->compress_ops
->copy
)
650 compr
->ops
->copy
= snd_soc_component_compr_copy
;
654 ret
= snd_compress_new(rtd
->card
->snd_card
, rtd
->id
, direction
,
657 component
= snd_soc_rtd_to_codec(rtd
, 0)->component
;
658 dev_err(component
->dev
,
659 "Compress ASoC: can't create compress for codec %s: %d\n",
660 component
->name
, ret
);
664 /* DAPM dai link stream work */
665 rtd
->close_delayed_work_func
= snd_soc_close_delayed_work
;
668 compr
->private_data
= rtd
;
670 dev_dbg(rtd
->card
->dev
, "Compress ASoC: %s <-> %s mapping ok\n",
671 codec_dai
->name
, cpu_dai
->name
);
675 EXPORT_SYMBOL_GPL(snd_soc_new_compress
);