pinebuds/platform/drivers/ana/best2300p/analog_best2300p.c

2320 lines
73 KiB
C

/***************************************************************************
*
* Copyright 2015-2019 BES.
* All rights reserved. All unpublished rights reserved.
*
* No part of this work may be used or reproduced in any form or by any
* means, or stored in a database or retrieval system, without prior written
* permission of BES.
*
* Use of this work is governed by a license granted by BES.
* This work contains confidential and proprietary information of
* BES. which is protected by copyright, trade secret,
* trademark and other intellectual property rights.
*
****************************************************************************/
#include "analog.h"
#include "cmsis.h"
#include "plat_types.h"
#ifdef RTOS
#include "cmsis_os.h"
#endif
#include "hal_chipid.h"
#include "hal_cmu.h"
#include "hal_codec.h"
#include "hal_timer.h"
#include "hal_trace.h"
#include "pmu.h"
#include "tgt_hardware.h"
#define VCM_ON
// Not using 1uF
#define VCM_CAP_100NF
#if defined(CODEC_HIGH_QUALITY)
#undef LOW_CODEC_BIAS
#else
#define LOW_CODEC_BIAS
#endif
#define DAC_DC_CALIB_BIT_WIDTH 14
#define DEFAULT_ANC_FF_ADC_GAIN_DB 6
#define DEFAULT_ANC_FB_ADC_GAIN_DB 6
#define DEFAULT_VOICE_ADC_GAIN_DB 12
#ifndef ANALOG_ADC_A_GAIN_DB
#if defined(ANC_APP) && defined(ANC_FF_ENABLED) && \
((ANC_FF_MIC_CH_L == AUD_CHANNEL_MAP_CH0) || \
(ANC_FF_MIC_CH_R == AUD_CHANNEL_MAP_CH0))
#define ANALOG_ADC_A_GAIN_DB DEFAULT_ANC_FF_ADC_GAIN_DB
#elif defined(ANC_APP) && defined(ANC_FB_ENABLED) && \
((ANC_FB_MIC_CH_L == AUD_CHANNEL_MAP_CH0) || \
(ANC_FB_MIC_CH_R == AUD_CHANNEL_MAP_CH0))
#define ANALOG_ADC_A_GAIN_DB DEFAULT_ANC_FB_ADC_GAIN_DB
#else
#define ANALOG_ADC_A_GAIN_DB DEFAULT_VOICE_ADC_GAIN_DB
#endif
#endif
#ifndef ANALOG_ADC_B_GAIN_DB
#if defined(ANC_APP) && defined(ANC_FF_ENABLED) && \
((ANC_FF_MIC_CH_L == AUD_CHANNEL_MAP_CH1) || \
(ANC_FF_MIC_CH_R == AUD_CHANNEL_MAP_CH1))
#define ANALOG_ADC_B_GAIN_DB DEFAULT_ANC_FF_ADC_GAIN_DB
#elif defined(ANC_APP) && defined(ANC_FB_ENABLED) && \
((ANC_FB_MIC_CH_L == AUD_CHANNEL_MAP_CH1) || \
(ANC_FB_MIC_CH_R == AUD_CHANNEL_MAP_CH1))
#define ANALOG_ADC_B_GAIN_DB DEFAULT_ANC_FB_ADC_GAIN_DB
#else
#define ANALOG_ADC_B_GAIN_DB DEFAULT_VOICE_ADC_GAIN_DB
#endif
#endif
#ifndef ANALOG_ADC_C_GAIN_DB
#if defined(ANC_APP) && defined(ANC_FF_ENABLED) && \
((ANC_FF_MIC_CH_L == AUD_CHANNEL_MAP_CH2) || \
(ANC_FF_MIC_CH_R == AUD_CHANNEL_MAP_CH2))
#define ANALOG_ADC_C_GAIN_DB DEFAULT_ANC_FF_ADC_GAIN_DB
#elif defined(ANC_APP) && defined(ANC_FB_ENABLED) && \
((ANC_FB_MIC_CH_L == AUD_CHANNEL_MAP_CH2) || \
(ANC_FB_MIC_CH_R == AUD_CHANNEL_MAP_CH2))
#define ANALOG_ADC_C_GAIN_DB DEFAULT_ANC_FB_ADC_GAIN_DB
#else
#define ANALOG_ADC_C_GAIN_DB DEFAULT_VOICE_ADC_GAIN_DB
#endif
#endif
#ifndef ANALOG_ADC_D_GAIN_DB
#if defined(ANC_APP) && defined(ANC_FF_ENABLED) && \
((ANC_FF_MIC_CH_L == AUD_CHANNEL_MAP_CH3) || \
(ANC_FF_MIC_CH_R == AUD_CHANNEL_MAP_CH3))
#define ANALOG_ADC_D_GAIN_DB DEFAULT_ANC_FF_ADC_GAIN_DB
#elif defined(ANC_APP) && defined(ANC_FB_ENABLED) && \
((ANC_FB_MIC_CH_L == AUD_CHANNEL_MAP_CH3) || \
(ANC_FB_MIC_CH_R == AUD_CHANNEL_MAP_CH3))
#define ANALOG_ADC_D_GAIN_DB DEFAULT_ANC_FB_ADC_GAIN_DB
#else
#define ANALOG_ADC_D_GAIN_DB DEFAULT_VOICE_ADC_GAIN_DB
#endif
#endif
#ifndef ANALOG_ADC_E_GAIN_DB
#if defined(ANC_APP) && defined(ANC_FF_ENABLED) && \
((ANC_FF_MIC_CH_L == AUD_CHANNEL_MAP_CH4) || \
(ANC_FF_MIC_CH_R == AUD_CHANNEL_MAP_CH4))
#define ANALOG_ADC_E_GAIN_DB DEFAULT_ANC_FF_ADC_GAIN_DB
#elif defined(ANC_APP) && defined(ANC_FB_ENABLED) && \
((ANC_FB_MIC_CH_L == AUD_CHANNEL_MAP_CH4) || \
(ANC_FB_MIC_CH_R == AUD_CHANNEL_MAP_CH4))
#define ANALOG_ADC_E_GAIN_DB DEFAULT_ANC_FB_ADC_GAIN_DB
#else
#define ANALOG_ADC_E_GAIN_DB DEFAULT_VOICE_ADC_GAIN_DB
#endif
#endif
#ifndef LINEIN_ADC_GAIN_DB
#define LINEIN_ADC_GAIN_DB 0
#endif
#ifndef CFG_HW_AUD_MICKEY_DEV
#define CFG_HW_AUD_MICKEY_DEV (AUD_VMIC_MAP_VMIC1)
#endif
#ifndef ANC_VMIC_CFG
#error "No ANC VMIC configured"
#define ANC_VMIC_CFG (AUD_VMIC_MAP_VMIC1)
#endif
// 61
#define REG_CODEC_EN_ADCA (1 << 0)
#define REG_CODEC_EN_ADCB (1 << 1)
#define REG_CODEC_EN_ADCC (1 << 2)
#define REG_CODEC_EN_ADCD (1 << 3)
#define REG_CODEC_ADCA_DITHER_EN (1 << 4)
#define REG_CODEC_ADCB_DITHER_EN (1 << 5)
#define REG_CODEC_ADCC_DITHER_EN (1 << 6)
#define REG_CODEC_ADCD_DITHER_EN (1 << 7)
#define REG_CODEC_ADCA_CH_SEL_SHIFT 8
#define REG_CODEC_ADCA_CH_SEL_MASK (0x3 << REG_CODEC_ADCA_CH_SEL_SHIFT)
#define REG_CODEC_ADCA_CH_SEL(n) BITFIELD_VAL(REG_CODEC_ADCA_CH_SEL, n)
#define REG_CODEC_ADCB_CH_SEL_SHIFT 10
#define REG_CODEC_ADCB_CH_SEL_MASK (0x3 << REG_CODEC_ADCB_CH_SEL_SHIFT)
#define REG_CODEC_ADCB_CH_SEL(n) BITFIELD_VAL(REG_CODEC_ADCB_CH_SEL, n)
#define REG_CODEC_ADCC_CH_SEL_SHIFT 12
#define REG_CODEC_ADCC_CH_SEL_MASK (0x3 << REG_CODEC_ADCC_CH_SEL_SHIFT)
#define REG_CODEC_ADCC_CH_SEL(n) BITFIELD_VAL(REG_CODEC_ADCC_CH_SEL, n)
#define REG_CODEC_ADCD_CH_SEL_SHIFT 14
#define REG_CODEC_ADCD_CH_SEL_MASK (0x3 << REG_CODEC_ADCD_CH_SEL_SHIFT)
#define REG_CODEC_ADCD_CH_SEL(n) BITFIELD_VAL(REG_CODEC_ADCD_CH_SEL, n)
// 62
#define REG_CODEC_RESET_ADCA (1 << 0)
#define REG_CODEC_RESET_ADCB (1 << 1)
#define REG_CODEC_RESET_ADCC (1 << 2)
#define REG_CODEC_RESET_ADCD (1 << 3)
#define CFG_RESET_ADCA_DR (1 << 4)
#define CFG_RESET_ADCB_DR (1 << 5)
#define CFG_RESET_ADCC_DR (1 << 6)
#define CFG_RESET_ADCD_DR (1 << 7)
#define REG_RX_PGAA_RESET (1 << 8)
#define REG_RX_PGAB_RESET (1 << 9)
#define REG_RX_PGAC_RESET (1 << 10)
#define REG_RX_PGAD_RESET (1 << 11)
#define CFG_RESET_PGAA_DR (1 << 12)
#define CFG_RESET_PGAB_DR (1 << 13)
#define CFG_RESET_PGAC_DR (1 << 14)
#define CFG_RESET_PGAD_DR (1 << 15)
// 63
#define REG_CODEC_ADCA_GAIN_BIT_SHIFT 0
#define REG_CODEC_ADCA_GAIN_BIT_MASK (0x7 << REG_CODEC_ADCA_GAIN_BIT_SHIFT)
#define REG_CODEC_ADCA_GAIN_BIT(n) BITFIELD_VAL(REG_CODEC_ADCA_GAIN_BIT, n)
#define REG_CODEC_ADCB_GAIN_BIT_SHIFT 3
#define REG_CODEC_ADCB_GAIN_BIT_MASK (0x7 << REG_CODEC_ADCB_GAIN_BIT_SHIFT)
#define REG_CODEC_ADCB_GAIN_BIT(n) BITFIELD_VAL(REG_CODEC_ADCB_GAIN_BIT, n)
#define REG_CODEC_ADCC_GAIN_BIT_SHIFT 6
#define REG_CODEC_ADCC_GAIN_BIT_MASK (0x7 << REG_CODEC_ADCC_GAIN_BIT_SHIFT)
#define REG_CODEC_ADCC_GAIN_BIT(n) BITFIELD_VAL(REG_CODEC_ADCC_GAIN_BIT, n)
#define REG_CODEC_ADCD_GAIN_BIT_SHIFT 9
#define REG_CODEC_ADCD_GAIN_BIT_MASK (0x7 << REG_CODEC_ADCD_GAIN_BIT_SHIFT)
#define REG_CODEC_ADCD_GAIN_BIT(n) BITFIELD_VAL(REG_CODEC_ADCD_GAIN_BIT, n)
#define REG_CODEC_ADCA_GAIN_UPDATE (1 << 12)
#define REG_CODEC_ADCB_GAIN_UPDATE (1 << 13)
#define REG_CODEC_ADCC_GAIN_UPDATE (1 << 14)
#define REG_CODEC_ADCD_GAIN_UPDATE (1 << 15)
// 67
#define REG_CODEC_ADC_IBSEL_REG_SHIFT 0
#define REG_CODEC_ADC_IBSEL_REG_MASK (0xF << REG_CODEC_ADC_IBSEL_REG_SHIFT)
#define REG_CODEC_ADC_IBSEL_REG(n) BITFIELD_VAL(REG_CODEC_ADC_IBSEL_REG, n)
#define REG_CODEC_ADC_IBSEL_VCOMP_SHIFT 4
#define REG_CODEC_ADC_IBSEL_VCOMP_MASK (0xF << REG_CODEC_ADC_IBSEL_VCOMP_SHIFT)
#define REG_CODEC_ADC_IBSEL_VCOMP(n) BITFIELD_VAL(REG_CODEC_ADC_IBSEL_VCOMP, n)
#define REG_CODEC_ADC_IBSEL_VREF_SHIFT 8
#define REG_CODEC_ADC_IBSEL_VREF_MASK (0xF << REG_CODEC_ADC_IBSEL_VREF_SHIFT)
#define REG_CODEC_ADC_IBSEL_VREF(n) BITFIELD_VAL(REG_CODEC_ADC_IBSEL_VREF, n)
#define REG_CODEC_ADC_LPFVCM_SW_SHIFT 12
#define REG_CODEC_ADC_LPFVCM_SW_MASK (0xF << REG_CODEC_ADC_LPFVCM_SW_SHIFT)
#define REG_CODEC_ADC_LPFVCM_SW(n) BITFIELD_VAL(REG_CODEC_ADC_LPFVCM_SW, n)
// 68
#define REG_CODEC_ADC_OP1_IBIT_SHIFT 0
#define REG_CODEC_ADC_OP1_IBIT_MASK (0x3 << REG_CODEC_ADC_OP1_IBIT_SHIFT)
#define REG_CODEC_ADC_OP1_IBIT(n) BITFIELD_VAL(REG_CODEC_ADC_OP1_IBIT, n)
#define REG_CODEC_ADC_OP1_R_SEL (1 << 2)
#define REG_CODEC_ADC_OP2_IBIT_SHIFT 3
#define REG_CODEC_ADC_OP2_IBIT_MASK (0x3 << REG_CODEC_ADC_OP2_IBIT_SHIFT)
#define REG_CODEC_ADC_OP2_IBIT(n) BITFIELD_VAL(REG_CODEC_ADC_OP2_IBIT, n)
#define REG_CODEC_ADC_OP2_R_SEL (1 << 5)
#define REG_CODEC_ADC_OP3_IBIT_SHIFT 6
#define REG_CODEC_ADC_OP3_IBIT_MASK (0x3 << REG_CODEC_ADC_OP3_IBIT_SHIFT)
#define REG_CODEC_ADC_OP3_IBIT(n) BITFIELD_VAL(REG_CODEC_ADC_OP3_IBIT, n)
#define REG_CODEC_ADC_OP3_R_SEL (1 << 8)
#define REG_CODEC_ADC_OP4_IBIT_SHIFT 9
#define REG_CODEC_ADC_OP4_IBIT_MASK (0x3 << REG_CODEC_ADC_OP4_IBIT_SHIFT)
#define REG_CODEC_ADC_OP4_IBIT(n) BITFIELD_VAL(REG_CODEC_ADC_OP4_IBIT, n)
#define REG_CODEC_ADC_OP4_R_SEL (1 << 11)
#define REG_CODEC_ADC_VREF_SEL_SHIFT 12
#define REG_CODEC_ADC_VREF_SEL_MASK (0xF << REG_CODEC_ADC_VREF_SEL_SHIFT)
#define REG_CODEC_ADC_VREF_SEL(n) BITFIELD_VAL(REG_CODEC_ADC_VREF_SEL, n)
// 69
#define REG_CODEC_BIAS_IBSEL_SHIFT 0
#define REG_CODEC_BIAS_IBSEL_MASK (0xF << REG_CODEC_BIAS_IBSEL_SHIFT)
#define REG_CODEC_BIAS_IBSEL(n) BITFIELD_VAL(REG_CODEC_BIAS_IBSEL, n)
#define REG_CODEC_BIAS_IBSEL_TX_SHIFT 4
#define REG_CODEC_BIAS_IBSEL_TX_MASK (0xF << REG_CODEC_BIAS_IBSEL_TX_SHIFT)
#define REG_CODEC_BIAS_IBSEL_TX(n) BITFIELD_VAL(REG_CODEC_BIAS_IBSEL_TX, n)
#define REG_CODEC_BIAS_IBSEL_VOICE_SHIFT 8
#define REG_CODEC_BIAS_IBSEL_VOICE_MASK \
(0xF << REG_CODEC_BIAS_IBSEL_VOICE_SHIFT)
#define REG_CODEC_BIAS_IBSEL_VOICE(n) \
BITFIELD_VAL(REG_CODEC_BIAS_IBSEL_VOICE, n)
#define REG_CODEC_BIAS_LOWV (1 << 12)
#define REG_CODEC_BIAS_LOWV_LP (1 << 13)
#define REG_CODEC_BUF_LOWPOWER (1 << 14)
#define REG_CODEC_BUF_LOWPOWER2 (1 << 15)
// 6A
#define REG_CODEC_ADC_REG_VSEL_SHIFT 0
#define REG_CODEC_ADC_REG_VSEL_MASK (0x7 << REG_CODEC_ADC_REG_VSEL_SHIFT)
#define REG_CODEC_ADC_REG_VSEL(n) BITFIELD_VAL(REG_CODEC_ADC_REG_VSEL, n)
#define REG_CODEC_ADC_RES_SEL_SHIFT 3
#define REG_CODEC_ADC_RES_SEL_MASK (0x7 << REG_CODEC_ADC_RES_SEL_SHIFT)
#define REG_CODEC_ADC_RES_SEL(n) BITFIELD_VAL(REG_CODEC_ADC_RES_SEL, n)
#define REG_CODEC_BUF_LOWVCM_SHIFT 6
#define REG_CODEC_BUF_LOWVCM_MASK (0x7 << REG_CODEC_BUF_LOWVCM_SHIFT)
#define REG_CODEC_BUF_LOWVCM(n) BITFIELD_VAL(REG_CODEC_BUF_LOWVCM, n)
#define REG_CODEC_EN_BIAS (1 << 9)
#define REG_CODEC_EN_BIAS_LP (1 << 10)
#define REG_CODEC_EN_RX_EXT (1 << 11)
#define REG_CODEC_EN_TX_EXT (1 << 12)
#define REG_CODEC_DAC_CLK_EDGE_SEL (1 << 13)
#define CFG_TX_CH0_MUTE (1 << 14)
#define CFG_TX_CH1_MUTE (1 << 15)
// 6B
#define REG_CODEC_EN_VCM (1 << 0)
#define REG_CODEC_VCM_EN_LPF (1 << 1)
#define REG_CODEC_LP_VCM (1 << 2)
#define REG_CODEC_VCM_LOW_VCM_SHIFT 3
#define REG_CODEC_VCM_LOW_VCM_MASK (0xF << REG_CODEC_VCM_LOW_VCM_SHIFT)
#define REG_CODEC_VCM_LOW_VCM(n) BITFIELD_VAL(REG_CODEC_VCM_LOW_VCM, n)
#define REG_CODEC_VCM_LOW_VCM_LP_SHIFT 7
#define REG_CODEC_VCM_LOW_VCM_LP_MASK (0xF << REG_CODEC_VCM_LOW_VCM_LP_SHIFT)
#define REG_CODEC_VCM_LOW_VCM_LP(n) BITFIELD_VAL(REG_CODEC_VCM_LOW_VCM_LP, n)
#define REG_CODEC_VCM_LOW_VCM_LPF_SHIFT 11
#define REG_CODEC_VCM_LOW_VCM_LPF_MASK (0xF << REG_CODEC_VCM_LOW_VCM_LPF_SHIFT)
#define REG_CODEC_VCM_LOW_VCM_LPF(n) BITFIELD_VAL(REG_CODEC_VCM_LOW_VCM_LPF, n)
#define REG_CODEC_EN_VCM_BUFFER (1 << 15)
// 6C
#define REG_CODEC_RX_EN_VTOI (1 << 0)
#define REG_CODEC_RX_VTOI_I_DAC2_SHIFT 1
#define REG_CODEC_RX_VTOI_I_DAC2_MASK (0x7 << REG_CODEC_RX_VTOI_I_DAC2_SHIFT)
#define REG_CODEC_RX_VTOI_I_DAC2(n) BITFIELD_VAL(REG_CODEC_RX_VTOI_I_DAC2, n)
#define REG_CODEC_RX_VTOI_IDAC_SEL_SHIFT 4
#define REG_CODEC_RX_VTOI_IDAC_SEL_MASK \
(0xF << REG_CODEC_RX_VTOI_IDAC_SEL_SHIFT)
#define REG_CODEC_RX_VTOI_IDAC_SEL(n) \
BITFIELD_VAL(REG_CODEC_RX_VTOI_IDAC_SEL, n)
#define REG_CODEC_RX_VTOI_VCS_SEL_SHIFT 8
#define REG_CODEC_RX_VTOI_VCS_SEL_MASK (0x1F << REG_CODEC_RX_VTOI_VCS_SEL_SHIFT)
#define REG_CODEC_RX_VTOI_VCS_SEL(n) BITFIELD_VAL(REG_CODEC_RX_VTOI_VCS_SEL, n)
#define REG_CODEC_ADCA_RES_2P5K_DR (1 << 13)
#define REG_CODEC_ADCB_RES_2P5K_DR (1 << 14)
#define REG_CODEC_ADCC_RES_2P5K_DR (1 << 15)
// 6D
#define REG_CODEC_TX_DAC_MUTEL (1 << 0)
#define REG_CODEC_TX_DAC_MUTER (1 << 1)
#define REG_CODEC_TX_DAC_SWR_SHIFT 2
#define REG_CODEC_TX_DAC_SWR_MASK (0x3 << REG_CODEC_TX_DAC_SWR_SHIFT)
#define REG_CODEC_TX_DAC_SWR(n) BITFIELD_VAL(REG_CODEC_TX_DAC_SWR, n)
#define REG_CODEC_TX_DAC_VREF_L_SHIFT 4
#define REG_CODEC_TX_DAC_VREF_L_MASK (0xF << REG_CODEC_TX_DAC_VREF_L_SHIFT)
#define REG_CODEC_TX_DAC_VREF_L(n) BITFIELD_VAL(REG_CODEC_TX_DAC_VREF_L, n)
#define REG_CODEC_TX_DAC_VREF_R_SHIFT 8
#define REG_CODEC_TX_DAC_VREF_R_MASK (0xF << REG_CODEC_TX_DAC_VREF_R_SHIFT)
#define REG_CODEC_TX_DAC_VREF_R(n) BITFIELD_VAL(REG_CODEC_TX_DAC_VREF_R, n)
#define REG_CODEC_TX_EAR_CAS_BIT_SHIFT 12
#define REG_CODEC_TX_EAR_CAS_BIT_MASK (0x3 << REG_CODEC_TX_EAR_CAS_BIT_SHIFT)
#define REG_CODEC_TX_EAR_CAS_BIT(n) BITFIELD_VAL(REG_CODEC_TX_EAR_CAS_BIT, n)
#define REG_CODEC_TX_EAR_DIS_SHIFT 14
#define REG_CODEC_TX_EAR_DIS_MASK (0x3 << REG_CODEC_TX_EAR_DIS_SHIFT)
#define REG_CODEC_TX_EAR_DIS(n) BITFIELD_VAL(REG_CODEC_TX_EAR_DIS, n)
// 6E
#define REG_CODEC_TX_EAR_COMP_L_SHIFT 0
#define REG_CODEC_TX_EAR_COMP_L_MASK (0x7 << REG_CODEC_TX_EAR_COMP_L_SHIFT)
#define REG_CODEC_TX_EAR_COMP_L(n) BITFIELD_VAL(REG_CODEC_TX_EAR_COMP_L, n)
#define REG_CODEC_TX_EAR_COMP_R_SHIFT 3
#define REG_CODEC_TX_EAR_COMP_R_MASK (0x7 << REG_CODEC_TX_EAR_COMP_R_SHIFT)
#define REG_CODEC_TX_EAR_COMP_R(n) BITFIELD_VAL(REG_CODEC_TX_EAR_COMP_R, n)
#define REG_CODEC_TX_EAR_DOUBLEBIAS (1 << 6)
#define REG_CODEC_TX_EAR_DR_EN (1 << 7)
#define REG_CODEC_TX_EAR_DR_ST_SHIFT 8
#define REG_CODEC_TX_EAR_DR_ST_MASK (0x7 << REG_CODEC_TX_EAR_DR_ST_SHIFT)
#define REG_CODEC_TX_EAR_DR_ST(n) BITFIELD_VAL(REG_CODEC_TX_EAR_DR_ST, n)
#define REG_CODEC_TX_EAR_ENBIAS (1 << 11)
#define REG_CODEC_TX_EAR_FBCAP_SHIFT 12
#define REG_CODEC_TX_EAR_FBCAP_MASK (0x3 << REG_CODEC_TX_EAR_FBCAP_SHIFT)
#define REG_CODEC_TX_EAR_FBCAP(n) BITFIELD_VAL(REG_CODEC_TX_EAR_FBCAP, n)
#define REG_CODEC_TX_EAR_IBSEL_SHIFT 14
#define REG_CODEC_TX_EAR_IBSEL_MASK (0x3 << REG_CODEC_TX_EAR_IBSEL_SHIFT)
#define REG_CODEC_TX_EAR_IBSEL(n) BITFIELD_VAL(REG_CODEC_TX_EAR_IBSEL, n)
// 6F
#define REG_CODEC_TX_EAR_DRE_GAIN_L_SHIFT 0
#define REG_CODEC_TX_EAR_DRE_GAIN_L_MASK \
(0x1F << REG_CODEC_TX_EAR_DRE_GAIN_L_SHIFT)
#define REG_CODEC_TX_EAR_DRE_GAIN_L(n) \
BITFIELD_VAL(REG_CODEC_TX_EAR_DRE_GAIN_L, n)
#define REG_CODEC_TX_EAR_DRE_GAIN_R_SHIFT 5
#define REG_CODEC_TX_EAR_DRE_GAIN_R_MASK \
(0x1F << REG_CODEC_TX_EAR_DRE_GAIN_R_SHIFT)
#define REG_CODEC_TX_EAR_DRE_GAIN_R(n) \
BITFIELD_VAL(REG_CODEC_TX_EAR_DRE_GAIN_R, n)
#define DRE_GAIN_SEL_L (1 << 10)
#define DRE_GAIN_SEL_R (1 << 11)
#define REG_CODEC_TX_EAR_DRE_GAIN_L_UPDATE (1 << 12)
#define REG_CODEC_TX_EAR_DRE_GAIN_R_UPDATE (1 << 13)
#define REG_CODEC_TX_EAR_GAIN_SHIFT 14
#define REG_CODEC_TX_EAR_GAIN_MASK (0x3 << REG_CODEC_TX_EAR_GAIN_SHIFT)
#define REG_CODEC_TX_EAR_GAIN(n) BITFIELD_VAL(REG_CODEC_TX_EAR_GAIN, n)
// 70
#define REG_CODEC_TX_EAR_LCAL (1 << 0)
#define REG_CODEC_TX_EAR_RCAL (1 << 1)
#define REG_CODEC_TX_EAR_LPBIAS (1 << 2)
#define REG_CODEC_TX_EAR_OCEN (1 << 3)
#define REG_CODEC_TX_EAR_OFFEN (1 << 4)
#define REG_CODEC_TX_EAR_OUTPUTSEL_SHIFT 5
#define REG_CODEC_TX_EAR_OUTPUTSEL_MASK \
(0xF << REG_CODEC_TX_EAR_OUTPUTSEL_SHIFT)
#define REG_CODEC_TX_EAR_OUTPUTSEL(n) \
BITFIELD_VAL(REG_CODEC_TX_EAR_OUTPUTSEL, n)
#define REG_CODEC_TX_EAR_SOFTSTART_SHIFT 9
#define REG_CODEC_TX_EAR_SOFTSTART_MASK \
(0x3F << REG_CODEC_TX_EAR_SOFTSTART_SHIFT)
#define REG_CODEC_TX_EAR_SOFTSTART(n) \
BITFIELD_VAL(REG_CODEC_TX_EAR_SOFTSTART, n)
#define CFG_TX_TREE_EN (1 << 15)
// 71
#define REG_CODEC_TX_EAR_LOWGAINL_SHIFT 0
#define REG_CODEC_TX_EAR_LOWGAINL_MASK (0x3 << REG_CODEC_TX_EAR_LOWGAINL_SHIFT)
#define REG_CODEC_TX_EAR_LOWGAINL(n) BITFIELD_VAL(REG_CODEC_TX_EAR_LOWGAINL, n)
#define REG_CODEC_TX_EAR_OFF_BITL_SHIFT 2
#define REG_CODEC_TX_EAR_OFF_BITL_MASK \
(0x3FFF << REG_CODEC_TX_EAR_OFF_BITL_SHIFT)
#define REG_CODEC_TX_EAR_OFF_BITL(n) BITFIELD_VAL(REG_CODEC_TX_EAR_OFF_BITL, n)
// 72
#define REG_CODEC_TX_EAR_LOWGAINR_SHIFT 0
#define REG_CODEC_TX_EAR_LOWGAINR_MASK (0x3 << REG_CODEC_TX_EAR_LOWGAINR_SHIFT)
#define REG_CODEC_TX_EAR_LOWGAINR(n) BITFIELD_VAL(REG_CODEC_TX_EAR_LOWGAINR, n)
#define REG_CODEC_TX_EAR_OFF_BITR_SHIFT 2
#define REG_CODEC_TX_EAR_OFF_BITR_MASK \
(0x3FFF << REG_CODEC_TX_EAR_OFF_BITR_SHIFT)
#define REG_CODEC_TX_EAR_OFF_BITR(n) BITFIELD_VAL(REG_CODEC_TX_EAR_OFF_BITR, n)
// 73
#define REG_CODEC_TX_EN_DACLDO (1 << 0)
#define REG_CODEC_TX_EN_EARPA_L (1 << 1)
#define REG_CODEC_TX_EN_EARPA_R (1 << 2)
#define REG_CODEC_TX_EN_LCLK (1 << 3)
#define REG_CODEC_TX_EN_RCLK (1 << 4)
#define REG_CODEC_TX_EN_LDAC (1 << 5)
#define REG_CODEC_TX_EN_RDAC (1 << 6)
#define REG_CODEC_TX_EN_LPPA (1 << 7)
#define REG_CODEC_TX_EN_S1PA (1 << 8)
#define REG_CODEC_TX_EN_S2PA (1 << 9)
#define REG_CODEC_TX_EN_S3PA (1 << 10)
#define REG_CODEC_TX_EN_S4PA (1 << 11)
#define REG_CODEC_TX_EN_S5PA (1 << 12)
#define REG_IDETLEAR_EN (1 << 13)
#define REG_IDETREAR_EN (1 << 14)
#define REG_CODEC_TX_SW_MODE (1 << 15)
// 74
#define REG_CODEC_TX_RVREF_CAP_BIT (1 << 0)
#define REG_DAC_LDO0P9_VSEL_SHIFT 1
#define REG_DAC_LDO0P9_VSEL_MASK (0x1F << REG_DAC_LDO0P9_VSEL_SHIFT)
#define REG_DAC_LDO0P9_VSEL(n) BITFIELD_VAL(REG_DAC_LDO0P9_VSEL, n)
#define REG_BYPASS_TX_REGULATOR (1 << 6)
#define REG_PU_TX_REGULATOR (1 << 7)
#define REG_TX_REGULATOR_BIT_SHIFT 8
#define REG_TX_REGULATOR_BIT_MASK (0xF << REG_TX_REGULATOR_BIT_SHIFT)
#define REG_TX_REGULATOR_BIT(n) BITFIELD_VAL(REG_TX_REGULATOR_BIT, n)
#define REG_TX_REG_CAP_BIT (1 << 12)
#define REG_CODEC_TX_EAR_VCM_BIT_SHIFT 13
#define REG_CODEC_TX_EAR_VCM_BIT_MASK (0x3 << REG_CODEC_TX_EAR_VCM_BIT_SHIFT)
#define REG_CODEC_TX_EAR_VCM_BIT(n) BITFIELD_VAL(REG_CODEC_TX_EAR_VCM_BIT, n)
#define REG_CODEC_TX_EAR_VCM_SEL (1 << 15)
// 75
#define REG_CRYSTAL_SEL_LV (1 << 0)
#define REG_EXTPLL_SEL (1 << 1)
#define REG_AUDPLL_CAL_EN (1 << 2)
#define REG_AUDPLL_CP_IEN_SHIFT 3
#define REG_AUDPLL_CP_IEN_MASK (0xF << REG_AUDPLL_CP_IEN_SHIFT)
#define REG_AUDPLL_CP_IEN(n) BITFIELD_VAL(REG_AUDPLL_CP_IEN, n)
#define REG_AUDPLL_CP_SWRC_SHIFT 7
#define REG_AUDPLL_CP_SWRC_MASK (0x3 << REG_AUDPLL_CP_SWRC_SHIFT)
#define REG_AUDPLL_CP_SWRC(n) BITFIELD_VAL(REG_AUDPLL_CP_SWRC, n)
#define REG_AUDPLL_DIG_SWRC_SHIFT 9
#define REG_AUDPLL_DIG_SWRC_MASK (0x3 << REG_AUDPLL_DIG_SWRC_SHIFT)
#define REG_AUDPLL_DIG_SWRC(n) BITFIELD_VAL(REG_AUDPLL_DIG_SWRC, n)
#define REG_AUDPLL_VCO_SPD_SHIFT 11
#define REG_AUDPLL_VCO_SPD_MASK (0x7 << REG_AUDPLL_VCO_SPD_SHIFT)
#define REG_AUDPLL_VCO_SPD(n) BITFIELD_VAL(REG_AUDPLL_VCO_SPD, n)
#define REG_AUDPLL_VCO_SWRC_SHIFT 14
#define REG_AUDPLL_VCO_SWRC_MASK (0x3 << REG_AUDPLL_VCO_SWRC_SHIFT)
#define REG_AUDPLL_VCO_SWRC(n) BITFIELD_VAL(REG_AUDPLL_VCO_SWRC, n)
// 7A
#define REG_PU_OSC (1 << 0)
#define REG_BBPLL_TST_EN (1 << 1)
#define REG_AUDPLL_TRIGGER_EN (1 << 2)
#define REG_AUDPLL_FREQ_EN (1 << 3)
#define REG_AUDPLL_CLK_FBC_EDGE (1 << 4)
#define REG_AUDPLL_INT_DEC_SEL_SHIFT 5
#define REG_AUDPLL_INT_DEC_SEL_MASK (0x7 << REG_AUDPLL_INT_DEC_SEL_SHIFT)
#define REG_AUDPLL_INT_DEC_SEL(n) BITFIELD_VAL(REG_AUDPLL_INT_DEC_SEL, n)
#define REG_AUDPLL_DITHER_BYPASS (1 << 8)
#define REG_AUDPLL_PRESCALER_DEL_SEL_SHIFT 9
#define REG_AUDPLL_PRESCALER_DEL_SEL_MASK \
(0xF << REG_AUDPLL_PRESCALER_DEL_SEL_SHIFT)
#define REG_AUDPLL_PRESCALER_DEL_SEL(n) \
BITFIELD_VAL(REG_AUDPLL_PRESCALER_DEL_SEL, n)
#define REG_AUDPLL_FREQ_34_32_SHIFT 13
#define REG_AUDPLL_FREQ_34_32_MASK (0x7 << REG_AUDPLL_FREQ_34_32_SHIFT)
#define REG_AUDPLL_FREQ_34_32(n) BITFIELD_VAL(REG_AUDPLL_FREQ_34_32, n)
// 7E
#define REG_CLKMUX_DVDD_SEL (1 << 0)
#define REG_CLKMUX_LDO0P9_VSEL_SHIFT 1
#define REG_CLKMUX_LDO0P9_VSEL_MASK (0x1F << REG_CLKMUX_LDO0P9_VSEL_SHIFT)
#define REG_CLKMUX_LDO0P9_VSEL(n) BITFIELD_VAL(REG_CLKMUX_LDO0P9_VSEL, n)
#define REG_PU_CLKMUX_LDO0P9 (1 << 6)
#define REG_AUDPLL_LDO_VREF_SHIFT 7
#define REG_AUDPLL_LDO_VREF_MASK (0x7 << REG_AUDPLL_LDO_VREF_SHIFT)
#define REG_AUDPLL_LDO_VREF(n) BITFIELD_VAL(REG_AUDPLL_LDO_VREF, n)
#define REG_AUDPLL_LPF_BW_SEL (1 << 10)
#define REG_CODEC_ADC_DITHER0P5_EN (1 << 11)
#define REG_CODEC_ADC_DITHER0P25_EN (1 << 12)
#define REG_CODEC_ADC_DITHER1_EN (1 << 13)
#define REG_CODEC_ADC_DITHER2_EN (1 << 14)
#define REG_CODEC_ADC_DITHER_PHASE_SEL (1 << 15)
// 174
#define CFG_TX_PEAK_OFF_ADC_EN (1 << 0)
#define CFG_TX_PEAK_OFF_DAC_EN (1 << 1)
#define CFG_PEAK_DET_DR (1 << 2)
#define CFG_TX_PEAK_OFF_ADC (1 << 3)
#define CFG_TX_PEAK_OFF_DAC (1 << 4)
#define CFG_PEAK_DET_DB_DELAY_SHIFT 5
#define CFG_PEAK_DET_DB_DELAY_MASK (0x7 << CFG_PEAK_DET_DB_DELAY_SHIFT)
#define CFG_PEAK_DET_DB_DELAY(n) BITFIELD_VAL(CFG_PEAK_DET_DB_DELAY, n)
#define REG_CODEC_TX_PEAK_DET_BIT (1 << 8)
#define REG_CODEC_TX_PEAK_NL_EN (1 << 9)
#define REG_CODEC_TX_PEAK_NR_EN (1 << 10)
#define REG_CODEC_TX_PEAK_PL_EN (1 << 11)
#define REG_CODEC_TX_PEAK_PR_EN (1 << 12)
#define CFG_TX_CLK_INV (1 << 13)
#define CFG_CODEC_DIN_L_RST (1 << 14)
#define CFG_CODEC_DIN_R_RST (1 << 15)
// C4
#define CODEC_RESAMPLE_CLK_BUF_PU (1 << 2)
// 16A
#define REG_CODEC_EN_ADCE (1 << 0)
#define DIG_CODEC_ADCE_DITHER_EN (1 << 1)
#define DIG_CODEC_ADCE_CH_SEL_SHIFT 2
#define DIG_CODEC_ADCE_CH_SEL_MASK (0x3 << DIG_CODEC_ADCE_CH_SEL_SHIFT)
#define DIG_CODEC_ADCE_CH_SEL(n) BITFIELD_VAL(DIG_CODEC_ADCE_CH_SEL, n)
#define REG_CODEC_RESET_ADCE (1 << 4)
#define CFG_RESET_ADCE_DR (1 << 5)
#define REG_CODEC_ADCE_GAIN_BIT_SHIFT 6
#define REG_CODEC_ADCE_GAIN_BIT_MASK (0x7 << REG_CODEC_ADCE_GAIN_BIT_SHIFT)
#define REG_CODEC_ADCE_GAIN_BIT(n) BITFIELD_VAL(REG_CODEC_ADCE_GAIN_BIT, n)
#define REG_CODEC_ADCE_GAIN_UPDATE (1 << 9)
#define REG_CODEC_ADCE_RES_2P5K (1 << 10)
#define REG_CODEC_ADCE_RES_2P5K_UPDATE (1 << 11)
#define DIG_CODEC_ADCE_IDETE_EN (1 << 12)
#define REG_RX_ADCE_ZERO_DET_EN (1 << 13)
#define CFG_ADCE_DITHER_CLK_INV (1 << 14)
#define DIG_CODEC_ADCE_CLK_SEL (1 << 15)
// 16B
#define DIG_CODEC_ADCE_IBSEL_OP1_SHIFT 0
#define DIG_CODEC_ADCE_IBSEL_OP1_MASK (0xF << DIG_CODEC_ADCE_IBSEL_OP1_SHIFT)
#define DIG_CODEC_ADCE_IBSEL_OP1(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_OP1, n)
#define DIG_CODEC_ADCE_IBSEL_OP2_SHIFT 4
#define DIG_CODEC_ADCE_IBSEL_OP2_MASK (0xF << DIG_CODEC_ADCE_IBSEL_OP2_SHIFT)
#define DIG_CODEC_ADCE_IBSEL_OP2(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_OP2, n)
#define DIG_CODEC_ADCE_IBSEL_OP3_SHIFT 8
#define DIG_CODEC_ADCE_IBSEL_OP3_MASK (0xF << DIG_CODEC_ADCE_IBSEL_OP3_SHIFT)
#define DIG_CODEC_ADCE_IBSEL_OP3(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_OP3, n)
#define DIG_CODEC_ADCE_IBSEL_OP4_SHIFT 12
#define DIG_CODEC_ADCE_IBSEL_OP4_MASK (0xF << DIG_CODEC_ADCE_IBSEL_OP4_SHIFT)
#define DIG_CODEC_ADCE_IBSEL_OP4(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_OP4, n)
// 16C
#define DIG_CODEC_ADCE_IBSEL_REG_SHIFT 0
#define DIG_CODEC_ADCE_IBSEL_REG_MASK (0xF << DIG_CODEC_ADCE_IBSEL_REG_SHIFT)
#define DIG_CODEC_ADCE_IBSEL_REG(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_REG, n)
#define DIG_CODEC_ADCE_IBSEL_VCOMP_SHIFT 4
#define DIG_CODEC_ADCE_IBSEL_VCOMP_MASK \
(0xF << DIG_CODEC_ADCE_IBSEL_VCOMP_SHIFT)
#define DIG_CODEC_ADCE_IBSEL_VCOMP(n) \
BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_VCOMP, n)
#define DIG_CODEC_ADCE_IBSEL_VREF_SHIFT 8
#define DIG_CODEC_ADCE_IBSEL_VREF_MASK (0xF << DIG_CODEC_ADCE_IBSEL_VREF_SHIFT)
#define DIG_CODEC_ADCE_IBSEL_VREF(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_VREF, n)
#define DIG_CODEC_ADCE_IBSEL_VREFBUF_SHIFT 12
#define DIG_CODEC_ADCE_IBSEL_VREFBUF_MASK \
(0xF << DIG_CODEC_ADCE_IBSEL_VREFBUF_SHIFT)
#define DIG_CODEC_ADCE_IBSEL_VREFBUF(n) \
BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_VREFBUF, n)
// 16D
#define DIG_CODEC_ADCE_IBSEL_IDAC2_SHIFT 0
#define DIG_CODEC_ADCE_IBSEL_IDAC2_MASK \
(0xF << DIG_CODEC_ADCE_IBSEL_IDAC2_SHIFT)
#define DIG_CODEC_ADCE_IBSEL_IDAC2(n) \
BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_IDAC2, n)
#define DIG_CODEC_ADCE_OP1_IBIT_SHIFT 4
#define DIG_CODEC_ADCE_OP1_IBIT_MASK (0x3 << DIG_CODEC_ADCE_OP1_IBIT_SHIFT)
#define DIG_CODEC_ADCE_OP1_IBIT(n) BITFIELD_VAL(DIG_CODEC_ADCE_OP1_IBIT, n)
#define DIG_CODEC_ADCE_OP1_R_SEL (1 << 6)
#define DIG_CODEC_ADCE_OP2_IBIT_SHIFT 7
#define DIG_CODEC_ADCE_OP2_IBIT_MASK (0x3 << DIG_CODEC_ADCE_OP2_IBIT_SHIFT)
#define DIG_CODEC_ADCE_OP2_IBIT(n) BITFIELD_VAL(DIG_CODEC_ADCE_OP2_IBIT, n)
#define DIG_CODEC_ADCE_OP2_R_SEL (1 << 9)
#define DIG_CODEC_ADCE_OP3_IBIT_SHIFT 10
#define DIG_CODEC_ADCE_OP3_IBIT_MASK (0x3 << DIG_CODEC_ADCE_OP3_IBIT_SHIFT)
#define DIG_CODEC_ADCE_OP3_IBIT(n) BITFIELD_VAL(DIG_CODEC_ADCE_OP3_IBIT, n)
#define DIG_CODEC_ADCE_OP3_R_SEL (1 << 12)
#define DIG_CODEC_ADCE_OP4_IBIT_SHIFT 13
#define DIG_CODEC_ADCE_OP4_IBIT_MASK (0x3 << DIG_CODEC_ADCE_OP4_IBIT_SHIFT)
#define DIG_CODEC_ADCE_OP4_IBIT(n) BITFIELD_VAL(DIG_CODEC_ADCE_OP4_IBIT, n)
#define DIG_CODEC_ADCE_OP4_R_SEL (1 << 15)
// 16E
#define DIG_CODEC_ADCE_VREF_SEL_SHIFT 0
#define DIG_CODEC_ADCE_VREF_SEL_MASK (0xF << DIG_CODEC_ADCE_VREF_SEL_SHIFT)
#define DIG_CODEC_ADCE_VREF_SEL(n) BITFIELD_VAL(DIG_CODEC_ADCE_VREF_SEL, n)
#define DIG_CODEC_ADCE_VREFBUF_BIT_SHIFT 4
#define DIG_CODEC_ADCE_VREFBUF_BIT_MASK \
(0xF << DIG_CODEC_ADCE_VREFBUF_BIT_SHIFT)
#define DIG_CODEC_ADCE_VREFBUF_BIT(n) \
BITFIELD_VAL(DIG_CODEC_ADCE_VREFBUF_BIT, n)
#define DIG_CODEC_ADCE_REG_VSEL_SHIFT 8
#define DIG_CODEC_ADCE_REG_VSEL_MASK (0x7 << DIG_CODEC_ADCE_REG_VSEL_SHIFT)
#define DIG_CODEC_ADCE_REG_VSEL(n) BITFIELD_VAL(DIG_CODEC_ADCE_REG_VSEL, n)
#define DIG_CODEC_ADCE_CAP_BIT (1 << 11)
#define REG_VOICE_SEL_VREF_BIN_SHIFT 12
#define REG_VOICE_SEL_VREF_BIN_MASK (0xF << REG_VOICE_SEL_VREF_BIN_SHIFT)
#define REG_VOICE_SEL_VREF_BIN(n) BITFIELD_VAL(REG_VOICE_SEL_VREF_BIN, n)
// 16F
#define REG_VOICE_LP_COMP_SHIFT 0
#define REG_VOICE_LP_COMP_MASK (0x7 << REG_VOICE_LP_COMP_SHIFT)
#define REG_VOICE_LP_COMP(n) BITFIELD_VAL(REG_VOICE_LP_COMP, n)
#define REG_VOICE_LP_AMPA_SHIFT 3
#define REG_VOICE_LP_AMPA_MASK (0x7 << REG_VOICE_LP_AMPA_SHIFT)
#define REG_VOICE_LP_AMPA(n) BITFIELD_VAL(REG_VOICE_LP_AMPA, n)
#define REG_VOICE_LP_AMPB_SHIFT 6
#define REG_VOICE_LP_AMPB_MASK (0x7 << REG_VOICE_LP_AMPB_SHIFT)
#define REG_VOICE_LP_AMPB(n) BITFIELD_VAL(REG_VOICE_LP_AMPB, n)
#define REG_VOICE_LP_LDO_SHIFT 9
#define REG_VOICE_LP_LDO_MASK (0x7 << REG_VOICE_LP_LDO_SHIFT)
#define REG_VOICE_LP_LDO(n) BITFIELD_VAL(REG_VOICE_LP_LDO, n)
#define REG_VOICE_LP_VREF_SHIFT 12
#define REG_VOICE_LP_VREF_MASK (0x7 << REG_VOICE_LP_VREF_SHIFT)
#define REG_VOICE_LP_VREF(n) BITFIELD_VAL(REG_VOICE_LP_VREF, n)
#define CFG_REG_VOICE_TRIG_ADCE_EN (1 << 15)
// 170
#define REG_VOICE_HIGH_TUNE_A_SHIFT 0
#define REG_VOICE_HIGH_TUNE_A_MASK (0xF << REG_VOICE_HIGH_TUNE_A_SHIFT)
#define REG_VOICE_HIGH_TUNE_A(n) BITFIELD_VAL(REG_VOICE_HIGH_TUNE_A, n)
#define REG_VOICE_HIGH_TUNE_B_SHIFT 4
#define REG_VOICE_HIGH_TUNE_B_MASK (0xF << REG_VOICE_HIGH_TUNE_B_SHIFT)
#define REG_VOICE_HIGH_TUNE_B(n) BITFIELD_VAL(REG_VOICE_HIGH_TUNE_B, n)
#define REG_VOICE_GAIN_A_SHIFT 8
#define REG_VOICE_GAIN_A_MASK (0x7 << REG_VOICE_GAIN_A_SHIFT)
#define REG_VOICE_GAIN_A(n) BITFIELD_VAL(REG_VOICE_GAIN_A, n)
#define REG_VOICE_GAIN_B_SHIFT 11
#define REG_VOICE_GAIN_B_MASK (0x7 << REG_VOICE_GAIN_B_SHIFT)
#define REG_VOICE_GAIN_B(n) BITFIELD_VAL(REG_VOICE_GAIN_B, n)
#define CFG_ADC_START (1 << 14)
#define CFG_VOICE2ADCE (1 << 15)
// 171
#define CFG_VOICE_POWER_ON (1 << 0)
#define CFG_VOICE_TRIG_ENABLE (1 << 1)
#define CFG_VOICE_RESET (1 << 2)
#define CFG_VOICE_DR (1 << 3)
#define CFG_VOICE_PU_DELAY_SHIFT 4
#define CFG_VOICE_PU_DELAY_MASK (0x7 << CFG_VOICE_PU_DELAY_SHIFT)
#define CFG_VOICE_PU_DELAY(n) BITFIELD_VAL(CFG_VOICE_PU_DELAY, n)
#define CFG_VOICE_PRECH_DELAY_SHIFT 7
#define CFG_VOICE_PRECH_DELAY_MASK (0xFF << CFG_VOICE_PRECH_DELAY_SHIFT)
#define CFG_VOICE_PRECH_DELAY(n) BITFIELD_VAL(CFG_VOICE_PRECH_DELAY, n)
#define REG_VOICE_EN_AGPIO_TEST (1 << 15)
// 172
#define REG_VOICE_CLK_EDGE_SEL (1 << 0)
#define REG_VOICE_PRECH (1 << 1)
#define REG_VOICE_PU (1 << 2)
#define REG_VOICE_PU_LDO (1 << 3)
#define REG_VOICE_SEL_VCM0P3_BIN_SHIFT 4
#define REG_VOICE_SEL_VCM0P3_BIN_MASK (0x7 << REG_VOICE_SEL_VCM0P3_BIN_SHIFT)
#define REG_VOICE_SEL_VCM0P3_BIN(n) BITFIELD_VAL(REG_VOICE_SEL_VCM0P3_BIN, n)
#define REG_VOICE_SEL_VCM_BIN_SHIFT 7
#define REG_VOICE_SEL_VCM_BIN_MASK (0xF << REG_VOICE_SEL_VCM_BIN_SHIFT)
#define REG_VOICE_SEL_VCM_BIN(n) BITFIELD_VAL(REG_VOICE_SEL_VCM_BIN, n)
#define REG_VOICE_SEL_VCMIN_BIN_SHIFT 11
#define REG_VOICE_SEL_VCMIN_BIN_MASK (0xF << REG_VOICE_SEL_VCMIN_BIN_SHIFT)
#define REG_VOICE_SEL_VCMIN_BIN(n) BITFIELD_VAL(REG_VOICE_SEL_VCMIN_BIN, n)
#define REG_VOICE_PU_OSC (1 << 15)
// 173
#define REG_VOICE_LDO_VBIT_SHIFT 0
#define REG_VOICE_LDO_VBIT_MASK (0x7 << REG_VOICE_LDO_VBIT_SHIFT)
#define REG_VOICE_LDO_VBIT(n) BITFIELD_VAL(REG_VOICE_LDO_VBIT, n)
#define REG_VOICE_OSC_FR_SHIFT 3
#define REG_VOICE_OSC_FR_MASK (0x7 << REG_VOICE_OSC_FR_SHIFT)
#define REG_VOICE_OSC_FR(n) BITFIELD_VAL(REG_VOICE_OSC_FR, n)
#define REG_VOICE_OSC_PWR_SHIFT 6
#define REG_VOICE_OSC_PWR_MASK (0x3 << REG_VOICE_OSC_PWR_SHIFT)
#define REG_VOICE_OSC_PWR(n) BITFIELD_VAL(REG_VOICE_OSC_PWR, n)
#define CFG_VOICE_DET_DELAY_SHIFT 8
#define CFG_VOICE_DET_DELAY_MASK (0xFF << CFG_VOICE_DET_DELAY_SHIFT)
#define CFG_VOICE_DET_DELAY(n) BITFIELD_VAL(CFG_VOICE_DET_DELAY, n)
// 174
#define CFG_TX_PEAK_OFF_ADC_EN (1 << 0)
#define CFG_TX_PEAK_OFF_DAC_EN (1 << 1)
#define CFG_PEAK_DET_DR (1 << 2)
#define CFG_TX_PEAK_OFF_ADC (1 << 3)
#define CFG_TX_PEAK_OFF_DAC (1 << 4)
#define CFG_PEAK_DET_DB_DELAY_SHIFT 5
#define CFG_PEAK_DET_DB_DELAY_MASK (0x7 << CFG_PEAK_DET_DB_DELAY_SHIFT)
#define CFG_PEAK_DET_DB_DELAY(n) BITFIELD_VAL(CFG_PEAK_DET_DB_DELAY, n)
#define REG_CODEC_TX_PEAK_DET_BIT (1 << 8)
#define REG_CODEC_TX_PEAK_NL_EN (1 << 9)
#define REG_CODEC_TX_PEAK_NR_EN (1 << 10)
#define REG_CODEC_TX_PEAK_PL_EN (1 << 11)
#define REG_CODEC_TX_PEAK_PR_EN (1 << 12)
#define CFG_TX_CLK_INV (1 << 13)
#define CFG_CODEC_DIN_L_RST (1 << 14)
#define CFG_CODEC_DIN_R_RST (1 << 15)
// 175
#define CODEC_DIN_L_HI_RSTVAL_SHIFT 0
#define CODEC_DIN_L_HI_RSTVAL_MASK (0xFFFF << CODEC_DIN_L_HI_RSTVAL_SHIFT)
#define CODEC_DIN_L_HI_RSTVAL(n) BITFIELD_VAL(CODEC_DIN_L_HI_RSTVAL, n)
// 176
#define CODEC_DIN_L_LO_RSTVAL_SHIFT 0
#define CODEC_DIN_L_LO_RSTVAL_MASK (0xFFFF << CODEC_DIN_L_LO_RSTVAL_SHIFT)
#define CODEC_DIN_L_LO_RSTVAL(n) BITFIELD_VAL(CODEC_DIN_L_LO_RSTVAL, n)
// 177
#define CODEC_DIN_R_HI_RSTVAL_SHIFT 0
#define CODEC_DIN_R_HI_RSTVAL_MASK (0xFFFF << CODEC_DIN_R_HI_RSTVAL_SHIFT)
#define CODEC_DIN_R_HI_RSTVAL(n) BITFIELD_VAL(CODEC_DIN_R_HI_RSTVAL, n)
// 178
#define CODEC_DIN_R_LO_RSTVAL_SHIFT 0
#define CODEC_DIN_R_LO_RSTVAL_MASK (0xFFFF << CODEC_DIN_R_LO_RSTVAL_SHIFT)
#define CODEC_DIN_R_LO_RSTVAL(n) BITFIELD_VAL(CODEC_DIN_R_LO_RSTVAL, n)
// 179
#define REG_AUDPLL_LDOPRECHG_TIMER_SHIFT 0
#define REG_AUDPLL_LDOPRECHG_TIMER_MASK \
(0x1F << REG_AUDPLL_LDOPRECHG_TIMER_SHIFT)
#define REG_AUDPLL_LDOPRECHG_TIMER(n) \
BITFIELD_VAL(REG_AUDPLL_LDOPRECHG_TIMER, n)
#define REG_AUDPLL_PRECHG_BEGIN_TIMER_SHIFT 5
#define REG_AUDPLL_PRECHG_BEGIN_TIMER_MASK \
(0x1F << REG_AUDPLL_PRECHG_BEGIN_TIMER_SHIFT)
#define REG_AUDPLL_PRECHG_BEGIN_TIMER(n) \
BITFIELD_VAL(REG_AUDPLL_PRECHG_BEGIN_TIMER, n)
#define REG_AUDPLL_PRECHG_END_TIMER_SHIFT 10
#define REG_AUDPLL_PRECHG_END_TIMER_MASK \
(0x1F << REG_AUDPLL_PRECHG_END_TIMER_SHIFT)
#define REG_AUDPLL_PRECHG_END_TIMER(n) \
BITFIELD_VAL(REG_AUDPLL_PRECHG_END_TIMER, n)
#define REG_CODEC_ADCD_RES_2P5K_DR (1 << 15)
// 17A
#define CFG_PRE_CHARGE_ADCE_DR (1 << 0)
#define REG_CODEC_ADCE_PRE_CHARGE (1 << 1)
#define ADCE_OPEN_TIMER_DLY_SHIFT 2
#define ADCE_OPEN_TIMER_DLY_MASK (0xF << ADCE_OPEN_TIMER_DLY_SHIFT)
#define ADCE_OPEN_TIMER_DLY(n) BITFIELD_VAL(ADCE_OPEN_TIMER_DLY, n)
#define ADCE_PRE_CHARGE_TIMER_DLY_SHIFT 6
#define ADCE_PRE_CHARGE_TIMER_DLY_MASK (0xFF << ADCE_PRE_CHARGE_TIMER_DLY_SHIFT)
#define ADCE_PRE_CHARGE_TIMER_DLY(n) BITFIELD_VAL(ADCE_PRE_CHARGE_TIMER_DLY, n)
#define REG_VOICE_LOW_TUNE_SHIFT 14
#define REG_VOICE_LOW_TUNE_MASK (0x3 << REG_VOICE_LOW_TUNE_SHIFT)
#define REG_VOICE_LOW_TUNE(n) BITFIELD_VAL(REG_VOICE_LOW_TUNE, n)
// 17B
#define REG_COARSE_EN (1 << 0)
#define REG_XTAL_FREQ_LLC_SFT_RSTN (1 << 1)
#define REG_COARSE_POLAR_SEL (1 << 2)
#define REG_AUDPLL_RSTB_TIMER_SHIFT 3
#define REG_AUDPLL_RSTB_TIMER_MASK (0x1F << REG_AUDPLL_RSTB_TIMER_SHIFT)
#define REG_AUDPLL_RSTB_TIMER(n) BITFIELD_VAL(REG_AUDPLL_RSTB_TIMER, n)
#define RX_TIMER_RSTN_DLY_SHIFT 8
#define RX_TIMER_RSTN_DLY_MASK (0xFF << RX_TIMER_RSTN_DLY_SHIFT)
#define RX_TIMER_RSTN_DLY(n) BITFIELD_VAL(RX_TIMER_RSTN_DLY, n)
// 17C
#define REG_CNT_COARSE_MARK_SHIFT 0
#define REG_CNT_COARSE_MARK_MASK (0xFFFF << REG_CNT_COARSE_MARK_SHIFT)
#define REG_CNT_COARSE_MARK(n) BITFIELD_VAL(REG_CNT_COARSE_MARK, n)
// 17D
#define REG_CLK_GOAL_DIV_NUM_SHIFT 0
#define REG_CLK_GOAL_DIV_NUM_MASK (0x1FF << REG_CLK_GOAL_DIV_NUM_SHIFT)
#define REG_CLK_GOAL_DIV_NUM(n) BITFIELD_VAL(REG_CLK_GOAL_DIV_NUM, n)
#define REG_COARSE_TUN_CODE_SHIFT 9
#define REG_COARSE_TUN_CODE_MASK (0x3F << REG_COARSE_TUN_CODE_SHIFT)
#define REG_COARSE_TUN_CODE(n) BITFIELD_VAL(REG_COARSE_TUN_CODE, n)
#define REG_COARSE_TUN_CODE_DR (1 << 15)
// 17E
#define SSC_ENABLE (1 << 0)
#define TRI_FREQ_OFST_SEL_SHIFT 1
#define TRI_FREQ_OFST_SEL_MASK (0x7 << TRI_FREQ_OFST_SEL_SHIFT)
#define TRI_FREQ_OFST_SEL(n) BITFIELD_VAL(TRI_FREQ_OFST_SEL, n)
#define TRI_FREQ_SEL_SHIFT 4
#define TRI_FREQ_SEL_MASK (0x3 << TRI_FREQ_SEL_SHIFT)
#define TRI_FREQ_SEL(n) BITFIELD_VAL(TRI_FREQ_SEL, n)
#define REG_VOICE_EN_REF_TEST (1 << 6)
#define REG_VOICE_GAIN_BASE_SHIFT 7
#define REG_VOICE_GAIN_BASE_MASK (0x7 << REG_VOICE_GAIN_BASE_SHIFT)
#define REG_VOICE_GAIN_BASE(n) BITFIELD_VAL(REG_VOICE_GAIN_BASE, n)
#define CFG_VOICE_PRECH_DONE_DELAY_SHIFT 10
#define CFG_VOICE_PRECH_DONE_DELAY_MASK \
(0x1F << CFG_VOICE_PRECH_DONE_DELAY_SHIFT)
#define CFG_VOICE_PRECH_DONE_DELAY(n) \
BITFIELD_VAL(CFG_VOICE_PRECH_DONE_DELAY, n)
#define REG_CODEC_LP_VCM_DR (1 << 15)
// 17F
#define TX_PEAK_DET_STATUS (1 << 0)
#define TX_PEAK_DET_NL_STATUS (1 << 1)
#define TX_PEAK_DET_NR_STATUS (1 << 2)
#define TX_PEAK_DET_PL_STATUS (1 << 3)
#define TX_PEAK_DET_PR_STATUS (1 << 4)
#define DBG_STATE_SHIFT 5
#define DBG_STATE_MASK (0x3 << DBG_STATE_SHIFT)
#define DBG_STATE(n) BITFIELD_VAL(DBG_STATE, n)
enum ANA_REG_T {
ANA_REG_61 = 0x61,
ANA_REG_62,
ANA_REG_63,
ANA_REG_64,
ANA_REG_65,
ANA_REG_66,
ANA_REG_67,
ANA_REG_68,
ANA_REG_69,
ANA_REG_6A,
ANA_REG_6B,
ANA_REG_6C,
ANA_REG_6D,
ANA_REG_6E,
ANA_REG_6F,
ANA_REG_70,
ANA_REG_71,
ANA_REG_72,
ANA_REG_73,
ANA_REG_74,
ANA_REG_75,
ANA_REG_76,
ANA_REG_77,
ANA_REG_78,
ANA_REG_79,
ANA_REG_7A,
ANA_REG_7B,
ANA_REG_7C,
ANA_REG_7D,
ANA_REG_7E,
ANA_REG_7F,
ANA_REG_161 = 0x161,
ANA_REG_162,
ANA_REG_163,
ANA_REG_164,
ANA_REG_165,
ANA_REG_166,
ANA_REG_167,
ANA_REG_168,
ANA_REG_169,
ANA_REG_16A,
ANA_REG_16B,
ANA_REG_16C,
ANA_REG_16D,
ANA_REG_16E,
ANA_REG_16F,
ANA_REG_170,
ANA_REG_171,
ANA_REG_172,
ANA_REG_173,
ANA_REG_174,
ANA_REG_175,
ANA_REG_176,
ANA_REG_177,
ANA_REG_178,
ANA_REG_179,
ANA_REG_17A,
ANA_REG_17B,
ANA_REG_17C,
ANA_REG_17D,
ANA_REG_17E,
ANA_REG_17F,
ANA_REG_RF_C4 = 0xC4,
};
enum ANA_CODEC_USER_T {
ANA_CODEC_USER_DAC = (1 << 0),
ANA_CODEC_USER_ADC = (1 << 1),
ANA_CODEC_USER_CODEC = (1 << 2),
ANA_CODEC_USER_MICKEY = (1 << 3),
ANA_CODEC_USER_ANC_FF = (1 << 4),
ANA_CODEC_USER_ANC_FB = (1 << 5),
ANA_CODEC_USER_VAD = (1 << 6),
};
struct ANALOG_PLL_CFG_T {
uint32_t freq;
uint8_t div;
uint64_t val;
};
#ifdef ANC_PROD_TEST
#define OPT_TYPE
#else
#define OPT_TYPE const
#endif
static OPT_TYPE uint16_t vcodec_mv = (uint16_t)(VCODEC_VOLT * 1000);
static bool ana_spk_req;
static bool ana_spk_muted;
static bool ana_spk_enabled;
static bool anc_calib_mode;
static enum ANA_CODEC_USER_T adc_map[MAX_ANA_MIC_CH_NUM];
static enum ANA_CODEC_USER_T vmic_map[MAX_ANA_MIC_CH_NUM];
static enum ANA_CODEC_USER_T codec_common_map;
static enum ANA_CODEC_USER_T adda_common_map;
static enum ANA_CODEC_USER_T vcodec_map;
static enum ANA_AUD_PLL_USER_T ana_aud_pll_map;
#ifdef ANC_APP
#ifndef DYN_ADC_GAIN
#define DYN_ADC_GAIN
#endif
#endif
#ifdef DYN_ADC_GAIN
static int8_t adc_gain_offset[MAX_ANA_MIC_CH_NUM];
#endif
static const int8_t adc_db[] = {
-9, -6, -3, 0, 3, 6, 9, 12,
};
static const int8_t tgt_adc_db[MAX_ANA_MIC_CH_NUM] = {
ANALOG_ADC_A_GAIN_DB, ANALOG_ADC_B_GAIN_DB, ANALOG_ADC_C_GAIN_DB,
ANALOG_ADC_D_GAIN_DB, ANALOG_ADC_E_GAIN_DB,
};
// Max allowed total tune ratio (5000ppm)
#define MAX_TOTAL_TUNE_RATIO 0.005000
static struct ANALOG_PLL_CFG_T ana_pll_cfg[2];
static int pll_cfg_idx;
void analog_aud_freq_pll_config(uint32_t freq, uint32_t div) {
// CODEC_FREQ is likely 24.576M (48K series) or 22.5792M (44.1K series)
// PLL_nominal = CODEC_FREQ * CODEC_DIV
// PLL_cfg_val = ((CODEC_FREQ * CODEC_DIV) / 26M) * (1 << 28)
int i, j;
uint64_t PLL_cfg_val;
uint16_t high, low, bit34_32;
uint16_t val;
if (pll_cfg_idx < ARRAY_SIZE(ana_pll_cfg) &&
ana_pll_cfg[pll_cfg_idx].freq == freq &&
ana_pll_cfg[pll_cfg_idx].div == div) {
return;
}
j = ARRAY_SIZE(ana_pll_cfg);
for (i = 0; i < ARRAY_SIZE(ana_pll_cfg); i++) {
if (ana_pll_cfg[i].freq == freq && ana_pll_cfg[i].div == div) {
break;
}
if (j == ARRAY_SIZE(ana_pll_cfg) && ana_pll_cfg[i].freq == 0) {
j = i;
}
}
if (i < ARRAY_SIZE(ana_pll_cfg)) {
pll_cfg_idx = i;
PLL_cfg_val = ana_pll_cfg[pll_cfg_idx].val;
} else {
if (j < ARRAY_SIZE(ana_pll_cfg)) {
pll_cfg_idx = j;
} else {
pll_cfg_idx = 0;
}
PLL_cfg_val = ((uint64_t)(1 << 28) * freq * div + 26000000 / 2) / 26000000;
ana_pll_cfg[pll_cfg_idx].freq = freq;
ana_pll_cfg[pll_cfg_idx].div = div;
ana_pll_cfg[pll_cfg_idx].val = PLL_cfg_val;
}
low = PLL_cfg_val & 0xFFFF;
high = (PLL_cfg_val >> 16) & 0xFFFF;
bit34_32 = (PLL_cfg_val >> 32) & 0xFFFF;
pmu_pll_div_set(HAL_CMU_PLL_AUD, PMU_PLL_DIV_CODEC, div);
analog_write(ANA_REG_7C, low);
analog_write(ANA_REG_7B, high);
analog_read(ANA_REG_7A, &val);
val = SET_BITFIELD(val, REG_AUDPLL_FREQ_34_32, bit34_32) | REG_AUDPLL_FREQ_EN;
analog_write(ANA_REG_7A, val);
}
void analog_aud_pll_tune(float ratio) {
#ifdef __AUDIO_RESAMPLE__
if (hal_cmu_get_audio_resample_status()) {
return;
}
#endif
// CODEC_FREQ is likely 24.576M (48K series) or 22.5792M (44.1K series)
// PLL_nominal = CODEC_FREQ * CODEC_DIV
// PLL_cfg_val = ((CODEC_FREQ * CODEC_DIV) / 26M) * (1 << 28)
// Delta = ((SampleDiff / Fs) / TimeDiff) * PLL_cfg_val
int64_t delta, new_pll;
uint16_t new_high, new_low;
uint16_t val, new_bit34_32;
if (pll_cfg_idx >= ARRAY_SIZE(ana_pll_cfg) ||
ana_pll_cfg[pll_cfg_idx].freq == 0) {
ANALOG_INFO_TRACE(1,
"%s: WARNING: aud pll config cache invalid. Skip tuning",
__FUNCTION__);
return;
}
if (ABS(ratio) > MAX_TOTAL_TUNE_RATIO) {
ANALOG_INFO_TRACE(1,
"\n------\nWARNING: TUNE: ratio=%d is too large and will "
"be cut\n------\n",
FLOAT_TO_PPB_INT(ratio));
if (ratio > 0) {
ratio = MAX_TOTAL_TUNE_RATIO;
} else {
ratio = -MAX_TOTAL_TUNE_RATIO;
}
}
ANALOG_INFO_TRACE(2, "%s: ratio=%d", __FUNCTION__, FLOAT_TO_PPB_INT(ratio));
new_pll = (int64_t)ana_pll_cfg[pll_cfg_idx].val;
delta = (int64_t)(new_pll * ratio);
new_pll += delta;
new_low = new_pll & 0xFFFF;
new_high = (new_pll >> 16) & 0xFFFF;
new_bit34_32 = (new_pll >> 32) & 0xFFFF;
analog_write(ANA_REG_7C, new_low);
analog_write(ANA_REG_7B, new_high);
analog_read(ANA_REG_7A, &val);
val = SET_BITFIELD(val, REG_AUDPLL_FREQ_34_32, new_bit34_32) |
REG_AUDPLL_FREQ_EN;
analog_write(ANA_REG_7A, val);
}
void analog_aud_osc_clk_enable(bool enable) {
uint16_t val;
if (enable) {
analog_read(ANA_REG_RF_C4, &val);
val |= CODEC_RESAMPLE_CLK_BUF_PU;
analog_write(ANA_REG_RF_C4, val);
analog_read(ANA_REG_7A, &val);
val |= REG_PU_OSC;
analog_write(ANA_REG_7A, val);
analog_read(ANA_REG_75, &val);
val |= REG_CRYSTAL_SEL_LV;
analog_write(ANA_REG_75, val);
#if 0
analog_read(ANA_REG_174, &val);
val |= CFG_TX_CLK_INV;
analog_write(ANA_REG_174, val);
#endif
} else {
#if 0
analog_read(ANA_REG_174, &val);
val &= ~CFG_TX_CLK_INV;
analog_write(ANA_REG_174, val);
#endif
analog_read(ANA_REG_75, &val);
val &= ~REG_CRYSTAL_SEL_LV;
analog_write(ANA_REG_75, val);
analog_read(ANA_REG_7A, &val);
val &= ~REG_PU_OSC;
analog_write(ANA_REG_7A, val);
analog_read(ANA_REG_RF_C4, &val);
val &= ~CODEC_RESAMPLE_CLK_BUF_PU;
analog_write(ANA_REG_RF_C4, val);
}
}
void analog_aud_pll_open(enum ANA_AUD_PLL_USER_T user) {
if (user >= ANA_AUD_PLL_USER_END) {
return;
}
#ifdef __AUDIO_RESAMPLE__
if (user == ANA_AUD_PLL_USER_CODEC && hal_cmu_get_audio_resample_status()) {
analog_aud_osc_clk_enable(true);
return;
}
#endif
if (ana_aud_pll_map == 0) {
hal_cmu_pll_enable(HAL_CMU_PLL_AUD, HAL_CMU_PLL_USER_AUD);
}
ana_aud_pll_map |= user;
}
void analog_aud_pll_close(enum ANA_AUD_PLL_USER_T user) {
if (user >= ANA_AUD_PLL_USER_END) {
return;
}
#ifdef __AUDIO_RESAMPLE__
if (user == ANA_AUD_PLL_USER_CODEC && hal_cmu_get_audio_resample_status()) {
analog_aud_osc_clk_enable(false);
return;
}
#endif
ana_aud_pll_map &= ~user;
if (ana_aud_pll_map == 0) {
hal_cmu_pll_disable(HAL_CMU_PLL_AUD, HAL_CMU_PLL_USER_AUD);
}
}
static void analog_aud_enable_dac(uint32_t dac) {
uint16_t val_6e;
uint16_t val_70;
uint16_t val_73;
analog_read(ANA_REG_6E, &val_6e);
analog_read(ANA_REG_70, &val_70);
if (dac & (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1)) {
val_6e |= REG_CODEC_TX_EAR_DR_EN | REG_CODEC_TX_EAR_ENBIAS;
analog_write(ANA_REG_6E, val_6e);
osDelay(1);
val_70 |= CFG_TX_TREE_EN;
analog_write(ANA_REG_70, val_70);
osDelay(1);
val_73 = 0;
if (dac & AUD_CHANNEL_MAP_CH0) {
val_73 |=
REG_CODEC_TX_EN_EARPA_L | REG_CODEC_TX_EN_LCLK | REG_CODEC_TX_EN_LDAC;
}
if (dac & AUD_CHANNEL_MAP_CH1) {
val_73 |= REG_CODEC_TX_EN_EARPA_R | REG_CODEC_TX_EN_RCLK |
REG_CODEC_TX_EN_RDAC | REG_CODEC_TX_EN_LDAC;
}
val_73 |= REG_CODEC_TX_EN_DACLDO | REG_CODEC_TX_EN_LPPA;
analog_write(ANA_REG_73, val_73);
osDelay(1);
val_73 |= REG_CODEC_TX_EN_S1PA;
analog_write(ANA_REG_73, val_73);
// Ensure 1ms delay before enabling dac_pa
osDelay(1);
} else {
// Ensure 1ms delay after disabling dac_pa
osDelay(1);
analog_read(ANA_REG_73, &val_73);
val_73 &= ~REG_CODEC_TX_EN_S1PA;
analog_write(ANA_REG_73, val_73);
osDelay(1);
val_73 = 0;
analog_write(ANA_REG_73, val_73);
osDelay(1);
val_70 &= ~CFG_TX_TREE_EN;
analog_write(ANA_REG_70, val_70);
osDelay(1);
val_6e &= ~(REG_CODEC_TX_EAR_DR_EN | REG_CODEC_TX_EAR_ENBIAS);
analog_write(ANA_REG_6E, val_6e);
}
}
static void analog_aud_enable_dac_pa(uint32_t dac) {
uint16_t val_73;
analog_read(ANA_REG_73, &val_73);
if (dac & (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1)) {
val_73 |= REG_CODEC_TX_EN_S4PA;
analog_write(ANA_REG_73, val_73);
#ifdef AUDIO_OUTPUT_DC_CALIB_ANA
hal_codec_dac_sdm_reset_clear();
#endif
} else {
#ifdef AUDIO_OUTPUT_DC_CALIB_ANA
hal_codec_dac_sdm_reset_set();
#endif
val_73 &= ~REG_CODEC_TX_EN_S4PA;
analog_write(ANA_REG_73, val_73);
}
}
static void analog_aud_enable_adc(enum ANA_CODEC_USER_T user,
enum AUD_CHANNEL_MAP_T ch_map, bool en) {
int i;
uint16_t val_61, val_6c, val_16a;
enum ANA_CODEC_USER_T old_map;
bool set;
bool global_update;
ANALOG_DEBUG_TRACE(3, "[%s] user=%d ch_map=0x%x", __func__, user, ch_map);
global_update = false;
analog_read(ANA_REG_61, &val_61);
analog_read(ANA_REG_16A, &val_16a);
for (i = 0; i < MAX_ANA_MIC_CH_NUM; i++) {
if (ch_map & (AUD_CHANNEL_MAP_CH0 << i)) {
set = false;
if (en) {
if (adc_map[i] == 0) {
set = true;
}
adc_map[i] |= user;
} else {
old_map = adc_map[i];
adc_map[i] &= ~user;
if (old_map != 0 && adc_map[i] == 0) {
set = true;
}
}
if (set) {
global_update = true;
if (i == 4) {
if (adc_map[i]) {
val_16a |= REG_CODEC_EN_ADCE;
} else {
val_16a &= ~REG_CODEC_EN_ADCE;
}
} else {
if (adc_map[i]) {
val_61 |= (REG_CODEC_EN_ADCA << i);
} else {
val_61 &= ~(REG_CODEC_EN_ADCA << i);
}
}
}
}
}
analog_write(ANA_REG_61, val_61);
analog_write(ANA_REG_16A, val_16a);
if (global_update) {
for (i = 0; i < MAX_ANA_MIC_CH_NUM; i++) {
if (adc_map[i]) {
break;
}
}
analog_read(ANA_REG_6C, &val_6c);
if (i < MAX_ANA_MIC_CH_NUM) {
val_6c |= REG_CODEC_RX_EN_VTOI;
} else {
val_6c &= ~REG_CODEC_RX_EN_VTOI;
}
analog_write(ANA_REG_6C, val_6c);
}
}
static uint32_t db_to_adc_gain(int db) {
int i;
uint8_t cnt;
const int8_t *list;
list = adc_db;
cnt = ARRAY_SIZE(adc_db);
for (i = 0; i < cnt - 1; i++) {
if (db < list[i + 1]) {
break;
}
}
if (i == cnt - 1) {
return i;
} else if (db * 2 < list[i] + list[i + 1]) {
return i;
} else {
return i + 1;
}
}
static int8_t get_chan_adc_gain(uint32_t i) {
int8_t gain;
gain = tgt_adc_db[i];
#ifdef DYN_ADC_GAIN
if (adc_gain_offset[i] < 0 && -adc_gain_offset[i] > gain) {
gain = 0;
} else {
gain += adc_gain_offset[i];
}
#endif
return gain;
}
static void analog_aud_set_adc_gain(enum AUD_IO_PATH_T input_path,
enum AUD_CHANNEL_MAP_T ch_map) {
int i;
int gain;
uint16_t gain_val;
uint16_t val, val_16a;
analog_read(ANA_REG_63, &val);
if (ch_map & AUD_CHANNEL_MAP_CH4) {
analog_read(ANA_REG_16A, &val_16a);
} else {
val_16a = 0;
}
for (i = 0; i < MAX_ANA_MIC_CH_NUM; i++) {
if (ch_map & (AUD_CHANNEL_MAP_CH0 << i)) {
if (0) {
#ifdef ANC_APP
#ifdef ANC_FF_ENABLED
} else if ((ANC_FF_MIC_CH_L | ANC_FF_MIC_CH_R) &
(AUD_CHANNEL_MAP_CH0 << i)) {
gain = get_chan_adc_gain(i);
#endif
#ifdef ANC_FB_ENABLED
} else if ((ANC_FB_MIC_CH_L | ANC_FB_MIC_CH_R) &
(AUD_CHANNEL_MAP_CH0 << i)) {
gain = get_chan_adc_gain(i);
#endif
#endif
} else if (input_path == AUD_INPUT_PATH_LINEIN) {
gain = LINEIN_ADC_GAIN_DB;
} else {
gain = get_chan_adc_gain(i);
}
gain_val = db_to_adc_gain(gain);
if (i < MAX_ANA_MIC_CH_NUM - 1) {
val = (val & ~(REG_CODEC_ADCA_GAIN_BIT_MASK << 3 * i)) |
(REG_CODEC_ADCA_GAIN_BIT(gain_val) << 3 * i);
} else {
val_16a = SET_BITFIELD(val_16a, REG_CODEC_ADCE_GAIN_BIT, gain_val);
}
}
}
analog_write(ANA_REG_63, val);
if (ch_map & AUD_CHANNEL_MAP_CH4) {
analog_write(ANA_REG_16A, val_16a);
}
}
#ifdef ANC_APP
void analog_aud_apply_anc_adc_gain_offset(enum ANC_TYPE_T type,
int16_t offset_l, int16_t offset_r) {
enum ANC_TYPE_T single_type;
enum AUD_CHANNEL_MAP_T ch_map;
uint32_t l, r;
int8_t org_l, adj_l;
int8_t org_r, adj_r;
// qdb to db
offset_l /= 4;
offset_r /= 4;
while (type) {
l = get_msb_pos(type);
single_type = (1 << l);
type &= ~single_type;
ch_map = 0;
l = r = 32;
if (0) {
#if defined(ANC_FF_MIC_CH_L) || defined(ANC_FF_MIC_CH_R)
} else if (single_type == ANC_FEEDFORWARD) {
ch_map |= ANC_FF_MIC_CH_L | ANC_FF_MIC_CH_R;
l = get_msb_pos(ANC_FF_MIC_CH_L);
r = get_msb_pos(ANC_FF_MIC_CH_R);
#endif
#if defined(ANC_FB_MIC_CH_L) || defined(ANC_FB_MIC_CH_R)
} else if (single_type == ANC_FEEDBACK) {
ch_map = ANC_FB_MIC_CH_L | ANC_FB_MIC_CH_R;
l = get_msb_pos(ANC_FB_MIC_CH_L);
r = get_msb_pos(ANC_FB_MIC_CH_R);
#endif
} else {
continue;
}
if ((l >= MAX_ANA_MIC_CH_NUM || adc_gain_offset[l] == offset_l) &&
(r >= MAX_ANA_MIC_CH_NUM || adc_gain_offset[r] == offset_r)) {
continue;
}
ANALOG_INFO_TRACE(0, "ana: apply anc adc gain offset: type=%d offset=%d/%d",
single_type, offset_l, offset_r);
org_l = adj_l = 0;
if (l < MAX_ANA_MIC_CH_NUM) {
adc_gain_offset[l] = 0;
if (offset_l) {
org_l = adc_db[db_to_adc_gain(get_chan_adc_gain(l))];
adc_gain_offset[l] = offset_l;
adj_l = adc_db[db_to_adc_gain(get_chan_adc_gain(l))];
}
}
org_r = adj_r = 0;
if (r < MAX_ANA_MIC_CH_NUM) {
adc_gain_offset[r] = 0;
if (offset_r) {
org_r = adc_db[db_to_adc_gain(get_chan_adc_gain(r))];
adc_gain_offset[r] = offset_r;
adj_r = adc_db[db_to_adc_gain(get_chan_adc_gain(r))];
}
}
hal_codec_apply_anc_adc_gain_offset(single_type, (org_l - adj_l),
(org_r - adj_r));
analog_aud_set_adc_gain(AUD_INPUT_PATH_MAINMIC, ch_map);
}
}
#endif
#ifdef DYN_ADC_GAIN
void analog_aud_apply_adc_gain_offset(enum AUD_CHANNEL_MAP_T ch_map,
int16_t offset) {
enum AUD_CHANNEL_MAP_T map;
int i;
#ifdef ANC_APP
#ifdef ANC_FF_ENABLED
ch_map &= ~(ANC_FF_MIC_CH_L | ANC_FF_MIC_CH_R);
#endif
#ifdef ANC_FB_ENABLED
ch_map &= ~(ANC_FB_MIC_CH_L | ANC_FB_MIC_CH_R);
#endif
#endif
if (ch_map) {
map = ch_map;
while (map) {
i = get_msb_pos(map);
map &= ~(1 << i);
if (i < MAX_ANA_MIC_CH_NUM) {
adc_gain_offset[i] = offset;
}
}
ANALOG_INFO_TRACE(2, "ana: apply adc gain offset: ch_map=0x%X offset=%d",
ch_map, offset);
analog_aud_set_adc_gain(AUD_INPUT_PATH_MAINMIC, ch_map);
}
}
#endif
void analog_aud_set_dac_gain(int32_t v) {}
uint32_t analog_codec_get_dac_gain(void) { return 0; }
uint32_t analog_codec_dac_gain_to_db(int32_t gain) { return 0; }
int32_t analog_codec_dac_max_attn_db(void) { return 0; }
static int POSSIBLY_UNUSED dc_calib_checksum_valid(uint32_t efuse) {
int i;
uint32_t cnt = 0;
uint32_t chksum_mask = (1 << (16 - DAC_DC_CALIB_BIT_WIDTH)) - 1;
for (i = 0; i < DAC_DC_CALIB_BIT_WIDTH; i++) {
if (efuse & (1 << i)) {
cnt++;
}
}
return (((~cnt) & chksum_mask) ==
((efuse >> DAC_DC_CALIB_BIT_WIDTH) & chksum_mask));
}
static int16_t dc_calib_val_decode(int16_t val) {
#ifdef AUDIO_OUTPUT_DC_CALIB_ANA
uint32_t sign_bit = (1 << (DAC_DC_CALIB_BIT_WIDTH - 1));
uint32_t num_mask = sign_bit - 1;
if (val & sign_bit) {
val = -(val & num_mask);
}
#endif
return val;
}
void analog_aud_get_dc_calib_value(int16_t *dc_l, int16_t *dc_r) {
static const uint8_t EFUSE_PAGE_DIFF_1P7V[2] = {
PMU_EFUSE_PAGE_DCCALIB2_L,
PMU_EFUSE_PAGE_DCCALIB2_R,
};
static const uint8_t EFUSE_PAGE_DIFF_1P95V[2] = {
PMU_EFUSE_PAGE_DCCALIB_L,
PMU_EFUSE_PAGE_DCCALIB_R,
};
const uint8_t *page;
uint16_t efuse;
union DC_EFUSE_T {
struct DC_VALUE_T {
int16_t dc : DAC_DC_CALIB_BIT_WIDTH;
uint16_t checksum : (16 - DAC_DC_CALIB_BIT_WIDTH);
} val;
uint16_t reg;
};
union DC_EFUSE_T dc;
if (vcodec_mv >= 1900) {
page = EFUSE_PAGE_DIFF_1P95V;
} else {
page = EFUSE_PAGE_DIFF_1P7V;
}
pmu_get_efuse(page[0], &efuse);
if (dc_calib_checksum_valid(efuse)) {
ANALOG_INFO_TRACE(1, "Dc calib L OK: 0x%04x", efuse);
dc.reg = efuse;
*dc_l = dc.val.dc;
} else {
ANALOG_INFO_TRACE(1, "Warning: Bad dc calib efuse L: 0x%04x", efuse);
*dc_l = 0;
}
pmu_get_efuse(page[1], &efuse);
if (dc_calib_checksum_valid(efuse)) {
ANALOG_INFO_TRACE(1, "Dc calib R OK: 0x%04x", efuse);
dc.reg = efuse;
*dc_r = dc.val.dc;
} else {
ANALOG_INFO_TRACE(1, "Warning: Bad dc calib efuse R: 0x%04x", efuse);
*dc_r = 0;
}
ANALOG_INFO_TRACE(2, "ANA: DC CALIB L=0x%04hX/%d R=0x%04hX/%d", *dc_l,
dc_calib_val_decode(*dc_l), *dc_r,
dc_calib_val_decode(*dc_r));
#if defined(ANA_DC_CALIB_L) || defined(ANA_DC_CALIB_R)
#ifdef ANA_DC_CALIB_L
*dc_l = ANA_DC_CALIB_L;
#endif
#ifdef ANA_DC_CALIB_R
*dc_r = ANA_DC_CALIB_R;
#endif
ANALOG_INFO_TRACE(2, "ANA: OVERRIDE DC CALIB L=0x%04hX/%d R=0x%04hX/%d",
*dc_l, dc_calib_val_decode(*dc_l), *dc_r,
dc_calib_val_decode(*dc_r));
#endif
return;
}
#ifdef AUDIO_OUTPUT_DC_CALIB_ANA
static void analog_aud_dc_calib_init(void) {
uint16_t val;
int16_t dc_l, dc_r;
analog_aud_get_dc_calib_value(&dc_l, &dc_r);
analog_read(ANA_REG_71, &val);
val = SET_BITFIELD(val, REG_CODEC_TX_EAR_OFF_BITL, dc_l);
analog_write(ANA_REG_71, val);
analog_read(ANA_REG_72, &val);
val = SET_BITFIELD(val, REG_CODEC_TX_EAR_OFF_BITR, dc_r);
analog_write(ANA_REG_72, val);
}
static void analog_aud_dc_calib_enable(bool en) {
uint16_t val;
analog_read(ANA_REG_70, &val);
val |= REG_CODEC_TX_EAR_OFFEN;
analog_write(ANA_REG_70, val);
}
#endif
static void analog_aud_vcodec_enable(enum ANA_CODEC_USER_T user, bool en) {
uint32_t lock;
bool set = false;
lock = int_lock();
if (en) {
if (vcodec_map == 0) {
set = true;
}
vcodec_map |= user;
} else {
vcodec_map &= ~user;
if (vcodec_map == 0) {
set = true;
}
}
int_unlock(lock);
if (set) {
pmu_codec_config(!!vcodec_map);
}
}
static void analog_aud_enable_common_internal(enum ANA_CODEC_USER_T user,
bool en) {
uint32_t lock;
uint16_t val_6b;
bool set = false;
lock = int_lock();
if (en) {
if (codec_common_map == 0) {
set = true;
}
codec_common_map |= user;
} else {
codec_common_map &= ~user;
if (codec_common_map == 0) {
set = true;
}
}
int_unlock(lock);
if (set) {
analog_read(ANA_REG_6B, &val_6b);
if (codec_common_map) {
val_6b |= REG_CODEC_EN_VCM;
} else {
val_6b &= ~(REG_CODEC_EN_VCM | REG_CODEC_VCM_EN_LPF);
}
if (codec_common_map) {
// RTOS application startup time is long enougth for VCM charging
#if !(defined(VCM_ON) && defined(RTOS))
// VCM fully stable time is about 60ms/1.95V or 150ms/1.7V
// Quick startup:
// 1) Disable VCM LPF and target to a higher voltage than the required one
// 2) Wait for a short time when VCM is in quick charge (high voltage)
// 3) Enable VCM LPF and target to the required VCM LPF voltage
analog_write(ANA_REG_6B, SET_BITFIELD(val_6b, REG_CODEC_VCM_LOW_VCM, 0));
uint32_t delay;
#if defined(VCM_CAP_100NF)
if (vcodec_mv >= 1900) {
delay = 6;
} else {
delay = 10;
}
#else
if (vcodec_mv >= 1900) {
delay = 25;
} else {
delay = 100;
}
#endif
osDelay(delay);
#if 0
// Target to a voltage near the required one
analog_write(ANA_REG_6B, val_6b);
osDelay(10);
#endif
#endif // !(VCM_ON && RTOS)
val_6b |= REG_CODEC_VCM_EN_LPF;
}
analog_write(ANA_REG_6B, val_6b);
}
}
static void analog_aud_enable_codec_common(enum ANA_CODEC_USER_T user,
bool en) {
#ifndef VCM_ON
analog_aud_enable_common_internal(user, en);
#endif
}
static void analog_aud_enable_adda_common(enum ANA_CODEC_USER_T user, bool en) {
uint32_t lock;
uint16_t val_6a, val_6b, val_74, val_7e;
bool set = false;
lock = int_lock();
if (en) {
if (adda_common_map == 0) {
set = true;
}
adda_common_map |= user;
} else {
adda_common_map &= ~user;
if (adda_common_map == 0) {
set = true;
}
}
int_unlock(lock);
if (set) {
analog_read(ANA_REG_6A, &val_6a);
analog_read(ANA_REG_6B, &val_6b);
if (vcodec_mv >= 1700) {
analog_read(ANA_REG_74, &val_74);
} else {
val_74 = 0;
}
analog_read(ANA_REG_7E, &val_7e);
if (adda_common_map) {
val_6a |= REG_CODEC_EN_BIAS;
analog_write(ANA_REG_6A, val_6a);
if (vcodec_mv >= 1700) {
val_74 |= REG_PU_TX_REGULATOR;
analog_write(ANA_REG_74, val_74);
hal_sys_timer_delay_us(10);
val_74 &= ~REG_BYPASS_TX_REGULATOR;
analog_write(ANA_REG_74, val_74);
}
val_6b |= REG_CODEC_EN_VCM_BUFFER;
val_7e |= REG_PU_CLKMUX_LDO0P9;
} else {
val_6b &= ~REG_CODEC_EN_VCM_BUFFER;
val_7e &= ~REG_PU_CLKMUX_LDO0P9;
if (vcodec_mv >= 1700) {
val_74 |= REG_BYPASS_TX_REGULATOR;
analog_write(ANA_REG_74, val_74);
val_74 &= ~REG_PU_TX_REGULATOR;
analog_write(ANA_REG_74, val_74);
}
val_6a &= ~REG_CODEC_EN_BIAS;
analog_write(ANA_REG_6A, val_6a);
}
analog_write(ANA_REG_6B, val_6b);
analog_write(ANA_REG_7E, val_7e);
}
}
static void analog_aud_enable_vmic(enum ANA_CODEC_USER_T user, uint32_t dev) {
uint32_t lock;
enum ANA_CODEC_USER_T old_map;
bool set = false;
int i;
uint32_t pmu_map = 0;
lock = int_lock();
for (i = 0; i < MAX_ANA_MIC_CH_NUM; i++) {
if (dev & (AUD_VMIC_MAP_VMIC1 << i)) {
if (vmic_map[i] == 0) {
set = true;
}
vmic_map[i] |= user;
} else {
old_map = vmic_map[i];
vmic_map[i] &= ~user;
if (old_map != 0 && vmic_map[i] == 0) {
set = true;
}
}
if (vmic_map[i]) {
pmu_map |= (AUD_VMIC_MAP_VMIC1 << i);
}
}
int_unlock(lock);
if (set) {
pmu_codec_mic_bias_enable(pmu_map);
#ifdef VOICE_DETECTOR_EN
pmu_codec_mic_bias_lowpower_mode(pmu_map);
#endif
if (pmu_map) {
osDelay(1);
}
}
}
uint32_t analog_aud_get_max_dre_gain(void) {
if (vcodec_mv >= 1900) {
return 0x11;
} else {
return 0xF;
}
}
int analog_reset(void) { return 0; }
void analog_open(void) {
uint16_t val;
val = REG_CODEC_ADCA_CH_SEL(1) | REG_CODEC_ADCB_CH_SEL(1) |
REG_CODEC_ADCC_CH_SEL(1) | REG_CODEC_ADCD_CH_SEL(1);
analog_write(ANA_REG_61, val);
val = CFG_RESET_PGAA_DR | CFG_RESET_PGAB_DR | CFG_RESET_PGAC_DR |
CFG_RESET_PGAD_DR;
analog_write(ANA_REG_62, val);
val = 0; // REG_CODEC_ADCA_GAIN_UPDATE | REG_CODEC_ADCB_GAIN_UPDATE |
// REG_CODEC_ADCC_GAIN_UPDATE | REG_CODEC_ADCD_GAIN_UPDATE;
analog_write(ANA_REG_63, val);
val = REG_CODEC_ADC_IBSEL_REG(8) | REG_CODEC_ADC_IBSEL_VCOMP(8) |
REG_CODEC_ADC_IBSEL_VREF(8) | REG_CODEC_ADC_LPFVCM_SW(7);
analog_write(ANA_REG_67, val);
val = REG_CODEC_ADC_OP1_IBIT(2) | REG_CODEC_ADC_VREF_SEL(4);
analog_write(ANA_REG_68, val);
val = REG_CODEC_BIAS_IBSEL(8) | REG_CODEC_BIAS_IBSEL_VOICE(8);
if (vcodec_mv >= 1900) {
val |= REG_CODEC_BIAS_IBSEL_TX(5);
} else {
#ifdef LOW_CODEC_BIAS
val |= REG_CODEC_BIAS_IBSEL_TX(1);
#else
val |= REG_CODEC_BIAS_IBSEL_TX(3);
#endif
}
analog_write(ANA_REG_69, val);
val = REG_CODEC_ADC_REG_VSEL(3) | REG_CODEC_BUF_LOWVCM(4) |
REG_CODEC_EN_RX_EXT | REG_CODEC_EN_TX_EXT | REG_CODEC_DAC_CLK_EDGE_SEL;
val |= REG_CODEC_EN_BIAS_LP;
analog_write(ANA_REG_6A, val);
uint16_t vcm, vcm_lpf;
if (vcodec_mv >= 1900) {
vcm = 7;
vcm_lpf = 0xA;
} else if (vcodec_mv >= 1800) {
vcm = vcm_lpf = 7;
} else {
vcm = vcm_lpf = 7;
}
val = REG_CODEC_VCM_LOW_VCM(vcm) | REG_CODEC_VCM_LOW_VCM_LP(vcm) |
REG_CODEC_VCM_LOW_VCM_LPF(vcm_lpf);
analog_write(ANA_REG_6B, val);
val = REG_CODEC_RX_VTOI_I_DAC2(4) | REG_CODEC_RX_VTOI_IDAC_SEL(8) |
REG_CODEC_RX_VTOI_VCS_SEL(0x10);
analog_write(ANA_REG_6C, val);
if (vcodec_mv > 1900) {
val = REG_CODEC_TX_DAC_VREF_L(9) | REG_CODEC_TX_DAC_VREF_R(9) |
REG_CODEC_TX_EAR_CAS_BIT(3);
} else if (vcodec_mv == 1900) {
val = REG_CODEC_TX_DAC_VREF_L(0xA) | REG_CODEC_TX_DAC_VREF_R(0xA) |
REG_CODEC_TX_EAR_CAS_BIT(3);
} else {
val = REG_CODEC_TX_DAC_VREF_L(2) | REG_CODEC_TX_DAC_VREF_R(2) |
REG_CODEC_TX_EAR_CAS_BIT(1);
}
analog_write(ANA_REG_6D, val);
val = REG_CODEC_TX_EAR_IBSEL(2);
#ifdef LOW_CODEC_BIAS
if (vcodec_mv < 1900) {
val = REG_CODEC_TX_EAR_IBSEL(0);
}
#endif
val |= REG_CODEC_TX_EAR_COMP_L(7) | REG_CODEC_TX_EAR_COMP_R(7) |
REG_CODEC_TX_EAR_DR_ST(1) | REG_CODEC_TX_EAR_FBCAP(3);
analog_write(ANA_REG_6E, val);
val = REG_CODEC_TX_EAR_DRE_GAIN_L(0xF) | REG_CODEC_TX_EAR_DRE_GAIN_R(0xF) |
DRE_GAIN_SEL_L | DRE_GAIN_SEL_R | REG_CODEC_TX_EAR_GAIN(1);
#ifdef DAC_DRE_GAIN_DC_UPDATE
val |=
REG_CODEC_TX_EAR_DRE_GAIN_L_UPDATE | REG_CODEC_TX_EAR_DRE_GAIN_R_UPDATE;
#endif
analog_write(ANA_REG_6F, val);
val = REG_CODEC_TX_EAR_OUTPUTSEL(1) | REG_CODEC_TX_EAR_SOFTSTART(8) |
REG_CODEC_TX_EAR_OCEN | REG_CODEC_TX_EAR_LPBIAS;
analog_write(ANA_REG_70, val);
val = REG_DAC_LDO0P9_VSEL(2) | REG_BYPASS_TX_REGULATOR |
REG_CODEC_TX_EAR_VCM_BIT(3) | REG_CODEC_TX_EAR_VCM_SEL;
if (vcodec_mv >= 1900) {
val |= REG_CODEC_TX_RVREF_CAP_BIT | REG_TX_REGULATOR_BIT(0xD);
} else {
val |= REG_TX_REGULATOR_BIT(4);
}
analog_write(ANA_REG_74, val);
val = REG_CLKMUX_DVDD_SEL | REG_CLKMUX_LDO0P9_VSEL(2) |
REG_AUDPLL_LDO_VREF(4) | REG_AUDPLL_LPF_BW_SEL;
analog_write(ANA_REG_7E, val);
// Optimize bottom noise, dig_codec_adcE_vref_sel[3:0] should be 0x4 ————by
// jeff 20200916
analog_read(ANA_REG_16E, &val);
val = SET_BITFIELD(val, DIG_CODEC_ADCE_VREF_SEL, 0x4);
analog_write(ANA_REG_16E, val);
#ifdef AUDIO_OUTPUT_DC_CALIB_ANA
analog_aud_dc_calib_init();
analog_aud_dc_calib_enable(true);
#endif
#ifdef VCM_ON
analog_aud_enable_common_internal(ANA_CODEC_USER_DAC, true);
#endif
}
void analog_sleep(void) {
#ifdef VOICE_DETECTOR_EN
if ((adda_common_map & ANA_CODEC_USER_VAD) &&
(adc_map[4] & ANA_CODEC_USER_VAD) == 0) {
uint16_t val;
analog_read(ANA_REG_6B, &val);
val = (val & ~REG_CODEC_EN_VCM_BUFFER) | REG_CODEC_LP_VCM;
analog_write(ANA_REG_6B, val);
}
#endif
}
void analog_wakeup(void) {
#ifdef VOICE_DETECTOR_EN
if ((adda_common_map & ANA_CODEC_USER_VAD) &&
(adc_map[4] & ANA_CODEC_USER_VAD) == 0) {
uint16_t val;
analog_read(ANA_REG_6B, &val);
val = (val & ~REG_CODEC_LP_VCM) | REG_CODEC_EN_VCM_BUFFER;
analog_write(ANA_REG_6B, val);
}
#endif
}
void analog_aud_codec_anc_enable(enum ANC_TYPE_T type, bool en) {
enum ANA_CODEC_USER_T user;
enum AUD_CHANNEL_MAP_T ch_map;
user = 0;
ch_map = 0;
#if defined(ANC_FF_MIC_CH_L) || defined(ANC_FF_MIC_CH_R)
if (type & ANC_FEEDFORWARD) {
user |= ANA_CODEC_USER_ANC_FF;
ch_map |= ANC_FF_MIC_CH_L | ANC_FF_MIC_CH_R;
}
#endif
#if defined(ANC_FB_MIC_CH_L) || defined(ANC_FB_MIC_CH_R)
if (type & ANC_FEEDFORWARD) {
user |= ANA_CODEC_USER_ANC_FB;
ch_map |= ANC_FB_MIC_CH_L | ANC_FB_MIC_CH_R;
}
#endif
ANALOG_DEBUG_TRACE(0, "%s: type=%d en=%d ch_map=0x%x", __func__, type, en,
ch_map);
if (en) {
analog_aud_enable_vmic(user, ANC_VMIC_CFG);
analog_aud_enable_codec_common(user, true);
analog_aud_enable_adda_common(user, true);
analog_aud_set_adc_gain(AUD_INPUT_PATH_MAINMIC, ch_map);
analog_aud_enable_adc(user, ch_map, true);
} else {
analog_aud_apply_anc_adc_gain_offset(type, 0, 0);
analog_aud_enable_adc(user, ch_map, false);
analog_aud_enable_adda_common(user, false);
analog_aud_enable_codec_common(user, false);
analog_aud_enable_vmic(user, 0);
}
}
void analog_aud_codec_anc_boost(bool en,
ANALOG_ANC_BOOST_DELAY_FUNC delay_func) {
uint16_t val;
int ret;
if (vcodec_mv >= 1800) {
return;
}
if (delay_func == NULL) {
delay_func = (ANALOG_ANC_BOOST_DELAY_FUNC)osDelay;
}
if (en) {
// -2.1 dB
hal_codec_set_anc_boost_gain_attn(0.78523563f);
delay_func(1);
}
analog_read(ANA_REG_6B, &val);
val &= ~REG_CODEC_VCM_EN_LPF;
analog_write(ANA_REG_6B, val);
osDelay(1);
do {
if (en) {
ret = pmu_codec_volt_ramp_up();
} else {
ret = pmu_codec_volt_ramp_down();
}
delay_func(1);
} while (ret);
analog_read(ANA_REG_6B, &val);
val |= REG_CODEC_VCM_EN_LPF;
analog_write(ANA_REG_6B, val);
if (!en) {
delay_func(1);
// 0 dB
hal_codec_set_anc_boost_gain_attn(1.0f);
}
}
void analog_aud_mickey_enable(bool en) {
if (en) {
analog_aud_vcodec_enable(ANA_CODEC_USER_MICKEY, true);
analog_aud_enable_vmic(ANA_CODEC_USER_MICKEY, CFG_HW_AUD_MICKEY_DEV);
analog_aud_enable_codec_common(ANA_CODEC_USER_MICKEY, true);
} else {
analog_aud_enable_codec_common(ANA_CODEC_USER_MICKEY, false);
analog_aud_enable_vmic(ANA_CODEC_USER_MICKEY, 0);
analog_aud_vcodec_enable(ANA_CODEC_USER_MICKEY, false);
}
}
void analog_aud_codec_adc_enable(enum AUD_IO_PATH_T input_path,
enum AUD_CHANNEL_MAP_T ch_map, bool en) {
uint32_t dev;
if (en) {
dev = hal_codec_get_input_path_cfg(input_path);
// Enable vmic first to overlap vmic stable time with codec vcm stable time
analog_aud_enable_vmic(ANA_CODEC_USER_ADC, dev);
analog_aud_enable_codec_common(ANA_CODEC_USER_ADC, true);
analog_aud_enable_adda_common(ANA_CODEC_USER_ADC, true);
analog_aud_set_adc_gain(input_path, ch_map);
analog_aud_enable_adc(ANA_CODEC_USER_ADC, ch_map, true);
} else {
analog_aud_enable_adc(ANA_CODEC_USER_ADC, ch_map, false);
analog_aud_enable_adda_common(ANA_CODEC_USER_ADC, false);
analog_aud_enable_codec_common(ANA_CODEC_USER_ADC, false);
analog_aud_enable_vmic(ANA_CODEC_USER_ADC, 0);
}
}
static void analog_aud_codec_config_speaker(void) {
bool en;
if (ana_spk_req && !ana_spk_muted) {
en = true;
} else {
en = false;
}
if (ana_spk_enabled != en) {
ana_spk_enabled = en;
if (en) {
analog_aud_enable_dac_pa(CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV);
} else {
analog_aud_enable_dac_pa(0);
}
}
}
void analog_aud_codec_speaker_enable(bool en) {
ana_spk_req = en;
analog_aud_codec_config_speaker();
}
void analog_aud_codec_dac_enable(bool en) {
if (en) {
analog_aud_enable_codec_common(ANA_CODEC_USER_DAC, true);
analog_aud_enable_adda_common(ANA_CODEC_USER_DAC, true);
pmu_codec_hppa_enable(1);
analog_aud_enable_dac(CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV);
#if !defined(AUDIO_OUTPUT_DC_CALIB_ANA) && !defined(AUDIO_OUTPUT_DC_CALIB)
osDelay(1);
analog_aud_codec_speaker_enable(true);
#endif
} else {
#if !defined(AUDIO_OUTPUT_DC_CALIB_ANA) && !defined(AUDIO_OUTPUT_DC_CALIB)
analog_aud_codec_speaker_enable(false);
osDelay(1);
#endif
analog_aud_enable_dac(0);
pmu_codec_hppa_enable(0);
analog_aud_enable_adda_common(ANA_CODEC_USER_DAC, false);
analog_aud_enable_codec_common(ANA_CODEC_USER_DAC, false);
}
}
void analog_aud_codec_open(void) {
analog_aud_vcodec_enable(ANA_CODEC_USER_CODEC, true);
#ifdef _AUTO_SWITCH_POWER_MODE__
// pmu_mode_change(PMU_POWER_MODE_DIG_DCDC);
#endif
}
void analog_aud_codec_close(void) {
static const enum AUD_CHANNEL_MAP_T all_ch =
AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1 | AUD_CHANNEL_MAP_CH2 |
AUD_CHANNEL_MAP_CH3 | AUD_CHANNEL_MAP_CH4;
analog_aud_codec_speaker_enable(false);
osDelay(1);
analog_aud_codec_dac_enable(false);
analog_aud_codec_adc_enable(AUD_IO_PATH_NULL, all_ch, false);
#ifdef _AUTO_SWITCH_POWER_MODE__
// pmu_mode_change(PMU_POWER_MODE_ANA_DCDC);
#endif
analog_aud_vcodec_enable(ANA_CODEC_USER_CODEC, false);
}
void analog_aud_codec_mute(void) {
#ifndef AUDIO_OUTPUT_DC_CALIB
// analog_codec_tx_pa_gain_sel(0);
#endif
ana_spk_muted = true;
analog_aud_codec_config_speaker();
}
void analog_aud_codec_nomute(void) {
ana_spk_muted = false;
analog_aud_codec_config_speaker();
#ifndef AUDIO_OUTPUT_DC_CALIB
// analog_aud_set_dac_gain(dac_gain);
#endif
}
int analog_debug_config_audio_output(bool diff) { return 0; }
int analog_debug_config_codec(uint16_t mv) {
#ifdef ANC_PROD_TEST
int ret;
ret = pmu_debug_config_codec(mv);
if (ret) {
return ret;
}
vcodec_mv = mv;
#endif
return 0;
}
int analog_debug_config_low_power_adc(bool enable) { return 0; }
void analog_debug_config_anc_calib_mode(bool enable) {
anc_calib_mode = enable;
}
bool analog_debug_get_anc_calib_mode(void) { return anc_calib_mode; }
int analog_debug_config_vad_mic(bool enable) { return 0; }
#ifdef VOICE_DETECTOR_EN
static void analog_aud_codec_vad_ini(void) {
#if 1
unsigned short v;
#if 0
//0x6a,0x0503
analog_read(ANA_REG_6A, &v);
v = SET_BITFIELD(v, REG_CODEC_ADC_REG_VSEL, 0x3);
v = SET_BITFIELD(v, REG_CODEC_BUF_LOWVCM, 0x4);
v |= REG_CODEC_EN_BIAS_LP;
analog_write(ANA_REG_6A, v);
//0x6b,0x3bbf
analog_read(ANA_REG_6B, &v);
#if 0
v = SET_BITFIELD(v, REG_CODEC_VCM_LOW_VCM, 0x7);
v = SET_BITFIELD(v, REG_CODEC_VCM_LOW_VCM_LP, 0x7);
v = SET_BITFIELD(v, REG_CODEC_VCM_LOW_VCM_LPF, 0x7);
v &= ~REG_CODEC_EN_VCM_BUFFER;
#else
v = SET_BITFIELD(v, REG_CODEC_VCM_LOW_VCM, 0x6);
v = SET_BITFIELD(v, REG_CODEC_VCM_LOW_VCM_LP, 0x6);
v = SET_BITFIELD(v, REG_CODEC_VCM_LOW_VCM_LPF, 0x6);
v |= REG_CODEC_EN_VCM_BUFFER;
#endif
analog_write(ANA_REG_6B, v);
//0x74,0xc544
analog_read(ANA_REG_74, &v);
v &= ~REG_CODEC_TX_RVREF_CAP_BIT;
v = SET_BITFIELD(v, REG_DAC_LDO0P9_VSEL, 0x2);
#if 0
v |= REG_BYPASS_TX_REGULATOR;
v &= ~REG_PU_TX_REGULATOR;
#else
v &= ~REG_BYPASS_TX_REGULATOR;
v |= REG_PU_TX_REGULATOR;
#endif
v = SET_BITFIELD(v, REG_TX_REGULATOR_BIT, 0x5);
v = SET_BITFIELD(v, REG_CODEC_TX_EAR_VCM_BIT, 0x2);
v |= REG_CODEC_TX_EAR_VCM_SEL;
analog_write(ANA_REG_74, v);
#endif
// 0x173, 0x0805
v = REG_VOICE_LDO_VBIT(5) | CFG_VOICE_DET_DELAY(8);
analog_write(ANA_REG_173, v);
// 0x17d,0x817f
v = REG_CLK_GOAL_DIV_NUM(0x17f) | REG_COARSE_TUN_CODE_DR;
analog_write(ANA_REG_17D, v);
#if 1
// 0x171,0x1047
v = CFG_VOICE_RESET | CFG_VOICE_PU_DELAY(4) | CFG_VOICE_PRECH_DELAY(0x7f);
analog_write(ANA_REG_171, v);
#endif
// 0x17a
analog_read(ANA_REG_17A, &v);
v = SET_BITFIELD(v, REG_VOICE_LOW_TUNE, 0x3);
analog_write(ANA_REG_17A, v);
// 0x161[15] = 1; //cfg_reg_clkmux_dvdd_sel
analog_read(ANA_REG_161, &v);
v |= 1 << 15;
analog_write(ANA_REG_161, v);
// 0x170[15] = 1; //cfg_voice2adcE
analog_read(ANA_REG_170, &v);
v = SET_BITFIELD(v, REG_VOICE_GAIN_A, 0x3);
v = SET_BITFIELD(v, REG_VOICE_GAIN_B, 0x3);
v = SET_BITFIELD(v, REG_VOICE_HIGH_TUNE_A, 0xa);
v = SET_BITFIELD(v, REG_VOICE_HIGH_TUNE_B, 0x4);
v |= CFG_VOICE2ADCE;
analog_write(ANA_REG_170, v);
osDelay(1);
#endif
}
static void analog_aud_codec_vad_fin(void) {
unsigned short v;
analog_read(ANA_REG_170, &v);
v &= ~CFG_VOICE2ADCE;
analog_write(ANA_REG_170, v);
}
static void analog_aud_codec_vad_trig_en(bool en) {
#if 1
unsigned short v;
uint32_t lock;
lock = int_lock();
analog_read(ANA_REG_171, &v);
if (en)
v |= CFG_VOICE_TRIG_ENABLE;
else
v &= ~CFG_VOICE_TRIG_ENABLE;
analog_write(ANA_REG_171, v);
int_unlock(lock);
#endif
}
static void analog_aud_codec_vad_pu(bool en) {
#if 1
unsigned short v;
uint32_t lock;
lock = int_lock();
analog_read(ANA_REG_171, &v);
if (en)
v |= CFG_VOICE_POWER_ON;
else
v &= ~CFG_VOICE_POWER_ON;
analog_write(ANA_REG_171, v);
int_unlock(lock);
#endif
}
void analog_aud_vad_enable(enum AUD_VAD_TYPE_T type, bool en) {
if (type == AUD_VAD_TYPE_DIG) {
uint32_t dev;
enum AUD_CHANNEL_MAP_T ch_map;
dev = hal_codec_get_input_path_cfg(AUD_INPUT_PATH_VADMIC);
ch_map = dev & AUD_CHANNEL_MAP_ANA_ALL;
analog_aud_enable_adc(ANA_CODEC_USER_VAD, ch_map, en);
} else if (type == AUD_VAD_TYPE_MIX || type == AUD_VAD_TYPE_ANA) {
if (en) {
analog_aud_codec_vad_ini();
analog_aud_codec_vad_pu(true);
osDelay(1);
analog_aud_codec_vad_trig_en(true);
// pmu_codec_vad_save_power();
} else {
// pmu_codec_vad_restore_power();
// Must power off before disabling trigger
analog_aud_codec_vad_pu(false);
osDelay(1);
analog_aud_codec_vad_trig_en(false);
analog_aud_codec_vad_fin();
}
}
}
void analog_aud_vad_adc_enable(bool en) {
uint32_t dev;
enum AUD_CHANNEL_MAP_T ch_map;
dev = hal_codec_get_input_path_cfg(AUD_INPUT_PATH_VADMIC);
ch_map = dev & AUD_CHANNEL_MAP_ANA_ALL;
if (en) {
// Enable vmic first to overlap vmic stable time with codec vcm stable time
analog_aud_enable_vmic(ANA_CODEC_USER_VAD, dev);
analog_aud_enable_codec_common(ANA_CODEC_USER_VAD, true);
analog_aud_enable_adda_common(ANA_CODEC_USER_VAD, true);
analog_aud_set_adc_gain(AUD_INPUT_PATH_VADMIC, ch_map);
} else {
analog_aud_enable_adda_common(ANA_CODEC_USER_VAD, false);
analog_aud_enable_codec_common(ANA_CODEC_USER_VAD, false);
analog_aud_enable_vmic(ANA_CODEC_USER_VAD, 0);
}
}
#endif