⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 power_control.c

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -