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

📄 powerbutton.c

📁 此压缩包为杰得开发得z228的BSP的源代码,可以实现很多功能,尤其是视频解码有很好的效果.
💻 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 + -