Home | History | Annotate | Download | only in server
      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