]> sigrok.org Git - libsigrok.git/blob - src/hardware/baylibre-acme/gpio.c
Build: Set local include directories in Makefile.am
[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 <glib.h>
21 #include <glib/gstdio.h>
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <libsigrok/libsigrok.h>
27 #include "libsigrok-internal.h"
28 #include "gpio.h"
29
30 #define LOG_PREFIX "gpio"
31
32 static int open_and_write(const gchar *path, const gchar *buf)
33 {
34         FILE *fd;
35         ssize_t wr;
36
37         fd = g_fopen(path, "w");
38         if (!fd) {
39                 sr_err("Error opening %s: %s", path, strerror(errno));
40                 return -1;
41         }
42
43         wr = g_fprintf(fd, "%s", buf);
44         fclose(fd);
45         if (wr < 0) {
46                 sr_err("Error writing to %s: %s", path, strerror(errno));
47                 return -1;
48         }
49
50         return 0;
51 }
52
53 SR_PRIV int sr_gpio_export(unsigned gpio)
54 {
55         GString *path, *buf;
56         gboolean exported;
57         int status;
58
59         path = g_string_sized_new(128);
60         g_string_printf(path, "/sys/class/gpio/gpio%d", gpio);
61         exported = g_file_test(path->str, G_FILE_TEST_IS_DIR);
62         g_string_free(path, TRUE);
63         if (exported)
64                 return 0; /* Already exported. */
65
66         buf = g_string_sized_new(16);
67         g_string_printf(buf, "%u\n", gpio);
68         status = open_and_write("/sys/class/gpio/export", buf->str);
69         g_string_free(buf, TRUE);
70
71         return status;
72 }
73
74 SR_PRIV int sr_gpio_set_direction(unsigned gpio, unsigned direction)
75 {
76         GString *path, *buf;
77         int status;
78
79         path = g_string_sized_new(128);
80         buf = g_string_sized_new(16);
81         g_string_printf(path, "/sys/class/gpio/gpio%d/direction", gpio);
82         g_string_printf(buf, "%s\n", direction == GPIO_DIR_IN ? "in" : "out");
83
84         status = open_and_write(path->str, buf->str);
85
86         g_string_free(path, TRUE);
87         g_string_free(buf, TRUE);
88
89         return status;
90 }
91
92 SR_PRIV int sr_gpio_set_value(unsigned gpio, unsigned value)
93 {
94         GString *path, *buf;
95         int status;
96
97         path = g_string_sized_new(128);
98         buf = g_string_sized_new(16);
99         g_string_printf(path, "/sys/class/gpio/gpio%d/value", gpio);
100         g_string_printf(buf, "%d\n", value);
101
102         status = open_and_write(path->str, buf->str);
103
104         g_string_free(path, TRUE);
105         g_string_free(buf, TRUE);
106
107         return status;
108 }
109
110 SR_PRIV int sr_gpio_get_value(int gpio)
111 {
112         FILE *fd;
113         GString *path;
114         int ret, status;
115
116         path = g_string_sized_new(128);
117         g_string_printf(path, "/sys/class/gpio/gpio%d/value", gpio);
118         fd = g_fopen(path->str, "r");
119         if (!fd) {
120                 sr_err("Error opening %s: %s", path->str, strerror(errno));
121                 g_string_free(path, TRUE);
122                 return -1;
123         }
124
125         status = fscanf(fd, "%d", &ret);
126         fclose(fd);
127         if (status != 1) {
128                 sr_err("Error reading from %s: %s", path, strerror(errno));
129                 g_string_free(path, TRUE);
130                 return -1;
131         }
132
133         g_string_free(path, TRUE);
134         return ret;
135 }
136
137 SR_PRIV int sr_gpio_setval_export(int gpio, int value)
138 {
139         int status;
140
141         status = sr_gpio_export(gpio);
142         if (status < 0)
143                 return status;
144
145         status = sr_gpio_set_direction(gpio, GPIO_DIR_OUT);
146         if (status < 0)
147                 return status;
148
149         status = sr_gpio_set_value(gpio, value);
150         if (status < 0)
151                 return status;
152
153         return 0;
154 }
155
156 SR_PRIV int sr_gpio_getval_export(int gpio)
157 {
158         int status;
159
160         status = sr_gpio_export(gpio);
161         if (status < 0)
162                 return status;
163
164         status = sr_gpio_set_direction(gpio, GPIO_DIR_IN);
165         if (status < 0)
166                 return status;
167
168         return sr_gpio_get_value(gpio);
169 }