]> sigrok.org Git - libsigrok.git/blob - src/hardware/baylibre-acme/gpio.c
Build: Include <config.h> first in all source files
[libsigrok.git] / src / hardware / baylibre-acme / gpio.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2015 Bartosz Golaszewski <bgolaszewski@baylibre.com>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <glib.h>
22 #include <glib/gstdio.h>
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <errno.h>
26 #include <string.h>
27 #include <libsigrok/libsigrok.h>
28 #include "libsigrok-internal.h"
29 #include "gpio.h"
30
31 #define LOG_PREFIX "gpio"
32
33 static int open_and_write(const gchar *path, const gchar *buf)
34 {
35         FILE *fd;
36         ssize_t wr;
37
38         fd = g_fopen(path, "w");
39         if (!fd) {
40                 sr_err("Error opening %s: %s", path, g_strerror(errno));
41                 return -1;
42         }
43
44         wr = g_fprintf(fd, "%s", buf);
45         fclose(fd);
46         if (wr < 0) {
47                 sr_err("Error writing to %s: %s", path, g_strerror(errno));
48                 return -1;
49         }
50
51         return 0;
52 }
53
54 SR_PRIV int sr_gpio_export(unsigned gpio)
55 {
56         GString *path, *buf;
57         gboolean exported;
58         int status;
59
60         path = g_string_sized_new(128);
61         g_string_printf(path, "/sys/class/gpio/gpio%d", gpio);
62         exported = g_file_test(path->str, G_FILE_TEST_IS_DIR);
63         g_string_free(path, TRUE);
64         if (exported)
65                 return 0; /* Already exported. */
66
67         buf = g_string_sized_new(16);
68         g_string_printf(buf, "%u\n", gpio);
69         status = open_and_write("/sys/class/gpio/export", buf->str);
70         g_string_free(buf, TRUE);
71
72         return status;
73 }
74
75 SR_PRIV int sr_gpio_set_direction(unsigned gpio, unsigned direction)
76 {
77         GString *path, *buf;
78         int status;
79
80         path = g_string_sized_new(128);
81         buf = g_string_sized_new(16);
82         g_string_printf(path, "/sys/class/gpio/gpio%d/direction", gpio);
83         g_string_printf(buf, "%s\n", direction == GPIO_DIR_IN ? "in" : "out");
84
85         status = open_and_write(path->str, buf->str);
86
87         g_string_free(path, TRUE);
88         g_string_free(buf, TRUE);
89
90         return status;
91 }
92
93 SR_PRIV int sr_gpio_set_value(unsigned gpio, unsigned value)
94 {
95         GString *path, *buf;
96         int status;
97
98         path = g_string_sized_new(128);
99         buf = g_string_sized_new(16);
100         g_string_printf(path, "/sys/class/gpio/gpio%d/value", gpio);
101         g_string_printf(buf, "%d\n", value);
102
103         status = open_and_write(path->str, buf->str);
104
105         g_string_free(path, TRUE);
106         g_string_free(buf, TRUE);
107
108         return status;
109 }
110
111 SR_PRIV int sr_gpio_get_value(int gpio)
112 {
113         FILE *fd;
114         GString *path;
115         int ret, status;
116
117         path = g_string_sized_new(128);
118         g_string_printf(path, "/sys/class/gpio/gpio%d/value", gpio);
119         fd = g_fopen(path->str, "r");
120         if (!fd) {
121                 sr_err("Error opening %s: %s", path->str, g_strerror(errno));
122                 g_string_free(path, TRUE);
123                 return -1;
124         }
125
126         status = fscanf(fd, "%d", &ret);
127         fclose(fd);
128         if (status != 1) {
129                 sr_err("Error reading from %s: %s", path->str, g_strerror(errno));
130                 g_string_free(path, TRUE);
131                 return -1;
132         }
133
134         g_string_free(path, TRUE);
135         return ret;
136 }
137
138 SR_PRIV int sr_gpio_setval_export(int gpio, int value)
139 {
140         int status;
141
142         status = sr_gpio_export(gpio);
143         if (status < 0)
144                 return status;
145
146         status = sr_gpio_set_direction(gpio, GPIO_DIR_OUT);
147         if (status < 0)
148                 return status;
149
150         status = sr_gpio_set_value(gpio, value);
151         if (status < 0)
152                 return status;
153
154         return 0;
155 }
156
157 SR_PRIV int sr_gpio_getval_export(int gpio)
158 {
159         int status;
160
161         status = sr_gpio_export(gpio);
162         if (status < 0)
163                 return status;
164
165         status = sr_gpio_set_direction(gpio, GPIO_DIR_IN);
166         if (status < 0)
167                 return status;
168
169         return sr_gpio_get_value(gpio);
170 }