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.

PCM3070: PCM3070 EQ question

Part Number: PCM3070

Hi team, 

The customer is using PCM3070. He needs to set EQ. Now he uses two ways to set EQ. 

No matter what way, he cannot set the EQ correctly. The EQ  does not have any effect. 

Would you suggest how to set EQ correctly? 

The customer's setting EQ ways are as below:

One is write data one by one:
{
   0x2c, 0x00, 0x2c,
   0x2c, 0x01, 0x06,
   0x2c, 0x08, 0x00,
   0x2c, 0x09, 0x00,
   0x2c, 0x0a, 0x00,

   0x2c, 0x0c, 0x7f,
   0x2c, 0x0d, 0xff,
   0x2c, 0x0e, 0xff,

//--------- Left -----------------
   0x2c, 0x10, 0x3f,      //L  31Hz
   0x2c, 0x11, 0xf8,
   0x2c, 0x12, 0x40,

   0x2c, 0x14, 0x80,
   0x2c, 0x15, 0x19,
   0x2c, 0x16, 0x81,

   0x2c, 0x18, 0x3f,
   0x2c, 0x19, 0xee,
   0x2c, 0x1a, 0x90,

   0x2c, 0x1c, 0x7f,
   0x2c, 0x1d, 0xe6,
   0x2c, 0x1e, 0x7f,
}

Another is write data at one-time:

MAPI_U8 AmpEQ_Page44_Data[] =
{
   0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0x00,                              // 08~0F
   0x3F,0xF8,0x40,0x00,0x80,0x19,0x81,0x00,0x3F,0xEE,0x90,0x00,0x7F,0xE6,0x7F,0x00,   // 10~1F
}

Best Wishes,
Mickey Zhang
Asia Customer Support Center
Texas Instruments

  • Hi, Mickey,

    It seems that the device is being configured in adaptive mode, this allows the update of the filters while the device is running.

    In order to update the filters dynamically, after writing the required coefficients,  the bit D0 of register 44 [0x2C] should be written to '1' to perform the coefficient load to the filters. This is explained in detail in section 2.4.5.3 of the PCM3070 Application Reference Guide.

    Best Regards,

      -Diego Meléndez López
       Audio Applications Engineer

  • Hi Diego,

    The customer has another two questions:

    Q1: For the section 2.4.5.3 of the PCM3070 Application Reference Guide, the filters are switched between Buffer-A / B.

    Can the parameters be set the same for Buffer-A / B? That is for the registers Page44-52 and Page 62-70,

    can their values be set the same?

    Q2: The customer writes the registers of the filters coefficient through I2C one by one. The reading values are the same

    as the writing values. But when the customer uses multi-byte mode to write the registers of the filters coefficient,

    the reading values are different from the writing values. The customer would like to verify EQ can be started

    normally through I2C one by one?
  • Hi, Mickey,

    Please refer to below comments.

    1- The parameters can be the same for each buffer, it depends on end-user configuration if the values need to change at any point of the operation.

    2- There should be no issue in configuring the EQs by writing the coefficients one by one.

    Best Regards,

      -Diego Meléndez López
       Audio Applications Engineer

  • Hi Diego,

    Thanks for you support. Now the customer has still the issue.

    He uses the steps as below:
    1. Page0_01=0x01;
    2. Initialize registers Page0 and Page1;
    3. Write EQ data: Page44-46, Page62-64;
    4. Write register Page44_01=0x07.

    Initialize registers Page0 and Page1 are as below:

    MAPI_U8 AmpInitTbl[] =
    {
    0x00, 0x0b, 0x81, // NDAC divider
    0x00, 0x0c, 0x82, // MDAC divider
    0x00, 0x0d, 0x00, // OSR of DAC to 128, default
    0x00, 0x0e, 0x80, // default
    0x00, 0x1b, 0x20, // Set the word length of audio interface to 24bits PTM_P4
    //0x00, 0x3c, 0x08, // Set the DAC mode to PRB_P8
    0x00, 0x34, 0x08, // bit5-2=0010 to set GPIO input, bit1 is input status
    0x00, 0x3c, 0x01, // Set the DAC mode to PRB_P1, default
    0x00, 0x3f, 0xea, // Power up DAC , swap R/L channel? 6369 is d6, 828 is EA
    0x00, 0x40, 0x00, // Unmute DAC
    0x00, 0x41, 0x00, // DAC volume -> 0db
    0x00, 0x42, 0x00,

    0x01, 0x01, 0x00, // AVDD supply, default
    0x01, 0x02, 0x21, // Enable Master analog power control
    0x01, 0x0a, 0x00, // Input common mode
    0x01, 0x0c, 0x02, // DAC output to Headphone ???? NOTE, HP
    0x01, 0x0d, 0x02,
    0x01, 0x03, 0x00, // set the DAC PTM mode to PTM_P3/4
    0x01, 0x04, 0x00,
    0x01, 0x0e, 0x0a,//0x08, // DAC(bit3)/MA(bit1) output to LineOut
    0x01, 0x0f, 0x0a,//0x08,
    0x01, 0x09, 0x3f, // Power up Headphone & LineOut drivers. 0x3c-->0x0f, HP
    0x01, 0x10, 0x1d, // Unmute Headphone driver, 0db Gain, HP
    0x01, 0x11, 0x1d,
    0x01, 0x12, LINE_AMP_DEFAULT, // Unmute LineOut driver, 00db Gain
    0x01, 0x13, LINE_AMP_DEFAULT,
    0x01, 0x14, 0x25, // De-pop
    0x01, 0x18, MIXER_AMP_MUTE, //Mixer Amplifier Left Volume Control, 0db. 0x00 is 0db, 0x27 is -30.1db, 0x28--Mute
    0x01, 0x19, MIXER_AMP_MUTE,
    //0x01, 0x3b, 0x00, // Left PGA Volume Control, 0db. 00--5F(0dB--47.5dB).
    //0x01, 0x3c, 0x00,

    // For MIC input
    0x01, 0x34, 0x20, // Route IN1L to LEFT_P with 20K input impedance
    0x01, 0x36, 0x80, // Route Common Mode to LEFT_M with impedance of 20K
    0x01, 0x37, 0x20, // Route IN1R to RIGHT_P with input impedance of 20K
    0x01, 0x39, 0x80, // Route Common Mode to RIGHT_M with impedance of 20K
    0x01, 0x3b, PGA_DEFAULT, // Register of 0dB with input impedance of 20K => Channel Gain of 0dB
    0x01, 0x3c, PGA_DEFAULT, // Register of 0dB with input impedance of 20K => Channel Gain of 0dB
    0x01, 0x47, 0x32, // Set the input powerup time to 3.1ms (for ADC)
    0x01, 0x7b, 0x01, // Set the REF charging time to 40ms
    0xff,
    };

    When the customer does not write EQ data, the sound can be output properly.

    But when the customer uses the above steps and writes EQ data, then it sounds like rustling.

    Would you provide more suggestions? How to start EQ properly?

  • Hi, Mickey,

    Thanks for the feedback. It seems that the adaptive mode is not enabled before turning on the DAC, this is not a correct sequence, the adaptive mode should be enabled before powering up the ADC/DAC. Please ask customer to enable adaptive mode during the initialization sequence, then, try loading the coefficients with the process mentioned before by just writing a '1' to bit 0 off register 1 of page 44. The EQ settings can be written during the initial configuration as well.

    Best Regards,

      -Diego Meléndez López
       Audio Applications Engineer

  • Hi Diego,

    Thanks for your help. I will confirm with the customer.
  • Hi, Diego & Mickey,

    Thanks for your help!

     I set EQ parameters by PCM3070-K CS and recorded the commands. Then I tried to write thest registers and values according to the record. But It doesn't work.

    MAPI_U8 AmpEQSettingTbl_S[] = 
    {
    0x00, 0x00, 0x00,
    0x00, 0x04, 0x03,
    0x00, 0x05, 0x91,
    0x00, 0x06, 0x08,
    0x00, 0x07, 0x00,
    0x00, 0x08, 0x00,
    0x00, 0x1b, 0x20,
    0x00, 0x0b, 0x82,
    0x00, 0x0c, 0x88,
    0x00, 0x0d, 0x00,
    0x00, 0x0e, 0x80,
    0x00, 0x74, 0x00,
    0x00, 0x44, 0x00,
    0x00, 0x34, 0x08,
    0x00, 0x3c, 0x01,  // or 0x00?
    0x00, 0x0f, 0x02,
    0x00, 0x10, 0x1c,
    0x00, 0x11, 0x04,

    0x01, 0x01, 0x00,
    0x01, 0x02, 0x21,
    0x01, 0x7b, 0x01,

    0x2c, 0x01, 0x04,

    0xff,
    };
    MAPI_U8 AmpEQSettingTbl[] = 
    {
    0x2c, 0x08, 0x00,
    0x2c, 0x09, 0x00,
    0x2c, 0x0a, 0x00,
    0x2c, 0x0b, 0x00,

    0x2c, 0x0c, 0x7f,
    0x2c, 0x0d, 0xff,
    0x2c, 0x0e, 0xff,
    0x2c, 0x0f, 0x00,
            ......
    0x34, 0x7c, 0x80,
    0x34, 0x7d, 0x34,
    0x34, 0x7e, 0x76,

    0xff,
    };
    MAPI_U8 AmpEQSettingTbl_E[] = 
    {
    0x01, 0x14, 0x25,
    0x01, 0x0c, 0x0a,
    0x01, 0x0d, 0x0a,
    0x01, 0x0e, 0x0a,
    0x01, 0x0f, 0x0a,
    0x01, 0x09, 0x3f,
    0x01, 0x10, 0x1d,
    0x01, 0x11, 0x1d,
    0x01, 0x12, 0x06,
    0x01, 0x13, 0x06,
    0x01, 0x18, 0x24,
    0x01, 0x19, 0x24,

    0x00, 0x41, 0x00,
    0x00, 0x42, 0x00,
    0x00, 0x3f, 0xea,
    0x00, 0x40, 0x00,
    0x2c, 0x01, 0x05,
            
    0xff,
    };
    The above talbes are same to the records in CS. I tried to set Page01_Reg02 to 0x00 at first and set it to 0x01 in the end. The result is same. 
    Pls help to check what's wrong.
    Thanks and looking forward to your supply.

  • Hi, 

    Welcome to E2E, Thanks for your interest in our products!.

    From the code you sent, the coefficients are loaded correctly, so the filter effects should be noted in the outputs used. Are you able to get audio output?. Could you please elaborate more on the specific issue you are having now?. Also, could you please share more details  about the desired configuration?. Are you able to make the device work correctly with CS software?

    Best Regards,

      -Diego Meléndez López
       Audio Applications Engineer

  • hi, Diego,

    Thanks!

    I don't get audio output after loading the coefficients. But it works correctly with CS software. This is what I can't understand.

    I want to use PCM3070 to get 2.1 stereo audio and get better bass effect by the EQ. After we get them with CS software, we try to do it with codes but it's fail. So I request your support and help.

    I know the miniDSP has two different initialization methods: Preset mode (PRB) and Programming mode. The last debug is in Preset mode, right? So I want to try to get the code in programming mode with Purepath Studio. But I don't have the config of PCM3070 on Purepath Studio. Would you help to supply it?

  • Hi,

    From your configuration, it seems that the preset mode is used. if so, the biquads available for your specific PRB should be accesible. It is strange that the same register write sequence done with the CS software is not working in your system. Does the device works if you load the register sequence you sent using the CS software?.

    In order to get PurePath Studio, please go to the product folder in ti.com and request access. I can follow up with my Audio Software team to approve you.

    Best Regards,

      -Diego Meléndez López
       Audio Applications Engineer

  • hi, Diego,

    Thanks! I request the GDE. Pls help to approve asap. Thank you very much!
    "
    Thank you for requesting this file from Texas Instruments

    Your request will be reviewed - If you are approved, in a few days you will receive an email from TI. If you need to reach us, please contact audio_software@ti.com


    Thank you,
    Texas Instruments
    "
  • hi, Diego,

    I got the PurePath Studio. Thank you very much!

    For help to get the code quickly, would you please share a success config of PCM3070 (like PCM3070_Example1_PFW.pfw) on GDE?

  • Hi, 

    I would recommend you to take a look to this wiki entry, there you can find some useful information and examples about the miniDSP development and implementation.

    Best Regards,

      -Diego Meléndez López
       Audio Applications Engineer

  • Hi, Diego,

    I read the "Audio Converters" but didn't find examples about application with PCM3070. Maybe I'm stupid on this.

    The following codes is for EQ debugged but fail (no sound output). I just want to make 3pages data active. Should I do?  If init with the AmpInitTbl, it works in playback mode with stereo 2.0 normal.

    Hope you can help to check what is the problem. Thanks!

    /*@ <Include> @*/
    #include <stdio.h>
    #include <unistd.h>
    #include "debug.h"
    #include "device_audio_amp_I2S_PCM3070.h"
    #include "mapi_i2c_devTable.h"
    
    #include <fcntl.h>
    
    #include "mapi_syscfg_fetch.h"
    
    //#include "apiSWI2C.h"
    #include "mapi_i2c.h"
    #include "mapi_interface.h"
    #include "drvGPIO.h"
    #include "mapi_gpio.h"
    #include "mapi_gpio_devTable.h"
    #include "../../board/Model_type.h"
    
    //#include "Model.h"
    //#include "prima_support.h"
    #include "MSrv_Control.h"
    #include "MSrv_System_Database.h"
    #define OFD_PCM3070 1	// only for debug
    #define MIN_VOL 0
    #define MAX_VOL 100
    
    static MAPI_U8 i2s_vol_table[MAX_VOL+1]=
    {
    /*0--9*/	0X81, 0X90, 0Xa0, 0Xaa, 0Xb0, 0Xb8, 0Xc3, 0Xcd, 0Xd4, 0Xda, 
    /*10--19*/	0Xe0, 0Xe5, 0Xe8, 0Xea, 0Xec, 0Xee, 0Xef, 0Xf1, 0Xf2, 0Xf3, 
    /*20--29*/	0Xf4, 0Xf5, 0Xf6, 0Xf7, 0Xf8, 0XF9, 0XFa, 0XFa, 0XFb, 0XFb, 
    /*30--39*/	0XFc, 0XFd, 0XFd, 0XFe, 0XFe, 0XFF, 0XFF, 0X01, 0X01, 0X02, 
    /*40--49*/	0X03, 0X04, 0X04, 0X05, 0X06, 0X06, 0X07, 0X07, 0X08, 0X08, 
    /*50--59*/	0X09, 0X0a, 0X0a, 0X0b, 0X0c, 0X0c, 0X0d, 0X0d, 0X0e, 0X0e, 
    /*60--69*/	0X0f, 0X10, 0X11, 0X11, 0X12, 0X13, 0X14, 0X15, 0X15, 0X16, 
    /*70--79*/	0X16, 0X17, 0X17, 0X18, 0X18, 0X19, 0X1a, 0X1a, 0X1b, 0X1b, 
    /*80--89*/	0X1c, 0X1c, 0X1d, 0X1d, 0X1e, 0X1e, 0X1f, 0X1f, 0X20, 0X20, 
    /*90--99*/	0X21, 0X21, 0X22, 0X22, 0X23, 0X24, 0X24, 0X25, 0X25, 0X26, 
    /* 100*/		0X27,
    };
    
    #if SUPPORT_MIC_DETECT     
    static MAPI_U8 mic_vol_table[MAX_VOL+1]=
    {// Mixer volume, Mute =0x28, max=0,
    /*0--9*/	0x28,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
    /*10--19*/	0x26,0x26,0x26,0x26,0x26,0x25,0x25,0x25,0x25,0x25,
    /*20--29*/	0x24,0x24,0x24,0x24,0x24,0x23,0x23,0x23,0x23,0x22,
    /*30--39*/	0x22,0x22,0x22,0x21,0x21,0x21,0x20,0x20,0x20,0x20,
    /*40--49*/	0x1f,0x1f,0x1f,0x1f,0x1f,0x1e,0x1e,0x1e,0x1e,0x1d,
    /*50--59*/	0x1D,0x1D,0x1C,0x1C,0x1B,0x1A,0x1A,0x19,0x19,0x18,
    /*60--69*/	0x17,0x17,0x16,0x15,0x15,0x14,0x13,0x13,0x12,0x12,
    /*70--79*/	0x11,0x10,0x10,0x0F,0x0F,0x0E,0x0E,0x0D,0x0D,0x0C,
    /*80--89*/	0x0B,0x0B,0x0A,0x0A,0x09,0x08,0x08,0x07,0x06,0x06,
    /*90--99*/	0x05,0x05,0x04,0x04,0x03,0x03,0x02,0x02,0x01,0x01,
    /* 100*/		0X00,
    };
    #endif
    //-------------------------------------------------------------------------------------------------
    /// Constructor
    /// @param  None
    /// @return None
    //-------------------------------------------------------------------------------------------------
    device_audio_amp_I2S_PCM3070::device_audio_amp_I2S_PCM3070(void)
    {
        bInited = FALSE;
    }
    
    //-------------------------------------------------------------------------------------------------
    /// De-constructor
    /// @param  None
    /// @return None
    //-------------------------------------------------------------------------------------------------
    device_audio_amp_I2S_PCM3070::~device_audio_amp_I2S_PCM3070(void)
    {
        return;
    }
    
    #define InitTblLength 1024
    MAPI_BOOL Get_AmpInitTbl(MAPI_U8 *reg,const char *path)
    {
        MAPI_S16 fd = 0;
        MAPI_BOOL ret = FALSE;
    	if(path != NULL)
        {
    			fd = open(path, O_RDONLY);
    			if(fd != -1)
    			{
    				memset(reg, 0, InitTblLength);
    			if(read(fd, (MAPI_U8*)reg, InitTblLength) != -1)
    				{
    				ret = TRUE;
    				}
    				close(fd);
    			}
            }
        return ret;
    }
    
    MAPI_U8 device_audio_amp_I2S_PCM3070::ReadReg(MAPI_U8 uRegPage, MAPI_U8 uRegAddress, MAPI_U8 *pValue)
    {
    	MAPI_U8 u8Data = 0;
    	MAPI_U8 u8DataLength = 0;
    	MAPI_U8 u8RegAddr = 0;
    	mapi_i2c *iptr;
    
    	iptr = mapi_i2c::GetI2C_Dev(AMP_I2C_CHANNEL);
    	
    
    		u8RegAddr = I2C_REG_00;
    		u8Data = uRegPage;		
    		u8DataLength = 1;	
    		if(iptr->WriteBytes(1, &u8RegAddr, u8DataLength, &u8Data) == MAPI_FALSE)
    		{
    			printf("\n++++++ Tenny: PCM3070 I2C Bus Write Reg[0x%x] Fail ++++++\n", u8RegAddr);	
    			return MAPI_FALSE;
    		}
    		usleep(2000);
    
    	u8RegAddr = uRegAddress;
    	u8DataLength = 1;
    	if(iptr->ReadBytes(1, &u8RegAddr, u8DataLength, &u8Data) == MAPI_FALSE)
    	{
    		printf("\n++++++ Tenny: PCM3070 I2C Bus Write Reg[0x%x] Fail ++++++\n", u8RegAddr);
    		return MAPI_FALSE;
    	}
    	//printf("\n+++++++ Tenny: Read PCM3070 Page[%d]Reg[0x%x] is 0x%x +++++++\n", uRegPage, uRegAddress, u8Data);
    	usleep(2000);
    	*pValue = u8Data;
    	return MAPI_TRUE;
    }
    
    MAPI_BOOL device_audio_amp_I2S_PCM3070::WriteReg(MAPI_U8 uRegPage, MAPI_U8 uRegAddress, MAPI_U8 uDataToWrite)
    {
    	MAPI_U8 u8DataWrite = 0;
    	MAPI_U8 u8DataLength = 0;
    	MAPI_U8 u8RegAddr = 0;
    	mapi_i2c *iptr;
    
    	iptr = mapi_i2c::GetI2C_Dev(AMP_I2C_CHANNEL);
    	
    	
    		u8RegAddr = I2C_REG_00;
    		u8DataWrite = uRegPage;		
    		u8DataLength = 1;
    		if(iptr->WriteBytes(1, &u8RegAddr, u8DataLength, &u8DataWrite) == MAPI_FALSE)
    		{
    			printf("\n++++++ Tenny: PCM3070 I2C Bus Write Reg[0x%x] Fail ++++++\n", u8RegAddr);
    			return MAPI_FALSE;
    		}
    		usleep(2000);
    	
    	u8RegAddr = uRegAddress;
    	u8DataWrite = uDataToWrite;
    	u8DataLength = 1;
    	if(iptr->WriteBytes(1, &u8RegAddr, u8DataLength, &u8DataWrite) == MAPI_FALSE)
    	{
    		printf("\n++++++ Tenny: PCM3070 I2C Bus Write Reg[0x%x] Fail ++++++\n", u8RegAddr);
    		return MAPI_FALSE;
    	}
    	usleep(2000);
    	return MAPI_TRUE;
    }
    
    MAPI_BOOL device_audio_amp_I2S_PCM3070::WriteMultiReg(MAPI_U8 uRegPage, MAPI_U8 uRegAddress, MAPI_U8 *uDataToWrite)
    {
    	MAPI_U8 u8DataWrite = 0;
    	MAPI_U8 u8DataLength = 0;
    	MAPI_U8 u8RegAddr = 0;
    	//MAPI_U8 *pu8Datas;
    	mapi_i2c *iptr;
    
    	iptr = mapi_i2c::GetI2C_Dev(AMP_I2C_CHANNEL);
    	
    	
    	u8RegAddr = I2C_REG_00;
    	u8DataWrite = uRegPage;		
    	u8DataLength = 1;
    	if(iptr->WriteBytes(1, &u8RegAddr, u8DataLength, &u8DataWrite) == MAPI_FALSE)
    	{
    		printf("\n++++++ Tenny: PCM3070 I2C Bus Write Page Reg[0x%x] Fail ++++++\n", u8DataWrite);
    		return MAPI_FALSE;
    	}
    	usleep(2000);
    	
    	u8RegAddr = uRegAddress;
    	//u8DataWrite = uDataToWrite;
    	u8DataLength = 120;
    	if(iptr->WriteBytes(1, &u8RegAddr, u8DataLength, uDataToWrite) == MAPI_FALSE)
    	{
    		printf("\n++++++ Tenny: PCM3070 I2C Bus Write Reg[0x%x] Fail ++++++\n", u8RegAddr);
    		return MAPI_FALSE;
    	}
    	usleep(2000);
    	return MAPI_TRUE;
    }
    
    MAPI_U8 AmpEQSettingTbl_S[] = 
    {
    	0x00, 0x04, 0x03,
    	0x00, 0x05, 0x91,
    	0x00, 0x06, 0x08,
    	0x00, 0x07, 0x00,
    	0x00, 0x08, 0x00,
    	0x00, 0x1b, 0x20,	// Set the word length of audio interface to 24bits PTM_P4
    	0x00, 0x0b, 0x82,
    	0x00, 0x0c, 0x88,
    	0x00, 0x0d, 0x00,
    	0x00, 0x0e, 0x80,
    	0x00, 0x74, 0x00,
    	0x00, 0x44, 0x00,
    	0x00, 0x34, 0x08, 
    	0x00, 0x3c, 0x00,	// miniDSP_D preset mode: Set the DAC mode to PRB_P1; 0x00 for signal processing(Programming mode)
    	0x00, 0x0f, 0x02,
    	0x00, 0x10, 0x1c,
    	0x00, 0x11, 0x04,
    	0x00, 0x41, 0x00,
    	0x00, 0x42, 0x00,
    
    	0x01, 0x01, 0x08,
    	0x01, 0x02, 0x00,	//AVDD LDO powered down first
    
    	0x2c, 0x01, 0x04,
    
    	0xff,
    };
    
    MAPI_U8 AmpEQ_Page44_Data[] = 
    {
    	0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0x00,										// 08~0F
    	0x3F,0xF8,0x40,0x00,0x80,0x19,0x81,0x00,0x3F,0xEE,0x90,0x00,0x7F,0xE6,0x7F,0x00,	// 10~1F
    	0xC0,0x19,0x30,0x00,0x40,0x21,0x13,0x00,0x80,0x24,0x61,0x00,0x3F,0xBB,0x31,0x00,	// 20~2F
    	0x7F,0xDB,0x9F,0x00,0xC0,0x23,0xBC,0x00,0x40,0x1D,0x1A,0x00,0x80,0x34,0x76,0x00,	// 30~3F
    	0x3F,0xAF,0xC2,0x00,0x7F,0xCB,0x8A,0x00,0xC0,0x33,0x25,0x00,0x40,0x1F,0xF5,0x00,	// 40~4F
    	0x80,0x49,0x19,0x00,0x3F,0x99,0x76,0x00,0x7F,0xB6,0xE7,0x00,0xC0,0x46,0x96,0x00,	// 50~5F
    	0x40,0x0A,0xF4,0x00,0x80,0x6A,0x80,0x00,0x3F,0x8F,0xBA,0x00,0x7F,0x95,0x80,0x00,	// 60~6F
    	0xC0,0x65,0x52,0x00,0x3F,0xEB,0xE5,0x00,0x80,0x97,0xD0,0x00,0x3F,0x86,0x6F,0x00,	// 70~7F
    };
    
    MAPI_U8 AmpEQ_Page45_Data[] = 
    {
    	0x7F,0x68,0x30,0x00,0xC0,0x8D,0xAC,0x00,
    	0x3F,0xBD,0x9D,0x00,0x80,0xDE,0xAC,0x00,0x3F,0x78,0x5E,0x00,0x7F,0x21,0x54,0x00,
    	0xC0,0xCA,0x04,0x00,0x3F,0xE9,0xA0,0x00,0x81,0x42,0x84,0x00,0x3E,0xFC,0x3E,0x00,
    	0x7E,0xBD,0x7C,0x00,0xC1,0x1A,0x22,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,
    	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    	0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    	0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    };
    
    MAPI_U8 AmpEQ_Page46_Data[] = 
    {
    	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    	0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x8C,0x14,0x00,0x91,0xB9,0x93,0x00,
    	0x38,0x20,0x03,0x00,0x6E,0x46,0x6D,0x00,0xC8,0x53,0xE9,0x00,0x40,0x00,0x00,0x00,
    	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    	0x3E,0xFC,0x9C,0x00,0xB1,0x97,0x67,0x00,0x31,0x4E,0xF1,0x00,0x4E,0x68,0x99,0x00,
    	0xCF,0xB4,0x73,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x2C,0xBC,0x00,0xFF,0xA4,0xCF,0x00,
    };
    
    MAPI_U8 AmpEQSettingTbl_E[] = 
    {
    	0x01, 0x03, 0x00,		// set the DAC PTM mode to PTM_P3/4
    	0x01, 0x04, 0x00,
    	0x01, 0x14, 0x25,
    	0x01, 0x0c, 0x0a,
    	0x01, 0x0d, 0x0a,
    	0x01, 0x0e, 0x0a,
    	0x01, 0x0f, 0x0a,
    	0x01, 0x09, 0x3f,
    	0x01, 0x10, 0x08,
    	0x01, 0x11, 0x08,
    	0x01, 0x12, 0x06,
    	0x01, 0x13, 0x06,
    	0x01, 0x18, 0x14,
    	0x01, 0x19, 0x14,
    
    	0x01, 0x47, 0x32,	// Set the input powerup time to 3.1ms (for ADC)
    	0x01, 0x7b, 0x01,	// Set the REF charging time to 40ms
    	
    	0x00, 0x3f, 0xea,	// Power up DAC ,   swap R/L channel?   6369 is d6,  828 is EA
    	0x00, 0x40, 0x00,	// Unmute DAC
    
    	0x2c, 0x01, 0x05,
    	
    	0x01, 0x02, 0x21,	// Enable Master analog power control
    
    	0xff,
    };
    
    #define LINE_AMP_DEFAULT		0x04//0X0a    // 10dB
    #define MIXER_AMP_DEFAULT		0x14//0X00  // 0dB
    #define MIXER_AMP_MUTE			0X28 // mute
    
    #define PGA_DEFAULT		0x2D//  0x13 to fit AMP power, but it's not lound enough. So, don't care MIC input Power.
    
    //Following initial table is for Playback stereo 2.0 and it works normally.
    MAPI_U8 AmpInitTbl[] = 
    {
    	0x00, 0x0b, 0x81,		// NDAC divider
    	0x00, 0x0c, 0x82,		// MDAC divider
    	0x00, 0x0d, 0x00,		// OSR of DAC to 128, default
    	0x00, 0x0e, 0x80,			// default
    	0x00, 0x1b, 0x20,		// Set the word length of audio interface to 24bits PTM_P4
    	//0x00, 0x3c, 0x08,		// Set the DAC mode to PRB_P8
    	0x00, 0x34, 0x08,		// bit5-2=0010 to set GPIO input, bit1 is input status
    	0x00, 0x3c, 0x01,		// Set the DAC mode to PRB_P1, default 
    	0x00, 0x3f, 0xea,		// Power up DAC ,   swap R/L channel?   6369 is d6,  828 is EA
    	0x00, 0x40, 0x00,		// Unmute DAC
    	0x00, 0x41, 0x00,		// DAC volume ->  0db
    	0x00, 0x42, 0x00,
    	
    	0x01, 0x01, 0x00,		// AVDD supply, default
    	0x01, 0x02, 0x21,		// Enable Master analog power control
    	0x01, 0x0a, 0x00,		// Input common mode
    	0x01, 0x0c, 0x02,		// DAC output to Headphone   ???? NOTE,  HP
    	0x01, 0x0d, 0x02,
    	0x01, 0x03, 0x00,		// set the DAC PTM mode to PTM_P3/4
    	0x01, 0x04, 0x00,
    	0x01, 0x0e, 0x0a,//0x08,		// DAC(bit3)/MA(bit1) output to LineOut
    	0x01, 0x0f, 0x0a,//0x08,
    	0x01, 0x09, 0x3f,		// Power up Headphone & LineOut drivers.  0x3c-->0x0f, HP
    	0x01, 0x10, 0x1d,		// Unmute Headphone driver, 0db Gain,  HP
    	0x01, 0x11, 0x1d,
    	0x01, 0x12, LINE_AMP_DEFAULT,		// Unmute LineOut driver, 00db Gain
    	0x01, 0x13, LINE_AMP_DEFAULT,
    	0x01, 0x14, 0x25,		// De-pop
    	0x01, 0x18, MIXER_AMP_MUTE,		//Mixer Amplifier Left Volume Control, 0db.  0x00 is 0db, 0x27 is -30.1db, 0x28--Mute
    	0x01, 0x19, MIXER_AMP_MUTE,		
    	//0x01, 0x3b, 0x00,		// Left PGA Volume Control, 0db.  00--5F(0dB--47.5dB).
    	//0x01, 0x3c, 0x00,		
    
    // For MIC input
    	0x01, 0x34, 0x20,		// Route IN1L to LEFT_P with 20K input impedance
    	0x01, 0x36, 0x80,		// Route Common Mode to LEFT_M with impedance of 20K
    	0x01, 0x37, 0x20,		// Route IN1R to RIGHT_P with input impedance of 20K
    	0x01, 0x39, 0x80,		// Route Common Mode to RIGHT_M with impedance of 20K
    	0x01, 0x3b, PGA_DEFAULT,		// Register of 0dB with input impedance of 20K => Channel Gain of 0dB
    	0x01, 0x3c, PGA_DEFAULT,		// Register of 0dB with input impedance of 20K => Channel Gain of 0dB
    	0x01, 0x47, 0x32,		// Set the input powerup time to 3.1ms (for ADC)
    	0x01, 0x7b, 0x01,		// Set the REF charging time to 40ms
    
    	0xff,	
    };
    
    MAPI_BOOL device_audio_amp_I2S_PCM3070::Init(void)
    {
    	MAPI_U8 * Pstr = NULL;
    //	MAPI_U8 DataLength = 0;
    	MAPI_U8 u8RegPage = 0;
    	MAPI_U8 u8RegAddr = 0;
    	//MAPI_U8 AmpInitBin[1024];
    	MAPI_U8 initTry=5;
           MAPI_BOOL bERR = MAPI_TRUE;
    	if (bInited)
    		return MAPI_FALSE;
    
    	printf("******** Amplifier_Init Start *********\n");
    	//===========================================
    	while(initTry--)
    	{
    		if(Reset(MAPI_TRUE) == MAPI_FALSE)
    		{
    		 usleep(10*1000);
    		 printf("********PCM3070 Reset fail*********\n");
    		 continue;
    		 }
    		usleep(10*1000);
    
    		#if 1		//Tenny at 20170919: For debug EQ, but no sound output now
    		Pstr = AmpEQSettingTbl_S;
    		bERR = MAPI_TRUE;
    		do
    		{
    			u8RegPage = *Pstr;
    			u8RegAddr = *(++Pstr);
    			Pstr++;
    			if(WriteReg(u8RegPage, u8RegAddr, *Pstr) == MAPI_FALSE)
    			{
    				printf("\n++++++ Tenny: PCM3070 I2C Bus Write Reg[0x%x] Fail ++++++\n", u8RegAddr);
    				bERR = MAPI_FALSE;
    				break;
    			}			
    			Pstr++;
    		} while (*Pstr != 0xff);
    
    		WriteMultiReg(0x2c, 0x08, &AmpEQ_Page44_Data[0]);
    		WriteMultiReg(0x2d, 0x08, &AmpEQ_Page45_Data[0]);
    		WriteMultiReg(0x2e, 0x08, &AmpEQ_Page46_Data[0]);
    
    		Pstr = AmpEQSettingTbl_E;
    		bERR = MAPI_TRUE;
    		do
    		{
    			u8RegPage = *Pstr;
    			u8RegAddr = *(++Pstr);
    			Pstr++;
    			if(WriteReg(u8RegPage, u8RegAddr, *Pstr) == MAPI_FALSE)
    			{
    				printf("\n++++++ Tenny: PCM3070 I2C Bus Write Reg[0x%x] Fail ++++++\n", u8RegAddr);
    				bERR = MAPI_FALSE;
    				break;
    			}			
    			Pstr++;
    		} while (*Pstr != 0xff);
    		#else //Following config will output stereo 2.0
    		/*if(Get_AmpInitTbl(AmpInitBin,mapi_syscfg_fetch::GetAMPBinPath().c_str()))
    		{
    			Pstr = AmpInitBin;
    			printf("******** Get AmpInitTable from config path*********\n");
    		}
    		else */
    		{
    			Pstr = AmpInitTbl;
    		}
    		
    		bERR = MAPI_TRUE;
    		do
    		{
    			u8RegPage = *Pstr;
    			u8RegAddr = *(++Pstr);
    			Pstr++;
    			if(WriteReg(u8RegPage, u8RegAddr, *Pstr) == MAPI_FALSE)
    			{
    				printf("\n++++++ Tenny: PCM3070 I2C Bus Write Reg[0x%x] Fail ++++++\n", u8RegAddr);
    				bERR = MAPI_FALSE;
    				break;
    			}			
    			Pstr++;
    		} while (*Pstr != 0xff);
    		
    		#endif
    		if(bERR == MAPI_FALSE)
    		{
    		    printf("********PCM3070 Init fail *********\n");
    		    continue;
    		}	
    		else
    		{
    		  printf("********PCM3070 Init success *********\n");
    		}
    		usleep(200 * 1000);
    		printf("********Amplifier_Init Done *********\n");
        	       mapi_gpio *gptr = mapi_gpio::GetGPIO_Dev(MUTE);  gptr->SetOff();
    //		mapi_gpio *gptr1 = mapi_gpio::GetGPIO_Dev(EarPhoneMute);  gptr1->SetOff();
    			   
    		bInited = TRUE;
    		return MAPI_TRUE;
    	}
    	return MAPI_FALSE;
    }
    
    //-------------------------------------------------------------------------------------------------
    /// Finalize this Audio Amplifier
    /// @param None
    /// @return             \b OUT: MAPI_TRUE or MAPI_FALSE
    //-------------------------------------------------------------------------------------------------
    MAPI_BOOL device_audio_amp_I2S_PCM3070::Finalize(void)
    {
        printf("******** Amplifier_Finalize **********\n");
        Mute(TRUE);
        usleep(1000);
        bInited = FALSE;  
        return MAPI_TRUE;
    }
    
    //-------------------------------------------------------------------------------------------------
    /// Reset this Audio Amplifier
    /// @param bEnable	    \b IN: TRUE for enable; FALSE for disable
    /// @return             \b OUT: MAPI_TRUE or MAPI_FALSE
    //-------------------------------------------------------------------------------------------------
    MAPI_BOOL device_audio_amp_I2S_PCM3070::Reset(MAPI_BOOL bEnable)
    {
        return WriteReg(I2C_REG_PAGE_0, I2C_REG_P0_01, 0x01);    
    }
    
    //-------------------------------------------------------------------------------------------------
    /// Mute this Audio Amplifier
    /// @param bMute		\b IN: TRUE for Mute; FALSE for unMute
    /// @return 			\b OUT: MAPI_TRUE or MAPI_FALSE
    //-------------------------------------------------------------------------------------------------
    MAPI_BOOL device_audio_amp_I2S_PCM3070::Mute(MAPI_BOOL bMute)
    {
        //WriteReg(I2C_REG_PAGE_1, LINE_VOL_REG, 0x40);
        //WriteReg(I2C_REG_PAGE_1, LINE_VOL_REG+1, 0x40); 
    
          if(bMute == TRUE)
          	{
          		WriteReg(I2C_REG_PAGE_1, LINE_VOL_REG, 0x40);
       		WriteReg(I2C_REG_PAGE_1, LINE_VOL_REG+1, 0x40);
          	}
    	  
       	return MAPI_TRUE;
    }
    
    
    MAPI_BOOL device_audio_amp_I2S_PCM3070::AmpSwapOutputChannel(MAPI_BOOL bEnable)
    {
       // MAPI_BOOL ret = ExtendCmd(CMD_LR_SWAP, (MAPI_U32)bEnable, NULL, NULL);
        return 0;
    }
    
    MAPI_BOOL device_audio_amp_I2S_PCM3070::AmpSetSubWooferVolume(MAPI_BOOL bMute, MAPI_U8 u8Val)
    {
        MAPI_BOOL ret = MAPI_TRUE;
        return ret;
    }
    
    MAPI_BOOL device_audio_amp_I2S_PCM3070::I2sSetVolume(MAPI_U8 u8Vol)
    {  
        WriteReg(I2C_REG_PAGE_0, DAC_VOL_REG, i2s_vol_table[u8Vol]);
        WriteReg(I2C_REG_PAGE_0, DAC_VOL_REG+1, i2s_vol_table[u8Vol]);
    //    printf("I2sSetVolume, lipper\n");
        return MAPI_TRUE;
    }
    
    MAPI_BOOL device_audio_amp_I2S_PCM3070::MicSetVolume(MAPI_U8 u8Vol) 
    {    	
    //the Mixer vol is adjustable. 0--max, 40--mute
    #if SUPPORT_MIC_DETECT        
    	 MAPI_INPUT_SOURCE_TYPE enCurrentInputType;
            enCurrentInputType = MSrv_Control::GetInstance()->GetCurrentInputSource();
    	 if((enCurrentInputType == MAPI_INPUT_SOURCE_VGA)&&((MSrv_Control::GetInstance()->GetMSrvSystemDatabase()->GetVGAExtend()) == VGA3_EXTEND))
    	 {
    	     u8Vol =0;
    	 }
            MAPI_U16 mixRate = MSrv_Control::GetInstance()->GetMSrvSystemDatabase()->GetAudioMixRate();
    	if((mixRate&0x3000)==0x3000)
    	{
    		WriteReg(I2C_REG_PAGE_1, MIXER_VOL_REG, mic_vol_table[u8Vol]);
           	WriteReg(I2C_REG_PAGE_1, MIXER_VOL_REG+1, mic_vol_table[u8Vol]);	
    	}
    	//printf("MisSetVolume=%d\n",u8Vol);
    #endif	
           return MAPI_TRUE;
    }
    
    MAPI_BOOL device_audio_amp_I2S_PCM3070::MicEnable(MAPI_BOOL enable,  MAPI_U32 vol) 
    {    	
    #if SUPPORT_MIC_DETECT        
    	MAPI_U8 pga_val = enable?(PGA_DEFAULT):(0x80|PGA_DEFAULT);
    	WriteReg(I2C_REG_PAGE_1, PGA_VOL_REG,  pga_val);
           WriteReg(I2C_REG_PAGE_1, PGA_VOL_REG+1,  pga_val);
    	if(enable)
    	{
    		WriteReg(I2C_REG_PAGE_1, MIXER_VOL_REG, mic_vol_table[vol]);
           	WriteReg(I2C_REG_PAGE_1, MIXER_VOL_REG+1, mic_vol_table[vol]);		
    	}
    	else
    	{
    		WriteReg(I2C_REG_PAGE_1, MIXER_VOL_REG, mic_vol_table[0]);
           	WriteReg(I2C_REG_PAGE_1, MIXER_VOL_REG+1, mic_vol_table[0]);	
    	}
    	   
    #endif	
           return MAPI_TRUE;
    }