/*
 * Copyright (c) 2018-2020, NVIDIA CORPORATION.  All rights reserved. All
 * information contained herein is proprietary and confidential to NVIDIA
 * Corporation.  Any use, reproduction, or disclosure without the written
 * permission of NVIDIA Corporation is prohibited.
 */

#ifndef _CDI_MAX96712_H_
#define _CDI_MAX96712_H_

#include "devblk_cdi.h"
#include <stdbool.h>

#define MAX96712_MAX_NUM_LINK                 4u
#define MAX96712_MAX_NUM_PHY                  4u
#define MAX96712_NUM_VIDEO_PIPELINES          8u
#define MAX96712_OSC_MHZ                      25u

#define MAX96712_IS_GMSL_LINK_SET(linkVar, linkNum) (((1u << linkNum) & (uint8_t) linkVar) != 0u)
#define MAX96712_ADD_LINK(linkVar, linkVal)   (linkVar = (LinkMAX96712)((uint8_t) linkVar | \
                                                                        (uint8_t) linkVal))

typedef enum {
    CDI_CONFIG_MAX96712_INVALID = 0u,
    CDI_CONFIG_MAX96712_SET_PG_1920x1236,
    CDI_CONFIG_MAX96712_ENABLE_PG,
    CDI_CONFIG_MAX96712_ENABLE_BACKTOP,
    CDI_CONFIG_MAX96712_DISABLE_BACKTOP,
    CDI_CONFIG_MAX96712_TRIGGER_DESKEW,
    CDI_CONFIG_MAX96712_CHECK_CSIPLL_LOCK,
    CDI_CONFIG_MAX96712_ENABLE_REPLICATION,
    CDI_CONFIG_MAX96712_DISABLE_REPLICATION,
    CDI_CONFIG_MAX96712_NUM,
} ConfigSetsMAX96712;

typedef enum {
    CDI_READ_PARAM_CMD_MAX96712_INVALID = 0u,
    CDI_READ_PARAM_CMD_MAX96712_REV_ID,
    CDI_READ_PARAM_CMD_MAX96712_ERRB,
    CDI_READ_PARAM_CMD_MAX96712_CONTROL_CHANNEL_CRC_ERROR,
    CDI_READ_PARAM_CMD_MAX96712_ENABLED_LINKS,
    CDI_READ_PARAM_CMD_MAX96712_NUM,
} ReadParametersCmdMAX96712;

typedef enum {
    CDI_WRITE_PARAM_CMD_MAX96712_INVALID = 0u,

    /* GMSL1 related APIs */
    CDI_WRITE_PARAM_CMD_MAX96712_SET_DEFAULT_GMSL1_HIM_ENABLED,
    CDI_WRITE_PARAM_CMD_MAX96712_ENABLE_FORWARD_CHANNELS,
    CDI_WRITE_PARAM_CMD_MAX96712_DISABLE_FORWARD_CHANNELS,
    CDI_WRITE_PARAM_CMD_MAX96712_SET_DBL,
    CDI_WRITE_PARAM_CMD_MAX96712_DISABLE_DE,
    CDI_WRITE_PARAM_CMD_MAX96712_ENABLE_PACKET_BASED_CONTROL_CHANNEL,
    CDI_WRITE_PARAM_CMD_MAX96712_DISABLE_PACKET_BASED_CONTROL_CHANNEL,
    CDI_WRITE_PARAM_CMD_MAX96712_ENABLE_SPECIFIC_LINKS,
    CDI_WRITE_PARAM_CMD_MAX96712_SET_FSYNC,
    CDI_WRITE_PARAM_CMD_MAX96712_PIPELINE_MAPPING,
    CDI_WRITE_PARAM_CMD_MAX96712_OVERRIDE_DATATYPE,
    CDI_WRITE_PARAM_CMD_MAX96712_SET_MIPI,
    CDI_WRITE_PARAM_CMD_MAX96712_ENABLE_DOUBLE_PIXEL_MODE,
    CDI_WRITE_PARAM_CMD_MAX96712_SET_TX_SRC_ID,
    CDI_WRITE_PARAM_CMD_MAX96712_UNSET_DBL,
    CDI_WRITE_PARAM_CMD_MAX96712_SET_LINK_MODE,
    CDI_WRITE_PARAM_CMD_MAX96712_ENABLE_PERIODIC_AEQ,
    CDI_WRITE_PARAM_CMD_MAX96712_DISABLE_AUTO_ACK,
    CDI_WRITE_PARAM_CMD_MAX96712_NUM,
} WriteParametersCmdMAX96712;

typedef enum {
     CDI_MAX96712_GMSL_MODE_INVALID = 0u,
     CDI_MAX96712_GMSL_MODE_UNUSED,
     CDI_MAX96712_GMSL1_MODE,
     CDI_MAX96712_GMSL2_MODE,
} GMSLModeMAX96712;

typedef enum {
    CDI_MAX96712_I2CPORT_INVALID = 0u,
    CDI_MAX96712_I2CPORT_0,
    CDI_MAX96712_I2CPORT_1,
} I2CPortMAX96712;

typedef enum {
    CDI_MAX96712_MIPI_OUT_INVALID = 0u,
    CDI_MAX96712_MIPI_OUT_4x2,
    CDI_MAX96712_MIPI_OUT_2x4,
} MipiOutModeMAX96712;

typedef enum {
    CDI_MAX96712_PHY_MODE_INVALID = 0u,
    CDI_MAX96712_PHY_MODE_DPHY,
    CDI_MAX96712_PHY_MODE_CPHY,
} PHYModeMAX96712;

typedef enum {
    CDI_MAX96712_TXPORT_PHY_C = 0u,
    CDI_MAX96712_TXPORT_PHY_D,
    CDI_MAX96712_TXPORT_PHY_E,
    CDI_MAX96712_TXPORT_PHY_F,
} TxPortMAX96712;

typedef enum {
    CDI_MAX96712_REV_INVALID = 0u,
    CDI_MAX96712_REV_1,
    CDI_MAX96712_REV_2,
    CDI_MAX96712_REV_3,
    CDI_MAX96712_REV_4,
    CDI_MAX96712_REV_5,
} RevisionMAX96712;

typedef enum {
    CDI_MAX96712_LINK_NONE = 0u,
    CDI_MAX96712_LINK_0 = (1u << 0u),
    CDI_MAX96712_LINK_1 = (1u << 1u),
    CDI_MAX96712_LINK_2 = (1u << 2u),
    CDI_MAX96712_LINK_3 = (1u << 3u),
    CDI_MAX96712_LINK_ALL = 0xFu,
} LinkMAX96712;

typedef enum {
    CDI_MAX96712_FSYNC_INVALID = 0u,
    CDI_MAX96712_FSYNC_MANUAL,
    CDI_MAX96712_FSYNC_AUTO,
    CDI_MAX96712_FSYNC_OSC_MANUAL,
    CDI_MAX96712_FSYNC_EXTERNAL,
} FSyncModeMAX96712;

typedef enum {
    CDI_MAX96712_DATA_TYPE_INVALID = 0u,
    CDI_MAX96712_DATA_TYPE_RAW10,
    CDI_MAX96712_DATA_TYPE_RAW12,
    CDI_MAX96712_DATA_TYPE_RAW16,
    CDI_MAX96712_DATA_TYPE_RGB,
} DataTypeMAX96712;

/* Used as param for CheckLink() */
typedef enum {
    CDI_MAX96712_LINK_LOCK_INVALID = 0u,
    CDI_MAX96712_LINK_LOCK_GMSL1_CONFIG,
    CDI_MAX96712_LINK_LOCK_GMSL2,
    CDI_MAX96712_LINK_LOCK_VIDEO,
} LinkLockTypeMAX96712;

typedef enum {
    CDI_MAX96712_ERROR_INVALID = 0u,
    CDI_MAX96712_ERROR_NONE,
    CDI_MAX96712_ERROR_GMSL1_LINK_UNLOCK,
    CDI_MAX96712_ERROR_GMSL2_LINK_UNLOCK,
    CDI_MAX96712_GMSL1_DET_ERR,
    CDI_MAX96712_GMSL2_DEC_ERR,
    CDI_MAX96712_GMSL2_IDLE_ERR,
    CDI_MAX96712_GMSL1_PKTCC_CRC_ERR,
} FailureTypeMAX96712;

typedef enum {
    CDI_MAX96712_GPIO_0 = 0u, /* MFP0 */
    CDI_MAX96712_GPIO_1,      /* MFP1 */
    CDI_MAX96712_GPIO_2,      /* MFP2 */
    CDI_MAX96712_GPIO_3,      /* MFP3 */
    CDI_MAX96712_GPIO_4,      /* MFP4 */
    CDI_MAX96712_GPIO_5,      /* MFP5 */
    CDI_MAX96712_GPIO_6,      /* MFP6 */
    CDI_MAX96712_GPIO_7,      /* MFP7 */
    CDI_MAX96712_GPIO_8       /* MFP8 */
} GPIOIndexMAX96712;

typedef struct {
    uint8_t vcID;
    /* flag to indicate if emb data lines have emb data type */
    bool isEmbDataType;
    DataTypeMAX96712 dataType;
    /* flag to indicate if data type override is enabled */
    bool isDTOverride;
    /* flag to indicate if pipeline output is mapped to unused CSI controller.
     * Used only for Max96712 TPG modes */
    bool isMapToUnusedCtrl;
} LinkPipelineMapMAX96712;

typedef union {
    /* Used with CDI_READ_PARAM_CMD_MAX96712_REV_ID */
    RevisionMAX96712 revision;

    /* Used with CDI_READ_PARAM_CMD_MAX96712_CONTROL_CHANNEL_CRC_ERROR */
    struct {
        LinkMAX96712 link;
        uint8_t errVal;
    } ErrorStatus;

    /* Used with CDI_READ_PARAM_CMD_MAX96712_ENABLED_LINKS */
    LinkMAX96712 link;
} ReadParametersParamMAX96712;

typedef union {
    /* Used with CDI_WRITE_PARAM_CMD_MAX96712_PIPELINE_MAPPING */
    struct {
        LinkPipelineMapMAX96712 linkPipelineMap[MAX96712_MAX_NUM_LINK];
        LinkMAX96712 link;
    } PipelineMapping;

    /* Used with CDI_WRITE_PARAM_CMD_MAX96712_SET_DEFAULT_GMSL1_HIM_ENABLED */
    struct {
        LinkMAX96712 link;
        uint8_t step;
    } GMSL1HIMEnabled;

    /* Used with CDI_WRITE_PARAM_CMD_MAX96712_SET_FSYNC */
    struct {
        LinkMAX96712 link;
        FSyncModeMAX96712 FSyncMode;
        uint32_t pclk;
        uint32_t fps;
    } FSyncSettings;

    /* Used with CDI_WRITE_PARAM_CMD_MAX96712_SET_MIPI */
    struct {
        uint8_t mipiSpeed;                       /* MIPI speed in multiples of 100MHz */
        PHYModeMAX96712 phyMode;                 /* CPHY or DPHY */
    } MipiSettings;

    /* Used with CDI_WRITE_PARAM_CMD_MAX96712_PIPELINE_MAPPING */
    struct {
        DataTypeMAX96712 dataType;
        LinkMAX96712 link;
        bool embDataType;           /* Set to true if emb data has emb data type */
    } DoublePixelMode;

    /* Used with
     * CDI_WRITE_PARAM_CMD_MAX96712_SET_I2C_PORT
     * CDI_WRITE_PARAM_CMD_MAX96712_ENABLE_SPECIFIC_LINK
     * CDI_WRITE_PARAM_CMD_MAX96712_DISABLE_FORWARD_CHANNELS
     * CDI_WRITE_PARAM_CMD_MAX96712_ENABLE_FORWARD_CHANNELS
     * CDI_WRITE_PARAM_CMD_MAX96712_ENABLE_PACKET_BASED_CONTROL_CHANNEL
     * CDI_WRITE_PARAM_CMD_MAX96712_DISABLE_PACKET_BASED_CONTROL_CHANNE
     * CDI_WRITE_PARAM_CMD_MAX96712_DISABLE_DE
     * CDI_WRITE_PARAM_CMD_MAX96712_SET_DBL
     * CDI_WRITE_PARAM_CMD_MAX96712_SET_TX_SRC_ID
     */
    LinkMAX96712 link;
} WriteParametersParamMAX96712;

/* Parameter type used for GetErrorStatus() */
typedef struct {
    uint8_t link;                           /* Inp param. A single link whose status needs to be checked */
    FailureTypeMAX96712 failureType[MAX96712_MAX_NUM_LINK]; /* Outp param */
    uint8_t regVal[MAX96712_MAX_NUM_LINK];  /* Outp param */
} ErrorStatusMAX96712;

typedef struct {
    /* These must be set in supplied client ctx during driver creation */
    GMSLModeMAX96712 gmslMode[MAX96712_MAX_NUM_LINK]; /* GMSL1 or GMSL2. Unused links must be set to
                                                         CDI_MAX96712_GMSL_MODE_UNUSED */
    I2CPortMAX96712 i2cPort;                          /* I2C port 1 or 2 */
    TxPortMAX96712 txPort;                            /* MIPI output port */
    MipiOutModeMAX96712 mipiOutMode;                  /* MIPI configuration */
    PHYModeMAX96712 phyMode;                          /* CPHY or DPHY */
    bool slaveEnabled;                                /* Doesn't need to control sensor/serializer
                                                       * through aggregator */
    bool tpgEnabled;                                  /* TPG mode */
    /* These will be overwritten during creation */
    RevisionMAX96712 revision;                        /* Chip revision information */
    uint16_t manualFSyncFPS;                          /* Used to store manual fsync frequency */
    uint8_t linkMask;                                 /* Indicate what links to be enabled */

    /* Track the register update */
    uint8_t gmslModeUpdate;
    uint8_t linkSpeedUpdate;

    /* Long cable support */
    bool longCables[MAX96712_MAX_NUM_LINK];
} ContextMAX96712;

DevBlkCDIDeviceDriver *GetMAX96712NewDriver(void);

LinkMAX96712 GetMAX96712Link(uint8_t linkNum);

NvMediaStatus
MAX96712CheckPresence(
    DevBlkCDIDevice *handle);

NvMediaStatus
MAX96712SetDefaults(
    DevBlkCDIDevice *handle);

NvMediaStatus
MAX96712SetDeviceConfig(
    DevBlkCDIDevice *handle,
    uint32_t enumeratedDeviceConfig);

NvMediaStatus
MAX96712ReadRegister(
    DevBlkCDIDevice *handle,
    uint32_t deviceIndex,
    uint32_t registerNum,
    uint32_t dataLength,
    uint8_t *dataBuff);

NvMediaStatus
MAX96712WriteRegister(
    DevBlkCDIDevice *handle,
    uint32_t deviceIndex,
    uint32_t registerNum,
    uint32_t dataLength,
    uint8_t *dataBuff);

NvMediaStatus
MAX96712WriteParameters(
    DevBlkCDIDevice *handle,
    uint32_t parameterType,
    uint32_t parameterSize,
    void *parameter);

NvMediaStatus
MAX96712ReadParameters(
    DevBlkCDIDevice *handle,
    uint32_t parameterType,
    uint32_t parameterSize,
    void *parameter);

NvMediaStatus
MAX96712DumpRegisters(
    DevBlkCDIDevice *handle);

NvMediaStatus
MAX96712GetErrorStatus(
    DevBlkCDIDevice *handle,
    uint32_t parameterSize,
    void *parameter);

NvMediaStatus
MAX96712CheckLink(
    DevBlkCDIDevice *handle,
    uint32_t linkIndex,
    uint32_t linkType,
    bool display);

NvMediaStatus
MAX96712OneShotReset(
    DevBlkCDIDevice *handle,
    LinkMAX96712 link);

#endif /* _CDI_MAX96712_H_ */
