📄 wmxscalei2s.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 + -