?? battif.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 module contains a stub implementation of the battery PDD. OEMs
// that want to support the battery APIs on their platform can copy this
// file to their platform and link it into their own version of the power
// manager DLL.
//
// If the platform-specific power manager provides its own version of these
// entry points, this module will not be pulled into the link map from
// the pm_battapi library.
//
// To simplify testing the behavior of battery-sensitive applications on
// platforms (like CEPC or EMULATOR) that don't include physical batteries,
// this driver uses a memory-mapped file to store power information. This
// file is shared with the SETSTUBBAT test program in
// public\common\oak\drivers\battdrvr\test\setstubbat, which can update
// arbitrary battery values. Note that memory-mapped files require that
// the OS image include the "nkmapfile" component.
//
#include <battimpl.h>
#include <devload.h>
#include "battery.h"
#include "aclink.h"
#include "touch.h"
// typedefs for APIs that require the "nkmapfile" component
typedef WINBASEAPI HANDLE (WINAPI *PFN_CreateFileMappingW) (
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCWSTR lpName
);
typedef LPVOID (WINAPI *PFN_MapViewOfFile) (
HANDLE hFileMappingObject,
DWORD dwDesiredAccess,
DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow,
DWORD dwNumberOfBytesToMap
);
typedef BOOL (WINAPI *PFN_UnmapViewOfFile) (
LPCVOID lpBaseAddress
);
typedef BOOL (WINAPI * PFN_GwesPowerDown)(void);
#define MUTEX_TIMEOUT 5000
static PBATTERY_STATUS gpStatus;
static HANDLE ghMutex;
static HANDLE ghFileMap;
static PFN_CreateFileMappingW gpfnCreateFileMappingW;
static PFN_MapViewOfFile gpfnMapViewOfFile;
static PFN_UnmapViewOfFile gpfnUnmapViewOfFile;
#define BATTERY_ADC_USE_AUX3 TRUE
#define BATTERY_ADC_USE_AUX4 FALSE
static HANDLE gADCMutex;
//point to the AC97 read/write functions based on
//the needs for the power handler
BOOL (*g_pfnReadAc97) (BYTE Offset, UINT16 * Data, BYTE DevId);
BOOL (*g_pfnWriteAc97) (BYTE Offset, UINT16 Data, BYTE DevId);
//----------------------------------------------------------------------------------------------------------------
//local function
//----------------------------------------------------------------------------------------------------------------
BOOL g_pfnWriteAc97Mask(BYTE Offset, unsigned short int Data,unsigned short int Mask)
{
BOOL RetVal=FALSE;
unsigned short CodecData;
if(!Mask)
return RetVal;
if(Mask!=0xFFFF)
{
if(g_pfnReadAc97(Offset,&CodecData,DEV_BATTERY))
{
CodecData&=~Mask;
CodecData|=(Data&Mask);
RetVal=g_pfnWriteAc97(Offset,CodecData,DEV_BATTERY);
}
}
else
{
RetVal=g_pfnWriteAc97(Offset,Data,DEV_BATTERY);
}
return RetVal;
}
//----------------------------------------------------------------------------------------------------------------
//
// Function ADC_Lock()
//
// Purpose: This function will ensure that the AC 97 Link Controller is being used mutually exclusively.
// Either a read of a write operation is in progress at anytime.
//
//----------------------------------------------------------------------------------------------------------------
short int ADC_Lock()
{
DWORD retval;
retval=WaitForSingleObject(gADCMutex, 3000);
if(retval==WAIT_OBJECT_0)
{
return(TRUE);
}
else
{
DEBUGCHK(1);
return(FALSE);
}
}
//----------------------------------------------------------------------------------------------------------------
//
// Function ADC_Unlock()
//
// Purpose: To Unlock the ADC .
//
//----------------------------------------------------------------------------------------------------------------
short int ADC_Unlock()
{
ReleaseMutex(gADCMutex);
return(TRUE);
}
//----------------------------------------------------------------------------------------------------------------
//
// Function Get_Battery_ADCValue()
//
// Purpose: Get ADC value from AUX
//
//----------------------------------------------------------------------------------------------------------------
BOOL Get_Battery_ADCValue(unsigned Battery_Channel,unsigned short int *ADCValue)
{
unsigned short int BackupCB1,BackupCB2;
unsigned short adccr,adcDataReg;
BOOL noError=FALSE;
if(!PrimaryCodecReady())
{
return FALSE;
}
//backup touch panel control byte1 and control byte2
g_pfnReadAc97(RT_TP_CTRL_BYTE1,&BackupCB1,DEV_BATTERY);
g_pfnReadAc97(RT_TP_CTRL_BYTE2,&BackupCB2,DEV_BATTERY);
//set touch panel control byte 1
adccr=POW_TP_CTRL_3 | CB1_CR2 | CB1_CLK_DIV64 | CB1_DEL_8F;
g_pfnWriteAc97(RT_TP_CTRL_BYTE1,adccr, DEV_BATTERY);
//set touch panel control byte 2
adccr =CB2_AUX_EN | (Battery_Channel == CB2_AUX_SEL_AUX3 ? CB2_AUX_SEL_AUX3 : CB2_AUX_SEL_AUX4);
g_pfnWriteAc97(RT_TP_CTRL_BYTE2,adccr, DEV_BATTERY); //write to polling mode
//set Polling trigger
adccr |=CB2_POLL_TRIG;
//start to ADC convert
if(g_pfnWriteAc97(RT_TP_CTRL_BYTE2,adccr, DEV_BATTERY))
{
do
{
if(!g_pfnReadAc97(RT_TP_CTRL_BYTE2,(UINT16 *) &adcDataReg,DEV_BATTERY))
break;
} while (TEST(adcDataReg,CB2_POLL_TRIG));
g_pfnReadAc97(RT_TP_INDICATION,(UINT16 *) &adcDataReg,DEV_BATTERY);
if((adcDataReg&CB3_ADCSRC_AUX)==CB3_ADCSRC_AUX)
{
*ADCValue=adcDataReg & CB3_ADC_DATA;
noError=TRUE;
}
}
//restore touch panel control 1 and control 2
g_pfnWriteAc97(RT_TP_CTRL_BYTE1,BackupCB1, DEV_BATTERY);
g_pfnWriteAc97(RT_TP_CTRL_BYTE2,BackupCB2, DEV_BATTERY);
return(noError);
}
// this routine takes the battery mutex
DWORD
LockBattery(void)
{
DWORD dwStatus;
SETFNAME(_T("LockBattery"));
DEBUGCHK(ghMutex != NULL);
dwStatus = WaitForSingleObject(ghMutex, MUTEX_TIMEOUT);
if(dwStatus == WAIT_OBJECT_0) {
dwStatus = ERROR_SUCCESS;
} else {
dwStatus = GetLastError();
DEBUGCHK(dwStatus != ERROR_SUCCESS);
}
DEBUGMSG(dwStatus != ERROR_SUCCESS && ZONE_WARN,
(_T("%s: WaitForSingleObject() failed %d\r\n"), pszFname,
GetLastError()));
DEBUGCHK(dwStatus == ERROR_SUCCESS);
return dwStatus;
}
// this routine releases the battery mutex
DWORD
UnlockBattery(void)
{
DWORD dwStatus = ERROR_SUCCESS;
BOOL fOk;
SETFNAME(_T("UnlockBattery"));
DEBUGCHK(ghMutex != NULL);
fOk = ReleaseMutex(ghMutex);
if(!fOk) {
dwStatus = GetLastError();
DEBUGCHK(dwStatus != ERROR_SUCCESS);
}
DEBUGMSG(dwStatus != ERROR_SUCCESS && ZONE_WARN,
(_T("%s: ReleaseMutex() failed %d\r\n"), pszFname, GetLastError()));
DEBUGCHK(dwStatus == ERROR_SUCCESS);
return dwStatus;
}
BOOL WINAPI
BatteryPDDInitialize(LPCTSTR pszRegistryContext)
{
BOOL fOk = TRUE;
HKEY hk;
SYSTEM_POWER_STATUS_EX2 sps;
WORD wMainLevels = 3, wBackupLevels = 3;
BOOL fSupportsChange = FALSE;
SETFNAME(_T("BatteryPDDInitialize"));
DEBUGCHK(ghMutex == NULL);
DEBUGCHK(ghFileMap == NULL);
DEBUGCHK(gpStatus == NULL);
DEBUGCHK(pszRegistryContext != NULL);
// intialize the battery status structure -- assume AC power, no battery info
sps.ACLineStatus = AC_LINE_ONLINE;
sps.BatteryFlag = BATTERY_FLAG_HIGH;
sps.BatteryLifePercent = BATTERY_PERCENTAGE_UNKNOWN;
sps.Reserved1 = 0;
sps.BatteryLifeTime = BATTERY_LIFE_UNKNOWN;
sps.BatteryFullLifeTime = BATTERY_LIFE_UNKNOWN;
sps.Reserved2 = 0;
sps.BackupBatteryFlag = BATTERY_FLAG_HIGH;
sps.BackupBatteryLifePercent = BATTERY_PERCENTAGE_UNKNOWN;
sps.Reserved3 = 0;
sps.BackupBatteryLifeTime = BATTERY_LIFE_UNKNOWN;
sps.BackupBatteryFullLifeTime = BATTERY_LIFE_UNKNOWN;
sps.BatteryChemistry = BATTERY_CHEMISTRY_UNKNOWN;
sps.BatteryVoltage = 0;
sps.BatteryCurrent = 0;
sps.BatteryAverageCurrent = 0;
sps.BatteryAverageInterval = 0;
sps.BatterymAHourConsumed = 0;
sps.BatteryTemperature = 0;
sps.BackupBatteryVoltage = 0;
// get registry values, if present
hk = OpenDeviceKey(pszRegistryContext);
if(hk != NULL) {
DWORD dwSize, dwStatus, dwType, dwValue;
SYSTEM_POWER_STATUS_EX2 spstemp;
// get the number of main levels
dwSize = sizeof(dwValue);
dwStatus = RegQueryValueEx(hk, _T("MainLevels"), NULL, &dwType, (LPBYTE) &dwValue, &dwSize);
if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD) {
wMainLevels = (WORD) dwValue;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -