/*================================================================ Copyright (c) 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. =================================================================*/ #include "ql_api_common.h" #include "ql_audio.h" #include "ql_codec_config.h" /*=========================================================================== * Variables ===========================================================================*/ /* ES8311寄存器组,用户可以对照ES8311手册在此修改寄存器 g_es8311InitRegList: 初始化codec时会将此结构体中的配置发送给codec g_es8311PlayRegList: 开始播放时会将此结构体中的配置发送给codec g_es8311RecRegList: 开始录音时会将此结构体中的配置发送给codec g_es8311CloseRegList:关闭codec时会将此结构体中的配置发送给codec 播放时的调用流程: g_es8311InitRegList --> g_es8311PlayRegList --> g_es8311CloseRegList 录音时的调用流程: g_es8311InitRegList --> g_es8311RecRegList --> g_es8311CloseRegList */ static ql_codec_reg_t g_es8311InitRegList[] = ES8311_INIT_CONFIG; static ql_codec_reg_t g_es8311PlayRegList[] = ES8311_PLAY_CONFIG; static ql_codec_reg_t g_es8311RecRegList[] = ES8311_RECORD_CONFIG; static ql_codec_reg_t g_es8311CloseRegList[] = ES8311_CLOSE_CONFIG; static ql_aud_adc_cfg ql_adc_cfg = {QL_ADC_GAIN_LEVEL_9}; static ql_aud_dac_cfg ql_dac_cfg = {0xbf}; /*=========================================================================== * Functions ===========================================================================*/ extern ql_audio_errcode_e ql_es8311_read_reg(uint8 RegAddr, uint8 *p_value); extern ql_audio_errcode_e ql_es8311_write_reg(uint8 RegAddr, uint8 RegData); extern void quec_es8311_write_list(ql_codec_reg_t *regList, uint16_t len); static void quec_es8311_config_dac(bool mute_dac) { if(mute_dac) { ql_es8311_write_reg(ES8311_REG_DAC, 0); //音量为0,将dac寄存器关闭做到彻底静音 } else { ql_aud_set_dac_gain(&ql_dac_cfg);//音量不为0,根据ql_aud_get_adc_gain接口设置的增益来配置dac寄存器 } } /* 用户如果在app侧自行控制codec,需要在此处定义一个函数名为quec_es8311_cfg_cb的空函数,避免内核找不到此函数 导致编译报错,内核在开机时也会调用ql_aud_ext_codec_cfg将quec_es8311_cfg_cb函数注册为codec回调,用户在app 侧重新注册其他回调函数后,内核之前注册的回调函数就会失效,用户即可在app侧仿照此处的逻辑去控制外置codec寄存器 */ int quec_es8311_cfg_cb(ql_codec_cb_param_t *param) { switch(param->stage) { case QL_EXT_CODEC_INIT: quec_es8311_write_list(g_es8311InitRegList, sizeof(g_es8311InitRegList) / sizeof(ql_codec_reg_t)); break; case QL_EXT_CODEC_REC: quec_es8311_write_list(g_es8311RecRegList, sizeof(g_es8311RecRegList) / sizeof(ql_codec_reg_t)); ql_aud_set_adc_gain(&ql_adc_cfg);//配置增益 break; case QL_EXT_CODEC_PLAY: quec_es8311_write_list(g_es8311PlayRegList, sizeof(g_es8311PlayRegList) / sizeof(ql_codec_reg_t)); case QL_EXT_CODEC_SET_VOLUME: quec_es8311_config_dac(AUDIOHAL_SPK_MUTE == ql_get_volume() ? true : false); break; case QL_EXT_CODEC_DEINIT: quec_es8311_write_list(g_es8311CloseRegList, sizeof(g_es8311CloseRegList) / sizeof(ql_codec_reg_t)); break; default: break; } return 0; } /* 读取/配置ES8311的adc/dac增益 */ ql_audio_errcode_e ql_aud_set_adc_gain(ql_aud_adc_cfg * adc_cfg) { if((NULL == adc_cfg) || (adc_cfg->adc_gain < QL_ADC_GAIN_LEVEL_1) || (adc_cfg->adc_gain > QL_ADC_GAIN_LEVEL_12)) { return QL_AUDIO_INVALID_PARAM; } if(QL_ADC_GAIN_LEVEL_1 == adc_cfg->adc_gain) { if(ql_es8311_write_reg(ES8311_REG_ADC, 0x00))// reg 0x17 set volume mute { return QL_AUDIO_CODEC_WR_FAIL; } } else { uint16_t REG14 = ((1 << 4) | adc_cfg->adc_gain);// 0-3 bit adc pga gain value if(ql_es8311_write_reg(ES8311_REG_SYSTEM,REG14))// 8311 change adc pga gain reg 0x14 { return QL_AUDIO_CODEC_WR_FAIL; } if(ql_es8311_write_reg(ES8311_REG_ADC, 0xBF)) { return QL_AUDIO_CODEC_WR_FAIL; } } ql_adc_cfg.adc_gain = adc_cfg->adc_gain; return QL_AUDIO_SUCCESS; } ql_audio_errcode_e ql_aud_get_adc_gain(ql_aud_adc_cfg * adc_cfg) { if(NULL == adc_cfg) { return QL_AUDIO_INVALID_PARAM; } adc_cfg->adc_gain = ql_adc_cfg.adc_gain; return QL_AUDIO_SUCCESS; } ql_audio_errcode_e ql_aud_set_dac_gain(ql_aud_dac_cfg * dac_cfg) { if(ql_es8311_write_reg(0x32,dac_cfg->dac_gain))// 8311 change dac volume reg 0x32 { return QL_AUDIO_CODEC_WR_FAIL; } ql_dac_cfg.dac_gain = dac_cfg->dac_gain; return QL_AUDIO_SUCCESS; } ql_audio_errcode_e ql_aud_get_dac_gain(ql_aud_dac_cfg * dac_cfg) { if(dac_cfg == NULL) { return QL_AUDIO_INVALID_PARAM; } dac_cfg->dac_gain = ql_dac_cfg.dac_gain; return QL_AUDIO_SUCCESS; }