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

    ConfigAdcI2S(substream);
    SetI2SAdcIn(mAudioDigitalI2S);
    //EnableSideGenHw(Soc_Aud_InterConnectionOutput_O09,Soc_Aud_MemIF_Direction_DIRECTION_OUTPUT,true);

    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);

    SetI2SAdcEnable(true);

    // 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);

    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);

    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I05, Soc_Aud_InterConnectionOutput_O09);
    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I06, Soc_Aud_InterConnectionOutput_O10);

    EnableAfe(true);

}
Ejemplo n.º 2
0
static int mtk_pcm_dl1bt_start(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	AudDrv_Clk_On();
	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);
		/* BT SCO only support 16 bit */
		SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O02);
	} 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_O02);
	}

	/* here start digital part */
	SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I05,
		      Soc_Aud_InterConnectionOutput_O02);
	SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I06,
		      Soc_Aud_InterConnectionOutput_O02);
	SetConnection(Soc_Aud_InterCon_ConnectionShift,
		      Soc_Aud_InterConnectionInput_I05, Soc_Aud_InterConnectionOutput_O02);
	SetConnection(Soc_Aud_InterCon_ConnectionShift,
		      Soc_Aud_InterConnectionInput_I06, Soc_Aud_InterConnectionOutput_O02);

	/* set dl1 sample ratelimit_state */
	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 >> 1);
	SetIrqMcuSampleRate(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE, runtime->rate);
	SetIrqEnable(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE, true);

	if (GetMemoryPathEnable(Soc_Aud_Digital_Block_DAI_BT) == false) {
		/* set merge interface */
		SetMemoryPathEnable(Soc_Aud_Digital_Block_DAI_BT, true);
	} else {
		SetMemoryPathEnable(Soc_Aud_Digital_Block_DAI_BT, true);
	}

	SetVoipDAIBTAttribute(runtime->rate);
	SetDaiBtEnable(true);

	EnableAfe(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_fmtx_start(struct snd_pcm_substream *substream)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    AudDrv_Clk_On();

    //    mtk_wcn_cmb_stub_audio_ctrl((CMB_STUB_AIF_X)CMB_STUB_AIF_2);

    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_16BIT, Soc_Aud_InterConnectionOutput_O00); // FM Tx only support 16 bit
        SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O01); // FM Tx only support 16 bit
    }
    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);

    // set dl1 sample ratelimit_state
    SetSampleRate(Soc_Aud_Digital_Block_MEM_DL1, runtime->rate);
    SetChannels(Soc_Aud_Digital_Block_MEM_DL1, runtime->channels);

    // start MRG I2S Out
    SetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT, true);
    SetMrgI2SEnable(true, runtime->rate) ;

    // start 2nd I2S Out

    Set2ndI2SOutAttribute(runtime->rate) ;
    Set2ndI2SOutEnable(true);

    SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DL1, true);

    // here to set interrupt
    SetIrqMcuCounter(Soc_Aud_IRQ_MCU_MODE_IRQ1_MCU_MODE, (runtime->period_size * 2 / 3));
    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_i2s0_start(struct snd_pcm_substream *substream)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    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);


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

    //ConfigAdcI2S(substream);
    //Set2ndI2SAdcIn(mAudioDigitalI2S);//To do, JY

    SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_MOD_DAI, AFE_WLEN_16_BIT);
    SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O12);

    /* To Do, JY, MOD_DAI?
    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC_2) == false)
    {
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC_2, true);
        Set2ndI2SAdcEnable(true);
    }
    else
    {
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC_2, true);
    }
    */
    // 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_MOD_DAI, substream->runtime->rate);
    SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_MOD_DAI, true);

    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14, Soc_Aud_InterConnectionOutput_O12);
    EnableAfe(true);

}
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)
    {
#if 0   //Rainier no 24bit
        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);	
#endif
    }

    // 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);
}
static int Audio_hdmi_SideGen_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    printk("%s()\n", __func__);
    if (ucontrol->value.enumerated.item[0] > ARRAY_SIZE(HDMI_SIDEGEN))
    {
        printk("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 Channels = 2;
        uint32 HDMIchaanel = 8;
        uint32 Tdm_Lrck = 0;
        uint32 MclkDiv = 0;
        AudDrv_Clk_On ();
        SetHDMIAddress();
        copysinewavetohdmi(8);

        SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_HDMI, AFE_WLEN_16_BIT);
        SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_HDMI, AFE_WLEN_16_BIT);
        SetHDMIdatalength(Soc_Aud_I2S_WLEN_WLEN_16BITS);
        SetTDMDatalength(Soc_Aud_I2S_WLEN_WLEN_16BITS);
        SetTDMbckcycle(Soc_Aud_I2S_WLEN_WLEN_16BITS);
        Tdm_Lrck = ((Soc_Aud_I2S_WLEN_WLEN_16BITS + 1) * 16) - 1;

        // set APLL clock setting
        EnableApll1(true);
        EnableApll2(true);
        EnableI2SDivPower(AUDIO_APLL1_DIV4, true);
        EnableI2SDivPower(AUDIO_APLL1_DIV5, true);
        EnableI2SDivPower(AUDIO_APLL2_DIV4, true);
        EnableI2SDivPower(AUDIO_APLL2_DIV5, true);
        MclkDiv = SetCLkMclk(Soc_Aud_I2S3, samplerate);
        SetCLkBclk(MclkDiv, samplerate, Channels, Soc_Aud_I2S_WLEN_WLEN_16BITS);

        SetHDMIsamplerate(samplerate);
        SetHDMIChannels(HDMIchaanel);
        SetHDMIMCLK();
        SetHDMIBCLK();

        SetTDMLrckWidth(Tdm_Lrck);
        SetTDMbckcycle(Soc_Aud_I2S_WLEN_WLEN_16BITS);
        SetTDMChannelsSdata(Channels);
        SetTDMDatalength(Soc_Aud_I2S_WLEN_WLEN_16BITS);
        SetTDMI2Smode(Soc_Aud_I2S_FORMAT_I2S);
        SetTDMLrckInverse(false);
        SetTDMBckInverse(false);

		#if 0
        Afe_Set_Reg(AFE_TDM_CON2, 0, 0x0000000f); // tmp    0: Channel starts from O30/O31.
        Afe_Set_Reg(AFE_TDM_CON2, 1 << 4, 0x000000f0); // tmp    1: Channel starts from O32/O33.
        Afe_Set_Reg(AFE_TDM_CON2, 2 << 8, 0x00000f00); // tmp    2: Channel starts from O34/O35.
        Afe_Set_Reg(AFE_TDM_CON2, 3 << 12, 0x0000f000); // tmp    3: Channel starts from O36/O37.
		#endif
        Afe_Set_Reg(AUDIO_TOP_CON3, 1<<3,  1 << 3); //  inverse HDMI BCLK

        SetTDMEnable(true); //enable TDM
        Afe_Set_Reg(AUDIO_TOP_CON0, 0 << 20,  1 << 20); //  enable HDMI CK

        // here start digital part
        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);

        SetHDMIEnable(true);

        Afe_Set_Reg(AFE_DAC_CON0, 0x1, 0x1); // tmp    3: Channel starts from O36/O37.


    }
    else
    {
        SetHDMIEnable(false);
        SetTDMEnable(false);
        Afe_Set_Reg(AFE_DAC_CON0, 0x0, 0x0); // tmp    3: Channel starts from O36/O37.
        AudDrv_Clk_Off ();
    }
#endif
    return 0;
}
static int Audio_hdmi_SideGen_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    printk("%s()\n", __func__);
    if (ucontrol->value.enumerated.item[0] > ARRAY_SIZE(HDMI_SIDEGEN))
    {
        printk("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 Channels = 2;
        uint32 HDMIchaanel = 8;
        uint32 Tdm_Lrck = 0;
        uint32 MclkDiv = 0;

        //Enable Audio Driver Clock
        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 samplerate = 44100;
        uint32 Channels = 2;
        uint32 HDMIchaanel = 8;
        uint32 Tdm_Lrck = 0;
        uint32 MclkDiv = 0;

        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();

    }
#endif
    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;
}
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 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;
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
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;
}