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 19 int gpio_switch_open(const char *pathname) 20 { 21 return open(pathname, O_RDONLY); 22 } 23 24 int gpio_switch_read(int fd, void *buf, size_t n_bytes) 25 { 26 return read(fd, buf, n_bytes); 27 } 28 29 int gpio_switch_eviocgname(int fd, char *name, size_t n_bytes) 30 { 31 return ioctl(fd, EVIOCGNAME(n_bytes), name); 32 } 33 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 39 int gpio_switch_eviocgsw(int fd, void *bits, size_t n_bytes) 40 { 41 return ioctl(fd, EVIOCGSW(n_bytes), bits); 42 } 43 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", 55 path, strerror(errno)); 56 return NULL; 57 } 58 } 59 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 const char *path = udev_list_entry_get_name(dev_list_entry); 79 struct udev_device *dev = udev_device_new_from_syspath(udev, 80 path); 81 const char *devnode = udev_device_get_devnode(dev); 82 char *ioctl_name; 83 84 if (devnode == NULL) 85 continue; 86 87 ioctl_name = sys_input_get_device_name(devnode); 88 if (ioctl_name == NULL) 89 continue; 90 91 if (callback(devnode, ioctl_name, arg)) { 92 free(ioctl_name); 93 break; 94 } 95 free(ioctl_name); 96 } 97 udev_enumerate_unref(enumerate); 98 udev_unref(udev); 99 } 100