1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "mipi_csi_test.h"
10 #include "hdf_log.h"
11 #include "osal_time.h"
12 #include "securec.h"
13
14 #define HDF_LOG_TAG mipi_csi_test
15 #define SEQ_OUTPUT_DELAY 100 /* Delay time of sequential output, unit: ms */
16
17 // Input interface type of RX.
18 enum InterfaceType {
19 INTERFACE_MIPI = 0,
20 INTERFACE_LVDS,
21 INTERFACE_CMOS,
22 INTERFACE_BUTT
23 };
24
MipiCsiTestSetUp(struct MipiCsiTest * test)25 static int32_t MipiCsiTestSetUp(struct MipiCsiTest *test)
26 {
27 HDF_LOGI("%s: enter!", __func__);
28
29 if (test == NULL) {
30 HDF_LOGE("%s: test is NULL.", __func__);
31 return HDF_ERR_INVALID_OBJECT;
32 }
33
34 if (test->handle == NULL) {
35 HDF_LOGE("%s: enter! cntlrId:0x%x", __func__, test->cntlrId);
36 test->cntlrId = 0;
37 test->handle = MipiCsiOpen(test->cntlrId);
38 if (test->handle == NULL) {
39 HDF_LOGE("%s: failed.", __func__);
40 return HDF_FAILURE;
41 }
42 }
43
44 test->fails = 0;
45 HDF_LOGD("%s: cntlrId:0x%x", __func__, test->cntlrId);
46 return HDF_SUCCESS;
47 }
48
MipiCsiTestTearDown(struct MipiCsiTest * test)49 static void MipiCsiTestTearDown(struct MipiCsiTest *test)
50 {
51 if (test == NULL) {
52 return;
53 }
54 if (test->handle != NULL) {
55 MipiCsiClose(test->handle);
56 test->handle = NULL;
57 }
58 }
59
60 /**
61 * @brief Initialize the device parameters applying LVDS protocol.
62 *
63 * This is not fully tested!
64 *
65 * @since 1.0
66 */
InitLvdsDevAttr(LvdsDevAttr * lvdsAttr)67 static void InitLvdsDevAttr(LvdsDevAttr *lvdsAttr)
68 {
69 int i;
70 int j;
71 int k;
72 LvdsDevAttr attr;
73
74 if (lvdsAttr == NULL) {
75 return;
76 }
77
78 (void)memset_s(&attr, sizeof(LvdsDevAttr), 0, sizeof(LvdsDevAttr));
79 // Hi3516CV500 (DATA_TYPE_RAW_12BIT), Hi3516EV200 (DATA_TYPE_RAW_12BIT)
80 attr.inputDataType = DATA_TYPE_RAW_12BIT;
81 attr.wdrMode = HI_WDR_MODE_NONE;
82 // LVDS synchronization mode. LVDS_SYNC_MODE_SOF, LVDS_SYNC_MODE_SAV
83 attr.syncMode = LVDS_SYNC_MODE_SOF;
84 // LVDS Vsync type. LVDS_VSYNC_NORMAL, LVDS_VSYNC_SHARE, LVDS_VSYNC_HCONNECT
85 attr.vsyncAttr.syncType = LVDS_VSYNC_NORMAL;
86 // hconnect vsync blanking len, valid when the syncType is LVDS_VSYNC_HCONNECT
87 // This is not fully tested!
88 if (attr.vsyncAttr.syncType == LVDS_VSYNC_HCONNECT) {
89 attr.vsyncAttr.hblank1 = 0;
90 attr.vsyncAttr.hblank2 = 0;
91 }
92 // frame identification code: LVDS_FID_NONE, LVDS_FID_IN_SAV, LVDS_FID_IN_DATA
93 attr.fidAttr.fidType = LVDS_FID_NONE;
94 // Sony DOL has the Frame Information Line, in DOL H-Connection mode, should
95 // configure this flag as false to disable output the Frame Information Line.
96 // This is not fully tested!
97 attr.fidAttr.outputFil = 'm';
98 // LVDS bit size end mode: LVDS_ENDIAN_LITTLE, LVDS_ENDIAN_BIG
99 attr.dataEndian = LVDS_ENDIAN_LITTLE;
100 // sync code endian: little/big, LVDS_ENDIAN_LITTLE, LVDS_ENDIAN_BIG
101 attr.syncCodeEndian = LVDS_ENDIAN_LITTLE;
102 // laneId: -1 - disable
103 attr.laneId[0] = 0; /* 0 -- laneId 0 */
104 attr.laneId[1] = 1; /* 1 -- laneId 1 */
105 attr.laneId[2] = 2; /* 2 -- laneId 2 */
106 attr.laneId[3] = 3; /* 3 -- laneId 3 */
107
108 /** each vc has 4 params, syncCode[i]:
109 syncMode is SYNC_MODE_SOF: SOF, EOF, SOL, EOL
110 syncMode is SYNC_MODE_SAV: invalid sav, invalid eav, valid sav, valid eav */
111 // This is not fully tested!
112 for (i = 0; i < LVDS_LANE_NUM; i++) {
113 for (j = 0; j < WDR_VC_NUM; j++) {
114 for (k = 0; k < SYNC_CODE_NUM; k++) {
115 attr.syncCode[i][j][k] = 0; /* 0 -- frame0 sof */
116 }
117 }
118 }
119
120 *lvdsAttr = attr;
121 }
122
123 /**
124 * @brief Initialize MIPI device attributes.
125 *
126 * Data type (DT: data type)
127 * The data type describes the format and content of load data. Up to 64 data types are supported.
128 * There are only two data types for short packets, and the others belong to long packets.
129 *
130 * @Data type describe
131 * 0x00 – 0x07 Synchronous short packet data type
132 * 0x08 – 0x0F General short packet data type
133 * 0x10 – 0x17 General long packet data type
134 * 0x18 – 0x1F YUV data
135 * 0x20 – 0x27 RGB data
136 * 0x28 – 0x2F Raw data
137 * 0x30 – 0x37 User defined byte based data type
138 * 0x38 – 0x3F Reserved
139 *
140 * @since 1.0
141 */
InitMipiDevAttr(MipiDevAttr * mipiAttr)142 static void InitMipiDevAttr(MipiDevAttr *mipiAttr)
143 {
144 MipiDevAttr attr;
145 if (mipiAttr == NULL) {
146 return;
147 }
148
149 HDF_LOGI("%s: enter.", __func__);
150 (void)memset_s(&attr, sizeof(MipiDevAttr), 0, sizeof(MipiDevAttr));
151 // Hi3516CV500 (DATA_TYPE_RAW_12BIT), Hi3516EV200 (DATA_TYPE_RAW_12BIT)
152 attr.inputDataType = DATA_TYPE_RAW_12BIT;
153 // Hi3516CV500 (HI_MIPI_WDR_MODE_NONE), Hi3516EV200 (HI_MIPI_WDR_MODE_NONE)
154 attr.wdrMode = HI_MIPI_WDR_MODE_NONE;
155 // laneId: -1 - disable
156 // Hi3516CV500 (0, 1, 2, 3), Hi3516EV200 (0, 1, -1, -1)
157 attr.laneId[0] = 0; /* 0 -- laneId 0 */
158 attr.laneId[1] = 1; /* 1 -- laneId 1 */
159 attr.laneId[2] = 2; /* 2 -- laneId 2 */
160 attr.laneId[3] = 3; /* 3 -- laneId 3 */
161
162 // Used by the HI_MIPI_WDR_MODE_DT, This is not fully tested!
163 if (attr.wdrMode == HI_MIPI_WDR_MODE_DT) {
164 attr.dataType[0] = 0x39; /* 0x39 -- data type reserved */
165 attr.dataType[1] = 0x39; /* 0x39 -- data type reserved */
166 attr.dataType[2] = 0x39; /* 0x39 -- data type reserved */
167 attr.dataType[3] = 0x39; /* 0x39 -- data type reserved */
168 }
169
170 *mipiAttr = attr;
171 }
172
MipiGetIntputModeType(InputMode inputMode)173 static int MipiGetIntputModeType(InputMode inputMode)
174 {
175 switch (inputMode) {
176 case INPUT_MODE_SUBLVDS:
177 case INPUT_MODE_LVDS:
178 case INPUT_MODE_HISPI:
179 return INTERFACE_LVDS;
180 case INPUT_MODE_MIPI:
181 return INTERFACE_MIPI;
182 case INPUT_MODE_CMOS:
183 case INPUT_MODE_BT1120:
184 case INPUT_MODE_BT656:
185 case INPUT_MODE_BYPASS:
186 return INTERFACE_CMOS;
187 default:
188 break;
189 }
190
191 return INTERFACE_BUTT;
192 }
193
InitComboDevAttr(struct MipiCsiTest * test)194 static void InitComboDevAttr(struct MipiCsiTest *test)
195 {
196 enum InterfaceType interType;
197 ComboDevAttr attr;
198
199 (void)memset_s(&attr, sizeof(ComboDevAttr), 0, sizeof(ComboDevAttr));
200 // Hi3516CV500(0), Hi3516EV200(0)
201 attr.devno = 0;
202 // Hi3516CV500(INPUT_MODE_MIPI), Hi3516EV200(INPUT_MODE_MIPI)
203 attr.inputMode = INPUT_MODE_MIPI;
204 // Hi3516CV500(MIPI_DATA_RATE_X1), Hi3516EV200(MIPI_DATA_RATE_X1)
205 attr.dataRate = MIPI_DATA_RATE_X1;
206 // Hi3516CV500 (0, 204, 2592, 1944), Hi3516EV200 (0, 204, 2304, 1296), Hi3516DV300-imx335 (0, 0, 2592, 1944)
207 attr.imgRect.x = 0; /* 0: image sensor left-top positon */
208 attr.imgRect.y = 0; /* 0: image sensor right-top position */
209 attr.imgRect.width = 2592; /* 2592: image sensor width size */
210 attr.imgRect.height = 1944; /* 1944: image sensor height size */
211
212 interType = MipiGetIntputModeType(attr.inputMode);
213 if (interType == INTERFACE_MIPI) {
214 HDF_LOGI("%s: call[InitMipiDevAttr].", __func__);
215 InitMipiDevAttr(&attr.mipiAttr);
216 } else if (interType == INTERFACE_LVDS) {
217 HDF_LOGI("%s: call[InitLvdsDevAttr].", __func__);
218 InitLvdsDevAttr(&attr.lvdsAttr);
219 } else {
220 HDF_LOGE("%s: interType = %d is error!", __func__, attr.inputMode);
221 }
222
223 test->attr = attr;
224 }
225
MipiCsiSetComboDevAttrTest(struct MipiCsiTest * test)226 static int32_t MipiCsiSetComboDevAttrTest(struct MipiCsiTest *test)
227 {
228 int32_t ret;
229
230 InitComboDevAttr(test);
231 ret = MipiCsiSetComboDevAttr(test->handle, &(test->attr));
232 if ((ret == HDF_SUCCESS) || (ret == HDF_ERR_NOT_SUPPORT)) {
233 return HDF_SUCCESS;
234 }
235
236 HDF_LOGE("%s: failed.", __func__);
237 return ret;
238 }
239
MipiCsiSetPhyCmvmodeTest(struct MipiCsiTest * test)240 static int32_t MipiCsiSetPhyCmvmodeTest(struct MipiCsiTest *test)
241 {
242 int32_t ret;
243
244 test->devno = 0;
245 // PHY_CMV_GE1200MV or PHY_CMV_LT1200MV
246 test->cmvMode = PHY_CMV_GE1200MV;
247 ret = MipiCsiSetPhyCmvmode(test->handle, test->devno, test->cmvMode);
248 if ((ret == HDF_SUCCESS) || (ret == HDF_ERR_NOT_SUPPORT)) {
249 return HDF_SUCCESS;
250 }
251 HDF_LOGE("%s: failed.", __func__);
252
253 return ret;
254 }
255
MipiCsiResetSensorTest(struct MipiCsiTest * test)256 static int32_t MipiCsiResetSensorTest(struct MipiCsiTest *test)
257 {
258 int32_t ret;
259
260 // snsResetSource select 0 or 1, and must be less than SNS_MAX_RST_SOURCE_NUM
261 test->snsResetSource = 0;
262 ret = MipiCsiResetSensor(test->handle, test->snsResetSource);
263 if ((ret == HDF_SUCCESS) || (ret == HDF_ERR_NOT_SUPPORT)) {
264 return HDF_SUCCESS;
265 }
266 HDF_LOGE("%s: failed.", __func__);
267
268 return ret;
269 }
270
MipiCsiUnresetSensorTest(struct MipiCsiTest * test)271 static int32_t MipiCsiUnresetSensorTest(struct MipiCsiTest *test)
272 {
273 int32_t ret;
274
275 // snsResetSource select 0 or 1, and must be less than SNS_MAX_RST_SOURCE_NUM
276 test->snsResetSource = 0;
277 ret = MipiCsiUnresetSensor(test->handle, test->snsResetSource);
278 if ((ret == HDF_SUCCESS) || (ret == HDF_ERR_NOT_SUPPORT)) {
279 return HDF_SUCCESS;
280 }
281 HDF_LOGE("%s: failed.", __func__);
282
283 return ret;
284 }
285
MipiCsiResetRxTest(struct MipiCsiTest * test)286 static int32_t MipiCsiResetRxTest(struct MipiCsiTest *test)
287 {
288 int32_t ret;
289
290 // comboDev select 0 or 1, and must be less than MIPI_RX_MAX_DEV_NUM
291 test->comboDev = 0;
292 ret = MipiCsiResetRx(test->handle, test->comboDev);
293 if ((ret == HDF_SUCCESS) || (ret == HDF_ERR_NOT_SUPPORT)) {
294 return HDF_SUCCESS;
295 }
296 HDF_LOGE("%s: failed.", __func__);
297
298 return ret;
299 }
300
MipiCsiUnresetRxTest(struct MipiCsiTest * test)301 static int32_t MipiCsiUnresetRxTest(struct MipiCsiTest *test)
302 {
303 int32_t ret;
304
305 // comboDev select 0 or 1, and must be less than MIPI_RX_MAX_DEV_NUM
306 test->comboDev = 0;
307 ret = MipiCsiUnresetRx(test->handle, test->comboDev);
308 if ((ret == HDF_SUCCESS) || (ret == HDF_ERR_NOT_SUPPORT)) {
309 return HDF_SUCCESS;
310 }
311 HDF_LOGE("%s: failed.", __func__);
312
313 return ret;
314 }
315
MipiCsiSetHsModeTest(struct MipiCsiTest * test)316 static int32_t MipiCsiSetHsModeTest(struct MipiCsiTest *test)
317 {
318 int32_t ret;
319
320 // laneDivideMode: Hi3516CV500(LANE_DIVIDE_MODE_0), Hi3516EV200(LANE_DIVIDE_MODE_0)
321 test->laneDivideMode = LANE_DIVIDE_MODE_0;
322 ret = MipiCsiSetHsMode(test->handle, test->laneDivideMode);
323 if ((ret == HDF_SUCCESS) || (ret == HDF_ERR_NOT_SUPPORT)) {
324 return HDF_SUCCESS;
325 }
326 HDF_LOGE("%s: failed.", __func__);
327
328 return ret;
329 }
330
MipiCsiEnableMipiClockTest(struct MipiCsiTest * test)331 static int32_t MipiCsiEnableMipiClockTest(struct MipiCsiTest *test)
332 {
333 int32_t ret;
334
335 // comboDev select 0 or 1, and must be less than MIPI_RX_MAX_DEV_NUM
336 test->comboDev = 0;
337 ret = MipiCsiEnableClock(test->handle, test->comboDev);
338 if ((ret == HDF_SUCCESS) || (ret == HDF_ERR_NOT_SUPPORT)) {
339 return HDF_SUCCESS;
340 }
341 HDF_LOGE("%s: failed.", __func__);
342
343 return ret;
344 }
345
MipiCsiDisableMipiClockTest(struct MipiCsiTest * test)346 static int32_t MipiCsiDisableMipiClockTest(struct MipiCsiTest *test)
347 {
348 int32_t ret;
349
350 // comboDev select 0 or 1, and must be less than MIPI_RX_MAX_DEV_NUM
351 test->comboDev = 0;
352 ret = MipiCsiDisableClock(test->handle, test->comboDev);
353 if ((ret == HDF_SUCCESS) || (ret == HDF_ERR_NOT_SUPPORT)) {
354 return HDF_SUCCESS;
355 }
356 HDF_LOGE("%s: failed.", __func__);
357
358 return ret;
359 }
360
MipiCsiEnableSensorClockTest(struct MipiCsiTest * test)361 static int32_t MipiCsiEnableSensorClockTest(struct MipiCsiTest *test)
362 {
363 int32_t ret;
364
365 // snsClkSource select 0 or 1, and must be less than SNS_MAX_CLK_SOURCE_NUM
366 test->snsClkSource = 0;
367 ret = MipiCsiEnableSensorClock(test->handle, test->snsClkSource);
368 if ((ret == HDF_SUCCESS) || (ret == HDF_ERR_NOT_SUPPORT)) {
369 return HDF_SUCCESS;
370 }
371 HDF_LOGE("%s: failed.", __func__);
372
373 return ret;
374 }
375
MipiCsiDisableSensorClockTest(struct MipiCsiTest * test)376 static int32_t MipiCsiDisableSensorClockTest(struct MipiCsiTest *test)
377 {
378 int32_t ret;
379
380 // snsClkSource select 0 or 1, and must be less than SNS_MAX_CLK_SOURCE_NUM
381 test->snsClkSource = 0;
382 ret = MipiCsiDisableSensorClock(test->handle, test->snsClkSource);
383 if ((ret == HDF_SUCCESS) || (ret == HDF_ERR_NOT_SUPPORT)) {
384 return HDF_SUCCESS;
385 }
386 HDF_LOGE("%s: failed.", __func__);
387
388 return ret;
389 }
390
MipiCsiSetExtDataTypeTest(struct MipiCsiTest * test)391 static int32_t MipiCsiSetExtDataTypeTest(struct MipiCsiTest *test)
392 {
393 int32_t ret;
394 ExtDataType dataType;
395 dataType.devno = 0;
396 dataType.num = 0;
397
398 // extDataBitWidth set 8, 10, 12, 14 or 16.
399 dataType.extDataBitWidth[0] = 12; /* 12:magic bit width */
400 dataType.extDataBitWidth[1] = 12; /* 12:magic bit width */
401 dataType.extDataBitWidth[2] = 12; /* 12:magic bit width */
402
403 dataType.extDataType[0] = 0x39; /* 0x39 -- data type reserved */
404 dataType.extDataType[1] = 0x39; /* 0x39 -- data type reserved */
405 dataType.extDataType[2] = 0x39; /* 0x39 -- data type reserved */
406 test->dataType = dataType;
407
408 ret = MipiCsiSetExtDataType(test->handle, &test->dataType);
409 if ((ret == HDF_SUCCESS) || (ret == HDF_ERR_NOT_SUPPORT)) {
410 return HDF_SUCCESS;
411 }
412 HDF_LOGE("%s: failed.", __func__);
413
414 return ret;
415 }
416
MipiCsiTestByCmd(struct MipiCsiTest * test,uint8_t cmd)417 static int32_t MipiCsiTestByCmd(struct MipiCsiTest *test, uint8_t cmd)
418 {
419 int32_t ret = HDF_FAILURE;
420
421 if (test == NULL) {
422 HDF_LOGE("%s: test is NULL", __func__);
423 return ret;
424 }
425
426 HDF_LOGI("%s: test cmd %u, enter.", __func__, cmd);
427 switch (cmd) {
428 case MIPI_CSI_TEST_SET_HS_MODE:
429 ret = MipiCsiSetHsModeTest(test);
430 break;
431 case MIPI_CSI_TEST_DISABLE_MIPI_CLOCK:
432 ret = MipiCsiDisableMipiClockTest(test);
433 break;
434 case MIPI_CSI_TEST_ENABLE_MIPI_CLOCK:
435 ret = MipiCsiEnableMipiClockTest(test);
436 break;
437 case MIPI_CSI_TEST_RESET_RX:
438 ret = MipiCsiResetRxTest(test);
439 break;
440 case MIPI_CSI_TEST_DISABLE_SENSOR_CLOCK:
441 ret = MipiCsiDisableSensorClockTest(test);
442 break;
443 case MIPI_CSI_TEST_ENABLE_SENSOR_CLOCK:
444 ret = MipiCsiEnableSensorClockTest(test);
445 break;
446 case MIPI_CSI_TEST_RESET_SENSOR:
447 ret = MipiCsiResetSensorTest(test);
448 break;
449 case MIPI_CSI_TEST_SET_DEV_ATTR:
450 ret = MipiCsiSetComboDevAttrTest(test);
451 break;
452 case MIPI_CSI_TEST_SET_PHY_CMVMODE:
453 ret = MipiCsiSetPhyCmvmodeTest(test);
454 break;
455 case MIPI_CSI_TEST_SET_EXT_DATA_TYPE:
456 ret = MipiCsiSetExtDataTypeTest(test);
457 break;
458 case MIPI_CSI_TEST_UNRESET_RX:
459 ret = MipiCsiUnresetRxTest(test);
460 break;
461 case MIPI_CSI_TEST_UNRESET_SENSOR:
462 ret = MipiCsiUnresetSensorTest(test);
463 break;
464 default:
465 HDF_LOGE("%s: not support", __func__);
466 break;
467 }
468 HDF_LOGI("%s: test cmd %u, ret %d done.", __func__, cmd, ret);
469
470 return ret;
471 }
472
MipiCsiTestDoTest(struct MipiCsiTest * test,uint8_t cmd)473 static int32_t MipiCsiTestDoTest(struct MipiCsiTest *test, uint8_t cmd)
474 {
475 int32_t ret;
476 OsalMSleep(SEQ_OUTPUT_DELAY);
477
478 if (test == NULL) {
479 return HDF_ERR_INVALID_OBJECT;
480 }
481
482 #ifdef MIPI_CSI_TEST_SELF
483 int32_t i;
484 if (cmd != 0) {
485 return HDF_SUCCESS;
486 }
487 ret = MipiCsiTestSetUp(test);
488 if (ret != HDF_SUCCESS) {
489 HDF_LOGE("%s: setup fail!", __func__);
490 return ret;
491 }
492
493 for (i = 0; i < test->total; i++) {
494 if (MipiCsiTestByCmd(test, i) != HDF_SUCCESS) {
495 test->fails++;
496 }
497 }
498 HDF_LOGI("\n\n%s: **********PASS:%u FAIL:%u**************\n\n",
499 __func__, test->total - test->fails, test->fails);
500 ret = (test->fails > 0) ? HDF_FAILURE : HDF_SUCCESS;
501 MipiCsiTestTearDown(test);
502 #else
503 if (cmd == 0) {
504 ret = MipiCsiTestSetUp(test);
505 if (ret != HDF_SUCCESS) {
506 HDF_LOGE("%s: [MipiCsiTestSetUp] failed!", __func__);
507 return ret;
508 }
509 }
510 ret = MipiCsiTestByCmd(test, cmd);
511 if (cmd == (test->total - 1)) {
512 MipiCsiTestTearDown(test);
513 }
514 #endif
515 OsalMSleep(SEQ_OUTPUT_DELAY);
516
517 return ret;
518 }
519
MipiCsiTestBind(struct HdfDeviceObject * device)520 static int32_t MipiCsiTestBind(struct HdfDeviceObject *device)
521 {
522 static struct MipiCsiTest test;
523
524 test.cntlrId = 0;
525 test.total = MIPI_CSI_TEST_MAX;
526 test.doTest = MipiCsiTestDoTest;
527 device->service = &test.service;
528 #ifdef MIPI_CSI_TEST_SELF
529 HDF_LOGI("%s: test on init!", __func__);
530 test.doTest(&test, -1);
531 #endif
532 return HDF_SUCCESS;
533 }
534
MipiCsiTestInit(struct HdfDeviceObject * device)535 static int32_t MipiCsiTestInit(struct HdfDeviceObject *device)
536 {
537 (void)device;
538 return HDF_SUCCESS;
539 }
540
541 struct HdfDriverEntry g_mipiCsiTestEntry = {
542 .moduleVersion = 1,
543 .Bind = MipiCsiTestBind,
544 .Init = MipiCsiTestInit,
545 .moduleName = "PLATFORM_MIPI_CSI_TEST",
546 };
547 HDF_INIT(g_mipiCsiTestEntry);
548