/*
 * Project Name Camera DRIVER IN WINCE
 * Copyright  2007 Samsung Electronics Co, Ltd. All Rights Reserved. 
 *
 * This software is the confidential and proprietary information
 * of Samsung Electronics  ("Confidential Information").   
 * you shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with Samsung Electronics 
 *
 */

#ifndef __CUSTOMCAMERA_H__
#define __CUSTOMCAMERA_H__

// Default Constants
#define DEFAULT_CE_THREAD_PRIORITY 103
#define PC_REG_DEVINDEX_VAL_NAME TEXT("DeviceArrayIndex") 
#define PC_REG_DEVINDEX_VAL_LEN  sizeof(DWORD)
#define PC_REG_PRIORITY_VAL_NAME TEXT("Priority256")
#define PC_REG_PRIORITY_VAL_LEN sizeof(DWORD)
#define PC_REG_MEMBASE_VAL_NAME TEXT("MemBase")
#define PC_REG_MEMBASE_VAL_LEN  sizeof(DWORD)
#define PC_REG_MEMLEN_VAL_NAME  TEXT("MemLen")
#define PC_REG_MEMLEN_VAL_LEN   sizeof(DWORD)
#define PC_REG_PHYIRQ_VAL_NAME  TEXT("Irq")
#define PC_REG_PHYIRQ_VAL_LEN   sizeof(DWORD)

#define DISABLE  0
#define ENABLE   1

enum CAMERA_STATUS {
    STATUS_NOTSET   = -1,
    STATUS_READY    = 0,
    STATUS_RUNNING  = 1
};

typedef struct _CAMERA_STATE {
    CAMERA_STATUS   status;    
    IMG_TYPE_ITEM   imgtype;
    UINT32          imageSize;
    ADDRESS_MODE    addrmode;
    UINT32          pingpongCount;
    CAMERA_DMA_BUFFER_INFO  CAM_BUFFER_INFO[MAX_PINGPONG_NUM];
    BOOL            bWakeUp;
} CAMERA_STATE;

// Forward declare for use below
typedef struct __HW_OPEN_INFO HW_OPEN_INFO, *PHW_OPEN_INFO;

typedef struct _CONTEXT_CAMERA{
    UINT32  uCamID;
    DWORD   dwIntID;   // Interrupt Identifier, SysIntr    
    PHYSICAL_ADDRESS PhysPreviewAddr;
    PHYSICAL_ADDRESS PhysCodecAddr;
    PBYTE pPreviewVirtAddr;
    PBYTE pCodecVirtAddr;

    CAMERA_STATE PreviewState;
    CAMERA_STATE StillState;
    CAMERA_STATE VideoState;
    CameraHal   *pCameraIF;

    // Open context fo resource occupant
    PHW_OPEN_INFO pOccupantCam;
} CTX_CAMERA, *PCTX_CAMERA;

// @struct    HW_INDEP_INFO | Hardware Independent Serial Driver Head Information.
typedef struct __HW_INDEP_INFO {
    UINT32          uCamID;
    PCTX_CAMERA     pCtxCamera;     // @field Represents PDD object.
    PVOID           pHWHead;        // @field Device context for PDD.
    
    HANDLE          hKillDispatchThread;    // @field Synchonize thread end
    HANDLE          pDispatchThread;// @field ReceiveThread 
    ULONG           Priority256;    // @field CeThreadPriority of Dispatch Thread.    

    DWORD            OpenCnt;       // @field Protects use of this port 
    LIST_ENTRY       OpenList;      // @field Head of linked list of OPEN_INFOs    
    CRITICAL_SECTION OpenCS;        // @field Protects Open Linked List

    PHW_OPEN_INFO   pAccessOwner;   // @field Points to whichever open has acess permissions
} HW_INDEP_INFO, *PHW_INDEP_INFO;

// @struct    HW_OPEN_INFO | Info pertaining to each open instance of a device
typedef struct __HW_OPEN_INFO {
    PHW_INDEP_INFO  pCamHead;    // @field Pointer back to our HW_INDEP_INFO
    DWORD           AccessCode;     // @field What permissions was this opened with
    DWORD           ShareMode;      // @field What Share Mode was this opened with
    DWORD           StructUsers;    // @field Count of threads currently using struct.
    LIST_ENTRY      llist;          // @field Linked list of OPEN_INFOs
    PostProcContext PostCtxt;
    } HW_OPEN_INFO, *PHW_OPEN_INFO;



////// extern functions : Camera API //////
extern PCTX_CAMERA CusCam_Initialize(UINT32 uCamID, DWORD dwMemBase, DWORD dwPhyIrq);
extern void     CusCam_Deinitialize(UINT32 uCamID);
extern BOOL     CusCam_CameraInitialize(UINT32 uCamID);
extern void     CusCam_CameraDeinitialize(UINT32 uCamID);

////// static functions : Camera API
static void     CusCam_Reset(UINT32 uCamID);

static CAMERA_POST_ERROR CusCam_CalculateBufferOffset(IMG_TYPE_ITEM *img_type, int *yoffset, int *coffset);
static CAMERA_POST_ERROR CusCam_MakeUpBufferChain(CAMERA_STATE *CameraState, DWORD PhyAddr, DWORD VirAddr, int FrameSize);
    
static CAMERA_POST_ERROR CusCam_SetPreviewSize(CAM_IMGTYPE_ARGS *args, UINT32 uCamID);
static CAMERA_POST_ERROR CusCam_SetStillSize(CAM_IMGTYPE_ARGS *args, UINT32 uCamID);
static CAMERA_POST_ERROR CusCam_SetVideoSize(CAM_IMGTYPE_ARGS *args, UINT32 uCamID);
static CAMERA_POST_ERROR CusCam_StartPreview(CAM_START_ARGS *args, UINT32 uCamID);
static DWORD    CusCam_GetPreviewFrame(PVOID pBufIn, UINT32 uCamID);
static void     CusCam_StopPreview(UINT32 uCamID);
static DWORD CusCam_JPEGStillCut(CAM_STILLCUT_ARGS *args, UINT32 uCamID);
static CAMERA_POST_ERROR CusCam_StillCut(CAM_STILLCUT_ARGS *args, UINT32 uCamID);
static void     CusCam_DeinitializeBuffer(UINT32 uCamID);
static CAMERA_POST_ERROR CusCam_InitializeBuffer(UINT32 uCamID);
static int CusCam_CameraSetFormat(UINT32 width, UINT32 height, int format, int BufferType);

static int CusCam_CameraReleaseBuffer(int BufferType, UINT32 uCamID);
static int CusCam_CameraPrepareBuffer(P_CAMERA_DMA_BUFFER_INFO pBufInfo, int BufferType);
static DWORD CusCam_SetCallback(CAM_CALLBACK_ARGS *pArgs);
static DWORD CusCam_GetCurrentFrameNum(UINT32 uCamID);
static DWORD CusCam_SetOperationMode(CAMIF_OPERATION_MODE mode, UINT32 uCamID);
//////////////////////
////// Post API //////
extern void     CAM_initialize_context(UINT32 uCamID, CameraHal *pCameraHal);
extern void     CAM_deinitialize_context(UINT32 uCamID);

// Power Control
extern void CAM_initialize_post_power_context(DWORD uCamID);
extern void CAM_deinitialize_post_power_context(DWORD uCamID);
extern void CAM_post_power_on(DWORD uCamID);
extern void CAM_post_power_off(DWORD uCamID);
extern void CAM_power_init_APM();
extern void CAM_power_deinit_APM();
extern void CAM_power_set_APM(int m_uCamID,CEDEVICE_POWER_STATE APM_POWER_STATUS);
extern BOOL CusCam_PowerUp(UINT32 uCamID);
extern BOOL CusCam_PowerDown(UINT32 uCamID);




extern BOOL CAM_Resource_API_Proc(
    PHW_OPEN_INFO pOpenHead,
    DWORD dwCode,
    PBYTE pBufIn,
    DWORD dwLenIn,
    PBYTE pBufOut,
    DWORD dwLenOut,
    PDWORD pdwActualOut
    );

extern BOOL CAM_Camera_API_Proc(
    PHW_OPEN_INFO pOpenHead,
    DWORD dwCode,
    PBYTE pBufIn,
    DWORD dwLenIn,
    PBYTE pBufOut,
    DWORD dwLenOut,
    PDWORD pdwActualOut
    );

extern BOOL CAM_Post_API_Proc(
    PHW_OPEN_INFO pOpenHead,
    DWORD dwCode,
    PBYTE pBufIn,
    DWORD dwLenIn,
    PBYTE pBufOut,
    DWORD dwLenOut,
    PDWORD pdwActualOut
    );

#endif /*__CUSTOMCAMERA_H__*/
