/**
 * @file drv_hdmi_cec.c
 * @brief HDMI RX 模块提供的驱动层
 * @details 该模块接口提供给driver处理CEC相关接口。
 * @author HiView SoC Software Team
 * @version 0.0.1
 * @date 20220822
 * @copyright Copyright(c),2022-8, Hiview Software. All rights reserved.
 * @par History: 
 * <table>
 * <tr><th>作者                         <th>日期             <th>描述
 * <tr><td>HiView SoC Software Team   <td>20220822       <td>Create and first Version.
 * </table>
**/

#include "hv_comm_Assert.h"
#include "hv_vos_Comm.h"
#include "hv_chip_Config.h"
#include "hv_drv_HdmiInc.h"
#include "hv_cal_HdmiInc.h"
#include "hv_drv_HdmiRx.h"

static SCecControl g_stCecControl[HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM] = {0};

#define HV_MAX_CEC_VENDOR_INFO_LENTH  25

typedef struct
{
    UINT32          uiDeviceVenId;
    UCHAR8          VendorName[HV_MAX_CEC_VENDOR_INFO_LENTH];
} DeviceVendorInfo;

DeviceVendorInfo gstVendorSupportList[] = 
{
    {0x080046, "Sony Corporation"},
    {0x70F8AE, "Microsoft Corporation"}
};

UINT32 guiDeviceVendorID = 0;

VOID Hv_Drv_HdmiRx_CecInit(UCHAR8 ucPortIndex)
{
    /*检查入参*/
    HV_ASSERT_TRUE_VOID(ucPortIndex <= HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM);

    Hv_Vos_QUEUE_INIT_PARAMS stQueueParam;
    stQueueParam.queueLen = DMAX_CEC_MSG_CACHE_NUM;
    stQueueParam.itemSize = sizeof(SCecMsg);

    g_stCecControl[ucPortIndex].pstCECMsgQueue = Hv_Vos_QueueInit(&stQueueParam);
    g_stCecControl[ucPortIndex].ucDestinationLA = 0x0F;
    g_stCecControl[ucPortIndex].stCecCmd.ucGet = 0;
    g_stCecControl[ucPortIndex].stCecCmd.ucPut = 0;
    memset(g_stCecControl[ucPortIndex].stCecCmd.aucCmdBuf,0,sizeof(g_stCecControl[ucPortIndex].stCecCmd.aucCmdBuf));

    Hv_Cal_HdmiRx_CecInit(ucPortIndex);

    return;
}

/**
* @brief cec recv data
*/
Status Hv_Drv_HdmiRx_CecRecvData(UCHAR8 ucPortIndex)
{
    SCecMsg stCecMsg = {0x0,};
    SCecMsg stCecMsgSend = {0x0,};
    UCHAR8  ucMsgLen = 0;

    HV_ASSERT_TRUE_RET_NO_LOG(ucPortIndex <= HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM, HV_FAILURE);

    ucMsgLen = Hv_Cal_HdmiRx_ReceiveCecMsg(ucPortIndex, (UCHAR8 *)(&stCecMsg));
    HV_LOG_DEBUG(HDMI, "CEC RCV H:%x,O:%x,Len:%d",stCecMsg.ucHeader,stCecMsg.ucOPCode,ucMsgLen);
    switch (stCecMsg.ucOPCode)
    {
        case CEC_STANDBY:
        {
            break;
        }

        case CEC_MENU_STATUS:
        {
            break;
        }

        case CEC_USER_CONTROL_PRESSED:
        case CEC_USER_CONTROL_RELEASED:
        {
            // 按键响应 ==> 对应关机
            // ePowerToggleFunction ||  ePowerOffFunction
            if(stCecMsg.aucOperandBuf[0] == ePowerToggleFunction || stCecMsg.aucOperandBuf[0] == ePowerOffFunction)
            {
                HV_LOG_INFO(HDMI, "Power OFF the TV");
            }
            break;
        }

        case CEC_DEVICE_VENDOR_ID:
        {
            if(ucMsgLen == 5)
            {
                guiDeviceVendorID = stCecMsg.aucOperandBuf[0];
                guiDeviceVendorID <<= 8;
                guiDeviceVendorID += stCecMsg.aucOperandBuf[1];
                guiDeviceVendorID <<= 8;
                guiDeviceVendorID += stCecMsg.aucOperandBuf[2];

                HV_LOG_INFO(HDMI, "CEC-Device-Vendor-ID:0x%X", guiDeviceVendorID);
            }

            break;
        }

        case CEC_GIVE_PHYSICAL_ADDRESS:
        {
            if((stCecMsg.ucHeader & 0xF) == 0x0 || (stCecMsg.ucHeader & 0xF) == 0xF)
            {
                stCecMsgSend.ucHeader = 0xF;
                stCecMsgSend.ucOPCode = CEC_REPORT_PHYSICAL_ADDRESS;
                stCecMsgSend.aucOperandBuf[0] = (ucPortIndex + 1) << 4;
                stCecMsgSend.aucOperandBuf[1] = 0x0;
                stCecMsgSend.aucOperandBuf[2] = 0x0;
                Hv_Cal_HdmiRx_SendCecMsg(ucPortIndex, (UCHAR8 *)(&stCecMsgSend), 5);
                HV_LOG_DEBUG(HDMI, "CEC Send PHY ADDR");
            }

            break;
        }

        case CEC_ACTIVE_SOURCE:
        {
            //开机指令
            if((stCecMsg.ucHeader & 0xF) == 0x0 || (stCecMsg.ucHeader & 0xF) == 0xF)
            {
                HV_LOG_DEBUG(HDMI, "RCV CEC INACTIVE MSG.");
                HV_LOG_DEBUG(HDMI, "CEC RCV H:%x,O:%x,Len:%d", stCecMsg.ucHeader, stCecMsg.ucOPCode, ucMsgLen);
            }
            break;
        }

        case CEC_INACTIVE_SOURCE:
        {
            //关机指令  
            if((stCecMsg.ucHeader & 0xF) == 0x0)
            {
                HV_LOG_DEBUG(HDMI, "RCV CEC INACTIVE MSG.");
                //if(pfSendPowerOff != NULL)
                //{
                //    pfSendPowerOff();
                //}
            }
            break;
        }

        case CEC_GIVE_DEVICE_POWER_STATUS:
        {
            // 当前状态;
            if((stCecMsg.ucHeader & 0xF) == 0x0)
            {
                stCecMsgSend.ucHeader = (stCecMsg.ucHeader >> 4) & 0xF;
                stCecMsgSend.ucOPCode = CEC_REPORT_POWER_STATUS;
                stCecMsgSend.aucOperandBuf[0] = eCecPowerStatusOn;
                Hv_Cal_HdmiRx_SendCecMsg(ucPortIndex, (UCHAR8 *)(&stCecMsgSend), 3);
                HV_LOG_DEBUG(HDMI, "CEC RSP POWER STATUS");
            }

            break;
        }

        case CEC_GET_VERSION:
        {
            if((stCecMsg.ucHeader & 0xF) == 0x0 || (stCecMsg.ucHeader & 0xF) == 0xF)
            {
                stCecMsgSend.ucHeader = stCecMsg.ucHeader >> 4;
                stCecMsgSend.ucOPCode = CEC_VERSION;
                stCecMsgSend.aucOperandBuf[0] = 0x4;
                Hv_Cal_HdmiRx_SendCecMsg(ucPortIndex, (UCHAR8 *)(&stCecMsgSend), 3);
                HV_LOG_DEBUG(HDMI, "CEC Send VERSION");
            }

            break;
        }

        case CEC_INITIATE_ARC:
        {
            break;
        }

        default:
        {
            break;
        }
    }

    return HV_SUCCESS;
}


