static void StartAudioCaptureHardware(struct snd_pcm_substream *substream)
{
    printk("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
    SetIrqMcuCounter(Soc_Aud_IRQ_MCU_MODE_IRQ2_MCU_MODE, substream->runtime->period_size);
    SetIrqMcuSampleRate(Soc_Aud_IRQ_MCU_MODE_IRQ2_MCU_MODE, substream->runtime->rate);
    SetIrqEnable(Soc_Aud_IRQ_MCU_MODE_IRQ2_MCU_MODE, true);

    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    
}
static int Audio_hdmi_SideGen_Set(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_value *ucontrol)
{
	pr_debug("%s()\n", __func__);
	if (ucontrol->value.enumerated.item[0] > ARRAY_SIZE(HDMI_SIDEGEN)) {
		pr_err("return -EINVAL\n");
		return -EINVAL;
	}
#ifdef _TDM_8CH_SGEN_TEST
	mHdmi_sidegen_control = ucontrol->value.integer.value[0];

	if (mHdmi_sidegen_control) {
		uint32 samplerate = 44100;
		uint32 HDMIchaanel = 8;
		uint32 MclkDiv = 0;

		/* Enable Audio Driver Clock */
		AudDrv_ANA_Clk_On();
		AudDrv_Clk_On();
		AudDrv_Emi_Clk_On();

		/* Enable APLL */
		EnableApll(samplerate, true);
		EnableApllTuner(samplerate, true);

		/* HDMI I2S clock setting */
		MclkDiv = SetCLkMclk(Soc_Aud_HDMI_MCK, samplerate);
		SetCLkHdmiBclk(MclkDiv, samplerate, 2, 32);

		/* enable mclk divider */
		EnableSpdifDivPower(AUDIO_APLL_SPDIF_DIV, true);

		/* enable bck divider */
		EnableHDMIDivPower(AUDIO_APLL_HDMI_BCK_DIV, true);

		/* turn on hdmi clk */
		SetHdmiClkOn();

		/* Set Mem buffer */
		SetHDMIAddress();
		copysinewavetohdmi(8);

		/* config hdmi irq */
		SetIrqMcuCounter(Soc_Aud_IRQ_MCU_MODE_IRQ5_MCU_MODE, 44100);

		/* config hdmi interface */
		SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_HDMI,
			AFE_WLEN_16_BIT);	/* now fix 16bit */
		SetHdmiTdm1Config(44100, AFE_DATA_WLEN_32BIT);
		SetHdmiTdm2Config(44100);
		SetHDMIChannels(HDMIchaanel);

		/* config hdmi connection */
		SetHDMIConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I30,
				  Soc_Aud_InterConnectionOutput_O30);
		SetHDMIConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I31,
				  Soc_Aud_InterConnectionOutput_O31);
		SetHDMIConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I30,
				  Soc_Aud_InterConnectionOutput_O32);
		SetHDMIConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I31,
				  Soc_Aud_InterConnectionOutput_O33);
		SetHDMIConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I30,
				  Soc_Aud_InterConnectionOutput_O34);
		SetHDMIConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I31,
				  Soc_Aud_InterConnectionOutput_O35);
		SetHDMIConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I30,
				  Soc_Aud_InterConnectionOutput_O36);
		SetHDMIConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I31,
				  Soc_Aud_InterConnectionOutput_O37);

		/* Enable hdmi Memory Path */
		SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_HDMI, true);

		/* enable irq */
		SetIrqEnable(Soc_Aud_IRQ_MCU_MODE_IRQ5_MCU_MODE, true);

		/* enable hdmi out */
		SetHDMIEnable(true);

		/* enable afe */
		EnableAfe(true);

		/* enable TDM */
		SetTDMEnable(HDMIchaanel);

	} else {
		uint32 HDMIchaanel = 8;

		SetTDMEnable(false);

		SetHDMIEnable(false);

		SetIrqEnable(Soc_Aud_IRQ_MCU_MODE_IRQ5_MCU_MODE, false);

		SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_HDMI, false);

		EnableAfe(false);

		SetHdmiPcmInterConnection(Soc_Aud_InterCon_DisConnect, HDMIchaanel);

		SetHdmiClkOff();
		EnableSpdifDivPower(AUDIO_APLL_SPDIF_DIV, false);
		EnableHDMIDivPower(AUDIO_APLL_HDMI_BCK_DIV, false);

		AudDrv_Emi_Clk_Off();
		AudDrv_Clk_Off();
		AudDrv_ANA_Clk_Off();

	}
#endif
	return 0;
}
static int mtk_pcm_hdmi_start(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	uint32 mclkDiv;

	pr_debug("[%s] runtime->rate = %d, runtime->channels = %d, runtime->period_size = %d\n",
		__func__, runtime->rate, runtime->channels, (unsigned int)runtime->period_size);

	SetMemifSubStream(Soc_Aud_Digital_Block_MEM_HDMI, substream);

	/* HDMI I2S clock setting */
	mclkDiv = SetCLkMclk(Soc_Aud_HDMI_MCK, runtime->rate);
	SetCLkHdmiBclk(mclkDiv, runtime->rate, 2, 32);

	/* enable mclk divider */
	EnableSpdifDivPower(AUDIO_APLL_SPDIF_DIV, true);

	/* enable bck divider */
	EnableHDMIDivPower(AUDIO_APLL_HDMI_BCK_DIV, true);

	/* turn on hdmi clk */
	SetHdmiClkOn();

	/* config hdmi irq */
	SetIrqMcuCounter(Soc_Aud_IRQ_MCU_MODE_IRQ5_MCU_MODE, runtime->period_size);

	/* config hdmi interface */
	if (runtime->format == SNDRV_PCM_FORMAT_S32_LE
	    || runtime->format == SNDRV_PCM_FORMAT_U32_LE) {
		SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_HDMI,
					     AFE_WLEN_32_BIT_ALIGN_24BIT_DATA_8BIT_0);
		Afe_Set_Reg(AFE_HDMI_OUT_CON0, 0x2, 0x2);
	} else
		SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_HDMI, AFE_WLEN_16_BIT);

	SetHdmiTdm1Config(runtime->channels, AFE_DATA_WLEN_32BIT);
	SetHdmiTdm2Config(runtime->channels);
	SetHDMIChannels(runtime->channels);

	/* config hdmi connection */
	SetHdmiPcmInterConnection(Soc_Aud_InterCon_Connection, runtime->channels);

	/* Enable hdmi Memory Path */
	SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_HDMI, true);

	/* enable irq */
	SetIrqEnable(Soc_Aud_IRQ_MCU_MODE_IRQ5_MCU_MODE, true);

	/* enable hdmi out */
	SetHDMIEnable(true);

	/* enable afe */
	EnableAfe(true);

	/* enable TDM */
	SetTDMEnable(runtime->channels);

	pr_debug
	("[%s] AFE_IRQ_MCU_STATUS = 0x%x AFE_IRQ_MCU_EN = 0x%x AFE_IRQ_CNT5=0x%x AFE_IRQ_DEBUG =0x%x\n",
	__func__, Afe_Get_Reg(AFE_IRQ_MCU_STATUS), Afe_Get_Reg(AFE_IRQ_MCU_EN),
	Afe_Get_Reg(AFE_IRQ_CNT5), Afe_Get_Reg(AFE_IRQ_DEBUG));

	return 0;
}
static int Audio_i2s0_SideGen_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    uint32 u32AudioI2S = 0, MclkDiv0, MclkDiv3, REG448 = 0, REG44C = 0;
    uint32 samplerate = 0;
    AudDrv_Clk_On();

    printk("+%s() samplerate = %d, mi2s0_hdoutput_control = %d, mi2s0_extcodec_echoref_control = %d\n", __func__, samplerate, mi2s0_hdoutput_control, mi2s0_extcodec_echoref_control);
    if (ucontrol->value.enumerated.item[0] > ARRAY_SIZE(i2s0_SIDEGEN))
    {
        printk("return -EINVAL\n");
        return -EINVAL;
    }
    mi2s0_sidegen_control = ucontrol->value.integer.value[0];
    if (mi2s0_sidegen_control == 1)
    {
        samplerate = 48000;
    }
    else if (mi2s0_sidegen_control == 2)
    {
        samplerate = 44100;
    }
    else if (mi2s0_sidegen_control == 3)
    {
        samplerate = 32000;
    }
    else if (mi2s0_sidegen_control == 4)
    {
        samplerate = 16000;
        // here start digital part
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O00);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O01);
    }
    else if (mi2s0_sidegen_control == 5)
    {
        samplerate = 8000;
        // here start digital part
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O00);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O01);
    }
    if (mi2s0_extcodec_echoref_control == true)
    {
        printk("%s() Soc_Aud_InterCon_Connection  I01  O14\n",  __func__);
        //phone call echo reference connection: I0/I1->O13/O14(HW Gain1)->I11 ->O24
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I01, Soc_Aud_InterConnectionOutput_O14);//0x448, 0x10000
        REG448 = Afe_Get_Reg(AFE_GAIN1_CONN2);
        printk("%s() AFE_GAIN1_CONN2 (0X448) =0x%x\n",  __func__, REG448);

        printk("%s() Soc_Aud_InterCon_Connection  I11  O24\n",  __func__);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I11, Soc_Aud_InterConnectionOutput_O24);//0x44c, 0x8

        REG44C = Afe_Get_Reg(AFE_GAIN1_CONN3);
        printk("%s() AFE_GAIN1_CONN3 (0X44C) =0x%x\n",  __func__, REG44C);
        // Set HW_GAIN1
        SetHwDigitalGainMode(Soc_Aud_Hw_Digital_Gain_HW_DIGITAL_GAIN1, samplerate, 0x80);
        SetHwDigitalGainEnable(Soc_Aud_Hw_Digital_Gain_HW_DIGITAL_GAIN1, true);
        SetHwDigitalGain(0x80000, Soc_Aud_Hw_Digital_Gain_HW_DIGITAL_GAIN1);

        Afe_Set_Reg(AFE_DAC_CON1, 0x400, 0xF00);

    }

    if (mi2s0_sidegen_control != 0)
    {
        printk("%s() mi2s0_sidegen_control=%d, mi2s0_hdoutput_control=%d\n",  __func__, mi2s0_sidegen_control, mi2s0_hdoutput_control);
        AudDrv_Clk_On();
        Afe_Set_Reg(AUDIO_TOP_CON1, 0x2,  0x2);  // I2S0_SOFT_Reset
        uint32 Audio_I2S_Dac = 0;
        SetSampleRate(Soc_Aud_Digital_Block_MEM_I2S,  samplerate);
        Audio_I2S_Dac |= (Soc_Aud_LR_SWAP_NO_SWAP << 31);

        //        Audio_I2S_Dac |= (Soc_Aud_INV_BCK_INVESE << 29);//BCK Inv
        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);

        u32AudioI2S = SampleRateTransform(samplerate) << 8;
        u32AudioI2S |= Soc_Aud_I2S_FORMAT_I2S << 3; // us3 I2s format
        u32AudioI2S |= Soc_Aud_I2S_WLEN_WLEN_32BITS << 1; // 32 BITS
        if (mi2s0_hdoutput_control == true)
        {
            printk("%s() mi2s0_sidegen_control = %d set low jitter\n", __func__, mi2s0_sidegen_control);
            MclkDiv0 = SetCLkMclk(Soc_Aud_I2S0, samplerate); //select I2S
            SetCLkBclk(MclkDiv0, samplerate, 2, Soc_Aud_I2S_WLEN_WLEN_32BITS);

            MclkDiv3 = SetCLkMclk(Soc_Aud_I2S3, samplerate); //select I2S
            SetCLkBclk(MclkDiv3, samplerate, 2, Soc_Aud_I2S_WLEN_WLEN_32BITS);

            u32AudioI2S |= Soc_Aud_LOW_JITTER_CLOCK << 12 ; //Low jitter mode
            Audio_I2S_Dac |= Soc_Aud_LOW_JITTER_CLOCK << 12 ; //Low jitter mode
        }
        else
        {
            printk("%s() mi2s0_sidegen_control = %d NOT set low jitter\n", __func__, mi2s0_sidegen_control);
            u32AudioI2S &=  ~(Soc_Aud_LOW_JITTER_CLOCK << 12) ;
            Audio_I2S_Dac &=  ~(Soc_Aud_LOW_JITTER_CLOCK << 12) ;
        }

        // start I2S DAC out
        if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2) == false)
        {
            printk("%s(), mi2s0_sidegen_control=%d, write AFE_I2S_CON (0x%x), AFE_I2S_CON3(0x%x)\n", __func__, mi2s0_sidegen_control, Audio_I2S_Dac, u32AudioI2S);
            Afe_Set_Reg(AFE_I2S_CON, 0x0, 0x1);
            Afe_Set_Reg(AFE_I2S_CON3, 0x0, 0x1);
            udelay(200);
            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);
            udelay(200);
            Afe_Set_Reg(AUDIO_TOP_CON1, 0x0, 0x2); // I2S0_SOFT_Reset
            msleep(1);
            EnableAfe(true);
        }
        else
        {
            printk("%s(), mi2s0_sidegen_control=%d, write AFE_I2S_CON (0x%x), AFE_I2S_CON3(0x%x)\n", __func__, mi2s0_sidegen_control, Audio_I2S_Dac, u32AudioI2S);
            Afe_Set_Reg(AFE_I2S_CON, 0x0, 0x1);
            Afe_Set_Reg(AFE_I2S_CON3, 0x0, 0x1);
            udelay(200);
            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);
            udelay(200);
            Afe_Set_Reg(AUDIO_TOP_CON1, 0x0, 0x2); // I2S0_SOFT_Reset
            msleep(1);
            EnableAfe(true);
        }
    }
    else
    {
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2, false);
        if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_OUT_2) == false)
        {
            if (mi2s0_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();
    }
    AudDrv_Clk_Off();
    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);
			SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT,
						  Soc_Aud_InterConnectionOutput_O28);
			SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_24BIT,
						  Soc_Aud_InterConnectionOutput_O29);
			/* 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);
			SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT,
						  Soc_Aud_InterConnectionOutput_O28);
			SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT,
						  Soc_Aud_InterConnectionOutput_O29);
			/* 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;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}
Esempio n. 9
0
static int Audio_i2s0_SideGen_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    uint32 u32AudioI2S = 0;
    uint32 samplerate = 0;
    uint32 Audio_I2S_Dac;
    AudDrv_Clk_On();

    printk("%s() samplerate = %d mi2s0_hdoutput_control = %d\n", __func__, samplerate, mi2s0_hdoutput_control);
    if (ucontrol->value.enumerated.item[0] > ARRAY_SIZE(i2s0_SIDEGEN))
    {
        printk("return -EINVAL\n");
        return -EINVAL;
    }
    mi2s0_sidegen_control = ucontrol->value.integer.value[0];
    if (mi2s0_sidegen_control == 1)
    {
        samplerate = 48000;
    }
    else if (mi2s0_sidegen_control == 2)
    {
        samplerate = 44100;
    }
    else if (mi2s0_sidegen_control == 3)
    {
        samplerate = 32000;
    }
    else if (mi2s0_sidegen_control == 4)
    {
        samplerate = 16000;
        // here start digital part
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O00);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O01);
    }
    else if (mi2s0_sidegen_control == 5)
    {
        samplerate = 8000;
        // here start digital part
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O00);
        SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O01);
    }

    if (mi2s0_sidegen_control)
    {
        AudDrv_Clk_On();
        Afe_Set_Reg(AUDIO_TOP_CON1, 0x2,  0x2);  // I2S_SOFT_Reset
        Afe_Set_Reg(AUDIO_TOP_CON1, 0x1 << 4,  0x1 << 4); // I2S_SOFT_Reset
        Audio_I2S_Dac = 0;
        SetCLkMclk(Soc_Aud_I2S0, samplerate);
        SetSampleRate(Soc_Aud_Digital_Block_MEM_I2S,  samplerate);

        Audio_I2S_Dac |= (Soc_Aud_LR_SWAP_NO_SWAP << 31);
        if (mi2s0_hdoutput_control == true)
        {
            Audio_I2S_Dac |= Soc_Aud_LOW_JITTER_CLOCK << 12 ; //Low jitter mode
        }
        else
        {
            Audio_I2S_Dac |= Soc_Aud_NORMAL_CLOCK << 12 ; //Low jitter mode
        }
        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);


        u32AudioI2S = SampleRateTransform(samplerate) << 8;
        u32AudioI2S |= Soc_Aud_I2S_FORMAT_I2S << 3; // us3 I2s format
        u32AudioI2S |= Soc_Aud_I2S_WLEN_WLEN_32BITS << 1; // 32 BITS
        if (mi2s0_hdoutput_control == true)
        {
            u32AudioI2S |= Soc_Aud_LOW_JITTER_CLOCK << 12 ; //Low jitter mode
        }
        else
        {
            u32AudioI2S |= Soc_Aud_NORMAL_CLOCK << 12 ; //Low jitter mode
        }

        // start I2S DAC out
        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);
            Afe_Set_Reg(AUDIO_TOP_CON1, 0x0 << 4,  0x1 << 4);
            Afe_Set_Reg(AUDIO_TOP_CON1, 0x0,  0x2);  // I2S_SOFT_Reset
            EnableAfe(true);
        }
        else
        {
            printk("%s(), mi2s0_sidegen_control=%d, write AFE_I2S_CON (0x%x), AFE_I2S_CON3(0x%x)\n", __func__, mi2s0_sidegen_control, Audio_I2S_Dac, u32AudioI2S);
            Afe_Set_Reg(AFE_I2S_CON, 0x0, 0x1);
            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);
            Afe_Set_Reg(AUDIO_TOP_CON1, 0x0 << 4, 0x1 << 4);
            Afe_Set_Reg(AUDIO_TOP_CON1, 0x0, 0x2); // I2S_SOFT_Reset
            EnableAfe(true);
        }

    }
    else
    {
        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);
            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();
    }
    AudDrv_Clk_Off();
    return 0;
}
Esempio n. 10
0
static int mtk_pcm_i2s0_start(struct snd_pcm_substream *substream)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    uint32 Audio_I2S_Dac = 0;
    uint32 u32AudioI2S = 0;
    AudDrv_Clk_On();
    SetMemifSubStream(Soc_Aud_Digital_Block_MEM_DL1, substream);
    if (runtime->format == SNDRV_PCM_FORMAT_S32_LE || runtime->format == SNDRV_PCM_FORMAT_S32_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);
    }
    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_O00);
    SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O01);

    // here start digital part
    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I05, Soc_Aud_InterConnectionOutput_O00);
    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I06, Soc_Aud_InterConnectionOutput_O01);

    SetCLkMclk(Soc_Aud_I2S0, runtime->rate);
    SetSampleRate(Soc_Aud_Digital_Block_MEM_I2S,  runtime->rate);

    Audio_I2S_Dac |= (Soc_Aud_LR_SWAP_NO_SWAP << 31);
    if (mi2s0_hdoutput_control == true)
    {
        Audio_I2S_Dac |= Soc_Aud_LOW_JITTER_CLOCK << 12 ; //Low jitter mode
    }
    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);
    Afe_Set_Reg(AFE_I2S_CON, Audio_I2S_Dac | 0x1, MASK_ALL);

    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 (mi2s0_hdoutput_control == true)
    {
        u32AudioI2S |= Soc_Aud_LOW_JITTER_CLOCK << 12 ; //Low jitter mode
    }

    printk(" u32AudioI2S= 0x%x\n", u32AudioI2S);
    Afe_Set_Reg(AFE_I2S_CON3, u32AudioI2S | 1, AFE_MASK_ALL);

    SetSampleRate(Soc_Aud_Digital_Block_MEM_DL1, runtime->rate);
    SetChannels(Soc_Aud_Digital_Block_MEM_DL1, runtime->channels);
    SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DL1, true);

    // here to set interrupt
    SetIrqMcuCounter(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE, runtime->period_size);
    SetIrqMcuSampleRate(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE, runtime->rate);
    SetIrqEnable(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE, true);

    EnableAfe(true);

    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;
}
static void StartAudioMrgrxAWBHardware(struct snd_pcm_substream *substream)
{
    printk("StartAudioMrgrxAWBHardware \n");

    // here to set interrupt
    SetIrqMcuCounter(Soc_Aud_IRQ_MCU_MODE_IRQ2_MCU_MODE, substream->runtime->period_size >> 1);
    SetIrqMcuSampleRate(Soc_Aud_IRQ_MCU_MODE_IRQ2_MCU_MODE, substream->runtime->rate);
    SetIrqEnable(Soc_Aud_IRQ_MCU_MODE_IRQ2_MCU_MODE, true);

    SetSampleRate(Soc_Aud_Digital_Block_MEM_AWB, substream->runtime->rate);
    SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_AWB, true);

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


#if 0 // TODO(Harvey)
    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT) == false)
    {
        //set merge interface
        SetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT, true);
        SetMrgI2SEnable(true, substream->runtime->rate);
    }
    else
    {
        SetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT, true);
    }
#else
    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
        AudioDigtalI2S m2ndI2SInAttribute;
        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);
    
        SetI2SASRCConfig(true, 44100);  // Covert from 32000 Hz to 44100 Hz
        SetI2SASRCEnable(true);
    
        Set2ndI2SInEnable(true);
    }
    else
    {
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_2, true);
    }
#endif

    EnableAfe(true);
}