• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * mipi_tx_dev.c
3  *
4  * create vfs node for mipi
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_tx_dev.h"
20 #include <asm/io.h>
21 #include <asm/uaccess.h>
22 #include <linux/cdev.h>
23 #include <linux/device.h>
24 #include <linux/fs.h>
25 #include <linux/init.h>
26 #include <linux/kdev_t.h>
27 #include <linux/miscdevice.h>
28 #include <linux/module.h>
29 #include <linux/proc_fs.h>
30 #include <linux/semaphore.h>
31 #include <linux/seq_file.h>
32 #include <linux/version.h>
33 #include "hdf_base.h"
34 #include "hdf_log.h"
35 #include "mipi_dsi_core.h"
36 #include "mipi_tx_reg.h"
37 #include "osal_io.h"
38 #include "osal_mem.h"
39 #include "osal_uaccess.h"
40 #include "securec.h"
41 
42 #ifdef __cplusplus
43 #if __cplusplus
44 extern "C"{
45 #endif
46 #endif /* End of #ifdef __cplusplus */
47 
48 /****************************************************************************
49  * macro definition                                                         *
50  ****************************************************************************/
51 #define HDF_LOG_TAG                mipi_tx_dev
52 #define MIPI_TX_DEV_NAME           "hi_mipi_tx"
53 #define MIPI_TX_PROC_NAME          "mipi_tx"
54 #define NAME_LEN                   20
55 
56 struct MipiDsiVfsPara {
57     struct MipiDsiCntlr *cntlr;
58     struct miscdevice *miscdev;
59     struct semaphore sem;
60     void *priv;
61 };
62 
63 static struct MipiDsiVfsPara g_vfsPara[MAX_CNTLR_CNT];
64 static uint8_t g_curId = 0;
RegisterDevice(const char * name,uint8_t id,unsigned short mode,struct file_operations * ops)65 static int32_t RegisterDevice(const char *name, uint8_t id, unsigned short mode, struct file_operations *ops)
66 {
67     int32_t error;
68     struct miscdevice *dev = NULL;
69 
70     if ((name == NULL) || (ops == NULL) || (id >= MAX_CNTLR_CNT)) {
71         HDF_LOGE("%s: name, ops or id is error.", __func__);
72         return HDF_ERR_INVALID_PARAM;
73     }
74     dev = OsalMemCalloc(sizeof(struct miscdevice));
75     if (dev == NULL) {
76         HDF_LOGE("%s: [OsalMemCalloc] failed.", __func__);
77         return HDF_ERR_MALLOC_FAIL;
78     }
79     dev->fops = ops;
80     dev->name = OsalMemCalloc(NAME_LEN + 1);
81     if (dev->name == NULL) {
82         OsalMemFree(dev);
83         HDF_LOGE("%s: [OsalMemCalloc] failed.", __func__);
84         return HDF_ERR_MALLOC_FAIL;
85     }
86     if (id != 0) { /* 0 : id */
87         if (snprintf_s((char *)dev->name, NAME_LEN + 1, NAME_LEN, "%s%u", name, id) < 0) {
88             OsalMemFree((char *)dev->name);
89             OsalMemFree(dev);
90             HDF_LOGE("%s: [snprintf_s] failed.", __func__);
91             return HDF_FAILURE;
92         }
93     } else {
94         if (memcpy_s((char *)dev->name, NAME_LEN, name, strlen(name)) != EOK) {
95             OsalMemFree((char *)dev->name);
96             OsalMemFree(dev);
97             HDF_LOGE("%s: [memcpy_s] failed.", __func__);
98             return HDF_ERR_IO;
99         }
100     }
101     ops->owner = THIS_MODULE;
102     dev->minor = MISC_DYNAMIC_MINOR;
103     dev->mode = mode;
104     error = misc_register(dev);
105     if (error < 0) {
106         printk("%s: id %u cannot register miscdev on minor=%d (err=%d)",
107             __func__, id, MISC_DYNAMIC_MINOR, error);
108         OsalMemFree((char *)dev->name);
109         OsalMemFree(dev);
110         return error;
111     }
112 
113     g_vfsPara[id].miscdev = dev;
114     g_curId = id;
115     printk("mipi_dsi:create inode ok %s %d", dev->name, dev->minor);
116     HDF_LOGI("%s: success.", __func__);
117 
118     return HDF_SUCCESS;
119 }
120 
121 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
ProcRegister(const char * name,uint8_t id,unsigned short mode,const struct proc_ops * ops)122 static int32_t ProcRegister(const char *name, uint8_t id, unsigned short mode, const struct proc_ops *ops)
123 #else
124 static int32_t ProcRegister(const char *name, uint8_t id, unsigned short mode, const struct file_operations *ops)
125 #endif
126 {
127     char procName[NAME_LEN + 1];
128     struct proc_dir_entry* entry = NULL;
129     int32_t ret;
130 
131     if ((name == NULL) || (ops == NULL) || (id >= MAX_CNTLR_CNT)) {
132         HDF_LOGE("%s: name, ops or id is error.", __func__);
133         return HDF_ERR_INVALID_PARAM;
134     }
135     if (memset_s(procName, NAME_LEN + 1, 0, NAME_LEN + 1) != EOK) {
136         HDF_LOGE("%s: [memcpy_s] failed.", __func__);
137         return HDF_ERR_IO;
138     }
139     if (id != 0) {
140         ret = snprintf_s(procName, NAME_LEN + 1, NAME_LEN, "%s%u", name, id);
141     } else {
142         ret = snprintf_s(procName, NAME_LEN + 1, NAME_LEN, "%s", name);
143     }
144     if (ret < 0) {
145         printk(KERN_ERR "%s: procName %s snprintf_s fail", __func__, procName);
146         return HDF_FAILURE;
147     }
148     entry = proc_create(procName, mode, NULL, ops);
149     if (entry == NULL) {
150         printk(KERN_ERR "%s: proc_create name %s fail", __func__, procName);
151         return HDF_FAILURE;
152     }
153     HDF_LOGI("%s: success.", __func__);
154     return HDF_SUCCESS;
155 }
156 
UnregisterDevice(uint8_t id)157 static void UnregisterDevice(uint8_t id)
158 {
159     struct miscdevice *dev = NULL;
160 
161     if (id >= MAX_CNTLR_CNT) {
162         HDF_LOGE("%s: id error.", __func__);
163         return;
164     }
165     dev = g_vfsPara[id].miscdev;
166     if (dev == NULL) {
167         HDF_LOGE("%s: dev is NULL.", __func__);
168         return;
169     }
170 
171     misc_deregister(dev);
172     OsalMemFree((void *)dev->name);
173     dev->name = NULL;
174     OsalMemFree(dev);
175     dev = NULL;
176     g_curId = 0;
177     HDF_LOGI("%s: success.", __func__);
178 }
179 
ProcUnregister(const char * name,uint8_t id)180 static void ProcUnregister(const char *name, uint8_t id)
181 {
182     char procName[NAME_LEN + 1];
183     int32_t ret;
184 
185     if (id >= MAX_CNTLR_CNT) {
186         HDF_LOGE("%s: id error.", __func__);
187         return;
188     }
189     if (memset_s(procName, NAME_LEN + 1, 0, NAME_LEN + 1) != EOK) {
190         HDF_LOGE("%s: [memcpy_s] failed.", __func__);
191         return;
192     }
193     if (id != 0) {
194         ret = snprintf_s(procName, NAME_LEN + 1, NAME_LEN, "%s%u", name, id);
195     } else {
196         ret = snprintf_s(procName, NAME_LEN + 1, NAME_LEN, "%s", name);
197     }
198     if (ret < 0) {
199         printk(KERN_ERR "%s: procName format fail", __func__);
200         return;
201     }
202     remove_proc_entry(procName, NULL);
203     HDF_LOGI("%s: success.", __func__);
204 }
205 
SemaInit(struct semaphore * sem,uint16_t val)206 static int32_t SemaInit(struct semaphore *sem, uint16_t val)
207 {
208     if (sem == NULL) {
209         HDF_LOGE("%s: sem is NULL", __func__);
210         return HDF_ERR_INVALID_OBJECT;
211     }
212     sema_init(sem, val);
213     return HDF_SUCCESS;
214 }
215 
SemaDestroy(struct semaphore * sem)216 static void SemaDestroy(struct semaphore *sem)
217 {
218     // don't support sema_destory(sem)!
219     (void)sem;
220 }
221 
SemaDownInterruptable(struct semaphore * sem)222 static int32_t SemaDownInterruptable(struct semaphore *sem)
223 {
224     return down_interruptible(sem);
225 }
226 
SemaUp(struct semaphore * sem)227 static void SemaUp(struct semaphore *sem)
228 {
229     up(sem);
230 }
231 
GetId()232 static uint8_t GetId()
233 {
234     if (g_curId >= MAX_CNTLR_CNT) {
235         HDF_LOGE("%s: failed g_curId = %u.", __func__, g_curId);
236         return 0;
237     }
238 
239     HDF_LOGI("%s: success.", __func__);
240     return g_curId;
241 }
242 
GetIdFromFilep(struct file * filep)243 static uint8_t GetIdFromFilep(struct file *filep)
244 {
245     uint8_t id;
246     if (filep == NULL) {
247         HDF_LOGE("%s: filep is invalid.", __func__);
248         return 0;
249     }
250 
251     if (filep->private_data == NULL) {
252         HDF_LOGE("%s: private_data is NULL.", __func__);
253         return 0;
254     }
255 
256     id = (uint8_t)(filep->private_data);
257     if (id >= MAX_CNTLR_CNT) {
258         HDF_LOGE("%s: id error.", __func__);
259         return 0;
260     }
261 
262     return id;
263 }
264 
GetCntlrFromFilep(struct file * filep)265 static struct MipiDsiCntlr *GetCntlrFromFilep(struct file *filep)
266 {
267     uint8_t id;
268     if (filep == NULL) {
269         HDF_LOGE("%s: filep is invalid.", __func__);
270         return NULL;
271     }
272     id = GetId();
273 
274     return g_vfsPara[id].cntlr;
275 }
276 
GetSemaFromFilep(struct file * filep)277 static struct semaphore *GetSemaFromFilep(struct file *filep)
278 {
279     uint8_t id;
280     if (filep == NULL) {
281         HDF_LOGE("%s: filep is invalid.", __func__);
282         return NULL;
283     }
284     id = GetId();
285 
286     return &g_vfsPara[id].sem;
287 }
288 
GetCfgFromFilep(struct file * filep)289 static struct MipiCfg *GetCfgFromFilep(struct file *filep)
290 {
291     uint8_t id;
292     if (filep == NULL) {
293         HDF_LOGE("%s: filep is invalid.", __func__);
294         return NULL;
295     }
296     id = GetId();
297     if (g_vfsPara[id].cntlr == NULL) {
298         HDF_LOGE("%s: g_vfsPara[id].cntlr is NULL.", __func__);
299         return NULL;
300     }
301 
302     return &(g_vfsPara[id].cntlr->cfg);
303 }
304 
MipiDsiDevSetCfg(struct MipiDsiCntlr * cntlr,struct MipiCfg * arg)305 static int32_t MipiDsiDevSetCfg(struct MipiDsiCntlr *cntlr, struct MipiCfg *arg)
306 {
307     int32_t ret;
308     struct MipiCfg *temp = NULL;
309     uint32_t size;
310 
311     if (arg == NULL) {
312         HDF_LOGE("%s: arg is invalid.", __func__);
313         return HDF_ERR_INVALID_PARAM;
314     }
315 
316     if (cntlr == NULL) {
317         HDF_LOGE("%s: cntlr is NULL.", __func__);
318         return HDF_ERR_INVALID_PARAM;
319     }
320 
321     size = sizeof(struct MipiCfg);
322     temp = (struct MipiCfg *)OsalMemCalloc(size);
323     if (temp == NULL) {
324         HDF_LOGE("%s: OsalMemCalloc error.", __func__);
325         return HDF_ERR_MALLOC_FAIL;
326     }
327 
328     if (access_ok(
329 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0)
330         VERIFY_READ,
331 #endif
332         arg, size)) { /* user space */
333         if (CopyFromUser(temp, arg, size) != 0) {
334             OsalMemFree(temp);
335             temp = NULL;
336             HDF_LOGE("%s: [CopyFromUser] failed.", __func__);
337             return HDF_ERR_IO;
338         }
339     } else {
340         OsalMemFree(temp);
341         temp = NULL;
342         HDF_LOGE("%s: illegal user space address.", __func__);
343         return HDF_FAILURE;
344     }
345 
346     ret = MipiDsiCntlrSetCfg(cntlr, temp);
347     g_curId = cntlr->devNo;
348     OsalMemFree(temp);
349     HDF_LOGI("%s: success.", __func__);
350 
351     return ret;
352 }
353 
MipiDsiDevSetCmd(struct MipiDsiCntlr * cntlr,struct DsiCmdDesc * arg)354 int32_t MipiDsiDevSetCmd(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *arg)
355 {
356     int32_t ret;
357     struct DsiCmdDesc *temp = NULL;
358     uint32_t size;
359 
360     if (arg == NULL) {
361         HDF_LOGE("%s: arg is invalid.", __func__);
362         return HDF_ERR_INVALID_PARAM;
363     }
364 
365     if (cntlr == NULL) {
366         HDF_LOGE("%s: cntlr is NULL.", __func__);
367         return HDF_ERR_INVALID_PARAM;
368     }
369 
370     size = sizeof(struct DsiCmdDesc);
371     temp = (struct DsiCmdDesc *)OsalMemCalloc(size);
372     if (temp == NULL) {
373         HDF_LOGE("%s: [OsalMemCalloc] error.", __func__);
374         return HDF_ERR_MALLOC_FAIL;
375     }
376 
377     if (access_ok(
378 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0)
379         VERIFY_READ,
380 #endif
381         arg, size)) { /* user space */
382         if (CopyFromUser(temp, arg, size) != 0) {
383             OsalMemFree(temp);
384             temp = NULL;
385             HDF_LOGE("%s: [CopyFromUser] failed.", __func__);
386             return HDF_ERR_IO;
387         }
388     } else {
389         OsalMemFree(temp);
390         temp = NULL;
391         HDF_LOGE("%s: illegal user space address.", __func__);
392         return HDF_FAILURE;
393     }
394 
395     ret = MipiDsiCntlrTx(cntlr, temp);
396     OsalMemFree(temp);
397     HDF_LOGI("%s: success.", __func__);
398 
399     return ret;
400 }
401 
MipiDsiDevCmdCopyFromUser(GetDsiCmdDescTag * arg,GetDsiCmdDescTag * temp,uint32_t * size)402 int32_t MipiDsiDevCmdCopyFromUser(GetDsiCmdDescTag *arg, GetDsiCmdDescTag *temp, uint32_t *size)
403 {
404     if (access_ok(
405 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0)
406         VERIFY_READ,
407 #endif
408         arg, *size)) { /* user space */
409         if (CopyFromUser(temp, arg, *size) != 0) {
410             HDF_LOGE("%s: [CopyFromUser] failed.", __func__);
411             return HDF_ERR_IO;
412         }
413     } else {
414         HDF_LOGE("%s: illegal user space address.", __func__);
415         return HDF_FAILURE;
416     }
417     return HDF_SUCCESS;
418 }
419 
MipiDsiDevCmdCopyToUser(GetDsiCmdDescTag * arg,GetDsiCmdDescTag * temp,uint32_t * size)420 int32_t MipiDsiDevCmdCopyToUser(GetDsiCmdDescTag *arg, GetDsiCmdDescTag *temp, uint32_t *size)
421 {
422     if (access_ok(
423 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0)
424         VERIFY_WRITE,
425 #endif
426         arg, *size)) { /* user space */
427         if (CopyToUser(arg, temp, *size) != 0) {
428             HDF_LOGE("%s: [CopyToUser] failed.", __func__);
429             return HDF_ERR_IO;
430         }
431     } else {
432         HDF_LOGE("%s: illegal user space address.", __func__);
433         return HDF_FAILURE;
434     }
435     return HDF_SUCCESS;
436 }
437 
MipiDsiDevGetCmd(struct MipiDsiCntlr * cntlr,GetDsiCmdDescTag * arg)438 int32_t MipiDsiDevGetCmd(struct MipiDsiCntlr *cntlr, GetDsiCmdDescTag *arg)
439 {
440     int32_t ret;
441     GetDsiCmdDescTag *temp = NULL;
442     uint32_t size;
443 
444     if ((cntlr == NULL) || (arg == NULL)) {
445         HDF_LOGE("%s: cntlr or arg is NULL.", __func__);
446         return HDF_ERR_INVALID_PARAM;
447     }
448 
449     size = sizeof(GetDsiCmdDescTag);
450     temp = (GetDsiCmdDescTag *)OsalMemCalloc(size);
451     if (temp == NULL) {
452         HDF_LOGE("%s: [OsalMemCalloc] error.", __func__);
453         return HDF_ERR_MALLOC_FAIL;
454     }
455     if (MipiDsiDevCmdCopyFromUser(arg, temp, &size) != HDF_SUCCESS) {
456         goto fail0;
457     }
458     ret = MipiDsiCntlrRx(cntlr, &temp->readCmd, temp->readLen, temp->out);
459     if (ret != HDF_SUCCESS) {
460         HDF_LOGE("%s: [MipiDsiCntlrRx] failed.", __func__);
461         goto fail0;
462     }
463     if (MipiDsiDevCmdCopyToUser(arg, temp, &size) != HDF_SUCCESS) {
464         goto fail0;
465     }
466     OsalMemFree(temp);
467     temp = NULL;
468     HDF_LOGI("%s: success.", __func__);
469     return HDF_SUCCESS;
470 fail0:
471     OsalMemFree(temp);
472     temp = NULL;
473     return HDF_FAILURE;
474 }
475 
MipiDsiDevIoctl(struct file * filep,unsigned int cmd,unsigned long arg)476 static long MipiDsiDevIoctl(struct file *filep, unsigned int cmd, unsigned long arg)
477 {
478     int32_t ret = HDF_SUCCESS;
479     void *pArg = (void *)arg;
480     struct MipiDsiCntlr *cntlr = NULL;
481     struct semaphore *sem = NULL;
482 
483     if (filep == NULL || pArg == NULL) {
484         HDF_LOGE("%s: filep or pArg is NULL.", __func__);
485         return HDF_ERR_INVALID_OBJECT;
486     }
487     cntlr = GetCntlrFromFilep(filep);
488     if (cntlr == NULL) {
489         HDF_LOGE("%s: cntlr is NULL.", __func__);
490         return HDF_ERR_INVALID_OBJECT;
491     }
492 
493     sem = GetSemaFromFilep(filep);
494     if (sem == NULL) {
495         HDF_LOGE("%s: sem is NULL.", __func__);
496         return HDF_ERR_INVALID_OBJECT;
497     }
498 
499     (void)SemaDownInterruptable(sem);
500     switch (cmd) {
501         case HI_MIPI_TX_SET_DEV_CFG:
502             ret = MipiDsiDevSetCfg(cntlr, (struct MipiCfg *)pArg);
503             break;
504         case HI_MIPI_TX_SET_CMD:
505             ret = MipiDsiDevSetCmd(cntlr, (struct DsiCmdDesc *)pArg);
506             break;
507         case HI_MIPI_TX_GET_CMD:
508             ret = MipiDsiDevGetCmd(cntlr, (GetDsiCmdDescTag *)pArg);
509             break;
510         case HI_MIPI_TX_ENABLE:
511             MipiDsiCntlrSetHsMode(cntlr);
512             HDF_LOGI("%s: [MipiDsiCntlrSetHsMode] done.", __func__);
513             break;
514         case HI_MIPI_TX_DISABLE:
515             MipiDsiCntlrSetLpMode(cntlr);
516             HDF_LOGI("%s: [MipiDsiCntlrSetLpMode] done.", __func__);
517             break;
518         default:
519             HDF_LOGE("%s: [default] failed.", __func__);
520             ret = -1;
521             break;
522     }
523     SemaUp(sem);
524 
525     return ret;
526 }
527 
MipiDsiDevOpen(struct inode * inode,struct file * filep)528 static int MipiDsiDevOpen(struct inode *inode, struct file *filep)
529 {
530     uint8_t id;
531     (void)inode;
532     (void)filep;
533 
534     id = GetId();
535     g_vfsPara[id].cntlr = MipiDsiCntlrOpen(id);
536     HDF_LOGI("%s: success.", __func__);
537 
538     return 0;
539 }
540 
MipiDsiDevRelease(struct inode * inode,struct file * filep)541 static int MipiDsiDevRelease(struct inode *inode, struct file *filep)
542 {
543     uint8_t id;
544     (void)inode;
545     (void)filep;
546 
547     id = GetId();
548     if (g_vfsPara[id].cntlr != NULL) {
549         MipiDsiCntlrClose(g_vfsPara[id].cntlr);
550     }
551     HDF_LOGI("%s: success.", __func__);
552     return 0;
553 }
554 
MipiDsiDevProcDevShow(struct seq_file * s)555 static void MipiDsiDevProcDevShow(struct seq_file *s)
556 {
557     struct MipiCfg *cfg = NULL;
558     struct DsiTimingInfo *t = NULL;
559     uint8_t id;
560 
561     id = GetId();
562     if (g_vfsPara[id].cntlr == NULL) {
563         HDF_LOGE("%s: g_vfsPara[id].cntlr is NULL", __func__);
564         return;
565     }
566     cfg = &(g_vfsPara[id].cntlr->cfg);
567     t = &(cfg->timing);
568 
569     /* mipi tx device config */
570     seq_printf(s, "MIPI_Tx DEV CONFIG\n");
571     seq_printf(s, "%8s%15s%15s%15s%15s%15s\n",
572         "lane", "output_mode", "phy_data_rate", "pixel_clk(KHz)",
573         "video_mode", "output_fmt");
574     seq_printf(s, "%8d%15d%15d%15d%15d%15d\n",
575         cfg->lane,
576         cfg->mode,
577         cfg->phyDataRate,
578         cfg->pixelClk,
579         cfg->burstMode,
580         cfg->format);
581     seq_printf(s, "\r\n");
582     /* mipi tx device sync config */
583     seq_printf(s, "MIPI_Tx SYNC CONFIG\n");
584     seq_printf(s, "%14s%14s%14s%14s%14s%14s%14s%14s%14s\n",
585         "pkt_size", "hsa_pixels", "hbp_pixels", "hline_pixels", "vsa_lines", "vbp_lines",
586         "vfp_lines", "active_lines", "edpi_cmd_size");
587     seq_printf(s, "%14d%14d%14d%14d%14d%14d%14d%14d%14d\n",
588         t->xPixels,
589         t->hsaPixels,
590         t->hbpPixels,
591         t->hlinePixels,
592         t->vsaLines,
593         t->vbpLines,
594         t->vfpLines,
595         t->ylines,
596         t->edpiCmdSize);
597     seq_printf(s, "\r\n");
598     HDF_LOGI("%s: success.", __func__);
599 }
600 
MipiDsiDevProcShow(struct seq_file * m,void * v)601 static int MipiDsiDevProcShow(struct seq_file *m, void *v)
602 {
603     seq_printf(m, "\nModule: [MIPI_TX], Build Time["__DATE__", "__TIME__"]\n");
604     MipiDsiDevProcDevShow(m);
605     HDF_LOGI("%s: v %p", __func__, v);
606     HDF_LOGI("%s: success.", __func__);
607     return 0;
608 }
609 
MipiDsiDevProcOpen(struct inode * inode,struct file * file)610 static int MipiDsiDevProcOpen(struct inode *inode, struct file *file)
611 {
612     (void)inode;
613     HDF_LOGE("%s: enter.", __func__);
614     return single_open(file, MipiDsiDevProcShow, NULL);
615 }
616 
617 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
618 static struct proc_ops g_procMipiDsiDevOps = {
619     .proc_open = MipiDsiDevProcOpen,
620     .proc_read = seq_read,
621 };
622 #else
623 static struct file_operations g_procMipiDsiDevOps = {
624     .open = MipiDsiDevProcOpen,
625     .read = seq_read,
626 };
627 #endif
628 
629 static struct file_operations g_mipiTxfOps = {
630     .open = MipiDsiDevOpen,
631     .release = MipiDsiDevRelease,
632     .unlocked_ioctl = MipiDsiDevIoctl,
633 };
634 
MipiDsiDevModuleInit(uint8_t id)635 int32_t MipiDsiDevModuleInit(uint8_t id)
636 {
637     int32_t ret;
638 
639     /* 0660 : node mode */
640     ret = RegisterDevice(MIPI_TX_DEV_NAME, id, 0660, (struct file_operations *)&g_mipiTxfOps);
641     if (ret != HDF_SUCCESS) {
642         HDF_LOGE("%s: [RegisterDevice] fail: %d.", __func__, ret);
643         return ret;
644     }
645     ret = ProcRegister(MIPI_TX_PROC_NAME, id, 0440, &g_procMipiDsiDevOps); /* 0440 : proc file mode */
646     if (ret != HDF_SUCCESS) {
647         UnregisterDevice(id);
648         HDF_LOGE("%s: [ProcRegister] fail: %d.", __func__, ret);
649         return ret;
650     }
651 
652     ret = SemaInit(&g_vfsPara[id].sem, 1);
653     if (ret != HDF_SUCCESS) {
654         UnregisterDevice(id);
655         ProcUnregister(MIPI_TX_PROC_NAME, id);
656         HDF_LOGE("%s: [SemaInit] failed.", __func__);
657         return ret;
658     }
659     HDF_LOGI("%s: success!", __func__);
660     return ret;
661 }
662 
MipiDsiDevModuleExit(uint8_t id)663 void MipiDsiDevModuleExit(uint8_t id)
664 {
665     SemaDestroy(&g_vfsPara[id].sem);
666     UnregisterDevice(id);
667     ProcUnregister(MIPI_TX_PROC_NAME, id);
668 
669     HDF_LOGI("%s: success!", __func__);
670 }
671 
672 #ifdef __cplusplus
673 #if __cplusplus
674 }
675 #endif
676 #endif /* End of #ifdef __cplusplus */
677