日期:2014-05-16  浏览次数:20732 次

我对linux理解之alsa一
我们以imx51为平台,去分析alsa的架构。
有两个文件跟平台具体相关的:
一个是跟cpu的音频接口相关的:sound/soc/imx/imx-3stack-wm8994.c;
另一个是跟codec芯片有关的:sound/soc/codecs/wm8994.c
我们先看imx-3stack-wm8994.c中的初始化:
static int __init imx_3stack_init(void)
{
    int ret;

    ret = platform_driver_register(&imx_3stack_wm8994_audio_driver);//注册audio接口驱动
    if (ret)
        return -ENOMEM;

    imx_3stack_snd_device = platform_device_alloc("soc-audio", 2);//名字是soc-audio
    if (!imx_3stack_snd_device)
        return -ENOMEM;
    platform_set_drvdata(imx_3stack_snd_device, &imx_3stack_snd_devdata);//设置data
    imx_3stack_snd_devdata.dev = &imx_3stack_snd_device->dev;
    ret = platform_device_add(imx_3stack_snd_device);//将与soc_core中的platform匹配
    if (ret)
        platform_device_put(imx_3stack_snd_device);

    return ret;
}

这里面主要有两个工作:
1,platform_driver_register(&imx_3stack_wm8994_audio_driver);//注册audio接口驱动
2,platform_device_add(imx_3stack_snd_device);//将与soc_core中的platform匹配

我们先分析第一个工作,platform_driver_register(&imx_3stack_wm8994_audio_driver):
imx_3stack_wm8994_audio_driver定义:
static struct platform_driver imx_3stack_wm8994_audio_driver = {
    .probe = imx_3stack_wm8994_probe,
    .remove = imx_3stack_wm8994_remove,
    .driver = {
           .name = "imx-3stack-wm8994",
           },
};
对应它的device:
static struct platform_device mxc_wm8994_device = {
    .name = "imx-3stack-wm8994",
};
mxc_register_device(&mxc_wm8994_device, &wm8994_data);//设置了mxc_wm8994_device的data了
wm8994_data定义:
static struct mxc_audio_platform_data wm8994_data = {
    .ssi_num = 1,
    .src_port = 2,
    .ext_port = 4,
    .hp_irq = IOMUX_TO_IRQ_V3(F101_HEADSET_DET),
    .vdda_reg = "VGEN3",
    .vddd_reg = "VIOHI",
    .vdda = 1800000,
    .vddd = 2775000,
    .sysclk =24000000,
    .hp_status = wm8994_headset_det_status,
    .amp_enable = mxc_wm8994_amp_enable,
    .init = mxc_wm8994_plat_init,
    .finit = mxc_wm8994_plat_finit,
};
这样我们确认系统中device跟imx_3stack_wm8994_audio_driver对应,那下面会执行probe函数:
imx_3stack_wm8994_probe:
static int __devinit imx_3stack_wm8994_probe(struct platform_device *pdev)
{
    struct mxc_audio_platform_data *plat = pdev->dev.platform_data;
    struct imx_3stack_priv *priv = &card_priv;
    struct snd_soc_dai *wm8994_cpu_dai;
    int ret = 0;

    priv->pdev = pdev;

    imx_3stack_init_dam(plat->src_port, plat->ext_port);//初始化ssi和dai口子

    if (plat->src_port == 2)//由wm8994_data定义知道src_port=2
        wm8994_cpu_dai = imx_ssi_dai[2];
    else
        wm8994_cpu_dai = imx_ssi_dai[0];

    imx_3stack_dai.cpu_dai = wm8994_cpu_dai;//设定cpu的音频接口
    ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone);//创建耳机的属性文件
    if (ret < 0) {
        pr_err("%s:failed to create driver_attr_headphone\n", __func__);
        goto sysfs_err;
    }
    if (plat->init && plat->init())//如果plat的init定义,则执行
      &nbs