• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 #include <linux/module.h>
20 #include <linux/version.h>
21 #include "securec.h"
22 #include "hi_log.h"
23 #include "hi_common.h"
24 #include "hi_error_mpi.h"
25 #include "drv_gpio.h"
26 #include "drv_gpio_ioctl.h"
27 
28 #ifndef __KERNEL__
29 #ifdef HI_MOD_GPIO
30 #undef HI_MOD_GPIO
31 #define HI_MOD_GPIO "gpio_user"
32 #endif
33 #endif
34 
35 #define GPIO_MAX_NUM 1
36 static osal_semaphore g_gpio_sem_intf;
37 
38 typedef struct {
39     hi_u32 cmd;
40     hi_u32 group;
41     hi_u32 bit;
42     hi_u32 bit_value;
43 } gpio_proc_data;
44 
gpio_proc_write_cmd_process(hi_u32 cmd,hi_u32 group,hi_u32 bit,hi_u32 bit_value)45 static hi_void gpio_proc_write_cmd_process(hi_u32 cmd, hi_u32 group, hi_u32 bit, hi_u32 bit_value)
46 {
47     hi_u32 ret = HI_SUCCESS;
48 
49     switch (cmd) {
50         case 0: { // u32cmd为0,获取当前io的输入输出状态
51             hi_u32 input = 0;
52 
53             ret = hi_drv_gpio_get_dir_bit(group * 8 + bit, &input); // 每组8个io口
54             if (ret != HI_SUCCESS) {
55                 HI_PRINT("read dir error , group is %d , bit is %d\n", group, bit);
56                 break;
57             }
58 
59             HI_PRINT("dir[%d][%d] = %s\n", group, bit, input ? "input" : "output");
60 
61             break;
62         }
63         case 1: { // u32cmd为1,设置io口输入输出状态
64             ret = hi_drv_gpio_set_dir_bit(group * 8 + bit, bit_value); // 每组8个io口
65             if (ret != HI_SUCCESS) {
66                 HI_PRINT("write dir error, group is %d , bit is %d\n", group, bit);
67                 break;
68             }
69 
70             HI_PRINT("dir[%d][%d] = %s\n", group, bit, bit_value ? "input" : "output");
71 
72             break;
73         }
74         case 2: { // u32cmd为2,读取io口数据
75             hi_u32 value = 0;
76 
77             ret = hi_drv_gpio_read_bit(group * 8 + bit, &value); // 每组8个io口
78             if (ret != HI_SUCCESS) {
79                 HI_PRINT("read value error, group is %d , bit is %d\n", group, bit);
80                 break;
81             }
82 
83             HI_PRINT("Value [%d][%d] = %s\n", group, bit, value ? "high" : "low");
84 
85             break;
86         }
87         case 3: { // u32cmd为3,对io口置位
88             ret = hi_drv_gpio_write_bit(group * 8 + bit, bit_value); // 每组8个io口
89             if (ret != HI_SUCCESS) {
90                 HI_PRINT("write value error, group is %d , bit is %d\n", group, bit);
91                 break;
92             }
93 
94             HI_PRINT("Value [%d][%d] = %s\n", group, bit, bit_value ? "high" : "low");
95             break;
96         }
97         default: {
98             return;
99         }
100     }
101 }
102 
gpio_proc_read(hi_void * seqfile,hi_void * private)103 static hi_s32 gpio_proc_read(hi_void *seqfile, hi_void *private)
104 {
105     return HI_SUCCESS;
106 }
107 
gpio_drv_proc_help(unsigned int argc,char (* argv)[PROC_CMD_SINGEL_LENGTH_MAX],hi_void * private)108 static hi_s32 gpio_drv_proc_help(unsigned int argc, char (*argv)[PROC_CMD_SINGEL_LENGTH_MAX], hi_void *private)
109 {
110     HI_PRINT("---------------------------------Hisilicon GPIO Debug--------------------------------\n");
111     HI_PRINT("echo command para1 para2         path          explanation\n");
112     HI_PRINT("echo rdir  [group][bit]       > /proc/msp/gpio Read gpio direction\n");
113     HI_PRINT("echo wdir  [group][bit] [0/1] > /proc/msp/gpio Write gpio direction,1:input 0:output\n");
114     HI_PRINT("echo read  [group][bit]       > /proc/msp/gpio Read gpio level\n");
115     HI_PRINT("echo write [group][bit] [0/1] > /proc/msp/gpio Write gpio output level\n");
116     HI_PRINT("-------------------------------------------------------------------------------------\n");
117     return HI_SUCCESS;
118 }
119 
gpio_drv_proc_rdir(unsigned int argc,char (* argv)[PROC_CMD_SINGEL_LENGTH_MAX],hi_void * private)120 static hi_s32 gpio_drv_proc_rdir(unsigned int argc, char (*argv)[PROC_CMD_SINGEL_LENGTH_MAX], hi_void *private)
121 {
122     gpio_proc_data proc_data = {0};
123 
124     if (argc < 3) { // num of str is 3
125         HI_PRINT("---------------------------------Hisilicon GPIO Debug--------------------------------\n");
126         HI_PRINT("echo command para1 para2         path          explanation\n");
127         HI_PRINT("echo rdir  [group][bit]       > /proc/msp/gpio Read gpio direction\n");
128         HI_PRINT("echo wdir  [group][bit] [0/1] > /proc/msp/gpio Write gpio direction,1:input 0:output\n");
129         HI_PRINT("echo read  [group][bit]       > /proc/msp/gpio Read gpio level\n");
130         HI_PRINT("echo write [group][bit] [0/1] > /proc/msp/gpio Write gpio output level\n");
131         HI_PRINT("-------------------------------------------------------------------------------------\n");
132         return HI_FAILURE;
133     }
134 
135     proc_data.group = osal_strtol(argv[1], NULL, 10); // 字符串转成10进制
136     proc_data.bit = osal_strtol(argv[2], NULL, 10); // 第2组数据转成10进制
137     proc_data.cmd = 0;
138     gpio_proc_write_cmd_process(proc_data.cmd, proc_data.group, proc_data.bit, proc_data.bit_value);
139     return HI_SUCCESS;
140 }
141 
gpio_drv_proc_wdir(unsigned int argc,char (* argv)[PROC_CMD_SINGEL_LENGTH_MAX],hi_void * private)142 static hi_s32 gpio_drv_proc_wdir(unsigned int argc, char (*argv)[PROC_CMD_SINGEL_LENGTH_MAX], hi_void *private)
143 {
144     gpio_proc_data proc_data = {0};
145 
146     if (argc < 4) { // num of  str is 4
147         HI_PRINT("---------------------------------Hisilicon GPIO Debug--------------------------------\n");
148         HI_PRINT("echo command para1 para2         path          explanation\n");
149         HI_PRINT("echo rdir  [group][bit]       > /proc/msp/gpio Read gpio direction\n");
150         HI_PRINT("echo wdir  [group][bit] [0/1] > /proc/msp/gpio Write gpio direction,1:input 0:output\n");
151         HI_PRINT("echo read  [group][bit]       > /proc/msp/gpio Read gpio level\n");
152         HI_PRINT("echo write [group][bit] [0/1] > /proc/msp/gpio Write gpio output level\n");
153         HI_PRINT("-------------------------------------------------------------------------------------\n");
154         return HI_FAILURE;
155     }
156 
157     proc_data.group = osal_strtol(argv[1], NULL, 10); // 字符串转成10进制
158     proc_data.bit = osal_strtol(argv[2], NULL, 10); // 第2组数据转成10进制
159     proc_data.bit_value = osal_strtol(argv[3], NULL, 10); // 第3组数据转成10进制
160     proc_data.cmd = 1; // 1 :  set dir bit
161 
162     if (proc_data.bit_value > 1) {
163         HI_PRINT("please set value is 0 or 1\n");
164         return HI_FAILURE;
165     }
166 
167     gpio_proc_write_cmd_process(proc_data.cmd, proc_data.group, proc_data.bit, proc_data.bit_value);
168     return HI_SUCCESS;
169 }
170 
gpio_drv_proc_read(unsigned int argc,char (* argv)[PROC_CMD_SINGEL_LENGTH_MAX],hi_void * private)171 static hi_s32 gpio_drv_proc_read(unsigned int argc, char (*argv)[PROC_CMD_SINGEL_LENGTH_MAX], hi_void *private)
172 {
173     gpio_proc_data proc_data = {0};
174 
175     if (argc < 3) { // num of  str is 3
176         HI_PRINT("---------------------------------Hisilicon GPIO Debug--------------------------------\n");
177         HI_PRINT("echo command para1 para2         path          explanation\n");
178         HI_PRINT("echo rdir  [group][bit]       > /proc/msp/gpio Read gpio direction\n");
179         HI_PRINT("echo wdir  [group][bit] [0/1] > /proc/msp/gpio Write gpio direction,1:input 0:output\n");
180         HI_PRINT("echo read  [group][bit]       > /proc/msp/gpio Read gpio level\n");
181         HI_PRINT("echo write [group][bit] [0/1] > /proc/msp/gpio Write gpio output level\n");
182         HI_PRINT("-------------------------------------------------------------------------------------\n");
183         return HI_FAILURE;
184     }
185     proc_data.group = osal_strtol(argv[1], NULL, 10); // 字符串转成10进制
186     proc_data.bit = osal_strtol(argv[2], NULL, 10); // 第2组数据转成10进制
187     proc_data.cmd = 2; // 2 :  read gpio bit
188 
189     gpio_proc_write_cmd_process(proc_data.cmd, proc_data.group, proc_data.bit, proc_data.bit_value);
190     return HI_SUCCESS;
191 }
192 
gpio_drv_proc_write(unsigned int argc,char (* argv)[PROC_CMD_SINGEL_LENGTH_MAX],hi_void * private)193 static hi_s32 gpio_drv_proc_write(unsigned int argc, char (*argv)[PROC_CMD_SINGEL_LENGTH_MAX], hi_void *private)
194 {
195     gpio_proc_data proc_data = {0};
196 
197     if (argc < 4) { // num of  str is 4
198         HI_PRINT("---------------------------------Hisilicon GPIO Debug--------------------------------\n");
199         HI_PRINT("echo command para1 para2         path          explanation\n");
200         HI_PRINT("echo rdir  [group][bit]       > /proc/msp/gpio Read gpio direction\n");
201         HI_PRINT("echo wdir  [group][bit] [0/1] > /proc/msp/gpio Write gpio direction,1:input 0:output\n");
202         HI_PRINT("echo read  [group][bit]       > /proc/msp/gpio Read gpio level\n");
203         HI_PRINT("echo write [group][bit] [0/1] > /proc/msp/gpio Write gpio output level\n");
204         HI_PRINT("-------------------------------------------------------------------------------------\n");
205         return HI_FAILURE;
206     }
207 
208     proc_data.group = osal_strtol(argv[1], NULL, 10); // 字符串转成10进制
209     proc_data.bit = osal_strtol(argv[2], NULL, 10); // 第2组数据转成10进制
210     proc_data.bit_value = osal_strtol(argv[3], NULL, 10); // 第3组数据转成10进制
211     proc_data.cmd = 3; // 3 :  write gpio bit
212 
213     if (proc_data.bit_value > 1) {
214         HI_PRINT("please set value is 0 or 1\n");
215         return HI_FAILURE;
216     }
217 
218     gpio_proc_write_cmd_process(proc_data.cmd, proc_data.group, proc_data.bit, proc_data.bit_value);
219     return HI_SUCCESS;
220 }
221 
222 static osal_proc_cmd g_gpio_proc_cmd[] = {
223     {"help", gpio_drv_proc_help},
224     {"rdir",  gpio_drv_proc_rdir},
225     {"wdir", gpio_drv_proc_wdir},
226     {"read", gpio_drv_proc_read},
227     {"write", gpio_drv_proc_write},
228 };
229 
230 typedef struct hi_gpio_state {
231     hi_handle gpio_handle[GPIO_MAX_NUM];
232 } gpio_state;
233 
234 static gpio_state g_gpio_state;
235 
gpio_drv_lowpower_enter(hi_void * private_data)236 static hi_s32 gpio_drv_lowpower_enter(hi_void *private_data)
237 {
238     HI_LOG_NOTICE("Gpio lowpower enter OK\n");
239     return HI_SUCCESS;
240 }
241 
gpio_drv_lowpower_exit(hi_void * private_data)242 static hi_s32 gpio_drv_lowpower_exit(hi_void *private_data)
243 {
244     HI_LOG_NOTICE("Gpio lowpower exit OK\n");
245     return HI_SUCCESS;
246 }
247 
gpio_suspend(hi_void * private_data)248 static HI_S32 gpio_suspend(hi_void *private_data)
249 {
250     HI_PRINT("GPIO suspend OK\n");
251     return 0;
252 }
253 
gpio_resume(hi_void * private_data)254 static HI_S32 gpio_resume(hi_void *private_data)
255 {
256     HI_PRINT("GPIO resume OK\n");
257     return 0;
258 }
259 
hi_gpio_ioctl_set_int_type(unsigned int cmd,hi_void * arg,hi_void * private_data)260 static hi_s32 hi_gpio_ioctl_set_int_type(unsigned int cmd, hi_void *arg, hi_void *private_data)
261 {
262     long ret;
263     gpio_data st_data = { 0, 0, GPIO_INTTYPE_BUTT };
264     errno_t err;
265 
266     if (arg == HI_NULL) {
267         HI_LOG_ERR("arg is null!\n");
268         return HI_FAILURE;
269     }
270 
271     ret = osal_sem_down_interruptible(&g_gpio_sem_intf);
272     if (ret) {
273         HI_LOG_ERR("Semaphore lock is error. \n");
274         return HI_FAILURE;
275     }
276 
277     err = memcpy_s(&st_data, sizeof(st_data), arg, sizeof(gpio_data));
278     if (err != EOK) {
279         HI_LOG_ERR("memcpy_s fail!\n");
280         ret = HI_FAILURE;
281         osal_sem_up(&g_gpio_sem_intf);
282         return ret;
283     }
284 
285     ret = hi_drv_gpio_set_int_type(st_data.gpio_no, st_data.en_int_type);
286 
287     osal_sem_up(&g_gpio_sem_intf);
288 
289     return ret;
290 }
291 
hi_gpio_ioctl_set_int_enable(unsigned int cmd,hi_void * arg,hi_void * private_data)292 static hi_s32 hi_gpio_ioctl_set_int_enable(unsigned int cmd, hi_void *arg, hi_void *private_data)
293 {
294     long ret;
295     gpio_data st_data = { 0, 0, GPIO_INTTYPE_BUTT };
296     errno_t err;
297 
298     if (arg == HI_NULL) {
299         HI_LOG_ERR("arg is null!\n");
300         return HI_FAILURE;
301     }
302 
303     ret = osal_sem_down_interruptible(&g_gpio_sem_intf);
304     if (ret) {
305         HI_LOG_ERR("Semaphore lock is error. \n");
306         return HI_FAILURE;
307     }
308 
309     err = memcpy_s(&st_data, sizeof(st_data), arg, sizeof(gpio_data));
310     if (err != EOK) {
311         HI_LOG_ERR("memcpy_s fail!\n");
312         ret = HI_FAILURE;
313         osal_sem_up(&g_gpio_sem_intf);
314         return ret;
315     }
316 
317     if (st_data.b_enable == HI_TRUE) {
318         ret = hi_drv_gpio_clear_bit_int(st_data.gpio_no);
319         if (ret != HI_SUCCESS) {
320             HI_LOG_ERR("call hi_drv_gpio_clear_bit_int fail!\n");
321             osal_sem_up(&g_gpio_sem_intf);
322             return ret;
323         }
324     }
325 
326     ret = hi_drv_gpio_set_bit_int_enable(st_data.gpio_no, st_data.b_enable);
327     if (ret != HI_SUCCESS) {
328         HI_LOG_ERR("call hi_drv_gpio_set_bit_int_enable fail!\n");
329         osal_sem_up(&g_gpio_sem_intf);
330         return ret;
331     }
332 
333     osal_sem_up(&g_gpio_sem_intf);
334     return ret;
335 }
336 
hi_gpio_ioctl_get_int(unsigned int cmd,hi_void * arg,hi_void * private_data)337 static hi_s32 hi_gpio_ioctl_get_int(unsigned int cmd, hi_void *arg, hi_void *private_data)
338 {
339     long ret;
340     gpio_int gpio_int_value = {0, 0};
341     errno_t err;
342 
343     if (arg == HI_NULL) {
344         HI_LOG_ERR("arg is null!\n");
345         return HI_FAILURE;
346     }
347 
348     ret = osal_sem_down_interruptible(&g_gpio_sem_intf);
349     if (ret) {
350         HI_LOG_ERR("Semaphore lock is error. \n");
351         return HI_FAILURE;
352     }
353 
354     err = memcpy_s(&gpio_int_value, sizeof(gpio_int_value), arg, sizeof(gpio_int));
355     if (err != EOK) {
356         HI_LOG_ERR("memcpy_s fail!\n");
357         ret = HI_FAILURE;
358         osal_sem_up(&g_gpio_sem_intf);
359         return ret;
360     }
361 
362     ret = drv_gpio_query_int(&gpio_int_value);
363     if (ret == HI_SUCCESS) {
364         err = memcpy_s((gpio_int *)arg, sizeof(gpio_int), &gpio_int_value, sizeof(gpio_int_value));
365         if (err != EOK) {
366             HI_LOG_ERR("memcpy_s fail!\n");
367             ret = HI_FAILURE;
368             osal_sem_up(&g_gpio_sem_intf);
369             return ret;
370         }
371     } else {
372         ret = HI_ERR_GPIO_FAILED_GETINT;
373     }
374     osal_sem_up(&g_gpio_sem_intf);
375     return ret;
376 }
377 
hi_gpio_ioctl_get_gpio_num(unsigned int cmd,hi_void * arg,hi_void * private_data)378 static hi_s32 hi_gpio_ioctl_get_gpio_num(unsigned int cmd, hi_void *arg, hi_void *private_data)
379 {
380     long ret;
381     gpio_get_gpionum gpio_num = { 0, 0 };
382     errno_t err;
383 
384     if (arg == HI_NULL) {
385         HI_LOG_ERR("arg is null!\n");
386         return HI_FAILURE;
387     }
388 
389     ret = osal_sem_down_interruptible(&g_gpio_sem_intf);
390     if (ret) {
391         HI_LOG_ERR("Semaphore lock is error. \n");
392         return HI_FAILURE;
393     }
394 
395     hi_drv_gpio_get_gpio_num(&gpio_num);
396 
397     err = memcpy_s((gpio_get_gpionum *)arg, sizeof(gpio_get_gpionum), &gpio_num, sizeof(gpio_num));
398     if (err != EOK) {
399         HI_LOG_ERR("memcpy_s fail!\n");
400         ret = HI_FAILURE;
401         osal_sem_up(&g_gpio_sem_intf);
402         return ret;
403     }
404     ret = HI_SUCCESS;
405     osal_sem_up(&g_gpio_sem_intf);
406     return ret;
407 }
408 
hi_gpio_ioctl_set_output_type(unsigned int cmd,hi_void * arg,hi_void * private_data)409 static hi_s32 hi_gpio_ioctl_set_output_type(unsigned int cmd, hi_void *arg, hi_void *private_data)
410 {
411     long ret;
412     gpio_output_type st_output_type = { 0, GPIO_OUTPUTTYPE_BUTT };
413     errno_t err;
414 
415     if (arg == HI_NULL) {
416         HI_LOG_ERR("arg is null!\n");
417         return HI_FAILURE;
418     }
419 
420     ret = osal_sem_down_interruptible(&g_gpio_sem_intf);
421     if (ret) {
422         HI_LOG_ERR("Semaphore lock is error. \n");
423         return HI_FAILURE;
424     }
425 
426     err = memcpy_s(&st_output_type, sizeof(st_output_type),
427         (gpio_output_type *)(uintptr_t)arg, sizeof(gpio_output_type));
428     if (err != EOK) {
429         HI_LOG_ERR("memcpy_s fail!\n");
430         ret = HI_FAILURE;
431         osal_sem_up(&g_gpio_sem_intf);
432         return ret;
433     }
434 
435     ret = drv_gpio_set_output_type(st_output_type.gpio_no, st_output_type.en_output_type);
436 
437     osal_sem_up(&g_gpio_sem_intf);
438     return ret;
439 }
440 
441 
hi_gpio_ioctl_get_output_type(unsigned int cmd,hi_void * arg,hi_void * private_data)442 static hi_s32 hi_gpio_ioctl_get_output_type(unsigned int cmd, hi_void *arg, hi_void *private_data)
443 {
444     long ret;
445     gpio_output_type st_output_type = { 0, GPIO_OUTPUTTYPE_BUTT };
446     errno_t err;
447 
448     if (arg == HI_NULL) {
449         HI_LOG_ERR("arg is null!\n");
450         return HI_FAILURE;
451     }
452 
453     ret = osal_sem_down_interruptible(&g_gpio_sem_intf);
454     if (ret) {
455         HI_LOG_ERR("Semaphore lock is error. \n");
456         return HI_FAILURE;
457     }
458 
459     err = memcpy_s(&st_output_type, sizeof(st_output_type), arg, sizeof(gpio_output_type));
460     if (err != EOK) {
461         HI_LOG_ERR("memcpy_s fail!\n");
462         ret = HI_FAILURE;
463         osal_sem_up(&g_gpio_sem_intf);
464         return ret;
465     }
466 
467     ret = drv_gpio_get_output_type(st_output_type.gpio_no, &st_output_type.en_output_type);
468 
469     err = memcpy_s((gpio_output_type *)arg, sizeof(gpio_output_type), &st_output_type, sizeof(st_output_type));
470     if (err != EOK) {
471         HI_LOG_ERR("memcpy_s fail!\n");
472         ret = HI_FAILURE;
473         osal_sem_up(&g_gpio_sem_intf);
474         return ret;
475     }
476 
477     osal_sem_up(&g_gpio_sem_intf);
478     return ret;
479 }
480 
hi_gpio_ioctl_set_direct(unsigned int cmd,hi_void * arg,hi_void * private_data)481 static hi_s32 hi_gpio_ioctl_set_direct(unsigned int cmd, hi_void *arg, hi_void *private_data)
482 {
483     long ret;
484     gpio_direct st_direct = { 0, HI_FALSE };
485     errno_t err;
486 
487     if (arg == HI_NULL) {
488         HI_LOG_ERR("arg is null!\n");
489         return HI_FAILURE;
490     }
491 
492     ret = osal_sem_down_interruptible(&g_gpio_sem_intf);
493     if (ret) {
494         HI_LOG_ERR("Semaphore lock is error. \n");
495         return HI_FAILURE;
496     }
497 
498     err = memcpy_s(&st_direct, sizeof(st_direct), arg, sizeof(gpio_direct));
499     if (err != EOK) {
500         HI_LOG_ERR("memcpy_s fail!\n");
501         ret = HI_FAILURE;
502         osal_sem_up(&g_gpio_sem_intf);
503         return ret;
504     }
505 
506     ret = hi_drv_gpio_set_dir_bit(st_direct.gpio_no, st_direct.b_input);
507 
508     osal_sem_up(&g_gpio_sem_intf);
509 
510     return ret;
511 }
512 
hi_gpio_ioctl_get_direct(unsigned int cmd,hi_void * arg,hi_void * private_data)513 static hi_s32 hi_gpio_ioctl_get_direct(unsigned int cmd, hi_void *arg, hi_void *private_data)
514 {
515     long ret;
516     gpio_direct st_direct = { 0, HI_FALSE };
517     errno_t err;
518     hi_u32 st_direct_input_temp = st_direct.b_input;
519 
520     if (arg == HI_NULL) {
521         HI_LOG_ERR("arg is null!\n");
522         return HI_FAILURE;
523     }
524 
525     ret = osal_sem_down_interruptible(&g_gpio_sem_intf);
526     if (ret) {
527         HI_LOG_ERR("Semaphore lock is error. \n");
528         return HI_FAILURE;
529     }
530 
531     err = memcpy_s(&st_direct, sizeof(st_direct), arg, sizeof(gpio_direct));
532     if (err != EOK) {
533         HI_LOG_ERR("memcpy_s fail!\n");
534         ret = HI_FAILURE;
535         osal_sem_up(&g_gpio_sem_intf);
536         return ret;
537     }
538 
539     ret = hi_drv_gpio_get_dir_bit(st_direct.gpio_no, &st_direct_input_temp);
540 
541     err = memcpy_s((gpio_direct *)arg, sizeof(gpio_direct), &st_direct, sizeof(st_direct));
542     if (err != EOK) {
543         HI_LOG_ERR("memcpy_s fail!\n");
544         ret = HI_FAILURE;
545         osal_sem_up(&g_gpio_sem_intf);
546         return ret;
547     }
548 
549     osal_sem_up(&g_gpio_sem_intf);
550 
551     return ret;
552 }
553 
hi_gpio_ioctl_set_value(unsigned int cmd,hi_void * arg,hi_void * private_data)554 static hi_s32 hi_gpio_ioctl_set_value(unsigned int cmd, hi_void *arg, hi_void *private_data)
555 {
556     long ret;
557     gpio_value st_value = { 0, HI_FALSE };
558     errno_t err;
559 
560     if (arg == HI_NULL) {
561         HI_LOG_ERR("arg is null!\n");
562         return HI_FAILURE;
563     }
564 
565     ret = osal_sem_down_interruptible(&g_gpio_sem_intf);
566     if (ret) {
567         HI_LOG_ERR("Semaphore lock is error. \n");
568         return HI_FAILURE;
569     }
570 
571     err = memcpy_s(&st_value, sizeof(st_value), arg, sizeof(gpio_value));
572     if (err != EOK) {
573         HI_LOG_ERR("memcpy_s fail!\n");
574         ret = HI_FAILURE;
575         osal_sem_up(&g_gpio_sem_intf);
576         return ret;
577     }
578 
579     ret = hi_drv_gpio_write_bit(st_value.gpio_no, st_value.b_high_volt);
580 
581     osal_sem_up(&g_gpio_sem_intf);
582 
583     return ret;
584 }
585 
hi_gpio_ioctl_get_value(unsigned int cmd,hi_void * arg,hi_void * private_data)586 static hi_s32 hi_gpio_ioctl_get_value(unsigned int cmd, hi_void *arg, hi_void *private_data)
587 {
588     long ret;
589     gpio_value st_value = { 0, HI_FALSE };
590     errno_t err;
591     hi_u32 st_value_high_volt_temp = st_value.b_high_volt;
592 
593     if (arg == HI_NULL) {
594         HI_LOG_ERR("arg is null!\n");
595         return HI_FAILURE;
596     }
597 
598     ret = osal_sem_down_interruptible(&g_gpio_sem_intf);
599     if (ret) {
600         HI_LOG_ERR("Semaphore lock is error. \n");
601         return HI_FAILURE;
602     }
603 
604     err = memcpy_s(&st_value, sizeof(st_value), arg, sizeof(gpio_value));
605     if (err != EOK) {
606         HI_LOG_ERR("memcpy_s fail!\n");
607         ret = HI_FAILURE;
608         osal_sem_up(&g_gpio_sem_intf);
609         return ret;
610     }
611 
612     ret = hi_drv_gpio_read_bit(st_value.gpio_no, &st_value_high_volt_temp);
613 
614     err = memcpy_s((gpio_value *)arg, sizeof(gpio_value), &st_value, sizeof(st_value));
615     if (err != EOK) {
616         HI_LOG_ERR("memcpy_s fail!\n");
617         ret = HI_FAILURE;
618         osal_sem_up(&g_gpio_sem_intf);
619         return ret;
620     }
621 
622     osal_sem_up(&g_gpio_sem_intf);
623 
624     return ret;
625 }
626 
627 static osal_ioctl_cmd g_gpio_cmd_list[] = {
628     { CMD_GPIO_SET_INT_TYPE,               hi_gpio_ioctl_set_int_type },
629     { CMD_GPIO_SET_INT_ENABLE,           hi_gpio_ioctl_set_int_enable },
630     { CMD_GPIO_GET_INT,                       hi_gpio_ioctl_get_int },
631     { CMD_GPIO_GET_GPIONUM,               hi_gpio_ioctl_get_gpio_num },
632     { CMD_GPIO_SET_OUTPUTTYPE,          hi_gpio_ioctl_set_output_type },
633     { CMD_GPIO_GET_OUTPUTTYPE,          hi_gpio_ioctl_get_output_type },
634     { CMD_GPIO_SET_DIRECT,                  hi_gpio_ioctl_set_direct },
635     { CMD_GPIO_GET_DIRECT,                  hi_gpio_ioctl_get_direct },
636     { CMD_GPIO_SET_VALUE,                    hi_gpio_ioctl_set_value },
637     { CMD_GPIO_GET_VALUE,                   hi_gpio_ioctl_get_value },
638 };
639 
640 static osal_fileops g_gpio_fileops = {
641     .read = NULL,
642     .write = NULL,
643     .open = drv_gpio_open,
644     .release = drv_gpio_close,
645     .cmd_list = g_gpio_cmd_list,
646     .cmd_cnt = 0,
647 };
648 
649 static osal_pmops g_gpio_pmops = {
650     .pm_suspend = gpio_suspend,
651     .pm_resume =  gpio_resume,
652     .pm_lowpower_enter = gpio_drv_lowpower_enter,
653     .pm_lowpower_exit = gpio_drv_lowpower_exit,
654     .pm_poweroff = NULL,
655     .private_data = &g_gpio_state,
656 };
657 
658 static osal_dev g_gpio_device = {
659     .minor = UMAP_MIN_MINOR_GPIO,
660     .fops = &g_gpio_fileops,
661     .pmops = &g_gpio_pmops,
662 };
663 
664 
gpio_drv_proc_add(hi_void)665 hi_s32 gpio_drv_proc_add(hi_void)
666 {
667     hi_s32 ret;
668     HI_CHAR proc_name[16] = {0}; // 存放驱动名,最大长度16
669     osal_proc_entry *gpio_proc_entry = NULL;
670     hi_u32 len;
671     ret = snprintf_s(proc_name, sizeof(proc_name), sizeof(proc_name) - 1, "%s", HI_MOD_GPIO);
672     if (ret < 0) {
673         HI_LOG_ERR("secure func call error\n");
674         return HI_FAILURE;
675     }
676 
677     len = strlen(proc_name);
678     gpio_proc_entry = osal_proc_add(proc_name, len);
679     if (gpio_proc_entry == HI_NULL) {
680         HI_LOG_ERR("gpio add proc failed!\n");
681         return HI_FAILURE;
682     }
683 
684     len = sizeof(g_gpio_proc_cmd) / sizeof(osal_proc_cmd);
685     gpio_proc_entry->read = gpio_proc_read;
686     gpio_proc_entry->cmd_cnt = len;
687     gpio_proc_entry->cmd_list = g_gpio_proc_cmd;
688     gpio_proc_entry->private = NULL;
689 
690     return HI_SUCCESS;
691 }
692 
gpio_drv_proc_del(hi_s8 * proc_name)693 hi_s32 gpio_drv_proc_del(hi_s8 *proc_name)
694 {
695     hi_u32 len;
696 
697     if (proc_name == NULL) {
698         HI_LOG_ERR("proc_name is null\n");
699         return HI_FAILURE;
700     }
701 
702     len = strlen(proc_name);
703     osal_proc_remove(proc_name, len);
704     return HI_SUCCESS;
705 }
706 
gpio_drv_mod_init(hi_void)707 HI_S32 gpio_drv_mod_init(hi_void)
708 {
709     hi_s32 ret;
710 
711     osal_sem_init(&g_gpio_sem_intf, 1);
712 
713 #ifndef HI_MCE_SUPPORT
714 #ifndef HI_KEYLED_CT1642_KERNEL_SUPPORT
715     hi_drv_gpio_init();
716 #endif
717 #endif
718 
719     g_gpio_fileops.cmd_cnt = sizeof(g_gpio_cmd_list) / sizeof(osal_ioctl_cmd);
720 
721     ret = snprintf_s(g_gpio_device.name, sizeof(g_gpio_device.name),
722         sizeof(g_gpio_device.name) - 1, "%s", UMAP_DEVNAME_GPIO);
723     if (ret < 0) {
724         HI_LOG_ERR("snprintf_s failed!\n");
725         goto err0;
726     }
727 
728     ret = osal_dev_register(&g_gpio_device);
729     if (ret != HI_SUCCESS) {
730         HI_LOG_ERR("register gpio failed.\n");
731         return HI_FAILURE;
732     }
733 
734     ret = gpio_drv_proc_add();
735     if (ret != HI_SUCCESS) {
736         HI_LOG_ERR("call gpio_drv_proc_add failed!\n");
737         osal_dev_unregister(&g_gpio_device);
738         return HI_FAILURE;
739     }
740 
741 #ifdef MODULE
742     HI_PRINT("Load hi_gpio.ko success.\t(%s)\n", VERSION_STRING);
743 #endif
744 
745     return HI_SUCCESS;
746 
747 err0:
748 #ifndef HI_MCE_SUPPORT
749 #ifndef HI_KEYLED_CT1642_KERNEL_SUPPORT
750     hi_drv_gpio_de_init();
751 #endif
752 #endif
753     return HI_FAILURE;
754 }
755 
gpio_drv_mod_exit(hi_void)756 hi_void gpio_drv_mod_exit(hi_void)
757 {
758     hi_s32 ret;
759     errno_t sec_errno;
760     HI_CHAR proc_name[16] = {0}; // 存放驱动名,最大长度16
761     osal_sem_destory(&g_gpio_sem_intf);
762     sec_errno = snprintf_s(proc_name, sizeof(proc_name), sizeof(proc_name) - 1, "%s", HI_MOD_GPIO);
763     if (sec_errno < 0) {
764         HI_LOG_ERR("secure func call error\n");
765         return;
766     }
767     osal_dev_unregister(&g_gpio_device);
768 #if 1
769     ret = gpio_drv_proc_del(proc_name);
770     if (ret != HI_SUCCESS) {
771         HI_LOG_ERR("gpio_drv_proc_del failure!\n");
772     }
773 #endif
774 #ifndef HI_MCE_SUPPORT
775 #ifndef HI_KEYLED_CT1642_KERNEL_SUPPORT
776     hi_drv_gpio_de_init();
777 #endif
778 #endif
779 
780 #ifdef MODULE
781     HI_PRINT("remove hi_gpio.ko ok!\n");
782 #endif
783     return;
784 }
785 #ifdef __KERNEL__
786 #if defined(MODULE) || defined(CFG_HI_USER_DRV)
787 module_init(gpio_drv_mod_init);
788 module_exit(gpio_drv_mod_exit);
789 #endif
790 #endif
791 
792 MODULE_LICENSE("GPL");
793 
794