ALSA声卡驱动详解(16)
\rol %s\\n\,
widget->name); ret = -ENOMEM; break; } widget++; }
......
return ret; }
该函数只是简单的一个循环,为传入的widget模板数组依次调用
snd_soc_dapm_new_control函数,实际的工作由snd_soc_dapm_new_control完成,继续进入该函数,看看它做了那些工作。
我们之前已经说过,驱动中定义的snd_soc_dapm_widget数组,只是作为一个模板,所以,snd_soc_dapm_new_control所做的第一件事,就是为该widget重新分配内存,并把模板的内容拷贝过来:
[cpp] view plaincopy
static struct snd_soc_dapm_widget *
snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_widget *widget) {
struct snd_soc_dapm_widget *w; int ret;
if ((w = dapm_cnew_widget(widget)) == NULL) return NULL;
由dapm_cnew_widget完成内存申请和拷贝模板的动作。接下来,根据widget的类型做不同的处理: [cpp] view plaincopy
switch (w->id) {
case snd_soc_dapm_regulator_supply:
w->regulator = devm_regulator_get(dapm->dev, w->name);
......
if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
ret = regulator_allow_bypass(w->regulator, true);
......
41
}
break;
case snd_soc_dapm_clock_supply: #ifdef CONFIG_CLKDEV_LOOKUP
w->clk = devm_clk_get(dapm->dev, w->name); ...... #else
return NULL; #endif
break; default:
break; }
对于snd_soc_dapm_regulator_supply类型的widget,根据widget的名称获取对应的regulator结构,对于snd_soc_dapm_clock_supply类型的widget,根据widget的名称,获取对应的clock结构。接下来,根据需要,在widget的名称前加入必要的前缀:
[cpp] view plaincopy widget的power_check回调函数 widget类型 power_check回调函数 mixer类: snd_soc_dapm_switch dapm_generic_check_power snd_soc_dapm_mixer snd_soc_dapm_mixer_named_ctl mux类: snd_soc_dapm_mux snd_soc_dapm_mux snd_soc_dapm_mux snd_soc_dapm_dai_out snd_soc_dapm_dai_in 端点类: snd_soc_dapm_adc snd_soc_dapm_aif_out snd_soc_dapm_dac snd_soc_dapm_aif_in snd_soc_dapm_pga snd_soc_dapm_out_drv snd_soc_dapm_input snd_soc_dapm_output snd_soc_dapm_micbias dapm_generic_check_power dapm_adc_check_power dapm_dac_check_power dapm_generic_check_power 42
snd_soc_dapm_spk snd_soc_dapm_hp snd_soc_dapm_mic snd_soc_dapm_line snd_soc_dapm_dai_link 电源/时钟/影子widget: snd_soc_dapm_supply snd_soc_dapm_regulator_supply dapm_supply_check_power snd_soc_dapm_clock_supply snd_soc_dapm_kcontrol dapm_always_on_check_power 其它类型 if (dapm->codec && dapm->codec->name_prefix) w->name = kasprintf(GFP_KERNEL, \,
dapm->codec->name_prefix, widget->name); else
w->name = kasprintf(GFP_KERNEL, \, widget->name); 然后,为不同类型的widget设置合适的power_check电源状态回调函数,widget类型和对应的power_check回调函数设置如下表所示:
当音频路径发生变化时,power_check回调会被调用,用于检查该widget的电源状态是否需要更新。power_check设置完成后,需要设置widget所属的codec、platform和dapm context,几个用于音频路径的链表也需要初始化,然后,把该widget加入到声卡的widgets链表中: [cpp] view plaincopy w->dapm = dapm;
w->codec = dapm->codec;
w->platform = dapm->platform; INIT_LIST_HEAD(&w->sources); INIT_LIST_HEAD(&w->sinks); INIT_LIST_HEAD(&w->list); INIT_LIST_HEAD(&w->dirty);
list_add(&w->list, &dapm->card->widgets); 几个链表的作用如下:
sources 用于链接所有连接到该widget输入端的snd_soc_path结构 sinks 用于链接所有连接到该widget输出端的snd_soc_path结构 list 用于链接到声卡的widgets链表
dirty 用于链接到声卡的dapm_dirty链表 最后,把widget设置为connect状态: [cpp] view plaincopy
/* machine layer set ups unconnected pins and insertions */ w->connected = 1; return w;
43
connected字段代表着引脚的连接状态,目前,只有以下这些widget使用connected字段:
snd_soc_dapm_output snd_soc_dapm_input snd_soc_dapm_hp snd_soc_dapm_spk snd_soc_dapm_line snd_soc_dapm_vmid snd_soc_dapm_mic snd_soc_dapm_siggen
驱动程序可以使用以下这些api来设置引脚的连接状态: snd_soc_dapm_enable_pin
snd_soc_dapm_force_enable_pin snd_soc_dapm_disable_pin snd_soc_dapm_nc_pin
到此,widget已经被正确地创建并初始化,而且被挂在声卡的widgets链表中,以后我们就可以通过声卡的widgets链表来遍历所有的widget,再次强调一下snd_soc_dapm_new_controls函数所完成的主要功能:
为widget分配内存,并拷贝参数中传入的在驱动中定义好的模板 设置power_check回调函数
把widget挂在声卡的widgets链表中 为widget建立dapm kcontrol
定义一个widget,我们需要指定两个很重要的内容:一个是用于控制widget的电源状态的reg/shift等寄存器信息,另一个是用于控制音频路径切换的dapm kcontrol信息,这些dapm kcontrol有它们自己的reg/shift寄存器信息用于切换widget的路径连接方式。前一节的内容中,我们只是创建了widget的实例,并把它们注册到声卡的widgts链表中,但是到目前为止,包含在widget中的dapm kcontrol并没有建立起来,dapm框架在声卡的初始化阶段,等所有的widget(包括machine、platform、codec)都创建好之后,通过
snd_soc_dapm_new_widgets函数,创建widget内包含的dapm kcontrol,并初始化widget的初始电源状态和音频路径的初始连接状态。我们看看声卡的初始化函数,都有那些初始化与dapm有关: [cpp] view plaincopy
static int snd_soc_instantiate_card(struct snd_soc_card *card) {
......
/* card bind complete so register a sound card */
ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_D …… 此处隐藏:2865字,全部文档内容请下载后查看。喜欢就下载吧 ……
相关推荐:
- [实用模板]第八章:法国“新浪潮”与“左岸派”
- [实用模板]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,深
- 弟子规全文带拼音




