#ifndef PARASOFT_CPPTEST

#ifdef  __cplusplus
extern "C"
{
#endif

#include "DSPCommon.h"
#include "adrs_map.h"
#include "proc_def_cmos_eval.h"
#include "proc_def_sio.h"

void init_cmos_sony_imx136(UInt8 mode)
{
    cmos_power_on();

    // CLK_O       = 74.25MHz
    // CLK_PIX_DIV = 37.125MHz
    // CLK_PIX     = 148.5MHz
    SetReg32(REG_CKG_VIN, ((0xf0U << 24) | // CLK_PIX_DIV_PULSE
                           (0x55 << 16) | // CLK_PIX_PULSE
                           (7    << 8)  | // CLK_PIX_PERIOD
                           (4    << 2)  | // CLK_O_DIV
                           (1    << 1)  | // IMCLK_SEL
                           (0    << 0))); // PLL2a_SEL
    
    init_sio();

    reset_cmos();
    stop_cmos();

    // fix register
    set_sio_cmos_register(((REG_CMOS_CID0 << 8) | 0x54), 0x63);
    set_sio_cmos_register(((REG_CMOS_CID1 << 8) | 0x0f), 0x0e);
    set_sio_cmos_register(((REG_CMOS_CID1 << 8) | 0x16), 0x02);
    set_sio_cmos_register(((REG_CMOS_CID2 << 8) | 0x36), 0x71);
    set_sio_cmos_register(((REG_CMOS_CID2 << 8) | 0x39), 0xf1);
    set_sio_cmos_register(((REG_CMOS_CID2 << 8) | 0x41), 0xf2);
    set_sio_cmos_register(((REG_CMOS_CID2 << 8) | 0x42), 0x21);
    set_sio_cmos_register(((REG_CMOS_CID2 << 8) | 0x43), 0x21);
    set_sio_cmos_register(((REG_CMOS_CID2 << 8) | 0x48), 0xf2);
    set_sio_cmos_register(((REG_CMOS_CID2 << 8) | 0x49), 0x21);
    set_sio_cmos_register(((REG_CMOS_CID2 << 8) | 0x4a), 0x21);
    set_sio_cmos_register(((REG_CMOS_CID2 << 8) | 0x52), 0x01);
    set_sio_cmos_register(((REG_CMOS_CID2 << 8) | 0x54), 0xb1);
	
    if (mode == CMOS_MODE_2x2_960x600) {
	set_sio_cmos_register(REG_CMOS_CID0_STD12EN_ADBIT, 0);          // ADBIT = 0
	set_sio_cmos_register(REG_CMOS_CID0_MODE, 0x22);                // 2x2 add mode
	set_sio_cmos_register(REG_CMOS_CID0_V_H_RESERVE_WINMODE, 0);    // WUXGA
	set_sio_cmos_register(REG_CMOS_CID0_FRSEL, 0x1);                // CMOS 27MHz 30fps
        
	UInt32 hmax = 4800;
	UInt32 vmax = 750;
	set_sio_cmos_register(REG_CMOS_CID0_HMAX0, (hmax & 0x00ff));
	set_sio_cmos_register(REG_CMOS_CID0_HMAX1, ((hmax & 0xff00) >> 8));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX0, (vmax & 0x000ff));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX1, ((vmax & 0x0ff00) >> 8));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX2, ((vmax & 0x10000) >> 16));
        
	set_sio_cmos_register(REG_CMOS_CID0_ODBIT_OPORTSEL, 0x1);       // CMOS para SDR, 12bit
	set_sio_cmos_register(REG_CMOS_CID0_XVSOUTSEL_XHSOUTSEL, ((2 << 2) | (2 << 0))); // XVS, XHS out
        
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL0, 0x01);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL1, 0x40);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL2, 0x04);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL3, 0x42);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL4, 0x04);
        
	//shatter setting
	//set_sio_cmos_register(REG_CMOS_CID0_SHS10, (((vmax >> 8) & 0x000ff)     ));
	//set_sio_cmos_register(REG_CMOS_CID0_SHS11, (((vmax >> 8) & 0x0ff00) >> 8));
	//set_sio_cmos_register(REG_CMOS_CID0_SHS12, (((vmax >> 8) & 0x10000) >> 16)); 
        
    } else if (mode == CMOS_MODE_2x2_960x600_LVDS) {
	set_sio_cmos_register(REG_CMOS_CID0_STD12EN_ADBIT, 0);          // ADBIT = 0
	set_sio_cmos_register(REG_CMOS_CID0_MODE, 0x22);                // 2x2 add mode
	set_sio_cmos_register(REG_CMOS_CID0_V_H_RESERVE_WINMODE, 0);    // WUXGA
	set_sio_cmos_register(REG_CMOS_CID0_FRSEL, 0x1);                // LVDS 74.25MHz 50fps
        
	UInt32 hmax = 2200;
	UInt32 vmax = 675;
	set_sio_cmos_register(REG_CMOS_CID0_HMAX0, (hmax & 0x00ff));
	set_sio_cmos_register(REG_CMOS_CID0_HMAX1, ((hmax & 0xff00) >> 8));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX0, (vmax & 0x000ff));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX1, ((vmax & 0x0ff00) >> 8));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX2, ((vmax & 0x10000) >> 16));
        
	set_sio_cmos_register(REG_CMOS_CID0_ODBIT_OPORTSEL, 0xe1);      // LVDS 4ch DDR, 12bit
	set_sio_cmos_register(REG_CMOS_CID0_XVSOUTSEL_XHSOUTSEL, ((2 << 2) | (2 << 0))); // XVS, XHS out
        
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL0, 0x00);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL1, 0x30);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL2, 0x08);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL3, 0x30);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL4, 0x08);
        
    } else if (mode == LVDS_MODE_1920x1080) {
	set_sio_cmos_register(REG_CMOS_CID0_STD12EN_ADBIT, 0x1);          // ADBIT = 1
	set_sio_cmos_register(REG_CMOS_CID0_MODE, 0);                     // 1080p-FullHD mode
	set_sio_cmos_register(REG_CMOS_CID0_V_H_RESERVE_WINMODE, 0x10);   // 1080p
	set_sio_cmos_register(REG_CMOS_CID0_FRSEL, 0x0);                  // LVDS 74.25MHz 60fps
        
	UInt32 hmax = 1100;
	UInt32 vmax = 1125;
	set_sio_cmos_register(REG_CMOS_CID0_HMAX0, (hmax & 0x00ff));
	set_sio_cmos_register(REG_CMOS_CID0_HMAX1, ((hmax & 0xff00) >> 8));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX0, (vmax & 0x000ff));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX1, ((vmax & 0x0ff00) >> 8));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX2, ((vmax & 0x10000) >> 16));
        
	set_sio_cmos_register(REG_CMOS_CID0_ODBIT_OPORTSEL, 0xe1);       // LVDS4ch serial DDR, 12bit
	set_sio_cmos_register(REG_CMOS_CID0_XVSOUTSEL_XHSOUTSEL, ((2 << 2) | (2 << 0))); // XVS, XHS out
        
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL0, 0x00);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL1, 0x30);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL2, 0x08);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL3, 0x30);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL4, 0x08);
        
    } else if (mode == LVDS_MODE_1920x1080_30) {
	set_sio_cmos_register(REG_CMOS_CID0_STD12EN_ADBIT, 0x1);          // ADBIT = 1
	set_sio_cmos_register(REG_CMOS_CID0_MODE, 0);                     // 1080p-FullHD mode
	set_sio_cmos_register(REG_CMOS_CID0_V_H_RESERVE_WINMODE, 0x10);   // 1080p
	set_sio_cmos_register(REG_CMOS_CID0_FRSEL, 0x1);                  // LVDS 74.25MHz 30fps
        
	UInt32 hmax = 2200;
	UInt32 vmax = 1125;
	set_sio_cmos_register(REG_CMOS_CID0_HMAX0, (hmax & 0x00ff));
	set_sio_cmos_register(REG_CMOS_CID0_HMAX1, ((hmax & 0xff00) >> 8));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX0, (vmax & 0x000ff));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX1, ((vmax & 0x0ff00) >> 8));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX2, ((vmax & 0x10000) >> 16));
        
	set_sio_cmos_register(REG_CMOS_CID0_ODBIT_OPORTSEL, 0xe1);       // LVDS4ch serial DDR, 12bit
	set_sio_cmos_register(REG_CMOS_CID0_XVSOUTSEL_XHSOUTSEL, ((2 << 2) | (2 << 0))); // XVS, XHS out
        
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL0, 0x00);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL1, 0x30);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL2, 0x08);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL3, 0x30);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL4, 0x08);
        
    } else if (mode == LVDS_MODE_1920x1080_PARA) {
	set_sio_cmos_register(REG_CMOS_CID0_STD12EN_ADBIT, 0x1);          // ADBIT = 1
	set_sio_cmos_register(REG_CMOS_CID0_MODE, 0);                     // 1080p-FullHD mode
	set_sio_cmos_register(REG_CMOS_CID0_V_H_RESERVE_WINMODE, 0x10);   // 1080p
	set_sio_cmos_register(REG_CMOS_CID0_FRSEL, 0x2);                  // LVDS 74.25MHz 60fps
        
	UInt32 hmax = 4400;
	UInt32 vmax = 1125;
	set_sio_cmos_register(REG_CMOS_CID0_HMAX0, (hmax & 0x00ff));
	set_sio_cmos_register(REG_CMOS_CID0_HMAX1, ((hmax & 0xff00) >> 8));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX0, (vmax & 0x000ff));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX1, ((vmax & 0x0ff00) >> 8));
	set_sio_cmos_register(REG_CMOS_CID0_VMAX2, ((vmax & 0x10000) >> 16));
        
	set_sio_cmos_register(REG_CMOS_CID0_ODBIT_OPORTSEL, 0x01);       // LVDS4ch serial DDR, 12bit
	set_sio_cmos_register(REG_CMOS_CID0_XVSOUTSEL_XHSOUTSEL, ((2 << 2) | (2 << 0))); // XVS, XHS out
        
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL0, 0x01);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL1, 0x20);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL2, 0x0a);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL3, 0x30);
	set_sio_cmos_register(REG_CMOS_CID0_INCKSEL4, 0x08);
    }
    
    // gain setting 
    //set_sio_cmos_register(REG_CMOS_CID0_GAIN0, 0xd2);
    //set_sio_cmos_register(REG_CMOS_CID0_GAIN0, 0x69);
    //set_sio_cmos_register(REG_CMOS_CID0_GAIN1, 0x0); 
    //set_sio_cmos_register(REG_CMOS_CID0_GAIN0, 0x3C);
    //set_sio_cmos_register(REG_CMOS_CID0_GAIN1, 0x0); 
    set_sio_cmos_register(REG_CMOS_CID0_BLKLEVEL0, 0xf0);
    set_sio_cmos_register(REG_CMOS_CID0_BLKLEVEL1, 0x0);

    wakeup_cmos();
}

void reset_cmos(void)
{
    set_sio_cmos_register(REG_CMOS_CID0_SW_RESET, 1); // CMOS reset on
    set_sio_cmos_register(REG_CMOS_CID0_SW_RESET, 0); // CMOS reset off
}

void wakeup_cmos(void)
{
    set_sio_cmos_register(REG_CMOS_CID0_STANDBY, 0); // CMOS standby off
}

void standby_cmos(void)
{
    set_sio_cmos_register(REG_CMOS_CID0_STANDBY, 1); // CMOS standby on
}

void start_cmos(void)
{
    set_sio_cmos_register(REG_CMOS_CID0_XMSTA, 0);   // CMOS master mode start
}

void stop_cmos(void)
{
    set_sio_cmos_register(REG_CMOS_CID0_XMSTA, 1);   // CMOS master mode stop
    standby_cmos();
}

void cmos_power_off(void)
{
    // GPIO[14] = 0
    ClrRegFld32(REG_GPIO_1_GPIODIR,    (1 << 6));
    ClrRegFld32(REG_GPIO_1_GPIODATA_F, (1 << 6));
}

void cmos_power_on(void)
{
    // GPIO[14] = 1
    SetRegFld32(REG_GPIO_1_GPIODIR,    (1 << 6));
    SetRegFld32(REG_GPIO_1_GPIODATA_F, (1 << 6));
}

#ifdef  __cplusplus
}
#endif

#endif  //  PARASOFT_CPPTEST
