📄 hw_wm8750.c
字号:
/*********************************************************************************
* Copyright (C),2004-2005, Fuzhou Rockchip Co.,Ltd.
* All Rights Reserved
* V1.00
* FileName : Hw_wm8750.c
* Author : lzy
* Description:
* History :
* <author> <time> <version> <desc>
* lzy 07/6/29 1.0 ORG
*
$Log: hw_wm8750.c,v $
Revision 1.2 2008/06/19 04:43:30 Administrator
代码整理!
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.6 2007/11/17 06:13:19 Linzhengyuan
最大音量调整为40
Revision 1.5 2007/11/10 04:23:17 Huangxinyu
调试修改
Revision 1.4 2007/10/17 01:49:44 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==WM8750_CODEC)
#include "hw_wm8750.h"
#define Codec_IICAdress (0x1a<<1)
#define Codec_IICSpeed 200
static void CodecCommandSet(UINT32 uCmd, UINT32 uData)
{
UINT8 Codec_cmd, Codec_data;
I2C_Init(Codec_IICAdress, Codec_IICSpeed);
Codec_data = (UINT8)uData;
Codec_cmd = (UINT8)(((uCmd << 9) | uData) >> 8);
I2C_Write(Codec_cmd, &Codec_data, 1, NormalMode);
I2C_Deinit();
}
/* --------------------------------------------------------------------------
* 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)
{
CodecCommandSet(WM870_R5, 0x0008); // DAC soft mute
}
/* --------------------------------------------------------------------------
* FUNCTION: Codec_SetVolumet
* DESCRIPTION: set codec exit soft un MUTE
* INPUT: NONE
* RETURN: NONE
* NOTES: this function only used when DAC working
* -------------------------------------------------------------------------- */
void Codec_DACUnMute(void)
{
CodecCommandSet(WM870_R5, 0x0000); // DAC soft unmute
}
/* --------------------------------------------------------------------------
* FUNCTION: Codec_PowOnInitial:
*
* DESCRIPTION: Initial codec when power up
*
* RETURN: NONE
*
* NOTES:
* -------------------------------------------------------------------------- */
void Codec_PowerOnInitial(void)
{
IOMUX_SetI2SType(WM8750_CODEC);
SCU_SetCodecFreq(12000);
CodecCommandSet(WM870_R15, 0x012f); //software reset wm8750
CodecCommandSet(WM870_R27, 0x0040); // set VREF to output 40K
//2 setup output and DAC mute
CodecCommandSet(WM870_R10, WM_VOL_MUTE); // left DAC mute
CodecCommandSet(WM870_R11, WM_VOL_MUTE | WM_UPDATE_VOL); // right DAC mute
Codec_DACMute();
DelayMs_nops(10);
CodecCommandSet(WM870_R25, WM_VMID50k | WM_VREF); // setup Vmid and Vref, Vmid = 50k
DelayMs_nops(10);
CodecCommandSet(WM870_R26, 0x0000);
//2 setup digital audio interface
CodecCommandSet(WM870_R7, WM_MASTER_MODE | WM_I2S_MODE); //Audio inteface Data length and Data formate,16Bit
CodecCommandSet(WM870_R8, FREQ441kHz | WM_USB_MODE); //ADC and DAC sample frequence 44.118Khz,USB mode
//2 setup left and right MIXER
CodecCommandSet(WM870_R34, LD2LO | LO0DB);
CodecCommandSet(WM870_R37, RD2RO | RO0DB);
//1 setup no used register
CodecCommandSet(WM870_R35, 0x0070); // Right DAC to left MIXER: mute
CodecCommandSet(WM870_R36, 0x0070); //
CodecCommandSet(WM870_R38, 0x0070); //Mono out Mix Default: Mono Mixer no input, Lmixsel volume=0
CodecCommandSet(WM870_R39, 0x0070); //Mono out Mix Default: Mono Mixer no input, Rmixsel volume=0
CodecCommandSet(WM870_R40, 0x0000); // set output 2 mute
CodecCommandSet(WM870_R41, 0x0100); // set output 2 mute
CodecCommandSet(WM870_R24, 0x0004); // set output 3 ref
CodecCommandSet(EQ3D_enhance, EQ3D_disable);
}
/* --------------------------------------------------------------------------
* FUNCTION: Codec_RampUp:
*
* DESCRIPTION: Initial codec when power up
*
* RETURN: NONE
*
* NOTES:
* -------------------------------------------------------------------------- */
void Codec_RampUp(void)
{
}
/* --------------------------------------------------------------------------
* FUNCTION: Codec_DeIitial:
* DESCRIPTION: power off audio codec
* INPUT: NONE
* RETURN: NONE
* NOTES:
* -------------------------------------------------------------------------- */
void Codec_DeIitial(void)
{
CodecCommandSet(WM870_R25, WM_VREF);
CodecCommandSet(WM870_R26, 0x00);
}
/* --------------------------------------------------------------------------
* 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:
{
CodecCommandSet(WM870_R7, WM_MASTER_MODE | WM_I2S_MODE);
CodecCommandSet(WM870_R8, FREQ441kHz | WM_USB_MODE);
CodecCommandSet(WM870_R34, LD2LO | LO0DB);
CodecCommandSet(WM870_R37, RD2RO | RO0DB);
CodecCommandSet(WM870_R10, WM_VOL_0DB);
CodecCommandSet(WM870_R11, WM_VOL_0DB | WM_UPDATE_VOL);
CodecCommandSet(WM870_R25, WM_VMID50k | WM_VREF);
CodecCommandSet(WM870_R26, WM_DACL | WM_DACR | WM_LOUT1 | WM_ROUT1 | WM_OUT3);
}
break;
case Codec_FMin:
{
CodecCommandSet(WM870_R34, LI2LO | LO0DB);
CodecCommandSet(WM870_R37, RI2RO | RO0DB);
CodecCommandSet(WM870_R25, WM_VMID50k | WM_VREF);
CodecCommandSet(WM870_R26, WM_LOUT1 | WM_ROUT1 | WM_OUT3);
}
break;
case Codec_FMADC:
{
CodecCommandSet(WM870_R0, 0x003f); //Left channel PGA 0dB
CodecCommandSet(WM870_R1, 0x013f); //Left channel PGA 0dB
CodecCommandSet(WM870_R21, 0x00c3); //Left digital ADC 0dB
CodecCommandSet(WM870_R22, 0x01c3); //Right digital ADC 0dB
CodecCommandSet(WM870_R31, 0x0000);
CodecCommandSet(WM870_R32, 0x0000); //Left ADC select = Linput0 MICBoost = 0dB
CodecCommandSet(WM870_R33, 0x0000); //Left ADC select = Linput3 MICBoost = 0dB
CodecCommandSet(WM870_R34, LI2LO | LO0DB);
CodecCommandSet(WM870_R37, RI2RO | RO0DB);
CodecCommandSet(WM870_R25, WM_VMID50k | WM_VREF | WM_ADCL | WM_ADCR);
CodecCommandSet(WM870_R26, WM_LOUT1 | WM_ROUT1 | WM_OUT3);
}
break;
case Codec_LineADC:
{
CodecCommandSet(WM870_R0, 0x0057); //Left channel PGA 0dB
CodecCommandSet(WM870_R1, 0x0157); //Left channel PGA 0dB
CodecCommandSet(WM870_R21, 0x00c3); //Left digital ADC 0dB
CodecCommandSet(WM870_R22, 0x01c3); //Right digital ADC 0dB
CodecCommandSet(WM870_R31, 0x0000);
CodecCommandSet(WM870_R32, 0x0000); //Left ADC select = Linput0 MICBoost = 0dB
CodecCommandSet(WM870_R33, 0x0000); //Left ADC select = Linput0 MICBoost = 0dB
CodecCommandSet(WM870_R34, LO0DB);
CodecCommandSet(WM870_R37, RO0DB);
CodecCommandSet(WM870_R25, WM_VMID50k | WM_VREF | WM_ADCL | WM_ADCR);
CodecCommandSet(WM870_R26, 0x0000);
}
break;
case Codec_MICAdc:
{
CodecCommandSet(WM870_R0, 0x0117); //Left channel PGA 0dB
CodecCommandSet(WM870_R1, 0x0117); //Left channel PGA 0dB
CodecCommandSet(WM870_R21, 0x01c3); //Left digital ADC 0dB
CodecCommandSet(WM870_R22, 0x01c3); //Right digital ADC 0dB
CodecCommandSet(WM870_R10, 0x01ff); //Left digital DAC 0dB
CodecCommandSet(WM870_R11, 0x01ff); //Right digital DAC 0dB
CodecCommandSet(WM870_R31, 0x0040); // adc use mono mix, select left adc
CodecCommandSet(WM870_R32, 0x00a0); //Left ADC select = Linput3 MICBoost = 20dB
CodecCommandSet(WM870_R33, 0x0080); //Left ADC select = Linput3 MICBoost = 00dB
CodecCommandSet(WM870_R25, WM_VMID50k | WM_VREF | WM_AINL | WM_ADCL | WM_MICB); //Left ADC and Left PGA power on,Right ADC and Right PGA power off
CodecCommandSet(WM870_R26, 0x00);
}
break;
case Codec_Standby:
{
Codec_DACMute();
CodecCommandSet(WM870_R25, WM_VMID50k | WM_VREF);
CodecCommandSet(WM870_R26, 0x00);
}
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(WM870_R8, FREQ8kHz | WM_USB_MODE); //12MHZ,8KHZ
break;
case FS_11025Hz:
CodecCommandSet(WM870_R8, FREQ11025kHz | WM_USB_MODE); //12MHZ,11.025K
break;
case FS_12KHz:
CodecCommandSet(WM870_R8, FREQ12kHz | WM_USB_MODE); //12MHZ,12K
break;
case FS_16KHz:
CodecCommandSet(WM870_R8, FREQ16kHz | WM_USB_MODE); //12MHZ,16K
break;
case FS_22050Hz:
CodecCommandSet(WM870_R8, FREQ2205kHz | WM_USB_MODE); //12MHZ,22.05K
break;
case FS_24KHz:
CodecCommandSet(WM870_R8, FREQ24kHz | WM_USB_MODE); //12MHZ,24K
break;
case FS_32KHz:
CodecCommandSet(WM870_R8, FREQ32kHz | WM_USB_MODE); //12MHZ,32K
break;
case FS_48KHz:
CodecCommandSet(WM870_R8, FREQ48kHz | WM_USB_MODE); //12MHZ,48K
break;
case FS_44100Hz:
default:
CodecCommandSet(WM870_R8, FREQ441kHz | WM_USB_MODE); //12MHZ,44.1KHZ
break;
}
}
}
/* --------------------------------------------------------------------------
* FUNCTION: Codec_SetVolumet:
* DESCRIPTION: set codec output volume
* INPUT: volume
* RETURN: NONE
* NOTES: volume = 0 mean mute,
* -------------------------------------------------------------------------- */
void Codec_SetVolumet(unsigned int Volume)
{
UINT32 Vol ;
if (Volume > MAX_VOLUME)
Volume = MAX_VOLUME;
Vol = 41 + (Volume << 1);
if (Volume == 0)
{
Vol = 0;
}
// 最后几个音量步进为1
if (Volume <= 7) Vol = 47 + Volume;
CodecCommandSet(WM870_R2, Vol | 0x0080); // set output 1 volume
CodecCommandSet(WM870_R3, Vol | 0x0180);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -