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

📄 ac97.c

📁 pxa270触摸屏驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/**************** Audio support utilities ******************/

void Ac97SwRestoreDefaultsAudio (Ac97ContextT* ctxP)
    // Only restores the audio "current values" writeable record to the 
    //   default settings.
    // To place them into hardware, Ac97HwReconfigAudio() must be used.
{
    INT i;
    for (i = 0; i < AC97_NUM_MIXER_REGS; i++ )
    {
        if ( AC97_MR_USAGE_AUDIO == 
                        (*ctxP->mixerRegsDfltValsUsageP)[i].mixerRegUsage)
        {
            ctxP->mixerRegsCurrVals[i] = 
                        (*ctxP->mixerRegsDfltValsUsageP)[i].mixerRegDefaultVal;
        }
    }
} // Ac97SwRestoreDefaultsAudio ()
 

UINT32 Ac97HwReconfigAudio (Ac97ContextT* ctxP)
{
    // Does not permit a change in the resources used (controller comms, codec)
    // Does not change most recently set values of writeable regs
    // Enable all supported audio codec subsystems
    // Verify readiness of all supported audio codec subsystems
    // Write out all values in "current" Audio registers record to the codec
    // Set audio state variable flag fields. @@@ What are these?
    // Stop at first error.

    UINT32 status;
    UINT32 desiredSetting;
    UINT32 checkedSetting;
    INT    i = 0;

    // First, make sure that all audio subsystems are enabled and ready.
    status = Ac97PowerOnAudioSubsystems (ctxP); 

    // Now, write all audio settings to the codec and check them.

    // Try all mixer registers
    for (i = 0; (i < AC97_NUM_MIXER_REGS) && !status ; i++ )
    {
        // Touch only if standard audio writeable registers
        if ( AC97_MR_USAGE_AUDIO == 
                          (*ctxP->mixerRegsDfltValsUsageP)[i].mixerRegUsage)
        {
            // Write existing intended settings as found in SW record.
            desiredSetting = ctxP->mixerRegsCurrVals[i];
            status = XsAc97CtrlWriteCodecReg   
                                        (ctxP->audioIdForController, 
                                         i * 2,     // mixer regs step by 2
                                         desiredSetting);
            // Now check that the value was accepted
            if (!status)
            {
                status = XsAc97CtrlReadCodecReg
                                        (ctxP->audioIdForController, 
                                         i * 2,     // mixer regs step by 2
                                         &checkedSetting);
            }
            if (!status && (checkedSetting != desiredSetting))
            {
                // Failed compare means that at least one bit didn't set or clr
                status = ERR_T_NOBITSET;    
            }

        } // if AC97_MR_USAGE_AUDIO usage
    } // for all mixer registers

    if (!status)
    {
        ctxP->audioCodecReady       = TRUE;
        ctxP->audioCodecInitialized = TRUE;
    }
    else
    {
        ctxP->audioCodecReady       = FALSE;
        ctxP->audioCodecInitialized = FALSE;

        // First param is ID # of problem register.  Becomes -2 if the failure
        //  was during the subsystem power on subroutine.
        LOGERROR (ctxP->loggedError, ERR_L_AC97, 
                       ERR_S_AC97_HWRCNFG_AUD, status, (i-1)*2, 0, 0)
    }

    return (status);
    
} // Ac97HwReconfigAudio ()



// Runs the power-on state machine from PR1..4 previously being set 
// Also makes sure that all extended audio subsystems are enabled and ready.
// Assumes that basic communication with the codec is established.

UINT32 Ac97PowerOnAudioSubsystems (Ac97ContextT* ctxP)
{
    // Not supporting power modes for initial release, so only make sure that
    //  all subsystems supported by the target codec are ready.  State machine
    //  implementation will be needed when power modes are supported.

    UINT32 status;
    UINT32 ac97MrPowerdownCtrlStatTmp;
    INT    msTimeout = AC97_AUD_RDY_FROM_COLD_TOUT_MS;
    INT    errLoc  = 1;  // Default is error from subroutine
// DEBUG
    INT    commErrs = 0;

    // Return timeout error if subsystem readiness fails after n msec.

    // Get Powerdown status.  For this preliminary implementation, all
    //   subsystems should be enabled and ready.
    status = XsAc97CtrlReadCodecReg ( ctxP->audioIdForController,
                                      AC97_MR_POWERDOWN_CTRL_STAT, 
                                     &ac97MrPowerdownCtrlStatTmp);


//  DEBUG @@@
// Count comm errors rather than stopping for them.

    // Keep trying until all subsystems ready; stop on comm error or timeout
    while (  /* @@@  !status
            && */(ac97MrPowerdownCtrlStatTmp 
                     != ctxP->mixerRegsSpecialMasksP->mr0x26EaAudioReadyVal)
            &&  msTimeout)
    {
        //@@@ DEBUG
        DM_WaitMs (10);
        msTimeout--;
        status = XsAc97CtrlReadCodecReg ( ctxP->audioIdForController,
                                          AC97_MR_POWERDOWN_CTRL_STAT, 
                                         &ac97MrPowerdownCtrlStatTmp);
//  DEBUG @@@
        if (status)
        {
            commErrs++;
        }
    }

//  DEBUG @@@
//     LOGERROR (ctxP->loggedError, ERR_L_AC97, 
//                       ERR_S_AC97_PWR_ON_AUD_SUB, 0, 0, msTimeout, commErrs)
        
    if (!status && !msTimeout)
    {
        // No comm errors, but we timed out waiting for the subsystems
        // There are lots of timeouts possible while powering up.  The 
        //  identification of which type is made by tracing the error log
        //  and, in this case, if the first parameter is 2 instead of 1.

        status = ERR_T_TIMEOUT;
        errLoc = 2;                     //  Timeout waiting for readiness
    }


    if (status)
    {
        LOGERROR (ctxP->loggedError, ERR_L_AC97, 
                       ERR_S_AC97_PWR_ON_AUD_SUB, status, errLoc, 0, 0)
    }

    return (status);

} // Ac97PowerOnAudioSubsystems ()


UINT32 Ac97ShutdownAudioSubsystems (Ac97ContextT* ctxP)
{
    // Shut down audio subsystems, but leave the AC link and other global
    //   systems running.
    // Max shut down of audio systems without going into warm or cold reset.
    // Shut down AC97 audio services provided by controller and main 
    //   processor GPIOs. This includes unregistering AC97 and GPIO interrupts,
    //   returning descriptors and other allocated memory, setting the context
    //   flags to reflect the state, returning GPIO channels, etc.
    // Does not change local record of codec settings, nor does it change
    //   settings in the mixer registers other than to shut down the targeted
    //   audio subsystems.

    // Not supporting power modes for initial release, so stub actual power
    //  controls.
      // @@@Stub: still need to release buffers and clean up GPIO
    return (ERR_NONE);

} // Ac97ShutdownAudioSubsystems ()


/**************** Modem support utilities: stubs only  ******************/

void Ac97SwRestoreDefaultsModem (Ac97ContextT* ctxP)
    // Only restores the modem "current values" record to the default settings.
    // To place them into hardware, Ac97HwReconfigModem() must be used.
{
      // @@@Stub
} //  Ac97SwRestoreDefaultsModem()
 
UINT32 Ac97HwReconfigModem (Ac97ContextT* ctxP) // Not implemented; stub only
{
    // Does not permit a change in the resources used (controller comms, codec)
    // Does not change most recently set values of 
    // Verify codec readiness (not initial setup, can't assume this)
    // Enable all modem codec subsystems
    // Verify modem codec subsystem readiness
    // Set modem state variable flag fields.
    // Return timeout error if subsystem readiness fails after n msec.
      // @@@Stub
    return (ERR_NONE);

} //  Ac97HwReconfigModem()

UINT32 Ac97ShutdownModemSubsystems (Ac97ContextT* ctxP) // Not implemented; stub only
{
    // Shut down modem subsystems, but leave the AC link and other global
    //   systems running.
    // Shut down AC97 modem services provided by controller and main 
    //   processor GPIOs. This includes unregistering AC97 and GPIO interrupts,
    //   returning descriptors and other allocated memory, setting the context
    //   flags to reflect the state, returning GPIO channels, etc.
    // Does not change local record of codec settings, nor does it change
    //   settings in the mixer registers other than to shut down the targeted
    //   modem subsystems.
      // @@@Stub
    return (ERR_NONE);

} //  Ac97ShutdownModemSubsystems()


/**************** General AC97 codec support utilities ******************/

// Note: The compiler seems to truncate the parameter to a byte because
//    of the enum type.  This limits the effectiveness of range-checking.
// @@@ Consider changing the parameter to an int.
/*
UINT32 Ac97CheckRegId (AC97MixerRegisterIdT registerIdToCheck)
{
    UINT32 status = ERR_NONE;

    // Register must be in range and also even.  No odd registers supported
    //  by the spec.

    if ( (registerIdToCheck < 0 ) || 
         (registerIdToCheck > AC97_MR_MAX)|| 
         (registerIdToCheck & 1) )
    {
        status = ERR_T_ILLPARAM;
    }
    return (status);
    
} // Ac97CheckRegId ()

*/
/*
*******************************************************************************
*******************************************************************************
    Mixer Register Access functions
*******************************************************************************
*******************************************************************************
*/

UINT32 Ac97GetVendorIDandRev (Ac97ContextT* ctxP, 
                              PCHAR         vendorIdStringP, 
                              PINT          vendorRevNumberP)
{
    // Provides the vendor string and rev number info found in 
    //      mixer regs 0x7C + 0x7E
    // Some codecs provide duplicate or additional information elsewhere, but
    //      this is the information from the standard location

    UINT32 status; 
    UINT32 tmpMr7C;
    UINT32 tmpMr7E;

    // Get contents of Vendor ID 1 Mixer Register.  Use Audio Codec
    //  selector for convenience.
    status = XsAc97CtrlReadCodecReg  (ctxP->audioIdForController,
                                       AC97_MR_VENDOR_ID1, 
                                       &tmpMr7C);

    // Now get info from Vendor ID 2 reg.  Don't differentiate error locations
    //  if problem.
    if (!status)
    {
        status = XsAc97CtrlReadCodecReg  (ctxP->audioIdForController,
                                           AC97_MR_VENDOR_ID2,
                                           &tmpMr7E);
    }

    if (status)
    {
        LOGERROR (ctxP->loggedError, ERR_L_AC97, 
                       ERR_S_AC97_GET_MR_VENDOR_ID, status, 0, 0, 0)
    }
    else
    {
        *vendorIdStringP++ = (CHAR) (tmpMr7C >> 8) & 0xFF; // first char of ID
        *vendorIdStringP++ = (CHAR)  tmpMr7C & 0xFF;
        *vendorIdStringP++ = (CHAR) (tmpMr7E >> 8) & 0xFF;
        *vendorIdStringP   = (CHAR) '\0';

        *vendorRevNumberP  = (INT)   tmpMr7E & 0xFF;
    }
    
    return (status);

} // Ac97GetVendorIDandRev ()


UINT32 Ac97GetAnyMixerRegister (Ac97ContextT*        ctxP, 
                                AC97MixerRegisterIdT targetReg, 
                                PUINT16              curRegValueP)
{
    UINT32 status ;
    UINT32 regValTmp;

    // Assume that there is no real difference between audio and modem
    //  interface mappings in AC97 controller.  Just use the audio Id.
    // If there's really a difference, this function becomes more complex.
    status = XsAc97CtrlReadCodecReg (ctxP->audioIdForController, 
                                     targetReg,
                                     &regValTmp);
    if (status)
    {
        LOGERROR (ctxP->loggedError, ERR_L_AC97, 
                       ERR_S_AC97_GET_ANY_MIX_REG, status, targetReg, 0, 0)
    }
    else
    {
        // Really only 16 bits in a mixer register, although the HW interface
        //  returns 32 with upper 16 undefined.
        *curRegValueP = (UINT16) (regValTmp &  0xFFFF);
        // Record actual value from mixer register.
        // Divide by two for index because only even registers are used, 
        //  and structures assume that.
        ctxP->mixerRegsCurrVals[targetReg/2] = *curRegValueP;
    }
    return (status);

} // Ac97GetAnyMixerRegister ()


// This is a low-level routine.  No read-validation of write.  Such error 
//  checking is left to the calling routine.
// Universal access: "back door": Use with extreme caution!
/*
UINT32 Ac97SetAnyMixerRegister (Ac97ContextT*        ctxP, 
                                AC97MixerRegisterIdT targetReg, 
                                UINT16               newValue)
{
    UINT32 status ;

    // Assume that there is no real difference between audio and modem
    //  interface mappings in AC97 controller.  Just use the audio Id.
    // If there's really a difference, this function becomes more complex.
    status = XsAc97CtrlWriteCodecReg (ctxP->audioIdForController, 
                                      targetReg,
                                      newValue);
    if (status)
    {
        LOGERROR (ctxP->loggedError, ERR_L_AC97, 
                       ERR_S_AC97_SET_ANY_MIX_REG, status, targetReg, 0, 0)
        DM_CwDbgPrintf(DM_CW_AC97_CODEC,  
            "Err in Ac97SetAnyMixerRegister: %08x, reg %02X",status,targetReg);
    }
    else
    {

⌨️ 快捷键说明

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