When my card powers up, it configures the codec once and the configuration is not modified thereafter. We have a thousand cards in the field and the bug occurs only a few times per week. And I can't reproduce it in my lab.
I guess that maybe the register write sequence is not right, I tried a few changes without success.
We use the SPI bus for configuration. I am careful to add a 6.25 usec between the write access to register 45 to 93.
I have enabled the soft stepping in registers 19, 22, & 40. And the pop reduction in register 42. Can it have any negative effect?
I have noted that bit2 or register 65 & 72 are always set (Not all programmed gains to HPROUT have been applied yet.) Is it important, can it be fix by proper configuration? Can it be an indication that the output might be muted?
In one test I did at a customer site, I was able to clear the bug by rewriting only two registers: 64 and 65. Before writing, I read the values in both registers and they were correct. Then I wrote back the registers values as the configuration normally does: write(64, 0x80), write(65,0x11), write(65,0x19). Why did it work?
The file attached is the configuration file for the codec. The data structure lists the register addresses and values in the sequence they are written in the device.
I hope you can help me find the bug.
Best regards,
// L138_aic3106_init.c // // ** Define a structure with CODEC configuration. // ** Note the register must be written in the CODECs following the order of the structure (ex 0,8,9,10,98,etc.) // struct codec_init_table_t { uint8_t address, codec1_val; } codec_init_table [] = { /* address ,codec1 Register Name Function/command configured */ //GPIO, clock, misc. config //========================= {0 ,0x00 }, // Page select reg Always select page 0 {1 ,0x80 }, // Software reset To clear potential bugs {0 ,0x00 }, // Page select reg re-select page 0 {8 ,0x20 }, // Audio serial data I/F reg A BCLK,WCLK=input, Dout=tri-state,Disable 3D, disable digital mic {9 ,0x4F }, // Audio serial data I/F reg B serial data:dsp mode, 16bit timeslot, 256bit/frame,resync adc+dac, soft mute {10 ,0x00 }, // Audio serial data I/F reg C Codec1:timeslot=0 {11 ,0x00 }, // Audio codec OV flag Flags, PLL R = dont care {98 ,0x94 }, // GPIO1 Control Reg CODEC 1, GPIO 1 NOT USED, PROGRAM AS GENERAL OUTPUT = 0 {99 ,0x42 }, // GPIO2 Control Reg CODEC 1. GPIO 2 future use, PROGRAM AS GENERAL OUTPUT = 0 {100 ,0x88 }, // Additional GPIO Control reg A SCL,SDA used as General output = 0volt {101 ,0x01 }, // Additional GPIO Control reg B CODEC_CLKIN = CLKDIV_OUT, other GPIO don�t care in SPI mode {102 ,0x00 }, // Clock Generation Control CLKDIV_IN = MCLK, PLL bits = don�t care {107 ,0x30 }, // New Prgm ADC Digital Path and I2C Bus Cond HP filters L/R use default coef. L/R MIC are analog {108 ,0x00 }, // Passive Analog Signal Byp Sel in Powerdown No bypass on any analog signal during power down {109 ,0x00 }, // DAC Quiescent Current Adjust default DAC reference current {2 ,0xAA }, // Codec sample rate sel Codec sample rate = 8Khz = 48KHz / 6 {7 ,0x0A }, // Codec datapath setup dual rate off, L/R ADC on L/R play {3 ,0x10 }, // PLL prgm reg A PLL disabled, Q = CLKIN / (128 x fs(ref) = 12.288M / (128 x 48000) = 2, P= dont care {12 ,0xA0 }, // Audio codec digital filter ctl HP filter=100Hz ADC L+R, effect filter=disable, de-emphasis filter=disable {13 ,0x16 }, // headset/button detect reg A Codec1: disable headset detection. {14 ,0xC0 }, // headset/button detect reg B Codec1:ac coupled, Diff out //Inputs to ADC config //==================== //**init inputs step#1 {25 ,0x00 }, // MICBIAS ctl codec1:MICBIAS=disabled //**init inputs step#2 {17 ,0xFF }, // MIC3L/R to left ADC codec1:micL/R not connected to left ADC {18 ,0xFF }, // MIC3L/R to right ADC codec:micL/R not connected to right ADC. {19 ,0x00 }, //@ LINE1L to L ADC ctl Line1L to L ADC= codec1: 0dB codec1=SE !! KEEP LEFT ADC POWER DOWN !! {20 ,0x78 }, // LINE2L to L ADC ctl Line2L to L ADC= codec1: n.c. Disable weakly biased on input L ADC {21 ,0x78 }, // LINE1R to L ADC ctl Line1R to L ADC= codec1: n.c. Line1R: codec1=SE, codec2=FD, codec3=FD {22 ,0x00 }, //@ LINE1R to R ADC ctl Line1R to R ADC= codec1: 0dB. Enable R ADC. Line1R: codec1=SE, !! KEEP LEFT ADC POWER DOWN !! {23 ,0x78 }, // LINE2R to R ADC ctl Line2R to R ADC= codec1: n.c. Disable weakly biased on input R ADC {24 ,0x78 }, // LINE1L to R ADC ctl Line1L to R ADC= codec1: n.c. Line1L: codec1=SE, codec2=FD, codec3=SE //**init inputs step#3 {15 ,0x15 }, // Left ADC PGA gain ctl Left ADC not muted, PGA Gain: codec1 HDT mouth1= 10.5dB {16 ,0x15 }, // Right ADC PGA gain ctl Right ADC not muted, PGA Gain: codec1 HDT mouth1= 10.5dB //**init inputs step#4 {27 ,0x00 }, // L AGC ctl reg B disable L AGC {30 ,0x00 }, // R AGC ctl reg B disable R AGC //**init inputs step#5 {19 ,0x04 }, //@ LINE1L to L ADC ctl Line1L to L ADC= codec1: 0dB codec1=SE !! LEFT ADC POWER ON !! {22 ,0x04 }, //@ LINE1R to R ADC ctl Line1R to R ADC= codec1: 0dB. Enable R ADC. Line1R: codec1=SE !! RIGHT ADC POWER ON !! //DAC to outputs config //===================== //**init outputs step #1 {43 ,0x01 }, //@ L DAC digital volume ctl L DAC is not Muted, L DAC volume = -0.5dB to compensate Oct 28,2019 new output audio path configuration {44 ,0x01 }, //@ R DAC digital volume ctl R DAC is not Muted, R DAC volume = -0.5dB to compensate Oct 28,2019 new output audio path configuration //**init outputs step #2 {37 ,0xC0 }, // AC pwr and output driver L/R ADC power up, codec1:HPLCOM=diff {38 ,0x04 }, // high power output driver ctl codec1:HPRCOM=diff, Short circuit protection enabled {40 ,0x40 }, // high power output stage ctl VCM = 1.5v, disable:LINE2L, LINE2R, soft stepping 1 per fs //**init outputs step #3 {41 ,0x00 }, // DAC out switching ctl L DAC uses DAC_L1 path (less noise), R DAC use DAC_R1 path (less noise), L & R DAC volume have independent ctl {42 ,0x8E }, // Output driver pop reduction drv power on time=400ms, ramp-up step=4ms, weakly CM from bandgap ref //**init outputs step #4 (HPLOUT) {47 ,0x80 }, //@ DAC_L1 to HPLOUT volume DAC_L1 goes to HPLOUT with 0dB attenuation on codecs 1 {51 ,0x11 }, //@ HPLOUT output level ctl HPLOUT 0dB level, Muted!!, weak driver when disable, Full power-up. GAIN: codec1=1dB {51 ,0x19 }, //@ HPLOUT output level ctl HPLOUT 0dB level, not Muted, weak driver when disable, Full power-up. GAIN: codec1=1dB //**init outputs step #5 (HPLCOM) {58 ,0x00 }, // HPLCOM output level ctl HPLCOM disable. Overriden by register 37 bit5,4 in differential mode //**init outputs step #5 (HPROUT) {64 ,0x80 }, //@ DAC_R1 to HPROUT volume DAC_R1 goes to HPROUT with 0dB attenuation on codecs 1 {65 ,0x11 }, //@ HPROUT output level ctl HPROUT 0dB level, Muted!!, weak driver when disable, Full power-up. GAIN: codec1=1dB {65 ,0x19 }, //@ HPROUT output level ctl HPROUT 0dB level, not Muted, weak driver when disable, Full power-up. GAIN: codec1=1dB //**init outputs step #6 (HPRCOM) {72 ,0x00 } // HPRCOM output level ctl HPRCOM disable. Overriden by register 38 bit5,4,3 in differential mode //**init outputs step #7 (all unused line out) //nothing needed };