/**
 * This api calls the DCL interface to check and clear the PDN1 bit 7 set by flashtool
 * and scrambles theh powerkey1
 */
static kal_bool FT_ClearPowerKey(void)
{
    /// Driver RTC FT Power Off request
    RTC_CTRL_FT_POWEROFF_T ft_cmd_data;
    DCL_HANDLE rtc_handle = DclRTC_Open(DCL_RTC, FLAGS_NONE);
    DclRTC_Control(rtc_handle, RTC_CMD_FT_POWEROFF, (DCL_CTRL_DATA_T *) &ft_cmd_data);
    DclRTC_Close(rtc_handle);
    return (kal_bool)ft_cmd_data.fgMetaReset;
}
kal_bool F32K_Query_Is_XOSC32(void)
{
    DCL_HANDLE rtc_handler;
    RTC_CTRL_READ_XOSC_REG_T rtc_xosc32_config;
    
    rtc_handler = DclRTC_Open(DCL_RTC, FLAGS_NONE);
    DclRTC_Control(rtc_handler, RTC_CMD_RELOAD, (DCL_CTRL_DATA_T *)NULL);

    DclRTC_Control(rtc_handler, RTC_CMD_WRITE_TRIGGER_WAIT, NULL);

    DclRTC_Control(rtc_handler, RTC_CMD_READ_XOSC_REG, (DCL_CTRL_DATA_T *)&rtc_xosc32_config);
    
    DclRTC_Close(rtc_handler); 
    
    if ((rtc_xosc32_config.XOSCValue & 0x20) == 0x0)
        return KAL_TRUE;
    else
        return KAL_FALSE;
}
void ft_util_query_rtc(FT_UTILITY_COMMAND_CNF  *cnf)
{
    // HAL modification
    //RTC_GetTime(&cnf->result.rtc);
    DCL_HANDLE rtc_handle;
    RTC_CTRL_GET_TIME_T rtc_cmd_data3; // New Declaration
    cnf->status = FT_CNF_OK;
    rtc_handle = DclRTC_Open(DCL_RTC, FLAGS_NONE);
    if(DclRTC_Control(rtc_handle, RTC_CMD_GET_TIME, (DCL_CTRL_DATA_T *)&rtc_cmd_data3) != STATUS_OK)
    {
        cnf->status = FT_CNF_FAIL;
    }
    cnf->result.rtc.rtc_year = rtc_cmd_data3.u1Year;
    cnf->result.rtc.rtc_wday = rtc_cmd_data3.u1WDay;
    cnf->result.rtc.rtc_mon = rtc_cmd_data3.u1Mon;
    cnf->result.rtc.rtc_day = rtc_cmd_data3.u1Day;
    cnf->result.rtc.rtc_hour = rtc_cmd_data3.u1Hour;
    cnf->result.rtc.rtc_min = rtc_cmd_data3.u1Min;
    cnf->result.rtc.rtc_sec = rtc_cmd_data3.u1Sec;
    DclRTC_Close(rtc_handle);
}
kal_uint8 PW_PowerDetect(void)
{
#if !defined(DRV_RTC_NOT_EXIST) && !defined(DRV_RTC_OFF)

    kal_uint8  RTC_Firston;   
    RTC_CTRL_IS_FIRST_ON_T IsFirstOn; 
    kal_uint16 REG_COMM2;
    kal_uint8 return_value = 0;
    kal_bool factors[PWR_FACTOR_MAX] = {KAL_FALSE};
    DCL_HANDLE rtc_handler;
    PW_CTRL_POWER_ON_REASON PWRon;    

    RTC_CTRL_CONFIG_PDN_BIT_T rtc_cmd_data18;

    kal_bool PowerKeyStatus;
    kal_bool WdtRstFlag;

    rtc_handler = DclRTC_Open(DCL_RTC, FLAGS_NONE);
    rtc_cmd_data18.PDNIndex = DCL_RTC_PDN2;	
    DclRTC_Control(rtc_handler, RTC_CMD_READ_PDN_BITS, (DCL_CTRL_DATA_T *)&rtc_cmd_data18); // New API with CMD & DATA
    REG_COMM2 = rtc_cmd_data18.PDNValue;    

    DclRTC_Control(rtc_handler, RTC_CMD_IS_FIRST_ON, (DCL_CTRL_DATA_T *)&IsFirstOn);	

    // If RTC first on, reset PDN bits to normal reset
    RTC_Firston = (kal_uint8)IsFirstOn.fgFirstOn;
    DclRTC_Close(rtc_handler);

	if (RTC_Firston)      
	{
          REG_COMM2 = DRV_COMM_REG2_NORMAL_RESET; // REG_COMM2 will be refered in later check
	}

	// collect all factors
	// check RTC expired
	//if (PW_Is_RTC_Expired())
	if (DclPW_Is_RTC_Expired())
	{
		factors[PWR_FACTOR_RTC_EXPIRE] = KAL_TRUE;
	}

     PowerKeyStatus = BL_PowerKey_Press();
	// check power key pressed
	if (PowerKeyStatus)
	{
		factors[PWR_FACTOR_POWER_KEY] = KAL_TRUE;
	}

    if (USBDL_Cable_IN())
    {
        factors[PWR_FACTOR_CHARGER_IN] = KAL_TRUE;
    }

     WdtRstFlag = (PW_DRV_ReadReg16(WDT_STATUS) & WDT_STATUS_BITMASK)?(KAL_TRUE):(KAL_FALSE);  
     if (WdtRstFlag)
     {
		factors[PWR_FACTOR_WDT_RESET] = KAL_TRUE;
     }
    
	// check flags
	if (REG_COMM2 & DRV_COMM_REG2_NORMAL_RESET)
	{
		factors[PWR_FACTOR_NORMAL_RESET_FLG] = KAL_TRUE;
	}
	if (REG_COMM2 & DRV_COMM_REG2_CHRPWRON)
	{
		factors[PWR_FACTOR_CHRPWRON_FLG] = KAL_TRUE;
	}
	if (REG_COMM2 & DRV_COMM_REG2_USBMS_PWRON)
	{
		factors[PWR_FACTOR_USBMS_PWRON_FLG] = KAL_TRUE;
	}
	if (REG_COMM2 & DRV_COMM_REG2_RTCPWRON)
	{
		factors[PWR_FACTOR_RTCPWRON_FLG] = KAL_TRUE;
	}
	if (REG_COMM2 & DRV_COMM_REG2_SWITCH2IDLE_PWRON)
	{
		factors[PWR_FACTOR_SWITCH2IDLE_FLG] = KAL_TRUE;
	}
	// check power on type
	// priority: PWRKEYPWRON > ABNRESET > CHRPWRON > USBPWRON_WDT > USBPWRON > RTCPWRON


	#if defined(DRV_MISC_PWIC_FORCE_RETURN_PWRKEY_POWERON)
	{
		kal_uint32 tmp_i;
		for (tmp_i=0; tmp_i<PWR_FACTOR_MAX;tmp_i++){
			factors[tmp_i] = KAL_FALSE;
		}
		factors[PWR_FACTOR_SWITCH2IDLE_FLG] = KAL_TRUE;
	}
	#endif // #if defined(DRV_MISC_PWIC_FORCE_RETURN_PWRKEY_POWERON)


	if(factors[PWR_FACTOR_PRECHRPWRON_FLG])
	{
		//BMT.PWRon = (kal_uint8)CHRPWRON;//PRECHRPWRON
		PWRon=CHRPWRON;
	}
	else if (factors[PWR_FACTOR_SWITCH2IDLE_FLG])
	{
		//BMT.PWRon = (kal_uint8)PWRKEYPWRON;
		PWRon=PWRKEYPWRON;
	}
	else if (factors[PWR_FACTOR_SWITCH2CHR_FLG])
	{
		//BMT.PWRon = (kal_uint8)CHRPWRON;
		PWRon=CHRPWRON;
	}
	else if (factors[PWR_FACTOR_SWITCH2USB_FLG])
	{
		//BMT.PWRon = (kal_uint8)USBPWRON;
		PWRon=USBPWRON;
	}
	else if ((factors[PWR_FACTOR_POWER_KEY]&& !factors[PWR_FACTOR_CHARGER_IN]&& !factors[PWR_FACTOR_USB_IN])||
	         (factors[PWR_FACTOR_POWER_KEY]&& factors[PWR_FACTOR_CHARGER_IN]&& factors[PWR_FACTOR_WDT_RESET]&& factors[PWR_FACTOR_CHRPWRON_FLG])||
	         (factors[PWR_FACTOR_POWER_KEY]&& factors[PWR_FACTOR_USB_IN]&& factors[PWR_FACTOR_WDT_RESET]&& factors[PWR_FACTOR_USBMS_PWRON_FLG])||
	         (factors[PWR_FACTOR_POWER_KEY]&& factors[PWR_FACTOR_CHARGER_IN]&& !factors[PWR_FACTOR_WDT_RESET])||
	         (factors[PWR_FACTOR_POWER_KEY]&& factors[PWR_FACTOR_USB_IN]&& !factors[PWR_FACTOR_WDT_RESET]))
	{
		//BMT.PWRon = (kal_uint8)PWRKEYPWRON;
		PWRon=PWRKEYPWRON;
	}
	else if (factors[PWR_FACTOR_WDT_RESET]&&!factors[PWR_FACTOR_CHRPWRON_FLG]&&!factors[PWR_FACTOR_USBMS_PWRON_FLG]
	         &&!factors[PWR_FACTOR_RTCPWRON_FLG]&& !factors[PWR_FACTOR_NORMAL_RESET_FLG])
	{
		//BMT.PWRon = (kal_uint8)ABNRESET;
		PWRon=ABNRESET;
	}
	#ifdef __MA_L1__
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
	#endif // #ifdef __MA_L1__
	else if ((factors[PWR_FACTOR_CHARGER_IN]&&!factors[PWR_FACTOR_POWER_KEY])||
	         (factors[PWR_FACTOR_CHARGER_IN]&&factors[PWR_FACTOR_POWER_KEY]&&!factors[PWR_FACTOR_RTCPWRON_FLG]))
	{
		//BMT.PWRon = (kal_uint8)CHRPWRON;
		PWRon=CHRPWRON;
	}
	#ifdef __USB_ENABLE__
	else if ((factors[PWR_FACTOR_USB_IN]&&!factors[PWR_FACTOR_POWER_KEY]&&factors[PWR_FACTOR_WDT_RESET]&&
	         !factors[PWR_FACTOR_NORMAL_RESET_FLG]&&factors[PWR_FACTOR_USBMS_PWRON_FLG]))
	{
		#if defined(DRV_BMT_NONE_USB_POWER_ON)
		//BMT.PWRon = (kal_uint8)CHRPWRON;
		PWRon=CHRPWRON;
		#else //#if defined(DRV_BMT_NONE_USB_POWER_ON)
		//BMT.PWRon = (kal_uint8)USBPWRON_WDT;
		PWRon=USBPWRON_WDT;
		#endif //#if defined(DRV_BMT_NONE_USB_POWER_ON)
	}
	else if ((factors[PWR_FACTOR_USB_IN]&&!factors[PWR_FACTOR_POWER_KEY])||
	         (factors[PWR_FACTOR_USB_IN]&&factors[PWR_FACTOR_POWER_KEY]&&!factors[PWR_FACTOR_USBMS_PWRON_FLG])
	        )
	{
		#if defined(DRV_BMT_NONE_USB_POWER_ON)
		//BMT.PWRon = (kal_uint8)CHRPWRON;
		PWRon=CHRPWRON;
		#else //#if defined(DRV_BMT_NONE_USB_POWER_ON)
		//BMT.PWRon = (kal_uint8)USBPWRON;
		PWRon=USBPWRON;
		#endif //#if defined(DRV_BMT_NONE_USB_POWER_ON)
	}
	#endif // #ifdef __USB_ENABLE__
	else if ((factors[PWR_FACTOR_RTC_EXPIRE]&&!factors[PWR_FACTOR_RTCPWRON_FLG]))
	{
		//BMT.PWRon = (kal_uint8)RTCPWRON;
		PWRon=RTCPWRON;
	}  
	else
	{
        PWRon = UNKNOWN_PWRON;
	}

    
    if ((PWRon == ABNRESET) || (PWRon == UNKNOWN_PWRON))
    {
        return_value = 0;
    }
    else 
    {   return_value = 0;
        if (factors[PWR_FACTOR_POWER_KEY])
            return_value |= PWR_FACTOR_BL_POWER_KEY;   
        
        if (factors[PWR_FACTOR_CHARGER_IN])
            return_value |= PWR_FACTOR_BL_CABLE_IN;
        
        if (factors[PWR_FACTOR_RTC_EXPIRE])
            return_value |= PWR_FACTOR_BL_RTC_EXPIRE;

        if (factors[PWR_FACTOR_NORMAL_RESET_FLG])
            return_value |= PWR_FACTOR_BL_NORMAL_RESET_FLG;

        if (factors[PWR_FACTOR_CHRPWRON_FLG])
            return_value |= PWR_FACTOR_BL_CHRPWRON_FLG;

        if (factors[PWR_FACTOR_USBMS_PWRON_FLG])
            return_value |= PWR_FACTOR_BL_USBMS_PWRON_FLG;

        if (factors[PWR_FACTOR_RTCPWRON_FLG])
            return_value |= PWR_FACTOR_BL_RTCPWRON_FLG;

        if (factors[PWR_FACTOR_SWITCH2IDLE_FLG] | factors[PWR_FACTOR_SWITCH2CHR_FLG] | factors[PWR_FACTOR_SWITCH2USB_FLG])
            return_value |= PWR_FACTOR_BL_FACTORY_FLG;  
    }
    
    return return_value;
     

#else // #if !defined(DRV_RTC_NOT_EXIST) && !defined(DRV_RTC_OFF)
	//BMT.PWRon = PWRKEYPWRON;
    PWRon=PWRKEYPWRON;
    return_value = 0x1;

    return return_value;
#endif // #if !defined(DRV_RTC_NOT_EXIST) && !defined(DRV_RTC_OFF)

}
kal_uint32 F32K_Get_FQMTR_DATA_For_EOSC32_Trimming(kal_uint16 eosccal_value, kal_uint16 winset)
{
        kal_uint16 reg_value, reg_xosccal_value;
        kal_uint32 FQMTR_DATA, wait_count, latency_time_start;
       
        DCL_HANDLE rtc_handler;
        RTC_CTRL_WRITE_OSC32CON_REG_T rtc_osc32_con;

        
        reg_xosccal_value = DRV_F32K_Reg(RTC_XOSCCAL);
        reg_xosccal_value &= ~0x1f;
        reg_xosccal_value |= eosccal_value;
           
        rtc_handler = DclRTC_Open(DCL_RTC, FLAGS_NONE);

        rtc_osc32_con.OSC32CON_Reg = reg_xosccal_value;
        DclRTC_Control(rtc_handler, RTC_CMD_WRITE_OSC32CON_REG, (DCL_CTRL_DATA_T *)&rtc_osc32_con);
        DclRTC_Close(rtc_handler);        

        reg_value = FQMTR_RST;         
        DRV_F32K_WriteReg(FQMTR_CON0, reg_value); // Stop freq-meter 
        /* latency time (of FQMTR_BUSY bit eable) is 2 tick time of fixed clock 
           fixed clock is EOSC32 clock
        */
        latency_time_start = drv_get_current_time(); // 32k clock time tick
        wait_count = 0;
        while(wait_count < 0xffffffff)
        {
            if (drv_get_duration_tick(latency_time_start, drv_get_current_time()) > 50) // 25*2 tick
                break;
            
            wait_count++;
        }

#if defined(DRV_F32K_FQMTR_AS_6255)        
        while(DRV_F32K_Reg(FQMTR_CON2) & FQMTR_BUSY);        
        reg_value = FQMTR_EN | winset;        
        DRV_F32K_WriteReg(FQMTR_CON0, reg_value); // start freq-meter         
#elif defined(DRV_F32K_FQMTR_AS_6250)
        while(DRV_F32K_Reg(FQMTR_CON0) & FQMTR_BUSY);
        reg_value = winset; 
        DRV_F32K_WriteReg(FQMTR_CON3, reg_value); // start freq-meter         
        reg_value = FQMTR_EN; 
        DRV_F32K_WriteReg(FQMTR_CON0, reg_value); // start freq-meter 
#endif 
        
        /* latency time (of FQMTR_BUSY bit eable) is 2 tick time of fixed clock 
           fixed clock is EOSC32 clock
        */
        latency_time_start = drv_get_current_time(); // 32k clock time tick
        wait_count = 0;
        while(wait_count < 0xffffffff)
        {
            if (drv_get_duration_tick(latency_time_start, drv_get_current_time()) > 50) // 25*2 tick
                break;
            
            wait_count++;
        }

#if defined(DRV_F32K_FQMTR_AS_6255)          
        while(DRV_F32K_Reg(FQMTR_CON2) & FQMTR_BUSY);   
#elif defined(DRV_F32K_FQMTR_AS_6250)
        while(DRV_F32K_Reg(FQMTR_CON0) & FQMTR_BUSY);
#endif

        /* latency time (of get fqmtr_data ) is 1 tick time of test clock 
           test clock is 13M clock                                        
        */
        latency_time_start = drv_get_current_time();
        wait_count = 0;
        while(wait_count<0xffffffff)
        {
            if (drv_get_duration_tick(latency_time_start, drv_get_current_time()) > 10) // 10 32K tick       
                break;
            
            wait_count++;
        }

#if defined(DRV_F32K_FQMTR_AS_6255)
        //FQMTR_DATA = ((DRV_F32K_Reg(FQMTR_CON3)&0x7fff)<<15)|((DRV_F32K_Reg(FQMTR_CON2)&0x7fff));
        FQMTR_DATA = DRV_F32K_Reg(FQMTR_CON2)&0x7fff;
#elif defined(DRV_F32K_FQMTR_AS_6250)
        FQMTR_DATA = DRV_F32K_Reg(FQMTR_CON2);
#endif

        return FQMTR_DATA;
}