📄 power_control.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Module Name:
Drv.c Power Controller Driver
Abstract:
Streams interface driver (MDD)
Functions:
Notes:
--*/
#include <bsp.h>
#include <DrvLib.h>
#include <pmplatform.h>
#include "s3c6410_power_control.h"
#ifdef REMOVE_BEFORE_RELEASE
#define PWRCON_MSG(x)
#define PWRCON_INF(x)
#define PWRCON_ERR(x) RETAILMSG(TRUE, x)
#else
//#define PWRCON_MSG(x) RETAILMSG(TRUE, x)
#define PWRCON_MSG(x)
#define PWRCON_INF(x) RETAILMSG(TRUE, x)
//#define PWRCON_INF(x)
#define PWRCON_ERR(x) RETAILMSG(TRUE, x)
//#define PWRCON_ERR(x)
#endif
#define QUEUE_ENTRIES (16)
#define MAX_NAMELEN (64)
#define QUEUE_SIZE (QUEUE_ENTRIES*(sizeof(POWER_BROADCAST)+MAX_NAMELEN))
#define POWER_MONITOR_THREAD_PRIODITY (98)
//#define SLEEP_AGING_TEST
static volatile S3C6410_SYSCON_REG *g_pSysConReg = NULL;
static HANDLE g_hThreadPowerMon = NULL;
static HANDLE g_hMsgQueue = NULL;
static BOOL g_aIPPowerStatus[PWR_IP_MAX] = {FALSE, };
static BOOL g_bExitThread = FALSE;
static CRITICAL_SECTION csPowerCon;
INT WINAPI PowerMonitorThread(void)
{
HANDLE hPowerNotification = NULL;
MSGQUEUEOPTIONS msgOptions;
PPOWER_BROADCAST pB;
RESET_STATUS eRstStat;
UCHAR msgBuf[QUEUE_SIZE];
int iBytesInQueue = 0;
DWORD dwFlags;
int iSleepCount = 0;
PWRCON_INF((_T("[PWRCON:INF] ++PowerMonitorThread()\r\n")));
eRstStat = PwrCon_get_reset_status();
//-------------------------------------------------
// Set Power Monitor Thread Priority
//-------------------------------------------------
CeSetThreadPriority(g_hThreadPowerMon, POWER_MONITOR_THREAD_PRIODITY);
//-------------------------------------------------
// Create a message queue for Power Manager notifications.
//-------------------------------------------------
memset((void *)&msgOptions, 0x0, sizeof(msgOptions));
msgOptions.dwSize = sizeof(MSGQUEUEOPTIONS);
msgOptions.dwFlags = 0;
msgOptions.dwMaxMessages = QUEUE_ENTRIES;
msgOptions.cbMaxMessage = sizeof(POWER_BROADCAST) + MAX_NAMELEN;
msgOptions.bReadAccess = TRUE;
g_hMsgQueue = CreateMsgQueue(NULL, &msgOptions);
if (g_hMsgQueue == NULL )
{
PWRCON_ERR((_T("[PWRCON:ERR] PowerMonitorThread() : CreateMsgQueue() Failed : Err %d\r\n"), GetLastError()));
g_bExitThread = TRUE;
}
// Request Power notifications
hPowerNotification = RequestPowerNotifications(g_hMsgQueue, POWER_NOTIFY_ALL);
if (!hPowerNotification)
{
PWRCON_ERR((_T("[PWRCON:ERR] PowerMonitorThread() : RequestPowerNotifications() Failed : Err %d\r\n"), GetLastError()));
g_bExitThread = TRUE;
}
while(!g_bExitThread)
{
memset(msgBuf, 0x0, QUEUE_SIZE);
pB = (PPOWER_BROADCAST)msgBuf;
//PWRCON_INF((_T("[PWR:INF] PowerMonitorThread() : Wait for PM Notification\r\n")));
// Read message from queue.
if (!ReadMsgQueue(g_hMsgQueue, msgBuf, QUEUE_SIZE, &iBytesInQueue, INFINITE, &dwFlags))
{
if (g_bExitThread)
{
break;
}
PWRCON_ERR((_T("[PWRCON:ERR] PowerMonitorThread() : ReadMsgQueue() Failed : Err %d\r\n"), GetLastError()));
}
else if (iBytesInQueue < sizeof(POWER_BROADCAST))
{
PWRCON_ERR((_T("[PWRCON:ERR] PowerMonitorThread() : Receive Insufficient Message (Size is %d, Expected %d)\r\n"), iBytesInQueue, sizeof(POWER_BROADCAST)));
}
else
{
switch (pB->Message)
{
//-----------------------
// Notified State Transition
//-----------------------
case PBT_TRANSITION:
PWRCON_INF((_T("[PWRCON:INF] Notified [PBT_TRANSITION : %s (0x%08x)]\r\n"), pB->SystemPowerState, pB->Flags));
break;
//-----------------------
// Notified Resume State
//-----------------------
case PBT_RESUME:
PWRCON_INF((_T("[PWRCON:INF] Notified [PBT_RESUME]\r\n")));
{
DWORD dwWakeSrc = SYSWAKE_UNKNOWN;
DWORD dwBytesRet = 0;
if (KernelIoControl(IOCTL_HAL_GET_WAKE_SOURCE, NULL, 0, &dwWakeSrc, sizeof(dwWakeSrc), &dwBytesRet)
&& (dwBytesRet == sizeof(dwWakeSrc)))
{
switch(dwWakeSrc)
{
case SYSWAKE_POWER_BUTTON: // Power Button
PWRCON_INF((_T("[PWRCON:INF] Wake Up by Power Button\r\n")));
PWRCON_INF((_T("[PWRCON:INF] SetSystemPowerState(POWER_STATE_ON)\r\n")));
SetSystemPowerState(NULL, POWER_STATE_ON, POWER_FORCE);
break;
case OEMWAKE_RTC_ALARM:
PWRCON_INF((_T("[PWRCON:INF] Wake Up by RTC Alarm\r\n")));
//PWRCON_INF((_T("[PWRCON:INF] SetSystemPowerState(POWER_STATE_ON)\r\n")));
// Do not change Power State to POWER_STATE_ON
break;
case OEMWAKE_RTC_TICK:
PWRCON_INF((_T("[PWRCON:INF] Wake Up by RTC Tick\r\n")));
PWRCON_INF((_T("[PWRCON:INF] SetSystemPowerState(POWER_STATE_ON)\r\n")));
SetSystemPowerState(NULL, POWER_STATE_ON, POWER_FORCE);
break;
case OEMWAKE_KEYPAD:
PWRCON_INF((_T("[PWRCON:INF] Wake Up by Keypad\r\n")));
PWRCON_INF((_T("[PWRCON:INF] SetSystemPowerState(POWER_STATE_ON)\r\n")));
SetSystemPowerState(NULL, POWER_STATE_ON, POWER_FORCE);
break;
case OEMWAKE_MSM:
PWRCON_INF((_T("[PWRCON:INF] Wake Up by MSM I/F\r\n")));
//PWRCON_INF((_T("[PWRCON:INF] SetSystemPowerState(POWER_STATE_ON)\r\n")));
//SetSystemPowerState(NULL, POWER_STATE_ON, POWER_FORCE);
break;
case OEMWAKE_BATTERY_FAULT:
PWRCON_INF((_T("[PWRCON:INF] Wake Up by Battery Fault\r\n")));
//PWRCON_INF((_T("[PWRCON:INF] SetSystemPowerState(POWER_STATE_ON)\r\n")));
//SetSystemPowerState(NULL, POWER_STATE_ON, POWER_FORCE);
break;
case OEMWAKE_WARM_RESET:
PWRCON_INF((_T("[PWRCON:INF] Wake Up by Warm Reset\r\n")));
PWRCON_INF((_T("[PWRCON:INF] SetSystemPowerState(POWER_STATE_ON)\r\n")));
SetSystemPowerState(NULL, POWER_STATE_ON, POWER_FORCE);
break;
case OEMWAKE_HSI:
PWRCON_INF((_T("[PWRCON:INF] Wake Up by HSI I/F\r\n")));
//PWRCON_INF((_T("[PWRCON:INF] SetSystemPowerState(POWER_STATE_ON)\r\n")));
//SetSystemPowerState(NULL, POWER_STATE_ON, POWER_FORCE);
break;
default:
PWRCON_ERR((_T("[PWRCON:ERR] WakeUp Source = 0x%08x\r\n"), dwWakeSrc));
break;
}
#ifdef SLEEP_AGING_TEST
PWRCON_ERR((_T("[PWRCON] Sleep Count = %d\r\n"), iSleepCount));
Sleep(1000);
iSleepCount++;
SetSystemPowerState(NULL, POWER_STATE_SUSPEND, POWER_FORCE);
#endif
}
else
{
NKDbgPrintfW(L"PWRCON: Error getting wake source\r\n");
PWRCON_ERR((_T("[PWRCON:ERR] IOCTL_HAL_GET_WAKE_SOURCE Failed\r\n")));
PWRCON_ERR((_T("[PWRCON:ERR] System is Still in [PBT_RESUME] State\r\n")));
}
}
break;
//-----------------------------------
// Notified Power Supply changed (AC/DC)
//-----------------------------------
case PBT_POWERSTATUSCHANGE:
PWRCON_INF((_T("[PWRCON:INF] Notified [PBT_POWERSTATUSCHANGE]\r\n")));
break;
//---------------------------------
// Notified Power Information changed
//---------------------------------
case PBT_POWERINFOCHANGE:
{
PPOWER_BROADCAST_POWER_INFO ppbpi;
ppbpi = (PPOWER_BROADCAST_POWER_INFO)pB->SystemPowerState;
PWRCON_INF((_T("[PWRCON:INF] Notified [PBT_POWERINFOCHANGE]\r\n")));
//PWRCON_INF((_T("[PWRCON:INF] ACLine Status : %d\r\n"), ppbpi->bACLineStatus));
//PWRCON_INF((_T("[PWRCON:INF] Battery Flag : %d\r\n"), ppbpi->bBatteryFlag));
//PWRCON_INF((_T("[PWRCON:INF] Backup Flag : %d\r\n"), ppbpi->bBackupBatteryFlag));
//PWRCON_INF((_T("[PWRCON:INF] Level : %d\r\n"), ppbpi->dwNumLevels));
break;
}
default:
PWRCON_ERR((_T("[PWRCON:ERR] Notified Unknown Message [0x%08x]\r\n"), pB->Message));
break;
}
}
}
if (hPowerNotification)
{
StopPowerNotifications(hPowerNotification);
hPowerNotification = NULL;
}
if (g_hMsgQueue)
{
CloseMsgQueue(g_hMsgQueue);
g_hMsgQueue = NULL;
}
PWRCON_INF((_T("[PWRCON:INF] --PowerMonitorThread()\r\n")));
return 0;
}
static BOOL
PWC_AllocResources(void)
{
PWRCON_MSG((_T("[PWRCON] ++PWC_AllocResources()\r\n")));
//--------------------
// System Controller SFR
//--------------------
g_pSysConReg = (S3C6410_SYSCON_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_SYSCON, sizeof(S3C6410_SYSCON_REG), FALSE);
if (g_pSysConReg == NULL)
{
PWRCON_ERR((_T("[PWRCON:ERR] PWC_AllocResources() : g_pSysConReg DrvLib_MapIoSpace() Failed \n\r")));
return FALSE;
}
//--------------------
// Critical Section
//--------------------
InitializeCriticalSection(&csPowerCon);
PWRCON_MSG((_T("[PWRCON] --PWC_AllocResources()\r\n")));
return TRUE;
}
static void
PWC_ReleaseResources(void)
{
PWRCON_MSG((_T("[PWRCON] ++PWC_ReleaseResources()\r\n")));
if (g_pSysConReg != NULL)
{
DrvLib_UnmapIoSpace((PVOID)g_pSysConReg);
g_pSysConReg = NULL;
}
DeleteCriticalSection(&csPowerCon);
PWRCON_MSG((_T("[PWRCON] --PWC_ReleaseResources()\r\n")));
}
BOOL
DllMain(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
//DEBUGREGISTER(hinstDll);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -