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

📄 wmxscalei2s.c

📁 WM9713 audio codec driver for WinCE 5.0
💻 C
字号:
/*-----------------------------------------------------------------------------
 * 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: WMXScaleI2S.c 2924 2006-04-12 12:50:25Z fb $
 *
 * Functionality for configuring and using Inter-IC Sound (I2S) audio.
 *
 * 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 "WMPlatformDeviceContext.h"
#include "WMGlobals.h"
#include "WMPlatformDebug.h"
#include "WMPlatformI2S.h"

/*
 * Only build this if we need Audio I2S support.
 */
#if WM_I2S

/*
 * Global definitions
 */

/*
 * Function prototypes
 */
static WMSTATUS private_ConfigureI2SGPIO( WM_DEVICE_HANDLE hDevice );
static void private_UnconfigureI2SGPIO( WM_DEVICE_HANDLE hDevice );

/*-----------------------------------------------------------------------------
 * Function:    WMPlatformI2SInit
 *
 * Initialise the platform specific part of the I2S interface.
 *
 * Parameters:
 *      hDevice     handle to the device (from WMOpenDevice)
 *
 * Returns:     WMSTATUS
 *      See WMStatus.h
 *---------------------------------------------------------------------------*/
WMSTATUS WMPlatformI2SInit( WM_DEVICE_HANDLE hDevice )
{
    WM_XSCALE_DEVICE_CONTEXT    *pDeviceContext = 
								    (WM_XSCALE_DEVICE_CONTEXT*) hDevice;

    WMSTATUS status;

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

    /* Make sure the clock is switched on */
    pDeviceContext->v_pClkRegs->cken |= XLLP_CLKEN_I2S;

    status = private_ConfigureI2SGPIO( hDevice );
    if ( WM_ERROR( status ) )
    {
        goto error;
	}


    /*
     * Set up the I2S controller as the slave device.
     */
    pDeviceContext->v_pI2SRegs->SACR0 |= XLLP_SACR0_RFTH_VAL(I2S_INPUT_FIFO_DEPTH)  |
                                         XLLP_SACR0_TFTH_VAL(I2S_OUTPUT_FIFO_DEPTH) |
                                         XLLP_SACR0_BCKD;


    /*
     * Normal I2S mode, recording and replay enabled, no loopback.
     */
    pDeviceContext->v_pI2SRegs->SACR1 &= ~( XLLP_SACR1_AMSL |
                                            XLLP_SACR1_DREC |
                                            XLLP_SACR1_DRPL |
                                            XLLP_SACR1_ENLBF
                                          );

    /*
     * Enable FIFO receive and transmit service requests.
     */
    pDeviceContext->v_pI2SRegs->SAIMR |= XLLP_SAIMR_RFS | XLLP_SAIMR_TFS;

    /*
     * Now enable the I2S link.
     */
    pDeviceContext->v_pI2SRegs->SACR0 |= XLLP_SACR0_ENB;

    return WMS_SUCCESS;

error:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    WMPlatformI2SShutdown
 *
 * Shutdown the I2S interface.
 *
 * Parameters:
 *      hDevice     handle to the device (from WMOpenDevice)
 *      sampleRate  the sample rate to set up for
 *
 * Returns:     none
 *---------------------------------------------------------------------------*/
void WMPlatformI2SShutdown( WM_DEVICE_HANDLE hDevice )
{
    WM_XSCALE_DEVICE_CONTEXT *pDeviceContext =
								(WM_XSCALE_DEVICE_CONTEXT*) hDevice;

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

    pDeviceContext->v_pI2SRegs->SACR0 &= ~XLLP_SACR0_ENB; 
    pDeviceContext->v_pClkRegs->cken &= ~XLLP_CLKEN_I2S;
}

/*-----------------------------------------------------------------------------
 * Function:    WMPlatformI2SSetSampleRate
 *
 * Set the sample rate for the I2S interface, when the I2S controller is the
 * master.
 *
 * Parameters:
 *      hDevice     handle to the device (from WMOpenDevice)
 *      sampleRate  the requested sample rate
 *
 * Returns:     WMSTATUS
 *       See WMStatus.h.
 *---------------------------------------------------------------------------*/
WMSTATUS WMPlatformI2SSetSampleRate( WM_DEVICE_HANDLE hDevice, 
                                     WM_SAMPLE_RATE sampleRate  
                                   )
{
    WM_XSCALE_DEVICE_CONTEXT *pDeviceContext =
								(WM_XSCALE_DEVICE_CONTEXT*) hDevice;
    WMSTATUS                status = WMS_SUCCESS;
    unsigned long           sadiv;

    WM_ASSERT( hDevice, NULL != pDeviceContext );
    WM_ASSERT( hDevice, NULL != pDeviceContext->v_pI2SRegs );
    
    /*
     * Set the sample rate
     */
    switch (sampleRate)
    {
        case WM_SAMPLE_RATE_8K:
            sadiv = WM_I2S_8K;
            break;
        case WM_SAMPLE_RATE_11K025:
            sadiv = WM_I2S_11K025;
            break;
        case WM_SAMPLE_RATE_16K:
            sadiv = WM_I2S_16K;
            break;
        case WM_SAMPLE_RATE_22K05:
            sadiv = WM_I2S_22K05;
            break;
        case WM_SAMPLE_RATE_44K1:
            sadiv = WM_I2S_44K1;
            break;
        case WM_SAMPLE_RATE_48K:
            sadiv = WM_I2S_48K;
            break;
        default:
            status = WMS_UNSUPPORTED;
            goto error0;
    }

    pDeviceContext->v_pI2SRegs->SADIV = sadiv;

    /*
     * All done.
     */
    return WMS_SUCCESS;
    
    /*
     * Error cleanup.
     */
error0:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    private_ConfigureI2SGPIO
 *
 * This function configures the GPIO pins for the I2S interface on XScale
 * platforms, as follows:
 *
 *      Signals         Pin#        Direction       Alternate Function
 *      SYNC            GPIO31      output              1
 *      SDATA_OUT       GPIO30      output              1
 *      BIT_CLK         GPIO28      output              1
 *      SDATA_IN        GPIO29      input               2
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *
 * Returns:     void
 *---------------------------------------------------------------------------*/
static WMSTATUS private_ConfigureI2SGPIO( WM_DEVICE_HANDLE hDevice )
{
    WM_XSCALE_DEVICE_CONTEXT *pDeviceContext = 
								(WM_XSCALE_DEVICE_CONTEXT*) hDevice;

    WMSTATUS status;

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

    /* Only need to do this once */
    if ( pDeviceContext->v_pWMData )
    {
        if ( pDeviceContext->v_pWMData->flags & WM_GPIO_CONFIGURED_I2S )
        {
            goto done;
        }
    }

    /*
     * Check to see if a different control interface has already
     * been initialised by another driver. 
     * If it has been we should not try to configure this interface.
     */
    if ( pDeviceContext->v_pWMData->flags & WM_GPIO_CONFIGURED_AC97 )
    {
        status = WMS_RESOURCE_CONFLICT;
        goto error;
    }

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

    /* SDATAOUT, BITCLK and SYNC are outputs (1) */
    pDeviceContext->v_pGPIORegs->GPIO_REG(GPDR) |= 
                    ( GPIO_BIT_SDATA_OUT | GPIO_BIT_BITCLK | GPIO_BIT_SYNC );

    /* SDATA_IN is an input (0) */
    pDeviceContext->v_pGPIORegs->GPIO_REG(GPDR) &= ~GPIO_BIT_SDATA_IN;

    /* Set up the correct alternate functions */
    pDeviceContext->v_pGPIORegs->GPIO_ALTFN_REG =
                            ( ( pDeviceContext->v_pGPIORegs->GPIO_ALTFN_REG & ~GPIO_ALTFN_MASK ) |
                                ( GPIO_ALTFN_I2S_BITCLK       | 
                                  GPIO_ALTFN_I2S_SDATA_IN     | 
                                  GPIO_ALTFN_I2S_SDATA_OUT    |
                                  GPIO_ALTFN_I2S_SYNC
                                )
                            );
    /*
     * And we're done.
     */
done:
    /* Remember it's done so we don't try to do it twice */
    if ( pDeviceContext->v_pWMData )
    {
        pDeviceContext->v_pWMData->flags |= ( WM_GPIO_CONFIGURED_I2S | 
                                              WM_GPIO_CONFIGURED_HIFI
                                            );
    }

    return WMS_SUCCESS;

error:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    private_UnconfigureI2SGPIO
 *
 * This function unconfigures the GPIO pins for the AC link.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *
 * Returns:     void
 *---------------------------------------------------------------------------*/
static void private_UnconfigureI2SGPIO( WM_DEVICE_HANDLE hDevice )
{
    WM_XSCALE_DEVICE_CONTEXT *pDeviceContext = 
								(WM_XSCALE_DEVICE_CONTEXT*) hDevice;

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

#if WM_BOARD_MAINSTONEII
    WM_ASSERT( hDevice, NULL != pDeviceContext->v_pClkRegs );

    /* Disable clocking of the I2S controller device in processor */
    pDeviceContext->v_pClkRegs->cken &= ~XLLP_CLKEN_I2S;
#endif /* WM_BOARD_MAINSTONEII */


    /* We're less configured now */
    if ( pDeviceContext->v_pWMData )
    {
        pDeviceContext->v_pWMData->flags &= ~( WM_GPIO_CONFIGURED_HIFI |
                                               WM_GPIO_CONFIGURED_I2S
                                             );
    }

    return;
}
#endif /* WM_I2S */

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

⌨️ 快捷键说明

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