
#ifndef MTK_IR_PULSECHECK_H
#define MTK_IR_PULSECHECK_H


//-----------------------------------------------------------------------------
// Header files
//-----------------------------------------------------------------------------
#include "u_irrc_btn_def.h"
#include "x_timer.h"
#include "x_pdwnc.h"
#include "x_pinmux.h"
#include "ir_if.h"
#ifdef DEFINE_IS_LOG
#undef DEFINE_IS_LOG
#endif
#ifdef CC_MTK_LOADER
#define DEFINE_IS_LOG(level, fmt...)   Printf(fmt)
#else /* CC_MTK_LOADER */
#define DEFINE_IS_LOG	IR_IsLog
#endif /* CC_MTK_LOADER */
#include "x_debug.h"
#include "sirc_ir_tbl.h"
//#ifdef CC_QHB_UPGRADE_SUPPORT
#if 0
#include "x_hal_arm.h"
#include "x_irq.h"
#include "x_bim.h"
#include "drvcust_if.h"
#endif


//-----------------------------------------------------------------------------
// Static variables
//-----------------------------------------------------------------------------
// NEC IRRX key table
#ifndef KEY_ARRAY
#define KEY_ARRAY

static const KEYARRAY_T _arKeyArray[] =
{
    { 0x1, (sizeof(_arpulsecheckKeyMap01)/sizeof(KEYUNIT_T)), _arpulsecheckKeyMap01 },               //u4BitCnt=0xC    
#ifndef IR_BZ
//for BZ model, these keys are removed
    { 0x3, (sizeof(_arpulsecheckKeyMap03)/sizeof(KEYUNIT_T)), _arpulsecheckKeyMap03 },               //u4BitCnt=0xC          
#endif
    { 0x4, (sizeof(_arpulsecheckKeyMap04)/sizeof(KEYUNIT_T)), _arpulsecheckKeyMap04 },               //u4BitCnt=0xF
    { 0x1A, (sizeof(_arpulsecheckKeyMap1A)/sizeof(KEYUNIT_T)), _arpulsecheckKeyMap1A },              //u4BitCnt=0xF
    { 0x77, (sizeof(_arpulsecheckKeyMap77)/sizeof(KEYUNIT_T)), _arpulsecheckKeyMap77 },
    { 0x97, (sizeof(_arpulsecheckKeyMap97)/sizeof(KEYUNIT_T)), _arpulsecheckKeyMap97 },
    { 0xA4, (sizeof(_arpulsecheckKeyMapA4)/sizeof(KEYUNIT_T)), _arpulsecheckKeyMapA4 },    
    { 0xC4, (sizeof(_arpulsecheckKeyMapC4)/sizeof(KEYUNIT_T)), _arpulsecheckKeyMapC4 },
    { 0x081F, (sizeof(_arpulsecheckKeyMap081F)/sizeof(KEYUNIT_T)), _arpulsecheckKeyMap081F },        //u4BitCnt=20

};
#endif /* KEY_ARRAY */


//-----------------------------------------------------------------------------
// Macro definitions
//-----------------------------------------------------------------------------
/* 
 * IRRX customization
 */
#define IRRX_XFER_USR_TO_CRYSTAL_FUNC    _XferpulsecheckToCrystal
#define IRRX_SET_USR_WAKEUP_KEY_FUNC    _SetpulsecheckWakeupKey

#define DEFAULT_IRRX_TYPE               (IRRX_USR_TYPE)
#define IRRX_USR_KEYMAP_ARRAY           (_arKeyArray)
#define IRRX_USR_MAPARRAY_SIZE          (sizeof(_arKeyArray)/sizeof(KEYARRAY_T))
#define IRRX_NEC_KEYMAP_ARRAY            (NULL)
#define IRRX_NEC_MAPARRAY_SIZE            (0)
#define IRRX_RC5_KEYMAP_ARRAY           (NULL)
#define IRRX_RC5_KEYMAP_SIZE            (0)

/* 
 * pulsecheck SIRC frame cancel time: 150 ms
 */
//#define DEFAULT_IRRX_KEY_UP_TIMEOUT     (153)
#define DEFAULT_IRRX_KEY_UP_TIMEOUT     (115)

#define KEYPAD_POLLING_TIME             (30)

#define SONY_IR_SUPPORT_081F             (1)


/* The 'b' means when IR sampling counter larger than (7+1)*8-1 = 63, it stop decoding, this forms the noise cancel time.
 * if the last bit is 0, 63 * 0.064 = 4.032 (ms)
 * if the last bit is 1, whose high period at most 1.4 ms (22 samples),
 * and low period at least 0.4(6 samples) then it means 63 + 22 - 6 = 79 samples => 79 * 0.064 = 5.056 (ms)
 * So we can have a noise cancel approaching 4 ~ 5 ms (pulsecheck's standard: 3 ~ 6 ms)
 */
#define IRRX_USR_CONFIG                 0x126401//0x6201//(0x4701)
/* We choose an actual sample period = IRRX_USR_SAPERIOD * 256 / 3000000 (sec)
 * = 3 * 64 / 3000000 (sec) = 0.064 (msec)
 */
#define IRRX_USR_SAPERIOD               0x7e//(0x001B)  // Use IR sampling rate 3 * 64 / 3m s
/*
 * The theoretical value is 8 according pulsecheck's Spec, but we find 0x8 easy to cause 1 to be recevie 0 on Foxconn's board,
 * so we adjust the value to 0x6 (blind try) until 1 is not easy to be received as 0.
 */
// #define IRRX_USR_THRESHOLD          (0x0106)  // Use sampling counter threshold 6
#define IRRX_USR_THRESHOLD              0x102//0x101//(0x0104)  // Use sampling counter threshold 6

#define IRRX_CLK_SEL                    0x5

#define MAX_KEY_ARRAY IRRX_USR_MAPARRAY_SIZE

#define KEY_EQUAL(x, y) ((x)==(y))


#define DEFAULT_IRRX_REPEAT_VALID_TIME      (75) //150->75 for SW keyboard shift android frame work

#define SLOT_NUMBER        42//0x22

#ifndef CC_MTK_LOADER
#define POWER_IRRX_REPEAT_VALID_TIME	(150)
#define IRRC_IS_USR_LONG_PRESS_FUNC     (_IsUserLongPress)
#endif

UINT32 _u4TmpPulesCount[SLOT_NUMBER];//lili_5368
UINT32 _gu4TmpCurrSlot = 0;//
//#ifndef CC_MTK_LOADER
static UINT32 u4IrPulseTimeUnit = 25;
static BOOL _fgInit = FALSE;
UINT32 u4fgEnableCorrection = 1;

#include "sirc_ir_dbg.h"

//#endif
UINT32 g_u4IRRX_KEY_UP_TIMEOUT = DEFAULT_IRRX_KEY_UP_TIMEOUT;

//-----------------------------------------------------------------------------
// function prototypes
//-----------------------------------------------------------------------------
//#ifndef CC_MTK_LOADER
static UINT32 _pulsecheckIrDataCheck(UINT8 *pu1Data, UINT32 u4BitCnt, UINT32 *pu4Invalid, UINT32 u4FlagExactFramePeriod);
static UINT32 _LooseRepeatPulseChk(UINT32, UINT32, UINT32);
//#endif


//-----------------------------------------------------------------------------
// static functions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/** _IRRX_CrystalLookup()
 */
//-----------------------------------------------------------------------------
static UINT32 _CrystalLookup(const KEYUNIT_T *prKeyMap,
    UINT32 u4Size, UINT32 u4Data)
{
    UINT32 u4Min, u4Max, u4Avg;

    if (prKeyMap == NULL)
    {
        return BTN_INVALID;
    }

    if(u4Size == 1)
    {
        if (KEY_EQUAL(prKeyMap[0].u4Key, u4Data))
        {
            return prKeyMap[0].u4Crystal;
        }        
        else
        {
            return BTN_INVALID;
        }
    }

    u4Min = 0;
    u4Max = u4Size - 1;

    while (u4Max > u4Min)
    {
        u4Avg = (u4Max + u4Min) / 2;

        if (KEY_EQUAL(prKeyMap[u4Min].u4Key, u4Data))
        {
            return prKeyMap[u4Min].u4Crystal;
        }

        if (KEY_EQUAL(prKeyMap[u4Max].u4Key, u4Data))
        {
            return prKeyMap[u4Max].u4Crystal;
        }

        if (KEY_EQUAL(prKeyMap[u4Avg].u4Key, u4Data))
        {
            return prKeyMap[u4Avg].u4Crystal;
        }
        else if (prKeyMap[u4Avg].u4Key > u4Data)
        {
            u4Max = u4Avg;
        }
        else if (prKeyMap[u4Avg].u4Key < u4Data)
        {
            if (u4Min == u4Avg)
            {
                u4Max = u4Avg;
            }
            else
            {
                u4Min = u4Avg;
            }
        }
    }
    return BTN_INVALID;
}


//-----------------------------------------------------------------------------
/** IRRX_GetCrystalKey()
 */
//-----------------------------------------------------------------------------
static UINT32 _GetCrystalKey(UINT32 u4GroupId, UINT8 u1Data, UINT32 u4BitCnt)
{
    UINT32 i;

    if (_arKeyArray==NULL)
    {
        return BTN_INVALID;
    }

    for (i=0; i<MAX_KEY_ARRAY; i++)
    {
        if ((u4GroupId == _arKeyArray[i].u4GroupId) && 
            //((i==0) ? (u4BitCnt == 0xc) : (u4BitCnt == 0xf)))
            //david: modify for _arpulsecheckKeyMap03 of pulsecheck_ATV 
#ifdef IR_BZ
            (((i < 1) ? (u4BitCnt == 0xc) : (u4BitCnt == 0xf))||((u4GroupId == 0x081f)&&(u4BitCnt == 20))))
#else
            (((i < 2) ? (u4BitCnt == 0xc) : (u4BitCnt == 0xf))||((u4GroupId == 0x081f)&&(u4BitCnt == 20))))
#endif
        {
            return _CrystalLookup(_arKeyArray[i].prKeyMap,
                                _arKeyArray[i].u4Size, (UINT32)u1Data);
        }
    }

    return BTN_INVALID;
}
//-----------------------------------------------------------------------------
/** _IRRX_XferpulsecheckToCrystal() the IRRX data to Crystal IRRX key code map
 *      function.
 *  @param u4Info the IRRX received related attributes of the current data.
 *  @param pu1Data the IRRX received and current data.
 *  @return the Crystal button key. BTN_NONE is no key.
 */
//-----------------------------------------------------------------------------

static UINT32 _XferpulsecheckToCrystal(UINT32 u4Info, const UINT8 *pu1Data, IRRX_RAW_DATA_T *prRaw)
{
//    static HAL_TIME_T rLastIntrTime = { 0, 0 };
    static UINT32 u4PrevValidKey = BTN_NONE;
    UINT32 u4GrpId, u4BitCnt, u4Key;//, u4PrevData;
    static HAL_TIME_T rPrevValidTime = { 0, 0 };
    HAL_TIME_T rNowTime, rValidDelta;
    UINT32 i=0;//lili_5368
//#ifndef CC_MTK_LOADER
    UINT32 u4FlagExactFramePeriod;
    UINT32 u4Invalid = 0;
  
    if(!_fgInit)
    {
            if(IO32ReadFldAlign(PDWNC_PDMODE, FLD_DEEP_SLEEP))// 3Mhz
            {
                u4IrPulseTimeUnit = (IO32ReadFldAlign(PDWNC_IRCFGL, FLD_CHK_SAPERIOD) * 1000000)/(3 * 1000000);
            }
            else
            {
                u4IrPulseTimeUnit = (IO32ReadFldAlign(PDWNC_IRCFGL, FLD_CHK_SAPERIOD) * 1000000)/(24 * 1000000);
            }
            _fgInit = TRUE;
            LOG(7,"u4IrPulseTimeUnit is %d us\n", u4IrPulseTimeUnit);
    }
//#endif
    
    u4BitCnt = INFO_TO_BITCNT(u4Info);

//#ifndef CC_MTK_LOADER
    // GPIO_IrDataLog(pu1Data, u4BitCnt);
//#endif /* CC_5360_LOADER */

    /* Check empty data. */
    if ((u4BitCnt==0) || (pu1Data==NULL))
    {
        LOG(7, "(%d) BTN_NONE\n", __LINE__);
        return BTN_NONE;
    }
    _gu4TmpCurrSlot=0;
    for(i=0; ;i++)
    {
        if((u1IO32Read1B(PDWNC_CHKDATA0 + i) == 0 )||(i == SLOT_NUMBER))
		{
			break;
		}
    	_u4TmpPulesCount[i]=u1IO32Read1B(PDWNC_CHKDATA0+i);
        _gu4TmpCurrSlot++;
    }

    /* Validate bit count of receiving frame. */
    if((u4BitCnt!=0xc) && (u4BitCnt!=0xf) && (u4BitCnt!=0x14))
    {                    
        LOG(7, "BitCnt error (%d), (%d) BTN_NONE\n",u4BitCnt, __LINE__);
        return BTN_NONE;
    }

    HAL_GetTime(&rNowTime);
    HAL_GetDeltaTime(&rValidDelta, &rPrevValidTime, &rNowTime);
//#ifndef CC_MTK_LOADER
    u4FlagExactFramePeriod = 0;
    if(rValidDelta.u4Seconds == 0)
    {
        if ((rValidDelta.u4Micros > 42000) && (rValidDelta.u4Micros < 48000)) //45+-3
        {
            u4FlagExactFramePeriod = 1;
        }
    }
//#endif
//    u4PrevData = *((UINT32 *)pu1Data);
//#ifndef CC_MTK_LOADER
    if (_pulsecheckIrDataCheck((UINT8 *)pu1Data, u4BitCnt, &u4Invalid, u4FlagExactFramePeriod))//lili_5368
    {
        LOG(7, "(%d)### _pulsecheckIrDataCheck fail (BTN_NONE)\n", __LINE__);
        return BTN_NONE;
    }
//#endif /* CC_MTK_LOADER */

    //u4GrpId = (pu1Data[0] >> 7) | (pu1Data[1] << 1);
    #if SONY_IR_SUPPORT_081F
    u4GrpId = ((pu1Data[0] >> 7) | (pu1Data[1] << 1) | ((pu1Data[2]&0xf)<<9));
    #else
    u4GrpId = (pu1Data[0] >> 7) | (pu1Data[1] << 1);
    #endif
    LOG(1, "pu1Data[0]=0x%04x,pu1Data[1]=0x%04x,pu1Data[2]=0x%04x,u4GrpId=0x%04x\n",pu1Data[0],pu1Data[1],pu1Data[2],u4GrpId);
    u4Key = _GetCrystalKey(u4GrpId, pu1Data[0] & 0x7F, u4BitCnt);
	LOG(1,"pu1Data0=0x%08x,pu1Data1=0x%08x,u4GrpId=0x%08x,u4BitCnt=0x%08x.\n",pu1Data[0],pu1Data[1],u4GrpId,u4BitCnt);				
    if (u4Key == BTN_INVALID) 
    {
        u4Key = BTN_NONE; 
        LOG(7, "Lookup fail\n");                
    }
#if 0
    HAL_GetTime(&rNowTime);
    HAL_GetDeltaTime(&rValidDelta, &rPrevValidTime, &rNowTime);
#endif
    /* Validate if 1st frame equals to 2nd frame */
    if ((rValidDelta.u4Micros > (/*DEFAULT_IRRX_KEY_UP_TIMEOUT*/g_u4IRRX_KEY_UP_TIMEOUT * 1000)) || (rValidDelta.u4Seconds != 0))
    {
        u4PrevValidKey = BTN_NONE;
    }

    if (u4Key != u4PrevValidKey)
    {
        u4PrevValidKey = u4Key;     
        if (u4Key != BTN_NONE) { HAL_GetTime(&rPrevValidTime); }
        LOG(7, "(%d) ### Key:0x%08x Prev:0x%08x Delta:%d.%06d BTN_NONE[%d ms]\n", __LINE__, u4Key, u4PrevValidKey,
            rValidDelta.u4Seconds, rValidDelta.u4Micros, g_u4IRRX_KEY_UP_TIMEOUT);
        return BTN_NONE;
    }
    
    HAL_GetTime(&rPrevValidTime);
    //LOG(10, "Crystal key: 0x%8x\n", u4Key);    

    prRaw->u4Len = 4;
    x_memcpy((void*)prRaw->au1Data, (void*)pu1Data, 4);    
    if(u4Key == BTN_MUTE)
    {
        LOG(10, "Mute button...");    
//        LOG(0, "Mute button\n");    
    }
    return u4Key;
}

//-----------------------------------------------------------------------------
/** _SetpulsecheckWakeupKey() to set pulsecheck wakeup key
 *  @param
 *  @param
 *  @return
 */
//-----------------------------------------------------------------------------
static void _SetpulsecheckWakeupKey(void)
{

    UINT32 i, j, u4KeyNum, u4Val;

    if (_arKeyArray==NULL)
    {
        LOG(7, "NEC IR key array is not found.\n");
        return;
    }

    u4KeyNum = 0;
    vIO32WriteFldAlign(PDWNC_IREXP_EN, 0x1, FLD_BCEPEN);
    vIO32WriteFldAlign(PDWNC_EXP_BCNT, 0x0c,  FLD_EXP_BITCNT);
    if(DRVCUST_InitGet(eIrrxFlagAllWakeup))
    {
        vIO32Write4B(PDWNC_ENEXP_IRM, 0x00000f80);

        for (i=0; i < MAX_KEY_ARRAY ; i++)
        {
            vIO32WriteFldAlign(PDWNC_IREXP_EN, IREXP_EN(i), FLD_IREXPEN);

            u4Val = _arKeyArray[i].u4GroupId;     
            vIO32Write4B(PDWNC_EXP_IR0 + (4*i), u4Val);

        }
    }
    else
    {
        vIO32Write4B(PDWNC_ENEXP_IRM, 0x00000fff);
        for (i=0; i<MAX_KEY_ARRAY; i++)
        {
            for (j=0; j<_arKeyArray[i].u4Size; j++) // u4GroupId, prKeyMap
            {
                if ((u4KeyNum < MAX_EXP_KEY_NUM) &&
                    (_arKeyArray[i].prKeyMap[j].u4Crystal == BTN_POWER))
                {
                    vIO32WriteFldAlign(PDWNC_IREXP_EN,(IO32ReadFldAlign(PDWNC_IREXP_EN, FLD_IREXPEN) | IREXP_EN(u4KeyNum)), FLD_IREXPEN);

                    u4Val = (_arKeyArray[i].u4GroupId << 7) |
                            (_arKeyArray[i].prKeyMap[j].u4Key);
                    vIO32Write4B(PDWNC_EXP_IR0 + (4*u4KeyNum), u4Val);
                    u4KeyNum++;
                }
            }
        }
        // BTN_POWER_ON to wakeup        
        for (i=0; i<MAX_KEY_ARRAY; i++)
        {
            for (j=0; j<_arKeyArray[i].u4Size; j++) // u4GroupId, prKeyMap
            {
                if (DRVCUST_InitGet(eIrrxFlagPowerOnWakeup) &&
            (u4KeyNum < MAX_EXP_KEY_NUM) &&
                    (_arKeyArray[i].prKeyMap[j].u4Crystal == BTN_POWER_ON))
                {
                    vIO32WriteFldAlign(PDWNC_IREXP_EN,(IO32ReadFldAlign(PDWNC_IREXP_EN, FLD_IREXPEN) | IREXP_EN(u4KeyNum)), FLD_IREXPEN);
                    u4Val = (_arKeyArray[i].u4GroupId << 7) |
                            (_arKeyArray[i].prKeyMap[j].u4Key);
                    vIO32Write4B(PDWNC_EXP_IR0 + (4*u4KeyNum), u4Val);
                    u4KeyNum++;
                }
            }
        }
/*        
        for (i=0; i<MAX_KEY_ARRAY; i++)
        {
            for (j=0; j<_arKeyArray[i].u4Size; j++) // u4GroupId, prKeyMap
            {
                if ((u4KeyNum < MAX_EXP_KEY_NUM) &&
                    (_arKeyArray[i].prKeyMap[j].u4Crystal == BTN_PRG_UP))
                {
                    vIO32WriteFldAlign(PDWNC_IREXP_EN,(IO32ReadFldAlign(PDWNC_IREXP_EN, FLD_IREXPEN) | IREXP_EN(u4KeyNum)), FLD_IREXPEN);

                    u4Val = (_arKeyArray[i].u4GroupId << 7) |
                            (_arKeyArray[i].prKeyMap[j].u4Key);
                    vIO32Write4B(PDWNC_EXP_IR0 + (4*u4KeyNum), u4Val);
                    u4KeyNum++;
                }
            }
        }

        for (i=0; i<MAX_KEY_ARRAY; i++)
        {
            for (j=0; j<_arKeyArray[i].u4Size; j++) // u4GroupId, prKeyMap
            {
                if ((u4KeyNum < MAX_EXP_KEY_NUM) &&
                    (_arKeyArray[i].prKeyMap[j].u4Crystal == BTN_PRG_DOWN))
                {
                    vIO32WriteFldAlign(PDWNC_IREXP_EN,(IO32ReadFldAlign(PDWNC_IREXP_EN, FLD_IREXPEN) | IREXP_EN(u4KeyNum)), FLD_IREXPEN);

                    u4Val = (_arKeyArray[i].u4GroupId << 7) |
                            (_arKeyArray[i].prKeyMap[j].u4Key);
                    vIO32Write4B(PDWNC_EXP_IR0 + (4*u4KeyNum), u4Val);
                    u4KeyNum++;
                }
            }
        }
*/
    }

}


//#ifndef CC_MTK_LOADER
//-----------------------------------------------------------------------------
// Macro definitions
//-----------------------------------------------------------------------------
//#define CLOCK_SLOT_TIME(x)        ((1000 * (x)) /_u4CpuClkMhz)

//-----------------------------------------------------------------------------
// Static variables
//-----------------------------------------------------------------------------

// [0] is garbage. it's time from previous transaction (low to high) to the beginning of the leading pulse(high to low).
// [1] is leading pulse length of low ([high to low] to [low to high]) ... and so on.

// It's also the state machine for whole system.
#ifndef NDEBUG
static UINT32 u4GuidePulse = 0;
static UINT32 u4AvgTimeOff = 0;
static UINT32 u4MuteBtnAvgTimeOn0 = 0;
static UINT32 u4MuteBtnAvgTimeOn1 = 0;
#endif
/*static*/ UINT32 _u4CpuClkMhz = 0;

//-----------------------------------------------------------------------------
// Static functions
//-----------------------------------------------------------------------------    
#define g_u4GuidePulseMin 1800   //1900
#define g_u4GuidePulseMax 2840
	
	UINT32 gu4GuidePulseMin = g_u4GuidePulseMin;
	UINT32 gu4GuidePulseMax = g_u4GuidePulseMax;
	
	static UINT32 _ChkGuidePulseInvalid(UINT32 *pu4TimeSlot, UINT32 u4SlotNum)
	{
//		LOG(10,"GuidePulse, %d us ",(pu4TimeSlot[0])*u4IrPulseTimeUnit);
#ifndef NDEBUG
	u4GuidePulse = pu4TimeSlot[0] * u4IrPulseTimeUnit;
#endif	
		if (u4SlotNum < 1) { return 1; }
		if ((pu4TimeSlot[0] < gu4GuidePulseMin/u4IrPulseTimeUnit) ||	// 1.90ms
			(pu4TimeSlot[0] > gu4GuidePulseMax/u4IrPulseTimeUnit))		// 2.75ms
		{
			LOG(10,"Invalid GuidePulse, %d us\n", (pu4TimeSlot[0])*u4IrPulseTimeUnit );
			return 1;
		}
		return 0;
	}
	
#define g_u4TimeOffMin2  200 //280//300//450
#define g_u4TimeOffMax2  1350 //875//700
	
	UINT32 gu4TimeOffMin2 = g_u4TimeOffMin2;
	UINT32	gu4TimeOffMax2 = g_u4TimeOffMax2;
	
	static UINT32 _ChkTimeOffInvalid(UINT32 *pu4TimeSlot, UINT32 u4SlotNum)
	{
		UINT32 i, u4Sum, u4Cnt, fgRet;
	
	//UNUSED(u4AvgTimeOff);
		if (u4SlotNum < 2) { return 1; }
		u4Sum = 0;
		u4Cnt = 0;
		fgRet = 0;
		for (i=1; i<u4SlotNum; i+=2)
		{
			u4Sum += pu4TimeSlot[i];
			u4Cnt++;
			if ((pu4TimeSlot[i] < gu4TimeOffMin2/u4IrPulseTimeUnit) || // 0.45ms
				(pu4TimeSlot[i] > gu4TimeOffMax2/u4IrPulseTimeUnit))   // standard: 0.75ms, but Wistron's receiver tend to have longer Toff, so use 0.65ms
			{
				LOG(10, "Invalid TimeOff2 slot[%d] %d us\n", i,pu4TimeSlot[i]*u4IrPulseTimeUnit);
				fgRet = 1;
			}
		}
#ifndef NDEBUG	
	u4AvgTimeOff = (u4Sum / u4Cnt) * u4IrPulseTimeUnit;
#endif	
	//LOG(10, "Avg. TimeOff: %d ns\n", (u4AvgTimeOff*u4IrPulseTimeUnit));
		return fgRet;
	}
	
	
#define g_u4TimeOn0Min2  100  //280//500//470
#define g_u4TimeOn0Max2  900//800
	UINT32 gu4TimeOn0Min2 = g_u4TimeOn0Min2;
	UINT32 gu4TimeOn0Max2 = g_u4TimeOn0Max2;
	
	static UINT32 _ChkTimeOn0Invalid(UINT32 *pu4TimeSlot, UINT32 u4SlotNum)
	{
		UINT32 i;
	
		if (u4SlotNum < 3) { return 1; }
		for (i=2; i<u4SlotNum; i+=2)
		{
			if (pu4TimeSlot[i] < 880 /u4IrPulseTimeUnit) // 0.88ms
			{
				if ((pu4TimeSlot[i] < gu4TimeOn0Min2/u4IrPulseTimeUnit) || // 0.50ms
					(pu4TimeSlot[i] > gu4TimeOn0Max2/u4IrPulseTimeUnit))   // 0.80ms
				{
					LOG(10,  "Invalid TimeOn0 slot[%d] %d us \n", i, pu4TimeSlot[i]*u4IrPulseTimeUnit);
					return 1;
				}
			}
		}
#ifndef NDEBUG	
	u4MuteBtnAvgTimeOn0 = pu4TimeSlot[2] * u4IrPulseTimeUnit;
#endif	
		return 0;
	}
	
#define g_u4TimeOn1Min2  900 //950//1100//1075
#define g_u4TimeOn1Max2  1600 //1550//1600//1400
	UINT32 gu4TimeOn1Min2 = g_u4TimeOn1Min2;
	UINT32 gu4TimeOn1Max2 = g_u4TimeOn1Max2;
	static UINT32 _ChkTimeOn1Invalid(UINT32 *_u4PulesCount, UINT32 u4SlotNum)
		{
			UINT32 i;
			if (u4SlotNum < 3) { return 1; }
			for (i=2; i<u4SlotNum; i+=2)
			{
				if (_u4PulesCount[i] >= gu4TimeOn1Min2/u4IrPulseTimeUnit) // 1.05ms
				{
					if ((_u4PulesCount[i] < gu4TimeOn1Min2/u4IrPulseTimeUnit) ||   // 1.10ms
						(_u4PulesCount[i] > gu4TimeOn1Max2/u4IrPulseTimeUnit))	 // 1.40ms
					{
						LOG(10,  "Invalid TimeOn1 slot[%d] %d us\n", i, _u4PulesCount[i]*u4IrPulseTimeUnit);
						return 1;
					}
				}
			}
#ifndef NDEBUG	
	u4MuteBtnAvgTimeOn1 =  _u4PulesCount[6] * u4IrPulseTimeUnit;	
#endif	
			return 0;
		}


static UINT32 _LooseRepeatPulseChk(UINT32 u4Cnt, UINT32 u4PreData, UINT32 u4Data)
{
    UINT32 i;
    UINT32 u4Unmatch = 0;
    for(i = 0; i < u4Cnt; i++)
    {
        if( (u4PreData & (0x1UL << i)) ^ (u4Data & (0x1UL << i)) )
        {
            u4Unmatch++;
        }
        if(u4Unmatch > 2)
        {
            LOG(10,  "[RepeatPulseChk] DROP!! unmatch bits > 2 \n");
            return 0;//
        }
    }
    if(u4Unmatch)
    {
        LOG(10,  "[RepeatPulseChk] DROP!! unmatch bits %d\n", u4Unmatch);
    }
    return 1;
}

#define LOOSE_TIME_OFF_CHK_ERR      0x01
#define BASIC_TIME_OFF_CHK_ERR      0x02
#define LOOSE_BIT_1_CHK_ERR         0x04
#define STRICT_TIME_ON_0_CHK_ERR    0x08
#define STRICT_TIME_ON_1_CHK_ERR    0x10


#define g_u4OnlyTimeOffMin 200 //300
#define g_u4OnlyTimeOffMax 950 //700

    UINT32 gu4OnlyTimeOffMin = g_u4OnlyTimeOffMin;
    UINT32 gu4OnlyTimeOffMax = g_u4OnlyTimeOffMax;

	static UINT32 _ChkOnlyTimeOffInvalid(UINT32 *pu4TimeSlot, UINT32 u4SlotNum)
	{
		UINT32 i, fgRet;
	
		if (u4SlotNum < 2) { return 1; }
		fgRet = 0;
		for (i=1; i<u4SlotNum; i+=2)
		{
			if ((pu4TimeSlot[i]*u4IrPulseTimeUnit < gu4OnlyTimeOffMin) || // 0.45ms
				(pu4TimeSlot[i]*u4IrPulseTimeUnit > gu4OnlyTimeOffMax))   // standard: 0.75ms, but Wistron's receiver tend to have longer Toff, so use 0.65ms
			{
				LOG(10, "Invalid OnlyTimeOff slot[%d] %d us\n", i,pu4TimeSlot[i]*u4IrPulseTimeUnit);
				fgRet = 1;
			}
		}
		return fgRet;
	}
#define g_u4TimeOffStrictMax 1100
    
        UINT32 gu4TimeOffStrictMax = g_u4TimeOffStrictMax;
    
    	static UINT32 _ChkTimeOffStrict(UINT32 *pu4TimeSlot, UINT32 u4SlotNum)
    	{
    		UINT32 i, fgRet;
    	
    		if (u4SlotNum < 2) { return 1; }
    		fgRet = 0;
    		for (i=1; i<u4SlotNum; i+=2)
    		{
    			if (pu4TimeSlot[i]*u4IrPulseTimeUnit > gu4TimeOffStrictMax)
    			{
    				LOG(10, "Invalid TimeOffStrict slot[%d] %d us\n", i,pu4TimeSlot[i]*u4IrPulseTimeUnit);
    				fgRet = 1;
    			}
    		}
    		return fgRet;
    	}


#define g_u4OnlyTimeOn1Min 900  //1075
UINT32 gu4OnlyTimeOn1Min = g_u4OnlyTimeOn1Min;

#define g_u4OnlyTimeOn1Max 1600 // 1650
UINT32 gu4OnlyTimeOn1Max = g_u4OnlyTimeOn1Max;//1480;

#define g_u4OnlyTimeOn0Min 350  //500
UINT32 gu4OnlyTimeOn0Min = g_u4OnlyTimeOn0Min;//400;

#define g_u4OnlyTimeOn0Max 900
UINT32 gu4OnlyTimeOn0Max = g_u4OnlyTimeOn0Max;

UINT32 gu4Sum01Boundary = 1500;//1300;

void ir_set_threshold(UINT8 index, UINT32 value)
{
    switch(index)
    {
        case 0:  gu4GuidePulseMin     = value; break;
        case 1:  gu4GuidePulseMax     = value; break;
        
        case 2:  gu4TimeOffMin2       = value; break;
        case 3:  gu4TimeOffMax2       = value; break;
        
        case 4:  gu4TimeOn0Min2       = value; break;
        case 5:  gu4TimeOn0Max2       = value; break;

        case 6:  gu4TimeOn1Min2       = value; break;
        case 7:  gu4TimeOn1Max2       = value; break;

        case 8:  gu4OnlyTimeOffMin    = value; break;
        case 9:  gu4OnlyTimeOffMax    = value; break;
        
        case 10:  gu4OnlyTimeOn0Min   = value; break;
        case 11:  gu4OnlyTimeOn0Max   = value; break;

        case 12:  gu4OnlyTimeOn1Min   = value; break;
        case 13:  gu4OnlyTimeOn1Max   = value; break;

        case 14: gu4TimeOffStrictMax  = value; break;
        case 15: gu4Sum01Boundary     = value; break;
    }
}
void ir_dump_threshold(void)
{
    Printf("0:GuidePulseMin: %d\n", gu4GuidePulseMin);
    Printf("1:GuidePulseMax: %d\n", gu4GuidePulseMax);

    Printf("2:TimeOffMin2: %d\n", gu4TimeOffMin2);
    Printf("3:TimeOffMax2: %d\n", gu4TimeOffMax2);

    Printf("4:TimeOn0Min2: %d\n", gu4TimeOn0Min2);
    Printf("5:TimeOn0Max2: %d\n", gu4TimeOn0Max2);

    Printf("6:TimeOn1Min2: %d\n", gu4TimeOn1Min2);
    Printf("7:TimeOn1Max2: %d\n", gu4TimeOn1Max2);

    Printf("8:OnlyTimeOffMin: %d\n", gu4OnlyTimeOffMin);
    Printf("9:OnlyTimeOffMax: %d\n", gu4OnlyTimeOffMax);

    Printf("10:OnlyTimeOn0Min: %d\n", gu4OnlyTimeOn0Min);
    Printf("11:OnlyTimeOn0Max: %d\n", gu4OnlyTimeOn0Max);

    Printf("12:OnlyTimeOn1Min: %d\n", gu4OnlyTimeOn1Min);
    Printf("13:OnlyTimeOn1Max: %d\n", gu4OnlyTimeOn1Max);


    Printf("14:TimeOffStrictMax: %d\n", gu4TimeOffStrictMax);

    Printf("15:gu4Sum01Boundary: %d\n", gu4Sum01Boundary);
}

// return value: 1 to drop, 0 to process.
static UINT32 _pulsecheckIrDataCheck(UINT8 *pu1Data, UINT32 u4BitCnt, UINT32 *pu4Invalid, UINT32 u4RepeatPeriod)
{
    UINT32 _u4PulesCount[SLOT_NUMBER] = {0};//lili_5368
    INT32 i;
    UINT32 u4SlotNum, u4Bit;
    UINT32 u4Crit;
    UINT32 u4BadGuidePulse, u4BadTimeOff, u4OnlyBadTimeOff, u4TimeOffStrict;
    UINT32 u4BadTimeOn0, u4BadTimeOn1;
    UINT32 u4Correction = 0, u4FrameWidthErr = 0;
    static UINT32 u4PreValidBitCnt, u4PreValidData;
    LOG(10,  "Bit:%d Slot:%d Data:0x%02x%02x\n", u4BitCnt, _gu4TmpCurrSlot, pu1Data[1], pu1Data[0]);
    if(!(u4BitCnt == 12 || u4BitCnt == 15 || u4BitCnt == 20))
    {
        LOG(10,  "DROP!! bit count error!\n");
    }
    u4Crit = HalCriticalStart(); 
    u4SlotNum = _gu4TmpCurrSlot;
    _gu4TmpCurrSlot = 0;
    for (i=0; i<u4SlotNum; i++)
    {
        _u4PulesCount[i]=_u4TmpPulesCount[i];
    }
    HalCriticalEnd(u4Crit);

    add_histogram(_u4PulesCount, (u4BitCnt * 2) + 1);
    u4BadGuidePulse = _ChkGuidePulseInvalid(_u4PulesCount, (u4BitCnt * 2) + 1);
    u4BadTimeOff = _ChkTimeOffInvalid(_u4PulesCount, (u4BitCnt * 2) + 1);
    u4BadTimeOn0 = _ChkTimeOn0Invalid(_u4PulesCount, (u4BitCnt * 2) + 1);
    u4BadTimeOn1 = _ChkTimeOn1Invalid(_u4PulesCount, (u4BitCnt * 2) + 1);
    u4OnlyBadTimeOff = _ChkOnlyTimeOffInvalid(_u4PulesCount, (u4BitCnt * 2) + 1);
    u4TimeOffStrict = _ChkTimeOffStrict(_u4PulesCount, (u4BitCnt * 2) + 1);
    
#ifndef NDEBUG    
    LOG(10, "### GP %d us, Avg. TOff %d us, M_TOn0 %d us, M_TOn1 %d us, RepeatPeriod %d\n", u4GuidePulse, u4AvgTimeOff, u4MuteBtnAvgTimeOn0, u4MuteBtnAvgTimeOn1, u4RepeatPeriod);
#endif	
	if(u4BadGuidePulse)
	{
            add_error_counters(2);
        LOG(9, "Drop data by bad guide pulse\n");
		return 1;
	}	
    *pu4Invalid = u4BadGuidePulse + u4BadTimeOff + u4BadTimeOn0 + u4BadTimeOn1;
    if(u4fgEnableCorrection)    
    {
        if (!u4BadGuidePulse && !u4BadTimeOn0 && !u4BadTimeOn1 &&
            u4OnlyBadTimeOff)
        {
            if(!u4RepeatPeriod)
            {
                LOG(10,  "DROP!! Only TimeOff, %d us, [%d - %d] us\n", (_u4PulesCount[i] * u4IrPulseTimeUnit), 
                        gu4OnlyTimeOffMin, gu4OnlyTimeOffMax);
                add_error_counters(3);
                return 1; // to drop
            }
            else
            {
                u4FrameWidthErr |= LOOSE_TIME_OFF_CHK_ERR;
            }
        }
        if (u4TimeOffStrict)
        {
            if(!u4RepeatPeriod)
            {
                LOG(10,  "DROP!! TimeOff strict, %d us, %d, 0x%08x us\n", (_u4PulesCount[i] * u4IrPulseTimeUnit), 
                        _u4PulesCount[i] * u4IrPulseTimeUnit, _u4PulesCount[i] * u4IrPulseTimeUnit);
                add_error_counters(4);
                return 1; // to drop
            }
            else
            {
                u4FrameWidthErr |= BASIC_TIME_OFF_CHK_ERR;
            }
        }

        for(i = 1; i < (u4BitCnt * 2) ;  i+=2)
        {
            u4Bit = (i-1) >> 1;
#if 0  //mark by purplearrow
            if ((_u4PulesCount[i + 1] * u4IrPulseTimeUnit > /*880*/920) &&		// 0.88ms 920
                (_u4PulesCount[i + 1] * u4IrPulseTimeUnit < 1050))			// 1.05ms
            {
                if(!u4RepeatPeriod)
                {
                    // return 1 only when the TimeOff time is near 600ms.  if it larger than 750ms, no drop.
                    if (_u4PulesCount[i] * u4IrPulseTimeUnit < 600) // 0.60ms
                    {
                        // strong signal, need more check.
                        LOG(10,  "DROP!! no TimeOnX, %d us, %d, 0x%08x\n", (_u4PulesCount[i + 1] * u4IrPulseTimeUnit), 
                                _u4PulesCount[i + 1] * u4IrPulseTimeUnit, _u4PulesCount[i + 1] * u4IrPulseTimeUnit);
                        return 1; // to drop
                    }
                }
                else
                {
                    u4FrameWidthErr |= LOOSE_BIT_1_CHK_ERR;
                }
            }
#endif             
            // the odd is TimeOn0/TimeOn1.
            if ((_u4PulesCount[i]+_u4PulesCount[i+1]) * u4IrPulseTimeUnit < gu4Sum01Boundary)//check TimeOn0 :_u4PulesCount[i] means time off  ,_u4PulesCount[i+1] means TimeOn0
            {
                if(!u4RepeatPeriod)
                {
                    // it's TimeOn0.
                    if (!u4BadGuidePulse && !u4BadTimeOff && !u4BadTimeOn1 &&
                        ((_u4PulesCount[i + 1] * u4IrPulseTimeUnit < gu4OnlyTimeOn0Min) || (_u4PulesCount[i + 1] * u4IrPulseTimeUnit > gu4OnlyTimeOn0Max)))
                    {
                        LOG(10,  "DROP!! no TimeOn0, %d us, [%d - %d] us\n", (_u4PulesCount[i + 1] * u4IrPulseTimeUnit),
                            gu4OnlyTimeOn0Min, gu4OnlyTimeOn0Max);
                        add_error_counters(5);
                        return 1;
                    }
                }
                else
                {
                    u4FrameWidthErr |= STRICT_TIME_ON_0_CHK_ERR;
                }

                if (pu1Data[((u4Bit) >> 3)] & (1U << (u4Bit & 0x7)))
                {
                    u4Correction = 1;
                    LOG(10,  "bit%d 1=>0\n", u4Bit);
                    pu1Data[((u4Bit) >> 3)] &= ~(1U << (u4Bit & 0x7));
                }
            }
            else //check TimeOn1 
            {
                if(!u4RepeatPeriod)
                {
                    // it's TimeOn1.
                    if (!u4BadGuidePulse && !u4BadTimeOff && !u4BadTimeOn0 &&
                        ((_u4PulesCount[i + 1] * u4IrPulseTimeUnit < (gu4OnlyTimeOn1Min)) || (_u4PulesCount[i + 1] * u4IrPulseTimeUnit > gu4OnlyTimeOn1Max)))   // 1.1ms ~ 1.48ms
                    {
                        LOG(10,  "DROP!! no TimeOn1, %d us,[%d - %d]\n", (_u4PulesCount[i + 1] * u4IrPulseTimeUnit), gu4OnlyTimeOn1Min, gu4OnlyTimeOn1Max);
                        add_error_counters(6);
                        return 1;
                    }
                }
                else
                {
                    u4FrameWidthErr |= STRICT_TIME_ON_1_CHK_ERR;
                }

                if (!(pu1Data[((u4Bit) >> 3)] & (1U << (u4Bit & 0x7))))
                {
                    u4Correction = 1;
                    LOG(10,  "bit%d 0=>1\n", u4Bit);
                    pu1Data[((u4Bit) >> 3)] |= (1U << (u4Bit & 0x7));
                }
            }
        }
        if(u4Correction == 1)
        {
            LOG(10, "New Bit:%d Data:0x%02x%02x\n", u4BitCnt, pu1Data[1], pu1Data[0]);
        }
        if(!u4RepeatPeriod)
        {
            u4PreValidBitCnt = u4BitCnt;
            u4PreValidData = (((UINT32)pu1Data[2]) << 16) | (((UINT32)pu1Data[1]) << 8) | ((UINT32)pu1Data[0]);
        }
        else if(u4FrameWidthErr)
        {
            if((u4PreValidBitCnt == u4BitCnt) && (_LooseRepeatPulseChk(u4BitCnt, u4PreValidData, (((UINT32)pu1Data[2]) << 16) | (((UINT32)pu1Data[1]) << 8) | ((UINT32)pu1Data[0]))))
            {
                return 0;
            }
            else
            {
                if(u4FrameWidthErr & LOOSE_TIME_OFF_CHK_ERR)
                {
                    LOG(10,  "[FrameWidthErr]DROP!! no TimeOff[%d - %d] us\n", gu4OnlyTimeOffMin, gu4OnlyTimeOffMax);
                }
                if(u4FrameWidthErr & BASIC_TIME_OFF_CHK_ERR)
                {
                    LOG(10,  "[FrameWidthErr]DROP!! only TimeOff fail(>1100ms)\n");
                }
                if(u4FrameWidthErr & LOOSE_BIT_1_CHK_ERR)
                {
                    LOG(10,  "[FrameWidthErr]DROP!! (TimeOff < 600) and (920 < TimeOn < 1050)\n");
                }
                if(u4FrameWidthErr & STRICT_TIME_ON_0_CHK_ERR)
                {
                    LOG(10,  "[FrameWidthErr]DROP!! no TimeOn0[%d - %d] us\n", gu4OnlyTimeOn0Min, gu4OnlyTimeOn0Max);
                }
                if(u4FrameWidthErr & STRICT_TIME_ON_1_CHK_ERR)
                {
                    LOG(10,  "[FrameWidthErr]DROP!! no TimeOn1[%d - %d]\n",gu4OnlyTimeOn1Min, gu4OnlyTimeOn1Max);
                }
                add_error_counters(7);
                return 1;
            }
        }
        else
        {
            return 0;
        }
        return 0; // to process.
    }
    else
    {
        if(*pu4Invalid)
            return 1;
        else
            return 0;
    }
}

// return value: 1 to drop, 0 to process.
#ifndef CC_MTK_LOADER
static UINT32 _IsUserLongPress(UINT32 rDelta, IRRX_RAW_DATA_T *rRaw, IRRX_RAW_DATA_T *rPrevRaw)
{
	if (rRaw->u1Protocol == 0 && rRaw->u4Len == 4 && *(UINT32*)(rRaw->au1Data) == 0x00000095)
	{
	    LOG(1, "[IRRC]%d) Apply POWER_IRRX_REPEAT_VALID_TIME = %d\n", __LINE__, POWER_IRRX_REPEAT_VALID_TIME);
	    if (rDelta > (1000 * POWER_IRRX_REPEAT_VALID_TIME))
	    {
	        LOG(1, "[IRRC]%d) Not Repeat! ", __LINE__);
	        return 0;//the period of coming of the two continusing frame is larger than threshold ==> not long press
	    }
	    else
	    {
	        LOG(1, "[IRRC]%d) Repeat! ", __LINE__);
	        return 1;
	    }
	}
	else
    {
	    if (rDelta > (1000 * IRRX_QuerySetRepeatDuration(NULL)))
	    {
	        LOG(1, "[IRRC]%d) Not Repeat! ", __LINE__);
	        return 0;//the period of coming of the two continusing frame is larger than threshold ==> not long press
	    }
	    else
	    {
	       LOG(1, "[IRRC]%d) Repeat! ", __LINE__);
	        return 1;
	    }
    }
}
#endif

//#endif /* CC_MTK_LOADER */

//#ifdef CC_QHB_UPGRADE_SUPPORT
#if 0
#ifdef  CC_MTK_LOADER

#define u4SonyIRPowerKey 0x8f000

externC void HalEnableIRQ(void);
extern PFN_IRQ_HANDLER RegisterIrqHandler(PFN_IRQ_HANDLER pfnNewHandler);
#define LOADER_IRRX_IRQ_INIT_FUNC      (_LOADER_IrrxIrqInit)

static PFN_IRQ_HANDLER _pfnLoaderIrrxPreIrqIsr = NULL;
static void _LOADER_IrrxIrqIsr(void)
{	
    UINT32 u4Info;
    UINT32 au4IrRxData[4]={0};
    IRRX_RAW_DATA_T rRaw;
	UINT32 u4CrystalKey = 0;
	rRaw.u1Protocol = IRRX_RAW_DATA_NONE;
    rRaw.u4Len = 1;
    DTVCFG_T rDtvCfg;
    UINT32 u4Value;
	UINT8 u1StateCtrl = 4; //power on
    u4Value = PDWNC_ReadWakeupReason();
    /* read IRRX IRQ data. */
	if (BIM_IsIrqPending(VECTOR_PDWNC))
    {
        if(IO32ReadFldAlign(PDWNC_INTSTA,FLD_IR_INT_STA))    
        {
			u4Info = u4IO32Read4B(PDWNC_IRCNT);
			au4IrRxData[0] = u4IO32Read4B(PDWNC_IRDATA0);
			au4IrRxData[1] = u4IO32Read4B(PDWNC_IRDATA1);
			//Printf("[Loader IR]:0x%08x RxIsr Info:0x%08x 0x%08x%08x\n",u4IO32Read4B(PDWNC_INTSTA), u4Info, au4IrRxData[1], au4IrRxData[0]);
			u4CrystalKey = _XferpulsecheckToCrystal(u4Info,au4IrRxData,&rRaw);
			//Printf("QHB=0x%x,wakeupreason=%d,u1Upgrade_Ext=0x%x,u4CrystalKey=0x%08x.\n",rDtvCfg.u1Flags4,u4Value,rDtvCfg.u1Upgrade_Ext,u4CrystalKey);
			if(u4CrystalKey == u4SonyIRPowerKey)
			{
				UNUSED(EEPDTV_GetCfg(&rDtvCfg));
				if ((rDtvCfg.u1Flags4 & DTVCFG_FLAG4_QUIET_HOT_BOOT)&&(PDWNC_WAKE_UP_REASON_WATCHDOG == u4Value)&&((rDtvCfg.u1Upgrade_Ext & 0x59)))
				{
					Printf("[Upgrade]press IR power key reboot!!!!!!!!.\n");
					Printf("[QHB_zzuu]clear QHB flag9.\n");
					UNUSED(EEPDTV_GetCfg(&rDtvCfg));
					rDtvCfg.u1Flags4 &= (UINT8)~DTVCFG_FLAG4_QUIET_HOT_BOOT;
					UNUSED(EEPDTV_SetCfg(&rDtvCfg));
					if (EEPROM_Write(0x039D, (UPTR)&u1StateCtrl, 1))
					{
						Printf("Write EEPROM fail at PDWNC_Custom_EnterNextState : u4NextState = 0x%x\n", u1StateCtrl);
					}
                    PDWNC_Reboot();
				}
			}
			vIO32WriteFldAlign(PDWNC_IRCLR, 1, FLD_IRCLR);   //need to confirm this register zuyu
			vIO32WriteFldAlign(PDWNC_INTCLR, 1, FLD_IR_INTCLR);
        }
        BIM_ClearIrq(VECTOR_PDWNC);        
    }
    if (_pfnLoaderIrrxPreIrqIsr) { _pfnLoaderIrrxPreIrqIsr(); }
}


static void _LOADER_IrrxIrqInit(void)
{  
	vIO32WriteFldAlign(PDWNC_IRCLR, 1, FLD_IRCLR);	 //need to confirm this register zuyu
	vIO32WriteFldAlign(PDWNC_INTCLR, 1, FLD_IR_INTCLR);
    _pfnLoaderIrrxPreIrqIsr = RegisterIrqHandler(_LOADER_IrrxIrqIsr);
	printf("loader ir init\n");
	vIO32WriteFldAlign(PDWNC_ARM_INTEN, 1, FLD_IR_INTEN);
	vIO32WriteFldAlign(PDWNC_ARM_INTEN, 0, FLD_AUX_INTEN);
	BIM_EnableIrq(VECTOR_PDWNC);
	//enable pdwnc ir int for loader
    //HalEnableIRQ();//already enable int usb_isr init

}

#endif
#endif


#endif /* MTK_IR_pulsecheck_H */

