www.pudn.com > Battdrvr.rar > 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. 
// 
 
/* Copyright © 1999-2002 Intel Corp.  */ 
// Battery Driver implemented for Sandgate.  
//-------------------------------------------------------------------------------------------------- 
// Includes 
//-------------------------------------------------------------------------------------------------- 
#include  
#include  
#include  
#include  
#include "xllp_gpio.h" 
#include "xsbase270_g.h" 
 
//------------------------------------------------------------------------------------------------- 
// Defines 
//------------------------------------------------------------------------------------------------- 
//#define AD2   (6 << 2) 
//#define AD3   (7 << 2) 
#define MAXIMUM_VOLTAGE  546 
#define MAXIMUM_BAT_VOLTAGE  410 
#define MINIMUM_VOLTAGE  300 
 
#define PER	10 
 
#define BAT_SDA					(1<<31)//gpio95 
#define BAT_CLK					(1<<2) // 
#define BAT_CE					(1<<3) //gpio99 
#define BAT_STATUS				(1<<2)//gpio98 
#define WAIT					(20) 
 
//extern void  msWait(unsigned msVal); 
 
 
static volatile BULVERDE_GPIO_REG *g_pGPIORegs		= NULL; 
static volatile UINT8			  *g_pBATRegs		= NULL; 
static volatile UINT8			  *g_pShadowRegs	= NULL; 
 
__inline void XSBASE270_BAT_CLEARBIT(UINT32 clk) 
{ 
	*g_pShadowRegs &= ~(clk); 
	*g_pBATRegs = *g_pShadowRegs; 
} 
 
__inline void XSBASE270_BAT_SETBIT(UINT32 clk) 
{ 
	*g_pShadowRegs |= (clk); 
	*g_pBATRegs = *g_pShadowRegs; 
} 
 
 
UINT16 Get_BatteryVol() 
{ 
	UINT16 dat = 0; 
	int i = 0; 
	g_pGPIORegs->GPDR2 |= BAT_SDA; 
	g_pGPIORegs->GPDR3 |= BAT_CE; 
	g_pGPIORegs->GPCR2 = BAT_SDA; //pull down ce and data,enable chip 
	g_pGPIORegs->GPCR3 = BAT_CE; 
	Sleep(WAIT); 
	g_pGPIORegs->GPDR2 &= ~BAT_SDA; 
	for(i = 15; i >= 0; i--) 
	{ 
		XSBASE270_BAT_CLEARBIT(BAT_CLK); 
		Sleep(WAIT); 
		dat |= (((g_pGPIORegs->GPLR2 & BAT_SDA) != 0) ? 0x1 << i : 0); 
		XSBASE270_BAT_SETBIT(BAT_CLK); 
		Sleep(WAIT); 
	} 
	Sleep(WAIT * 2); 
	g_pGPIORegs->GPCR2 = BAT_SDA; 
	g_pGPIORegs->GPDR2 |= BAT_SDA; //pull up ce and data, disable chip 
	g_pGPIORegs->GPSR3 = BAT_CE; 
	Sleep(WAIT * 2); 
	DEBUGMSG(1, (TEXT("\r\nvoltage is 0x%x\r\n"), dat)); 
	dat = (dat & 0x1fe0) >> 5; 
	return (dat * 500 / 256); 
} 
//------------------------------------------------------------------------------------------------- 
// Global Variables 
//-------------------------------------------------------------------------------------------------- 
//volatile		GPIO_REGS	*v_pGPIOReg	= NULL; 
static int		first_time; 
static DWORD	terminal_voltage; 
static DWORD    lastvoltage[PER]={0}; 
//-------------------------------------------------------------------------------------------------- 
// Prototypes 
//-------------------------------------------------------------------------------------------------- 
/* 
short int ReadAC97(BYTE , unsigned short int * , BYTE ); 
short int WriteAC97(BYTE , unsigned short int, BYTE ); 
short int InitAcLink(volatile GPIO_REGS *, BYTE ); 
extern PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress); 
*/ 
BOOL WINAPI BatteryDrvrGetStatus( PSYSTEM_POWER_STATUS_EX2 ,PBOOL ); 
 
//------------------------------------------------------------------------------------------------------------ 
// Function: Battery_sampleADC 
//  
// Purpose:  Given the ADC number this function collects the digital value for the analog signal. 
//           sampling AD3 gives the charge and AD2 gives the temperature. 
// Returns:  an indicator as to whether the data is valid or Invalid. 
// 
//------------------------------------------------------------------------------------------------------------- 
/* 
BOOL Battery_sampleADC(DWORD *sample,unsigned ad_number)  
{ 
	unsigned int adccr=0; 
	unsigned int adcDataReg; 
 
	BOOL noError=FALSE; 
 
	adccr = ad_number | ADC_ENA;   
 
	if (WriteAC97(UCB_ADC_CR,*(unsigned short *)&adccr, DEV_BATTERY))  
	{ 
		adccr |= ADC_START; 
		if(WriteAC97(UCB_ADC_CR,*(unsigned short *)&adccr, DEV_BATTERY))  
		{ 
			do	{											// wait for sample completion 
					ReadAC97(UCB_ADC_DATA,(unsigned short *) &adcDataReg,DEV_TOUCH); 
				} while(!TEST(adcDataReg,ADC_DATA_VAL)); 
														 
			*sample=TEST(adcDataReg,ADC_DATA) ; 
															// disable adc 
			CLEAR(adccr,ADC_ENA); 
			WriteAC97(UCB_ADC_CR,*(unsigned short *)&adccr,DEV_BATTERY); 
			noError=TRUE; 
		} 
	} 
	return(noError); 
} 
*/ 
//------------------------------------------------------------------------------------------------------------ 
// Function: InitBatteryDriver 
//  
// Purpose:  Initialises the AC link used by the battery driver allocates the necessary memory. 
// Returns:  void 
// 
//------------------------------------------------------------------------------------------------------------- 
 
void InitBatteryDriver() 
{ 
	PHYSICAL_ADDRESS PA; 
	PA.QuadPart  = BULVERDE_BASE_REG_PA_GPIO; 
    g_pGPIORegs   = (BULVERDE_GPIO_REG *) MmMapIoSpace(PA, sizeof(BULVERDE_GPIO_REG), FALSE); 
 
	PA.QuadPart = 0x10200000; 
	g_pBATRegs = (UINT8*)MmMapIoSpace(PA, sizeof(UINT8), FALSE); 
 
	PA.QuadPart = 0xa3ff0000; 
	g_pShadowRegs = (UINT8*)MmMapIoSpace(PA, sizeof(UINT8), FALSE); 
 
	if(!g_pGPIORegs || !g_pBATRegs || !g_pShadowRegs) 
		return; 
 
	g_pGPIORegs->GAFR2_U &=~(0xC0000000);//gpio95 
	g_pGPIORegs->GAFR3_L &=~(0x000000F0);//gpio98,99 
} 
 
//------------------------------------------------------------------------------------------------------------ 
// Function: IsACOnline 
//  
// Purpose:  Simply indicates whether we are running out of AC or out of Battery. 
// Returns:  TRUE indicates we are running out of the AC wall power supply. 
//           FALSE indicates we are running out of Battery. 
// 
//------------------------------------------------------------------------------------------------------------- 
BOOL WINAPI IsACOnline(void) 
{ 
	g_pGPIORegs->GPDR3 &= ~BAT_STATUS;  
 
	if((g_pGPIORegs->GPLR3 & BAT_STATUS)) 
	{ 
	//	NKDbgPrintfW(TEXT("AC is ON\r\n")); 
	//	RETAILMSG(1,(TEXT("AC is ON\r\n"))); 
		return TRUE; 
	} 
	else 
	{ 
	//	NKDbgPrintfW(TEXT("Battery is ON\r\n")); 
	//	RETAILMSG(1,(TEXT("Battery is ON\r\n"))); 
		return FALSE; 
	} 
} 
 
BOOL WINAPI  
BatteryPDDInitialize(LPCTSTR pszRegistryContext) 
{ 
    BOOL fOk = TRUE; 
    SETFNAME(_T("BatteryPDDInitialize")); 
     
    UNREFERENCED_PARAMETER(pszRegistryContext); 
    DEBUGMSG(ZONE_PDD, (_T("%s: returning %d\r\n"), pszFname, fOk)); 
 
    return fOk; 
} 
 
void WINAPI  
BatteryPDDDeinitialize(void) 
{ 
    SETFNAME(_T("BatteryPDDDeinitialize")); 
 
    DEBUGMSG(ZONE_PDD, (_T("%s: invoked\r\n"), pszFname)); 
} 
 
void WINAPI  
BatteryPDDResume(void) 
{ 
    SETFNAME(_T("BatteryPDDResume")); 
 
    DEBUGMSG(ZONE_PDD, (_T("%s: invoked\r\n"), pszFname)); 
} 
 
void WINAPI  
BatteryPDDPowerHandler(BOOL bOff) 
{ 
    SETFNAME(_T("BatteryPDDPowerHandler")); 
 
    UNREFERENCED_PARAMETER(bOff); 
     
    DEBUGMSG(ZONE_PDD | ZONE_RESUME, (_T("%s: invoked w/ bOff %d\r\n"), pszFname, bOff)); 
} 
 
// This routine obtains the most current battery/power status available 
// on the platform.  It fills in the structures pointed to by its parameters 
// and returns TRUE if successful.  If there's an error, it returns FALSE. 
BOOL WINAPI 
BatteryPDDGetStatus( 
                    PSYSTEM_POWER_STATUS_EX2 pstatus, 
                    PBOOL pfBatteriesChangedSinceLastCall 
                    ) 
{ 
 
    // this function is used to report the battery status 
	// now, temperature, and terminal voltage 
//	DWORD charger_voltage; 
	DWORD sample; 
//	DWORD temperature = 0; 
//	unsigned ad_number = 5; 
	float voltage_percent = 0; 
	BOOL PowerStatus; 
	int i,sum=0; 
 
	DEBUGMSG(1, (_T("BatteryPDDGetStatus++\r\n"))); 
	if(first_time==0) 
	{ 
		InitBatteryDriver(); 
		PowerStatus = IsACOnline(); 
		if(PowerStatus)       
			terminal_voltage = MAXIMUM_VOLTAGE;   // charger is ON, i.e AC ON 
		else 
			terminal_voltage = MINIMUM_VOLTAGE;   // Battery is ON, charger OFF 
		first_time=1; 
		for(i=0;i0;i--) 
	{ 
		lastvoltage[i]=lastvoltage[i-1]; 
	} 
	lastvoltage[0]=sample; 
	for(i = 0; i terminal_voltage))    // AC ON, Battery OFF 
		terminal_voltage = sample; 
 
	if((PowerStatus==FALSE) && (sample <= terminal_voltage))   // AC OFF, Battery ON 
		sample = terminal_voltage; 
 
//	NKDbgPrintfW(TEXT("%d\r\n"),sample); 
 
//	Battery_sampleADC(&temperature, AD2); 
 
//	DEBUGMSG(1, (TEXT("Already sampling the voltage\r\n"))); 
     
	if(PowerStatus) 
	{ 
		pstatus->ACLineStatus	          =AC_LINE_ONLINE; 
		pstatus->BatteryFlag	          =BATTERY_FLAG_NO_BATTERY; 
	} 
 
	pstatus->ACLineStatus		          = AC_LINE_OFFLINE; 
	//voltage_percent = (float) (sample - MINIMUM_VOLTAGE)/(MAXIMUM_VOLTAGE-MINIMUM_VOLTAGE); 
	voltage_percent = (float) (sample - MINIMUM_VOLTAGE)/(MAXIMUM_BAT_VOLTAGE-MINIMUM_VOLTAGE); 
//	RETAILMSG(1, (TEXT("terminal_voltage is %d, voltage_percent=%d\r\n"), terminal_voltage, voltage_percent*100)); 
	// Level Indicator  
	if(voltage_percent >= 0.65) 
		pstatus->BatteryFlag  = BATTERY_FLAG_HIGH; 
    else if (( voltage_percent <0.65) && (voltage_percent >=0.1)) 
		pstatus->BatteryFlag  = BATTERY_FLAG_LOW; 
	else if(voltage_percent<=0.1) 
		pstatus->BatteryFlag  = BATTERY_FLAG_CRITICAL; 
 
	pstatus->BatteryLifePercent           = (BYTE) (voltage_percent * 100); 
	pstatus->Reserved1                  = 0; 
    pstatus->BatteryLifeTime            = BATTERY_LIFE_UNKNOWN; 
    pstatus->BatteryFullLifeTime        = BATTERY_LIFE_UNKNOWN; 
 
    pstatus->Reserved2                  = 0; 
    pstatus->BackupBatteryFlag          = BATTERY_FLAG_UNKNOWN; 
    pstatus->BackupBatteryLifePercent   = 0; 
    pstatus->Reserved3                  = 0; 
    pstatus->BackupBatteryLifeTime      = BATTERY_LIFE_UNKNOWN; 
    pstatus->BackupBatteryFullLifeTime  = BATTERY_LIFE_UNKNOWN; 
 
    pstatus->BatteryChemistry           = 0x04; 
    pstatus->BatteryVoltage             = (unsigned long) (voltage_percent * 4.1); ; 
    pstatus->BatteryCurrent             = 0; 
    pstatus->BatteryAverageCurrent      = 0; 
    pstatus->BatteryAverageInterval     = 0; 
    pstatus->BatterymAHourConsumed      = 0; 
    pstatus->BatteryTemperature         = 0; 
    pstatus->BackupBatteryVoltage       = 0; 
    
   *pfBatteriesChangedSinceLastCall = FALSE; 
	DEBUGMSG(1,(_T("BatteryPDDGetStatus--\r\n"))); 
    return (TRUE); 
} 
 
 
 
// This routine indicates how many battery levels will be reported 
// in the BatteryFlag and BackupBatteryFlag fields of the PSYSTEM_POWER_STATUS_EX2 
// filed in by BatteryPDDGetStatus().  This number ranges from 0 through 3 -- 
// see the Platform Builder documentation for details.  The main battery 
// level count is reported in the low word of the return value; the count  
// for the backup battery is in the high word. 
LONG 
BatteryPDDGetLevels( 
    void 
   	) 
{ 
    LONG lLevels = MAKELONG (3 /* main battery levels   */,   
                             3 /* backup battery levels */); 
 
    SETFNAME(_T("BatteryPDDPowerHandler")); 
 
    DEBUGMSG(ZONE_PDD, (_T("%s: returning %u (%d main levels, %d backup levels)\r\n"), 
        pszFname, LOWORD(lLevels), HIWORD(lLevels))); 
 
    return lLevels; 
} 
 
 
 
// This routine returns TRUE to indicate that the pfBatteriesChangedSinceLastCall 
// value filled in by BatteryPDDGetStatus() is valid.  If there is no way to 
// tell that the platform's batteries have been changed this routine should 
// return FALSE. 
BOOL 
BatteryPDDSupportsChangeNotification( 
    void 
   	) 
{ 
    BOOL fSupportsChange = FALSE; 
    SETFNAME(_T("BatteryPDDPowerHandler")); 
 
    DEBUGMSG(ZONE_PDD, (_T("%s: returning %d\r\n"), pszFname, fSupportsChange)); 
 
    return fSupportsChange; 
}