1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 #include <fcntl.h>
7 #include <linux/input.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <syslog.h>
11 #include <sys/stat.h>
12 #include <sys/types.h>
13 #include <unistd.h>
14 #include <libudev.h>
15
16 #include "cras_util.h"
17 #include "cras_gpio_jack.h"
18
gpio_switch_open(const char * pathname)19 int gpio_switch_open(const char *pathname)
20 {
21 return open(pathname, O_RDONLY);
22 }
23
gpio_switch_read(int fd,void * buf,size_t n_bytes)24 int gpio_switch_read(int fd, void *buf, size_t n_bytes)
25 {
26 return read(fd, buf, n_bytes);
27 }
28
gpio_switch_eviocgname(int fd,char * name,size_t n_bytes)29 int gpio_switch_eviocgname(int fd, char *name, size_t n_bytes)
30 {
31 return ioctl(fd, EVIOCGNAME(n_bytes), name);
32 }
33
gpio_switch_eviocgbit(int fd,void * buf,size_t n_bytes)34 int gpio_switch_eviocgbit(int fd, void *buf, size_t n_bytes)
35 {
36 return ioctl(fd, EVIOCGBIT(EV_SW, n_bytes), buf);
37 }
38
gpio_switch_eviocgsw(int fd,void * bits,size_t n_bytes)39 int gpio_switch_eviocgsw(int fd, void *bits, size_t n_bytes)
40 {
41 return ioctl(fd, EVIOCGSW(n_bytes), bits);
42 }
43
sys_input_get_device_name(const char * path)44 char *sys_input_get_device_name(const char *path)
45 {
46 char name[256];
47 int fd = open(path, O_RDONLY);
48
49 if (fd >= 0) {
50 gpio_switch_eviocgname(fd, name, sizeof(name));
51 close(fd);
52 return strdup(name);
53 } else {
54 syslog(LOG_WARNING, "Could not open '%s': %s", path,
55 strerror(errno));
56 return NULL;
57 }
58 }
59
gpio_switch_list_for_each(gpio_switch_list_callback callback,void * arg)60 void gpio_switch_list_for_each(gpio_switch_list_callback callback, void *arg)
61 {
62 struct udev *udev;
63 struct udev_enumerate *enumerate;
64 struct udev_list_entry *dl;
65 struct udev_list_entry *dev_list_entry;
66
67 if (!callback)
68 return;
69
70 udev = udev_new();
71 assert(udev != NULL);
72 enumerate = udev_enumerate_new(udev);
73 udev_enumerate_add_match_subsystem(enumerate, "input");
74 udev_enumerate_scan_devices(enumerate);
75 dl = udev_enumerate_get_list_entry(enumerate);
76
77 udev_list_entry_foreach(dev_list_entry, dl)
78 {
79 const char *path = udev_list_entry_get_name(dev_list_entry);
80 struct udev_device *dev =
81 udev_device_new_from_syspath(udev, path);
82 const char *devnode = udev_device_get_devnode(dev);
83 char *ioctl_name;
84
85 if (devnode == NULL)
86 continue;
87
88 ioctl_name = sys_input_get_device_name(devnode);
89 if (ioctl_name == NULL)
90 continue;
91
92 if (callback(devnode, ioctl_name, arg)) {
93 free(ioctl_name);
94 break;
95 }
96 free(ioctl_name);
97 }
98 udev_enumerate_unref(enumerate);
99 udev_unref(udev);
100 }
101