本帖最后由 qwe890asd 于 2017-10-3 16:02 编辑
AM335x(TQ335x)学习笔记——WM8960声卡驱动移植
3. 编写Machine驱动
内核代码有个很好的例子就是davinci-evm.c,这是am335x-evm评估板的Machine驱动,该评估采用的Codec并不是WM8960,因此,我们在该文件中添加WM8960信息即可。具体的修改如下: Step1. 添加compatible信息。修改后的内容如下: - static const struct of_device_id davinci_evm_dt_ids[] = {
- {
- .compatible = "ti,tq-evm-audio",
- .data = (void *) &evm_dai_wm8960,
- },
- {
- .compatible = "ti,da830-evm-audio",
- .data = (void *) &evm_dai_tlv320aic3x,
- },
- { /* sentinel */ }
- };
复制代码
Step2. 实现em_dai_wm8960。需要添加如下代码: - static struct snd_soc_dai_link evm_dai_wm8960 = {
- .name = "wm8960",
- .stream_name = "wm8960-hifi",
- .codec_dai_name = "wm8960-hifi",
- .ops = &evm_wm8960_ops,
- .init = evm_wm8960_init,
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM |
- SND_SOC_DAIFMT_NB_NF,
- };
复制代码
含义:
(1) codec_dai_name = "wm8960-hifi" --> 指定codec设备名称,与wm8960.c中指定的相同即可。 (2) ops --> 指定wm8960的各种操作函数,本文仅实现了hw_params函数。 (3) init --> 指定wm8960的初始化函数,主要是完成dapm相关的初始化。 (4) dai_fmt --> 指定音频的接口方式、主从关系和时钟翻转信息。SND_SOC_DAIFMT_I2S表示音频接口采用I2S协议;SND_SOC_DAIFMT_CBM_CFM表示Codec的BCLK为Master,LRCLK为Master,即wm8960为主,AM335x为从;SND_SOC_DAIFMT_NB_NF表示BCLK和LRCLK都不需要翻转。 Step3.实现evm_wm8960_init 这一部分主要是dapm相关的设置,本人理解也不是非常深刻,直接贴上代码,具体如下: - static const struct snd_soc_dapm_widget evm_wm8960_dapm_widgets[] = {
- SND_SOC_DAPM_SPK("Audio Out1", NULL),
- SND_SOC_DAPM_MIC("my Mic", NULL),
- SND_SOC_DAPM_MIC("my Line IN", NULL),
- };
-
- static const struct snd_kcontrol_new evm_wm8960_controls[] = {
- SOC_DAPM_PIN_SWITCH("Audio Out1"),
- SOC_DAPM_PIN_SWITCH("my Mic"),
- SOC_DAPM_PIN_SWITCH("my Line IN"),
- };
-
- static const struct snd_soc_dapm_route evm_wm8960_audio_map[] = {
- /* Connections to the ... */
- {"Audio Out1", NULL, "HP_L"},
- {"Audio Out1", NULL, "HP_R"},
-
- /* Mic */
- {"LINPUT1", NULL, "MICB"},
- {"MICB", NULL, "my Mic"},
-
- /* Line in */
- {"LINPUT3", NULL, "my Line IN"},
- {"RINPUT3", NULL, "my Line IN"},
- };
-
- static int evm_wm8960_init(struct snd_soc_pcm_runtime *rtd)
- {
- int err;
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- snd_soc_dapm_new_controls(dapm, evm_wm8960_dapm_widgets,
- ARRAY_SIZE(evm_wm8960_dapm_widgets ) );
-
- err = snd_soc_add_codec_controls(codec, evm_wm8960_controls,
- ARRAY_SIZE(evm_wm8960_controls));
-
- if (err < 0)
- return err;
-
- snd_soc_dapm_add_routes(dapm, evm_wm8960_audio_map,
- ARRAY_SIZE(evm_wm8960_audio_map));
-
- snd_soc_dapm_enable_pin(dapm, "Audio Out1");
- snd_soc_dapm_enable_pin(dapm, "my Mic");
-
- snd_soc_dapm_sync( dapm );
-
- return 0;
- }
复制代码
Step4. 实现evm_wm8960_ops及相关函数,需要添加如下代码: - static int evm_wm8960_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
- {
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_card *soc_card = rtd->card;
- int ret = 0;
- unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *)
- snd_soc_card_get_drvdata(soc_card))->sysclk;
-
- /* set the codec system clock */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- /* set the CPU system clock */
- ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
-
- return 0;
- }
-
- static struct snd_soc_ops evm_wm8960_ops = {
- .startup = evm_startup,
- .shutdown = evm_shutdown,
- .hw_params = evm_wm8960_hw_params,
- };
复制代码
至此,就完成了代码移植的全部工作,修改涉及到的三个文件是:tq335x.dts、davinci-evm.c和wm8960.c,修改后的这三个文件我会上传到我的资源,如有需要,请去我的资源中下载。
4. 配置内核 完成了代码的移植工作之后还需要对内核进一步配置。默认的内核将ALSA作为module加载,本文将编译进内核。具体步骤如下: Step1. 修改sound/soc/codecs/Kconfig,添加wm8960编译选项,修改后的内容如下: - config SND_SOC_WM8960
- tristate "Wolfson Microelectronics WM8960 CODEC"
- depends on I2C && INPUT
复制代码
Step2. 通过menuconfig配置内核
执行指令: - make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig
复制代码
进行如下修改: - Device Drivers --->
- <*> Sound card support --->
- <*> Advanced Linux Sound Architecture --->
- <*> ALSA for SoC audio support --->
- <*> SoC Audio for Texas Instruments chips using eDMA (AM33XX/43XX)
- -*- Multichannel Audio Serial Port (McASP) support
- <*> SoC Audio for the AM33XX chip based boards
- CODEC drivers --->
- <*> Wolfson Microelectronics WM8960 CODEC
复制代码
重新编译内核: - make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j8
|