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

📄 xllp_ac97acodec.c

📁 优龙pxa270平台试验程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
 **
 **  COPYRIGHT (C) 2000, 2001 Intel Corporation.
 **
 **  This software as well as the software described in it 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 Intel Corporation. Intel Corporation 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 Intel Corporation. 
 **
 **  FILENAME:       xllp_ac97acodec.c
 **
 **  PURPOSE:        XLLP for Bulverde's AC'97 Controller Unit.
 **                  Includes initialization, API and support
 **                  functions.  
 **
 **  Valid for    :  Subset of AC '97 Rev 2.1
 **
 **
 ******************************************************************************/


#include "xllp_ac97acodec.h"
#include "xllp_ost.h"
#include "xllp_clkmgr.h"
#include ".\xllp_gpio.h"
#include "xllp_intc.h"

//#define FORCE_ZOAR_SSPTXD_HIGH 1
//#define USE_AC97SYSCLK 1
//#define MSII 1


static XLLP_BOOL_T XllpAc97ACODECLinkLock(XLLP_AC97ACODEC_T * pAc97);
static XLLP_ACODEC_ERROR_T  XllpAc97ACODECShutdownAclink(XLLP_AC97ACODEC_T * pAc97Reg, P_XLLP_OST_T pOstRegs);
static XLLP_ACODEC_ERROR_T  XllpAc97ACODECColdReset(XLLP_ACODEC_CONTEXT_T * pAc97ctxt);


/*******************************************************************************
 *
 * FUNCTION:         XllpAc97ACodecInit
 *
 * DESCRIPTION:      Set up AC'97 relative GPIOs.
 *                   Enable AC'97 Controller device clock.
 *                   Perform a cold reset of the AC'97 controller and codec(s).
 *                   
 *                   Note: Does not enable any interrupt types within the 
 *                     ACUNIT, so no interrupts should occur at this point.
 *
 * INPUT PARAMETERS: 
 *       pAc97ctxt   a pointer to a XLLP_ACODEC_CONTEXT_T struct, which contains 
 *						necessary setup information.
 *
 * RETURNS:   
 *       Success:    0 
 *       Failure:    Refer to XllpAc97ACodecColdReset
 *
 * GLOBAL EFFECTS:   
 *
 * ASSUMPTIONS:      - No other systems, such as debuggers, are using the 
 *                     AC '97 Controller or codecs, or the AC Link.
 *                   - The software system will be unharmed by a cold reset of 
 *                     the entire AC '97 subsystem and any associated devices.
 *
 * CALLS:            XllpAc97ACodecColdReset      
 *
 * CALLED BY:        
 *
 * PROTOTYPE:        XLLP_ACODEC_ERROR_T  XllpAc97ACodecInit(XLLP_ACODEC_CONTEXT_T *pAc97ctxt)
 *
 *******************************************************************************/

XLLP_ACODEC_ERROR_T  XllpAc97ACodecInit(XLLP_ACODEC_CONTEXT_T *pAc97ctxt)
{
    XLLP_ACODEC_ERROR_T	status ;
    volatile XLLP_GPIO_T	*pGPIO = (volatile XLLP_GPIO_T *) pAc97ctxt->pGpioReg;
	volatile XLLP_CLKMGR_T *pCLKMGR = (volatile XLLP_CLKMGR_T *) pAc97ctxt->pClockReg;
    XLLP_UINT32_T pins[9], fn[6];
	
/*
#ifdef FORCE_ZOAR_SSPTXD_HIGH
//force gpio 87 low
    pins[0] = 1;  //SPECIFY 3 PIN ITEMS
    pins[1] =  87; //ssptxd2
    fn[0] = 1;
    fn[1] = XLLP_GPIO_ALT_FN_0;  ////no alt function, use as gpio
    XllpGpioSetOutput0((XLLP_GPIO_T *)pGPIO, pins);
    XllpGpioSetDirectionOut((XLLP_GPIO_T *)pGPIO, pins);
    XllpGpioSetAlternateFn((XLLP_GPIO_T *)pGPIO, pins, fn);
#endif
*/

    // Set bitclk, sdata_in_0
	pins[0] = 2;
    pins[1] = XLLP_GPIO_AC97BITCLK;
    pins[2] = XLLP_GPIO_AC97_SDATA_IN_0;
    fn[0] = 2;
    fn[1] = XLLP_GPIO_ALT_FN_1;
    fn[2] = XLLP_GPIO_ALT_FN_1;
    if (XLLP_TRUE == pAc97ctxt->bUseSecondaryCodec)
    {
		pins[0] = 3;
		pins[3] = XLLP_GPIO_KP_MKIN5;      // use this pin as AC97_SDATA_IN_1 
		fn[0] = 3;
		fn[3] = XLLP_GPIO_ALT_FN_2;
	}
	XllpGpioSetDirectionIn((XLLP_GPIO_T *)pGPIO, pins);
    XllpGpioSetAlternateFn((XLLP_GPIO_T *)pGPIO, pins, fn);
    
	// Set sdata_out, sync, sysclock
#ifdef USE_AC97SYSCLK //this is broken, we need to address this in another layer
    pins[0] = 3;  //SPECIFY 3 PIN ITEMS
#else
    pins[0] = 2;  //SPECIFY 2 PIN ITEMS
#endif
    pins[1] = XLLP_GPIO_AC97_SDATA_OUT;
    pins[2] = XLLP_GPIO_AC97_SYNC;

#ifdef USE_AC97SYSCLK 
#ifdef MSII //this is broken, we need to address this in another layer
    pins[3] =  XLLP_GPIO_BTRTS;     // use GPIO 45 as AC97_SYSCLK 
#else //ZOAR
	pins[3] =  XLLP_GPIO_KP_MKIN4;  // use GPIO 98 as AC97_SYSCLK
#endif
#endif

	fn[0] = 3; //SPECIFY 3 FUNCTION ITEMS
    fn[1] = XLLP_GPIO_ALT_FN_2;  //SDATA_OUT IS ALT FN 2
    fn[2] = XLLP_GPIO_ALT_FN_2;  //AC97_SYC IS ALT FN 2
    fn[3] = XLLP_GPIO_ALT_FN_1;  ////AC97_SYSCLK IS ALT FN on pin 45 or 98

    XllpGpioSetOutputState1((XLLP_GPIO_T *)pGPIO, pins);  //INITIAL STATE OF THE GPIO
    XllpGpioSetDirectionOut((XLLP_GPIO_T *)pGPIO, pins); //SET THEM FOR OUTPUT 
    XllpGpioSetAlternateFn((XLLP_GPIO_T *)pGPIO, pins, fn); //ASSIGN ALT FUNC FOR GPIOS

    // Set sdata_reset_n
    pins[0] = 1;
    pins[1] = XLLP_GPIO_AC97_RESET_n;
    fn[0] = 1;
    fn[1] = XLLP_GPIO_ALT_FN_0;
    XllpGpioSetOutput0((XLLP_GPIO_T *)pGPIO, pins);
    XllpGpioSetDirectionOut((XLLP_GPIO_T *)pGPIO, pins);
    XllpGpioSetAlternateFn((XLLP_GPIO_T *)pGPIO, pins, fn);
    
	
    // Enable clocking of AC '97 controller device in processor
    pCLKMGR->cken |= XLLP_CLKEN_AC97;
	
    // Perform the cold reset.
    // Also enables the codec(s), control unit and the control unit's FIFOs
    status = XllpAc97ACODECColdReset(pAc97ctxt);
    
    return (status);

} // End XllpAc97Init ()

/*******************************************************************************
 *
 * FUNCTION:         XllpAc97ACODECDeInit
 *
 * DESCRIPTION:      Shutdown AC97 unit clearly and thoroughly.
 *                   Release GPIOs used by AC97.
 *                   Disable clock to AC97 unit. 
 *
 * INPUT PARAMETERS: 
 *       pAc97ctxt   a pointer to a XLLP_ACODEC_CONTEXT_T struct, which contains 
 *						necessary information.
 *
 * RETURNS:
 *       Success:    0 (XLLP_AC97_NO_ERROR)
 *       Failure:    Refer to XllpAc97ACODECShutdownAclink
 *
 * CALLS:            XllpAc97ACODECShutdownAclink
 *
 * CALLED BY:        
 *
 * PROTOTYPE:        XLLP_ACODEC_ERROR_T  XllpAc97ACODECDeInit(P_XLLP_ACODEC_CONTEXT_T pAc97ctxt);
 *
 *******************************************************************************/

XLLP_ACODEC_ERROR_T  XllpAc97ACodecDeInit(XLLP_ACODEC_CONTEXT_T * pAc97ctxt)
{
    XLLP_ACODEC_ERROR_T	status ;
    volatile XLLP_GPIO_T	*pGPIO = (volatile XLLP_GPIO_T *) pAc97ctxt->pGpioReg;
	volatile XLLP_CLKMGR_T *pCLKMGR = (volatile XLLP_CLKMGR_T *) pAc97ctxt->pClockReg;
    XLLP_UINT32_T pins[8];
	
    status = XllpAc97ACODECShutdownAclink((P_XLLP_AC97ACODEC_T)(pAc97ctxt->pPCMReg), pAc97ctxt->pOSTRegs);

	if (XLLP_ACODEC_SUCCESS == status)
	{

	    // Disable clocking of AC '97 controller device in processor
	    pCLKMGR->cken &= ~XLLP_CLKEN_AC97;

		// Set all pins to default general input configuration.
        pins[0] = 5;

#ifdef USE_AC97SYSCLK 
#ifndef MSII //for zoar
    	pins[0] = 6;
        pins[6] = XLLP_GPIO_KP_MKIN4;     // use this pin as AC97_SYSCLK 
#endif    
#endif		
        pins[1] = XLLP_GPIO_AC97BITCLK;
        pins[2] = XLLP_GPIO_AC97_SDATA_IN_0;
        pins[3] = XLLP_GPIO_AC97_SDATA_OUT;
        pins[4] = XLLP_GPIO_AC97_SYNC;
        pins[5] = XLLP_GPIO_AC97_RESET_n;

        if (XLLP_TRUE == pAc97ctxt->bUseSecondaryCodec)
        {
			pins[0] ++;
			pins[pins[0]] = XLLP_GPIO_KP_MKIN5;      // use this pin as AC97_SDATA_IN_1 
		}
        
		XllpGpioSetDirectionIn((XLLP_GPIO_T *)pGPIO, pins);
        XllpGpioClearAlternateFn((XLLP_GPIO_T *)pGPIO, pins);
	}
    	
    return (status);
}


static void  XllpAc97ACODECGetStatus(XLLP_AC97_ACODEC_STAT_T *pStat, P_XLLP_AC97ACODEC_T pAc97Reg, XLLP_AC97_ACODEC_SEL_T codecSel)
{
	if (XLLP_AC97_ACODEC_PRIMARY == codecSel) 
	{
		pStat->codecReady = (pAc97Reg->GSR & XLLP_AC97_GSR_PCRDY_MSK) ? XLLP_TRUE : XLLP_FALSE;
    }
	else
	{
	    pStat->codecReady = (pAc97Reg->GSR & XLLP_AC97_GSR_SCRDY_MSK) ? XLLP_TRUE : XLLP_FALSE;
	}
} 


XLLP_ACODEC_ERROR_T XllpAc97ACodecWrite (XLLP_ACODEC_CONTEXT_T *pDevContext, XLLP_UINT16_T offset, XLLP_UINT16_T data)
{
    XLLP_ACODEC_ERROR_T	status = XLLP_ACODEC_SUCCESS;
    XLLP_BOOL_T			gotLink;
    XLLP_UINT32_T		timeRemaining;
    P_XLLP_VUINT32_T	pCodecReg;
    P_XLLP_AC97ACODEC_T pAc97Reg = (P_XLLP_AC97ACODEC_T)(pDevContext->pPCMReg); 
	P_XLLP_OST_T pOstRegs = pDevContext->pOSTRegs;
	XLLP_UINT32_T maxRWTimeOutUs = (pDevContext->uMaxReadWriteTimeOutMs) * 1000; 
	XLLP_AC97_ACODEC_SEL_T codecSel = XLLP_AC97_ACODEC_PRIMARY;
	
	if((offset == XLLP_AC97_CR_E_MDM_GPIO_PIN_STAT) && (WM_9712_ID == pDevContext->ACodecId))
    {
        // This is a work around for the WM9712 GPIO status issue.
        // Note that the WM9712 can only be used as a primary
        // AC97 device.
        
        XLLP_UINT16_T offsetdata = data << 1;
        
        pCodecReg = &(pAc97Reg->CodecRegsPrimaryAud[0]);

⌨️ 快捷键说明

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