ALSA声卡驱动详解(14)
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字,全部文档内容请下载后查看。喜欢就下载吧 ……
相关推荐:
- [实用模板]第八章:法国“新浪潮”与“左岸派”
- [实用模板]2021年北京上半年临床医学检验技师生物
- [实用模板]SAP GUI 7.10客户端安装配置文档
- [实用模板]2001年临床执业医师资格考试综合笔试试
- [实用模板]36机场工作实用英语词汇总结
- [实用模板](一)社会保险稽核通知书
- [实用模板]安全教育主题班会材料
- [实用模板]濉溪县春季呼吸道传染病防控应急演练方
- [实用模板]长沙房地产市场周报(1.30-2.3)
- [实用模板]六年级数学上册典中点 - 图文
- [实用模板]C程序设计(红皮书)习题官方参考答案
- [实用模板]中国证监会第一届创业板发行审核委员会
- [实用模板]桥梁工程复习题
- [实用模板]2011学而思数学及答案
- [实用模板]初中病句修改专项练习
- [实用模板]监理学习知识1 - 图文
- [实用模板]小机灵杯四年级试题
- [实用模板]国贸专业毕业论文模板
- [实用模板]教育学概论考试练习题-判断题4
- [实用模板]2015届高考英语一轮复习精品资料(译林
- 00Nkmhe_市场营销学工商管理_电子商务_
- 事业单位考试法律常识
- 诚信教育实施方案
- 吉大小天鹅食品安全检测箱方案(高中低
- 房地产销售培训资料
- 高一地理必修1复习提纲
- 新概念英语第二册lesson_1_练习题
- 证券公司内部培训资料
- 小学英语时间介词专项练习
- 新世纪英语专业综合教程(第二版)第1册U
- 【新课标】浙教版最新2018年八年级数学
- 工程建设管理纲要
- 外研版 必修一Module 4 A Social Surve
- Adobe认证考试 AE复习资料
- 基于H.264AVC与AVS标准的帧内预测技术
- 《食品检验机构资质认定管理办法》(质
- ABB变频器培训课件
- (完整版)小学说明文阅读练习题及答案
- 深思洛克(SenseLock) 深思IV,深思4,深
- 弟子规全文带拼音




