当前位置: 首页 > news >正文

MT6737 Android N 平台 Audio系统学习----录音到播放录音流程分析

http://blog.csdn.net/u014310046/article/details/54133688

 

本文将从主mic录音到播放流程来进行学习mtk audio系统架构。 
这里写图片描述

在AudioFlinger::RecordThread::threadLoop中会调用mInput->stream->read读取数据,stream就是audio_stream_in_t类型的指针,在执行open_input_stream时被初始化,先在它其实是一个legacy_stream_in类型的指针。当调用read时,in_read将会被调用。然后真正执行的是AudioStreamIn类中的read函数。

这里写图片描述
从上图可知要想实现mic录音,需要打通ADC0_L、ADC0_R/PreampL、PreampR/AIN0_P、AIN0_N(main mic)/AIN1_P、AIN1_N(headset mic)/AIN2_P、AIN2_N(ref mic)。 
下面开始分析从main mic录音。

1、snd_pcm_ops mtk_afe_capture_ops

static struct snd_pcm_ops mtk_afe_capture_ops = { 
.open = mtk_capture_pcm_open, 
.close = mtk_capture_pcm_close, 
.ioctl = snd_pcm_lib_ioctl, 
.hw_params = mtk_capture_pcm_hw_params, 
.hw_free = mtk_capture_pcm_hw_free, 
.prepare = mtk_capture_pcm_prepare, 
.trigger = mtk_capture_pcm_trigger, 
.pointer = mtk_capture_pcm_pointer, 
.copy = mtk_capture_pcm_copy, 
.silence = mtk_capture_pcm_silence, 
.page = mtk_capture_pcm_page, 
};

会先调用.open = mtk_capture_pcm_open打开capture。


static int mtk_capture_pcm_open(struct snd_pcm_substream *substream)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    int ret = 0; AudDrv_Clk_On(); AudDrv_ADC_Clk_On(); VUL_Control_context = Get_Mem_ControlT(Soc_Aud_Digital_Block_MEM_VUL); /* can allocate sram_dbg */ AfeControlSramLock(); #ifndef CAPTURE_FORCE_USE_DRAM if (GetSramState() == SRAM_STATE_FREE) { pr_warn("mtk_capture_pcm_open use sram\n"); mtk_capture_hardware.buffer_bytes_max = GetCaptureSramSize(); SetSramState(SRAM_STATE_CAPTURE); mCaptureUseSram = true; } else { pr_warn("mtk_capture_pcm_open use dram\n"); mtk_capture_hardware.buffer_bytes_max = UL1_MAX_BUFFER_SIZE; mCaptureUseSram = false; } #else pr_warn("mtk_capture_pcm_open use dram\n"); mtk_capture_hardware.buffer_bytes_max = UL1_MAX_BUFFER_SIZE; #endif AfeControlSramUnLock(); runtime->hw = mtk_capture_hardware; memcpy((void *)(&(runtime->hw)), (void *)&mtk_capture_hardware , sizeof(struct snd_pcm_hardware)); ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &constraints_sample_rates); ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) pr_warn("snd_pcm_hw_constraint_integer failed\n"); if (ret < 0) { pr_err("mtk_capture_pcm_close\n"); mtk_capture_pcm_close(substream); return ret; } if (mCaptureUseSram == false) AudDrv_Emi_Clk_On(); pr_warn("mtk_capture_pcm_open return\n"); return 0; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

接着调用mtk_capture_pcm_hw_params


static int mtk_capture_pcm_hw_params(struct snd_pcm_substream *substream,
                     struct snd_pcm_hw_params *hw_params)
{
    struct snd_pcm_runtime *runtime = substream->runtime; struct snd_dma_buffer *dma_buf = &substream->dma_buffer; int ret = 0; pr_warn("mtk_capture_pcm_hw_params\n"); dma_buf->dev.type = SNDRV_DMA_TYPE_DEV; dma_buf->dev.dev = substream->pcm->card->dev; dma_buf->private_data = NULL; if (mCaptureUseSram == true) { runtime->dma_bytes = params_buffer_bytes(hw_params); pr_warn("mtk_capture_pcm_hw_params mCaptureUseSram dma_bytes = %zu\n", runtime->dma_bytes); substream->runtime->dma_area = (unsigned char *)Get_Afe_SramBase_Pointer(); substream->runtime->dma_addr = Get_Afe_Sram_Phys_Addr(); } else if (Capture_dma_buf->area) { pr_warn("Capture_dma_buf = %p Capture_dma_buf->area = %p apture_dma_buf->addr = 0x%lx\n", Capture_dma_buf, Capture_dma_buf->area, (long) Capture_dma_buf->addr); runtime->dma_bytes = params_buffer_bytes(hw_params); runtime->dma_area = Capture_dma_buf->area; runtime->dma_addr = Capture_dma_buf->addr; } else { pr_warn("mtk_capture_pcm_hw_params snd_pcm_lib_malloc_pages\n"); ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); } SetVULBuffer(substream, hw_params); pr_warn("mtk_capture_pcm_hw_params dma_bytes = %zu dma_area = %p dma_addr = 0x%lx\n", substream->runtime->dma_bytes, substream->runtime->dma_area, (long)substream->runtime->dma_addr); return ret; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

调用mtk_capture_pcm_trigger

static int mtk_capture_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
    pr_warn("mtk_capture_pcm_trigger cmd = %d\n", cmd); //mtk_capture_pcm_trigger cmd = 1 switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: return mtk_capture_alsa_start(substream);//调用mtk_capture_alsa_start case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: return mtk_capture_alsa_stop(substream); } return -EINVAL; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

调用mtk_capture_alsa_start


static int mtk_capture_alsa_start(struct snd_pcm_substream *substream)
{
    pr_warn("mtk_capture_alsa_start\n");
    SetMemifSubStream(Soc_Aud_Digital_Block_MEM_VUL, substream); StartAudioCaptureHardware(substream); #ifdef DENALI_FPGA_EARLYPORTING /* ccc early porting, copy from TurnOnDacPower() and ADC_LOOP_DAC_Func() */ /* Afe_Set_Reg(AFE_SGEN_CON0, 0x24862862, 0xffffffff); */ /* Ana_Set_Reg(PMIC_AFE_TOP_CON0, 0x0002, 0x0002); //UL from sinetable */ /* Ana_Set_Reg(PMIC_AFE_TOP_CON0, 0x0001, 0x0001); //DL from sinetable */ /* Ana_Set_Reg(AFE_SGEN_CFG0 , 0x0080 , 0xffff); */ /* Ana_Set_Reg(AFE_SGEN_CFG1 , 0x0101 , 0xffff); */ Ana_Get_Reg(AFE_AUDIO_TOP_CON0); /* power on clock */ Ana_Get_Reg(AFUNC_AUD_CON2); Ana_Get_Reg(AFUNC_AUD_CON0); /* sdm audio fifo clock power on */ Ana_Get_Reg(AFUNC_AUD_CON2); /* sdm power on */ Ana_Get_Reg(AFUNC_AUD_CON2); /* sdm fifo enable */ Ana_Get_Reg(AFE_DL_SDM_CON1); /* set attenuation gain */ Ana_Get_Reg(AFE_UL_DL_CON0); /* [0] afe enable */ Ana_Get_Reg(AFE_PMIC_NEWIF_CFG0); /* 8k sample rate */ Ana_Get_Reg(AFE_DL_SRC2_CON0_H);/* 8k sample rate */ Ana_Get_Reg(AFE_DL_SRC2_CON0_L); /* turn off mute function and turn on dl */ Ana_Get_Reg(PMIC_AFE_TOP_CON0); /* set DL in normal path, not from sine gen table */ Ana_Get_Reg(AFE_SGEN_CFG0); /* set DL in normal path, not from sine gen table */ Ana_Get_Reg(AFE_SGEN_CFG1); /* set DL in normal path, not from sine gen table */ Ana_Get_Reg(TOP_CLKSQ); /* Enable CLKSQ 26MHz */ Ana_Get_Reg(TOP_CLKSQ_SET); /* Turn on 26MHz source clock */ Ana_Get_Reg(AFE_AUDIO_TOP_CON0); /* power on clock */ Ana_Get_Reg(FPGA_CFG1); /* must set in FPGA platform for PMIC digital loopback */ #endif return 0; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

接着调用StartAudioCaptureHardware


static void StartAudioCaptureHardware(struct snd_pcm_substream *substream)
{
    pr_warn("StartAudioCaptureHardware\n");

    ConfigAdcI2S(substream);
    SetI2SAdcIn(mAudioDigitalI2S);

    SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_VUL, AFE_WLEN_16_BIT);
    SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_VUL, AFE_WLEN_16_BIT);
    SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O09);
    SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O10);

    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC) == false) { SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC, true); SetI2SAdcEnable(true); } else { SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC, true); } SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I03, Soc_Aud_InterConnectionOutput_O09); SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I04, Soc_Aud_InterConnectionOutput_O10); if (substream->runtime->format == SNDRV_PCM_FORMAT_S32_LE || substream->runtime->format == SNDRV_PCM_FORMAT_U32_LE) { SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_VUL, AFE_WLEN_32_BIT_ALIGN_8BIT_0_24BIT_DATA); SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT, Soc_Aud_InterConnectionOutput_O09); SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT, Soc_Aud_InterConnectionOutput_O10); } /* here to set interrupt */ irq_add_user(substream, Soc_Aud_IRQ_MCU_MODE_IRQ2_MCU_MODE, substream->runtime->rate, substream->runtime->period_size); SetSampleRate(Soc_Aud_Digital_Block_MEM_VUL, substream->runtime->rate); SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_VUL, true); EnableAfe(true); #ifdef DENALI_FPGA_EARLYPORTING /* ccc early porting test, copy from TurnOnADcPowerACC() */ /* here to set digital part */ /* Topck_Enable(true); */ /* AdcClockEnable(true); */ /* Ana_Set_Reg(AFE_ADDA2_UL_SRC_CON1_L, 0x0000, 0xffff); //power on ADC clk //early porting 6752 remove */ Ana_Set_Reg(AFE_AUDIO_TOP_CON0, 0x0000, 0xffff); /* power on clock */ /* Ana_Set_Reg(AFE_ADDA2_UL_SRC_CON1_L, 0x0000, 0xffff); //power on ADC clk //early porting 6752 remove */ Ana_Set_Reg(PMIC_AFE_TOP_CON0, 0x0000, 0xffff); /* configure ADC setting */ Ana_Set_Reg(AFE_UL_DL_CON0, 0x0001, 0xffff); /* turn on afe */ Ana_Set_Reg(AFE_PMIC_NEWIF_CFG2, 0x302F, 0xffff); /* config UL up8x_rxif adc voice mode, 8k sample rate */ Ana_Set_Reg(AFE_UL_SRC0_CON0_H, (0 << 3 | 0 << 1) , 0x001f);/* ULsampling rate, 8k sample rate */ /* Ana_Set_Reg(AFE_ADDA2_UL_SRC_CON0_H, (ULSampleRateTransform(SampleRate_VUL2) << 3 | ULSampleRateTransform(SampleRate_VUL2) << 1) , 0x001f); // ULsampling rate */ /* Ana_Set_Reg(AFE_ADDA2_UL_SRC_CON0_L, 0x0041, 0xffff); */ Ana_Set_Reg(AFE_UL_SRC0_CON0_L, 0x0005, 0xffff); /* power on uplink, and loopback to DL */ Afe_Set_Reg(FPGA_CFG1, 0x1, 0xffff); /* must set in FPGA platform for PMIC digital loopback */ #endif } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

下面对上面函数进行分析 
(1)SetI2SAdcIn

////////////////////////////////////////////////* static void ConfigAdcI2S(struct snd_pcm_substream *substream) { mAudioDigitalI2S->mLR_SWAP = Soc_Aud_LR_SWAP_NO_SWAP; mAudioDigitalI2S->mBuffer_Update_word = 8; mAudioDigitalI2S->mFpga_bit_test = 0; mAudioDigitalI2S->mFpga_bit = 0; mAudioDigitalI2S->mloopback = 0; mAudioDigitalI2S->mINV_LRCK = Soc_Aud_INV_LRCK_NO_INVERSE; mAudioDigitalI2S->mI2S_FMT = Soc_Aud_I2S_FORMAT_I2S; mAudioDigitalI2S->mI2S_WLEN = Soc_Aud_I2S_WLEN_WLEN_16BITS; mAudioDigitalI2S->mI2S_SAMPLERATE = (substream->runtime->rate); } *///////////////////////////////////////////////// bool SetI2SAdcIn(AudioDigtalI2S *DigtalI2S) { uint32 Audio_I2S_Adc = 0; memcpy((void *)AudioAdcI2S, (void *)DigtalI2S, sizeof(AudioDigtalI2S)); if (false == AudioAdcI2SStatus) { uint32 eSamplingRate = SampleRateTransform(AudioAdcI2S->mI2S_SAMPLERATE); uint32 dVoiceModeSelect = 0; Afe_Set_Reg(AFE_ADDA_TOP_CON0, 0, 0x1); /* Using Internal ADC */ if (eSamplingRate == Soc_Aud_I2S_SAMPLERATE_I2S_8K) dVoiceModeSelect = 0; else if (eSamplingRate == Soc_Aud_I2S_SAMPLERATE_I2S_16K) dVoiceModeSelect = 1; else if (eSamplingRate == Soc_Aud_I2S_SAMPLERATE_I2S_32K) dVoiceModeSelect = 2; else if (eSamplingRate == Soc_Aud_I2S_SAMPLERATE_I2S_48K) dVoiceModeSelect = 3; Afe_Set_Reg(AFE_ADDA_UL_SRC_CON0, (dVoiceModeSelect << 19) | (dVoiceModeSelect << 17), 0x001E0000); Afe_Set_Reg(AFE_ADDA_NEWIF_CFG0, 0x03F87201, 0xFFFFFFFF); /* up8x txif sat on */ Afe_Set_Reg(AFE_ADDA_NEWIF_CFG1, ((dVoiceModeSelect < 3) ? 1 : 3) << 10, 0x00000C00); } else { Afe_Set_Reg(AFE_ADDA_TOP_CON0, 1, 0x1); /* Using External ADC */ Audio_I2S_Adc |= (AudioAdcI2S->mLR_SWAP << 31); Audio_I2S_Adc |= (AudioAdcI2S->mBuffer_Update_word << 24); Audio_I2S_Adc |= (AudioAdcI2S->mINV_LRCK << 23); Audio_I2S_Adc |= (AudioAdcI2S->mFpga_bit_test << 22); Audio_I2S_Adc |= (AudioAdcI2S->mFpga_bit << 21); Audio_I2S_Adc |= (AudioAdcI2S->mloopback << 20); Audio_I2S_Adc |= (SampleRateTransform(AudioAdcI2S->mI2S_SAMPLERATE) << 8); Audio_I2S_Adc |= (AudioAdcI2S->mI2S_FMT << 3); Audio_I2S_Adc |= (AudioAdcI2S->mI2S_WLEN << 1); pr_debug("%s Audio_I2S_Adc = 0x%x", __func__, Audio_I2S_Adc); Afe_Set_Reg(AFE_I2S_CON2, Audio_I2S_Adc, MASK_ALL); } return true; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

(2) 
SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I03, Soc_Aud_InterConnectionOutput_O09); 
SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I04, Soc_Aud_InterConnectionOutput_O10); 
(3)设置中断

/* here to set interrupt */
    irq_add_user(substream,
             Soc_Aud_IRQ_MCU_MODE_IRQ2_MCU_MODE,
             substream->runtime->rate,
             substream->runtime->period_size);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
int irq_add_user(const void *_user,
         enum Soc_Aud_IRQ_MCU_MODE _irq,
         unsigned int _rate,
         unsigned int _count)
{
    unsigned long flags;
    struct irq_user *new_user; struct irq_user *ptr; spin_lock_irqsave(&afe_control_lock, flags); //irq_add_user(), user dc5fa000, irq 1, rate 48000, count 960 pr_debug("%s(), user %p, irq %d, rate %d, count %d\n", __func__, _user, _irq, _rate, _count); /* check if user already exist */ list_for_each_entry(ptr, &irq_managers[_irq].users, list) { if (ptr->user == _user) { pr_err("error, _user %p already exist\n", _user); dump_irq_manager(); pr_err("error, _user already exist\n"); } } /* create instance */ new_user = kzalloc(sizeof(*new_user), GFP_ATOMIC); if (!new_user) { spin_unlock_irqrestore(&afe_control_lock, flags); return -ENOMEM; } new_user->user = _user; new_user->request_rate = _rate; new_user->request_count = _count; INIT_LIST_HEAD(&new_user->list); /* add user to list */ list_add(&new_user->list, &irq_managers[_irq].users); /* */ if (irq_managers[_irq].is_on) { if (is_period_smaller(_irq, new_user)) check_and_update_irq(new_user, _irq); } else { enable_aud_irq(new_user, _irq, _rate, _count); } spin_unlock_irqrestore(&afe_control_lock, flags); return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
/* IRQ Manager */
static int enable_aud_irq(const struct irq_user *_irq_user, enum Soc_Aud_IRQ_MCU_MODE _irq, unsigned int _rate, unsigned int _count) { /* SetIrqMcuSampleRate(), Irqmode 1, SampleRate 48000 SetIrqMcuCounter(), Irqmode 1, Counter 960 SetIrqEnable(), Irqmode 1, bEnable 1 */ SetIrqMcuSampleRate(_irq, _rate); SetIrqMcuCounter(_irq, _count); SetIrqEnable(_irq, true); irq_managers[_irq].is_on = true; irq_managers[_irq].rate = _rate; irq_managers[_irq].count = _count; irq_managers[_irq].selected_user = _irq_user; return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

(4) 
SetSampleRate(Soc_Aud_Digital_Block_MEM_VUL, substream->runtime->rate);


bool SetSampleRate(uint32 Aud_block, uint32 SampleRate)
{
    /* pr_debug("%s Aud_block = %d SampleRate = %d\n", __func__, Aud_block, SampleRate); */
    // SampleRate = SampleRateTransform(SampleRate); switch (Aud_block) { case Soc_Aud_Digital_Block_MEM_DL1:{ Afe_Set_Reg(AFE_DAC_CON1, SampleRate, 0x0000000f); break; } case Soc_Aud_Digital_Block_MEM_DL2:{ Afe_Set_Reg(AFE_DAC_CON1, SampleRate << 4, 0x000000f0); break; } case Soc_Aud_Digital_Block_MEM_I2S:{ Afe_Set_Reg(AFE_DAC_CON1, SampleRate << 8, 0x00000f00); break; } case Soc_Aud_Digital_Block_MEM_AWB:{ Afe_Set_Reg(AFE_DAC_CON1, SampleRate << 12, 0x0000f000); break; } case Soc_Aud_Digital_Block_MEM_VUL:{ Afe_Set_Reg(AFE_DAC_CON1, SampleRate << 16, 0x000f0000); break; } case Soc_Aud_Digital_Block_MEM_DAI:{ if (SampleRate == Soc_Aud_I2S_SAMPLERATE_I2S_8K) Afe_Set_Reg(AFE_DAC_CON0, 0 << 24, 3 << 24); else if (SampleRate == Soc_Aud_I2S_SAMPLERATE_I2S_16K) Afe_Set_Reg(AFE_DAC_CON0, 1 << 24, 3 << 24); else if (SampleRate == Soc_Aud_I2S_SAMPLERATE_I2S_32K) Afe_Set_Reg(AFE_DAC_CON0, 2 << 24, 3 << 24); else return false; break; } case Soc_Aud_Digital_Block_MEM_MOD_DAI:{ if (SampleRate == Soc_Aud_I2S_SAMPLERATE_I2S_8K) Afe_Set_Reg(AFE_DAC_CON1, 0 << 30, 3 << 30); else if (SampleRate == Soc_Aud_I2S_SAMPLERATE_I2S_16K) Afe_Set_Reg(AFE_DAC_CON1, 1 << 30, 3 << 30); else return false; break; } case Soc_Aud_Digital_Block_MEM_VUL_DATA2:{ Afe_Set_Reg(AFE_DAC_CON0, SampleRate << 20, 0x00f00000); break; } return true; } return false; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

(5)

bool SetMemoryPathEnable(uint32 Aud_block, bool bEnable)
{
    /*pr_debug("%s Aud_block = %d bEnable = %d\n", __func__, Aud_block, bEnable);*/
    if (Aud_block >= Soc_Aud_Digital_Block_NUM_OF_DIGITAL_BLOCK)
        return false;

    /* set for counter */ if (bEnable == true) { if (mAudioMEMIF[Aud_block]->mUserCount == 0) mAudioMEMIF[Aud_block]->mState = true; mAudioMEMIF[Aud_block]->mUserCount++; } else { mAudioMEMIF[Aud_block]->mUserCount--; if (mAudioMEMIF[Aud_block]->mUserCount == 0) mAudioMEMIF[Aud_block]->mState = false; if (mAudioMEMIF[Aud_block]->mUserCount < 0) { mAudioMEMIF[Aud_block]->mUserCount = 0; pr_err("warning , user count <0\n"); } } /*pr_debug("%s Aud_block = %d mAudioMEMIF[Aud_block]->mUserCount = %d\n", __func__, Aud_block, mAudioMEMIF[Aud_block]->mUserCount);*/ if (Aud_block > Soc_Aud_Digital_Block_NUM_OF_MEM_INTERFACE) return true; if ((bEnable == true) && (mAudioMEMIF[Aud_block]->mUserCount == 1)) Afe_Set_Reg(AFE_DAC_CON0, bEnable << (Aud_block + 1), 1 << (Aud_block + 1)); else if ((bEnable == false) && (mAudioMEMIF[Aud_block]->mUserCount == 0)) Afe_Set_Reg(AFE_DAC_CON0, bEnable << (Aud_block + 1), 1 << (Aud_block + 1)); return true; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

(6)

                 */
void EnableAfe(bool bEnable)
{
    unsigned long flags;
    bool MemEnable = false; #ifdef CONFIG_OF #ifdef CONFIG_MTK_LEGACY int ret; ret = GetGPIO_Info(1, &pin_audclk, &pin_mode_audclk); if (ret < 0) { pr_err("EnableAfe GetGPIO_Info FAIL1!!!\n"); return; } ret = GetGPIO_Info(2, &pin_audmiso, &pin_mode_audmiso); if (ret < 0) { pr_err("EnableAfe GetGPIO_Info FAIL2!!!\n"); return; } ret = GetGPIO_Info(3, &pin_audmosi, &pin_mode_audmosi); if (ret < 0) { pr_err("EnableAfe GetGPIO_Info FAIL3!!!\n"); return; } #endif #endif spin_lock_irqsave(&afe_control_lock, flags); MemEnable = CheckMemIfEnable(); if (false == bEnable && false == MemEnable) { Afe_Set_Reg(AFE_DAC_CON0, 0x0, 0x1); #ifndef CONFIG_FPGA_EARLY_PORTING #ifdef CONFIG_OF #if defined(CONFIG_MTK_LEGACY) mt_set_gpio_mode(pin_audclk, GPIO_MODE_00); /* GPIO24, AUD_CLK_MOSI. */ /* this GPIO only use in record and VOW */ mt_set_gpio_mode(pin_audmiso, GPIO_MODE_00); /* GPIO25, AUD_DAT_MISO */ mt_set_gpio_mode(pin_audmosi, GPIO_MODE_00); /* GPIO26, AUD_DAT_MOSI */ #else AudDrv_GPIO_PMIC_Select(bEnable); #endif #else mt_set_gpio_mode(GPIO_AUD_CLK_MOSI_PIN, GPIO_MODE_00); /* GPIO24, AUD_CLK_MOSI. */ /* this GPIO only use in record and VOW */ mt_set_gpio_mode(GPIO_AUD_DAT_MISO_PIN, GPIO_MODE_00); /* GPIO25, AUD_DAT_MISO */ mt_set_gpio_mode(GPIO_AUD_DAT_MOSI_PIN, GPIO_MODE_00); /* GPIO26, AUD_DAT_MOSI */ #endif #endif } else if (true == bEnable && true == MemEnable) { #ifndef CONFIG_FPGA_EARLY_PORTING #ifdef CONFIG_OF #if defined(CONFIG_MTK_LEGACY) mt_set_gpio_mode(pin_audclk, GPIO_MODE_01); /* GPIO24, AUD_CLK_MOSI */ /* this GPIO only use in record and VOW */ mt_set_gpio_mode(pin_audmiso, GPIO_MODE_01); /* GPIO25, AUD_DAT_MISO */ mt_set_gpio_mode(pin_audmosi, GPIO_MODE_01); /* GPIO26, AUD_DAT_MOSI */ #else AudDrv_GPIO_PMIC_Select(bEnable); #endif #else mt_set_gpio_mode(GPIO_AUD_CLK_MOSI_PIN, GPIO_MODE_01); /* GPIO24, AUD_CLK_MOSI */ /* this GPIO only use in record and VOW */ mt_set_gpio_mode(GPIO_AUD_DAT_MISO_PIN, GPIO_MODE_01); /* GPIO25, AUD_DAT_MISO */ mt_set_gpio_mode(GPIO_AUD_DAT_MOSI_PIN, GPIO_MODE_01); /* GPIO26, AUD_DAT_MOSI */ #endif #endif Afe_Set_Reg(AFE_DAC_CON0, 0x1, 0x1); } spin_unlock_irqrestore(&afe_control_lock, flags); } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86

上面打开capture,配置了硬件 ,配置afe,设置中断。下面进入codec。

对mic模式选择设置

SOC_ENUM_EXT("Audio_MIC1_Mode_Select", Audio_UL_Enum[17], Audio_Mic1_Mode_Select_Get,
             Audio_Mic1_Mode_Select_Set),
SOC_ENUM_EXT("Audio_MIC2_Mode_Select", Audio_UL_Enum[18], Audio_Mic2_Mode_Select_Get, Audio_Mic2_Mode_Select_Set),
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

//Audio_Mic1_Mode_Select_Set() mAudio_Analog_Mic1_mode = 0
static int Audio_Mic1_Mode_Select_Set(struct snd_kcontrol *kcontrol,
                      struct snd_ctl_elem_value *ucontrol) { pr_warn("%s()\n", __func__); if (ucontrol->value.enumerated.item[0] > ARRAY_SIZE(Audio_AnalogMic_Mode)) { pr_err("return -EINVAL\n"); return -EINVAL; } mAudio_Analog_Mic1_mode = ucontrol->value.integer.value[0]; pr_warn("%s() mAudio_Analog_Mic1_mode = %d\n", __func__, mAudio_Analog_Mic1_mode); return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
//Audio_Mic2_Mode_Select_Set() mAudio_Analog_Mic2_mode = 0
static int Audio_Mic2_Mode_Select_Set(struct snd_kcontrol *kcontrol,
                      struct snd_ctl_elem_value *ucontrol) { pr_warn("%s()\n", __func__); if (ucontrol->value.enumerated.item[0] > ARRAY_SIZE(Audio_AnalogMic_Mode)) { pr_err("return -EINVAL\n"); return -EINVAL; } mAudio_Analog_Mic2_mode = ucontrol->value.integer.value[0]; pr_warn("%s() mAudio_Analog_Mic2_mode = %d\n", __func__, mAudio_Analog_Mic2_mode); return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

static int mAudio_Analog_Mic1_mode = AUDIO_ANALOGUL_MODE_ACC;
static int mAudio_Analog_Mic2_mode = AUDIO_ANALOGUL_MODE_ACC;
typedef enum { AUDIO_ANALOGUL_MODE_ACC = 0, AUDIO_ANALOGUL_MODE_DCC, AUDIO_ANALOGUL_MODE_DMIC, AUDIO_ANALOGUL_MODE_DCCECMDIFF, AUDIO_ANALOGUL_MODE_DCCECMSINGLE, } AUDIO_ANALOGUL_MODE; 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

mAudio_Analog_Mic1_mode = ucontrol->value.integer.value[0]; 
mAudio_Analog_Mic2_mode = ucontrol->value.integer.value[0]; 
从mAudio_Analog_Mic1_mode和mAudio_Analog_Mic2_mode值可判断mic使用的模式,0:ACC 1:DCC 2:DMIC 3:DCCECMDIFF 4:DCCECMSINGLE

下面设置Audio_MicSource1_Set 
SOC_ENUM_EXT(“Audio_MicSource1_Setting”, Audio_UL_Enum[13], Audio_MicSource1_Get, 
Audio_MicSource1_Set),

//Audio_MicSource1_Set() index = 0 done
static int Audio_MicSource1_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { /* 6752 used for ADC1 Mic source selection, "ADC1" is main_mic, "ADC2" is headset_mic */ int index = 0; pr_warn("%s()\n", __func__); if (ucontrol->value.enumerated.item[0] > ARRAY_SIZE(Pmic_Digital_Mux)) { pr_err("return -EINVAL\n"); return -EINVAL; } index = ucontrol->value.integer.value[0]; pr_warn("%s() index = %d done\n", __func__, index); mCodec_data->mAudio_Ana_Mux[AUDIO_MICSOURCE_MUX_IN_1] = ucontrol->value.integer.value[0]; return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

接下来设置 
SOC_ENUM_EXT(“Audio_ADC_1_Switch”, Audio_UL_Enum[0], Audio_ADC1_Get, Audio_ADC1_Set), 
SOC_ENUM_EXT(“Audio_ADC_2_Switch”, Audio_UL_Enum[1], Audio_ADC2_Get, Audio_ADC2_Set),


static int Audio_ADC1_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    pr_warn("%s()\n", __func__); mutex_lock(&Ana_Power_Mutex); if (ucontrol->value.integer.value[0]) { if (mAudio_Analog_Mic1_mode == AUDIO_ANALOGUL_MODE_ACC) TurnOnADcPowerACC(AUDIO_ANALOG_DEVICE_IN_ADC1, true); else if (mAudio_Analog_Mic1_mode == AUDIO_ANALOGUL_MODE_DCC) TurnOnADcPowerDCC(AUDIO_ANALOG_DEVICE_IN_ADC1, true, 0); else if (mAudio_Analog_Mic1_mode == AUDIO_ANALOGUL_MODE_DMIC) TurnOnADcPowerDmic(AUDIO_ANALOG_DEVICE_IN_ADC1, true); else if (mAudio_Analog_Mic1_mode == AUDIO_ANALOGUL_MODE_DCCECMDIFF) TurnOnADcPowerDCC(AUDIO_ANALOG_DEVICE_IN_ADC1, true, 1); else if (mAudio_Analog_Mic1_mode == AUDIO_ANALOGUL_MODE_DCCECMSINGLE) TurnOnADcPowerDCC(AUDIO_ANALOG_DEVICE_IN_ADC1, true, 2); mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_IN_ADC1] = ucontrol->value.integer.value[0]; } else { mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_IN_ADC1] = ucontrol->value.integer.value[0]; if (mAudio_Analog_Mic1_mode == AUDIO_ANALOGUL_MODE_ACC) TurnOnADcPowerACC(AUDIO_ANALOG_DEVICE_IN_ADC1, false); else if (mAudio_Analog_Mic1_mode == AUDIO_ANALOGUL_MODE_DCC) TurnOnADcPowerDCC(AUDIO_ANALOG_DEVICE_IN_ADC1, false, 0); else if (mAudio_Analog_Mic1_mode == AUDIO_ANALOGUL_MODE_DMIC) TurnOnADcPowerDmic(AUDIO_ANALOG_DEVICE_IN_ADC1, false); else if (mAudio_Analog_Mic1_mode == AUDIO_ANALOGUL_MODE_DCCECMDIFF) TurnOnADcPowerDCC(AUDIO_ANALOG_DEVICE_IN_ADC1, false, 1); else if (mAudio_Analog_Mic1_mode == AUDIO_ANALOGUL_MODE_DCCECMSINGLE) TurnOnADcPowerDCC(AUDIO_ANALOG_DEVICE_IN_ADC1, false, 2); } mutex_unlock(&Ana_Power_Mutex); return 0; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
static int Audio_ADC2_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    pr_warn("%s()\n", __func__); mutex_lock(&Ana_Power_Mutex); if (ucontrol->value.integer.value[0]) { if (mAudio_Analog_Mic2_mode == AUDIO_ANALOGUL_MODE_ACC) TurnOnADcPowerACC(AUDIO_ANALOG_DEVICE_IN_ADC2, true); else if (mAudio_Analog_Mic2_mode == AUDIO_ANALOGUL_MODE_DCC) TurnOnADcPowerDCC(AUDIO_ANALOG_DEVICE_IN_ADC2, true, 0); else if (mAudio_Analog_Mic2_mode == AUDIO_ANALOGUL_MODE_DMIC) TurnOnADcPowerDmic(AUDIO_ANALOG_DEVICE_IN_ADC2, true); else if (mAudio_Analog_Mic2_mode == AUDIO_ANALOGUL_MODE_DCCECMDIFF) TurnOnADcPowerDCC(AUDIO_ANALOG_DEVICE_IN_ADC2, true, 1); else if (mAudio_Analog_Mic2_mode == AUDIO_ANALOGUL_MODE_DCCECMSINGLE) TurnOnADcPowerDCC(AUDIO_ANALOG_DEVICE_IN_ADC2, true, 2); mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_IN_ADC2] = ucontrol->value.integer.value[0]; } else { mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_IN_ADC2] = ucontrol->value.integer.value[0]; if (mAudio_Analog_Mic2_mode == AUDIO_ANALOGUL_MODE_ACC) TurnOnADcPowerACC(AUDIO_ANALOG_DEVICE_IN_ADC2, false); else if (mAudio_Analog_Mic2_mode == AUDIO_ANALOGUL_MODE_DCC) TurnOnADcPowerDCC(AUDIO_ANALOG_DEVICE_IN_ADC2, false, 0); else if (mAudio_Analog_Mic2_mode == AUDIO_ANALOGUL_MODE_DMIC) TurnOnADcPowerDmic(AUDIO_ANALOG_DEVICE_IN_ADC2, false); else if (mAudio_Analog_Mic2_mode == AUDIO_ANALOGUL_MODE_DCCECMDIFF) TurnOnADcPowerDCC(AUDIO_ANALOG_DEVICE_IN_ADC2, false, 1); else if (mAudio_Analog_Mic2_mode == AUDIO_ANALOGUL_MODE_DCCECMSINGLE) TurnOnADcPowerDCC(AUDIO_ANALOG_DEVICE_IN_ADC2, false, 2); } mutex_unlock(&Ana_Power_Mutex); return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

TurnOnADcPowerACC ADCType = 13 enable = 1, refmic_using_ADC_L=0 
TurnOnADcPowerACC ADCType = 14 enable = 1, refmic_using_ADC_L=0



static bool TurnOnADcPowerACC(int ADCType, bool enable)
{
    bool refmic_using_ADC_L;

    refmic_using_ADC_L = false;

    pr_warn("%s ADCType = %d enable = %d, refmic_using_ADC_L=%d\n", __func__, ADCType, enable, refmic_using_ADC_L); if (enable) { /* uint32 ULIndex = GetULFrequency(mBlockSampleRate[AUDIO_ANALOG_DEVICE_IN_ADC]); */ uint32 SampleRate_VUL1 = mBlockSampleRate[AUDIO_ANALOG_DEVICE_IN_ADC]; /* uint32 SampleRate_VUL2 = mBlockSampleRate[AUDIO_ANALOG_DEVICE_IN_ADC_2]; */ if (GetMicbias == 0) { MicbiasRef = Ana_Get_Reg(AUDENC_ANA_CON9) & 0x0700; /* save current micbias ref set by accdet */ pr_warn("MicbiasRef=0x%x\n", MicbiasRef); GetMicbias = 1; } if (GetAdcStatus() == false) { audckbufEnable(true); /* Ana_Set_Reg(LDO_VCON1, 0x0301, 0xffff); //VA28 remote sense //removed in MT6328 */ Ana_Set_Reg(LDO_CON2, 0x8102, 0xffff); /* LDO enable control by RG_VAUD28_EN, Enable AVDD28_LDO (Default on) */ NvregEnable(true); /* ClsqAuxEnable(true); */ ClsqEnable(true); Ana_Set_Reg(AUDDEC_ANA_CON6, 0x0004, 0x0004); /* Enable audio ADC CLKGEN */ Ana_Set_Reg(AUDENC_ANA_CON3, 0x0000, 0xffff); /* ADC CLK from CLKGEN (13MHz) */ Ana_Set_Reg(AUDDEC_ANA_CON6, 0x0104, 0x0104); /* Enable LCLDO_ENC 1P8V */ Ana_Set_Reg(AUDDEC_ANA_CON7, 0x0006, 0x0006); /* LCLDO_ENC remote sense */ /* Ana_Set_Reg(AUDENC_ANA_CON6, 0x1515, 0xffff); //default value */ Ana_Set_Reg(AUDENC_ANA_CON6, 0x0555, 0xffff); /* default value MT6328 */ Ana_Set_Reg(AUDENC_ANA_CON4, 0x0800, 0xffff); /* default value */ } if (ADCType == AUDIO_ANALOG_DEVICE_IN_ADC1) { /* main and headset mic */ pr_warn("%s AUDIO_ANALOG_DEVICE_IN_ADC1 mux =%d\n", __func__, mCodec_data->mAudio_Ana_Mux[AUDIO_MICSOURCE_MUX_IN_1]); if (mCodec_data->mAudio_Ana_Mux[AUDIO_MICSOURCE_MUX_IN_1] == 0) {//主mic /* "ADC1", main_mic */ SetDCcoupleNP(AUDIO_MIC_BIAS0, mAudio_Analog_Mic1_mode); /* micbias0 DCCopuleNP */ /* Ana_Set_Reg(AUDENC_ANA_CON9, 0x0201, 0xff09); //Enable MICBIAS0, MISBIAS0 = 1P9V */ Ana_Set_Reg(AUDENC_ANA_CON9, 0x0711, 0xff19); /* Enable MICBIAS0, MISBIAS0 = 1P9V, also enable MICBIAS1 at the same time to avoid noise */ } else if (mCodec_data->mAudio_Ana_Mux[AUDIO_MICSOURCE_MUX_IN_1] == 1) {//耳机mic /* "ADC2", headset mic */ SetDCcoupleNP(AUDIO_MIC_BIAS1, mAudio_Analog_Mic1_mode); /* micbias1 DCCopuleNP */ Ana_Set_Reg(AUDENC_ANA_CON9, 0x0710, 0xff90); /* Enable MICBIAS1, MISBIAS1 = 2P5V ?// or 2P7V George? */ } /* Ana_Set_Reg(AUDENC_ANA_CON15, 0x0003, 0x000f); //Audio L PGA 18 dB gain(SMT) */ Ana_Set_Reg(AUDENC_ANA_CON10, 0x0003, 0x000f); /* Audio L PGA 18 dB gain(SMT) MT6328 */ } else if (ADCType == AUDIO_ANALOG_DEVICE_IN_ADC2) { /* ref mic */ pr_warn("%s AUDIO_ANALOG_DEVICE_IN_ADC2 refmic_using_ADC_L =%d\n", __func__, refmic_using_ADC_L); SetDCcoupleNP(AUDIO_MIC_BIAS0, mAudio_Analog_Mic2_mode); /* micbias0 DCCopuleNP */ if (mCodec_data->mAudio_Ana_Mux[AUDIO_MICSOURCE_MUX_IN_1] == 1) { /*Enable MICBIAS0, MISBIAS0 = 2P7V */ Ana_Set_Reg(AUDENC_ANA_CON9, 0x0710, 0xff90); } else { /* "ADC2", headset mic */ SetDCcoupleNP(AUDIO_MIC_BIAS1, mAudio_Analog_Mic1_mode); /* micbias1 DCCopuleNP */ Ana_Set_Reg(AUDENC_ANA_CON9, 0x0711, 0xff19); /* Enable MICBIAS1, MISBIAS1 = 1P9V// or 2P7V George? */ /* Enable MICBIAS0, MISBIAS0 = 1P9V, also enable MICBIAS1 to avoid noise */ } if (refmic_using_ADC_L == false) { /* Ana_Set_Reg(AUDENC_ANA_CON15, 0x0030, 0x00f0); //Audio R PGA 18 dB gain(SMT) */ Ana_Set_Reg(AUDENC_ANA_CON10, 0x0033, 0x00ff); /* Audio R PGA 18 dB gain(SMT) MT6328 */ } else { /* Ana_Set_Reg(AUDENC_ANA_CON15, 0x0003, 0x000f); //Audio L PGA 18 dB gain(SMT) */ Ana_Set_Reg(AUDENC_ANA_CON10, 0x0003, 0x000f); /* Audio L PGA 18 dB gain(SMT) MT6328 */ } } if (ADCType == AUDIO_ANALOG_DEVICE_IN_ADC1) { /* main and headset mic */ Ana_Set_Reg(AUDENC_ANA_CON3, 0x0800, 0xf900); /* PGA stb enhance */ if (mCodec_data->mAudio_Ana_Mux[AUDIO_MICSOURCE_MUX_IN_1] == 0) { /* "ADC1", main_mic */ Ana_Set_Reg(AUDENC_ANA_CON0, 0x0041, 0x00C1);  /* Audio L preamplifier input sel : AIN0. Enable audio L PGA */ Ana_Set_Reg(AUDENC_ANA_CON0, 0x0541, 0xffff);  /* Audio L ADC input sel : L PGA. Enable audio L ADC */ } else if (mCodec_data->mAudio_Ana_Mux[AUDIO_MICSOURCE_MUX_IN_1] == 1) { /* "ADC2", headset mic */ Ana_Set_Reg(AUDENC_ANA_CON0, 0x0500, 0xffff);  /* Audio L ADC input sel : L PGA. Enable audio L ADC */ Ana_Set_Reg(AUDENC_ANA_CON0, 0x0581, 0xffff);  /* Audio L preamplifier input sel : AIN1. Enable audio L PGA */ } } else if (ADCType == AUDIO_ANALOG_DEVICE_IN_ADC2) { /* ref mic */ Ana_Set_Reg(AUDENC_ANA_CON3, 0x0800, 0xf900); /* PGA stb enhance */ if (refmic_using_ADC_L == false) { Ana_Set_Reg(AUDENC_ANA_CON1, 0x00C1, 0x00C1);  /* Audio R preamplifier input sel : AIN2. Enable audio R PGA */ Ana_Set_Reg(AUDENC_ANA_CON1, 0x05C1, 0xffff);  /* Audio R ADC input sel : R PGA. Enable audio R ADC */ } else { Ana_Set_Reg(AUDENC_ANA_CON0, 0x00c1, 0x00C1);  /* Audio L preamplifier input sel : AIN2. Enable audio L PGA */ Ana_Set_Reg(AUDENC_ANA_CON0, 0x05c1, 

转载于:https://www.cnblogs.com/Ph-one/p/6879750.html

相关文章:

  • 双链表的初始化,建立,插入,查找,删除。
  • 顺序栈的初始化,建立,插入,查找,删除。
  • 顺序队列的初始化,建立,插入,查找,删除。
  • 链队列的初始化,建立,插入,查找,删除。
  • 链栈的初始化,建立,插入,查找,删除。
  • 顺序串的初始化,建立,插入,查找,删除。
  • quick check
  • http://blog.csdn.net/renfufei/article/details/37725057/
  • github 博客模板
  • 好用的Markdown编辑器一览
  • 复旦大学考研科目
  • 51单片机GPIO口模拟串口通信
  • 第一部分软件工程基础[专业课考试1]
  • 第二部分计算机系统基础[专业课考试2]
  • 第三部分数据结构[专业课考试3]
  • [PHP内核探索]PHP中的哈希表
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • Mac转Windows的拯救指南
  • mysql_config not found
  • Redux 中间件分析
  • spring + angular 实现导出excel
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 学习使用ExpressJS 4.0中的新Router
  • 异常机制详解
  • 怎么把视频里的音乐提取出来
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • #QT项目实战(天气预报)
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (十五)使用Nexus创建Maven私服
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • ../depcomp: line 571: exec: g++: not found
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .NET 发展历程
  • .net6使用Sejil可视化日志
  • .NET成年了,然后呢?
  • .NET微信公众号开发-2.0创建自定义菜单
  • @value 静态变量_Python彻底搞懂:变量、对象、赋值、引用、拷贝
  • [04]Web前端进阶—JS伪数组
  • [20150321]索引空块的问题.txt
  • [ASP.NET MVC]如何定制Numeric属性/字段验证消息
  • [CareerCup] 14.5 Object Reflection 对象反射
  • [CTSC2014]企鹅QQ
  • [GN] Vue3.2 快速上手 ---- 核心语法2
  • [Head First设计模式]策略模式
  • [JavaScript] JavaScript事件注册,事件委托,冒泡,捕获,事件流
  • [Labtools 27-1429] XML parser encountered a problem in file