This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AIC3104环境底噪问题,已再次上传wav格式录音文件,请帮忙分析

Other Parts Discussed in Thread: TLV320AIC3104

AIC3104如果关掉AGC,PGA设置为0,无环境底噪,声音听起来不错,但是灵敏度很差,必须嘴对着MIC说话才有很好的效果,PGA设置越高,环境底噪就越大。

如果开启AGC,PGA设置为0,无论怎么调NOISE threshold和Target level和AGC GAIN,环境底噪始终存在。这个环境底噪是要通过设置寄存器的参数来消除吗?能给出参考设置吗?

  • 其它的语音方案拾音效果非常好,一点环境底噪都没有,用TI的这个芯片就存在这样的问题,请ti的人员帮忙看看,应该从硬件和软件上注意什么吗?请问出一点建议。

  • 你好:

    开PGA把噪声放大是肯定的,PGA放大,是会和噪声一起放大的。

    输出您是用的HP还是Speaker输出,还是line out输出?有可能是Out of band noise。

    还有,硬件上,你查一下电源,地的情况,看一看是否是地噪声引起的。

    MIC输入是差分输入吗?

     

  • 我们现在只实现录音,录音数据是传输到PC端,用windows7自带的录音软件进行测试的。硬件上电源和地都隔离了,之前没有隔离的时候有其它噪声,隔离后就没有了。MIC是差分输入。

    现在录音声音都还是可以的,就是想要把环境噪声给过滤掉,或者将环境噪声降到最低。是不是要调AGC这些参数,可是我们调来调去,效果都不是很好。主要是我们有个其它codec的参考平台,效果和参考平台差距挺大。

  • 首先给您分享一个我私藏的文件:

                                                                                                     TLV320AIC310X音频CODEC内部寄存器的正确配置

      

                                                                                                                                          聂景贵        德州仪器应用工程师

             摘要

     

    TLV320AIC310X,TI通用音频CODEC系列,包含有AIC3101/04/05/06/07。 以其优越的音质效果,灵活的信号处理能力,被广泛应用于便提式消费类电子产品中,例如音乐手机,PMP,DV,录音笔等。然而,对于许多初始接触此类CODEC的工程师来讲,面对名目繁多,使用灵活的内部寄存器设置时,要正确理解使用该器件仍然是一件比较困难的事。

     

    本文详细讨论了AIC310X内部寄存器设置的含义,以帮助产品研发人员正确理解内部寄存器的含义,充分发挥该类器件的功能及缩短产品研发周期。本文所包含实例中寄存器的配置可以直接移植到用户应用系统主程序之中,无需作任何修改或仅仅作极少数的调整根据不同设置要求,例如系统主时钟区别,输入输出端子不同组合等。

     

     


    1   AIC310X内部寄存器的分配

    AIC310X内部寄存器被分配成两页:Page0和Page1。Page0寄存器用于器件功能的配置,Page1仅用于音效处理数字滤波器系数的设置,例如,低音加重,3D音效等。尽管每一页含有多达128个寄存器(包含保留寄存器以及只读寄存器),事实上,在许多应用场合下,用户仅需要对少数几个寄存器对其进行操作,而绝大数可以使用其默认值,无需任何操作。

    AIC310X内部寄存器I2C读写格式如下

     

     

    本文以AIC3104为例,针对其内部不同的功能模块以应用实例的方式,对相关寄存器作详细的探讨,以方便用户根据应用要求正确理解与配置AIC310X内部寄存器。

     

    提示1:在AIC310X音频CODEC初始上电时,必须确保至少10ns 以上的硬件复位低周期,以便后续I2C读写正常。

     

    2   AIC310X内部时钟,I2S接口,输出级配置寄存器

    下述功能模块寄存器的配置可以在系统初始化时被执行,在应用中系统主处理器不会对其进行频繁的操作。

    2.1 时钟寄存器

    AIC310X内部时钟的产生非常灵活,一个显著的特点是即使在系统不能提供主时钟(MCLK)的情况下,仍可以由音频接口的位时钟(BCLK)来产生CODEC内部所需要的所有动作时钟。有两个通路用于时钟的产生,对于常规音频输入主时钟,例如11.2896 MHz /12.288MHz,AIC310X可以使用内部整数倍分频器(Q值),以降低系统的功耗。其他时钟如12M,13MHz 等非常规音频主时钟,可以利用内部PLL来精密产生。AIC310X时钟寄存器由Register(简写成Reg) 2到7以及11,101,102所组成,其时钟配置树及对应的寄存器如图1所示,粗体为上电默认值。

     

          

                              

             图 1      AIC310X 内部时钟产生流程

    实例1:24MHz系统主时钟(MCLK)输入,使用PLL,ADC/DAC采样频率为48KHz,配置PLL的P.R.J.D值如下:

    P=2,   R=1,    J=8,    D=1920

     

    时钟寄存器设置如下:

     

    W30  65  00          使用PLL来产生codec内部时钟

    W30  07  00          选择48KHz参考采样频率

    W30  03  P2          允许PLL,P=2

    W30  04  20           J=8

    W30  05  1E           1E为D值的高8位

    W30  06  00           00为D值的低6位

     

    提示2:D值的转换(十进制转换为D值2个16进制值)

    Step 1: 转换十进制D值到16进制,再到二进制

    1920=0x780H=0111 10000000B

    Step 2: 未满14位二进制值补足零到高位以形成完整的14位二进制值

    0111 1000 0000B==00 0111 1000 0000B

    Step 3: 根据D值寄存器存贮的规定,补足两个零到上述14位D值的低位以形成两个完整的字节(寄存器6要求D1.D0位为00 )

    00 0111 1000 0000B →00 0111 1000 0000 00B

    Step 4: 将上述16位二进制值分成2个字节分别用于Reg 6和5

    Reg 6=00 0111 10=1E  .Reg 5=00 0000 00=00

     

    提示3:Reg 5的写入必须立即紧跟着 Reg 6,两个寄存器必须同时写入以确保PLL正常动作。

     

    提示4:在配置完PLL后,必须等待50ms以上再上电 ADC 或DAC。

     

    2.2 音频I2S接口寄存器

     

    AIC310X除支持标准格式音频接口外,还支持分时复用模式(TDM),几个音频CODEC可以共享一根I2S总线,节省此类应用中主处理的硬件资源。另外,AIC310X的音频接口可根据系统要求灵活地配置成I2S主模式(BCLK/WCLK由AIC310X产生)或从模式(BCLK/WCLK输入到AIC310X),Reg 8.9.10控制AIC310X音频接口。

     

    Reg 8: D7-D6  接口主从模式控制

             11   主模式, BCLK/WCLK从AIC310X输出

    00   从模式, BCLK/WCLK输入到AIC310X

    D5  仅分时复用(TDM)时使用

                                     0   I2S DATA线不设置为高阻状态

    1   I2S DATA线设置为高阻状态

    D4  仅主模式时使用

    0   当内部ADC以及DAC POWER Off时BCLK/WCLK停止输出

    1   当内部ADC以及DAC POWER Off时BCLK/WCLK仍在输出

     

    Reg 9: D7-D6  数据接口模式选择

    00=I2S       01=DSP      10=RJ        11=LJ

    D5-D4  数据字长选择

    00=16bits    01=20bits   10=24bits    11=32bits

    D3  仅有效于主模式

    0    连续BCLK时钟输出,每WCLK中BCLK时钟数目= 2X数据字长

    1    固定BCLK时钟输出,每WCLK中BCLK时钟数目= 256

          D2-D1  ADC/DAC重新同步

    1    当一帧中群时延超过±1/4fs时重新自动同步CODEC时钟

    0    不重新同步

    D0  重新同步时静音的动作

    1    重新同步期间,ADC/DAC自动静音

    0    重新同步期间,ADC/DAC 并不自动静音

     

    Reg10: 通常仅用于分时复用模式(TDM),用于控制在一帧中数据起始位的位置。

     

    提示5:建议在正常应用中当 Reg 9 D2D1D0设置为1,以消除由于数据(DATA)输入不同步而产生的杂音现象

     

    实例2:配置音频接口主模式,24位,I2S格式

     

             W30 08 D0            接口主模式,即使在ADC以及DAC POWER Off时BCLK/WCLK仍有输出

             W30 09 27            24bit ,I2S格式,允许重新同步

     

    2.3 输出级配置

    Reg 14.38.40.42设置了AIC310X输出端子的连接模式,共模电压(直流偏置电压)及电容输出型驱动器上电延时等。

     

    Reg 14   配置HPLOUT/HPROUT及HPLCOM/HPRCOM输出端子连接方式,图2是二种典型的应用:

     

     

     

                                Cap mode Stereo Headphone

                                External Stereo Single-end Amp

                                          Stereo Line out

                                               (1)

     

        

                                     Cap mode Stereo headphone

                                     External Mono Differential Amp

                               Stereo Line out

                          (2)

     

    图 2    AIC310X 常用输出配置

     

    Reg 38   输出级驱动器短路检测, 建议使用默认值

    Reg 40   根据CODEC的电源电压配置适当的输出直流偏置电压,以获取无失真信号最大摆幅

    Reg 42   控制输出直流偏压对输出电容充电的速度以消除电容输出应用时的POP声

     

    实例3:3.3V CODEC 电源, HPLOUT/HPROUT电容型输出

     

    W30 0E 80            电容型输出

    W30 28 40            输出直流偏压电压设定为1.65V

    W30 2A 8E            输出级上升延时400ms,信号上升时间4ms

     

    3. ADC通道寄存器

     

    相对于其他类型的CODEC,AIC310X ADC通道增加了两个附加功能:AGC及数字音效处理。它们可以对输入信号进行数字域的处理以进一步地改善录制信号质量,相关寄存器的配置将在章节5中详细讨论。除此之外,由Reg 15 到 Reg 25 控制模拟输入到ADC通道的选择及ADC的动作 。

    AIC310X的模拟输入增加了许多灵活性,包括通道间混音,通道间自由切换,通道间输入电平的匹配(例如FM信号输入与基带信号输入),支持差分或单端输入(AIC3105除外) 等。内部集成的低噪声PGA(可编程增益放大器)可用于小信号的放大,可选的偏置电压输出支持了多种麦克风偏置电压的要求。

     

    AIC310X ADC通道模拟输入及相应的控制寄存器如图3所示(以AIC3104 为例)

                图3      ADC通道模拟输入及相应的控制寄存器            

    实例4:单端MIC从AIC310X MIC1/LP输入。MIC偏置电压为2.5V,放大增益为26dB。I2S L/R通道同时输出麦克风信号

        W30 13 04           连接MIC1LP到  L-PGA,MIC1设置为单端输入模式,L-ADC上电

    W30 18 00           同时连接MIC1LP到R-PGA

    W30 16 7C           R-ADC上电

    W30 19 40           麦克风偏置电压为2.5V

    W30 0F 34           L-PGA增益设定为26dB

    W30 10 34           R-PGA增益设定为26dB

    4. DAC模拟输出通道

    AIC310X模拟输出比较灵活,图4显示了DAC及模拟输出通道相关寄存器的设置。

                   图4       DAC及模拟输出通道寄存器的设置

                                                   

    提示3: ① AIC310X支持3路DAC输出,DAC-1/DAC-2/DAC-3,建议应用中仅适用DAC-1输出,以简化寄存器设置,提高系统的性能。

    所有模拟输出端子可实行电平的调整,建议正常应用中电平设置值为0dB,最大不应大于3dB。

    ③ AIC 310X支持模拟及数字音量调整,建议使用模拟音量调整。

    ④ HPLCOM/HPRCOM独立应用时,注意寄存器的设置顺序如实例7,8所示。

     

    实例5:配置图2(1)所示的输出,Stereo Headphone, Stereo external audio amplifier.     

    W30 25 E0           L-DAC/R-DAC上电,HPLCOM独立单端输出

    W30 29 01           L-DAC选择DAC-L1,R-DAC选择 DAC-R1,左通道DAC数字音量跟随右通道音量值。

    W30 2C 09           设置DAC数字音量=0dB。

    W30 26 10           HPRCOM独立单端输出。

    W30 33 00           HPLOUT上电非静音,电平设置= 0dB

    W30 2F 80           HPLOUT通道模拟音量设置,DAC-L1引入到HPLOUT,音量= 0dB

    W30 3A 00           HPLCOM上电非静音,电平设置=0dB

    W30 36 80           HPLCOM模拟音量设置, DAC-L1引入到HPLCOM,音量=0dB

    W30 41 00           HPROUT上电,非静音,电平设置=0dB

    W30 40 80           HPROUT模拟音量设置,DAC-R1引入到HPROUT,音量=0dB

    W30 48 00           HPRCOM上电非静音,电平=0dB

    W30 47 80           HPRCOM模拟音量设置DAC-R1引入到HPRCOM,音量=0dB

    W30 07 8A           L-DAC播放I2S-L输入信号, R-DAC播放I2S-R输入信号

     

     实例6:配置图2⑵所示的输出, Stereo Headphone, Differential Mono audio amplifier, Stereo Line out

    W30 25 E0          同实例5

    W30 29 01          同实例5

    W30 2C 00          同实例5

    W30 26 18          HPRCOM配置成HPLCOM的差分对

    W30 52 80          DAC-L1引入到线性输出端子,音量=0dB

    W30 5C 80          DAC-R1引入到线性输出端子,音量=0dB

    W30 56 09          L路线性输出端子上电非静音,电平设置=0dB

    W30 5D 09          R路线性输出端子上电非静音,电平设置=0dB

    W30 33 00          同实例5

    W30 2F 80          同实例5

    W30 3A 00          同实例5

    W30 36 8C          DAC-L1引入到HPLCOM,音量=-6dB

    W30 39 8C          DAC-R1引入到HPLCOM,音量=-6dB

    注:R36,R39将左右路输入信号混合以产生单声道输出信号

                                W30 41 00          同实例5

                                W30 40 80          同实例5

                                W30 07 8A          同实例5

     

    5   AIC310X附加功能

    三个附加功能进一步增强AIC310X音色处理效果及应用灵活性。

    ①AGC

    ②数字音效滤波器

    ③模拟有源及无源旁路直通

    5.1 AGC

    为了提高语音录制效果,AIC310X提供了AGC功能来维持录音电平的恒定输出及减少环境噪声,9个专用寄存器Reg 26到R35控制了整个的动作。理解AGC的几个变量有助于正确设置AGC的参数

                                 Target Gain               录音信号最终恒定输出电平值

                                 Attack Time               决定了AGC降低PGA增益的速度

                                 Decay Time                决定了AGC增加PGA增益的速度

                                 Noise gate threshold      输入信号平均能量低于此值时,AGC认为是噪声而保持输出在静音

                                 Max PGA gain applicable   AGC能够放大输入信号的增益最大值

                                 Hysteresis                用于消除AGC动作时的呼吸效应

                                 Noise detect Debounce     设定一个时间窗口来检测输入噪声信号电平

                                 Signal detect Debounce    设定一个时间窗口来检测输入信号电平

     

    提示7:① AGC Max PGA Gain applicable( 简称AGC Gain)与PGA Gain 关联动作

    当PGA Gain>AGC Gain时,AGC放大信号最大增益由AGC Gain决定。当PGA Gain<AGC Gain,AGC放大信号的最大增益由PGA Gain决定。

    ② Hysteresis动作原理是:

    AGC输出从静音转变为正常语音信号输出仅当输入信号电平≥ Noise gate threshold + Hysteresis。

    AGC输出从正常语音信号转变为静音输出仅当输入信号电平≤ Noise gate threshold - Hysteresis。

    Hysteresis 的动作如图5 所示,目的是减少临界状态(Noise gate threshold)时AGC呼吸效应。

     

                       

                          图5      Hysteresis 的动作

     

    ③ AGC功能的最佳应用需要有一定的经验及技巧,尤其是Noise gate threshold及Hysteresis的设置

       Step1 :  在没有语音信号输入时,降低Max PGA gain applicable 以使输出噪声达到可接受水平。

       Step2 :  输入最低的语音信号,增加Noise gate threshold以事轻微信号可以被放大或检测。 

       Step3 :  如果语音信号在结尾时比较嘈杂,减少Decay Time。如果语音信号在开始时较差,增加Attack Time

       Step4 :  反复调整AGC 变量以获得最佳录制语音信号

     

    实例8  环境噪声相对于输入信号幅度较小。AGC 变量设置如下:

                      Target gain = -5.5 db

                      Attack time = 20ms,Decay time = 500ms

                      Noise threshold = -84db

                      Maximum gain applicable =32db

                      Hysteresis = 1db

                      Noise detect debounce = 512ms,Signal detect debounce = 32ms

            寄存器设置值如下:

                      W30 1A 8F         Left AGC enable, Target gain = -5.5db, Attack time = 20ms, decay time = 500ms

                      W30 1B 9A         Left AGC Maximum gain applicable = 32db

                      W30 1C 38         Left AGC Hysteresis =1db, noise threshold = -84db

                      W30 22 7F         Left AGC Noise detect debounce = 512ms, signal debounce = 32ms

                      W30 1D 8F         Right AGC enable, Target gain = -5.5db, Attack = 20ms, decay = 500ms

                      W30 1E 9A         Right AGC Maximum gain applicable = 32db

                      W30 1C 38         Right AGC Hysteresis =1db, noise threshold = -84db

                      W30 23 7F         Right AGC Noise detect debounce = 512ms, signal debounce = 32ms

     

    实例8  环境噪声相对于输入信号幅度较大,AGC 变量设置如下:

                      Target gain = -5.5 db

                      Attack time = 20ms,Decay time = 500ms

                      Noise threshold = -80db

                      Maximum gain applicable =30db

                      Hysteresis = 3db

                      Noise detect debounce = 512ms,Signal detect debounce = 32ms

             寄存器设置值如下:

                      W30 1A 8F         Left AGC enable, Target gain = -5.5db, Attack time = 20ms, decay time = 500ms

                      W30 1B 96         Left AGC Maximum gain applicable = 30db

                      W30 1C b6         Left AGC Hysteresis =3db, noise threshold = -80db

                      W30 22 7F         Left AGC Noise detect debounce = 512ms, signal debounce = 32ms

                      W30 1D 8F         Right AGC enable, Target gain = -5.5db, Attack time = 20ms, decay time = 500ms

                      W30 1E 96         Right AGC Maximum gain applicable = 30db

                      W30 1C b6         Right AGC Hysteresis =3db, noise threshold = -80db

                      W30 23 7F         Right AGC Noise detect debounce = 512ms, signal debounce = 32ms

     

    6.2 数字音效处理滤波器

    AIC310X提供了各种数字音效处理以进一步提高音质效果,低音加重/EQ/3D是最普遍的应用。Page1寄存器用于存放数字音效处理滤波器的设置值。

     

    提示8:① 为了方便音效滤波器系数的生成,请至www.ti.com下载TLV320AIC310XEVM演示软件,利用此软件可方便用户生成各种音效处理的滤波器系数值。

    在应用中,动态更改音效时,请注意以下寄存器写入时序

            Step1  取消数字音效处理器

    Step2  转到Page1

    Step3  写入新的滤波器设置值到相关寄存器

    Step4  转回Page0

    Step4  重新允许数字音效处理器

    实例9:由其他音效转为3D音效,3D具有较强的扩展深度。

                      W30 0C 00          取消数字音效处理器 Reg12 D3D2D1D0 = 0000

    W30 00 01          转到Page1

    W30 35 7F 7F       3D 扩展深度系数

    W30 00 00          转到Page0

    W30 08 04          3D音效处理允许  Reg8 D2 = 1

     

    实例10:由3D音效转为EQ音效。EQ中心频率400Hz,带宽200Hz,增益9dB

                      W30 08 00          3D音效处理关闭  Reg8 D2 = 0

    W30 0C 00          # 取消数字音效处理器 (仅在动态调整数字音效滤波器系数写入)

    W30 00 01          转到Page1

    W30 01 7F FF       Left通道滤波器系数

    W30 03 85 25       Left通道滤波器系数

    W30 05 76 1D       Left通道滤波器系数

    W30 07 00 00       Left通道滤波器系数

    W30 09 41 A3       Left通道滤波器系数

    W30 0B 00 00       Left通道滤波器系数

    W30 0D 7D FF       Left通道滤波器系数

    W30 0F 83 99       Left通道滤波器系数

    W30 11 00 00       Left通道滤波器系数

    W30 13 00 00       Left通道滤波器系数

    W30 15 3A F3       Left通道滤波器系数

    W30 17 F4 C3       Left通道滤波器系数

    W30 19 50 4B       Left通道滤波器系数

    W30 1B 7F 7F       Left通道滤波器系数

    W30 1D 85 25       Right通道滤波器系数

    W30 1F 76 1D       Right通道滤波器系数

    W30 21 00 00       Right通道滤波器系数

    W30 23 41 A3       Right通道滤波器系数

    W30 25 00 00       Right通道滤波器系数

    W30 27 7D FF       Right通道滤波器系数

    W30 29 83 99       Right通道滤波器系数

    W30 2B 00 00       Right通道滤波器系数

    W30 2D 00 00       Right通道滤波器系数

    W30 2F 3A F3       Right通道滤波器系数

    W30 31 F4 C3       Right通道滤波器系数

    W30 33 50 4B       Right通道滤波器系数

    W30 00 00          转到Page0

    W30 0C 0A          打开数字音效处理器 Reg12 D3=1,D1 = 1

     

    6.3   模拟有源及无源旁边直通

     

    6.3.1 有源PGA输出旁边

    PGA的输出可以旁路ADC及DAC而直接引入到所有输出端子,其设置和DAC输出完全一样,仅仅相关寄存器序号相差数值1, 例如:

    PGA_L/R到HPL/Rout               DAC_L/R到HPL/Rout

    W30 2E 80                       W30 2F 80

    W30 3F 80                       W30 40 80

    6.3.2 无源旁边功能

    无源旁边直通可以将输入信号直接从输入端子引到输出端子,旁路掉内部所有电路,此种模式可以工作在无时钟状态。

             

    提示9: AIC3104无源旁边功能仅有效于MIC/Line1通道,MIC/Line2通道无此功能。         

     

    实例11: 引入MIC1LP/RP到LEFT_LOP / RIGHT_LOP

                               

    W30 6C 11          MIC1LP to LEFT_LOP, MIC1RP to RIGHT_LOP

    7   结束语

     

    本文以应用实例的方式详细叙述了AIC310X 内部功能模块寄存器的设置,最终的应用可参考各功能模块应用实例中寄存器的设置参数来作相应的调整。有关详细的寄存器描述请参考AIC310X相关器件的数据手册。应用中注意提示部分的内容。

     

    8   参考文献

          1:TLV320AIC3104,LOW-POWER STEREO AUDIO CODEC FOR PORTABLE AUDIO/TELEPHONY, 数据手册.

        2: TLV320AIC3104 Programming Made Easy,TLV320AIC3104应用报告, WWW.TI.COM

     

       
    这前两周一直在调AIC3104的驱动,这是个音频codec芯片,可以实现语音对讲功能。AIC3104是通过I2C方式与CPU通信,来设置寄存器,另外是IIS接口进行语音的Mic_in和Line_out功能。已经通了。能够实现功能了。。刚好给楼主分享下。楼主可以参考参考。。
    下面是aic3104的驱动源代码:
    1. /*   extdrv/peripheral/vda/adv7179.c 
    2.  * 
    3.  * 
    4.  * Copyright (c) 2006 Hisilicon Co., Ltd. 
    5.  * 
    6.  * This program is free software; you can redistribute it and/or modify 
    7.  * it under the terms of the GNU General Public License as published by 
    8.  * the Free Software Foundation; either version 2 of the License, or 
    9.  * (at your option) any later version. 
    10.  * 
    11.  * This program is distributed in the hope that it will be useful, 
    12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    14.  * GNU General Public License for more details. 
    15.  * 
    16.  * You should have received a copy of the GNU General Public License 
    17.  * along with this program. 
    18.  * 
    19.  * 
    20.  * History: 
    21.  *     17-Apr-2006 create this file 
    22.  * 
    23.  */  
    24. #include <linux/unistd.h>  
    25. #include <linux/module.h>  
    26. //#include <linux/config.h>  
    27. #include <linux/errno.h>  
    28. #include <linux/miscdevice.h>  
    29. #include <linux/fcntl.h>  
    30. #include <linux/init.h>  
    31. #include <linux/delay.h>  
    32. #include <linux/proc_fs.h>  
    33. #include <linux/workqueue.h>  
    34. #include <asm/uaccess.h>  
    35. #include <asm/system.h>  
    36. #include <asm/io.h>  
    37. //#include <linux/kcom.h>  
    38. #include <linux/random.h>  
    39. //#include "stapp_main.h"  
    40. #include "sti7105.h"  
    41. #include "stsys.h"  
    42. #include "stddefs.h"  
    43. #include "sti2c.h"  
    44. #include "staudlx_aic3104.h"  
    45. //#include "stcommon.h"  
    46. //#include "stavmem.h"  
    47. ///////////////////////PRE-DEFINITIONS/////////////////////////  
    48. //module name string  
    49. #define MOD_STR     "aic3104"  
    50. #define MOD_STR_E    "aic3104 ERROR"  
    51. //chip and id register addr  
    52. #define CHIP_A_I2C_ADDR  0x30//0x30//0x18  
    53. #define I2C0 0x00  
    54. //#define TRUE (bool) 1  
    55. /*************************************************** 
    56.  (1). AIC3104 I2S work mode 
    57. Define 0xd0 if work as master 
    58. Define 0x00 if work as slave 
    59. ***************************************************/  
    60. #define AIC3104_WORK_MODE  0x00  
    61. /*************************************************** 
    62. (2). Global debug info switch 
    63. ***************************************************/  
    64. #define GLOBAL_DEBUG  
    65. //AIC3104 version info.  
    66. #define AIC3104_VER_MIN  0//  0~63  
    67. #define AIC3104_VER_SEC  0//  0~63  
    68. #define AIC3104_VER_MAJ  1//  0~31  
    69. #define AIC3104_VER_DAY  25// 1~31  
    70. #define AIC3104_VER_MON  3// 1~12  
    71. #define AIC3104_VER_YER  10// 00~63  
    72.   
    73. static STI2C_Handle_t i2c_handle;  
    74. static int nbpages = 0, chains[2] = {0,0};  
    75.    
    76. typedef enum _tagDRV_ERR_CODE_  
    77. {  
    78.  //general return code  
    79.  NO_ERROR = 0,  
    80.  ERR_NO_DEV ,  
    81.  ERR_GPIO_I2C_RD,  
    82.  ERR_GPIO_I2C_WR,  
    83.  ERR_VERSION_CHK,  
    84.  ERR_DRV_REG,  
    85.  ERR_OUT_OF_RANGE,  
    86.  ERR_INVALID_CMD  
    87. }DRV_ERR_CODE;  
    88. /* 
    89. ST_ErrorCode_t STI2C_Read (   STI2C_Handle_t Handle,         //chip, I2CHandle 
    90.                               U8             *Buffer_p,                     //read reg 
    91.                               U32            MaxLen,                       //MAX_BYTE_READ,  
    92.                               U32            Timeout,                     //100, 
    93.                               U32            *ActLen_p)                //target buffer 
    94. ST_ErrorCode_t STI2C_Write(   STI2C_Handle_t Handle,// ----chip 
    95.                               const U8       *Buffer_p,           //write reg 
    96.                               U32            NumberToWrite,      // -- bytes 
    97.                               U32            Timeout,              //new 
    98.                               U32            *ActLen_p)         //  source buffer 
    99. //#define cfg_bytes_write(chip, reg, buf, bytes)    gpio_i2c_write_multi(chip, reg, buf, bytes) 
    100. //#define cfg_bytes_read(chip, reg, buf, bytes)    gpio_i2c_read_multi(chip, reg, buf, bytes) 
    101. */  
    102. //#define cfg_bytes_write(buf,NumToWrite,Timeout,nwrite)  STI2C_Write(i2c_handle,buf, NumToWrite, Timeout, nwrite)  
    103. //#define cfg_bytes_read(buf,NumToRead,Timeout,nread)  STI2C_Read(i2c_handle,buf, NumToRead, Timeout, nread)  
    104.   
    105. /// 模块软件版本定义  
    106. typedef struct {  
    107.   unsigned  minver : 6; //  0~63  
    108.   unsigned  secver : 6; //  0~63  
    109.   unsigned  majver : 5; //  0~31  
    110.   unsigned  day : 5; // 日: 1~31  
    111.   unsigned  month : 4; // 月: 1~12  
    112.   unsigned  year : 6; // 年: 2000~2063  
    113. } SWVERSION, *PSWVERSION;  
    114. #define VINFO2STR(str, v) sprintf(str, "V%d.%d.%d build%04d%02d%02d\n", v.majver, v.secver, v.minver, v.year+2000, v.month, v.day)  
    115. /* 
    116. typedef  struct {                                  
    117.         int minor;                         
    118.         const char *name;                  
    119.         const struct file_operations *fops; 
    120.              
    121. } miscdevice; 
    122. */  
    123. typedef struct aic3104_information {  
    124.  U8 *Buffer_p;   
    125.  U32 Size;  
    126. } aic3104_info_t;  
    127. //data type  
    128. /*typedef unsigned char U8; 
    129. typedef signed char S8; 
    130. typedef unsigned short U16; 
    131. typedef signed short S16; 
    132. typedef unsigned int U32; 
    133. typedef signed int S32;*/  
    134. ///////////////////////PRE-DEFINITIONS/////////////////////////  
    135. static const U8 *MODULE_NAME = NULL, *MODULE_NAME_E = NULL;  
    136. //aic3104初始化数据,拷贝自杨总的代码,未作任何修改  
    137. static U8 init_data[] =  
    138. {  
    139.  2, 0x00,  
    140.  4, 0xc0,  
    141.  7, 0x0a,  
    142.  8, AIC3104_WORK_MODE,  
    143.  9, 0x08,  
    144.  14, 0x88,  
    145.  15, 0x00,  
    146.  16, 0x00,  
    147.  17, 0x0f,  
    148.  18, 0xf0,  
    149.  19, 0x7f,  
    150.  22, 0x7f,  
    151.  25, 0x80,  
    152.  37, 0xd0,  
    153.  38, 0x0c,  
    154.  40, 0x82,  
    155.  43, 0x00,  
    156.  44, 0x00,  
    157.  47, 0x80,  
    158.  51, 0x0f,  
    159.  64, 0x80,  
    160.  65, 0x0f,  
    161.  82, 0x80,  
    162.  86, 0x0b,  
    163.  92, 0x80,  
    164.  93, 0x0b,  
    165.  101, 0x01  
    166. };  
    167. ST_DeviceName_t PIO_DeviceName[] = {"PIO0","PIO1","PIO2","PIO3","PIO4","PIO5","PIO6","PIO7","PIO8","PIO9","PIO10","PIO11","PIO12","PIO13","PIO14","PIO15","PIO16","PIO17","PIO18","PIO19","PIO20","PIO21","PIO22","PIO23","PIO24","PIO25","PIO26"};  
    168. extern S32 GetAudioHoldSignal(void);  
    169. static S32 chip_detect(void)  
    170. {  
    171.         U32 ErrorCode;  
    172.  U32 nread ,nwrite;  
    173.  U8 temp_buf[2];  
    174.  if (NULL == temp_buf)  
    175.         {  
    176.   return -1;  
    177.         }  
    178.  /* aic3104 doesn't  provide read-only chip id registers, so a i2c read instead */  
    179. // if(cfg_bytes_read(CHIP_A_I2C_ADDR, 0x08, &buf, 1))  
    180.    
    181.   
    182.    
    183.  temp_buf[0] = 0x08;    
    184.  ErrorCode = STI2C_WriteNoStop(i2c_handle, temp_buf, 1, 100, &nwrite);  
    185.  if(ST_NO_ERROR != ErrorCode )  
    186.  {  
    187.   printk("I2C write addr error : 0x%x\n",ErrorCode);  
    188.   return ErrorCode;  
    189.  }  
    190.    
    191.  ErrorCode = STI2C_Read(i2c_handle, temp_buf, 1, 100, &nread);  
    192.  if(ST_NO_ERROR != ErrorCode )  
    193.  {  
    194.   printk("I2C read data error : 0x%x\n",ErrorCode);  
    195.   return ErrorCode;  
    196.  }  
    197. // printk("Reg 08 = 0x%x\n",temp_buf[0]);  
    198.  return NO_ERROR;  
    199. }  
    200. static U32 audio_detect(void)  
    201. {  
    202. #if 0  
    203.  S32 state;  
    204.  state = GetAudioHoldSignal();  
    205.    
    206.  if(state < 0)  
    207.  {  
    208.   printk("\n%s: GetAudioHoldSignal() call failed!", MODULE_NAME_E);  
    209.   return -ERR_NO_DEV;//Not support audio  
    210.  }  
    211.    
    212.  return state;  
    213. #else  
    214.  return 0;//audio is always supported  
    215. #endif  
    216. }  
    217. static S32 audio_mode_init(void)  
    218. {  
    219.  U32 i;  
    220. // U32 addr,dat;  
    221.  S32 ret = NO_ERROR;  
    222.  U32 nwrite;  
    223.  STI2C_Params_t I2C_Params;  
    224.  U32 ErrorCode;  
    225.  I2C_Params.I2cAddress = 0x30;  
    226.  I2C_Params.AddressType      = STI2C_ADDRESS_7_BITS;  
    227.         I2C_Params.BaudRate         = STI2C_RATE_NORMAL;  
    228.         I2C_Params.BusAccessTimeOut = 100000;  
    229.         ErrorCode = STI2C_SetParams(i2c_handle, &I2C_Params);  
    230.  if(ST_NO_ERROR != ErrorCode)  
    231.  {  
    232.   printk("I2C set params error:%u\n",ErrorCode);  
    233.   return -1;  
    234.  }  
    235.    
    236. // printk("I2C set params sucess!\n");  
    237.  for(i = 0; i < sizeof(init_data); i += 2)  
    238.  {  
    239.  // addr = init_data[i];  
    240.  // dat = init_data[i + 1];  
    241.     //    ret |= cfg_bytes_write(CHIP_A_I2C_ADDR,addr,&dat,1);  
    242.   ret |= STI2C_Write(i2c_handle,&init_data[i],2,100,&nwrite);  
    243.   if(ST_NO_ERROR != ErrorCode)  
    244.   {  
    245.    printk("I2C write data error : 0x%x",ErrorCode);  
    246.   }  
    247.     
    248. //  printk("init write data : [%d] >> %x\n",init_data[i],init_data[i+1]);  
    249.     
    250.   if(ret)  
    251.   {  
    252.    //printk("\n%s: i2c write failed in audio_mode_init() when write 0x%02x to 0x%02x", MODULE_NAME_E, dat, addr);  
    253.    printk("\n%s: i2c write failed in audio_mode_init() when write 0x%02x to 0x%02x", MODULE_NAME_E, init_data[i],init_data[i+1]);  
    254.    return -ERR_GPIO_I2C_WR;  
    255.   }  
    256.  }  
    257.  return NO_ERROR;  
    258. }  
    259. #ifdef GLOBAL_DEBUG  
    260. S32 reg_dump(void)  
    261. {  
    262.  U32 i;  
    263. // U32 addr, dat;  
    264.  S32 ret = NO_ERROR;  
    265.  U32 nread,nwrite;  
    266.  U8 temp_buf[54];  
    267.  U32 ErrorCode;  
    268.   
    269. // printk("start read data :\n\n\n\n");  
    270.  for(i = 0; i < sizeof(init_data); i += 2)  
    271.  {  
    272. //  addr = init_data[i];  
    273. //  dat = 0xff;  
    274.  // ret |= cfg_bytes_read(CHIP_A_I2C_ADDR, addr, &dat, 1);  
    275.   ErrorCode = STI2C_WriteNoStop(i2c_handle,&init_data[i],1,100,&nwrite);  
    276.   if(ST_NO_ERROR != ErrorCode)  
    277.   {  
    278.    printk("reg_dmup: I2C write addr error:0x%x",ErrorCode);  
    279.    return ErrorCode;  
    280.   }  
    281.   
    282. //  printk("write reg addr = %d\n",init_data[i]);  
    283.     
    284.   ErrorCode = STI2C_Read(i2c_handle,&temp_buf[i + 1],1,100,&nread);  
    285.   if(ST_NO_ERROR != ErrorCode)  
    286.   {  
    287.    printk("reg_dmup: I2C write data error:0x%x",ErrorCode);  
    288.    return ErrorCode;  
    289.   }  
    290.    
    291. //  printk("read data = 0x%x\n",temp_buf[i + 1]);  
    292. /* 
    293.   if(ErrorCode) 
    294.   { 
    295.    ret = -ERR_GPIO_I2C_RD; 
    296.    printk("\n%s: i2c read failed in reg_dump() when write 0x%02x to 0x%02x", MODULE_NAME_E, init_data[i], init_data[i+1]); 
    297.    break; 
    298.   } 
    299. */  
    300.   if(init_data[i + 1] != temp_buf[i + 1])  
    301.   {  
    302.    printk("\n%s: data verify failed in addr %d:0x%x, read out 0x%x\n", MODULE_NAME, init_data[i], init_data[i + 1], temp_buf[i + 1]);  
    303.      
    304.   }  
    305.  }  
    306.    
    307. // printk("reg_dmup: sucess!\n");  
    308.  return ret;  
    309. }  
    310. #endif  
    311.   
    312. static S32 dev_open1(struct inode * inode, struct file * file)  
    313. {  
    314.  return NO_ERROR;  
    315. }  
    316. static S32 dev_ioctl1(struct inode *inode, struct file *file, U32 cmd, U32 arg)  
    317. {  
    318. // U32 buf;  
    319.  U32 ret;  
    320.  U8 temp_buf[2];  
    321.  U32 __user *argp = (U32 __user *)arg;  
    322.  U32 nwrite;  
    323.  switch(cmd)  
    324.  {  
    325.   case AIC3104_SET_MIC_IN_MODE:  
    326.      
    327.  //  buf = 0x70;  
    328.    temp_buf[0] = 0x15;  
    329.    temp_buf[1] = 0x70;  
    330.  //  ret = cfg_bytes_write(CHIP_A_I2C_ADDR, 0x15, &buf, 1);  
    331.    ret = STI2C_Write(i2c_handle,temp_buf,2,100,&nwrite);  
    332.    if(ST_NO_ERROR != ret)   
    333.    {  
    334.     printk("dev_ioctl: i2c write error :0x%x ",ret);  
    335.    }    
    336.    
    337.  //  buf = 0x40;  
    338.    temp_buf[0] = 0x25;  
    339.    temp_buf[1] = 0x40;  
    340.  //  ret |= cfg_bytes_write(CHIP_A_I2C_ADDR, 0x25, &buf, 1);  
    341.    ret = STI2C_Write(i2c_handle, temp_buf,2,100,&nwrite);  
    342.    if(ret)  
    343.    {  
    344.     printk("\n%s: i2c write failed in mic in setting", MODULE_NAME_E);  
    345.     return -AIC3104_SET_MIC_IN_MODE_FAIL;  
    346.    }  
    347.    break;  
    348.   case AIC3104_SET_LINE_IN_MODE:  
    349.      
    350.   // buf = 0x00;  
    351.    temp_buf[0] = 0x15;  
    352.    temp_buf[1] = 0x00;  
    353.   // ret = cfg_bytes_write(CHIP_A_I2C_ADDR, 0x15, &buf, 1);  
    354.    ret = STI2C_Write(i2c_handle,temp_buf,2,100,&nwrite);  
    355.    if(ST_NO_ERROR != ret)   
    356.    {  
    357.     printk("dev_ioctl: i2c write error :0x%x ",ret);  
    358.    }  
    359.   
    360.   // buf = 0x00;  
    361.    temp_buf[0] = 0x25;  
    362.    temp_buf[1] = 0x00;  
    363.   // ret |= cfg_bytes_write(CHIP_A_I2C_ADDR, 0x25, &buf, 1);  
    364.    ret = STI2C_Write(i2c_handle,temp_buf,2,100,&nwrite);  
    365.    if(ret)  
    366.    {  
    367.     printk("\n%s: i2c write failed in mic in setting", MODULE_NAME_E);  
    368.     return -AIC3104_SET_MIC_IN_MODE_FAIL;  
    369.    }  
    370.    break;  
    371.   case AIC3104_GET_SW_VER:  
    372.    {  
    373.     SWVERSION ver;  
    374.     ver.day = AIC3104_VER_DAY;  
    375.     ver.month = AIC3104_VER_MON;  
    376.     ver.year = AIC3104_VER_YER;  
    377.     ver.minver = AIC3104_VER_MIN;  
    378.     ver.secver = AIC3104_VER_SEC;  
    379.     ver.majver = AIC3104_VER_MAJ;  
    380.     if(copy_to_user(argp, &ver, sizeof(SWVERSION)))  
    381.     {  
    382.      printk("\n%s: GET_SW_VERSION copy_to_user() failed.", MODULE_NAME_E);  
    383.      return -AIC3104_GET_SW_VER_FAIL;  
    384.     }  
    385.    }  
    386.    break;  
    387.     
    388.   default:  
    389.    printk("\n%s: un-supported ioctl command[0x%08x]!", MODULE_NAME_E, cmd);  
    390.    return -AIC3104_IOCTL_FAIL;  
    391.  }  
    392.  return AIC3104_IOCTL_OK;  
    393. }  
    394. static  U32 dev_close1(struct inode * inodep, struct file * filep)  
    395. {  
    396.  return NO_ERROR;  
    397. }  
    398. /* 
    399.  *  The various file operations we support. 
    400.  */  
    401. static struct file_operations dev_fops =  
    402. {  
    403.  .owner = THIS_MODULE,  
    404.  .open = dev_open1,  
    405.  .ioctl  = dev_ioctl1,  
    406.  .release = dev_close1  
    407. };  
    408. static struct miscdevice device_driver =  
    409. {  
    410.  MISC_DYNAMIC_MINOR,  
    411.  "aic3104",  
    412.  &dev_fops  
    413. };  
    414. static void chip_init(void)  
    415. {  
    416. //#if(!RST_FOR_HB8016T)  
    417. #if 0  
    418.  U8 i;  
    419.  U32 j;  
    420.  ////Reset aic3104 in 7024T  
    421.  //set as a gpio  
    422.  j = HW_REG32(PORT_26_MODE);  
    423.  j &= 0xfc;  
    424.  HW_REG32(PORT_26_MODE) = j;  
    425.  //disable INT  
    426.  i = HW_REG8(GPIO_2_IE);  
    427.  i &= 0xbf;  
    428.  HW_REG8(GPIO_2_IE) = i;  
    429.  //set reset-port as output  
    430.  i = HW_REG8(GPIO_2_DIR);  
    431.  i |= 0x40;  
    432.  HW_REG8(GPIO_2_DIR) = i;  
    433.  HW_REG8(GPIO_26_DAT) = GPIO_26;  
    434.  udelay(500);  
    435.  HW_REG8(GPIO_26_DAT) = 0;//10ns is enough  
    436.  for(i = 0; i < 100; i++)  
    437.  {  
    438.   udelay(1000);  
    439.  }  
    440.  HW_REG8(GPIO_26_DAT) = GPIO_26;  
    441.  udelay(500);  
    442. #endif  
    443. //#endif  
    444. }  
    445. static S32 __init dev_init1(void)  
    446. {  
    447.  S32 ret = 0;  
    448.  MODULE_NAME = MOD_STR;  
    449.  MODULE_NAME_E = MOD_STR_E;  
    450.    
    451.  STI2C_InitParams_t I2C_InitParams;  
    452.  STI2C_OpenParams_t I2C_OpenParams;  
    453.  U32 ErrCode;  
    454.  U32 ReadReg;  
    455.  /* Initialize I2C (0) */  
    456.  /* ------------------ */  
    457.  /* Configure PIO2[2,3] as I2C alternate functions for SSC0 */  
    458.    
    459. // SYS_ClearBitsDev32LE(ST7105_CFG_BASE_ADDRESS+0x154/*SYSTEM_CONFIG21*/,(1<< 2));  
    460. // SYS_ClearBitsDev32LE(ST7105_CFG_BASE_ADDRESS+0x154/*SYSTEM_CONFIG21*/,(1<< 3));  
    461. // SYS_SetBitsDev32LE  (ST7105_CFG_BASE_ADDRESS+0x154/*SYSTEM_CONFIG21*/,(1<<10));  
    462. // SYS_SetBitsDev32LE  (ST7105_CFG_BASE_ADDRESS+0x154/*SYSTEM_CONFIG21*/,(1<<11));  
    463.    
    464.  STSYS_WriteRegDev32LE(ST7105_CFG_BASE_ADDRESS+0x154/*SYSTEM_CONFIG21*/,0x6c00);  
    465.  ReadReg = STSYS_ReadRegDev32LE(ST7105_CFG_BASE_ADDRESS+0x154/*SYSTEM_CONFIG21*/);  
    466.    
    467.   /* reset the aic3104 */  
    468.  STSYS_WriteRegDev32LE(0xFD020030,0xb9);  
    469.  STSYS_WriteRegDev32LE(0xFD020030,0x39);  
    470.    
    471. // printk("<1> PIO2 Config Reg is %x\n",ReadReg);  
    472.    
    473.  /* Get clock configuration */  
    474.   /* ======================= */  
    475. //  ErrCode=ST_GetClockInfo(&CLOCK_Info);  
    476. //  if (ErrCode!=ST_NO_ERROR)  
    477. //   {  
    478. //     printk("Get Clock info error : %u\n",ErrCode);  
    479. //  return(ErrCode);  
    480. //   }   
    481.   
    482.  memset(&I2C_InitParams,0,sizeof(STI2C_InitParams_t));  
    483.    
    484.  I2C_InitParams.BaseAddress         = (U32 *)ST7105_SSC0_BASE_ADDRESS;  
    485.   I2C_InitParams.InterruptNumber     = ST7105_SSC0_INTERRUPT;  
    486. //  I2C_InitParams.InterruptLevel      = SSC_0_INTERRUPT_LEVEL;  
    487.  I2C_InitParams.MasterSlave         = STI2C_MASTER;  
    488.   I2C_InitParams.BaudRate            = STI2C_RATE_NORMAL;  
    489.   I2C_InitParams.MaxHandles          = 8;  
    490.   I2C_InitParams.ClockFrequency      = 0x5f5e100;  
    491. // I2C_InitParams.DriverPartition     = cache_partition_sdk[0];  
    492.   I2C_InitParams.PIOforSDA.BitMask   = PIO_BIT_3;  
    493.   I2C_InitParams.PIOforSCL.BitMask   = PIO_BIT_2;  
    494.   I2C_InitParams.EvtHandlerName[0]   = '\0';  
    495.   I2C_InitParams.GlitchWidth         = 0;  
    496.   I2C_InitParams.SlaveAddress        = 0;  
    497.   I2C_InitParams.FifoEnabled         = FALSE;  
    498.   strcpy(I2C_InitParams.PIOforSDA.PortName,PIO_DeviceName[2]);  
    499.   strcpy(I2C_InitParams.PIOforSCL.PortName,PIO_DeviceName[2]);  
    500.   ErrCode=STI2C_Init("I2C0",&I2C_InitParams);  
    501.   if (ErrCode!=ST_NO_ERROR)  
    502.   {  
    503.        
    504.   printk("I2C Init ERROR : %u\n",ErrCode);  
    505.   return(ErrCode);  
    506.    }  
    507.     
    508. //      printk("I2C init succes!\n");         
    509.         /*---Open I2C---*/  
    510.         memset(&I2C_OpenParams,0,sizeof(STI2C_OpenParams_t));  
    511.  I2C_OpenParams.BusAccessTimeOut = 100000;  
    512.  I2C_OpenParams.AddressType      = STI2C_ADDRESS_7_BITS;  
    513.  I2C_OpenParams.I2cAddress       = 0x30;  
    514.  I2C_OpenParams.BaudRate         = STI2C_RATE_NORMAL;  
    515.  ErrCode=STI2C_Open("I2C0",&I2C_OpenParams, &i2c_handle);  
    516.  if (ST_NO_ERROR != ErrCode )  
    517.  {  
    518.   printk("<1> aic3104 i2c error: %u\n", ErrCode);  
    519.   printk("<2> I2cAddress is %x\n",I2C_OpenParams.I2cAddress);  
    520.    
    521.   
    522.   return;  
    523.  }  
    524. // printk("i2c_handle = 0x%x\n",i2c_handle);  
    525. // printk("I2C open success!\n");  
    526. /* i2c write*/  
    527. /* 
    528.  STI2C_Lock(i2c_handle,TRUE);  
    529.  aic3104_info.Buffer_p[0] = 0; 
    530.  buff_p = 0; 
    531.  ErrCode=STI2C_WriteNoStop(i2c_handle,&buff_p,1,100,&nwrite); 
    532.  if(ST_NO_ERROR != ErrCode) 
    533.  { 
    534.    
    535.    
    536.   printk("I2C write error : 0x%x",ErrCode); 
    537.   STI2C_Unlock(i2c_handle); 
    538.    
    539.   return; 
    540.  }  
    541.  printk(KERN_ALERT "write success\n"); 
    542. */  
    543.   
    544.  chip_init();  
    545. // printk("chip init success!\n");  
    546.  //detect support audio or not  
    547.  if(audio_detect())  
    548.  {  
    549.   printk("\n%s: hw config error, audio is not supported by this board!", MODULE_NAME_E);  
    550.   goto dev_init_exit;  
    551.  }  
    552.    
    553. // printk("audio detect success!\n");  
    554.    
    555.    
    556.  //detect the chip  
    557.  if(chip_detect())  
    558.  {  
    559.   printk("\n%s: hw config error, can't find chip aic3104!", MODULE_NAME_E);  
    560.   goto dev_init_exit;  
    561.  }  
    562.    
    563. // printk("chip detect success!\n");  
    564.  //init chip  
    565.  if(audio_mode_init())  
    566.  {  
    567.   goto dev_init_exit;  
    568.  }  
    569.    
    570. // printk("audio_mode_init success!\n");  
    571. #ifdef GLOBAL_DEBUG  
    572.  //if(0)//reg_dump())  
    573.  if(reg_dump())  
    574.  {  
    575.   goto dev_init_exit;  
    576.  }  
    577. #endif  
    578. #if(!((0xd0 == AIC3104_WORK_MODE) || (0x00 == AIC3104_WORK_MODE)))  
    579.  #error "Work mode config error, compile stopped!";  
    580. #endif  
    581.  //register driver  
    582.  ret = misc_register(&device_driver);  
    583.  if(ret)  
    584.  {  
    585.   printk("\n%s: chip found but register failed[%d]", MODULE_NAME_E, ret);  
    586.   goto dev_init_exit;  
    587.  }  
    588.  printk("<1>audio codec driver registered successfully!\n");  
    589.  //KDPF(("\n%s: audio codec driver registered successfully, acts as %s!\n", MODULE_NAME, AIC3104_WORK_MODE ? "MASTER" : "SLAVE"))  
    590.  return NO_ERROR;  
    591. dev_init_exit:  
    592.  return -ERR_NO_DEV;  
    593. }  
    594. static void __exit dev_exit(void)  
    595. {  
    596.  misc_deregister(&device_driver);  
    597. }  
    598. module_init(dev_init1);  
    599. module_exit(dev_exit);  
    600. #ifdef MODULE  
    601. #include <linux/compile.h>  
    602. #endif  
    603. //module_param(norm_mode, int, S_IRUGO);  
    604. MODULE_INFO(build, UTS_VERSION);  
    605. MODULE_LICENSE("GPL");  
    606. MODULE_AUTHOR("hisilicon");  
  • PGA会把噪声放大,PGA放大会和噪声一起放大的。

  • 你好:

    能否将您的环境噪声录下来发到论坛上?我想看一下主要分布在哪个频段,看能否常使用滤波器滤掉。

    谢谢。

  •  非常感谢你的热心帮助!你这2个资料我都有,谢谢!

  • 附件是录音文件,一共有4个,分别对应4种不同的参数设置。请帮忙分析一下,看看要怎么改善。多谢!

  • 你好:

    我用Audacity打不开这个文件。我是想说你录一下底噪,然后用audacity分析一下底噪的频谱,看一下底噪分布在那个频段,然后AIC3104里有个filter,看能否用filter减弱这个底噪。

  • 请问filter是设置page0/register12,page0/register107,page1/register71-76寄存器相关设置吗?

  • 你好,

    是的。ADC的HP有两种配置方式:

    1.选择固定的频点:配置register 12,可以选0.0045fs=210hz或者0.0125fs=600HZ.此时register 107 配置成0x00

    2.自己配置N0,N1,D1,还是用TI BQ配置系数,可设置成任意频点.

    TIBQ下载链接:

    http://www.ti.com/tool/COEFFICIENT-CALC?keyMatch=TIBQ&tisearch=Search-EN

     

     

  • 不知道图片中这个软件怎么设置?我们要设置page1/register71-76的参数,请将关键设置点告知我,官网上也可以看到这个软件的使用说明。谢谢!
  • 我们现在用audacity分析底噪的频谱大概是1.5KHZ左右,ADC 采样率是16Khz,还有增益不知道怎么看怎么设置,我们生成的参数如下:

    设置后底噪是减少了,不过还是有,然后设置成1.6-1.8KHZ,好像也都差不多。不知道增益设置是什么意思?我们现在就选择了high pass,Fc=1500,Fs=16000,其它都没有设置。

  • 用audacity录了2段音频,一段是只有噪声的,一段是有人的声音的。请帮忙分析,如果可以,也可以告诉我们page1/regist71-76的参数值,或者告诉我们BQ怎么设置。谢谢!

  • 你好:

    增益设置就是说High pass后,通带有没有增益。你的理解都是对的啊。设置之后应该会有效果,需要在附件频点调一调。

  • 您好:

            非常感谢您的分享,,有点小缺点就是您分享的 TLV320AIC310X音频CODEC内部寄存器的正确配置 这篇文章不显示图。能否给我传一份完整的文档。非常感谢!谢谢!我的邮箱:52397968@qq.com

  • 你好,

          我现在调3106,发现只要PGA值调大一点,录音就出现破音,请问这个一般什么问题引起的,谢谢!

    我的音频录音文件在连接:

    http://dl.vmall.com/c0iw4mjatz

    谢谢

  • 你好:

    这个是有可能的,录音的时候PGA增益过大,录进去的音频也会破音。超过了电源的限制。

    如果录音的时候就破音了,那PGA的增益就不能这么大了。

     

     

  • 你好,

          感谢你的回复,但是我用32K采样时,并没有破音,而在44.1和48K采样就会出现破音,用软件看了一下,发现AIC3016的低通滤波器效果并没有那么理想,采样后的数据仍然有较多高频

  • 你好:

    1.你如何知道是录音的时候破音的?我觉得发生ADC转化和采样率并没有关系,所以如果你的话筒和采样率没有关系就不会出现这样的情况。但是可以确定的是,PGA不能调太大,录音时破音了就不好办了。

    2. 你换采样率的时候,滤波器的参数要跟着采样率变化,滤波器的系数和采样率相关。还有你是用的1阶还是2阶滤波器,2阶滤波器对高频的衰减更厉害一些。还有那个软件看高频,是总是有的。

  • 你好,

    滤波器数有跟着采样率变化,录制下来的后,发现是说话的刚开始,会有点沙沙声,请问这一般是是什么引起的,可以从哪方面入手,谢谢!

  • 你好:

    你的意思是说录音刚开始的时候有沙沙声,后来录的就没有沙沙声?

    这种现象我还没见过呢,如果录音过程一直有沙沙声,那就得检查一下时钟,是否同源同步,CLK是否是对的。

  • fang liu1 ,您好,

    请问这个问题解决了吗,我也碰见同样的问题。 

  • 你好,

          请你参考datesheet,调节AGC和滤波器,需要耐心

    BR

    stone

  • 你好,请问可以请教一下你吗? 我的QQ:54321387. 谢谢。

  • 您好:

      能否把这个文件发给我一份呢?谢谢阿。cslg_zhou@163.com我的邮箱。

  • fang liu1你好:

      我现在也在配置TLV3104,IN2L,IN2R输入,HPLOUT,HPROUT输出,遇到了问题,

    1:播放音乐的时候出错,log为playback write error (DMA or IRQ trouble?)    aplay: pcm_write:1710: write error: Input/output error

    2:我用示波器测量了MCLK测量不到,会是这个原因吗?

    能否给个配好的寄存器给我参考下呢?谢谢阿,新人一枚,感激不尽。











  • 我建立了一个群,便于交流,有兴趣者加入:TI音频CODEC技术交流 167571854

  • 我也遇到这个问题:

    我把噪声分为:电路内部噪声又称电流和环境噪声

    电流噪声这一块主要和我们的PCB走线有关系,属于容易结局的部分;

    环境噪声这一块就不好办了,我听了你的录音,这个在电路上很难消除,我觉得AGC能把这个噪声消掉,但是环境噪声变换,AGC 的噪声阀值也要动态调节,这个问题确实是不好解决!TI音频CODEC技术交流 群167571854

  • 您好!

             我也是通过调整High Pass,噪声有所改善,但是仍然会有一些。当Fc设置高些或者增益改变的大些,噪声和人声都没有了。请问还有什么方法?

  • 您好!

             我也是通过调整High Pass,噪声有所改善,但是仍然会有一些。当Fc设置高些或者增益改变的大些,噪声和人声都没有了。请问还有什么方法?您是怎么做的?

  • 您好请问下,linux内核哪个版本里面有支持TLV320AIC3104的驱动源码

  • 发的文档中没有图片,可不可以将文件发一份给我,邮箱:yinjiliang.2008@163.com

    谢谢!!!

  • 这个文档的原文件能不能发出一下!

  • 请问如何设置TI BQ 系数。谢谢

  • 你好,我在调试3106,采用IIC控制方式,可是IIC写入的数值与读出的数值不一致,用同样的IIC总线,写其他的IIC器件是没有错误的,这样得到您的回复,谢谢

  • 看不到图,有完整版么?现在遇到困难了。