--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <linux/input.h>
+#include <linux/input-event-codes.h>
+
+#include "mt_gpio.h"
+#include "signal_exit.h"
+#include "json_helpers.h"
+
+static void gpio_cb(EV_P_ ev_io *w_, int revents)
+{
+ static char *type = "gpio";
+
+ ev_io_gpio *w = (ev_io_gpio *)w_;
+ struct gpiod_line_event e;
+ int fd = w->fd;
+ char key = w->key;
+
+ if (gpiod_line_event_read_fd(w->w.fd, &e) == -1) {
+ perror("gpiod_line_event_read_fd");
+ return;
+ }
+
+ JSON_START();
+ JSON_STR(type);
+ JSON_NEXT();
+ JSON_CHAR(key);
+ JSON_END();
+}
+
+int mt_gpio_init(mt_gpio_t *self, struct ev_loop *loop, int fd)
+{
+ struct gpiod_chip *chip;
+ struct gpiod_line *line;
+ ev_io_gpio *w;
+ int lfd;
+
+ size_t i;
+
+ for (i = 0; i < GPIO_COUNT; i++) {
+ chip = gpiod_chip_open_by_number(pins[i].chip);
+ if (!chip) {
+ perror("gpiod_chip_open");
+ break;
+ }
+ line = gpiod_chip_get_line(chip, pins[i].offset);
+ if (!line) {
+ gpiod_chip_close(chip);
+ perror("gpiod_chip_get_line");
+ break;
+ }
+ if (gpiod_line_event_request_rising(line, GPIO_CONSUMER, GPIO_ACTIVE_LOW) == -1) {
+ gpiod_chip_close(chip);
+ perror("gpiod_line_event_request_rising");
+ break;
+ }
+ lfd = gpiod_line_event_get_fd(line);
+ if (lfd == -1) {
+ perror("gpiod_line_event_get_fd");
+ gpiod_chip_close(chip);
+ break;
+ }
+
+ self->chip[i] = chip;
+ w = &(self->w[i]);
+ w->fd = fd;
+ w->key = pins[i].key;
+ ev_io_init(&(w->w), gpio_cb, lfd, EV_READ);
+ ev_io_start(loop, (ev_io *)w);
+ }
+
+ if (i < GPIO_COUNT) {
+ for (size_t j = 0; j < i; j++) {
+ gpiod_chip_close(self->chip[j]);
+ }
+ return -1;
+ }
+
+ return 0;
+}
+
+void mt_gpio_deinit(mt_gpio_t *self)
+{
+ for (size_t i = 0; i < GPIO_COUNT; i++) {
+ gpiod_chip_close(self->chip[i]);
+ }
+}
+
+#ifndef NO_MAIN
+int main(int argc, char **argv)
+{
+ struct ev_loop *loop = EV_DEFAULT;
+ mt_gpio_t gpio;
+
+ set_signal_exit(loop);
+
+ if (mt_gpio_init(&gpio, loop, STDOUT_FILENO) != 0) {
+ return -1;
+ }
+
+ ev_run(loop, 0);
+
+ mt_gpio_deinit(&gpio);
+
+ return 0;
+}
+#endif