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 int soc_pcm_apply_symmetry(struct snd_pcm_substream
*substream
)
32 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
33 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
34 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
37 if (!codec_dai
->driver
->symmetric_rates
&&
38 !cpu_dai
->driver
->symmetric_rates
&&
39 !rtd
->dai_link
->symmetric_rates
)
42 /* This can happen if multiple streams are starting simultaneously -
43 * the second can need to get its constraints before the first has
44 * picked a rate. Complain and allow the application to carry on.
48 "Not enforcing symmetric_rates due to race\n");
52 dev_dbg(&rtd
->dev
, "Symmetry forces %dHz rate\n", rtd
->rate
);
54 ret
= snd_pcm_hw_constraint_minmax(substream
->runtime
,
55 SNDRV_PCM_HW_PARAM_RATE
,
56 rtd
->rate
, rtd
->rate
);
59 "Unable to apply rate symmetry constraint: %d\n", ret
);
67 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
68 * then initialized and any private data can be allocated. This also calls
69 * startup for the cpu DAI, platform, machine and codec DAI.
71 static int soc_pcm_open(struct snd_pcm_substream
*substream
)
73 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
74 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
75 struct snd_soc_platform
*platform
= rtd
->platform
;
76 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
77 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
78 struct snd_soc_dai_driver
*cpu_dai_drv
= cpu_dai
->driver
;
79 struct snd_soc_dai_driver
*codec_dai_drv
= codec_dai
->driver
;
82 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
84 /* startup the audio subsystem */
85 if (cpu_dai
->driver
->ops
->startup
) {
86 ret
= cpu_dai
->driver
->ops
->startup(substream
, cpu_dai
);
88 printk(KERN_ERR
"asoc: can't open interface %s\n",
94 if (platform
->driver
->ops
&& platform
->driver
->ops
->open
) {
95 ret
= platform
->driver
->ops
->open(substream
);
97 printk(KERN_ERR
"asoc: can't open platform %s\n", platform
->name
);
102 if (codec_dai
->driver
->ops
->startup
) {
103 ret
= codec_dai
->driver
->ops
->startup(substream
, codec_dai
);
105 printk(KERN_ERR
"asoc: can't open codec %s\n",
111 if (rtd
->dai_link
->ops
&& rtd
->dai_link
->ops
->startup
) {
112 ret
= rtd
->dai_link
->ops
->startup(substream
);
114 printk(KERN_ERR
"asoc: %s startup failed\n", rtd
->dai_link
->name
);
119 /* Check that the codec and cpu DAIs are compatible */
120 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
121 runtime
->hw
.rate_min
=
122 max(codec_dai_drv
->playback
.rate_min
,
123 cpu_dai_drv
->playback
.rate_min
);
124 runtime
->hw
.rate_max
=
125 min(codec_dai_drv
->playback
.rate_max
,
126 cpu_dai_drv
->playback
.rate_max
);
127 runtime
->hw
.channels_min
=
128 max(codec_dai_drv
->playback
.channels_min
,
129 cpu_dai_drv
->playback
.channels_min
);
130 runtime
->hw
.channels_max
=
131 min(codec_dai_drv
->playback
.channels_max
,
132 cpu_dai_drv
->playback
.channels_max
);
133 runtime
->hw
.formats
=
134 codec_dai_drv
->playback
.formats
& cpu_dai_drv
->playback
.formats
;
136 codec_dai_drv
->playback
.rates
& cpu_dai_drv
->playback
.rates
;
137 if (codec_dai_drv
->playback
.rates
138 & (SNDRV_PCM_RATE_KNOT
| SNDRV_PCM_RATE_CONTINUOUS
))
139 runtime
->hw
.rates
|= cpu_dai_drv
->playback
.rates
;
140 if (cpu_dai_drv
->playback
.rates
141 & (SNDRV_PCM_RATE_KNOT
| SNDRV_PCM_RATE_CONTINUOUS
))
142 runtime
->hw
.rates
|= codec_dai_drv
->playback
.rates
;
144 runtime
->hw
.rate_min
=
145 max(codec_dai_drv
->capture
.rate_min
,
146 cpu_dai_drv
->capture
.rate_min
);
147 runtime
->hw
.rate_max
=
148 min(codec_dai_drv
->capture
.rate_max
,
149 cpu_dai_drv
->capture
.rate_max
);
150 runtime
->hw
.channels_min
=
151 max(codec_dai_drv
->capture
.channels_min
,
152 cpu_dai_drv
->capture
.channels_min
);
153 runtime
->hw
.channels_max
=
154 min(codec_dai_drv
->capture
.channels_max
,
155 cpu_dai_drv
->capture
.channels_max
);
156 runtime
->hw
.formats
=
157 codec_dai_drv
->capture
.formats
& cpu_dai_drv
->capture
.formats
;
159 codec_dai_drv
->capture
.rates
& cpu_dai_drv
->capture
.rates
;
160 if (codec_dai_drv
->capture
.rates
161 & (SNDRV_PCM_RATE_KNOT
| SNDRV_PCM_RATE_CONTINUOUS
))
162 runtime
->hw
.rates
|= cpu_dai_drv
->capture
.rates
;
163 if (cpu_dai_drv
->capture
.rates
164 & (SNDRV_PCM_RATE_KNOT
| SNDRV_PCM_RATE_CONTINUOUS
))
165 runtime
->hw
.rates
|= codec_dai_drv
->capture
.rates
;
169 snd_pcm_limit_hw_rates(runtime
);
170 if (!runtime
->hw
.rates
) {
171 printk(KERN_ERR
"asoc: %s <-> %s No matching rates\n",
172 codec_dai
->name
, cpu_dai
->name
);
175 if (!runtime
->hw
.formats
) {
176 printk(KERN_ERR
"asoc: %s <-> %s No matching formats\n",
177 codec_dai
->name
, cpu_dai
->name
);
180 if (!runtime
->hw
.channels_min
|| !runtime
->hw
.channels_max
||
181 runtime
->hw
.channels_min
> runtime
->hw
.channels_max
) {
182 printk(KERN_ERR
"asoc: %s <-> %s No matching channels\n",
183 codec_dai
->name
, cpu_dai
->name
);
187 /* Symmetry only applies if we've already got an active stream. */
188 if (cpu_dai
->active
|| codec_dai
->active
) {
189 ret
= soc_pcm_apply_symmetry(substream
);
194 pr_debug("asoc: %s <-> %s info:\n",
195 codec_dai
->name
, cpu_dai
->name
);
196 pr_debug("asoc: rate mask 0x%x\n", runtime
->hw
.rates
);
197 pr_debug("asoc: min ch %d max ch %d\n", runtime
->hw
.channels_min
,
198 runtime
->hw
.channels_max
);
199 pr_debug("asoc: min rate %d max rate %d\n", runtime
->hw
.rate_min
,
200 runtime
->hw
.rate_max
);
202 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
203 cpu_dai
->playback_active
++;
204 codec_dai
->playback_active
++;
206 cpu_dai
->capture_active
++;
207 codec_dai
->capture_active
++;
211 rtd
->codec
->active
++;
212 mutex_unlock(&rtd
->pcm_mutex
);
216 if (rtd
->dai_link
->ops
&& rtd
->dai_link
->ops
->shutdown
)
217 rtd
->dai_link
->ops
->shutdown(substream
);
220 if (codec_dai
->driver
->ops
->shutdown
)
221 codec_dai
->driver
->ops
->shutdown(substream
, codec_dai
);
224 if (platform
->driver
->ops
&& platform
->driver
->ops
->close
)
225 platform
->driver
->ops
->close(substream
);
228 if (cpu_dai
->driver
->ops
->shutdown
)
229 cpu_dai
->driver
->ops
->shutdown(substream
, cpu_dai
);
231 mutex_unlock(&rtd
->pcm_mutex
);
236 * Power down the audio subsystem pmdown_time msecs after close is called.
237 * This is to ensure there are no pops or clicks in between any music tracks
238 * due to DAPM power cycling.
240 static void close_delayed_work(struct work_struct
*work
)
242 struct snd_soc_pcm_runtime
*rtd
=
243 container_of(work
, struct snd_soc_pcm_runtime
, delayed_work
.work
);
244 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
246 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
248 pr_debug("pop wq checking: %s status: %s waiting: %s\n",
249 codec_dai
->driver
->playback
.stream_name
,
250 codec_dai
->playback_active
? "active" : "inactive",
251 codec_dai
->pop_wait
? "yes" : "no");
253 /* are we waiting on this codec DAI stream */
254 if (codec_dai
->pop_wait
== 1) {
255 codec_dai
->pop_wait
= 0;
256 snd_soc_dapm_stream_event(rtd
,
257 codec_dai
->driver
->playback
.stream_name
,
258 SND_SOC_DAPM_STREAM_STOP
);
261 mutex_unlock(&rtd
->pcm_mutex
);
265 * Called by ALSA when a PCM substream is closed. Private data can be
266 * freed here. The cpu DAI, codec DAI, machine and platform are also
269 static int soc_pcm_close(struct snd_pcm_substream
*substream
)
271 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
272 struct snd_soc_platform
*platform
= rtd
->platform
;
273 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
274 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
275 struct snd_soc_codec
*codec
= rtd
->codec
;
277 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
279 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
280 cpu_dai
->playback_active
--;
281 codec_dai
->playback_active
--;
283 cpu_dai
->capture_active
--;
284 codec_dai
->capture_active
--;
291 if (!cpu_dai
->active
&& !codec_dai
->active
)
294 /* Muting the DAC suppresses artifacts caused during digital
295 * shutdown, for example from stopping clocks.
297 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
298 snd_soc_dai_digital_mute(codec_dai
, 1);
300 if (cpu_dai
->driver
->ops
->shutdown
)
301 cpu_dai
->driver
->ops
->shutdown(substream
, cpu_dai
);
303 if (codec_dai
->driver
->ops
->shutdown
)
304 codec_dai
->driver
->ops
->shutdown(substream
, codec_dai
);
306 if (rtd
->dai_link
->ops
&& rtd
->dai_link
->ops
->shutdown
)
307 rtd
->dai_link
->ops
->shutdown(substream
);
309 if (platform
->driver
->ops
&& platform
->driver
->ops
->close
)
310 platform
->driver
->ops
->close(substream
);
311 cpu_dai
->runtime
= NULL
;
313 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
314 /* start delayed pop wq here for playback streams */
315 codec_dai
->pop_wait
= 1;
316 schedule_delayed_work(&rtd
->delayed_work
,
317 msecs_to_jiffies(rtd
->pmdown_time
));
319 /* capture streams can be powered down now */
320 snd_soc_dapm_stream_event(rtd
,
321 codec_dai
->driver
->capture
.stream_name
,
322 SND_SOC_DAPM_STREAM_STOP
);
325 mutex_unlock(&rtd
->pcm_mutex
);
330 * Called by ALSA when the PCM substream is prepared, can set format, sample
331 * rate, etc. This function is non atomic and can be called multiple times,
332 * it can refer to the runtime info.
334 static int soc_pcm_prepare(struct snd_pcm_substream
*substream
)
336 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
337 struct snd_soc_platform
*platform
= rtd
->platform
;
338 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
339 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
342 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
344 if (rtd
->dai_link
->ops
&& rtd
->dai_link
->ops
->prepare
) {
345 ret
= rtd
->dai_link
->ops
->prepare(substream
);
347 printk(KERN_ERR
"asoc: machine prepare error\n");
352 if (platform
->driver
->ops
&& platform
->driver
->ops
->prepare
) {
353 ret
= platform
->driver
->ops
->prepare(substream
);
355 printk(KERN_ERR
"asoc: platform prepare error\n");
360 if (codec_dai
->driver
->ops
->prepare
) {
361 ret
= codec_dai
->driver
->ops
->prepare(substream
, codec_dai
);
363 printk(KERN_ERR
"asoc: codec DAI prepare error\n");
368 if (cpu_dai
->driver
->ops
->prepare
) {
369 ret
= cpu_dai
->driver
->ops
->prepare(substream
, cpu_dai
);
371 printk(KERN_ERR
"asoc: cpu DAI prepare error\n");
376 /* cancel any delayed stream shutdown that is pending */
377 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
&&
378 codec_dai
->pop_wait
) {
379 codec_dai
->pop_wait
= 0;
380 cancel_delayed_work(&rtd
->delayed_work
);
383 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
384 snd_soc_dapm_stream_event(rtd
,
385 codec_dai
->driver
->playback
.stream_name
,
386 SND_SOC_DAPM_STREAM_START
);
388 snd_soc_dapm_stream_event(rtd
,
389 codec_dai
->driver
->capture
.stream_name
,
390 SND_SOC_DAPM_STREAM_START
);
392 snd_soc_dai_digital_mute(codec_dai
, 0);
395 mutex_unlock(&rtd
->pcm_mutex
);
400 * Called by ALSA when the hardware params are set by application. This
401 * function can also be called multiple times and can allocate buffers
402 * (using snd_pcm_lib_* ). It's non-atomic.
404 static int soc_pcm_hw_params(struct snd_pcm_substream
*substream
,
405 struct snd_pcm_hw_params
*params
)
407 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
408 struct snd_soc_platform
*platform
= rtd
->platform
;
409 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
410 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
413 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
415 if (rtd
->dai_link
->ops
&& rtd
->dai_link
->ops
->hw_params
) {
416 ret
= rtd
->dai_link
->ops
->hw_params(substream
, params
);
418 printk(KERN_ERR
"asoc: machine hw_params failed\n");
423 if (codec_dai
->driver
->ops
->hw_params
) {
424 ret
= codec_dai
->driver
->ops
->hw_params(substream
, params
, codec_dai
);
426 printk(KERN_ERR
"asoc: can't set codec %s hw params\n",
432 if (cpu_dai
->driver
->ops
->hw_params
) {
433 ret
= cpu_dai
->driver
->ops
->hw_params(substream
, params
, cpu_dai
);
435 printk(KERN_ERR
"asoc: interface %s hw params failed\n",
441 if (platform
->driver
->ops
&& platform
->driver
->ops
->hw_params
) {
442 ret
= platform
->driver
->ops
->hw_params(substream
, params
);
444 printk(KERN_ERR
"asoc: platform %s hw params failed\n",
450 rtd
->rate
= params_rate(params
);
453 mutex_unlock(&rtd
->pcm_mutex
);
457 if (cpu_dai
->driver
->ops
->hw_free
)
458 cpu_dai
->driver
->ops
->hw_free(substream
, cpu_dai
);
461 if (codec_dai
->driver
->ops
->hw_free
)
462 codec_dai
->driver
->ops
->hw_free(substream
, codec_dai
);
465 if (rtd
->dai_link
->ops
&& rtd
->dai_link
->ops
->hw_free
)
466 rtd
->dai_link
->ops
->hw_free(substream
);
468 mutex_unlock(&rtd
->pcm_mutex
);
473 * Frees resources allocated by hw_params, can be called multiple times
475 static int soc_pcm_hw_free(struct snd_pcm_substream
*substream
)
477 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
478 struct snd_soc_platform
*platform
= rtd
->platform
;
479 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
480 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
481 struct snd_soc_codec
*codec
= rtd
->codec
;
483 mutex_lock_nested(&rtd
->pcm_mutex
, rtd
->pcm_subclass
);
485 /* apply codec digital mute */
487 snd_soc_dai_digital_mute(codec_dai
, 1);
489 /* free any machine hw params */
490 if (rtd
->dai_link
->ops
&& rtd
->dai_link
->ops
->hw_free
)
491 rtd
->dai_link
->ops
->hw_free(substream
);
493 /* free any DMA resources */
494 if (platform
->driver
->ops
&& platform
->driver
->ops
->hw_free
)
495 platform
->driver
->ops
->hw_free(substream
);
497 /* now free hw params for the DAIs */
498 if (codec_dai
->driver
->ops
->hw_free
)
499 codec_dai
->driver
->ops
->hw_free(substream
, codec_dai
);
501 if (cpu_dai
->driver
->ops
->hw_free
)
502 cpu_dai
->driver
->ops
->hw_free(substream
, cpu_dai
);
504 mutex_unlock(&rtd
->pcm_mutex
);
508 static int soc_pcm_trigger(struct snd_pcm_substream
*substream
, int cmd
)
510 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
511 struct snd_soc_platform
*platform
= rtd
->platform
;
512 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
513 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
516 if (codec_dai
->driver
->ops
->trigger
) {
517 ret
= codec_dai
->driver
->ops
->trigger(substream
, cmd
, codec_dai
);
522 if (platform
->driver
->ops
&& platform
->driver
->ops
->trigger
) {
523 ret
= platform
->driver
->ops
->trigger(substream
, cmd
);
528 if (cpu_dai
->driver
->ops
->trigger
) {
529 ret
= cpu_dai
->driver
->ops
->trigger(substream
, cmd
, cpu_dai
);
537 * soc level wrapper for pointer callback
538 * If cpu_dai, codec_dai, platform driver has the delay callback, than
539 * the runtime->delay will be updated accordingly.
541 static snd_pcm_uframes_t
soc_pcm_pointer(struct snd_pcm_substream
*substream
)
543 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
544 struct snd_soc_platform
*platform
= rtd
->platform
;
545 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
546 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
547 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
548 snd_pcm_uframes_t offset
= 0;
549 snd_pcm_sframes_t delay
= 0;
551 if (platform
->driver
->ops
&& platform
->driver
->ops
->pointer
)
552 offset
= platform
->driver
->ops
->pointer(substream
);
554 if (cpu_dai
->driver
->ops
->delay
)
555 delay
+= cpu_dai
->driver
->ops
->delay(substream
, cpu_dai
);
557 if (codec_dai
->driver
->ops
->delay
)
558 delay
+= codec_dai
->driver
->ops
->delay(substream
, codec_dai
);
560 if (platform
->driver
->delay
)
561 delay
+= platform
->driver
->delay(substream
, codec_dai
);
563 runtime
->delay
= delay
;
568 /* ASoC PCM operations */
569 static struct snd_pcm_ops soc_pcm_ops
= {
570 .open
= soc_pcm_open
,
571 .close
= soc_pcm_close
,
572 .hw_params
= soc_pcm_hw_params
,
573 .hw_free
= soc_pcm_hw_free
,
574 .prepare
= soc_pcm_prepare
,
575 .trigger
= soc_pcm_trigger
,
576 .pointer
= soc_pcm_pointer
,
579 /* create a new pcm */
580 int soc_new_pcm(struct snd_soc_pcm_runtime
*rtd
, int num
)
582 struct snd_soc_codec
*codec
= rtd
->codec
;
583 struct snd_soc_platform
*platform
= rtd
->platform
;
584 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
585 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
588 int ret
= 0, playback
= 0, capture
= 0;
590 /* check client and interface hw capabilities */
591 snprintf(new_name
, sizeof(new_name
), "%s %s-%d",
592 rtd
->dai_link
->stream_name
, codec_dai
->name
, num
);
594 if (codec_dai
->driver
->playback
.channels_min
)
596 if (codec_dai
->driver
->capture
.channels_min
)
599 dev_dbg(rtd
->card
->dev
, "registered pcm #%d %s\n",num
,new_name
);
600 ret
= snd_pcm_new(rtd
->card
->snd_card
, new_name
,
601 num
, playback
, capture
, &pcm
);
603 printk(KERN_ERR
"asoc: can't create pcm for codec %s\n", codec
->name
);
607 /* DAPM dai link stream work */
608 INIT_DELAYED_WORK(&rtd
->delayed_work
, close_delayed_work
);
611 pcm
->private_data
= rtd
;
612 if (platform
->driver
->ops
) {
613 soc_pcm_ops
.mmap
= platform
->driver
->ops
->mmap
;
614 soc_pcm_ops
.pointer
= platform
->driver
->ops
->pointer
;
615 soc_pcm_ops
.ioctl
= platform
->driver
->ops
->ioctl
;
616 soc_pcm_ops
.copy
= platform
->driver
->ops
->copy
;
617 soc_pcm_ops
.silence
= platform
->driver
->ops
->silence
;
618 soc_pcm_ops
.ack
= platform
->driver
->ops
->ack
;
619 soc_pcm_ops
.page
= platform
->driver
->ops
->page
;
623 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_PLAYBACK
, &soc_pcm_ops
);
626 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_CAPTURE
, &soc_pcm_ops
);
628 if (platform
->driver
->pcm_new
) {
629 ret
= platform
->driver
->pcm_new(rtd
);
631 pr_err("asoc: platform pcm constructor failed\n");
636 pcm
->private_free
= platform
->driver
->pcm_free
;
637 printk(KERN_INFO
"asoc: %s <-> %s mapping ok\n", codec_dai
->name
,