1 /*
2  * Copyright 2017, 2020 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_camera.h"
10 #include "fsl_camera_receiver.h"
11 #include "fsl_csi.h"
12 #include "fsl_csi_camera_adapter.h"
13 
14 /*******************************************************************************
15  * Definitions
16  ******************************************************************************/
17 
18 /*******************************************************************************
19  * Prototypes
20  ******************************************************************************/
21 
22 static status_t CSI_ADAPTER_Init(camera_receiver_handle_t *handle,
23                                  const camera_config_t *config,
24                                  camera_receiver_callback_t callback,
25                                  void *userData);
26 
27 static status_t CSI_ADAPTER_Deinit(camera_receiver_handle_t *handle);
28 
29 static status_t CSI_ADAPTER_Start(camera_receiver_handle_t *handle);
30 
31 static status_t CSI_ADAPTER_Stop(camera_receiver_handle_t *handle);
32 
33 static status_t CSI_ADAPTER_SubmitEmptyBuffer(camera_receiver_handle_t *handle, uint32_t buffer);
34 
35 static status_t CSI_ADAPTER_GetFullBuffer(camera_receiver_handle_t *handle, uint32_t *buffer);
36 
37 static void CSI_ADAPTER_Callback(CSI_Type *base, csi_handle_t *handle, status_t status, void *userData);
38 
39 static status_t CSI_ADAPTER_InitExt(camera_receiver_handle_t *handle,
40                                     const camera_config_t *config,
41                                     const void *specialConfig,
42                                     camera_receiver_callback_t callback,
43                                     void *userData);
44 
45 /*******************************************************************************
46  * Variables
47  ******************************************************************************/
48 const camera_receiver_operations_t csi_ops = {.init              = CSI_ADAPTER_Init,
49                                               .deinit            = CSI_ADAPTER_Deinit,
50                                               .start             = CSI_ADAPTER_Start,
51                                               .stop              = CSI_ADAPTER_Stop,
52                                               .submitEmptyBuffer = CSI_ADAPTER_SubmitEmptyBuffer,
53                                               .getFullBuffer     = CSI_ADAPTER_GetFullBuffer,
54                                               .init_ext          = CSI_ADAPTER_InitExt};
55 
56 /*******************************************************************************
57  * Code
58  ******************************************************************************/
59 
CSI_ADAPTER_Init(camera_receiver_handle_t * handle,const camera_config_t * config,camera_receiver_callback_t callback,void * userData)60 static status_t CSI_ADAPTER_Init(camera_receiver_handle_t *handle,
61                                  const camera_config_t *config,
62                                  camera_receiver_callback_t callback,
63                                  void *userData)
64 {
65     csi_config_t csiConfig;
66 
67     csi_resource_t *resource        = (csi_resource_t *)(handle->resource);
68     csi_private_data_t *privateData = (csi_private_data_t *)(handle->privateData);
69 
70     CSI_GetDefaultConfig(&csiConfig);
71 
72     csiConfig.bytesPerPixel = config->bytesPerPixel;
73 
74     if (kCAMERA_InterfaceGatedClock == config->interface)
75     {
76         csiConfig.workMode = kCSI_GatedClockMode;
77     }
78     else if (kCAMERA_InterfaceNonGatedClock == config->interface)
79     {
80         csiConfig.workMode = kCSI_NonGatedClockMode;
81     }
82     else if (kCAMERA_InterfaceCCIR656 == config->interface)
83     {
84         csiConfig.workMode = kCSI_CCIR656ProgressiveMode;
85     }
86     else
87     {
88         return kStatus_InvalidArgument;
89     }
90 
91     csiConfig.linePitch_Bytes = config->frameBufferLinePitch_Bytes;
92     csiConfig.dataBus         = resource->dataBus;
93     csiConfig.useExtVsync     = true;
94     csiConfig.height          = FSL_VIDEO_EXTRACT_HEIGHT(config->resolution);
95     csiConfig.width           = FSL_VIDEO_EXTRACT_WIDTH(config->resolution);
96 
97     csiConfig.polarityFlags = 0U;
98     if ((uint32_t)kCAMERA_HrefActiveHigh == (config->controlFlags & (uint32_t)kCAMERA_HrefActiveHigh))
99     {
100         csiConfig.polarityFlags |= (uint32_t)kCSI_HsyncActiveHigh;
101     }
102     if ((uint32_t)kCAMERA_DataLatchOnRisingEdge == (config->controlFlags & (uint32_t)kCAMERA_DataLatchOnRisingEdge))
103     {
104         csiConfig.polarityFlags |= (uint32_t)kCSI_DataLatchOnRisingEdge;
105     }
106     if ((uint32_t)kCAMERA_VsyncActiveHigh != (config->controlFlags & (uint32_t)kCAMERA_VsyncActiveHigh))
107     {
108         csiConfig.polarityFlags |= (uint32_t)kCSI_VsyncActiveLow;
109     }
110 
111     (void)CSI_Init(resource->csiBase, &csiConfig);
112 
113     privateData->callback = callback;
114     privateData->userData = userData;
115 
116     return CSI_TransferCreateHandle(resource->csiBase, &(privateData->csiHandle), CSI_ADAPTER_Callback,
117                                     (void *)(handle));
118 }
119 
CSI_ADAPTER_Deinit(camera_receiver_handle_t * handle)120 static status_t CSI_ADAPTER_Deinit(camera_receiver_handle_t *handle)
121 {
122     CSI_Deinit(((csi_resource_t *)handle->resource)->csiBase);
123 
124     return kStatus_Success;
125 }
126 
CSI_ADAPTER_Start(camera_receiver_handle_t * handle)127 static status_t CSI_ADAPTER_Start(camera_receiver_handle_t *handle)
128 {
129     return CSI_TransferStart(((csi_resource_t *)handle->resource)->csiBase,
130                              &(((csi_private_data_t *)(handle->privateData))->csiHandle));
131 }
132 
CSI_ADAPTER_Stop(camera_receiver_handle_t * handle)133 static status_t CSI_ADAPTER_Stop(camera_receiver_handle_t *handle)
134 {
135     return CSI_TransferStop(((csi_resource_t *)handle->resource)->csiBase,
136                             &(((csi_private_data_t *)(handle->privateData))->csiHandle));
137 }
138 
CSI_ADAPTER_SubmitEmptyBuffer(camera_receiver_handle_t * handle,uint32_t buffer)139 static status_t CSI_ADAPTER_SubmitEmptyBuffer(camera_receiver_handle_t *handle, uint32_t buffer)
140 {
141     return CSI_TransferSubmitEmptyBuffer(((csi_resource_t *)handle->resource)->csiBase,
142                                          &(((csi_private_data_t *)(handle->privateData))->csiHandle), buffer);
143 }
144 
CSI_ADAPTER_GetFullBuffer(camera_receiver_handle_t * handle,uint32_t * buffer)145 static status_t CSI_ADAPTER_GetFullBuffer(camera_receiver_handle_t *handle, uint32_t *buffer)
146 {
147     return CSI_TransferGetFullBuffer(((csi_resource_t *)handle->resource)->csiBase,
148                                      &(((csi_private_data_t *)(handle->privateData))->csiHandle), buffer);
149 }
150 
CSI_ADAPTER_Callback(CSI_Type * base,csi_handle_t * handle,status_t status,void * userData)151 static void CSI_ADAPTER_Callback(CSI_Type *base, csi_handle_t *handle, status_t status, void *userData)
152 {
153     camera_receiver_handle_t *cameraReceiverHandle = (camera_receiver_handle_t *)userData;
154     csi_private_data_t *privateData                = (csi_private_data_t *)(cameraReceiverHandle->privateData);
155 
156     if (NULL != privateData->callback)
157     {
158         if (kStatus_CSI_FrameDone == status)
159         {
160             status = kStatus_Success;
161         }
162         else
163         {
164             status = kStatus_Fail;
165         }
166         privateData->callback(cameraReceiverHandle, status, privateData->userData);
167     }
168 }
169 
CSI_ADAPTER_InitExt(camera_receiver_handle_t * handle,const camera_config_t * config,const void * specialConfig,camera_receiver_callback_t callback,void * userData)170 static status_t CSI_ADAPTER_InitExt(camera_receiver_handle_t *handle,
171                                     const camera_config_t *config,
172                                     const void *specialConfig,
173                                     camera_receiver_callback_t callback,
174                                     void *userData)
175 {
176     return CSI_ADAPTER_Init(handle, config, callback, userData);
177 }
178