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, 0xffff);
                /* Audio L ADC input sel : L PGA. Enable audio L ADC */
            }
        }

        SetMicPGAGain();

        if (GetAdcStatus() == false) {
            /* here to set digital part */
            Topck_Enable(true);
            /* AdcClockEnable(true); */
            if (GetDacStatus() == false) {
                Ana_Set_Reg(AFE_AUDIO_TOP_CON0, 0x005a, 0xffff);
                /* power on clock */
            } else {
                Ana_Set_Reg(AFE_AUDIO_TOP_CON0, 0x0000, 0xffff);
                /* power on clock */
            }
            Ana_Set_Reg(PMIC_AFE_TOP_CON0, 0x0000, 0xffff);
            /* configure ADC setting */
            /* Ana_Set_Reg(AFUNC_AUD_CON2, 0x0006, 0xffff);
            //sdm audio fifo clock power on */
            /* Ana_Set_Reg(AFUNC_AUD_CON0, 0xc3a1, 0xffff);
            //scrambler clock on enable */
            /* Ana_Set_Reg(AFUNC_AUD_CON2, 0x0003, 0xffff);
            //sdm power on */
            /* Ana_Set_Reg(AFUNC_AUD_CON2, 0x000b, 0xffff);
            //sdm fifo enable */
            /* Ana_Set_Reg(AFE_DL_SDM_CON1, 0x001e, 0xffff);
            //set attenuation gain */
            Ana_Set_Reg(AFE_UL_DL_CON0, 0x0001, 0xffff);
            /* [0] afe enable */

            Ana_Set_Reg(AFE_UL_SRC0_CON0_H,
            (ULSampleRateTransform(SampleRate_VUL1) << 3 | ULSampleRateTransform(SampleRate_VUL1) << 1),
            0x001f);
            /* UL sample rate and mode configure */
            Ana_Set_Reg(AFE_UL_SRC0_CON0_L, 0x0001, 0xffff);
            /* UL turn on */
        }
    } else {
        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) {
            Ana_Set_Reg(AFE_UL_SRC0_CON0_L, 0x0000, 0xffff);
            /* UL turn off */
            Ana_Set_Reg(AFE_AUDIO_TOP_CON0, 0x0020, 0x0020);
            /* up-link power down */
        }
        if (ADCType == AUDIO_ANALOG_DEVICE_IN_ADC1) {
            /* main and headset mic */
            if (mCodec_data->mAudio_Ana_Mux[AUDIO_MICSOURCE_MUX_IN_1] == 0) {
                /* "ADC1", main_mic */
                Ana_Set_Reg(AUDENC_ANA_CON0, 0x0041, 0xffff);
                /* Audio L ADC input sel : off, disable audio L ADC */
                Ana_Set_Reg(AUDENC_ANA_CON3, 0x0000, 0xffff);
                /* PGA stb enhance off */
                /* Ana_Set_Reg(AUDENC_ANA_CON15, 0x0000, 0x000f); //Audio L PGA 0 dB gain */
                Ana_Set_Reg(AUDENC_ANA_CON10, 0x0000, 0x000f);
                /* MT6328 Audio L PGA 0 dB gain */

                Ana_Set_Reg(AUDENC_ANA_CON0, 0x0000, 0xffff);
                /* Audio L preamplifier input sel : off, disable audio L PGA */
            } 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 preamplifier input sel : off, disable audio L PGA */
                Ana_Set_Reg(AUDENC_ANA_CON0, 0x0000, 0xffff);
                /* Audio L ADC input sel : off, disable audio L ADC */
                Ana_Set_Reg(AUDENC_ANA_CON3, 0x0000, 0xffff);
                /* PGA stb enhance off */
                /* Ana_Set_Reg(AUDENC_ANA_CON15, 0x0000, 0x000f);
                //Audio L PGA 0 dB gain */
                Ana_Set_Reg(AUDENC_ANA_CON10, 0x0000, 0x000f);
                /* MT6328 Audio L PGA 0 dB gain */
            }

            Ana_Set_Reg(AUDENC_ANA_CON4, 0x0000, 0xffff);   /*  */
            Ana_Set_Reg(AUDENC_ANA_CON6, 0x2020, 0xffff);   /*  */

            if (mCodec_data->mAudio_Ana_Mux[AUDIO_MICSOURCE_MUX_IN_1] == 0) {
                /* "ADC1", main_mic */
                /* Ana_Set_Reg(AUDENC_ANA_CON9, (MicbiasRef|0x0000), 0xff09);
                //disable MICBIAS0, restore to micbias set by accdet */
                Ana_Set_Reg(AUDENC_ANA_CON9, (MicbiasRef | 0x0000), 0xff19);
                /* disable MICBIAS0 and MICBIAS1, restore to micbias set by accdet */
            } else if (mCodec_data->mAudio_Ana_Mux[AUDIO_MICSOURCE_MUX_IN_1] == 1) {
                /* "ADC2", headset mic */
                Ana_Set_Reg(AUDENC_ANA_CON9, (MicbiasRef | 0x0000), 0xff90);
                /* disable MICBIAS1, restore to micbias set by accdet */
            }
        } else if (ADCType == AUDIO_ANALOG_DEVICE_IN_ADC2) {    /* ref mic */
            if (refmic_using_ADC_L == false) {
                Ana_Set_Reg(AUDENC_ANA_CON1, 0x00C1, 0xffff);
                /* Audio R ADC input sel : off, disable audio R ADC */
                Ana_Set_Reg(AUDENC_ANA_CON3, 0x0000, 0xffff);
                /* PGA stb enhance off */
                Ana_Set_Reg(AUDENC_ANA_CON10, 0x0000, 0x00ff);
                /* Audio R PGA 0 dB gain //MT6328 */
                Ana_Set_Reg(AUDENC_ANA_CON1, 0x0000, 0xffff);
                /* Audio R preamplifier input sel : off, disable audio R PGA */
            } else {
                Ana_Set_Reg(AUDENC_ANA_CON0, 0x00c1, 0xffff);
                /* Audio L ADC input sel : off, disable audio L ADC */
                Ana_Set_Reg(AUDENC_ANA_CON3, 0x0000, 0xffff);
                /* PGA stb enhance off */
                Ana_Set_Reg(AUDENC_ANA_CON10, 0x0000, 0x000f);
                /* Audio L PGA 0 dB gain */
                Ana_Set_Reg(AUDENC_ANA_CON0, 0x0000, 0xffff);
                /* Audio L preamplifier input sel : off, disable audio L PGA */
            }
            Ana_Set_Reg(AUDENC_ANA_CON4, 0x0000, 0xffff);   /*  */
            Ana_Set_Reg(AUDENC_ANA_CON6, 0x2020, 0xffff);   /*  */

            /* Ana_Set_Reg(AUDENC_ANA_CON9, (MicbiasRef|0x0000), 0xff09);
            //disable MICBIAS0, restore to micbias set by accdet */
            Ana_Set_Reg(AUDENC_ANA_CON9, (MicbiasRef | 0x0000), 0xff19);
            /* disable MICBIAS0 and MICBIAS1, restore to micbias set by accdet */
        }
        if (GetAdcStatus() == false) {
            Ana_Set_Reg(AUDDEC_ANA_CON7, 0x0000, 0x0006);
            /* LCLDO_ENC remote sense off */
            Ana_Set_Reg(AUDDEC_ANA_CON6, 0x0004, 0x0104);
            /* disable LCLDO_ENC 1P8V */

            Ana_Set_Reg(AUDENC_ANA_CON3, 0x0000, 0xffff);
            /* disable ADC CLK from CLKGEN (13MHz) */
            Ana_Set_Reg(AUDDEC_ANA_CON6, 0x0000, 0x0104);
            /* disable audio ADC CLKGEN */

            if (GetDLStatus() == false) {
                Ana_Set_Reg(AFE_UL_DL_CON0, 0x0000, 0xffff);
                /* afe disable */
                Ana_Set_Reg(AFE_AUDIO_TOP_CON0, 0x0084, 0x0084);
                /* afe power down and total audio clk disable */
            }

            /* AdcClockEnable(false); */
            Topck_Enable(false);
            /* ClsqAuxEnable(false); */
            ClsqEnable(false);
            NvregEnable(false);
            audckbufEnable(false);
        }
        GetMicbias = 0;
    }
    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
  • 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
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 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
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287

下面设置 
SOC_ENUM_EXT(“Audio_Preamp1_Switch”, Audio_UL_Enum[4], Audio_PreAmp1_Get, 
Audio_PreAmp1_Set), 
SOC_ENUM_EXT(“Audio_Preamp2_Switch”, Audio_UL_Enum[23], Audio_PreAmp2_Get, 
Audio_PreAmp2_Set),

//AudioPreAmp1_Sel Mul_Sel = 1
static int Audio_PreAmp1_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    pr_warn("%s()\n", __func__);

    if (ucontrol->value.enumerated.item[0] > ARRAY_SIZE(PreAmp_Mux_function)) {
        pr_err("return -EINVAL\n");
        return -EINVAL;
    }
    mCodec_data->mAudio_Ana_Mux[AUDIO_ANALOG_MUX_IN_PREAMP_1] =
        ucontrol->value.integer.value[0];
    AudioPreAmp1_Sel(mCodec_data->mAudio_Ana_Mux[AUDIO_ANALOG_MUX_IN_PREAMP_1]);
    pr_warn("%s() done\n", __func__);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
static bool AudioPreAmp1_Sel(int Mul_Sel)
{
    pr_warn("%s Mul_Sel = %d ", __func__, Mul_Sel);
    if (Mul_Sel == 0)
        Ana_Set_Reg(AUDENC_ANA_CON0, 0x0000, 0x00C0);   /* pinumx open */
    else if (Mul_Sel == 1)
        Ana_Set_Reg(AUDENC_ANA_CON0, 0x0040, 0x00C0);   /* AIN0 */
    else if (Mul_Sel == 2)
        Ana_Set_Reg(AUDENC_ANA_CON0, 0x0080, 0x00C0);   /* AIN1 */
    else if (Mul_Sel == 3)
        Ana_Set_Reg(AUDENC_ANA_CON0, 0x00C0, 0x00C0);   /* AIN2 */
    else
        pr_warn("AudioPreAmp1_Sel warning");

    return true;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
//AudioPreAmp2_Sel Mul_Sel = 1
static int Audio_PreAmp2_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    pr_warn("%s()\n", __func__);

    if (ucontrol->value.enumerated.item[0] > ARRAY_SIZE(PreAmp_Mux_function)) {
        pr_err("return -EINVAL\n");
        return -EINVAL;
    }
    mCodec_data->mAudio_Ana_Mux[AUDIO_ANALOG_MUX_IN_PREAMP_2] =
        ucontrol->value.integer.value[0];
    AudioPreAmp2_Sel(mCodec_data->mAudio_Ana_Mux[AUDIO_ANALOG_MUX_IN_PREAMP_2]);
    pr_warn("%s() done\n", __func__);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
static bool AudioPreAmp2_Sel(int Mul_Sel)
{
    pr_warn("%s Mul_Sel = %d ", __func__, Mul_Sel);

    if (Mul_Sel == 0)
        Ana_Set_Reg(AUDENC_ANA_CON1, 0x0000, 0x00C0);   /* pinumx open */
    else if (Mul_Sel == 1)
        Ana_Set_Reg(AUDENC_ANA_CON1, 0x0040, 0x00C0);   /* AIN0 */
    else if (Mul_Sel == 2)
        Ana_Set_Reg(AUDENC_ANA_CON1, 0x0080, 0x00C0);   /* AIN1 */
    else if (Mul_Sel == 3)
        Ana_Set_Reg(AUDENC_ANA_CON1, 0x00C0, 0x00C0);   /* AIN2 */
    else
        pr_warn("AudioPreAmp1_Sel warning");

    return true;
}
  • 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

到此MIC录音准备工作已经完成,后面就是录音。

下面看下播放录音

设置Audio_AmpR_Set()

SOC_ENUM_EXT(“Audio_Amp_R_Switch”, Audio_DL_Enum[0], Audio_AmpR_Get, Audio_AmpR_Set),

static int Audio_AmpR_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    mutex_lock(&Ana_Ctrl_Mutex);

    pr_warn("%s()\n", __func__);
    if ((ucontrol->value.integer.value[0] == true)
        && (mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_OUT_HEADSETR] == false)) {
        Audio_Amp_Change(AUDIO_ANALOG_CHANNELS_RIGHT1, true);
        mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_OUT_HEADSETR] =
            ucontrol->value.integer.value[0];
    } else if ((ucontrol->value.integer.value[0] == false)
           && (mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_OUT_HEADSETR] ==
               true)) {
        mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_OUT_HEADSETR] =
            ucontrol->value.integer.value[0];
        Audio_Amp_Change(AUDIO_ANALOG_CHANNELS_RIGHT1, false);
    }
    mutex_unlock(&Ana_Ctrl_Mutex);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

static void Audio_Amp_Change(int channels, bool enable)
{
    if (enable) {
        if (GetDLStatus() == false)
            TurnOnDacPower();

        /* here pmic analog control */
        if (mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_OUT_HEADSETL] == false
            && mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_OUT_HEADSETR] ==
            false) {
            pr_warn("%s\n", __func__);

            /* upmu_set_rg_vio18_cal(1);// for MT6328 E1 VIO18 patch only */
            /* set analog part (HP playback) */
            Ana_Set_Reg(AUDNCP_CLKDIV_CON1, 0x0001, 0xffff);
            /* Turn on DA_600K_NCP_VA18 */
            Ana_Set_Reg(AUDNCP_CLKDIV_CON2, 0x002B, 0xffff);
            /* Set NCP clock as 604kHz // 26MHz/43 = 604KHz */
            Ana_Set_Reg(AUDNCP_CLKDIV_CON0, 0x0001, 0xffff);
            /* Toggle RG_DIVCKS_CHG */
            Ana_Set_Reg(AUDNCP_CLKDIV_CON4, 0x0000, 0xffff);
            /* Set NCP soft start mode as default mode */
            Ana_Set_Reg(AUDNCP_CLKDIV_CON3, 0x0000, 0xffff);
            /* Enable NCP */
            Ana_Set_Reg(AUDDEC_ANA_CON6, 0x0A41, 0xfeeb);
            /* Enable cap-less HC LDO (1.5V) & LDO VA33REFGEN */
            Ana_Set_Reg(AUDDEC_ANA_CON6, 0x2AC1, 0xfeeb);
            /* Enable cap-less LC LDO (1.5V) */
            Ana_Set_Reg(AUDDEC_ANA_CON7, 0x8000, 0x8000);
            /* Enable NV regulator (-1.5V) */
            Ana_Set_Reg(ZCD_CON0, 0x0000, 0xffff);
            /* Disable AUD_ZCD */
            Ana_Set_Reg(AUDDEC_ANA_CON0, 0xE080, 0xffff);
            /* Disable headphone, voice and short-ckt protection. HP MUX is opened, voice MUX is set mute */
            Ana_Set_Reg(AUDDEC_ANA_CON6, 0x2AC0, 0xfeeb);
            /* Enable IBIST */
            Ana_Set_Reg(AUDDEC_ANA_CON4, 0x0700, 0xffff);
            /* Enable HP & HS drivers bias circuit */
            Ana_Set_Reg(AUDDEC_ANA_CON5, 0x5490, 0xffff);
            /* HP/HS ibias & DR bias current optimization */
            udelay(50);
            Ana_Set_Reg(ZCD_CON2, 0x0F9F, 0xffff);
            /* Set HPR/HPL gain as minimum (~ -40dB) */
            Ana_Set_Reg(ZCD_CON3, 0x001F, 0xffff);
            /* Set voice gain as minimum (~ -40dB) */
            Ana_Set_Reg(AUDDEC_ANA_CON1, 0x0480, 0xffff);
            /* De_OSC of HP and enable output STBENH */
            Ana_Set_Reg(AUDDEC_ANA_CON1, 0x1480, 0xffff);
            /* De_OSC of voice, enable output STBENH */
            Ana_Set_Reg(AUDDEC_ANA_CON0, 0xE090, 0xffff);
            /* Enable voice driver */
            Ana_Set_Reg(AUDDEC_ANA_CON1, 0x14A0, 0xffff);
            /* Enable pre-charge buffer */
            udelay(50);
            Ana_Set_Reg(AUDDEC_ANA_CON6, 0x2AC2, 0xfeeb);
            /* Enable AUD_CLK */
            Ana_Set_Reg(AUDDEC_ANA_CON0, 0xE09F, 0xffff);
            /* Enable Audio DAC */

            /* Apply digital DC compensation value to DAC */
            Ana_Set_Reg(ZCD_CON2, 0x0489, 0xffff);
            /* Set HPR/HPL gain to -1dB, step by step */
            SetDcCompenSation();
            udelay(100);
            Ana_Set_Reg(AUDDEC_ANA_CON0, 0xF49F, 0xffff);
            /* Switch HP MUX to audio DAC */
            /* here may cause pop */
            /* msleep(1); //6752 removed */
            Ana_Set_Reg(AUDDEC_ANA_CON0, 0xF4FF, 0xffff);
            /* Enable HPR/HPL */
            udelay(50);
            Ana_Set_Reg(AUDDEC_ANA_CON1, 0x1480, 0xffff);
            /* Disable pre-charge buffer */
            Ana_Set_Reg(AUDDEC_ANA_CON1, 0x0480, 0xffff);
            /* Disable De_OSC of voice */
            /* Ana_Set_Reg(AUDDEC_ANA_CON0, 0xF46F, 0xffff); //Disable voice buffer & Open HS input MUX */
            Ana_Set_Reg(AUDDEC_ANA_CON0, 0xF46F, 0xffff);
            /* Disable voice buffer & Open HS input MUX  //MT6328 George table error */

            Ana_Set_Reg(AUDDEC_ANA_CON4, 0x0300, 0xffff);
            /* Disable HS drivers bias circuit */

            /* apply volume setting */
            HeadsetVoloumeSet();
        }

    } else {
        if (mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_OUT_HEADSETL] == false
            && mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_OUT_HEADSETR] ==
            false) {
            pr_warn("Audio_Amp_Change off amp\n");
            HeadsetVoloumeRestore();    /* Set HPR/HPL gain as -1dB, step by step */
            Ana_Set_Reg(ZCD_CON2, 0x0F9F, 0xffff); /* Set HPR/HPL gain as minimum (~ -40dB) */
            Ana_Set_Reg(AUDDEC_ANA_CON0, 0xF40F, 0xffff);   /* Disable HPR/HPL */
        }

        if (GetDLStatus() == false) {
            Ana_Set_Reg(AUDDEC_ANA_CON4, 0x0000, 0xffff);
            /* Disable drivers bias circuit */
            Ana_Set_Reg(AUDDEC_ANA_CON0, 0x0000, 0xffff);
            /* Disable Audio DAC */
            Ana_Set_Reg(AUDDEC_ANA_CON6, 0x2AC0, 0xfeeb);
            /* Disable AUD_CLK, bit2/4/8 is for ADC, do not set */
            Ana_Set_Reg(AUDDEC_ANA_CON7, 0x0000, 0x8000);
            /* Disable NV regulator (-1.5V) */
            /*Ana_Set_Reg(AUDDEC_ANA_CON6, 0x0001, 0xfeeb);*/
            Ana_Set_Reg(AUDDEC_ANA_CON6, 0x02c1, 0xfeeb); /* for AUX detection */
            /* Disable cap-less LDOs (1.5V) & Disable IBIST */
            TurnOffDacPower();
        }
        EnableDcCompensation(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
  • 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
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 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
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
static void HeadsetVoloumeSet(void)
{
    int index = 0, oldindex = 0, offset = 0, count = 1;

    index = mCodec_data->mAudio_Ana_Volume[AUDIO_ANALOG_VOLUME_HPOUTR];
    oldindex = 8;
    if (index > oldindex) {
        pr_warn("%s index = %d oldindex = %d\n", __func__ , index, oldindex);
        offset = index - oldindex;
        while (offset > 0) {
            Ana_Set_Reg(ZCD_CON2, ((oldindex + count) << 7) | (oldindex + count),
                    0xf9f);
            offset--;
            count++;
            udelay(200);
        }
    } else {
        pr_warn("%s index = %d oldindex = %d\n", __func__ , index, oldindex);
        offset = oldindex - index;
        while (offset > 0) {
            Ana_Set_Reg(ZCD_CON2, ((oldindex - count) << 7) | (oldindex - count),
                    0xf9f);
            offset--;
            count++;
            udelay(200);
        }
    }
    Ana_Set_Reg(ZCD_CON2, (index << 7) | (index), 0xf9f);
}
  • 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
  • 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

下面设置Audio_AmpL_Set 
SOC_ENUM_EXT(“Audio_Amp_L_Switch”, Audio_DL_Enum[1], Audio_AmpL_Get, Audio_AmpL_Set),

static int Audio_AmpL_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    mutex_lock(&Ana_Ctrl_Mutex);

    pr_warn("%s() gain = %ld\n ", __func__, ucontrol->value.integer.value[0]);
    if ((ucontrol->value.integer.value[0] == true)
        && (mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_OUT_HEADSETL] == false)) {
        Audio_Amp_Change(AUDIO_ANALOG_CHANNELS_LEFT1, true);
        mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_OUT_HEADSETL] =
            ucontrol->value.integer.value[0];
    } else if ((ucontrol->value.integer.value[0] == false)
           && (mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_OUT_HEADSETL] ==
               true)) {
        mCodec_data->mAudio_Ana_DevicePower[AUDIO_ANALOG_DEVICE_OUT_HEADSETL] =
            ucontrol->value.integer.value[0];
        Audio_Amp_Change(AUDIO_ANALOG_CHANNELS_LEFT1, false);
    }
    mutex_unlock(&Ana_Ctrl_Mutex);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

mtklog:

01-02 06:11:00.406964  5247  5247 W [15525.148408]: (1)[5247:AudioIn_1E][name:mt_soc_codec_63xx&]Audio_Mic1_Mode_Select_Set()
01-02 06:11:00.406989  5247  5247 W [15525.148433]: (1)[5247:AudioIn_1E][name:mt_soc_codec_63xx&]Audio_Mic1_Mode_Select_Set() mAudio_Analog_Mic1_mode = 0
01-02 06:11:00.407547  5247  5247 W [15525.148991]: (1)[5247:AudioIn_1E][name:mt_soc_codec_63xx&]Audio_Mic2_Mode_Select_Set()
01-02 06:11:00.407572  5247  5247 W [15525.149016]: (1)[5247:AudioIn_1E][name:mt_soc_codec_63xx&]Audio_Mic2_Mode_Select_Set() mAudio_Analog_Mic2_mode = 0
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

从mAudio_Analog_Mic1_mode和mAudio_Analog_Mic2_mode值可判断mic使用的模式,0:ACC 1:DCC 2:DMIC 3:DCCECMDIFF 4:DCCECMSINGLE

Audio_ADC1_Set()
//ADCType代表打开电源类型  enable :1:打开电源 0:关闭电源
TurnOnADcPowerACC ADCType = 13 enable = 1, refmic_using_ADC_L=0
MicbiasRef=0x700
TurnOnADcPowerACC  AUDIO_ANALOG_DEVICE_IN_ADC1 mux =0
SetDCcoupleNP MicBias= 0 mode = 0
SetMicPGAGain  AUDIO_ANALOG_VOLUME_MICAMP1 index =3
Audio_ADC2_Set()
TurnOnADcPowerACC ADCType = 14 enable = 1, refmic_using_ADC_L=0
TurnOnADcPowerACC  AUDIO_ANALOG_DEVICE_IN_ADC2 refmic_using_ADC_L =0
SetDCcoupleNP MicBias= 0 mode = 0
SetDCcoupleNP MicBias= 1 mode = 0
SetMicPGAGain  AUDIO_ANALOG_VOLUME_MICAMP1 index =3
//mux值: 0:main mic  1:headset mic
//AUDIO_ANALOG_DEVICE_IN_ADC1 main mic和 headset mic
//AUDIO_ANALOG_DEVICE_IN_ADC2 ref mic
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
Audio_PreAmp1_Set()
AudioPreAmp1_Sel Mul_Sel = 1
Audio_PreAmp1_Set() done
Audio_PreAmp2_Set()
AudioPreAmp2_Sel Mul_Sel = 1
Audio_PreAmp2_Set() done
Mul_Sel值:  0:pinumx open  1:AIN0  2:AIN2  3:AIN3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Audio_AmpR_Set() 
TurnOnDacPower 
Audio_Amp_Change 
SetHprOffsetTrim mHprTrimOffset = 2043 TrimOffset = 2048 
SetHpLOffsetTrim mHprTrimOffset = 2045 TrimOffset = 2048 
HeadsetVoloumeSet index = 7 oldindex = 8 
Audio_AmpL_Set() gain = 1 //gain为1代表播放 gain为0代表关闭 
Ext_Speaker_Amp_Change ON+ 
Sgm3718_Switch_Off enter 
Sgm3718_Switch_Off out 
Ext_Speaker_Amp_Change AW87318_AW87319_Switch_Audio_OFF- 
Sgm3718_Switch_On enter 
Ext_Speaker_Amp_Change AW87318_AW87319_Switch_Audio_Speaker 
Ext_Speaker_Amp_Change ON-

时间: 2024-10-06 03:21:18

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

Android 4.1 Audio系统变化说明

转自Android 4.1 Audio系统变化说明 Android 4.1,英文代号简称JB.在国人眼里,JB这个词还和动物有点关系.Google如此频繁修改Android,终于推出了一个可以被大家整天JB JB挂在嘴上的版本.以后我的文章也可以一面用JB表示版本号,一面用JB表示毛主席常说的"战略上的鄙视了".请大家根据上下文揣摩我写下JB一词的心情. 今天将稍深入得介绍一下JB 4.1在Audio系统做的翻天覆地的改动.这里先啰嗦几句:就像80后经常抱怨自己晚生了几年一样,马上就会

HTML5+ 手机端录音和播放录音

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>录音播放</title> <script type=&quo

Linux根文件皇冠体育平台开发系统:/etc/init.d/rcS文件分析

rcS文件的作用皇冠体育平台开发论坛:haozbbs.com Q1446595067 rcS是一个脚本文件,在inittab文件中本解析调用,用于配置Linux系统.2.rcS文件分析 #! /bin/sh #指定系统使用的shell PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin: #初始化环境变量PATH,操作系统执行程序默认到PATH指定的目录下寻找该程序 runlevel=S #设置系统运行级别为S,即单用户模式,只有一个控制台终端,供

Linux嵌入式驱动学习之路⑤u-boot启动流程分析

这里说的u-boot启动流程,值得是从上电开机执行u-boot,到u-boot,到u-boot加载操作系统的过程.这一过程可以分为两个过程,各个阶段的功能如下. 第一阶段的功能: 硬件设备初始化. 加载u-boot第二阶段代码到RAM空间. 设置好栈. 跳转到第二阶段代码入口. 第二阶段的功能: 初始化本阶段使用的硬件设备. 检查系统内存映射. 将内核从Flash读取到RAM中. 为内核设置启动参数. 调用内核. u-boot启动第一阶段流程 根据连接器脚本 board/samsung/$(BO

uboot学习之uboot-spl的程序流程分析

uboot-spl的程序流程主要包含下面的几个函数: _start->reset->save_boot_params->cpu_init_crit->lowlevel_init->_main->board_init_f 在armv7架构的uboot-spl,主要需要做如下事情 关闭中断,svc模式 禁用MMU.TLB 芯片级.板级的一些初始化操作  IO初始化 时钟 内存 选项,串口初始化 选项,nand flash初始化 其他额外的操作 加载BL2,跳转到BL2 下面

Android -- Audio Native服务之启动流程分析(一)

Android -- Audio Native服务之启动流程分析(一) Android中的Audio系统是比较庞大.繁杂的一部分内容, 其中会涉及较多的音频编解码.多媒体制式与Android Audio HAL设备管理的知识.随着Android的发展,其所支持的音频设备也变得越来丰富,如扬声器.耳机.听筒等等:这种变化也为Android管理如此丰富的音频设备以及如何正确.合理地切换音频输出提出了更高的要求.面对如此繁杂的管理要求,我们分析Android Audio服务的历程想必也不会轻松.接下来

[深入理解Android卷一全文-第七章]深入理解Audio系统

由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该由于纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容. 第7章  深入理解Audio系统 本章主要内容 ·  具体分析AudioTrack. ·  具体分析AudioFlinger. ·  具体分析AudioPolicyService. 本章涉及的源代码文件名称及位置 以下是本章分析的源代码文件名称及其位置. ·  AudioTrack.java framewor

针对Android平台我们需要学习如何在Unity中调用Android的JAVA代码。

Unity for Android 比较特殊,Unity for IOS 打包是将XCODE工程直接交给开发者,开发者可以在工程的基础上继续添加新的视图,最后由开发者自行打包生成IPA包,发布程序.而Unity for Android打包直接生成APK包,等于说源代码开发者是看不到的,但是Unity的自身确实有些局限,针对Android平台我们需要学习如何在Unity中调用Android的JAVA代码.本章我们的目标是使用Unity的脚本打开Activity.首先我们创建一个普通的Android

android 系统学习资料

android系统学习资料见以下网址,希望对大家有点帮助! http://cache.baiducontent.com/c?m=9d78d513d9901df918b0cf281a17a771682097133bc0a16368a4925f92144c30437197bd30521413a0b16b6671b83957fd844065470237c6eadf893acacd943f5f8e3045700bf13105d269b8bb4332b724872b9eb86de3aeb772cda188