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

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

    SetMemIfFetchFormatPerSample(Soc_Aud_Digital_Block_MEM_VUL_DATA2, AFE_WLEN_16_BIT);
    SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O21);
    SetoutputConnectionFormat(OUTPUT_DATA_FORMAT_16BIT, Soc_Aud_InterConnectionOutput_O22);

    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC_2) == false)
    {
        SetMemoryPathEnable(Soc_Aud_Digital_Block_I2S_IN_ADC_2, true);
        Set2ndI2SAdcEnable(true);//To Do, JY
    }
    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_VUL_DATA2, substream->runtime->rate);
    SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_VUL_DATA2, true);

    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I17, Soc_Aud_InterConnectionOutput_O21);
    SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I18, Soc_Aud_InterConnectionOutput_O22);
    EnableAfe(true);

}
static snd_pcm_uframes_t mtk_i2s0_awb_pcm_pointer(struct snd_pcm_substream *substream)
{
    kal_int32 HW_memory_index = 0;
    kal_int32 HW_Cur_ReadIdx = 0;
    //kal_uint32 Frameidx =0;
    AFE_BLOCK_T *Awb_Block = &(I2S0_AWB_Control_context->rBlock);
    PRINTK_AUD_AWB("mtk_i2s0_awb_pcm_pointer Awb_Block->u4WriteIdx;= 0x%x \n",Awb_Block->u4WriteIdx);
    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_AWB) == true)
    {
        // get total bytes to copysinewavetohdmi
        //Frameidx =audio_bytes_to_frame(substream , Awb_Block->u4WriteIdx);
        //return Frameidx;

        HW_Cur_ReadIdx = Align64ByteSize(Afe_Get_Reg(AFE_AWB_CUR));
        if (HW_Cur_ReadIdx == 0)
        {
            printk("[Auddrv] mtk_awb_pcm_pointer  HW_Cur_ReadIdx ==0 \n");
            HW_Cur_ReadIdx = Awb_Block->pucPhysBufAddr;
        }
        HW_memory_index = (HW_Cur_ReadIdx - Awb_Block->pucPhysBufAddr);
        Previous_Hw_cur = HW_memory_index;
        PRINTK_AUD_AWB("[Auddrv] mtk_i2s0_awb_pcm_pointer =0x%x HW_memory_index = 0x%x\n", HW_Cur_ReadIdx, HW_memory_index);
        return audio_bytes_to_frame(substream,Previous_Hw_cur);
    }
    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
    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);

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

    EnableAfe(true);
}
Beispiel #4
0
static void StartAudioBtDaiHardware(struct snd_pcm_substream *substream)
{
	pr_debug("StartAudioBtDaiHardware\n");

	/* here to set interrupt */
	SetIrqMcuCounter(Soc_Aud_IRQ_MCU_MODE_IRQ2_MCU_MODE, substream->runtime->period_size >> 2);
	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_DAI, substream->runtime->rate);
	SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DAI, true);

	/* here to turn off digital part */
	SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I02,
		      Soc_Aud_InterConnectionOutput_O11);

	if (GetMemoryPathEnable(Soc_Aud_Digital_Block_DAI_BT) == false) {
		SetMemoryPathEnable(Soc_Aud_Digital_Block_DAI_BT, true);
		SetVoipDAIBTAttribute(substream->runtime->rate);
		SetDaiBtEnable(true);
	} else {
		SetMemoryPathEnable(Soc_Aud_Digital_Block_DAI_BT, true);
	}

	EnableAfe(true);
}
static snd_pcm_uframes_t mtk_capture_pcm_pointer(struct snd_pcm_substream *substream)
{
    kal_int32 HW_memory_index = 0;
    kal_int32 HW_Cur_ReadIdx = 0;
    //kal_uint32 Frameidx = 0;
    kal_int32 Hw_Get_bytes = 0;
    bool bIsOverflow = false;
    unsigned long flags;
    AFE_BLOCK_T *UL1_Block = &(VUL_Control_context->rBlock);
    PRINTK_AUD_UL1("mtk_capture_pcm_pointer Awb_Block->u4WriteIdx;= 0x%x \n", UL1_Block->u4WriteIdx);
    Auddrv_UL1_Spinlock_lock();
    spin_lock_irqsave(&VUL_Control_context->substream_lock, flags);
    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_VUL) == true)
    {

        HW_Cur_ReadIdx = Align64ByteSize(Afe_Get_Reg(AFE_VUL_CUR));
        if (HW_Cur_ReadIdx == 0)
        {
            PRINTK_AUD_UL1("[Auddrv] mtk_awb_pcm_pointer  HW_Cur_ReadIdx ==0 \n");
            HW_Cur_ReadIdx = UL1_Block->pucPhysBufAddr;
        }
        HW_memory_index = (HW_Cur_ReadIdx - UL1_Block->pucPhysBufAddr);

        // update for data get to hardware
        Hw_Get_bytes = (HW_Cur_ReadIdx - UL1_Block->pucPhysBufAddr) - UL1_Block->u4WriteIdx;
        if (Hw_Get_bytes < 0)
        {
            Hw_Get_bytes += UL1_Block->u4BufferSize;
        }
        UL1_Block->u4WriteIdx	+= Hw_Get_bytes;
        UL1_Block->u4WriteIdx	%= UL1_Block->u4BufferSize;
        UL1_Block->u4DataRemained += Hw_Get_bytes;
        

        // buffer overflow
        if (UL1_Block->u4DataRemained > UL1_Block->u4BufferSize)
        {
            bIsOverflow = true;
            printk("mtk_capture_pcm_pointer buffer overflow u4DMAReadIdx:%x, u4WriteIdx:%x, u4DataRemained:%x, u4BufferSize:%x \n",
                   UL1_Block->u4DMAReadIdx, UL1_Block->u4WriteIdx, UL1_Block->u4DataRemained, UL1_Block->u4BufferSize);
        }
        
        PRINTK_AUD_UL1("[Auddrv] mtk_capture_pcm_pointer =0x%x HW_memory_index = 0x%x\n", HW_Cur_ReadIdx, HW_memory_index);
        spin_unlock_irqrestore(&VUL_Control_context->substream_lock, flags);
        Auddrv_UL1_Spinlock_unlock();

        if (bIsOverflow == true)
        {
            return -1;
        }
        return audio_bytes_to_frame(substream, HW_memory_index);
    }
    spin_unlock_irqrestore(&VUL_Control_context->substream_lock, flags);
    Auddrv_UL1_Spinlock_unlock();
    return 0;

}
static int Audio_mrgrx_Volume_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    mmrgrx_Volume = ucontrol->value.integer.value[0];
    printk("%s mmrgrx_Volume = 0x%x \n", __func__, mmrgrx_Volume);
    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT) == true)
    {
        SetHwDigitalGain(mmrgrx_Volume, Soc_Aud_Hw_Digital_Gain_HW_DIGITAL_GAIN1);
    }
    return 0;
}
static snd_pcm_uframes_t mtk_pcm_I2S0dl1_pointer(struct snd_pcm_substream *substream)
{
    kal_int32 HW_memory_index = 0;
    kal_int32 HW_Cur_ReadIdx = 0;
    kal_uint32 Frameidx = 0;
    kal_int32 Afe_consumed_bytes = 0;
    AFE_BLOCK_T *Afe_Block = &pI2S0dl1MemControl->rBlock;
    unsigned long flags;
    //struct snd_pcm_runtime *runtime = substream->runtime;

    spin_lock_irqsave(&pI2S0dl1MemControl->substream_lock, flags);
    PRINTK_AUD_DL1(" %s Afe_Block->u4DMAReadIdx = 0x%x\n", __func__, Afe_Block->u4DMAReadIdx);

    // get total bytes to copy
    //Frameidx = audio_bytes_to_frame(substream , Afe_Block->u4DMAReadIdx);
    //return Frameidx;

    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DL1) == true)
    {
        HW_Cur_ReadIdx = Afe_Get_Reg(AFE_DL1_CUR);
        if (HW_Cur_ReadIdx == 0)
        {
            PRINTK_AUDDRV("[Auddrv] HW_Cur_ReadIdx ==0 \n");
            HW_Cur_ReadIdx = Afe_Block->pucPhysBufAddr;
        }

        HW_memory_index = (HW_Cur_ReadIdx - Afe_Block->pucPhysBufAddr);
        if (HW_memory_index >=  Afe_Block->u4DMAReadIdx)
        {
            Afe_consumed_bytes = HW_memory_index - Afe_Block->u4DMAReadIdx;
        }
        else
        {
            Afe_consumed_bytes = Afe_Block->u4BufferSize + HW_memory_index - Afe_Block->u4DMAReadIdx ;
        }

        Afe_consumed_bytes = Align64ByteSize(Afe_consumed_bytes);

        Afe_Block->u4DataRemained -= Afe_consumed_bytes;
        Afe_Block->u4DMAReadIdx += Afe_consumed_bytes;
        Afe_Block->u4DMAReadIdx %= Afe_Block->u4BufferSize;
        PRINTK_AUD_DL1("[Auddrv] HW_Cur_ReadIdx =0x%x HW_memory_index = 0x%x Afe_consumed_bytes  = 0x%x\n", HW_Cur_ReadIdx, HW_memory_index, Afe_consumed_bytes);
        spin_unlock_irqrestore(&pI2S0dl1MemControl->substream_lock, flags);

        return audio_bytes_to_frame(substream , Afe_Block->u4DMAReadIdx);
    }
    else
    {
        Frameidx = audio_bytes_to_frame(substream , Afe_Block->u4DMAReadIdx);
        spin_unlock_irqrestore(&pI2S0dl1MemControl->substream_lock, flags);
        return Frameidx;
    }

}
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 void StartAudioFMI2SAWBHardware(struct snd_pcm_substream *substream)
{
	AudioDigtalI2S m2ndI2SInAttribute;

	pr_warn("StartAudioFMI2SAWBHardware\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 */
	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);


	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_io((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 (substream->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);
}
static int mtk_mrgrx_awb_alsa_stop(struct snd_pcm_substream *substream)
{
    printk("mtk_mrgrx_awb_alsa_stop \n");
    StopAudioAWBHardware(substream);
    RemoveMemifSubStream(Soc_Aud_Digital_Block_MEM_AWB, substream);

    SetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT, false);
    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MRG_I2S_OUT) == false)
    {
        SetMrgI2SEnable(false, substream->runtime->rate);
    }
    return 0;
}
static snd_pcm_uframes_t mtk_pcm_dl2_pointer(struct snd_pcm_substream *substream)
{
	kal_int32 HW_memory_index = 0;
	kal_int32 HW_Cur_ReadIdx = 0;
	kal_uint32 Frameidx = 0;
	kal_int32 Afe_consumed_bytes = 0;
	AFE_BLOCK_T *Afe_Block = &pMemControl->rBlock;
	/* struct snd_pcm_runtime *runtime = substream->runtime; */
	PRINTK_AUD_DL2(" %s Afe_Block->u4DMAReadIdx = 0x%x\n", __func__, Afe_Block->u4DMAReadIdx);

	Auddrv_Dl2_Spinlock_lock();

	/* get total bytes to copy */
	/* Frameidx = audio_bytes_to_frame(substream , Afe_Block->u4DMAReadIdx); */
	/* return Frameidx; */

	if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DL2) == true) {
		HW_Cur_ReadIdx = Afe_Get_Reg(AFE_DL2_CUR);
		if (HW_Cur_ReadIdx == 0) {
			PRINTK_AUDDRV("[Auddrv] HW_Cur_ReadIdx ==0\n");
			HW_Cur_ReadIdx = Afe_Block->pucPhysBufAddr;
		}

		HW_memory_index = (HW_Cur_ReadIdx - Afe_Block->pucPhysBufAddr);
		if (HW_memory_index >= Afe_Block->u4DMAReadIdx) {
			Afe_consumed_bytes = HW_memory_index - Afe_Block->u4DMAReadIdx;
		} else {
			Afe_consumed_bytes = Afe_Block->u4BufferSize + HW_memory_index -
			    Afe_Block->u4DMAReadIdx;
		}

#ifdef AUDIO_64BYTE_ALIGN	/* no need to do 64byte align */
		Afe_consumed_bytes = Align64ByteSize(Afe_consumed_bytes);
#endif

		Afe_Block->u4DataRemained -= Afe_consumed_bytes;
		Afe_Block->u4DMAReadIdx += Afe_consumed_bytes;
		Afe_Block->u4DMAReadIdx %= Afe_Block->u4BufferSize;
		PRINTK_AUD_DL2
		    ("[Auddrv] HW_Cur_ReadIdx =0x%x HW_memory_index = 0x%x Afe_consumed_bytes  = 0x%x\n",
		     HW_Cur_ReadIdx, HW_memory_index, Afe_consumed_bytes);
		Auddrv_Dl2_Spinlock_unlock();

		Frameidx = audio_bytes_to_frame(substream, Afe_Block->u4DMAReadIdx);
	} else {
		Frameidx = audio_bytes_to_frame(substream, Afe_Block->u4DMAReadIdx);
		Auddrv_Dl2_Spinlock_unlock();
	}
	return Frameidx;
}
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_fm_i2s_awb_alsa_stop(struct snd_pcm_substream *substream)
{
	pr_warn("mtk_fm_i2s_awb_alsa_stop\n");
	StopAudioFMI2SAWBHardware(substream);
	RemoveMemifSubStream(Soc_Aud_Digital_Block_MEM_AWB, substream);

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

	return 0;
}
static int mtk_bt_dai_alsa_stop(struct snd_pcm_substream *substream)
{
	/* AFE_BLOCK_T *Dai_Block = &(Bt_Dai_Control_context->rBlock); */
	pr_warn("mtk_bt_dai_alsa_stop\n");

	SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DAI, false);

	SetMemoryPathEnable(Soc_Aud_Digital_Block_DAI_BT, false);
	if (GetMemoryPathEnable(Soc_Aud_Digital_Block_DAI_BT) == false)
		SetDaiBtEnable(false);

	StopAudioBtDaiHardware(substream);
	RemoveMemifSubStream(Soc_Aud_Digital_Block_MEM_DAI, substream);
	return 0;
}
static snd_pcm_uframes_t mtk_pcm_fmtx_pointer(struct snd_pcm_substream *substream)
{
    kal_int32 HW_memory_index = 0;
    kal_int32 HW_Cur_ReadIdx = 0;
    kal_uint32 Frameidx = 0;
    kal_int32 Afe_consumed_bytes = 0;

    AFE_BLOCK_T *Afe_Block = &pMemControl->rBlock;
    PRINTK_AUD_FMTX("[mtk_pcm_fmtx_pointer] Afe_Block->u4DMAReadIdx = 0x%x\n", Afe_Block->u4DMAReadIdx);

    Auddrv_Dl1_Spinlock_lock();

    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DL1) == true)
    {
        HW_Cur_ReadIdx = Afe_Get_Reg(AFE_DL1_CUR);
        if (HW_Cur_ReadIdx == 0)
        {
            PRINTK_AUD_FMTX("[Auddrv] HW_Cur_ReadIdx ==0 \n");
            HW_Cur_ReadIdx = Afe_Block->pucPhysBufAddr;
        }
        HW_memory_index = (HW_Cur_ReadIdx - Afe_Block->pucPhysBufAddr);
        if (HW_memory_index >=  Afe_Block->u4DMAReadIdx)
        {
            Afe_consumed_bytes = HW_memory_index - Afe_Block->u4DMAReadIdx;
        }
        else
        {
            Afe_consumed_bytes = Afe_Block->u4BufferSize + HW_memory_index - Afe_Block->u4DMAReadIdx ;
        }

        Afe_consumed_bytes = Align64ByteSize(Afe_consumed_bytes);

        Afe_Block->u4DataRemained -= Afe_consumed_bytes;
        Afe_Block->u4DMAReadIdx += Afe_consumed_bytes;
        Afe_Block->u4DMAReadIdx %= Afe_Block->u4BufferSize;
        PRINTK_AUD_DL1("[Auddrv] HW_Cur_ReadIdx =0x%x HW_memory_index = 0x%x Afe_consumed_bytes	= 0x%x\n", HW_Cur_ReadIdx, HW_memory_index, Afe_consumed_bytes);
        Auddrv_Dl1_Spinlock_unlock();
        return audio_bytes_to_frame(substream , Afe_Block->u4DMAReadIdx);
    }
    else
    {
        Frameidx = audio_bytes_to_frame(substream , Afe_Block->u4DMAReadIdx);
        Auddrv_Dl1_Spinlock_unlock();
        return Frameidx;
    }
}
static int mtk_mrgrx_awb_alsa_stop(struct snd_pcm_substream *substream)
{
	AFE_BLOCK_T *Awb_Block = &(Mrgrx_AWB_Control_context->rBlock);
	pr_debug("mtk_mrgrx_awb_alsa_stop\n");
	StopAudioAWBHardware(substream);
	Awb_Block->u4DMAReadIdx = 0;
	Awb_Block->u4WriteIdx = 0;
	Awb_Block->u4DataRemained = 0;
	RemoveMemifSubStream(Soc_Aud_Digital_Block_MEM_AWB);

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

	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)
    {
#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 mtk_voice_bt1_prepare(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtimeStream = substream->runtime;

	pr_debug("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) {
		pr_err("%s with SNDRV_PCM_STREAM_CAPTURE\n", __func__);
		return 0;
	}

	AudDrv_ANA_Clk_On();
	AudDrv_Clk_On();

	/* here start digital part */
	SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I02,
		      Soc_Aud_InterConnectionOutput_O17);
	SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I02,
		      Soc_Aud_InterConnectionOutput_O18);
	SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I14,
		      Soc_Aud_InterConnectionOutput_O02);
	SetConnection(Soc_Aud_InterCon_Connection, Soc_Aud_InterConnectionInput_I21,
		      Soc_Aud_InterConnectionOutput_O08);

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

	/* now use samplerate 8000 */
	SetModemSpeechDAIBTAttribute(runtimeStream->rate);
	SetDaiBtEnable(true);
	voice_bt1Pcm.mPcmModeWidebandSel =
	    (runtimeStream->rate ==
	     8000) ? Soc_Aud_PCM_MODE_PCM_MODE_8K : Soc_Aud_PCM_MODE_PCM_MODE_16K;
	voice_bt1Pcm.mAsyncFifoSel = Soc_Aud_BYPASS_SRC_SLAVE_USE_ASYNC_FIFO;
	SetModemPcmConfig(MODEM_1, voice_bt1Pcm);
	SetModemPcmEnable(MODEM_1, true);
	EnableAfe(true);
	voice_bt_Status = true;

	return 0;
}
static snd_pcm_uframes_t mtk_i2s0_awb_pcm_pointer(struct snd_pcm_substream *substream)
{
    kal_int32 HW_memory_index = 0;
    kal_int32 HW_Cur_ReadIdx = 0;
/*modified by jiaqing.yang for ALPS02074446(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P67) 20150706 begin*/
#if 0
	//kal_uint32 Frameidx =0;
#else
	kal_uint32 Frameidx =0;
#endif
/*modified by jiaqing.yang for ALPS02074446(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P67) 20150706 end*/
    AFE_BLOCK_T *Awb_Block = &(I2S0_AWB_Control_context->rBlock);
    PRINTK_AUD_AWB("mtk_i2s0_awb_pcm_pointer Awb_Block->u4WriteIdx;= 0x%x \n",Awb_Block->u4WriteIdx);
    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_AWB) == true)
    {
        // get total bytes to copysinewavetohdmi
/*modified by jiaqing.yang for ALPS02074446(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P67) 20150706 begin*/
#if 0
        //Frameidx =audio_bytes_to_frame(substream , Awb_Block->u4WriteIdx);
        //return Frameidx;
#else
		Frameidx =audio_bytes_to_frame(substream , Awb_Block->u4WriteIdx);
        return Frameidx;
#endif
/*modified by jiaqing.yang for ALPS02074446(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P67) 20150706 begin*/

/*modified by jiaqing.yang for ALPS02074446(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P67) 20150706 begin*/
#if 0
/*modified by jiaqing.yang for ALPS02074446(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P67) 20150706 end*/
        HW_Cur_ReadIdx = Align64ByteSize(Afe_Get_Reg(AFE_AWB_CUR));
        if (HW_Cur_ReadIdx == 0)
        {
            printk("[Auddrv] mtk_awb_pcm_pointer  HW_Cur_ReadIdx ==0 \n");
            HW_Cur_ReadIdx = Awb_Block->pucPhysBufAddr;
        }
        HW_memory_index = (HW_Cur_ReadIdx - Awb_Block->pucPhysBufAddr);
        Previous_Hw_cur = HW_memory_index;
        PRINTK_AUD_AWB("[Auddrv] mtk_i2s0_awb_pcm_pointer =0x%x HW_memory_index = 0x%x\n", HW_Cur_ReadIdx, HW_memory_index);
        return audio_bytes_to_frame(substream,Previous_Hw_cur);
/*modified by jiaqing.yang for ALPS02074446(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P67) 20150706 begin*/
#endif
/*modified by jiaqing.yang for ALPS02074446(For_JHZ6735M_65C_L_ALPS.L1.MP3.V1_P67) 20150706 end*/
    }
    return 0;
}
static int Audio_I2S0dl1_hdoutput_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    printk("%s()\n", __func__);
    if (ucontrol->value.enumerated.item[0] > ARRAY_SIZE(I2S0dl1_HD_output))
    {
        printk("return -EINVAL\n");
        return -EINVAL;
    }

    mI2S0dl1_hdoutput_control = ucontrol->value.integer.value[0];

    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_HDMI) == true)
    {
        printk("return HDMI enabled\n");
        return 0;
    }

    return 0;
}
static snd_pcm_uframes_t mtk_pcm_hdmi_pointer(struct snd_pcm_substream *substream)
{
	kal_int32 HW_memory_index = 0;
	kal_int32 HW_Cur_ReadIdx = 0;
	kal_uint32 Frameidx = 0;
	kal_int32 Afe_consumed_bytes = 0;
	AFE_BLOCK_T *Afe_Block = &(pMemControl->rBlock);

	PRINTK_AUD_HDMI("%s Afe_Block->u4DMAReadIdx = 0x%x\n", __func__,
		Afe_Block->u4DMAReadIdx);

	if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_HDMI) == true) {
		HW_Cur_ReadIdx = Afe_Get_Reg(AFE_HDMI_CUR);

		if (HW_Cur_ReadIdx == 0) {
			PRINTK_AUD_HDMI("[Auddrv] HW_Cur_ReadIdx == 0\n");
			HW_Cur_ReadIdx = Afe_Block->pucPhysBufAddr;
		}

		HW_memory_index = (HW_Cur_ReadIdx - Afe_Block->pucPhysBufAddr);

		if (HW_memory_index >= Afe_Block->u4DMAReadIdx)
			Afe_consumed_bytes = HW_memory_index - Afe_Block->u4DMAReadIdx;
		else {
			Afe_consumed_bytes = Afe_Block->u4BufferSize + HW_memory_index
				- Afe_Block->u4DMAReadIdx;
		}

		Afe_Block->u4DataRemained -= Afe_consumed_bytes;
		Afe_Block->u4DMAReadIdx += Afe_consumed_bytes;
		Afe_Block->u4DMAReadIdx %= Afe_Block->u4BufferSize;

		PRINTK_AUD_HDMI
			("[Auddrv] HW_Cur_ReadIdx = 0x%x, HW_memory_index = 0x%x, Afe_consumed_bytes = 0x%x\n",
			HW_Cur_ReadIdx, HW_memory_index, Afe_consumed_bytes);

		return audio_bytes_to_frame(substream, Afe_Block->u4DMAReadIdx);
	}

	Frameidx = audio_bytes_to_frame(substream, Afe_Block->u4DMAReadIdx);
	return Frameidx;
}
static int Audio_I2S0dl1_hdoutput_Set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    printk("%s()\n", __func__);
    if (ucontrol->value.enumerated.item[0] > ARRAY_SIZE(I2S0dl1_HD_output))
    {
        printk("return -EINVAL\n");
        return -EINVAL;
    }

    mI2S0dl1_hdoutput_control = ucontrol->value.integer.value[0];

    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_HDMI) == true )
    {
        printk("return HDMI enabled\n");
    
        return 0;
    }  

    if (mI2S0dl1_hdoutput_control)
    {
        // set APLL clock setting
        AudDrv_Clk_On();
        EnableApll1(true);
        EnableApll2(true);
        EnableI2SDivPower(AUDIO_APLL1_DIV0, true);
        EnableI2SDivPower(AUDIO_APLL2_DIV0, true);
        AudDrv_APLL1Tuner_Clk_On();
        AudDrv_APLL2Tuner_Clk_On();
    }
    else
    {  
        // 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();
        AudDrv_Clk_Off();
    }
    return 0;
}
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 void StopAudioCaptureHardware(struct snd_pcm_substream *substream)
{
    printk("StopAudioCaptureHardware \n");

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

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

    SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_VUL, false);

    // here to turn off digital part
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I00, Soc_Aud_InterConnectionOutput_O09);
    SetConnection(Soc_Aud_InterCon_DisConnect, Soc_Aud_InterConnectionInput_I01, Soc_Aud_InterConnectionOutput_O10);

    EnableAfe(false);
}
static int mtk_bt_dai_alsa_stop(struct snd_pcm_substream *substream)
{
	AFE_BLOCK_T *Dai_Block = &(Bt_Dai_Control_context->rBlock);
	pr_debug("mtk_bt_dai_alsa_stop\n");

	SetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_DAI, false);

	SetMemoryPathEnable(Soc_Aud_Digital_Block_DAI_BT, false);
	if (GetMemoryPathEnable(Soc_Aud_Digital_Block_DAI_BT) == false) {
		SetDaiBtEnable(false);
	}

	StopAudioBtDaiHardware(substream);

	Dai_Block->u4DMAReadIdx = 0;
	Dai_Block->u4WriteIdx = 0;
	Dai_Block->u4DataRemained = 0;

	RemoveMemifSubStream(Soc_Aud_Digital_Block_MEM_DAI);
	return 0;
}
static snd_pcm_uframes_t mtk_capture_pcm_pointer(struct snd_pcm_substream *substream)
{
    kal_int32 HW_memory_index = 0;
    kal_int32 HW_Cur_ReadIdx = 0;
    //kal_uint32 Frameidx = 0;
    kal_int32 Hw_Get_bytes = 0;
    AFE_BLOCK_T *UL1_Block = &(VUL_Control_context->rBlock);
    PRINTK_AUD_UL1("mtk_capture_pcm_pointer Awb_Block->u4WriteIdx;= 0x%x \n", UL1_Block->u4WriteIdx);
    Auddrv_UL1_Spinlock_lock();
    if (GetMemoryPathEnable(Soc_Aud_Digital_Block_MEM_VUL) == true)
    {

        HW_Cur_ReadIdx = Align64ByteSize(Afe_Get_Reg(AFE_VUL_CUR));
        if (HW_Cur_ReadIdx == 0)
        {
            PRINTK_AUD_UL1("[Auddrv] mtk_awb_pcm_pointer  HW_Cur_ReadIdx ==0 \n");
            HW_Cur_ReadIdx = UL1_Block->pucPhysBufAddr;
        }
        HW_memory_index = (HW_Cur_ReadIdx - UL1_Block->pucPhysBufAddr);

        // update for data get to hardware
        Hw_Get_bytes = (HW_Cur_ReadIdx - UL1_Block->pucPhysBufAddr) - UL1_Block->u4WriteIdx;
        if (Hw_Get_bytes < 0)
        {
            Hw_Get_bytes += UL1_Block->u4BufferSize;
        }
        UL1_Block->u4WriteIdx	+= Hw_Get_bytes;
        UL1_Block->u4WriteIdx	%= UL1_Block->u4BufferSize;
        UL1_Block->u4DataRemained += Hw_Get_bytes;
        PRINTK_AUD_UL1("[Auddrv] mtk_capture_pcm_pointer =0x%x HW_memory_index = 0x%x\n", HW_Cur_ReadIdx, HW_memory_index);
        Auddrv_UL1_Spinlock_unlock();

        return audio_bytes_to_frame(substream, HW_memory_index);
    }
    Auddrv_UL1_Spinlock_unlock();
    return 0;

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

#ifndef DENALI_FPGA_EARLYPORTING            
    mtk_wcn_cmb_stub_audio_ctrl((CMB_STUB_AIF_X)CMB_STUB_AIF_0);
#endif
    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();
	AudDrv_ANA_Clk_Off();
    mPrepareDone = false;
    SetFMEnableFlag(false);
    
    return 0;
}
Beispiel #29
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_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;
    SetFMEnableFlag(false);
    return 0;
}