dapm_power_widgets流程分析

dapm_power_widgets是dapm机制的入口函数。dapm机制介绍见 https://www.cnblogs.com/bobfly1984/p/13966890.html。

dapm_power_one_widget

dapm_power_one_widget
-->dapm_widget_power_check
-->dapm_widget_set_power

dapm_up_seq 和 dapm_down_seq 数组:定义了widget上下电的优先级,值越小优先级越高。

dapm_widget_power_check:调用widget的power_check()回调函数决定其power状态。不同类型widget有不同的power_check()回调函数。判断一个widget是否上电或下电基于这个widget是否在完整音频路径上。见下面 dapm_generic_check_power()分析。

dapm_widget_set_power:遍历widget的源path实例和目的path实例,如果path实例connect状态为真,则更新相邻widget的power状态,把相邻widget添加到dirty链表,重新调用dapm_power_one_widget,把power状态沿着源端方向和目的端方向更新到每个widget。最后把widget按照上下电优先级添加到up_list和down_list链表。

dapm_widget_update

仅仅只有配置widget kcontrols触发DAPM机制时才会调用此函数。此函数流程如下:

  1. 遍历kcontrol相关的所有widget,调用每个widget的event()回调函数,发送SND_SOC_DAPM_PRE_REG事件。
  2. 更新kcontrol寄存器值,设置音频路径。
  3. 遍历kcontrol相关的所有widget,调用每个widget的event()回调函数,发送SND_SOC_DAPM_POST_REG事件。

dapm_seq_run

dapm_seq_run
-->dapm_seq_run_coalesced

up_list和down_list保存了需要上电和下电的widget,队列元素越靠前,优先级越高。

dapm_seq_run:遍历up_list或者down_list链表。把相同优先级且相同reg且相同dapm context且相同subseq的widgets组织在一起,本来多次写寄存器操作合并成一次写寄存器操作。

dapm机制引发的dapm context的bias变化

dapm core为platform、codec、snd card的bias信息以及set_bias_level()回调定义了新的数据结构即dapm context。换句话说就是dapm context分为platform、codec、snd card。

在dapm机制入口函数里,首先把所有的dapm context的target_bias_level设置为off状态,在widget上下电检查后,如果widget的power状态是on,则把on状态widget所属的dapm context的target_bias_level设置为on状态。强制把声卡上的所有context的target_bias_level设置为相同状态,要么on要么off。调用dapm_pre_sequence_async()函数触发context朝off或prepare状态转换,up_list和down_list的widgets上下电后,调用dapm_post_sequence_async()函数触发context朝on或standby状态转换。

dapm_generic_check_power

这个函数通过调用is_connected_input_ep()和is_connected_output_ep()检查widget是否在完整音频路径上。

is_connected_input_ep()函数返回widget到input端点widget路径的个数,is_connected_output_ep()函数返回widget到output端点widget路径的个数。只有当到输入端点和输出端点的路径都存在时,我们就认为这个widget在完整音频路径上,也意味着这个widget需要上电。

原文地址:https://www.cnblogs.com/bobfly1984/p/14462100.html