本文主要是介绍[RK3566-Android11] 关于双TAS5805M-攻放IC-立体声+低音组2.1通路调试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
问题描述
由于RK3566/3568/3588的新平台没有适配tas5805m的驱动,驱动库里只有老版本的571x的低芯片版本的驱动,这里我们可以使用Ti提供TAS5805M驱动《Linux Driver for TAS5805M》中的tas5805m.c和tas5805m.h文件修改适用于新平台,需要注意由于kernel版本升级,tas5805m.c中snd_soc_codec方法被弃用,需要修改为snd_soc_component方法,还有一些类似的codec方法都需要替换为对应的component函数,然后根据库里老的tas571x.c驱动,将其中的gpio控制部分移植过来。这边由于代码问题,无法附上修改好的tas5805m.c文件。可根据我的叙述,尝试自行修改。
我这里由于使用了两个TAS5805M的驱动,所以使用了2份tas5805m.c驱动来控制,dts配置如下:
tas5805m_sound: tas5805m-sound {compatible = "simple-audio-card";simple-audio-card,format = "i2s";simple-audio-card,name = "rockchip,tas5805m";simple-audio-card,mclk-fs = <256>;simple-audio-card,dai-link@0 {format = "i2s";cpu {sound-dai = <&i2s1_8ch>;};codec {sound-dai = <&tas5805m>;};};simple-audio-card,dai-link@1 {format = "i2s";cpu {sound-dai = <&i2s1_8ch>;};codec {sound-dai = <&tas5805ms>;};};};&i2c2 {
...//0x2f 立体声tas5805m: tas5805m@2f {#sound-dai-cells = <0>;compatible = "ti,tas5805m";reg = <0x2f>;pinctrl-names = "default";pinctrl-0 = <&i2s1m0_mclk>;//CPU_AM_EN GPIO1_B0_Dpdn-gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_LOW>;//I2S1_MCLK_M0 GPIO1 A2reset-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>;status = "okay";};//0x2e 低音tas5805ms: tas5805ms@2e {#sound-dai-cells = <0>;compatible = "ti,tas5805ms";reg = <0x2e>;status = "okay";};
...
}
遇到的问题:
1.播放音乐喇叭无声音
最开始调试的时候,我先单独调试了一个芯片,根据上面的驱动部分修改cat /proc/asound/cards查看声卡注册成功,但是没有声音出来,这是需要使用 tinyplay /data/test1k-44100.wav -D 1 命令,强制I2S通过喇叭出声音。我这里强制I2S是可以出声音的,如果没声音,需要检查对应的i2s软/硬件配置是否正确。
2.hdmi sound声音优先级高于功放
这是RK的声音通路设计,我调试的时候发现一直没声音,结果拔了HDMI后声音出来了。如果要修改优先级,可以在frameworks\av\services\audiopolicy\enginedefault\src\Engine.cpp中,将AUDIO_DEVICE_OUT_SPEAKER的优先级高于AUDIO_DEVICE_OUT_AUX_DIGITAL,如下:
if (devices2.isEmpty()) {devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);}if ((devices2.isEmpty()) && (strategy != STRATEGY_SONIFICATION)) {// no sonification on aux digital (e.g. HDMI)devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_AUX_DIGITAL);}if ((devices2.isEmpty()) &&(getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET);}// if (devices2.isEmpty()) {// devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);// }
3.双芯片注册regmap_register_patch时有时失败
tas5805m.c驱动中需要使用regmap_register_patch方法去注册tas5805m.h的tas5805m_init_sequence函数,去修改寄存器,达到立体声和低音的效果,如下:
ret = regmap_register_patch(regmap, tas5805m_init_sequence, ARRAY_SIZE(tas5805m_init_sequence));printk("tas5805m:>>>>>>>>>>>> regmap_register_patch: ret = %d<<<<<<<<<<<<<<<<",ret);if (ret != 0){dev_err(dev, "Failed to initialize TAS5805M: %d\n",ret);goto err;}
这里双驱动的时候,发现驱动加载时,ret经常注册失败返回-6,导致声音注册失败无声,虽然可以屏蔽此处,不注册效果也可以出声,但是无法使用立体声效果。经过反复研究,发现I2C的clock-frequency高一点的时候就会出现概率注册失败的情况,clock-frequency在10的低速时,则不会失败,跟Ti沟通,Ti那边说初始化时候要保持I2S稳定信号,需要在初始化之前保证I2S1提前输出稳定信号就可以。
4.tas5805m.h的使用问题
由于需要立体声+低音组成2.1的效果,所以根据我的硬件,0x2f立体声这路,需要使用2.1的.h配置。
而0x2e低音这路,需要使用1.0的.h配置,这部分。配置文件如下:
https://pan.baidu.com/s/1cZDh03eCm0vZhQAfJu2Lcg ou0v
https://pan.baidu.com/s/1i35fkz8iTd9Kt6R7iV9BBw y58a
tas5805m.h是2.1
tas5805ms.h是1.0
遇到类似问题,可以私聊我。
后续问题:
按照RK驱动注册流程,即使打上I2S常开补丁,I2S-CLK也是在声卡注册之后也就是I2C之后才能出来波形,如下图:
(图中:黄色为 i2c2 的 I2C2_SDA_M1 蓝色为 i2s1 的 I2S1_SCLK_TX_M0_PMIC)
按照以上波形,开机后,I2S在I2C之后,这样TAS5805M驱动在注册时会导致写入的寄存器配置失效。
会导致最高音量时会出现失真的情况,如下图。
按照TI的的要求,我们需要iis信号出来以后再写iic,如下图:
这里我们只需要在打上I2S常开补丁之后,更换驱动的编译顺序,就可以让I2S的信号比I2C的信号先出来。如下图:
这里我们把rockchip/的编译优先级提高,把codecs/的注册放到最后。在用示波器测量如下图:
可以看到,I2S的信号提前出来了。这时我们再使用1K-0db的音源测试看看:
最高音量不削顶了,不在有失真的情况,说明通过TAS5805M写入I2C寄存器成功了。
这篇关于[RK3566-Android11] 关于双TAS5805M-攻放IC-立体声+低音组2.1通路调试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!