Linux alsa驱动中的CODEC寄存器配置问题

您所在的位置:网站首页 lookat怎么读语音 Linux alsa驱动中的CODEC寄存器配置问题

Linux alsa驱动中的CODEC寄存器配置问题

#Linux alsa驱动中的CODEC寄存器配置问题| 来源: 网络整理| 查看: 265

 调试Audio CODEC时,有时候需要读codec寄存器的值以确认是否配置寄存器成功。  记得之前调试wm8978时,发现这个CODEC的寄存器不能读,每次读的结果都是0xff.  后来在linux上调试wm8978时,用snd_soc_read()又能读到所配置的值,感觉很诧异。当时也没有细究。  这两天有空,在linux内核中看了一下相关代码,发现关于通过I2C读写CODEC的代码在 sound/soc/soc-cache.c中。  在这个.c文件中定义了不少类似 snd_soc_X_Y_read() 和 snd_soc_X_Y_write()的函数,X代表地址位数,Y代码  数据位数,例如snd_soc_7_9_read()用于地址是7位,数据是9位的CODEC,wolfson的CODEC大多数是这种情况。  另外有个用于具体的CODEC驱动去设置X,Y值的接口,以便选择对应的读写函数,这个接口是:     int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,                 int addr_bits, int data_bits,                 enum snd_soc_control_type control)  例如wm8960.c中有如下配置调用:       ret =snd_soc_codec_set_cache_io(codec,7,9,control);         现在说一下snd_soc_X_Y_write()这类函数,例如:   static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,          unsigned int reg)   {    u16 *cache = codec->reg_cache;    if (reg >= codec->reg_cache_size)     return -1;    return cache[reg];   }     一看代码,原来这里的读,竟然不是从CODEC的寄存器中读出来的,而是从一个cache缓存中读出来的。  再看一下对应的write函数就一清二楚了,原来在write时将所写的寄存器的值同时缓存到cache中,read时  直接从cache中读出。         static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,         unsigned int value)   {    u16 *cache = codec->reg_cache;    u8 data[2];    int ret;

   BUG_ON(codec->volatile_register);

   data[0] = (reg > 8) & 0x0001);    data[1] = value & 0x00ff;

   if (reg < codec->reg_cache_size)     cache[reg] = value;

   if (codec->cache_only) {     codec->cache_sync = 1;     return 0;    }

   dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);

   ret = codec->hw_write(codec->control_data, data, 2);    if (ret == 2)     return 0;    if (ret < 0)     return ret;    else     return -EIO;   }     这样,近期一个奇怪的问题又有好解释了:       通过I2C配置sensor后,通过aplay播放音乐无动静(无声音),但通过snd_soc_read()读CODEC(wm8960)各寄存器的值  又是正常的(和能正常播放时的配置一样),用示波器量了一下CODEC的LRCK管脚,没有任何东西(本应该有clock输出的,因为  CODEC被配置为master模式)。原来snd_soc_read()读到的值根本就是之前写进去的缓存,并不是真正CODEC中已经配置的值,  显然CODEC没有正常配置,所以没有LRCK信号输出。       



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3