背景
最近在做一个安卓项目,需要把原厂适配的功放干掉,更换成供应链提供的新功放。而在功放驱动添加完毕后,发现安卓端播放音乐无声。一般出现这种问题的原因都是是功放初始化时序不对,或者初始化完成了但未开功放,但是查看功放注册和开关时的调试信息后,我发现是这两种情况的可能性不算大,因为功放原厂不会给一个初始化不出声的linux驱动配置,大概率还是其他原因导致的异常。
分析步骤
* 内核启动后,使用dmesg命令,发现功放注册正常
* 使用cat /proc/asound/cards命令查看声卡,发现声卡挂载成功,侧面印证功放注册正常。
* 通过dmesg发现播放时,播放音乐时功放初始化过程无异常,表示I2C通信正常,功放初始化时序正常。
* 通过示波器量功放的I2S,I2C波形、功放复位脚信号,以及功放输出载波,发现波形都正常,侧面印证了以上结论。
综合以上信息,怀疑是安卓输出信号为mute信号或者I2S格式与功放配置的格式不匹配导致无法解码。
疑点确认
有了初步的怀疑方向,就需要抓取数据验证怀疑,此时确认该疑点最好的方法便是分析I2S数据波形。由于手头上有一个DSLogic U3Pro16,因此直接将I2S信号脚飞出来,使用逻辑分析仪抓取波形分析。分析到的数据如下:
从数据上看,SDO脚信号明显是有数据(播放音乐时,SDO脚数据明显存在较大幅度的数值变化),且数据正常。但查看WCK频率则明显反常,一般32bit I2S配置都是MCLK = 4 * BCK = 64 * LRCK,而抓取到的数据提示是 BCK(48KHz) = 32 LRCK(1.53MHz),也就意味着安卓端I2S的工作模式为16bit模式(非16bit 32位每通道传输模式)。而结合供应商提供的功放驱动中的配置目录提示配置文件为I2S 32bit工作模式的情况,初步确认此问题属于功放I2S配置与源端提供I2S波形不匹配导致的问题。
问题解决
既然锁定了问题原因,剩下的就是针对性解决问题。此时将待调试板卡的I2C脚接出,在功放工作时,使用供应商提供的demo板的I2C跳接至待调试小板上,在线将I2S工作模式设置为16bit,且将BCK设置为32倍LRCK,喇叭出声,问题确认。
问题确认后,后续收尾步骤为将调试小板的配置导入驱动,重新编译固件烧录验证,确认出声音后代表问题已解决。