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

📄 wmcontrollink.c

📁 WM9713 audio codec driver for WinCE 5.0
💻 C
📖 第 1 页 / 共 4 页
字号:
    WM_BOOL				isPhysicalRead = FALSE;
    WM_BOOL				isDefaultReg = FALSE;

    /* Make sure we are reading from a valid register */
    if ( !private_IsValidRegister( hDevice, reg ) )
    {
        status = WMS_REG_NOT_PRESENT;
        goto error0;
    }

    /* Protect ourselves */
    if ( !WMLockGlobalData( hDevice ) )
    {
        status = WMS_LOCK_TIMED_OUT;
        goto error0;
    }
    if ( !WMLockLink( hDevice ) )
    {
        status = WMS_LOCK_TIMED_OUT;
        goto error1;
    }

    /* Check the link's up */
#if WM_CACHE_POWER_STATE
    {
        WM_DEVICE_CONTEXT   *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );

        if ( pDeviceContext->v_pWMData &&
             !( pDeviceContext->v_pWMData->WmPower & WM_POWER_LINK )
             )
        {
            status = WMS_ACLINK_NOT_ACTIVE;
            goto error2;
        }
    }
#endif

#if WM_USE_SHADOW_REGISTERS
    /* Get it from the shadow register if available */
    status = private_ReadShadowRegister( hDevice, reg, &value );
    if ( WM_SUCCESS( status ) )
    {
        goto done;
    }
#endif /* WM_USE_SHADOW_REGISTERS */

    /* We need to go to the register itself */
    platformStatus = WMPlatformRead( hDevice, reg, &value );

    isPhysicalRead = TRUE;

    /* 
     * Check to see if the error was due to a uninitialised read-only register:
     * If so report this back to the caller.
     */
    if ( ( WMS_SHADOW_UNINTIALISED == status ) && WMS_UNSUPPORTED == platformStatus )
    {
        goto error2;
    }

    /* We are only interested in the status from WMPlatformRead now */
    status = platformStatus;
    if ( WM_ERROR( status ) && ( WMS_UNSUPPORTED != status ) )
    {
        goto error2;
    }


#if WM_USE_SHADOW_REGISTERS
done:
#endif /* WM_USE_SHADOW_REGISTERS */

    *pValue = value;

    /* Let other threads in again */
    WMUnlockLink( hDevice );
    WMUnlockGlobalData( hDevice );

#if WM_USE_SHADOW_REGISTERS
    if( WMS_UNSUPPORTED != status )
    {
        isDefaultReg = WMIsDefaultRegValue( hDevice, reg, value );
    }
#endif /* WM_USE_SHADOW_REGISTERS */


    WM_REG_TRACE( hDevice, (
                  "==> WMRead:    R%02Xh == 0x%04X    %s %s",
                  reg,
                  value,
                  isPhysicalRead ? WMStatusText( status ) : "shadowed",
                  isDefaultReg ? "** DEFAULT **" : ""
                ));

    return status;

    /*
     * Error handling.
     */
error2:
    WMUnlockLink( hDevice );
    
error1:
    /* Let other threads in again */
    WMUnlockGlobalData( hDevice );

error0:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    WMWrite
 *
 * Writes the value to the given register.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *      reg                 register to write to
 *      value               value to write
 *
 * Returns:     WMSTATUS
 *      See WMStatus.h.
 *---------------------------------------------------------------------------*/
WMSTATUS WMWrite( WM_DEVICE_HANDLE hDevice,
                  WM_REGTYPE reg,
                  WM_REGVAL value
                )
{
    WMSTATUS            status = WMS_SUCCESS;
    const WM_CHIPDEF    *pChipDef;
    WM_BOOL             isReset;
	WM_BOOL				isPhysicalWrite = TRUE;

    /* Make sure we are writing to a valid register */
    if ( !private_IsValidRegister( hDevice, reg ) )
    {
        /*
         * We need to allow WM_I2S_INIT_TEST_REGISTER for I2S devices
         * even though it does not exist.
         */
        if ( !(WM_IS_I2S( hDevice ) && WM_I2S_INIT_TEST_REGISTER == reg) )
        {
            status = WMS_REG_NOT_PRESENT;
            goto error0;
        }
    }

    /* Protect ourselves */
    if ( !WMLockGlobalData( hDevice ) )
    {
        status = WMS_LOCK_TIMED_OUT;
        goto error0;
    }
    if ( !WMLockLink( hDevice ) )
    {
        status = WMS_LOCK_TIMED_OUT;
        goto error1;
    }

    /* Check the link's up */
#if WM_CACHE_POWER_STATE
    {
        WM_DEVICE_CONTEXT   *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );

        if ( pDeviceContext->v_pWMData &&
             !( pDeviceContext->v_pWMData->WmPower & WM_POWER_LINK )
             )
        {
            status = WMS_ACLINK_NOT_ACTIVE;
            goto error2;
        }
    }
#endif

    pChipDef = WMGetChipDef( hDevice );
    if ( !pChipDef )
    {
        status = WMS_NO_SUPPORTED_DEVICE;
        goto error2;

    }

    /*
     * Work out if it's a reset - we need to do various extra tasks if so.
     */
    isReset = ( pChipDef->resetReg == reg );
    
#if WM_USE_SHADOW_REGISTERS
    /* 
     * Save it to the shadow register if appropriate.
     * If this is the reset register then we need to restore
     * default values to the shadow registers.
     * If the return value is WMS_RETURN_TRUE then the value
     * to be written is the value that is currently on the
     * device so we do not need to do the physical write.
     * For all other return codes we must write to the device.
     */
    if ( isReset )
    {
        status = WMS_SUCCESS;
    }
    else
    {
        status = private_WriteShadowRegister( hDevice, reg, value );
    }
#if !WM_DEBUG_WRITE_THROUGH
    if ( WMS_RETURN_TRUE == status && WM_I2S_INIT_TEST_REGISTER != reg )
    {
        /*
         * The register already held the value we were setting, so
         * we won't actually do the write.
         */
		isPhysicalWrite = FALSE;
        status = WMS_SUCCESS;
    }
    else
#endif /* !WM_DEBUG_WRITE_THROUGH */
#endif /* WM_USE_SHADOW_REGISTERS */
    {
        /* Now do the write */
        status = WMPlatformWrite( hDevice, reg, value );
        if ( WM_ERROR( status ) )
        {
            goto error2;
        }
        
        if ( isReset )
        {
            /*
             * Now update our state to match the reset.
             */
            private_ResetState( hDevice );
        }
    }

    /* Let other threads in again */
    WMUnlockLink( hDevice );
    WMUnlockGlobalData( hDevice );

    WM_REG_TRACE( hDevice, (
                  "==> WMWrite:   R%02Xh := 0x%04X    %s %s",
                  reg,
                  value,
                  isPhysicalWrite ? WMStatusText( status ) : "not changed",
                  isReset ? "** RESET **" : ""
                ));

    return status;

    /*
     * Error handling.
     */
error2:
    WMUnlockLink( hDevice );
    
error1:
    /* Let other threads in again */
    WMUnlockGlobalData( hDevice );

error0:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    WMSetField
 *
 * Sets the given field of the given register to the given value.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *        reg                 register to write to
 *      value               value to write
 *      mask                mask of field to update
 *
 * Returns:     WMSTATUS
 *     See WMStatus.h.
 *---------------------------------------------------------------------------*/
WMSTATUS WMSetField( WM_DEVICE_HANDLE   hDevice,
                     WM_REGTYPE         reg,
                     WM_REGVAL          value,
                     WM_REGVAL          mask
                   )
{
    WMSTATUS    status;
    WM_REGVAL regVal;

    /* Get the current value */
    status = WMRead( hDevice, reg, &regVal );
    if ( WM_ERROR( status ) )
    {
        goto end;
    }

    /* Clear the field we're wanting to update */
    regVal &= ~mask;

    /* Set it to our new value */
    regVal |= (value & mask);

    /* And write it back again */
    status = WMWrite( hDevice, reg, regVal );

end:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    WMClearField
 *
 * Sets the given field of the given register to 0.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *      reg                 register to write to
 *      mask                mask of field to update
 *
 * Returns:     WMSTATUS
 *     See WMStatus.h.
 *---------------------------------------------------------------------------*/
WMSTATUS WMClearField( WM_DEVICE_HANDLE hDevice,
                       WM_REGTYPE reg,
                       WM_REGVAL mask
                     )
{
    return WMSetField( hDevice, reg, 0, mask );
}

/*-----------------------------------------------------------------------------
 * Function:    WMReset
 *
 * Forces a cold reset of a Wolfson device.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *
 * Returns:     WMSTATUS
 *      See WMStatus.h
 *---------------------------------------------------------------------------*/
WMSTATUS WMReset( WM_DEVICE_HANDLE hDevice )
{
    WMSTATUS            status;

    /*
     * Do a cold reset.
     */
    status = WMPlatformReset( hDevice );
    
    WM_REG_TRACE( hDevice, (
                  "==> WMReset:                     %s",
                  WMStatusText( status )
                ));
    if ( WM_ERROR( status ) )
    {
        goto error0;
    }

    /*
     * Now update our state to match.
     */
    private_ResetState( hDevice );
    
    /*
     * We're done.
     */
    return WMS_SUCCESS;
    
    /*
     * Error cleanup.
     */
error0:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    private_ResetState
 *
 * Resets our global state to default values.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *
 * Returns:     void
 *---------------------------------------------------------------------------*/
static void private_ResetState( WM_DEVICE_HANDLE hDevice )
{
    WM_DEVICE_CONTEXT   *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
    const WM_CHIPDEF    *pChipDef;
    
    if ( pDeviceContext->v_pWMData )
    {
        /*
         * Lock our global data.
         */
        if ( WMLockGlobalData( hDevice ) )
        {
            /*
             * Look up our chipdef.
             */
            pChipDef = WMGetChipDef( hDevice );
            WM_ASSERT( hDevice, pChipDef );
            if ( !pChipDef )
            {
                goto finish;
            }
            
#if WM_CACHE_POWER_STATE
            /*
             * The power is back to default.
             */
            pDeviceContext->v_pWMData->WmPower = pChipDef->defaultPower;

            /*
             * And our cached power register values are no longer valid.
             */
            pDeviceContext->v_pWMData->flags &= ~(WM_POWERREG_VALID);
#endif

#if WM_USE_SHADOW_REGISTERS
            /*
             * Set our shadow registers to their default values.
             */
            private_InitShadowRegisters( hDevice );
#endif
        
#if WM_AUDIO
            /* Clear the flags */
            pDeviceContext->v_pWMData->audioData.flags = 0;
        
            /* Mute everything */
            pDeviceContext->v_pWMData->audioData.mutes = 0xFFFF;

⌨️ 快捷键说明

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