1 /*
2 * Copyright (c) Texas Instruments Incorporated 2018
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
33 /**
34 * \file fvid2_drvMgr.c
35 *
36 * \brief FVID2 driver manager layer.
37 * This file implements driver management functionality.
38 *
39 */
41 /* ========================================================================== */
42 /* Include Files */
43 /* ========================================================================== */
45 /* This is needed for vsnprintf */
46 #include <stdio.h>
47 #include <stdarg.h>
48 #include <ti/drv/fvid2/include/fvid2_drvMgr.h>
50 /* ========================================================================== */
51 /* Macros & Typedefs */
52 /* ========================================================================== */
54 /** \brief Number of entries in FVID2 standard info table. */
55 #define FDM_NUM_STD_INFO_ENTRIES (sizeof (gFdmStdInfoTable) / \
56 sizeof (Fvid2_ModeInfo))
58 /** \brief Number of entries in FVID2 standard info table. */
59 #define FDM_NUM_DATA_FMT_STR_ENTRIES (sizeof (gFdmDataFmtStrTable) / \
60 sizeof (Fdm_DataFmtString))
62 /** \brief Number of entries in FVID2 standard info table. */
63 #define FDM_NUM_STD_STR_ENTRIES (sizeof (gFdmStdStrTable) / \
64 sizeof (Fdm_StdString))
66 #if defined (FVID2_CFG_TRACE_ENABLE)
67 #define REMOTE_DEBUG_SERVER_PRINT_BUF_LEN (uint32_t) (1024U * 2U)
68 #endif
70 /* ========================================================================== */
71 /* Structure Declarations */
72 /* ========================================================================== */
74 /**
75 * struct Fdm_Driver
76 * \brief Structure to store driver information.
77 */
78 typedef struct
79 {
80 const Fvid2_DrvOps *drvOps;
81 /**< Driver operation table pointer. */
82 uint32_t numOpens;
83 /**< Number of times the driver is opened using create API. */
84 uint32_t isUsed;
85 /**< Flag indicating whether the object is used or not. */
86 } Fdm_Driver;
88 /**
89 * struct Fdm_Channel
90 * \brief Structure to store channel information.
91 */
92 typedef struct
93 {
94 Fdm_Driver *drv;
95 /**< Pointer to the driver object to which this channel is created. */
96 Fdrv_Handle drvHandle;
97 /**< Driver handle returned by the actual driver. */
98 Fvid2_CbParams cbParams;
99 /**< Application call back parameters. */
100 uint32_t isUsed;
101 /**< Flag indicating whether the object is used or not. */
102 } Fdm_Channel;
104 /**
105 * struct Fdm_DataFmtString
106 * \brief Structure to store data format and string pair.
107 */
108 typedef struct
109 {
110 uint32_t dataFmt;
111 /**< Data format. Refer \ref Fvid2_DataFormat*/
112 const char *dataFmtStr;
113 /**< Pointer to data format string. */
114 } Fdm_DataFmtString;
116 /**
117 * struct Fdm_StdString
118 * \brief Structure to store standard and string pair.
119 */
120 typedef struct
121 {
122 uint32_t standard;
123 /**< Standard. Refer \ref Fvid2_Standard */
124 const char *stdStr;
125 /**< Pointer to data format string. */
126 } Fdm_StdString;
128 /**
129 * struct Fdm_Object
130 * \brief Struture to store all global objects.
131 */
132 typedef struct
133 {
134 const char *versionString;
135 /**< FVID2 drivers version number as string. */
136 uint32_t versionNumber;
137 /**< FVID2 drivers version number as string. */
138 Fdm_Driver fdmDriverObjects[FVID2_CFG_FDM_NUM_DRV_OBJS];
139 /**< FDM Driver objects. */
140 Fdm_Channel fdmChannelObjects[FVID2_CFG_FDM_NUM_CH_OBJS];
141 /**< FDM Channel objects. */
142 SemaphoreP_Handle lockSem;
143 /**< Semaphore to protect function calls and other memory allocation. */
144 SemaphoreP_Handle printSem;
145 /**< Semaphore to protect print buffer. */
146 } Fdm_Object;
148 #if defined (FVID2_CFG_TRACE_ENABLE)
149 typedef struct
150 {
151 uint32_t coreId;
152 char printBuf[REMOTE_DEBUG_SERVER_PRINT_BUF_LEN];
153 } RemoteDebug_ServerObj;
154 #endif
156 /* ========================================================================== */
157 /* Function Declarations */
158 /* ========================================================================== */
159 /**
160 * Below ifdef __cplusplus is added so that C++ build passes without
161 * typecasting. This is because the prototype is build as C type
162 * whereas this file is build as CPP file. Hence we get C++ build error.
163 * Also if tyecasting is used, then we get MisraC error Rule 11.1.
164 */
165 #ifdef __cplusplus
166 extern "C" {
167 #endif
168 static int32_t fdmDriverCbFxn(void *fdmData);
169 static int32_t fdmDriverErrCbFxn(void *fdmData, void *errList);
170 static Fdm_Driver *fdmAllocDriverObject(void);
171 static int32_t fdmFreeDriverObject(const Fvid2_DrvOps *drvOps);
172 static Fdm_Channel *fdmAllocChannelObject(void);
173 static int32_t fdmFreeChannelObject(Fdm_Channel *channel);
174 #ifdef __cplusplus
175 }
176 #endif
178 /* ========================================================================== */
179 /* Global Variables */
180 /* ========================================================================== */
182 #if defined (FVID2_CFG_TRACE_ENABLE)
183 static RemoteDebug_ServerObj gRemoteDebug_serverObj = {0};
184 #endif
186 /** \brief FDM init params. */
187 static Fvid2_InitPrms gFdmInitPrms = {NULL};
189 /** \brief FDM objects. */
190 static Fdm_Object gFdmObj;
192 /** \brief FVID2 standard information table. */
193 static Fvid2_ModeInfo gFdmStdInfoTable[] =
194 {
195 /* Standard, FrameWidth, FrameHeight, ScanFormat, PixelClock (KHz), FPS */
196 {FVID2_STD_NTSC, 720U, 480U, FVID2_SF_INTERLACED, 27000U, 30U,
197 0U, 0U, 0U, 0U, 0U, 0U},
198 {FVID2_STD_PAL, 720U, 576U, FVID2_SF_INTERLACED, 27000U, 25U,
199 0U, 0U, 0U, 0U, 0U, 0U},
200 {FVID2_STD_480I, 720U, 480U, FVID2_SF_INTERLACED, 27000U, 30U,
201 0U, 0U, 0U, 0U, 0U, 0U},
202 {FVID2_STD_576I, 720U, 576U, FVID2_SF_INTERLACED, 27000U, 25U,
203 0U, 0U, 0U, 0U, 0U, 0U},
204 {FVID2_STD_480P, 720U, 480U, FVID2_SF_PROGRESSIVE,27000U, 60U,
205 0U, 0U, 0U, 0U, 0U, 0U},
206 {FVID2_STD_576P, 720U, 576U, FVID2_SF_PROGRESSIVE,27000U, 50U,
207 0U, 0U, 0U, 0U, 0U, 0U},
208 {FVID2_STD_720P_60, 1280U, 720U, FVID2_SF_PROGRESSIVE,74250U, 60U,
209 0U, 0U, 0U, 0U, 0U, 0U},
210 {FVID2_STD_720P_50, 1280U, 720U, FVID2_SF_PROGRESSIVE,74250U, 50U,
211 0U, 0U, 0U, 0U, 0U, 0U},
212 {FVID2_STD_1080I_60, 1920U, 1080U, FVID2_SF_INTERLACED, 74250U, 30U,
213 0U, 0U, 0U, 0U, 0U, 0U},
214 {FVID2_STD_1080I_50, 1920U, 1080U, FVID2_SF_INTERLACED, 74250U, 25U,
215 0U, 0U, 0U, 0U, 0U, 0U},
216 {FVID2_STD_1080P_60, 1920U, 1080U, FVID2_SF_PROGRESSIVE,148500U, 60U,
217 0U, 0U, 0U, 0U, 0U, 0U},
218 {FVID2_STD_1080P_50, 1920U, 1080U, FVID2_SF_PROGRESSIVE,148500U, 50U,
219 0U, 0U, 0U, 0U, 0U, 0U},
220 {FVID2_STD_1080P_24, 1920U, 1080U, FVID2_SF_PROGRESSIVE,74250U, 24U,
221 0U, 0U, 0U, 0U, 0U, 0U},
222 {FVID2_STD_1080P_30, 1920U, 1080U, FVID2_SF_PROGRESSIVE,74250U, 30U,
223 0U, 0U, 0U, 0U, 0U, 0U},
224 {FVID2_STD_VGA_60, 640U, 480U, FVID2_SF_PROGRESSIVE,25175U, 60U,
225 0U, 0U, 0U, 0U, 0U, 0U},
226 {FVID2_STD_VGA_72, 640U, 480U, FVID2_SF_PROGRESSIVE,31500U, 72U,
227 0U, 0U, 0U, 0U, 0U, 0U},
228 {FVID2_STD_VGA_75, 640U, 480U, FVID2_SF_PROGRESSIVE,31500U, 75U,
229 0U, 0U, 0U, 0U, 0U, 0U},
230 {FVID2_STD_VGA_85, 640U, 480U, FVID2_SF_PROGRESSIVE,36000U, 85U,
231 0U, 0U, 0U, 0U, 0U, 0U},
232 {FVID2_STD_WVGA_60, 800U, 480U, FVID2_SF_PROGRESSIVE,33500U, 60U,
233 0U, 0U, 0U, 0U, 0U, 0U},
234 {FVID2_STD_SVGA_60, 800U, 600U, FVID2_SF_PROGRESSIVE,40000U, 60U,
235 0U, 0U, 0U, 0U, 0U, 0U},
236 {FVID2_STD_SVGA_72, 800U, 600U, FVID2_SF_PROGRESSIVE,50000U, 72U,
237 0U, 0U, 0U, 0U, 0U, 0U},
238 {FVID2_STD_SVGA_75, 800U, 600U, FVID2_SF_PROGRESSIVE,49500U, 75U,
239 0U, 0U, 0U, 0U, 0U, 0U},
240 {FVID2_STD_SVGA_85, 800U, 600U, FVID2_SF_PROGRESSIVE,56250U, 85U,
241 0U, 0U, 0U, 0U, 0U, 0U},
242 {FVID2_STD_WSVGA_70, 1024U, 600U, FVID2_SF_PROGRESSIVE,50800U, 70U,
243 0U, 0U, 0U, 0U, 0U, 0U},
244 {FVID2_STD_XGA_60, 1024U, 768U, FVID2_SF_PROGRESSIVE,65000U, 60U,
245 0U, 0U, 0U, 0U, 0U, 0U},
246 {FVID2_STD_XGA_DSS_TDM_60, 1024U, 768U, FVID2_SF_PROGRESSIVE,64000U, 60U,
247 0U, 0U, 0U, 0U, 0U, 0U},
248 {FVID2_STD_XGA_70, 1024U, 768U, FVID2_SF_PROGRESSIVE,75000U, 70U,
249 0U, 0U, 0U, 0U, 0U, 0U},
250 {FVID2_STD_XGA_75, 1024U, 768U, FVID2_SF_PROGRESSIVE,78750U, 75U,
251 0U, 0U, 0U, 0U, 0U, 0U},
252 {FVID2_STD_XGA_85, 1024U, 768U, FVID2_SF_PROGRESSIVE,94500U, 85U,
253 0U, 0U, 0U, 0U, 0U, 0U},
254 {FVID2_STD_WXGA_30, 1280U, 800U, FVID2_SF_PROGRESSIVE,34125U, 30U,
255 0U, 0U, 0U, 0U, 0U, 0U},
256 {FVID2_STD_WXGA_60, 1280U, 800U, FVID2_SF_PROGRESSIVE,83500U, 60U,
257 0U, 0U, 0U, 0U, 0U, 0U},
258 {FVID2_STD_WXGA_75, 1280U, 800U, FVID2_SF_PROGRESSIVE,102250U, 75U,
259 0U, 0U, 0U, 0U, 0U, 0U},
260 {FVID2_STD_WXGA_85, 1280U, 800U, FVID2_SF_PROGRESSIVE,117500U, 85U,
261 0U, 0U, 0U, 0U, 0U, 0U},
262 {FVID2_STD_1440_900_60, 1440U, 900U, FVID2_SF_PROGRESSIVE,106500U, 60U,
263 0U, 0U, 0U, 0U, 0U, 0U},
264 {FVID2_STD_1368_768_60, 1368U, 768U, FVID2_SF_PROGRESSIVE,85860U, 60U,
265 0U, 0U, 0U, 0U, 0U, 0U},
266 {FVID2_STD_1366_768_60, 1366U, 768U, FVID2_SF_PROGRESSIVE,85500U, 60U,
267 0U, 0U, 0U, 0U, 0U, 0U},
268 {FVID2_STD_1360_768_60, 1360U, 768U, FVID2_SF_PROGRESSIVE,85500U, 60U,
269 0U, 0U, 0U, 0U, 0U, 0U},
270 {FVID2_STD_SXGA_60, 1280U, 1024U, FVID2_SF_PROGRESSIVE,108000U, 60U,
271 0U, 0U, 0U, 0U, 0U, 0U},
272 {FVID2_STD_SXGA_75, 1280U, 1024U, FVID2_SF_PROGRESSIVE,135000U, 75U,
273 0U, 0U, 0U, 0U, 0U, 0U},
274 {FVID2_STD_SXGA_85, 1280U, 1024U, FVID2_SF_PROGRESSIVE,157500U, 85U,
275 0U, 0U, 0U, 0U, 0U, 0U},
276 {FVID2_STD_WSXGAP_60, 1680U, 1050U, FVID2_SF_PROGRESSIVE,146250U, 60U,
277 0U, 0U, 0U, 0U, 0U, 0U},
278 {FVID2_STD_SXGAP_60, 1400U, 1050U, FVID2_SF_PROGRESSIVE,121750U, 60U,
279 0U, 0U, 0U, 0U, 0U, 0U},
280 {FVID2_STD_SXGAP_75, 1400U, 1050U, FVID2_SF_PROGRESSIVE,156000U, 75U,
281 0U, 0U, 0U, 0U, 0U, 0U},
282 {FVID2_STD_UXGA_60, 1600U, 1200U, FVID2_SF_PROGRESSIVE,162000U, 60U,
283 0U, 0U, 0U, 0U, 0U, 0U},
284 {FVID2_STD_WXGA_5x3_30, 1280U, 800U, FVID2_SF_PROGRESSIVE,34125U, 30U,
285 0U, 0U, 0U, 0U, 0U, 0U},
286 {FVID2_STD_WXGA_5x3_60, 1280U, 800U, FVID2_SF_PROGRESSIVE,68250U, 60U,
287 0U, 0U, 0U, 0U, 0U, 0U},
288 {FVID2_STD_WXGA_5x3_75, 1280U, 800U, FVID2_SF_PROGRESSIVE,102250U, 75U,
289 0U, 0U, 0U, 0U, 0U, 0U}
290 };
292 /** \brief Data format string table. */
293 static Fdm_DataFmtString gFdmDataFmtStrTable[] =
294 {
295 {FVID2_DF_YUV422I_UYVY, "YUV422I_UYVY" },
296 {FVID2_DF_YUV422I_YUYV, "YUV422I_YUYV" },
297 {FVID2_DF_YUV422I_YVYU, "YUV422I_YVYU" },
298 {FVID2_DF_YUV422I_VYUY, "YUV422I_VYUY" },
299 {FVID2_DF_YUV422SP_UV, "YUV422SP_UV" },
300 {FVID2_DF_YUV422SP_VU, "YUV422SP_VU" },
301 {FVID2_DF_YUV422P, "YUV422P" },
302 {FVID2_DF_YUV420SP_UV, "YUV420SP_UV" },
303 {FVID2_DF_YUV420SP_VU, "YUV420SP_VU" },
304 {FVID2_DF_YUV420P, "YUV420P" },
305 {FVID2_DF_YUV444P, "YUV444P" },
306 {FVID2_DF_YUV444I, "YUV444I" },
307 {FVID2_DF_RGB16_565, "RGB16_565" },
308 {FVID2_DF_ARGB16_1555, "ARGB16_1555" },
309 {FVID2_DF_RGBA16_5551, "RGBA16_5551" },
310 {FVID2_DF_ARGB16_4444, "ARGB16_4444" },
311 {FVID2_DF_RGBA16_4444, "RGBA16_4444" },
312 {FVID2_DF_BGRX_4444, "RGBX12_4444" },
313 {FVID2_DF_XBGR_4444, "XRGB12_4444" },
314 {FVID2_DF_ARGB24_6666, "ARGB24_6666" },
315 {FVID2_DF_RGBA24_6666, "RGBA24_6666" },
316 {FVID2_DF_RGB24_888, "RGB24_888" },
317 {FVID2_DF_XBGR24_8888, "XBGR24_8888" },
318 {FVID2_DF_RGBX24_8888, "RGBX24_8888" },
319 {FVID2_DF_BGRX24_8888, "BGRX24_8888" },
320 {FVID2_DF_ARGB32_8888, "ARGB32_8888" },
321 {FVID2_DF_RGBA32_8888, "RGBA32_8888" },
322 {FVID2_DF_BGR16_565, "BGR16_565" },
323 {FVID2_DF_ABGR16_1555, "ABGR16_1555" },
324 {FVID2_DF_ABGR16_4444, "ABGR16_4444" },
325 {FVID2_DF_BGRA16_5551, "BGRA16_5551" },
326 {FVID2_DF_BGRA16_4444, "BGRA16_4444" },
327 {FVID2_DF_AGBR16_1555, "AGBR16_1555" },
328 {FVID2_DF_AGBR16_4444, "AGBR16_4444" },
329 {FVID2_DF_XGBR16_1555, "XGBR16_1555" },
330 {FVID2_DF_BGRX16_5551, "BGRX16_5551" },
331 {FVID2_DF_ABGR24_6666, "ABGR24_6666" },
332 {FVID2_DF_BGR24_888, "BGR24_888" },
333 {FVID2_DF_ABGR32_8888, "ABGR32_8888" },
334 {FVID2_DF_BGRA24_6666, "BGRA24_6666" },
335 {FVID2_DF_BGRA32_8888, "BGRA32_8888" },
336 {FVID2_DF_BITMAP8, "BITMAP8" },
337 {FVID2_DF_BITMAP4_LOWER, "BITMAP4_LOWER" },
338 {FVID2_DF_BITMAP4_UPPER, "BITMAP4_UPPER" },
339 {FVID2_DF_BITMAP2_OFFSET0, "BITMAP2_OFFSET0" },
340 {FVID2_DF_BITMAP2_OFFSET1, "BITMAP2_OFFSET1" },
341 {FVID2_DF_BITMAP2_OFFSET2, "BITMAP2_OFFSET2" },
342 {FVID2_DF_BITMAP2_OFFSET3, "BITMAP2_OFFSET3" },
343 {FVID2_DF_BITMAP1_OFFSET0, "BITMAP1_OFFSET0" },
344 {FVID2_DF_BITMAP1_OFFSET1, "BITMAP1_OFFSET1" },
345 {FVID2_DF_BITMAP1_OFFSET2, "BITMAP1_OFFSET2" },
346 {FVID2_DF_BITMAP1_OFFSET3, "BITMAP1_OFFSET3" },
347 {FVID2_DF_BITMAP1_OFFSET4, "BITMAP1_OFFSET4" },
348 {FVID2_DF_BITMAP1_OFFSET5, "BITMAP1_OFFSET5" },
349 {FVID2_DF_BITMAP1_OFFSET6, "BITMAP1_OFFSET6" },
350 {FVID2_DF_BITMAP1_OFFSET7, "BITMAP1_OFFSET7" },
351 {FVID2_DF_BITMAP8_BGRA32, "BITMAP8_BGRA32" },
352 {FVID2_DF_BITMAP4_BGRA32_LOWER, "BITMAP4_BGRA32_LOWER" },
353 {FVID2_DF_BITMAP4_BGRA32_UPPER, "BITMAP4_BGRA32_UPPER" },
354 {FVID2_DF_BITMAP2_BGRA32_OFFSET0, "BITMAP2_BGRA32_OFFSET0"},
355 {FVID2_DF_BITMAP2_BGRA32_OFFSET1, "BITMAP2_BGRA32_OFFSET1"},
356 {FVID2_DF_BITMAP2_BGRA32_OFFSET2, "BITMAP2_BGRA32_OFFSET2"},
357 {FVID2_DF_BITMAP2_BGRA32_OFFSET3, "BITMAP2_BGRA32_OFFSET3"},
358 {FVID2_DF_BITMAP1_BGRA32_OFFSET0, "BITMAP1_BGRA32_OFFSET0"},
359 {FVID2_DF_BITMAP1_BGRA32_OFFSET1, "BITMAP1_BGRA32_OFFSET1"},
360 {FVID2_DF_BITMAP1_BGRA32_OFFSET2, "BITMAP1_BGRA32_OFFSET2"},
361 {FVID2_DF_BITMAP1_BGRA32_OFFSET3, "BITMAP1_BGRA32_OFFSET3"},
362 {FVID2_DF_BITMAP1_BGRA32_OFFSET4, "BITMAP1_BGRA32_OFFSET4"},
363 {FVID2_DF_BITMAP1_BGRA32_OFFSET5, "BITMAP1_BGRA32_OFFSET5"},
364 {FVID2_DF_BITMAP1_BGRA32_OFFSET6, "BITMAP1_BGRA32_OFFSET6"},
365 {FVID2_DF_BITMAP1_BGRA32_OFFSET7, "BITMAP1_BGRA32_OFFSET7"},
366 {FVID2_DF_BAYER_RAW, "BAYER_RAW" },
367 {FVID2_DF_BAYER_GRBG, "BAYER_GRBG" },
368 {FVID2_DF_BAYER_RGGB, "BAYER_RGGB" },
369 {FVID2_DF_BAYER_BGGR, "BAYER_BGGR" },
370 {FVID2_DF_BAYER_GBRG, "BAYER_GBRG" },
371 {FVID2_DF_RAW_VBI, "RAW_VBI" },
372 {FVID2_DF_RAW24, "RAW24" },
373 {FVID2_DF_RAW16, "RAW16" },
374 {FVID2_DF_RAW08, "RAW08" },
375 {FVID2_DF_BGRX32_8888, "BGRX32_8888" },
376 {FVID2_DF_BGRA16_1555, "BGRA16_1555" },
377 {FVID2_DF_BGRX16_1555, "BGRX16_1555" },
378 {FVID2_DF_BGRA32_1010102, "BGRA32_1010102" },
379 {FVID2_DF_BGRX32_1010102, "BGRX32_1010102" },
380 {FVID2_DF_RGBA32_1010102, "RGBA32_1010102" },
381 {FVID2_DF_RGBX32_1010102, "RGBX32_1010102" },
382 {FVID2_DF_BGRA64_16161616, "BGRA64_16161616" },
383 {FVID2_DF_BGRX64_16161616, "BGRX64_16161616" },
384 {FVID2_DF_ABGR64_16161616, "ABGR64_16161616" },
385 {FVID2_DF_XBGR64_16161616, "XBGR64_16161616" },
386 {FVID2_DF_XRGB32_8888, "XRGB32_8888" },
387 {FVID2_DF_RGBX16_4444, "RGBX16_4444" },
388 {FVID2_DF_BGR16_565_A8, "BRG16_565_A8" },
389 {FVID2_DF_RGB16_565_A8, "RGB16_565_A8" },
390 {FVID2_DF_MISC, "MISC" },
391 {FVID2_DF_INVALID, "INVALID" },
392 };
394 /** \brief Standard string table. */
395 static Fdm_StdString gFdmStdStrTable[] =
396 {
397 {FVID2_STD_NTSC, "NTSC" },
398 {FVID2_STD_PAL, "PAL" },
399 {FVID2_STD_480I, "480I" },
400 {FVID2_STD_576I, "576I" },
401 {FVID2_STD_CIF, "CIF" },
402 {FVID2_STD_HALF_D1, "HALF_D1" },
403 {FVID2_STD_D1, "D1" },
404 {FVID2_STD_480P, "480P" },
405 {FVID2_STD_576P, "576P" },
406 {FVID2_STD_720P_60, "720P60" },
407 {FVID2_STD_720P_50, "720P50" },
408 {FVID2_STD_1080I_60, "1080I60" },
409 {FVID2_STD_1080I_50, "1080I50" },
410 {FVID2_STD_1080P_60, "1080P60" },
411 {FVID2_STD_1080P_50, "1080P50" },
412 {FVID2_STD_1080P_24, "1080P24" },
413 {FVID2_STD_1080P_30, "1080P30" },
414 {FVID2_STD_VGA_60, "VGA60" },
415 {FVID2_STD_VGA_72, "VGA72" },
416 {FVID2_STD_VGA_75, "VGA75" },
417 {FVID2_STD_VGA_85, "VGA85" },
418 {FVID2_STD_WVGA_60, "WVGA60" },
419 {FVID2_STD_SVGA_60, "SVGA60" },
420 {FVID2_STD_SVGA_72, "SVGA72" },
421 {FVID2_STD_SVGA_75, "SVGA75" },
422 {FVID2_STD_SVGA_85, "SVGA85" },
423 {FVID2_STD_WSVGA_70, "WSVGA70" },
424 {FVID2_STD_XGA_60, "XGA60" },
425 {FVID2_STD_XGA_DSS_TDM_60, "XGA_DSS_TDM_60" },
426 {FVID2_STD_XGA_70, "XGA70" },
427 {FVID2_STD_XGA_75, "XGA75" },
428 {FVID2_STD_XGA_85, "XGA85" },
429 {FVID2_STD_WXGA_30, "WXGA30" },
430 {FVID2_STD_WXGA_60, "WXGA60" },
431 {FVID2_STD_WXGA_75, "WXGA75" },
432 {FVID2_STD_WXGA_85, "WXGA85" },
433 {FVID2_STD_1440_900_60, "1440X900@60" },
434 {FVID2_STD_1368_768_60, "1368X768@60" },
435 {FVID2_STD_1366_768_60, "1366X768@60" },
436 {FVID2_STD_1360_768_60, "1360X768@60" },
437 {FVID2_STD_SXGA_60, "SXGA60" },
438 {FVID2_STD_SXGA_75, "SXGA75" },
439 {FVID2_STD_SXGA_85, "SXGA85" },
440 {FVID2_STD_WSXGAP_60, "WSXGAP60" },
441 {FVID2_STD_SXGAP_60, "SXGAP60" },
442 {FVID2_STD_SXGAP_75, "SXGAP75" },
443 {FVID2_STD_UXGA_60, "UXGA60" },
444 {FVID2_STD_MUX_2CH_D1, "MUX_2CH_D1" },
445 {FVID2_STD_MUX_2CH_HALF_D1, "MUX_2CH_HALF_D1"},
446 {FVID2_STD_MUX_2CH_CIF, "MUX_2CH_CIF" },
447 {FVID2_STD_MUX_4CH_D1, "MUX_4CH_D1" },
448 {FVID2_STD_MUX_4CH_CIF, "MUX_4CH_CIF" },
449 {FVID2_STD_MUX_4CH_HALF_D1, "MUX_4CH_HALF_D1"},
450 {FVID2_STD_MUX_8CH_CIF, "MUX_8CH_CIF" },
451 {FVID2_STD_MUX_8CH_HALF_D1, "MUX_8CH_HALF_D1"},
452 {FVID2_STD_WXGA_5x3_30, "WXGA_5x3_30" },
453 {FVID2_STD_WXGA_5x3_60, "WXGA_5x3_60" },
454 {FVID2_STD_WXGA_5x3_75, "WXGA_5x3_75" },
455 {FVID2_STD_AUTO_DETECT, "AUTO_DETECT" },
456 {FVID2_STD_CUSTOM, "CUSTOM" },
457 };
459 /* ========================================================================== */
460 /* Function Definitions */
461 /* ========================================================================== */
463 /**
464 * Fvid2_init
465 * \brief FVID2 init function.
466 *
467 * Initializes the drivers and the hardware.
468 * This function should be called before calling any of driver API's.
469 *
470 * \param arg Not used currently. Meant for future purpose.
471 *
472 * \return Returns 0 on success else returns error value.
473 */
474 int32_t Fvid2_init(const Fvid2_InitPrms *initPrms)
475 {
476 uint32_t cnt;
477 int32_t retVal = FVID2_SOK;
478 uint32_t initValue;
479 SemaphoreP_Params params;
481 Fvid2InitPrms_init(&gFdmInitPrms);
482 if (NULL != initPrms)
483 {
484 Fvid2Utils_memcpy(&gFdmInitPrms, initPrms, (uint32_t)(sizeof (gFdmInitPrms)));
485 }
487 /* Init all global variables to zero */
488 Fvid2Utils_memset(&gFdmObj, 0U, sizeof (gFdmObj));
490 /* Mark pool flags as free */
491 for (cnt = 0u; cnt < FVID2_CFG_FDM_NUM_DRV_OBJS; cnt++)
492 {
493 gFdmObj.fdmDriverObjects[cnt].isUsed = (uint32_t) FALSE;
494 }
495 for (cnt = 0u; cnt < FVID2_CFG_FDM_NUM_CH_OBJS; cnt++)
496 {
497 gFdmObj.fdmChannelObjects[cnt].isUsed = (uint32_t) FALSE;
498 }
500 gFdmObj.versionString = FVID2_VERSION_STRING;
501 gFdmObj.versionNumber = FVID2_VERSION_NUMBER;
503 /* Allocate lock semaphore */
504 SemaphoreP_Params_init(¶ms);
505 params.mode = SemaphoreP_Mode_BINARY;
506 initValue = 1U;
507 gFdmObj.lockSem = SemaphoreP_create(initValue, ¶ms);
508 if (NULL == gFdmObj.lockSem)
509 {
510 GT_0trace(Fvid2Trace, GT_ERR, "FVID2 semaphore create failed!!\r\n");
511 retVal = FVID2_EALLOC;
512 }
513 SemaphoreP_Params_init(¶ms);
514 params.mode = SemaphoreP_Mode_BINARY;
515 initValue = 1U;
516 gFdmObj.printSem = SemaphoreP_create(initValue, ¶ms);
517 if (NULL == gFdmObj.printSem)
518 {
519 GT_0trace(Fvid2Trace, GT_ERR, "FVID2 semaphore create failed!!\r\n");
520 retVal = FVID2_EALLOC;
521 }
523 /* Free-up memory if error occurs */
524 if (FVID2_SOK != retVal)
525 {
526 (void) Fvid2_deInit(NULL);
527 }
529 return (retVal);
530 }
532 /**
533 * Fvid2_deInit
534 * \brief FVID2 deinit function.
535 *
536 * Uninitializes the drivers and the hardware.
537 *
538 * \param arg Not used currently. Meant for future purpose.
539 *
540 * \return Returns 0 on success else returns error value.
541 */
542 int32_t Fvid2_deInit(void *args)
543 {
544 int32_t retVal = FVID2_SOK;
546 /* Delete the lock semaphore */
547 if (NULL != gFdmObj.lockSem)
548 {
549 (void) SemaphoreP_delete(gFdmObj.lockSem);
550 gFdmObj.lockSem = NULL;
551 }
552 if (NULL != gFdmObj.printSem)
553 {
554 (void) SemaphoreP_delete(gFdmObj.printSem);
555 gFdmObj.printSem = NULL;
556 }
558 return (retVal);
559 }
561 /**
562 * Fvid2_getVersionString
563 * \brief Get the FVID2 driver version in string form. This API can be
564 * called before calling #Fvid2_init().
565 *
566 * \return Returns pointer to FVID2 version string.
567 */
568 const char *Fvid2_getVersionString(void)
569 {
570 return (FVID2_VERSION_STRING);
571 }
573 /**
574 * Fvid2_getVersionNumber
575 * \brief Get the FVID2 driver version in number form. This API can be
576 * called before calling #Fvid2_init().
577 *
578 * \return FVID2 version number.
579 */
580 uint32_t Fvid2_getVersionNumber(void)
581 {
582 return (FVID2_VERSION_NUMBER);
583 }
585 /**
586 * Fvid2_registerDriver
587 * \brief FVID2 register driver function.
588 */
589 int32_t Fvid2_registerDriver(const Fvid2_DrvOps *drvOps)
590 {
591 int32_t retVal = FVID2_SOK;
592 Fdm_Driver *drv;
593 uint32_t cnt;
595 /* Check for NULL pointers */
596 OSAL_Assert(NULL_PTR == drvOps);
598 (void) SemaphoreP_pend(gFdmObj.lockSem, SemaphoreP_WAIT_FOREVER);
600 /* Check whether the driver is already registered */
601 for (cnt = 0u; cnt < FVID2_CFG_FDM_NUM_DRV_OBJS; cnt++)
602 {
603 if (TRUE == gFdmObj.fdmDriverObjects[cnt].isUsed)
604 {
605 /* Check for NULL pointers */
606 OSAL_Assert(NULL_PTR == gFdmObj.fdmDriverObjects[cnt].drvOps);
608 if (drvOps->drvId == gFdmObj.fdmDriverObjects[cnt].drvOps->drvId)
609 {
610 GT_0trace(Fvid2Trace, GT_ERR,
611 "Driver with same id already registered!!\r\n");
612 retVal = FVID2_EDRIVER_INUSE;
613 break;
614 }
615 }
616 }
618 if (FVID2_SOK == retVal)
619 {
620 /* Get a free driver object */
621 drv = fdmAllocDriverObject();
622 if (NULL != drv)
623 {
624 drv->drvOps = drvOps;
625 drv->numOpens = 0U;
626 }
627 else
628 {
629 GT_0trace(Fvid2Trace, GT_ERR, "Alloc driver object failed!!\r\n");
630 retVal = FVID2_EALLOC;
631 }
632 }
634 (void) SemaphoreP_post(gFdmObj.lockSem);
636 return (retVal);
637 }
639 /**
640 * Fvid2_unRegisterDriver
641 * \brief FVID2 unregister driver function.
642 */
643 int32_t Fvid2_unRegisterDriver(const Fvid2_DrvOps *drvOps)
644 {
645 int32_t retVal = FVID2_EFAIL;
647 /* Check for NULL pointers */
648 OSAL_Assert(NULL_PTR == drvOps);
650 (void) SemaphoreP_pend(gFdmObj.lockSem, SemaphoreP_WAIT_FOREVER);
652 /* Free the driver object */
653 retVal = fdmFreeDriverObject(drvOps);
655 (void) SemaphoreP_post(gFdmObj.lockSem);
657 return (retVal);
658 }
660 /**
661 * Fvid2_create
662 * \brief Opens the driver identified by the driver ID.
663 */
664 Fvid2_Handle Fvid2_create(uint32_t drvId,
665 uint32_t instanceId,
666 void *createArgs,
667 void *createStatusArgs,
668 const Fvid2_CbParams *cbParams)
669 {
670 Fdm_Driver *drv = NULL;
671 uint32_t cnt;
672 Fdrv_Handle drvHandle = NULL;
673 Fdm_Channel *channel = NULL;
674 Fvid2_DrvCbParams fdmCbParams, *tempCbParams;
676 (void) SemaphoreP_pend(gFdmObj.lockSem, SemaphoreP_WAIT_FOREVER);
678 /* Get the matching driver object */
679 for (cnt = 0u; cnt < FVID2_CFG_FDM_NUM_DRV_OBJS; cnt++)
680 {
681 if (TRUE == gFdmObj.fdmDriverObjects[cnt].isUsed)
682 {
683 /* Check for NULL pointers */
684 OSAL_Assert(NULL_PTR == gFdmObj.fdmDriverObjects[cnt].drvOps);
686 if (drvId == gFdmObj.fdmDriverObjects[cnt].drvOps->drvId)
687 {
688 drv = &gFdmObj.fdmDriverObjects[cnt];
689 /* Allocate channel object */
690 channel = fdmAllocChannelObject();
691 break;
692 }
693 }
694 }
696 if (NULL != channel)
697 {
698 if (NULL != drv->drvOps->createFxn)
699 {
700 if (NULL != cbParams)
701 {
702 if (NULL != cbParams->cbFxn)
703 {
704 fdmCbParams.fdmCbFxn = &fdmDriverCbFxn;
705 }
706 else
707 {
708 fdmCbParams.fdmCbFxn = NULL;
709 }
710 if (NULL != cbParams->errCbFxn)
711 {
712 fdmCbParams.fdmErrCbFxn = &fdmDriverErrCbFxn;
713 }
714 else
715 {
716 fdmCbParams.fdmErrCbFxn = NULL;
717 }
719 fdmCbParams.handle = channel;
720 fdmCbParams.errList = cbParams->errList;
721 fdmCbParams.fdmData = channel;
722 tempCbParams = &fdmCbParams;
723 }
724 else
725 {
726 tempCbParams = NULL;
727 }
729 /* Call the driver's create function */
730 drvHandle = drv->drvOps->createFxn(
731 drvId,
732 instanceId,
733 createArgs,
734 createStatusArgs,
735 tempCbParams);
736 }
737 else
738 {
739 GT_0trace(Fvid2Trace, GT_ERR, "Driver Ops not supported!!\r\n");
740 }
742 if (NULL != drvHandle)
743 {
744 drv->numOpens++;
746 channel->drv = drv;
747 channel->drvHandle = drvHandle;
748 Fvid2CbParams_init(&channel->cbParams);
749 if (NULL != cbParams)
750 {
751 Fvid2Utils_memcpy(
752 &channel->cbParams,
753 cbParams,
754 sizeof (Fvid2_CbParams));
755 }
756 }
757 else
758 {
759 GT_0trace(Fvid2Trace, GT_ERR, "Driver create failed!!\r\n");
761 /* Free the allocated channel object */
762 (void) fdmFreeChannelObject(channel);
763 channel = NULL;
764 }
765 }
766 else
767 {
768 GT_0trace(Fvid2Trace, GT_ERR, "EALLOC: Invalid driver ID!!\r\n");
769 }
771 (void) SemaphoreP_post(gFdmObj.lockSem);
773 return (channel);
774 }
776 /**
777 * Fvid2_delete
778 * \brief Application calls Fvid2_delete to close the logical channel
779 * associated with FVID2 handle.
780 */
781 int32_t Fvid2_delete(Fvid2_Handle handle, void *deleteArgs)
782 {
783 int32_t retVal = FVID2_SOK;
784 Fdm_Channel *channel;
786 (void) SemaphoreP_pend(gFdmObj.lockSem, SemaphoreP_WAIT_FOREVER);
788 if (NULL != handle)
789 {
790 channel = (Fdm_Channel *) handle;
792 /* Check for NULL pointers */
793 OSAL_Assert(NULL_PTR == channel->drv);
794 OSAL_Assert(NULL_PTR == channel->drv->drvOps);
796 if (NULL != channel->drv->drvOps->deleteFxn)
797 {
798 /* Call the driver's delete function */
799 retVal = channel->drv->drvOps->deleteFxn(
800 channel->drvHandle,
801 deleteArgs);
802 }
803 else
804 {
805 GT_0trace(Fvid2Trace, GT_ERR, "Driver Ops not supported!!\r\n");
806 }
808 channel->drv->numOpens--;
809 /* Free the allocated channel object */
810 channel->drv = NULL;
811 channel->drvHandle = NULL;
812 channel->cbParams.cbFxn = NULL;
813 channel->cbParams.errCbFxn = NULL;
814 channel->cbParams.errList = NULL;
815 channel->cbParams.appData = NULL;
816 (void) fdmFreeChannelObject(channel);
817 }
818 else
819 {
820 GT_0trace(Fvid2Trace, GT_ERR, "EBADARGS: NULL pointer!!\r\n");
821 retVal = FVID2_EBADARGS;
822 }
824 (void) SemaphoreP_post(gFdmObj.lockSem);
826 return (retVal);
827 }
829 /**
830 * Fvid2_control
831 * \brief An application calls Fvid2_control to send device-specific control
832 * commands to the video driver.
833 */
834 int32_t Fvid2_control(Fvid2_Handle handle,
835 uint32_t cmd,
836 void *cmdArgs,
837 void *cmdStatusArgs)
838 {
839 int32_t retVal = FVID2_SOK;
840 Fdm_Channel *channel;
842 if (NULL != handle)
843 {
844 channel = (Fdm_Channel *) handle;
846 /* Check for NULL pointers */
847 OSAL_Assert(NULL_PTR == channel->drv);
848 OSAL_Assert(NULL_PTR == channel->drv->drvOps);
850 if (NULL != channel->drv->drvOps->controlFxn)
851 {
852 /* Call the driver's control function */
853 retVal = channel->drv->drvOps->controlFxn(
854 channel->drvHandle,
855 cmd,
856 cmdArgs,
857 cmdStatusArgs);
858 }
859 else
860 {
861 GT_0trace(Fvid2Trace, GT_ERR, "Driver Ops not supported!!\r\n");
862 retVal = FVID2_EUNSUPPORTED_OPS;
863 }
864 }
865 else
866 {
867 GT_0trace(Fvid2Trace, GT_ERR, "EBADARGS: NULL pointer!!\r\n");
868 retVal = FVID2_EBADARGS;
869 }
871 return (retVal);
872 }
874 /**
875 * Fvid2_queue
876 * \brief An application calls Fvid2_queue to submit a video buffer to the
877 * video device driver.
878 * This is used in capture/display drivers.
879 */
880 int32_t Fvid2_queue(Fvid2_Handle handle,
881 Fvid2_FrameList *frameList,
882 uint32_t streamId)
883 {
884 int32_t retVal = FVID2_SOK;
885 Fdm_Channel *channel;
887 if (NULL != handle)
888 {
889 channel = (Fdm_Channel *) handle;
891 /* Check for NULL pointers */
892 OSAL_Assert(NULL_PTR == channel->drv);
893 OSAL_Assert(NULL_PTR == channel->drv->drvOps);
895 if (NULL != channel->drv->drvOps->queueFxn)
896 {
897 /* Call the driver's queue function */
898 retVal = channel->drv->drvOps->queueFxn(
899 channel->drvHandle,
900 frameList,
901 streamId);
902 }
903 else
904 {
905 GT_0trace(Fvid2Trace, GT_ERR, "Driver Ops not supported!!\r\n");
906 retVal = FVID2_EUNSUPPORTED_OPS;
907 }
908 }
909 else
910 {
911 GT_0trace(Fvid2Trace, GT_ERR, "EBADARGS: NULL pointer!!\r\n");
912 retVal = FVID2_EBADARGS;
913 }
915 return (retVal);
916 }
918 /**
919 * Fvid2_dequeue
920 * \brief An application calls Fvid2_dequeue to request the video device
921 * driver to give ownership of a video buffer.
922 * This is used in capture/display drivers.
923 */
924 int32_t Fvid2_dequeue(Fvid2_Handle handle,
925 Fvid2_FrameList *frameList,
926 uint32_t streamId,
927 uint32_t timeout)
928 {
929 int32_t retVal = FVID2_SOK;
930 Fdm_Channel *channel;
932 if (NULL != handle)
933 {
934 channel = (Fdm_Channel *) handle;
936 /* Check for NULL pointers */
937 OSAL_Assert(NULL_PTR == channel->drv);
938 OSAL_Assert(NULL_PTR == channel->drv->drvOps);
940 if (NULL != channel->drv->drvOps->dequeueFxn)
941 {
942 /* Call the driver's dequeue function */
943 retVal = channel->drv->drvOps->dequeueFxn(
944 channel->drvHandle,
945 frameList,
946 streamId,
947 timeout);
948 }
949 else
950 {
951 GT_0trace(Fvid2Trace, GT_ERR, "Driver Ops not supported!!\r\n");
952 retVal = FVID2_EUNSUPPORTED_OPS;
953 }
954 }
955 else
956 {
957 GT_0trace(Fvid2Trace, GT_ERR, "EBADARGS: NULL pointer!!\r\n");
958 retVal = FVID2_EBADARGS;
959 }
961 return (retVal);
962 }
964 /**
965 * Fvid2_processRequest
966 * \brief An application calls Fvid2_processRequest to submit a video buffer
967 * to the video device driver.
968 */
969 int32_t Fvid2_processRequest(Fvid2_Handle handle,
970 Fvid2_FrameList *inFrameList,
971 Fvid2_FrameList *outFrameList,
972 uint32_t timeout)
973 {
974 int32_t retVal = FVID2_SOK;
975 Fdm_Channel *channel;
977 if (NULL != handle)
978 {
979 channel = (Fdm_Channel *) handle;
981 /* Check for NULL pointers */
982 OSAL_Assert(NULL_PTR == channel->drv);
983 OSAL_Assert(NULL_PTR == channel->drv->drvOps);
985 if (NULL != channel->drv->drvOps->processRequestFxn)
986 {
987 /* Call the driver's process frame function */
988 retVal = channel->drv->drvOps->processRequestFxn(
989 channel->drvHandle,
990 inFrameList,
991 outFrameList,
992 timeout);
993 }
994 else
995 {
996 GT_0trace(Fvid2Trace, GT_ERR, "Driver Ops not supported!!\r\n");
997 retVal = FVID2_EUNSUPPORTED_OPS;
998 }
999 }
1000 else
1001 {
1002 GT_0trace(Fvid2Trace, GT_ERR, "EBADARGS: NULL pointer!!\r\n");
1003 retVal = FVID2_EBADARGS;
1004 }
1006 return (retVal);
1007 }
1009 /**
1010 * Fvid2_getProcessedRequest
1011 * \brief An application calls Fvid2_getProcessedRequest to request the video
1012 * device driver to give ownership of a video buffer.
1013 */
1014 int32_t Fvid2_getProcessedRequest(Fvid2_Handle handle,
1015 Fvid2_FrameList *inFrameList,
1016 Fvid2_FrameList *outFrameList,
1017 uint32_t timeout)
1018 {
1019 int32_t retVal = FVID2_SOK;
1020 Fdm_Channel *channel;
1022 if (NULL != handle)
1023 {
1024 channel = (Fdm_Channel *) handle;
1026 /* Check for NULL pointers */
1027 OSAL_Assert(NULL_PTR == channel->drv);
1028 OSAL_Assert(NULL_PTR == channel->drv->drvOps);
1030 if (NULL != channel->drv->drvOps->getProcessedRequestFxn)
1031 {
1032 /* Call the driver's get process frame function */
1033 retVal = channel->drv->drvOps->getProcessedRequestFxn(
1034 channel->drvHandle,
1035 inFrameList,
1036 outFrameList,
1037 timeout);
1038 }
1039 else
1040 {
1041 GT_0trace(Fvid2Trace, GT_ERR, "Driver Ops not supported!!\r\n");
1042 retVal = FVID2_EUNSUPPORTED_OPS;
1043 }
1044 }
1045 else
1046 {
1047 GT_0trace(Fvid2Trace, GT_ERR, "EBADARGS: NULL pointer!!\r\n");
1048 retVal = FVID2_EBADARGS;
1049 }
1051 return (retVal);
1052 }
1054 /**
1055 * Fvid2_getModeInfo
1056 * \brief Function to get the information about various FVID2 modes/standards.
1057 */
1058 int32_t Fvid2_getModeInfo(Fvid2_ModeInfo *modeInfo)
1059 {
1060 int32_t retVal = FVID2_SOK;
1061 uint32_t entryCnt;
1062 Fvid2_ModeInfo *matchedEntry = NULL;
1064 if (NULL != modeInfo)
1065 {
1066 for (entryCnt = 0U; entryCnt < FDM_NUM_STD_INFO_ENTRIES; entryCnt++)
1067 {
1068 if (gFdmStdInfoTable[entryCnt].standard == modeInfo->standard)
1069 {
1070 matchedEntry = &gFdmStdInfoTable[entryCnt];
1071 break;
1072 }
1073 }
1075 if (NULL == matchedEntry)
1076 {
1077 GT_0trace(Fvid2Trace, GT_ERR, "Unsupported standard!!\r\n");
1078 retVal = FVID2_EINVALID_PARAMS;
1079 }
1080 else
1081 {
1082 Fvid2Utils_memcpy(modeInfo, matchedEntry, sizeof (Fvid2_ModeInfo));
1083 }
1084 }
1085 else
1086 {
1087 GT_0trace(Fvid2Trace, GT_ERR, "EBADARGS: NULL pointer!!\r\n");
1088 retVal = FVID2_EBADARGS;
1089 }
1091 return (retVal);
1092 }
1094 /**
1095 * \brief Function to get the name of the data format in printable string.
1096 *
1097 * \param dataFmt [IN] Data format to get the name.
1098 * For valid values see #Fvid2_DataFormat.
1099 *
1100 * \return Returns a const pointer to the string. If the data format is not
1101 * known, then it return the string as "UNKNOWN".
1102 */
1103 const char *Fvid2_getDataFmtString(uint32_t dataFmt)
1104 {
1105 uint32_t entryCnt;
1106 const char *dataFmtStr = NULL;
1108 for (entryCnt = 0U; entryCnt < FDM_NUM_DATA_FMT_STR_ENTRIES; entryCnt++)
1109 {
1110 if (gFdmDataFmtStrTable[entryCnt].dataFmt == dataFmt)
1111 {
1112 dataFmtStr = gFdmDataFmtStrTable[entryCnt].dataFmtStr;
1113 break;
1114 }
1115 }
1117 if (NULL == dataFmtStr)
1118 {
1119 dataFmtStr = "UNKNOWN";
1120 }
1122 return (dataFmtStr);
1123 }
1125 /**
1126 * \brief Function to get the name of the standard in printable string.
1127 *
1128 * \param standard [IN] Standard to get the name.
1129 * For valid values see #Fvid2_Standard.
1130 *
1131 * \return Returns a const pointer to the string. If the standard is not
1132 * known, then it return the string as "UNKNOWN".
1133 */
1134 const char *Fvid2_getStandardString(uint32_t standard)
1135 {
1136 uint32_t entryCnt;
1137 const char *stdStr = NULL;
1139 for (entryCnt = 0U; entryCnt < FDM_NUM_STD_STR_ENTRIES; entryCnt++)
1140 {
1141 if (gFdmStdStrTable[entryCnt].standard == standard)
1142 {
1143 stdStr = gFdmStdStrTable[entryCnt].stdStr;
1144 break;
1145 }
1146 }
1148 if (NULL == stdStr)
1149 {
1150 stdStr = "UNKNOWN";
1151 }
1153 return (stdStr);
1154 }
1156 /**
1157 * Fvid2_checkFrameList
1158 * \brief Checks the FVID2 frame list for error and returns appropriate error.
1159 * This is used by the drivers and not by the application.
1160 */
1161 int32_t Fvid2_checkFrameList(const Fvid2_FrameList *frameList,
1162 uint32_t maxFrames)
1163 {
1164 int32_t retVal = FVID2_SOK;
1165 uint32_t frmCnt;
1167 /* Check for NULL pointer */
1168 if (NULL == frameList)
1169 {
1170 GT_0trace(Fvid2Trace, GT_ERR, "EBADARGS: NULL pointer!!\r\n");
1171 retVal = FVID2_EBADARGS;
1172 }
1173 else
1174 {
1175 /* Check whether num frames is within range */
1176 if (frameList->numFrames > maxFrames)
1177 {
1178 GT_0trace(Fvid2Trace, GT_ERR, "Number of frames exceeds max!!\r\n");
1179 retVal = FVID2_EOUT_OF_RANGE;
1180 }
1182 /* Check whether num frames is within range */
1183 if (frameList->numFrames > FVID2_MAX_FRAME_PTR)
1184 {
1185 GT_0trace(Fvid2Trace, GT_ERR,
1186 "Number of frames exceeds FVID2 max!!\r\n");
1187 retVal = FVID2_EOUT_OF_RANGE;
1188 }
1190 /* Check whether num frames is zero */
1191 if (0U == frameList->numFrames)
1192 {
1193 GT_0trace(Fvid2Trace, GT_ERR, "Number of frames is zero!!\r\n");
1194 retVal = FVID2_EOUT_OF_RANGE;
1195 }
1197 if (FVID2_SOK == retVal)
1198 {
1199 /* Check the individual frame pointers */
1200 for (frmCnt = 0U; frmCnt < frameList->numFrames; frmCnt++)
1201 {
1202 /* Check for NULL pointer */
1203 if (NULL == frameList->frames[frmCnt])
1204 {
1205 GT_0trace(Fvid2Trace, GT_ERR,
1206 "EBADARGS: NULL pointer!!\r\n");
1207 retVal = FVID2_EBADARGS;
1208 break;
1209 }
1210 }
1211 }
1212 }
1214 return (retVal);
1215 }
1217 /**
1218 * Fvid2_checkDqFrameList
1219 * \brief Checks the FVID2 frame list of dequeue call for error and returns
1220 * appropriate error. For dequeue operation, the frame pointers in the frames
1221 * should not be checked as this will be filled by the driver.
1222 * This is used by the drivers and not by the application.
1223 */
1224 int32_t Fvid2_checkDqFrameList(const Fvid2_FrameList *frameList,
1225 uint32_t maxFrames)
1226 {
1227 int32_t retVal = FVID2_SOK;
1229 /* Check for NULL pointer */
1230 if (NULL == frameList)
1231 {
1232 GT_0trace(Fvid2Trace, GT_ERR, "EBADARGS: NULL pointer!!\r\n");
1233 retVal = FVID2_EBADARGS;
1234 }
1235 else
1236 {
1237 /* Check whether max frames is within range */
1238 if (maxFrames > FVID2_MAX_FRAME_PTR)
1239 {
1240 GT_0trace(Fvid2Trace, GT_ERR,
1241 "Number of frames exceeds FVID2 max!!\r\n");
1242 retVal = FVID2_EOUT_OF_RANGE;
1243 }
1244 }
1246 return (retVal);
1247 }
1249 /**
1250 * Fvid2_copyFrameList
1251 * \brief Copies the source frame list to the destination frame list.
1252 * This also resets the frame pointers from the source frame list.
1253 * This is used by the drivers and not by the application.
1254 */
1255 void Fvid2_copyFrameList(Fvid2_FrameList *dest, Fvid2_FrameList *src)
1256 {
1257 uint32_t frmCnt;
1259 /* Check for NULL pointers */
1260 OSAL_Assert(NULL_PTR == dest);
1261 OSAL_Assert(NULL_PTR == src);
1262 OSAL_Assert(src->numFrames >= FVID2_MAX_FRAME_PTR);
1264 dest->numFrames = src->numFrames;
1265 dest->drvData = src->drvData;
1267 /* Copy the individual frames */
1268 for (frmCnt = 0U; frmCnt < src->numFrames; frmCnt++)
1269 {
1270 dest->frames[frmCnt] = src->frames[frmCnt];
1271 src->frames[frmCnt] = NULL;
1272 }
1274 return;
1275 }
1277 /**
1278 * Fvid2_duplicateFrameList
1279 * \brief Duplicate the source frame list to the destination frame list.
1280 * This does not reset the frame pointers from the source frame list.
1281 * This is used by the drivers and not by the application.
1282 */
1283 void Fvid2_duplicateFrameList(Fvid2_FrameList *dest, const Fvid2_FrameList *src)
1284 {
1285 uint32_t frmCnt;
1287 /* Check for NULL pointers */
1288 OSAL_Assert(NULL_PTR == dest);
1289 OSAL_Assert(NULL_PTR == src);
1290 OSAL_Assert(src->numFrames >= FVID2_MAX_FRAME_PTR);
1292 dest->numFrames = src->numFrames;
1293 dest->drvData = src->drvData;
1295 /* Duplicate the individual frames */
1296 for (frmCnt = 0U; frmCnt < src->numFrames; frmCnt++)
1297 {
1298 dest->frames[frmCnt] = src->frames[frmCnt];
1299 }
1301 return;
1302 }
1304 /**
1305 * fdmDriverCbFxn
1306 * \brief FVID2 driver manager driver callback function. Whenever the drivers
1307 * wants to call the application callback function, this function will be
1308 * called by the driver and FDM will in turn call the application callback
1309 * function.
1310 * This is used by the drivers and not by the application.
1311 */
1312 static int32_t fdmDriverCbFxn(void *fdmData)
1313 {
1314 int32_t retVal;
1315 Fdm_Channel *channel;
1317 /* Check for NULL pointers */
1318 OSAL_Assert(NULL_PTR == fdmData);
1320 channel = (Fdm_Channel *) fdmData;
1321 OSAL_Assert((Fvid2_CbFxn) NULL_PTR == channel->cbParams.cbFxn);
1322 retVal = channel->cbParams.cbFxn(channel, channel->cbParams.appData);
1324 return (retVal);
1325 }
1327 /**
1328 * fdmDriverErrCbFxn
1329 * \brief FVID2 driver manager driver error callback function.
1330 * Whenever the drivers wants to call the application error callback function,
1331 * this function will be called by the driver and FDM will in turn call the
1332 * application error callback function.
1333 * This is used by the drivers and not by the application.
1334 */
1335 static int32_t fdmDriverErrCbFxn(void *fdmData, void *errList)
1336 {
1337 int32_t retVal;
1338 Fdm_Channel *channel;
1340 /* Check for NULL pointers */
1341 OSAL_Assert(NULL_PTR == fdmData);
1343 channel = (Fdm_Channel *) fdmData;
1344 OSAL_Assert((Fvid2_ErrCbFxn) NULL_PTR == channel->cbParams.errCbFxn);
1345 retVal =
1346 channel->cbParams.errCbFxn(channel, channel->cbParams.appData, errList);
1348 return (retVal);
1349 }
1351 /**
1352 * fdmAllocDriverObject
1353 * \brief Allocate memory for driver object from static memory pool.
1354 * Returns NULL if memory pool is full.
1355 */
1356 static Fdm_Driver *fdmAllocDriverObject(void)
1357 {
1358 uint32_t cnt;
1359 Fdm_Driver *drv = NULL;
1361 /* Get a free driver object */
1362 for (cnt = 0u; cnt < FVID2_CFG_FDM_NUM_DRV_OBJS; cnt++)
1363 {
1364 if (FALSE == gFdmObj.fdmDriverObjects[cnt].isUsed)
1365 {
1366 drv = &gFdmObj.fdmDriverObjects[cnt];
1367 drv->isUsed = (uint32_t) TRUE;
1368 break;
1369 }
1370 }
1372 return (drv);
1373 }
1375 /**
1376 * fdmFreeDriverObject
1377 * \brief Free-up the memory allocated for driver object.
1378 */
1379 static int32_t fdmFreeDriverObject(const Fvid2_DrvOps *drvOps)
1380 {
1381 uint32_t cnt;
1382 int32_t retVal = FVID2_EFAIL;
1384 /* Check for NULL pointers */
1385 OSAL_Assert(NULL_PTR == drvOps);
1387 /* Free the driver object */
1388 for (cnt = 0u; cnt < FVID2_CFG_FDM_NUM_DRV_OBJS; cnt++)
1389 {
1390 if ((TRUE == gFdmObj.fdmDriverObjects[cnt].isUsed) &&
1391 (drvOps == gFdmObj.fdmDriverObjects[cnt].drvOps))
1392 {
1393 if (0u == gFdmObj.fdmDriverObjects[cnt].numOpens)
1394 {
1395 gFdmObj.fdmDriverObjects[cnt].isUsed = (uint32_t) FALSE;
1396 gFdmObj.fdmDriverObjects[cnt].drvOps = NULL;
1397 gFdmObj.fdmDriverObjects[cnt].numOpens = 0u;
1398 retVal = FVID2_SOK;
1399 }
1400 else
1401 {
1402 GT_0trace(Fvid2Trace, GT_ERR, "Driver in use!!\r\n");
1403 retVal = FVID2_EDEVICE_INUSE;
1404 }
1405 break;
1406 }
1407 }
1409 if (FVID2_EFAIL == retVal)
1410 {
1411 GT_0trace(Fvid2Trace, GT_ERR, "Driver ops not found!!\r\n");
1412 }
1414 return (retVal);
1415 }
1417 /**
1418 * fdmAllocChannelObject
1419 * \brief Allocate memory for channel object from static memory pool.
1420 * Returns NULL if memory pool is full.
1421 */
1422 static Fdm_Channel *fdmAllocChannelObject(void)
1423 {
1424 uint32_t cnt;
1425 Fdm_Channel *channel = NULL;
1427 /* Get a free channel object */
1428 for (cnt = 0u; cnt < FVID2_CFG_FDM_NUM_CH_OBJS; cnt++)
1429 {
1430 if (FALSE == gFdmObj.fdmChannelObjects[cnt].isUsed)
1431 {
1432 channel = &gFdmObj.fdmChannelObjects[cnt];
1433 channel->isUsed = (uint32_t) TRUE;
1434 break;
1435 }
1436 }
1438 return (channel);
1439 }
1441 /**
1442 * fdmFreeChannelObject
1443 * \brief Free-up the memory allocated for channel object.
1444 */
1445 static int32_t fdmFreeChannelObject(Fdm_Channel *channel)
1446 {
1447 int32_t retVal = FVID2_EALLOC;
1449 /* Check for NULL pointers */
1450 OSAL_Assert(NULL_PTR == channel);
1452 /* Free the channel object */
1453 if (TRUE == channel->isUsed)
1454 {
1455 channel->isUsed = (uint32_t) FALSE;
1456 retVal = FVID2_SOK;
1457 }
1458 else
1459 {
1460 GT_0trace(Fvid2Trace, GT_ERR,
1461 "Freeing a channel object not in use!!\r\n");
1462 }
1464 return (retVal);
1465 }
1467 void Fvid2_printf(const char *format, ...)
1468 {
1469 #if defined (FVID2_CFG_TRACE_ENABLE)
1470 va_list vaArgPtr;
1471 char *buf = NULL;
1473 (void) SemaphoreP_pend(gFdmObj.printSem, SemaphoreP_WAIT_FOREVER);
1475 buf = &gRemoteDebug_serverObj.printBuf[0];
1476 (void) va_start(vaArgPtr, format);
1477 (void) vsnprintf(buf, REMOTE_DEBUG_SERVER_PRINT_BUF_LEN,
1478 (const char *) format, vaArgPtr);
1479 va_end(vaArgPtr);
1481 if(gFdmInitPrms.printFxn != NULL)
1482 {
1483 gFdmInitPrms.printFxn(buf);
1484 }
1486 (void) SemaphoreP_post(gFdmObj.printSem);
1487 #endif
1488 return;
1489 }