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

📄 wmxscaledmacontext.c

📁 WM9713 audio codec driver for WinCE 5.0
💻 C
📖 第 1 页 / 共 2 页
字号:
/*-----------------------------------------------------------------------------
 * 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: WMXScaleDMAContext.c 2530 2005-12-07 10:48:44Z ian $
 *
 * This file contains XScale functionality for DMA initialisation and
 * allocation.
 *
 * Warning:
 *  This driver is specifically written for Wolfson Codecs. It is not a 
 *  general CODEC device driver.
 *
 *  This platform file is specifically designed to work with the Cotulla AC'97
 *  controller and the Lubbock and Mainstone XScale platforms from Intel.  There
 *  is no guarantee of correct operation with other platforms/controllers.
 *
 * -----------------------------------------------------------------------------*/

/*
 * Include files
 */
#include <windows.h>

#include "WMCommon.h"
#include "WMDMAContext.h"
#include "WMPlatform_OS.h"
#include "WMPlatformDeviceContext.h"
#include "WMAudioInternal.h"

/* Sanity check on library Audio configuration */
#if WMAUDIO_MAX_BUFFER_SIZE > AUDIO_BUFFER_SIZE
#error WMAUDIO_MAX_BUFFER_SIZE is too large
#endif /* WMAUDIO_MAX_BUFFER_SIZE > AUDIO_BUFFER_SIZE */

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

/*
 * Global definitions
 */

/*
 * A macro for initialising the DMA Details table.
 */
#define DMA_CHAN( _channel, _addr, _flags, _bytesPerSample, _burstSize, _device ) \
        { _channel, (void *)_addr, _flags, _bytesPerSample, _burstSize, _device }

/*
 * Public data.
 */
DMAContext                     g_WMDMAContext = {0};

/*
 * Private data
 */

/*
 * The predefined details of the channels we use.
 */
static DMA_CHANNEL_DETAILS s_ChannelDetails[] = 
{
#if WM_AC97
    DMA_CHAN(
            WMAUDIO_AC97_STEREO_OUT,        /* API channel ID*/
            DMAC_AC97_AUDIO_XMIT_FIFO,      /* FIFO address */
            WM_OUTPUT|WM_STEREO,            /* whether: input, stereo or wide */
            4,                              /* bytes per sample */
            DMAC_BURST_SIZE_32_BYTES,       /* Maximum burst size */
            DMA_CHAN_AC97_STEREO_OUT        /* DMA Device ID (DRCMR) */
    ),
    DMA_CHAN(
            WMAUDIO_AC97_STEREO_IN,         /* API channel ID*/
            DMAC_AC97_AUDIO_RCV_FIFO,       /* FIFO address */
            WM_INPUT|WM_STEREO,             /* whether: input, stereo or wide */
            4,                              /* bytes per sample */
            DMAC_BURST_SIZE_32_BYTES,       /* Maximum burst size */
            DMA_CHAN_AC97_STEREO_IN         /* DMA Device ID (DRCMR) */
    ),
#if WM_MONODAC
    DMA_CHAN(
            WMAUDIO_AC97_MONO_OUT,          /* API channel ID*/
            DMAC_AC97_MONO_XMIT_FIFO,       /* FIFO address */
            WM_OUTPUT|WM_MONO|WM_WIDE,      /* whether: input, stereo or wide */
            4,                              /* bytes per sample */
            DMAC_BURST_SIZE_32_BYTES,       /* Maximum burst size */
            DMA_CHAN_AC97_MONO_OUT          /* DMA Device ID (DRCMR) */
    ),
#endif /* WM_MONODAC */
#endif /* WM_AC97 */
#if WM_I2S
    DMA_CHAN(
            WMAUDIO_I2S_STEREO_OUT,         /* API channel ID*/
            DMAC_I2S_AUDIO_XMIT_FIFO,       /* FIFO address */
            WM_OUTPUT|WM_STEREO,            /* whether: input, stereo or wide */
            4,                              /* bytes per sample */
            DMAC_BURST_SIZE_32_BYTES,       /* Maximum burst size */
            DMA_CHAN_I2S_STEREO_OUT         /* DMA Device ID (DRCMR) */
    ),
    DMA_CHAN(
            WMAUDIO_I2S_STEREO_IN,          /* API channel ID*/
            DMAC_I2S_AUDIO_RCV_FIFO,        /* FIFO address */
            WM_INPUT|WM_STEREO,             /* whether: input, stereo or wide */
            4,                              /* bytes per sample */
            DMAC_BURST_SIZE_32_BYTES,       /* Maximum burst size */
            DMA_CHAN_I2S_STEREO_IN          /* DMA Device ID (DRCMR) */
    ),
#endif /* WM_I2S */
#if WM_VOICE
    DMA_CHAN(
            WMAUDIO_VOICE_OUT,              /* API channel ID*/
            DMAC_SSP2_AUDIO_XMIT_FIFO,      /* FIFO address */
            WM_OUTPUT|WM_MONO,              /* whether: input, stereo or wide */
            2,                              /* bytes per sample */
            DMAC_BURST_SIZE_16_BYTES,       /* Maximum burst size */
            DMA_CHAN_VOICE_OUT              /* DMA Device ID (DRCMR) */
    ),
    DMA_CHAN(
            WMAUDIO_VOICE_IN,               /* API channel ID*/
            DMAC_SSP2_AUDIO_RCV_FIFO,       /* FIFO address */
            WM_INPUT|WM_MONO,               /* whether: input, stereo or wide */
            2,                              /* bytes per sample */
            DMAC_BURST_SIZE_16_BYTES,       /* Maximum burst size */
            DMA_CHAN_VOICE_IN               /* DMA Device ID (DRCMR) */
    ),
#endif /* WM_VOICE */
    /* Place holder for end of array */
	DMA_CHAN(
            WMAUDIO_INVALID_CHANNEL,        /* API channel ID*/
            0,                              /* FIFO address */
            0,                              /* whether: input, stereo or wide */
            0,                              /* bytes per sample */
            0,                              /* Maximum burst size */
            0                               /* DMA Device ID (DRCMR) */
    )
};

/* 
 * We can not use the last array member as this is only a placeholder This is 
 * why we subtract 1 from the the array count to give the available channels.
 */
#define WM_AVAILABLE_DMA_CHANNELS	(WM_ARRAY_COUNT( s_ChannelDetails ) - 1)

/*
 * Function prototypes
 */
static WMSTATUS private_AllocateDMAMemory( WM_DEVICE_HANDLE hDevice,
                                           DMAContext *pDMAContext
                                         );
static void private_InitialiseDMAMemory( WM_DEVICE_HANDLE hDevice,
                                         DMAContext *pDMAContext
                                       );
static void private_AssignDMAMemory( WM_DEVICE_HANDLE hDevice,
                                     DMAContext *pDMAContext,
                                     int DMAChannels
                                   );

static void private_PrepareDeviceMapping( WM_DEVICE_HANDLE hDevice,
                                          DMAContext *pDMAContext
                                        );

/*-----------------------------------------------------------------------------
 * Function:    WMInitDMAContext
 *
 * Initialises the DMA and returns a pointer to the DMA context for passing
 * to the device context.
 * 
 * Parameters:
 *      hDevice     handle to the device (from WMOpenDevice)
 *      ppContext   a variable to receive the pointer to the context structure.
 *
 * Returns:     WMSTATUS
 *		See WMStatus.h
 *---------------------------------------------------------------------------*/
WMSTATUS WMInitDMAContext( WM_DEVICE_HANDLE hDevice, DMAContext **ppContext )
{
    WMSTATUS                    status;
    DMAContext                  *pDMAContext;

    pDMAContext = &g_WMDMAContext;

    /* Check whether we're initialised */
    if ( pDMAContext->initialised )
    {
        goto InitDone;
    }

    /*
     * Allocate the memory for the DMA buffers and descriptors.
     */
    status = private_AllocateDMAMemory( hDevice, pDMAContext );
    if( WM_ERROR( status ) )
    {
        goto error;
    }

    /*
     * Map the memory for the DMA buffers and descriptors.
     */
    private_InitialiseDMAMemory( hDevice, pDMAContext );

    /*
     * Fill in the device mapping table.
     */
    private_PrepareDeviceMapping( hDevice, pDMAContext );

    /*
     * Set the DMA Context flag to TRUE as we have filled
     * in the DMA Context and it is ready to be used.
     */
    pDMAContext->initialised = TRUE;

InitDone:
    *ppContext = pDMAContext;
    return WMS_SUCCESS;

    /*
     * Error handling.
     */
error:
    pDMAContext->initialised = FALSE;

    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    WMDMAGetChannelDef
 *
 * Returns a pointer to the requested channel definition corresponding to 
 * the channel.
 *
 * Parameters:
 *      hDevice         handle to the device (from WMOpenDevice)
 *      APIChannel      the API channel ID.
 *
 * Returns:     ChannelDef *
 *				NULL indicates an error  - 
 *				the appropriate structure was not found
 *---------------------------------------------------------------------------*/
ChannelDef *WMDMAGetChannelDef( WM_DEVICE_HANDLE  hDevice,
								WMAUDIO_CHANNEL   APIChannel
                              )
{
	WM_XSCALE_DEVICE_CONTEXT	*pDeviceContext = 
									(WM_XSCALE_DEVICE_CONTEXT*) hDevice;
    DMAContext					*pDMAContext = pDeviceContext->pDMAContext;
    unsigned int                i;

    WM_ASSERT( hDevice, pDMAContext->initialised );
	
    for ( i = 0; i < WM_AVAILABLE_DMA_CHANNELS; i++ )
	{
		if ( APIChannel == pDMAContext->pDMAChannels[i].APIChannel )
		{
			return ( &(pDMAContext->pDMAChannels[i]) );
		}
	}

	/* No matching channel found */
	WM_TRACE( hDevice, (
			  "WMDMAGetChannelDef - NO definition for channel %d found",
			  APIChannel
			           ) 
			);
	return ((ChannelDef *)NULL);
}

/*-----------------------------------------------------------------------------
 * Function:    WMDMAGetChannelDetails
 *
 * Returns a pointer to the requested static DMA setup structure corresponding 
 * to the channel.
 *
 * Parameters:
 *      hDevice     handle to the device (from WMOpenDevice)
 *      APIChannel  the Wolfson channel ID
 *
 * Returns:     DMA_CHANNEL_DETAILS *
 *				NULL indicates an error  - 
 *				the appropriate structure was not found
 *---------------------------------------------------------------------------*/
const DMA_CHANNEL_DETAILS *WMDMAGetChannelDetails( WM_DEVICE_HANDLE hDevice,
                                    			   WMAUDIO_CHANNEL  APIChannel
                              					 )
{
	WM_XSCALE_DEVICE_CONTEXT	*pDeviceContext =
									(WM_XSCALE_DEVICE_CONTEXT*) hDevice;
    DMAContext					*pDMAContext = pDeviceContext->pDMAContext;
    unsigned int                i;

	WM_ASSERT( hDevice, WMAUDIO_DEFAULT_INPUT != APIChannel );
	WM_ASSERT( hDevice, WMAUDIO_DEFAULT_OUTPUT != APIChannel );

    for ( i = 0; i < WM_AVAILABLE_DMA_CHANNELS; i++ )
	{
		if ( APIChannel == pDMAContext->pChannelDetails[i].APIChannel )
		{
			return ( &pDMAContext->pChannelDetails[i] );
		}
	}

⌨️ 快捷键说明

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