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