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

ALSA声卡驱动详解(16)

来源:网络收集 时间:2026-07-01
导读: \rol %s\\n\, widget->name); ret = -ENOMEM; break; } widget++; } ...... return ret; } 该函数只是简单的一个循环,为传入的widget模板数组依次调用 snd_soc_dapm_new_control函数,实际的工作由snd_soc_dapm_ne

\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字,全部文档内容请下载后查看。喜欢就下载吧 ……

ALSA声卡驱动详解(16).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)