// INTEL CONFIDENTIAL
// Copyright 2014-2016 Intel Corporation All Rights Reserved.
//
// The source code contained or described herein and all documents related to the source code
// ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the
// Material remains with Intel Corporation or its suppliers and licensors. The Material
// contains trade secrets and proprietary and confidential information of Intel or its
// suppliers and licensors. The Material is protected by worldwide copyright and trade
// secret laws and treaty provisions. No part of the Material may be used, copied,
// reproduced, modified, published, uploaded, posted, transmitted, distributed, or
// disclosed in any way without Intel prior express written permission.
//
// No license under any patent, copyright, trade secret or other intellectual property right
// is granted to or conferred upon you by disclosure or delivery of the Materials, either
// expressly, by implication, inducement, estoppel or otherwise. Any license under such
// intellectual property rights must be express and approved by Intel in writing.
//
// Module Name:
//
//    public.h
//
// Abstract:
//
//    This module contains the common declarations shared by drivers
//    and user applications.
//
// Environment:
//
//    user and kernel

#ifndef __PUBLIC_H
#define __PUBLIC_H

#include "sensor_types.h"

#define DEFINE2STRING(x) #x
#define DEFINEVALUE2STRING(x) DEFINE2STRING(## x)

#define VALUE_NOT_VALID 0xFFFF



//
// Device interfaces GUIDs
//

// ISP device interface GUID = {475CA657-B694-4CC8-A36B-8D49B39113B8}

static const GUID GUID_DEVINTERFACE_ISP =
{ 0x475ca657, 0xb694, 0x4cc8, {0xa3, 0x6b, 0x8d, 0x49, 0xb3, 0x91, 0x13, 0xb8 } };

#ifdef PIXTER_GAL_DRV
// HCI device interface GUID = {73992AEE-2FAA-4A87-9A78-A705B4957EB8}
static const GUID GUID_DEVINTERFACE_HCI,
{0xdd5fd08, 0x94f0, 0x4d90, {0xb6, 0x92, 0xa, 0x17, 0xee, 0xdd, 0xac, 0xcc } };
#else
// HCI device interface GUID = {73992AEE-2FAA-4A87-9A78-A705B4957EB8}
static const GUID GUID_DEVINTERFACE_HCI =
{ 0x73992aee, 0x2faa, 0x4a87, { 0x9a, 0x78, 0xa7, 0x5, 0xb4, 0x95, 0x7e, 0xb8 } };

#endif

// {6A31B25F-B7B6-4ED7-B23D-5BBC6CD1C655}
static const GUID GUID_DEVINTERFACE_IVCAM_USB_HC =
{ 0x6a31b25f, 0xb7b6, 0x4ed7, { 0xb2, 0x3d, 0x5b, 0xbc, 0x6c, 0xd1, 0xc6, 0x55 } };


// Module device interface GUID = {13E089CB-3FE5-4BF1-AA81-33AED2B1F00C}
DEFINE_GUID(GUID_DEVINTERFACE_MODULE,
0x13e089cb, 0x3fe5, 0x4bf1, 0xaa, 0x81, 0x33, 0xae, 0xd2, 0xb1, 0xf0, 0xc);

// {DB53BE49-6227-48FA-A2F9-9524D27C03D7}
static const GUID GUID_DEVINTERFACE_SENSOR =
{ 0xdb53be49, 0x6227, 0x48fa, { 0xa2, 0xf9, 0x95, 0x24, 0xd2, 0x7c, 0x3, 0xd7 } };

// Support device interface GUID = {CE01E2E4-B83B-487B-9E48-5142C760715A}
static const GUID GUID_DEVINTERFACE_SUPPORT =
{ 0xce01e2e4, 0xb83b, 0x487b, { 0x9e, 0x48, 0x51, 0x42, 0xc7, 0x60, 0x71, 0x5a } };

// HC Spif injector device interface GUID = {628CFB44-CA22-4BAB-BD63-72BED9CC8FF6}
DEFINE_GUID (GUID_DEVINTERFACE_HC_SPIF_INJECTOR,
0x628cfb44, 0xca22, 0x4bab, 0xbd, 0x63, 0x72, 0xbe, 0xd9, 0xcc, 0x8f, 0xf6);

//
// Setup Class GUID for SkyCam Class. This is same as the SKYCAM CLASS guid in the INF files.
// {8AA0E251-075C-4011-BA17-6F77A5654D9F}
DEFINE_GUID(GUID_DEVCLASS_SKYCAM,
0x8aa0e251, 0x75c, 0x4011, 0xba, 0x17, 0x6f, 0x77, 0xa5, 0x65, 0x4d, 0x9f);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//                                      Camera location GUIDS
//
//
//    Left and Right refer to user facing orientation (world facing left is behind the user facing left).
//                         Illustration - Looking at the screen from above.
//
//    World Facing                             World Facing                                   World Facing
//        Left                                                                                    Right
//  |-----------------------------------------------------------------------------------------------------|
//  |############################################ Screen #################################################|
//  |-----------------------------------------------------------------------------------------------------|
//    User Facing                               User Facing                                    User Facing
//        Left                                                                                    Right
//
//
//  ADDING ADDITIONAL LOCATION GUIDS REQUIRE ADDING THESE GUIDS IN SensorGuidFactory.cpp IN AVSTREAM DRIVER
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////


// This GUID is used for the sensor to indicate that it didn't find matching
// location (either no BIOS info or GUIDS above don't match to the location).
// {634935AB-D1DC-4F72-B881-6280CDE7CB4F}
static const GUID GUID_CAMERA_UNSPECIFIED_LOCATION =
{ 0x634935ab, 0xd1dc, 0x4f72, { 0xb8, 0x81, 0x62, 0x80, 0xcd, 0xe7, 0xcb, 0x4f } };

// {2C704ABB-FB0A-4D2F-A8E1-51787E4E83A6}
static const GUID GUID_CAMERA_USER_FACING =
{ 0x2c704abb, 0xfb0a, 0x4d2f, { 0xa8, 0xe1, 0x51, 0x78, 0x7e, 0x4e, 0x83, 0xa6 } };

// {9B4D10C2-F163-4431-B6C6-643A5F72938E}
static const GUID GUID_CAMERA_USER_FACING_LEFT =
{ 0x9b4d10c2, 0xf163, 0x4431, { 0xb6, 0xc6, 0x64, 0x3a, 0x5f, 0x72, 0x93, 0x8e } };

// {089F8E59-FFE6-4494-97E5-92273C08F2F1}
static const GUID GUID_CAMERA_USER_FACING_RIGHT =
{ 0x89f8e59, 0xffe6, 0x4494, { 0x97, 0xe5, 0x92, 0x27, 0x3c, 0x8, 0xf2, 0xf1 } };

// {34033FC4-D3A4-4C9C-ABD9-8F891A6AB3E6}
static const GUID GUID_CAMERA_WORLD_FACING =
{ 0x34033fc4, 0xd3a4, 0x4c9c, { 0xab, 0xd9, 0x8f, 0x89, 0x1a, 0x6a, 0xb3, 0xe6 } };

// {E540240C-6D97-490E-B068-738E1C510CCF}
static const GUID GUID_CAMERA_WORLD_FACING_LEFT =
{ 0xe540240c, 0x6d97, 0x490e, { 0xb0, 0x68, 0x73, 0x8e, 0x1c, 0x51, 0xc, 0xcf } };

// {CE46C6BB-90DF-4932-8EC1-ADD1804961A1}
static const GUID GUID_CAMERA_WORLD_FACING_RIGHT =
{ 0xce46c6bb, 0x90df, 0x4932, { 0x8e, 0xc1, 0xad, 0xd1, 0x80, 0x49, 0x61, 0xa1 } };

// {81692303-BDAB-41C1-803D-EF3196A27D09}
static const GUID GUID_DEFAULT_CAMERA_LOCATION_0 =
{ 0x81692303, 0xbdab, 0x41c1, { 0x80, 0x3d, 0xef, 0x31, 0x96, 0xa2, 0x7d, 0x9 } };

// {A3BA7324-0DA0-409E-93AB-D3E1504A3E70}
static const GUID GUID_DEFAULT_CAMERA_LOCATION_1 =
{ 0xa3ba7324, 0xda0, 0x409e, { 0x93, 0xab, 0xd3, 0xe1, 0x50, 0x4a, 0x3e, 0x70 } };

// {4710C310-AFBD-4876-B822-6E8A13885035}
static const GUID GUID_DEFAULT_CAMERA_LOCATION_2 =
{ 0x4710c310, 0xafbd, 0x4876, { 0xb8, 0x22, 0x6e, 0x8a, 0x13, 0x88, 0x50, 0x35 } };

// {094336FD-3022-4C7F-A102-446B2B779EFA}
static const GUID GUID_DEFAULT_CAMERA_LOCATION_3 =
{ 0x94336fd, 0x3022, 0x4c7f, { 0xa1, 0x2, 0x44, 0x6b, 0x2b, 0x77, 0x9e, 0xfa } };

// This GUID is used for sensor mock driver.
// {1CA1E34D-74A9-4F1A-936F-EB4F9E78E359}
static const GUID GUID_CAMERA_DUMMY =
{ 0x1ca1e34d, 0x74a9, 0x4f1a, { 0x93, 0x6f, 0xeb, 0x4f, 0x9e, 0x78, 0xe3, 0x59 } };

// This GUID is used for Rolling shutter IR sensor
static const GUID GUID_CAMERA_IR_USER_FACING_RIGHT =
{ 0x7fd29f46, 0xfb65, 0x4f12, { 0xb2, 0xc4, 0x14, 0x58, 0x30, 0xf1, 0x9f, 0xdd } };

// End of Camera location GUIDS
//////////////////////////////////////////////////////////////////////////

#define DEVICE_CSI3                                 0x8001  //x8000- vendor specific //[TODO] check if we can use it
#define MAX_SYMBOLIC_LINK_NAME_SIZE                 255
#define CSH_FBPT_FRAMES_NUMBER             63

#define OUTPUT_IOCTL_FBPT_BUFFER_SIZE   20

#define FRAME_WIDTH     512
#define FRAME_HEIGHT    512

#define HW_PRESENT 0

#define MAX_BUFFERS_NUMBER 10

#define DMA_LINE_END_ALIGNMENT 64

#define DDR_WORD_LENGTH        32

#define SET_BIT(var, pos)               ((var) |= (1<<(pos)))
#define SET_MASK(var, mask)             ((var) |= (mask))
#define CLEAR_BIT(var, pos)             ((var) &= ~(1<<(pos)))
#define CLEAR_MASK(var, mask)           ((var) &= ~(mask))
#define CHECK_BIT(var, pos)             ((var) & (1<<(pos)))
#define CHECK_MASK(var, mask)           ((var) & (mask))


#define CSI3_IOCTL(_index_) \
    (DWORD) CTL_CODE (DEVICE_CSI3, _index_, METHOD_BUFFERED, FILE_READ_DATA)


#define IOCTL_HCI_SEND_ASYNC_NOTIFICATION           CSI3_IOCTL (0x5)
#define IOCTL_HCI_FINISH_SENSOR_COMMANDS            CSI3_IOCTL (0x7)
#define IOCTL_HCI_PROCESS_ONE_CMD                   CSI3_IOCTL (0x11)
#define IOCTL_ISP_SET_RESOLUTION_DEBUG              CSI3_IOCTL (0x12)
#define IOCTL_ISP_SET_RESOLUTION                    CSI3_IOCTL (0x12)
#define IOCTL_ISP_GET_SENSOR_CONNECTION             CSI3_IOCTL (0x13)
#define IOCTL_ISP_GET_VERSION                       CSI3_IOCTL (0x14)
#define IOCTL_HCI_PROCESS_ONE_FRAME                 CSI3_IOCTL (0x19)
#define IOCTL_HCI_TRIGGER_INTERRUPT                 CSI3_IOCTL (0x20)
#define    IOCTL_ISP_GET_FRAME_RATE                    CSI3_IOCTL (0x22)
#define    IOCTL_ISP_GET_BINNING_MODE                    CSI3_IOCTL (0x23)
#define IOCTL_ISP_GET_REGISTER                        CSI3_IOCTL (0x25)
#define IOCTL_ISP_SET_REGISTER                        CSI3_IOCTL (0x26)
#define IOCTL_ISP_GET_CAPS                            CSI3_IOCTL (0x27)
#define IOCTL_ISP_RESET_SENSOR                        CSI3_IOCTL (0x28)
#define IOCTL_ISP_GET_EXPOSURE                        CSI3_IOCTL (0x29)
#define IOCTL_ISP_SET_EXPOSURE                        CSI3_IOCTL (0x30)
#define IOCTL_ISP_GET_FOCUS_POSITION                CSI3_IOCTL (0x31)
#define IOCTL_ISP_SET_FOCUS_POSITION                CSI3_IOCTL (0x32)
#define IOCTL_ISP_GET_FOCUS_STATUS                    CSI3_IOCTL (0x33)
#define IOCTL_ISP_GET_EEPROM                        CSI3_IOCTL (0x34)
#define IOCTL_ISP_SET_EEPROM                        CSI3_IOCTL (0x35)
#define IOCTL_ISP_SET_ISO                            CSI3_IOCTL (0x36)
#define IOCTL_ISP_GET_ISO                            CSI3_IOCTL (0x37)
#define IOCTL_ISP_GET_SUPPORTED_RESOLUTIONS            CSI3_IOCTL (0x38)
#define IOCTL_ISP_SET_GAIN                            CSI3_IOCTL (0x39)
#define IOCTL_ISP_GET_GAIN                            CSI3_IOCTL (0x40)
#define IOCTL_ISP_SET_APERTURE                        CSI3_IOCTL (0x41)
#define IOCTL_ISP_GET_APERTURE                        CSI3_IOCTL (0x42)

#define IOCTL_ISP_GET_MODE_DATA                        CSI3_IOCTL (0x44)
#define IOCTL_ISP_GET_SENSOR_INFO                    CSI3_IOCTL (0x45)
#define IOCTL_ISP_GET_CALIBRATION_DATA                CSI3_IOCTL (0x46)
#define IOCTL_ISP_START_VIEWFINDER                    CSI3_IOCTL (0x47)
#define IOCTL_ISP_STOP_VIEWFINDER                    CSI3_IOCTL (0x48)
#ifdef SKYCAM_DEBUG_INTERFACE
#define IOCTL_ISP_SET_EXPOSURE_TIME                    CSI3_IOCTL (0x49)
#endif
#define IOCTL_ISP_SET_ACTIVE                        CSI3_IOCTL (0x4A)
#define IOCTL_ISP_SET_IDLE                            CSI3_IOCTL (0x4B)
// flash
#define IOCTL_ISP_ARM_FLASH                            CSI3_IOCTL (0x50)
#define IOCTL_ISP_TRANSLATE_FLASH_STROBE_INDICATOR    CSI3_IOCTL (0x51)
#define IOCTL_ISP_STOP_FLASH                        CSI3_IOCTL (0x52)

#define IOCTL_ISP_GET_FLASH_INFO                    CSI3_IOCTL (0x54)
#define IOCTL_ISP_GET_TORCH_INFO                    CSI3_IOCTL (0x55)
#define IOCTL_ISP_TORCH_ON                            CSI3_IOCTL (0x56)
#define IOCTL_ISP_TORCH_OFF                            CSI3_IOCTL (0x57)
#define IOCTL_ISP_BEGIN_WLED_SESSION                CSI3_IOCTL (0x58)
#define IOCTL_ISP_END_WLED_SESSION                    CSI3_IOCTL (0x59)

#define IOCTL_SNSR_TEST_PATTERN                        CSI3_IOCTL (0x90)
#define IOCTL_SNSR_STROBE_FLASH                        CSI3_IOCTL (0x91)
#define IOCTL_SNSR_TEST_U26                            CSI3_IOCTL (0x92)
#define IOCTL_SNSR_SET_RESOLUTION_FROM_FILE            CSI3_IOCTL (0x93)
#define IOCTL_SNSR_TEST_GPIO_CONNECTION_CREATE_DESTROY    CSI3_IOCTL(0x94)

typedef ULONG  CIO2_LINK_ID, *PCIO2_LINK_ID;

#ifdef VC707_DMA
#define HC_LINK_NUMBER                  4
#else
#define HC_LINK_NUMBER                  2
#endif

#define CIO2_VC_NUMBER                  4
#define CIO2_VC_NOT_USED                0xFF

#define CIO2_RUN_INFINITE      0

// This (same) structure is provided by the BIOS to each of the sensor drivers as part of its ACPI resources (hence it is global and not per sensor).
// The sensor driver provides it to the AVStream driver, and the AVStream driver provides it to the CSI2 HC driver with every sensor link that it wants to create.
#pragma pack(1)
typedef struct _HOST_CONTROLLER_GLOBAL
{
    ULONG G_DphyLinkEnFuses;    // BIOS report of PVT_FUSVAL register that it read over the MSG IOSF-SB (driver invisible register). This register reflects
    // the host controller's fuses.
    // CSI2 HC Driver can use this information to verify if an attempt to create sensor link operation can be supported for the
    // requested link (if link is fused out or not). This (same) value is provided by the BIOS to each of the sensor drivers as
    // part of its ACPI SSDB buffer (hence it is a global value and not per sensor).
    // The sensor driver provides it to the AVStream driver, and the AVStream driver provides it to the CSI2 HC driver with
    // every sensor link that it wants to create.

    ULONG G_LanesClockDivision;    // BIOS reports MIPI CSI2 lanes clock division settings using this parameter. This parameter (bits 2:0, all rest bits MBZ)
    // should be written by the CSI2 HC driver to LANES_DIV field in the PBM_ARB_CTRL register. This register reflects the lanes
    // clocks division per sensor (assuming that it's PHY is not fused out).
    // This (same) value is provided by the BIOS to each of the sensor drivers as part of its ACPI SSDB buffer (hence it is a
    // global value and not per sensor).
    // The sensor driver provides it to the AVStream driver, and the AVStream driver provides it to the CSI2 HC driver with every sensor link that it wants to
    // create.
} HOST_CONTROLLER_GLOBAL, *PHOST_CONTROLLER_GLOBAL;
#pragma pack()

/*******************
* \brief A unique indentifier for a single CSI2 host controller
*
* Typically, this structure is provided as ACPI resource for a specific sensor
*
*******************/

typedef struct _PCI_BDF
{
    USHORT Function : 3;            // Function number of the host controller
    USHORT Device : 5;            // Device number of the host controller
    USHORT Bus : 8;                // Bus number of the host controller. A PCH device is usually on bus 0.
} PCI_BDF, *PPCI_BDF;

typedef union _PCI_INSTANCE_ID
{
    PCI_BDF DeviceBDF;                    // SW useful bit field representation
    USHORT    BdfValue;                    // BIOS friendly format
} PCI_INSTANCE_ID, *PPCI_INSTANCE_ID;

#pragma pack(1)
typedef struct _CSI2_HOST_CONTROLLER
{
    GUID CSI2DataStreamInterfaceGUID;
    // GUID CommandControlInterfaceGUID; // CSI2 host controller does not have Command Control HW support hence does not have such interface

    PCI_INSTANCE_ID InstanceID;    // Driver returns in this field the deviceID and FunctionID of the device instance (from its B-D-F).
    // The returned value should be calculated by the driver and by the BIOS in same way to make a match.
    // When the CIO2 device is configured in PCI mode then its B-D-F is 0-20-3 (DevFunc = 0xA3, Bus = 0x00)
    // When the CIO2 device is configured in hidden device mode then its B-D-F is of the IMGU: 0-5-0 (DevFunc = 0x28, Bus = 0x00)
} CSI2_HOST_CONTROLLER, *PCSI2_HOST_CONTROLLER;
#pragma pack()

#pragma pack(1)
typedef struct _SKC_SENSOR_DRIVER_SUBDB_VIEW
{
    UCHAR ROMType;
        // 0x00: ROM_NONE
        // 0x01: ROM_OTP
        // 0x02: ROM_EEPROM_16K_64
        // 0x03: ROM_EEPROM_16K_16
        // 0x04: ROM_OTP_ACPI_ACPI
        // 0x05: ROM_ACPI
        // 0x06: ROM_EEPROM_BRCA016GWZ
        // 0x07: ROM_EEPROM_24AA32
        // 0x08: ROM_EEPROM_CAT24C08
        // 0x09: ROM_EEPROM_M24C64
        // 0x0A: ROM_EFLASH_DW9806B
        // 0x0B: ROM_EEPROM_CAT24C16
    UCHAR VcmType;
        // #define VCM_NONE         0
        // #define VCM_AD5823       1
        // #define VCM_DW9714       2
        // #define VCM_AD5816       3
        // #define VCM_DW9719       4
        // #define VCM_DW9718       5
        // #define VCM_DW9806B      6
        // #define VCM_WV517S       7
        // #define VCM_LC898122XA   8
    UCHAR Platform; // for SKC:  0x09
        // 0: "Unknown"
        // 1: "BYT"
        // 2: "CHT"
        // 3: "CHT1"  // for CHT1
        // 4: "CHT2"  // for CHT2
        // 5: "CHT_CR"
        // 6: "CHT_COPOP"
        // 7: "BSW"
        // 8: "BXT"
        // 9: "SKC"
    UCHAR PlatformSub;  // 0x00
        //0: "Unknown"
        //1: "FFD"             // for Platform FFD/RVP
        //2: "EB"              // for CHT1
        //3: "SAKU"           // for CHT2
    UCHAR FlashSupport;
       //#define DEFINE_DRIVER  0
       //#define FLASH_DISABLE  2
       //#define FLASH_ENABLE   3
    UCHAR PrivacyLED; // 0x00:   privacy LED support
    UCHAR Degree;
       //#define DEGREE_0    0
       //#define DEGREE_180   1
    UCHAR MipiDefine; // 0x01: MIPI info defined in ACPI 0x00: MIPI info defined in sensor driver
    ULONG Mclk;
    // 19200000: 19.2 MHz
    // 24000000: 24 MHz
    // 20000000: 20 MHz
    UCHAR ControlLogicID;
    //  0:  Control Logic 0
    //  1:  Control Logic 1
    UCHAR MipiDataFormat; // MipiDataFormat RAW10:0x00
    UCHAR SiliconVersion;  //Silicon SKC driver not use currently, keep 0x00
    UCHAR CustomerID;
    //INTEL       0
    //MS          1
    //LENOVO      2
    //ASUS        3
    //ACER        4
    //HP          5
    //SUMSANG     6
    UCHAR MclkPort;
   UCHAR CamPosition; //0->position1(CRD-G2 Left position) 1->position2(CRD-G2 Right position)
   UCHAR Voltagerail; //0-->3 voltage rail; 1-->2 voltage rail
   UCHAR Reserved[11];
} SKC_SENSOR_DRIVER_SUBDB_VIEW;
#pragma pack()

// A unique identifier for a single CSI3 host controller
// Typically, this structure is provided as ACPI resource for a specific sensor
// {5B65C121-F1CC-4117-9D8C-439D2195745A}
DEFINE_GUID(CSI3DataStreamInterfaceGUID, 0x5b65c121, 0xf1cc, 0x4117, 0x9d, 0x8c, 0x43, 0x9d, 0x21, 0x95, 0x74, 0x5a);

#pragma pack(1)
typedef struct _CSI3_HOST_CONTROLLER
{
    GUID            CSI3DataStreamInterfaceGUID;
    GUID            CommandControlInterfaceGUID;

    PCI_INSTANCE_ID InstanceID;    // Driver returns in this field the deviceID and FunctionID of the device instance (from its B-D-F).
    // The returned value should be calculated by the driver and by the BIOS in same way to make a match.
} CSI3_HOST_CONTROLLER, *PCSI3_HOST_CONTROLLER;
#pragma pack()

/*******************
* \brief A unique indentifier for a single USB host controller
*
*******************/
// A unique identifier for a single USB host controller
// Typically, this structure is provided as ACPI resource for a specific sensor
// {??????}
//DEFINE_GUID(<<USBDataStreamInterfaceGUID>>, ???);
#pragma pack(1)
typedef struct
{
    // place holder
    GUID USBDataStreamInterfaceGUID;
    GUID CommandControlInterfaceGUID;
    //USB_INSTANCE_ID InstanceID; // ??
} USB_HOST_CONTROLLER;
#pragma pack()

// Union for all possible host controller configurations
//
// Contains all possible host controllers (CSI2, CSI3, USB). Intended as a container for transferring the configuration between different entities.
// This union is used by the SkyCam AVStream driver. It receives it from the sensor driver. SkyCam AVStream driver looks at the 1st member of the union
// which is the GUID of the host controller's interface. This GUID distinguishes between the different host controllers and is published by the host
// controller driver as its interface. Once the connection is done, the AVStream driver makes sure that the interface represents the expected InstanceID
// as the sensor driver provides (and comes from the BIOS as part of the sensor driver resources).
#pragma pack(1)
typedef union _HOST_CONTROLLER
{
    CSI2_HOST_CONTROLLER Csi2;    // CSI2 host controller connection to sensor
    CSI3_HOST_CONTROLLER Csi3;    // CSI3 host controller connection to sensor
    USB_HOST_CONTROLLER Usb;    // USB-based host controller connection to sensor
} HOST_CONTROLLER, *PHOST_CONTROLLER;
#pragma pack()

// These are platform parameters that should set registers 0x24~0x48 of the CSI2-FE of the link. They have to be configured according to the sensor's
// specific parameters! BIOS provides this table to the sensor driver as part of the ACPI resources of the sensor. The sensor driver has to provide these values to the CSI2 driver through the AVStream driver.
// The values are not only sensor specific, but are platform routing specific and are result of measurements and tuning (there can be different distances even for lanes of same link), so some lanes have to
// add delays that are platform related). Mostly Settle time is important. Termination time can be 0.
#pragma pack(1)
typedef struct _LINK_DELAY_PARAMETERS
{
    ULONG CSI_RX_DLY_CNT_TERMEN_CLANE;      // Sets the link's CSI2-FE register at offset 0x24
    ULONG CSI_RX_DLY_CNT_SETTLE_CLANE;      // Sets the link's CSI2-FE register at offset 0x28
    ULONG CSI_RX_DLY_CNT_TERMEN_DLANE0;     // Sets the link's CSI2-FE register at offset 0x2C
    ULONG CSI_RX_DLY_CNT_SETTLE_DLANE0;     // Sets the link's CSI2-FE register at offset 0x30
    ULONG CSI_RX_DLY_CNT_TERMEN_DLANE1;     // Sets the link's CSI2-FE register at offset 0x34
    ULONG CSI_RX_DLY_CNT_SETTLE_DLANE1;     // Sets the link's CSI2-FE register at offset 0x38
    ULONG CSI_RX_DLY_CNT_TERMEN_DLANE2;     // Sets the link's CSI2-FE register at offset 0x3C
    ULONG CSI_RX_DLY_CNT_SETTLE_DLANE2;     // Sets the link's CSI2-FE register at offset 0x40
    ULONG CSI_RX_DLY_CNT_TERMEN_DLANE3;     // Sets the link's CSI2-FE register at offset 0x44
    ULONG CSI_RX_DLY_CNT_SETTLE_DLANE3;     // Sets the link's CSI2-FE register at offset 0x48
} LINK_DELAY_PARAMETERS, *PLINK_DELAY_PARAMETERS;
#pragma pack()

typedef struct _MIPI_COMPRESSION_FORMT
{
    UCHAR CompressionScheme    :3;        // One of COMPRESSION_SCHEME
    UCHAR CompressionPredictor :1;        // One of COMPRESSION_PREDICTOR
    UCHAR Reserved             :4;
} MIPI_COMPRESSION_FORMT, *PMIPI_COMPRESSION_FORMT;


// DRV_REFACTORING
typedef enum
{
    GSP_CODE_1 = 0x08,                        // Generic Short Packet Code 1
    GSP_CODE_2 = 0x09,                        // Generic Short Packet Code 2
    GSP_CODE_3 = 0x0A,                        // Generic Short Packet Code 3
    GSP_CODE_4 = 0x0B,                        // Generic Short Packet Code 4
    GSP_CODE_5 = 0x0C,                        // Generic Short Packet Code 5
    GSP_CODE_6 = 0x0D,                        // Generic Short Packet Code 6
    GSP_CODE_7 = 0x0E,                        // Generic Short Packet Code 7
    GSP_CODE_8 = 0x0F,                        // Generic Short Packet Code 8

    EMBEDDED_8b = 0x12,                        // Embedded data

    YUV420_8b = 0x18,                        // YUV420 8 bit
    YUV420_10b = 0x19,                        // YUV420 10 bit
    YUV420_8b_l = 0x1A,                        // Legacy YUV420 8 bit
    YUV420_8b_CSPS = 0x1C,                    // YUV420 8-bit (Chroma Shifted Pixel Sampling)
    YUV420_10b_CSPS = 0x1D,                    // YUV420 10-bit (Chroma Shifted Pixel Sampling)
    YUV422_8b = 0x1E,                        // YUV422 8-bit
    YUV422_10b = 0x1F,                        // YUV422 10-bit

    RGB444 = 0x20,                            // RGB444
    RGB555 = 0x21,                            // RGB555
    RGB565_HC = 0x22,                        // RGB565 - TBD DRV_REFACTORING - type name conflict with AVStream
    RGB666 = 0x23,                            // RGB666
    RGB888 = 0x24,                            // RGB888

    RAW6 = 0x28,                            // RAW6 (Not supported by SRP CSI2 host controller)
    RAW7 = 0x29,                            // RAW7 (Not supported by SRP CSI2 host controller)
    RAW8 = 0x2A,                            // RAW8
    RAW10 = 0x2B,                            // RAW10
    RAW12 = 0x2C,                            // RAW12
    RAW14 = 0x2D,                            // RAW14

    // User defined 8-bit Data Types - are typically used to carry JPEG, MPEG4 and compressed RAW frames
    USER_DEFINED_8BIT_1 = 0x30,                // User Defined 8-bit Data Type 1
    USER_DEFINED_8BIT_2 = 0x31,                // User Defined 8-bit Data Type 2
    USER_DEFINED_8BIT_3 = 0x32,                // User Defined 8-bit Data Type 3
    USER_DEFINED_8BIT_4 = 0x33,                // User Defined 8-bit Data Type 4
    USER_DEFINED_8BIT_5 = 0x34,                // User Defined 8-bit Data Type 5
    USER_DEFINED_8BIT_6 = 0x35,                // User Defined 8-bit Data Type 6
    USER_DEFINED_8BIT_7 = 0x36,                // User Defined 8-bit Data Type 7
    USER_DEFINED_8BIT_8 = 0x37,                // User Defined 8-bit Data Type 8

    UNUSED_DATA_TYPE = 0xFF                    // Reserved by Intel CSI2 host controller driver to flag an un used data type.
} MIPI_DATA_TYPE;

#define IS_IMAGE_MIPI_DATA_TYPE(mipiType)   ((mipiType >= YUV420_8b) && (mipiType <= RAW14))

/*******************
// Capture output data format definitions. This table defines the CSI2 host controller output data format.
// This information will allow the CSI2 host controller to setup its pixel formatter accordingly and possibly perform the required
// data reformatting from MIPI packed format to OS friendly format. CAPTURE_DATA_FORMAT is related to the host memory formated output
// from the CSI2 host controller that is placed in host buffers that are pointed by ImageMDL data stream.
// The PreImageEmbedded and PostImageEmbedded data streams support only binary format data types.
// Intel CSI2 host controller does not support every defined data type at its input!
//
*******************/
typedef enum
{
    RAW8p = 0,                      // Output format for MIPI RAW8. 8 bpp packed to 32B. Padding at line end to 64B.
    RAW10p = 1,                     // Output format for MIPI RAW10. 10 bpp packed to 32B. Padding at line end to 64B.
    RAW12p = 2,                            // Output format for MIPI RAW12. 12 bpp packed to 32B. Padding at line end to 64B.
    RAW14p = 3,                            // Output format for MIPI RAW14. 14 bpp packed to 32B. Padding at line end to 64B.
    //YUY2_LEp16 = 4,                        // Output format for MIPI YUV422_8b. Y1UY2V... format. Padding at line end to 16B.
    YUY2_LEp64 = 5,                        // Output format for MIPI YUV422_8b. Y1UY2V... format. Padding at line end to 64B.
    //UYVY_LEp16 = 6,                        // Output format for MIPI YUV422_8b. UY1VY2... format. Padding at line end to 16B.
    UYVY_LEp64 = 7,                        // Output format for MIPI YUV422_8b. UY1VY2... format. Padding at line end to 64B.
    //NV12_LEp16 = 8,                        // Output format for MIPI YUV420_8b_CSPS. NV12 planar2 output format. Padding at line end to 16B.
    NV12_LEp64 = 9,                        // Output format for MIPI YUV420_8b_CSPS. NV12 planar2 output format. Padding at line end to 64B.
    //NV21_LEp16 = 10,                        // Output format for MIPI YUV420_8b_CSPS. NV21 planar2 output format. Padding at line end to 16B.
    NV21_LEp64 = 11,                        // Output format for MIPI YUV420_8b_CSPS. NV21 planar2 output format. Padding at line end to 64B.

    //RGBA_LEp16 = 12,                        // Output format for MIPI RGB888. 24 bpp RGB + 8b of zeroes packed to 32b. Padding at line end to 16B.
    RGBA_LEp64 = 13,                        // Output format for MIPI RGB888. 24 bpp RGB + 8b of zeroes packed to 32b. Padding at line end to 64B.
    //BGRA_LEp16 = 14,                        // Output format for MIPI RGB888. 24 bpp BGR (B,R swapped) + 8b of zeroes packed to 32b. Padding at line end to 16B.
    BGRA_LEp64 = 15,                        // Output format for MIPI RGB888. 24 bpp BGR (B,R swapped) + 8b of zeroes packed to 32b. Padding at line end to 64B.

    RGB565_3ppc_LEp64 = 16,                // Output format for MIPI RGB565. 16 bpp RGB. Padding at line end to 64B. Note: Either RGB565_3ppc_LEp64 or RGB565_4ppc_LEp64 should be exposed per HW capabilities
    RGB565_4ppc_LEp64 = 17,                // Output format for MIPI RGB565. 16 bpp RGB. Padding at line end to 64B. Note: Either RGB565_3ppc_LEp64 or RGB565_4ppc_LEp64 should be exposed per HW capabilities

    PRI_EMBEDDED8p = 18,                // Output format for Pre Image Embedded Data type - MIPI EMBEDDED_8 (that is not compressed). 8 bpp packed to 32B. Padding at line end to 64B. ??? Verify with Liron ???
    //POI_EMBEDDED8p = 19,                // Output format for Post Image Embedded Data type (not supported in MIPI CSI2). ??? Verify with Liron ???
    GSP_EMBEDDED8p = 20,                // Output format for Generic Short Packet Data type - GSP_CODE_1..GSP_CODE_8, (that is not compressed). 8 bpp packed to 32B. Padding at line end to 64B. ??? Verify with Liron ???

    I420_LEp64 = 21,                        // Output format for MIPI YUV420_8b. YV12 planar3 output format. Padding at line end to 64B.

    USER_DEFINED_8BIT_1p,
    USER_DEFINED_8BIT_2p,
    USER_DEFINED_8BIT_3p,
    USER_DEFINED_8BIT_4p,
    USER_DEFINED_8BIT_5p,
    USER_DEFINED_8BIT_6p,
    USER_DEFINED_8BIT_7p,
    USER_DEFINED_8BIT_8p

} CAPTURE_DATA_TYPE;

// The following structure is used to define one of the VC's data types (pre image data, image data, post image data, generic short packet data, etc.) that
// is supported for a specific sensor in a specific VC.
typedef struct _DATA_TYPE_SETTINGS
{
    // The following parameters define the MIPI input
    MIPI_DATA_TYPE MipiDataType;    // Data Type used by the sensor's transmission on this VC.
    //
    // A value of UNUSED_DATA_TYPE (out of the range of values that are defined in the MIPI CSI2 specification) is used
    // here to indicate that the sensor does not transmit data of this type (either pre image, image, post image or generic
    // short packet). A value of UNUSED_DATA_TYPE makes the rest of the structure not relevant. Similarly the fields in
    // IMAGE_FRAMES_BUNDLE are not relevant for this kind of data type.
    //
    // The values in this field typically comply to MIPI CSI2 specification, table 3, Datatype Classes (possible values
    // are of 6 bits). Values other than the listed below are not supported.
    // - For Pre Image Embedded Data - 0x12. See 'Table 9 Generic 8-bit Long Packet Data Types' in
    //     mipi_CSI-2_specification_v1-1.pdf.
    // - For Image Data - The range betwwen 0x18 and 0x37
    //     > YUV image data would use 0x18-0x1F. See 'Table 10 YUV Image Data Types' in mipi_CSI-2_specification_v1-1.pdf.
    //     > RGB image data would use 0x20-0x24. See 'Table 16 RGB Image Data Types' in mipi_CSI-2_specification_v1-1.pdf.
    //     > RAW image data would use 0x28-0x2D. See 'Table 20 RAW Image Data Types' in mipi_CSI-2_specification_v1-1.pdf.
    //     > User Defined image data would use 0x30-0x37. See 'Table 27 User Defined 8-bit Data Types' in
    //       mipi_CSI-2_specification_v1-1.pdf.
    //       When one of these data type is used, the Compression field below MUST be filled with meaningful information
    //       (e.g. if compression is enabled or not).
    // - For Post Image Embedded Data - TBD. Post image embedded data in MIPI CSI2 have same data type as of the pre image
    //     embedded data and hence this data goes to the pre image embedded data buffer. For CSI2 sensors, the post image
    //     data buffers should not be allocated or defined.
    //     This is a placeholder for MIPI CSI3 sensors.
    // - For Generic Short Packet Data - 0x08..0x0F. See 'Table 7 Generic Short Packet Data Type Codes' in
    //     mipi_CSI-2_specification_v1-1.pdf.

    MIPI_COMPRESSION_FORMT Compression;    // This field is useful only for a RAW sensor that transmits its image data with compression, and not for the
    // embedded data or for non RAW image data types. In such case the image data stream has to use User Defined 8-bit Data
    // Type in the range of 0x30-0x37 (see 'Table 27 User Defined 8-bit Data Types' and 'Annex E Data Compression for RAW
    // Data Types' in mipi_CSI-2_specification_v1-1.pdf).

    ULONG CRCErrorsThreshold;        // Treshold value for number of CRC errors in frame lines that result with frame error. Typically this threshold should
    // be 0 (error on 1st CRC error). This is an option for future use (e.g. in video conference, if image quality is less
    // important one or two bad image lines may be acceptable). This parameter should be filled by the AVStream driver and
    // override the value that is supplied by the sensor driver (for consistency it appears in the structure that is used
    // by te sensor driver). Sensor driver should put a 0 in this field.
    // This option is designed mostly for the image data streams. Pre image and generic short packet streams (if used),
    // should set this field to 0.

    // The following parameters define the capture buffer output for the above specified input data type
    CAPTURE_DATA_TYPE CaptureDataFormat; // Output data format. This is the required format of the output buffer. CaptureDataFormat must correlate to a
    // supported MipiDataType.
    // If the two parameters contradict each other then link creation (CreateSensorDataLink) would fail with an error.
    // SkyCam AVStream driver should first query what kind of CaptureDataFormat are supported by the CSI2 Host controller
    // for a required MipiDataType. Another option for the SkyCam AVStream driver is to query the CSI2 host controller
    // driver what kind of MipiDataType is required as input from the sensor for a required CaptureDataFormat.

    ULONG MaxDataSize;                // Up to this size the host controller will collect data into the provided buffers for this type of data. If set to
    // 0 then this data type is not used. In such case the buffer (MDL) pointer can be NULL. This parameter is set by
    // the AVStream driver per the buffer it allocated for this data type.

    BOOLEAN    BufferIsNonSnoop;        // This flag should be set only if the client driver knows for sure that SW would never read the captured output
    // buffers (this is mostly applicable to the buffers that are described by ImageBuffer.BufferMDL.
    // This will cause the CSI2 host controller to perform DMA transactions to this buffer using non snoop transactions.

    // The below values are mostly of interest for the Image data. Currently the intent is to use it to predict the CSI2 host controller buffer effective fill rate and the
    // contribution of this sensor. Each of the sensor's VCs may have another frame rate and timing parameters.
    ULONG HorizonatlLineTransmissionTime;    // In Nano Seconds. Counts the time pixels data are transmitted from start of line to end of line where horizonatl blank starts. Allows the
    // host controller driver to plan its device buffer watermarks for power management and LTR.
    ULONG HorizonatlBlankTime;                // In Nano Seconds. Counts the time from end of line pixels transmission to start of next line. Allows the host controller driver to
    // plan its device buffer watermarks for power management and LTR.
    ULONG VerticalBlankTime;                // In Nano Seconds. Counts the time from end of last line's horizontal blank to start of next frame's first line. Allows the host controller driver to
    // plan its device buffer watermarks for power management and LTR.
    ULONG FrameTime;                        // In Nano Seconds. Counts frame duration. 1/FrameTime is the frame rate.
    // Frame time = (HorizonatlLineTransmissionTime + HorizonatlBlankTime) * NumOfLines + VerticalBlankTime.
    // Allows the host controller driver to plan its device buffer watermarks for power management and LTR.
    ULONG ImageWidth;                        // Image width in pixels
    ULONG ImageHeight;                        // Image height in pixels
} DATA_TYPE_SETTINGS, *PDATA_TYPE_SETTINGS;

#define CIO2_DATA_TYPES_MAX 16

typedef struct _VC_SETTINGS
{
    UCHAR VC_Value;                            // VC used for this stream. Supported values are 0,1,2,3. A value of 0xFF means that this VC is not used by the sensor and the rest
    // of this structure has no meaningful value.

    DATA_TYPE_SETTINGS    DataType[CIO2_DATA_TYPES_MAX];        // CIO2 host controller supports up to 16 pairs of VC and data type per link. If the sensor makes use of a single VC, then
    // up to 16 different data types can be used. If the sensor transmits in more than one VC, then the amount of data types in all the
    // VCs must not exceed 16.
    // A RAW sensor that supports HDR may send multiple images (up to 4) each with its image data and embedded data on its own VC. Also here,
    // the amount of data types in all the VCs must not exceed 16. In this setup, it is expected that all VCs would transmit in same frame
    // rate and always in same order between the VCs, such that the driver can eliminate interrupts on all related DMA engines and setup the
    // last transmitted frame of the sesnor to generate interrupt for the whole set of buffers.
    // If there are two sensors that share a link then each of them utilize a different VC. Also here, the amount of data types in all the
    // VCs must not exceed 16.
    // RAW sensors transmit their per image settings ('embedded data' - dump of sensor registers that the sensor used for taking this image) using
    // specific data type, and their image data using another data type.

    MIPI_DATA_TYPE ExpectedLastDataTypeBeforeEOF;    // Sensor driver should specify here which of the different data types it transmits last - before end of frame (all
    // other data types transmiossion is assumed to end before this one).
    // This value should match only one of the DataType values in one of the above DATA_TYPE_SETTINGS for this
    // stream. The CSI2 HC driver makes use of this hint to order its look up table (LUT) for this stream
    // such that the last expected data type transfer will reside last in the LUT. This will guarantee
    // proper CSI2 buffers eviction. In addition the CSI2 HC driver will request an end of frame interrupt
    // from the DMA of this last data type DMA to guarantee that all other data type DMAs are already done.
    // In the case the sensor transmits frames in more than one Virtual Channel (VC), then this parameter
    // should be set as described above only at the VC that is expected to complete the transmission of its
    // frame last. All other VCs that end their data trasmission before, should set this parameter to
    // UNUSED_DATA_TYPE (0xFF) - this means that the order that their entries in the LUT is set does not matter, and only the
    // entries of the last transmitting VC should be set in the above mentioned order. Similarly the DMA
    // engines of these VCs (not the one that transmits last) should not be set to generate interrupts,
    // and only the matching one of the last transmitting VC would generate an interrupt at frame end for
    // all of them.

} VC_SETTINGS, *PVC_SETTINGS;

// Note: Same structure (and its dependencies structures) resides in the SensorInterface.h file. Currently same structure serves both sides. If this will
// be true, then this structure (and its dependencies) should be placed in an external H file that should be included into both include files. Note that
// at the sensor driver interface this structure is provided to the AVStream driver, while this structure is provided by the AVStream driver to the CSI2 HC
// driver.
// Similar handling the VC_SETTINGS above deserves.
typedef struct _SENSOR_LINK
{
    HOST_CONTROLLER HostControllerID;        // Identification of the host controller to which this sensor connects

    HOST_CONTROLLER_GLOBAL HostControllerGlobal; // This (same) structure is provided by the BIOS to each of the sensor drivers as part of its ACPI
    // resources (hence it is global and not per sensor).
    // The sensor driver provides it to the AVStream driver, and the AVStream driver provides it to the CSI2
    // HC driver with every sensor link that it wants to create.

    UCHAR LinkSharingKey;                    // BIOS sets this flag.
    // When 0, this CSI2 link is not shared with another sensor. All VCs on the link belong to one sesnor.
    // When a non 0 value is used, the link is shared between one or more sensors, each controlled by its own sensor driver.
    // Each of the link sharing drivers must get same LinkSharingKey from the BIOS. If there are other links that are shared
    // by two or more sensors, the BIOS must provide them a different LinkSharingKey.

    ULONG LinkUsed;                            // Link used by this sensor stream. The value for each of the platform sensors depends on platform routing.
    // Valid numbers are:
    //        0 - This sensor uses link0. A high resolution sensor that uses two links must put in this field a value
    //            of 0 and LanesUsed is 8.
    //        1 - This sensor uses link1
    //        2 - This sensor uses link2
    //        3 - This sensor uses link3
    // Values other than the listed are not supported.
    // The Sensor driver receives from the BIOS as part of its ACPI resources the LinkUsed parameter. The sensor
    // driver reports to the AVStream driver the LinkUsed and the AVStream driver reports it to the CSI2 HC driver.

    UCHAR LanesUsed;                        // Number of lanes connected for this sensor. The value for each of the platform sensors depends on platform
    // routing. However even if a sensor is connected to number of lanes, it still can be used with a smaller number
    // of lanes. It is the decission of its sensor driver how many lanes to use. This decission may be based on the
    // selected resolution and frame rate based on power calculations at the sensor driver. This means that this
    // setting may vary based on sensor settings. Valid numbers are:
    //        1 - One lane
    //        2 - Two lanes
    //        3 - Three lanes
    //        4 - Four lanes
    //        8 - Eight lanes (requires CSI2 HC to be in 'channel merging' mode. Selection of 8 lanes is possible only
    //            for high resolution sensor, and requires also that LinkUsed is 0. In addition in this mode, Channel
    //            Merging mode parameter is required (see below).
    // Values other than the listed are not supported.
    //
    // The Sensor driver receives from the BIOS as part of its ACPI resources the ActualNumberOfLanes. The sensor
    // driver reports to the AVStream driver the LanesUsed per sensor driver decission (LanesUsed must
    // be < ActualNumberOfLanes) and the AVStream driver reports it to the CSI2 HC driver.

    LINK_DELAY_PARAMETERS LinkDelayParameters;// These are platform parameters that should set registers 0x24 0x48 of the CSI2-FE of the link. They have
    // to be configured according to the sensor specific parameters! BIOS provides this table to the sensor driver
    // as part of the ACPI resources of the sensor. The sensor driver has to provide these values to the CSI2 driver
    // through the AVStream driver.
    // The values are not only sensor specific, but are platform routing specific and are result of measurements and
    // tuning (there can be different distances even for lanes of same link), so some lanes have to add delays that
    // are platform related). Mostly Settle time is important. Termination time can be 0.

    ULONG ActualLaneSpeed;                    // Actual lane speed that the sensor uses for the lanes it uses. This parameter is a result of platform
    // validation at the OEM and is defined to allow limiting the MIPI data rate in case the platform routing
    // results with errors in higher speeds. This parameter is provided to the sensor driver by the BIOS as part of
    // the sensor's ACPI resources. The sensor driver should use this parameter to limit its sensor MIPI speed
    // accordingly. The sensor driver would decide what is the sensor's MIPI speed per the required settings (may
    // use different speed per resolution or power calculations) and provide its current link speed parameter within
    // this structure member per its settings to the AVStream driver which will forward it to the CSI2 HC driver.
    // The CSI2 HC driver use this parameter as the current link speed and not the MAX link speed and may use it
    // with LanesUsed and the values that it receives from the other sensors along with number of active links to
    // calculate the SRAM watermarks and the LTR values.
    // Values are in bits/sec. Examples:
    //        1000000000 - 1000Mbps (1Gbps)
    //        1500000000 - 1500Mbps (1.5Gbps) - this is the typical maximum speed for MIPI CSI2

    ULONG ChannelMergingMode;                // Channel Merging Mode is applicable only for sensors that use 8 lanes (LanesUsed = 8). Otherwise this field
    // has no meaning.
    // Sensor driver fills this field. AVStream driver forwards without change to the CSI2 HC driver in same field
    // of the structure.
    // Values:
    //    000: Odd/Even
    //    001: Even/Odd
    //    010: 4/4 no swap
    //    011: 4/4 swap
    //    100: reserved
    //    101: reserved
    //    110: reserved
    //    111: reserved

    VC_SETTINGS VcSettings[4];                // Settings for each of the supported Virtual Channels. Note: an unsupported VC would have the VcSettings[4].VC_Value = 0xFF.

    BOOLEAN SensorProvidesFrameNumbers;        // CSI2 provides a mechanism to provide frame numbers by the sensor. However there are sensors that flip frame
    // numbers as 0,1,0,1... in a non meaningful way. The CSI2 host controller has a capability to count frames by
    // itself. If FALSE, sensor frame numbers that the sensor generates are not accurate or meningful, and frame
    // numbers should be provided by the CSI2 HC. If TRUE, sensor provides meaningful frame numbers and CSI2 HC
    // should place these frame numbers in the frame descriptors.

} SENSOR_LINK, *PSENSOR_LINK;

//[TODO][wchojnow] move the structs to ispstubdrvPublic.h or similar ??
typedef struct _INPUT_RESOLUTION
{
    SNSR_RESOLUTION_DEBUG resolution;
    CIO2_LINK_ID           linkId;
} INPUT_RESOLUTION, *PINPUT_RESOLUTION;

typedef struct _OUTPUT_SENSOR_CONNECTION
{
    UCHAR       sensorLinkValid[HC_LINK_NUMBER];
    SENSOR_LINK  sensorLink[HC_LINK_NUMBER];
} OUTPUT_SENSOR_CONNECTION, *POUTPUT_SENSOR_CONNECTION;

typedef enum _STREAM_SOURCE
{
    STREAM_SOURCE_SENSOR = 0,       //CSI2 Sensor
    STREAM_SOURCE_DFT,              //DFT file
    STREAM_SOURCE_MAX
} STREAM_SOURCE;

typedef enum _SENSOR_MODE
{
    SENSOR_MODE_LIVE_STREAM = 0,        //CSI2 Sensor (live stream)
    SENSOR_MODE_TEST_PATTERN_SOLID,     //CSI2 Sensor (test pattern - solid color)
    SENSOR_MODE_TEST_PATTERN_COLORBARS, //CSI2 Sensor (test pattern - color bars)
    SENSOR_MODE_MAX                     //Value above or equal MODE_MAX means custom test pattern
} SENSOR_MODE;

/*******************
* \brief Frame data format definitions
*
*******************/
typedef struct _CAPTURE_DATA_FORMAT
{
    ULONG pixelsPerRow;
    ULONG rowsInFrame;
    MIPI_DATA_TYPE pixelDataType;
    CAPTURE_DATA_TYPE captureDataType;
} CAPTURE_DATA_FORMAT, *PCAPTURE_DATA_FORMAT;

typedef enum
{
    bpp8 = 0,
    bpp10 = 1,
    bpp12 = 2,
    bpp14 = 3,
} BITS_PER_PIXEL;

typedef struct _CIO2_PXF_FORMAT
{
    MIPI_DATA_TYPE             inputFormat;
    UCHAR                      ppc;
    CAPTURE_DATA_TYPE          outputFormat;
    UCHAR                      pSwap4;
    BITS_PER_PIXEL             bppField;
    UCHAR                      spec;
    UCHAR                      pck;
    UCHAR                      bitsPerPixel;
    UCHAR                      dmaRequired;
} CIO2_PXF_FORMAT, *PCIO2_PXF_FORMAT;

// Enumeration of frames bundle reporting mode
typedef enum
{
    FBRM_START_OF_FRAMES_BUNDLE = 0,    // Report when frame starts reception. This mode intends to allow the ISP to process frame N-1 when frmae N starts. Note - this mode is
    // currently only a placeholder !
    FBRM_END_OF_FRAMES_BUNDLE = 1,    // Report when frames bundle reception completed
    FBRM_FRAMES_BUNDLE_LINE_NUMBER = 2    // Report when frame reception passed a predefined line number. This mode intends to allow the ISP to start process frame N when its reception
    // passed a certain threshold (line number). This is a cut through mode that allows the ISP to finish its frame processing short time after the
    // frame ends. It requires that the threshold line will be safe (not too small) to make sure the ISP is not too fast and will either get into
    // data underrun situation or need to wait (by polling current line number at the CSI2 host controller descriptor) for the CSI2 host controller
    // to fill next chunk of lines to be processed.
    // When this mode is used, ThresholdLineNumber and LineNumberUpdate are meaningful.
    // Note - this mode is currently only a placeholder !
} FRAMES_BUNDLE_REPORT_MODE;

// Enumeration of frame reporting state
typedef enum
{
    FRAME_REPORT_START_OF_FRAME = 0,         // Frames bundle provided when subsequent frames bundle started reception. The returned IMAGE_FRAMES_BUNDLE in this case is of the previous frames bundle.
    // At this point the IMAGE_FRAMES_BUNDLE of the previous completed frames bundle returns to the AVStream driver.
    FRAME_REPORT_END_OF_FRAME = 1,        // Frame notification at end of frames bundle. The returned IMAGE_FRAMES_BUNDLE in this case is of the current completed frames bundle.
    // At this point the IMAGE_FRAMES_BUNDLE of the current completed frames bundle returns to the AVStream driver.
    FRAME_REPORT_REACHED_FRAME_LINE = 2,        // Frames bundle notification due to received expected number of lines of the current frame. The returned IMAGE_FRAMES_BUNDLE in this case is of
    // the current frames bundle. In this case the CurrentFrameFBPT_VA and CurrentFrameFBPT_PA are meaningful and will be used by the ISP to look at
    // receive progress through the CurLineNum field of the FBPT of the CSI2 HC device descriptor. When the FRAME_REPORT_STATE is
    // FRAME_REPORT_REACHED_FRAME_LINE then the IMAGE_FRAMES_BUNDLE (of the current frame) still belongs to the CSI2 HC driver!
    // Once the ISP completes the processing of this progressing current frame, it interrupts the ISP driver and this will cause the AVStream
    // driver to call the CompletedFramesBundleProcessing API of the CSI2 host controller driver which in turn will return the completed frame buffer
    // with the latest updated status to the AVStream driver by calling the FRAME_COMLETE callback (now with State of FRAME_REPORT_END_OF_FRAME).
    // At this point the ownership of IMAGE_FRAMES_BUNDLE of the completed frames bundle returns to the AVStream driver.
    FRAME_REPORT_NONE = 0xFF    // Frames bundle returned as received - not used (buffers are empty). Usually used at end of stream when CSI2 HC driver returns to the AVStream driver the
    // last unused buffers.
} FRAME_REPORT_STATE;

typedef enum
{
    HCI_DMA_TRANSACTION_CREATED = 0,
    HCI_DMA_TRANSACTION_STATE_INITIALIZED,
    HCI_DMA_TRANSACTION_STATE_EXECUTED,
    HCI_DMA_TRANSACTION_STATE_PROGRAMMED,
    HCI_DMA_TRANSACTION_STATE_COMPLETED,
    HCI_DMA_TRANSACTION_STATE_RELEASED,
    HCI_DMA_TRANSACTION_STATE_CANCELED,
    HCI_DMA_TRANSACTION_STATE_INVALID
} HCI_DMA_TRANSACTION_STATE;

typedef enum
{
    HCI_SUCCESS = 0,
    HCI_ERROR_NO_BUFFERS_FROM_ISP,
    HCI_ERROR_UNSPECIFIED
} HCI_ERROR_CODE;

typedef struct _STREAM_CONTEXT
{
    CIO2_LINK_ID linkID;
} STREAM_CONTEXT, *PSTREAM_CONTEXT;

#pragma warning(disable : 4214)     //warning C4214: nonstandard extension used : bit field types other than int
#ifdef VC707_DMA
typedef struct _HCI_FBPT_ENTRY
{
    // LOP0 - 128 bits
    ULONGLONG Valid                     : 1;  // byte 1 - 3
    ULONGLONG IOC                       : 1;
    ULONGLONG IOS                       : 1;
    ULONGLONG FailxSucc                 : 1;
    ULONGLONG ErrCode                   : 20;
    ULONGLONG Reserved0                 : 8;  // byte 4

    ULONGLONG CurLineNum                : 14; // byte 5 - 6
    ULONGLONG Reserved02                : 2;
    ULONGLONG FrameNo                   : 16; // byte 7 - 8

    ULONGLONG FirstPageOffsetBytes      : 12;  // byte 9 - 12
    ULONGLONG Reserved03                : 20;

    ULONGLONG LOP0Addr                  : 32;  // byte 13 - 16

    // there is no fixed number of subentries - but each entry have always 4 subentries,
    // only number of entries per frame is variable
    // LOP1
    ULONGLONG TimeStamp                 : 32;  // byte 17 - 20

    ULONGLONG NumOfBytes                : 28;  // byte 21 - 24
    ULONGLONG Reserved11                : 4;

    ULONGLONG LastPageAvailableBytes    : 12;  // byte 25 - 26
    ULONGLONG Reserved12                : 4;
    ULONGLONG NumOfPages                : 16;  // byte 27 - 28

    ULONGLONG LOP1Addr                  : 32;  // byte 29 - 32

    // LOP2
    ULONGLONG Reserved31;                     // byte 33 - 40

    ULONGLONG Reserved32                : 32;  // byte 41 - 44

    ULONGLONG LOP2Addr                  : 32;  // byte 45 - 48


    // LOP3
    ULONGLONG Reserved41;                     // byte 49 - 56

    ULONGLONG Reserved42                : 32;  // byte 57 - 60

    ULONGLONG LOP3Addr                  : 32;  // byte 61 - 64
} HCI_FBPT_ENTRY, *PHCI_FBPT_ENTRY;
#else
typedef struct _HCI_FBPT_ENTRY
{
    // LOP0
    ULONGLONG Valid              : 1;
    ULONGLONG FailxSucc          : 1;
    ULONGLONG ErrCode            : 5;
    ULONGLONG IOC                : 1;
    ULONGLONG LOP0Addr          : 56;

    ULONGLONG FrameNo           : 16;
    ULONGLONG PreImDataSize     : 16;
    ULONGLONG PostImDataSize    : 16;
    ULONGLONG Reserved1         : 16;

    // there is no fixed number of subentries - but each entry have always 4 subentries,
    // only number of entries per frame is variable
    // LOP1
    ULONGLONG Reserved2       :8;
    ULONGLONG LOP1Addr        :56;

    ULONGLONG Reserved22;

    // LOP2
    ULONGLONG Reserved3       :8;
    ULONGLONG LOP2Addr        :56;

    ULONGLONG Reserved32;

    // LOP3
    ULONGLONG Reserved4       :8;
    ULONGLONG LOP3Addr        :56;

    ULONGLONG Reserved42;
} HCI_FBPT_ENTRY, *PHCI_FBPT_ENTRY;
#endif  //VC707_DMA

// Link statistics
// ToDO - Need to add here all kind of statistics that the HW expose and driver can log
typedef struct _LINK_STATISTICS
{
//    OUT ULONG    NumOfEccErrors;
//    OUT ULONG    NumOfXYZ;            // ToDO - Need to add here all kind of statistics that the HW expose and driver can log  (that are also reported per frame in FrameComplete)
    OUT ULONG   PXM_CRC;
    OUT ULONG   PXM_ECC;
    // INT_STS_EXT_IE errors
    OUT ULONG   IE_ECC_RE;
    OUT ULONG   IE_DPHY_NR;
    OUT ULONG   IE_ECC_NR;
    OUT ULONG   IE_CRCERR;
    OUT ULONG   IE_InterFrameData;
    OUT ULONG   IE_PKT2SHORT;
    OUT ULONG   IE_PKT2LONG;
    OUT ULONG   IE_IRQ;
    // INT_STS_EXT_OE errors
    OUT ULONG   OE_DMA_OutputError;
    OUT ULONG   OE_OutputErrorFromInMgr;
    // CmpCode errors (also reported for each frame in FrameComplete)
    // Error reported by CSI2 Controller
    OUT ULONG   CmpCode_CSI2_DPHY_NR;
    OUT ULONG   CmpCode_CSI2_ECC_NR;
    OUT ULONG   CmpCode_CSI2_DPHY_RE;
    OUT ULONG   CmpCode_CSI2_ECC_RE;
    OUT ULONG   CmpCode_CSI2_CRCERR;
    OUT ULONG   CmpCode_CSI2_NO_FE;
    OUT ULONG   CmpCode_CSI2_InterFrameData;
    OUT ULONG   CmpCode_CSI2_PKT2SHORT;
    OUT ULONG   CmpCode_CSI2_PKT2LONG;
    // Errors reported by the CHC (Input and Output)
    OUT ULONG   CmpCode_CHC_CRCERRS;
    OUT ULONG   CmpCode_CHC_SRAMFULL;
    OUT ULONG   CmpCode_CHC_TBLFULL;
    OUT ULONG   CmpCode_CHC_MRGERR;
    OUT ULONG   CmpCode_CHC_BufOverflow;
} LINK_STATISTICS, *PLINK_STATISTICS;

typedef struct _SUPPORTED_CAPTURE_DATA_FORMATS
{
    ULONG                NumOfSupportedDataFormats;        // Specifies how many entries in the SupportedCaptureDataFormats are valid (possible values 1..8)
    CAPTURE_DATA_TYPE    SupportedCaptureDataFormats[8];    // Up to 8 different data formats
} SUPPORTED_CAPTURE_DATA_FORMATS, *PSUPPORTED_CAPTURE_DATA_FORMATS;

typedef struct _SUPPORTED_MIPI_DATA_TYPES
{
    ULONG            NumOfSupportedDataTypes;            // Specifies how many entries in the SupportedMipiDataTypes are valid (possible values 1..8)
    MIPI_DATA_TYPE    SupportedMipiDataTypes[8];            // Up to 8 different data types
} SUPPORTED_MIPI_DATA_TYPES, *PSUPPORTED_MIPI_DATA_TYPES;

//define IOCTL timeout in ms
#define TIMEOUT_MS_IOCTL 2000

//global base
#define GLOBAL_IOCTL_FUNCCODE_BASE                  0x800
// Global operations
#define GLOBAL_IOCTL_BASE                           GLOBAL_IOCTL_FUNCCODE_BASE
#define GLOBAL_IOCTL_GET_VERSION_FUNCTION_CODE      GLOBAL_IOCTL_BASE+0x1

//MMIO operations - register and buffer
#define MMIO_IOCTL_BASE                             GLOBAL_IOCTL_FUNCCODE_BASE+0x50
#define MMIO_IOCTL_READ_REG32_FUNCTION_CODE         MMIO_IOCTL_BASE+0x1
#define MMIO_IOCTL_WRITE_REG32_FUNCTION_CODE        MMIO_IOCTL_BASE+0x2
#define MMIO_IOCTL_READ_REG64_FUNCTION_CODE         MMIO_IOCTL_BASE+0x3
#define MMIO_IOCTL_WRITE_REG64_FUNCTION_CODE        MMIO_IOCTL_BASE+0x4
#define MMIO_IOCTL_READ_BUFFER_FUNCTION_CODE        MMIO_IOCTL_BASE+0x5
#define MMIO_IOCTL_WRITE_BUFFER_FUNCTION_CODE       MMIO_IOCTL_BASE+0x6
#define MMIO_IOCTL_FRAME_LIST_FILE_FUNCTION_CODE    MMIO_IOCTL_BASE+0x7
#define MMIO_IOCTL_SELECT_SOURCE_FUNCTION_CODE      MMIO_IOCTL_BASE+0x8

//PCI operations
#define PCI_IOCTL_BASE                              GLOBAL_IOCTL_FUNCCODE_BASE+0x100
#define PCI_IOCTL_SAVE_FUNCTION_CODE                PCI_IOCTL_BASE+0x1
#define PCI_IOCTL_RESTORE_FUNCTION_CODE             PCI_IOCTL_BASE+0x2
#define PCI_IOCTL_RESET_FUNCTION_CODE               PCI_IOCTL_BASE+0x3

//IOCTL BASE FOR CPX FUNCTIONS
#define CPIO_IOCTL_FUNCCODE_BASE                    GLOBAL_IOCTL_FUNCCODE_BASE+0x120

//IOCTL BASE FOR CPHW FUNCTIONS
#define CPHW_IOCTL_FUNCCODE_BASE                    GLOBAL_IOCTL_FUNCCODE_BASE+0x150

//IOCTL BASE FOR CPX FUNCTIONS
#define CPX_IOCTL_FUNCCODE_BASE                     GLOBAL_IOCTL_FUNCCODE_BASE+0x200
#define CPX_RESET_DEVICE_FUNCTION_CODE              CPX_IOCTL_FUNCCODE_BASE+0x11

#define CPX_IOCTL_DMA_BASE                          GLOBAL_IOCTL_FUNCCODE_BASE+0x250
#define CPX_IOCTL_DMA_CREATE_SENSOR_DATA_LINK       CPX_IOCTL_DMA_BASE+0x1
#define CPX_IOCTL_DMA_START_STREAM                  CPX_IOCTL_DMA_BASE+0x2
#define CPX_IOCTL_DMA_STOP_STREAM                   CPX_IOCTL_DMA_BASE+0x3
#define CPX_IOCTL_DMA_SUBMIT_FRAMES_BUNDLE          CPX_IOCTL_DMA_BASE+0x4
#define CPX_IOCTL_DMA_GET_FRAME                     CPX_IOCTL_DMA_BASE+0x5
#define CPX_IOCTL_SELECT_STREAM_SOURCE              CPX_IOCTL_DMA_BASE+0x6
#define CPX_IOCTL_DMA_GET_FBPT_ENTRY                CPX_IOCTL_DMA_BASE+0x7
#define CPX_IOCTL_DMA_GET_LINK_STATISTICS           CPX_IOCTL_DMA_BASE+0x8
#define CPX_IOCTL_TRIGGER_FLASH                     CPX_IOCTL_DMA_BASE+0x9
#define CPX_IOCTL_QUERY_HOST_CONTROLLER             CPX_IOCTL_DMA_BASE+0xA
#define CPX_IOCTL_QUERY_MIPI_DT_TO_CAPTURE_DT       CPX_IOCTL_DMA_BASE+0xB
#define CPX_IOCTL_QUERY_CAPTURE_DT_TO_MIPI_DT       CPX_IOCTL_DMA_BASE+0xC
#define CPX_IOCTL_GET_TIMESTAMP                     CPX_IOCTL_DMA_BASE+0xD
#define CPX_IOCTL_FRAME_BUNDLE_PROCESSING_COMPLETE  CPX_IOCTL_DMA_BASE+0xE

/**************************************************************************
/* IOCTL DESCRIPTION
/**************************************************************************/

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      GLOBAL_IOCTL_GET_VERSION
// DESCRIPTION:     Read driver/HW versions
// INPUT BUFFER:    IOCTL_GET_VERSION
// OUTPUT BUFFER:   ULONG32 (Version)
//////////////////////////////////////////////////////////////////////////
#define IOCTL_GET_VERSION               CTL_CODE(FILE_DEVICE_UNKNOWN, GLOBAL_IOCTL_GET_VERSION_FUNCTION_CODE, METHOD_BUFFERED,  FILE_ANY_ACCESS)
typedef struct _IOCTLGetVersion_
{
    ULONG32 ulComponentID;                          // Component ID for version query (TComponentID)
} IOCTL_GET_VERSION_BUFF, *PIOCTL_GET_VERSION_BUFF;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_FRAME_LIST_FILE
// DESCRIPTION:     Get framelist file name
// INPUT BUFFER:    the name above includes a list of files, each of which contains one frame
// OUTPUT BUFFER:   NULL
//////////////////////////////////////////////////////////////////////////
#define IOCTL_FRAME_LIST_FILE           CTL_CODE(FILE_DEVICE_UNKNOWN, MMIO_IOCTL_FRAME_LIST_FILE_FUNCTION_CODE, METHOD_BUFFERED,  FILE_ANY_ACCESS)

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_SELECT_SOURCE
// DESCRIPTION:     Select source for input frames
// INPUT BUFFER:    IOCTL_SELECT_SOURCE
// OUTPUT BUFFER:   NULL
//////////////////////////////////////////////////////////////////////////
#define IOCTL_SELECT_SOURCE             CTL_CODE(FILE_DEVICE_UNKNOWN, MMIO_IOCTL_SELECT_SOURCE_FUNCTION_CODE, METHOD_BUFFERED,  FILE_ANY_ACCESS)

typedef struct _IOCTLSelectSourceDescriptor_
{
    ULONG32 source_mode;
    ULONG32 ulTotalDescriptorSize; //depicts the actual buffer size inc. for validation
} IOCTL_SELECT_SOURCE_DESCRIPTOR, *PIOCTL_SELECT_SOURCE_DESCRIPTOR;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_READ_BUFFER
// DESCRIPTION:     Read memory buffer
// INPUT BUFFER:    IOCTL_BUFFER_DESCRIPTOR
// OUTPUT BUFFER:   IOCTL_BUFFER_DESCRIPTOR
//////////////////////////////////////////////////////////////////////////
#define IOCTL_READ_BUFFER               CTL_CODE(FILE_DEVICE_UNKNOWN, MMIO_IOCTL_READ_BUFFER_FUNCTION_CODE, METHOD_BUFFERED,  FILE_ANY_ACCESS)

typedef struct _IOCTLBufferInfoHeader_
{
    ULONG64 ulOffset;
    ULONG32 ulSize;
    ULONG32 ulTotalDescriptorSize; //depicts the actual buffer size inc. the allocation
#ifndef PIXTER_GAL_DRV
    ULONG   bufferNumber; //! we support up to MAX_BUFFERS_NUMBER of buffers
#endif
} IOCTL_BUFFER_INFO_HEADER, *PIOCTL_BUFFER_INFO_HEADER;

typedef struct _IOCTLBufferDescriptor_
{
    IOCTL_BUFFER_INFO_HEADER Header;
    ULONG32 ulBufferStartAddr;
} IOCTL_BUFFER_DESCRIPTOR, *PIOCTL_BUFFER_DESCRIPTOR;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_WRITE_BUFFER
// DESCRIPTION:     Write memory buffer
// INPUT BUFFER:    IOCTL_BUFFER_DESCRIPTOR
// OUTPUT BUFFER:   NULL
//////////////////////////////////////////////////////////////////////////
#define IOCTL_WRITE_BUFFER              CTL_CODE(FILE_DEVICE_UNKNOWN, MMIO_IOCTL_WRITE_BUFFER_FUNCTION_CODE, METHOD_BUFFERED,  FILE_ANY_ACCESS)

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_READ_REGISTER32
// DESCRIPTION:     Read 32bit register
// INPUT BUFFER:    IOCTL_REG_DESCRIPTOR32
// OUTPUT BUFFER:   IOCTL_REG_DESCRIPTOR32
//////////////////////////////////////////////////////////////////////////
#define IOCTL_READ_REGISTER32           CTL_CODE(FILE_DEVICE_UNKNOWN, MMIO_IOCTL_READ_REG32_FUNCTION_CODE, METHOD_BUFFERED,  FILE_ANY_ACCESS)

typedef struct _IOCTLRegDescriptor32_
{
    ULONG32 ulChannel;
    ULONG32 ulOffset;
    ULONG32 ulValue;
} IOCTL_REG_DESCRIPTOR32, *PIOCTL_REG_DESCRIPTOR32;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_WRITE_REGISTER32
// DESCRIPTION:     Write 32bit register
// INPUT BUFFER:    IOCTL_REG_DESCRIPTOR32
// OUTPUT BUFFER:   IOCTL_REG_DESCRIPTOR32
//////////////////////////////////////////////////////////////////////////
#define IOCTL_WRITE_REGISTER32          CTL_CODE(FILE_DEVICE_UNKNOWN, MMIO_IOCTL_WRITE_REG32_FUNCTION_CODE, METHOD_BUFFERED,  FILE_ANY_ACCESS)

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_READ_REGISTER64
// DESCRIPTION:     Read 64bit register
// INPUT BUFFER:    IOCTL_REG_DESCRIPTOR64
// OUTPUT BUFFER:   IOCTL_REG_DESCRIPTOR64
//////////////////////////////////////////////////////////////////////////
#define IOCTL_READ_REGISTER64           CTL_CODE(FILE_DEVICE_UNKNOWN, MMIO_IOCTL_READ_REG64_FUNCTION_CODE, METHOD_BUFFERED,  FILE_ANY_ACCESS)
typedef struct _IOCTLRegDescriptor64_
{
    ULONG32 ulChannel;
    ULONG32 ulOffset;
    ULONG64 ulValue;
} IOCTL_REG_DESCRIPTOR64, *PIOCTL_REG_DESCRIPTOR64;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_WRITE_REGISTER64
// DESCRIPTION:     Write 64bit register
// INPUT BUFFER:    IOCTL_REG_DESCRIPTOR64
// OUTPUT BUFFER:   none
//////////////////////////////////////////////////////////////////////////
#define IOCTL_WRITE_REGISTER64          CTL_CODE(FILE_DEVICE_UNKNOWN, MMIO_IOCTL_WRITE_REG64_FUNCTION_CODE, METHOD_BUFFERED,  FILE_ANY_ACCESS)

//Sagi - limit these IOCTLS to debug mode only
//Fail these IOCTL automatically STATUS_UNSUPPORTED

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_SAVE_PCI_CONFIG_SPACE
// DESCRIPTION:     Save PCI configuration space for specific device
// INPUT BUFFER:    none
// OUTPUT BUFFER:   none
//////////////////////////////////////////////////////////////////////////
#define IOCTL_SAVE_PCI_CONFIG_SPACE     CTL_CODE(FILE_DEVICE_UNKNOWN, PCI_IOCTL_SAVE_FUNCTION_CODE, METHOD_BUFFERED,  FILE_ANY_ACCESS)

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_RESTORE_PCI_CONFIG_SPACE
// DESCRIPTION:     Restore PCI configuration space for specific device
// INPUT BUFFER:    none
// OUTPUT BUFFER:   none
//////////////////////////////////////////////////////////////////////////
#define IOCTL_RESTORE_PCI_CONFIG_SPACE  CTL_CODE(FILE_DEVICE_UNKNOWN, PCI_IOCTL_RESTORE_FUNCTION_CODE, METHOD_BUFFERED,  FILE_ANY_ACCESS)

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_RESET_DEVICE
// DESCRIPTION:     Reset HW devices
// INPUT BUFFER:    Reset type (ULONG32 - TResetType)
// OUTPUT BUFFER:   none
//////////////////////////////////////////////////////////////////////////

//block SAVE/RESTORE PCI SPACE
#define IOCTL_RESET_DEVICE              CTL_CODE(FILE_DEVICE_UNKNOWN, PCI_IOCTL_RESET_FUNCTION_CODE, METHOD_BUFFERED,  FILE_ANY_ACCESS)

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_HC_SELECT_STREAM_SOURCE
// DESCRIPTION:     Select stream source (DFT vs CSI2 sensor)
// INPUT BUFFER:    HC_SELECT_STREAM_SOURCE
// OUTPUT BUFFER:   NULL
//////////////////////////////////////////////////////////////////////////
#define IOCTL_HC_SELECT_STREAM_SOURCE   CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_IOCTL_SELECT_STREAM_SOURCE, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _HC_SELECT_STREAM_SOURCE
{
    ULONG32 sourceID;
} HC_SELECT_STREAM_SOURCE, *PHC_SELECT_STREAM_SOURCE;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_GET_FBPT_ENTRY
// DESCRIPTION:     Get fbpt entry
// INPUT BUFFER:    INPUT_IOCTL_GET_FBPT_ENTRY
// OUTPUT BUFFER:   OUTPUT_IOCTL_GET_FBPT_ENTRY
//////////////////////////////////////////////////////////////////////////
#define IOCTL_GET_FBPT_ENTRY            CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_IOCTL_DMA_GET_FBPT_ENTRY, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _INPUT_IOCTL_GET_FBPT_ENTRY
{
    ULONG dmaID;
    ULONG EntryID;
} INPUT_IOCTL_GET_FBPT_ENTRY, *PINPUT_IOCTL_GET_FBPT_ENTRY;

typedef struct _OUTPUT_IOCTL_GET_FBPT_ENTRY
{
    HCI_FBPT_ENTRY  fbptEntry;
    UINT8           buffer[OUTPUT_IOCTL_FBPT_BUFFER_SIZE];
    UINT8           bBufferCopied;
    PVOID           pVirtualAddr;
    ULONG           frameSize;
    ULONG           linkId;
} OUTPUT_IOCTL_GET_FBPT_ENTRY, *POUTPUT_IOCTL_GET_FBPT_ENTRY;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_GET_LINK_STATISTIC
// DESCRIPTION:     Get link statistics
// INPUT BUFFER:    INPUT_IOCTL_LINK_STATISTIC
// OUTPUT BUFFER:   OUTPUT_IOCTL_GET_LINK_STATISTIC
//////////////////////////////////////////////////////////////////////////
#define IOCTL_GET_LINK_STATISTICS            CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_IOCTL_DMA_GET_LINK_STATISTICS, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _INPUT_IOCTL_GET_LINK_STATISTICS
{
    CIO2_LINK_ID linkID;
} INPUT_IOCTL_GET_LINK_STATISTICS, *PINPUT_IOCTL_GET_LINK_STATISTICS;

typedef struct _OUTPUT_IOCTL_GET_LINK_STATISTICS
{
    CIO2_LINK_ID           linkId;
    LINK_STATISTICS linkStatistics;
} OUTPUT_IOCTL_GET_LINK_STATISTICS, *POUTPUT_IOCTL_GET_LINK_STATISTICS;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_QUERY_HOST_CONTROLLER
// DESCRIPTION:     Returns Host Controller BDF
// INPUT BUFFER:    NULL
// OUTPUT BUFFER:   OUTPUT_IOCTL_QUERY_HOST_CONTROLLER
//////////////////////////////////////////////////////////////////////////
#define IOCTL_QUERY_HOST_CONTROLLER             CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_IOCTL_QUERY_HOST_CONTROLLER, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _OUTPUT_IOCTL_QUERY_HOST_CONTROLLER
{
    HOST_CONTROLLER HostController;
} OUTPUT_IOCTL_QUERY_HOST_CONTROLLER, *POUTPUT_IOCTL_QUERY_HOST_CONTROLLER;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_QUERY_MIPI_DT_TO_CAPTURE_DT
// DESCRIPTION:     Returns mapping between MIPI data type and Capture data format
// INPUT BUFFER:    MIPI_DATA_TYPE
// OUTPUT BUFFER:   SUPPORTED_CAPTURE_DATA_FORMAT
//////////////////////////////////////////////////////////////////////////
#define IOCTL_QUERY_MIPI_DT_TO_CAPTURE_DT        CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_IOCTL_QUERY_MIPI_DT_TO_CAPTURE_DT, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _INPUT_IOCTL_QUERY_MIPI_DT_TO_CAPTURE_DT
{
    MIPI_DATA_TYPE MipiDataType;                         // Data Type used for the sensor's transmission on this VC
} INPUT_IOCTL_QUERY_MIPI_DT_TO_CAPTURE_DT, *PINPUT_IOCTL_QUERY_MIPI_DT_TO_CAPTURE_DT;

typedef struct _OUTPUT_IOCTL_QUERY_MIPI_DT_TO_CAPTURE_DT
{
    SUPPORTED_CAPTURE_DATA_FORMATS CaptureDataFormats;
} OUTPUT_IOCTL_QUERY_MIPI_DT_TO_CAPTURE_DT, *POUTPUT_IOCTL_QUERY_MIPI_DT_TO_CAPTURE_DT;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_QUERY_MIPI_DT_TO_CAPTURE_DT
// DESCRIPTION:     Returns mapping between MIPI data type and Capture data format
// INPUT BUFFER:    CAPTURE_DATA_TYPE
// OUTPUT BUFFER:   SUPPORTED_MIPI_DATA_TYPE
//////////////////////////////////////////////////////////////////////////
#define IOCTL_QUERY_CAPTURE_DT_TO_MIPI_DT        CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_IOCTL_QUERY_CAPTURE_DT_TO_MIPI_DT, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _INPUT_IOCTL_QUERY_CAPTURE_DT_TO_MIPI_DT
{
    CAPTURE_DATA_TYPE CaptureDataFormat;
} INPUT_IOCTL_QUERY_CAPTURE_DT_TO_MIPI_DT, *PINPUT_IOCTL_QUERY_CAPTURE_DT_TO_MIPI_DT;

typedef struct _OUTPUT_IOCTL_QUERY_CAPTURE_DT_TO_MIPI_DT
{
    SUPPORTED_MIPI_DATA_TYPES MipiDataTypes;
} OUTPUT_IOCTL_QUERY_CAPTURE_DT_TO_MIPI_DT, *POUTPUT_IOCTL_QUERY_CAPTURE_DT_TO_MIPI_DT;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_GET_TIMESTAMP
// DESCRIPTION:     Returns global timestamp
// INPUT BUFFER:    NULL
// OUTPUT BUFFER:   Timestamp
//////////////////////////////////////////////////////////////////////////
#define IOCTL_GET_TIMESTAMP        CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_IOCTL_GET_TIMESTAMP, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _OUTPUT_IOCTL_GET_TIMESTAMP
{
    ULONGLONG Timestamp;
} OUTPUT_IOCTL_GET_TIMESTAMP, *POUTPUT_IOCTL_GET_TIMESTAMP;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_FRAME_BUNDLE_PROCESSING_COMPLETE
// DESCRIPTION:     Returns mapping between MIPI data type and Capture data format
// INPUT BUFFER:    NULL
// OUTPUT BUFFER:   Timestamp
//////////////////////////////////////////////////////////////////////////
#define IOCTL_FRAME_BUNDLE_PROCESSING_COMPLETE        CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_IOCTL_FRAME_BUNDLE_PROCESSING_COMPLETE, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _INPUT_IOCTL_FRAME_BUNDLE_PROCESSING_COMPLETE
{
    CIO2_LINK_ID         linkID;
//    IMAGE_FRAMES_BUNDLE pFramesBundle;
} INPUT_IOCTL_FRAME_BUNDLE_PROCESSING_COMPLETE, *PINPUT_IOCTL_FRAME_BUNDLE_PROCESSING_COMPLETE;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_TRIGGER_FLASH
// DESCRIPTION:     In HostControllerDriver triggers flash
// INPUT BUFFER:    ULONG
// OUTPUT BUFFER:   NULL
//////////////////////////////////////////////////////////////////////////
#define IOCTL_TRIGGER_FLASH             CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_IOCTL_TRIGGER_FLASH, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _INPUT_IOCTL_TRIGGER_FLASH
{
    CIO2_LINK_ID linkID;
    ULONG pbmFlashTmToTrg;
    ULONG pbmFlashTrgWdt;
} INPUT_IOCTL_TRIGGER_FLASH, *PINPUT_IOCTL_TRIGGER_FLASH;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_CREATE_SENSOR_DATA_LINK
// DESCRIPTION:     Creates sensor data link - configures channel with data format, e.g. resolution, bits per pixel, data type
// INPUT BUFFER:    IOCTL_CREATE_SENSOR_DATA_LINK_INPUT
// OUTPUT BUFFER:   NULL
//////////////////////////////////////////////////////////////////////////
#define IOCTL_CREATE_SENSOR_DATA_LINK   CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_IOCTL_DMA_CREATE_SENSOR_DATA_LINK, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _IOCTL_CREATE_SENSOR_DATA_LINK_INPUT
{
    SENSOR_LINK                 linkConfig;
    USHORT                      estimatedNumberOfFrames;
    FRAMES_BUNDLE_REPORT_MODE   reportMode;
    SHORT                       thresholdLineNumber;
    SHORT                       lineNumberUpdate;
    //PVOID *StreamContext
} IOCTL_CREATE_SENSOR_DATA_LINK_INPUT, *PIOCTL_CREATE_SENSOR_DATA_LINK_INPUT;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_START_STREAM
// DESCRIPTION:     In HostControllerDriver starts DMA or in IspMockDriver starts DMA & sensor
// INPUT BUFFER:    ULONG
// OUTPUT BUFFER:   NULL
//////////////////////////////////////////////////////////////////////////
#define IOCTL_START_STREAM              CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_IOCTL_DMA_START_STREAM, METHOD_BUFFERED, FILE_ANY_ACCESS)

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_STOP_STREAM
// DESCRIPTION:     In HostControllerDriver stops DMA or in IspMockDriver stops DMA & sensor
// INPUT BUFFER:    ULONG
// OUTPUT BUFFER:   NULL
//////////////////////////////////////////////////////////////////////////
#define IOCTL_STOP_STREAM               CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_IOCTL_DMA_STOP_STREAM, METHOD_BUFFERED, FILE_ANY_ACCESS)

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_SUBMIT_FRAME
// DESCRIPTION:     Submits one frame buffer
// INPUT BUFFER:    HC_SUBMIT_FRAME_BUFFER
// OUTPUT BUFFER:   NULL
//////////////////////////////////////////////////////////////////////////
#define IOCTL_SUBMIT_FRAMES_BUNDLE      CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_IOCTL_DMA_SUBMIT_FRAMES_BUNDLE, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _USER_CAPTURE_BUFFER
{
    IN      PVOID pVirtualAddr;
    IN      ULONG length;
    OUT     ULONG dataLen;      //actual data length in the buffer
    OUT     ULONG errorStatus;
} USER_CAPTURE_BUFFER, *PUSER_CAPTURE_BUFFER;

typedef struct _USER_IMAGE_FRAME_DESCRIPTOR
{
    UCHAR vcValue;
    USER_CAPTURE_BUFFER buffer[CIO2_DATA_TYPES_MAX];
} USER_IMAGE_FRAME_DESCRIPTOR, *PUSER_IMAGE_FRAME_DESCRIPTOR;

typedef struct _USER_IMAGE_FRAMES_BUNDLE
{
    IN OUT  USER_IMAGE_FRAME_DESCRIPTOR userImageFrameDescriptor[CIO2_VC_NUMBER];
    IN      BOOLEAN                     notifyOnEvent;
    OUT     ULONG                       frameNumber;
    OUT     ULONGLONG                   timeStamp;
    IN      PVOID                       Cookie;
} USER_IMAGE_FRAMES_BUNDLE, *PUSER_IMAGE_FRAMES_BUNDLE;

typedef struct _IOCTL_SUBMIT_FRAMES_BUNDLE_INPUT
{
    CIO2_LINK_ID                linkId;
    USER_IMAGE_FRAMES_BUNDLE    userFramesBundle;
} IOCTL_SUBMIT_FRAMES_BUNDLE_INPUT, *PIOCTL_SUBMIT_FRAMES_BUNDLE_INPUT;


//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_GET_FRAME
// DESCRIPTION:     Gets one frame buffer
// INPUT BUFFER:    NULL
// OUTPUT BUFFER:   HCI_COMPLETED_FRAME_BUFFER
//////////////////////////////////////////////////////////////////////////
#define IOCTL_GET_FRAME                 CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_IOCTL_DMA_GET_FRAME, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _FRAMES_BUNDLE_DEBUG_DATA
{
    // Statistics and debug data
    ULONG                       errorCode;

    ULONG                       numberofBuffersAllocated;
    ULONG                       allocIdx;
    ULONG                       readIdx;
    ULONG                       SFs;
    ULONG                       RFs;
    ULONG                       ISRs;
    ULONG                       DPC;
    ULONG                       CF;
    ULONG                       CFE;

    HCI_DMA_TRANSACTION_STATE   DmaStateRead;
    HCI_DMA_TRANSACTION_STATE   DmaStateAlloc;
    ULONG                       numberOfDTI;
    ULONG                       numberOfDTE;
    ULONG                       numberOfDTC;
    ULONG                       numberOfDTR;
    ULONG                       numberOfDTCF;
    ULONG32                     addr_l;
    ULONG32                     addr_h;
} FRAMES_BUNDLE_DEBUG_DATA, *PFRAMES_BUNDLE_DEBUG_DATA;

typedef struct _IOCTL_GET_FRAMES_BUNDLE_OUTPUT
{
    BOOLEAN                     bFramesBundleAvailable;
    CIO2_LINK_ID                linkId;
    USER_IMAGE_FRAMES_BUNDLE    userFramesBundle;
    FRAMES_BUNDLE_DEBUG_DATA    debugData;
} IOCTL_GET_FRAMES_BUNDLE_OUTPUT, *PIOCTL_GET_FRAMES_BUNDLE_OUTPUT;

//////////////////////////////////////////////////////////////////////////
// IOCTL NAME:      IOCTL_CPX_RESET_DEVICE
// DESCRIPTION:     Select stream source (DFT vs CSI2 sensor)
// INPUT BUFFER:    CPX_RESET_DEVICE_DESCRIPTOR
// OUTPUT BUFFER:   NULL
//////////////////////////////////////////////////////////////////////////
#define IOCTL_CPX_RESET_DEVICE          CTL_CODE(FILE_DEVICE_UNKNOWN, CPX_RESET_DEVICE_FUNCTION_CODE, METHOD_BUFFERED,  FILE_ANY_ACCESS)

typedef struct _CPX_RESET_DEVICE_DESCRIPTOR
{
    ULONG32 ulResetType;    // Reset type (TResetType)
    ULONG32 ulDelaySec;      // Additional delay (in seconds) between the PCI config space SAVE and RESTORE
} IOCTL_CPX_RESET_DEVICE_DESCRIPTOR, *PIOCTL_CPX_RESET_DEVICE_DESCRIPTOR;

#endif  //__PUBLIC_H
