////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
// All rights reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file camxsocutils.h
///
/// @brief SoC-level HW info. Camera HW specific info should NOT be included here.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef CAMXSOCUTILS_H
#define CAMXSOCUTILS_H

// NOWHINE FILE CF017: Spurious whining

#ifdef _LINUX
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#endif // _LINUX

#include "camxdefs.h"
#include "camxtypes.h"

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Forward Declarations
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Type Definitions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/// @brief SoC Information
enum class SocId
{
    Invalid        = 0,     ///< Invalid SOC Id
    SDM845         = 321,   ///< SDM845 SOC Id
    SDM670         = 336,   ///< SDM670 SOC Id
    SDM855         = 339,   ///< SDM855 SOC Id
    QCS605         = 347,   ///< QCS605 SOC Id
    SM6150         = 355,   ///< SM6150 SOC Id
    SDM865         = 356,   ///< SDM865 SOC Id
    SDM710         = 360,   ///< SDM710 SOC Id
    SDM855P        = 361,   ///< SDM855P SOC Id
    SM7150         = 365,   ///< SM7150 SOC Id
    SM7150P        = 366,   ///< SM7150P SOC Id
    SXR1120        = 370,   ///< SXR1120 SOC Id
    SXR1130        = 371,   ///< SXR1130 SOC Id
    SA6145P        = 377,   ///< SA6145P SOC Id
    SDM712         = 393,   ///< SDM712 SOC Id
    SM7250         = 400,   ///< SM7250 SOC Id
    SM6250         = 407,   ///< SM6250 SOC Id
    SM8350         = 415,   ///< SM8350 SOC Id
    Kamorta        = 417,   ///< Kamorta SOC Id
    KamortaP       = 420,   ///< Kamorta SOC Id
    SM6350         = 434,   ///< SM6350 SOC Id
    SM8350P        = 439,   ///< SM8350 APQ SOC Id
    QSM7250        = 440,   ///< QSM7250 SOC Id
    KamortaHigh    = 444,   ///< Kamorta SOC Id
    KamortaHighP   = 445,   ///< Kamorta SOC Id
    Cedros         = 450,   ///< Cedros SOC Id
    Mannar         = 454,   ///< Mannar SOC Id
    Bodrum         = 456,   ///< Bodrum SOC Id
    SM8450         = 457,   ///< SM8450 SOC Id
    SM8450P        = 482,   ///< SM8450 APQ SOC Id
    SM7225         = 459,   ///< SM6350 AB SOC Id
    Kodiak         = 475,   ///< Kodiak SOC Id
    APQKodiak      = 499,   ///< APQ Kodiak SOC Id
    LTEKodiak      = 515,   ///< Kodiak LTE SOCId
    SM8325         = 501,   ///< SM8325 SOC Id
    SM8325P        = 502,   ///< SM8325 APQ SOC Id
    Fillmore       = 506,   ///< SM7450 SOC Id
    SM8550         = 519,   ///< SM8550 SOC Id
    SM8475         = 530,   ///< SM8475 SOC Id
    SM8475APQ      = 531,   ///< SM8475APQ SOC Id
    SA8775P        = 534,   ///< LeMans SA8775P SOC Id
    SM8550P        = 536,   ///< SM8550P SOC Id
    Netrani        = 537,   ///< Netrani SOC Id
    SM8475LTE      = 540,   ///< SM8475LTE SOC Id
    FillmoreAPQ    = 547,   ///< SM7450 SMP SOC Id
    SC8380XP       = 555,   ///< Hamoa SC8380XP SOC Id
    SM8650         = 557,   ///< SM8650 SOC Id
    FillmoreLTE    = 564,   ///< SM7425 SOC Id
    Clarence       = 568,   ///< Clarence SOC Id
    SM8650APQ      = 577,   ///< SM8650 APQ SOC Id
    KALAMA_SG      = 600,   ///< SM8550 SG SOC Id
    KALAMAP_SG     = 601,   ///< SM8550P SG SOC Id
    ClarenceAPQ    = 602,   ///< ClarenceAPQ SOC Id
    QCS_KAILUA     = 603,   ///< SM8550 without Modem
    QCM_KAILUA     = 604,   ///< SM8550 with Modem
    SA7255P        = 606,   ///< Monaco SA7255P SOC Id
    Camano         = 608,   ///< Camano SOC Id
    SM8635         = 614,   ///< SM8635 SOC Id
    SM7675         = 632,   ///< SM7675 SOC Id
    Milos          = 636,   ///< Milos SOC Id
    SM8635APQ      = 642,   ///< SM8635 APQ SOC Id
    SM7675APQ      = 643,   ///< SM7675 APQ SOC Id
    QCS9100_IOT    = 667,   ///< LeMans qcs9100 IOT SOC Id
    QCS8300        = 674,   ///< Monaco qcs8300 SOC Id
    QCS8275        = 675,   ///< Monaco QCS8275 SOC Id
    QCS9075        = 676,   ///< Lemans QCS9075 SOC Id
    QCS615         = 680,   ///< QCS615 SOC Id
    QCS9100        = 693,   ///< LeMans qcs9100 SOC Id
    Hamoa10     = 710,   ///< Hamoa SOC Id
    Hamoa       = 709,   ///< Hamoa SOC Id
    Purwa          = 635,   ///< Purwa Compute SOC Id
    QCSPurwa       = 711,   ///< Purwa IOT SOC Id
    Glymur         = 662,   ///< Glymur Compute SOC Id
    GlymurP        = 698,   ///< Glymur P SOC Id
    GlymurAPQ      = 699,   ///< Glymur APQ SOC Id
    QCSGlymur      = 719,   ///< Glymur IOT SOC Id
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// DDRRank
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
enum class DDRRank
{
    Invalid  = 0,   ///< Invalid
    Single   = 1,   ///< Single DDR Rank
    Dual     = 2,   ///< Dual DDR Rank
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// DDRType
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
enum class DDRType
{
    Invalid  = 0,   ///< Invalid
    LPDDR3   = 5,   ///< DDR Type LPDDR3
    LPDDR4   = 6,   ///< DDR Type LPDDR4
    LPDDR4X  = 7,   ///< DDR Type LPDDR4X
    LPDDR5   = 8,   ///< DDR Type LPDDR5
    LPDDR5X  = 9,   ///< DDR Type LPDDR5X
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief SoC Utilities
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class SocUtils
{
public:

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsMimasArch
    ///
    /// @brief  Helper method to determine if the SoC uses Mimas architecture for camera HW.
    ///
    /// @param  socId socId to check
    ///
    /// @return TRUE if the socId is of a Mimas based project, FALSE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_VISIBILITY_PUBLIC static CAMX_INLINE BOOL IsMimasArch(
        SocId socId = SocId::Invalid)
    {
        if (SocId::Invalid == socId)
        {
            socId = GetSocId();
        }

        BOOL isMimasSoc = FALSE;
        switch (socId)
        {
            case SocId::Kamorta:
            case SocId::KamortaP:
            case SocId::KamortaHigh:
            case SocId::KamortaHighP:
            case SocId::Mannar:
                isMimasSoc = TRUE;
                break;
            default:
                break;
        }

        return isMimasSoc;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsMimas2Arch
    ///
    /// @brief  Helper method to determine if the SoC uses mimas2 architecture for camera HW.
    ///
    /// @param  socId socId to check
    ///
    /// @return TRUE if the socId is of a mimas2 based project, FALSE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CAMX_INLINE BOOL IsMimas2Arch(
        SocId socId = SocId::Invalid)
    {
        if (SocId::Invalid == socId)
        {
            socId = GetSocId();
        }

        BOOL isMimas2Soc = FALSE;
        switch (socId)
        {
            case SocId::Netrani:
            case SocId::Clarence:
            case SocId::ClarenceAPQ:
            case SocId::Camano:
            case SocId::Milos:
                isMimas2Soc = TRUE;
                break;
            default:
                break;
        }

        return isMimas2Soc;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsPremiumTierTitanArch
    ///
    /// @brief  Helper method to determine if the SoC uses premium-tier Titan architecture for camera HW.
    ///
    /// @param  socId socId to check
    ///
    /// @return TRUE if the socId is of a premium-tier Titan based project, FALSE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CAMX_INLINE BOOL IsPremiumTierTitanArch(
        SocId socId = SocId::Invalid)
    {
        if (SocId::Invalid == socId)
        {
            socId = GetSocId();
        }

        switch (socId)
        {
            case SocId::SM8650:
            case SocId::SM8650APQ:
            case SocId::SM8635:
            case SocId::SM7675:
            case SocId::SM8635APQ:
            case SocId::SM7675APQ:
            case SocId::SM8550:
            case SocId::SM8475:
            case SocId::SM8475APQ:
            case SocId::SM8475LTE:
            case SocId::SM8450:
            case SocId::SM8450P:
            case SocId::QCS_KAILUA:
            case SocId::QCM_KAILUA:
            case SocId::QCS9100:
            case SocId::SM6150:
            case SocId::Hamoa:
            case SocId::Hamoa10:
            case SocId::Purwa:
            case SocId::QCSPurwa:
            case SocId::Glymur:
            case SocId::GlymurP:
            case SocId::GlymurAPQ:
            case SocId::QCSGlymur:
            case SocId::SA6145P:
            case SocId::QCS615:
                return true;

            default:
                break;
        }
        return false;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsKamortaPlatformIdLow
    ///
    /// @brief  Helper method to determine if target is Kamorta low chipset.
    ///
    /// @return TRUE if the socId is Kamorta, FALSE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CAMX_INLINE BOOL IsKamortaPlatformIdLow()
    {
        SocId socId = GetSocId();
        return ((SocId::Kamorta  == socId) ||
                (SocId::KamortaP == socId));
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsKamortaPlatform
    ///
    /// @brief  Helper method to determine if target is Kamorta
    ///
    /// @return TRUE if the socId is Kamorta, FALSE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CAMX_INLINE BOOL IsKamortaPlatform()
    {
        SocId socId = GetSocId();
        return ((SocId::Kamorta      == socId) ||
                (SocId::KamortaP     == socId) ||
                (SocId::KamortaHigh  == socId) ||
                (SocId::KamortaHighP == socId));
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsMannarPlatform
    ///
    /// @brief  Helper method to determine if target is Mannar
    ///
    /// @return TRUE if the socId is Mannar, FALSE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CAMX_INLINE BOOL IsMannarPlatform()
    {
        SocId socId = GetSocId();
        return (SocId::Mannar == socId);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsFillmorePlatform
    ///
    /// @brief  Helper method to determine if Fillmore is Mannar.
    ///
    /// @return TRUE if the socId is Fillmore, FALSE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     static CAMX_INLINE BOOL IsFillmorePlatform()
     {
        SocId socId = GetSocId();
        return ((SocId::Fillmore   == socId) ||
               (SocId::FillmoreAPQ == socId) ||
               (SocId::FillmoreLTE == socId));
     }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsNetraniPlatform
    ///
    /// @brief  Helper method to determine if target is Netrani.
    ///
    /// @return TRUE if the socId is Netrani, FALSE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CAMX_INLINE BOOL IsNetraniPlatform()
    {
        SocId socId = GetSocId();
        return (SocId::Netrani == socId);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsCamanoPlatform
    ///
    /// @brief  Helper method to determine if target is Camano.
    ///
    /// @return TRUE if the socId is Camano, FALSE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CAMX_INLINE BOOL IsCamanoPlatform()
    {
        SocId socId = GetSocId();
        return (SocId::Camano == socId);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsMilosPlatform
    ///
    /// @brief  Helper method to determine if target is Milos.
    ///
    /// @return TRUE if the socId is Milos, FALSE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CAMX_INLINE BOOL IsMilosPlatform()
    {
        SocId socId = GetSocId();
        return (SocId::Milos == socId);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsClarencePlatform
    ///
    /// @brief  Helper method to determine if target is Netrani.
    ///
    /// @return TRUE if the socId is Clarence, FALSE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CAMX_INLINE BOOL IsClarencePlatform()
    {
        SocId socId = GetSocId();
        return (SocId::Clarence == socId);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsSupportAppPortIPE
    ///
    /// @brief  Helper method to determine if target support 3rd port IPE enabled
    ///
    /// @return TRUE if the socId is support 3rd port IPE, FALSE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CAMX_INLINE BOOL IsSupportAppPortIPE()
    {
        SocId socId = GetSocId();

        return ((FALSE == IsMimasArch())        &&
                (FALSE == IsFillmorePlatform()) &&
                (SocId::SDM845      != socId)   &&
                (SocId::SDM670      != socId)   &&
                (SocId::SDM855      != socId)   &&
                (SocId::QCS605      != socId)   &&
                (SocId::SM6150      != socId)   &&
                (SocId::SDM865      != socId)   &&
                (SocId::SDM855P     != socId)   &&
                (SocId::SM7150      != socId)   &&
                (SocId::SM7150P     != socId)   &&
                (SocId::SXR1120     != socId)   &&
                (SocId::SXR1130     != socId)   &&
                (SocId::SDM712      != socId)   &&
                (SocId::SM7250      != socId)   &&
                (SocId::SM6250      != socId)   &&
                (SocId::SM8350      != socId)   &&
                (SocId::SM6350      != socId)   &&
                (SocId::SM8350P     != socId)   &&
                (SocId::QSM7250     != socId)   &&
                (SocId::Cedros      != socId)   &&
                (SocId::Bodrum      != socId)   &&
                (SocId::SM8450      != socId)   &&
                (SocId::SM8450P     != socId)   &&
                (SocId::SM7225      != socId)   &&
                (SocId::Kodiak      != socId)   &&
                (SocId::APQKodiak   != socId)   &&
                (SocId::LTEKodiak   != socId)   &&
                (SocId::SM8325      != socId)   &&
                (SocId::SM8325P     != socId)   &&
                (SocId::SM8475      != socId)   &&
                (SocId::SM8475APQ   != socId)   &&
                (SocId::SM8475LTE   != socId)   &&
                (SocId::Netrani     != socId)   &&
                (SocId::Clarence    != socId)   &&
                (SocId::ClarenceAPQ != socId));
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsSupportGPURotation
    ///
    /// @brief  Helper method to determine if target support GPU rotation
    ///
    /// @return TRUE if the socId is support GPU rotation, FALSE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CAMX_INLINE BOOL IsSupportGPURotation()
    {
        SocId socId = GetSocId();

        BOOL bSupported = FALSE;
        switch (socId)
        {
            case SocId::Netrani:
            case SocId::Clarence:
            case SocId::ClarenceAPQ:
            case SocId::Camano:
                bSupported = TRUE;
                break;
            default:
                break;
        }

        return bSupported;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsSupportBayerAlignment
    ///
    /// @brief  Helper method to determine if target support Bayer Alignment
    ///
    /// @return FALSE if the socId doesn't support Bayer Alignment, TRUE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CAMX_INLINE BOOL IsSupportBayerAlignment()
    {
        SocId socId = GetSocId();

        BOOL bSupported = TRUE;
        switch (socId)
        {
            case SocId::Netrani:
            case SocId::Clarence:
            case SocId::ClarenceAPQ:
            case SocId::Camano:
                bSupported = FALSE;
                break;
            default:
                break;
        }

        return bSupported;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsSupportDynamicRangeTenBitThroughAndroidAPI
    ///
    /// @brief  Helper method to determine if target support dynamic range through Android API
    ///
    /// @return FALSE if the socId doesn't support dynamic range through Android API, TRUE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CAMX_INLINE BOOL IsSupportDynamicRangeTenBitThroughAndroidAPI()
    {
        BOOL bSupported = TRUE;

        if (TRUE == SocUtils::IsMimas2Arch(SocUtils::GetSocId()))
        {
            bSupported = FALSE;
        }

        return bSupported;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetSocIdForSensorbinmap
    ///
    /// @brief  Query for HW for the SoC Id. This fetches the real socid.
    ///
    /// @return socId returned by the HW being probed; SocId::Invalid on failure.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_VISIBILITY_PUBLIC static SocId GetSocIdForSensorbinmap()
    {
        static SocId   socId = SocId::Invalid;

        const UINT  ChipsetBufferSize    = 32; // Size of the chipset buffer
        const CHAR* pSOCDevPathPrimary   = "/sys/devices/soc0/soc_id";
        const CHAR* pSOCDevPathSecondary = "/sys/devices/system/soc/soc0/id";
        INT32       socFd;
        CHAR        buf[ChipsetBufferSize] = { 0 };

        if (0 == access(pSOCDevPathPrimary, F_OK))
        {
            socFd = open(pSOCDevPathPrimary, O_RDONLY);
        }
        else
        {
            socFd = open(pSOCDevPathSecondary, O_RDONLY);
        }

        if (0 < socFd)
        {
            INT ret = read(socFd, buf, sizeof(buf) - 1);
            if (-1 != ret)
            {
                socId = static_cast<SocId>(atoi(buf));
            }
            close(socFd);
        }

        return socId;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetifRidesx
    ///
    /// @brief  Query for compatible string to find if ridesx.
    ///
    /// @return TRUE if ridesx.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_VISIBILITY_PUBLIC static BOOL GetifRidesx()
    {

        const UINT  BufferSize    = 100; // Size of the compatible string
        const CHAR* pSOCDevPathPrimary   = "/proc/device-tree/compatible";
        INT32       socFd = 0;
        CHAR        buf[BufferSize] = { 0 };
        CHAR        machine_name[] = "ride";
        CHAR        *p = NULL;

        if (0 == access(pSOCDevPathPrimary, F_OK))
        {
            socFd = open(pSOCDevPathPrimary, O_RDONLY);
        }

        if (0 < socFd)
        {
            INT ret = read(socFd, buf, sizeof(buf) - 1);
            if (-1 != ret)
            {
                p = strstr(buf,machine_name);
                if(p)
                {
                   close(socFd);
                   return TRUE;
                }
            }
            close(socFd);
        }

        return FALSE;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetSocId
    ///
    /// @brief  Query for HW for the SoC Id.
    ///
    /// @return socId returned by the HW being probed; SocId::Invalid on failure.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_VISIBILITY_PUBLIC static SocId GetSocId()
    {
        static SocId   socId = SocId::Invalid;

        const UINT  ChipsetBufferSize    = 32; // Size of the chipset buffer
        const CHAR* pSOCDevPathPrimary   = "/sys/devices/soc0/soc_id";
        const CHAR* pSOCDevPathSecondary = "/sys/devices/system/soc/soc0/id";
        INT32       socFd;
        CHAR        buf[ChipsetBufferSize] = { 0 };

        if (0 == access(pSOCDevPathPrimary, F_OK))
        {
            socFd = open(pSOCDevPathPrimary, O_RDONLY);
        }
        else
        {
            socFd = open(pSOCDevPathSecondary, O_RDONLY);
        }

        if (0 < socFd)
        {
            INT ret = read(socFd, buf, sizeof(buf) - 1);
            if (-1 != ret)
            {
                socId = static_cast<SocId>(atoi(buf));
            }
            close(socFd);
        }

        // Override target variants to register as base
        if (SocId::SM8450P == socId)
        {
            socId = SocId::SM8450; // Waipio
        }
        else if((SocId::SM8550P     == socId) ||
                (SocId::KALAMA_SG   == socId) ||
                (SocId::KALAMAP_SG  == socId) ||
                (SocId::QCS_KAILUA  == socId) ||
                (SocId::QCM_KAILUA  == socId))
        {
            socId = SocId::SM8550; // Kailua
        }

        // Use SM8475 in place of SM8475APQ and SM8475LTE
        if ((SocId::SM8475APQ == socId) || (SocId::SM8475LTE == socId))
        {
            socId = SocId::SM8475;
        }

        if((SocId::SA8775P      == socId) ||
           (SocId::QCS9075      == socId) ||
           (SocId::QCS9100_IOT  == socId) ||
           (SocId::QCS9100      == socId))
        {
            socId = SocId::QCS9100; // Lemans
        }

        if((SocId::SA7255P      == socId) ||
           (SocId::QCS8275      == socId) ||
           (SocId::QCS8300      == socId))
        {
            socId = SocId::QCS8300; // Monaco
        }

        if((SocId::Hamoa      == socId) ||
            (SocId::Hamoa10   == socId))
        {
            socId = SocId::Hamoa; // hamoa
        }

        if ((SocId::QCS615  == socId) ||
            (SocId::SA6145P == socId))
        {
            socId = SocId::QCS615; //talos
        }

        if ((SocId::Purwa    == socId) ||
            (SocId::QCSPurwa == socId))
        {
            socId = SocId::Purwa; //Purwa
        }

        if ((SocId::Glymur    == socId) ||
            (SocId::GlymurP   == socId) ||
            (SocId::GlymurAPQ == socId) ||
            (SocId::QCSGlymur == socId))
        {
            socId = SocId::Glymur; //Glymur
        }

        return socId;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetSocNameForTopology
    ///
    /// @brief  Query for getting the SOC name for Topology selection
    ///
    /// @return socName returned.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_VISIBILITY_PUBLIC static const CHAR* GetSocNameForTopology()
    {
        const CHAR *socName = NULL;

        switch (SocUtils::GetSocId())
        {
            case SocId::Clarence:
                socName = "clarence";
                break;

            case SocId::SA7255P:
            case SocId::QCS8275:
            case SocId::QCS8300:
                socName = "qcs9100";
                break;

            case SocId::Hamoa  :
            case SocId::Hamoa10:
            case SocId::QCSPurwa:
            case SocId::Purwa:
            case SocId::Glymur:
            case SocId::GlymurP:
            case SocId::GlymurAPQ:
            case SocId::QCSGlymur:
                socName = "hamoa";
                break;

            case SocId::SA6145P:
            case SocId::QCS615:
                socName = "qcs615";
                break;

            default:
                socName = GetSocName(FALSE);
                break;
        }

        return socName;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetSocNameForSettings
    ///
    /// @brief  Query for getting the SOC name for Settings Library
    ///
    /// @return socName returned.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_VISIBILITY_PUBLIC static const CHAR* GetSocNameForSettings()
    {
        const CHAR *socName = NULL;

        switch (SocUtils::GetSocId())
        {
            case SocId::Clarence:
                socName = "clarence";
                break;

            case SocId::QCS8300:
                socName = "qcs9100";
                break;

            case SocId::SA6145P:
            case SocId::QCS615:
                socName = "qcs615";
                break;
            case SocId::Hamoa10:
            case SocId::Hamoa  :
            case SocId::QCSPurwa:
            case SocId::Purwa  :
            case SocId::Glymur:
            case SocId::GlymurP:
            case SocId::GlymurAPQ:
            case SocId::QCSGlymur:
                socName = "hamoa";
                break;

            default:
                socName = GetSocName(FALSE);
                break;
        }

        return socName;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetTargetNameForSoc
    ///
    /// @brief  Query for getting the Target name for Soc
    ///
    /// @return socName returned.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_VISIBILITY_PUBLIC static const CHAR* GetTargetNameForSoc()
    {
        const CHAR *targetName = NULL;

        switch (SocUtils::GetSocId())
        {
            case SocId::QCS8300:
                targetName = "monaco";
                break;

            case SocId::Hamoa:
            case SocId::Hamoa10:
                targetName = "hamoa";
                break;

            case SocId::QCSPurwa:
            case SocId::Purwa:
                targetName = "purwa";
                break;

            case SocId::Glymur:
            case SocId::GlymurP:
            case SocId::GlymurAPQ:
            case SocId::QCSGlymur:
                targetName = "glymur";
                break;

            default:
                targetName = GetSocName(TRUE);
                break;
        }

        return targetName;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetSocName
    ///
    /// @brief  Query for common name for corressponding SocId
    ///
    /// @param  isHandle to check socName is required for handle utility or others
    ///
    /// @return socName returned.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_VISIBILITY_PUBLIC static const CHAR* GetSocName(bool isHandle = false)
    {

        switch (SocUtils::GetSocId())
        {
            case SocId::Kamorta:
            case SocId::KamortaP:
            case SocId::KamortaHigh:
            case SocId::KamortaHighP:
                    return "kamorta";

            case SocId::SDM865:
                if (false == isHandle)
                {
                    return "sdm865";
                }
                else
                {
                    return "kona";
                }

            case SocId::SM8325:
            case SocId::SM8325P:
            case SocId::SM8350:
            case SocId::SM8350P:
            case SocId::Bodrum:
                if (false == isHandle)
                {
                    return "sm8350";
                }
                else
                {
                    return "lahaina";
                }

            case SocId::Kodiak:
            case SocId::APQKodiak:
            case SocId::LTEKodiak:
                return "kodiak";

            case SocId::Fillmore:
            case SocId::FillmoreAPQ:
            case SocId::FillmoreLTE:
                return "fillmore";

            case SocId::SM8450:
            case SocId::SM8450P:
            case SocId::SM8475:
                if (false == isHandle)
                {
                    return "sm8450";
                }
                else
                {
                    return "taro";
                }

            case SocId::Mannar:
                return "mannar";

            case SocId::Clarence:
            case SocId::ClarenceAPQ:
            case SocId::Netrani:
                return "netrani";

            case SocId::Camano:
                return "camano";

            case SocId::Milos:
                return "milos";

            case SocId::SM8550:
            case SocId::SM8550P:
            case SocId::KALAMA_SG:
            case SocId::KALAMAP_SG:
            case SocId::QCS_KAILUA:
            case SocId::QCM_KAILUA:
                if (false == isHandle)
                {
                    return "sm8550";
                }
                else
                {
                    return "kailua";
                }

            case SocId::SM8650:
            case SocId::SM8650APQ:
            case SocId::SM8635:
            case SocId::SM7675:
            case SocId::SM8635APQ:
            case SocId::SM7675APQ:
                if (false == isHandle)
                {
                    return "sm8650";
                }
                else
                {
                    return "lanai";
                }

            case SocId::QCS9100:
            case SocId::QCS8300:
                if (false == isHandle)
                {
                    return "qcs9100";
                }
                else
                {
                    return "lemans";
                }

            case SocId::SM6150:
                return "talos";

            case SocId::Hamoa:
            case SocId::Hamoa10:
            case SocId::Purwa:
            case SocId::QCSPurwa:
            case SocId::Glymur:
            case SocId::GlymurP:
            case SocId::GlymurAPQ:
            case SocId::QCSGlymur:
                return "hamoa";

            case SocId::SA6145P:
            case SocId::QCS615:
                return "qcs615";

            case SocId::SDM855:
            case SocId::SDM855P:
            case SocId::SDM845:
            case SocId::SDM670:
            case SocId::QCS605:
            case SocId::SM7150:
            case SocId::SM7150P:
            case SocId::SDM710:
            case SocId::SXR1120:
            case SocId::SXR1130:
            case SocId::SDM712:
            case SocId::SM7250:
            case SocId::SM6250:
            case SocId::SM6350:
            case SocId::SM7225:
                return "kona";

            default:
                return NULL;
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetDDRRank
    ///
    /// @brief  method to get DDR device rank
    ///
    /// @return DDR device rank; -1 on failure
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_VISIBILITY_PUBLIC CAMX_INLINE static DDRRank GetDDRRank()
    {
        static DDRRank ddrRank = DDRRank::Invalid;
        if (DDRRank::Invalid == ddrRank)
        {
#ifdef LE_CAMERA
            ddrRank = static_cast<DDRRank>(QueryDDRRank("/sys/kernel/ddr_info/num_ranks", 0));
#else
            ddrRank = static_cast<DDRRank>(QuerySocInfoInt32("/sys/firmware/devicetree/base/memory/ddr_device_rank_ch0"));
#endif // LE_CAMERA
        }
        return ddrRank;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetDDRType
    ///
    /// @brief  method to get DDR device type
    ///
    /// @return DDR device type; -1 on failure
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_VISIBILITY_PUBLIC CAMX_INLINE static DDRType GetDDRType()
    {
        static DDRType ddrType = DDRType::Invalid;
        if (DDRType::Invalid == ddrType)
        {
#ifdef LE_CAMERA
            ddrType = static_cast<DDRType>(QuerySocInfoInt32("/sys/kernel/ddr_info/device_type"));
#else
            ddrType = static_cast<DDRType>(QuerySocInfoInt32("/sys/firmware/devicetree/base/memory/ddr_device_type"));
#endif // LE_CAMERA
        }
        return ddrType;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsSocIdModified
    ///
    /// @brief  Returns whether or not we are running on a modified platform, such as new code base on previous chipset
    ///
    /// @return TRUE if we are running on a modified platform, FALSE otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_VISIBILITY_PUBLIC static BOOL IsSocIdModified()
    {
        BOOL            isModified  = FALSE;
        static SocId    socId       = SocId::Invalid;

#ifdef ANDROID
        if (SocId::Invalid == socId)
        {
            const UINT  ChipsetBufferSize    = 32; // Size of the chipset buffer
            const CHAR* pSOCDevPathPrimary   = "/sys/devices/soc0/soc_id";
            const CHAR* pSOCDevPathSecondary = "/sys/devices/system/soc/soc0/id";
            INT32       socFd;
            CHAR        buf[ChipsetBufferSize] = { 0 };

            if (0 == access(pSOCDevPathPrimary, F_OK))
            {
                socFd = open(pSOCDevPathPrimary, O_RDONLY);
            }
            else
            {
                socFd = open(pSOCDevPathSecondary, O_RDONLY);
            }

            if (0 < socFd)
            {
                INT ret = read(socFd, buf, sizeof(buf) - 1);
                if (-1 != ret)
                {
                    socId = static_cast<SocId>(atoi(buf));
                }
                close(socFd);
            }

            // Elaborate on logic if required here
            if (socId != SocUtils::GetSocId())
            {
                isModified = TRUE;
            }

        }
#endif // ANDROID

        return isModified;
    }


private:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// QuerySocInfoInt32
    ///
    /// @brief  Query SoC HW for INT32 bits of data from location specified in pFilePath
    ///
    /// @param  pFilePath  String containing the file path to query
    ///
    /// @return Queried data; -1 on failure
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_VISIBILITY_PUBLIC static INT32 QuerySocInfoInt32(
       const CHAR* pFilePath);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// QueryDDRRank
    ///
    /// @brief  Query SoC HW for INT32 bits of ddr rank data from location specified in pFilePath
    ///
    /// @param  pFilePath  String containing the file path to query
    /// @param  rankIndex  int of rank
    ///
    /// @return Queried data; -1 on failure
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_VISIBILITY_PUBLIC static INT32 QueryDDRRank(
       const CHAR* pFilePath, const int rankIndex);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// LogError
    ///
    /// @brief  Log the error string associated with the current errno value and prefix with pPrefixStr
    ///
    /// @param  pPrefixStr   String to prefix the system errno string with
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CAMX_VISIBILITY_PUBLIC static VOID LogError(
        const CHAR* pPrefixStr);

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

#ifdef __cplusplus
}
#endif // __cplusplus

#endif // CAMXSOCUTILS_H
