#include "my_includes.h"
#include "I2C.h" 
#include "AUDIO.h"


#ifdef DEBUG_AUDIO
    #define AUDIO_DEBUG(x)    DEBUG(x)
#else
    #define AUDIO_DEBUG(x)
#endif
 
/*
//  Audio Data Index
parameter   Dummy_DATA  =   0;
parameter   SET_LIN_L   =   1;
parameter   SET_LIN_R   =   2;
parameter   SET_HEAD_L  =   3;
parameter   SET_HEAD_R  =   4;
parameter   A_PATH_CTRL =   5;
parameter   D_PATH_CTRL =   6;
parameter   POWER_ON    =   7;
parameter   SET_FORMAT  =   8;
parameter   SAMPLE_CTRL =   9;
parameter   SET_ACTIVE  =   10;

    
    Dummy_DATA  :   LUT_DATA    <=  16'h0000;
    SET_LIN_L   :   LUT_DATA    <=  16'h001A;
    SET_LIN_R   :   LUT_DATA    <=  16'h021A;
    SET_HEAD_L  :   LUT_DATA    <=  16'h047B;
    SET_HEAD_R  :   LUT_DATA    <=  16'h067B;
    A_PATH_CTRL :   LUT_DATA    <=  16'h08F8;
    D_PATH_CTRL :   LUT_DATA    <=  16'h0A06;
    POWER_ON    :   LUT_DATA    <=  16'h0C00;
    SET_FORMAT  :   LUT_DATA    <=  16'h0E01;
    SAMPLE_CTRL :   LUT_DATA    <=  16'h1002;
    SET_ACTIVE  :   LUT_DATA    <=  16'h1201;    
    
*/ 

/*
 // ROM[0]= 16'h1e00;
    ROM[0]= 16'h0c00;        //power down
    ROM[1]= 16'h0ec2;        //master
    ROM[2]= 16'h0838;        //sound select
    
    ROM[3]= 16'h1000;        //mclk
    
    ROM[4]= 16'h0017;        //
    ROM[5]= 16'h0217;        //
    ROM[6]= {8'h04,1'b0,vol[6:0]};       //
    ROM[7]= {8'h06,1'b0,vol[6:0]};       //sound vol
    
    //ROM[4]= 16'h1e00;      //reset    
    ROM[`rom_size]= 16'h1201;//active
    DATA_A=ROM[address];
   */

bool aduio_RegWrite(alt_u8 reg_index, alt_u16 data16);

bool aduio_RegWrite(alt_u8 reg_index, alt_u16 data16){
    bool bSuccess;
    alt_u8 data, control;
    data = data16 & 0xFF;
    control = (reg_index << 1) | ((data16 >> 8) & 0x01);
//    AUDIO_DEBUG(("[AUDIO] i2c write, reg=%Xh , data=%Xh(%02Xh/%02Xh)\r\n", reg_index, data16, control, data));
    AUDIO_DEBUG(("[AUDIO] i2c write, %02Xh/%02Xh\r\n", control, data));
    bSuccess = I2C_AUDIO_Write(control, data);
    if (!bSuccess) 
        AUDIO_DEBUG(("[AUDIO] write reg fail!!!!\r\n"));
    usleep(50*1000);        
    return bSuccess;        
}


bool AUDIO_Init(void){
    bool bSuccess;
    AUDIO_DEBUG(("[AUDIO] AUDIO_Init\r\n"));
    
    if (bSuccess)
        bSuccess = AUDIO_Reset();
//    AUDIO_SetLeftLineInVol(0x1A);
//    AUDIO_SetRightLineInVol(0x1A);
//    AUDIO_SetLeftLineOutVol(0x7B);
//    AUDIO_SetRightLineOutVol(0x7B);
    if (bSuccess)
        bSuccess = AUDIO_SetAnaloguesPath(AANALOGUE_SIDEATT_N15 | AANALOGUE_SIDETONE | AANALOGUE_DACSEL | AANALOGUE_BYPASS);  // 0xF8
    if (bSuccess)
        bSuccess = AUDIO_SetDigitalPath(ADIGITAL_DEEMP_48K);
    if (bSuccess)
        bSuccess = AUDIO_SetPowerDown(0x00);
    if (bSuccess)
        bSuccess = AUDIO_SetInterface(AIF_MSB_LEFTJUST | AIF_16BIT);
    if (bSuccess)
        bSuccess = AUDIO_SetSampling(ASAMPLING_BOSR);
    if (bSuccess)
        bSuccess = AUDIO_SetActive(TRUE);
    return bSuccess;        


}


bool AUDIO_SetLeftLineInVol(alt_u8 vol){
    bool bSuccess;
    alt_u16 data;
    AUDIO_DEBUG(("[AUDIO] set left-linein vol=%Xh\r\n", vol));
    data = vol;
    data &= 0x1F;
    bSuccess = aduio_RegWrite(REG_AUDIO_LEFT_LINEIN, data);
    return bSuccess;
    
}

bool AUDIO_SetRightLineInVol(alt_u8 vol){
    bool bSuccess;
    alt_u16 data;
    AUDIO_DEBUG(("[AUDIO] set right-linein vol=%Xh\r\n", vol));
    data = vol;
    data &= 0x1F;
    bSuccess = aduio_RegWrite(REG_AUDIO_RIGHT_LINEIN, data);
    return bSuccess;
    
}

bool AUDIO_SetLeftLineOutVol(alt_u8 vol){
    bool bSuccess;
    alt_u16 data;
    if (vol < 0x40)
        vol = 0x40;
    AUDIO_DEBUG(("[AUDIO] set left-lineout vol=%Xh\r\n", vol));
    data = vol;
    data &= 0x7F;
    bSuccess = aduio_RegWrite(REG_AUDIO_LEFT_LINEOUT, data);
    return bSuccess;
    
}

bool AUDIO_SetRightLineOutVol(alt_u8 vol){
    bool bSuccess;
    alt_u16 data;
    if (vol < 0x40)
        vol = 0x40;
    AUDIO_DEBUG(("[AUDIO] set right-lineout vol=%Xh\r\n", vol));
    data = vol;
    data &= 0x7F;
    bSuccess = aduio_RegWrite(REG_AUDIO_RIGHT_LINEOUT, data);
    return bSuccess;
    
}

bool AUDIO_SetAnaloguesPath(alt_u16 data){
    bool bSuccess;
    AUDIO_DEBUG(("[AUDIO] set analogues-path=%Xh\r\n", data));
    bSuccess = aduio_RegWrite(REG_AUDIO_ANALOGUE_PATH, data);
    return bSuccess;
    
}

bool AUDIO_SetDigitalPath(alt_u16 data){
    bool bSuccess;
    AUDIO_DEBUG(("[AUDIO] set digital-path=%Xh\r\n", data));
    bSuccess = aduio_RegWrite(REG_AUDIO_DIGITAL_PATH, data);
    return bSuccess;
    
}

bool AUDIO_SetPowerDown(alt_u16 data){
    bool bSuccess;
    AUDIO_DEBUG(("[AUDIO] set power-down=%Xh\r\n", data));
    bSuccess = aduio_RegWrite(REG_AUDIO_POWER_DOWN, data);
    return bSuccess;
    
}

bool AUDIO_SetInterface(alt_u16 data){
    bool bSuccess;
    AUDIO_DEBUG(("[AUDIO] set interface=%Xh\r\n", data));
    bSuccess = aduio_RegWrite(REG_AUDIO_INTERFACE, data);
    return bSuccess;
}

bool AUDIO_SetSampling(alt_u16 data){
    bool bSuccess;
    AUDIO_DEBUG(("[AUDIO] set sampling=%Xh\r\n", data));
    bSuccess = aduio_RegWrite(REG_AUDIO_SAMPLING, data);
    return bSuccess;
    
}


bool AUDIO_SetActive(bool bActive){
    bool bSuccess;
    AUDIO_DEBUG(("[AUDIO] set %s\r\n", bActive?"active":"inactive"));
    bSuccess = aduio_RegWrite(REG_AUDIO_ACTIVE, bActive?0x01:0x00);
    return bSuccess;
    
}

bool AUDIO_Reset(void){
    bool bSuccess;
    AUDIO_DEBUG(("[AUDIO] reset\r\n"));
    bSuccess = aduio_RegWrite(REG_AUDIO_RESET, 0x00);
    return bSuccess;
    
}




