• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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