• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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