• 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/kernel.h>
21 #include <linux/printk.h>
22 #include <linux/interrupt.h>
23 #include <linux/gpio.h>
24 #include "hi_osal.h"
25 
26 #define MAX_GPIO_NUM (28 * 8) /* The max gpio number in 96cv 900/300  */
27 static unsigned int g_gpio_to_irq[MAX_GPIO_NUM] = {0};
28 
osal_gpio_get_direction(unsigned int gpio)29 int osal_gpio_get_direction(unsigned int gpio)
30 {
31     int ret_val;
32     struct gpio_desc *desc = NULL;
33 
34     ret_val = gpio_request(gpio, NULL);
35     if (ret_val != 0) {
36         osal_printk("[%s]:request gpio[No:%u] failed.\n", __FUNCTION__, gpio);
37         return -1;
38     }
39 
40     desc = gpio_to_desc(gpio);
41     if (desc == NULL) {
42         osal_printk("[%s]:gpio_to_desc failed.\n", __FUNCTION__);
43         gpio_free(gpio);
44         return -1;
45     }
46 
47     ret_val = gpiod_get_direction(desc);
48     if (ret_val != 0 && ret_val != 1) {
49         osal_printk("[%s]:gpiod_get_direction failed. return %d\n", __FUNCTION__, ret_val);
50         gpio_free(gpio);
51         return -1;
52     }
53 
54     gpio_free(gpio);
55 
56     return ret_val;
57 }
58 EXPORT_SYMBOL(osal_gpio_get_direction);
59 
osal_gpio_set_direction(unsigned int gpio,unsigned int dir)60 int osal_gpio_set_direction(unsigned int gpio, unsigned int dir)
61 {
62     int ret;
63 
64     if (dir != 1 && dir != 0) {
65         osal_printk("set direction failed. invalid dir\n");
66         return -1;
67     }
68 
69     ret = gpio_request(gpio, NULL);
70     if (ret != 0) {
71         osal_printk("[%s]:request gpio[No:%d] failed.\n", __FUNCTION__, gpio);
72         return -1;
73     }
74 
75     if (dir == 1) { /* set input */
76         ret = gpio_direction_input(gpio);
77         if (ret != 0) {
78             osal_printk("set direction input failed. gpio[No:%d], return %d\n", gpio, ret);
79             goto out;
80         }
81     } else { /* set output */
82         ret = gpio_direction_output(gpio, 0); /* default output low level */
83         if (ret != 0) {
84             osal_printk("set direction output failed, gpio[No:%u], return %d\n", gpio, ret);
85             goto out;
86         }
87     }
88 
89 out:
90     gpio_free(gpio);
91 
92     return ret;
93 }
94 EXPORT_SYMBOL(osal_gpio_set_direction);
95 
osal_gpio_set_value(unsigned int gpio,int value)96 void osal_gpio_set_value(unsigned int gpio, int value)
97 {
98     int ret_val;
99 
100     ret_val = gpio_request(gpio, NULL);
101     if (ret_val != 0) {
102         osal_printk("[%s]:request gpio[No:%d] failed.\n", __FUNCTION__, gpio);
103         gpio_free(gpio);
104         return;
105     }
106     gpio_set_value(gpio, value);
107     gpio_free(gpio);
108 
109     return;
110 }
111 EXPORT_SYMBOL(osal_gpio_set_value);
112 
osal_gpio_get_value(unsigned int gpio)113 int osal_gpio_get_value(unsigned int gpio)
114 {
115     int ret_val;
116 
117     ret_val = gpio_request(gpio, NULL);
118     if (ret_val != 0) {
119         osal_printk("[%s]:request gpio[No:%d] failed.\n", __FUNCTION__, gpio);
120         gpio_free(gpio);
121         return -1;
122     }
123     ret_val = gpio_get_value(gpio);
124     gpio_free(gpio);
125 
126     return ret_val;
127 }
128 EXPORT_SYMBOL(osal_gpio_get_value);
129 
osal_gpio_irq_request(unsigned int gpio,osal_irq_handler handler,unsigned long flags,const char * name,void * dev)130 int osal_gpio_irq_request(unsigned int gpio, osal_irq_handler handler,
131     unsigned long flags, const char *name, void *dev)
132 {
133     int ret, irq;
134 
135     if (name == NULL || gpio >= MAX_GPIO_NUM) {
136         printk("%s - param invalid ! \n", __FUNCTION__);
137         return -1;
138     }
139 
140     ret = gpio_request(gpio, NULL);
141     if (ret != 0) {
142         osal_printk("[%s]:request gpio[No:%d] failed.\n", __FUNCTION__, gpio);
143         return -1;
144     }
145 
146     irq = gpio_to_irq(gpio);
147     if (irq < 0) {
148         osal_printk("call gpio_to_irq failed. gpio[No:%d], return %d\n", gpio, ret);
149         gpio_free(gpio);
150         return -1;
151     }
152     g_gpio_to_irq[gpio] = irq;
153     ret = request_threaded_irq(irq, (irq_handler_t)handler, NULL, flags, name, dev);
154     if (ret != 0) {
155         osal_printk("call request_threaded_irq failed. gpio[No:%d], return %d\n", gpio, ret);
156         gpio_free(gpio);
157         return -1;
158     }
159     gpio_free(gpio);
160 
161     return irq;
162 }
163 EXPORT_SYMBOL(osal_gpio_irq_request);
164 
osal_gpio_irq_free(unsigned int gpio,void * dev)165 void osal_gpio_irq_free(unsigned int gpio, void *dev)
166 {
167     unsigned int irq;
168 
169     if (gpio >= MAX_GPIO_NUM) {
170         osal_printk("[%s]:invalid gpio num.\n", __FUNCTION__);
171         return;
172     }
173 
174     if (g_gpio_to_irq[gpio] == 0) {
175         osal_printk("[%s]:this gpio had not requested irq before.[GPIO:%d]\n", __FUNCTION__, gpio);
176         return;
177     }
178 
179     irq = g_gpio_to_irq[gpio];
180     free_irq(irq, dev);
181     g_gpio_to_irq[gpio] = 0;
182 
183     return;
184 }
185 EXPORT_SYMBOL(osal_gpio_irq_free);
186 
187