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 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 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;
    AFE_BLOCK_T *Awb_Block = &(TDM_VUL_Control_context->rBlock);
    PRINTK_AUD_UL1("mtk_capture_pcm_pointer Awb_Block->u4WriteIdx;= 0x%x \n", Awb_Block->u4WriteIdx);
    if (TDM_VUL_Control_context->interruptTrigger == 1)
    {

        Previous_Hw_cur = Awb_Block->u4WriteIdx;
        return Awb_Block->u4WriteIdx >> 2;

        HW_Cur_ReadIdx = Afe_Get_Reg(AFE_AWB_CUR);
        if (HW_Cur_ReadIdx == 0)
        {
            PRINTK_AUD_UL1("[Auddrv] mtk_capture_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_UL1("[Auddrv] mtk_capture_pcm_pointer =0x%x HW_memory_index = 0x%x\n", HW_Cur_ReadIdx, HW_memory_index);
        TDM_VUL_Control_context->interruptTrigger = 0;
        return (HW_memory_index >> 2);
    }
static int mtk_capture_pcm_copy(struct snd_pcm_substream *substream,
                                int channel, snd_pcm_uframes_t pos,
                                void __user *dst, snd_pcm_uframes_t count)
{

    AFE_MEM_CONTROL_T *pVUL_MEM_ConTrol = NULL;
    AFE_BLOCK_T  *Vul_Block = NULL;
    char *Read_Data_Ptr = (char *)dst;
    ssize_t DMA_Read_Ptr = 0 , read_size = 0, read_count = 0;
    //struct snd_pcm_runtime *runtime = substream->runtime;
    unsigned long flags;

    PRINTK_AUD_UL1("mtk_capture_pcm_copy pos = %lucount = %lu \n ", pos, count);
    // get total bytes to copy
    count = Align64ByteSize(audio_frame_to_bytes(substream , count));

    // check which memif nned to be write
    pVUL_MEM_ConTrol = VUL_Control_context;
    Vul_Block = &(pVUL_MEM_ConTrol->rBlock);

    if (pVUL_MEM_ConTrol == NULL)
    {
        printk("cannot find MEM control !!!!!!!\n");
        msleep(50);
        return 0;
    }

    if (Vul_Block->u4BufferSize <= 0)
    {
        msleep(50);
        printk("Vul_Block->u4BufferSize <= 0  =%d\n", Vul_Block->u4BufferSize);
        return 0;
    }

    if (CheckNullPointer((void *)Vul_Block->pucVirtBufAddr))
    {
        printk("CheckNullPointer  pucVirtBufAddr = %p\n", Vul_Block->pucVirtBufAddr);
        return 0;
    }

    spin_lock_irqsave(&auddrv_ULInCtl_lock, flags);
    if (Vul_Block->u4DataRemained >  Vul_Block->u4BufferSize)
    {
        PRINTK_AUD_UL1("AudDrv_MEMIF_Read u4DataRemained=%x > u4BufferSize=%x" , Vul_Block->u4DataRemained, Vul_Block->u4BufferSize);
        Vul_Block->u4DataRemained = 0;
        Vul_Block->u4DMAReadIdx   = Vul_Block->u4WriteIdx;
    }
    if (count >  Vul_Block->u4DataRemained)
    {
        read_size = Vul_Block->u4DataRemained;
    }
    else
    {
        read_size = count;
    }

    DMA_Read_Ptr = Vul_Block->u4DMAReadIdx;
    spin_unlock_irqrestore(&auddrv_ULInCtl_lock, flags);

    PRINTK_AUD_UL1("AudDrv_MEMIF_Read finish0, read_count:%x, read_size:%x, u4DataRemained:%x, u4DMAReadIdx:0x%x, u4WriteIdx:%x \r\n",
                   (unsigned int)read_count, (unsigned int)read_size, Vul_Block->u4DataRemained, Vul_Block->u4DMAReadIdx, Vul_Block->u4WriteIdx);

    if (DMA_Read_Ptr + read_size < Vul_Block->u4BufferSize)
    {
        if (DMA_Read_Ptr != Vul_Block->u4DMAReadIdx)
        {
            printk("AudDrv_MEMIF_Read 1, read_size:%zu, DataRemained:%x, DMA_Read_Ptr:0x%zu, DMAReadIdx:%x \r\n",
                   read_size, Vul_Block->u4DataRemained, DMA_Read_Ptr, Vul_Block->u4DMAReadIdx);
        }

        if (copy_to_user((void __user *)Read_Data_Ptr, (Vul_Block->pucVirtBufAddr + DMA_Read_Ptr), read_size))
        {

            printk("AudDrv_MEMIF_Read Fail 1 copy to user Read_Data_Ptr:%p, pucVirtBufAddr:%p, u4DMAReadIdx:0x%x, DMA_Read_Ptr:%zu,read_size:%zu", Read_Data_Ptr, Vul_Block->pucVirtBufAddr, Vul_Block->u4DMAReadIdx, DMA_Read_Ptr, read_size);
            return 0;
        }

        read_count += read_size;
        spin_lock(&auddrv_ULInCtl_lock);
        Vul_Block->u4DataRemained -= read_size;
        Vul_Block->u4DMAReadIdx += read_size;
        Vul_Block->u4DMAReadIdx %= Vul_Block->u4BufferSize;
        DMA_Read_Ptr = Vul_Block->u4DMAReadIdx;
        spin_unlock(&auddrv_ULInCtl_lock);

        Read_Data_Ptr += read_size;
        count -= read_size;

        PRINTK_AUD_UL1("AudDrv_MEMIF_Read finish1, copy size:%x, u4DMAReadIdx:0x%x, u4WriteIdx:%x, u4DataRemained:%x \r\n",
                       (unsigned int)read_size, Vul_Block->u4DMAReadIdx, Vul_Block->u4WriteIdx, Vul_Block->u4DataRemained);
    }

    else
    {
        uint32 size_1 = Vul_Block->u4BufferSize - DMA_Read_Ptr;
        uint32 size_2 = read_size - size_1;

        if (DMA_Read_Ptr != Vul_Block->u4DMAReadIdx)
        {

            printk("AudDrv_MEMIF_Read 2, read_size1:%x, DataRemained:%x, DMA_Read_Ptr:%zu, DMAReadIdx:%x \r\n",
                   size_1, Vul_Block->u4DataRemained, DMA_Read_Ptr, Vul_Block->u4DMAReadIdx);
        }
        if (copy_to_user((void __user *)Read_Data_Ptr, (Vul_Block->pucVirtBufAddr + DMA_Read_Ptr), (unsigned int)size_1))
        {

            printk("AudDrv_MEMIF_Read Fail 2 copy to user Read_Data_Ptr:%p, pucVirtBufAddr:%p, u4DMAReadIdx:0x%x, DMA_Read_Ptr:%zu,read_size:%zu",
                   Read_Data_Ptr, Vul_Block->pucVirtBufAddr, Vul_Block->u4DMAReadIdx, DMA_Read_Ptr, read_size);
            return 0;
        }

        read_count += size_1;
        spin_lock(&auddrv_ULInCtl_lock);
        Vul_Block->u4DataRemained -= size_1;
        Vul_Block->u4DMAReadIdx += size_1;
        Vul_Block->u4DMAReadIdx %= Vul_Block->u4BufferSize;
        DMA_Read_Ptr = Vul_Block->u4DMAReadIdx;
        spin_unlock(&auddrv_ULInCtl_lock);


        PRINTK_AUD_UL1("AudDrv_MEMIF_Read finish2, copy size_1:%x, u4DMAReadIdx:0x%x, u4WriteIdx:0x%x, u4DataRemained:%x \r\n",
                       size_1, Vul_Block->u4DMAReadIdx, Vul_Block->u4WriteIdx, Vul_Block->u4DataRemained);

        if (DMA_Read_Ptr != Vul_Block->u4DMAReadIdx)
        {

            printk("AudDrv_AWB_Read 3, read_size2:%x, DataRemained:%x, DMA_Read_Ptr:%zu, DMAReadIdx:%x \r\n",
                   size_2, Vul_Block->u4DataRemained, DMA_Read_Ptr, Vul_Block->u4DMAReadIdx);
        }
        if (copy_to_user((void __user *)(Read_Data_Ptr + size_1), (Vul_Block->pucVirtBufAddr + DMA_Read_Ptr), size_2))
        {

            printk("AudDrv_MEMIF_Read Fail 3 copy to user Read_Data_Ptr:%p, pucVirtBufAddr:%p, u4DMAReadIdx:0x%x , DMA_Read_Ptr:%zu, read_size:%zu", Read_Data_Ptr, Vul_Block->pucVirtBufAddr, Vul_Block->u4DMAReadIdx, DMA_Read_Ptr, read_size);
            return read_count << 2;
        }

        read_count += size_2;
        spin_lock(&auddrv_ULInCtl_lock);
        Vul_Block->u4DataRemained -= size_2;
        Vul_Block->u4DMAReadIdx += size_2;
        DMA_Read_Ptr = Vul_Block->u4DMAReadIdx;
        spin_unlock(&auddrv_ULInCtl_lock);

        count -= read_size;
        Read_Data_Ptr += read_size;

        PRINTK_AUD_UL1("AudDrv_MEMIF_Read finish3, copy size_2:%x, u4DMAReadIdx:0x%x, u4WriteIdx:0x%x u4DataRemained:%x \r\n",
                       size_2, Vul_Block->u4DMAReadIdx, Vul_Block->u4WriteIdx, Vul_Block->u4DataRemained);
    }

    return read_count >> 2;
}