/* 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: xiaojun.zhu $
 * $Date  $
 * $RCSfile: drv_vbi.h,v $
 * $Revision: #2 $
 *
 *---------------------------------------------------------------------------*/
#ifndef _DRV_VBI_H_
#define _DRV_VBI_H_

#include "typedef.h"
#include "nptv_if.h"
#include "hw_vbi.h"
#include "drv_tvd.h"

#if AUTO_CC_DETECT
#define SCANLINE_CC_RETRY   10
#define SCANLINE_CC_NUM 4
#define SCANLINE_CC_TESTLOOP    20
#define SCANLINE_CC_TH    8
#define AUTO_CC_NOT_DEFULT_TH 3
typedef enum
{
    SCANLINE_IDLE = 0,
    SCANLINE_INIT,
    SCANLINE_START,
    SCANLINE_FINISH,
    SCANLINE_NOT_FOUND
} SCANLINE_STATE_T;
#endif


/* VBI working modes */
typedef enum
{
    VBI_CC_VCHIP_MODE = 0,
    VBI_TTX_MODE      = 1,
    VBI_ANAS_MODE     = 2,
    VBI_WSS_ONLY_MODE = 3,
    VBI_MODE_NUM
}VBI_MODE_T;

typedef enum
{
    VBI_TTX_SERVICE = 0,
    VBI_CC_SERVICE,
    VBI_CC2X_SERVICE,
    VBI_WSS525_SERVICE,
    VBI_WSS625_SERVICE,
    VBI_VPS_SERVICE,
    VBI_TYPE_B_WSS_SERVICE,
    VBI_SERVICE_NUM
}VBI_SERVICE_T;

typedef enum
{
    E_FIELD_NORMAL = 0,
    E_FIELD_INVERSED, 
    E_FIELD_UNKNOW,
}AV_FIELD_TYPE;

typedef enum
{
    E_AV_NTSC = 0,
    E_AV_PAL,
    E_AV_UNKNOW,
}AV_SRC_TYPE;

typedef enum
{
    CLINfy_Disable = 0,
    CLINfy_EnOnly  = 1,  //Turn On CLI Nfy Path Only
    CLINfy_EnAll   = 2,  //Turn On MW Nfy Path & CLI Nfy Path
}CLI_NFY_T;

typedef struct
{
    AV_FIELD_TYPE E_AVFieldType;
    AV_SRC_TYPE E_AVSrcType;
}__attribute__ ((packed)) VBI_AV_INFO;

typedef struct
{
    BOOL   bEnWSS525TOut; //Enable/Disable WSS525TimeOut Mechanism 
    BOOL   bEnWSS625TOut; //Enable/Disable WSS625TimeOut mechanism
    UINT8  u1ThresHold;   //Not Detected for last X(ThresHold) consecutive frames, 
    UINT32 u4NoWSSData;   //Notifyed u4NOWSSData to upperlayer.
}__attribute__ ((packed)) VBI_WSS_TIMEOUT_INFO;


typedef struct
{
    BOOL   bEnCCTimeOut;  //Enable/Disable CC TimeOut mechanism
    UINT8  u1ThresHold;   //Not Detected for last X(ThresHold) consecutive frames, 
    UINT8  u1NoCCData0;   //Notifyed u1NoCCData0 to upperlayer. 
    UINT8  u1NoCCData1;   //Notifyed u1NoCCData1 to upperlayer. 
}__attribute__ ((packed)) VBI_CC_TIMEOUT_INFO;


typedef struct
{
    UINT8 u1F0_SET;  // Filed0 Line Setting.
    UINT8 u1F1_SET;  // Field1 Line Setting.
}__attribute__ ((packed)) LINE;

typedef struct
{
    UINT8 u1F0_START; // Field0 Start Setting. 
    UINT8 u1F0_END;   // Field0 end Setting. 
    UINT8 u1F1_START; // Field1 Start Setting. 
    UINT8 u1F1_END;   // Field1 end Setting. 
}__attribute__ ((packed)) LINE_RANGE;


typedef struct
{
    BOOL bEnMenuLineSet;
    LINE AV_NTSC_CC;
    LINE AV_PAL_CC;
    LINE AV_NTSC_WSS;
    LINE AV_PAL_WSS;
    LINE AV_PAL_VPS;
    LINE_RANGE AV_PAL_TT;
    LINE_RANGE AV_NTSC_CC2X;
    LINE HDTV_NTSC_CC;
    LINE HDTV_PAL_CC;
    LINE HDTV_NTSC_WSS;
    LINE HDTV_PAL_WSS;      
    LINE HDTV_NTSC_WSS_PSCAN; //480P CGMS WSS
    LINE HDTV_PAL_WSS_PSAN;   //576P CGMS WSS
    LINE HDTV_720P_WSS; //720P CGMS WSS
    LINE HDTV_1080I_WSS;   //1080I CGMS WSS
    LINE HDTV_NTSC_TYPE_B_WSS_PSCAN; //480P TYPE B CGMS WSS
    LINE HDTV_720P_TYPE_B_WSS; //720P TYPE B CGMS WSS
    LINE HDTV_1080I_TYPE_B_WSS;   //1080I TYPE B CGMS WSS
    LINE_RANGE HDTV_PAL_TT;
}__attribute__ ((packed)) VBI_LINE_INFO;

#ifdef CC_ATV_PVR_SUPPORT
#define VBI_PVR_SEI_UNIT    50
typedef enum
{
    E_PVR_CC = 0,
    E_PVR_AFD,
    E_PVR_TTX,
    E_PVR_UNKNOW,
}VBI_PVR_NOTIFY_TYPE;

typedef struct
{
    UINT8 u1NotifyType;
    UINT32 u4StartAddr;
    UINT32 u4Size;
    UINT32 u4STC;
}__attribute__ ((packed)) VBI_PVR_NOTIFY_DATA;

typedef struct
{
    UINT8 u1CCType:2;
    UINT8 u1CCValid:1;
    UINT8 u1MarkerBits:5;
    UINT8 u1CCData1;
    UINT8 u1CCData2;
}__attribute__ ((packed)) VBI_PVR_CC_DATA;

typedef struct
{
    //NAL Unit
    UINT32 u4NALUStartCode;//0x00000001
    UINT8 u1NalUnitType:5;//0x6: SEI_RBSP
    UINT8 u1NalRefIdc:2;
    UINT8 u1ForbiddenZeroBit:1;
    UINT8 u1SEIPayloadType;//0x4: 
    UINT8 u1SEIPayloadSize;

    //SEI Syntax
    UINT8 u1CountryCode;//0xB5
    UINT16 u2ProviderCode;//0x0031
    UINT32 u4UserIdentifier;//0x47413934

    //User Structure
    UINT32 u4UserDataStartCode;//0x000001B2
    UINT32 u4ATSCIdentifier;//0x47413934
    UINT8 u1UserDataTypeCode;//0x03
    UINT8 u1CCCount:5;
    UINT8 u1AdditionalDataFlag:1;
    UINT8 u1ProcessCCFlag:1;
    UINT8 u1ProcessEMFlag:1;
    UINT8 u1EMData;
    VBI_PVR_CC_DATA arCCData[2];
    UINT8 u1MarkerBits;

    UINT8 u1RbspTrailingBits;//0x80
}__attribute__ ((packed)) VBI_PVR_CC_SEI_DATA;

typedef struct
{
    //NAL Unit
    UINT32 u4NALUStartCode;//0x00000001
    UINT8 u1NalUnitType:5;//0x6: SEI_RBSP
    UINT8 u1NalRefIdc:2;
    UINT8 u1ForbiddenZeroBit:1;
    UINT8 u1SEIPayloadType;//0x4: 
    UINT8 u1SEIPayloadSize;

    //SEI Syntax
    UINT8 u1CountryCode;//0xB5
    UINT16 u2ProviderCode;//0x0031
    UINT32 u4UserIdentifier;//0x44544731

    //User Structure
    UINT32 u4UserDataStartCode;//0x000001B2?
    UINT32 u4AFDIdentifier;//0x44544731
    UINT8 u1Reserved1:6;
    UINT8 u1ActiveFormatFlag:1;
    UINT8 u1Zero:1;
    UINT8 u1ActiveFormat:4;
    UINT8 u1Reserved2:4;
    
    UINT8 u1RbspTrailingBits;//0x80
}__attribute__ ((packed)) VBI_PVR_AFD_SEI_DATA;
#endif

/** Function prototype for CLI cmd. */
typedef void (*VBI_PFN_CLI_NFY) (void *pInput);

/* VBI0 is with Composite for weak signal/eye-height processing */
/* VBI2 is with Component for there is no weak signal issue */

/* Two VBI slicers */
#define VBI0 1
#define VBI2 2

/* FIFO mode */
#define CC_FIFO		0
#define TTX_FIFO    1

/* CC2X Config */
#define SUPPORT_CLOSE_CAPTION_2X 0
#define EN_TVE_CB                1
#ifdef CC_TVD_SUPPORT_DDI
#define FORCE_ENABLE_ANAS        1
#define BYPASS_VBI_VALIDATION    1
#define INIT_VBI_BY_NOTIFY_ONOFF 1
#define DEFAULT_4_3_EUWSS        1
#define MAIN_SUB_VBI_NOTIFY      1
#else
#define FORCE_ENABLE_ANAS        0
#define BYPASS_VBI_VALIDATION    0
#define INIT_VBI_BY_NOTIFY_ONOFF 0
#define DEFAULT_4_3_EUWSS        0
#define MAIN_SUB_VBI_NOTIFY      0
#endif

/* Initialize VBI slicer parameters */
EXTERN void VBI_Init(VBI_MODE_T t_VbiMode);

//EXTERN void VBIISR_Init(void);
EXTERN void VBI_ISR(void);

/* Enable VBI slicer */
EXTERN void VBI_Enable(void);

/* Disable VBI slicer */
EXTERN void VBI_Disable(void);

/* Enabe VBI slicer individually */
EXTERN void VBI_EnableBySlicer(UINT8 u1VBISuite) ;

/* Disabe VBI slicer individually */
EXTERN void VBI_DisableBySlicer(UINT8 u1VBISuite);

/* Reset VBI setting in mode change */
EXTERN void VBI_ResetSrc(UINT8 u1Path);

/* Qeery VBI AV INFO */
EXTERN void VBI_QueryAVInfo(VBI_AV_INFO *pVBIAvInfo);

/* Set VBI AV Filed INFO */
EXTERN void VBI_SetAVFieldType(BOOL bIs525, BOOL bIsFieldIvs, UINT8 u1Mode);

EXTERN void VBI_SetLineInfoByAP(BOOL bIs525, UINT8 u1Mode, UINT8 u1Line);

/* Set VBI WSS TIME OUT INFO */
EXTERN void VBI_SetWSSTimeOutInfo(VBI_WSS_TIMEOUT_INFO *pWssTOutInfo);

/* Set VBI CC TIME OUT INFO */
EXTERN void VBI_SetCCTimeOutInfo(VBI_CC_TIMEOUT_INFO *pCcTOutInfo);

/* Set VBI LINE INFO */
EXTERN void VBI_SetLineInfo(VBI_LINE_INFO * pVbiLineInfo);

/* Set VBI Slicer Path */
EXTERN void VBI_SetSlicerPath(UINT8 u1VBISuite, UINT8 u1Path);

/* Get VBI Slicer Path */
EXTERN UINT8 VBI_GetSlicerPath(UINT8 u1VBISuite);

/* Set VBI ECC OnOff */
EXTERN void VBI_SetCCECC(UINT8 u1OnOff);

EXTERN UINT8 VBI_GetCGMSA(UINT8 u1Path);
EXTERN void VBI_GetAnalogCopyProtect(UINT8 u1Path, UINT32 *pu4PAL_wss, UINT32 *pu4NTSC_wss);

#ifdef CC_ATV_PVR_SUPPORT
EXTERN BOOL VBI_QuryTTXOnOffStatus(void);
EXTERN BOOL VBI_QuryCCOnOffStatus(void);
EXTERN BOOL VBI_QuryWSSOnOffStatus(void);
EXTERN void VBI_PVRStartNotifyCCOnOff(UINT8 u1Path, UINT8 u1OnOff);
EXTERN BOOL VBI_PVRRetrieveCCData(VBI_PVR_NOTIFY_DATA *pNotifyData);
EXTERN BOOL VBI_PVRRetrieveAFDData(VBI_PVR_NOTIFY_DATA *pNotifyData);
EXTERN BOOL VBI_PVRRetrieveTTXData(VBI_PVR_NOTIFY_DATA *pNotifyData);
EXTERN BOOL VBI_PVRPrintCCSEIData(VBI_PVR_CC_SEI_DATA *pData);
EXTERN BOOL VBI_PVRPrintAFDSEIData(VBI_PVR_AFD_SEI_DATA *pData);
#endif

#if VBI_CLI_SUPPORT
EXTERN BOOL VBI_QueryNotifyOnOffStatus(VBI_SERVICE_T t_vbi_svs, UINT8 u1Path);
EXTERN void VBI_SetCLINotifyTTXFP(NPTV_PFN_TTX_NFY pfnTTXnotify);
EXTERN void VBI_SetCLINotifyCCFP(NPTV_PFN_CC_NFY pfnCCnotify);
EXTERN void VBI_SetCLINotifyCC2XFP(NPTV_PFN_CC2X_NFY pfnCC2Xnotify);
EXTERN void VBI_SetCLINotifyWSSFP(NPTV_PFN_WSS_NFY pfnWSSnotify);
#if SUPPORT_TYPE_B_VBI
EXTERN void VBI_SetCLINotifyTypeBWSSFP(NPTV_PFN_TYPE_B_WSS_NFY pfnTypeBWSSnotify);
#endif
EXTERN void VBI_SetCLINotifyVPSFP(NPTV_PFN_VPS_NFY pfnVPSnotify);
EXTERN void VBI_SetCLINotifyPFN(VBI_PFN_CLI_NFY pfnCLINotify);
EXTERN void VBI_CoreRst(UINT8 bVBISuite);
EXTERN UINT32 VBI_GetLineEn(UINT8 bVBISuite);
EXTERN void VBI_SetLineEn(UINT8 bVBISuite, UINT32 u4LineEn);
EXTERN UINT32 VBI_GetLSC(UINT8 bVBISuite);
EXTERN void VBI_SetLSC(UINT8 bVBISuite, UINT32 u4LSC);
EXTERN UINT8 VBI_GetSrc(UINT8 bVBISuite);
EXTERN void VBI_SetSrc(UINT8 bVBISuite, UINT8 bSrc);
EXTERN UINT32 VBI_GetOutputMode(UINT8 bVBISuite);
EXTERN void VBI_SetOutputMode(UINT8 bVBISuite, UINT32 u4Mode);
EXTERN UINT8 VBI_GetZC(UINT8 bVBISuite);
EXTERN void VBI_SetZC(UINT8 bVBISuite, UINT32 u4ZC);
EXTERN void VBI_GetCcLine(UINT8 bVBISuite, UINT8 u1Field, UINT8* pu1CcStart, UINT8* pu1CcEnd);
EXTERN void VBI_SetCcLine(UINT8 bVBISuite, UINT8 u1Field, UINT8 u1CcStart, UINT8 u1CcEnd);
EXTERN void VBI_GetWssLine(UINT8 bVBISuite, UINT8 u1Field, UINT8* pu1Line);
EXTERN void VBI_SetWssLine(UINT8 bVBISuite, UINT8 u1Field, UINT8 u1Line);
#if SUPPORT_TYPE_B_VBI
EXTERN void VBI_GetTypeBWssLine(UINT8 bVBISuite, UINT8 u1Field, UINT8 *pu1Line);
EXTERN void VBI_SetTypeBWssLine(UINT8 bVBISuite, UINT8 u1Field, UINT8 u1Line);
#endif

EXTERN void VBI_GetTtxLine(UINT8 bVBISuite, UINT8 u1Field, UINT8* pu1Start, UINT8* pu1End);
EXTERN void VBI_SetTtxLine(UINT8 bVBISuite, UINT8 u1Field, UINT8 u1Start, UINT8 u1End);
EXTERN void VBI_GetVpsLine(UINT8 bVBISuite, UINT8 u1Field, UINT8* pu1Start, UINT8* pu1End);
EXTERN void VBI_SetVpsLine(UINT8 bVBISuite, UINT8 u1Field, UINT8 u1Start, UINT8 u1End);
EXTERN void VBI_SetDbgPort(UINT32 u4Mode);
EXTERN UPTR VBI_GetMbase0(UINT8 bVBISuite);
EXTERN UINT32 VBI_GetMOffset(UINT8 bVBISuite);
EXTERN VBI_MODE_T VBI_GetVBIMode(void);
EXTERN void VBI_SetCLINotifyMode(UINT8 u1NfyMode);
EXTERN BOOL VBI_AdjVBIGain(UINT8 u1Gain);
#if AUTO_CC_DETECT
EXTERN void VBI_AutoCCOnOff(UINT8 u1OnOff);
#endif
EXTERN void VBI_DramDumpOnOff(UINT8 u1OnOff);
#if SUPPORT_TOFU_DISPLAY
EXTERN void VBI_CCToFuOnOff(UINT8 u1OnOff, UINT8 u1LoTh, UINT8 u1HiTh);
#endif
#endif // end of VBI_CLI_SUPPORT

#endif

