diff options
Diffstat (limited to 'samples')
-rw-r--r-- | samples/Kconfig | 6 | ||||
-rw-r--r-- | samples/Makefile | 2 | ||||
-rw-r--r-- | samples/hidraw/Makefile | 10 | ||||
-rw-r--r-- | samples/hidraw/hid-example.c | 178 |
4 files changed, 195 insertions, 1 deletions
diff --git a/samples/Kconfig b/samples/Kconfig index 41063e7592d2..96a7572853f7 100644 --- a/samples/Kconfig +++ b/samples/Kconfig | |||
@@ -61,4 +61,10 @@ config SAMPLE_KDB | |||
61 | Build an example of how to dynamically add the hello | 61 | Build an example of how to dynamically add the hello |
62 | command to the kdb shell. | 62 | command to the kdb shell. |
63 | 63 | ||
64 | config SAMPLE_HIDRAW | ||
65 | bool "Build simple hidraw example" | ||
66 | depends on HIDRAW && HEADERS_CHECK | ||
67 | help | ||
68 | Build an example of how to use hidraw from userspace. | ||
69 | |||
64 | endif # SAMPLES | 70 | endif # SAMPLES |
diff --git a/samples/Makefile b/samples/Makefile index f26c0959fd86..6280817c2b7e 100644 --- a/samples/Makefile +++ b/samples/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # Makefile for Linux samples code | 1 | # Makefile for Linux samples code |
2 | 2 | ||
3 | obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ | 3 | obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ |
4 | hw_breakpoint/ kfifo/ kdb/ | 4 | hw_breakpoint/ kfifo/ kdb/ hidraw/ |
diff --git a/samples/hidraw/Makefile b/samples/hidraw/Makefile new file mode 100644 index 000000000000..382eeae77bd6 --- /dev/null +++ b/samples/hidraw/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # kbuild trick to avoid linker error. Can be omitted if a module is built. | ||
2 | obj- := dummy.o | ||
3 | |||
4 | # List of programs to build | ||
5 | hostprogs-y := hid-example | ||
6 | |||
7 | # Tell kbuild to always build the programs | ||
8 | always := $(hostprogs-y) | ||
9 | |||
10 | HOSTCFLAGS_hid-example.o += -I$(objtree)/usr/include | ||
diff --git a/samples/hidraw/hid-example.c b/samples/hidraw/hid-example.c new file mode 100644 index 000000000000..816e2dcda7ca --- /dev/null +++ b/samples/hidraw/hid-example.c | |||
@@ -0,0 +1,178 @@ | |||
1 | /* | ||
2 | * Hidraw Userspace Example | ||
3 | * | ||
4 | * Copyright (c) 2010 Alan Ott <alan@signal11.us> | ||
5 | * Copyright (c) 2010 Signal 11 Software | ||
6 | * | ||
7 | * The code may be used by anyone for any purpose, | ||
8 | * and can serve as a starting point for developing | ||
9 | * applications using hidraw. | ||
10 | */ | ||
11 | |||
12 | /* Linux */ | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/input.h> | ||
15 | #include <linux/hidraw.h> | ||
16 | |||
17 | /* | ||
18 | * Ugly hack to work around failing compilation on systems that don't | ||
19 | * yet populate new version of hidraw.h to userspace. | ||
20 | * | ||
21 | * If you need this, please have your distro update the kernel headers. | ||
22 | */ | ||
23 | #ifndef HIDIOCSFEATURE | ||
24 | #define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len) | ||
25 | #define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len) | ||
26 | #endif | ||
27 | |||
28 | /* Unix */ | ||
29 | #include <sys/ioctl.h> | ||
30 | #include <sys/types.h> | ||
31 | #include <sys/stat.h> | ||
32 | #include <fcntl.h> | ||
33 | #include <unistd.h> | ||
34 | |||
35 | /* C */ | ||
36 | #include <stdio.h> | ||
37 | #include <string.h> | ||
38 | #include <stdlib.h> | ||
39 | #include <errno.h> | ||
40 | |||
41 | const char *bus_str(int bus); | ||
42 | |||
43 | int main(int argc, char **argv) | ||
44 | { | ||
45 | int fd; | ||
46 | int i, res, desc_size = 0; | ||
47 | char buf[256]; | ||
48 | struct hidraw_report_descriptor rpt_desc; | ||
49 | struct hidraw_devinfo info; | ||
50 | |||
51 | /* Open the Device with non-blocking reads. In real life, | ||
52 | don't use a hard coded path; use libudev instead. */ | ||
53 | fd = open("/dev/hidraw0", O_RDWR|O_NONBLOCK); | ||
54 | |||
55 | if (fd < 0) { | ||
56 | perror("Unable to open device"); | ||
57 | return 1; | ||
58 | } | ||
59 | |||
60 | memset(&rpt_desc, 0x0, sizeof(rpt_desc)); | ||
61 | memset(&info, 0x0, sizeof(info)); | ||
62 | memset(buf, 0x0, sizeof(buf)); | ||
63 | |||
64 | /* Get Report Descriptor Size */ | ||
65 | res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size); | ||
66 | if (res < 0) | ||
67 | perror("HIDIOCGRDESCSIZE"); | ||
68 | else | ||
69 | printf("Report Descriptor Size: %d\n", desc_size); | ||
70 | |||
71 | /* Get Report Descriptor */ | ||
72 | rpt_desc.size = desc_size; | ||
73 | res = ioctl(fd, HIDIOCGRDESC, &rpt_desc); | ||
74 | if (res < 0) { | ||
75 | perror("HIDIOCGRDESC"); | ||
76 | } else { | ||
77 | printf("Report Descriptor:\n"); | ||
78 | for (i = 0; i < rpt_desc.size; i++) | ||
79 | printf("%hhx ", rpt_desc.value[i]); | ||
80 | puts("\n"); | ||
81 | } | ||
82 | |||
83 | /* Get Raw Name */ | ||
84 | res = ioctl(fd, HIDIOCGRAWNAME(256), buf); | ||
85 | if (res < 0) | ||
86 | perror("HIDIOCGRAWNAME"); | ||
87 | else | ||
88 | printf("Raw Name: %s\n", buf); | ||
89 | |||
90 | /* Get Physical Location */ | ||
91 | res = ioctl(fd, HIDIOCGRAWPHYS(256), buf); | ||
92 | if (res < 0) | ||
93 | perror("HIDIOCGRAWPHYS"); | ||
94 | else | ||
95 | printf("Raw Phys: %s\n", buf); | ||
96 | |||
97 | /* Get Raw Info */ | ||
98 | res = ioctl(fd, HIDIOCGRAWINFO, &info); | ||
99 | if (res < 0) { | ||
100 | perror("HIDIOCGRAWINFO"); | ||
101 | } else { | ||
102 | printf("Raw Info:\n"); | ||
103 | printf("\tbustype: %d (%s)\n", | ||
104 | info.bustype, bus_str(info.bustype)); | ||
105 | printf("\tvendor: 0x%04hx\n", info.vendor); | ||
106 | printf("\tproduct: 0x%04hx\n", info.product); | ||
107 | } | ||
108 | |||
109 | /* Set Feature */ | ||
110 | buf[0] = 0x9; /* Report Number */ | ||
111 | buf[1] = 0xff; | ||
112 | buf[2] = 0xff; | ||
113 | buf[3] = 0xff; | ||
114 | res = ioctl(fd, HIDIOCSFEATURE(4), buf); | ||
115 | if (res < 0) | ||
116 | perror("HIDIOCSFEATURE"); | ||
117 | else | ||
118 | printf("ioctl HIDIOCGFEATURE returned: %d\n", res); | ||
119 | |||
120 | /* Get Feature */ | ||
121 | buf[0] = 0x9; /* Report Number */ | ||
122 | res = ioctl(fd, HIDIOCGFEATURE(256), buf); | ||
123 | if (res < 0) { | ||
124 | perror("HIDIOCGFEATURE"); | ||
125 | } else { | ||
126 | printf("ioctl HIDIOCGFEATURE returned: %d\n", res); | ||
127 | printf("Report data (not containing the report number):\n\t"); | ||
128 | for (i = 0; i < res; i++) | ||
129 | printf("%hhx ", buf[i]); | ||
130 | puts("\n"); | ||
131 | } | ||
132 | |||
133 | /* Send a Report to the Device */ | ||
134 | buf[0] = 0x1; /* Report Number */ | ||
135 | buf[1] = 0x77; | ||
136 | res = write(fd, buf, 2); | ||
137 | if (res < 0) { | ||
138 | printf("Error: %d\n", errno); | ||
139 | perror("write"); | ||
140 | } else { | ||
141 | printf("write() wrote %d bytes\n", res); | ||
142 | } | ||
143 | |||
144 | /* Get a report from the device */ | ||
145 | res = read(fd, buf, 16); | ||
146 | if (res < 0) { | ||
147 | perror("read"); | ||
148 | } else { | ||
149 | printf("read() read %d bytes:\n\t", res); | ||
150 | for (i = 0; i < res; i++) | ||
151 | printf("%hhx ", buf[i]); | ||
152 | puts("\n"); | ||
153 | } | ||
154 | close(fd); | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | const char * | ||
159 | bus_str(int bus) | ||
160 | { | ||
161 | switch (bus) { | ||
162 | case BUS_USB: | ||
163 | return "USB"; | ||
164 | break; | ||
165 | case BUS_HIL: | ||
166 | return "HIL"; | ||
167 | break; | ||
168 | case BUS_BLUETOOTH: | ||
169 | return "Bluetooth"; | ||
170 | break; | ||
171 | case BUS_VIRTUAL: | ||
172 | return "Virtual"; | ||
173 | break; | ||
174 | default: | ||
175 | return "Other"; | ||
176 | break; | ||
177 | } | ||
178 | } | ||