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

📄 hwctxt.cpp

📁 realtek562x系列驱动源码。wince
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// 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.
//
/*++

Module Name: 

        hwctxt.cpp

Abstract:

ChangesLog:

06-28-2005
    1. Added installable ISR for audio DMA interrupt handling.
    2. Improved DMA buffer handling.
    3. AC97 shared resource management is now in ACLink.lib which is shared by touch driver.
    4. Added power management support.

--*/
/* 
** Copyright 2000-2003 Intel Corporation All Rights Reserved
**
** Portions of the source code contained or described herein and all documents
** related to such source code (Material) are owned by Intel Corporation
** or its suppliers or licensors and is licensed by Microsoft Corporation for distribution.  
** Title to the Material remains with Intel Corporation or its suppliers and licensors. 
** Use of the Materials is subject to the terms of the Microsoft license agreement which accompanied the Materials.  
** No other license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise 
** Some portion of the Materials may be copyrighted by Microsoft Corporation..
*/

#include <windows.h>
#if __cplusplus
extern "C" {
#endif
#include "xllp_ost.h"

#if __cplusplus
}
#endif

#include "ac97.h"
#include "wavemain.h"
#include "dmac.h"

#if !USE_I2S_INTERFACE	

#include <aclink.h>

#else

#include "i2s_control.h"
#include <xllp_i2s.h>	

#endif

#if USE_I2S_INTERFACE

#define DMA_CHMAP_I2S_RCV      2          // DRCMR2 - map dma channel for I2S receive request
#define DMA_CHMAP_I2S_TRA      3          // DRCMR3 - map dma channel for I2S transmit request

#endif	

#define DMA_INTERRUPT_REGISTER  0x400000f0

const LPCWSTR g_wszDmaIsrDll     = L"giisr.dll";
const LPCWSTR g_wszDmaIsrHandler = L"ISRHandler";

HardwareContext *g_pHWContext=NULL;

static const POWER_CAPABILITIES g_PowerCaps = 
{
    // DeviceDx:    Supported power states
    DX_MASK(D0) | DX_MASK(D1) | DX_MASK(D2) | DX_MASK(D3) | DX_MASK(D4),

    0,              // WakeFromDx:
    0,              // InrushDx:    No inrush of power

    {               // Power: Maximum milliwatts in each state
        0x00000001, //        D0 = 0
        0x00000001, //        D1 = 0
        0x00000001, //        D2 = 0
        0x00000001, //        D3 = 0
        0x00000001  //        D4 = 0 (off)
    },

    {               // Latency
        0x00000000, //        D0 = 0
        0x00000000, //        D1 = 0
        0x00000000, //        D2 = 0
        0x00000000, //        D3 = 0
        0x00000000  //        D4 = 0
    },

    0,                    // Flags: None
};

BOOL HardwareContext::CreateHWContext(DWORD Index)
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+HardwareContext::CreateHWContext")));

    //if the hardware context exists then don't init again
    if (g_pHWContext)
    {
        return TRUE;
    }

    g_pHWContext = new HardwareContext;
    if (!g_pHWContext)
    {
        return FALSE;  //oops we should have not be null
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-HardwareContext::CreateHWContext")));

    return g_pHWContext->Init(Index);
}

HardwareContext::HardwareContext(): m_InputDeviceContext(), m_OutputDeviceContext()
{
    InitializeCriticalSection(&m_Lock);  //some code is not reentrant
    m_Initialized=FALSE;  //we are just getting started, we are not initialized yet

    m_fOutputRenderMonoOnly = 0;
}

HardwareContext::~HardwareContext()
{
    DeleteCriticalSection(&m_Lock);             //we're going down, clean up semiphore
}


BOOL HardwareContext::Init(DWORD Index)
{
    DEBUGMSG(ZONE_INIT, (TEXT("+HardwareContext::Init")));

    //initialize the hardware, bring it up to a state ready for quick rendering of 
    //audio streams and UI sounds
    m_DriverIndex       = Index;
    m_InPowerHandler    = FALSE;
    m_InputDMARunning   = FALSE;
    m_OutputDMARunning  = FALSE;
    m_NumForcedSpeaker  = 0;
    m_Sleeping          = FALSE;
    m_audioDeinit       = FALSE;

    m_SysIntrAudioDMA   = SYSINTR_UNDEFINED;
    m_hAudioInterrupt   = NULL;
    hOutputIntEvent     = NULL;
    hInputIntEvent      = NULL;
    m_hDMAIsrHandler    = NULL;
    
    m_PlaybackChannel   = (XLLP_DMAC_CHANNEL_T)DMA_CH_OUT;         // DMA Ch. 1
    m_RecordingChannel  = (XLLP_DMAC_CHANNEL_T)DMA_CH_RCV;         // DMA Ch. 4

    // Initial power state
    m_dwPowerState      = D0;

    GetRegKeys();

    m_OutputDeviceContext.SetMono(m_fOutputRenderMonoOnly);


	ALLOCATE_RT_CODEC_CLASS

	if(!m_RTCodec)
	{
		return FALSE;
	}
	else
	{
		if(!m_RTCodec->Init(this))
		{
			return FALSE;
		}		
	}
  
    
    if (!MapDeviceRegisters())
    {
        goto Exit;
    }
    
    if (!InitAudioDMA())
    {
        goto Exit;
    }

    if (!MapDMADescriptors())
    {
        goto Exit;
    }
    
    // Map the DMA buffers (and fill the descriptors) into driver's virtual address space
    if (!MapDMABuffers())
    {
        goto Exit;
    }

    if (!InitInterruptThread())
    {
        goto Exit;
    }

#if USE_I2S_INTERFACE
    // Bring up IIS-LINK and initialize the Codec
    if(InitializeI2S(FALSE))
#else
    // Bring up AC-LINK and initialize the Codec
    if(InitializeACLink(FALSE, DEV_AUDIO))
#endif

    {
        PowerUp();
        InitCodec();
    }
    else
    {
        goto Exit;
    }

#if 0
    //do a quick diag--see if we can read and write registers
    TestAcLink();
#endif
#if 0
    {
const short MySineWave[164] = {
0, 0, 1285, 2563, 2563, 5063, 3825, 7438, 5063, 9630, 6270, 11585, 7438, 13255, 8561, 14598, 9630, 15582, 10641, 16182, 11585, 16384, 12458, 16182, 13255, 15582, 13970, 14598, 14598, 13255, 15137, 11585, 15582, 9630, 15931, 7438, 16182, 5063, 16333, 2563, 16384, 0, 16333, -2563, 16182, -5063, 15931, -7438, 15582, -9630, 15137, -11585, 14598, -13255, 13970, -14598, 13255, -15582, 12458, -16182, 11585, -16384, 10641, -16182, 9630, -15582, 8561, -14598, 7438, -13255, 6270, -11585, 5063, -9630, 3825, -7438, 2563, -5063, 1285, -2563, 0, 0, -1285, 2563, -2563, 5063, -3825, 7438, -5063, 9630, -6270, 11585, -7438, 13255, -8561, 14598, -9630, 15582, -10641, 16182, -11585, 16384, -12458, 16182, -13255, 15582, -13970, 14598, -14598, 13255, -15137, 11585, -15582, 9630, -15931, 7438, -16182, 5063, -16333, 2563, -16384, 0, -16333, -2563, -16182, -5063, -15931, -7438, -15582, -9630, -15137, -11585, -14598, -13255, -13970, -14598, -13255, -15582, -12458, -16182, -11585, -16384, -10641, -16182, -9630, -15582, -8561, -14598, -7438, -13255, -6270, -11585, -5063, -9630, -3825, -7438, -2563, -5063, -1285, -2563, 0, 0};

        int i,j;
        for (j=0; j<10; j++)
        {
            for (i=0; i<=162; i+=2)
            { 
                while ((m_pGPIORegisters->GPLR0 & (1 << 31)) != (1 << 31)); //freeze until it's high
                while ((m_pGPIORegisters->GPLR0 & (1 << 31)) != 0);        //freez until it goes low
                m_pAc97regs->PCDR = (MySineWave[i] << 16) | MySineWave[i+1] ;
             }
         }
    }
#endif   

    // Configure the DMA controller
    InitInputDMA();
    InitOutputDMA();

    m_Initialized = TRUE;

Exit: 
    if (FALSE == m_Initialized)
    {//fail to initialize
        Deinit();
    }
	RETAILMSG(1,(TEXT("Audio Init\r\n")));	
    DEBUGMSG(ZONE_INIT, (TEXT("-HardwareContext::Init")));
    return m_Initialized;
}


BOOL HardwareContext::MapDMABuffers()
{
    PBYTE pbDMATemp;
    DMA_ADAPTER_OBJECT Adapter;
    PHYSICAL_ADDRESS   PA;

    DEBUGMSG(ZONE_INIT, (TEXT("+MapDMABuffers")));

    Adapter.ObjectSize    = sizeof(DMA_ADAPTER_OBJECT);
    Adapter.InterfaceType = Internal;
    Adapter.BusNumber     = 0;

    pbDMATemp = (BYTE *) HalAllocateCommonBuffer(&Adapter, (AUDIO_BUFFER_SIZE * NUM_DMA_AUDIO_BUFFERS), &PA, FALSE);
    if (!pbDMATemp)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: AudioInitialize: failed to allocate DMA buffer(s).\r\n")));
        return(FALSE);
    }
    m_Output_pbDMA_PAGES[0] = pbDMATemp;
    m_Output_pbDMA_PAGES[1] = pbDMATemp + AUDIO_BUFFER_SIZE;

    m_Input_pbDMA_PAGES[0]  = pbDMATemp + 2*AUDIO_BUFFER_SIZE;
    m_Input_pbDMA_PAGES[1]  = pbDMATemp + 3*AUDIO_BUFFER_SIZE;

    m_Output_pbDMA_PAGES_Physical[0] = (BYTE *)PA.LowPart;
    m_Output_pbDMA_PAGES_Physical[1] = (BYTE *)PA.LowPart + AUDIO_BUFFER_SIZE;

    m_Input_pbDMA_PAGES_Physical[0]  = (BYTE *)PA.LowPart + 2*AUDIO_BUFFER_SIZE;
    m_Input_pbDMA_PAGES_Physical[1]  = (BYTE *)PA.LowPart + 3*AUDIO_BUFFER_SIZE;
    
    return TRUE;
}

void HardwareContext::InitInputDMA()
{

        FillInputDescriptors();
        //Dump the Descriptor
/*      RETAILMSG(ZONE_ERROR, (TEXT( "\r\n")));
        RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvA->ddadr %x \r\n" ),m_vpAudioRcvA->ddadr) );  
        RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvA->dsadr %x \r\n" ),m_vpAudioRcvA->dsadr) );
        RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvA->dtadr %x \r\n" ),m_vpAudioRcvA->dtadr) );
        RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvA->dcmd  %x \r\n" ),m_vpAudioRcvA->dcmd ) );


        RETAILMSG(ZONE_ERROR, (TEXT( "\r\n")));
        RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvB->ddadr %x \r\n" ),m_vpAudioRcvB->ddadr) );  
        RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvB->dsadr %x \r\n" ),m_vpAudioRcvB->dsadr) );
        RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvB->dtadr %x \r\n" ),m_vpAudioRcvB->dtadr) );
        RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvB->dcmd  %x \r\n" ),m_vpAudioRcvB->dcmd ) );*/


}

void HardwareContext::InitOutputDMA()
{
        FillOutputDescriptors();
        //Dump the Descriptor
//      RETAILMSG(ZONE_ERROR, (TEXT( "\r\n")));
//      RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitA->ddadr %x \r\n" ),m_vpAudioXmitA->ddadr) );        
//      RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitA->dsadr %x \r\n" ),m_vpAudioXmitA->dsadr) );
//      RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitA->dtadr %x \r\n" ),m_vpAudioXmitA->dtadr) );
//      RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitA->dcmd  %x \r\n" ),m_vpAudioXmitA->dcmd ) );


//      RETAILMSG(ZONE_ERROR, (TEXT( "\r\n")));
//      RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitB->ddadr %x \r\n" ),m_vpAudioXmitB->ddadr) );        
//      RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitB->dsadr %x \r\n" ),m_vpAudioXmitB->dsadr) );
//      RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitB->dtadr %x \r\n" ),m_vpAudioXmitB->dtadr) );
//      RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitB->dcmd  %x \r\n" ),m_vpAudioXmitB->dcmd ) );


}

int HardwareContext::GetNextOutputBuffer(void)
{
   return ((UINT32)m_pDMARegisters->ddg[m_PlaybackChannel].dsadr >= (UINT32)m_Output_pbDMA_PAGES_Physical[1]) ? 0 : 1 ;
}

void HardwareContext::StartOutputDMA()
{
    DEBUGMSG(ZONE_VERBOSE, (TEXT("+StartOutputDMA\r\n")));


    if (!m_OutputDMARunning)
    {

        ULONG OutputTransferred;

#if RT_ALC5621
		m_RTCodec->WriteCodecRegMask(RT5621_MISC_CTRL,DISABLE_FAST_VREG,DISABLE_FAST_VREG);	//disable fast vreg,it will affect quality of audio
#else
		m_RTCodec->WriteCodecRegMask(RT_MISC_CTRL,DISABLE_FAST_VREG,DISABLE_FAST_VREG);	//disable fast vreg,it will affect quality of audio
#endif

        // Fill in the first DMA buffer before kicking start DMA, which will
        // generate an interrupt (e.g. STARTINTR) right away. The IST thread will then
        // fill in the second DMA buffer.
        OutputTransferred = TransferOutputBuffer(0);

        if (OutputTransferred) 
        {
            m_OutputDMARunning=TRUE;

            // Initialize the DMA channel format
            //set the sample rate on every buffer due to ac97 work around. (???)
            SetSampleRate(SAMPLERATE, WAPI_OUT);

#if USE_I2S_INTERFACE

			m_pI2SRegs->SAICR=XLLP_SAICR_TUR;//clear transmit FIFO underrun

#else

            m_pAc97regs->POSR =  0x10;  //clear the output Fifo error

#endif

            if(OutputTransferred < AUDIO_BUFFER_SIZE)
            {
	        // Set second buffer descriptor STOP bit and the minimum length
                // in case we overrun into the second buffer.
                m_vpAudioXmitB->ddadr |= DESC_ADDRESS_STOP_MASK;
                m_vpAudioXmitB->dcmd = DMAC_AC97_XMITAB_CMD_MASK | 32;
            }

            RETAILMSG(ZONE_VERBOSE, (TEXT( "Starting DMA XMIT channel %d \r\n" ),m_PlaybackChannel) );

            // Load descriptor address reg to initialize DMA, pointing
            // to the buffer just loaded.
            m_pDMARegisters->ddg[m_PlaybackChannel].ddadr =(UINT32)m_vpAudioXmitA_Physical;

#if USE_I2S_INTERFACE

			m_pDMARegisters->drcmr[DMA_CHMAP_I2S_TRA] = DMA_MAP_VALID_MASK | m_PlaybackChannel ;

#else                

            m_pDMARegisters->drcmr[DMA_CHMAP_AC97_OUT] = DMA_MAP_VALID_MASK | m_PlaybackChannel ;

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -