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