📄 wm8753.c
字号:
/*-----------------------------------------------------------------------------
* Copyright (c) Wolfson Microelectronics plc. All rights reserved.
*
* This software as well as any related documentation 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 Wolfson Microelectronics plc. Wolfson Microelectronics plc
* 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 Wolfson Microelectronics plc.
*
* $Id: WM8753.c 3998 2006-10-03 13:00:37Z fb $
*
* This file specifies the per-device specific behaviour for the WM8753.
*
* Warning:
* This driver is specifically written for Wolfson Codecs. It is not a
* general CODEC device driver.
*
* --------------------------------------------------------------------------*/
/*
* Include files
*/
#include "WMCommon.h"
#include "WMGPIO.h"
#include "WM8753RegisterDefs.h"
#include "WM8753Power.h"
#include "WM8753Audio.h"
#include "WM8753AudioPaths.h"
#if WM8753_FAMILY
/*
* Global definitions
*/
#if WM_USE_SHADOW_REGISTERS
/*
* Shadow registers
*/
static const WM_SHADOW_REGISTERS s_WM8753Shadowed[] =
{
{ WM8753_DAC_CONTROL, 0x0008 }, /* 0x01 */
{ WM8753_ADC_CONTROL, 0x0000 }, /* 0x02 */
{ WM8753_VOICE_AUDIO_INTERFACE, 0x000A }, /* 0x03 */
{ WM8753_HIFI_AUDIO_INTERFACE, 0x000A }, /* 0x04 */
{ WM8753_INTERFACE_CONTROL, 0x0033 }, /* 0x05 */
{ WM8753_SAMPLE_RATE_CTRL_1, 0x0000 }, /* 0x06 */
{ WM8753_SAMPLE_RATE_CTRL_2, 0x0007 }, /* 0x07 */
{ WM8753_LEFT_DAC_VOLUME, 0x00FF }, /* 0x08 */
{ WM8753_RIGHT_DAC_VOLUME, 0x00FF }, /* 0x09 */
{ WM8753_BASS_CONTROL, 0x000F }, /* 0x0A */
{ WM8753_TREBLE_CONTROL, 0x000F }, /* 0x0B */
{ WM8753_ALC_1, 0x007B }, /* 0x0C */
{ WM8753_ALC_2, 0x0000 }, /* 0x0D */
{ WM8753_ALC_3, 0x0032 }, /* 0x0E */
{ WM8753_NOISE_GATE, 0x0000 }, /* 0x0F */
{ WM8753_LEFT_ADC_VOLUME, 0x00C3 }, /* 0x10 */
{ WM8753_RIGHT_ADC_VOLUME, 0x00C3 }, /* 0x11 */
{ WM8753_ADD_CONTROL_1, 0x00C0 }, /* 0x12 */
{ WM8753_3D_CONTROL, 0x0000 }, /* 0x13 */
{ WM8753_PWR_MGMT_1, 0x0000 }, /* 0x14 */
{ WM8753_PWR_MGMT_2, 0x0000 }, /* 0x15 */
{ WM8753_PWR_MGMT_3, 0x0000 }, /* 0x16 */
{ WM8753_PWR_MGMT_4, 0x0000 }, /* 0x17 */
{ WM8753_ID_REGISTER, 0x0000 }, /* 0x18 */
{ WM8753_INTERUPT_POLARITY, 0x0000 }, /* 0x19 */
{ WM8753_INTERUPT_ENABLE, 0x0000 }, /* 0x1A */
{ WM8753_GPIO_CONTROL_1, 0x0000 }, /* 0x1B */
{ WM8753_GPIO_CONTROL_2, 0x0000 }, /* 0x1C */
{ WM8753_RECORD_MIX_1, 0x0055 }, /* 0x20 */
{ WM8753_RECORD_MIX_2, 0x0005 }, /* 0x21 */
{ WM8753_LEFT_OUT_MIX_1, 0x0050 }, /* 0x22 */
{ WM8753_LEFT_OUT_MIX_2, 0x0055 }, /* 0x23 */
{ WM8753_RIGHT_OUT_MIX_1, 0x0050 }, /* 0x24 */
{ WM8753_RIGHT_OUT_MIX_2, 0x0055 }, /* 0x25 */
{ WM8753_MONO_OUT_MIX_1, 0x0050 }, /* 0x26 */
{ WM8753_MONO_OUT_MIX_2, 0x0055 }, /* 0x27 */
{ WM8753_LOUT1_VOLUME, 0x0079 }, /* 0x28 */
{ WM8753_ROUT1_VOLUME, 0x0079 }, /* 0x29 */
{ WM8753_LOUT2_VOLUME, 0x0079 }, /* 0x2A */
{ WM8753_ROUT2_VOLUME, 0x0079 }, /* 0x2B */
{ WM8753_MONOOUT_VOLUME, 0x0079 }, /* 0x2C */
{ WM8753_OUTPUT_CONTROL, 0x0000 }, /* 0x2D */
{ WM8753_ADC_INPUT_MODE, 0x0000 }, /* 0x2E */
{ WM8753_INPUT_CONTROL_1, 0x0000 }, /* 0x2F */
{ WM8753_INPUT_CONTROL_2, 0x0000 }, /* 0x30 */
{ WM8753_LEFT_INPUT_VOLUME, 0x0097 }, /* 0x31 */
{ WM8753_RIGHT_INPUT_VOLUME, 0x0097 }, /* 0x32 */
{ WM8753_MIC_BIAS_COMP_CONTROL, 0x0000 }, /* 0x33 */
{ WM8753_CLOCK_CONTROL, 0x0004 }, /* 0x34 */
{ WM8753_PLL1_CONTROL_1, 0x0000 }, /* 0x35 */
{ WM8753_PLL1_CONTROL_2, 0x0083 }, /* 0x36 */
{ WM8753_PLL1_CONTROL_3, 0x0024 }, /* 0x37 */
{ WM8753_PLL1_CONTROL_4, 0x01BA }, /* 0x38 */
{ WM8753_PLL2_CONTROL_1, 0x0000 }, /* 0x39 */
{ WM8753_PLL2_CONTROL_2, 0x0083 }, /* 0x3A */
{ WM8753_PLL2_CONTROL_3, 0x0024 }, /* 0x3B */
{ WM8753_PLL2_CONTROL_4, 0x01BA }, /* 0x3C */
{ WM8753_BIAS_CONTROL, 0x0000 }, /* 0x3D */
{ WM8753_ADD_CONTROL_2, 0x0000 } /* 0x3F */
};
#endif /* WM_USE_SHADOW_REGISTERS */
/*******************************************************************************
* Action tables for the profiles.
*/
/*
* HiFi Playback
*
* Playback from I2S to all outputs.
*/
static const WM_ACTION s_HiFiPlaybackActions[] =
{
/* Set MONO2 to inverse of MONO1 */
WMACT_SET_FIELD( WM8753_OUTPUT_CONTROL,
WM8753_MONO2SEL_MONO1INV,
WM8753_MONO2SEL_MASK
),
/* Route HiFi DAC to all outputs */
WMACT_SET_BITS( WM8753_LEFT_OUT_MIX_1, WM8753_DAC2OUT ), /* Set LD2LO */
WMACT_SET_BITS( WM8753_RIGHT_OUT_MIX_1, WM8753_DAC2OUT ), /* Set RD2RO */
WMACT_SET_BITS( WM8753_MONO_OUT_MIX_1, WM8753_DAC2OUT ), /* Set LD2MO */
WMACT_SET_BITS( WM8753_MONO_OUT_MIX_2, WM8753_DAC2OUT ), /* Set RD2MO */
/* Enable zero-cross on outputs */
WMACT_SET_BITS( WM8753_LOUT1_VOLUME, WM8753_OUTVOL_ZEROCROSS ),
WMACT_SET_BITS( WM8753_ROUT1_VOLUME, WM8753_OUTVOL_ZEROCROSS | WM8753_VOLUME_UPDATE ),
WMACT_SET_BITS( WM8753_LOUT2_VOLUME, WM8753_OUTVOL_ZEROCROSS ),
WMACT_SET_BITS( WM8753_ROUT2_VOLUME, WM8753_OUTVOL_ZEROCROSS | WM8753_VOLUME_UPDATE ),
WMACT_SET_BITS( WM8753_MONOOUT_VOLUME, WM8753_OUTVOL_ZEROCROSS ),
/* Power up and start streaming to HiFi DAC */
WMACT_ENABLE_STREAM( WM_STREAM_HIFI_OUT ),
WMACT_POWERUP( WM_POWER_AUDIO_HIFI_DAC | WM_POWER_OUTPUTS | WM_POWER_MIXERS ),
};
/*
* Voice Playback
*
* Playback from PCM to all outputs.
*/
static const WM_ACTION s_VoicePlaybackActions[] =
{
/* Set MONO2 to inverse of MONO1 */
WMACT_SET_FIELD( WM8753_OUTPUT_CONTROL,
WM8753_MONO2SEL_MONO1INV,
WM8753_MONO2SEL_MASK
),
/* Route VxDAC to all outputs */
WMACT_SET_BITS( WM8753_LEFT_OUT_MIX_2, WM8753_VXDAC2OUT ), /* Set VXD2LO */
WMACT_SET_BITS( WM8753_RIGHT_OUT_MIX_2, WM8753_VXDAC2OUT ), /* Set VXD2RO */
WMACT_SET_BITS( WM8753_MONO_OUT_MIX_2, WM8753_VXD2MO ), /* Set VXD2MO */
/* Enable zero-cross on outputs */
WMACT_SET_BITS( WM8753_LOUT1_VOLUME, WM8753_OUTVOL_ZEROCROSS ),
WMACT_SET_BITS( WM8753_ROUT1_VOLUME, WM8753_OUTVOL_ZEROCROSS | WM8753_VOLUME_UPDATE ),
WMACT_SET_BITS( WM8753_LOUT2_VOLUME, WM8753_OUTVOL_ZEROCROSS ),
WMACT_SET_BITS( WM8753_ROUT2_VOLUME, WM8753_OUTVOL_ZEROCROSS | WM8753_VOLUME_UPDATE ),
WMACT_SET_BITS( WM8753_MONOOUT_VOLUME, WM8753_OUTVOL_ZEROCROSS ),
/* Power up and start streaming to Voice DAC */
WMACT_ENABLE_STREAM( WM_STREAM_VOICE_OUT ),
WMACT_POWERUP( WM_POWER_AUDIO_VOICE_DAC | WM_POWER_OUTPUTS | WM_POWER_MIXERS ),
};
/*
* ALCRecord
*
* Record from ALC. This is a basic profile used by the other record profiles.
*/
static const WM_ACTION s_ALCRecordActions[] =
{
/* Select LPGA (ALC) on left, and record from left only. */
WMACT_SET_FIELD( WM8753_ADC_INPUT_MODE,
WM8753_LEFTADCSEL_PGA | WM8753_MONOMIX_STEREO,
WM8753_LEFTADCSEL_MASK | WM8753_MONOMIX_MASK
),
WMACT_SET_FIELD( WM8753_ADC_CONTROL,
WM8753_DATSEL_L_L,
WM8753_DATSEL_MASK
),
/* Unmute left PGA */
WMACT_SET_FIELD( WM8753_LEFT_INPUT_VOLUME,
0 | WM8753_VOLUME_UPDATE,
WM8753_INVOL_MUTE | WM8753_VOLUME_UPDATE
),
#ifdef WM_ENABLE_SIDETONE
/* Send sidetone to LOUT/ROUT */
WMACT_POWERUP( WM_POWER_OUTPUTS ),
WMACT_SET_BITS( WM8753_LEFT_OUT_MIX_2, WM8753_ST2OUT ),
WMACT_SET_BITS( WM8753_RIGHT_OUT_MIX_2, WM8753_ST2OUT ),
#endif /* WM_ENABLE_SIDETONE */
/* Configure ALC */
WMACT_WRITE( WM8753_ALC_1, WM8753_ALC1_VOICE | WM8753_ALC_LEFT | WM8753_ALC_RIGHT ),
WMACT_SET_FIELD( WM8753_ALC_2, WM8753_ALC2_VOICE, WM8753_ALC2_PROFILE_MASK ),
WMACT_WRITE( WM8753_ALC_3, WM8753_ALC3_VOICE ),
WMACT_WRITE( WM8753_NOISE_GATE, WM8753_NOISE_GATE_VOICE ),
/* Start streaming from ADC via default input stream */
WMACT_ENABLE_STREAM( WM_STREAM_DEFAULT_INPUT ),
/* Finally power up the ADC and mixers */
WMACT_POWERUP( WM_POWER_AUDIO_ADCS | WM_POWER_MIXERS ),
};
/*
* DirectLineInRecord
*
* Direct Line from the input source. This is a basic profile used by the Line In record profiles.
*/
static const WM_ACTION s_DirectLineInRecordActions[] =
{
#ifdef WM_ENABLE_SIDETONE
/* LM Signal to Left Mixer 0dB */
WMACT_WRITE( WM8753_LEFT_OUT_MIX_1, WM8753_MIX2OUT | WM8753_MIXVOL_0DB ),
/* RM Signal to Right Mixer 0dB */
WMACT_WRITE( WM8753_RIGHT_OUT_MIX_1, WM8753_MIX2OUT | WM8753_MIXVOL_0DB ),
/* Power up the mixers and the outputs */
WMACT_POWERUP( WM_POWER_OUTPUTS ),
#endif /* WM_ENABLE_SIDETONE */
/* Power up the mixers and the outputs */
WMACT_POWERUP( WM_POWER_MIXERS ),
/* Start streaming from ADC via default input stream */
WMACT_ENABLE_STREAM( WM_STREAM_DEFAULT_INPUT ),
};
/*
* LineRecord
*
* Record from LINES to I2S.
*/
static const WM_ACTION s_LineRecordActions[] =
{
/* Set line mix to be LINE1 + LINE2, LM/RM/MM to Line */
WMACT_SET_FIELD( WM8753_INPUT_CONTROL_1,
WM8753_LEFTMUXSEL_LINE1 |
WM8753_RIGHTMUXSEL_LINE2 |
WM8753_MONOMUXSEL_LINE |
WM8753_LINEMIXSEL_MIX,
WM8753_LEFTMUXSEL_MASK |
WM8753_RIGHTMUXSEL_MASK |
WM8753_MONOMUXSEL_MASK |
WM8753_LINEMIXSEL_MASK
),
/* Set ADC Input select to LINE1/2 Mono */
WMACT_SET_FIELD( WM8753_ADC_INPUT_MODE,
WM8753_LEFTADCSEL_LINE1 |
WM8753_RIGHTADCSEL_LINE2 |
WM8753_MONOMIX_DIGITAL,
WM8753_LEFTADCSEL_MASK |
WM8753_RIGHTADCSEL_MASK |
WM8753_MONOMIX_MASK
),
/* Set Left ADC Volume to 0dB */
WMACT_WRITE( WM8753_LEFT_ADC_VOLUME, WM8753_ADCVOL_0DB ),
/* Set Right ADC Volume to 0dB */
WMACT_WRITE( WM8753_RIGHT_ADC_VOLUME, WM8753_ADCVOL_0DB | WM8753_VOLUME_UPDATE ),
/* left data = left ADC; right data = right ADC */
WMACT_SET_FIELD( WM8753_ADC_CONTROL,
WM8753_DATSEL_L_L,
WM8753_DATSEL_MASK
),
#if WM_ENABLE_ALC
/* Send LINES to the ALC and MIC mux (sidetone) */
WMACT_SET_FIELD( WM8753_INPUT_CONTROL_2,
WM8753_LINEALC | WM8753_MICMUX_LEFT_PGA,
WM8753_LINEALC | WM8753_MICMUX_MASK
),
/* Now load the common ALC record profile */
WMACT_LOAD_PROFILE( "ALC Record" ),
#else
/* Now load the common direct line in record profile */
WMACT_LOAD_PROFILE( "Direct LineIn" ),
#endif
};
/*
* MicRecord
*
* Record from Mic1/Mic2 to I2S.
* Note: MIC1 + MIC2 goes through ALC to left.
*/
static const WM_ACTION s_MicRecordActions[] =
{
/* Now load the common ALC record profile */
WMACT_LOAD_PROFILE( "ALC Record" ),
/* Send MIC1 to the ALC and MIC mux (sidetone) */
WMACT_SET_FIELD( WM8753_INPUT_CONTROL_2,
WM8753_MIC1ALC | WM8753_MIC2ALC | WM8753_MICMUX_LEFT_PGA,
WM8753_MIC1ALC | WM8753_MIC2ALC | WM8753_MICMUX_MASK
),
/* Power up MIC amp and set full MIC boost */
WMACT_SET_BITS( WM8753_PWR_MGMT_2,
WM8753_PWR2_MICAMP1EN | WM8753_PWR2_MICAMP2EN
),
WMACT_SET_FIELD( WM8753_INPUT_CONTROL_1,
WM8753_MIC1BOOST_30DB | WM8753_MIC2BOOST_30DB,
WM8753_MIC1BOOST_MASK | WM8753_MIC2BOOST_MASK
),
};
/*
* Mic1Record
*
* Record from Mic1 to I2S.
* Note: MIC1 goes through ALC to both channels.
*/
static const WM_ACTION s_Mic1RecordActions[] =
{
/* Send MIC1 to the ALC and MIC mux (sidetone) */
WMACT_SET_FIELD( WM8753_INPUT_CONTROL_2,
WM8753_MIC1ALC | WM8753_MICMUX_LEFT_PGA,
WM8753_MIC1ALC | WM8753_MICMUX_MASK
),
/* Now load the common ALC record profile */
WMACT_LOAD_PROFILE( "ALC Record" ),
/* Power up MIC amp and set full MIC boost */
WMACT_SET_BITS( WM8753_PWR_MGMT_2,
WM8753_PWR2_MICAMP1EN
),
WMACT_SET_FIELD( WM8753_INPUT_CONTROL_1,
WM8753_MIC1BOOST_30DB,
WM8753_MIC1BOOST_MASK
),
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -