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

📄 wmaudio.c

📁 WM9713 audio codec driver for WinCE 5.0
💻 C
📖 第 1 页 / 共 3 页
字号:
 /*-----------------------------------------------------------------------------
 * Copyright (c) Wolfson Microelectronics plc.  All rights reserved.
 *
 * This software as well as any related documentation is furnished under 
 * license and may only be used or copied in accordance with the terms of the 
 * license. The information in this file is furnished for informational use 
 * only, is subject to change without notice, and should not be construed as 
 * a commitment by Wolfson Microelectronics plc. Wolfson Microelectronics plc
 * assumes no responsibility or liability for any errors or inaccuracies that
 * may appear in this document or any software that may be provided in
 * association with this document. 
 *
 * Except as permitted by such license, no part of this document may be 
 * reproduced, stored in a retrieval system, or transmitted in any form or by 
 * any means without the express written consent of Wolfson Microelectronics plc. 
 *
 * $Id: WMAudio.c 2364 2005-11-04 15:56:03Z ib $
 *
 * This file contains platform-independent routines for controlling the audio
 * operation on Wolfson codecs.
 *
 * Warning:
 *  This driver is specifically written for Wolfson Codecs. It is not a 
 *  general CODEC device driver.
 *
 * -----------------------------------------------------------------------------*/

/*
 * Include files
 */
#include "WMCommon.h"
#include "WMDevice.h"
#include "WMGlobals.h"
#include "WMControlLink.h"
#include "WMPlatformI2S.h"
#include "WM8753Audio.h"
#include "WMAudio.h"
#include "WMDMA.h"
#include "WMVoice.h"
#include "WMPower.h"

#if WM_TESTING
#   include "Test/WMTestCommon.h"
#   include "Test/WMAudioTests.h"
#   include "Test/WMPlatformTests.h"
#endif

/*
 * Only build this if we're doing Audio support.
 */
#if WM_AUDIO

/*
 * Global definitions
 */

/*
 * Private data
 */
 
/*
 * Function prototypes
 */

/*-----------------------------------------------------------------------------
 * Function:    WMAudioInit
 *
 * Initialises the Audio functionality.
 *
 * Parameters:
 *      hDevice      handle to the device (from WMOpenDevice)
 *
 * Returns:     WMSTATUS
 *		See WMStatus.h
 *---------------------------------------------------------------------------*/
WMSTATUS WMAudioInit( WM_DEVICE_HANDLE hDevice )
{
    WMSTATUS            status;
    WM_DEVICE_CONTEXT   *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );

    /* Initialise the I2S interface */
#if WM_I2S
    if ( WM_IS_I2S( hDevice ) )
    {
        status = WMPlatformI2SInit( hDevice );
        if ( WM_ERROR( status ) )
        {
            goto error0;
        }
    }
#endif

#if WM_TESTING && WM_AUTOTEST_AUDIO
    /*
     * Run audio tests, actually generating some sound.
     * NOTE: This hits the hardware directly so it must
     *       be run before we initialise the DMA.
     */
	WMTEST_RUN( WMTestPlatformAudio( hDevice ) );
#endif

#if WM_AUDIO_STREAM
    /* Initialise the DMA */
    status = WMDMAInit( hDevice );
    if ( WM_ERROR( status ) )
    {
        goto error1;
    }
#endif

	/*
	 * Take the mutex.
	 */
	if ( !WMLockGlobalData( hDevice ) )
	{
		status = WMS_LOCK_TIMED_OUT;
		goto error2;
	}

	/*
	 * Initialise our global data.
	 */
	if ( pDeviceContext->v_pWMData )
	{
		/* Clear the flags */
		pDeviceContext->v_pWMData->audioData.flags = 0;
    
		/* Mute everything */
		pDeviceContext->v_pWMData->audioData.mutes = 0xFFFF;
	}

    /*
     * Set up our default streams.
     */
	if ( WM_STREAM_INVALID_STREAM == pDeviceContext->defaultOutputStream )
    {
        if ( WM_IS_DAC_SUPPORTED( hDevice ) )
		{
			pDeviceContext->defaultOutputStream = WM_STREAM_HIFI_OUT;
			/*
			 * Check the streams exist.
			 */
			WM_ASSERT( hDevice,
					( WMAUDIO_INVALID_CHANNEL !=
					 _WMAudioStreamToChannel( hDevice,
											  pDeviceContext->defaultOutputStream
											) )
					);
		}
        if ( WM_IS_ADC_SUPPORTED( hDevice ) )
		{
#if WM_VOICE && WM8753_FAMILY
			if ( IS_WM8753_FAMILY( hDevice ) )
			{
				pDeviceContext->defaultInputStream = WM_STREAM_VOICE_IN;
			}
			else
#endif /* WM_VOICE && WM8753_FAMILY */
			{
				pDeviceContext->defaultInputStream = WM_STREAM_HIFI_IN;
			}

			/*
			 * Check the streams exist.
			 */
			WM_ASSERT( hDevice,
					( WMAUDIO_INVALID_CHANNEL !=
					 _WMAudioStreamToChannel( hDevice,
											  pDeviceContext->defaultInputStream
											) )
					);
		}
    }
    
	/* We're done */
	WMUnlockGlobalData( hDevice );

#if WM_TESTING && WM_AUTOTEST_AUDIO
    /*
     * Run audio tests, actually generating some sound,
     * using the library this time.
     */
    WMTEST_RUN( WMTestAudio( hDevice ) );
#endif

    return WMS_SUCCESS;

    /*
     * Error cleanup.
     */

error2:
#if WM_AUDIO_STREAM   
    WMDMAShutdown( hDevice );

error1:
#endif
#if WM_I2S
    if ( WM_IS_I2S( hDevice ) )
    {
        WMPlatformI2SShutdown( hDevice );
    }

error0:
#endif
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    WMAudioShutdown
 *
 * Shuts down the Audio functionality.
 *
 * Parameters:
 *      (none)
 *
 * Returns:     void
 *---------------------------------------------------------------------------*/
void WMAudioShutdown( WM_DEVICE_HANDLE hDevice )
{
#if WM_AUDIO_STREAM   
    WMDMAShutdown( hDevice );
#endif
	WMLinkShutdown( hDevice, WM_DRIVER_AUDIO );
}

/*-----------------------------------------------------------------------------
 * Function:    WMAudioPowerUp
 *
 * Called to power up the Audio-specific sections of the chip.
 *
 * Parameters:
 *      hDevice         handle to the device (from WMOpenDevice)
 *      powerSections   The sections to power up.
 *
 * Returns:     WMSTATUS
 *		See WMStatus.h.
 *---------------------------------------------------------------------------*/
WMSTATUS WMAudioPowerUp( WM_DEVICE_HANDLE   hDevice, 
                         WM_POWERFLAG       powerSections
                       )
{
    WMSTATUS status;

    /* Power up the relevant sections of the chip */
    status = WMPowerUp( hDevice, WM_DRIVER_AUDIO, powerSections );
    if ( WM_ERROR( status ) && WMS_UNSUPPORTED != status )
    {
        goto error;
    }

    return WMS_SUCCESS;

error:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    WMAudioPowerDown
 *
 * Called to power down the audio-specific sections of the chip.  Note if the
 * sections are still in use by another driver they will not actually be
 * powered down.
 *
 * Parameters:
 *      hDevice         handle to the device (from WMOpenDevice)
 *      powerSections   The sections to power down.
 *
 * Returns:     WMSTATUS
 *		See WMStatus.h.
 *---------------------------------------------------------------------------*/
WMSTATUS WMAudioPowerDown( WM_DEVICE_HANDLE hDevice,
                           WM_POWERFLAG     powerSections
                         )
{
    WMSTATUS status;

    /* Power down our section of the chip */
    status = WMPowerDown( hDevice, WM_DRIVER_AUDIO, powerSections );
    if ( WM_ERROR( status ) && WMS_UNSUPPORTED != status )
    {
        goto error;
    }

    return WMS_SUCCESS;

error:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    WMAudioConfigureInterface
 *
 * Configures the streaming format for the link for the given interface.
 * Note: this is not required for AC'97 streams - HIFI and MONO on AC'97
 * codecs.
 *
 * Parameters:
 *      hDevice         handle to the device (from WMOpenDevice)
 *      audioIF         the interface to configure
 *      isMaster        whether the codec masters the link
 *      format          the streaming format to use
 *      width           the number of bits per sample
 *      flags           extra configuration flags
 *
 * Returns:     WMSTATUS
 *      See WMStatus.h.
 *---------------------------------------------------------------------------*/
WMSTATUS WMAudioConfigureInterface( WM_DEVICE_HANDLE     hDevice,
                                    WM_AUDIO_INTERFACE   audioIF,
                                    WM_BOOL              isMaster,
                                    WM_AUDIOIF_FORMAT    format,
                                    WM_AUDIOIF_WIDTH     width,
                                    WM_AUDIOIF_FLAGS     flags
                                  )
{
    WM_DEVICE_CONTEXT   *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
    WMSTATUS            status = WMS_UNSUPPORTED;
    const WM_CHIPDEF    *pChipDef;

    /*
     * Check the device supports the interface.
     */
    if ( WM_IS_AC97( hDevice ) ||!WMAudioIsInterfaceSupported( hDevice, audioIF ) )
    {
        status = WMS_UNSUPPORTED;
        goto error;
    }
    
    /*
     * Check we've got a function to call.
     */
    pChipDef = WMGetChipDef( hDevice );
    WM_ASSERT( hDevice, pChipDef );
    if ( !pChipDef )
    {
        status = WMS_NO_SUPPORTED_DEVICE;
        goto error;
    }
    
    if ( !pChipDef->vtable.fnConfigureInterface )
    {
        status = WMS_UNSUPPORTED;
        goto error;
    }
    
    /*
     * And call the codec-specific function.
     */
    status = pChipDef->vtable.fnConfigureInterface( hDevice, 
                                                    audioIF,
                                                    isMaster,
                                                    format,
                                                    width,
                                                    flags
                                                  );
    if ( WM_ERROR( status ) )
    {
        goto error;
    }

    /*
     * Save our settings.
     */
    if ( pDeviceContext->v_pWMData )
    {
        /*
         * Lock our global data.
         */
        if ( WMLockGlobalData( hDevice ) )
        {
            if ( WM_AUDIOIF_HIFI == audioIF )
            {
                pDeviceContext->v_pWMData->audioData.flags |= WM_AUDIO_HIFI_CONFIGURED;
                if ( isMaster )
                    pDeviceContext->v_pWMData->audioData.flags |= WM_AUDIO_HIFI_MASTER;
                else
                    pDeviceContext->v_pWMData->audioData.flags &= ~WM_AUDIO_HIFI_MASTER;
            }
#if WM_VOICE
            else /* Voice */
            {
                pDeviceContext->v_pWMData->audioData.flags |= WM_AUDIO_VOICE_CONFIGURED;
                if ( isMaster )
                    pDeviceContext->v_pWMData->audioData.flags |= WM_AUDIO_VOICE_MASTER;
                else
                    pDeviceContext->v_pWMData->audioData.flags &= ~WM_AUDIO_VOICE_MASTER;
            }
#endif /* WM_VOICE */

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

    /*
     * We're done.
     */
    return WMS_SUCCESS;
    
error:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    WMAudioUnconfigureInterface
 *
 * Unconfigures the streaming format for the link for the given interface.
 * Note: this is not required for AC'97 streams - HIFI and MONO on AC'97
 * codecs.
 *
 * Parameters:
 *      hDevice         handle to the device (from WMOpenDevice)
 *      audioIF         the interface to configure
 *
 * Returns:     WMSTATUS
 *      See WMStatus.h.
 *---------------------------------------------------------------------------*/
WMSTATUS WMAudioUnconfigureInterface( WM_DEVICE_HANDLE     hDevice,
                                      WM_AUDIO_INTERFACE   audioIF
									)
{
    WM_DEVICE_CONTEXT   *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
    WMSTATUS            status = WMS_UNSUPPORTED;
    const WM_CHIPDEF    *pChipDef;

    /*
     * Check the device supports the interface.
     */
    if ( WM_IS_AC97( hDevice ) ||!WMAudioIsInterfaceSupported( hDevice, audioIF ) )
    {
        status = WMS_UNSUPPORTED;
        goto error;
    }
    
    /*
     * Check we've got a function to call.
     */
    pChipDef = WMGetChipDef( hDevice );
    WM_ASSERT( hDevice, pChipDef );
    if ( !pChipDef )
    {
        status = WMS_NO_SUPPORTED_DEVICE;
        goto error;
    }
    
    if ( !pChipDef->vtable.fnUnconfigureInterface )
    {
        status = WMS_UNSUPPORTED;
        goto error;
    }
    
    /*
     * And call the codec-specific function.
     */
    status = pChipDef->vtable.fnUnconfigureInterface( hDevice, audioIF );
    if ( WM_ERROR( status ) )
    {
        goto error;
    }

    /*
     * Save our settings.
     */
    if ( pDeviceContext->v_pWMData )
    {
        /*
         * Lock our global data.
         */
        if ( WMLockGlobalData( hDevice ) )
        {
            if ( WM_AUDIOIF_HIFI == audioIF )
            {
                pDeviceContext->v_pWMData->audioData.flags &= ~WM_AUDIO_HIFI_CONFIGURED;
            }
#           if WM_VOICE
                else    /* Voice */
                {
                    pDeviceContext->v_pWMData->audioData.flags &= ~WM_AUDIO_VOICE_CONFIGURED;
                }
#           endif /* WM_VOICE */

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

    /*
     * We're done.
     */
    return WMS_SUCCESS;

error:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    WMAudioIsInterfaceConfigured
 *
 * Queries whether the given interface has been configured.
 * Note: this requires global data.  If there is no global data, this
 * function will return WMS_UNSUPPORTED.
 *
 * Parameters:
 *      hDevice         handle to the device (from WMOpenDevice)
 *      audioIF         the interface to query
 *
 * Returns:     WMSTATUS
 *      WMS_RETURN_TRUE     - interface is configured
 *      WMS_RETURN_FALSE    - interface is not configured
 *      WMS_UNSUPPORTED     - no global data, or interface not supported
 *---------------------------------------------------------------------------*/
WMSTATUS WMAudioIsInterfaceConfigured( WM_DEVICE_HANDLE     hDevice,
                                       WM_AUDIO_INTERFACE   audioIF
                                     )
{
    WM_DEVICE_CONTEXT   *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
    WMSTATUS            status = WMS_UNSUPPORTED;
    
    /*

⌨️ 快捷键说明

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