ALSA声卡驱动详解(18)
接着,对几种能影响音频路径的widget,创建并初始化它们所包含的dapm kcontrol:
[cpp] view plaincopy switch(w->id) {
case snd_soc_dapm_switch: case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl: dapm_new_mixer(w); break;
case snd_soc_dapm_mux:
case snd_soc_dapm_virt_mux:
46
case snd_soc_dapm_value_mux: dapm_new_mux(w); break;
case snd_soc_dapm_pga:
case snd_soc_dapm_out_drv: dapm_new_pga(w); break; default:
break; }
需要用到的创建函数分别是:
dapm_new_mixer() 对于mixer类型,用该函数创建dapm kcontrol; dapm_new_mux() 对于mux类型,用该函数创建dapm kcontrol; dapm_new_pga() 对于pga类型,用该函数创建dapm kcontrol;
然后,根据widget寄存器的当前值,初始化widget的电源状态,并设置到power字段中:
[cpp] view plaincopy
/* Read the initial power state from the device */ if (w->reg >= 0) {
val = soc_widget_read(w, w->reg) >> w->shift; val &= w->mask;
if (val == w->on_val) w->power = 1; }
接着,设置new字段,表明该widget已经初始化完成,我们还要吧该widget加入到声卡的dapm_dirty链表中,表明该widget的状态发生了变化,稍后在合适的时刻,dapm框架会扫描dapm_dirty链表,统一处理所有已经变化的widget。为什么要统一处理?因为dapm要控制各种widget的上下电顺序,同时也是为了减少寄存器的读写次数(多个widget可能使用同一个寄存器): [cpp] view plaincopy w->new = 1;
dapm_mark_dirty(w, \); dapm_debugfs_add_widget(w);
最后,通过dapm_power_widgets函数,统一处理所有位于dapm_dirty链表上的widget的状态改变: [cpp] view plaincopy
dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP); ...... return 0;
dapm mixer kcontrol
47
上一节中,我们提到,对于mixer类型的dapm kcontrol,我们会使用dapm_new_mixer来完成具体的创建工作,先看代码后分析: [cpp] view plaincopy
static int dapm_new_mixer(struct snd_soc_dapm_widget *w) {
int i, ret;
struct snd_soc_dapm_path *path;
/* add kcontrol */
(1) for (i = 0; i < w->num_kcontrols; i++) { /* match name */
(2) list_for_each_entry(path, &w->sources, list_sink) {
/* mixer/mux paths name must match control name */
(3) if (path->name != (char *)w->kcontrol_news[i].name)
continue;
(4) if (w->kcontrols[i]) {
dapm_kcontrol_add_path(w->kcontrols[i], path);
continue; }
(5) ret = dapm_create_or_share_mixmux_kcontrol(w, i);
if (ret < 0)
return ret;
(6) dapm_kcontrol_add_path(w->kcontrols[i], path); } }
return 0; }
(1) 因为一个mixer是由多个kcontrol组成的,每个kcontrol控制着mixer的一个输入端的开启和关闭,所以,该函数会根据kcontrol的数量做循环,逐个建立对应的kcontrol。
48
(2)(3) 之前多次提到,widget之间使用snd_soc_path进行连接,widget的sources链表保存着所有和输入端连接的snd_soc_path结构,所以我们可以用kcontrol模板中指定的名字来匹配对应的snd_soc_path结构。
(4) 因为一个输入脚可能会连接多个输入源,所以可能在上一个输入源的path关联时已经创建了这个kcontrol,所以这里判断kcontrols指针数组中对应索引中的指针值,如果已经赋值,说明kcontrol已经在之前创建好了,所以我们只要简单地把连接该输入端的path加入到kcontrol的path_list链表中,并且增加一个虚拟的影子widget,该影子widget连接和输入端对应的源widget,因为使用了
kcontrol本身的reg/shift等寄存器信息,所以实际上控制的是该kcontrol的开和关,这个影子widget只有在kcontrol的autodisable字段被设置的情况下才会被创建,该特性使得source的关闭时,与之连接的mixer的输入端也可以自动关闭,这个特性通过dapm_kcontrol_add_path来实现这一点: [cpp] view plaincopy
static void dapm_kcontrol_add_path(const struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_path *path) {
struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
/* 把kcontrol连接的path加入到paths链表中 */
/* paths链表所在的dapm_kcontrol_data结构会保存在kcontrol的private_data字段中 */
list_add_tail(&path->list_kcontrol, &data->paths);
if (data->widget) {
snd_soc_dapm_add_path(data->widget->dapm, data->widget,
path->source, NULL, NULL); } }
(5) 如果kcontrol之前没有被创建,则通过
dapm_create_or_share_mixmux_kcontrol创建这个输入端的kcontrol,同理,kcontrol对应的影子widget也会通过dapm_kcontrol_add_path判断是否需要创建。
dapm mux kcontrol
因为一个widget最多只会包含一个mux类型的damp kcontrol,所以他的创建方法稍有不同,dapm框架使用dapm_new_mux函数来创建mux类型的dapm kcontrol:
[cpp] view plaincopy
static int dapm_new_mux(struct snd_soc_dapm_widget *w) {
49
struct snd_soc_dapm_context *dapm = w->dapm; struct snd_soc_dapm_path *path; int ret;
(1) if (w->num_kcontrols != 1) { dev_err(dapm->dev,
\trols\\n\,
w->name); return -EINVAL; }
if (list_empty(&w->sources)) { dev_err(dapm->dev, \, w->name); return -EINVAL; }
(2) ret = dapm_create_or_share_mixmux_kcontrol(w, 0); …… 此处隐藏:2047字,全部文档内容请下载后查看。喜欢就下载吧 ……
相关推荐:
- [实用模板]第八章:法国“新浪潮”与“左岸派”
- [实用模板]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,深
- 弟子规全文带拼音




