AM335x(TQ335x)学习笔记——WM8960声卡驱动移植
至此,就完成了DTS的全部配置,后面我会将完整的DTS文件上传到我的资源。
2. Codec驱动完善
Step1. 修改Codec驱动,使其支持DTS
由于我们在DTS中指定了Codec的compatible为"wlf,wm8960",而Linux内核自带的WM8960驱动并没有支持新式的DTS模式关联。修改方法很简单,添加i2c_driver的.driver中指定of_match_table即可,修改后的代码片段如下:
- staticconststructof_device_idwm8960_of_match[]={
- {.compatible="wlf,wm8960",},
- {}
- };
- MODULE_DEVICE_TABLE(of,wm8960_of_match);
- staticstructi2c_driverwm8960_i2c_driver={
- .driver={
- .name="wm8960",
- .owner=THIS_MODULE,
- .of_match_table=wm8960_of_match,
- },
- .probe=wm8960_i2c_probe,
- .remove=wm8960_i2c_remove,
- .id_table=wm8960_i2c_id,
- };
默认的WM8960驱动初始化信息不够完整,还需要对WM8960进行额外的初始化,修改后的代码片段如下:
- staticintwm8960_probe(structsnd_soc_codec*codec)
- {
- structwm8960_priv*wm8960=snd_soc_codec_get_drvdata(codec);
- structwm8960_data*pdata=dev_get_platdata(codec->dev);
- intret;
- wm8960->set_bias_level=wm8960_set_bias_level_out3;
- if(!pdata){
- dev_warn(codec->dev,"Noplatformdatasupplied");
- }else{
- if(pdata->capless)
- wm8960->set_bias_level=wm8960_set_bias_level_capless;
- }
- ret=wm8960_reset(codec);
- if(ret<0){
- dev_err(codec->dev,"Failedtoissuereset");
- returnret;
- }
- wm8960->set_bias_level(codec,SND_SOC_BIAS_STANDBY);
- /*Latchtheupdatebits*/
- snd_soc_update_bits(codec,WM8960_LINVOL,0x100,0x100);
- snd_soc_update_bits(codec,WM8960_RINVOL,0x100,0x100);
- snd_soc_update_bits(codec,WM8960_LADC,0x100,0x100);
- snd_soc_update_bits(codec,WM8960_RADC,0x100,0x100);
- snd_soc_update_bits(codec,WM8960_LDAC,0x100,0x100);
- snd_soc_update_bits(codec,WM8960_RDAC,0x100,0x100);
- snd_soc_update_bits(codec,WM8960_LOUT1,0x100,0x100);
- snd_soc_update_bits(codec,WM8960_ROUT1,0x100,0x100);
- snd_soc_update_bits(codec,WM8960_LOUT2,0x100,0x100);
- snd_soc_update_bits(codec,WM8960_ROUT2,0x100,0x100);
- /*otherconfiguration*/
- snd_soc_update_bits(codec,WM8960_POWER1,0x1ea,0x1ea);
- snd_soc_update_bits(codec,WM8960_POWER2,0x1f8,0x1f8);
- snd_soc_update_bits(codec,WM8960_POWER3,0xcc,0xcc);
- snd_soc_update_bits(codec,WM8960_LOUTMIX,0x100,0x100);
- snd_soc_update_bits(codec,WM8960_ROUTMIX,0x100,0x100);
- snd_soc_update_bits(codec,WM8960_POWER3,0xc,0xc);
- snd_soc_update_bits(codec,WM8960_LOUT1,0x7f,0x7f);
- snd_soc_update_bits(codec,WM8960_ROUT1,0x7f,0x7f);
- snd_soc_update_bits(codec,WM8960_IFACE2,0x40,0x40);
- snd_soc_update_bits(codec,WM8960_MONOMIX2,0x120,0x120);
- snd_soc_update_bits(codec,WM8960_LINPATH,0x1f8,0x138);
- snd_soc_update_bits(codec,WM8960_LINVOL,0x19f,0x11f);
- snd_soc_update_bits(codec,WM8960_RINVOL,0x19f,0x11f);
- snd_soc_update_bits(codec,WM8960_LOUT2,0x1ff,0x1ff);
- snd_soc_update_bits(codec,WM8960_ROUT2,0x1ff,0x1ff);
- snd_soc_update_bits(codec,WM8960_CLASSD3,0x1a,0x12);
- snd_soc_update_bits(codec,WM8960_CLASSD1,0xc0,0xc0);
- snd_soc_add_codec_controls(codec,wm8960_snd_controls,
- ARRAY_SIZE(wm8960_snd_controls));
- wm8960_add_widgets(codec);
- return0;
- }
Step3. 调整WM8960驱动结构
内核中自带的WM8960驱动结构很旧,编写Machine是需要过多的了解Codec芯片内部细节,本文对WM8960的驱动结构进行了调整,可以使Machine忽略Codec的内部细节。
修改的大体内容如下:
(1) 添加set_sysclk函数,接收Machine设置的sysclk时钟频率。具体本文就是DTS中设置的24576000。
(2) 在hw_params中添加BCLK、DACCLK、ADCCLK的配置操作。hw_params可以根据参数和sysclk对以上参数进行设置,放在这里很合适。
(3) 去除函数wm8960_set_dai_clkdiv,并将wm8960_set_dai_pll设置为驱动内部函数,不作为set_pll接口提供给内核驱动(实际上内核驱动也不调用这个函数)。
Step4. 修改WM8960的route信息
根据TQ335x的原理图可知,使用WM8960进行录音或放音时使用的LRCLK是同一个,都是DACCLK,故在snd_soc_dapm_route添加如下两行信息:
- {"LeftDAC",NULL,"LeftInputMixer"},
- {"R
AM335xTQ335xWM8960声卡驱动移 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)
