]> rtime.felk.cvut.cz Git - coffee/mt-apps.git/blob - mt_gpio.c
mt_server: Use "%s" format string in syslog()
[coffee/mt-apps.git] / mt_gpio.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <sys/stat.h>
5 #include <fcntl.h>
6 #include <linux/input.h>
7 #include <linux/input-event-codes.h>
8
9 #include "mt_gpio.h"
10 #include "signal_exit.h"
11 #include "json_helpers.h"
12
13 static void gpio_cb(EV_P_ ev_io *w_, int revents)
14 {
15     static char *type = "gpio";
16
17     ev_io_gpio *w = (ev_io_gpio *)w_;
18     struct gpiod_line_event e;
19     int fd = w->fd;
20     char key = w->key;
21
22     if (gpiod_line_event_read_fd(w->w.fd, &e) == -1) {
23         perror("gpiod_line_event_read_fd");
24         return;
25     }
26
27     JSON_START();
28     JSON_STR(type);
29     JSON_NEXT();
30     JSON_CHAR(key);
31     JSON_END();
32 }
33
34 int mt_gpio_init(mt_gpio_t *self, struct ev_loop *loop, int fd)
35 {
36     struct gpiod_chip *chip;
37     struct gpiod_line *line;
38     ev_io_gpio *w;
39     int lfd;
40
41     size_t i;
42
43     for (i = 0; i < GPIO_COUNT; i++) {
44         chip = gpiod_chip_open_by_number(pins[i].chip);
45         if (!chip) {
46             perror("gpiod_chip_open");
47             break;
48         }
49         line = gpiod_chip_get_line(chip, pins[i].offset);
50         if (!line) {
51             gpiod_chip_close(chip);
52             perror("gpiod_chip_get_line");
53             break;
54         }
55         if (gpiod_line_event_request_rising(line, GPIO_CONSUMER, GPIO_ACTIVE_LOW) == -1) {
56             gpiod_chip_close(chip);
57             perror("gpiod_line_event_request_rising");
58             break;
59         }
60         lfd = gpiod_line_event_get_fd(line);
61         if (lfd == -1) {
62             perror("gpiod_line_event_get_fd");
63             gpiod_chip_close(chip);
64             break;
65         }
66
67         self->chip[i] = chip;
68         w = &(self->w[i]);
69         w->fd = fd;
70         w->key = pins[i].key;
71         ev_io_init(&(w->w), gpio_cb, lfd, EV_READ);
72         ev_io_start(loop, (ev_io *)w);
73     }
74
75     if (i < GPIO_COUNT) {
76         for (size_t j = 0; j < i; j++) {
77             gpiod_chip_close(self->chip[j]);
78         }
79         return -1;
80     }
81
82     return 0;
83 }
84
85 void mt_gpio_deinit(mt_gpio_t *self)
86 {
87     for (size_t i = 0; i < GPIO_COUNT; i++) {
88         gpiod_chip_close(self->chip[i]);
89     }
90 }
91
92 #ifndef NO_MAIN
93 int main(int argc, char **argv)
94 {
95     struct ev_loop *loop = EV_DEFAULT;
96     mt_gpio_t gpio;
97
98     set_signal_exit(loop);
99
100     if (mt_gpio_init(&gpio, loop, STDOUT_FILENO) != 0) {
101         return -1;
102     }
103
104     ev_run(loop, 0);
105
106     mt_gpio_deinit(&gpio);
107     ev_loop_destroy(loop);
108
109     return 0;
110 }
111 #endif