DAPM-4 Path/Route添加过程
- route分类:
- route转化为Path
- codec驱动add widget
- Mechine驱动add kcontrol
route分类:
-
常规route
{“sink”, NULL, “source”},其path->connect=1 -
sink widget是Mixer
{“Mixer”, name1, “source1”}
{“Mixer”, name2, “source2”}
name1和name2是kcontrol,可以通过控制kcontrol来打开某条path -
sink widget是Muxer
{“Mixer”, value1, “source1”}
{“Mixer”, value2, “source2”}
只有一个kcontrol,通过设置kcontrol 的value来打开某条path
route转化为Path
codec驱动add widget
-
根据名字找到source, sink widget
-
构造Path
.source : 指向source widget
.sink : 指向sink widget
.kcontrol : NULL, 要在Mechine驱动中才会创建 -
设置path->connect
3.1 kcontrol == NULL, connect=1 , (static)
3.2 kcontrol != NULL, (dynamic)- sink widget为ADC, DAC的path,一般直接(无开关),故path->connect=1
- sink widget为mixer,Muxer是path, path->connect=根据寄存器的值设置
- sink widget为Mic,spk,HP,path->connect=0
-
把Path放入链表
list_add(&path->list, &dapm->card->paths); list_add(&path->list_sink, &wsink->sources); list_add(&path->list_source, &wsource->sinks);
根据链表可知道任一widget的链接关系:
wm8960_probe(struct snd_soc_codec *codec)
wm8960_add_widgets(codec);
snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets,ARRAY_SIZE(wm8960_dapm_widgets));
snd_soc_dapm_new_control(dapm, widget);
list_add(&w->list, &dapm->card->widgets); //添加到声卡中的widgets链表中
// 此时只是找到 sink 和 source widget并添加到path中。kcontrol要在mechine驱动中才会去创建和注册
snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths)); // 这里找到sink 和 source widget
snd_soc_dapm_add_route(dapm, route); // for (i = 0; i < num; i++) {
list_add(&path->list, &dapm->card->paths);
list_add(&path->list_sink, &wsink->sources);
list_add(&path->list_source, &wsource->sinks);
Mechine驱动add kcontrol
snd_soc_dapm_new_widgets
它会导到Mux/Mixer中,snd_kcontrol_new被构造成snd_kcontrol,进而设置path->kcontrol
snd_smdk_probe(struct platform_device *pdev) // Mechine驱动的probe()函数
snd_soc_register_card(struct snd_soc_card *card)
snd_soc_instantiate_card(struct snd_soc_card *card)
soc_probe_dai_link()
soc_post_component_init(card, codec, num, 0);
snd_soc_dapm_new_widgets(&codec->dapm); //Make sure all DAPM widgets are instantiated