/**
 * @file hv_mw_AudioInterrupt.c
 * @brief audio driver chip abstract layer file.
 * @details This file provides the following functions: \n
 *          (1) Audio Mute & unMute Interrupt functions \n
 *
 * @author HiView SoC Software Team
 * @version 1.0.0
 * @date 2023-01-16
 * @copyright Copyright(c),2022-8, Hiview Software. All rights reserved.
 * @par History:
 * <table>
 * <tr><th>Author                        <th>Date         <th>Change Description
 * <tr><td>HiView SoC Software Team      <td>2022-08-23   <td>init
 * </table>
 */


#include "hv_comm_Assert.h"
#include "hv_vos_Comm.h"
#include "hv_chip_Irq.h"
#include "hv_mw_InputPortManager.h"
#include "hv_mw_Channel_Manager.h"
#include "hv_mw_SystemManager.h"
#include "hv_mw_AudioInterrupt.h"
#include "hv_drv_DpuCommon.h"
#include "hv_drv_DpuMainMute.h"
#include "hv_drv_Audio.h"
#include "hv_cal_Audio.h"
#ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
#include "hv_drv_DpuSubMute.h"
#endif

static HV_VOS_ISR_RESULT_E Hv_Mw_Audio_IRQHandler(UINT32 irqNum, void *arg)
{
    UINT32 uiRegValue = Hv_Cal_Audio_DataPathMuteSource();
    Hv_Vos_WClrMiscInt(irqNum - HV_CHIP_IRQ_BASE);
    Hv_Vos_MaskIrq(irqNum);

    if ((uiRegValue & _AUDIO_PATH_UNMUTE) && (g_uiInterruptTriggerMode == _AUDIO_INT_EDGE_P))
    {
        //Mute DAC
        Hv_Drv_Audio_DACMute(_AUDIO_MUTE_BIT_HW);
        //Trigger unMute
        Hv_Cal_Audio_SetUnMuteTrigger();
        //Clear Int flag
        Hv_Cal_Audio_ClearInt(_AUDIO_PATH_UNMUTE);
        Hv_Vos_WClrMiscInt(irqNum - HV_CHIP_IRQ_BASE);
        Hv_Vos_UnmaskIrq(HV_CHIP_IRQ_AUDIO);
        return HV_VOS_ISR_HANDLED;
    }
    else
    {
        SystemEvent     stSystemEvent;
        HV_VOS_QUEUE_S* xSystembQueue = Hv_Mw_System_GetSystemQueue();
        HV_ASSERT_VALID_PTR_RET_NO_LOG(xSystembQueue, HV_VOS_ISR_HANDLED);

        if ((uiRegValue & _AUDIO_PATH_UNMUTE) && (g_uiInterruptTriggerMode == _AUDIO_INT_EDGE_N))
        {
            Hv_Cal_Audio_DisableAllInt_ClearInt(_AUDIO_PATH_UNMUTE);
            //Trigger Mute
            Hv_Cal_Audio_SetMuteTrigger();

            stSystemEvent.usEventId = CHANNEL_EVENT_ID_AUDIO_MUTE_STATE_CHANGE;
        }
        else if (uiRegValue & _AUDIO_DETECT_FS)
        {
            //if audio pll is unlocked, do nothing
            if(Hv_Drv_Audio_GetClockLockState() == 0)
            {
                return HV_VOS_ISR_HANDLED;
            }

            Hv_Cal_Audio_DisableAllInt_ClearInt(_AUDIO_DETECT_FS);

            //Mute DAC
            Hv_Drv_Audio_DACMute(_AUDIO_MUTE_BIT_FS);

            stSystemEvent.usEventId = CHANNEL_EVENT_ID_AUDIO_FS_CHANGE;
        }
        else
        {
            HV_LOG_ASSERT(AUDIO, "Audio interrupt handler: LOGICAL ERROR!");
        }

        stSystemEvent.enEventType = SYSTEM_REV_EVENT_TYPE_CHANNEL;
        stSystemEvent.ucChannelType = Hv_Mw_Channel_IsAudioOnThisChannel(CHANNEL_TYPE_MAIN) ? CHANNEL_TYPE_MAIN : CHANNEL_TYPE_SUB;
        stSystemEvent.uiValue = uiRegValue;
        Hv_Vos_QueueSendFromISR(xSystembQueue, (void *)&stSystemEvent);

        return HV_VOS_ISR_HANDLED;
    }
}

Status Hv_Mw_Audio_Interrupt_Enable(LinkPortIndex eAudioSrc)
{
    if(eAudioSrc < LINK_PORT_INDEX_DP_RX0)
    {
        Hv_Cal_Audio_ClearTXMute_EnableAllInt(HV_FALSE);
    }
    else
    {
        Hv_Cal_Audio_ClearTXMute_EnableAllInt(HV_TRUE);
    }

    return HV_SUCCESS;
}

Status Hv_Mw_Audio_Interrupt_Disable(VOID)
{
    Hv_Cal_Audio_DisableAllInt_ClearInt(0x7ff);
    Hv_Vos_WClrMiscInt(HV_CHIP_IRQ_AUDIO - HV_CHIP_IRQ_BASE);
    Hv_Vos_MaskIrq(HV_CHIP_IRQ_AUDIO);


    return HV_SUCCESS;
}

Status Hv_Mw_Audio_Interrupt_Init(VOID)
{
    Hv_Vos_AttachIsr(HV_CHIP_IRQ_AUDIO, Hv_Mw_Audio_IRQHandler, NULL);
    Hv_Vos_UnmaskIrq(HV_CHIP_IRQ_AUDIO);

    return HV_SUCCESS;
}

