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

📄 hwctxt.cpp

📁 freesacle mx21下的声卡alc5620的驱动程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// 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.
//
//------------------------------------------------------------------------------
//
//  Copyright (C) 2004-2006, Freescale Semiconductor, Inc. All Rights Reserved
//  THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
//  BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
//  FREESCALE SEMICONDUCTOR, INC.
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2005, MOTOROLA, INC. All Rights Reserved
// THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
// BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
// MOTOROLA, INC.
//
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//
//  Module: hwctxt.cpp
//
// Hardware context for audio driver. Contains code to support both STAC9753 and 
// WM8731 codecs. The audio driver uses DMA chaining with double buffering to 
// remove SSI overruns/underruns.
//
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// INCLUDE FILES  
//------------------------------------------------------------------------------
#include "wavemain.h"
#include <ceddk.h>

//------------------------------------------------------------------------------
// GLOBAL DEFINITIONS  
//------------------------------------------------------------------------------
//#if AC97
// Set 1 to use variable rate mode, default is fixed rate. 
//#define VRA         0       
//#endif 

#define AUDIO_CH_OUT     2
#define AUDIO_CH_IN      1

//------------------------------------------------------------------------------
// GLOBAL OR STATIC VARIABLES  
//------------------------------------------------------------------------------
HardwareContext *g_pHWContext = NULL;

//------------------------------------------------------------------------------
// STATIC FUNCTION PROTOTYPES  
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// EXPORTED FUNCTIONS
//------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------

#ifdef DEBUG
DBGPARAM dpCurSettings = {
    TEXT("WaveDriver"), {
        TEXT("Test")           //  0   ZONE_TEST
        ,TEXT("Params")         //  1   ZONE_PARAMS
        ,TEXT("Verbose")        //  2   ZONE_VERBOSE
        ,TEXT("Interrupt")      //  3   ZONE_INTERRUPT
        ,TEXT("WODM")           //  4   ZONE_WODM
        ,TEXT("WIDM")           //  5   ZONE_WIDM
        ,TEXT("PDD")            //  6   ZONE_PDD
        ,TEXT("MDD")            //  7   ZONE_MDD
        ,TEXT("Regs")           //  8   ZONE_REGS
        ,TEXT("Misc")           //  9   ZONE_MISC
        ,TEXT("Init")           // 10   ZONE_INIT
        ,TEXT("IOcontrol")      // 11   ZONE_IOCTL
        ,TEXT("Alloc")          // 12   ZONE_ALLOC
        ,TEXT("Function")       // 13   ZONE_FUNCTION
        ,TEXT("Warning")        // 14   ZONE_WARN
        ,TEXT("Error")          // 15   ZONE_ERROR
    },
    (1 << 15)   // Errors
    |   (1 << 14)   // Warnings
};
#endif

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)
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+Init\r\n")));
    
    if(m_Initialized)
    {
        return FALSE;
    }

    m_dwInputGain = 0xFFFF;
    m_dwOutputGain = 0xFFFF;
    m_fInputMute = FALSE;
    m_fOutputMute = FALSE;
    
    //----- 1. Initialize the state/status variables -----
    m_DriverIndex       = Index;
    m_InPowerHandler    = FALSE;
    m_InputDMARunning   = FALSE;
    m_OutputDMARunning  = FALSE;
    
    //----- 2. 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")));
        goto Exit;
    }
    
    //----- 3. Call BSP function to initialize audio -----
    BSPAudioInit();

    //----- 3.  Power up the audio -----
    PowerUp();

    //----- 4. Configure the Codec -----
    BSPAudioInitCodec();
    
    //----- 5. Initialize the interrupt thread -----
    if (!InitInterruptThread())
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("WAVEDEV.DLL:HardwareContext::Init() - Failed to initialize interrupt thread.\r\n")));
        goto Exit;
    }

    m_Initialized = TRUE;

Exit:
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+Init m_Initialized=%d\r\n"), m_Initialized));

    return m_Initialized;
}


//------------------------------------------------------------------------------
// 
//   FUNCTION:       Deinit
// 
//   DESCRIPTION:    De-initialises the audio hardware
// 
//   PARAMETERS:     
//                   None
// 
//   RETURNS:        
//                   TRUE for success initialisation.
//                   FALSE otherwise
// 
//------------------------------------------------------------------------------
BOOL HardwareContext::Deinit()
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+Deinit\r\n")));

    //----- 1. Disable the input/output channels -----
    BSPAudioStartOutput(FALSE);
    BSPAudioStartInput(FALSE);

    //----- 2. Disable/clear DMA input/output interrupts -----
    DDKDmacDisableChannelIntr(m_DmaRxChannel);
    DDKDmacStopChan(m_DmaRxChannel);
    DDKDmacDisableChannelIntr(m_DmaTxChannel);
    DDKDmacStopChan(m_DmaTxChannel);

    //----- 3. Turn the audio hardware off -----
    AudioMute((AUDIO_CH_OUT | AUDIO_CH_IN), TRUE);

    //----- 4. Unmap the control registers and DMA buffers -----
    BSPAudioDeinit();
    UnmapDMABuffers();

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-Deinit\r\n")));
    return TRUE;
}


//------------------------------------------------------------------------------
//
//  FUNCTION:       MapDMABuffers
//
//  DESCRIPTION:    Map both DMA pages into the local address space
//
//  PARAMETERS:     
//                  None
//
//  RETURNS:        
//                  TRUE for success
//                  FALSE otherwise
//
//------------------------------------------------------------------------------
BOOL HardwareContext::MapDMABuffers()
{
    PBYTE pVirtDMABufferAddr = NULL;
    DMA_ADAPTER_OBJECT Adapter;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+MapDMABuffers\r\n")));

    memset(&Adapter, 0, sizeof(DMA_ADAPTER_OBJECT));
    Adapter.InterfaceType = Internal;
    Adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);

    // Allocate a block of virtual memory (physically contiguous) for the DMA buffers.
    //
    pVirtDMABufferAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter, (AUDIO_DMA_PAGE_SIZE * 4), &m_PhysDMABufferAddr, FALSE);
    if (pVirtDMABufferAddr == NULL)
    {
        ERRORMSG(TRUE, (TEXT("WAVEDEV.DLL:HardwareContext::MapDMABuffers() - Failed to allocate DMA buffer.\r\n")));
        return(FALSE);
    }

    // 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] = pVirtDMABufferAddr;
    m_Output_pbDMA_PAGES[1] = pVirtDMABufferAddr + AUDIO_DMA_PAGE_SIZE;
    m_Input_pbDMA_PAGES[0]  = pVirtDMABufferAddr + (2 * AUDIO_DMA_PAGE_SIZE);
    m_Input_pbDMA_PAGES[1]  = pVirtDMABufferAddr + (3 * AUDIO_DMA_PAGE_SIZE);

    // Return physical addresses for TX and RX buffer
    m_DmaTxBuffer[0] = (UINT32)m_PhysDMABufferAddr.QuadPart;
    m_DmaTxBuffer[1] = (UINT32)m_PhysDMABufferAddr.QuadPart + AUDIO_DMA_PAGE_SIZE;
    m_DmaRxBuffer[0] = (UINT32)m_PhysDMABufferAddr.QuadPart + (2 * AUDIO_DMA_PAGE_SIZE);
    m_DmaRxBuffer[1] = (UINT32)m_PhysDMABufferAddr.QuadPart + (3 * AUDIO_DMA_PAGE_SIZE);
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("-MapDMABuffers\r\n")));

    return TRUE;

}

//------------------------------------------------------------------------------
//
//  FUNCTION:       UnmapDMABuffers
//
//  DESCRIPTION:    Unmap DMA pages 
//
//  PARAMETERS:     
//                  None
//
//  RETURNS:        
//                  TRUE for success
//                  FALSE otherwise
//
//------------------------------------------------------------------------------
BOOL HardwareContext::UnmapDMABuffers()
{
    if(m_Output_pbDMA_PAGES[0])
    {
        DMA_ADAPTER_OBJECT Adapter;

        memset(&Adapter, 0, sizeof(DMA_ADAPTER_OBJECT));
        Adapter.InterfaceType = Internal;
        Adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);

        HalFreeCommonBuffer(&Adapter, 0, m_PhysDMABufferAddr, m_Output_pbDMA_PAGES[0], FALSE);
    }

    return TRUE;
}

MMRESULT HardwareContext::SetOutputGain (DWORD dwGain)
{
	DEBUGMSG(ZONE_FUNCTION, (TEXT("+SetOutputGain\r\n")));
	
	BSPSetOutputGain(dwGain);
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("-SetOutputGain\r\n")));

        return MMSYSERR_NOERROR;
}

MMRESULT HardwareContext::SetOutputMute(BOOL fMute)
{
    m_fOutputMute = fMute;

    // Mute outputs
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+SetOutputMute\r\n")));

    BSPSetOutputMute(m_fOutputMute);
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+SetOutputMute\r\n")));

    return MMSYSERR_NOERROR;
}

BOOL HardwareContext::GetOutputMute (void)
{
    return m_fOutputMute;
}

DWORD HardwareContext::GetOutputGain (void)
{
    return m_dwOutputGain;
}

BOOL HardwareContext::GetInputMute (void)
{
    return m_fInputMute;
}

MMRESULT HardwareContext::SetInputMute (BOOL fMute)
{
    m_fInputMute = fMute;
    return m_InputDeviceContext.SetGain(fMute ? 0: m_dwInputGain);
}

DWORD HardwareContext::GetInputGain (void)
{
    return m_dwInputGain;
}

MMRESULT HardwareContext::SetInputGain (DWORD dwGain)
{
    m_dwInputGain = dwGain;
    if (! m_fInputMute)
    {
        m_InputDeviceContext.SetGain(dwGain);
    }
    return MMSYSERR_NOERROR;
}

//------------------------------------------------------------------------------
//
//  FUNCTION:       StartOutputDMA
//
//  DESCRIPTION:    Start playback DMA
//
//  PARAMETERS:     
//                  None
//
//  RETURNS:        
//                  None
//
//------------------------------------------------------------------------------
BOOL HardwareContext::StartOutputDMA()
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+StartOutputDMA\r\n")));
        
    UINT32 OutputTransferred;
    
    if(!m_OutputDMARunning)
    {
        //----- 1. Initialize our buffer counters -----
        // For now, pretend output dma is running in case we accidentally get reentered
        m_OutputDMARunning=TRUE;
        m_OutBytes[0] = 0;
        m_OutBytes[1] = 0;
        m_TxBufIndex = 0;


        //----- 2. Prime the output buffer with sound data -----
        OutputTransferred = TransferOutputBuffers();    
        OutputTransferred += TransferOutputBuffers();
              
        //----- 3. If we did transfer any data to the DMA buffers, go ahead and enable DMA -----
        if(OutputTransferred)
        {
            //----- 4. Configure the channel for playback -----
            DDKDmacSetSrcAddress(m_DmaTxChannel, m_DmaTxBuffer[0]);
            DDKDmacSetRepeatType(m_DmaTxChannel, DMAC_REPEAT_FOREVER);
            DDKDmacEnableChannelIntr(m_DmaTxChannel);

⌨️ 快捷键说明

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