1 /*
2 * Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
3 *
4 * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
5 * the the people's Republic of China and other countries.
6 * All Allwinner Technology Co.,Ltd. trademarks are used with permission.
7 *
8 * DISCLAIMER
9 * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
10 * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
11 * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
12 * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
13 * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
14 * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
15 * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
19 * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
20 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
21 * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
22 * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 #ifndef __SOUND_CORE_H
33 #define __SOUND_CORE_H
34 #include <stdint.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <errno.h>
38 #include <hal_sem.h>
39 #include <hal_mutex.h>
40 #include <interrupt.h>
41 #include <hal_cache.h>
42 #include <sunxi_hal_common.h>
43 #include "aw_list.h"
44 #include "pcm_common.h"
45 #include "hal_atomic.h"
46 #include "hal_interrupt.h"
47 //#define SNDRV_DEBUG
48
49 #define SND_CORE_VERSION "V1.4.0"
50
51 typedef unsigned int hal_irq_state_t;
52
53 #define hal_local_irq_enable() hal_interrupt_enable()
54 #define hal_local_irq_disable() hal_interrupt_disable()
55 #define hal_local_irq_save(flags) \
56 do { \
57 flags = hal_interrupt_save(); \
58 } while (0)
59 #define hal_local_irq_restore(flags) \
60 do { \
61 hal_interrupt_restore(flags); \
62 } while (0)
63
64 typedef void* __iomem;
65 typedef __iomem dma_addr_t;
66
67 struct snd_dai;
68 struct snd_pcm_substream;
69 struct snd_pcm_hw_params;
70 struct snd_pcm_runtime;
71 struct snd_pcm;
72
73 typedef hal_mutex_t snd_mutex_t;
74 snd_mutex_t snd_mutex_init(void);
75 int snd_mutex_lock_timeout(snd_mutex_t mutex, long ms);
76 int snd_mutex_lock(snd_mutex_t mutex);
77 void snd_mutex_unlock(snd_mutex_t mutex);
78 void snd_mutex_destroy(snd_mutex_t mutex);
79
80 typedef struct {
81 hal_sem_t sem;
82 int waiting;
83 } *snd_schd_t;
84 snd_schd_t snd_schd_init(void);
85 int snd_schd_timeout(snd_schd_t schd, long ms);
86 void snd_schd_wakeup(snd_schd_t schd);
87 void snd_schd_destroy(snd_schd_t schd);
88
89 void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream);
90 void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream);
91
92 hal_irq_state_t _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream);
93 void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
94 unsigned long flags);
95
96 #define snd_pcm_stream_lock_irqsave(substream, flags) \
97 do { \
98 flags = _snd_pcm_stream_lock_irqsave(substream); \
99 } while (0)
100
101 #define snd_readb(reg) (*(volatile uint8_t *)(reg))
102 #define snd_readw(reg) (*(volatile uint16_t *)(reg))
103 #define snd_readl(reg) (*(volatile uint32_t *)(reg))
104 #define snd_writeb(value,reg) (*(volatile uint8_t *)(reg) = (value))
105 #define snd_writew(value,reg) (*(volatile uint16_t *)(reg) = (value))
106 #define snd_writel(value,reg) (*(volatile uint32_t *)(reg) = (value))
107
108 #define snd_malloc(size) calloc(1, size)
109 #define snd_strdup(ptr) strdup(ptr)
110 #define snd_free(ptr) free((void *)ptr)
111
112
113 #define SNDRV_LOG_COLOR_NONE "\e[0m"
114 #define SNDRV_LOG_COLOR_RED "\e[31m"
115 #define SNDRV_LOG_COLOR_GREEN "\e[32m"
116 #define SNDRV_LOG_COLOR_YELLOW "\e[33m"
117 #define SNDRV_LOG_COLOR_BLUE "\e[34m"
118
119 #ifdef SNDRV_DEBUG
120 #define snd_print(fmt, args...) \
121 printf(SNDRV_LOG_COLOR_GREEN "[SND_DEBUG][%s:%d]" fmt \
122 SNDRV_LOG_COLOR_NONE, __FUNCTION__, __LINE__, ##args)
123 #else
124 #define snd_print(fmt, args...)
125 #endif
126
127 #if 0
128 #define snd_info(fmt, args...) \
129 printf(SNDRV_LOG_COLOR_BLUE "[SND_INFO][%s:%d]" fmt \
130 SNDRV_LOG_COLOR_NONE, __FUNCTION__, __LINE__, ##args)
131 #else
132 #define snd_info(fmt, args...)
133 #endif
134
135 #define snd_err(fmt, args...) \
136 printf(SNDRV_LOG_COLOR_RED "[SND_ERR][%s:%d]" fmt \
137 SNDRV_LOG_COLOR_NONE, __FUNCTION__, __LINE__, ##args)
138 #if 0
139 #define snd_lock_debug(fmt, args...) \
140 printf(SNDRV_LOG_COLOR_RED "[SND_LOCK_DEBUG][%s:%u]" fmt \
141 SNDRV_LOG_COLOR_NONE, __FUNCTION__, __LINE__, ##args)
142 #else
143 #define snd_lock_debug(fmt, args...)
144 #endif
145
146 typedef int snd_ctl_elem_type_t;
147 #define SND_CTL_ELEM_TYPE_INTEGER ((snd_ctl_elem_type_t)0)
148 #define SND_CTL_ELEM_TYPE_ENUMERATED ((snd_ctl_elem_type_t)1)
149 #define SND_CTL_ELEM_TYPE_LAST SND_CTL_ELEM_TYPE_ENUMERATE
150
151 #define SND_CTL_ENUM_AUTO_MASK (0)
152
153 #define SND_CTL_KCONTROL(xname, xreg, xshift, xmax) \
154 { \
155 .type = SND_CTL_ELEM_TYPE_INTEGER, \
156 .name = xname, \
157 .reg = xreg, \
158 .shift = xshift, \
159 .max = xmax, \
160 .min = 0, \
161 .get = NULL, \
162 .set = NULL, \
163 .count = 1, \
164 }
165
166 #define SND_CTL_KCONTROL_EXT(xname, xmax, xmin, xget, xset) \
167 { \
168 .type = SND_CTL_ELEM_TYPE_INTEGER, \
169 .name = xname, \
170 .reg = 0, \
171 .shift = 0, \
172 .max = xmax, \
173 .min = xmin, \
174 .get = xget, \
175 .set = xset, \
176 .count = 1, \
177 }
178
179 #define SND_CTL_KCONTROL_EXT_REG(xname, xreg, xshift, xmax, xget, xset) \
180 { \
181 .type = SND_CTL_ELEM_TYPE_INTEGER, \
182 .name = xname, \
183 .reg = xreg, \
184 .shift = xshift, \
185 .max = xmax, \
186 .min = 0, \
187 .get = xget, \
188 .set = xset, \
189 .count = 1, \
190 }
191
192 #define SND_CTL_KCONTROL_VALUE_EXT(xname, xreg, xshift, xmax, xmin, xget, xset) \
193 { \
194 .type = SND_CTL_ELEM_TYPE_INTEGER, \
195 .name = xname, \
196 .reg = xreg, \
197 .shift = xshift, \
198 .max = xmax, \
199 .min = xmin, \
200 .get = xget, \
201 .set = xset, \
202 .count = 1, \
203 }
204
205 #define SND_CTL_KCONTROL_USER(xname, xmax, xmin, xcur) \
206 { \
207 .type = SND_CTL_ELEM_TYPE_INTEGER, \
208 .name = xname, \
209 .max = xmax, \
210 .min = xmin, \
211 .reg = xcur, \
212 .get = NULL, \
213 .set = NULL, \
214 .count = 1, \
215 .private_data_type = SND_MODULE_USER, \
216 }
217
218 #define SND_CTL_ENUM(xname, xitems, xtexts, xreg, xshift) \
219 { \
220 .type = SND_CTL_ELEM_TYPE_ENUMERATED, \
221 .name = xname,\
222 .items = xitems, \
223 .texts = xtexts, \
224 .reg = xreg, \
225 .shift = xshift, \
226 .mask = SND_CTL_ENUM_AUTO_MASK, \
227 .get = NULL, \
228 .set = NULL, \
229 .count = 1, \
230 }
231
232 #define SND_CTL_ENUM_EXT(xname, xitems, xtexts, xmask, xget, xset) \
233 { \
234 .type = SND_CTL_ELEM_TYPE_ENUMERATED, \
235 .name = xname,\
236 .items = xitems, \
237 .texts = xtexts, \
238 .mask = xmask, \
239 .get = xget, \
240 .set = xset, \
241 .count = 1, \
242 }
243
244 #define SND_CTL_ENUM_VALUE_EXT(xname, xitems, xtexts, xreg, xshift, xmask, xget, xset) \
245 { \
246 .type = SND_CTL_ELEM_TYPE_ENUMERATED, \
247 .name = xname,\
248 .items = xitems, \
249 .texts = xtexts, \
250 .reg = xreg, \
251 .shift = xshift, \
252 .mask = xmask, \
253 .get = xget, \
254 .set = xset, \
255 .count = 1, \
256 }
257
258 enum snd_platform_type {
259 SND_PLATFORM_TYPE_CPUDAI = 0,
260 SND_PLATFORM_TYPE_INTERNAL_I2S,
261 SND_PLATFORM_TYPE_DAUDIO0 = 5,
262 SND_PLATFORM_TYPE_DAUDIO1,
263 SND_PLATFORM_TYPE_DAUDIO2,
264 SND_PLATFORM_TYPE_DAUDIO3,
265 SND_PLATFORM_TYPE_DAUDIO_MAX,
266 SND_PLATFORM_TYPE_DMIC = 10,
267 SND_PLATFORM_TYPE_SPDIF = 12,
268 SND_PLATFORM_TYPE_MAX,
269 };
270
271 enum snd_module_type {
272 SND_MODULE_UNKNOWN = 0,
273 SND_MODULE_CODEC,
274 SND_MODULE_PLATFORM,
275 SND_MODULE_USER,
276 };
277
278 enum {
279 SNDRV_PCM_STREAM_PLAYBACK = 0,
280 SNDRV_PCM_STREAM_CAPTURE,
281 SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE,
282 };
283
284 enum snd_device_type {
285 SNDRV_DEV_CONTROL,
286 SNDRV_DEV_PCM,
287 SNDRV_DEV_TIMER,
288 };
289
290 struct sunxi_dma_params {
291 char *name;
292 dma_addr_t dma_addr;
293 uint32_t src_maxburst;
294 uint32_t dst_maxburst;
295 uint8_t dma_drq_type_num;
296 };
297
298 struct snd_dma_buffer {
299 dma_addr_t addr;
300 size_t bytes;
301 };
302
303 struct snd_pcm_ops {
304 int (*open)(struct snd_pcm_substream *substream);
305 int (*close)(struct snd_pcm_substream *substream);
306 int (*ioctl)(struct snd_pcm_substream * substream,
307 unsigned int cmd, void *arg);
308 int (*hw_params)(struct snd_pcm_substream *substream,
309 struct snd_pcm_hw_params *params);
310 int (*hw_free)(struct snd_pcm_substream *substream);
311 int (*prepare)(struct snd_pcm_substream *substream);
312 int (*trigger)(struct snd_pcm_substream *substream, int cmd);
313 snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *substream);
314 int (*copy)(struct snd_pcm_substream *substream, int channel,
315 snd_pcm_uframes_t pos,
316 void *buf, snd_pcm_uframes_t count);
317 };
318
319 struct snd_dai_ops {
320 int (*set_sysclk)(struct snd_dai *dai,
321 int clk_id, unsigned int freq, int dir);
322 int (*set_clkdiv)(struct snd_dai *dai, int div_id, int div);
323 int (*set_pll)(struct snd_dai *dai, int pll_id, int source,
324 unsigned int freq_in, unsigned int freq_out);
325 int (*set_fmt)(struct snd_dai *dai, unsigned int fmt);
326 int (*startup)(struct snd_pcm_substream *,
327 struct snd_dai *);
328 void (*shutdown)(struct snd_pcm_substream *,
329 struct snd_dai *);
330 int (*hw_params)(struct snd_pcm_substream *,
331 struct snd_pcm_hw_params *, struct snd_dai *);
332 int (*hw_free)(struct snd_pcm_substream *,
333 struct snd_dai *);
334 int (*prepare)(struct snd_pcm_substream *,
335 struct snd_dai *);
336 int (*trigger)(struct snd_pcm_substream *, int,
337 struct snd_dai *);
338 int (*dapm_control)(struct snd_pcm_substream *,
339 struct snd_dai *, int onoff);
340 };
341
342 struct snd_pcm_hardware {
343 uint32_t info;
344 uint32_t formats;
345 uint32_t rates;
346 uint32_t rate_min;
347 uint32_t rate_max;
348 uint32_t channels_min;
349 uint32_t channels_max;
350 uint32_t buffer_bytes_max;
351 uint32_t period_bytes_min;
352 uint32_t period_bytes_max;
353 uint32_t periods_min;
354 uint32_t periods_max;
355 };
356
357 struct snd_pcm_hw_constrains {
358 union snd_interval intervals[SND_PCM_HW_PARAM_LAST_INTERVAL - SND_PCM_HW_PARAM_FIRST_INTERVAL + 1];
359 unsigned int rules_num;
360 unsigned int rules_all;
361 struct snd_pcm_hw_rule *rules;
362 };
363
constrs_interval(struct snd_pcm_hw_constrains * constrs,snd_pcm_hw_param_t var)364 static inline snd_interval_t *constrs_interval(struct snd_pcm_hw_constrains *constrs,
365 snd_pcm_hw_param_t var)
366 {
367 return &constrs->intervals[var - SND_PCM_HW_PARAM_FIRST_INTERVAL];
368 }
369
370 struct snd_pcm_stream {
371 const char *stream_name;
372 uint64_t formats;
373 uint32_t rates;
374 uint32_t rate_min;
375 uint32_t rate_max;
376 uint32_t channels_min;
377 uint32_t channels_max;
378 };
379
380 struct snd_dai {
381 const char *name;
382 uint32_t id;
383 struct snd_pcm_stream playback;
384 struct snd_pcm_stream capture;
385 const struct snd_dai_ops *ops;
386 void *playback_dma_data;
387 void *capture_dma_data;
388 int (*probe)(struct snd_dai *dai);
389 int (*remove)(struct snd_dai *dai);
390 void *component;
391 };
392
393 typedef struct snd_codec {
394 const char *name;
395 struct snd_dai *codec_dai;
396 uint32_t codec_dai_num;
397 int (*probe)(struct snd_codec *);
398 int (*remove)(struct snd_codec *);
399 void *private_data;
400 void *codec_base_addr;
401 bool playback_only;
402 bool capture_only;
403 struct snd_pcm_hardware *hw;
404 unsigned int (*read)(struct snd_codec *, unsigned int);
405 unsigned int (*write)(struct snd_codec *, unsigned int, unsigned int);
406 struct snd_kcontrol *controls;
407 unsigned int num_controls;
408 } snd_codec_t;
409
410 struct snd_platform {
411 char *name;
412 int type;
413 int (*probe)(struct snd_platform *);
414 int (*remove)(struct snd_platform *);
415 int (*pcm_new)(struct snd_pcm *);
416 void (*pcm_free)(struct snd_pcm *);
417 const struct snd_pcm_ops *ops;
418 struct snd_dai *cpu_dai;
419 void *private_data;
420 void *mem_base;
421 struct snd_kcontrol *controls;
422 unsigned int num_controls;
423 struct snd_pcm_hardware *pcm_hw;
424 };
425
426
427 struct snd_pcm_runtime {
428 snd_pcm_uframes_t hw_ptr_base;
429 snd_pcm_access_t access;
430 snd_pcm_format_t format;
431 unsigned int rate;
432 unsigned int channels;
433 unsigned int can_paused;
434 snd_pcm_uframes_t period_size;
435 unsigned int periods;
436 snd_pcm_uframes_t buffer_size;
437 snd_pcm_uframes_t min_align; /* Min alignment for the format, frame align */
438 unsigned int frame_bits;
439 unsigned int sample_bits;
440 unsigned int no_period_wakeup: 1;
441
442 dma_addr_t dma_addr;
443 size_t dma_bytes;
444
445 struct snd_dma_buffer *dma_buffer_p;
446
447 /* private section */
448 void *private_data;
449
450 struct snd_pcm_mmap_status *status;
451 struct snd_pcm_mmap_control *control;
452
453 /* HW constrains */
454 struct snd_pcm_hardware hw;
455 struct snd_pcm_hw_constrains hw_constrains;
456
457 /* Other params */
458 snd_pcm_uframes_t start_threshold;
459 snd_pcm_uframes_t stop_threshold;
460 snd_pcm_uframes_t silence_size;
461
462 snd_pcm_uframes_t silence_start;
463 snd_pcm_uframes_t silence_filled;
464
465 snd_pcm_uframes_t boundary;
466
467 /* locking / scheduling */
468 snd_pcm_uframes_t twake;
469 snd_schd_t tsleep; /* transfer sleep */
470 snd_schd_t sleep; /* poll sleep (drain...) */
471 snd_schd_t dsleep; /* direct access sleep */
472
473 snd_schd_t dsleep_list[32];
474
475 unsigned int xrun_cnt;
476
477 snd_mutex_t pcm_mutex;
478 };
479
480 struct snd_ctl_info {
481 unsigned int id;
482 snd_ctl_elem_type_t type;
483 const unsigned char *name;
484 unsigned long value;
485 int min,max;
486 int count;
487 /* for enum */
488 unsigned int items;
489 const char * const *texts;
490
491 unsigned long *private_data;
492 };
493
494 typedef int (snd_kcontrol_get_t) (struct snd_kcontrol *, struct snd_ctl_info *);
495 typedef int (snd_kcontrol_set_t) (struct snd_kcontrol *, unsigned long);
496
497 struct snd_kcontrol {
498 unsigned int id;
499 snd_ctl_elem_type_t type;
500 const unsigned char *name;
501 int reg;
502 unsigned int shift;
503 int min,max;
504 int mask;
505 int count;
506 /* for enum */
507 unsigned int items;
508 const char * const *texts;
509 unsigned long value;
510
511 snd_kcontrol_get_t *get;
512 snd_kcontrol_set_t *set;
513 struct list_head list;
514 int dynamic;
515 void *private_data;
516 int private_data_type;
517 };
518
519 struct snd_ctl {
520 struct snd_card *card;
521 char id[64];
522 struct list_head controls;
523 int controls_num;
524 snd_mutex_t ctl_mutex;
525 };
526
527 typedef struct snd_pcm_substream {
528 struct snd_pcm *pcm;
529 char name[48];
530 int stream;
531 struct snd_pcm_runtime *runtime;
532 struct snd_pcm_ops *ops;
533 struct snd_dma_buffer dma_buffer;
534 hal_spinlock_t lock;
535 int ref_count;
536 int dapm_state;
537 int hw_opened;
538 } snd_pcm_substream_t;
539
540 struct snd_pcm {
541 struct snd_card *card;
542 char name[48];
543 char id[32];
544 int num;
545 struct snd_pcm_substream *streams[2];
546 struct list_head list;
547 enum snd_device_type type;
548 void (*private_free) (struct snd_pcm *pcm);
549 snd_mutex_t open_mutex;
550 };
551
552 struct snd_card {
553 char *name;
554 int num;
555 struct snd_codec *codec;
556 struct snd_platform *platform;
557 struct list_head devices;
558 struct list_head list;
559 struct snd_ctl *ctl;
560 };
561
562 void snd_core_version(void);
563 int snd_card_register(const char *name,
564 struct snd_codec *codec,
565 int platform_type);
566 int snd_card_unregister_all(void);
567
snd_soc_dai_get_component(struct snd_dai * dai)568 static inline void *snd_soc_dai_get_component(struct snd_dai *dai)
569 {
570 return dai->component;
571 }
572
snd_soc_get_codec_dai(struct snd_pcm_substream * substream)573 static inline struct snd_dai *snd_soc_get_codec_dai(struct snd_pcm_substream *substream)
574 {
575 struct snd_codec *codec;
576 if (!substream || !substream->pcm || !substream->pcm->card)
577 return NULL;
578 codec = substream->pcm->card->codec;
579 if (!codec)
580 return NULL;
581 return codec->codec_dai;
582 }
583
snd_soc_get_cpu_dai(struct snd_pcm_substream * substream)584 static inline struct snd_dai *snd_soc_get_cpu_dai(struct snd_pcm_substream *substream)
585 {
586 struct snd_platform *platform;
587 if (!substream || !substream->pcm || !substream->pcm->card)
588 return NULL;
589 platform = substream->pcm->card->platform;
590 if (!platform)
591 return NULL;
592 return platform->cpu_dai;
593 }
594
snd_pcm_set_runtime_buffer(struct snd_pcm_substream * substream,struct snd_dma_buffer * bufp)595 static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream,
596 struct snd_dma_buffer *bufp)
597 {
598 struct snd_pcm_runtime *runtime = substream->runtime;
599
600 if (bufp) {
601 runtime->dma_buffer_p = bufp;
602 runtime->dma_addr = bufp->addr;
603 runtime->dma_bytes = bufp->bytes;
604 } else {
605 runtime->dma_buffer_p = NULL;
606 runtime->dma_addr = 0;
607 runtime->dma_bytes = 0;
608 }
609 }
610
611 int snd_ctl_add_elem(struct snd_ctl *ctl, struct snd_ctl_info *info);
612 int snd_ctl_remove_elem(struct snd_ctl *ctl, struct snd_kcontrol *control);
613 struct snd_card *snd_card_find_by_name(const char *name);
614 struct snd_card *snd_card_find_by_num(int num);
615 int snd_card_get_number(void);
616 struct snd_pcm *snd_card_find_pcm(struct snd_card *card, int device_num);
617 void snd_set_runtime_hwparams(struct snd_pcm_substream *substream,
618 const struct snd_pcm_hardware *hw);
619 void snd_kcontrol_to_snd_ctl_info(struct snd_kcontrol *kcontrol,
620 struct snd_ctl_info *info, unsigned long value);
621 int snd_soc_dai_set_fmt(struct snd_dai *dai, unsigned int fmt);
622 /* card list */
623 void snd_card_list(void);
624 int sunxi_soundcard_init(void);
625
626 #endif /* __SOUND_CORE_H */
627