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

📄 ac97.c

📁 pxa270触摸屏驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
        Ac97ClearFifoStatus (fifoInfoP);
    }

    if (!status)
    {
        if (!(fifoInfoP->fifoStatus & AC97_FIFO_ST_DMA_CHAN_ACQ))
        {   // Need to get DMA channel

            // Get DMA channel and record the results.
            // Parameter values for XsDmaGetFreeChannel()
            //          intialized in Ac97SWInit()
            fifoInfoP->dmaChannel =  XsDmaGetFreeChannel (
                                     fifoInfoP->dmaChannelPrioReq,
                                     fifoInfoP->dmaDeviceName,
                                     fifoInfoP->fifoStatus & AC97_FIFO_ST_DIR_TX,
                                    &fifoInfoP->dmaChannelPrioCmp);

            if (-1 == fifoInfoP->dmaChannel)
            {   // No channel available.  Record fact and clean up.

                // The convention is 0s for most uninitialized members
                fifoInfoP->dmaChannel        = 0; 
                fifoInfoP->dmaChannelPrioReq = 0;
                fifoInfoP->dmaChannelPrioCmp = 0;

                Ac97WriteFifoStatus (fifoInfoP, 
                                     AC97_FIFO_ST_DMA_CHAN_NA,
                                     AC97_SET);
                status = ERR_T_NOT_AVAIL;
                errLoc = 4;
            }
            else
            {
                Ac97WriteFifoStatus (fifoInfoP, 
                                     AC97_FIFO_ST_DMA_CHAN_ACQ,
                                     AC97_SET);
                Ac97WriteFifoStatus (fifoInfoP, 
                                     AC97_FIFO_ST_DMA_CHAN_NA,
                                     AC97_CLEAR);
            }
        } // if (need to get DMA channel)


        if (!status )
        {
            if (!(fifoInfoP->stopDescriptorRootP))
            {
                 // 0-length descriptor, points to self.  Needs no buffer.
                fifoInfoP->stopDescriptorRootP = 
                    XsDmaCreateBareDescChain (fifoInfoP->dmaChannel, 1, 0);

            } // Get stopDMA descriptor, if needed.

            if (!fifoInfoP->stopDescriptorRootP)
            {
                status = ERR_T_NOT_AVAIL;
                errLoc = 5;
            }
            else
            {
                // Don't declare open until all operations performed.
                Ac97WriteFifoStatus (fifoInfoP, 
                                     AC97_FIFO_ST_OPEN,
                                     AC97_SET);

                // Give our caller the address of the info structure.
                // It will be needed for client operations on this FIFO.
                *fifoInfoAddrP = fifoInfoP;

            } // else: Have stopDMA descriptor.

        } // if (Acquired DMA channel OK)

    } // else (no configuration error conditions)

    if (status)
    {
        LOGERROR (fifoInfoP->parentAc97ctxP->loggedError, 
                  ERR_L_AC97,
                  ERR_S_AC97_OPEN_FIFO,
                  status,
                  fifoInfoP->fifoId,
                  errLoc,
                  0)
    }

    return(status);

} // Ac97OpenFifo



UINT32 Ac97OpenFifoPcmIn (Ac97ContextT* ctxP, 
                          Ac97FifoProcessingInfoT** fifoInfoPP)
{
    return (Ac97OpenFifo(ctxP, fifoInfoPP, XS_AC97CTRL_FIFO_AUDIO_IN));
}    

UINT32 Ac97OpenFifoPcmOut (Ac97ContextT* ctxP, 
                           Ac97FifoProcessingInfoT** fifoInfoPP)
{
    return (Ac97OpenFifo(ctxP, fifoInfoPP, XS_AC97CTRL_FIFO_AUDIO_OUT));
}    

UINT32 Ac97OpenFifoMicIn (Ac97ContextT* ctxP, 
                          Ac97FifoProcessingInfoT** fifoInfoPP)
{
    return (Ac97OpenFifo(ctxP, fifoInfoPP, XS_AC97CTRL_FIFO_MIC_IN));
}    

UINT32 Ac97OpenFifoModemIn (Ac97ContextT* ctxP, 
                            Ac97FifoProcessingInfoT** fifoInfoPP)
{
    return (Ac97OpenFifo(ctxP, fifoInfoPP, XS_AC97CTRL_FIFO_MODEM_IN));
}    

UINT32 Ac97OpenFifoModemOut (Ac97ContextT* ctxP,  
                             Ac97FifoProcessingInfoT** fifoInfoPP)
{
    return (Ac97OpenFifo(ctxP, fifoInfoPP, XS_AC97CTRL_FIFO_MODEM_OUT));
}    



// Record first error condition, but continue closing down as much as possible
UINT32 Ac97CloseFifo (Ac97FifoProcessingInfoT* fifoInfoP)
{
    UINT32 status = ERR_NONE;
    UINT32 statusTmp = ERR_NONE;
    int errloc = 0;

    DM_CwDbgPrintf(DM_CW_AC97_CODEC, 
                "Ac97CloseFifo: Fifo, ID = %d; Addr = %08X; Name = %s \n",
                 fifoInfoP->fifoId, (UINT32) fifoInfoP, fifoInfoP->fifoNameStrP);
    DM_CwDbgPrintf(DM_CW_AC97_CODEC, 
                "Fifo status word: %X\n",fifoInfoP->fifoStatus);

    // No-op gracefuly if null or not open.
    if (fifoInfoP)
    {
    
        if (fifoInfoP->fifoStatus & AC97_FIFO_ST_OPEN)
        {
            // Graceful termination of any current operations.
            //  Includes disabling of interrupts
            status = Ac97StopFifo (fifoInfoP);
            if (status && !statusTmp)
            {
                statusTmp = status;
                errloc   = 1;
            }
    

            // Do the close here!
            // Close includes disposing of all resources but not changing
            //   configuration settings.

            fifoInfoP->clientBufP                   = 0;
            fifoInfoP->dmaDescriptorHwPaddrNextTmp  = 0;
            fifoInfoP->samplesProcessed             = 0;
        
            // Mark as closed now.  Buffers really can't be used at this point.
            // In a pre-emptive multitasking environment, a "closing" flag or  
            // more effective mutex would be needed to bracket this entire
            // function.
            fifoInfoP->fifoStatus &= AC97_FIFO_ST_OPEN_MSK;


            // Return DMA channel: This also unregisters DMA handler, disables
            //  DMA interrupts for the channel and generally cleans up 
            //  the DMA interface.
            status = XsDmaFreeChannel(fifoInfoP->dmaChannel);
            if (status && !statusTmp)
            {
                statusTmp = status;
                errloc   = 2;
            }

            // Unregister FIFO interrupt handler.  Also disables this 
            //  FIFO interrupt.
            status = XsAc97CtrlUnRegisterHandler (fifoInfoP->fifoInterruptId);
            if (status && !statusTmp)
            {
                statusTmp = status;
                errloc   = 3;
            }
            Ac97WriteFifoStatus (fifoInfoP, 
                                 AC97_FIFO_ST_FIFO_ISR_REG,
                                 AC97_CLEAR);

            // Return all descriptors and buffers to pool.  Chain may be either
            // closed or open.
            if (fifoInfoP->standardModeDescriptorRootP)
            {
                status = XsDmaDestroyChain (fifoInfoP->
                                                  standardModeDescriptorRootP);
                fifoInfoP->standardModeDescriptorRootP = NULL;
                if (status && !statusTmp)
                {
                    statusTmp = status;
                    errloc   = 4;
                }
            }

            // Special handling for DMA loop mode.  The subroutine knows all.
            status = Ac97FreeDmaLoopDescriptors (fifoInfoP);
            if (status && !statusTmp)
            {
                statusTmp = status;
                errloc   = 5;
            }

            //  Now all descriptor chains are gone, so clear the active pointer
            fifoInfoP->activeDescriptorRootP = NULL;
            Ac97WriteFifoStatus (fifoInfoP, 
                                 (AC97_FIFO_ST_DMA_CHAN_ACQ |
                                  AC97_FIFO_ST_DMA_ISR_REG),
                                 AC97_CLEAR);

            if (statusTmp)
            {
                LOGERROR (fifoInfoP->parentAc97ctxP->loggedError, 
                          ERR_L_AC97, ERR_S_AC97_CLOSE_FIFO, statusTmp,errloc,0,0)
            }

// @@@ This probably should be inside an "else"

            Ac97WriteFifoStatus (fifoInfoP, 
                                 AC97_FIFO_ST_OPEN,
                                 AC97_CLEAR);

        } // if (fifoInfoP->fifoStatus & AC97_FIFO_ST_OPEN)
    } // if (fifoInfoP)

    DM_CwDbgPrintf(DM_CW_AC97_CODEC, 
                "End Ac97CloseFifo\n");
    DM_CwDbgPrintf(DM_CW_AC97_CODEC, 
                "Fifo status word: %X\n",fifoInfoP->fifoStatus);

    return (status);

} // Ac97CloseFifo()
*/

// Returns the number of samples read into client buffer.  4 bytes / sample.
// -1 indicates no bytes available and an error condition.  Use Ac97CheckFifoStatus
//  and Ac97ClearFifoStatus
// Must be read from an open, readable Fifo
INT Ac97ReadBuf (Ac97FifoProcessingInfoT* fifoInfoP, PUINT32 inbufP, INT numSamples)
{
    UINT32 status = ERR_NONE;
    INT    numRead = 0;
//    @@@
    if (!(fifoInfoP->fifoStatus & AC97_FIFO_ST_OPEN))
    {
        status =  ERR_T_WRONG_STATE; 
    	;//masked zzm
        Ac97WriteFifoStatus (fifoInfoP, 
                             AC97_FIFO_ST_INVALID_OP,
                             AC97_SET);
    
    }    
    else if (fifoInfoP->fifoStatus & AC97_FIFO_ST_DIR_TX)
    {
        status = ERR_T_NORECEIVE;  // Can't read from a Tx FIFO
      //masked zzm
        Ac97WriteFifoStatus (fifoInfoP, 
                             AC97_FIFO_ST_INVALID_OP,
                             AC97_SET);
    }
    else if (fifoInfoP->fifoStatus &0 /*@@@*/)
    {
    
    }

//@@@ // try to do the read here!


    if (status)
    {
        numRead = -1;
        LOGERROR (fifoInfoP->parentAc97ctxP->loggedError, 
                  ERR_L_AC97, 
                  ERR_S_AC97_READ_BUF, 
                  status, 
                  fifoInfoP->fifoId, 
                  (UINT32)&fifoInfoP->parentAc97ctxP, 
                  0)
    }
 
    return (numRead);
    
} // Ac97ReadBuf()

// Returns the number of samples read from client buffer into driver buffer.  
//   4 bytes / sample.
// -1 indicates no bytes transferred and an error condition.  Use 
//  Ac97CheckFifoStatus and Ac97ClearFifoStatus.
// Must be written to an open, writable Fifo
INT Ac97WriteBuf (Ac97FifoProcessingInfoT* fifoInfoP, PUINT32 outbufP, INT numSamples)
{
    UINT32 status = ERR_NONE;
    INT    numWritten = 0;
  //  @@@
    
    fifoInfoP->fifoStatus = AC97_FIFO_ST_INVALID_OP;

    if (!(fifoInfoP->fifoStatus & AC97_FIFO_ST_OPEN))
    {
        status =  ERR_T_WRONG_STATE; 
        Ac97WriteFifoStatus (fifoInfoP, 
                             AC97_FIFO_ST_INVALID_OP,
                             AC97_SET);
    }    
    else if (fifoInfoP->fifoStatus & AC97_FIFO_ST_DIR_TX)
    {
        status = ERR_T_NOTRANSMIT;  // Can't write to a Rx FIFO
        Ac97WriteFifoStatus (fifoInfoP, 
                             AC97_FIFO_ST_INVALID_OP,
                             AC97_SET);
    }

//@@@ // try to do the write here!

    if (status)
    {
        numWritten = -1;
        LOGERROR (fifoInfoP->parentAc97ctxP->loggedError, 
                  ERR_L_AC97, 
                  ERR_S_AC97_WRITE_BUF, 
                  status, 
                  fifoInfoP->fifoId, 
                  (UINT32)&fifoInfoP->parentAc97ctxP, 
                  0)
    }
 
    return (numWritten);

} // Ac97WriteBuf()

// Gets the fifoStatus word from the target Ac97FifoProcessingInfoT struct
//  Should be interpreted with the "AC97_FIFO_ST_" constants
// Clears AC97_FIFO_ST_INVALID_OP status on read.
UINT32 Ac97CheckFifoStatus (Ac97FifoProcessingInfoT* fifoInfoP)
{
    return (fifoInfoP->fifoStatus);
}    

// Clears error indications in the fifoStatus word and also supporting data
//  such as the current number of DMA restarts.
void Ac97ClearFifoStatus (Ac97FifoProcessingInfoT* fifoInfoP)
{
    // Clear all error indications from this FIFO's record.

    fifoInfoP->dmaRestarts                  = 0;
    fifoInfoP->isrError                     = 0;
    fifoInfoP->ac97FifoErrs                 = 0;

    fifoInfoP->fifoStatus &= AC97_FIFO_ST_CLR_EVNT_MSK;
    
} // Ac97ClearFifoStatus ()

// @@@ ??? Ac97PauseAudio



⌨️ 快捷键说明

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