/*
 * Project Name MFC DRIVER IN WINCE
 * Copyright  2009 Samsung Electronics Co, Ltd. All Rights Reserved.
 *
 * This file implements MFC driver.
 *
 * @name MFC DRIVER Module (MfcPower.c)
 * @author Jiyoung Shin (idon.shin@samsung.com)
 * @date 2009/06/05
 */



#include <windows.h>
#include <register_map.h>
#include <bsp.h>
#include "DrvLib_mem.h"
#include "pmplatform.h"
#include "MfcPower.h"
#include "MfcLogMsg.h"

HANDLE   hPwrControl;
HANDLE   PWC_msgQ = NULL;

BOOL MFCPowerInit()
{
    hPwrControl = CreateFile( L"PWC0:", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
    if (INVALID_HANDLE_VALUE == hPwrControl )
    {
        LOG_MSG(LOG_ERROR, "MFCPowerInit", "Power initialization failed");
        return FALSE;
    } 

    return TRUE;
}

BOOL MFCPowerOnOff(int on_off)
{
    DWORD dwIPIndex = PWR_IP_MFC;
    DWORD dwBytes;    
    static int isOn = 0;

    if (on_off == 0)
    {
        if(isOn == 1)
        {
            isOn = 0;

            if ( !DeviceIoControl(hPwrControl, IOCTL_PWRCON_SET_POWER_OFF, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
            {
                LOG_MSG(LOG_ERROR, "MFCPowerOnOff", "Power Off Failed");
                return FALSE;
            }            

            RETAILMSG(1, (L"MFC power off\r\n"));
        }
    }
    else 
    {
        if(isOn == 0)
        {
            isOn = 1;
            
            if ( !DeviceIoControl(hPwrControl, IOCTL_PWRCON_SET_POWER_ON, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
            {
                LOG_MSG(LOG_ERROR, "MFCPowerOnOff", "Power On Failed");
                return FALSE;
            }        
            Sleep(10);
            RETAILMSG(1, (L"MFC power on\r\n"));
        }
    }
    return TRUE;
}



BOOL MFCClockOnOff(int on_off)
{

    DWORD dwIPIndex = CLK_IP0_MFC;
    DWORD dwBytes;
    static int isOn = 0;

    if (on_off == 0) {
        if(isOn == 1)
        {
            isOn = 0;
            if ( !DeviceIoControl(hPwrControl, IOCTL_PWRCON_SET_CLOCK_OFF, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
            {
                LOG_MSG(LOG_ERROR, "MFCPowerOnOff", "Power Off Failed");
                return FALSE;
            }
            RETAILMSG(0, (L"MFC Clock off\r\n"));
        }
    }
    else {
        if(isOn == 0)
        {
            isOn = 1;
            if ( !DeviceIoControl(hPwrControl, IOCTL_PWRCON_SET_CLOCK_ON, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
            {
                LOG_MSG(LOG_ERROR, "MFCPowerOnOff", "Power On Failed");
                return FALSE;
            }
            RETAILMSG(0, (L"MFC Clock On\r\n"));
        }
    }

    return TRUE;
}

#ifdef POWER_CNTRL_APM
void MFCPowerSetToAPM(CEDEVICE_POWER_STATE APM_POWER_STATUS)
{
    MSG_DEV_STATE   txmqParam;
    
    txmqParam.bLPModeSupport = FALSE;
    txmqParam.dwDeviceID = IRQ_MFC;
    txmqParam.dwMsg = DTOP_POWER_SET;
    txmqParam.dwLParam = APM_POWER_STATUS;
    txmqParam.dwRParam = 0;

    if(!WriteMsgQueue(PWC_msgQ, &txmqParam, sizeof(MSG_DEV_STATE), INFINITE, 0))
    {
        RETAILMSG(1,(TEXT(" WriteMsgQueue Error(0x%x)\r\n"),GetLastError()));
    }

    return;
}

void MFCPowerInitToAPM()
{
    MSGQUEUEOPTIONS msgOptions;
    
    memset((void *)&msgOptions, 0x0, sizeof(msgOptions));
    msgOptions.dwSize = sizeof(MSGQUEUEOPTIONS);
    msgOptions.dwFlags = 0;
    msgOptions.dwMaxMessages = 1024;
    msgOptions.cbMaxMessage = sizeof(MSG_DEV_STATE);
    msgOptions.bReadAccess = FALSE;

    PWC_msgQ = CreateMsgQueue(OEMPM_MSGQ_NAME, &msgOptions);

    return;
}
#endif

#ifdef BSP_USEDVFS
BOOL MFCDvfsSetLevelFix()
{
    DWORD dwBytes;
    PROFILE_LIST dwLimit = HIGH_NORM_PERF;

    if(!DeviceIoControl(hPwrControl, IOCTL_DVFS_SET_PROFILE, &dwLimit, sizeof(DWORD),NULL,0,&dwBytes,NULL))
    {
        LOG_MSG(LOG_ERROR, "MFCDvfsSetLevelFix", "IOCTL_DVFS_SET_PROFILE Failed");
        return FALSE;
    }

    return TRUE;
}

BOOL MFCDvfsClearLevelFix()
{
    DWORD dwBytes;
    PROFILE_LIST dwLimit = HIGH_NORM_PERF;

    if(!DeviceIoControl(hPwrControl, IOCTL_DVFS_CLEAR_PROFILE, &dwLimit, sizeof(DWORD),NULL,0,&dwBytes,NULL))
    {
        LOG_MSG(LOG_ERROR, "MFCDvfsClearLevelFix", "IOCTL_DVFS_CLEAR_PROFILE Failed");
        return FALSE;
    }

    return TRUE;

}
#endif // BSP_USEDVFS

