434e7643d2fa240d5f810db1b6f0947da8d2dc8e
[platform/core/system/peripheral-bus.git] / src / interface / gpio.c
1 /*
2  * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <poll.h>
24
25 #include "gpio.h"
26 #include "peripheral_common.h"
27
28 #define MAX_ERR_LEN 255
29
30 int gpio_get_edge_mode(int gpiopin, gpio_edge_e *edge)
31 {
32         int fd, len;
33         char gpio_dev[GPIO_BUFFER_MAX] = {0, };
34         char gpio_buf[GPIO_BUFFER_MAX] = {0, };
35
36         snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/edge", gpiopin);
37         fd = open(gpio_dev, O_RDONLY);
38
39         if (fd < 0) {
40                 char errmsg[MAX_ERR_LEN];
41                 strerror_r(errno, errmsg, MAX_ERR_LEN);
42                 _E("Can't Open /sys/class/gpio/gpio%d/edge: %s\n", gpiopin, errmsg);
43                 return -ENODEV;
44         }
45
46         len = read(fd, &gpio_buf, GPIO_BUFFER_MAX);
47         if (len <= 0) {
48                 close(fd);
49                 _E("Error: gpio edge read error\n");
50                 return -EIO;
51         }
52
53         if (0 == strncmp(gpio_buf, "none", strlen("none")))
54                 *edge = GPIO_EDGE_NONE;
55         else if (0 == strncmp(gpio_buf, "both", strlen("both")))
56                 *edge = GPIO_EDGE_BOTH;
57         else if (0 == strncmp(gpio_buf, "rising", strlen("rising")))
58                 *edge = GPIO_EDGE_RISING;
59         else if (0 == strncmp(gpio_buf, "falling", strlen("falling")))
60                 *edge = GPIO_EDGE_FALLING;
61         else {
62                 close(fd);
63                 _E("Error: gpio edge is wrong\n");
64                 return -EIO;
65         }
66
67         close(fd);
68
69         return 0;
70 }
71
72 int gpio_get_direction(int gpiopin, gpio_direction_e *dir)
73 {
74         int fd, len;
75         char gpio_dev[GPIO_BUFFER_MAX] = {0, };
76         char gpio_buf[GPIO_BUFFER_MAX] = {0, };
77
78         snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/direction", gpiopin);
79         fd = open(gpio_dev, O_RDONLY);
80
81         if (fd < 0) {
82                 char errmsg[MAX_ERR_LEN];
83                 strerror_r(errno, errmsg, MAX_ERR_LEN);
84                 _E("Can't Open /sys/class/gpio/gpio%d/direction: %s\n", gpiopin, errmsg);
85                 return -ENODEV;
86         }
87
88         len = read(fd, &gpio_buf, GPIO_BUFFER_MAX);
89         if (len <= 0) {
90                 close(fd);
91                 _E("Error: gpio direction read error\n");
92                 return -EIO;
93         }
94
95         if (0 == strncmp(gpio_buf, "in", strlen("in")))
96                 *dir = GPIO_DIRECTION_IN;
97         else if (0 == strncmp(gpio_buf, "out", strlen("out")))
98                 *dir = GPIO_DIRECTION_OUT;
99         else {
100                 close(fd);
101                 _E("Error: gpio direction is wrong\n");
102                 return -EIO;
103         }
104
105         close(fd);
106
107         return 0;
108 }
109
110 int gpio_read(int gpiopin, int *value)
111 {
112         int fd, len;
113         char gpio_dev[GPIO_BUFFER_MAX] = {0, };
114         char gpio_buf[GPIO_BUFFER_MAX] = {0, };
115
116         snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/value", gpiopin);
117         fd = open(gpio_dev, O_RDONLY);
118         if (fd < 0) {
119                 char errmsg[MAX_ERR_LEN];
120                 strerror_r(errno, errmsg, MAX_ERR_LEN);
121                 _E("Can't Open /sys/class/gpio/gpio%d pin value: %s\n", gpiopin, errmsg);
122                 return -ENODEV;
123         }
124
125         len = read(fd, &gpio_buf, 1);
126         close(fd);
127
128         if (len <= 0) {
129                 _E("Error: gpio read error \n");
130                 return -EIO;
131         }
132
133         if (0 == strncmp(gpio_buf, "1", strlen("1")))
134                 *value = 1;
135         else if (0 == strncmp(gpio_buf, "0", strlen("0")))
136                 *value = 0;
137         else {
138                 _E("Error: gpio value is error \n");
139                 return -EIO;
140         }
141
142         return 0;
143 }
144
145
146 int gpio_open(int gpiopin)
147 {
148         int fd, len, status;
149         char gpio_export[GPIO_BUFFER_MAX] = {0, };
150
151         gpio_close(gpiopin);
152
153         fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY);
154
155         if (fd < 0) {
156                 char errmsg[MAX_ERR_LEN];
157                 strerror_r(errno, errmsg, MAX_ERR_LEN);
158                 _E("Can't Open /sys/class/gpio/export :%s\n", errmsg);
159                 return -ENODEV;
160         }
161
162         len = snprintf(gpio_export, GPIO_BUFFER_MAX, "%d", gpiopin);
163         status = write(fd, gpio_export, len);
164
165         if (status != len) {
166                 close(fd);
167                 _E("Error: gpio open error \n");
168                 return -EIO;
169         }
170
171         close(fd);
172
173         return 0;
174 }
175
176 int gpio_close(int gpiopin)
177 {
178         int fd, len, status;
179         char gpio_unexport[GPIO_BUFFER_MAX] = {0, };
180
181         fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY);
182         if (fd < 0) {
183                 char errmsg[MAX_ERR_LEN];
184                 strerror_r(errno, errmsg, MAX_ERR_LEN);
185                 _E("Can't Open /sys/class/gpio/unexport %s\n", errmsg);
186                 return -ENODEV;
187         }
188
189         len = snprintf(gpio_unexport, GPIO_BUFFER_MAX, "%d", gpiopin);
190         status = write(fd, gpio_unexport, len);
191
192         if (status != len) {
193                 close(fd);
194                 _E("Error: gpio open error \n");
195                 return -EIO;
196         }
197
198         close(fd);
199
200         return 0;
201 }
202
203
204 int gpio_set_edge_mode(int gpiopin, gpio_edge_e edge)
205 {
206         int fd, status;
207         char gpio_dev[GPIO_BUFFER_MAX] = {0, };
208
209         snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/edge", gpiopin);
210         fd = open(gpio_dev, O_WRONLY);
211         if (fd < 0) {
212                 char errmsg[MAX_ERR_LEN];
213                 strerror_r(errno, errmsg, MAX_ERR_LEN);
214                 _E("Can't Open /sys/class/gpio/gpio%d/edge: %s\n", gpiopin, errmsg);
215                 return -ENODEV;
216         }
217
218         if (edge == GPIO_EDGE_NONE)
219                 status = write(fd, "none", strlen("none")+1);
220         else if (edge == GPIO_EDGE_RISING)
221                 status = write(fd, "rising", strlen("rising")+1);
222         else if (edge == GPIO_EDGE_FALLING)
223                 status = write(fd, "falling", strlen("falling")+1);
224         else if (edge == GPIO_EDGE_BOTH)
225                 status = write(fd, "both", strlen("both")+1);
226         else {
227                 close(fd);
228                 _E("Error: gpio edge is wrong\n");
229                 return -EIO;
230         }
231
232         if (status <= 0) {
233                 close(fd);
234                 _E("Error: gpio edge set error\n");
235                 return -EIO;
236         }
237
238         close(fd);
239
240         return 0;
241 }
242
243 int gpio_set_direction(int gpiopin, gpio_direction_e dir)
244 {
245         int fd, status;
246         char gpio_dev[GPIO_BUFFER_MAX] = {0, };
247
248         snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/direction", gpiopin);
249         fd = open(gpio_dev, O_WRONLY);
250         if (fd < 0) {
251                 char errmsg[MAX_ERR_LEN];
252                 strerror_r(errno, errmsg, MAX_ERR_LEN);
253                 _E("Can't Open /sys/class/gpio/gpio%d/direction: %s\n", gpiopin, errmsg);
254                 return -ENODEV;
255         }
256
257         if (dir == GPIO_DIRECTION_OUT)
258                 status = write(fd, "out", strlen("out")+1);
259         else if (dir == GPIO_DIRECTION_IN)
260                 status = write(fd, "in", strlen("in")+1);
261         else {
262                 close(fd);
263                 _E("Error: gpio direction is wrong\n");
264                 return -EIO;
265         }
266
267         if (status <= 0) {
268                 close(fd);
269                 _E("Error: gpio direction set error\n");
270                 return -EIO;
271         }
272
273         close(fd);
274
275         return 0;
276 }
277
278 int gpio_write(int gpiopin, int value)
279 {
280         int fd, status;
281         char gpio_dev[GPIO_BUFFER_MAX] = {0, };
282
283         snprintf(gpio_dev, GPIO_BUFFER_MAX, SYSFS_GPIO_DIR"/gpio%d/value", gpiopin);
284         fd = open(gpio_dev, O_WRONLY);
285
286         if (fd < 0) {
287                 char errmsg[MAX_ERR_LEN];
288                 strerror_r(errno, errmsg, MAX_ERR_LEN);
289                 _E("Can't Open /sys/class/gpio/gpio%d/value: %s\n", gpiopin, errmsg);
290                 return -ENODEV;
291         }
292
293         if (value == 1)
294                 status = write(fd, "1", strlen("1")+1);
295         else if (value == 0)
296                 status = write(fd, "0", strlen("0")+1);
297         else {
298                 close(fd);
299                 _E("Error: gpio write value error \n");
300                 return -EIO;
301         }
302
303         if (status <= 0) {
304                 close(fd);
305                 _E("Error: gpio write error\n");
306                 return -EIO;
307         }
308
309         close(fd);
310
311         return 0;
312 }
313
314 int gpio_open_isr(int gpiopin)
315 {
316         int fd;
317         char gpio_dev[GPIO_BUFFER_MAX] = {0, };
318
319         snprintf(gpio_dev, sizeof(gpio_dev)-1, SYSFS_GPIO_DIR"/gpio%d/value", gpiopin);
320
321         _D("open isr string [%s]", gpio_dev);
322
323         fd = open(gpio_dev, O_RDONLY);
324         if (fd < 0) {
325                 char errmsg[MAX_ERR_LEN];
326                 strerror_r(errno, errmsg, MAX_ERR_LEN);
327                 _E("Can't Open /sys/class/gpio/gpio%d pin value: %s\n", gpiopin, errmsg);
328                 return -ENODEV;
329         }
330
331         return fd;
332 }
333
334 int gpio_close_isr(int file_hndl)
335 {
336         if (file_hndl == (int)NULL)
337                 return -EINVAL;
338
339         close(file_hndl);
340
341         return 0;
342 }
343
344 int gpio_read_isr(void *fdset, char *rev_buf, int length)
345 {
346         int poll_state = 0;
347         int len;
348         struct pollfd poll_events;
349
350         poll_events.fd = ((struct pollfd*)fdset)->fd;
351         poll_events.events = POLLPRI;
352         poll_events.revents = ((struct pollfd*)fdset)->revents;
353
354         poll_state = poll((struct pollfd*)&poll_events, 1, -1);  // 0 is going to return directly.
355
356         if (poll_state < 0) {
357                 _E("poll() failed!\n");
358                 return -EIO;
359         }
360
361         if (poll_events.revents & POLLPRI) {
362                 lseek(poll_events.fd, 0, SEEK_SET);
363                 len = read(poll_events.fd, rev_buf, length);
364                 if (len == -1)
365                         return -EIO;
366         }
367
368         return poll_state;
369 }