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-
MT6737 Android N 平台 Audio系统学习----录音到播放录音流程分析的更多相关文章
- Java生鲜电商平台-生鲜系统中微服务架构设计与分析实战
Java生鲜电商平台-生鲜系统中微服务架构设计与分析实战 说明: Java生鲜系统中微服务的拆分应该如何架构设计与分析呢?以下是我的实战中的设计与经验分析. 目录 1. 微服务简介2. 当前现状3. ...
- C# 录音和播放录音-NAudio
在使用C#进行录音和播放录音功能上,使用NAudio是个不错的选择. NAudio是个开源,相对功能比较全面的类库,它包含录音.播放录音.格式转换.混音调整等操作,具体可以去Github上看看介绍和源 ...
- [Android] 录音与播放录音实现
http://blog.csdn.net/cxf7394373/article/details/8313980 android开发文档中有一个关于录音的类MediaRecord,一张图介绍了基本的流程 ...
- Android 12(S) 图像显示系统 - HWC HAL 初始化与调用流程
必读: Android 12(S) 图像显示系统 - 开篇 接口定义 源码位置:/hardware/interfaces/graphics/composer/ 在源码目录下可以看到4个版本的HIDL ...
- Android系统开发--灯光系统之电池灯的流程分析
Android系统开发--Android灯光系统之电池灯的流程分析 前期系统准备 运行初始化,创建系统服务 创建电池服务,获得电池灯;创建监听者监听上报电池事件: mSystemServiceMana ...
- uboot学习之uboot-spl的程序流程分析
uboot-spl的程序流程主要包含下面的几个函数: _start->reset->save_boot_params->cpu_init_crit->lowlevel_init ...
- Android之 MTP框架和流程分析
概要 本文的目的是介绍Android系统中MTP的一些相关知识.主要的内容包括:第1部分 MTP简介 对Mtp协议进行简单的介绍.第2部分 MTP框架 介绍 ...
- C# NAudio录音和播放音频文件-实时绘制音频波形图(从音频流数据获取,而非设备获取)
NAudio的录音和播放录音都有对应的类,我在使用Wav格式进行录音和播放录音时使用的类时WaveIn和WaveOut,这两个类是对功能的回调和一些事件触发. 在WaveIn和WaveOut之外还有对 ...
- AVFoundation之录音及播放
录音 在开始录音前,要把会话方式设置成AVAudioSessionCategoryPlayAndRecord //设置为播放和录音状态,以便可以在录制完之后播放录音 AVAudioSession *s ...
随机推荐
- POJ 3171 区间覆盖最小值&&线段树优化dp
Cleaning Shifts Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4715 Accepted: 1590 D ...
- netcore3.0 webapi集成Swagger 5.0
在项目中引用Swashbuckle.AspNetCore和Swashbuckle.AspNetCore.Filters两个dll,在Startup中的ConfigureServices相关配置代码如下 ...
- 洛谷——P2386 放苹果
P2386 放苹果 题目背景 (poj1664) 题目描述 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分发(5,1,1和1,1,5是同一种方法) 输入输出格式 输入 ...
- iOS应用崩溃日志揭秘
这篇文章还可以在这里找到 英语 Learn how to make sense of crash logs! 本文作者是 Soheil Moayedi Azarpour, 他是一名独立iOS开发者. ...
- git 使用及常用命令
git在团队项目中的使用流程 1.首先从一个git远程仓库中clone项目到本地 ? 1 git clone 仓库地址 2.创建开发分支 一般我们写代码不会在master分支上面写,而是新建一个分支 ...
- SSH 原理和公匙私匙
先主要介绍了Telnet.SSH 的通信原理,分析了其通信时的工作流程. Telnet 无论Telnet协议连接的是什么类型终端,都会转换为NVT(Net Virtual Terminal)格式进行通 ...
- 查找——图文翔解SkipList(跳跃表)
跳跃表 跳跃列表(也称跳表)是一种随机化数据结构,基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作须要O(logn)平均时间). 基本上.跳跃列表是对有序的链表添加上附加的前进链接,添加是以随 ...
- vs升级c++项目遇到的一些问题
1.error C1189: #error : This file requires _WIN32_WINNT to be #defined at least to 0x0403. Value 0x ...
- 3D打印技术之切片引擎(4)
[此系列文章基于熔融沉积( fused depostion modeling, FDM )成形工艺] 这一篇文章我讲一下多边打印的问题,多边打印是切片引擎的一项关键的技术. 图1 双边打印 首先.它能 ...
- swich-----case语句的用法
转: http://xinzhi.wenda.so.com/a/1517927252619839