]> sigrok.org Git - libsigrok.git/blame - src/hardware/baylibre-acme/gpio.c
baylibre-acme: Add basic support for ACME revB.
[libsigrok.git] / src / hardware / baylibre-acme / gpio.c
CommitLineData
289eebd7
BG
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
6ec6c43b 20#include <config.h>
289eebd7
BG
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>
c1aae900 27#include <libsigrok/libsigrok.h>
515ab088
UH
28#include "libsigrok-internal.h"
29#include "gpio.h"
289eebd7
BG
30
31#define LOG_PREFIX "gpio"
32
33static 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) {
7237e912 40 sr_err("Error opening %s: %s", path, g_strerror(errno));
289eebd7
BG
41 return -1;
42 }
43
44 wr = g_fprintf(fd, "%s", buf);
45 fclose(fd);
46 if (wr < 0) {
7237e912 47 sr_err("Error writing to %s: %s", path, g_strerror(errno));
289eebd7
BG
48 return -1;
49 }
50
51 return 0;
52}
53
54SR_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
75SR_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
93SR_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
111SR_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) {
7237e912 121 sr_err("Error opening %s: %s", path->str, g_strerror(errno));
289eebd7
BG
122 g_string_free(path, TRUE);
123 return -1;
124 }
125
126 status = fscanf(fd, "%d", &ret);
127 fclose(fd);
128 if (status != 1) {
6433156c 129 sr_err("Error reading from %s: %s", path->str, g_strerror(errno));
289eebd7
BG
130 g_string_free(path, TRUE);
131 return -1;
132 }
133
134 g_string_free(path, TRUE);
135 return ret;
136}
137
138SR_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
157SR_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}