免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1721 | 回复: 3
打印 上一主题 下一主题

[内核模块] 内核ASoC之path [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-01-21 03:44 |只看该作者 |倒序浏览
内核ASoC之path
http://www.alivepea.me/kernel/asoc-path/

ASoC的DAPM是怎么做到需要用户空间参与功耗最小的呢?以codec为例,它运行时的功耗 主要取决于:1. codec供电电压越低,功耗越低; 2. 将codec中没有使用的部件widget 下电禁用。第1点和硬件设计有关,第2点就是DAPM最重要的工作内容了。那它是怎么做 到呢?

widget与path
下图是WM8750的框图。



如上图,speaker右声道播放音频流时,流经与DAPM相关的widget: ①snd_soc_dapm_dai_in. ②snd_soc_dapm_dac. ③snd_soc_dapm_mixer. ④snd_soc_dapm_pga. ⑤snd_soc_dapm_spk.

speaker播放音频时的通路Route:①→②→③→④→⑤. 在这条通路上的widget上电, 不在这条通路上的widget,即没有使用到的,都需要下电禁用。

如果这时插入耳机,用户希望声音从耳机出来,会怎么样呢?如下图。



上图中widget:⑥snd_soc_dapm_pga. ⑦snd_soc_hp.

在耳机播放播放右声道音频流的通路Route:①→②→③→⑥→⑦. 在给widget⑥和⑦上 电之前,还要先让widget④和⑤下电。

各部件widget之间的连通关系通过path表示,如下图。



widget通过sinks链接上的path遍历下一个sink widget,通过sources链接上的path遍 历上一个source widget. 判断一个widget是否在活动的通路上,就是判断该widget能 否遍历到音频输入端点和输出端点.如上图speaker播放时,输入端点是①,输出端点是 ⑤;earphone播放时,输入端点是①,输出端点是⑦.

实现
下面是代码is_connect_output_ep()的解析,用于判断某个widget能否连通到输出端 点。

static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
struct snd_soc_dapm_widget_list **list)
{
struct snd_soc_dapm_path *path;
int con = 0;

if (widget->outputs >= 0)
return widget->outputs;

DAPM_UPDATE_STAT(widget, path_checks);

switch (widget->id) { /* 这几个部件都不可能连通到输出端点 */
case snd_soc_dapm_supply:
case snd_soc_dapm_regulator_supply:
case snd_soc_dapm_clock_supply:
case snd_soc_dapm_kcontrol:
return 0;
default:
break;
}

switch (widget->id) { /* 录制时的输出端点 */
case snd_soc_dapm_adc:
case snd_soc_dapm_aif_out:
case snd_soc_dapm_dai_out:
if (widget->active) { /* 只有substream打开后,才能成为活动的输出端点 */
widget->outputs = snd_soc_dapm_suspend_check(widget);
return widget->outputs;
}
default:
break;
}

if (widget->connected) { /* 可插拨的widget如earphone是否在板上 */
/* connected pin ? */
if (widget->id == snd_soc_dapm_output && !widget->ext) { /* 没有外接widget的output也是输出端点 */
widget->outputs = snd_soc_dapm_suspend_check(widget);
return widget->outputs;
}

/* connected jack or spk ? */
if (widget->id == snd_soc_dapm_hp ||
widget->id == snd_soc_dapm_spk ||
(widget->id == snd_soc_dapm_line &&
!list_empty(&widget->sources))) { /* hp,spk,line都是输出端点 */
widget->outputs = snd_soc_dapm_suspend_check(widget);
return widget->outputs;
}
}

list_for_each_entry(path, &widget->sinks, list_source) { /* 枚举像mixer/mux widget的下一个widget */
DAPM_UPDATE_STAT(widget, neighbour_checks);

if (path->weak) /* 需要略过的路径 */
continue;

if (path->walking) /* 回环的路径 */
return 1;

if (path->walked) /* 已遍历的路径 */
continue;

trace_snd_soc_dapm_output_path(widget, path);

if (path->sink && path->connect) { /* 对于mixer/mux部件来说,如果当前的path是连通的,继续向下遍历 */
path->walked = 1;
path->walking = 1;

/* do we need to add this widget to the list ? */
if (list) {
int err;
err = dapm_list_add_widget(list, path->sink); /* 保存遍历轨迹 */
if (err < 0) {
dev_err(widget->dapm->dev,
"ASoC: could not add widget %s\n",
widget->name);
path->walking = 0;
return con;
}
}

con += is_connected_output_ep(path->sink, list); /* 进入下一个sink widget 继续遍历 */

path->walking = 0;
}
}

widget->outputs = con;

return con; /* 返回遍历输出端点的连通数*/
}
view rawis_connected_output_ep.c hosted with ❤ by GitHub
上面的代码其实就是特定有向图的路径深度优先的搜索算法。当没有音频在播放时,由 于widget①的active状态为0,不是输入端点,整个codec就没有活动通路,所有的 widget都在下电状态。 当speaker播放时,耳机没有插入时,snd_soc_dapm_headphone 的connected状态为0,不能被当作活动通路上的输出端点,widgets⑥和⑦仍处下电状态。 当耳机插入后,如果用户不希望声音同时从headphone/speaker同时出来,设定speaker 的widget->connected后,会自动将widget④和⑤下电,⑥和⑦上电。

判断是否连通到输入端点的代码is_connect_input_ep()与上面很相似,就略过了。

总结
DAPM通过对widget建立path,在不需要用户的干预下根据不同的通路让codec处在功耗最 小的工作状态。在注意的是,除了播放时插拨耳机改变通路外,还有播放时,用户通过 切换mixer/mux这种widgets,也会改变通路。

~EOF~

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
2 [报告]
发表于 2014-01-21 09:35 |只看该作者
虽然这个不熟,但是还是要顶linyunxian

论坛徽章:
0
3 [报告]
发表于 2014-01-21 09:56 |只看该作者
回复 2# humjb_1983


    怎么听起来有那么点基情的赶脚

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
4 [报告]
发表于 2014-01-21 10:18 |只看该作者
linyunxian 发表于 2014-01-21 09:56
回复 2# humjb_1983

有感觉就对了~~,呵呵
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP