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

📄 audio.c

📁 windows ce 下ARM9音频驱动代码
💻 C
📖 第 1 页 / 共 4 页
字号:

/*++
Copyright (c) 2001, 2002 BSQUARE Corporation.  All rights reserved.

Module Name:

    Audio.c

Module Description:

    This module contains the implementation of PDD interface routines for
    the platform wave device driver.

Author:

    Benny Ng    25-June-2001

Revision History:

    Yuqun Cao   16-Jan-2002

        1. Add critical section protection in WaveProc(). It is called from
           different threads. The MDD layer does not synchronize the access.

    Thomas Satagaj  22-Apr-2002

        1. Add InitializeAacPower()  to cycle codec power.

--*/

#include "bceddk.h"
#include "chip.h"
#include "audio.h"
#include "ac97.h"

//#pragma optimize("", off)

//*TSAT* 27-Dec-2002 Turn on debug messages
//#undef  DEBUGMSG
//#define DEBUGMSG(cond, msg) RETAILMSG(1, msg)


#define WORD_ALIGNMENT  4
#define SLEEP_VAL       3

//
// Required global for MDD.
//
ULONG gIntrAudio = SYSINTR_NOP;

static const PHYSICAL_ADDRESS HighestPhysAddr = PHYSICAL_ADDRESS_MAXIMUM;
static PWAVE_DEVICE_INSTANCE WaveDevice = NULL;
static PWAVE_RESOURCE WaveInResource = NULL;
static PWAVE_RESOURCE WaveOutResource = NULL;

PWAVE_DEVICE_INSTANCE
getWaveDevice( VOID )
{
    return WaveDevice;
}

//
// Private Routines.
//

static
BOOLEAN
InitializePlatformRegisters(
    IN PWAVE_DEVICE_INSTANCE WaveDevice
    )

/*++

Routine Description:


Arguments:


Return Value:

--*/

{
    BOOLEAN RoutineSuccess = TRUE;

    DEBUGMSG(1, (TEXT("InitializePlatformRegisters:\r\n")));
    return RoutineSuccess;
}


static
BOOLEAN
InitializeAacPower(
    IN BOOLEAN PwrOn
    )
/*++

Routine Description:

    This routine is used to modify the write-only I/O Board Control Register.
    Only the kernel routine can be used since it maintains the software shadow
     register to track the BCR's contents.
    What this routine does is turn on/turn off power to the AC97 codec.

Arguments:

    PwrOn - TRUE  - Set nAC97_PWR_EN = LO to enable  codec power.
          - FALSE - Set nAC97_PWR_EN = HI to disable codec power.

Return Value:

    TRUE if power was set as requested.

--*/

{
    BOOL            bSuccess;           //Status
    USHORT_MODIFY   usModify;           //Struct to pass to the bcr routine.
    ULONG           ulBytsRet;          //Bytes returned.

    //*************************************************************************
    //* The I/O board has a (74LVC273PW) control latch to control power of
    //*  various I/O board peripherals (pc card, ethernet, audio, etc.)
    //* This latch is loaded with a write only control register through the
    //*  processor board CPLD.
    //* Since this register is write only and is required to control devices
    //*  that will exist in unknown process spaces, we use the IOCTL mechanism
    //*  to change and maintain the BCR in a single location.
    //*
    //* This routine will make the IOCTL call to enable/disable power to the
    //*  AC97 audio codec.
    //*
    //* BitMask  tells the kernel routine which bit in the BCR will be altered.
    //* BitValu  tells the kernel routine how to set that bit.
    //*  0 = power on.
    //*  1 = power off.
    //*
    //*************************************************************************
    if(PwrOn == TRUE)
    {
      usModify.Value    = 0;
    }
    else
    {
      usModify.Value    = CPLD_W_BDCTL_AC97_EN;
    }

    usModify.Address    = 0;
    usModify.Mask       = CPLD_W_BDCTL_AC97_EN;

    bSuccess            = KernelIoControl(IOCTL_HAL_BCR_MODIFY,
                                          &usModify,
                                          sizeof(usModify),
                                          NULL,
                                          0,
                                          &ulBytsRet);
    DEBUGMSG((bSuccess == FALSE), (TEXT("InitializeAacPower: Failed BCR modify.\r\n")));
    return(bSuccess);
}


static
BOOLEAN
InitializeAacRegisters(
    IN PWAVE_DEVICE_INSTANCE WaveDevice
    )

/*++

Routine Description:

    Initializes the AAC registers.

Arguments:

    WaveDevice - Pointer to the wave device configuration structure whose
        corresponding AAC registers are to be initialized.

Return Value:

    TRUE if successful, FALSE otherwise.

--*/

{
    long timeoutcounter;
    ULONG  tmp;

    DEBUGMSG(1, (TEXT("InitializeAacRegisters:\r\n")));

//	InitializeAacPower(FALSE);
//	Sleep(500);
//	InitializeAacPower(TRUE);
//	Sleep(500);

    //
    // Enable the AAC block 
    //  ***NOTE*** This call drives PH6 HI which releases the codec from reset.
    //
    WRITE_REGISTER_ULONG(&WaveDevice->AacRegPtr->AACGCR, AAC_GCR_AACIFE);
    Sleep(30);
    WRITE_REGISTER_ULONG(&WaveDevice->AacRegPtr->AACRESET, 0x3);
	Sleep(500);
//   WRITE_REGISTER_ULONG(&WaveDevice->AacRegPtr->AACRESET, 0x00);
//	Sleep(500);   

	//
    // Wait for the AC97 Codec Ready signal
    //
    timeoutcounter = 9999999;
    while ((READ_REGISTER_ULONG(&WaveDevice->AacRegPtr->AACRGIS) & AAC_RGIS_CODECREADY)==0)  {
        timeoutcounter--;
//        if (timeoutcounter == 0)        {
//            return FALSE;
//        }
    }  // endwhile
    

    //
    // Setup the TX FIFO
    //

    tmp = (AAC_TXCR_TEN | AAC_TXCR_TX3 | AAC_TXCR_TX4);

#ifndef NOAUDIODMA
    //
    // DMA uses Compact Mode.
    //

    tmp |= AAC_TXCR_CM;

#endif

    WRITE_REGISTER_ULONG(&WaveDevice->AacRegPtr->AACTXCR1, tmp);
    Drv_AHBBus_ExtraWrite();

    if (READ_REGISTER_ULONG(&WaveDevice->AacRegPtr->AACTXCR1) != tmp) {

        DEBUGMSG(1, (TEXT("InitializeAacRegisters: Initialize AACTXCR1 failed\r\n")));
        return FALSE;
    }
        
    if ((READ_REGISTER_ULONG(&WaveDevice->AacRegPtr->AACSR1) & AAC_SR_TXFE) != AAC_SR_TXFE) {

        DEBUGMSG(1, (TEXT("InitializeAacRegisters: AACSR1 failed\r\n")));
        return FALSE;
    }

    //
    // Setup the RX FIFO
    //

    tmp = (AAC_RXCR_REN | AAC_RXCR_RX3 | AAC_RXCR_RX4);

#ifndef NOAUDIODMA
    //
    // DMA uses Compact Mode.
    //

    tmp |= AAC_RXCR_CM;

#endif

    WRITE_REGISTER_ULONG(&WaveDevice->AacRegPtr->AACRXCR1, tmp);

    if (READ_REGISTER_ULONG(&WaveDevice->AacRegPtr->AACRXCR1) != tmp) {

        DEBUGMSG(1, (TEXT("InitializeAacRegisters: Initialize AACRXCR1 failed\r\n")));
        return FALSE;
    }
        
        DEBUGMSG(1, (TEXT("InitializeAacRegisters: Sucessfull\r\n")));

    return TRUE;
}


static
BOOLEAN
InitializeDmaResources(
    IN OUT PWAVE_DEVICE_INSTANCE WaveDevice
    )

/*++

Routine Description:


Arguments:

    WaveDevice - Pointer to the wave device configuration structure for which
        DMA resources are to be allocated and initialized.

Return Value:

    TRUE if successful, FALSE otherwise.

--*/

{
    BOOLEAN RoutineSuccess;
    BOOLEAN Success;
    ULONG TotalDmaBufferSize;
    PVOID DmaBuffersBase;
    PHYSICAL_ADDRESS DmaBuffersPhysAddr;
    PMDL DmaBuffersMdl;
    DEVICE_DESCRIPTION DeviceDescription;
    ULONG NumMapRegisters;
    PADAPTER_OBJECT AdapterObject;
    PVOID MapRegistersBase;

    RoutineSuccess = FALSE;

        DEBUGMSG(1, (TEXT("InitializeDmaResources:\r\n")));

    //
    // Allocate the memory for DMA buffers from the physical memory pool.
    // This will guarantee virtually and physically contiguous memory.
    //
    TotalDmaBufferSize = WaveDevice->DmaBufferSize * 4;

	DEBUGMSG(1,(TEXT("TotalDmaBufferSize = %d\r\n"),TotalDmaBufferSize));

    DmaBuffersBase = MmAllocatePhysicalMemory(TotalDmaBufferSize,
                                              HighestPhysAddr,
                                              WORD_ALIGNMENT,
                                              &DmaBuffersPhysAddr);

    DEBUGMSG(1, (TEXT("InitializeDmaResources: DmaBuffersPhysAddr=0x%x TotalDmaBufferSize=0x%x CurrentProcessID=%X\r\n"),
                 DmaBuffersPhysAddr.LowPart,
                 TotalDmaBufferSize,GetCurrentProcessId()));

    if (DmaBuffersBase == NULL) {

        DEBUGMSG(1, (TEXT("InitializeDmaResources: Physical memory allocation failed\r\n")));
        goto ErrorReturn;
    }

    WaveDevice->DmaBuffersBase = DmaBuffersBase;

    //
    // Create a MDL for the above.  This is passed to the HalMapTransfer
    // routine.  Note that we could just use the physical and virtual
    // addresses returned by MmAllocatePhysicalMemory, but that would kind of
    // violate the driver model.
    //
    DmaBuffersMdl = MmCreateMdl(NULL,
                                DmaBuffersBase,
                                TotalDmaBufferSize);

    if (DmaBuffersMdl == NULL) {

        DEBUGMSG(1, (TEXT("InitializeDmaResources: Failed to create MDL\r\n")));
        goto ErrorReturn;
    }

	DEBUGMSG(1,(TEXT("MDL Created\r\n")));

    WaveDevice->DmaBuffersMdl = DmaBuffersMdl;

    //
    // Initialize the device description structure's relevant fields.
    // Note that most are don't cares and are left uninitialized.  With
    // the device description, get the adapter.
    //

    DeviceDescription.DmaChannel = WaveDevice->DmaChannelOutput;

    NumMapRegisters = 0;

    //
    // Get the adapter object for output.
    //
    AdapterObject = HalGetAdapter(&DeviceDescription, &NumMapRegisters);

    if (AdapterObject == NULL) {

        DEBUGMSG(1, (TEXT("InitializeDmaResources: Failed to get adapter for output\r\n")));
        goto ErrorReturn;
    }

	DEBUGMSG(1,(TEXT("Output Adapter Object Created\r\n")));

    WaveDevice->AdapterObjectOutput = AdapterObject;

    //
    // Allocate the DMA channel for output.
    //
    Success = HalAllocateAdapterChannel((PDMA_ADAPTER_OBJECT)(AdapterObject),
                                        0,
                                        &MapRegistersBase);

    if (Success == FALSE) {

        DEBUGMSG(1, (TEXT("InitializeDmaResources: Failed to allocate DMA channel for output\r\n")));
        goto ErrorReturn;
    }

    WaveDevice->MapRegsBaseOutput = MapRegistersBase;

	DEBUGMSG(1,(TEXT("Output DMA Channel Allocated\r\n")));

    //
    // Get the adapter object for input.
    //
    DeviceDescription.DmaChannel = WaveDevice->DmaChannelInput;

    NumMapRegisters = 0;

    AdapterObject = HalGetAdapter(&DeviceDescription,
                                  &NumMapRegisters);

    if (AdapterObject == NULL) {

        DEBUGMSG(1, (TEXT("InitializeDmaResources: Failed to get adapter for input\r\n")));
        goto ErrorReturn;
    }

	DEBUGMSG(1,(TEXT("Input Adapter Created\r\n")));

    WaveDevice->AdapterObjectInput = AdapterObject;

    //
    // Allocate the DMA channel for input.
    //
    Success = HalAllocateAdapterChannel((PDMA_ADAPTER_OBJECT)(AdapterObject),
                                        0,
                                        &MapRegistersBase);

    if (Success == FALSE) {
        DEBUGMSG(1, (TEXT("InitializeDmaResources: Failed to allocate DMA channel for input\r\n")));
        goto ErrorReturn;
    }

    WaveDevice->MapRegsBaseInput = MapRegistersBase;

    DEBUGMSG(1, (TEXT("-InitializeDmaResources: success\r\n")));
    RoutineSuccess = TRUE;

ErrorReturn:

    return RoutineSuccess;

}

⌨️ 快捷键说明

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