DAPM-path、route、context

widget之间的连接器 - path

path相当于电路中的一根跳线,它把一个widget的输出端和另一个widget的输入端连接在一起,path用snd_soc_dapm_path结构来描述:

struct snd_soc_dapm_path {
        const char *name;
 
        /* source (input) and sink (output) widgets */
        struct snd_soc_dapm_widget *source;
        struct snd_soc_dapm_widget *sink;
        struct snd_kcontrol *kcontrol;
 
        /* status */
        u32 connect:1;  /* source and sink widgets are connected */
        u32 walked:1;   /* path has been walked */
        u32 walking:1;  /* path is in the process of being walked */
        u32 weak:1;     /* path ignored for power management */
 
        int (*connected)(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink);
 
        struct list_head list_source;
        struct list_head list_sink;
        struct list_head list;
};

当widget之间发生连接关系时,snd_soc_dapm_path作为连接者,它的source字段会指向该连接的起始端widget,而它的sink字段会指向该连接的到达端widget,还记得前面snd_soc_dapm_widget结构中的两个链表头字段:sources和sinks么?widget的输入端和输出端可能连接着多个path,所有输入端的snd_soc_dapm_path结构通过list_sink字段挂在widget的souces链表中,同样,所有输出端的snd_soc_dapm_path结构通过list_source字段挂在widget的sinks链表中。

connect,walked,walking,weak是几个辅助字段,用于帮助所有path的遍历。

widget的连接关系 - route

一个路径的连接至少包含以下几个元素:起始端widget,跳线path,到达端widget,在DAPM中,用snd_soc_dapm_route结构来描述这样一个连接关系:

struct snd_soc_dapm_route {
        const char *sink;
        const char *control;
        const char *source;
        int (*connected)(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink);
};

sink指向到达端widget的名字字符串,source指向起始端widget的名字字符串,control指向负责控制该连接所对应的kcontrol名字字符串,connected回调则定义了上一节所提到的自定义连接检查回调函数。该结构的意义很明显就是:source通过一个kcontrol,和sink连接在一起,现在是否处于连接状态,请调用connected回调函数检查。

这里直接使用名字字符串来描述连接关系,所有定义好的route,最后都要注册到dapm系统中,dapm会根据这些名字找出相应的widget,并动态地生成所需要的snd_soc_dapm_path结构,正确地处理各个链表和指针的关系,实现两个widget之间的连接。

DAPM context

直译过来的意思是dapm上下文。可以这么理解:dapm把整个音频系统,按照功能和偏置电压级别,划分为若干个电源域,每个域包含各自的widget,每个域中所有的widget通常都处于同一个偏置电压级别上,而一个电源域就是一个dapm context,通常会有以下几种dapm context:

  • 属于codec中的widget位于一个dapm context中

  • 属于platform中的widget位于一个dapm context中

  • 属于整个声卡的widget位于一个dapm context中

对于音频系统的硬件来说,通常要提供合适的偏置电压才能正常地工作,有了dapm context这种组织方式,我们可以方便地对同一组widget进行统一的偏置电压管理,ASoC用snd_soc_dapm_context结构来表示一个dapm context:

扫描二维码关注公众号,回复: 14657485 查看本文章
struct snd_soc_dapm_context {
		enum snd_soc_bias_level bias_level;
		unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
		/* Go to BIAS_OFF in suspend if the DAPM context is idle */
		unsigned int suspend_bias_off:1;
		
		struct device *dev; /* from parent - for debug */
		struct snd_soc_component *component; /* parent component */
		struct snd_soc_card *card; /* parent card */
		
		/* used during DAPM updates */
		enum snd_soc_bias_level target_bias_level;
		struct list_head list;
		
		struct snd_soc_dapm_wcache path_sink_cache;
		struct snd_soc_dapm_wcache path_source_cache;
		
#ifdef CONFIG_DEBUG_FS
		struct dentry *debugfs_dapm;
#endif
};

snd_soc_bias_level的取值范围是以下几种:

  • SND_SOC_BIAS_OFF

  • SND_SOC_BIAS_STANDBY

  • SND_SOC_BIAS_PREPARE

  • SND_SOC_BIAS_ON

代表widget结构snd_soc_dapm_widget中,有一个snd_soc_dapm_context结构指针,指向所属的codec、platform、card、或dai的dapm结构。同时,所有的dapm结构,通过它的list字段,链接到代表声卡的snd_soc_card结构的dapm_list链表头字段 。

猜你喜欢

转载自blog.csdn.net/hhx123456798/article/details/123303344