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

📄 xllp_ak2440.c

📁 PXA270硬件测试源代码
💻 C
字号:

/******************************************************************************
**
**  COPYRIGHT (C) 2001, 2002 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:       ak2440.c
**
**  PURPOSE: contains functions specific to the AKM ak2440 audio codec
**           
**                  
**
******************************************************************************/
//#include <bvd1.h>
//#include <bvd1bd.h>
#include "xllp_ak2440.h"
#include "xllp_acodec.h"
#include "xllp_i2s.h"
#include "xllp_i2c.h"
#include "xllp_ssp.h"
#include ".\xllp_gpio.h"

#define USE_BVD_SSP     1
//#define USE_GARSON_SSP  1

XLLP_ACODEC_ERROR_T XllpAKCodecWrite(XLLP_ACODEC_CONTEXT_T *pDeviceContext, XLLP_UINT16_T regAddr, XLLP_UINT16_T regVaule)
{
//	P_XLLP_I2C_T        pCtrlReg = (pDeviceContext->pAcodecReg)->pCtrlReg;
    XLLP_UINT16_T    timer=0;



	(pDeviceContext->pCtrlReg)->ISAR = 0x0;
	(pDeviceContext->pCtrlReg)->ICR = 0;


	// STEP 1: Send the Sensor Address.
	(pDeviceContext->pCtrlReg)->ICR |= (XLLP_ICR_UIE | XLLP_ICR_SCLEA);	
	(pDeviceContext->pCtrlReg)->IDBR = 0x9e;   // AK2440_SLAVE_ADDRESS;

	(pDeviceContext->pCtrlReg)->ICR |= (XLLP_ICR_UIE | XLLP_ICR_SCLEA | XLLP_ICR_START | XLLP_ICR_TB);

	while(!((pDeviceContext->pCtrlReg)->ISR & XLLP_ISR_ITE))
	{
	//	timer++;
	//	if(timer == 65536)
	//	{
		//	EdbgOutputDebugString ( "XllpACodecWrite,STEP1 %x \r\n",pCtrlReg->ISR); 
	//		return (XLLP_ACODEC_CONTROLLER_INTERFACE_TIMEOUT);
	//	}

	}
	timer = 0;

	(pDeviceContext->pCtrlReg)->ISR |= XLLP_ISR_ITE;

	// STEP 2: Send the register address
	(pDeviceContext->pCtrlReg)->IDBR = regAddr;
	(pDeviceContext->pCtrlReg)->ICR = (XLLP_ICR_UIE | XLLP_ICR_SCLEA | XLLP_ICR_TB);

	while(!((pDeviceContext->pCtrlReg)->ISR & XLLP_ISR_ITE))
	{
	//	timer++;
	//	if(timer == 65536)
	//	{
		//	EdbgOutputDebugString ( "XllpACodecWrite,STEP1 %x \r\n",pCtrlReg->ISR); 
	//		return (XLLP_ACODEC_CONTROLLER_INTERFACE_TIMEOUT);
	//	}

	}
    timer = 0;

	(pDeviceContext->pCtrlReg)->ISR |= XLLP_ISR_ITE;

	// STEP 3: Now the register data	
	(pDeviceContext->pCtrlReg)->IDBR = regVaule;
	(pDeviceContext->pCtrlReg)->ICR = (XLLP_ICR_UIE | XLLP_ICR_SCLEA | XLLP_ICR_TB |XLLP_ICR_STOP);

	while(!((pDeviceContext->pCtrlReg)->ISR & XLLP_ISR_ITE));

	(pDeviceContext->pCtrlReg)->ISR |= XLLP_ISR_ITE;   //clear ITE 

	
	return XLLP_ACODEC_SUCCESS;
}


XLLP_ACODEC_ERROR_T XllpAKCodecRead(XLLP_ACODEC_CONTEXT_T *pDeviceContext, XLLP_UINT16_T regAddr, XLLP_UINT16_T *regVaule)
{
	XLLP_UINT32_T  temp;
    XLLP_UINT16_T timer = 0;
	//EdbgOutputDebugString ( "Enter XllpACodecRead\r\n");

  
    (pDeviceContext->pClockReg)->cken |=  XLLP_CLKEN_I2C;
     (pDeviceContext->pCtrlReg)->ICR = XLLP_ICR_UR;
    XllpOstDelayMicroSeconds( pDeviceContext->pOSTRegs,1);
     (pDeviceContext->pCtrlReg)->ICR = 0;
	
	//P_XLLP_I2C_T        pCtrlReg = (pDeviceContext->pAcodecReg)->pCtrlReg;
	(pDeviceContext->pCtrlReg)->ISAR = 0x0;
	//(pDeviceContext->pCtrlReg)->ICR = 0;
      (pDeviceContext->pCtrlReg)->ICR = (XLLP_ICR_UIE|XLLP_ICR_SCLEA);
    XllpOstDelayMicroSeconds( pDeviceContext->pOSTRegs,100);
	//EdbgOutputDebugString ( "after setting ISAR\r\n");
	// STEP 1: Send the akm2440 address, Master Transmit mode -AKM manual P60 -- first do dummy write
	(pDeviceContext->pCtrlReg)->ICR  = (XLLP_ICR_UIE | XLLP_ICR_SCLEA);
	(pDeviceContext->pCtrlReg)->IDBR =  0x9e;    //AK2440_SLAVE_ADDRESS;
     
	(pDeviceContext->pCtrlReg)->ICR  = (XLLP_ICR_UIE | XLLP_ICR_SCLEA | XLLP_ICR_START | XLLP_ICR_TB);
//     EdbgOutputDebugString ( "after setting ICR\r\n");
	while(!((pDeviceContext->pCtrlReg)->ISR & XLLP_ISR_ITE))
	{
		//timer++;

		//if(timer == 65536)
	//	{
	//		EdbgOutputDebugString ( "XllpACodecWrite,STEP1 %x \r\n",(pDeviceContext->pCtrlReg)->ISR); 
		//	return (XLLP_ACODEC_CONTROLLER_INTERFACE_TIMEOUT);
	//	}

		
	}
    timer = 0;

	(pDeviceContext->pCtrlReg)->ISR |= XLLP_ISR_ITE;

	//EdbgOutputDebugString ( "step1 : pI2CReg->ISR %x \r\n",(pDeviceContext->pCtrlReg)->ISR);

	// STEP 2: Send register address down to the AKM card
	(pDeviceContext->pCtrlReg)->IDBR = regAddr;
//     EdbgOutputDebugString ( "step2 : pI2CReg->IDBR %x \r\n",(pDeviceContext->pCtrlReg)->IDBR);
	(pDeviceContext->pCtrlReg)->ICR = (XLLP_ICR_UIE  |XLLP_ICR_SCLEA | XLLP_ICR_TB);

	while(!((pDeviceContext->pCtrlReg)->ISR & XLLP_ISR_ITE));
	{
	//	timer++;

	//	if(timer == 1000)
	//	{
			//EdbgOutputDebugString ( "XllpACodecWrite,STEP1 %x \r\n",pCtrlReg->ISR); 
	//		return (XLLP_ACODEC_CONTROLLER_INTERFACE_TIMEOUT);
	//	}

	}
    timer = 0;

	(pDeviceContext->pCtrlReg)->ISR |= XLLP_ISR_ITE;
//     EdbgOutputDebugString ( "step2 : (pDeviceContextp->CtrlReg)->ISR %x \r\n",(pDeviceContext->pCtrlReg)->ISR);
	// STEP 3: Master reissue the start condition, slave address and slave address with the R/W bit set to 1.
	(pDeviceContext->pCtrlReg)->IDBR = 0x9f;  //(AK2440_SLAVE_ADDRESS|0x1);    //0x1 -- means READ operation
	(pDeviceContext->pCtrlReg)->ICR = (XLLP_ICR_UIE | XLLP_ICR_SCLEA | XLLP_ICR_START | XLLP_ICR_TB );

	while(!((pDeviceContext->pCtrlReg)->ISR & XLLP_ISR_ITE))
	{
		timer++;

		if(timer == 65536)
		{
			//EdbgOutputDebugString ( "XllpACodecWrite,STEP1 %x \r\n",pCtrlReg->ISR); 
			return (XLLP_ACODEC_CONTROLLER_INTERFACE_TIMEOUT);
		}

	}

	timer = 0;

//     EdbgOutputDebugString ( "step3 : pI2CReg->ISR %x \r\n",(pDeviceContext->pCtrlReg)->ISR);
	(pDeviceContext->pCtrlReg)->ISR |= XLLP_ISR_ITE;
    
	//STEP4: Read operation
	(pDeviceContext->pCtrlReg)->ICR =(XLLP_ICR_STOP | XLLP_ICR_TB | XLLP_ICR_ACKNACK |XLLP_ICR_UIE |XLLP_ICR_SCLEA  );
    while(!((pDeviceContext->pCtrlReg)->ISR & XLLP_ISR_IRF))
	{
			timer++;

		if(timer == 65536)
		{
			//EdbgOutputDebugString ( "XllpACodecWrite,STEP1 %x \r\n",pCtrlReg->ISR); 
			return (XLLP_ACODEC_CONTROLLER_INTERFACE_TIMEOUT);
		}

	}
		//EdbgOutputDebugString ( "step4 : pI2CReg->ISR %x \r\n",(pDeviceContext->pCtrlReg)->ISR);
	(pDeviceContext->pCtrlReg)->ISR |= XLLP_ISR_IRF;         //clear the bit

	temp = (pDeviceContext->pCtrlReg)->IDBR;
	//EdbgOutputDebugString ("step4 :temp =%x \r\n",temp);
    *regVaule = (XLLP_UINT8_T) temp;
   // (pDeviceContext->pCtrlReg)->ICR &= ~(XLLP_ICR_STOP |XLLP_ISR_ACKNACK);    //Clear STOP and ACKNAK bits 
    (pDeviceContext->pCtrlReg)->ICR = 0;
	return XLLP_ACODEC_SUCCESS;
}

XLLP_ACODEC_ERROR_T XllpAkSetMasterVol(XLLP_ACODEC_CONTEXT_T *pDeviceContext,unsigned short int GainInDb)
{
	//stub
	return (XLLP_ACODEC_SUCCESS);

}

XLLP_ACODEC_ERROR_T XllpAkGetInSampleRate(XLLP_ACODEC_CONTEXT_T *pDeviceContext, unsigned short int * RateInKhz)
{
	*RateInKhz=8000;  //AKM SSP interface only supports 8 khz sample rate
	return (XLLP_ACODEC_SUCCESS);
}

XLLP_ACODEC_ERROR_T XllpAkGetOutSampleRate (XLLP_ACODEC_CONTEXT_T *pDeviceContext,unsigned short int * RateInKhz)
{

	switch((pDeviceContext->pPCMReg)->SADIV)	{
	case 0x48:
		*RateInKhz=8000; //8k
		break;
	case 0x34:
		*RateInKhz=11025; //11k
		break;
	case 0x24:
		*RateInKhz=16000; //16k
		break;
	case 0x1a:
		*RateInKhz=22050; //22.05KHZ
		break;
	case 0xd:
		*RateInKhz=44100; //44.100KHZ
		break;
	case 0xc:
		*RateInKhz=48000; //48KHZ
		break;
		
	default:
		return(XLLP_ACODEC_SAMPLERATE_INVALID);
		break;
	}
	return (XLLP_ACODEC_SUCCESS);

}
XLLP_ACODEC_ERROR_T XllpAkSetInSampleRate(XLLP_ACODEC_CONTEXT_T *pDeviceContext,unsigned short int RateInKhz)
{
	//note: we assume the AKM is in slave mode (i2s bitclk comes from apps cpu)
	//therefore the SSP path has a fixed sample rate of 8khz
	
	return (XLLP_ACODEC_CODEC_FEATURE_NOT_SUPPORTED);

}
XLLP_ACODEC_ERROR_T XllpAkSetOutSampleRate (XLLP_ACODEC_CONTEXT_T *pDeviceContext,unsigned short int RateInKhz)
{
	//note: we assume the AKM is in slave mode (i2s bitclk comes from apps cpu)
	//therefore we set the divisor to the bitclock

	switch(RateInKhz)	{
	case 8000:
		(pDeviceContext->pPCMReg)->SADIV = 0x48; //appx 8 khz //don't let the 48 confuse you, it's only 8k
		break;
	case 11025:
		(pDeviceContext->pPCMReg)->SADIV = 0x34; //appx 11.025 khz
		break;
	case 16000:
		(pDeviceContext->pPCMReg)->SADIV = 0x24; //appx 16 khz
		break;
	case 22050:
		(pDeviceContext->pPCMReg)->SADIV = 0x1a; //appx  22.05 khz
		break;
	case 44100:
		(pDeviceContext->pPCMReg)->SADIV = 0xd; //appx 44.1khz
		break;
	case 48000:
		(pDeviceContext->pPCMReg)->SADIV = 0xc; //appx 48khz
		break;
		
	default:
		return(XLLP_ACODEC_SAMPLERATE_INVALID);
		break;

	}
	return (XLLP_ACODEC_SUCCESS);

}
XLLP_ACODEC_ERROR_T XllpAkEnableSspPath (XLLP_ACODEC_CONTEXT_T *pDeviceContext,XLLP_UINT8_T uiDirection)
{
	//todo: specify control of PCM interface to save power (set the transmit path switchs (tx3, tx4, etc)

	return (XLLP_ACODEC_SUCCESS);

}
XLLP_ACODEC_ERROR_T XllpAkDisableSspPath (XLLP_ACODEC_CONTEXT_T *pDeviceContext,XLLP_UINT8_T uiDirection)
{
	//todo: specify control of PCM interface to save power (set the transmit path switchs (tx3, tx4, etc)

	return (XLLP_ACODEC_SUCCESS);

}
XLLP_ACODEC_ERROR_T XllpAkCodecSpecificInit (XLLP_ACODEC_CONTEXT_T *pDeviceContext)
{
		

		XllpAKCodecWrite(pDeviceContext, AK_CLKCNT, 0x87); // 13mhz external clock, 44.1KHZ sample rate, PLL1 off 0xD7
        XllpAKCodecWrite(pDeviceContext, AK_CLKCNT2, 0xc); // Slave mode for PCM   0xC for Slave mode
		XllpAKCodecWrite(pDeviceContext, AK_PDCNT1, 0xf); // turn off PLL1 and PLL3 and CLKO
	    XllpAKCodecWrite(pDeviceContext, AK_PDCNT2,0x7f);
		XllpAKCodecWrite(pDeviceContext,AK_PDCNT3,	0x3f);   //before is 0x31
		XllpAKCodecWrite(pDeviceContext,AK_RXPTHCNT1,	0x7f);  //0x14
		XllpAKCodecWrite(pDeviceContext,AK_RXPTHCNT2,0x7f);  //0x18
		XllpAKCodecWrite(pDeviceContext,AK_STADDCNT, 0);
		XllpAKCodecWrite(pDeviceContext,AK_TXPTHCNT,		0x17);   //original 0x15
		XllpAKCodecWrite(pDeviceContext,AK_VR5SET,		0x15);
		XllpAKCodecWrite(pDeviceContext,AK_VRSTSET,		0x06);
		XllpAKCodecWrite(pDeviceContext,AK_LEFTVOL,		0xc);//max
		XllpAKCodecWrite(pDeviceContext,AK_RIGHTVOL,		0xc);
        XllpAKCodecWrite(pDeviceContext,AK_MASTERVOL,		0x0);
		XllpAKCodecWrite(pDeviceContext,AK_DACIFCNT,	0x12);//I2S compatible mode with MCLK1 output disable
		XllpAKCodecWrite(pDeviceContext,AK_CODECSET,	0x80); // pcm -- high out, codec data shift =128khz
		XllpAKCodecWrite(pDeviceContext,AK_RXPTHCNT3,		0x14); // 0b 001 0100 // SPL output rx_sumleft, epl sum left
		XllpAKCodecWrite(pDeviceContext,AK_RXPTHCNT4,		0x14); // 0b 001 0100 // SPR output rx_sumright, epl sum right
		XllpAKCodecWrite(pDeviceContext,AK_DACGAIN,0xe); //bass boost 
		XllpAKCodecWrite(pDeviceContext, AK_TXVRSET, 0xa); // -10db (louder and its distorted)




	return (XLLP_ACODEC_SUCCESS);
}

XLLP_ACODEC_ERROR_T XllpAkCodecSpecificDeinit (XLLP_ACODEC_CONTEXT_T *pDeviceContext)
{
    return (XLLP_ACODEC_SUCCESS);
}

XLLP_ACODEC_ERROR_T XllpAKEnterEuipmentState(XLLP_ACODEC_CONTEXT_T *pDeviceContext, XLLP_ACODEC_EQUIPMENT_T State)
{
    return (XLLP_ACODEC_SUCCESS);
}

XLLP_ACODEC_ERROR_T XllpAKQueryEquipmentState(XLLP_ACODEC_CONTEXT_T *pDeviceContext, XLLP_ACODEC_EQUIPMENT_T * State)
{
   return (XLLP_ACODEC_SUCCESS);
}

⌨️ 快捷键说明

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