0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <unistd.h>
0010 #include <stdlib.h>
0011 #include <stdio.h>
0012 #include <errno.h>
0013 #include <string.h>
0014 #include <fcntl.h>
0015 #include <getopt.h>
0016 #include <sys/ioctl.h>
0017 #include <linux/gpio.h>
0018 #include "gpio-utils.h"
0019
0020 #define CONSUMER "gpio-utils"
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 int gpiotools_request_line(const char *device_name, unsigned int *lines,
0058 unsigned int num_lines,
0059 struct gpio_v2_line_config *config,
0060 const char *consumer)
0061 {
0062 struct gpio_v2_line_request req;
0063 char *chrdev_name;
0064 int fd;
0065 int i;
0066 int ret;
0067
0068 ret = asprintf(&chrdev_name, "/dev/%s", device_name);
0069 if (ret < 0)
0070 return -ENOMEM;
0071
0072 fd = open(chrdev_name, 0);
0073 if (fd == -1) {
0074 ret = -errno;
0075 fprintf(stderr, "Failed to open %s, %s\n",
0076 chrdev_name, strerror(errno));
0077 goto exit_free_name;
0078 }
0079
0080 memset(&req, 0, sizeof(req));
0081 for (i = 0; i < num_lines; i++)
0082 req.offsets[i] = lines[i];
0083
0084 req.config = *config;
0085 strcpy(req.consumer, consumer);
0086 req.num_lines = num_lines;
0087
0088 ret = ioctl(fd, GPIO_V2_GET_LINE_IOCTL, &req);
0089 if (ret == -1) {
0090 ret = -errno;
0091 fprintf(stderr, "Failed to issue %s (%d), %s\n",
0092 "GPIO_GET_LINE_IOCTL", ret, strerror(errno));
0093 }
0094
0095 if (close(fd) == -1)
0096 perror("Failed to close GPIO character device file");
0097 exit_free_name:
0098 free(chrdev_name);
0099 return ret < 0 ? ret : req.fd;
0100 }
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 int gpiotools_set_values(const int fd, struct gpio_v2_line_values *values)
0112 {
0113 int ret;
0114
0115 ret = ioctl(fd, GPIO_V2_LINE_SET_VALUES_IOCTL, values);
0116 if (ret == -1) {
0117 ret = -errno;
0118 fprintf(stderr, "Failed to issue %s (%d), %s\n",
0119 "GPIOHANDLE_SET_LINE_VALUES_IOCTL", ret,
0120 strerror(errno));
0121 }
0122
0123 return ret;
0124 }
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 int gpiotools_get_values(const int fd, struct gpio_v2_line_values *values)
0136 {
0137 int ret;
0138
0139 ret = ioctl(fd, GPIO_V2_LINE_GET_VALUES_IOCTL, values);
0140 if (ret == -1) {
0141 ret = -errno;
0142 fprintf(stderr, "Failed to issue %s (%d), %s\n",
0143 "GPIOHANDLE_GET_LINE_VALUES_IOCTL", ret,
0144 strerror(errno));
0145 }
0146
0147 return ret;
0148 }
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158 int gpiotools_release_line(const int fd)
0159 {
0160 int ret;
0161
0162 ret = close(fd);
0163 if (ret == -1) {
0164 perror("Failed to close GPIO LINE device file");
0165 ret = -errno;
0166 }
0167
0168 return ret;
0169 }
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180 int gpiotools_get(const char *device_name, unsigned int line)
0181 {
0182 int ret;
0183 unsigned int value;
0184 unsigned int lines[] = {line};
0185
0186 ret = gpiotools_gets(device_name, lines, 1, &value);
0187 if (ret)
0188 return ret;
0189 return value;
0190 }
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205 int gpiotools_gets(const char *device_name, unsigned int *lines,
0206 unsigned int num_lines, unsigned int *values)
0207 {
0208 int fd, i;
0209 int ret;
0210 int ret_close;
0211 struct gpio_v2_line_config config;
0212 struct gpio_v2_line_values lv;
0213
0214 memset(&config, 0, sizeof(config));
0215 config.flags = GPIO_V2_LINE_FLAG_INPUT;
0216 ret = gpiotools_request_line(device_name, lines, num_lines,
0217 &config, CONSUMER);
0218 if (ret < 0)
0219 return ret;
0220
0221 fd = ret;
0222 for (i = 0; i < num_lines; i++)
0223 gpiotools_set_bit(&lv.mask, i);
0224 ret = gpiotools_get_values(fd, &lv);
0225 if (!ret)
0226 for (i = 0; i < num_lines; i++)
0227 values[i] = gpiotools_test_bit(lv.bits, i);
0228 ret_close = gpiotools_release_line(fd);
0229 return ret < 0 ? ret : ret_close;
0230 }
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 int gpiotools_set(const char *device_name, unsigned int line,
0243 unsigned int value)
0244 {
0245 unsigned int lines[] = {line};
0246
0247 return gpiotools_sets(device_name, lines, 1, &value);
0248 }
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263 int gpiotools_sets(const char *device_name, unsigned int *lines,
0264 unsigned int num_lines, unsigned int *values)
0265 {
0266 int ret, i;
0267 struct gpio_v2_line_config config;
0268
0269 memset(&config, 0, sizeof(config));
0270 config.flags = GPIO_V2_LINE_FLAG_OUTPUT;
0271 config.num_attrs = 1;
0272 config.attrs[0].attr.id = GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES;
0273 for (i = 0; i < num_lines; i++) {
0274 gpiotools_set_bit(&config.attrs[0].mask, i);
0275 gpiotools_assign_bit(&config.attrs[0].attr.values,
0276 i, values[i]);
0277 }
0278 ret = gpiotools_request_line(device_name, lines, num_lines,
0279 &config, CONSUMER);
0280 if (ret < 0)
0281 return ret;
0282
0283 return gpiotools_release_line(ret);
0284 }