alsa之dapm笔记
2016-03-08 16:28
603 查看
参考博客
宗旨
snd_soc_dapm_context
snd_soc_dapm_widget
DAPM之内部API
DAPM之外部API
检查snd_soc_dapm_widget需要上电还是下电,也就是新的电源状态。这里power一词应该用英语的角度去理解,power up/down,power意思处理电源。dapm_generic_check_power函数是snd_soc_dapm_widget的check_power成员函数的一个特例,函数思路是如果同时连接到激活的输入端(is_connected_input_ep非零)和激活的输出端(is_connected_output_ep非零)则返回1(也就是需要上电),否则返回0(也就是需要下电)。容易理解,既然一条线路输入输出都已经上电,那么中间路径的控件自然需要上电。
dapm_power_widgets
dapm_power_widgets处理widgets电源,将声卡所有肮脏widgets电源进行处理,该上电的上电,该下电的下电。函数思路是遍历声卡肮脏widget列表,按照固定下/上电顺序插入到down_list/up_list列表。然后,先将down_list的widget下电。最后将up_list的widget上电。值得注意的是dapm_power_one_widget除了将widget插入到down_list或者up_list外,还会将通过snd_soc_dapm_path连接相邻widget污染(自己要上电,则告诉相邻的widget也要上电;反之下电亦然)。代码参考dapm_widget_set_power函数,此处不做详述。
如果snd_soc_dapm_widget的dirty链表未加入任何链表则表示干净,加入snd_soc_card的dapm_dirty链表之后则表示肮脏。
宗旨
snd_soc_dapm_context
snd_soc_dapm_widget
DAPM之内部API
DAPM之外部API
参考博客
ALSA架构详解宗旨
分析dapm的代码不应以弄清除dapm原理为目标,而应该是出于可以看懂和编写codec或者platform驱动目的。毕竟代码万万,linux kernel已经封装的接口又不需要驱动开发者实现。驱动开发者不应该浪费有限的生命。snd_soc_dapm_context
dapm把整个音频系统,按照功能和偏置电压级别,划分为若干个电源域,每个域包含各自的widget,每个域中的所有widget通常都处于同一个偏置电压级别上,而一个电源域就是一个dapm context。snd_soc_dapm_context被内嵌到代表codec、platform、card、dai的结构体中:struct snd_soc_codec { ...... struct snd_soc_dapm_context dapm; ...... }; struct snd_soc_platform { ...... struct snd_soc_dapm_context dapm; ...... }; struct snd_soc_card { ...... struct snd_soc_dapm_context dapm; ...... }; struct snd_soc_dai { ...... struct snd_soc_dapm_context dapm; ...... };
snd_soc_dapm_widget
所有snd_soc_dapm_widget注册时都挂载在snd_soc_card的widget链表。struct snd_soc_card { ...... struct list_head widgets; ...... };
DAPM之内部API
dapm_widget_power_checkstatic int dapm_widget_power_check(struct snd_soc_dapm_widget *w) { if (w->power_checked) return w->new_power; if (w->force) w->new_power = 1; else w->new_power = w->power_check(w); w->power_checked = true; return w->new_power; } /* Generic check to see if a widget should be powered. */ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) { int in, out; DAPM_UPDATE_STAT(w, power_checks); in = is_connected_input_ep(w); dapm_clear_walk(w->dapm); out = is_connected_output_ep(w); dapm_clear_walk(w->dapm); return out != 0 && in != 0; }
检查snd_soc_dapm_widget需要上电还是下电,也就是新的电源状态。这里power一词应该用英语的角度去理解,power up/down,power意思处理电源。dapm_generic_check_power函数是snd_soc_dapm_widget的check_power成员函数的一个特例,函数思路是如果同时连接到激活的输入端(is_connected_input_ep非零)和激活的输出端(is_connected_output_ep非零)则返回1(也就是需要上电),否则返回0(也就是需要下电)。容易理解,既然一条线路输入输出都已经上电,那么中间路径的控件自然需要上电。
dapm_power_widgets
/* * Scan each dapm widget for complete audio path. * A complete path is a route that has valid endpoints i.e.:- * * o DAC to output pin. * o Input Pin to ADC. * o Input pin to Output pin (bypass, sidetone) * o DAC to ADC (loopback). */ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) { ... /* Check which widgets we need to power and store them in * lists indicating if they should be powered up or down. We * only check widgets that have been flagged as dirty but note * that new widgets may be added to the dirty list while we * iterate. */ list_for_each_entry(w, &card->dapm_dirty, dirty) { dapm_power_one_widget(w, &up_list, &down_list); } ... dapm_seq_run(dapm, &down_list, event, false); ... dapm_seq_run(dapm, &up_list, event, true); ... }
dapm_power_widgets处理widgets电源,将声卡所有肮脏widgets电源进行处理,该上电的上电,该下电的下电。函数思路是遍历声卡肮脏widget列表,按照固定下/上电顺序插入到down_list/up_list列表。然后,先将down_list的widget下电。最后将up_list的widget上电。值得注意的是dapm_power_one_widget除了将widget插入到down_list或者up_list外,还会将通过snd_soc_dapm_path连接相邻widget污染(自己要上电,则告诉相邻的widget也要上电;反之下电亦然)。代码参考dapm_widget_set_power函数,此处不做详述。
DAPM之外部API
dapm_mark_dirtystatic bool dapm_dirty_widget(struct snd_soc_dapm_widget *w) { return !list_empty(&w->dirty); } void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason) { if (!dapm_dirty_widget(w)) { dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n", w->name, reason); list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty); } } EXPORT_SYMBOL_GPL(dapm_mark_dirty);
如果snd_soc_dapm_widget的dirty链表未加入任何链表则表示干净,加入snd_soc_card的dapm_dirty链表之后则表示肮脏。
相关文章推荐
- 除了被程序猿嫌弃,让产品经理懂点技术还有什么理由?
- yum与rpm的区别以及详细介绍
- 产品经理最好用的工具都在这里了
- Is it possible to display icons in a PopupMenu?PopupMenu中显示图片是否可能
- mysql:You can't specify target table 'bpm_tksign_data' for update in FROM clause
- 产品新人一年的产品经历,产品经理的世界是这样的!
- rpm 更新/升级 软件包(libGL-devel手动安装过程)
- 开发人员面对产品经理的“为难” 得淡定
- 如何将自己培养成一个优秀的产品经理
- SPM第一次作业
- 基于概率的矩阵分解原理详解(PMF)
- yum下载rpm包到本地
- mysql 5.7.11 rpm安装
- pm2 的使用
- Can't locate ExtUtils/MakeMaker.pm in @INC
- rpm命令收集
- 【error】npm install报错
- K2BPM怎么让金融数据更有意义?
- 租房时代,K2 BPM软件带你拥抱更好生活
- IPMI特点和功能