基于i.MX6X的音频驱动分析(二)音频驱动的流程,平台数据,内核配置与测试
音频驱动的打开流程
ALSA音频驱动执行以下设备打开流程:
- 分配一个空闲的操作子流
- 打开低层硬件设备
- 提供硬件能力给ALSA runtime信息(包括硬件,DMA,软件支持能力)
- 配置读写DMA通道
- 配置CPU DAI和Codec DAI接口
- 配置Codec硬件
- 触发传输。
音频传输触发后,接下来的DMA读写操作则由DMA的中断 Callback函数操作。
音频驱动平台数据
文件 include/linux/fsl_devices.h定义了数据结构mxc_audio_platform_data,表示音频驱动的平台数据结构,其中成员需要根据具体硬件设计配置,参考wm8960的设置:
static struct mxc_audio_platform_data wm8960_data = {
.ssi_num = 1,//表示使用的SSI通道数目
.src_port = 2,//表示连接到SSI上的Audmux接口号
.ext_port = 3,//连接到外部pin的audmux接口号
.hp_gpio = SABRESD_HEADPHONE_DET,////耳机检查所用的GPIO
.hp_active_low = 0,////当耳机插入时,检查用的GPIO的电平状态,如果为低,则这个值是1
/*.mic_gpio = SABRESD_MICROPHONE_DET,*/
.mic_gpio = -1,//麦克风检查所用的GPIO
.mic_active_low = 1,//当麦克风插入时,检查用的GPIO的电平状态,如果为低,则这个值是1
.init = mxc_wm8960_init, //初始化音频codec时的callback函数,一般用于配置音频codec的时钟
.clock_enable = wm8960_clk_enable,//打开,关闭音频时钟的callback函数。
};
连接到SSI上的Audmux接口号,参考i.MX6XRM的Audmux,一般Port 1,2,7连接到内部的SSI上,3,4,5,6连接到外部的pin上。
mxc_wm8960_init函数如下 :
static int mxc_wm8960_init(void)
{
wm8960_data.sysclk = wm8960_clk_rate;
gpio_request(SABRESD_CODEC_PWR_EN, "aud_4v2");
gpio_direction_output(SABRESD_CODEC_PWR_EN, 1);
msleep(1);
gpio_set_value(SABRESD_CODEC_PWR_EN, 1);
return 0;
}
主要WM8960的主时钟是由i.MX6X的CLKO输出24M给WM8960,然后WM8960做主,i.MX6X做从的。原理图如下:
音频驱动内核配置
WM8962的音频内核menuconfig配置为:
Device drivers >
Sound card support >
Advanced Linux Sound Architecture >
ALSA for SoC audio support >
SoC Audio for the NXP i.MX CPU, SoC Audio support for WM8960
其它codec的内核配置类似