/*
 * 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 _CNVMDESERIALIZER_HPP_
#define _CNVMDESERIALIZER_HPP_

#include "NvSIPLPlatformCfg.hpp"
#include "devblk_cdi.h"

#include "CNvMDevice.hpp"
#include "utils/utils.hpp"

namespace nvsipl
{

//! Base deserializer class
class CNvMDeserializer : public CNvMDevice
{
public:
    virtual ~CNvMDeserializer() = default;

    enum LinkMode {
        LINK_MODE_GMSL1,
        LINK_MODE_GMSL2
    };

    typedef struct {
        std::uint8_t linkIndex;
        LinkMode linkMode;
    } DeserLinkModes;

    enum : uint8_t {
        LINK_MASK_0 = (1 << 0),
        LINK_MASK_1 = (1 << 1),
        LINK_MASK_2 = (1 << 2),
        LINK_MASK_3 = (1 << 3),
        LINK_MASK_ALL = LINK_MASK_0 | LINK_MASK_1 | LINK_MASK_2 | LINK_MASK_3
    };

    //! Deserializer Parameter structure
    typedef struct {
        CNvMDevice::DeviceParams oDeviceParams;
        NvMediaICPInterfaceType eInterface;
        NvMediaICPCsiPhyMode ePhyMode;
        std::vector<DeserLinkModes> ovLinkModes;
        uint8_t linkMask;
        bool longCables[MAX_CAMERAMODULES_PER_BLOCK] = {false, false, false, false};
    } DeserializerParams;

    struct LinkAction {
        enum Action {
            LINK_NO_ACTION = 0,
            LINK_ENABLE,
            LINK_DISABLE,
        };
        uint8_t linkIdx;
        Action action = LINK_NO_ACTION;
    };

    virtual SIPLStatus SetConfig(const DeserInfo *deserInfo, DeserializerParams *params);

    virtual SIPLStatus EnableLinks(uint8_t linkMask) = 0; //Enable all links configured using deserLinkModes

    virtual SIPLStatus ControlLinks(const std::vector<LinkAction>& linkActions) = 0;

    virtual SIPLStatus CheckLinkLock(uint8_t linkMask) = 0;

    //! Detect errors
    virtual SIPLStatus DetectErrors(std::uint8_t& cameraModules);

    std::uint32_t GetMipiSpeed();

protected:
    //! Constructor
    CNvMDeserializer();

    //! Holding ICP interface type
    NvMediaICPInterfaceType m_eInterface;

    //! Holding ICP CSI phy mode
    NvMediaICPCsiPhyMode m_ePhyMode;

    std::vector<DeserLinkModes> m_ovLinkModes;

    std::uint32_t m_uMipiSpeed;

    std::uint8_t m_linkMask;

    bool m_longCables[MAX_CAMERAMODULES_PER_BLOCK] = {false, false, false, false};
};

} // end of namespace nvsipl
#endif //_CNVMDESERIALIZER_HPP_
