1 /*
2 * mipi_csi_dev.c
3 *
4 * create vfs node for mipi-csi
5 *
6 * Copyright (c) 2021 Huawei Device Co., Ltd.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19 #include "mipi_csi_dev.h"
20 #include <linux/miscdevice.h>
21 #include <linux/proc_fs.h>
22 #include <linux/seq_file.h>
23 #include <linux/version.h>
24 #include "hdf_log.h"
25 #include "mipi_csi_core.h"
26 #include "osal_mem.h"
27 #include "securec.h"
28
29 #ifdef __cplusplus
30 #if __cplusplus
31 extern "C" {
32 #endif
33 #endif /* End of #ifdef __cplusplus */
34
35 /* macro definition */
36 #define HDF_LOG_TAG mipi_csi_dev
37 #define MIPI_RX_DEV_NAME "mipi_csi_dev"
38 #define MIPI_RX_PROC_NAME "mipi_rx"
39 #define MAX_DEV_NAME_LEN 48
40 #define HIMEDIA_DYNAMIC_MINOR 255
41
42 #define COMBO_MAX_LANE_NUM 4
43
44 #define COMBO_MIN_WIDTH 32
45 #define COMBO_MIN_HEIGHT 32
46
47 #define MIPI_HEIGHT_ALIGN 2
48 #define MIPI_WIDTH_ALIGN 2
49 #define MIPI_RX_MAX_PHY_NUM 1
50 #define LANE_DATA_COUNT 12
51
52 #define ENABLE_INT_MASK
53
54 // SeqBuf and seq_file are used in different os.
55 typedef struct seq_file SysProcEntryTag;
56 struct MipiCsiVfsPara {
57 struct MipiCsiCntlr *cntlr;
58 struct miscdevice *miscDev;
59 // mutex and OsalMutex are used in different os.
60 struct OsalMutex lock;
61 void *priv;
62 };
63
64 static struct MipiCsiVfsPara g_vfsPara;
SysSeqPrintf(SysProcEntryTag * m,const char * f,...)65 void SysSeqPrintf(SysProcEntryTag *m, const char *f, ...)
66 {
67 va_list args;
68
69 va_start(args, f);
70 // LosBufPrintf and seq_printf are used in different os.
71 seq_printf(m, f, args);
72 va_end(args);
73 }
74
SysMutexLock(struct OsalMutex * mutex)75 static int32_t SysMutexLock(struct OsalMutex *mutex)
76 {
77 // mutex_lock_interruptible and OsalMutexLock are used in different os.
78 return OsalMutexLock(mutex);
79 }
80
RegisterDevice(const char * name,uint8_t id,unsigned short mode,struct file_operations * ops)81 static int32_t RegisterDevice(const char *name, uint8_t id, unsigned short mode, struct file_operations *ops)
82 {
83 int32_t error;
84 struct miscdevice *dev = NULL;
85
86 if ((name == NULL) || (ops == NULL) || (id >= MAX_CNTLR_CNT)) {
87 HDF_LOGE("%s: name, ops or id is error.", __func__);
88 return HDF_ERR_INVALID_PARAM;
89 }
90 dev = OsalMemCalloc(sizeof(struct miscdevice));
91 if (dev == NULL) {
92 HDF_LOGE("%s: [OsalMemCalloc] failed.", __func__);
93 return HDF_ERR_MALLOC_FAIL;
94 }
95 dev->fops = ops;
96 dev->name = OsalMemCalloc(MAX_DEV_NAME_LEN + 1);
97 if (dev->name == NULL) {
98 OsalMemFree(dev);
99 HDF_LOGE("%s: [OsalMemCalloc] failed.", __func__);
100 return HDF_ERR_MALLOC_FAIL;
101 }
102 if (id != 0) { /* 0 : id */
103 if (snprintf_s((char *)dev->name, MAX_DEV_NAME_LEN + 1, MAX_DEV_NAME_LEN, "%s%u", name, id) < 0) {
104 OsalMemFree((char *)dev->name);
105 OsalMemFree(dev);
106 HDF_LOGE("%s: [snprintf_s] failed.", __func__);
107 return HDF_FAILURE;
108 }
109 } else {
110 if (memcpy_s((char *)dev->name, MAX_DEV_NAME_LEN, name, strlen(name)) != EOK) {
111 OsalMemFree((char *)dev->name);
112 OsalMemFree(dev);
113 HDF_LOGE("%s: [memcpy_s] failed.", __func__);
114 return HDF_ERR_IO;
115 }
116 }
117 ops->owner = THIS_MODULE;
118 dev->minor = MISC_DYNAMIC_MINOR;
119 dev->mode = mode;
120
121 // register_driver and misc_register are used in different os.
122 error = misc_register(dev);
123 if (error < 0) {
124 HDF_LOGE("%s: id %u cannot register miscDev on minor=%d (err=%d)",
125 __func__, id, MISC_DYNAMIC_MINOR, error);
126 OsalMemFree((char *)dev->name);
127 OsalMemFree(dev);
128 return error;
129 }
130
131 g_vfsPara.miscDev = dev;
132 HDF_LOGI("%s: create inode ok, name = %s, minor = %d", __func__, dev->name, dev->minor);
133
134 return HDF_SUCCESS;
135 }
136
UnregisterDevice(uint8_t id)137 static void UnregisterDevice(uint8_t id)
138 {
139 struct miscdevice *dev = NULL;
140
141 if (id >= MAX_CNTLR_CNT) {
142 HDF_LOGE("%s: id error.", __func__);
143 return;
144 }
145 dev = g_vfsPara.miscDev;
146 if (dev == NULL) {
147 HDF_LOGE("%s: dev is NULL.", __func__);
148 return;
149 }
150
151 // unregister_driver <---> misc_deregister
152 misc_deregister(dev);
153 OsalMemFree((void *)dev->name);
154 dev->name = NULL;
155 OsalMemFree(dev);
156 dev = NULL;
157 HDF_LOGI("%s: success.", __func__);
158 }
159
GetCntlr(const SysProcEntryTag * s)160 static struct MipiCsiCntlr *GetCntlr(const SysProcEntryTag *s)
161 {
162 if (s == NULL) {
163 HDF_LOGE("%s: s is NULL.", __func__);
164 return NULL;
165 }
166 return g_vfsPara.cntlr;
167 }
168
MipiSetComboDevAttr(struct MipiCsiVfsPara * vfsPara,ComboDevAttr * pAttr)169 static int MipiSetComboDevAttr(struct MipiCsiVfsPara *vfsPara, ComboDevAttr *pAttr)
170 {
171 int ret;
172
173 if (vfsPara == NULL) {
174 HDF_LOGE("%s: vfsPara is NULL.", __func__);
175 return HDF_ERR_INVALID_OBJECT;
176 }
177
178 if (SysMutexLock(&(vfsPara->lock))) {
179 HDF_LOGE("%s: [OsalMutexLock] failed.", __func__);
180 return HDF_FAILURE;
181 }
182 ret = MipiCsiCntlrSetComboDevAttr(vfsPara->cntlr, pAttr);
183 OsalMutexUnlock(&(vfsPara->lock));
184
185 return ret;
186 }
187
MipiSetExtDataType(struct MipiCsiVfsPara * vfsPara,ExtDataType * dataType)188 static int MipiSetExtDataType(struct MipiCsiVfsPara *vfsPara, ExtDataType *dataType)
189 {
190 if (vfsPara == NULL) {
191 HDF_LOGE("%s: vfsPara is NULL.", __func__);
192 return HDF_ERR_INVALID_OBJECT;
193 }
194
195 if (dataType == NULL) {
196 HDF_LOGE("%s: dataType is NULL.", __func__);
197 return HDF_ERR_INVALID_OBJECT;
198 }
199
200 if (SysMutexLock(&(vfsPara->lock))) {
201 HDF_LOGE("%s: [OsalMutexLock] failed.", __func__);
202 return HDF_FAILURE;
203 }
204 MipiCsiCntlrSetExtDataType(vfsPara->cntlr, dataType);
205 OsalMutexUnlock(&(vfsPara->lock));
206
207 return HDF_SUCCESS;
208 }
209
MipiSetPhyCmvmode(struct MipiCsiVfsPara * vfsPara,uint8_t devno,PhyCmvMode cmvMode)210 static int MipiSetPhyCmvmode(struct MipiCsiVfsPara *vfsPara, uint8_t devno, PhyCmvMode cmvMode)
211 {
212 if (vfsPara == NULL) {
213 HDF_LOGE("%s: vfsPara is NULL.", __func__);
214 return HDF_ERR_INVALID_OBJECT;
215 }
216
217 if (SysMutexLock(&(vfsPara->lock))) {
218 HDF_LOGE("%s: [OsalMutexLock] failed.", __func__);
219 return HDF_FAILURE;
220 }
221 MipiCsiCntlrSetPhyCmvmode(vfsPara->cntlr, devno, cmvMode);
222 OsalMutexUnlock(&(vfsPara->lock));
223
224 return HDF_SUCCESS;
225 }
226
MipiRxIoctl(struct file * filep,unsigned int cmd,unsigned long arg)227 static long MipiRxIoctl(struct file *filep, unsigned int cmd, unsigned long arg)
228 {
229 unsigned long *argp = (unsigned long *)(uintptr_t)arg;
230 struct MipiCsiCntlr *cntlr = g_vfsPara.cntlr;
231 int ret = HDF_FAILURE;
232 if ((argp == NULL) || (cntlr == NULL)) {
233 HDF_LOGE("%s: argp or cntlr is NULL.", __func__);
234 return HDF_ERR_INVALID_OBJECT;
235 }
236 (void)filep;
237 switch (cmd) {
238 case HI_MIPI_SET_DEV_ATTR:
239 ret = MipiSetComboDevAttr(&g_vfsPara, (ComboDevAttr *)argp);
240 break;
241 case HI_MIPI_SET_PHY_CMVMODE: {
242 PhyCmv *pPhyCmv = (PhyCmv *)argp;
243 ret = MipiSetPhyCmvmode(&g_vfsPara, pPhyCmv->devno, pPhyCmv->cmvMode);
244 break;
245 }
246 case HI_MIPI_RESET_SENSOR:
247 ret = MipiCsiCntlrResetSensor(cntlr, (uint8_t)argp);
248 break;
249 case HI_MIPI_UNRESET_SENSOR:
250 ret = MipiCsiCntlrUnresetSensor(cntlr, (uint8_t)argp);
251 break;
252 case HI_MIPI_RESET_MIPI:
253 ret = MipiCsiCntlrResetRx(cntlr, (uint8_t)argp);
254 break;
255 case HI_MIPI_UNRESET_MIPI:
256 ret = MipiCsiCntlrUnresetRx(cntlr, (uint8_t)argp);
257 break;
258 case HI_MIPI_RESET_SLVS:
259 break;
260 case HI_MIPI_UNRESET_SLVS:
261 break;
262 case HI_MIPI_SET_HS_MODE:
263 ret = MipiCsiCntlrSetHsMode(cntlr, (LaneDivideMode)argp);
264 break;
265 case HI_MIPI_ENABLE_MIPI_CLOCK:
266 ret = MipiCsiCntlrEnableClock(cntlr, (uint8_t)argp);
267 break;
268 case HI_MIPI_DISABLE_MIPI_CLOCK:
269 ret = MipiCsiCntlrDisableClock(cntlr, (uint8_t)argp);
270 break;
271 case HI_MIPI_ENABLE_SLVS_CLOCK:
272 break;
273 case HI_MIPI_DISABLE_SLVS_CLOCK:
274 break;
275 case HI_MIPI_ENABLE_SENSOR_CLOCK:
276 ret = MipiCsiCntlrEnableSensorClock(cntlr, (uint8_t)argp);
277 break;
278 case HI_MIPI_DISABLE_SENSOR_CLOCK:
279 ret = MipiCsiCntlrDisableSensorClock(cntlr, (uint8_t)argp);
280 break;
281 case HI_MIPI_SET_EXT_DATA_TYPE:
282 ret = MipiSetExtDataType(&g_vfsPara, (ExtDataType *)argp);
283 break;
284 default:
285 break;
286 }
287 HDF_LOGI("%s: cmd = %d %s.", __func__, cmd, (ret == HDF_SUCCESS) ? "success" : "failed");
288 return ret;
289 }
290
291 #ifdef CONFIG_COMPAT
MipiRxCompatIoctl(struct file * filep,unsigned int cmd,unsigned long arg)292 static long MipiRxCompatIoctl(struct file *filep, unsigned int cmd, unsigned long arg)
293 {
294 return MipiRxIoctl(filep, cmd, arg);
295 }
296 #endif
297
298 #ifdef CONFIG_HI_PROC_SHOW_SUPPORT
299 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
ProcRegister(const char * name,uint8_t id,unsigned short mode,const struct proc_ops * ops)300 static int32_t ProcRegister(const char *name, uint8_t id, unsigned short mode, const struct proc_ops *ops)
301 #else
302 static int32_t ProcRegister(const char *name, uint8_t id, unsigned short mode, const struct file_operations *ops)
303 #endif
304 {
305 char procName[MAX_DEV_NAME_LEN + 1];
306 struct proc_dir_entry* entry = NULL;
307 int32_t ret;
308
309 if ((name == NULL) || (ops == NULL) || (id >= MAX_CNTLR_CNT)) {
310 HDF_LOGE("%s: name, ops or id is error.", __func__);
311 return HDF_ERR_INVALID_PARAM;
312 }
313 if (memset_s(procName, MAX_DEV_NAME_LEN + 1, 0, MAX_DEV_NAME_LEN + 1) != EOK) {
314 HDF_LOGE("%s: [memcpy_s] failed.", __func__);
315 return HDF_ERR_IO;
316 }
317 if (id != 0) {
318 ret = snprintf_s(procName, MAX_DEV_NAME_LEN + 1, MAX_DEV_NAME_LEN, "%s%u", name, id);
319 } else {
320 ret = snprintf_s(procName, MAX_DEV_NAME_LEN + 1, MAX_DEV_NAME_LEN, "%s", name);
321 }
322 if (ret < 0) {
323 HDF_LOGE("%s: procName %s [snprintf_s] fail", __func__, procName);
324 return HDF_FAILURE;
325 }
326
327 // proc_create and CreateProcEntry are used in different os.
328 entry = proc_create(procName, mode, NULL, ops);
329 if (entry == NULL) {
330 HDF_LOGE("%s: [proc_create] name %s fail", __func__, procName);
331 return HDF_FAILURE;
332 }
333 HDF_LOGI("%s: success.", __func__);
334 return HDF_SUCCESS;
335 }
336
ProcUnregister(const char * name,uint8_t id)337 static void ProcUnregister(const char *name, uint8_t id)
338 {
339 char procName[MAX_DEV_NAME_LEN + 1];
340 int32_t ret;
341
342 if (id >= MAX_CNTLR_CNT) {
343 HDF_LOGE("%s: id error.", __func__);
344 return;
345 }
346 if (memset_s(procName, MAX_DEV_NAME_LEN + 1, 0, MAX_DEV_NAME_LEN + 1) != EOK) {
347 HDF_LOGE("%s: [memcpy_s] failed.", __func__);
348 return;
349 }
350 if (id != 0) {
351 ret = snprintf_s(procName, MAX_DEV_NAME_LEN + 1, MAX_DEV_NAME_LEN, "%s%u", name, id);
352 } else {
353 ret = snprintf_s(procName, MAX_DEV_NAME_LEN + 1, MAX_DEV_NAME_LEN, "%s", name);
354 }
355 if (ret < 0) {
356 HDF_LOGE("%s: [snprintf_s] failed.", __func__);
357 return;
358 }
359
360 // remove_proc_entry and ProcFreeEntry are used in different os.
361 remove_proc_entry(procName, NULL);
362 HDF_LOGI("%s: success.", __func__);
363 }
364
MipiGetIntputModeName(InputMode inputMode)365 static const char *MipiGetIntputModeName(InputMode inputMode)
366 {
367 switch (inputMode) {
368 case INPUT_MODE_SUBLVDS:
369 case INPUT_MODE_LVDS:
370 case INPUT_MODE_HISPI:
371 return "LVDS";
372
373 case INPUT_MODE_MIPI:
374 return "MIPI";
375
376 case INPUT_MODE_CMOS:
377 case INPUT_MODE_BT1120:
378 case INPUT_MODE_BT656:
379 case INPUT_MODE_BYPASS:
380 return "CMOS";
381
382 default:
383 break;
384 }
385
386 return "N/A";
387 }
388
MipiGetRawDataTypeName(DataType type)389 static const char *MipiGetRawDataTypeName(DataType type)
390 {
391 switch (type) {
392 case DATA_TYPE_RAW_8BIT:
393 return "RAW8";
394
395 case DATA_TYPE_RAW_10BIT:
396 return "RAW10";
397
398 case DATA_TYPE_RAW_12BIT:
399 return "RAW12";
400
401 case DATA_TYPE_RAW_14BIT:
402 return "RAW14";
403
404 case DATA_TYPE_RAW_16BIT:
405 return "RAW16";
406
407 case DATA_TYPE_YUV420_8BIT_NORMAL:
408 return "yuv420_8bit_normal";
409
410 case DATA_TYPE_YUV420_8BIT_LEGACY:
411 return "yuv420_8bit_legacy";
412
413 case DATA_TYPE_YUV422_8BIT:
414 return "yuv422_8bit";
415
416 case DATA_TYPE_YUV422_PACKED:
417 return "yuv422_packed";
418
419 default:
420 break;
421 }
422
423 return "N/A";
424 }
425
MipiGetDataRateName(MipiDataRate dataRate)426 static const char *MipiGetDataRateName(MipiDataRate dataRate)
427 {
428 switch (dataRate) {
429 case MIPI_DATA_RATE_X1:
430 return "X1";
431
432 case MIPI_DATA_RATE_X2:
433 return "X2";
434
435 default:
436 break;
437 }
438
439 return "N/A";
440 }
441
MipiPrintMipiWdrMode(MipiWdrMode wdrMode)442 static const char *MipiPrintMipiWdrMode(MipiWdrMode wdrMode)
443 {
444 switch (wdrMode) {
445 case HI_MIPI_WDR_MODE_NONE:
446 return "None";
447
448 case HI_MIPI_WDR_MODE_VC:
449 return "VC";
450
451 case HI_MIPI_WDR_MODE_DT:
452 return "DT";
453
454 case HI_MIPI_WDR_MODE_DOL:
455 return "DOL";
456
457 default:
458 break;
459 }
460
461 return "N/A";
462 }
463
MipiPrintLvdsWdrMode(WdrMode wdrMode)464 static const char *MipiPrintLvdsWdrMode(WdrMode wdrMode)
465 {
466 switch (wdrMode) {
467 case HI_WDR_MODE_NONE:
468 return "None";
469
470 case HI_WDR_MODE_2F:
471 return "2F";
472
473 case HI_WDR_MODE_3F:
474 return "3F";
475
476 case HI_WDR_MODE_4F:
477 return "4F";
478
479 case HI_WDR_MODE_DOL_2F:
480 return "DOL_2F";
481
482 case HI_WDR_MODE_DOL_3F:
483 return "DOL_3F";
484
485 case HI_WDR_MODE_DOL_4F:
486 return "DOL_4F";
487
488 default:
489 break;
490 }
491
492 return "N/A";
493 }
494
MipiPrintLaneDivideMode(LaneDivideMode mode)495 static const char *MipiPrintLaneDivideMode(LaneDivideMode mode)
496 {
497 if (mode == LANE_DIVIDE_MODE_0) {
498 return "4";
499 } else {
500 return "2+2";
501 }
502 }
503
ProcShowMipiDevice(SysProcEntryTag * s,struct MipiCsiCntlr * cntlr)504 static void ProcShowMipiDevice(SysProcEntryTag *s, struct MipiCsiCntlr *cntlr)
505 {
506 int32_t ret;
507 const char *wdrMode = NULL;
508 uint8_t devno;
509 InputMode inputMode;
510 DataType dataType;
511 MipiDevCtx tag;
512
513 ret = MipiCsiDebugGetMipiDevCtx(cntlr, &tag);
514 if (ret != HDF_SUCCESS) {
515 HDF_LOGE("%s: [MipiCsiDebugGetMipiDevCtx] failed.", __func__);
516 return;
517 }
518
519 SysSeqPrintf(s, "\nMIPI DEV ATTR\n");
520 SysSeqPrintf(s,
521 "%8s" "%10s" "%10s" "%20s" "%10s" "%8s" "%8s" "%8s" "%8s" "\n",
522 "Devno", "WorkMode", "DataRate", "DataType", "WDRMode", "ImgX", "ImgY", "ImgW", "ImgH");
523
524 for (devno = 0; devno < MIPI_RX_MAX_DEV_NUM; devno++) {
525 ComboDevAttr *pdevAttr = &tag.comboDevAttr[devno];
526 inputMode = pdevAttr->inputMode;
527 if (!tag.devCfged[devno]) {
528 continue;
529 }
530
531 if (inputMode == INPUT_MODE_MIPI) {
532 dataType = pdevAttr->mipiAttr.inputDataType;
533 wdrMode = MipiPrintMipiWdrMode(pdevAttr->mipiAttr.wdrMode);
534 } else {
535 dataType = pdevAttr->lvdsAttr.inputDataType;
536 wdrMode = MipiPrintLvdsWdrMode(pdevAttr->lvdsAttr.wdrMode);
537 }
538
539 SysSeqPrintf(s, "%8d" "%10s" "%10s" "%20s" "%10s" "%8d" "%8d" "%8d" "%8d" "\n",
540 devno,
541 MipiGetIntputModeName(inputMode),
542 MipiGetDataRateName(pdevAttr->dataRate),
543 MipiGetRawDataTypeName(dataType),
544 wdrMode,
545 pdevAttr->imgRect.x,
546 pdevAttr->imgRect.y,
547 pdevAttr->imgRect.width,
548 pdevAttr->imgRect.height);
549 }
550 }
551
ProcShowMipiLane(SysProcEntryTag * s,struct MipiCsiCntlr * cntlr)552 static void ProcShowMipiLane(SysProcEntryTag *s, struct MipiCsiCntlr *cntlr)
553 {
554 int32_t ret;
555 uint8_t devno;
556 InputMode inputMode;
557 MipiDevCtx tag;
558
559 ret = MipiCsiDebugGetMipiDevCtx(cntlr, &tag);
560 if (ret != HDF_SUCCESS) {
561 HDF_LOGE("%s: [MipiCsiDebugGetMipiDevCtx] failed.", __func__);
562 return;
563 }
564
565 SysSeqPrintf(s, "\nMIPI LANE INFO\n");
566 SysSeqPrintf(s, "%8s" "%24s" "\n", "Devno", "LaneID");
567
568 for (devno = 0; devno < MIPI_RX_MAX_DEV_NUM; devno++) {
569 ComboDevAttr *pdevAttr = &tag.comboDevAttr[devno];
570
571 inputMode = pdevAttr->inputMode;
572 if (!tag.devCfged[devno]) {
573 continue;
574 }
575
576 if (inputMode == INPUT_MODE_MIPI) {
577 SysSeqPrintf(s, "%8d" "%10d,%3d,%3d,%3d" "\n",
578 devno,
579 pdevAttr->mipiAttr.laneId[0], /* 0 -- laneId 0 */
580 pdevAttr->mipiAttr.laneId[1], /* 1 -- laneId 1 */
581 pdevAttr->mipiAttr.laneId[2], /* 2 -- laneId 2 */
582 pdevAttr->mipiAttr.laneId[3]); /* 3 -- laneId 3 */
583 } else if (inputMode == INPUT_MODE_LVDS ||
584 inputMode == INPUT_MODE_SUBLVDS ||
585 inputMode == INPUT_MODE_HISPI) {
586 SysSeqPrintf(s, "%8d" "%10d,%3d,%3d,%3d" "\n",
587 devno,
588 pdevAttr->lvdsAttr.laneId[0],
589 pdevAttr->lvdsAttr.laneId[1],
590 pdevAttr->lvdsAttr.laneId[2], /* 2 -- laneId 2 */
591 pdevAttr->lvdsAttr.laneId[3]); /* 3 -- laneId 3 */
592 }
593 }
594 }
595
GetPhyData(struct MipiCsiCntlr * cntlr,int phyId,int laneId)596 static unsigned int GetPhyData(struct MipiCsiCntlr *cntlr, int phyId, int laneId)
597 {
598 int32_t ret;
599 unsigned int laneData;
600
601 ret = MipiCsiDebugGetPhyData(cntlr, phyId, laneId, &laneData);
602 if (ret != HDF_SUCCESS) {
603 HDF_LOGE("%s: [MipiCsiDebugGetPhyData] failed.", __func__);
604 return 0;
605 }
606
607 return laneData;
608 }
609
GetPhyMipiLinkData(struct MipiCsiCntlr * cntlr,int phyId,int laneId)610 static unsigned int GetPhyMipiLinkData(struct MipiCsiCntlr *cntlr, int phyId, int laneId)
611 {
612 int32_t ret;
613 unsigned int laneData;
614
615 ret = MipiCsiDebugGetPhyMipiLinkData(cntlr, phyId, laneId, &laneData);
616 if (ret != HDF_SUCCESS) {
617 HDF_LOGE("%s: [MipiCsiDebugGetPhyMipiLinkData] failed.", __func__);
618 return 0;
619 }
620
621 return laneData;
622 }
623
GetPhyLvdsLinkData(struct MipiCsiCntlr * cntlr,int phyId,int laneId)624 static unsigned int GetPhyLvdsLinkData(struct MipiCsiCntlr *cntlr, int phyId, int laneId)
625 {
626 int32_t ret;
627 unsigned int laneData;
628
629 ret = MipiCsiDebugGetPhyLvdsLinkData(cntlr, phyId, laneId, &laneData);
630 if (ret != HDF_SUCCESS) {
631 HDF_LOGE("%s: [MipiCsiDebugGetPhyLvdsLinkData] failed.", __func__);
632 return 0;
633 }
634
635 return laneData;
636 }
637
ProcShowMipiPhyData(SysProcEntryTag * s,struct MipiCsiCntlr * cntlr)638 static void ProcShowMipiPhyData(SysProcEntryTag *s, struct MipiCsiCntlr *cntlr)
639 {
640 int i;
641
642 SysSeqPrintf(s, "\nMIPI PHY DATA INFO\n");
643 SysSeqPrintf(s, "%8s" "%15s" "%19s" "%24s" "%22s" "\n",
644 "PhyId", "LaneId", "PhyData", "MipiData", "LvdsData");
645
646 for (i = 0; i < MIPI_RX_MAX_PHY_NUM; i++) {
647 SysSeqPrintf(s,
648 "%8d%8d,%2d,%2d,%2d, 0x%02x,0x%02x,0x%02x,0x%02x 0x%02x,0x%02x,0x%02x,0x%02x"
649 " 0x%02x,0x%02x,0x%02x,0x%02x\n",
650 i,
651 4 * i, /* 4 * i + 0 -- phyId laneId 0 */
652 4 * i + 1, /* 4 * i + 1 -- phyId laneId 1 */
653 4 * i + 2, /* 4 * i + 2 -- phyId laneId 2 */
654 4 * i + 3, /* 4 * i + 3 -- phyId laneId 3 */
655 GetPhyData(cntlr, i, 0), /* 0 -- laneId 0 */
656 GetPhyData(cntlr, i, 1), /* 1 -- laneId 1 */
657 GetPhyData(cntlr, i, 2), /* 2 -- laneId 2 */
658 GetPhyData(cntlr, i, 3), /* 3 -- laneId 3 */
659 GetPhyMipiLinkData(cntlr, i, 0), /* 0 -- laneId 0 */
660 GetPhyMipiLinkData(cntlr, i, 1), /* 1 -- laneId 1 */
661 GetPhyMipiLinkData(cntlr, i, 2), /* 2 -- laneId 2 */
662 GetPhyMipiLinkData(cntlr, i, 3), /* 3 -- laneId 3 */
663 GetPhyLvdsLinkData(cntlr, i, 0), /* 0 -- laneId 0 */
664 GetPhyLvdsLinkData(cntlr, i, 1), /* 1 -- laneId 1 */
665 GetPhyLvdsLinkData(cntlr, i, 2), /* 2 -- laneId 2 */
666 GetPhyLvdsLinkData(cntlr, i, 3)); /* 3 -- laneId 3 */
667 }
668 }
669
ProcShowMipiDetectInfo(SysProcEntryTag * s,struct MipiCsiCntlr * cntlr,uint8_t devnoArray[],int mipiCnt)670 static void ProcShowMipiDetectInfo(SysProcEntryTag *s, struct MipiCsiCntlr *cntlr,
671 uint8_t devnoArray[], int mipiCnt)
672 {
673 int32_t ret;
674 ImgSize imageSize;
675 short vcNum;
676 int devnoIdx;
677
678 SysSeqPrintf(s, "\nMIPI DETECT INFO\n");
679 SysSeqPrintf(s, "%6s%3s%8s%8s\n", "Devno", "VC", "width", "height");
680
681 for (devnoIdx = 0; devnoIdx < mipiCnt; devnoIdx++) {
682 for (vcNum = 0; vcNum < WDR_VC_NUM; vcNum++) {
683 ret = MipiCsiDebugGetMipiImgsizeStatis(cntlr, devnoArray[devnoIdx], vcNum, &imageSize);
684 if (ret != HDF_SUCCESS) {
685 HDF_LOGE("%s: [MipiCsiDebugGetMipiImgsizeStatis] failed.", __func__);
686 return;
687 }
688 SysSeqPrintf(s, "%6d%3d%8u%8u\n",
689 devnoArray[devnoIdx], vcNum, imageSize.width, imageSize.height);
690 }
691 }
692 }
693
ProcShowLvdsDetectInfo(SysProcEntryTag * s,struct MipiCsiCntlr * cntlr,uint8_t devnoArray[],int mipiCnt)694 static void ProcShowLvdsDetectInfo(SysProcEntryTag *s, struct MipiCsiCntlr *cntlr,
695 uint8_t devnoArray[], int mipiCnt)
696 {
697 int32_t ret;
698 ImgSize imageSize;
699 short vcNum;
700 int devnoIdx;
701
702 SysSeqPrintf(s, "\nLVDS DETECT INFO\n");
703 SysSeqPrintf(s, "%6s%3s%8s%8s\n", "Devno", "VC", "width", "height");
704
705 for (devnoIdx = 0; devnoIdx < mipiCnt; devnoIdx++) {
706 for (vcNum = 0; vcNum < WDR_VC_NUM; vcNum++) {
707 ret = MipiCsiDebugGetLvdsImgsizeStatis(cntlr, devnoArray[devnoIdx], vcNum, &imageSize);
708 if (ret != HDF_SUCCESS) {
709 HDF_LOGE("%s: [MipiCsiDebugGetLvdsImgsizeStatis] failed.", __func__);
710 return;
711 }
712 SysSeqPrintf(s, "%6d%3d%8d%8d\n",
713 devnoArray[devnoIdx], vcNum, imageSize.width, imageSize.height);
714 }
715 }
716 }
717
ProcShowLvdsLaneDetectInfo(SysProcEntryTag * s,struct MipiCsiCntlr * cntlr,uint8_t devnoArray[],int mipiCnt)718 static void ProcShowLvdsLaneDetectInfo(SysProcEntryTag *s, struct MipiCsiCntlr *cntlr,
719 uint8_t devnoArray[], int mipiCnt)
720 {
721 int32_t ret;
722 ImgSize imageSize;
723 short lane;
724 int devnoIdx;
725 ComboDevAttr *pstcomboDevAttr = NULL;
726 MipiDevCtx tag;
727
728 ret = MipiCsiDebugGetMipiDevCtx(cntlr, &tag);
729 if (ret != HDF_SUCCESS) {
730 HDF_LOGE("%s: [MipiCsiDebugGetMipiDevCtx] failed.", __func__);
731 return;
732 }
733
734 SysSeqPrintf(s, "\nLVDS LANE DETECT INFO\n");
735 SysSeqPrintf(s, "%6s%6s%8s%8s\n", "Devno", "Lane", "width", "height");
736
737 for (devnoIdx = 0; devnoIdx < mipiCnt; devnoIdx++) {
738 pstcomboDevAttr = &tag.comboDevAttr[devnoArray[devnoIdx]];
739 for (lane = 0; lane < LVDS_LANE_NUM; lane++) {
740 if (pstcomboDevAttr->lvdsAttr.laneId[lane] == -1) {
741 continue;
742 }
743 ret = MipiCsiDebugGetLvdsLaneImgsizeStatis(cntlr, devnoArray[devnoIdx], lane, &imageSize);
744 if (ret != HDF_SUCCESS) {
745 HDF_LOGE("%s: [MipiCsiDebugGetLvdsLaneImgsizeStatis] failed.", __func__);
746 return;
747 }
748
749 SysSeqPrintf(s, "%6d%6d%8d%8d\n",
750 devnoArray[devnoIdx], pstcomboDevAttr->lvdsAttr.laneId[lane],
751 imageSize.width, imageSize.height);
752 }
753 }
754 }
755
ProcShowMipiHsMode(SysProcEntryTag * s,struct MipiCsiCntlr * cntlr)756 static void ProcShowMipiHsMode(SysProcEntryTag *s, struct MipiCsiCntlr *cntlr)
757 {
758 int32_t ret;
759 MipiDevCtx tag;
760 LaneDivideMode laneDivideMode;
761
762 ret = MipiCsiDebugGetMipiDevCtx(cntlr, &tag);
763 if (ret != HDF_SUCCESS) {
764 HDF_LOGE("%s: [MipiCsiDebugGetMipiDevCtx] failed.", __func__);
765 return;
766 }
767
768 laneDivideMode = tag.laneDivideMode;
769 SysSeqPrintf(s, "\nMIPI LANE DIVIDE MODE\n");
770 SysSeqPrintf(s, "%6s" "%20s" "\n", "MODE", "LANE DIVIDE");
771 SysSeqPrintf(s, "%6d" "%20s" "\n", laneDivideMode, MipiPrintLaneDivideMode(laneDivideMode));
772 }
773
ProcShowPhyCilIntErrCnt(SysProcEntryTag * s,struct MipiCsiCntlr * cntlr)774 static void ProcShowPhyCilIntErrCnt(SysProcEntryTag *s, struct MipiCsiCntlr *cntlr)
775 {
776 int32_t ret;
777 PhyErrIntCnt tag;
778 int phyId;
779
780 SysSeqPrintf(s, "\nPHY CIL ERR INT INFO\n");
781 SysSeqPrintf(s, "%8s%11s%10s%12s%12s%12s%12s%9s%8s%10s%10s%10s%10s\n",
782 "PhyId", "Clk2TmOut", "ClkTmOut", "Lane0TmOut", "Lane1TmOut", "Lane2TmOut", "Lane3TmOut",
783 "Clk2Esc", "ClkEsc", "Lane0Esc", "Lane1Esc", "Lane2Esc", "Lane3Esc");
784
785 for (phyId = 0; phyId < MIPI_RX_MAX_PHY_NUM; phyId++) {
786 ret = MipiCsiDebugGetPhyErrIntCnt(cntlr, phyId, &tag);
787 if (ret != HDF_SUCCESS) {
788 HDF_LOGE("%s: [MipiCsiDebugGetPhyErrIntCnt] failed.", __func__);
789 return;
790 }
791
792 SysSeqPrintf(s, "%8d%11d%10d%12d%12d%12d%12d%9d%8d%10d%10d%10d%10d\n",
793 phyId,
794 tag.clk1FsmTimeoutErrCnt,
795 tag.clk0FsmTimeoutErrCnt,
796 tag.d0FsmTimeoutErrCnt,
797 tag.d1FsmTimeoutErrCnt,
798 tag.d2FsmTimeoutErrCnt,
799 tag.d3FsmTimeoutErrCnt,
800 tag.clk1FsmEscapeErrCnt,
801 tag.clk0FsmEscapeErrCnt,
802 tag.d0FsmEscapeErrCnt,
803 tag.d1FsmEscapeErrCnt,
804 tag.d2FsmEscapeErrCnt,
805 tag.d3FsmEscapeErrCnt);
806 }
807 }
808
ProcShowMipirxCrcErr(SysProcEntryTag * s,struct MipiCsiCntlr * cntlr,const uint8_t devnoArray[],int mipiCnt)809 static void ProcShowMipirxCrcErr(SysProcEntryTag *s, struct MipiCsiCntlr *cntlr,
810 const uint8_t devnoArray[], int mipiCnt)
811 {
812 int32_t ret;
813 MipiErrIntCnt tag;
814 int devnoIdx;
815 uint8_t devno;
816
817 SysSeqPrintf(s, "\nMIPI ERROR INT INFO 1\n");
818 SysSeqPrintf(s, "%8s%6s%8s%8s%8s%8s%14s%14s%14s%14s\n",
819 "Devno", "Ecc2", "Vc0CRC", "Vc1CRC", "Vc2CRC", "Vc3CRC",
820 "Vc0EccCorrct", "Vc1EccCorrct", "Vc2EccCorrct", "Vc3EccCorrct");
821
822 for (devnoIdx = 0; devnoIdx < mipiCnt; devnoIdx++) {
823 devno = devnoArray[devnoIdx];
824 ret = MipiCsiDebugGetMipiErrInt(cntlr, devno, &tag);
825 if (ret != HDF_SUCCESS) {
826 HDF_LOGE("%s: [MipiCsiDebugGetMipiErrInt] failed.", __func__);
827 return;
828 }
829
830 SysSeqPrintf(s, "%8d%6d%8d%8d%8d%8d%14d%14d%14d%14d\n",
831 devno,
832 tag.errEccDoubleCnt,
833 tag.vc0ErrCrcCnt,
834 tag.vc1ErrCrcCnt,
835 tag.vc2ErrCrcCnt,
836 tag.vc3ErrCrcCnt,
837 tag.vc0ErrEccCorrectedCnt,
838 tag.vc1ErrEccCorrectedCnt,
839 tag.vc2ErrEccCorrectedCnt,
840 tag.vc3ErrEccCorrectedCnt);
841 }
842 }
843
ProcShowMipirxVcErr(SysProcEntryTag * s,struct MipiCsiCntlr * cntlr,const uint8_t devnoArray[],int mipiCnt)844 static void ProcShowMipirxVcErr(SysProcEntryTag *s, struct MipiCsiCntlr *cntlr,
845 const uint8_t devnoArray[], int mipiCnt)
846 {
847 int32_t ret;
848 MipiErrIntCnt tag;
849 int devnoIdx;
850 uint8_t devno;
851
852 SysSeqPrintf(s, "\nMIPI ERROR INT INFO 2\n");
853 SysSeqPrintf(s, "%8s%7s%7s%7s%7s%11s%11s%11s%11s\n",
854 "Devno", "Vc0Dt", "Vc1Dt", "Vc2Dt", "Vc3Dt",
855 "Vc0FrmCrc", "Vc1FrmCrc", "Vc2FrmCrc", "Vc3FrmCrc");
856
857 for (devnoIdx = 0; devnoIdx < mipiCnt; devnoIdx++) {
858 devno = devnoArray[devnoIdx];
859 ret = MipiCsiDebugGetMipiErrInt(cntlr, devno, &tag);
860 if (ret != HDF_SUCCESS) {
861 HDF_LOGE("%s: [MipiCsiDebugGetMipiErrInt] failed.", __func__);
862 return;
863 }
864 SysSeqPrintf(s, "%8d%7d%7d%7d%7d%11d%11d%11d%11d\n",
865 devno,
866 tag.errIdVc0Cnt,
867 tag.errIdVc1Cnt,
868 tag.errIdVc2Cnt,
869 tag.errIdVc3Cnt,
870 tag.errFrameDataVc0Cnt,
871 tag.errFrameDataVc1Cnt,
872 tag.errFrameDataVc2Cnt,
873 tag.errFrameDataVc3Cnt);
874 }
875 SysSeqPrintf(s, "\nMIPI ERROR INT INFO 3\n");
876 SysSeqPrintf(s, "%8s%11s%11s%11s%11s%12s%12s%12s%12s\n",
877 "Devno", "Vc0FrmSeq", "Vc1FrmSeq", "Vc2FrmSeq", "Vc3FrmSeq",
878 "Vc0BndryMt", "Vc1BndryMt", "Vc2BndryMt", "Vc3BndryMt");
879 for (devnoIdx = 0; devnoIdx < mipiCnt; devnoIdx++) {
880 devno = devnoArray[devnoIdx];
881 ret = MipiCsiDebugGetMipiErrInt(cntlr, devno, &tag);
882 if (ret != HDF_SUCCESS) {
883 HDF_LOGE("%s: [MipiCsiDebugGetMipiErrInt] failed.", __func__);
884 return;
885 }
886 SysSeqPrintf(s, "%8d%11d%11d%11d%11d%12d%12d%12d%12d\n",
887 devno,
888 tag.errFSeqVc0Cnt,
889 tag.errFSeqVc1Cnt,
890 tag.errFSeqVc2Cnt,
891 tag.errFSeqVc3Cnt,
892 tag.errFBndryMatchVc0Cnt,
893 tag.errFBndryMatchVc1Cnt,
894 tag.errFBndryMatchVc2Cnt,
895 tag.errFBndryMatchVc3Cnt);
896 }
897 }
898
ProcShowMipirxFifoErr(SysProcEntryTag * s,struct MipiCsiCntlr * cntlr,const uint8_t devnoArray[],int mipiCnt)899 static void ProcShowMipirxFifoErr(SysProcEntryTag *s, struct MipiCsiCntlr *cntlr,
900 const uint8_t devnoArray[], int mipiCnt)
901 {
902 int32_t ret;
903 MipiErrIntCnt tag;
904 int devnoIdx;
905 uint8_t devno;
906
907 SysSeqPrintf(s, "\nMIPI ERROR INT INFO 4\n");
908 SysSeqPrintf(s, "%8s%15s%14s%14s%15s\n",
909 "Devno", "DataFifoRdErr", "CmdFifoRdErr", "CmdFifoWrErr", "DataFifoWrErr");
910
911 for (devnoIdx = 0; devnoIdx < mipiCnt; devnoIdx++) {
912 devno = devnoArray[devnoIdx];
913 ret = MipiCsiDebugGetMipiErrInt(cntlr, devno, &tag);
914 if (ret != HDF_SUCCESS) {
915 HDF_LOGE("%s: [MipiCsiDebugGetMipiErrInt] failed.", __func__);
916 return;
917 }
918
919 SysSeqPrintf(s, "%8d%15d%14d%14d%15d\n",
920 devno,
921 tag.dataFifoRderrCnt,
922 tag.cmdFifoRderrCnt,
923 tag.dataFifoWrerrCnt,
924 tag.cmdFifoWrerrCnt);
925 }
926 }
927
ProcShowMipiIntErr(SysProcEntryTag * s,struct MipiCsiCntlr * cntlr,uint8_t devnoArray[],int mipiCnt)928 static void ProcShowMipiIntErr(SysProcEntryTag *s, struct MipiCsiCntlr *cntlr, uint8_t devnoArray[], int mipiCnt)
929 {
930 ProcShowMipirxCrcErr(s, cntlr, devnoArray, mipiCnt);
931 ProcShowMipirxVcErr(s, cntlr, devnoArray, mipiCnt);
932 ProcShowMipirxFifoErr(s, cntlr, devnoArray, mipiCnt);
933 }
934
ProcShowLvdsIntErr(SysProcEntryTag * s,struct MipiCsiCntlr * cntlr,const uint8_t devnoArray[],int lvdsCnt)935 static void ProcShowLvdsIntErr(SysProcEntryTag *s, struct MipiCsiCntlr *cntlr,
936 const uint8_t devnoArray[], int lvdsCnt)
937 {
938 int32_t ret;
939 LvdsErrIntCnt tag;
940 uint8_t devno;
941 int devnoIdx;
942
943 SysSeqPrintf(s, "\nLVDS ERROR INT INFO\n");
944 SysSeqPrintf(s, "%8s%10s%10s%8s%9s%12s%12s\n",
945 "Devno", "CmdRdErr", "CmdWrErr", "PopErr", "StatErr", "Link0WrErr", "Link0RdErr");
946
947 for (devnoIdx = 0; devnoIdx < lvdsCnt; devnoIdx++) {
948 devno = devnoArray[devnoIdx];
949 ret = MipiCsiDebugGetLvdsErrIntCnt(cntlr, devno, &tag);
950 if (ret != HDF_SUCCESS) {
951 HDF_LOGE("%s: [MipiCsiDebugGetLvdsErrIntCnt] failed.", __func__);
952 return;
953 }
954
955 SysSeqPrintf(s, "%8d%10d%10d%8d%9d%12d%12d\n",
956 devno,
957 tag.cmdRdErrCnt,
958 tag.cmdWrErrCnt,
959 tag.popErrCnt,
960 tag.lvdsStateErrCnt,
961 tag.link0RdErrCnt,
962 tag.link0WrErrCnt);
963 }
964 }
965
ProcShowAlignIntErr(SysProcEntryTag * s,struct MipiCsiCntlr * cntlr)966 static void ProcShowAlignIntErr(SysProcEntryTag *s, struct MipiCsiCntlr *cntlr)
967 {
968 int32_t ret;
969 AlignErrIntCnt tag;
970 uint8_t devno;
971
972 SysSeqPrintf(s, "\nALIGN ERROR INT INFO\n");
973 for (devno = 0; devno < MIPI_RX_MAX_DEV_NUM; devno++) {
974 ret = MipiCsiDebugGetAlignErrIntCnt(cntlr, devno, &tag);
975 if (ret != HDF_SUCCESS) {
976 HDF_LOGE("%s: [MipiCsiDebugGetAlignErrIntCnt] failed.", __func__);
977 continue;
978 }
979 SysSeqPrintf(s, "%8s%14s%10s%10s%10s%10s\n",
980 "Devno", "FIFO_FullErr", "Lane0Err", "Lane1Err", "Lane2Err", "Lane3Err");
981 SysSeqPrintf(s, "%8d%14d%10d%10d%10d%10d\n",
982 devno,
983 tag.fifoFullErrCnt,
984 tag.lane0AlignErrCnt,
985 tag.lane1AlignErrCnt,
986 tag.lane2AlignErrCnt,
987 tag.lane3AlignErrCnt);
988 }
989 }
990
MipiLvdsProcShow(int mipiCnt,int lvdsCnt,uint8_t devnoMipi[MIPI_RX_MAX_DEV_NUM],uint8_t devnoLvds[MIPI_RX_MAX_DEV_NUM],SysProcEntryTag * s)991 static void MipiLvdsProcShow(int mipiCnt, int lvdsCnt, uint8_t devnoMipi[MIPI_RX_MAX_DEV_NUM],
992 uint8_t devnoLvds[MIPI_RX_MAX_DEV_NUM], SysProcEntryTag *s)
993 {
994 struct MipiCsiCntlr *cntlr = GetCntlr(s);
995 if (cntlr == NULL) {
996 HDF_LOGE("%s: cntlr is NULL.", __func__);
997 return;
998 }
999
1000 if (mipiCnt > 0 || lvdsCnt > 0) {
1001 ProcShowMipiHsMode(s, cntlr);
1002 ProcShowMipiDevice(s, cntlr);
1003 ProcShowMipiLane(s, cntlr);
1004 ProcShowMipiPhyData(s, cntlr);
1005 }
1006
1007 if (mipiCnt > 0) {
1008 ProcShowMipiDetectInfo(s, cntlr, devnoMipi, mipiCnt);
1009 }
1010
1011 if (lvdsCnt > 0) {
1012 ProcShowLvdsDetectInfo(s, cntlr, devnoLvds, lvdsCnt);
1013 ProcShowLvdsLaneDetectInfo(s, cntlr, devnoLvds, lvdsCnt);
1014 }
1015
1016 if (mipiCnt > 0 || lvdsCnt > 0) {
1017 ProcShowPhyCilIntErrCnt(s, cntlr);
1018 }
1019
1020 if (mipiCnt > 0) {
1021 ProcShowMipiIntErr(s, cntlr, devnoMipi, mipiCnt);
1022 }
1023
1024 if (lvdsCnt > 0) {
1025 ProcShowLvdsIntErr(s, cntlr, devnoLvds, lvdsCnt);
1026 }
1027
1028 if (mipiCnt > 0 || lvdsCnt > 0) {
1029 ProcShowAlignIntErr(s, cntlr);
1030 }
1031 }
1032
GetMipiOrLvdsDeviceCount(SysProcEntryTag * s,int * pmipiCnt,int * plvdsCnt,uint8_t devnoMipi[],uint8_t devnoLvds[])1033 static int32_t GetMipiOrLvdsDeviceCount(SysProcEntryTag *s, int *pmipiCnt, int *plvdsCnt, uint8_t devnoMipi[],
1034 uint8_t devnoLvds[])
1035 {
1036 int32_t ret;
1037 uint8_t devno;
1038 int mipiCnt = 0;
1039 int lvdsCnt = 0;
1040 InputMode inputMode;
1041 MipiDevCtx tag;
1042 struct MipiCsiCntlr *cntlr = NULL;
1043
1044 if ((pmipiCnt == NULL) || (plvdsCnt == NULL) || (devnoMipi == NULL) || (devnoLvds == NULL)) {
1045 HDF_LOGE("%s: pmipiCnt, plvdsCnt and other parameters are invalid.", __func__);
1046 return HDF_ERR_INVALID_PARAM;
1047 }
1048 cntlr = GetCntlr(s);
1049 if (cntlr == NULL) {
1050 HDF_LOGE("%s: cntlr is NULL.", __func__);
1051 return HDF_ERR_INVALID_OBJECT;
1052 }
1053 ret = MipiCsiDebugGetMipiDevCtx(cntlr, &tag);
1054 if (ret != HDF_SUCCESS) {
1055 HDF_LOGE("%s: [MipiCsiDebugGetMipiDevCtx] failed.", __func__);
1056 return ret;
1057 }
1058
1059 for (devno = 0; devno < MIPI_RX_MAX_DEV_NUM; devno++) {
1060 if (!tag.devCfged[devno]) {
1061 continue;
1062 }
1063
1064 inputMode = tag.comboDevAttr[devno].inputMode;
1065 if (inputMode == INPUT_MODE_MIPI) {
1066 devnoMipi[mipiCnt] = devno;
1067 mipiCnt++;
1068 } else if ((inputMode == INPUT_MODE_LVDS) || (inputMode == INPUT_MODE_SUBLVDS) ||
1069 (inputMode == INPUT_MODE_HISPI)) {
1070 devnoLvds[lvdsCnt] = devno;
1071 lvdsCnt++;
1072 }
1073 }
1074 *pmipiCnt = mipiCnt;
1075 *plvdsCnt = lvdsCnt;
1076
1077 return ret;
1078 }
1079
MipiProcShow(SysProcEntryTag * s)1080 static void MipiProcShow(SysProcEntryTag *s)
1081 {
1082 int32_t ret;
1083 int mipiCnt;
1084 int lvdsCnt;
1085 uint8_t devnoMipi[MIPI_RX_MAX_DEV_NUM] = {0};
1086 uint8_t devnoLvds[MIPI_RX_MAX_DEV_NUM] = {0};
1087
1088 ret = GetMipiOrLvdsDeviceCount(s, &mipiCnt, &lvdsCnt, devnoMipi, devnoLvds);
1089 if (ret != HDF_SUCCESS) {
1090 HDF_LOGE("%s: [GetMipiOrLvdsDeviceCount] failed.", __func__);
1091 return;
1092 }
1093 MipiLvdsProcShow(mipiCnt, lvdsCnt, devnoMipi, devnoLvds, s);
1094 }
1095
MipiRxProcShow(SysProcEntryTag * s,void * v)1096 static int MipiRxProcShow(SysProcEntryTag *s, void *v)
1097 {
1098 SysSeqPrintf(s, "\nModule: [MIPI_RX], Build Time["__DATE__", "__TIME__"]\n");
1099 MipiProcShow(s);
1100 HDF_LOGI("%s: v %p", __func__, v);
1101 HDF_LOGI("%s: success.", __func__);
1102 return HDF_SUCCESS;
1103 }
1104
MipiCsiDevProcOpen(struct inode * inode,struct file * file)1105 static int MipiCsiDevProcOpen(struct inode *inode, struct file *file)
1106 {
1107 (void)inode;
1108 HDF_LOGI("%s: enter.", __func__);
1109 return single_open(file, MipiRxProcShow, NULL);
1110 }
1111
1112 // ProcFileOperations and file_operations are used in different os.
1113 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
1114 static const struct proc_ops g_procMipiCsiDevOps = {
1115 .proc_open = MipiCsiDevProcOpen,
1116 .proc_read = seq_read,
1117 };
1118 #else
1119 static const struct file_operations g_procMipiCsiDevOps = {
1120 .open = MipiCsiDevProcOpen,
1121 .read = seq_read,
1122 };
1123 #endif
1124 #endif
1125
MipiRxInit(void)1126 static int MipiRxInit(void)
1127 {
1128 OsalMutexInit(&g_vfsPara.lock);
1129
1130 return HDF_SUCCESS;
1131 }
1132
MipiRxExit(void)1133 static void MipiRxExit(void)
1134 {
1135 OsalMutexDestroy(&g_vfsPara.lock);
1136 }
1137
MipiRxOpen(struct inode * inode,struct file * filep)1138 static int MipiRxOpen(struct inode *inode, struct file *filep)
1139 {
1140 (void)inode;
1141 (void)filep;
1142
1143 g_vfsPara.cntlr = MipiCsiCntlrGet(0);
1144 HDF_LOGI("%s: success.", __func__);
1145
1146 return HDF_SUCCESS;
1147 }
1148
MipiRxRelease(struct inode * inode,struct file * filep)1149 static int MipiRxRelease(struct inode *inode, struct file *filep)
1150 {
1151 (void)inode;
1152 (void)filep;
1153
1154 if (g_vfsPara.cntlr != NULL) {
1155 MipiCsiCntlrPut(g_vfsPara.cntlr);
1156 }
1157 HDF_LOGI("%s: success.", __func__);
1158
1159 return HDF_SUCCESS;
1160 }
1161
1162 // file_operations_vfs and file_operations are used in different os.
1163 static const struct file_operations g_mipiRxFops = {
1164 .open = MipiRxOpen,
1165 .release = MipiRxRelease,
1166 .unlocked_ioctl = MipiRxIoctl,
1167 #ifdef CONFIG_COMPAT
1168 .compat_ioctl = MipiRxCompatIoctl,
1169 #endif
1170 };
1171
MipiCsiDevModuleInit(uint8_t id)1172 int MipiCsiDevModuleInit(uint8_t id)
1173 {
1174 int32_t ret;
1175
1176 /* 0660 : node mode */
1177 ret = RegisterDevice(MIPI_RX_DEV_NAME, id, 0660, (struct file_operations *)&g_mipiRxFops);
1178 if (ret != HDF_SUCCESS) {
1179 HDF_LOGE("%s: [RegisterDevice] fail: %d.", __func__, ret);
1180 return ret;
1181 }
1182 #ifdef CONFIG_HI_PROC_SHOW_SUPPORT
1183 ret = ProcRegister(MIPI_RX_PROC_NAME, id, 0440, &g_procMipiCsiDevOps); /* 0440 : proc file mode */
1184 if (ret != HDF_SUCCESS) {
1185 UnregisterDevice(id);
1186 HDF_LOGE("%s: [ProcRegister] fail: %d.", __func__, ret);
1187 return ret;
1188 }
1189 #endif
1190
1191 ret = MipiRxInit();
1192 if (ret != HDF_SUCCESS) {
1193 UnregisterDevice(id);
1194 #ifdef CONFIG_HI_PROC_SHOW_SUPPORT
1195 ProcUnregister(MIPI_RX_PROC_NAME, id);
1196 #endif
1197 HDF_LOGE("%s: [MipiRxInit] failed.", __func__);
1198 return ret;
1199 }
1200
1201 HDF_LOGI("%s: success!", __func__);
1202 return ret;
1203 }
1204
MipiCsiDevModuleExit(uint8_t id)1205 void MipiCsiDevModuleExit(uint8_t id)
1206 {
1207 MipiRxExit();
1208 #ifdef CONFIG_HI_PROC_SHOW_SUPPORT
1209 ProcUnregister(MIPI_RX_PROC_NAME, id);
1210 #endif
1211 UnregisterDevice(id);
1212
1213 HDF_LOGI("%s: success!", __func__);
1214 }
1215
1216 #ifdef __cplusplus
1217 #if __cplusplus
1218 }
1219
1220 #endif
1221 #endif /* End of #ifdef __cplusplus */
1222