/* 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: pcmcia_if.h,v $
 * $Revision$
 *---------------------------------------------------------------------------*/

#ifndef PCMCIA_IF_H
#define PCMCIA_IF_H

//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------
#include "x_lint.h"

LINT_EXT_HEADER_BEGIN
#include "x_typedef.h"
#include "x_gpio.h"
#include "x_pcmcia.h"
#include "x_os.h"
LINT_EXT_HEADER_END

//-----------------------------------------------------------------------------
// PCMCIA Global Configuration Definitions
//-----------------------------------------------------------------------------
#if defined(CC_INTERNAL_CI) || defined(CC_EXTERNAL_CI)
    #define PCMCIA_TYPE_CI
#elif defined(CC_INTERNAL_POD) || defined(CC_EXTERNAL_POD)
    #define PCMCIA_TYPE_POD
#endif

#if defined(CC_INTERNAL_CI) || defined(CC_INTERNAL_POD)
    #define PCMCIA_TYPE_INTERNAL
#elif defined(CC_EXTERNAL_CI) || defined(CC_EXTERNAL_POD)
    #define PCMCIA_TYPE_EXTERNAL
#endif

#if defined(PCMCIA_TYPE_INTERNAL) || defined(PCMCIA_TYPE_EXTERNAL)
    #define PCMCIA_ENABLED
#else
    #define PCMCIA_DISABLED
#endif

#if defined(CC_INTERNAL_CI) && defined(CC_EXTERNAL_CI)
#error "Both CC_INTERNAL_CI & CC_EXTERNAL_CI are defined !"
#endif

#if defined(CC_INTERNAL_POD) && defined(CC_EXTERNAL_POD)
#error "Both CC_INTERNAL_POD & CC_EXTERNAL_POD are defined !"
#endif


#define MAX_CIS_MAP_SIZE    256 /* Max CIS map buffer size */

//#define CC_FAST_INIT 1

/// Return values
#define POD_OK                          ((INT32)     0)
#define POD_NOT_INIT                    ((INT32)    -1)
#define POD_ALREADY_INIT                ((INT32)    -2)
#define POD_INIT_FAILED                 ((INT32)    -3)
#define POD_INV_ARG                     ((INT32)    -4)
#define POD_MODULE_NOT_INSERTED         ((INT32)    -5)
#define POD_CIS_ERROR                   ((INT32)    -6)
#define POD_REGISTER_ISR_FAILED         ((INT32)    -7)
#define POD_CHANNEL_RESET_FAILED        ((INT32)    -8)
#define POD_BUF_SIZE_NGO_FAILED         ((INT32)    -9)
#define POD_DA_FR_INT_ENABLE_FAILED     ((INT32)   -10)
#define POD_INVALID_ACCESS_MODE         ((INT32)   -11)
#define POD_EXCEED_MAX_BUF_SIZE         ((INT32)   -12)
#define POD_TIME_OUT                    ((INT32)   -13)
#define POD_CMD_ERROR                   ((INT32)   -14)
#define POD_READ_ERROR                  ((INT32)   -15)
#define POD_WRITE_ERROR                 ((INT32)   -16)
#define POD_DATA_AVAILABLE              ((INT32)   -17)
#define POD_POWER_CTRL_ERROR            ((INT32)   -18)
#define POD_REG_TEST_ERROR              ((INT32)   -19)
#define POD_CLI_ERROR                   ((INT32)   -20)
#define POD_DMA_BUF_NOT_ALLOC           ((INT32)   -21)
#define POD_UNKNOWN_COND                ((INT32)   -22)

// POD state
#define POD_INSERTED                ((UINT32)   (1 << 0))
#define POD_FREE                    ((UINT32)   (1 << 1))
#define POD_DATA_AVIL               ((UINT32)   (1 << 2))
#define POD_FREE_EXT                ((UINT32)   (1 << 3))
#define POD_DATA_AVIL_EXT           ((UINT32)   (1 << 4))
#define POD_VS1                     ((UINT32)   (1 << 5)) /* Added for DK PODware */
#define POD_VS2                     ((UINT32)   (1 << 6)) /* Added for DK PODware */
#define POD_READY_IREQ              ((UINT32)   (1 << 7)) /* Added for DK PODware */
#define POD_OVERCURRENT             ((UINT32)   (1 << 8)) /* Added for DK PODware */

// Definitions of POD status register
#define POD_STS_RE                  ((UINT32)   (1 << 0))
#define POD_STS_WE                  ((UINT32)   (1 << 1))
#define POD_STS_IIR                 ((UINT32)   (1 << 4))
#define POD_STS_FR                  ((UINT32)   (1 << 6))
#define POD_STS_DA                  ((UINT32)   (1 << 7))
//-----------------------------------------------------------------------------
// Macro definitions
//-----------------------------------------------------------------------------
#define MIN_VALUE(a, b)                 ((a < b) ? a : b)


//-----------------------------------------------------------------------------
// Type definitions
//-----------------------------------------------------------------------------
typedef void (*pcmcia_cam_connectivity_nfy)(BOOL  fgCamConnected);

typedef enum
{
    PCMCIA_ROUTE_TYPE_IN_INTERNAL_DEMOD,
    PCMCIA_ROUTE_TYPE_IN_PVR,
    PCMCIA_ROUTE_TYPE_IN_DVBS2_SERIAL,
    PCMCIA_ROUTE_TYPE_IN_DVBS2_PARALLEL,
}PCMCIA_ROUTE_TYPE;

typedef enum
{
    PCMCIA_TS_MAIN_TUNER,
    PCMCIA_TS_SUB_TUNER
}PCMCIA_TUNER_ID;

typedef enum
{
    PCMCIA_TS_EXTERNAL_DEMOD_P,
    PCMCIA_TS_EXTERNAL_DEMOD_S1,
    PCMCIA_TS_EXTERNAL_DEMOD_S2,
    PCMCIA_TS_INTERNAL_DEMOD_P,
    PCMCIA_TS_INTERNAL_DEMOD_S,

    // not used, just avoid build error
    PCMCIA_TS_TYPE_DVB_T,
    PCMCIA_TS_TYPE_DVB_C,
    PCMCIA_TS_TYPE_DVB_S,
    PCMCIA_TS_TYPE_DTMB,
    PCMCIA_TS_TYPE_DMUX_P,
    PCMCIA_TS_TYPE_DMUX_P2,
    PCMCIA_TS_TYPE_UNKNOWN
}PCMCIA_TS_TYPE;

#ifdef CC_DUAL_TUNER_SUPPORT
typedef enum
{
    PCMCIA_DUAL_TS_EXT1 = 0,      //TS0
    PCMCIA_DUAL_TS_EXT2,      //TS1
    PCMCIA_DUAL_TS_NONE       //Bypass TS0 and TS1
}PCMCIA_DUAL_TS_TYPE;
typedef enum
{
    PCMCIA_DUAL_DEMUX_IDX0 = 0,   // index0
    PCMCIA_DUAL_DEMUX_IDX1,      // index1
    PCMCIA_DUAL_DEMUX_IDX2,       // index2
    PCMCIA_DUAL_DEMUX_IDX3       // index3
}PCMCIA_DUAL_DEMUX_IDX_TYPE;
#endif
typedef enum
{
    PCMCIA_ISR_NONE,
    PCMCIA_ISR_SIF,     // used only for external CI
    PCMCIA_ISR_IREQ     // used for both internal/external CI
}PCMCIA_ISR;

typedef enum
{
    MT8295_VERSION_NONE,
    MT8295_VERSION_AE,
    MT8295_VERSION_BNE,
    MT5135_VERSION_AE
}PCMCIA_EXTERNAL_IC_VERSION;

typedef enum
{
    POD_SDA = 0,
    POD_DMA
} POD_IO_STATE_T;

/** POD operation mode
 */
typedef enum
{
    PCMCIA_IF_TYPE_NFI,
    PCMCIA_IF_TYPE_SPI
} PCMCIA_IF_TYPE_T;

/** POD channel selection
 */
typedef enum
{
    EXT_CHANNEL         = (1 << 26),
    DATA_CHANNEL        = ~EXT_CHANNEL
} POD_CHANNEL_T;

/// CIS information structure
typedef struct
{
    BOOL      fgPodModuleType;
    BOOL      fgVpp;
    BOOL      fgIrq;
    UINT8     u1ModuleInterfaceType;
    UINT8     u1CorValue;
    UINT16    u2CorAddr;
} CIS_INFO_T;

typedef enum
{
    PCMCIA_CARD_TYPE_UNKNOWN = 0,
    PCMCIA_CARD_TYPE_CI,
    PCMCIA_CARD_TYPE_POD
}PCMCIA_CARD_TYPE;

typedef enum
{
    PCMCIA_CHIP_TYPE_UNKNOWN = 0,
    PCMCIA_CHIP_TYPE_INTERNAL,
    PCMCIA_CHIP_TYPE_EXTERNAL
}PCMCIA_CHIP_TYPE;

typedef enum
{
    PCMCIA_CAM_CONNECT = 0,
    PCMCIA_CAM_DISCONNECT,
    PCMCIA_OVER_CURRENT,
    PCMCIA_DET_CD_UNNORMAL,
}PCMCIA_NFY_EVENT;

typedef enum
{
    PCMCIA_MAINCHIP_UNKNOWN = 0,
    PCMCIA_MAINCHIP_MT5365,
    PCMCIA_MAINCHIP_MT5366,
} PCMCIA_MAINCHIP;

typedef VOID (*x_pcmcia_nfy_fct)(PCMCIA_NFY_EVENT eNfyEventCode);

#ifdef CC_SUPPORT_STR
typedef VOID (*x_pcmcia_fb_cb_fct)(UINT8 ui1_fb_status);
#endif
EXTERN PCMCIA_CARD_TYPE ePcmciaCardType;
EXTERN PCMCIA_CHIP_TYPE ePcmciaChipType;


#ifndef CC_MTK_LOADER
//-----------------------------------------------------------------------------
// Inter-file functions
//-----------------------------------------------------------------------------
EXTERN INT32    PCMCIA_GetTsFmt(void);
EXTERN void     PCMCIA_SetTsPath(BOOL fgExternalDemod, BOOL fgThroughCard);
#ifdef CC_ENABLE_SOFT_TUNER
EXTERN void     PCMCIA_SetTsSource(UINT8 SourceId);
#endif
#ifdef CC_DUAL_TUNER_SUPPORT
EXTERN void     PCMCIA_SetRemuxEnable(BOOL fgRemuxEnable);
EXTERN BOOL     PCMCIA_GetRemuxStatus(void);
EXTERN BOOL     PCMCIA_GetDualTunerID(void);
EXTERN INT32    PCMCIA_SetDualTsPath(PCMCIA_DUAL_TS_TYPE eDualTsPath);
#endif
EXTERN INT32    PCMCIA_Init(void);
EXTERN INT32    PCMCIA_PinChk(void);
EXTERN INT32    PCMCIA_LowLevelInit(void);
EXTERN UINT32   PCMCIA_RawRead32(UINT32 offset);
EXTERN UINT32   PCMCIA_RawWrite32(UINT32 offset, UINT32 value);
EXTERN INT32    PCMCIA_Read(POD_IO_STATE_T eIoState, UINT8* pu1Data, UINT16* pu2DataLen);
EXTERN INT32    PCMCIA_Write(POD_IO_STATE_T eIoState, const UINT8* pu1Data, UINT16 u2DataLen);
EXTERN INT32    PCMCIA_ReadReg(POD_IO_STATE_T eIoState, UINT32 u4RegAddr, UINT8* pu1Data, UINT16 pu2DataLen);
EXTERN INT32    PCMCIA_WriteReg(POD_IO_STATE_T eIoState, UINT32 u4RegAddr, const UINT8* pu1Data, UINT16 u2DataLen);
EXTERN INT32    PCMCIA_ReadCor(UINT16 u2CorAddress);
EXTERN INT32    PCMCIA_WriteCor(UINT16 u2CorAddress, UINT8 u1CorValue);
EXTERN void     PCMCIA_CamPwrControl(BOOL bManualControl);
EXTERN void     PCMCIA_CamPwrOnOff(BOOL bPwrOn);
EXTERN INT32    PCMCIA_Reset(BOOL b_set);
EXTERN void     PCMCIA_ResetCam(void);
EXTERN void     PCMCIA_ResetPcmciaHw(void);
EXTERN void     PCMCIA_ThreadNoAssert(BOOL bNoAssert);
EXTERN void     PCMCIA_StopThread(void);
EXTERN INT32    PCMCIA_EnableIsr(void);
EXTERN PCMCIA_IF_TYPE_T     PCMCIA_GetIfType(void);
EXTERN void                 PCMCIA_SetIfType(PCMCIA_IF_TYPE_T eOpMode);
EXTERN INT32    PCMCIA_GetPodCiAccessMode(POD_ACCESS_MODE_T* peAccessMode);
EXTERN INT32    PCMCIA_SetPodCiAccessMode(POD_ACCESS_MODE_T eAccessMode);
EXTERN INT32    PCMCIA_GetDaFrIntStatus(POD_ACCESS_MODE_T  eAccessMode, UINT8* pu1DaFrSts);
EXTERN BOOL     PCMCIA_ResetChannel(void);

#ifdef CC_SUPPORT_STR
EXTERN INT32    PCMCIA_ReInit(void);
EXTERN void     PCMCIA_RegFastBootCB(x_pcmcia_fb_cb_fct pfnFBCb);
EXTERN INT32    PCMCIA_PowerON(void);
#endif
EXTERN INT32    PCMCIA_NegotiatedBufSize(UINT16* pu2BufSize);
EXTERN INT32    PCMCIA_WaitForModuleStatus(UINT8 u1StatusBit, UINT16 u2TimeOut);
EXTERN INT32    PCMCIA_ParseCis(UINT8* pu1CisMap, CIS_INFO_T* prInfo);
EXTERN INT32    PCMCIA_CheckCIS(UINT8* pu1Cis, UINT16 *addrcor, UINT8 *cor);
EXTERN INT32    PCMCIA_CheckCIPLUSCapability(UINT8 *pui1CIPlusCap);
EXTERN UINT32   PCMCIA_GetBypass(void);
EXTERN void     PCMCIA_SetBypass(BOOL fgBypass);
EXTERN void     PCMCIA_SetBypassTsRouting(BOOL fgBypass);
EXTERN INT32    PCMCIA_PcmciaToPod(BOOL fgPcmciaToPod);
EXTERN INT32    PCMCIA_PcmciaEnableTS(BOOL fgPcmciaEnableTS);
EXTERN INT32    PCMCIA_DetectCard(void);
EXTERN INT32    PCMCIA_TsOutputCard(void);
EXTERN INT32    PCMCIA_CAMWorkAroundInfo(void);
EXTERN INT32    PCMCIA_PcmciaDetachMW(BOOL fgDetach);
EXTERN INT32    PCMCIA_TestCardReady(void);
EXTERN BOOL     PCMCIA_DetectPodActive(void);
EXTERN void     PCMCIA_ExternalDemodOnOff(BOOL fgOnOff);
EXTERN void     PCMCIA_ParallelTsOnOff(BOOL fgOnOff);
EXTERN void     PCMCIA_RegIsr(UINT16 u2IntNo, x_os_isr_fct pfnIsr, x_os_isr_fct *ppfnOld);
#ifdef CI_PLUS_IP_STRM_SUPPORT
EXTERN void     PCMCIA_SetHBBTVMode(BOOL fgHBBTVMode);
#endif
EXTERN void     PCMCIA_RegCamStatusCbk(x_pcmcia_nfy_fct pfn);
EXTERN void     PCMCIA_ExternalIcSetTsClkRate(UINT32 u4ClkRate);
EXTERN void     PCMCIA_EnableDemodTs(UINT8 u1TunerId);
EXTERN void     PCMCIA_DisableDemodTs(UINT8 u1TunerId);
EXTERN void     PCMCIA_AutoSetTsRoutingPath(void);
EXTERN void     PCMCIA_SLT(UINT8 u1TsIndex, UINT8 u1TsClkRate, UINT8 u1TsDataWidth);
EXTERN void     PCMCIA_Demo(pcmcia_cam_connectivity_nfy pfnCbk);
EXTERN void             PCMCIA_SetTsType(PCMCIA_TS_TYPE eTypeValue);
EXTERN PCMCIA_TS_TYPE   PCMCIA_GetTsType(void);
EXTERN void     PCMCIA_UpdateTsStatus(void);
EXTERN void     PCMCIA_CiCamWorkaround(CI_CAM_WRORKAROUND_DRV_T eCiCamWorkaround, void* vParam);
EXTERN INT32    PCMCIA_SetCamVer(CAM_VERSION_TYPE_T eCamVer);
#endif // CC_MTK_LOADER
EXTERN INT32    CI_GPIO_Init(void);
EXTERN INT32    CI_GPIO_Range_Check(INT32 i4GpioNum);
EXTERN INT32    CI_MT8295_GPIO_Range_Check(INT32 i4GpioNum);
EXTERN INT32    CI_MT5135_GPIO_Range_Check(INT32 i4GpioNum);
EXTERN INT32    CI_GPIO_Enable(INT32 i4GpioNum, INT32 * pi4Polarity);
EXTERN INT32    CI_GPIO_Input(INT32 i4GpioNum);
EXTERN INT32    CI_GPIO_Output(INT32 i4GpioNum, INT32 * pi4DriveHighLow);
EXTERN INT32    CI_GPIO_Intrq(INT32 i4Gpio, INT32 *pfgSet);
EXTERN INT32    CI_GPIO_Reg(INT32 i4Gpio, GPIO_TYPE eType, PFN_GPIO_CALLBACK pfnCallback);
EXTERN INT32    CI_GPIO_Query(INT32 i4Gpio, INT32 *pi4Intr, INT32 *pi4Fall, INT32 *pi4Rise);
#ifdef CC_FAST_INIT
EXTERN INT32    CI_GPIO_Suspend(void);
EXTERN INT32    CI_GPIO_Resume(void);
EXTERN INT32    CI_GPIO_ResumeINTEN(INT32 i4Gpio, GPIO_TYPE eType);
#endif
#ifndef CC_MTK_LOADER
EXTERN INT32    PCMCIA_BIM_GetDeviceData(BYTE *pu1DeviceID, BYTE u1Size);
EXTERN INT32    PCMCIA_BIM_GetDeviceID(BYTE *pu1DeviceID, BYTE u1Size);
EXTERN INT32    PCMCIA_BIM_GetSecureID(BYTE *pu1SecureID, BYTE u1Size);

EXTERN void     PCMCIA_Set2Bit(BOOL fg2Bit);
EXTERN BOOL     PCMCIA_Get2Bit(void);
EXTERN void     PcmciaSetDriving(UINT32 u4Driving);
EXTERN void     PcmciaSetTsClock(UINT32 u4TsClock);
EXTERN void     PcmciaSetSysClock(UINT32 u4SysClock);
#ifdef CC_FAST_INIT
EXTERN void     PCMCIA_pm_suspend(void);
EXTERN void     PCMCIA_pm_resume(void);
#endif
#endif // CC_MTK_LOADER

#endif //PCMCIA_IF_H
