1+ /* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
2+ *
3+ * Redistribution and use in source and binary forms, with or without
4+ * modification, are permitted provided that the following conditions are met:
5+ * 1. Redistributions of source code must retain the above copyright
6+ * notice, this list of conditions and the following disclaimer.
7+ * 2. Redistributions in binary form must reproduce the above copyright
8+ * notice, this list of conditions and the following disclaimer in the
9+ * documentation and/or other materials provided with the distribution.
10+ *
11+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
12+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
13+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
17+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+ */
25+
26+ /*
27+ * Copyright (c) 2006-2025 RT-Thread Development Team
28+ *
29+ * SPDX-License-Identifier: Apache-2.0
30+ */
31+
32+ #include <rtthread.h>
33+ #include <rthw.h>
34+
35+ #if defined(RT_USING_POSIX_DEVIO )
36+ #include <dfs_posix.h>
37+ #include <poll.h>
38+ #include <termios.h>
39+ #endif
40+
41+ #define AI2D_LOG_ENABLE
42+ struct ai_2d_dev_handle {
43+ rt_wqueue_t * wait ;
44+ };
45+
46+
47+ #ifdef AI2D_LOG_ENABLE
48+ #define ai_2d_log (s ...) rt_kprintf(s)
49+ #else
50+ static int ai_2d_log (const char * fmt , ...)
51+ {
52+ return 0 ;
53+ }
54+ #endif
55+
56+ #define ai_2d_info (s ...) do { \
57+ ai_2d_log("<ai_2d> "); \
58+ ai_2d_log(s); \
59+ ai_2d_log("\r\n"); \
60+ } while (0)
61+
62+ #define ai_2d_err (s ...) do { \
63+ ai_2d_log("<err>[%s:%d] ", __func__, __LINE__); \
64+ ai_2d_log(s); \
65+ ai_2d_log("\r\n"); \
66+ } while (0)
67+
68+ static struct rt_device g_ai_2d_device = {0 };
69+ static struct rt_event g_ai_2d_event = {0 };
70+ extern void * gnne_base_addr ;
71+
72+ static int ai_2d_device_open (struct dfs_file * file )
73+ {
74+ struct ai_2d_dev_handle * handle ;
75+ rt_device_t device ;
76+
77+ handle = rt_malloc (sizeof (struct ai_2d_dev_handle ));
78+ if (handle == RT_NULL ) {
79+ ai_2d_err ("malloc failed\n" );
80+ return -1 ;
81+ }
82+ device = (rt_device_t )file -> vnode -> data ;
83+ handle -> wait = & device -> wait_queue ;
84+ file -> data = (void * )handle ;
85+ return RT_EOK ;
86+ }
87+
88+ static int ai_2d_device_close (struct dfs_file * file )
89+ {
90+ struct ai_2d_dev_handle * handle ;
91+
92+ handle = (struct ai_2d_dev_handle * )file -> data ;
93+ if (handle == RT_NULL ) {
94+ ai_2d_err ("try to close a invalid handle" );
95+ return - RT_EINVAL ;
96+ }
97+ rt_free (handle );
98+ file -> data = RT_NULL ;
99+ return RT_EOK ;
100+ }
101+
102+ static int ai_2d_device_ioctl (struct dfs_file * file , int cmd , void * args )
103+ {
104+ return 0 ;
105+ }
106+
107+ int ai_2d_device_poll (struct dfs_file * file , struct rt_pollreq * req )
108+ {
109+ struct ai_2d_dev_handle * handle ;
110+ unsigned int flags ;
111+ handle = (struct ai_2d_dev_handle * )file -> data ;
112+ if (!handle ) {
113+ ai_2d_err ("ai_2d_dev_handle NULL!" );
114+ return - EINVAL ;
115+ }
116+ rt_event_recv (& g_ai_2d_event , 0x01 , RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR , RT_WAITING_FOREVER , NULL );
117+ rt_poll_add (handle -> wait , req );
118+ return POLLIN ;
119+ }
120+
121+ static const struct dfs_file_ops ai_2d_input_fops = {
122+ .open = ai_2d_device_open ,
123+ .close = ai_2d_device_close ,
124+ .ioctl = ai_2d_device_ioctl ,
125+ .poll = ai_2d_device_poll ,
126+ };
127+
128+ #define IRQN_AI2D_INTERRUPT (16 + 175)
129+ static void irq_callback (int irq , void * data )
130+ {
131+ rt_wqueue_t * wait = (rt_wqueue_t * )data ;
132+ volatile rt_uint32_t * write_addr = (rt_uint32_t * )((char * )gnne_base_addr + 0xca0 );
133+ if (gnne_base_addr == RT_NULL ) {
134+ ai_2d_err ("ai2d interrupts while the hardware is not yet initialized\n" );
135+ }
136+ write_addr [0 ] = 1 ;
137+ write_addr [1 ] = 0 ;
138+ write_addr [2 ] = 0 ;
139+ write_addr [3 ] = 0 ;
140+ rt_wqueue_wakeup (wait , (void * )POLLIN );
141+ rt_event_send (& g_ai_2d_event , 0x1 );
142+ }
143+
144+ int ai_2d_device_init (void )
145+ {
146+ int ret = 0 ;
147+ rt_device_t ai_2d_device = & g_ai_2d_device ;
148+
149+ ret = rt_event_init (& g_ai_2d_event , "ai_2d_event" , RT_IPC_FLAG_PRIO );
150+ if (ret ) {
151+ ai_2d_err ("event init failed\n" );
152+ return - ENOMEM ;
153+ }
154+
155+ ret = rt_device_register (ai_2d_device , "ai_2d_device" , RT_DEVICE_FLAG_RDWR );
156+ if (ret ) {
157+ ai_2d_err ("ai_2d_device register fail\n" );
158+ return ret ;
159+ }
160+
161+ rt_wqueue_init (& ai_2d_device -> wait_queue );
162+ rt_hw_interrupt_install (IRQN_AI2D_INTERRUPT , irq_callback , & ai_2d_device -> wait_queue , "ai_2d_irq" );
163+ rt_hw_interrupt_umask (IRQN_AI2D_INTERRUPT );
164+
165+ ai_2d_device -> fops = & ai_2d_input_fops ;
166+
167+ #ifndef RT_FASTBOOT
168+ if (!ret )
169+ ai_2d_info ("%s OK\n" , __func__ );
170+ #endif
171+ return ret ;
172+ }
0 commit comments