////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019-2023 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxisphwsetting.h
/// @brief ISP Hardware Setting Base Class
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef CAMXISPHWSETTING_H
#define CAMXISPHWSETTING_H

#include "camxcsl.h"
#include "camxcslifedefs.h"
#include "camxdefs.h"
#include "camxdebugprint.h"
#include "bps_data.h"
#include "camxstatsdebugdatawriter.h"

CAMX_NAMESPACE_BEGIN

struct  IFEDefaultModuleConfig;
class   ISPHWSetting;
class   CmdBuffer;

const INT32 ISPHWDualIFEMaxIndex = 2;   ///< Max IFEs processing for Dual-IFE
const INT32 ISPHWDualTFEMaxIndex = 2;   ///< Max TFEs processing for Dual-TFE

static const UINT32 MaxDirectBinArray   = 16;   ///< In XCFA modules maximum No of Drrect bin ROI's
static const UINT32 MaxIndirectBinArray = 4;    ///< In XCFA Module Maximum No of In Direct bin ROI's
static const UINT32 MaxColorArray       = 64;   ///< Max Color Array to accomodate 8*8/3*3/2*2 CFA's

/// @brief CSID Reg OFFSets
struct CSIDRegOffset
{
    UINT32 regOffset1;             ///< RegOffset1
    UINT32 regOffset2;             ///< RegOffset2
    UINT32 regOffset3;             ///< RegOffset3
    UINT32 regOffset4;             ///< RegOffset4
    UINT32 regOffset5;             ///< RegOffset5
};

/// @brief IQ module debug dump register structure
struct DumpInfo
{
    UINT32  startRegAddr;    ///< Start address of the register of range
    UINT32  numRegs;         ///< The number of registers to be programmed.
    UINT32* pRegRangeAddr;   ///< The pointer to the structure in memory or a single varaible.
};

/// @brief SFE Reg Group Types
enum SFERegGroupTypes
{
    SFETopReg            = 0, ///< SFETop
    SFECommonReg,             ///< BUS Read/ Write , Line Smoother and other common non IQ Modules
    SFEQCFADemuxReg,          ///< QCFA Demux
    SFEHDRRemosiacBinReg,     ///< GDR Remosaic Bin
    SFELCRReg,                ///< SFE LCR
    SFEChannel0Reg,           ///< Channel 0 Path
    SFEChannel1Reg,           ///< CHannel 1 Path
    SFEChannel2Reg,           ///< Channel 2 Path
    SFEPreviewPathReg,        ///< Preview path
    SFESnapshotPathReg,       ///< Snapshot Reg
    SFEStatsPath0Reg,         ///< Stats Path 0
    SFEStatsPath1Reg,         ///< Stats Path 1
    SFEStatsPath2Reg,         ///< Stats Path 2
};

/// @brief SFE Reg Dump Info
struct SFERegDumpInfo
{
    SFERegGroupTypes regGroupType;  ///< Register Group Type
    IFERegReadInfo   regReadInfo;   ///< Register Read Info
};

/// @brief Exposure context index
enum ISPContextIndex
{
    DefaultContextIndex = 0,                    ///< Default context index
    LongContextIndex    = DefaultContextIndex,  ///< Long exposure context index
    MiddleContextIndex,                         ///< Middle exposure context index
    ShortContextIndex,                          ///< Short exposure context inex
    MaxContextIndex,                            ///< Max exposure context indexes
};

// @brief Map ContextTypeID to ISPContextIndex
static const ISPContextIndex MapISPContext[] =
{
    ISPContextIndex::DefaultContextIndex,       ///< ContextTypeID::Default
    ISPContextIndex::ShortContextIndex,         ///< ContextTypeID::ShortExposure
    ISPContextIndex::MiddleContextIndex,        ///< ContextTypeID::MiddleExposure
    ISPContextIndex::LongContextIndex,          ///< ContextTypeID::LongExposure
};

/// @brief ISP HW input information and ouput ISP HW setting
struct ISPHWCreateData
{
    BOOL            isMultiContext; ///< Allocate resources for multi-context usecase
    BOOL            isDualIFE;      ///< Allocate resources for Dual-IFE usecase
    BOOL            isDualTFE;      ///< Allocate resources for Dual-TFE usecase
    ISPHWSetting*   pISPHWSetting;  ///< Returned reference to ISP HW setting module (output)
};

/// @brief HW Context Information
struct ISPHWContextInfo
{
    UINT32  contextType;    ///< CamX Context type
    UINT32  hwIndex;        ///< For Dual-IFE two index to be use
    UINT32  contextIndex;   ///< Exposure context index
};

/// @brief Packet Builder Interface
struct ISPHWSettingPBIface
{
    UINT32 (*RequiredWriteRegRangeSizeInDwords)(UINT32  numVals);    ///< fPtr for RequiredWriteRegRangeSizeInDwords
    UINT32 (*RequiredWriteDMISizeInDwords)();                        ///< fPtr for RequiredWriteDMISizeInDwords
    CamxResult (*WriteDMI) (
        CmdBuffer*  pCmdBuffer,
        UINT32      DMIAddr,
        UINT8       DMISel,
        CmdBuffer*  pDMIBuf,
        UINT32      offset,
        UINT32      size);
    CamxResult (*WriteRegRange)(
        CmdBuffer*  pCmdBuffer,
        UINT32      reg,
        UINT32      numVals,
        UINT32*     pVals);
    unsigned int (*cdm_get_cmd_header_size)(
        unsigned int command);
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Base Class for all the ISP HW Setting
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class ISPHWSetting
{
public:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ISPHWSetting
    ///
    /// @brief  Constructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ISPHWSetting() = default;


    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// CreateCmdList
    ///
    /// @brief  Generate the Command List
    ///
    /// @param  pInputData       Pointer to the Inputdata
    /// @param  pDMIBufferOffset Pointer for DMI Buffer
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult CreateCmdList(
        VOID* pInputData,
        UINT32* pDMIBufferOffset) = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// CreateSubCmdList
    ///
    /// @brief  Generate the Sub Command List
    ///
    /// @param  pInputData       Pointer to the Inputdata
    /// @param  pDMIBufferOffset Pointer for DMI Buffer
    /// @param  pEnableData      Pointer to the enablement data
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult CreateSubCmdList(
        VOID*   pInputData,
        UINT32* pDMIBufferOffset,
        VOID*   pEnableData)
    {
        CAMX_UNREFERENCED_PARAM(pInputData);
        CAMX_UNREFERENCED_PARAM(pDMIBufferOffset);
        CAMX_UNREFERENCED_PARAM(pEnableData);

        return CamxResultSuccess;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// UpdateFirmwareData
    ///
    /// @brief  Update Firmware Data
    ///
    /// @param  pInputData          Pointer to the InputData
    /// @param  moduleEnable        Boolean TRUE if module is enabled
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult UpdateFirmwareData(
        VOID*  pInputData,
        BOOL   moduleEnable)
    {
        CAMX_UNREFERENCED_PARAM(pInputData);
        CAMX_UNREFERENCED_PARAM(moduleEnable);

        return CamxResultSuccess;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// UpdateTuningMetadata
    ///
    /// @brief  Update Tuning Metadata
    ///
    /// @param  pInputData      Pointer to the InputData
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult UpdateTuningMetadata(
        VOID*  pInputData)
    {
        CAMX_UNREFERENCED_PARAM(pInputData);

        return CamxResultSuccess;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// UpdateTuningMetadata
    ///
    /// @brief  Update Tuning Metadata
    ///
    /// @param  pInputData      Pointer to the InputData
    /// @param  pFWParameter    Pointer to the FW parameter
    /// @param  pRegData        Pointer to the register data
    /// @param  pDMILUT         Pointer to the DMI LUT
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult UpdateTuningMetadata(
        VOID*   pInputData,
        VOID*   pFWParameter,
        VOID*   pRegData,
        VOID*   pDMILUT)
    {
        CAMX_UNREFERENCED_PARAM(pInputData);
        CAMX_UNREFERENCED_PARAM(pFWParameter);
        CAMX_UNREFERENCED_PARAM(pRegData);
        CAMX_UNREFERENCED_PARAM(pDMILUT);

        return CamxResultEFailed;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// UpdateInternalData
    ///
    /// @brief  Update internal data from hw setting
    ///
    /// @param  pInputData      Pointer to the InputData
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult UpdateInternalData(
        VOID*  pInputData)
    {
        CAMX_UNREFERENCED_PARAM(pInputData);

        return CamxResultSuccess;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// PackIQRegisterSetting
    ///
    /// @brief  Calculate register settings based on common library result
    ///
    /// @param  pInput       Pointer to the Input data to the IQ module for calculation
    /// @param  pOutput      Pointer to the Output data to the IQ module for DMI calculation
    ///
    /// @return Return CamxResult.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult PackIQRegisterSetting(
        VOID*  pInput,
        VOID*  pOutput)
    {
        CAMX_UNREFERENCED_PARAM(pInput);
        CAMX_UNREFERENCED_PARAM(pOutput);

        return CamxResultSuccess;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetHWCapability
    ///
    /// @brief  Get HW capability data, initialize common values used for initialization and adjustments
    ///
    /// @param  pHWCapability  Data to be fill with specific HW capability
    /// @param  titanVersion   Titan Version
    /// @param  pDefaultConfig Pointer to Default Config
    ///
    /// @return Return CamxResult
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult GetHWCapability(
        VOID*                   pHWCapability,
        UINT32                  titanVersion,
        IFEDefaultModuleConfig* pDefaultConfig)
    {
        CAMX_UNREFERENCED_PARAM(pHWCapability);
        CAMX_UNREFERENCED_PARAM(titanVersion);
        CAMX_UNREFERENCED_PARAM(pDefaultConfig);

        return CamxResultSuccess;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetRegCmd
    ///
    /// @brief  Return register command
    ///
    /// @return Pointer to register set
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CAMX_INLINE VOID* GetRegCmd()
    {
        return NULL;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// DumpRegConfig
    ///
    /// @brief  Print register configuration of Crop module for debug
    ///
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual VOID DumpRegConfig() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// DumpDMIData
    ///
    /// @brief  Print DMI configuration of DSX module for debug
    ///
    /// @param  pData  Pointer to the Output Data
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual VOID DumpDMIData(
        VOID* pData)
    {
        CAMX_UNREFERENCED_PARAM(pData);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetRegSize
    ///
    /// @brief  Returns register size
    ///
    ///
    /// @return Number of bytes of register structure.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual UINT GetRegSize()
    {
        return 0;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetCommandLength
    ///
    /// @brief  returning command length
    ///
    /// @return length of command for the module
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    UINT32 GetCommandLength()
    {
        return m_cmdLength;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// SetCommandLength
    ///
    /// @brief  Set command length
    ///
    /// @param  cmdLength Length of command for the module.
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID SetCommandLength(
        UINT32 cmdLength)
    {
        m_cmdLength = cmdLength;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetCommandLengthBLUR
    ///
    /// @brief  returning  BLUR command length
    ///
    /// @return length of command for the BLUR module
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    UINT32 GetCommandLengthBLUR()
    {
        return m_cmdLengthBLUR;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// SetCommandLengthBLUR
    ///
    /// @brief  Set command length BLUR
    ///
    /// @param  cmdLength Length of command for the BLUR module.
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID SetCommandLengthBLUR(
        UINT32 cmdLength)
    {
        m_cmdLengthBLUR = cmdLength;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// FillIFEDMIReadInfo
    ///
    /// @brief  Helper function to fill Reg Read Info
    ///
    /// @param  pDMIReadInfo  Pointer to the DMI Read Info to be filled
    /// @param  offset        DMI Reg Offset
    /// @param  bankOffset    DMI Bank Offset
    /// @param  numberOfReads number of DMI Data reads
    /// @param  bankSelect    bank Select
    /// @param  lutSelect     LUT Select
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_INLINE VOID FillIFEDMIReadInfo(
        IFERegReadInfo* pDMIReadInfo,
        UINT32          offset,
        UINT32          bankOffset,
        UINT32          numberOfReads,
        UINT32          bankSelect,
        UINT32          lutSelect)
    {
        if (NULL != pDMIReadInfo)
        {
            pDMIReadInfo->readType                                       = IFERegDumpReadTypeDMI;
            pDMIReadInfo->regDescriptor.dmiReadCmd.regWriteCmd[0].offset = offset;
            pDMIReadInfo->regDescriptor.dmiReadCmd.regWriteCmd[0].value  = 0x100000;
            pDMIReadInfo->regDescriptor.dmiReadCmd.numberOfRegWrites++;
            pDMIReadInfo->regDescriptor.dmiReadCmd.regWriteCmd[1].offset = offset + 0x4;
            pDMIReadInfo->regDescriptor.dmiReadCmd.regWriteCmd[1].value  = lutSelect;
            pDMIReadInfo->regDescriptor.dmiReadCmd.numberOfRegWrites++;
            pDMIReadInfo->regDescriptor.dmiReadCmd.regWriteCmd[2].offset = bankOffset;
            pDMIReadInfo->regDescriptor.dmiReadCmd.regWriteCmd[2].value  = bankSelect;
            pDMIReadInfo->regDescriptor.dmiReadCmd.numberOfRegWrites++;
            pDMIReadInfo->regDescriptor.dmiReadCmd.regRangeCmd.numberOfRegisters = numberOfReads;
            pDMIReadInfo->regDescriptor.dmiReadCmd.regRangeCmd.offset            = offset + 0x8;
            pDMIReadInfo->regDescriptor.dmiReadCmd.postregWriteCmd[1].offset     = offset + 0x4;
            pDMIReadInfo->regDescriptor.dmiReadCmd.postregWriteCmd[1].value      = 0;
            pDMIReadInfo->regDescriptor.dmiReadCmd.numberOfPostWrites++;
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// CreateCmdListBLUR
    ///
    /// @brief  Generate the Command List
    ///
    /// @param  pInputData       Pointer to the Inputdata
    /// @param  pDMIBufferOffset Pointer for DMI Buffer
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult CreateCmdListBLUR(
        VOID*   pInputData,
        UINT32* pDMIBufferOffset)
    {
        CAMX_UNREFERENCED_PARAM(pInputData);
        CAMX_UNREFERENCED_PARAM(pDMIBufferOffset);

        return CamxResultSuccess;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// PackIQRegisterSettingBLUR
    ///
    /// @brief  Calculate BLUR register settings based on common library result
    ///
    /// @param  pInput       Pointer to the Input data to the IQ module for calculation
    /// @param  pOutput      Pointer to the Output data to the IQ module for DMI calculation
    ///
    /// @return Return CamxResult.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult PackIQRegisterSettingBLUR(
        VOID*  pInput,
        VOID*  pOutput)
    {
        CAMX_UNREFERENCED_PARAM(pInput);
        CAMX_UNREFERENCED_PARAM(pOutput);

        return CamxResultSuccess;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// UpdateTuningMetadataBLUR
    ///
    /// @brief  Update Tuning Metadata for BLUR
    ///
    /// @param  pTuningMetadata      Pointer to the Tuning Metadata
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult UpdateTuningMetadataBLUR(
        VOID*  pTuningMetadata)
    {
        CAMX_UNREFERENCED_PARAM(pTuningMetadata);

        return CamxResultSuccess;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetStripeCommandLength
    ///
    /// @brief  returning Stripe command length
    ///
    /// @return length of command for the module
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    UINT32 GetStripeCommandLength()
    {
        return m_stripeCmdLength;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// SetStripeCommandLength
    ///
    /// @brief  Set Stripe command length
    ///
    /// @param  cmdLength Length of command for the module.
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID SetStripeCommandLength(
        UINT32 cmdLength)
    {
        m_stripeCmdLength = cmdLength;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Get32bitDMILength
    ///
    /// @brief  return 32 bit DMI length
    ///
    /// @return Number of DWord of DMI
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    UINT32 Get32bitDMILength()
    {
        return m_32bitDMILength;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Set32bitDMILength
    ///
    /// @brief  Set 32 bit DMI length
    ///
    /// @param  dmiLength offset The 32-bit DMI buffer offset.
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID Set32bitDMILength(
        UINT32 dmiLength)
    {
        m_32bitDMILength = dmiLength;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Get64bitDMILength
    ///
    /// @brief  return 64 bit DMI length in Dword
    ///
    /// @return Number of DWord of DMI
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    UINT32 Get64bitDMILength()
    {
        return m_64bitDMILength;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Set64bitDMILength
    ///
    /// @brief  Set 64 bit DMI length in Dword
    ///
    /// @param  dmiLength offset The 64-bit DMI buffer offset.
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID Set64bitDMILength(
        UINT32 dmiLength)
    {
        m_64bitDMILength = dmiLength;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetPipelineBitDepth
    ///
    /// @brief  return pipeline bit depth
    ///
    /// @return pipeline bit depth
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual UINT32 GetPipelineBitDepth() const
    {
        return 0;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// UpdateIQRegisterBankSel
    ///
    /// @brief  Update packed register BANK_SEL value
    ///
    /// @param  pContext    HW context identification data
    /// @param  bankSel     To be updated in the packet data
    ///
    /// @return Return CamxResult
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult UpdateIQRegisterBankSel(
        ISPHWContextInfo*   pContext,
        UINT8               bankSel)
    {
        CAMX_UNREFERENCED_PARAM(pContext);
        CAMX_UNREFERENCED_PARAM(bankSel);

        return CamxResultENotImplemented;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// SetupInternalData
    ///
    /// @brief  Update module internal Data from register
    ///
    /// @param  pData Pointer to internal data to be updated
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult SetupInternalData(
        VOID* pData)
    {
        CAMX_UNREFERENCED_PARAM(pData);
        return CamxResultSuccess;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetModuleData
    ///
    /// @brief  Get IQ module specific data
    ///
    /// @param  pModuleData Pointer pointing to Module specific data
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CAMX_INLINE VOID GetModuleData(
        VOID* pModuleData)
    {
        CAMX_UNREFERENCED_PARAM(pModuleData);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ~ISPHWSetting
    ///
    /// @brief  Destructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual ~ISPHWSetting() = default;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// FillDebugData
    ///
    /// @brief  Fill the debugData with an inline template function.
    ///         Due to some of the debugData structures have different name of their data member. (E.g.: LUT, XXXConfig)
    ///         So here we pass one more pointer pDesDebugData, which points to the data member directly to make it works.
    ///
    /// @param  pDesDebugDataStruct     Pointer to destination debugData struct
    /// @param  pDesDebugData           Pointer to destination debugData
    /// @param  pSrcDebugData           Pointer to source debugData
    /// @param  pDebugDataWriter        Pointer to debugData writer
    /// @param  debugDataTagID          debugData TagID
    /// @param  debugDataTagType        debugData TagType
    /// @param  pathID                  Path ID
    /// @param  debugDataPipelineID     debugData PipelineID
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    template <class DebugDataStruct>
    CAMX_INLINE VOID FillDebugData(
        VOID*                   pDesDebugDataStruct,
        VOID*                   pDesDebugData,
        VOID*                   pSrcDebugData,
        DebugDataWriter*        pDebugDataWriter,
        DebugDataTagID          debugDataTagID,
        DebugDataTagType        debugDataTagType,
        UINT8                   pathID              = 0,
        DebugDataPipelineID     debugDataPipelineID = DebugDataPipelineID::IPE)
    {
        CamxResult  result  = CamxResultSuccess;

        UINT32              debugDataSizeWithHeader = sizeof(DebugDataStruct);
        UINT32              debugDataSize           = debugDataSizeWithHeader - sizeof(DebugDataHeaderV1);
        DebugDataStruct*    pDebugDataStruct        = reinterpret_cast<DebugDataStruct*>(pDesDebugDataStruct);

        Utils::Memcpy(pDesDebugData, pSrcDebugData, debugDataSize);

        pDebugDataWriter->FillTuningMetadataHeader(&pDebugDataStruct->header, debugDataPipelineID, pathID);

        result = pDebugDataWriter->AddDataTag(debugDataTagID,
                                              debugDataTagType,
                                              1,
                                              pDesDebugDataStruct,
                                              debugDataSizeWithHeader);

        if (CamxResultSuccess != result)
        {
            // Non-fatal error
            CAMX_LOG_WARN(CamxLogGroupIQMod, "AddDataTag failed with error: %u, TagID: %u, TagType: %u, PipelineID: %u",
                          result,
                          static_cast<UINT32>(debugDataTagID),
                          static_cast<UINT32>(debugDataTagType),
                          static_cast<UINT32>(debugDataPipelineID));
        }
    };

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// FillHWSettingDMIDumps
    ///
    /// @brief  Fill DMI reg dump info
    ///
    /// @param rDMIRegDumpVector    Reference to a vector to fill in the DMI dumps
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual VOID FillHWSettingDMIDumps(
        std::vector<ISPRegDumpInfo>& rDMIRegDumpVector)
    {
        CAMX_UNREFERENCED_PARAM(rDMIRegDumpVector);
    }

    const CHAR* m_pNodeIdentifier;   ///< Pointer to store Node Identifier

    ISPHWSettingPBIface* m_pPBIFace; ///< Packet builder Interface.

private:
    UINT32      m_cmdLength;         ///< The length of the Command List, in dwords
    UINT        m_stripeCmdLength;   ///< The length of the Command List per stripe, in dwords
    UINT32      m_32bitDMILength;    ///< The length of the 32 bit DMI Table, in dwords
    UINT32      m_64bitDMILength;    ///< The length of the 32 bit DMI Table, in dwords
    UINT32      m_cmdLengthBLUR;     ///< The length of the BLUR Command List, in dwords

    ISPHWSetting(const ISPHWSetting&)            = delete; ///< Disallow the copy constructor
    ISPHWSetting& operator=(const ISPHWSetting&) = delete; ///< Disallow assignment operator
};

CAMX_NAMESPACE_END

#endif // CAMXISPHWSETTING_H
