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

📄 wmcontrollink.c

📁 WM9713 audio codec driver for WinCE 5.0
💻 C
📖 第 1 页 / 共 4 页
字号:
    {
        status = WMS_NO_SUPPORTED_DEVICE;
        goto done;
    }

    /*
     * Check to make sure that the global registers are available to use.
     */
    v_pWMData = pDeviceContext->v_pWMData;

    if ( !v_pWMData )
    {
        status = WMS_RESOURCE_NULL;
        goto done;
    }

    /*
     * Make sure non-shadowed registers are initialised to unset.
     */
    for ( shadow = 0; shadow < WM_MAX_SHADOW_REGS; shadow++ )
    {
        v_pWMData->shadowRegisters[ shadow ] = WM_REGISTER_UNSET;
    }
    
    /*
     * Run through the registers.
     */
    for ( shadow = 0; shadow < pChipDef->nShadowedRegisters; shadow++ )
    {
        /* Set the default value in the shadow register */
        WM_REGTYPE          reg = pChipDef->pShadowedRegisters[ shadow ].reg;
        WM_REGTYPE          regNum;
        unsigned short      regOffset;
        
        /*
         * Work out our array index.
         */
        regOffset = pChipDef->regOffset;
        regNum = reg / regOffset;
        WM_ASSERT( hDevice, regNum < WM_MAX_SHADOW_REGS );
        
        v_pWMData->shadowRegisters[ regNum ] =
            pChipDef->pShadowedRegisters[ shadow ].defaultValue;
    }

done:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    private_WriteShadowRegister
 *
 * Writes the value to the given shadow register.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *      reg                 register to write to
 *      value               value to write
 *
 * Returns:     WMSTATUS
 *                          WMS_RETURN_TRUE if value to write is the same as 
 *                          the value that was previously shadowed.
 *                          WMS_RETURN_FALSE if value to write is _not_ the 
 *                          same as the value that was previously shadowed.
 *                          See WMStatus.h for all other return values.
 *---------------------------------------------------------------------------*/
static WMSTATUS private_WriteShadowRegister( WM_DEVICE_HANDLE   hDevice,
                                             WM_REGTYPE         reg,
                                             WM_REGVAL          value
                                           )
{
    unsigned int            shadow;
    const WM_CHIPDEF        *pChipDef       = NULL;
    WM_DEVICE_CONTEXT       *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
    volatile WM_SHARED_DATA *v_pWMData;
    WMSTATUS                status          = WMS_UNABLE_TO_SHADOW;
    unsigned short          regOffset;
    WM_REGTYPE              regNum;

    WM_ASSERT( hDevice, NULL != pDeviceContext );
    WM_ASSERT( hDevice, NULL != pDeviceContext->v_pWMData );

    /*
     * Look up our chipdef.
     */
    pChipDef = WMGetChipDef( hDevice );
    if ( !pChipDef )
    {
        status = WMS_NO_SUPPORTED_DEVICE;
        goto done;
    }
    
    /*
     * Check to make sure that the global registers are available to use.
     */
    v_pWMData = pDeviceContext->v_pWMData;

    if ( !v_pWMData )
    {
        status = WMS_RESOURCE_NULL;
        goto done;
    }

    /*
     * Work out our array index.
     */
    regOffset = pChipDef->regOffset;
    regNum = reg / regOffset;
    if ( regNum >= WM_MAX_SHADOW_REGS )
	{
		status = WMS_REG_NOT_PRESENT;
		goto done;
	}

    /*
     * Run through the registers.
     */
    for ( shadow = 0; shadow < pChipDef->nShadowedRegisters; shadow++ )
    {
        /* Try and find a match for the register */
        if ( pChipDef->pShadowedRegisters[ shadow ].reg == reg )
        {
            /*
             * Assume we didn't need to change the value.
             */
            status = WMS_RETURN_TRUE;

            /*
             * The WM8731 family have the concept of "BOTH", which writes
             * the same value to both channels, so we need to do some
             * special handling to make sure our shadow values are correct.
             */
            if ( WM_HAS_BOTH( hDevice ) )
            {
                WM_REGTYPE signalRegNum;

#if WM_BOTH_QUICK_AND_DIRTY
                WM_ASSERT( hDevice, IS_WM8731_FAMILY( hDevice ) );
                if ( value & WM8731_VOLUME_BOTH )
                {
                    switch ( reg )
                    {
                        case WM8731_LEFT_INPUT_VOLUME:
                            signalRegNum = WM8731_RIGHT_INPUT_VOLUME;
                            break;
                        case WM8731_RIGHT_INPUT_VOLUME:
                            signalRegNum = WM8731_LEFT_INPUT_VOLUME;
                            break;
                        case WM8731_LEFT_HEADPHONE_VOLUME:
                            signalRegNum = WM8731_RIGHT_HEADPHONE_VOLUME;
                            break;
                        case WM8731_RIGHT_HEADPHONE_VOLUME:
                            signalRegNum = WM8731_LEFT_HEADPHONE_VOLUME;
                            break;
                        default:
                            signalRegNum = WM_REG_INVALID;
                    }

                    if ( WM_REG_INVALID != signalRegNum )
                    {
                        value &= ~WM8731_VOLUME_BOTH;

                        /*
                         * Check to see if the previous shadowed value is the
                         * same as the value we have been given.  If not, update
                         * it and remember we need to do the write to the device.
                         */
                        if ( v_pWMData->shadowRegisters[ signalRegNum ] != value )
                        {
                            v_pWMData->shadowRegisters[ signalRegNum ] = value;
                            status = WMS_RETURN_FALSE;
                            WM_REG_TRACE( hDevice, (
                                          "==> WMWrite:   R%02Xh := 0x%04X    (updated via BOTH)",
                                          signalRegNum,
                                          value
                                        ));
                        }
                    }
                }

#else /* WM_BOTH_QUICK_AND_DIRTY */

                unsigned int    nSignal;
                WM_AUDIO_SIGNAL signal = WM_AUDIO_SIGNAL_UNKNOWN;

                /* Check for a signal with this register */
                for ( nSignal = 0; nSignal < pChipDef->signalCount; nSignal++ )
                {
                    const WM_SIGNAL_DETAILS *pSignalDetails;
                    pSignalDetails = &pChipDef->pSignalDetails[ nSignal ];
                    if ( pSignalDetails->reg == reg &&
                         pSignalDetails->flags & WM_SIG_HAS_BOTH &&
                         value & pSignalDetails->specialFlag
                       )
                    {
                        signal = pSignalDetails->signal;
                        value &= ~pSignalDetails->specialFlag;
                        break;
                    }
                }

                /* 
                 * If there was a match, run through the signals again,
                 * looking for matching registers and update them too.
                 */
                if ( WM_AUDIO_SIGNAL_UNKNOWN != signal )
                {
                    for ( nSignal = 0; nSignal < pChipDef->signalCount; nSignal++ )
                    {
                        const WM_SIGNAL_DETAILS *pSignalDetails;
                        pSignalDetails = &pChipDef->pSignalDetails[ nSignal ];
                        if ( pSignalDetails->signal == signal &&
                             pSignalDetails->reg != reg
                           )
                        {
                            /*
                             * Check to see if the previous shadowed value is the
                             * same as the value we have been given.  If not, update
                             * it and remember we need to do the write to the device.
                             */
                            signalRegNum = pSignalDetails->reg / regOffset;
                            if ( v_pWMData->shadowRegisters[ signalRegNum ] != value )
                            {
                                v_pWMData->shadowRegisters[ signalRegNum ] = value;
                                status = WMS_RETURN_FALSE;
                                WM_REG_TRACE( hDevice, (
                                              "==> WMWrite:   R%02Xh := 0x%04X    (updated via BOTH)",
                                              pSignalDetails->reg,
                                              value
                                            ));
                            }
                        }
                    }
                }
#endif  /* WM_BOTH_QUICK_AND_DIRTY*/
            }

            /*
             * Check to see if the previous shadowed value is the
             * same as the value we have been given.  If not, update
             * it and remember we need to do the write to the device.
             */
            if ( v_pWMData->shadowRegisters[ regNum ] != value )
            {
                /* Write the new value to the shadow register */
                v_pWMData->shadowRegisters[ regNum ] = value;
                status = WMS_RETURN_FALSE;
            }
            
            goto done;
        }
    } 

done:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    private_ReadShadowRegister
 *
 * Reads the value from the given shadow register.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *      reg                 register to read from
 *      pValue              variable to receive value
 *
 * Returns:     WMSTATUS
 *      See WMStatus.h.
 *---------------------------------------------------------------------------*/
static WMSTATUS private_ReadShadowRegister( WM_DEVICE_HANDLE    hDevice,
                                            WM_REGTYPE          reg,
                                            WM_REGVAL           *pValue
                                          )
{
    unsigned int            shadow;
    const WM_CHIPDEF        *pChipDef       = NULL;
    WM_DEVICE_CONTEXT       *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
    volatile WM_SHARED_DATA *v_pWMData      = pDeviceContext->v_pWMData;
    WMSTATUS                status          = WMS_UNABLE_TO_SHADOW;
    WM_REGTYPE              regNum;
    unsigned short          regOffset;

    WM_ASSERT( hDevice, NULL != pDeviceContext );
    WM_ASSERT( hDevice, NULL != pDeviceContext->v_pWMData );

    /*
     * Look up our chipdef.
     */
    pChipDef = WMGetChipDef( hDevice );
    if ( !pChipDef )
    {
        status = WMS_NO_SUPPORTED_DEVICE;
        goto done;
    }
    
    /*
     * Check to make sure that the global registers are available to use.
     */
    if ( !v_pWMData )
    {
        status = WMS_RESOURCE_NULL;
        goto done;
    }

    /*
     * Work out our array index.
     */
    regOffset = pChipDef->regOffset;
    regNum = reg / regOffset;
    if ( regNum >= WM_MAX_SHADOW_REGS )
	{
		status = WMS_REG_NOT_PRESENT;
		goto done;
	}

    /*
     * Run through the registers.
     */
    for ( shadow = 0; shadow < pChipDef->nShadowedRegisters; shadow++ )
    {
        /* Try and find a match for the register */
        if ( pChipDef->pShadowedRegisters[ shadow ].reg == reg )
        {
            /* Read the value from the shadow register */
            *pValue = v_pWMData->shadowRegisters[ regNum ];

            /*
             * If I2S device does not have a default value 
             * for this register report the error
             */
            if ( WM_IS_I2S( hDevice ) && (WM_REGISTER_UNSET == *pValue) )
            {
                status = WMS_SHADOW_UNINTIALISED;
            }
            else
            {
                status = WMS_SUCCESS;
            }

            goto done;
        }
    } 

done:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    private_ReadDefaulyShadowRegister
 *
 * Reads the default value from the given shadow register.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *      reg                 register to read from
 *      pValue              variable to receive value
 *
 * Returns:     WMSTATUS
 *      See WMStatus.h.
 *---------------------------------------------------------------------------*/
static WMSTATUS private_ReadDefaultShadowRegister( WM_DEVICE_HANDLE    hDevice,
                                                   WM_REGTYPE          reg,
                                                   WM_REGVAL           *pValue
                                                 )
{
    unsigned int            shadow;
    const WM_CHIPDEF        *pChipDef       = NULL;
    WMSTATUS                status          = WMS_SHADOW_UNINTIALISED;
    WM_REGTYPE              regNum;
    unsigned short          regOffset;

    /*
     * Look up our chipdef.
     */
    pChipDef = WMGetChipDef( hDevice );
    if ( !pChipDef )
    {
        status = WMS_NO_SUPPORTED_DEVICE;
        goto done;
    }

    /*
     * Work out our array index.
     */
    regOffset = pChipDef->regOffset;
    regNum = reg / regOffset;
    if ( regNum >= WM_MAX_SHADOW_REGS )
	{
		status = WMS_REG_NOT_PRESENT;
		goto done;
	}

    /*
     * Run through the registers.
     */
    for ( shadow = 0; shadow < pChipDef->nShadowedRegisters; shadow++ )
    {
        /* Try and find a match for the register */
        if ( pChipDef->pShadowedRegisters[ shadow ].reg == reg )
        {
            /* Read the default value from the shadow register */
            *pValue = pChipDef->pShadowedRegisters[ shadow ].defaultValue;

            /*
             * If I2S device does not have a default value 
             * for this register report the error
             */
            if ( WM_IS_I2S( hDevice ) && (WM_REGISTER_UNSET == *pValue) )
            {
                status = WMS_SHADOW_UNINTIALISED;
            }
            else
            {
                status = WMS_SUCCESS;
            }

            goto done;
        }
    } 

done:
    return status;
}
#endif/* WM_USE_SHADOW_REGISTERS */

/*------------------------------ END OF FILE ---------------------------------*/

⌨️ 快捷键说明

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