在2.6.38之后,内核声卡驱动基本都变成Asoc模型。关于Asoc模型的话,内核文档里面进行了详细的说明,也有一些高手写了博文(http://blog.csdn.net/droidphone/article/details/7231605)。这段时间认真看了一下Asoc模型,然后找了一个3.3.4的内核版本在研究。把自己的一点点体会写在这里(内核版本:3.3.4)
首先是关于移植的,也就是在BSP板级文件中构建自己所需要的几个结构体。
由于Asoc进行了改进,它分为三个部分:machine、codec、platform。比如XC2440这个machine里面有s3c2440相关的platform连接的uda1341这个codec,而且platform和codec内核驱动都是跨平台的,machine当然一般不同。
machine文件的名字一般是platform_codec这样的形式,它主要用来连接platform和codec,缺少了它的platform和codec是工作不了的。比如我们的XC2440的话 ,它的这个machine文件就是s3c24xx_uda134x.c,这个文件是我们需要的,是以platform_driver的形式构建的。我们继续看里面的内容,里面有一个非常重要的结构体。
点击(此处)折叠或打开
- struct snd_soc_dai_link {
- /* config - must be set by machine driver */
- const char *name; /* Codec name */
- const char *stream_name; /* Stream name */
- const char *codec_name; /* for multi-codec */
- const struct device_node *codec_of_node;
- const char *platform_name; /* for multi-platform */
- const struct device_node *platform_of_node;
- const char *cpu_dai_name;
- const struct device_node *cpu_dai_of_node;
- const char *codec_dai_name;
- unsigned int dai_fmt; /* format to set on init */
- /* Keep DAI active over suspend */
- unsigned int ignore_suspend:1;
- /* Symmetry requirements */
- unsigned int symmetric_rates:1;
- /* pmdown_time is ignored at stop */
- unsigned int ignore_pmdown_time:1;
- /* codec/machine specific init - e.g. add machine controls */
- int (*init)(struct snd_soc_pcm_runtime *rtd);
- /* machine stream operations */
- struct snd_soc_ops *ops;
- };
这个结构体就是我们machine用来绑定plarform和codec的结构体。在s3c24xx_uda134x.c文件里面的定义如下:
点击(此处)折叠或打开
- static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
- .name = "UDA134X",
- .stream_name = "UDA134X",
- .codec_name = "uda134x-codec",
- .codec_dai_name = "uda134x-hifi",
- .cpu_dai_name = "s3c24xx-iis",
- .ops = &s3c24xx_uda134x_ops,
- .platform_name = "samsung-audio",
- };
对应上面的解释,这里我们要用到的就是codec_name ,cpu_dai_name,platform_name这三个。其他第一个就是codec的名字,由于经过一个链表匹配,我们就知道了uda134x.c这个文件是我们需要的。同样的道理,S3c24xx-i2s.c 和 dma.c这两个文件也是我们需要的。如果不了解匹配的过程,也可以通过搜索来找到这三个文件,因为这三个文件都是通过platform_driver的形式来构造的,如果与它的名字匹配的话,那么这个文件就是我们需要的。
经过上面的过程之后,我们就可以开始在我们的BSP板级文件中构建我们的platform_device了,其中有两个是内核已经帮我们弄好了的,我们只需要加入数组中即可。其他两个就自己定义即可。
点击(此处)折叠或打开
- &s3c_device_iis,
- &uda1340_codec,
- &xc2440_audio,
- &samsung_asoc_dma,
在我们的BSP的platform_device数组中加入上面四个文件,其中第一个和最后一个是内核构建好了的,最开始三星的demo板BSP的mach-smdk2440.c中也只加入了这两个。中间两个需要自己构建。
点击(此处)折叠或打开
- static struct platform_device uda1340_codec = {
- .name = "uda134x-codec",
- .id = -1,
- };
点击(此处)折叠或打开
- /* AUDIO */
- static struct s3c24xx_uda134x_platform_data xc2440_audio_pins = {
- .l3_clk = S3C2410_GPB(4),
- .l3_mode = S3C2410_GPB(2),
- .l3_data = S3C2410_GPB(3),
- .model = UDA134X_UDA1341
- };
- static struct platform_device xc2440_audio = {
- .name = "s3c24xx_uda134x",
- .id = 0,
- .dev = {
- .platform_data = &xc2440_audio_pins,
- },
- };
经过以上步骤,就可以配置和编译了。
同样我们再看一下machine文件smdk_wm9713.c ,这个文件是三星平台wm9713,wm9714的machine文件。我们同样看下面匹配绑定的结构体。
点击(此处)折叠或打开
- static struct snd_soc_dai_link smdk_dai = {
- .name = "AC97",
- .stream_name = "AC97 PCM",
- .platform_name = "samsung-audio",
- .cpu_dai_name = "samsung-ac97",
- .codec_dai_name = "wm9713-hifi",
- .codec_name = "wm9713-codec",
- };