]> sigrok.org Git - libsigrok.git/blob - src/hardware/baylibre-acme/gpio.c
output/csv: use intermediate time_t var, silence compiler warning
[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         status = sr_gpio_set_direction(gpio, GPIO_DIR_OUT);
68         if (status < 0)
69                 return status;
70
71         buf = g_string_sized_new(16);
72         g_string_printf(buf, "%u\n", gpio);
73         status = open_and_write("/sys/class/gpio/export", buf->str);
74         g_string_free(buf, TRUE);
75
76         return status;
77 }
78
79 SR_PRIV int sr_gpio_set_direction(unsigned gpio, unsigned direction)
80 {
81         GString *path, *buf;
82         int status;
83
84         path = g_string_sized_new(128);
85         buf = g_string_sized_new(16);
86         g_string_printf(path, "/sys/class/gpio/gpio%d/direction", gpio);
87         g_string_printf(buf, "%s\n", direction == GPIO_DIR_IN ? "in" : "out");
88
89         status = open_and_write(path->str, buf->str);
90
91         g_string_free(path, TRUE);
92         g_string_free(buf, TRUE);
93
94         return status;
95 }
96
97 SR_PRIV int sr_gpio_set_value(unsigned gpio, unsigned value)
98 {
99         GString *path, *buf;
100         int status;
101
102         path = g_string_sized_new(128);
103         buf = g_string_sized_new(16);
104         g_string_printf(path, "/sys/class/gpio/gpio%d/value", gpio);
105         g_string_printf(buf, "%d\n", value);
106
107         status = open_and_write(path->str, buf->str);
108
109         g_string_free(path, TRUE);
110         g_string_free(buf, TRUE);
111
112         return status;
113 }
114
115 SR_PRIV int sr_gpio_get_value(int gpio)
116 {
117         FILE *fd;
118         GString *path;
119         int ret, status;
120
121         path = g_string_sized_new(128);
122         g_string_printf(path, "/sys/class/gpio/gpio%d/value", gpio);
123         fd = g_fopen(path->str, "r");
124         if (!fd) {
125                 sr_err("Error opening %s: %s", path->str, g_strerror(errno));
126                 g_string_free(path, TRUE);
127                 return -1;
128         }
129
130         status = fscanf(fd, "%d", &ret);
131         fclose(fd);
132         if (status != 1) {
133                 sr_err("Error reading from %s: %s", path->str, g_strerror(errno));
134                 g_string_free(path, TRUE);
135                 return -1;
136         }
137
138         g_string_free(path, TRUE);
139         return ret;
140 }
141
142 SR_PRIV int sr_gpio_setval_export(int gpio, int value)
143 {
144         int status;
145
146         status = sr_gpio_export(gpio);
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         return sr_gpio_get_value(gpio);
166 }