📄 powerbutton.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.
//
/* ++
PCF50606 Power Supply Controller & Battery Management
Notes:
======
o) I2c client
-- */
#include <windows.h>
#include <nkintr.h>
#include <windev.h>
#include <winbase.h>
#include <ceddk.h>
#include "oalintr.h"
#include "platform.h"
#include "pwr.h"
#include "WM9712.h"
static DWORD PWR_IST(LPVOID Context);
// Make sure the driver builds OK in tinykern configuration
HMODULE g_hMod = NULL;
typedef void (*PFN_GwesPowerOffSystem)(void);
PFN_GwesPowerOffSystem g_pfnGwesPowerOffSystem = NULL;
GPIO_REGS *v_pIOPregs = NULL;
static const TCHAR szPowerButton[] = TEXT("PowerButtonEvent");
#define ENABLE TRUE
#define DISABLE FALSE
CRITICAL_SECTION m_Lock;
FILE * fp = NULL;
static UCHAR *g_AudioRegBase = NULL;// Pointer to memory mapped AACI regs.
// Test and wait for flags to clear
#define _TWMAX 10
#define TESTWAIT(test,dbgmsg) \
{ \
int _testwait = 0; \
while( (test) && _testwait < _TWMAX ) \
{ \
Sleep(1); \
_testwait++; \
} \
if( _testwait == _TWMAX ); \
}
//-----------------------------------------------------------------------
// VOID AACI_RegWrite32 (USHORT reg, ULONG val)
//
// Writes 32 bits to the 5530/5540 I/O port
//-----------------------------------------------------------------------
VOID AACI_RegWrite32(USHORT reg, ULONG val)
{
PULONG reg_loc;
reg_loc = (PULONG)(g_AudioRegBase + reg);
*reg_loc = val;
}
//-----------------------------------------------------------------------
// ULONG AACI_RegRead32(USHORT reg)
//
// Reads 32 bits from the 5530/5540 I/O port
//-----------------------------------------------------------------------
ULONG AACI_RegRead32(USHORT reg)
{
PULONG reg_loc;
ULONG val;
reg_loc = (PULONG)(g_AudioRegBase + reg);
val = *reg_loc;
return( val );
}
// -----------------------------------------------------------------------------
// FIFO operations
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Hardware (CODEC and AACI) operations
// -----------------------------------------------------------------------------
// Internal function to send raw data to the codec
static VOID CodecSend( ULONG raw_codec_reg, ULONG raw_codec_data )
{
// First check that the AACISLxTX registers are empty
TESTWAIT(!( AACI_RegRead32(AACIReg_SlotFlag) &
(AACIBit_Slot1TXEmpty | AACIBit_Slot2TXEmpty)),
"Slot1TXEmpty | Slot2TXEmpty")
AACI_RegWrite32( AACIReg_Slot2Tx, raw_codec_data );
AACI_RegWrite32( AACIReg_Slot1Tx, raw_codec_reg );
// Pause so that slots can be transmitted
Sleep(1);
// Wait till slots 1&2 transmit complete
TESTWAIT(AACI_RegRead32(AACIReg_SlotFlag) &
(AACIBit_Slot1TXBusy | AACIBit_Slot2TXBusy),
"Slot1TXBusy | Slot2TXBusy")
// Pause here for the operation to complete on the CODEC, i.e. wait for
// data to be returned or CODEC registers to be updated depending on
// read or write
Sleep(1);
}
//-----------------------------------------------------------------------
//
// USHORT AACI_CodecRead16( USHORT codec_reg )
//
// Reads data from the CODEC
//
//-----------------------------------------------------------------------
USHORT AACI_CodecRead16( USHORT codec_reg )
{
// Tell the codec we are trying to read a register
CodecSend( (((ULONG)codec_reg) << 12) | AACIBit_Slot1Tx_Read, (ULONG)0 );
// Check if LM4549 has returned requested value
TESTWAIT(!( AACI_RegRead32( AACIReg_SlotFlag ) & AACIBit_Slot2RXValid ),
"Slot2RXValid")
return( (USHORT)(AACI_RegRead32( AACIReg_Slot2Rx ) >> 4) );
}
//-----------------------------------------------------------------------
//
// void AACI_CodecWrite16( USHORT codec_reg, USHORT codec_data )
//
// Writes data to the CODEC
//
//-----------------------------------------------------------------------
VOID AACI_CodecWrite16( USHORT codec_reg, USHORT codec_data )
{
CodecSend( (((ULONG)codec_reg) << 12), (((ULONG)codec_data) << 4) );
}
//******************** FOR TOUCHPANEL
void udelay(unsigned int usec)
{
int i;
i = usec *33;
while(i--);
}
#define TESTWAIT1(test,looptime) \
{ \
int _testwait = 0; \
while( (test) && _testwait < looptime ) \
{ \
udelay(10); \
_testwait++; \
} \
if( _testwait == looptime ); \
}
#define LOOP_TIME 10000
#define AACI_TIMEOUT 10000 // Timeout for reading FIFOs (10mS)
#define AACI_SLFR 0x068
#define AACI_SL1TXBUSY 0x0002
// AACI Slot status bits
#define AACI_SL2TXBUSY 0x0008
#define AACI_SL2TX 0x05C
#define AACI_SL1TX 0x054
#define AACI_SL2RX 0x058
// Write a value to a CODEC control register
static int apAACI_WriteRegister( USHORT reg, USHORT value )
{
if(!g_AudioRegBase)return FALSE;
// First check that the AACISLxTX registers are empty
TESTWAIT1(!( AACI_RegRead32(AACIReg_SlotFlag) &
(AACIBit_Slot1TXEmpty | AACIBit_Slot2TXEmpty)), LOOP_TIME)
AACI_RegWrite32( AACIReg_Slot2Tx, (((ULONG)value) << 4) );
AACI_RegWrite32( AACIReg_Slot1Tx, (((ULONG)reg) << 12));
if(fp)
{
fprintf(fp, "touch driver write reg = %x, value = %x\n", reg, value);
fflush(fp);
}
return TRUE;
}
static USHORT apAACI_ReadRegister(USHORT reg)
{
//int timer;
unsigned int data;//, stat;
if(!g_AudioRegBase)return FALSE;
TESTWAIT1(!( AACI_RegRead32(AACIReg_SlotFlag) &
(AACIBit_Slot1TXEmpty | AACIBit_Slot2TXEmpty)), AACI_TIMEOUT)
AACI_RegWrite32( AACIReg_Slot2Tx, 0 );
AACI_RegWrite32( AACIReg_Slot1Tx, (((ULONG)reg) << 12) | AACIBit_Slot1Tx_Read );
TESTWAIT1(!( AACI_RegRead32(AACIReg_SlotFlag) &
(AACIBit_Slot1TXEmpty | AACIBit_Slot2TXEmpty)), LOOP_TIME)
data = ( (USHORT)(AACI_RegRead32( AACIReg_Slot2Rx ) >> 4) );
if(0)
{
fprintf(fp, "reg=%x,data=%x\n", reg, data);
fflush(fp);
}
return data;
}
//*****************************************************************
/* ++
The reset value of the PCF50606 INTxM registers is 0: Interrupt enabled.
Once we enable the interrupt they start firing unless we mask them _before_
enabeling the interrupt(s).
-- */
DWORD HW_Init(PPWR_CONTEXT pPWR)
{
DWORD dwErr = ERROR_SUCCESS;
PHYSICAL_ADDRESS PhysicalAddress;
DEBUGMSG(ZONE_INIT, (TEXT(">WM9712_Init(%p)\n"), ActivePath));
InitializeCriticalSection(&m_Lock); // add by he
// Map in address space for AACI hardware registers
PhysicalAddress.HighPart = 0;
PhysicalAddress.LowPart = PHYS_AACI_BASE;
g_AudioRegBase = (UCHAR *)MmMapIoSpace (PhysicalAddress, AACI_HWREGS_SIZE,//物理地址影射到虚拟地址
FALSE);
return dwErr;
}
DWORD HW_Deinit(PPWR_CONTEXT pPWR)
{
if ( !pPWR )
return ERROR_INVALID_PARAMETER;
RETAILMSG(1,(TEXT("+PWR_Deinit \r\n")));
return ERROR_SUCCESS;
}
DWORD HW_Open(PPWR_CONTEXT pPWR)
{
RETAILMSG(1, (TEXT("PCF: HW_Open \r\n")));
return ERROR_SUCCESS;
}
DWORD HW_Close(PPWR_CONTEXT pPWR)
{
RETAILMSG(1, (TEXT("PCF: HW_Close \r\n")));
return ERROR_SUCCESS;
}
BOOL HW_PowerUp(PPWR_CONTEXT pPWR)
{
RETAILMSG(1, (TEXT("PCF: HW_PowerUp \r\n")));
// pPWR->State = RUN;
return TRUE;
}
BOOL HW_PowerDown(PPWR_CONTEXT pPWR)
{
RETAILMSG(1, (TEXT("PCF: HW_PowerDown \r\n")));
return TRUE;
}
BOOL HW_PowerCapabilities(PPWR_CONTEXT pPWR,PPOWER_CAPABILITIES ppc)
{
return TRUE;
}
BOOL HW_PowerSet(PPWR_CONTEXT pPWR,PCEDEVICE_POWER_STATE pDx)
{
CEDEVICE_POWER_STATE NewDx = *pDx;
return TRUE;
}
BOOL HW_PowerGet(PPWR_CONTEXT pPWR,PCEDEVICE_POWER_STATE pDx)
{
// return our Current Dx value
*pDx = pPWR->Dx;
RETAILMSG(1, (TEXT("PCF: IOCTL_POWER_GET: D%u \r\n"), pPWR->Dx));
return TRUE;
}
typedef struct
{
USHORT reg;
USHORT data;
} PARA, *pPARA;
#define WM9712_WRITE 1
#define WM9712_READ 0
#define TOUCHP_READ 2
#define TOUCHP_WRITE 3
#define WAVE_SET_4C 4
#define TOUCH_SET_4C 5
#define DEBUG_FLUSH 6
BOOL HW_IOControl(PPWR_CONTEXT pPWR,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut)
{
//DWORD dwErr = ERROR_SUCCESS;
//unsigned int data;
// DWORD time1,time2,time3,time4;
//if(fp == NULL) fp = fopen("driver_9712.txt", "a+");
switch (dwCode) {
case WM9712_WRITE:
EnterCriticalSection(&m_Lock); // by he
AACI_CodecWrite16( ((pPARA)pBufIn)->reg, ((pPARA)pBufIn)->data);
LeaveCriticalSection(&m_Lock);
#if 0
if(fp)
{
fprintf(fp, " write reg = %x, data = %x\n", ((pPARA)pBufIn)->reg, ((pPARA)pBufIn)->data);
fflush(fp);
}
#endif
break;
case WM9712_READ:
EnterCriticalSection(&m_Lock); // by he
*(USHORT*)pBufOut = AACI_CodecRead16(*(USHORT*)pBufIn);
*pdwActualOut = 2;
LeaveCriticalSection(&m_Lock);
#if 0
if(fp)
{
fprintf(fp, " read reg = %x, result = %x\n", *(USHORT*)pBufIn, *(USHORT*)pBufOut);
fflush(fp);
}
#endif
break;
case TOUCHP_READ:
//time1 = GetTickCount();
EnterCriticalSection(&m_Lock);
*(USHORT*)pBufOut = apAACI_ReadRegister(*(USHORT*)pBufIn);
LeaveCriticalSection(&m_Lock);
//time2 = GetTickCount();
if(0)
{
//fprintf(fp, "touch_read t1=%u,t2=%u,t3=%u,t4=%u\n", time1,time2);
//fflush(fp);
}
//*pdwActualOut = 2;
#if 0
if(fp)
{
fprintf(fp, "touch read reg = %x, result = %x\n", *(USHORT*)pBufIn, *(USHORT*)pBufOut);
//fflush(fp);
}
#endif
break;
case TOUCHP_WRITE:
//time1 = GetTickCount();
EnterCriticalSection(&m_Lock);
apAACI_WriteRegister( ((pPARA)pBufIn)->reg, ((pPARA)pBufIn)->data);
LeaveCriticalSection(&m_Lock);
//time2 = GetTickCount();
if(0)
{
//fprintf(fp, "touch_read t1=%u,t2=%u,t3=%u,t4=%u\n", time1,time2);
//fflush(fp);
}
#if 0
if(fp)
{
fprintf(fp, " write reg = %x, data = %x\n", ((pPARA)pBufIn)->reg, ((pPARA)pBufIn)->data);
fflush(fp);
}
#endif
break;
case TOUCH_SET_4C:
//配置pendown模式
//time1 = GetTickCount();
EnterCriticalSection(&m_Lock);
//time2 = GetTickCount();
apAACI_WriteRegister(0x4c,apAACI_ReadRegister(0x4c)&(~0x0008));
//time3 = GetTickCount();
LeaveCriticalSection(&m_Lock);
//time4 = GetTickCount();
if(fp)
{
//fprintf(fp, "touch t1=%u,t2=%u,t3=%u,t4=%u\n", time1,time2,time3,time4);
fflush(fp);
}
if(fp)
{
//fprintf(fp, "touch t1=%u,t2=%u,t3=%u,t4=%u\n", time1,time2,time3,time4);
fflush(fp);
}
if(0)
{
//fprintf(fp, "touch SET_4C data = %x\n", data);
fflush(fp);
}
break;
case WAVE_SET_4C:
//time1 = GetTickCount();
EnterCriticalSection(&m_Lock);
//time2 = GetTickCount();
AACI_CodecWrite16( 0x4c, (AACI_CodecRead16(0x4c)&(~0x02)) );
//time3 = GetTickCount();
LeaveCriticalSection(&m_Lock);
//time4 = GetTickCount();
if(fp)
{
//fprintf(fp, "wav t1=%u,t2=%u,t3=%u,t4=%u\n", time1,time2,time3,time4);
fflush(fp);
}
if(0)
{
//fprintf(fp, "WAVE SET_4C data = %x\n", (AACI_CodecRead16(0x4c)&(~0x02)));
fflush(fp);
}
break;
case DEBUG_FLUSH:
if(fp)fflush(fp);
break;
default:
if(fp)
{
fprintf(fp, "default case %x", dwCode);
}
break;
}
//return dwErr;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -