?? hwctxt.cpp.bak
字號:
//
// 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.
#include "wavemain.h"
#include "p2.h"
#include "s2440.h"
#include "dma.h"
#include "I2S.h"
#include "utldrv.h"
#include "hwctxt.h"
#include "IIC.h"
#include "Pm.h"
#include "winioctl.h"
#include "pkfuncs.h"
//#include "Volumecontrol.h"
#include <notify.h>
#define DMA_CH_MIC 2
#define DMA_CH_OUT 1
#define DELAY_COUNT 0x100000
int rec_mode=0;
//-------------------------------- Global Variables --------------------------------------
volatile IISreg *v_pIISregs = NULL; // I2S control registers
volatile IICreg *v_pIICregs = NULL; //IIC control registers
volatile IOPreg *v_pIOPregs = NULL; // GPIO registers (needed to enable I2S and SPI)
volatile DMAreg *v_pDMAregs = NULL; // DMA registers (needed for I/O on I2S bus)
volatile CLKPWRreg *g_pCLKPWRreg = NULL; // Clock power registers (needed to enable I2S and SPI clocks)
volatile INTreg *s2440INT = NULL;
volatile PWMreg *v_pPWMreg =NULL;
UTL_FASTCALL g_tblFastCall; // Needed for fast driver->driver calling mechanism
HANDLE g_hUTLObject = INVALID_HANDLE_VALUE;
HardwareContext *g_pHWContext = NULL;
unsigned int delay_count;
//----------------------------------------------------------------------------------------
//BOOL gHP_flag=false;
//bool gb_changed=false; //
//bool b_prolevel=false;
//bool b_nowlevel=false;
//HANDLE m_hVolumeIncrEvent=NULL;
//HANDLE m_hVolumeReduEvent=NULL;
//HANDLE m_hBKLightEvent=NULL;
//bool gb_HP_changed=false;
//bool gb_SP_changed=false;
//---------------------------------------------
DBGPARAM dpCurSettings = {
TEXT("CONSOLE"), {
TEXT("0"),TEXT("1"),TEXT("2"),TEXT("3"),
TEXT("4"),TEXT("5"),TEXT("6"),TEXT("7"),
TEXT("8"),TEXT("9"),TEXT("10"),TEXT("11"),
TEXT("12"),TEXT("Function"),TEXT("Init"),TEXT("Error")},
0x8000 // Errors only, by default
};
//void dump_audio_input_sfr(void);
BOOL HardwareContext::CreateHWContext(DWORD Index)
{
if (g_pHWContext)
{
return TRUE;
}
g_pHWContext = new HardwareContext;
if (!g_pHWContext)
{
return FALSE;
}
return g_pHWContext->Init(Index);
}
HardwareContext::HardwareContext() //
: m_InputDeviceContext(), m_OutputDeviceContext()
{
InitializeCriticalSection(&m_Lock);
m_Initialized=FALSE;
}
HardwareContext::~HardwareContext()
{
DeleteCriticalSection(&m_Lock);
}
BOOL HardwareContext::Init(DWORD Index)
{
if (m_Initialized)
{
return FALSE;
}
//----- 1. Initialize the state/status variables -----
m_DriverIndex = Index;
m_IntrAudio = SYSINTR_AUDIO;
m_InPowerHandler = FALSE;
m_InputDMARunning = FALSE;
m_OutputDMARunning = FALSE;
m_InputDMAStatus = DMA_CLEAR;
m_OutputDMAStatus = DMA_CLEAR;
Headset_InterruptEvent =NULL;
Headset_InterruptThread=NULL;
//----- 2. Map the necessary descriptory channel and control registers into the driver's virtual address space -----
if(!MapRegisters()) //iis initialed!
{
DEBUGMSG(ZONE_ERROR, (TEXT("WAVEDEV.DLL:HardwareContext::Init() - Failed to map config registers.\r\n")));
return FALSE;
}
//----- 3. Map the DMA buffers into driver's virtual address space -----
if(!MapDMABuffers())
{
DEBUGMSG(ZONE_ERROR, (TEXT("WAVEDEV.DLL:HardwareContext::Init() - Failed to map DMA buffers.\r\n")));
return FALSE;
}
//----- 4. Configure the Codec -----
InitCodec(); //Initial IIC pin!
//InitializeCriticalSection(&m_Lock); //critical section been initialized!
//----- 5. Initialize the interrupt thread -----
if (!InitInterruptThread())
{
DEBUGMSG(ZONE_ERROR, (TEXT("WAVEDEV.DLL:HardwareContext::Init() - Failed to initialize interrupt thread.\r\n")));
return FALSE;
}
m_Initialized=TRUE;
//
// Power Manager expects us to init in D0.
// We are normally in D4 unless we are opened for play.
// Inform the PM.
//
m_Dx = D0;
//Audio power statue power down! D4 is mean off!
DevicePowerNotify(_T("MAX1:"),(_CEDEVICE_POWER_STATE)D4, POWER_NAME);
//VOLUME CONTROL!!!
//SoundControlInit();
//song
return TRUE;
}
BOOL HardwareContext::MapRegisters()
{
v_pIISregs = (volatile IISreg *)VirtualAlloc(0,sizeof(IISreg),MEM_RESERVE, PAGE_NOACCESS);
if (!v_pIISregs)
{
DEBUGMSG(1,(TEXT("IISreg: VirtualAlloc failed!\r\n")));
return FALSE;
}
if (!VirtualCopy((PVOID)v_pIISregs,(PVOID)(IIS_BASE),sizeof(IISreg), PAGE_READWRITE | PAGE_NOCACHE ))
{
DEBUGMSG(1,(TEXT("IISreg: VirtualCopy failed!\r\n")));
return FALSE;
}
//////////////////////////////////////////////////////////////////////////////
v_pIICregs = (volatile IICreg *)VirtualAlloc(0,sizeof(IICreg),MEM_RESERVE, PAGE_NOACCESS);
if (!v_pIICregs)
{
DEBUGMSG(1,(TEXT("IICreg: VirtualAlloc failed!\r\n")));
return FALSE;
}
if (!VirtualCopy((PVOID)v_pIICregs,(PVOID)(IIC_BASE),sizeof(IICreg), PAGE_READWRITE | PAGE_NOCACHE ))
{
DEBUGMSG(1,(TEXT("IICreg: VirtualCopy failed!\r\n")));
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
v_pIOPregs = (volatile IOPreg *)VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE, PAGE_NOACCESS);
if (!v_pIOPregs)
{
DEBUGMSG(1,(TEXT("IOPreg: VirtualAlloc failed!\r\n")));
return FALSE;
}
if (!VirtualCopy((PVOID)v_pIOPregs,(PVOID)(IOP_BASE),sizeof(IOPreg), PAGE_READWRITE | PAGE_NOCACHE ))
{
DEBUGMSG(1,(TEXT("IOPreg: VirtualCopy failed!\r\n")));
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////////////////
v_pDMAregs = (volatile DMAreg *)VirtualAlloc(0,sizeof(DMAreg),MEM_RESERVE, PAGE_NOACCESS);
if (!v_pDMAregs)
{
DEBUGMSG(1,(TEXT("DMAreg: VirtualAlloc failed!\r\n")));
return FALSE;
}
if (!VirtualCopy((PVOID)v_pDMAregs,(PVOID)(DMA_BASE),sizeof(DMAreg), PAGE_READWRITE | PAGE_NOCACHE ))
{
DEBUGMSG(1,(TEXT("DMAreg: VirtualCopy failed!\r\n")));
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
s2440INT = (volatile INTreg *)VirtualAlloc(0,sizeof(INTreg),MEM_RESERVE, PAGE_NOACCESS);
if (!v_pDMAregs)
{
DEBUGMSG(1,(TEXT("INTreg: VirtualAlloc failed!\r\n")));
return FALSE;
}
if (!VirtualCopy((PVOID)s2440INT,(PVOID)(INT_BASE),sizeof(INTreg), PAGE_READWRITE | PAGE_NOCACHE ))
{
DEBUGMSG(1,(TEXT("INTreg: VirtualCopy failed!\r\n")));
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
g_pCLKPWRreg = (volatile CLKPWRreg *)VirtualAlloc(0,sizeof(CLKPWRreg),MEM_RESERVE, PAGE_NOACCESS);
if (!g_pCLKPWRreg)
{
DEBUGMSG(1,(TEXT("DMAreg: VirtualAlloc failed!\r\n")));
return FALSE;
}
if (!VirtualCopy((PVOID)g_pCLKPWRreg,(PVOID)(CLKPWR_BASE),sizeof(CLKPWRreg), PAGE_READWRITE | PAGE_NOCACHE ))
{
DEBUGMSG(1,(TEXT("DMAreg: VirtualCopy failed!\r\n")));
return FALSE;
}
////////////////////////////////////////////////
v_pPWMreg = (volatile PWMreg *)VirtualAlloc(0,sizeof(PWMreg),MEM_RESERVE, PAGE_NOACCESS);
if (!v_pPWMreg)
{
DEBUGMSG(1,(TEXT("DMAreg: VirtualAlloc failed!\r\n")));
return FALSE;
}
if (!VirtualCopy((PVOID)v_pPWMreg,(PVOID)(PWM_BASE),sizeof(PWMreg), PAGE_READWRITE | PAGE_NOCACHE ))
{
DEBUGMSG(1,(TEXT("DMAreg: VirtualCopy failed!\r\n")));
return FALSE;
}
///////////////////////////////////////////////////
PowerUp(); //initial IIS !
return TRUE;
}
BOOL HardwareContext::Deinit()
{
//----- 1. Disable the input/output channels -----
// AUDIO_IN_DMA_DISABLE();
// v_pIISregs->rIISCON &= ~RECEIVE_DMA_REQUEST_ENABLE;
// v_pIISregs->rIISFCON &= ~( RECEIVE_FIFO_ACCESS_DMA | RECEIVE_FIFO_ENABLE);
// v_pDMAregs->rDMASKTRIG1 |= STOP_DMA_TRANSFER;
// v_pDMAregs->rDMASKTRIG1 &= ~ENABLE_DMA_CHANNEL;;
//AUDIO_OUT_DMA_DISABLE();
v_pDMAregs->rDMASKTRIG2 |= STOP_DMA_TRANSFER;
v_pDMAregs->rDMASKTRIG2 &= ~ENABLE_DMA_CHANNEL;
//----- 2. Disable/clear DMA input/output interrupts -----
//AUDIO_IN_CLEAR_INTERRUPTS();
v_pDMAregs->rDCON1 = v_pDMAregs->rDCON1;
//AUDIO_OUT_CLEAR_INTERRUPTS();
v_pDMAregs->rDCON2 = v_pDMAregs->rDCON2;
//----- 3. Turn the audio hardware off -----
//AudioMute(IIC_OUTPUT_CHANNEl|IIC_INPUT_CHANNEl, TRUE);
//----- 4. Unmap the control registers and DMA buffers -----
UnmapRegisters();
UnmapDMABuffers();
return TRUE;
}
BOOL HardwareContext::UnmapRegisters()
{
//----- 1. Free the fast driver-->driver calling mechanism object -----
if(g_hUTLObject)
{
CloseHandle(g_hUTLObject);
}
return TRUE;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: MapDMABuffers()
Description: Maps the DMA buffers used for audio input/output
on the I2S bus.
Returns: Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::MapDMABuffers()
{
BOOL bSuccess=FALSE;
PBYTE pTemp;
//----- 1. Allocate a block of virtual memory big enough to hold the DMA buffers -----
if(!(pTemp = (PBYTE)VirtualAlloc(0, AUDIO_DMA_PAGE_SIZE * 4, MEM_RESERVE, PAGE_NOACCESS)))
{
DEBUGMSG(ZONE_ERROR, (TEXT("WAVEDEV.DLL:HardwareContext::MapDMABuffers() - Unable to allocate memory for DMA buffers!\r\n")));
goto MAP_ERROR;
}
//----- 2. Map the physical DMA buffer to the virtual address we just allocated -----
if(!VirtualCopy((LPVOID)pTemp, (LPVOID)AUDIO_DMA_BUFFER_BASE, (AUDIO_DMA_PAGE_SIZE * 4), //4*2048
PAGE_READWRITE | PAGE_NOCACHE))
{
DEBUGMSG(ZONE_ERROR, (TEXT("WAVEDEV.DLL:HardwareContext::MapDMABuffers() - VirtualCopy() failed when binding DMA buffers.\r\n")));
goto MAP_ERROR;
}
//----- 3. Setup the DMA page pointers -----
// NOTE: Currently, input and output each have two DMA pages; these pages are used in a round-robin
// fashion so that the OS can read/write one buffer while the audio codec chip read/writes the
// other buffer.
m_Output_pbDMA_PAGES[0] = pTemp;
m_Output_pbDMA_PAGES[1] = pTemp + AUDIO_DMA_PAGE_SIZE;
m_Input_pbDMA_PAGES[0] = pTemp + 2*AUDIO_DMA_PAGE_SIZE;
m_Input_pbDMA_PAGES[1] = pTemp + 3*AUDIO_DMA_PAGE_SIZE;
return TRUE;
MAP_ERROR:
if(pTemp)
VirtualFree(pTemp, 0, MEM_RELEASE);
return FALSE;
}
BOOL HardwareContext::UnmapDMABuffers()
{
if(m_Output_pbDMA_PAGES[0])
{
VirtualFree((PVOID)m_Output_pbDMA_PAGES[0], 0, MEM_RELEASE);
}
return TRUE;
}
BOOL HardwareContext::Codec_channel()
{
//****** Port B Initialize *****
return TRUE;
}
BOOL HardwareContext::InitCodec()
{
//HP detection interrupt trigger !
//v_pIOPregs->rGPFCON &= ~(0x3 << 2);//input
///////////////////////////////////////////////////////////
//keybutton interrupt!
//v_pIOPregs->rGPFCON &= ~(0x3<<6|0x3<<14); // eint 3 7
//v_pIOPregs->rGPFCON |= (0x2<<6|0x2<<14);
//v_pIOPregs->rGPFUP&=0x0; //pull-up enable!
//v_pIOPregs->rEXTINT0&=~(0x7<<12|0x7<<28);
// v_pIOPregs->rEXTINT0|=(0x2<<12|0x2<<28); //Falling edge triggered
//////////////////////////////////////////
//bklight!
//v_pIOPregs->rGPGCON&=~(0x3<<22); //GPG11
//v_pIOPregs->rGPGCON|=(0x1<<22); //output!
//v_pIOPregs->rGPGUP&=~(0x1<<22); //pull-up enable!
//v_pIOPregs->rGPGDAT|=(0x1<<11); //output 1 close light!
//////////////////////////////////////
IIC_Initialize();
return TRUE;
}
BOOL HardwareContext::InitOutputDMA()
{
//RETAILMSG(1,(TEXT("-------InitOutputDMA----------!\r\n")));
//----- 1. Initialize the DMA channel for output mode and use the first output DMA buffer -----
//Base address of source data to transfer!
v_pDMAregs->rDISRC2 = (int)(AUDIO_DMA_BUFFER_PHYS);
//ahb bus ! increment! //0x02 0x01
v_pDMAregs->rDISRCC2 &= ~(SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS);//(11) // Source is system bus, increment addr
//----- 2. Initialize the DMA channel to send data over the I2S bus -----
//Base address (start address) of destination for the transfer.
v_pDMAregs->rDIDST2 = (int)IISFIF_PHYS; //DMA's address of the FIFO register!
//(11) apb bus ! fixed!
v_pDMAregs->rDIDSTC2 |= (DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS); // Dest is periperal bus, fixed addr
//----- 3. Configure the DMA channel's transfer characteristics: handshake, sync PCLK, interrupt, -----
// single(unit) tx, single service, I2SSDO, I2S request, no(problem) auto-reload, half-word, tx count
//31 29 (0) 23 20 (1k)
v_pDMAregs->rDCON2 = ( HANDSHAKE_MODE | GENERATE_INTERRUPT | I2SSDO_DMA2 | DMA_TRIGGERED_BY_HARDWARE
| TRANSFER_HALF_WORD | (AUDIO_DMA_PAGE_SIZE / 2 ) );//1024
//----- 4. Reset the playback pointers -----
//AUDIO_RESET_PLAYBACK_POINTER();
//ioPlaybackPointerLow (v_pDMAregs->rDISRC2)
ioPlaybackPointerLow = (AUDIO_DMA_BUFFER_PHYS);
//(v_pDMAregs->rDISRC2)
ioPlaybackPointerHigh = (AUDIO_DMA_BUFFER_PHYS + AUDIO_DMA_PAGE_SIZE);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -