教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 精品文档 > 实用模板 >

ALSA声卡驱动详解(14)

来源:网络收集 时间:2026-07-01
导读: static int wm8993_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { ...... ret = snd_soc_register_codec(soc_codec_dev_wm8993, ...... } 这回使得ASoc把codec的dai注册到系统中,并把这些

static int wm8993_i2c_probe(struct i2c_client *i2c,

const struct i2c_device_id *id) {

......

ret = snd_soc_register_codec(&i2c->dev,

&soc_codec_dev_wm8993, &wm8993_dai, 1); ...... }

这回使得ASoc把codec的dai注册到系统中,并把这些dai都挂在全局链表变量dai_list中,然后,在codec被machine驱动匹配后,soc_probe_codec函数会被调用,他会通过全局链表变量dai_list查找所有属于该codec的dai,调用

snd_soc_dapm_new_dai_widgets函数来生成该dai的播放流widget和录音流widget:

[cpp] view plaincopy

static int soc_probe_codec(struct snd_soc_card *card, struct snd_soc_codec *codec) {

......

/* Create DAPM widgets for each DAI stream */ list_for_each_entry(dai, &dai_list, list) { if (dai->dev != codec->dev) continue;

snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); }

...... }

我们看看snd_soc_dapm_new_dai_widgets的代码: [cpp] view plaincopy

int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,

struct snd_soc_dai *dai) {

struct snd_soc_dapm_widget template; struct snd_soc_dapm_widget *w;

WARN_ON(dapm->dev != dai->dev);

memset(&template, 0, sizeof(template)); template.reg = SND_SOC_NOPM;

// 创建播放 dai widget if (dai->driver->playback.stream_name) { template.id = snd_soc_dapm_dai_in;

36

template.name = dai->driver->playback.stream_name;

template.sname = dai->driver->playback.stream_name;

w = snd_soc_dapm_new_control(dapm, &template);

w->priv = dai;

dai->playback_widget = w; }

// 创建录音 dai widget

if (dai->driver->capture.stream_name) {

template.id = snd_soc_dapm_dai_out; template.name = dai->driver->capture.stream_name;

template.sname = dai->driver->capture.stream_name;

w = snd_soc_dapm_new_control(dapm, &template);

w->priv = dai;

dai->capture_widget = w; }

return 0; }

分别为Playback和Capture创建了一个widget,widget的priv字段指向了该dai,这样通过widget就可以找到相应的dai,并且widget的名字就是snd_soc_dai_driver结构的stream_name。

cpu dai widget

这里顺便说一个小意外,昨天晚上手贱,执行了一下git pull,版本升级到了3.12 rc7,结果发现ASoc的代码有所变化,于是稍稍纠结了一下,用新的代码继续还是恢复之前的3.10 rc5?经过查看了一些变化后,发现还是新的版本改进得更合理,现在决定,后面的内容都是基于3.12 rc7了。如果大家发现后面贴的代码和之前贴的有差异的地方,自己比较一下这两个版本的代码吧!

回到cpu dai,以前的内核版本由驱动通过snd_soc_register_dais注册,新的版本中,这个函数变为了soc-core的内部函数,驱动改为使用

snd_soc_register_component注册,snd_soc_register_component函数再通过调用snd_soc_register_dai/snd_soc_register_dais来完成实际的注册工作。和codec dai widget一样,cpu dai widget也发生在machine驱动匹配上相应的platform驱动之后,soc_probe_platform会被调用,在soc_probe_platform函数

37

中,通过比较dai->dev和platform->dev,挑选出属于该platform的dai,然后通过snd_soc_dapm_new_dai_widgets为cpu dai创建相应的widget: [cpp] view plaincopy

static int soc_probe_platform(struct snd_soc_card *card,

struct snd_soc_platform *platform) {

int ret = 0;

const struct snd_soc_platform_driver *driver = platform->driver;

struct snd_soc_dai *dai;

......

if (driver->dapm_widgets)

snd_soc_dapm_new_controls(&platform->dapm, driver->dapm_widgets, driver->num_dapm_widgets);

/* Create DAPM widgets for each DAI stream */ list_for_each_entry(dai, &dai_list, list) { if (dai->dev != platform->dev) continue;

snd_soc_dapm_new_dai_widgets(&platform->dapm, dai); }

platform->dapm.idle_bias_off = 1;

......

if (driver->controls)

snd_soc_add_platform_controls(platform, driver->controls,

driver->num_controls); if (driver->dapm_routes)

snd_soc_dapm_add_routes(&platform->dapm, driver->dapm_routes,

driver->num_dapm_routes); ......

return 0; }

38

从上面的代码我们也可以看出,在上面的”创建和注册widget“一节提到的第一种方法,即通过给snd_soc_platform_driver结构的dapm_widgets和

num_dapm_widgets字段赋值,ASoc会自动为我们创建所需的widget,真正执行创建工作就在上面所列的soc_probe_platform函数中完成的,普通的kcontrol和音频路径也是一样的原理。反推回来,codec的widget也是一样的,在

soc_probe_codec中会做同样的事情,只是我上面贴出来soc_probe_codec的代码里没有贴出来,有兴趣的读者自己查看一下它的代码即可。

花了这么多篇幅来讲解dai widget,好像现在看来它还没有什么用处。嗯,不要着急,实际上dai widget是一条完整dapm音频路径的重要元素,没有她,我们无法完成dapm的动态电源管理工作,因为它是音频流和其他widget的纽带,细节我们要留到下一篇文章中来阐述了。 端点widget

一条完整的dapm音频路径,必然有起点和终点,我们把位于这些起点和终点的widget称之为端点widget。以下这些类型的widg …… 此处隐藏:2787字,全部文档内容请下载后查看。喜欢就下载吧 ……

ALSA声卡驱动详解(14).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wendang/520655.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)