📄 xllp_wm8753.c
字号:
/******************************************************************************
**
** 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_wm8753.c
**
** PURPOSE: XLLP ACODEC for wm8753 codec.
**
** Valid for : wm8753 codec
**
**
******************************************************************************/
#include "xllp_Wm8753.h"
#include "xllp_acodec.h"
#include "xllp_i2s.h"
#include "xllp_i2c.h"
#include "xllp_ssp.h"
#include "xllp_gpio.h"
XLLP_ACODEC_ERROR_T XllpWm8753CodecWrite(XLLP_ACODEC_CONTEXT_T *pDeviceContext, XLLP_UINT16_T regOffset, XLLP_UINT16_T regVal)
{
XLLP_UINT16_T timer=0;
XLLP_UINT16_T temp=0;
(pDeviceContext->pCtrlReg)->ISAR = 0x0;
(pDeviceContext->pCtrlReg)->ICR = 0;
temp = ( regOffset<<9 | regVal); //combine register address and content into 16 bit data
// STEP 1: Send the Sensor Address.
(pDeviceContext->pCtrlReg)->ICR |= (XLLP_ICR_UIE | XLLP_ICR_SCLEA);
(pDeviceContext->pCtrlReg)->IDBR = 0x34; //0x34; // WOLFSON8753_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++;
//NKDbgPrintfW (TEXT( "XllpACodecWrite,STEP1 %d \r\n"),timer );
if(timer == 1000)
{
//NKDbgPrintfW (TEXT( "XllpACodecWrite,STEP1 \r\n"));
return (XLLP_ACODEC_CONTROLLER_INTERFACE_TIMEOUT);
}
}
timer = 0;
(pDeviceContext->pCtrlReg)->ISR |= XLLP_ISR_ITE;
// STEP 2: Send the MSB
//EdbgOutputDebugString ( "Register Address %x \r\n",(temp & 0xff00)>>8);
(pDeviceContext->pCtrlReg)->IDBR = (temp & 0xff00)>>8; //LSB
(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,STEP2 %x \r\n",(pDeviceContext->pCtrlReg)->ISR);
return (XLLP_ACODEC_CONTROLLER_INTERFACE_TIMEOUT);
}
}
timer = 0;
(pDeviceContext->pCtrlReg)->ISR |= XLLP_ISR_ITE;
//STEP3: Now sending LSB
// EdbgOutputDebugString ( "Register Content %x \r\n",(temp &0x00ff));
(pDeviceContext->pCtrlReg)->IDBR = (temp &0x00ff); //LSB
(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 XllpWm8753CodecRead(XLLP_ACODEC_CONTEXT_T *pDeviceContext, XLLP_UINT16_T regOffset, XLLP_UINT16_T *regVal)
{
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 = (XLLP_ICR_UIE|XLLP_ICR_SCLEA);
//EdbgOutputDebugString ( "after setting ISAR\r\n");
// STEP 1: Send the WOlfson8753 address, Master Transmit mode
(pDeviceContext->pCtrlReg)->ICR = (XLLP_ICR_UIE | XLLP_ICR_SCLEA);
(pDeviceContext->pCtrlReg)->IDBR = 0x35; //WOLFSON8753_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 = regOffset;
// 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 = 0x33; //(WOLFSON8753_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 first byte operation
(pDeviceContext->pCtrlReg)->ICR =( XLLP_ICR_TB | 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);
*regVal = (XLLP_UINT16_T) (pDeviceContext->pCtrlReg)->IDBR;
// (pDeviceContext->pCtrlReg)->ICR &= ~(XLLP_ICR_STOP |XLLP_ISR_ACKNACK); //Clear STOP and ACKNAK bits
(pDeviceContext->pCtrlReg)->ICR = 0;
//STEP5: Read second BYTE 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);
*regVal |= (XLLP_UINT8_T) ( (pDeviceContext->pCtrlReg)->IDBR<<8);
(pDeviceContext->pCtrlReg)->ICR = 0;
return XLLP_ACODEC_SUCCESS;
}
XLLP_ACODEC_ERROR_T XllpWm8753CodecSpecificInit (XLLP_ACODEC_CONTEXT_T *pDeviceContext)
{
XllpWm8753CodecWrite(pDeviceContext, Wm8753_INPUTCTRL1, 0x10);
XllpWm8753CodecWrite(pDeviceContext, Wm8753_ADCINPUTMODE, 0x3d);
XllpWm8753CodecWrite(pDeviceContext,Wm8753_ADCCONTROL, 0x18);//0x1c); //ADC high pass filter cutoff 170HZ, enable high pass filter
XllpWm8753CodecWrite(pDeviceContext, Wm8753_PM1,0x1D0); //0xD0); //VREF,Voice codec enabled , MICB disabled
XllpWm8753CodecWrite(pDeviceContext,Wm8753_PM2, 0x1ff);// 0x9); //linemix and Left ADC enabled
XllpWm8753CodecWrite(pDeviceContext,Wm8753_PM3, 0x04); // 0x1ff); //all output enabled MONO1, LOUT1 enabled
XllpWm8753CodecWrite(pDeviceContext,Wm8753_PM4, 0x0f);//0x5); //Left and MONOmix enabled
XllpWm8753CodecWrite(pDeviceContext,Wm8753_MOUTMIX1, 0xD0);
XllpWm8753CodecWrite(pDeviceContext,Wm8753_MOUTMIX2, 0x0D); //enable voice DAC to Monomixer, 0dB
XllpWm8753CodecWrite(pDeviceContext, Wm8753_CLOCKCTRL, 0x189); //internal master clock for voice codec is PCMCLK, orginal is 0x4
XllpWm8753CodecWrite(pDeviceContext,Wm8753_PLL2CTRL1, 0x27); //PLL2 active and enabled, just for test purpose, should be 0x7
XllpWm8753CodecWrite(pDeviceContext,Wm8753_PLL2CTRL2, 0xe8); //N=7 k =23f548, F2=98.304MHZ
XllpWm8753CodecWrite(pDeviceContext,Wm8753_PLL2CTRL3, 0x1fa);
XllpWm8753CodecWrite(pDeviceContext,Wm8753_PLL2CTRL4, 0x148);
XllpWm8753CodecWrite(pDeviceContext, Wm8753_PCMAUDIOIF,0xf3); //0xb3); //16bit, DSP mode, modeB
XllpWm8753CodecWrite(pDeviceContext, Wm8753_IFCONTROL,0x3); //0x0); //VXFS input.
XllpWm8753CodecWrite(pDeviceContext, Wm8753_SAMPLERATECTRL1, 0x100); //voice codec sample rate is 256fs
XllpWm8753CodecWrite(pDeviceContext,Wm8753_LOUTMIX2, 0x100); //voice DAC to left mixer
return (XLLP_ACODEC_SUCCESS);
}
XLLP_ACODEC_ERROR_T XllpWm8753EnableSspPath (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 XllpWm8753DisableSspPath (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 XllpWm8753SetMasterVol(XLLP_ACODEC_CONTEXT_T *pDeviceContext,XLLP_UINT16_T GainInDb)
{
//stub
return (XLLP_ACODEC_SUCCESS);
}
XLLP_ACODEC_ERROR_T XllpWm8753GetInSampleRate(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 XllpWm8753GetOutSampleRate (XLLP_ACODEC_CONTEXT_T *pDeviceContext,XLLP_UINT16_T * 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 XllpWm8753SetInSampleRate(XLLP_ACODEC_CONTEXT_T *pDeviceContext,XLLP_UINT16_T 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 XllpWm8753SetOutSampleRate (XLLP_ACODEC_CONTEXT_T *pDeviceContext,XLLP_UINT16_T 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 XllpWm8753CodecSpecificDeinit (XLLP_ACODEC_CONTEXT_T *pDeviceContext)
{
return (XLLP_ACODEC_SUCCESS);
}
XLLP_ACODEC_ERROR_T XllpWm8753EnterEuipmentState(XLLP_ACODEC_CONTEXT_T *pDeviceContext, XLLP_ACODEC_EQUIPMENT_T State)
{
return (XLLP_ACODEC_SUCCESS);
}
XLLP_ACODEC_ERROR_T XllpWm8753QueryEquipmentState(XLLP_ACODEC_CONTEXT_T *pDeviceContext, XLLP_ACODEC_EQUIPMENT_T * State)
{
return (XLLP_ACODEC_SUCCESS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -