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