Beispiel #1
0
static int mtk_pcm_dl1_stop(struct snd_pcm_substream *substream)
{

    AFE_BLOCK_T *Afe_Block = &(pMemControl->rBlock);
    PRINTK_AUDDRV("mtk_pcm_dl1_stop \n");

    printk("%s \n", __func__);
    SetIrqEnable(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE, false);

    // here to turn off digital part
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I05, Soc_Aud_InterConnectionOutput_O03);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I06, Soc_Aud_InterConnectionOutput_O04);
    SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DL1, false);

    SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, false);
    if (GetI2SDacEnable() == false)
    {
        SetI2SDacEnable(false);
    }
    EnableAfe(false);
    RemoveMemifSubStream(Soc_Aud_Digital_Block_MEM_DL1,substream);
    AudDrv_Clk_Off();

    return 0;
}
static void StopAudioAWBHardware(struct snd_pcm_substream *substream)
{
    printk("StopAudioAWBHardware \n");

    SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_AWB, false);

    // here to set interrupt
    SetIrqEnable(Soc_Aud_IRQ_MCU_MODE_IRQ2_MCU_MODE, false);

    if (GetI2SDacEnable() == false)
    {
        SetI2SDacEnable(false);
    }

    // here to turn off digital part
#if 0 // TODO(Harvey)
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I15, Soc_Aud_InterConnectionOutput_O05);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I16, Soc_Aud_InterConnectionOutput_O06);
#else
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I00, Soc_Aud_InterConnectionOutput_O05);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I01, Soc_Aud_InterConnectionOutput_O06);
#endif

    EnableAfe(false);
}
static int mtk_soc_pcm_dl2_close(struct snd_pcm_substream *substream)
{
	pr_warn("%s\n", __func__);

	if (mPrepareDone == true) {
		/* stop DAC output */
		SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, false);
		if (GetI2SDacEnable() == false)
			SetI2SDacEnable(false);

		RemoveMemifSubStream(Soc_Aud_Digital_Block_MEM_DL2, substream);

		EnableAfe(false);
		mPrepareDone = false;
	}

	if (mPlaybackSramState == SRAM_STATE_PLAYBACKDRAM)
		AudDrv_Emi_Clk_Off();

	AfeControlSramLock();
	ClearSramState(mPlaybackSramState);
	mPlaybackSramState = GetSramState();
	AfeControlSramUnLock();
	AudDrv_Clk_Off();
	return 0;
}
static int mtk_pcm_fm_i2s_close(struct snd_pcm_substream *substream)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    printk("%s rate = %d\n", __func__, runtime->rate);

    //mtk_wcn_cmb_stub_audio_ctrl((CMB_STUB_AIF_X)CMB_STUB_AIF_0);//temp mark for early porting

    SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_2, false);
    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_2) == false)
    {
        SetI2SASRCEnable(false);
        SetI2SASRCConfig(false, 0); // Setting to bypass ASRC
        Set2ndI2SInEnable(false);
    }

    SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, false);
    if (GetI2SDacEnable() == false)
    {
        SetI2SDacEnable(false);
    }

    // interconnection setting
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I00, Soc_Aud_InterConnectionOutput_O13);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I01, Soc_Aud_InterConnectionOutput_O14);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I10, Soc_Aud_InterConnectionOutput_O03);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I11, Soc_Aud_InterConnectionOutput_O04);


    EnableAfe(false);

    AudDrv_I2S_Clk_Off();
    AudDrv_Clk_Off();
    mPrepareDone = false;
    return 0;
}
static int mtk_voice_close(struct snd_pcm_substream *substream)
{
    printk("mtk_voice_close \n");

    if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
    {
        printk("%s  with SNDRV_PCM_STREAM_CAPTURE \n", __func__);
        AudDrv_Clk_Off();
        AudDrv_ADC_Clk_Off();
        return 0;
    }

    //  todo : enable sidetone
    // here start digital part
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I03, Soc_Aud_InterConnectionOutput_O17);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I04, Soc_Aud_InterConnectionOutput_O18);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O03);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O04);

    SetI2SAdcEnable(false);
    SetI2SDacEnable(false);
    SetModemPcmEnable(MODEM_1, false);
    SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, false);
    SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC, false);

    EnableAfe(false);
    AudDrv_Clk_Off();
    AudDrv_ADC_Clk_Off();

    Voice_Status = false;

    return 0;
}
static int mtk_pcm_mrgrx_close(struct snd_pcm_substream *substream)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    printk("%s \n", __func__);

    mtk_wcn_cmb_stub_audio_ctrl((CMB_STUB_AIF_X)CMB_STUB_AIF_0);

    SetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT, false);
    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT) == false)
    {
        SetMrgI2SEnable(false, runtime->rate);
    }

    SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, false);
    if (GetI2SDacEnable() == false)
    {
        SetI2SDacEnable(false);
    }

    // interconnection setting
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I15, Soc_Aud_InterConnectionOutput_O13);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I16, Soc_Aud_InterConnectionOutput_O14);

    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I10, Soc_Aud_InterConnectionOutput_O03);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I11, Soc_Aud_InterConnectionOutput_O04);


    EnableAfe(false);

    AudDrv_Clk_Off();
    mPrepareDone = false;
    return 0;
}
static int mtk_voice1_extint_prepare(struct snd_pcm_substream *substream)
{
    struct snd_pcm_runtime *runtimeStream = substream->runtime;
    printk("%s rate = %d  channels = %d period_size = %lu\n", __func__,
           runtimeStream->rate, runtimeStream->channels, runtimeStream->period_size);

    if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
    {
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O03);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O04);
        // start I2S DAC out
        SetI2SDacOut(substream->runtime->rate);
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
        SetI2SDacEnable(true);
        EnableAfe(true);
        printk("%s  with SNDRV_PCM_STREAM_PLAYBACK \n",__func__);
    }
    else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
    {
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I03, Soc_Aud_InterConnectionOutput_O17);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I04, Soc_Aud_InterConnectionOutput_O18);
        ConfigAdcI2S(substream);
        SetI2SAdcIn(&mAudioDigitalI2S);
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC, true);
        SetI2SAdcEnable(true);
        EnableAfe(true);
        printk("%s  with SNDRV_PCM_STREAM_CAPTURE \n",__func__);
    }
    // here start digital part

    if(Voice_ExtInt_Status == 0)
    {
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I21, Soc_Aud_InterConnectionOutput_O07);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I21, Soc_Aud_InterConnectionOutput_O08);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I09, Soc_Aud_InterConnectionOutput_O25);
        VoiceExtIntPcm_Ext.mPcmModeWidebandSel = (runtimeStream->rate == 8000) ? Soc_Aud_PCM_MODE_PCM_MODE_8K : Soc_Aud_PCM_MODE_PCM_MODE_16K;
        VoiceExtIntPcm_Int.mPcmModeWidebandSel = (runtimeStream->rate == 8000) ? Soc_Aud_PCM_MODE_PCM_MODE_8K : Soc_Aud_PCM_MODE_PCM_MODE_16K;
        //VoiceExtPcm.mAsyncFifoSel = Soc_Aud_BYPASS_SRC_SLAVE_USE_ASYNC_FIFO;
        SetModemPcmConfig(MODEM_EXTERNAL, VoiceExtIntPcm_Ext);
        SetModemPcmEnable(MODEM_EXTERNAL, true);
        SetModemPcmConfig(MODEM_1, VoiceExtIntPcm_Int);
        SetModemPcmEnable(MODEM_1, true);
    }
    if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
    {
        Voice_ExtInt_Status |= VOICE_DL_ON;
    }
    else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
    {
        Voice_ExtInt_Status |= VOICE_UL_ON;
    }
    SetExternalModemStatus(true);
    return 0;
}
static int mtk_pcm_dl2_prepare(struct snd_pcm_substream *substream)
{
	bool mI2SWLen = Soc_Aud_I2S_WLEN_WLEN_16BITS;
	struct snd_pcm_runtime *runtime = substream->runtime;

	if (mPrepareDone == false) {
		pr_warn
		    ("%s format = %d SNDRV_PCM_FORMAT_S32_LE = %d SNDRV_PCM_FORMAT_U32_LE = %d\n",
		     __func__, runtime->format, SNDRV_PCM_FORMAT_S32_LE, SNDRV_PCM_FORMAT_U32_LE);
		SetMemifSubStream(Soc_Aud_Digital_Block_MEM_DL2, substream);

		if (runtime->format == SNDRV_PCM_FORMAT_S32_LE ||
		    runtime->format == SNDRV_PCM_FORMAT_U32_LE) {
			/* not support 24bit +++ */
			SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL2,
						     AFE_WLEN_32_BIT_ALIGN_8BIT_0_24BIT_DATA);
			SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT,
						  Soc_Aud_InterConnectionOutput_O03);
			SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT,
						  Soc_Aud_InterConnectionOutput_O04);
			/* not support 24bit --- */
			mI2SWLen = Soc_Aud_I2S_WLEN_WLEN_32BITS;
		} else {
			/* not support 24bit +++ */
			SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL2,
						     AFE_WLEN_16_BIT);
			SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT,
						  Soc_Aud_InterConnectionOutput_O03);
			SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT,
						  Soc_Aud_InterConnectionOutput_O04);
			/* not support 24bit --- */
			mI2SWLen = Soc_Aud_I2S_WLEN_WLEN_16BITS;
		}

		SetSampleRate(Soc_Aud_Digital_Block_MEM_I2S, runtime->rate);

		/* start I2S DAC out */
		if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC) == false) {
			SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
			SetI2SDacOut(substream->runtime->rate, false, mI2SWLen);
			SetI2SDacEnable(true);
		} else {
			SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
		}
		/* here to set interrupt_distributor */
		SetIrqMcuCounter(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE, runtime->period_size);
		SetIrqMcuSampleRate(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE, runtime->rate);

		EnableAfe(true);
		mPrepareDone = true;
	}
	return 0;
}
static int mtk_pcm_I2S0dl1_close(struct snd_pcm_substream *substream)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    printk("%s \n", __func__);

    if (mPrepareDone == true)
    {
        // stop DAC output
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, false);
        if (GetI2SDacEnable() == false)
        {
            SetI2SDacEnable(false);
        }
        // stop I2S output
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2, false);
        if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2) == false)
        {
            Afe_Set_Reg(AFE_I2S_CON3, 0x0, 0x1);
            //Afe_Set_Reg(AFE_I2S_CON, 0x0, 0x1);//K2 TODO: fix fm playback then mp3, i2s_con is misconfigured...
        }

        RemoveMemifSubStream(Soc_Aud_Digital_Block_MEM_DL1, substream);

        EnableAfe(false);

        if (mI2S0dl1_hdoutput_control == true)
        {
            printk("%s mI2S0dl1_hdoutput_control == %d \n", __func__, mI2S0dl1_hdoutput_control);

            EnableI2SDivPower(AUDIO_APLL12_DIV2, false);
            EnableI2SDivPower(AUDIO_APLL12_DIV4, false);   //Todo do we need open I2S3?

            EnableApll(runtime->rate, false);
            EnableApllTuner(runtime->rate, false);
        }

        mPrepareDone = false;
    }

    if (mPlaybackSramState == SRAM_STATE_PLAYBACKDRAM)
    {
        AudDrv_Emi_Clk_Off();
    }
    AfeControlSramLock();
    ClearSramState(mPlaybackSramState);
    mPlaybackSramState = GetSramState();
    AfeControlSramUnLock();
    AudDrv_Clk_Off();
    return 0;
}
static int mtk_pcm_mrgrx_prepare(struct snd_pcm_substream *substream)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    printk("%s rate = %d\n", __func__, runtime->rate);

    if (mPrepareDone == false)
    {
#ifndef DENALI_FPGA_EARLYPORTING               
        mtk_wcn_cmb_stub_audio_ctrl((CMB_STUB_AIF_X)CMB_STUB_AIF_3);
#endif
        // interconnection setting
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I15, Soc_Aud_InterConnectionOutput_O13);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I16, Soc_Aud_InterConnectionOutput_O14);

        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I10, Soc_Aud_InterConnectionOutput_O03);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I11, Soc_Aud_InterConnectionOutput_O04);

        // Set HW_GAIN
        SetHwDigitalGainMode(Soc_Aud_Hw_Digital_Gain_HW_DIGITAL_GAIN1, runtime->rate, 0x40);
        SetHwDigitalGainEnable(Soc_Aud_Hw_Digital_Gain_HW_DIGITAL_GAIN1, true);
        SetHwDigitalGain(mmrgrx_Volume, Soc_Aud_Hw_Digital_Gain_HW_DIGITAL_GAIN1);

        // start I2S DAC out
        if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC) == false)
        {
            SetI2SDacOut(runtime->rate,false, Soc_Aud_I2S_WLEN_WLEN_16BITS);
            SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
            SetI2SDacEnable(true);
        }
        else
        {
            SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
        }

        if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT) == false)
        {
            //set merge interface
            SetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT, true);
            SetMrgI2SEnable(true, runtime->rate);
        }
        else
        {
            SetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT, true);
        }

        EnableAfe(true);
        mPrepareDone = true;
    }
    return 0;
}
static int mtk_voice_extint_close(struct snd_pcm_substream *substream)
{
    printk("mtk_voice_extint_close \n");

    if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
    {
        printk("%s  with SNDRV_PCM_STREAM_CAPTURE \n",__func__);
        SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O03);
        SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O04);
        SetI2SDacEnable(false);
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, false);
        Voice_ExtInt_Status &= ~VOICE_DL_ON;
        if(Voice_ExtInt_Status == 0)
        {
            SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I21, Soc_Aud_InterConnectionOutput_O07);
            SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I21, Soc_Aud_InterConnectionOutput_O08);
            SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I09, Soc_Aud_InterConnectionOutput_O25);
            SetModemPcmEnable(MODEM_EXTERNAL, false);
            SetModemPcmEnable(MODEM_1, false);
        }
        EnableAfe(false);
        AudDrv_Clk_Off();
        AudDrv_ADC_Clk_Off();
    }
    else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
    {
        printk("%s  with SNDRV_PCM_STREAM_CAPTURE \n",__func__);
        SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I03, Soc_Aud_InterConnectionOutput_O17);
        SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I04, Soc_Aud_InterConnectionOutput_O18);
        SetI2SAdcEnable(false);
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC, false);
        Voice_ExtInt_Status &= ~VOICE_UL_ON;
        if(Voice_ExtInt_Status == 0)
        {
            SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I21, Soc_Aud_InterConnectionOutput_O07);
            SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I21, Soc_Aud_InterConnectionOutput_O08);
            SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I09, Soc_Aud_InterConnectionOutput_O25);
            SetModemPcmEnable(MODEM_EXTERNAL, false);
            SetModemPcmEnable(MODEM_1, false);
        }
        EnableAfe(false);
        AudDrv_Clk_Off();
        AudDrv_ADC_Clk_Off();
    }

    SetExternalModemStatus(false);

    return 0;
}
static int mtk_voice1_prepare(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtimeStream = substream->runtime;
	pr_warn("mtk_voice1_prepare rate = %d  channels = %d period_size = %lu\n",
	       runtimeStream->rate, runtimeStream->channels, runtimeStream->period_size);

	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
		pr_warn("%s  with SNDRV_PCM_STREAM_CAPTURE\n", __func__);
		return 0;
	}
	/* here start digital part */
	SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I03,
		      Soc_Aud_InterConnectionOutput_O17);
	SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I04,
		      Soc_Aud_InterConnectionOutput_O18);
	SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14,
		      Soc_Aud_InterConnectionOutput_O03);
	SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14,
		      Soc_Aud_InterConnectionOutput_O04);

	/* start I2S DAC out */
	SetI2SDacOut(substream->runtime->rate, false, Soc_Aud_I2S_WLEN_WLEN_16BITS);
	SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);

	ConfigAdcI2S(substream);
	SetI2SAdcIn(&mAudioDigitalI2S);
	SetI2SDacEnable(true);

#ifdef PMIC_RESET_WORKAROUND
	pr_warn("%s ,PMIC_RESET_WORKAROUND reset ABB_AFE_CON2/ABB_AFE_CON4\n", __func__);
	Ana_Set_Reg(ABB_AFE_CON2, 0x0, 0xffff);	/* reset to default value */
	Ana_Set_Reg(ABB_AFE_CON4, 0x0, 0xffff);	/* reset to default value */
#endif

	SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC, true);
	SetI2SAdcEnable(true);
	EnableAfe(true);
	Voice1Pcm.mPcmModeWidebandSel = (runtimeStream->rate == 8000) ?
	    Soc_Aud_PCM_MODE_PCM_MODE_8K : Soc_Aud_PCM_MODE_PCM_MODE_16K;
	Voice1Pcm.mAsyncFifoSel = Soc_Aud_BYPASS_SRC_SLAVE_USE_ASYNC_FIFO;
	SetModemPcmConfig(MODEM_1, Voice1Pcm);
	SetModemPcmEnable(MODEM_1, true);

	Voice_Status = true;

	return 0;
}
static void StopAudioFMI2SAWBHardware(struct snd_pcm_substream *substream)
{
	pr_warn("StopAudioFMI2SAWBHardware\n");

	SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_AWB, false);

	/* here to set interrupt */
	SetIrqEnable(Soc_Aud_IRQ_MCU_MODE_IRQ2_MCU_MODE, false);

	if (GetI2SDacEnable() == false)
		SetI2SDacEnable(false);

	/* here to turn off digital part */
	SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I00,
		      Soc_Aud_InterConnectionOutput_O05);
	SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I01,
		      Soc_Aud_InterConnectionOutput_O06);

	EnableAfe(false);
}
static int mtk_uldlloopbackpcm_close(struct snd_pcm_substream *substream)
{
    printk("%s \n", __func__);
    if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
    {
        printk("%s  with SNDRV_PCM_STREAM_CAPTURE \n", __func__);
        return 0;
    }

    // interconnection setting
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I03, Soc_Aud_InterConnectionOutput_O00);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I04, Soc_Aud_InterConnectionOutput_O01);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I03, Soc_Aud_InterConnectionOutput_O03);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I04, Soc_Aud_InterConnectionOutput_O04);

    
    SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC, false);
    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC) == false)
    {
        SetI2SAdcEnable(false);
    }

    // stop DAC output
    SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, false);
    if (GetI2SDacEnable() == false)
    {
        SetI2SDacEnable(false);
    }

    // stop I2S
    Afe_Set_Reg(AFE_I2S_CON3, 0x0, 0x1);
    Afe_Set_Reg(AFE_I2S_CON, 0x0, 0x1);
    Afe_Set_Reg(AFE_I2S_CON1, 0x0, 0x1);
    Afe_Set_Reg(AFE_I2S_CON2, 0x0, 0x1);

    EnableAfe(false);

    AudDrv_Clk_Off();
    AudDrv_ADC_Clk_Off();
    return 0;
}
static int mtk_voice1_prepare(struct snd_pcm_substream *substream)
{
    struct snd_pcm_runtime *runtimeStream = substream->runtime;
    printk("mtk_alsa_prepare rate = %d  channels = %d period_size = %lu\n",
           runtimeStream->rate, runtimeStream->channels, runtimeStream->period_size);

    if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
    {
        printk("%s  with SNDRV_PCM_STREAM_CAPTURE \n", __func__);
        return 0;
    }
    // here start digital part
    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I03, Soc_Aud_InterConnectionOutput_O17);
    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I04, Soc_Aud_InterConnectionOutput_O18);
    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O03);
    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O04);

    // start I2S DAC out
    SetI2SDacOut(substream->runtime->rate, false, Soc_Aud_I2S_WLEN_WLEN_16BITS);
    SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);

    ConfigAdcI2S(substream);
    SetI2SAdcIn(&mAudioDigitalI2S);
    SetI2SDacEnable(true);

    SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC, true);
    SetI2SAdcEnable(true);
    EnableAfe(true);
    Voice1Pcm.mPcmModeWidebandSel = (runtimeStream->rate == 8000) ? Soc_Aud_PCM_MODE_PCM_MODE_8K : Soc_Aud_PCM_MODE_PCM_MODE_16K;
    Voice1Pcm.mAsyncFifoSel = Soc_Aud_BYPASS_SRC_SLAVE_USE_ASYNC_FIFO;
    SetModemPcmConfig(MODEM_1, Voice1Pcm);
    SetModemPcmEnable(MODEM_1, true);

    Voice_Status = true;

    return 0;
}
Beispiel #16
0
static int mtk_pcm_I2S0dl1_close(struct snd_pcm_substream *substream)
{
    printk("%s \n", __func__);

    if (mPrepareDone == true)
    {
        // stop DAC output
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, false);
        if (GetI2SDacEnable() == false)
        {
            SetI2SDacEnable(false);
        }
        // stop I2S output
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2, false);
        if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2) == false)
        {
            Afe_Set_Reg(AFE_I2S_CON3, 0x0, 0x1);
            //Afe_Set_Reg(AFE_I2S_CON, 0x0, 0x1);//K2 TODO: fix fm playback then mp3, i2s_con is misconfigured...
        }

        RemoveMemifSubStream(Soc_Aud_Digital_Block_MEM_DL1, substream);

        EnableAfe(false);
        mPrepareDone = false;
    }

    if (mPlaybackSramState == SRAM_STATE_PLAYBACKDRAM)
    {
        AudDrv_Emi_Clk_Off();
    }
    AfeControlSramLock();
    ClearSramState(mPlaybackSramState);
    mPlaybackSramState = GetSramState();
    AfeControlSramUnLock();
    AudDrv_Clk_Off();
    return 0;
}
static int mtk_uldlloopback_pcm_prepare(struct snd_pcm_substream *substream)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    //uint32 eSamplingRate = SampleRateTransform(runtime->rate);
    //uint32 dVoiceModeSelect = 0;
    //uint32 Audio_I2S_Dac = 0;
    uint32 u32AudioI2S = 0;

    if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
    {
        printk("%s  with mtk_uldlloopback_pcm_prepare \n", __func__);
        return 0;
    }

    printk("%s rate = %d\n", __func__, runtime->rate);

    Afe_Set_Reg(AFE_TOP_CON0, 0x00000000, 0xffffffff);
    if (runtime->format == SNDRV_PCM_FORMAT_S32_LE || runtime->format == SNDRV_PCM_FORMAT_U32_LE)
    {
        SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL1, AFE_WLEN_32_BIT_ALIGN_8BIT_0_24BIT_DATA);
        SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL2, AFE_WLEN_32_BIT_ALIGN_8BIT_0_24BIT_DATA);
        SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT, Soc_Aud_InterConnectionOutput_O03);
        SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT, Soc_Aud_InterConnectionOutput_O04);
    }
    else
    {
        SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL1, AFE_WLEN_16_BIT);
        SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL2, AFE_WLEN_16_BIT);
        SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O03);
        SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O04);
    }

    // interconnection setting
    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I03, Soc_Aud_InterConnectionOutput_O00);
    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I04, Soc_Aud_InterConnectionOutput_O01);
    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I03, Soc_Aud_InterConnectionOutput_O03);
    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I04, Soc_Aud_InterConnectionOutput_O04);

    Afe_Set_Reg(AFE_ADDA_TOP_CON0, 0, 0x1); //Using Internal ADC

    u32AudioI2S |= Soc_Aud_LOW_JITTER_CLOCK << 12 ; //Low jitter mode
    u32AudioI2S |= SampleRateTransform(runtime->rate) << 8;
    u32AudioI2S |= Soc_Aud_I2S_FORMAT_I2S << 3; // us3 I2s format
    u32AudioI2S |= Soc_Aud_I2S_WLEN_WLEN_32BITS << 1; // 32 BITS
    printk("u32AudioI2S= 0x%x\n", u32AudioI2S);
    Afe_Set_Reg(AFE_I2S_CON3, u32AudioI2S | 1, AFE_MASK_ALL);

     // start I2S DAC out
    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC) == false)
    {
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
        SetI2SDacOut(substream->runtime->rate, false, Soc_Aud_I2S_WLEN_WLEN_32BITS);
        SetI2SDacEnable(true);
    }
    else
    {
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
    }

    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC) == false)
    {
        ConfigAdcI2S(substream);
        SetI2SAdcIn(&mAudioDigitalI2S);
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC, true);
        SetI2SAdcEnable(true);
    }
    else
    {
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC, true);
    }

    EnableAfe(true);

    return 0;
}
Beispiel #18
0
static int mtk_pcm_I2S0dl1_prepare(struct snd_pcm_substream *substream)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    uint32 Audio_I2S_Dac = 0, MclkDiv0, MclkDiv3;
    uint32 u32AudioI2S = 0;
    if (mPrepareDone == false)
    {
        pr_debug("%s format = %d SNDRV_PCM_FORMAT_S32_LE = %d SNDRV_PCM_FORMAT_U32_LE = %d \n", __func__, runtime->format, SNDRV_PCM_FORMAT_S32_LE, SNDRV_PCM_FORMAT_U32_LE);
        SetMemifSubStream(Soc_Aud_Digital_Block_MEM_DL1, substream);

        if (runtime->format == SNDRV_PCM_FORMAT_S32_LE || runtime->format == SNDRV_PCM_FORMAT_U32_LE)
        {
            SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL1, AFE_WLEN_32_BIT_ALIGN_8BIT_0_24BIT_DATA);
            SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL2, AFE_WLEN_32_BIT_ALIGN_8BIT_0_24BIT_DATA);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT, Soc_Aud_InterConnectionOutput_O03);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT, Soc_Aud_InterConnectionOutput_O04);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT, Soc_Aud_InterConnectionOutput_O00);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT, Soc_Aud_InterConnectionOutput_O01);
        }
        else
        {
            SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL1, AFE_WLEN_16_BIT);
            SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL2, AFE_WLEN_16_BIT);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O03);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O04);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O00);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O01);
        }
        SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O00);
        SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O01);

        SetSampleRate(Soc_Aud_Digital_Block_MEM_I2S,  runtime->rate);

        Audio_I2S_Dac |= (Soc_Aud_LR_SWAP_NO_SWAP << 31);
        if (mI2S0dl1_hdoutput_control == true)
        {
            MclkDiv0 = SetCLkMclk(Soc_Aud_I2S0, runtime->rate); //select I2S
            SetCLkBclk(MclkDiv0,  runtime->rate, runtime->channels, Soc_Aud_I2S_WLEN_WLEN_32BITS);

            Audio_I2S_Dac |= Soc_Aud_LOW_JITTER_CLOCK << 12 ; //Low jitter mode
        }
        else
        {
            Audio_I2S_Dac &= ~(Soc_Aud_LOW_JITTER_CLOCK << 12) ;
        }

        Audio_I2S_Dac |= (Soc_Aud_I2S_IN_PAD_SEL_I2S_IN_FROM_IO_MUX << 28);//I2S in from io_mux
        Audio_I2S_Dac |= (Soc_Aud_INV_LRCK_NO_INVERSE << 5);
        Audio_I2S_Dac |= (Soc_Aud_I2S_FORMAT_I2S << 3);
        Audio_I2S_Dac |= (Soc_Aud_I2S_WLEN_WLEN_32BITS << 1);

        // I2S out Setting
        u32AudioI2S = SampleRateTransform(runtime->rate) << 8;
        u32AudioI2S |= Soc_Aud_I2S_FORMAT_I2S << 3; // us3 I2s format
        u32AudioI2S |= Soc_Aud_I2S_WLEN_WLEN_32BITS << 1; // 32 BITS

        if (mI2S0dl1_hdoutput_control == true)
        {
            MclkDiv3 = SetCLkMclk(Soc_Aud_I2S3, runtime->rate); //select I2S
            SetCLkBclk(MclkDiv3,  runtime->rate, runtime->channels, Soc_Aud_I2S_WLEN_WLEN_32BITS);
            u32AudioI2S |= Soc_Aud_LOW_JITTER_CLOCK << 12 ; //Low jitter mode
        }
        else
        {
            u32AudioI2S &=  ~(Soc_Aud_LOW_JITTER_CLOCK << 12) ;
        }

        if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2) == false)
        {
            SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2, true);
            Afe_Set_Reg(AFE_I2S_CON, Audio_I2S_Dac | 0x1, MASK_ALL);
            Afe_Set_Reg(AFE_I2S_CON3, u32AudioI2S | 1, AFE_MASK_ALL);
        }
        else
        {
            SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2, true);
        }

        // start I2S DAC out
        if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC) == false)
        {
            SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
            SetI2SDacOut(substream->runtime->rate);
            SetI2SDacEnable(true);
        }
        else
        {
            SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
        }
        // here to set interrupt_distributor
        SetIrqMcuCounter(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE, runtime->period_size);
        SetIrqMcuSampleRate(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE, runtime->rate);

        EnableAfe(true);
        mPrepareDone = true;
    }
    return 0;
}
static int mtk_pcm_fm_i2s_prepare(struct snd_pcm_substream *substream)
{
    AudioDigtalI2S m2ndI2SInAttribute;

    struct snd_pcm_runtime *runtime = substream->runtime;
    printk("%s rate = %d\n", __func__, runtime->rate);

    if (mPrepareDone == false)
    {
        //mtk_wcn_cmb_stub_audio_ctrl((CMB_STUB_AIF_X)CMB_STUB_AIF_3);//temp mark for early porting

        // interconnection setting
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I00, Soc_Aud_InterConnectionOutput_O13);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I01, Soc_Aud_InterConnectionOutput_O14);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I10, Soc_Aud_InterConnectionOutput_O03);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I11, Soc_Aud_InterConnectionOutput_O04);

        ///<<<lenovo-sw, fangzf1 @2015-06-11 for fm
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I10, Soc_Aud_InterConnectionOutput_O00);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I11, Soc_Aud_InterConnectionOutput_O01);
        ///lenovo-sw, fangzf1 @2015-06-11 for fm>>>

        // Set HW_GAIN
        SetHwDigitalGainMode(Soc_Aud_Hw_Digital_Gain_HW_DIGITAL_GAIN1, runtime->rate, 0x40);
        SetHwDigitalGainEnable(Soc_Aud_Hw_Digital_Gain_HW_DIGITAL_GAIN1, true);
        SetHwDigitalGain(mfm_i2s_Volume, Soc_Aud_Hw_Digital_Gain_HW_DIGITAL_GAIN1);

        // start I2S DAC out
        if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC) == false)
        {
            SetI2SDacOut(runtime->rate,false,Soc_Aud_I2S_WLEN_WLEN_16BITS);
            SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
            SetI2SDacEnable(true);
        }
        else
        {
            SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
        }
        if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_2) == false)
        {
            //set merge interface
            SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_2, true);

            // Config 2nd I2S IN
            memset((void *)&m2ndI2SInAttribute, 0, sizeof(m2ndI2SInAttribute));

            m2ndI2SInAttribute.mLR_SWAP = Soc_Aud_LR_SWAP_NO_SWAP;
            m2ndI2SInAttribute.mI2S_IN_PAD_SEL = false; // I2S_IN_FROM_CONNSYS
            m2ndI2SInAttribute.mI2S_SLAVE = Soc_Aud_I2S_SRC_SLAVE_MODE;
            m2ndI2SInAttribute.mI2S_SAMPLERATE = 32000;
            m2ndI2SInAttribute.mINV_LRCK = Soc_Aud_INV_LRCK_NO_INVERSE;
            m2ndI2SInAttribute.mI2S_FMT = Soc_Aud_I2S_FORMAT_I2S;
            m2ndI2SInAttribute.mI2S_WLEN = Soc_Aud_I2S_WLEN_WLEN_16BITS;
            Set2ndI2SIn(&m2ndI2SInAttribute);

	    if (runtime->rate == 48000)
		    SetI2SASRCConfig(true, 48000);  /* Covert from 32000 Hz to 48000 Hz */
	    else
		    SetI2SASRCConfig(true, 44100);  /* Covert from 32000 Hz to 44100 Hz */
            SetI2SASRCEnable(true);

            Set2ndI2SInEnable(true);
        }
        else
        {
            SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_2, true);
        }

        EnableAfe(true);
        mPrepareDone = true;
    }
    return 0;
}
Beispiel #20
0
static int mtk_pcm_I2S0dl1_close(struct snd_pcm_substream *substream)
{
    pr_debug("%s \n", __func__);

    if (mPrepareDone == true)
    {
//Flyme { [email protected] Fix low jitter mode issue that sound will be abnormal when the MediaService reboot 
	if (mi2s0_sidegen_control) {
		SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2, false);
		if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2) == false)
		{
		    if (mI2S0dl1_hdoutput_control == true)
		    {
			Afe_Set_Reg(AFE_I2S_CON3, 0, 1 << 12); //Clear Low jitter mode setting
		    }
		    Afe_Set_Reg(AFE_I2S_CON3, 0x0, 0x1);
		    Afe_Set_Reg(AFE_I2S_CON, 0x0, 0x1);
		    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O00);
		    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O01);
		    EnableAfe(false);
		}
		AudDrv_Clk_Off();
		mi2s0_sidegen_control = 0;
	}
        if (mI2S0dl1_hdoutput_control) {
		// set APLL clock setting
		EnableApll1(false);
		EnableApll2(false);
		EnableI2SDivPower(AUDIO_APLL1_DIV0, false);
		EnableI2SDivPower(AUDIO_APLL2_DIV0, false);
		AudDrv_APLL1Tuner_Clk_Off();
		AudDrv_APLL2Tuner_Clk_Off();
		mI2S0dl1_hdoutput_control = false;
	}
// }
        // stop DAC output
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, false);
        if (GetI2SDacEnable() == false)
        {
            SetI2SDacEnable(false);
        }
        // stop I2S output
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2, false);
        if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2) == false)
        {
            Afe_Set_Reg(AFE_I2S_CON3, 0x0, 0x1);
            Afe_Set_Reg(AFE_I2S_CON, 0x0, 0x1);
        }

        RemoveMemifSubStream(Soc_Aud_Digital_Block_MEM_DL1,substream);

        EnableAfe(false);
        mPrepareDone = false;
    }

    if(mPlaybackSramState == SRAM_STATE_PLAYBACKDRAM)
    {
        AudDrv_Emi_Clk_Off();
    }
    AfeControlSramLock();
    ClearSramState(mPlaybackSramState);
    mPlaybackSramState = GetSramState();
    AfeControlSramUnLock();
    AudDrv_Clk_Off();
    return 0;
}
static int mtk_pcm_I2S0dl1_prepare(struct snd_pcm_substream *substream)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    uint32 MclkDiv3;
    uint32 u32AudioI2S = 0;
    bool mI2SWLen;
    if (mPrepareDone == false)
    {
        printk("%s format = %d SNDRV_PCM_FORMAT_S32_LE = %d SNDRV_PCM_FORMAT_U32_LE = %d \n", __func__, runtime->format, SNDRV_PCM_FORMAT_S32_LE, SNDRV_PCM_FORMAT_U32_LE);
        SetMemifSubStream(Soc_Aud_Digital_Block_MEM_DL1, substream);

        if (runtime->format == SNDRV_PCM_FORMAT_S32_LE || runtime->format == SNDRV_PCM_FORMAT_U32_LE)
        {
            SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL1, AFE_WLEN_32_BIT_ALIGN_8BIT_0_24BIT_DATA);
            SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL2, AFE_WLEN_32_BIT_ALIGN_8BIT_0_24BIT_DATA);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT, Soc_Aud_InterConnectionOutput_O03);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT, Soc_Aud_InterConnectionOutput_O04);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT, Soc_Aud_InterConnectionOutput_O00);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT, Soc_Aud_InterConnectionOutput_O01);
            mI2SWLen = Soc_Aud_I2S_WLEN_WLEN_32BITS;
        }
        else
        {
            SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL1, AFE_WLEN_16_BIT);
            SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_DL2, AFE_WLEN_16_BIT);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O03);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O04);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O00);
            SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O01);
            mI2SWLen = Soc_Aud_I2S_WLEN_WLEN_16BITS;
        }

        SetSampleRate(Soc_Aud_Digital_Block_MEM_I2S,  runtime->rate);

        // I2S out Setting
        u32AudioI2S = SampleRateTransform(runtime->rate) << 8;
        u32AudioI2S |= Soc_Aud_I2S_FORMAT_I2S << 3; // us3 I2s format
        u32AudioI2S |= Soc_Aud_I2S_WLEN_WLEN_32BITS << 1; //32bit

        if (mI2S0dl1_hdoutput_control == true)
        {
            printk("%s mI2S0dl1_hdoutput_control == %d\n", __func__, mI2S0dl1_hdoutput_control);
            // open apll
            EnableApll(runtime->rate, true);
            EnableApllTuner(runtime->rate, true);

            MclkDiv3 = SetCLkMclk(Soc_Aud_I2S1, runtime->rate); //select I2S
            MclkDiv3 = SetCLkMclk(Soc_Aud_I2S3, runtime->rate); //Todo do we need open I2S3?

            //Following wil not affect hw. because I2S0-I2S3 BCK is generated by APLL1 DIV0 APLL2 Div0
            SetCLkBclk(MclkDiv3,  runtime->rate, runtime->channels, Soc_Aud_I2S_WLEN_WLEN_32BITS);

            EnableI2SDivPower(AUDIO_APLL12_DIV2, true);
            EnableI2SDivPower(AUDIO_APLL12_DIV4, true);   //Todo do we need open I2S3?

            u32AudioI2S |= Soc_Aud_LOW_JITTER_CLOCK << 12 ; //Low jitter mode

        }
        else
        {
            u32AudioI2S &=  ~(Soc_Aud_LOW_JITTER_CLOCK << 12) ;
        }

        if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2) == false)
        {
            SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2, true);
            //Afe_Set_Reg(AFE_I2S_CON, Audio_I2S_Dac | 0x1, MASK_ALL); //K2 TODO: fix fm playback then mp3, i2s_con is misconfigured...
            Afe_Set_Reg(AFE_I2S_CON3, u32AudioI2S | 1, AFE_MASK_ALL);
        }
        else
        {
            SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2, true);
        }

        // start I2S DAC out
        if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC) == false)
        {
            SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
            SetI2SDacOut(substream->runtime->rate, mI2S0dl1_hdoutput_control, mI2SWLen);
            SetI2SDacEnable(true);
        }
        else
        {
            SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_DAC, true);
        }
        // here to set interrupt_distributor
        SetIrqMcuCounter(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE, runtime->period_size);
        SetIrqMcuSampleRate(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE, runtime->rate);

        EnableAfe(true);
        mPrepareDone = true;
    }
    return 0;
}