2 * soc-pcm.c -- ALSA SoC PCM
4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd.
6 * Copyright (C) 2010 Slimlogic Ltd.
7 * Copyright (C) 2010 Texas Instruments Inc.
9 * Authors: Liam Girdwood <lrg@ti.com>
10 * Mark Brown <broonie@opensource.wolfsonmicro.com>
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/delay.h>
22 #include <linux/slab.h>
23 #include <linux/workqueue.h>
24 #include <sound/core.h>
25 #include <sound/pcm.h>
26 #include <sound/pcm_params.h>
27 #include <sound/soc.h>
28 #include <sound/initval.h>
30 static DEFINE_MUTEX(pcm_mutex
);
32 static int soc_pcm_apply_symmetry(struct snd_pcm_substream
*substream
)
34 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
35 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
36 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
39 if (!codec_dai
->driver
->symmetric_rates
&&
40 !cpu_dai
->driver
->symmetric_rates
&&
41 !rtd
->dai_link
->symmetric_rates
)
44 /* This can happen if multiple streams are starting simultaneously -
45 * the second can need to get its constraints before the first has
46 * picked a rate. Complain and allow the application to carry on.
50 "Not enforcing symmetric_rates due to race\n");
54 dev_dbg(&rtd
->dev
, "Symmetry forces %dHz rate\n", rtd
->rate
);
56 ret
= snd_pcm_hw_constraint_minmax(substream
->runtime
,
57 SNDRV_PCM_HW_PARAM_RATE
,
58 rtd
->rate
, rtd
->rate
);
61 "Unable to apply rate symmetry constraint: %d\n", ret
);
69 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
70 * then initialized and any private data can be allocated. This also calls
71 * startup for the cpu DAI, platform, machine and codec DAI.
73 static int soc_pcm_open(struct snd_pcm_substream
*substream
)
75 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
76 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
77 struct snd_soc_platform
*platform
= rtd
->platform
;
78 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
79 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
80 struct snd_soc_dai_driver
*cpu_dai_drv
= cpu_dai
->driver
;
81 struct snd_soc_dai_driver
*codec_dai_drv
= codec_dai
->driver
;
84 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
86 /* startup the audio subsystem */
87 if (cpu_dai
->driver
->ops
->startup
) {
88 ret
= cpu_dai
->driver
->ops
->startup(substream
, cpu_dai
);
90 printk(KERN_ERR
"asoc: can't open interface %s\n",
96 if (platform
->driver
->ops
&& platform
->driver
->ops
->open
) {
97 ret
= platform
->driver
->ops
->open(substream
);
99 printk(KERN_ERR
"asoc: can't open platform %s\n", platform
->name
);
104 if (codec_dai
->driver
->ops
->startup
) {
105 ret
= codec_dai
->driver
->ops
->startup(substream
, codec_dai
);
107 printk(KERN_ERR
"asoc: can't open codec %s\n",
113 if (rtd
->dai_link
->ops
&& rtd
->dai_link
->ops
->startup
) {
114 ret
= rtd
->dai_link
->ops
->startup(substream
);
116 printk(KERN_ERR
"asoc: %s startup failed\n", rtd
->dai_link
->name
);
121 /* Check that the codec and cpu DAIs are compatible */
122 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
123 runtime
->hw
.rate_min
=
124 max(codec_dai_drv
->playback
.rate_min
,
125 cpu_dai_drv
->playback
.rate_min
);
126 runtime
->hw
.rate_max
=
127 min(codec_dai_drv
->playback
.rate_max
,
128 cpu_dai_drv
->playback
.rate_max
);
129 runtime
->hw
.channels_min
=
130 max(codec_dai_drv
->playback
.channels_min
,
131 cpu_dai_drv
->playback
.channels_min
);
132 runtime
->hw
.channels_max
=
133 min(codec_dai_drv
->playback
.channels_max
,
134 cpu_dai_drv
->playback
.channels_max
);
135 runtime
->hw
.formats
=
136 codec_dai_drv
->playback
.formats
& cpu_dai_drv
->playback
.formats
;
138 codec_dai_drv
->playback
.rates
& cpu_dai_drv
->playback
.rates
;
139 if (codec_dai_drv
->playback
.rates
140 & (SNDRV_PCM_RATE_KNOT
| SNDRV_PCM_RATE_CONTINUOUS
))
141 runtime
->hw
.rates
|= cpu_dai_drv
->playback
.rates
;
142 if (cpu_dai_drv
->playback
.rates
143 & (SNDRV_PCM_RATE_KNOT
| SNDRV_PCM_RATE_CONTINUOUS
))
144 runtime
->hw
.rates
|= codec_dai_drv
->playback
.rates
;
146 runtime
->hw
.rate_min
=
147 max(codec_dai_drv
->capture
.rate_min
,
148 cpu_dai_drv
->capture
.rate_min
);
149 runtime
->hw
.rate_max
=
150 min(codec_dai_drv
->capture
.rate_max
,
151 cpu_dai_drv
->capture
.rate_max
);
152 runtime
->hw
.channels_min
=
153 max(codec_dai_drv
->capture
.channels_min
,
154 cpu_dai_drv
->capture
.channels_min
);
155 runtime
->hw
.channels_max
=
156 min(codec_dai_drv
->capture
.channels_max
,
157 cpu_dai_drv
->capture
.channels_max
);
158 runtime
->hw
.formats
=
159 codec_dai_drv
->capture
.formats
& cpu_dai_drv
->capture
.formats
;
161 codec_dai_drv
->capture
.rates
& cpu_dai_drv
->capture
.rates
;
162 if (codec_dai_drv
->capture
.rates
163 & (SNDRV_PCM_RATE_KNOT
| SNDRV_PCM_RATE_CONTINUOUS
))
164 runtime
->hw
.rates
|= cpu_dai_drv
->capture
.rates
;
165 if (cpu_dai_drv
->capture
.rates
166 & (SNDRV_PCM_RATE_KNOT
| SNDRV_PCM_RATE_CONTINUOUS
))
167 runtime
->hw
.rates
|= codec_dai_drv
->capture
.rates
;
171 snd_pcm_limit_hw_rates(runtime
);
172 if (!runtime
->hw
.rates
) {
173 printk(KERN_ERR
"asoc: %s <-> %s No matching rates\n",
174 codec_dai
->name
, cpu_dai
->name
);
177 if (!runtime
->hw
.formats
) {
178 printk(KERN_ERR
"asoc: %s <-> %s No matching formats\n",
179 codec_dai
->name
, cpu_dai
->name
);
182 if (!runtime
->hw
.channels_min
|| !runtime
->hw
.channels_max
||
183 runtime
->hw
.channels_min
> runtime
->hw
.channels_max
) {
184 printk(KERN_ERR
"asoc: %s <-> %s No matching channels\n",
185 codec_dai
->name
, cpu_dai
->name
);
189 /* Symmetry only applies if we've already got an active stream. */
190 if (cpu_dai
->active
|| codec_dai
->active
) {
191 ret
= soc_pcm_apply_symmetry(substream
);
196 pr_debug("asoc: %s <-> %s info:\n",
197 codec_dai
->name
, cpu_dai
->name
);
198 pr_debug("asoc: rate mask 0x%x\n", runtime
->hw
.rates
);
199 pr_debug("asoc: min ch %d max ch %d\n", runtime
->hw
.channels_min
,
200 runtime
->hw
.channels_max
);
201 pr_debug("asoc: min rate %d max rate %d\n", runtime
->hw
.rate_min
,
202 runtime
->hw
.rate_max
);
204 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
205 cpu_dai
->playback_active
++;
206 codec_dai
->playback_active
++;
208 cpu_dai
->capture_active
++;
209 codec_dai
->capture_active
++;
213 rtd
->codec
->active
++;
214 mutex_unlock(&rtd
->pcm_mutex
);
218 if (rtd
->dai_link
->ops
&& rtd
->dai_link
->ops
->shutdown
)
219 rtd
->dai_link
->ops
->shutdown(substream
);
222 if (codec_dai
->driver
->ops
->shutdown
)
223 codec_dai
->driver
->ops
->shutdown(substream
, codec_dai
);
226 if (platform
->driver
->ops
&& platform
->driver
->ops
->close
)
227 platform
->driver
->ops
->close(substream
);
230 if (cpu_dai
->driver
->ops
->shutdown
)
231 cpu_dai
->driver
->ops
->shutdown(substream
, cpu_dai
);
233 mutex_unlock(&rtd
->pcm_mutex
);
238 * Power down the audio subsystem pmdown_time msecs after close is called.
239 * This is to ensure there are no pops or clicks in between any music tracks
240 * due to DAPM power cycling.
242 static void close_delayed_work(struct work_struct
*work
)
244 struct snd_soc_pcm_runtime
*rtd
=
245 container_of(work
, struct snd_soc_pcm_runtime
, delayed_work
.work
);
246 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
248 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
250 pr_debug("pop wq checking: %s status: %s waiting: %s\n",
251 codec_dai
->driver
->playback
.stream_name
,
252 codec_dai
->playback_active
? "active" : "inactive",
253 codec_dai
->pop_wait
? "yes" : "no");
255 /* are we waiting on this codec DAI stream */
256 if (codec_dai
->pop_wait
== 1) {
257 codec_dai
->pop_wait
= 0;
258 snd_soc_dapm_stream_event(rtd
,
259 codec_dai
->driver
->playback
.stream_name
,
260 SND_SOC_DAPM_STREAM_STOP
);
263 mutex_unlock(&rtd
->pcm_mutex
);
267 * Called by ALSA when a PCM substream is closed. Private data can be
268 * freed here. The cpu DAI, codec DAI, machine and platform are also
271 static int soc_pcm_close(struct snd_pcm_substream
*substream
)
273 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
274 struct snd_soc_platform
*platform
= rtd
->platform
;
275 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
276 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
277 struct snd_soc_codec
*codec
= rtd
->codec
;
279 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
281 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
282 cpu_dai
->playback_active
--;
283 codec_dai
->playback_active
--;
285 cpu_dai
->capture_active
--;
286 codec_dai
->capture_active
--;
293 if (!cpu_dai
->active
&& !codec_dai
->active
)
296 /* Muting the DAC suppresses artifacts caused during digital
297 * shutdown, for example from stopping clocks.
299 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
300 snd_soc_dai_digital_mute(codec_dai
, 1);
302 if (cpu_dai
->driver
->ops
->shutdown
)
303 cpu_dai
->driver
->ops
->shutdown(substream
, cpu_dai
);
305 if (codec_dai
->driver
->ops
->shutdown
)
306 codec_dai
->driver
->ops
->shutdown(substream
, codec_dai
);
308 if (rtd
->dai_link
->ops
&& rtd
->dai_link
->ops
->shutdown
)
309 rtd
->dai_link
->ops
->shutdown(substream
);
311 if (platform
->driver
->ops
&& platform
->driver
->ops
->close
)
312 platform
->driver
->ops
->close(substream
);
313 cpu_dai
->runtime
= NULL
;
315 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
316 /* start delayed pop wq here for playback streams */
317 codec_dai
->pop_wait
= 1;
318 schedule_delayed_work(&rtd
->delayed_work
,
319 msecs_to_jiffies(rtd
->pmdown_time
));
321 /* capture streams can be powered down now */
322 snd_soc_dapm_stream_event(rtd
,
323 codec_dai
->driver
->capture
.stream_name
,
324 SND_SOC_DAPM_STREAM_STOP
);
327 mutex_unlock(&rtd
->pcm_mutex
);
332 * Called by ALSA when the PCM substream is prepared, can set format, sample
333 * rate, etc. This function is non atomic and can be called multiple times,
334 * it can refer to the runtime info.
336 static int soc_pcm_prepare(struct snd_pcm_substream
*substream
)
338 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
339 struct snd_soc_platform
*platform
= rtd
->platform
;
340 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
341 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
344 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
346 if (rtd
->dai_link
->ops
&& rtd
->dai_link
->ops
->prepare
) {
347 ret
= rtd
->dai_link
->ops
->prepare(substream
);
349 printk(KERN_ERR
"asoc: machine prepare error\n");
354 if (platform
->driver
->ops
&& platform
->driver
->ops
->prepare
) {
355 ret
= platform
->driver
->ops
->prepare(substream
);
357 printk(KERN_ERR
"asoc: platform prepare error\n");
362 if (codec_dai
->driver
->ops
->prepare
) {
363 ret
= codec_dai
->driver
->ops
->prepare(substream
, codec_dai
);
365 printk(KERN_ERR
"asoc: codec DAI prepare error\n");
370 if (cpu_dai
->driver
->ops
->prepare
) {
371 ret
= cpu_dai
->driver
->ops
->prepare(substream
, cpu_dai
);
373 printk(KERN_ERR
"asoc: cpu DAI prepare error\n");
378 /* cancel any delayed stream shutdown that is pending */
379 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
&&
380 codec_dai
->pop_wait
) {
381 codec_dai
->pop_wait
= 0;
382 cancel_delayed_work(&rtd
->delayed_work
);
385 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
386 snd_soc_dapm_stream_event(rtd
,
387 codec_dai
->driver
->playback
.stream_name
,
388 SND_SOC_DAPM_STREAM_START
);
390 snd_soc_dapm_stream_event(rtd
,
391 codec_dai
->driver
->capture
.stream_name
,
392 SND_SOC_DAPM_STREAM_START
);
394 snd_soc_dai_digital_mute(codec_dai
, 0);
397 mutex_unlock(&rtd
->pcm_mutex
);
402 * Called by ALSA when the hardware params are set by application. This
403 * function can also be called multiple times and can allocate buffers
404 * (using snd_pcm_lib_* ). It's non-atomic.
406 static int soc_pcm_hw_params(struct snd_pcm_substream
*substream
,
407 struct snd_pcm_hw_params
*params
)
409 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
410 struct snd_soc_platform
*platform
= rtd
->platform
;
411 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
412 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
415 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
417 if (rtd
->dai_link
->ops
&& rtd
->dai_link
->ops
->hw_params
) {
418 ret
= rtd
->dai_link
->ops
->hw_params(substream
, params
);
420 printk(KERN_ERR
"asoc: machine hw_params failed\n");
425 if (codec_dai
->driver
->ops
->hw_params
) {
426 ret
= codec_dai
->driver
->ops
->hw_params(substream
, params
, codec_dai
);
428 printk(KERN_ERR
"asoc: can't set codec %s hw params\n",
434 if (cpu_dai
->driver
->ops
->hw_params
) {
435 ret
= cpu_dai
->driver
->ops
->hw_params(substream
, params
, cpu_dai
);
437 printk(KERN_ERR
"asoc: interface %s hw params failed\n",
443 if (platform
->driver
->ops
&& platform
->driver
->ops
->hw_params
) {
444 ret
= platform
->driver
->ops
->hw_params(substream
, params
);
446 printk(KERN_ERR
"asoc: platform %s hw params failed\n",
452 rtd
->rate
= params_rate(params
);
455 mutex_unlock(&rtd
->pcm_mutex
);
459 if (cpu_dai
->driver
->ops
->hw_free
)
460 cpu_dai
->driver
->ops
->hw_free(substream
, cpu_dai
);
463 if (codec_dai
->driver
->ops
->hw_free
)
464 codec_dai
->driver
->ops
->hw_free(substream
, codec_dai
);
467 if (rtd
->dai_link
->ops
&& rtd
->dai_link
->ops
->hw_free
)
468 rtd
->dai_link
->ops
->hw_free(substream
);
470 mutex_unlock(&rtd
->pcm_mutex
);
475 * Frees resources allocated by hw_params, can be called multiple times
477 static int soc_pcm_hw_free(struct snd_pcm_substream
*substream
)
479 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
480 struct snd_soc_platform
*platform
= rtd
->platform
;
481 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
482 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
483 struct snd_soc_codec
*codec
= rtd
->codec
;
485 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
487 /* apply codec digital mute */
489 snd_soc_dai_digital_mute(codec_dai
, 1);
491 /* free any machine hw params */
492 if (rtd
->dai_link
->ops
&& rtd
->dai_link
->ops
->hw_free
)
493 rtd
->dai_link
->ops
->hw_free(substream
);
495 /* free any DMA resources */
496 if (platform
->driver
->ops
&& platform
->driver
->ops
->hw_free
)
497 platform
->driver
->ops
->hw_free(substream
);
499 /* now free hw params for the DAIs */
500 if (codec_dai
->driver
->ops
->hw_free
)
501 codec_dai
->driver
->ops
->hw_free(substream
, codec_dai
);
503 if (cpu_dai
->driver
->ops
->hw_free
)
504 cpu_dai
->driver
->ops
->hw_free(substream
, cpu_dai
);
506 mutex_unlock(&rtd
->pcm_mutex
);
510 static int soc_pcm_trigger(struct snd_pcm_substream
*substream
, int cmd
)
512 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
513 struct snd_soc_platform
*platform
= rtd
->platform
;
514 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
515 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
518 if (codec_dai
->driver
->ops
->trigger
) {
519 ret
= codec_dai
->driver
->ops
->trigger(substream
, cmd
, codec_dai
);
524 if (platform
->driver
->ops
&& platform
->driver
->ops
->trigger
) {
525 ret
= platform
->driver
->ops
->trigger(substream
, cmd
);
530 if (cpu_dai
->driver
->ops
->trigger
) {
531 ret
= cpu_dai
->driver
->ops
->trigger(substream
, cmd
, cpu_dai
);
539 * soc level wrapper for pointer callback
540 * If cpu_dai, codec_dai, platform driver has the delay callback, than
541 * the runtime->delay will be updated accordingly.
543 static snd_pcm_uframes_t
soc_pcm_pointer(struct snd_pcm_substream
*substream
)
545 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
546 struct snd_soc_platform
*platform
= rtd
->platform
;
547 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
548 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
549 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
550 snd_pcm_uframes_t offset
= 0;
551 snd_pcm_sframes_t delay
= 0;
553 if (platform
->driver
->ops
&& platform
->driver
->ops
->pointer
)
554 offset
= platform
->driver
->ops
->pointer(substream
);
556 if (cpu_dai
->driver
->ops
->delay
)
557 delay
+= cpu_dai
->driver
->ops
->delay(substream
, cpu_dai
);
559 if (codec_dai
->driver
->ops
->delay
)
560 delay
+= codec_dai
->driver
->ops
->delay(substream
, codec_dai
);
562 if (platform
->driver
->delay
)
563 delay
+= platform
->driver
->delay(substream
, codec_dai
);
565 runtime
->delay
= delay
;
570 /* ASoC PCM operations */
571 static struct snd_pcm_ops soc_pcm_ops
= {
572 .open
= soc_pcm_open
,
573 .close
= soc_pcm_close
,
574 .hw_params
= soc_pcm_hw_params
,
575 .hw_free
= soc_pcm_hw_free
,
576 .prepare
= soc_pcm_prepare
,
577 .trigger
= soc_pcm_trigger
,
578 .pointer
= soc_pcm_pointer
,
581 /* create a new pcm */
582 int soc_new_pcm(struct snd_soc_pcm_runtime
*rtd
, int num
)
584 struct snd_soc_codec
*codec
= rtd
->codec
;
585 struct snd_soc_platform
*platform
= rtd
->platform
;
586 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
587 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
590 int ret
= 0, playback
= 0, capture
= 0;
592 /* check client and interface hw capabilities */
593 snprintf(new_name
, sizeof(new_name
), "%s %s-%d",
594 rtd
->dai_link
->stream_name
, codec_dai
->name
, num
);
596 if (codec_dai
->driver
->playback
.channels_min
)
598 if (codec_dai
->driver
->capture
.channels_min
)
601 dev_dbg(rtd
->card
->dev
, "registered pcm #%d %s\n",num
,new_name
);
602 ret
= snd_pcm_new(rtd
->card
->snd_card
, new_name
,
603 num
, playback
, capture
, &pcm
);
605 printk(KERN_ERR
"asoc: can't create pcm for codec %s\n", codec
->name
);
609 /* DAPM dai link stream work */
610 INIT_DELAYED_WORK(&rtd
->delayed_work
, close_delayed_work
);
613 pcm
->private_data
= rtd
;
614 if (platform
->driver
->ops
) {
615 soc_pcm_ops
.mmap
= platform
->driver
->ops
->mmap
;
616 soc_pcm_ops
.pointer
= platform
->driver
->ops
->pointer
;
617 soc_pcm_ops
.ioctl
= platform
->driver
->ops
->ioctl
;
618 soc_pcm_ops
.copy
= platform
->driver
->ops
->copy
;
619 soc_pcm_ops
.silence
= platform
->driver
->ops
->silence
;
620 soc_pcm_ops
.ack
= platform
->driver
->ops
->ack
;
621 soc_pcm_ops
.page
= platform
->driver
->ops
->page
;
625 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_PLAYBACK
, &soc_pcm_ops
);
628 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_CAPTURE
, &soc_pcm_ops
);
630 if (platform
->driver
->pcm_new
) {
631 ret
= platform
->driver
->pcm_new(rtd
);
633 pr_err("asoc: platform pcm constructor failed\n");
638 pcm
->private_free
= platform
->driver
->pcm_free
;
639 printk(KERN_INFO
"asoc: %s <-> %s mapping ok\n", codec_dai
->name
,