📄 wm8731.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: WM8731.c 2364 2005-11-04 15:56:03Z ib $
*
* This file specifies the per-device specific behaviour for the WM8731 and
* related devices (codecs WM8731 and WM8734 and DACs WM8711 and WM8721).
* Although these are different silicon, they all share the same register map
* for the operations they support.
*
* 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 "WM8731RegisterDefs.h"
#include "WM8731Power.h"
#include "WM8731Audio.h"
#if WM8731_FAMILY
/*
* Global definitions
*/
#if WM_USE_SHADOW_REGISTERS
/*
* Shadow registers
*/
static const WM_SHADOW_REGISTERS s_WM8731Shadowed[] =
{
{ WM8731_LEFT_INPUT_VOLUME, 0x0097 }, /* 0x00 */
{ WM8731_RIGHT_INPUT_VOLUME, 0x0097 }, /* 0x01 */
{ WM8731_LEFT_HEADPHONE_VOLUME, 0x0079 }, /* 0x02 */
{ WM8731_RIGHT_HEADPHONE_VOLUME, 0x0079 }, /* 0x03 */
{ WM8731_ANALOGUE_PATH_CONTROL, 0x000A }, /* 0x04 */
{ WM8731_DIGITAL_PATH_CONTROL, 0x0008 }, /* 0x05 */
{ WM8731_POWERDOWN_CONTROL, 0x009F }, /* 0x06 */
{ WM8731_INTERFACE_CONTROL, 0x000A }, /* 0x07 */
{ WM8731_SAMPLE_RATE_CONTROL, 0x0000 }, /* 0x08 */
{ WM8731_ACTIVE_CONTROL, 0x0000 }, /* 0x09 */
{ WM8731_RESET, 0x0000 }, /* 0x0F */
};
static const WM_SHADOW_REGISTERS s_WM8711Shadowed[] =
{
{ WM8731_LEFT_HEADPHONE_VOLUME, 0x0079 }, /* 0x02 */
{ WM8731_RIGHT_HEADPHONE_VOLUME, 0x0079 }, /* 0x03 */
{ WM8731_ANALOGUE_PATH_CONTROL, 0x000A }, /* 0x04 */
{ WM8731_DIGITAL_PATH_CONTROL, 0x0008 }, /* 0x05 */
{ WM8731_POWERDOWN_CONTROL, 0x009F }, /* 0x06 */
{ WM8731_INTERFACE_CONTROL, 0x000A }, /* 0x07 */
{ WM8731_SAMPLE_RATE_CONTROL, 0x0000 }, /* 0x08 */
{ WM8731_ACTIVE_CONTROL, 0x0000 }, /* 0x09 */
{ WM8731_RESET, 0x0000 }, /* 0x0F */
};
#endif /* WM_USE_SHADOW_REGISTERS */
/*
* HiFi Playback
*
* Playback from I2S to all outputs.
*/
static const WM_ACTION s_HiFiPlaybackActions[] =
{
/* Enable DAC to output */
WMACT_SET_BITS( WM8731_ANALOGUE_PATH_CONTROL, WM8731_DACSEL ),
/* Enable zero-cross on outputs */
WMACT_SET_BITS( WM8731_LEFT_HEADPHONE_VOLUME,
WM8731_VOLUME_BOTH | WM8731_OUTVOL_ZERO_CROSS
),
/* 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 ),
/* Unmute DAC */
WMACT_CLEAR_BITS( WM8731_DIGITAL_PATH_CONTROL, WM8731_DAC_MUTE ),
};
/*
* Stop Playback
*
* Stops all playback, both HiFi and Voice.
*/
static const WM_ACTION s_StopPlaybackActions[] =
{
/* Mute the DAC */
WMACT_SET_BITS( WM8731_DIGITAL_PATH_CONTROL, WM8731_DAC_MUTE ),
/* Stop all playback */
WMACT_DISABLE_STREAM( WM_STREAM_HIFI_OUT ),
/* Power down the DAC */
#if WM_ENABLE_SIDETONE
WMACT_POWERDOWN( WM_POWER_AUDIO_HIFI_DAC ),
#else
WMACT_POWERDOWN( WM_POWER_AUDIO_HIFI_DAC | WM_POWER_OUTPUTS | WM_POWER_MIXERS ),
#endif
};
/*
* CommonRecord
*
* This is a basic profile used by the other record profiles.
*/
static const WM_ACTION s_CommonRecordActions[] =
{
/* Unmute inputs */
WMACT_SET_FIELD( WM8731_LEFT_INPUT_VOLUME,
WM8731_VOLUME_BOTH | 0,
WM8731_VOLUME_BOTH | WM8731_INVOL_MUTE
),
#if WM_ENABLE_SIDETONE
/* Send sidetone to LOUT/ROUT */
WMACT_POWERUP( WM_POWER_OUTPUTS ),
/* Turn on sidetone */
WMACT_SET_BITS( WM8731_ANALOGUE_PATH_CONTROL, WM8731_SIDETONE ),
#endif /* WM_ENABLE_SIDETONE */
/* Finally power up the ADC and mixers */
WMACT_POWERUP( WM_POWER_AUDIO_ADCS | WM_POWER_MIXERS ),
};
/*
* LineRecord
*
* Record from LINES to I2S.
*/
static const WM_ACTION s_LineRecordActions[] =
{
/* Select line input */
WMACT_SET_FIELD( WM8731_ANALOGUE_PATH_CONTROL,
WM8731_INPUT_LINE,
WM8731_INPUT_MASK
),
/* Now load the common ALC record profile */
WMACT_LOAD_PROFILE( "Common Record" ),
/* Power up Line input */
WMACT_CLEAR_BITS( WM8731_POWERDOWN_CONTROL, WM8731_POWERDOWN_LINEIN ),
/* Start streaming from ADC via HiFi interface */
WMACT_ENABLE_STREAM( WM_STREAM_HIFI_IN ),
};
/*
* MicRecord
*
* Record from MIC to I2S.
*/
static const WM_ACTION s_MicRecordActions[] =
{
/* Select MIC input and MIC boost */
WMACT_SET_FIELD( WM8731_ANALOGUE_PATH_CONTROL,
WM8731_INPUT_MIC | 0 | WM8731_MIC_BOOST,
WM8731_INPUT_MASK | WM8731_MUTE_MIC | WM8731_MIC_BOOST
),
/* Now load the common ALC record profile */
WMACT_LOAD_PROFILE( "Common Record" ),
/* Power up MIC amp */
WMACT_CLEAR_BITS( WM8731_POWERDOWN_CONTROL, WM8731_POWERDOWN_MIC ),
/* Start streaming from ADC via HiFi interface */
WMACT_ENABLE_STREAM( WM_STREAM_HIFI_IN ),
};
/*
* Stop Record
*
* Stop recording. Note there is only one (stereo) ADC input on the WM8731,
* so this stops both HiFi and Voice record.
*/
static const WM_ACTION s_StopRecordActions[] =
{
/* Stop all streaming */
WMACT_DISABLE_STREAM( WM_STREAM_HIFI_IN ),
/* Power down the ADC */
WMACT_POWERDOWN( WM_POWER_AUDIO_ADCS ),
/* Select MIC input so we can mute it */
WMACT_SET_FIELD( WM8731_ANALOGUE_PATH_CONTROL,
WM8731_INPUT_MIC | WM8731_MUTE_MIC,
WM8731_INPUT_MASK | WM8731_MUTE_MIC
),
/* Mute input PGAs */
WMACT_SET_BITS( WM8731_LEFT_INPUT_VOLUME,
WM8731_VOLUME_BOTH | WM8731_INVOL_MUTE
),
/* Turn off sidetone */
WMACT_CLEAR_BITS( WM8731_ANALOGUE_PATH_CONTROL, WM8731_SIDETONE ),
};
/*
* Standby
*
* Not doing anything, but still powered up.
*/
static const WM_ACTION s_StandbyActions[] =
{
/* Mute the DAC */
WMACT_SET_BITS( WM8731_DIGITAL_PATH_CONTROL, WM8731_DAC_MUTE ),
/* Stop all streaming */
WMACT_DISABLE_STREAM( WM_STREAM_HIFI_OUT ),
WMACT_DISABLE_STREAM( WM_STREAM_HIFI_IN ),
/* Select MIC input so we can mute it */
WMACT_SET_FIELD( WM8731_ANALOGUE_PATH_CONTROL,
WM8731_INPUT_MIC | WM8731_MUTE_MIC,
WM8731_INPUT_MASK | WM8731_MUTE_MIC
),
/* Mute input PGAs */
WMACT_SET_BITS( WM8731_LEFT_INPUT_VOLUME,
WM8731_VOLUME_BOTH | WM8731_INVOL_MUTE
),
/* Turn off sidetone */
WMACT_CLEAR_BITS( WM8731_ANALOGUE_PATH_CONTROL, WM8731_SIDETONE ),
/* Power down Line input and MIC */
WMACT_SET_BITS( WM8731_POWERDOWN_CONTROL,
WM8731_POWERDOWN_LINEIN | WM8731_POWERDOWN_MIC
),
};
/*
* Powerdown
*
* Low-power state.
*/
static const WM_ACTION s_PowerdownActions[] =
{
/* Stop everything */
WMACT_LOAD_PROFILE( "Standby" ),
/* Now power everything down */
WMACT_POWERDOWN( WM_POWER_ALL ),
};
static const WM_PROFILE s_WM8731Profiles[] =
{
WM_PROFILE_ENTRY( "HiFi playback", WM_CHIP_WM8731, s_HiFiPlaybackActions ),
WM_PROFILE_ENTRY( "Mic record", WM_CHIP_WM8731, s_MicRecordActions ),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -