📄 hw_rockcodec.c
字号:
/*********************************************************************************
* Copyright (C),2004-2005, Fuzhou Rockchip Co.,Ltd.
* All Rights Reserved
* V1.00
* FileName : Hw_codec.c
* Author : lzy
* Description:
* History :
* <author> <time> <version> <desc>
* lzy 07/6/29 1.0 ORG
*
$Log: HW_rockcodec.c,v $
Revision 1.3 2008/06/19 04:43:30 Administrator
代码整理!
Revision 1.2 2008/05/29 12:06:05 HXY
增加有无电容输出的区分
Revision 1.1.1.1 2008/05/07 04:15:08 Administrator
no message
Revision 1.1.1.1 2008/03/06 13:29:04 Lingzhaojun
no message
Revision 1.1.1.1 2007/12/21 02:34:33 Lingzhaojun
12.21
Revision 1.2 2007/12/14 15:09:29 Hanjiang
rm972 pp后的版本上传
Revision 1.1.1.1 2007/12/11 14:19:28 cvsadmin
no message
Revision 1.2 2007/12/04 13:46:03 Fangzhenfu
新 SDK 整合完后上传!!!
Revision 1.1.1.1 2007/12/01 01:30:06 Lingzhaojun
no message
Revision 1.8 2007/11/26 14:36:00 Huangxinyu
针对VX979的修改
Revision 1.7 2007/11/21 09:09:07 Huangzufang
录音提交
Revision 1.6 2007/11/17 06:12:55 Linzhengyuan
修改Codec_mode 更改的bug,最大音量调整为40
Revision 1.5 2007/11/10 04:22:42 Huangxinyu
调试修改
Revision 1.4 2007/10/17 01:48:16 Huangxinyu
修改发现的bug
Revision 1.3 2007/10/15 09:03:44 Huangxinyu
根据RK27提交修改driver
Revision 1.2 2007/10/08 02:38:40 Lingzhaojun
添加版本自动注释脚本
*********************************************************************************/
#include "hw_include.h"
#if (CODEC_TYPE == INTERNAL_CODEC)
#include "Hw_rockcodec.h"
#define Codec_IICAdress (0x27<<1)
#define Codec_IICSpeed 200
#define MAX_OUTLEVEL 0x09
static UINT32 Codec_mode;
static void CodecCommandSet(UINT8 uCmd, UINT8 uData)
{
I2C_Init(Codec_IICAdress, Codec_IICSpeed);
I2C_Write(uCmd, &uData, 1, NormalMode);
I2C_Deinit();
}
void CodecGainSet(unsigned char i) // add by huang hzf
{
switch (i)
{
case 1:
CodecCommandSet(CGR10, 0x00);
break;
case 2:
CodecCommandSet(CGR10, 0x33);
break;
case 3:
CodecCommandSet(CGR10, 0x77);
break;
case 4:
CodecCommandSet(CGR10, 0xCC);
break;
case 5:
CodecCommandSet(CGR10, 0xFF);
break;
default:
break;
}
}
/* --------------------------------------------------------------------------
* FUNCTION: Codec_RampUp:
*
* DESCRIPTION: Initial codec when power up
*
* RETURN: NONE
*
* NOTES:
* -------------------------------------------------------------------------- */
void Codec_RampUp(void)
{
#if ( BOARDTYPE == RK2706_VX979)
GPIO_SetPinLevel(GPIOPortC_Pin5, GPIO_HIGH);
#endif
}
/* --------------------------------------------------------------------------
* FUNCTION: Codec_PowOnInitial:
*
* DESCRIPTION: Initial codec when power up
*
* RETURN: NONE
*
* NOTES:
* -------------------------------------------------------------------------- */
void Codec_PowerOnInitial(void)
{
IOMUX_SetI2SType(INTERNAL_CODEC);
// SB =0 , SB_SLEEP = 1 set codec normal work
CodecCommandSet(PMR2, SB_SLEEP | GIM | SB_MC); // set codec sleep
CodecCommandSet(AICR, DAC_SERIAL | ADC_SERIAL | DAC_I2S | ADC_I2S);
CodecCommandSet(CR1, SB_MICBIAS | DAC_MUTE | DACSEL); //
CodecCommandSet(CR2, DAC_ADWL16 | ADC_ADWL16 | ADC_HPF);
CodecCommandSet(CCR1, CRYSTAL_12M); // 12M input
CodecCommandSet(CCR2, (FREQ441kHz << 4) | FREQ441kHz); //44.1KHZ for ADC and DAC
#if defined(CODEC_NOCAPOUT)
CodecCommandSet(CRR, RATIO_2 | KFast_8 | TRESH_128);
#else
CodecCommandSet(CRR, RATIO_8 | KFast_32 | TRESH_128);
#endif
Codec_SetVolumet(0);
CodecCommandSet(CGR6, 0x1f | GAIN_BYLEFT); // set mic input volume GOSL and GOSR CGR7 = CGR6
CodecCommandSet(TR1, NOSC);
// CodecCommandSet(ICR, 0xff); // mask all interrrupt
CodecCommandSet(PMR1, SB_OUT | SB_MIX | SB_ADC | SB_IN1 | SB_IN2 | SB_MIC | SB_IND);
DelayMs_nops(10);
// SB =0 SB_SLEEP = 0
CodecCommandSet(PMR2, GIM | SB_MC);
DelayMs_nops(10);
// SB_DAC = 0, set DAC active
CodecCommandSet(PMR1, SB_OUT | SB_MIX | SB_ADC | SB_IN1 | SB_IN2 | SB_MIC | SB_IND);
DelayMs_nops(10);
// SB_MIX = 0, set mixer active
CodecCommandSet(PMR1, SB_OUT | SB_ADC | SB_IN1 | SB_IN2 | SB_MIC | SB_IND);
DelayMs_nops(10);
// SB_out = 0, set output stage active
CodecCommandSet(PMR1, SB_ADC | SB_IN1 | SB_IN2 | SB_MIC | SB_IND);
// Codec_RampUp();
// DelayMs_nops(10);
}
/* --------------------------------------------------------------------------
* FUNCTION: Codec_DeIitial:
* DESCRIPTION: power off audio codec
* INPUT: NONE
* RETURN: NONE
* NOTES:
* -------------------------------------------------------------------------- */
void Codec_DeIitial(void)
{
#if defined(CODEC_NOCAPOUT)
CodecCommandSet(PMR2, SB | SB_MC | SB_SLEEP);
#else
CodecCommandSet(PMR2, SB | SB_SLEEP);
#endif
}
/* --------------------------------------------------------------------------
* FUNCTION: Codec_SetMode:
*
* DESCRIPTION: setup codec input/output to application mode
* INPUT: CodecMode_en_t Codec_DACout/Codec_FMin/Codec_LineADC/Codec_MICAdc/Codec_Standby
* RETURN: NONE
* NOTES: if exit from application, like FM or MIC , please set codec to standby mode
* -------------------------------------------------------------------------- */
void Codec_SetMode(CodecMode_en_t Codecmode)
{
switch (Codecmode)
{
case Codec_DACout:
{
Codec_mode = SB_MICBIAS | DACSEL;
CodecCommandSet(CR1, Codec_mode | DAC_MUTE | HP_DIS);
USDELAY(10);
CodecCommandSet(PMR1, SB_ADC | SB_IN1 | SB_IN2 | SB_MIC | SB_IND);
#if defined(CODEC_NOCAPOUT)
CodecCommandSet(PMR2, GIM);
#else
CodecCommandSet(PMR2, GIM | SB_MC);
#endif
CodecCommandSet(CR1, Codec_mode | DAC_MUTE);
}
break;
case Codec_FMin:
{
Codec_mode = SB_MICBIAS | BYPASS1;
CodecCommandSet(CR1, Codec_mode | DAC_MUTE);
CodecCommandSet(PMR1, SB_DAC | SB_ADC | SB_IN2 | SB_MIC | SB_IND);
#if defined(CODEC_NOCAPOUT)
CodecCommandSet(PMR2, GIM);
#else
CodecCommandSet(PMR2, GIM | SB_MC);
#endif
}
break;
case Codec_FMADC:
{
Codec_mode = SB_MICBIAS | BYPASS1;
CodecCommandSet(CR1, Codec_mode | DAC_MUTE);
CodecCommandSet(CR2, DAC_ADWL16 | ADC_ADWL16 | ADC_HPF | INSEL_LINE1);
CodecCommandSet(CGR10, 0x00); // set FM ADC input gain
CodecCommandSet(PMR1, SB_DAC | SB_IN2 | SB_MIC | SB_IND);
#if defined(CODEC_NOCAPOUT)
CodecCommandSet(PMR2, GIM);
#else
CodecCommandSet(PMR2, GIM | SB_MC);
#endif
}
break;
case Codec_LineADC:
{
Codec_mode = SB_MICBIAS | BYPASS1 | HP_DIS;
CodecCommandSet(CR1, Codec_mode | DAC_MUTE);
USDELAY(10);
CodecCommandSet(CR2, DAC_ADWL16 | ADC_ADWL16 | ADC_HPF | INSEL_LINE1);
CodecCommandSet(CGR10, 0x00); // set line in ADC input gain
CodecCommandSet(PMR1, SB_DAC | SB_IN2 | SB_MIC | SB_IND); //SB_MIX|
#if defined(CODEC_NOCAPOUT)
CodecCommandSet(PMR2, GIM);
#else
CodecCommandSet(PMR2, GIM | SB_MC);
#endif
Codec_SetVolumet(0);
}
break;
case Codec_MICAdc:
{
Codec_mode = SB_MICBIAS | HP_DIS; //SIDETONE|
CodecCommandSet(CR1, Codec_mode | DAC_MUTE);
USDELAY(10);
CodecCommandSet(CR2, DAC_ADWL16 | ADC_ADWL16 | ADC_HPF | INSEL_MIC);
// remove the setting, because CGR10 will be set at RECWIN.c, lzy 4.14
// CodecCommandSet(CGR10, 0x33); // set MIC input gain GIL and GIR
CodecCommandSet(PMR1, SB_DAC | SB_IN1 | SB_IN2 | SB_IND); //SB_MIX|
#if defined(CODEC_NOCAPOUT)
CodecCommandSet(PMR2, GIM);
#else
CodecCommandSet(PMR2, GIM | SB_MC);
#endif
Codec_SetVolumet(0);
}
break;
case Codec_Standby:
{
#if ( BOARDTYPE == RK2706_VX979)
GPIO_SetPinLevel(GPIOPortC_Pin5, GPIO_LOW);
USDELAY(10);
#endif
Codec_SetVolumet(0);
Codec_mode = SB_MICBIAS | DAC_MUTE;
CodecCommandSet(CR1, Codec_mode);
USDELAY(1000);
CodecCommandSet(PMR1, SB_OUT | SB_ADC | SB_IN1 | SB_IN2 | SB_MIC | SB_IND);
}
break;
}
}
/* --------------------------------------------------------------------------
* FUNCTION: Codec_SetSampleRate:
* DESCRIPTION: setup codec sample rate both for ADC and DAC application
* INPUT: CodecFS_en_t 8kHz ~ 48KHz
* RETURN: NONE
* NOTES:
* -------------------------------------------------------------------------- */
void Codec_SetSampleRate(CodecFS_en_t CodecFS)
{
if (CodecFS < FSSTOP)
{
switch (CodecFS)
{
case FS_8000Hz:
CodecCommandSet(CCR2, (FREQ8kHz << 4) | FREQ8kHz); //8KHZ
break;
case FS_11025Hz:
CodecCommandSet(CCR2, (FREQ11025kHz << 4) | FREQ11025kHz); //11.025K
break;
case FS_12KHz:
CodecCommandSet(CCR2, (FREQ12kHz << 4) | FREQ12kHz); //12K
break;
case FS_16KHz:
CodecCommandSet(CCR2, (FREQ16kHz << 4) | FREQ16kHz); //16K
break;
case FS_22050Hz:
CodecCommandSet(CCR2, (FREQ2205kHz << 4) | FREQ2205kHz); //22.05K
break;
case FS_24KHz:
CodecCommandSet(CCR2, (FREQ24kHz << 4) | FREQ24kHz); //24K
break;
case FS_32KHz:
CodecCommandSet(CCR2, (FREQ32kHz << 4) | FREQ32kHz); //32K
break;
case FS_44100Hz:
CodecCommandSet(CCR2, (FREQ441kHz << 4) | FREQ441kHz); //44.1KHZ
break;
case FS_48KHz:
CodecCommandSet(CCR2, (FREQ48kHz << 4) | FREQ48kHz); //48K
break;
}
}
}
/* --------------------------------------------------------------------------
* FUNCTION: Codec_SetVolumet:
* DESCRIPTION: set codec output volume
* INPUT: volume
* RETURN: NONE
* NOTES: volume = 0 mean mute,
* -------------------------------------------------------------------------- */
void Codec_SetVolumet(unsigned int Volume)
{
UINT16 vol, vol_out, vol_in ;
if (Volume > MAX_VOLUME) Volume = MAX_VOLUME;
if (Volume == 0)
{
Codec_mode |= HP_DIS;
CodecCommandSet(CR1, Codec_mode);
}
else
{
Codec_mode &= ~HP_DIS;
CodecCommandSet(CR1, Codec_mode);
vol = MAX_VOLUME - Volume;
vol += MAX_OUTLEVEL;
if (vol >= 31)
{
vol_out = 31; // 0x1f
// 最大音量调节范围只有46-MAX_OUTLEVEL = 36,这里只好将最小几个相同
if (vol > 46)
vol_in = 15;
else
vol_in = vol - 31;
}
else
{
vol_in = 0x0;
vol_out = vol;
}
CodecCommandSet(CGR8, vol_out | GAIN_BYLEFT); // set output volume GOL and GOL, CGR9= CGR8
CodecCommandSet(CGR1, (vol_in << 4) | vol_in); // set DAC input volume GODL and GODR
CodecCommandSet(CGR2, (vol_in + 4) | GAIN_BYLEFT); // set line1 input volume GOBL1 and GOBR1, CGR3 = CGR2
CodecCommandSet(CGR4, (vol_in + 4) | GAIN_BYLEFT); // set line2 input volume GOBL2 and GOBR2 CGR5 = CGR4
// mic output gain is no setup because we no using MIC monitor function
// CodecCommandSet(CGR6, (vol_in + 4) |GAIN_BYLEFT); // set mic input volume GOSL and GOSR CGR7 = CGR6
}
}
/* --------------------------------------------------------------------------
* FUNCTION: Codec_DACMute
* DESCRIPTION: set codec DAC soft mute
* INPUT: NONE
* RETURN: NONE
* NOTES: this function only used when DAC working
* -------------------------------------------------------------------------- */
void Codec_DACMute(void)
{
Codec_mode |= DAC_MUTE;
CodecCommandSet(CR1, DAC_MUTE | Codec_mode); // DAC soft mute
}
/* --------------------------------------------------------------------------
* FUNCTION: Codec_SetVolumet
* DESCRIPTION: set codec exit soft MUTE
* INPUT: NONE
* RETURN: NONE
* NOTES: this function only used when DAC working
* -------------------------------------------------------------------------- */
void Codec_DACUnMute(void)
{
Codec_mode &= ~DAC_MUTE;
CodecCommandSet(CR1, Codec_mode); // DAC soft un mute
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -