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

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxeepromdriverapi.h
/// @brief EEPROM Driver function declarations
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef CAMXEEPROMDRIVERAPI_H
#define CAMXEEPROMDRIVERAPI_H

#include "camxcommondriverapi.h"

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

#define HW_ROLLOFF_TABLE_SIZE 221
#define MAX_AF_CALI_DISTANCES 10

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// EEPROMIlluminantType
/// Comments:      Type of the illuminant
///                Supported illuminants are D65, TL84, A, D50 and H
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
enum class EEPROMIlluminantType
{
    D65  = 0,
    TL84 = 1,
    A    = 2,
    D50  = 3,
    H    = 4,
    MAX  = 5
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// RegisterSetting
/// Comments:      Register setting configuration
///                Contains: register address, register data, register address type, register data type,
///                operation and delay in micro seconds
///                 element for slaveAddr
///                 element for registerAddr
///                 element for registerData
///                 element for regAddrType
///                 element for regDataType
///                 element for operation
///                 element for delayUs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct RegisterSetting
{
    /// Slave address to communicate with the device
    UINT32             slaveAddrExists;
    UINT32             slaveAddrID;
    UINT16             slaveAddr;
    /// Register address that is accessed
    UINT32             registerAddr;
    /// List of data items in bytes seperated by space as delimiter.
    /// Data may be written to an I2C slave in burst mode.
    /// If operation is WRITE, a single registerData item is to be written into location specified by registerAddr.
    /// For operation WRITE_BURST, a list of 1 or more registerData items will be written serially starting
    /// at the location specified by registerAddr, and the I2C slave will internally increment the address for each
    /// registerData item.
    /// For operation WRITE_SEQUENTIAL, a list of 1 or more registerData items will be written serially starting
    /// at the location specified by registerAddr, but the address is explicitly generated by the driver for each
    /// registerData item in the list.
    /// If operation is READ, registerData is the number of bytes to be read from the specified register address
    UINT32             registerDataCount;
    UINT32             registerDataID;
    RegisterData*      registerData;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// regAddrType
    ///
    /// Range:         [1,4]
    /// Comments:      Register address / data size in bytes
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    I2CRegAddrDataType regAddrType;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// regDataType
    ///
    /// Range:         [1,4]
    /// Comments:      Register address / data size in bytes
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    I2CRegAddrDataType regDataType;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// operation
    /// Default Value: WRITE
    /// Comments:      Type of I2C operation
    ///                Valid values are: WRITE, WRITE_BURST, WRITE_SEQUENTIAL, READ, POLL
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    OperationType      operation;
    /// Delay in micro seconds. Delay is 0 if not explicitly provided
    /// For operation WRITE, the delay value is applied at the end of the single register data item.
    /// For operation WRITE_BURST, WRITE_SEQUENTIAL, the delay value is applied at the end of the burst sequence.
    UINT32             delayUsExists;
    UINT32             delayUsID;
    UINT32             delayUs;
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// SettingsInfo
/// Comments:      Sequence of register settings to configure the device
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct SettingsInfo
{

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// regSetting - Array
    /// Min Length:    1
    /// Max Length:    Unbounded
    /// Comments:      Register setting configuration
    ///                Contains: register address, register data, register address type, register data type,
    ///                operation and delay in micro seconds
    ///                 element for slaveAddr
    ///                 element for registerAddr
    ///                 element for registerData
    ///                 element for regAddrType
    ///                 element for regDataType
    ///                 element for operation
    ///                 element for delayUs
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    UINT32           regSettingCount;
    UINT32           regSettingID;
    RegisterSetting* regSetting;
};

/// @brief White balance calibration data
struct WBCalibration
{
    BOOL                    isAvailable;    ///< Indicates whether WB calibration data is avialabe or not.
    EEPROMIlluminantType    illuminant;     ///< Indicates color temperature illuminant type
    FLOAT                   rOverG;         ///< R over G data
    FLOAT                   bOverG;         ///< B over G data
    FLOAT                   grOverGB;       ///< GR over GB data
    SettingsInfo            settings;       ///< Contain the register settings to write for WB calibration
};

struct LSCCalibration
{
    BOOL                    isAvailable;                    ///< Indicates whether LSC calibration data is avialabe or not
    EEPROMIlluminantType    illuminant;                     ///< Indicates color temperature illuminant type
    UINT16                  meshHWRollOffSize;              ///< indicates the roll of table size
    FLOAT                   rGain[HW_ROLLOFF_TABLE_SIZE];   ///< R gain table
    FLOAT                   grGain[HW_ROLLOFF_TABLE_SIZE];  ///< GR gain table
    FLOAT                   gbGain[HW_ROLLOFF_TABLE_SIZE];  ///< GB gain table
    FLOAT                   bGain[HW_ROLLOFF_TABLE_SIZE];   ///< B gain table
    SettingsInfo            settings;                       ///< Contain the register settings to write for LSC calibration
};

struct AFLens
{
    UINT32  chartDistanceCM;    ///< Chart distance in centimetres
    INT16   DACValue;           ///< Lens position DAC value at chart distance
    FLOAT   stepPosition;       ///< lens position step value(linearized) corresponding to DAC value
};

struct AFCalibration
{
    BOOL        isAvailable;                ///< Indicates whether AF calibration data is available or not
    INT16       macroDAC;                   ///< DAC value for the actuator macro region
    INT16       infinityDAC;                ///< DAC value for the actuator infinity region
    AFLens      calibrationInfo[MAX_AF_CALI_DISTANCES]; ///< contains chart distance and correpsonding DAC values
    UINT32      numberOfDistances;          ///< Number of calibrated distances
    FLOAT       macroMargin;                ///< margin to extend towards macro region
    FLOAT       infinityMargin;             ///< margin to extend towards infinity region
    UINT16      hallOffsetBias;             ///< hall bias value to write
    UINT32      hallRegisterAddr;           ///< hall register address to update OTP data
    INT16       gravityOffset0to90;         ///< memory offset value value of gravity offset from 0 to 90
    INT16       gravityOffset90to180;       ///< memory offset value value of gravity offset from 90 to 180
    UINT32      actuatorID;                 ///< actuator ID to identify the actuator when there are multiple actuators
};

struct LensIntrinsicData
{
    BOOL  isAvailable;              ///< LensData present in driver or not
    FLOAT f_x;                      ///< Horizontal focal length
    FLOAT f_y;                      ///< Vertical focal length
    FLOAT c_x;                      ///< Horizontal position of op plane not aligned with lens plane
    FLOAT c_y;                      ///< Vertical position of op plane not aligned with lens plane
    FLOAT s;                        ///< Skew
    FLOAT distortionRadial_k1;      ///< Radial Distortion Coefficient kappa_1
    FLOAT distortionRadial_k2;      ///< Radial Distortion Coefficient kappa_2
    FLOAT distortionRadial_k3;      ///< Radial Distortion Coefficient kappa_3
    FLOAT distortionTangential_p1;  ///< Tangential Distortion Coefficient kappa_4
    FLOAT distortionTangential_p2;  ///< Tangential Distortion Coefficient kappa_5

};

/// @brief APIs in eeprom library
typedef struct EEPROMLibraryAPI
{
    UINT  size;         ///< Size of eeprom library API structure
    UINT  majorVersion; ///< Major version of the Library API
    UINT  minorVersion; ///< Minor version of the Library API

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// pFormatLSCSettings
    ///
    /// @brief  Format the LSC settings
    ///
    /// @param  otpdata      pointer to otp data
    /// @param  otpdatasize  size of otp data
    /// @param  pLSCData     pointer to LSC calibration data to fill LSC reg settings
    /// @return 1 if successful else 0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID (*pFormatLSCSettings)(UINT8* otpdata,
        UINT32 otpdatasize,
        LSCCalibration* pLSCData); ///< pointer to FormatLSCSettings function

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// pFormatAWBSettings
    ///
    /// @brief  Format the awb settings
    ///
    /// @param  otpdata      pointer to otp data
    /// @param  otpdatasize  size of otp data
    /// @param  pWBData      pointer to WB calibration data to fill WB reg settings
    ///
    /// @return 1 if successful else 0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID (*pFormatWBSettings)(UINT8* otpdata,
        UINT32             otpdatasize,
        WBCalibration* pWBData);  ///< pointer to FormatAutoWhiteBalanceSettings function

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// pGetLensIntrinsicInfo
    ///
    /// @brief  Get Depth Sensor Lens Intrinsic Info
    ///
    /// @param  otpdata      pointer to otp data
    /// @param  otpdatasize  size of otp data
    /// @param  pIntrData    pointer to lens intrinsic info struct to fill lens intrinsic info from otp data
    ///
    /// @return 1 if successful else 0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    BOOL (*pGetLensIntrinsicInfo)(UINT8* otpdata,
        UINT32 otpdatasize,
        LensIntrinsicData *pIntrData);  ///< pointer to GetLensIntrinsicInfo function

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// pFillAFChartData
    ///
    /// @brief  Fill AF chart data

    /// @param  otpdata      pointer to otp data
    /// @param  otpdatasize  size of otp data
    /// @param  pAFData      pointer to AF calibration data
    ///
    /// @return 1 if successful else 0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID (*pFillAFChartData)(UINT8* otpdata,
        UINT32 otpdatasize,
        AFCalibration *pAFData);  ///< pointer to FillAFChartData function
} EEPROMLibraryAPI;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// GetEEPROMLibraryAPIs
///
/// @brief Returns the EEPROM library API structure
///
/// @param pEEPROMLibraryAPI pointer to the EEPROM library API structure.
///
/// This function is the entry point for the library. CamX will query the shared library for this method by name.
///
/// @return None
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CDK_VISIBILITY_PUBLIC void GetEEPROMLibraryAPIs(
    EEPROMLibraryAPI* pEEPROMLibraryAPI);

#ifdef __cplusplus
} // CamX Namespace
#endif // __cplusplus

#endif // CAMXEEPROMDRIVERAPI_H
