Linux 驱动之 ALSA(三)编解码器类驱动实例
这里以 Wolfson 公司的编解码芯片 WM8960 为例来说明上篇介绍的相关内容。
定义 widget 所需的 DAPM Kcontrol
1 | static const struct snd_kcontrol_new wm8960_loutput_mixer[] = { |
在上述代码中定义了左右输出通道的混音器控件,以及单声道输出混音器:wm8960_loutput_mixer、wm8960_routput_mixer、wm8960_mono_out。
定义真实的 widget,包括 DAMP 控件
1 | static const struct snd_soc_dapm_widget wm8960_dapm_widgets[] = { |
在这一步中为左右声道选择器定义了一个 MUX widget,他们是 Left Output Mixer、Right Output Mixer 和 Mono Output Mixer。 我们还为每个扬声器定义了一个混音器 widget:SPK_LP、SPK_LN、HP_L、HP_R、SPK_RP、SPK_RN、OUT3。具体的混音器控制由 wm8960_loutput_mixer、wm8960_routput_mixer、wm8960_mono_out 来完成,这三个 widget 都具有 power 属性,因此,当这些 widget 中的一个或多个位于一个有效的音频路径时,DAPM 框架可以通过其各自的寄存器的第 7 和第 8 位来控制电源状态。
定义 widget 的连接路径
1 | static const struct snd_soc_dapm_route audio_paths[] = { |
通过这一步的定义我们知道 Left output Mux 和 Right output Mux 有三个输入引脚,分别是 Boost Bypass Switch、LINPUT3 Switch、PCM Playback Switch。Mono Output Mixer 只有两个输入引脚,Left Switch、Right Switch,所以,上述定义的含义如下:
- Left Boost Mixer 通过 Boost Bypass Switch 连接到 Left Output Mixer
- Left DAC 通过 PCM Playback Switch 连接到 Left Output Mixer
- LINPUT3 通过 LINPUT3 Switch 连接到 Left Output Mixer
- Left Output Mixer 连接到 LOUT1 PGA,但是此链接没有开关控制
- Right xxx 同理这里不一一列举出来了
在编解码器驱动程序的 probe 回调函数中注册 widget 和路径
1 | static int wm8960_add_widgets(struct snd_soc_component *component) |
当 machine 驱动程序 probe 到这个编解码时,就会调用编解码器组件的 probe 回调函数 wm8960_probe,以完成编解码器驱动程序的初始化。编解码器需要绑定到 platform 驱动程序才能发挥作用,这是后面要介绍的内容。
流程
由于函数调用栈很深,没有办法一一列出,这里通过一个思维导图来将各函数调用关系列出来,感兴趣的读者可以自行阅读源码。
参考文献
《Linux 设备驱动开发-约翰-马德奥》