/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

/*-----------------------------------------------------------------------------
 *
 * $Author$
 * $Date$
 * $RCSfile: cec_if.h,v $
 * $Revision$
 *
 *---------------------------------------------------------------------------*/
#ifndef _CEC_IF_H_
#define _CEC_IF_H_

#include "x_typedef.h"



#define CEC_TX_FRAME (TRUE)
#define CEC_RX_FRAME (FALSE)

#define CEC_LOG_BROADCAST CEC_LOG_UNREGISTERED
#define CEC_SUCCESS (0)
#define CEC_ERROR (1)


typedef enum {
    CEC_FRAME_RX,
    CEC_FRAME_TX
}CEC_FRAME_TYPE;

typedef struct
{
    UINT8 destination : 4;
    UINT8 initiator   : 4;
} CEC_HEADER_BLOCK;

typedef struct
{
    CEC_HEADER_BLOCK header;
    UINT8 opcode;
    UINT8 operand[16];
} CEC_FRAME_BLOCK;

typedef struct
{
    UINT8 size; // Actual frame block size.
    UINT8 sendidx;
    UINT8 reTXcnt;
    void* txtag;
    CEC_FRAME_BLOCK blocks;
} CEC_FRAME_DESCRIPTION;

typedef struct
{
    BOOL         fgActSrcReved;
    UINT8        u1PhyAddr[2];
}CEC_FRAME_ACTSRCREVED;

typedef enum
{
    OPCODE_FEATURE_ABORT = 0x00,                // 4
    OPCODE_IMAGE_VIEW_ON = 0x04,                // 2
    OPCODE_TUNER_STEP_INCREMENT = 0x05,            // 2
    OPCODE_TUNER_STEP_DECREMENT = 0x06,            // 2
    OPCODE_TUNER_DEVICE_STATUS = 0x07,            // 7 or 10
    OPCODE_GIVE_TUNER_DEVICE_STATUS = 0x08,            // 3
    OPCODE_RECORD_ON = 0x09,                // 3~10
    OPCODE_RECORD_STATUS = 0x0A,                // 3
    OPCODE_RECORD_OFF = 0x0B,                // 2
    OPCODE_TEXT_VIEW_ON = 0x0D,                // 2
    OPCODE_RECORD_TV_SCREEN = 0x0F,                // 2
    OPCODE_GIVE_DECK_STATUS = 0x1A,                // 3
    OPCODE_DECK_STATUS = 0x1B,                // 3
    OPCODE_SET_MENU_LANGUAGE = 0x32,            // 5
    OPCODE_CLEAR_ANALOGUE_TIMER = 0x33,            // 13
    OPCODE_SET_ANALOGUE_TIMER = 0x34,            // 13
    OPCODE_TIMER_STATUS = 0x35,                // 3 or 5
    OPCODE_STANDBY = 0x36,                    // 2
    OPCODE_PLAY = 0x41,                    // 3
    OPCODE_DECK_CONTROL = 0x42,                // 3
    OPCODE_TIMER_CLEARED_STATUS = 0x43,            // 3
    OPCODE_USER_CONTROL_PRESSED = 0x44,            // 3
    OPCODE_USER_CONTROL_RELEASED = 0x45,            // 2
    OPCODE_GIVE_OSD_NAME = 0x46,                // 2
    OPCODE_SET_OSD_NAME = 0x47,                // 3~16
    OPCODE_SET_OSD_STRING = 0x64,                // 4~16
    OPCODE_SET_TIMER_PROGRAM_TITLE = 0x67,            // 3~16
    OPCODE_SYSTEM_AUDIO_MODE_REQUEST = 0x70,        // 4
    OPCODE_GIVE_AUDIO_STATUS = 0x71,            // 2
    OPCODE_SET_SYSTEM_AUDIO_MODE = 0x72,            // 3
    OPCODE_REPORT_AUDIO_STATUS = 0x7A,            // 3
    OPCODE_GIVE_SYSTEM_AUDIO_MODE_STATUS = 0x7D,        // 2
    OPCODE_SYSTEM_AUDIO_MODE_STATUS = 0x7E,            // 3
    OPCODE_ROUTING_CHANGE = 0x80,                // 6
    OPCODE_ROUTING_INFORMATION = 0x81,            // 4
    OPCODE_ACTIVE_SOURCE = 0x82,                // 4
    OPCODE_GIVE_PHYSICAL_ADDRESS = 0x83,            // 2
    OPCODE_REPORT_PHYSICAL_ADDRESS = 0x84,            // 5
    OPCODE_REQUEST_ACTIVE_SOURCE = 0x85,            // 2
    OPCODE_SET_STREAM_PATH = 0x86,                // 4
    OPCODE_DEVICE_VENDOR_ID = 0x87,                // 5
    OPCODE_VENDOR_COMMAND = 0x89,                // <= 16
    OPCODE_VENDOR_REMOTE_BUTTON_DOWN = 0x8A,        // <= 16
    OPCODE_VENDOR_REMOTE_BUTTON_UP = 0x8B,            // 2
    OPCODE_GIVE_DEVICE_VENDOR_ID = 0x8C,            // 2
    OPCODE_MENU_REQUEST = 0x8D,                // 3
    OPCODE_MENU_STATUS = 0x8E,                // 3
    OPCODE_GIVE_DEVICE_POWER_STATUS = 0x8F,            // 2
    OPCODE_REPORT_POWER_STATUS = 0x90,            // 3
    OPCODE_GET_MENU_LANGUAGE = 0x91,            // 2
    OPCODE_SELECT_ANALOGUE_SERVICE = 0x92,            // 6
    OPCODE_SELECT_DIGITAL_SERVICE = 0x93,            // 9
    OPCODE_SET_DIGITAL_TIMER = 0x97,            // 16
    OPCODE_CLEAR_DIGITAL_TIMER = 0x99,            // 16
    OPCODE_SET_AUDIO_RATE = 0x9A,                // 3
    OPCODE_INACTIVE_SOURCE = 0x9D,                // 4
    OPCODE_CEC_VERSION = 0x9E,                // 3
    OPCODE_GET_CEC_VERSION = 0x9F,                // 2
    OPCODE_VENDOR_COMMAND_WITH_ID = 0xA0,            // <= 16
    OPCODE_CLEAR_EXTERNAL_TIMER = 0xA1,            // 10 ~ 11
    OPCODE_SET_EXTERNAL_TIMER = 0xA2,            // 10 ~ 11
    OPCODE_DEVICE_CHECK_ATMOS = 0xA3,
    OPCODE_GIVE_FEATURE       = 0xa5, /* ---> */
    OPCODE_REPORT_FEATURE     = 0xa6, /* ---> */
    OPCODE_ARC_INIT = 0xC0,                                      // 2
    OPCODE_ARC_REPORT_INIT = 0xC1,                      // 2
    OPCODE_ARC_REPORT_TERMINATE = 0xC2,          // 2
    OPCODE_ARC_REQUEST_INIT = 0xC3,                   // 2
    OPCODE_ARC_REQUEST_TERMINATE = 0xC4,       // 2
    OPCODE_ARC_TERMINATE = 0xC5,                        // 2
#ifdef SYS_MHL_SUPPORT
    OPCODE_MHL_CONTENT_ON = 0xE0,                // 4
    OPCODE_MHL_CONTENT_OFF = 0xE1,                // 4
    OPCODE_MHL_SCRATCHPAD_DATA = 0xE3,                // 4
#endif
    OPCODE_CDC_MESSAGE = 0xF8,
    OPCODE_ABORT = 0xFF,                    // 2
    OPCODE_NONE = 0xFFF
} CEC_OPCODE;
typedef enum
{
    CEC_LOG_TV                = 0,
    CEC_LOG_RECORDING_DEVICE1 = 1,
    CEC_LOG_RECORDING_DEVICE2 = 2,
    CEC_LOG_TUNER1            = 3,
    CEC_LOG_PLAYBACK_DEVICE1  = 4,
    CEC_LOG_AUDIO_SYSTEM      = 5,
    CEC_LOG_TUNER2            = 6,
    CEC_LOG_TUNER3            = 7,
    CEC_LOG_PLAYBACK_DEVICE2  = 8,
    CEC_LOG_RECORDING_DEVICE3 = 9,
    CEC_LOG_TUNER4            = 10,
    CEC_LOG_PLAYBACK_DEVICE3  = 11,
    CEC_LOG_RESERVED1         = 12,
    CEC_LOG_RESERVED2         = 13,
    CEC_LOG_FREE_USE          = 14,
    CEC_LOG_UNREGISTERED      = 15
} CEC_LOGICAL_ADDR;

typedef enum
{
    STATE_TX_SEND_FRAME = 0x0001,
    STATE_TX_WAIT_DATA_TAKEN = 0x0002,  /*Tx with data, not ping frame.*/
    STATE_TX_RESEND = 0x0004,
    STATE_TX_NOACK = 0x0008,
    STATE_TX_SEND_FRAME_OK = 0x0010,
    STATE_TX_BUSY = 0x0020,

    STATE_RX_GET_NEW_HEADER = 0x0100,
    STATE_RX_WAIT_COMPLETE = 0x0200
} CEC_SW_STATE;


typedef void (*x_cec_drv_nfy_data_arrival) (CEC_FRAME_DESCRIPTION* tInfo);
typedef void (*x_cec_drv_nfy_tx_result) (UINT8 u1Result,CEC_FRAME_DESCRIPTION *tInfo, void* txtag);
typedef void (*x_cec_drv_nfy_tx_header_result) (UINT8 u1Result, CEC_FRAME_DESCRIPTION *tInfo, UINT8 u1Dst);
typedef void (*x_cec_drv_nfy_5v_status) (UINT8 u1Port, BOOL fgOnOff, void *pvArg);


// *********************************************************************
// Export API
// *********************************************************************
EXTERN void CEC_SetRxCallback(x_cec_drv_nfy_data_arrival nfyinfo,void *arg);
EXTERN void CEC_SetTxCallback(x_cec_drv_nfy_tx_result nfyinfo,void *arg);
#ifdef CECNFY5VSTATUS
EXTERN void CEC_Set5VCallback(x_cec_drv_nfy_5v_status nfyfp,void *arg);
EXTERN void _Cec_Notify5VStatus(UINT8 u1Port, UINT8 u15vStatus);
#endif
EXTERN void CEC_SetTxHeaderCallback(x_cec_drv_nfy_tx_header_result nfyfp,void *arg);
#if defined(SYS_ANDROID_TV_TIF_SUPPORT)
EXTERN void CEC_HALSetMWReady(UINT8 mwrdy_val);
#else
EXTERN void CEC_SetMWReady(void);
#endif
EXTERN void CEC_SetLogicAddress(UINT8 u1LogicalAddr);
EXTERN void CEC_ClrLogicAddress(void);
EXTERN void CEC_SendStandby(UINT8 u1Standby);
EXTERN void CEC_SetWakeUp(UINT8 u1WakeUp);
EXTERN void CEC_SendStandardCmd(UINT8 u1StandardCmd);
EXTERN void CEC_SetEnable(BOOL fgEnable);
EXTERN UINT8 CEC_GetLogicalAddr(void);
EXTERN void CEC_CheckActiveSource(CEC_FRAME_ACTSRCREVED *prActiveSrc);
EXTERN void CEC_Init(void);
EXTERN void CEC_SetSysVtrl(UINT8 u1Onoff);
EXTERN void CEC_SetDbgLvl(UINT8 u1dbglvl);
EXTERN UINT8 CEC_EnqueueTx(CEC_FRAME_DESCRIPTION* frame);

//cec Arc control
#if defined (CC_HDMI_ARC_SPDIF_CTRL)|| defined (CC_HDMI_ARC_SPDIF_CTRL_89)
EXTERN void CEC_SetArcEnable(BOOL fgEnable);
EXTERN void CEC_LogArcEnable(void);
EXTERN void CEC_SetArcPinFunc(UINT8 u1PinFunc);
#endif

EXTERN void vHDMISetARCSwitch(UINT8 u1Port);
#ifdef SYS_ANDROID_TV_TIF_SUPPORT
EXTERN void CEC_SetArcSwitch(UINT8 u1Port);
#endif

#if defined(SYS_MHL_SUPPORT)
EXTERN CEC_FRAME_DESCRIPTION *_Cbus_GetTxReadFrame(void);
EXTERN CEC_FRAME_DESCRIPTION *_Cbus_GetRxReadFrame(void);
EXTERN void _Cbus_NotifyTxResult(UINT8 result, CEC_FRAME_DESCRIPTION *frame,void *arg);
EXTERN void _Cbus_NotifyRxResult(CEC_FRAME_DESCRIPTION *frame);
EXTERN void _Cbus_DequeueTx(void);
EXTERN void _Cbus_EnqueueRx(CEC_FRAME_DESCRIPTION *prFrame);
EXTERN void _Cbus_DequeueRx(void);
#endif
EXTERN void CEC_PrintStatus(void);
void vHDMIGetCECVendorID(UINT32 *pID);
#endif /* _CEC_IF_H_ */

