0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <ctype.h>
0011 #include <errno.h>
0012 #include <fcntl.h>
0013 #include <inttypes.h>
0014 #include <linux/gpio.h>
0015 #include <poll.h>
0016 #include <stdbool.h>
0017 #include <stdio.h>
0018 #include <stdlib.h>
0019 #include <string.h>
0020 #include <sys/ioctl.h>
0021 #include <unistd.h>
0022
0023 int main(int argc, char **argv)
0024 {
0025 struct gpio_v2_line_info_changed chg;
0026 struct gpio_v2_line_info req;
0027 struct pollfd pfd;
0028 int fd, i, j, ret;
0029 char *event, *end;
0030 ssize_t rd;
0031
0032 if (argc < 3)
0033 goto err_usage;
0034
0035 fd = open(argv[1], O_RDWR | O_CLOEXEC);
0036 if (fd < 0) {
0037 perror("unable to open gpiochip");
0038 return EXIT_FAILURE;
0039 }
0040
0041 for (i = 0, j = 2; i < argc - 2; i++, j++) {
0042 memset(&req, 0, sizeof(req));
0043
0044 req.offset = strtoul(argv[j], &end, 0);
0045 if (*end != '\0')
0046 goto err_usage;
0047
0048 ret = ioctl(fd, GPIO_V2_GET_LINEINFO_WATCH_IOCTL, &req);
0049 if (ret) {
0050 perror("unable to set up line watch");
0051 return EXIT_FAILURE;
0052 }
0053 }
0054
0055 pfd.fd = fd;
0056 pfd.events = POLLIN | POLLPRI;
0057
0058 for (;;) {
0059 ret = poll(&pfd, 1, 5000);
0060 if (ret < 0) {
0061 perror("error polling the linechanged fd");
0062 return EXIT_FAILURE;
0063 } else if (ret > 0) {
0064 memset(&chg, 0, sizeof(chg));
0065 rd = read(pfd.fd, &chg, sizeof(chg));
0066 if (rd < 0 || rd != sizeof(chg)) {
0067 if (rd != sizeof(chg))
0068 errno = EIO;
0069
0070 perror("error reading line change event");
0071 return EXIT_FAILURE;
0072 }
0073
0074 switch (chg.event_type) {
0075 case GPIO_V2_LINE_CHANGED_REQUESTED:
0076 event = "requested";
0077 break;
0078 case GPIO_V2_LINE_CHANGED_RELEASED:
0079 event = "released";
0080 break;
0081 case GPIO_V2_LINE_CHANGED_CONFIG:
0082 event = "config changed";
0083 break;
0084 default:
0085 fprintf(stderr,
0086 "invalid event type received from the kernel\n");
0087 return EXIT_FAILURE;
0088 }
0089
0090 printf("line %u: %s at %" PRIu64 "\n",
0091 chg.info.offset, event, (uint64_t)chg.timestamp_ns);
0092 }
0093 }
0094
0095 return 0;
0096
0097 err_usage:
0098 printf("%s: <gpiochip> <line0> <line1> ...\n", argv[0]);
0099 return EXIT_FAILURE;
0100 }