📄 pmic_audio.cpp
字号:
//------------------------------------------------------------------------------
//
// Copyright (C) 2004-2006, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
/*!
* @file pmic_audio.c
* @brief Implementation of the PMIC Audio driver APIs.
*
* The PMIC Audio driver and this API were developed to support the
* audio playback, recording, and mixing capabilities of the power
* management ICs that are available from Freescale Semiconductor, Inc.
* In particular, both the and MC13783 and SC5512 power management
* ICs are currently supported. All of the common features of each
* power management IC are available as well as access to all device-
* specific features. However, attempting to use a device-specific
* feature on a platform on which it is not supported will simply
* return an error status.
*
* The following operating modes are supported:
*
* @verbatim
Operating Mode MC1378 SC5512
---------------------------- ------ --------
Stereo DAC Playback Yes Yes
Stereo DAC Input Mixing Yes Yes
Voice CODEC Playback Yes Yes
Voice CODEC Input Mixing Yes No
Voice CODEC Mono Recording Yes Yes
Voice CODEC Stereo Recording Yes No
Microphone Bias Control Yes Yes
Output Amplifier Control Yes Yes
Output Mixing Control Yes Yes
Input Amplifier Control Yes Yes
Master/Slave Mode Select Yes Yes
Anti Pop Bias Circuit Control Yes Yes
@endverbatim
*
* Note that the Voice CODEC may also be referred to as the Telephone
* CODEC in the PMIC DTS documentation. Also note that, while the power
* management ICs do provide similar audio capabilities, each PMIC may
* support additional configuration settings and features. Therefore, it
* is highly recommended that the appropriate power management IC DTS
* documents be used in conjunction with this API interface. The following
* documents were used in the development of this API:
*
* [1] MC13783 Detailed Technical Specification (Level 3),
* Rev 1.3 - 04/09/17. Freescale Semiconductor, Inc.
*
* [2] iDEN Phoenix Platform Level 3 Detailed Technical Specification,
* Rev 2.2.1 5-12-2005. Motorola, Inc.
*
* @ingroup PMIC_MC13783_AUDIO
*/
/*===========================================================================*/
#include <windows.h> /* Needed for all standard WinCE definitions. */
#include <mmsystem.h>
#include <pmic_audio.h> /* PMIC audio driver API definitions. */
#include <pmic_adc.h> /* PMIC analog-to-digital converter interface defs. */
#include <pmic_lla.h> /* PMIC low-level interface definitions. */
#include <regs.h> /* MC13783 audio control register definitions. */
#ifdef DEBUG
// Debug zone bit positions
#define ZONEID_ERROR 0
#define ZONEID_WARN 1
#define ZONEID_INIT 2
#define ZONEID_FUNC 3
#define ZONEID_INFO 4
// Debug zone masks
#define ZONEMASK_ERROR (1 << ZONEID_ERROR)
#define ZONEMASK_WARN (1 << ZONEID_WARN)
#define ZONEMASK_INIT (1 << ZONEID_INIT)
#define ZONEMASK_FUNC (1 << ZONEID_FUNC)
#define ZONEMASK_INFO (1 << ZONEID_INFO)
// Debug zone args to DEBUGMSG
#define ZONE_ERROR DEBUGZONE(ZONEID_ERROR)
#define ZONE_WARN DEBUGZONE(ZONEID_WARN)
#define ZONE_INIT DEBUGZONE(ZONEID_INIT)
#define ZONE_FUNC DEBUGZONE(ZONEID_FUNC)
#define ZONE_INFO DEBUGZONE(ZONEID_INFO)
extern DBGPARAM dpCurSettings;
#endif // DEBUG
typedef enum
{
REG_IMR,
REG_RX0 = MC13783_AUD_RX0_ADDR,
REG_RX1 = MC13783_AUD_RX1_ADDR,
REG_AUDIO_TX = MC13783_AUD_TX_ADDR,
REG_SSI_NETWORK = MC13783_SSI_NW_ADDR,
REG_AUDIO_CODEC = MC13783_AUD_CDC_ADDR,
REG_STEREO_DAC = MC13783_AUD_STR_DAC_ADDR
} pmic_control_register;
/*===========================================================================*/
/*!
* Define the minimum sampling rate (in Hz) that is supported by the
* Stereo DAC.
*/
const unsigned MIN_STDAC_SAMPLING_RATE_HZ = 8000;
/*!
* Define the maximum sampling rate (in Hz) that is supported by the
* Stereo DAC.
*/
const unsigned MAX_STDAC_SAMPLING_RATE_HZ = 96000;
/*! @def SET_BITS
* Set a register field to a given value.
*/
#define SET_BITS(reg, field, value) (((value) << reg.field.offset) & \
reg.field.mask)
/*! @def GET_BITS
* Get the current value of a given register field.
*/
#define GET_BITS(reg, field, value) (((value) & reg.field.mask) >> \
reg.field.offset)
/*!
* @brief Define the possible states for a device handle.
*
* This enumeration is used to track the current state of each device handle.
*/
typedef enum
{
HANDLE_FREE, /*!< Handle is available for use. */
HANDLE_IN_USE /*!< Handle is currently in use. */
} HANDLE_STATE;
/*!
* @brief This structure is used to track the state of a microphone input.
*/
typedef struct
{
PMIC_AUDIO_INPUT_PORT mic; /*!< Microphone input port. */
PMIC_AUDIO_INPUT_MIC_STATE micOnOff; /*!< Microphone On/Off state. */
PMIC_AUDIO_MIC_AMP_MODE ampMode; /*!< Input amplifier mode. */
PMIC_AUDIO_MIC_GAIN gain; /*!< Input amplifier gain level. */
} PMIC_MICROPHONE_STATE;
/*!
* @brief Tracks whether a headset is currently attached or not.
*/
typedef enum {
NO_HEADSET, /*!< No headset currently attached. */
HEADSET_ON /*!< Headset has been attached. */
} HEADSET_STATUS;
/*!
* @brief This structure is used to define a specific hardware register field.
*
* All hardware register fields are defined using an offset to the LSB
* and a mask. The offset is used to right shift a register value before
* applying the mask to actually obtain the value of the field.
*/
typedef struct
{
unsigned char offset;/*!< Offset of LSB of register field. */
unsigned int mask; /*!< Mask value used to isolate register field.*/
} REGFIELD;
/*!
* @brief This structure lists all fields of the AUDIO_CODEC hardware register.
*/
typedef struct
{
REGFIELD CDCSSISEL; /*!< Codec SSI Bus Select */
REGFIELD CDCCLKSEL; /*!< Codec Clock Input Select */
REGFIELD CDCSM; /*!< Codec Slave/Master Select */
REGFIELD CDCBCLINV; /*!< Codec Bitclock Inversion */
REGFIELD CDCFSINV; /*!< Codec Framesync Inversion */
REGFIELD CDCFS; /*!< Bus Protocol Selection */
REGFIELD CDCCLK; /*!< Codec Clock Setting */
REGFIELD CDCFS8K16K; /*!< Codec Sampling Rate Select */
REGFIELD CDCEN; /*!< Codec Enable */
REGFIELD CDCCLKEN; /*!< Codec Master Clock Output Enable */
REGFIELD CDCTS; /*!< Codec SSI Tristate */
REGFIELD CDCDITH; /*!< Codec Dithering */
REGFIELD CDCRESET; /*!< Codec Digital Filter Reset */
REGFIELD CDCBYP; /*!< Codec Bypass */
REGFIELD CDCALM; /*!< Codec Analog Loopback */
REGFIELD CDCDLM; /*!< Codec Digital Loopback */
REGFIELD AUDIHPF; /*!< Transmit Highpass Filter Enable */
REGFIELD AUDOHPF; /*!< Receive Highpass Filter Enable */
} REGISTER_AUDIO_CODEC;
/*!
* @brief This variable is used to access the AUDIO_CODEC hardware register.
*
* This variable defines how to access all of the fields within the
* AUDIO_CODEC hardware register. The initial values consist of the offset
* and mask values needed to access each of the register fields.
*/
static const REGISTER_AUDIO_CODEC regAUDIO_CODEC = {
{ 0, 0x000001 }, /* CDCSSISEL */
{ 1, 0x000002 }, /* CDCCLKSEL */
{ 2, 0x000004 }, /* CDCSM */
{ 3, 0x000008 }, /* CDCBCLINV */
{ 4, 0x000010 }, /* CDCFSINV */
{ 5, 0x000060 }, /* CDCFS */
{ 7, 0x000380 }, /* CDCCLK */
{ 10, 0x000400 }, /* CDCFS8K16K */
{ 11, 0x000800 }, /* CDCEN */
{ 12, 0x001000 }, /* CDCCLKEN */
{ 13, 0x002000 }, /* CDCTS */
{ 14, 0x004000 }, /* CDCDITH */
{ 15, 0x008000 }, /* CDCRESET */
{ 16, 0x010000 }, /* CDCBYP */
{ 17, 0x020000 }, /* CDCALM */
{ 18, 0x040000 }, /* CDCDLM */
{ 19, 0x080000 }, /* AUDIHPF */
{ 20, 0x100000 } /* AUDOHPF */
};
/*!
* @brief This structure lists all fields of the STEREO_DAC hardware register.
*/
typedef struct
{
REGFIELD STDCSSISEL; /*!< Stereo DAC SSI Bus Select */
REGFIELD STDCCLKSEL; /*!< Stereo DAC Clock Input Select */
REGFIELD STDCSM; /*!< Stereo DAC Slave/Master Select */
REGFIELD STDCBCLINV; /*!< Stereo DAC Bitclock Inversion */
REGFIELD STDCFSINV; /*!< Stereo DAC Framesync Inversion */
REGFIELD STDCFS; /*!< Stereo DAC Bus Protocol Selection */
REGFIELD STDCCLK; /*!< Stereo DAC Clock Setting */
REGFIELD STDCFSDLYB; /*!< Stereo DAC Framesync Delay Bar */
REGFIELD STDCEN; /*!< Stereo DAC Enable */
REGFIELD STDCCLKEN; /*!< Stereo DAC Clocking Enable */
REGFIELD STDCRESET; /*!< Stereo DAC Digital Filter Reset */
REGFIELD SPDIF; /*!< Stereo DAC SSI SPDIF Mode */
REGFIELD SR; /*!< Stereo DAC Sampling Rate Select */
} REGISTER_STEREO_DAC;
/*!
* @brief This variable is used to access the STEREO_DAC hardware register.
*
* This variable defines how to access all of the fields within the
* STEREO_DAC hardware register. The initial values consist of the offset
* and mask values needed to access each of the register fields.
*/
static const REGISTER_STEREO_DAC regSTEREO_DAC = {
{ 0, 0x000001 }, /* STDCSSISEL */
{ 1, 0x000002 }, /* STDCCLKSEL */
{ 2, 0x000004 }, /* STDCSM */
{ 3, 0x000008 }, /* STDCBCLINV */
{ 4, 0x000010 }, /* STDCFSINV */
{ 5, 0x000060 }, /* STDCFS */
{ 7, 0x000380 }, /* STDCCLK */
{ 10, 0x000400 }, /* STDCFSDLYB */
{ 11, 0x000800 }, /* STDCEN */
{ 12, 0x001000 }, /* STDCCLKEN */
{ 15, 0x008000 }, /* STDCRESET */
{ 16, 0x010000 }, /* SPDIF */
{ 17, 0x1e0000 } /* SR */
};
/*!
* @brief This structure lists all fields of the RX0 hardware register.
*/
typedef struct
{
REGFIELD VAUDIOON; /*!< Forces VAUDIO in Active On Mode */
REGFIELD BIASEN; /*!< Audio Bias Enable */
REGFIELD BIASSPEED; /*!< Turn On Ramp Speed of the Audio Bias */
REGFIELD ASPEN; /*!< Amplifier Asp Enable */
REGFIELD ASPSEL; /*!< Asp Input Selector */
REGFIELD ALSPEN; /*!< Amplifier Alsp Enable */
REGFIELD ALSPREF; /*!< Bias Alsp at Common Audio Reference */
REGFIELD ALSPSEL; /*!< Alsp Input Selector */
REGFIELD LSPLEN; /*!< Output LSPL Enable */
REGFIELD AHSREN; /*!< Amplifier AhsR Enable */
REGFIELD AHSLEN; /*!< Amplifier AhsL Enable */
REGFIELD AHSSEL; /*!< Ahsr and Ahsl Input Selector */
REGFIELD HSPGDIS; /*!< Phantom Ground Disable */
REGFIELD HSDETEN; /*!< Headset Detect Enable */
REGFIELD HSDETAUTOB; /*!< Amplifier State Determined by Headset Detect */
REGFIELD ARXOUTREN; /*!< Output RXOUTR Enable */
REGFIELD ARXOUTLEN; /*!< Output RXOUTL Enable */
REGFIELD ARXOUTSEL; /*!< Arxout Input Selector */
REGFIELD CDCOUTEN; /*!< Output CDCOUT Enable */
REGFIELD HSLDETEN; /*!< Headset Left Channel Detect Enable */
REGFIELD ADDCDC; /*!< Adder Channel Codec Selection */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -