aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/input/misc
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/input/misc')
-rw-r--r--drivers/input/misc/Kconfig60
-rw-r--r--drivers/input/misc/Makefile12
-rw-r--r--drivers/input/misc/hp_sdc_rtc.c724
-rw-r--r--drivers/input/misc/m68kspkr.c83
-rw-r--r--drivers/input/misc/pcspkr.c97
-rw-r--r--drivers/input/misc/sparcspkr.c189
-rw-r--r--drivers/input/misc/uinput.c620
7 files changed, 1785 insertions, 0 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
new file mode 100644
index 000000000000..bb934e6d9636
--- /dev/null
+++ b/drivers/input/misc/Kconfig
@@ -0,0 +1,60 @@
1#
2# Input misc drivers configuration
3#
4menuconfig INPUT_MISC
5 bool "Miscellaneous devices"
6 help
7 Say Y here, and a list of miscellaneous input drivers will be displayed.
8 Everything that didn't fit into the other categories is here. This option
9 doesn't affect the kernel.
10
11 If unsure, say Y.
12
13if INPUT_MISC
14
15config INPUT_PCSPKR
16 tristate "PC Speaker support"
17 depends on ALPHA || X86 || X86_64 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES
18 help
19 Say Y here if you want the standard PC Speaker to be used for
20 bells and whistles.
21
22 If unsure, say Y.
23
24 To compile this driver as a module, choose M here: the
25 module will be called pcspkr.
26
27config INPUT_SPARCSPKR
28 tristate "SPARC Speaker support"
29 depends on PCI && (SPARC32 || SPARC64)
30 help
31 Say Y here if you want the standard Speaker on Sparc PCI systems
32 to be used for bells and whistles.
33
34 If unsure, say Y.
35
36 To compile this driver as a module, choose M here: the
37 module will be called sparcspkr.
38
39config INPUT_M68K_BEEP
40 tristate "M68k Beeper support"
41 depends on M68K
42
43config INPUT_UINPUT
44 tristate "User level driver support"
45 help
46 Say Y here if you want to support user level drivers for input
47 subsystem accessible under char device 10:223 - /dev/input/uinput.
48
49 To compile this driver as a module, choose M here: the
50 module will be called uinput.
51
52config HP_SDC_RTC
53 tristate "HP SDC Real Time Clock"
54 depends on GSC
55 select HP_SDC
56 help
57 Say Y here if you want to support the built-in real time clock
58 of the HP SDC controller.
59
60endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
new file mode 100644
index 000000000000..f8d01c69f349
--- /dev/null
+++ b/drivers/input/misc/Makefile
@@ -0,0 +1,12 @@
1#
2# Makefile for the input misc drivers.
3#
4
5# Each configuration option enables a list of files.
6
7obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
8obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
9obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
10obj-$(CONFIG_INPUT_98SPKR) += 98spkr.o
11obj-$(CONFIG_INPUT_UINPUT) += uinput.o
12obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c
new file mode 100644
index 000000000000..1cd7657f7e42
--- /dev/null
+++ b/drivers/input/misc/hp_sdc_rtc.c
@@ -0,0 +1,724 @@
1/*
2 * HP i8042 SDC + MSM-58321 BBRTC driver.
3 *
4 * Copyright (c) 2001 Brian S. Julin
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * Alternatively, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL").
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 *
29 * References:
30 * System Device Controller Microprocessor Firmware Theory of Operation
31 * for Part Number 1820-4784 Revision B. Dwg No. A-1820-4784-2
32 * efirtc.c by Stephane Eranian/Hewlett Packard
33 *
34 */
35
36#include <linux/hp_sdc.h>
37#include <linux/errno.h>
38#include <linux/types.h>
39#include <linux/init.h>
40#include <linux/module.h>
41#include <linux/time.h>
42#include <linux/miscdevice.h>
43#include <linux/proc_fs.h>
44#include <linux/poll.h>
45#include <linux/rtc.h>
46
47MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
48MODULE_DESCRIPTION("HP i8042 SDC + MSM-58321 RTC Driver");
49MODULE_LICENSE("Dual BSD/GPL");
50
51#define RTC_VERSION "1.10d"
52
53static unsigned long epoch = 2000;
54
55static struct semaphore i8042tregs;
56
57static hp_sdc_irqhook hp_sdc_rtc_isr;
58
59static struct fasync_struct *hp_sdc_rtc_async_queue;
60
61static DECLARE_WAIT_QUEUE_HEAD(hp_sdc_rtc_wait);
62
63static loff_t hp_sdc_rtc_llseek(struct file *file, loff_t offset, int origin);
64
65static ssize_t hp_sdc_rtc_read(struct file *file, char *buf,
66 size_t count, loff_t *ppos);
67
68static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file,
69 unsigned int cmd, unsigned long arg);
70
71static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait);
72
73static int hp_sdc_rtc_open(struct inode *inode, struct file *file);
74static int hp_sdc_rtc_release(struct inode *inode, struct file *file);
75static int hp_sdc_rtc_fasync (int fd, struct file *filp, int on);
76
77static int hp_sdc_rtc_read_proc(char *page, char **start, off_t off,
78 int count, int *eof, void *data);
79
80static void hp_sdc_rtc_isr (int irq, void *dev_id,
81 uint8_t status, uint8_t data)
82{
83 return;
84}
85
86static int hp_sdc_rtc_do_read_bbrtc (struct rtc_time *rtctm)
87{
88 struct semaphore tsem;
89 hp_sdc_transaction t;
90 uint8_t tseq[91];
91 int i;
92
93 i = 0;
94 while (i < 91) {
95 tseq[i++] = HP_SDC_ACT_DATAREG |
96 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN;
97 tseq[i++] = 0x01; /* write i8042[0x70] */
98 tseq[i] = i / 7; /* BBRTC reg address */
99 i++;
100 tseq[i++] = HP_SDC_CMD_DO_RTCR; /* Trigger command */
101 tseq[i++] = 2; /* expect 1 stat/dat pair back. */
102 i++; i++; /* buffer for stat/dat pair */
103 }
104 tseq[84] |= HP_SDC_ACT_SEMAPHORE;
105 t.endidx = 91;
106 t.seq = tseq;
107 t.act.semaphore = &tsem;
108 init_MUTEX_LOCKED(&tsem);
109
110 if (hp_sdc_enqueue_transaction(&t)) return -1;
111
112 down_interruptible(&tsem); /* Put ourselves to sleep for results. */
113
114 /* Check for nonpresence of BBRTC */
115 if (!((tseq[83] | tseq[90] | tseq[69] | tseq[76] |
116 tseq[55] | tseq[62] | tseq[34] | tseq[41] |
117 tseq[20] | tseq[27] | tseq[6] | tseq[13]) & 0x0f))
118 return -1;
119
120 memset(rtctm, 0, sizeof(struct rtc_time));
121 rtctm->tm_year = (tseq[83] & 0x0f) + (tseq[90] & 0x0f) * 10;
122 rtctm->tm_mon = (tseq[69] & 0x0f) + (tseq[76] & 0x0f) * 10;
123 rtctm->tm_mday = (tseq[55] & 0x0f) + (tseq[62] & 0x0f) * 10;
124 rtctm->tm_wday = (tseq[48] & 0x0f);
125 rtctm->tm_hour = (tseq[34] & 0x0f) + (tseq[41] & 0x0f) * 10;
126 rtctm->tm_min = (tseq[20] & 0x0f) + (tseq[27] & 0x0f) * 10;
127 rtctm->tm_sec = (tseq[6] & 0x0f) + (tseq[13] & 0x0f) * 10;
128
129 return 0;
130}
131
132static int hp_sdc_rtc_read_bbrtc (struct rtc_time *rtctm)
133{
134 struct rtc_time tm, tm_last;
135 int i = 0;
136
137 /* MSM-58321 has no read latch, so must read twice and compare. */
138
139 if (hp_sdc_rtc_do_read_bbrtc(&tm_last)) return -1;
140 if (hp_sdc_rtc_do_read_bbrtc(&tm)) return -1;
141
142 while (memcmp(&tm, &tm_last, sizeof(struct rtc_time))) {
143 if (i++ > 4) return -1;
144 memcpy(&tm_last, &tm, sizeof(struct rtc_time));
145 if (hp_sdc_rtc_do_read_bbrtc(&tm)) return -1;
146 }
147
148 memcpy(rtctm, &tm, sizeof(struct rtc_time));
149
150 return 0;
151}
152
153
154static int64_t hp_sdc_rtc_read_i8042timer (uint8_t loadcmd, int numreg)
155{
156 hp_sdc_transaction t;
157 uint8_t tseq[26] = {
158 HP_SDC_ACT_PRECMD | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN,
159 0,
160 HP_SDC_CMD_READ_T1, 2, 0, 0,
161 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN,
162 HP_SDC_CMD_READ_T2, 2, 0, 0,
163 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN,
164 HP_SDC_CMD_READ_T3, 2, 0, 0,
165 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN,
166 HP_SDC_CMD_READ_T4, 2, 0, 0,
167 HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN,
168 HP_SDC_CMD_READ_T5, 2, 0, 0
169 };
170
171 t.endidx = numreg * 5;
172
173 tseq[1] = loadcmd;
174 tseq[t.endidx - 4] |= HP_SDC_ACT_SEMAPHORE; /* numreg assumed > 1 */
175
176 t.seq = tseq;
177 t.act.semaphore = &i8042tregs;
178
179 down_interruptible(&i8042tregs); /* Sleep if output regs in use. */
180
181 if (hp_sdc_enqueue_transaction(&t)) return -1;
182
183 down_interruptible(&i8042tregs); /* Sleep until results come back. */
184 up(&i8042tregs);
185
186 return (tseq[5] |
187 ((uint64_t)(tseq[10]) << 8) | ((uint64_t)(tseq[15]) << 16) |
188 ((uint64_t)(tseq[20]) << 24) | ((uint64_t)(tseq[25]) << 32));
189}
190
191
192/* Read the i8042 real-time clock */
193static inline int hp_sdc_rtc_read_rt(struct timeval *res) {
194 int64_t raw;
195 uint32_t tenms;
196 unsigned int days;
197
198 raw = hp_sdc_rtc_read_i8042timer(HP_SDC_CMD_LOAD_RT, 5);
199 if (raw < 0) return -1;
200
201 tenms = (uint32_t)raw & 0xffffff;
202 days = (unsigned int)(raw >> 24) & 0xffff;
203
204 res->tv_usec = (suseconds_t)(tenms % 100) * 10000;
205 res->tv_sec = (time_t)(tenms / 100) + days * 86400;
206
207 return 0;
208}
209
210
211/* Read the i8042 fast handshake timer */
212static inline int hp_sdc_rtc_read_fhs(struct timeval *res) {
213 uint64_t raw;
214 unsigned int tenms;
215
216 raw = hp_sdc_rtc_read_i8042timer(HP_SDC_CMD_LOAD_FHS, 2);
217 if (raw < 0) return -1;
218
219 tenms = (unsigned int)raw & 0xffff;
220
221 res->tv_usec = (suseconds_t)(tenms % 100) * 10000;
222 res->tv_sec = (time_t)(tenms / 100);
223
224 return 0;
225}
226
227
228/* Read the i8042 match timer (a.k.a. alarm) */
229static inline int hp_sdc_rtc_read_mt(struct timeval *res) {
230 int64_t raw;
231 uint32_t tenms;
232
233 raw = hp_sdc_rtc_read_i8042timer(HP_SDC_CMD_LOAD_MT, 3);
234 if (raw < 0) return -1;
235
236 tenms = (uint32_t)raw & 0xffffff;
237
238 res->tv_usec = (suseconds_t)(tenms % 100) * 10000;
239 res->tv_sec = (time_t)(tenms / 100);
240
241 return 0;
242}
243
244
245/* Read the i8042 delay timer */
246static inline int hp_sdc_rtc_read_dt(struct timeval *res) {
247 int64_t raw;
248 uint32_t tenms;
249
250 raw = hp_sdc_rtc_read_i8042timer(HP_SDC_CMD_LOAD_DT, 3);
251 if (raw < 0) return -1;
252
253 tenms = (uint32_t)raw & 0xffffff;
254
255 res->tv_usec = (suseconds_t)(tenms % 100) * 10000;
256 res->tv_sec = (time_t)(tenms / 100);
257
258 return 0;
259}
260
261
262/* Read the i8042 cycle timer (a.k.a. periodic) */
263static inline int hp_sdc_rtc_read_ct(struct timeval *res) {
264 int64_t raw;
265 uint32_t tenms;
266
267 raw = hp_sdc_rtc_read_i8042timer(HP_SDC_CMD_LOAD_CT, 3);
268 if (raw < 0) return -1;
269
270 tenms = (uint32_t)raw & 0xffffff;
271
272 res->tv_usec = (suseconds_t)(tenms % 100) * 10000;
273 res->tv_sec = (time_t)(tenms / 100);
274
275 return 0;
276}
277
278
279/* Set the i8042 real-time clock */
280static int hp_sdc_rtc_set_rt (struct timeval *setto)
281{
282 uint32_t tenms;
283 unsigned int days;
284 hp_sdc_transaction t;
285 uint8_t tseq[11] = {
286 HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT,
287 HP_SDC_CMD_SET_RTMS, 3, 0, 0, 0,
288 HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT,
289 HP_SDC_CMD_SET_RTD, 2, 0, 0
290 };
291
292 t.endidx = 10;
293
294 if (0xffff < setto->tv_sec / 86400) return -1;
295 days = setto->tv_sec / 86400;
296 if (0xffff < setto->tv_usec / 1000000 / 86400) return -1;
297 days += ((setto->tv_sec % 86400) + setto->tv_usec / 1000000) / 86400;
298 if (days > 0xffff) return -1;
299
300 if (0xffffff < setto->tv_sec) return -1;
301 tenms = setto->tv_sec * 100;
302 if (0xffffff < setto->tv_usec / 10000) return -1;
303 tenms += setto->tv_usec / 10000;
304 if (tenms > 0xffffff) return -1;
305
306 tseq[3] = (uint8_t)(tenms & 0xff);
307 tseq[4] = (uint8_t)((tenms >> 8) & 0xff);
308 tseq[5] = (uint8_t)((tenms >> 16) & 0xff);
309
310 tseq[9] = (uint8_t)(days & 0xff);
311 tseq[10] = (uint8_t)((days >> 8) & 0xff);
312
313 t.seq = tseq;
314
315 if (hp_sdc_enqueue_transaction(&t)) return -1;
316 return 0;
317}
318
319/* Set the i8042 fast handshake timer */
320static int hp_sdc_rtc_set_fhs (struct timeval *setto)
321{
322 uint32_t tenms;
323 hp_sdc_transaction t;
324 uint8_t tseq[5] = {
325 HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT,
326 HP_SDC_CMD_SET_FHS, 2, 0, 0
327 };
328
329 t.endidx = 4;
330
331 if (0xffff < setto->tv_sec) return -1;
332 tenms = setto->tv_sec * 100;
333 if (0xffff < setto->tv_usec / 10000) return -1;
334 tenms += setto->tv_usec / 10000;
335 if (tenms > 0xffff) return -1;
336
337 tseq[3] = (uint8_t)(tenms & 0xff);
338 tseq[4] = (uint8_t)((tenms >> 8) & 0xff);
339
340 t.seq = tseq;
341
342 if (hp_sdc_enqueue_transaction(&t)) return -1;
343 return 0;
344}
345
346
347/* Set the i8042 match timer (a.k.a. alarm) */
348#define hp_sdc_rtc_set_mt (setto) \
349 hp_sdc_rtc_set_i8042timer(setto, HP_SDC_CMD_SET_MT)
350
351/* Set the i8042 delay timer */
352#define hp_sdc_rtc_set_dt (setto) \
353 hp_sdc_rtc_set_i8042timer(setto, HP_SDC_CMD_SET_DT)
354
355/* Set the i8042 cycle timer (a.k.a. periodic) */
356#define hp_sdc_rtc_set_ct (setto) \
357 hp_sdc_rtc_set_i8042timer(setto, HP_SDC_CMD_SET_CT)
358
359/* Set one of the i8042 3-byte wide timers */
360static int hp_sdc_rtc_set_i8042timer (struct timeval *setto, uint8_t setcmd)
361{
362 uint32_t tenms;
363 hp_sdc_transaction t;
364 uint8_t tseq[6] = {
365 HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT,
366 0, 3, 0, 0, 0
367 };
368
369 t.endidx = 6;
370
371 if (0xffffff < setto->tv_sec) return -1;
372 tenms = setto->tv_sec * 100;
373 if (0xffffff < setto->tv_usec / 10000) return -1;
374 tenms += setto->tv_usec / 10000;
375 if (tenms > 0xffffff) return -1;
376
377 tseq[1] = setcmd;
378 tseq[3] = (uint8_t)(tenms & 0xff);
379 tseq[4] = (uint8_t)((tenms >> 8) & 0xff);
380 tseq[5] = (uint8_t)((tenms >> 16) & 0xff);
381
382 t.seq = tseq;
383
384 if (hp_sdc_enqueue_transaction(&t)) {
385 return -1;
386 }
387 return 0;
388}
389
390static loff_t hp_sdc_rtc_llseek(struct file *file, loff_t offset, int origin)
391{
392 return -ESPIPE;
393}
394
395static ssize_t hp_sdc_rtc_read(struct file *file, char *buf,
396 size_t count, loff_t *ppos) {
397 ssize_t retval;
398
399 if (count < sizeof(unsigned long))
400 return -EINVAL;
401
402 retval = put_user(68, (unsigned long *)buf);
403 return retval;
404}
405
406static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait)
407{
408 unsigned long l;
409
410 l = 0;
411 if (l != 0)
412 return POLLIN | POLLRDNORM;
413 return 0;
414}
415
416static int hp_sdc_rtc_open(struct inode *inode, struct file *file)
417{
418 return 0;
419}
420
421static int hp_sdc_rtc_release(struct inode *inode, struct file *file)
422{
423 /* Turn off interrupts? */
424
425 if (file->f_flags & FASYNC) {
426 hp_sdc_rtc_fasync (-1, file, 0);
427 }
428
429 return 0;
430}
431
432static int hp_sdc_rtc_fasync (int fd, struct file *filp, int on)
433{
434 return fasync_helper (fd, filp, on, &hp_sdc_rtc_async_queue);
435}
436
437static int hp_sdc_rtc_proc_output (char *buf)
438{
439#define YN(bit) ("no")
440#define NY(bit) ("yes")
441 char *p;
442 struct rtc_time tm;
443 struct timeval tv;
444
445 memset(&tm, 0, sizeof(struct rtc_time));
446
447 p = buf;
448
449 if (hp_sdc_rtc_read_bbrtc(&tm)) {
450 p += sprintf(p, "BBRTC\t\t: READ FAILED!\n");
451 } else {
452 p += sprintf(p,
453 "rtc_time\t: %02d:%02d:%02d\n"
454 "rtc_date\t: %04d-%02d-%02d\n"
455 "rtc_epoch\t: %04lu\n",
456 tm.tm_hour, tm.tm_min, tm.tm_sec,
457 tm.tm_year + 1900, tm.tm_mon + 1,
458 tm.tm_mday, epoch);
459 }
460
461 if (hp_sdc_rtc_read_rt(&tv)) {
462 p += sprintf(p, "i8042 rtc\t: READ FAILED!\n");
463 } else {
464 p += sprintf(p, "i8042 rtc\t: %ld.%02d seconds\n",
465 tv.tv_sec, tv.tv_usec/1000);
466 }
467
468 if (hp_sdc_rtc_read_fhs(&tv)) {
469 p += sprintf(p, "handshake\t: READ FAILED!\n");
470 } else {
471 p += sprintf(p, "handshake\t: %ld.%02d seconds\n",
472 tv.tv_sec, tv.tv_usec/1000);
473 }
474
475 if (hp_sdc_rtc_read_mt(&tv)) {
476 p += sprintf(p, "alarm\t\t: READ FAILED!\n");
477 } else {
478 p += sprintf(p, "alarm\t\t: %ld.%02d seconds\n",
479 tv.tv_sec, tv.tv_usec/1000);
480 }
481
482 if (hp_sdc_rtc_read_dt(&tv)) {
483 p += sprintf(p, "delay\t\t: READ FAILED!\n");
484 } else {
485 p += sprintf(p, "delay\t\t: %ld.%02d seconds\n",
486 tv.tv_sec, tv.tv_usec/1000);
487 }
488
489 if (hp_sdc_rtc_read_ct(&tv)) {
490 p += sprintf(p, "periodic\t: READ FAILED!\n");
491 } else {
492 p += sprintf(p, "periodic\t: %ld.%02d seconds\n",
493 tv.tv_sec, tv.tv_usec/1000);
494 }
495
496 p += sprintf(p,
497 "DST_enable\t: %s\n"
498 "BCD\t\t: %s\n"
499 "24hr\t\t: %s\n"
500 "square_wave\t: %s\n"
501 "alarm_IRQ\t: %s\n"
502 "update_IRQ\t: %s\n"
503 "periodic_IRQ\t: %s\n"
504 "periodic_freq\t: %ld\n"
505 "batt_status\t: %s\n",
506 YN(RTC_DST_EN),
507 NY(RTC_DM_BINARY),
508 YN(RTC_24H),
509 YN(RTC_SQWE),
510 YN(RTC_AIE),
511 YN(RTC_UIE),
512 YN(RTC_PIE),
513 1UL,
514 1 ? "okay" : "dead");
515
516 return p - buf;
517#undef YN
518#undef NY
519}
520
521static int hp_sdc_rtc_read_proc(char *page, char **start, off_t off,
522 int count, int *eof, void *data)
523{
524 int len = hp_sdc_rtc_proc_output (page);
525 if (len <= off+count) *eof = 1;
526 *start = page + off;
527 len -= off;
528 if (len>count) len = count;
529 if (len<0) len = 0;
530 return len;
531}
532
533static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file,
534 unsigned int cmd, unsigned long arg)
535{
536#if 1
537 return -EINVAL;
538#else
539
540 struct rtc_time wtime;
541 struct timeval ttime;
542 int use_wtime = 0;
543
544 /* This needs major work. */
545
546 switch (cmd) {
547
548 case RTC_AIE_OFF: /* Mask alarm int. enab. bit */
549 case RTC_AIE_ON: /* Allow alarm interrupts. */
550 case RTC_PIE_OFF: /* Mask periodic int. enab. bit */
551 case RTC_PIE_ON: /* Allow periodic ints */
552 case RTC_UIE_ON: /* Allow ints for RTC updates. */
553 case RTC_UIE_OFF: /* Allow ints for RTC updates. */
554 {
555 /* We cannot mask individual user timers and we
556 cannot tell them apart when they occur, so it
557 would be disingenuous to succeed these IOCTLs */
558 return -EINVAL;
559 }
560 case RTC_ALM_READ: /* Read the present alarm time */
561 {
562 if (hp_sdc_rtc_read_mt(&ttime)) return -EFAULT;
563 if (hp_sdc_rtc_read_bbrtc(&wtime)) return -EFAULT;
564
565 wtime.tm_hour = ttime.tv_sec / 3600; ttime.tv_sec %= 3600;
566 wtime.tm_min = ttime.tv_sec / 60; ttime.tv_sec %= 60;
567 wtime.tm_sec = ttime.tv_sec;
568
569 break;
570 }
571 case RTC_IRQP_READ: /* Read the periodic IRQ rate. */
572 {
573 return put_user(hp_sdc_rtc_freq, (unsigned long *)arg);
574 }
575 case RTC_IRQP_SET: /* Set periodic IRQ rate. */
576 {
577 /*
578 * The max we can do is 100Hz.
579 */
580
581 if ((arg < 1) || (arg > 100)) return -EINVAL;
582 ttime.tv_sec = 0;
583 ttime.tv_usec = 1000000 / arg;
584 if (hp_sdc_rtc_set_ct(&ttime)) return -EFAULT;
585 hp_sdc_rtc_freq = arg;
586 return 0;
587 }
588 case RTC_ALM_SET: /* Store a time into the alarm */
589 {
590 /*
591 * This expects a struct hp_sdc_rtc_time. Writing 0xff means
592 * "don't care" or "match all" for PC timers. The HP SDC
593 * does not support that perk, but it could be emulated fairly
594 * easily. Only the tm_hour, tm_min and tm_sec are used.
595 * We could do it with 10ms accuracy with the HP SDC, if the
596 * rtc interface left us a way to do that.
597 */
598 struct hp_sdc_rtc_time alm_tm;
599
600 if (copy_from_user(&alm_tm, (struct hp_sdc_rtc_time*)arg,
601 sizeof(struct hp_sdc_rtc_time)))
602 return -EFAULT;
603
604 if (alm_tm.tm_hour > 23) return -EINVAL;
605 if (alm_tm.tm_min > 59) return -EINVAL;
606 if (alm_tm.tm_sec > 59) return -EINVAL;
607
608 ttime.sec = alm_tm.tm_hour * 3600 +
609 alm_tm.tm_min * 60 + alm_tm.tm_sec;
610 ttime.usec = 0;
611 if (hp_sdc_rtc_set_mt(&ttime)) return -EFAULT;
612 return 0;
613 }
614 case RTC_RD_TIME: /* Read the time/date from RTC */
615 {
616 if (hp_sdc_rtc_read_bbrtc(&wtime)) return -EFAULT;
617 break;
618 }
619 case RTC_SET_TIME: /* Set the RTC */
620 {
621 struct rtc_time hp_sdc_rtc_tm;
622 unsigned char mon, day, hrs, min, sec, leap_yr;
623 unsigned int yrs;
624
625 if (!capable(CAP_SYS_TIME))
626 return -EACCES;
627 if (copy_from_user(&hp_sdc_rtc_tm, (struct rtc_time *)arg,
628 sizeof(struct rtc_time)))
629 return -EFAULT;
630
631 yrs = hp_sdc_rtc_tm.tm_year + 1900;
632 mon = hp_sdc_rtc_tm.tm_mon + 1; /* tm_mon starts at zero */
633 day = hp_sdc_rtc_tm.tm_mday;
634 hrs = hp_sdc_rtc_tm.tm_hour;
635 min = hp_sdc_rtc_tm.tm_min;
636 sec = hp_sdc_rtc_tm.tm_sec;
637
638 if (yrs < 1970)
639 return -EINVAL;
640
641 leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
642
643 if ((mon > 12) || (day == 0))
644 return -EINVAL;
645 if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
646 return -EINVAL;
647 if ((hrs >= 24) || (min >= 60) || (sec >= 60))
648 return -EINVAL;
649
650 if ((yrs -= eH) > 255) /* They are unsigned */
651 return -EINVAL;
652
653
654 return 0;
655 }
656 case RTC_EPOCH_READ: /* Read the epoch. */
657 {
658 return put_user (epoch, (unsigned long *)arg);
659 }
660 case RTC_EPOCH_SET: /* Set the epoch. */
661 {
662 /*
663 * There were no RTC clocks before 1900.
664 */
665 if (arg < 1900)
666 return -EINVAL;
667 if (!capable(CAP_SYS_TIME))
668 return -EACCES;
669
670 epoch = arg;
671 return 0;
672 }
673 default:
674 return -EINVAL;
675 }
676 return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
677#endif
678}
679
680static struct file_operations hp_sdc_rtc_fops = {
681 .owner = THIS_MODULE,
682 .llseek = hp_sdc_rtc_llseek,
683 .read = hp_sdc_rtc_read,
684 .poll = hp_sdc_rtc_poll,
685 .ioctl = hp_sdc_rtc_ioctl,
686 .open = hp_sdc_rtc_open,
687 .release = hp_sdc_rtc_release,
688 .fasync = hp_sdc_rtc_fasync,
689};
690
691static struct miscdevice hp_sdc_rtc_dev = {
692 .minor = RTC_MINOR,
693 .name = "rtc_HIL",
694 .fops = &hp_sdc_rtc_fops
695};
696
697static int __init hp_sdc_rtc_init(void)
698{
699 int ret;
700
701 init_MUTEX(&i8042tregs);
702
703 if ((ret = hp_sdc_request_timer_irq(&hp_sdc_rtc_isr)))
704 return ret;
705 misc_register(&hp_sdc_rtc_dev);
706 create_proc_read_entry ("driver/rtc", 0, 0,
707 hp_sdc_rtc_read_proc, NULL);
708
709 printk(KERN_INFO "HP i8042 SDC + MSM-58321 RTC support loaded "
710 "(RTC v " RTC_VERSION ")\n");
711
712 return 0;
713}
714
715static void __exit hp_sdc_rtc_exit(void)
716{
717 remove_proc_entry ("driver/rtc", NULL);
718 misc_deregister(&hp_sdc_rtc_dev);
719 hp_sdc_release_timer_irq(hp_sdc_rtc_isr);
720 printk(KERN_INFO "HP i8042 SDC + MSM-58321 RTC support unloaded\n");
721}
722
723module_init(hp_sdc_rtc_init);
724module_exit(hp_sdc_rtc_exit);
diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c
new file mode 100644
index 000000000000..64abdd98d482
--- /dev/null
+++ b/drivers/input/misc/m68kspkr.c
@@ -0,0 +1,83 @@
1/*
2 * m68k beeper driver for Linux
3 *
4 * Copyright (c) 2002 Richard Zidlicky
5 * Copyright (c) 2002 Vojtech Pavlik
6 * Copyright (c) 1992 Orest Zborowski
7 *
8 */
9
10/*
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published by
13 * the Free Software Foundation
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/input.h>
20#include <asm/machdep.h>
21#include <asm/io.h>
22
23MODULE_AUTHOR("Richard Zidlicky <rz@linux-m68k.org>");
24MODULE_DESCRIPTION("m68k beeper driver");
25MODULE_LICENSE("GPL");
26
27static char m68kspkr_name[] = "m68k beeper";
28static char m68kspkr_phys[] = "m68k/generic";
29static struct input_dev m68kspkr_dev;
30
31static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
32{
33 unsigned int count = 0;
34
35 if (type != EV_SND)
36 return -1;
37
38 switch (code) {
39 case SND_BELL: if (value) value = 1000;
40 case SND_TONE: break;
41 default: return -1;
42 }
43
44 if (value > 20 && value < 32767)
45 count = 1193182 / value;
46
47 mach_beep(count, -1);
48
49 return 0;
50}
51
52static int __init m68kspkr_init(void)
53{
54 if (!mach_beep){
55 printk("%s: no lowlevel beep support\n", m68kspkr_name);
56 return -1;
57 }
58
59 m68kspkr_dev.evbit[0] = BIT(EV_SND);
60 m68kspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
61 m68kspkr_dev.event = m68kspkr_event;
62
63 m68kspkr_dev.name = m68kspkr_name;
64 m68kspkr_dev.phys = m68kspkr_phys;
65 m68kspkr_dev.id.bustype = BUS_HOST;
66 m68kspkr_dev.id.vendor = 0x001f;
67 m68kspkr_dev.id.product = 0x0001;
68 m68kspkr_dev.id.version = 0x0100;
69
70 input_register_device(&m68kspkr_dev);
71
72 printk(KERN_INFO "input: %s\n", m68kspkr_name);
73
74 return 0;
75}
76
77static void __exit m68kspkr_exit(void)
78{
79 input_unregister_device(&m68kspkr_dev);
80}
81
82module_init(m68kspkr_init);
83module_exit(m68kspkr_exit);
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
new file mode 100644
index 000000000000..3013194f462b
--- /dev/null
+++ b/drivers/input/misc/pcspkr.c
@@ -0,0 +1,97 @@
1/*
2 * PC Speaker beeper driver for Linux
3 *
4 * Copyright (c) 2002 Vojtech Pavlik
5 * Copyright (c) 1992 Orest Zborowski
6 *
7 */
8
9/*
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation
13 */
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/input.h>
19#include <asm/8253pit.h>
20#include <asm/io.h>
21
22MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
23MODULE_DESCRIPTION("PC Speaker beeper driver");
24MODULE_LICENSE("GPL");
25
26static char pcspkr_name[] = "PC Speaker";
27static char pcspkr_phys[] = "isa0061/input0";
28static struct input_dev pcspkr_dev;
29
30static DEFINE_SPINLOCK(i8253_beep_lock);
31
32static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
33{
34 unsigned int count = 0;
35 unsigned long flags;
36
37 if (type != EV_SND)
38 return -1;
39
40 switch (code) {
41 case SND_BELL: if (value) value = 1000;
42 case SND_TONE: break;
43 default: return -1;
44 }
45
46 if (value > 20 && value < 32767)
47 count = PIT_TICK_RATE / value;
48
49 spin_lock_irqsave(&i8253_beep_lock, flags);
50
51 if (count) {
52 /* enable counter 2 */
53 outb_p(inb_p(0x61) | 3, 0x61);
54 /* set command for counter 2, 2 byte write */
55 outb_p(0xB6, 0x43);
56 /* select desired HZ */
57 outb_p(count & 0xff, 0x42);
58 outb((count >> 8) & 0xff, 0x42);
59 } else {
60 /* disable counter 2 */
61 outb(inb_p(0x61) & 0xFC, 0x61);
62 }
63
64 spin_unlock_irqrestore(&i8253_beep_lock, flags);
65
66 return 0;
67}
68
69static int __init pcspkr_init(void)
70{
71 pcspkr_dev.evbit[0] = BIT(EV_SND);
72 pcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
73 pcspkr_dev.event = pcspkr_event;
74
75 pcspkr_dev.name = pcspkr_name;
76 pcspkr_dev.phys = pcspkr_phys;
77 pcspkr_dev.id.bustype = BUS_ISA;
78 pcspkr_dev.id.vendor = 0x001f;
79 pcspkr_dev.id.product = 0x0001;
80 pcspkr_dev.id.version = 0x0100;
81
82 input_register_device(&pcspkr_dev);
83
84 printk(KERN_INFO "input: %s\n", pcspkr_name);
85
86 return 0;
87}
88
89static void __exit pcspkr_exit(void)
90{
91 input_unregister_device(&pcspkr_dev);
92 /* turn off the speaker */
93 pcspkr_event(NULL, EV_SND, SND_BELL, 0);
94}
95
96module_init(pcspkr_init);
97module_exit(pcspkr_exit);
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
new file mode 100644
index 000000000000..cdc3fb3d5f46
--- /dev/null
+++ b/drivers/input/misc/sparcspkr.c
@@ -0,0 +1,189 @@
1/*
2 * Driver for PC-speaker like devices found on various Sparc systems.
3 *
4 * Copyright (c) 2002 Vojtech Pavlik
5 * Copyright (c) 2002 David S. Miller (davem@redhat.com)
6 */
7#include <linux/config.h>
8#include <linux/kernel.h>
9#include <linux/module.h>
10#include <linux/init.h>
11#include <linux/input.h>
12
13#include <asm/io.h>
14#include <asm/ebus.h>
15#ifdef CONFIG_SPARC64
16#include <asm/isa.h>
17#endif
18
19MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
20MODULE_DESCRIPTION("PC Speaker beeper driver");
21MODULE_LICENSE("GPL");
22
23static unsigned long beep_iobase;
24
25static char *sparcspkr_isa_name = "Sparc ISA Speaker";
26static char *sparcspkr_ebus_name = "Sparc EBUS Speaker";
27static char *sparcspkr_phys = "sparc/input0";
28static struct input_dev sparcspkr_dev;
29
30DEFINE_SPINLOCK(beep_lock);
31
32static void __init init_sparcspkr_struct(void)
33{
34 sparcspkr_dev.evbit[0] = BIT(EV_SND);
35 sparcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
36
37 sparcspkr_dev.phys = sparcspkr_phys;
38 sparcspkr_dev.id.bustype = BUS_ISA;
39 sparcspkr_dev.id.vendor = 0x001f;
40 sparcspkr_dev.id.product = 0x0001;
41 sparcspkr_dev.id.version = 0x0100;
42}
43
44static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
45{
46 unsigned int count = 0;
47 unsigned long flags;
48
49 if (type != EV_SND)
50 return -1;
51
52 switch (code) {
53 case SND_BELL: if (value) value = 1000;
54 case SND_TONE: break;
55 default: return -1;
56 }
57
58 if (value > 20 && value < 32767)
59 count = 1193182 / value;
60
61 spin_lock_irqsave(&beep_lock, flags);
62
63 /* EBUS speaker only has on/off state, the frequency does not
64 * appear to be programmable.
65 */
66 if (count) {
67 if (beep_iobase & 0x2UL)
68 outb(1, beep_iobase);
69 else
70 outl(1, beep_iobase);
71 } else {
72 if (beep_iobase & 0x2UL)
73 outb(0, beep_iobase);
74 else
75 outl(0, beep_iobase);
76 }
77
78 spin_unlock_irqrestore(&beep_lock, flags);
79
80 return 0;
81}
82
83static int __init init_ebus_beep(struct linux_ebus_device *edev)
84{
85 beep_iobase = edev->resource[0].start;
86
87 init_sparcspkr_struct();
88
89 sparcspkr_dev.name = sparcspkr_ebus_name;
90 sparcspkr_dev.event = ebus_spkr_event;
91
92 input_register_device(&sparcspkr_dev);
93
94 printk(KERN_INFO "input: %s\n", sparcspkr_ebus_name);
95 return 0;
96}
97
98#ifdef CONFIG_SPARC64
99static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
100{
101 unsigned int count = 0;
102 unsigned long flags;
103
104 if (type != EV_SND)
105 return -1;
106
107 switch (code) {
108 case SND_BELL: if (value) value = 1000;
109 case SND_TONE: break;
110 default: return -1;
111 }
112
113 if (value > 20 && value < 32767)
114 count = 1193182 / value;
115
116 spin_lock_irqsave(&beep_lock, flags);
117
118 if (count) {
119 /* enable counter 2 */
120 outb(inb(beep_iobase + 0x61) | 3, beep_iobase + 0x61);
121 /* set command for counter 2, 2 byte write */
122 outb(0xB6, beep_iobase + 0x43);
123 /* select desired HZ */
124 outb(count & 0xff, beep_iobase + 0x42);
125 outb((count >> 8) & 0xff, beep_iobase + 0x42);
126 } else {
127 /* disable counter 2 */
128 outb(inb_p(beep_iobase + 0x61) & 0xFC, beep_iobase + 0x61);
129 }
130
131 spin_unlock_irqrestore(&beep_lock, flags);
132
133 return 0;
134}
135
136static int __init init_isa_beep(struct sparc_isa_device *isa_dev)
137{
138 beep_iobase = isa_dev->resource.start;
139
140 init_sparcspkr_struct();
141
142 sparcspkr_dev.name = sparcspkr_isa_name;
143 sparcspkr_dev.event = isa_spkr_event;
144 sparcspkr_dev.id.bustype = BUS_ISA;
145
146 input_register_device(&sparcspkr_dev);
147
148 printk(KERN_INFO "input: %s\n", sparcspkr_isa_name);
149 return 0;
150}
151#endif
152
153static int __init sparcspkr_init(void)
154{
155 struct linux_ebus *ebus;
156 struct linux_ebus_device *edev = NULL;
157#ifdef CONFIG_SPARC64
158 struct sparc_isa_bridge *isa_br;
159 struct sparc_isa_device *isa_dev;
160#endif
161
162 for_each_ebus(ebus) {
163 for_each_ebusdev(edev, ebus) {
164 if (!strcmp(edev->prom_name, "beep"))
165 return init_ebus_beep(edev);
166 }
167 }
168#ifdef CONFIG_SPARC64
169 for_each_isa(isa_br) {
170 for_each_isadev(isa_dev, isa_br) {
171 /* A hack, the beep device's base lives in
172 * the DMA isa node.
173 */
174 if (!strcmp(isa_dev->prom_name, "dma"))
175 return init_isa_beep(isa_dev);
176 }
177 }
178#endif
179
180 return -ENODEV;
181}
182
183static void __exit sparcspkr_exit(void)
184{
185 input_unregister_device(&sparcspkr_dev);
186}
187
188module_init(sparcspkr_init);
189module_exit(sparcspkr_exit);
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
new file mode 100644
index 000000000000..158c8e845ff9
--- /dev/null
+++ b/drivers/input/misc/uinput.c
@@ -0,0 +1,620 @@
1/*
2 * User level driver support for input subsystem
3 *
4 * Heavily based on evdev.c by Vojtech Pavlik
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
21 *
22 * Changes/Revisions:
23 * 0.2 16/10/2004 (Micah Dowty <micah@navi.cx>)
24 * - added force feedback support
25 * - added UI_SET_PHYS
26 * 0.1 20/06/2002
27 * - first public version
28 */
29#include <linux/poll.h>
30#include <linux/slab.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/input.h>
34#include <linux/smp_lock.h>
35#include <linux/fs.h>
36#include <linux/miscdevice.h>
37#include <linux/uinput.h>
38
39static int uinput_dev_open(struct input_dev *dev)
40{
41 return 0;
42}
43
44static void uinput_dev_close(struct input_dev *dev)
45{
46
47}
48
49static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
50{
51 struct uinput_device *udev;
52
53 udev = dev->private;
54
55 udev->buff[udev->head].type = type;
56 udev->buff[udev->head].code = code;
57 udev->buff[udev->head].value = value;
58 do_gettimeofday(&udev->buff[udev->head].time);
59 udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;
60
61 wake_up_interruptible(&udev->waitq);
62
63 return 0;
64}
65
66static int uinput_request_alloc_id(struct input_dev *dev, struct uinput_request *request)
67{
68 /* Atomically allocate an ID for the given request. Returns 0 on success. */
69 struct uinput_device *udev = dev->private;
70 int id;
71
72 down(&udev->requests_sem);
73 for (id=0; id<UINPUT_NUM_REQUESTS; id++)
74 if (!udev->requests[id]) {
75 udev->requests[id] = request;
76 request->id = id;
77 up(&udev->requests_sem);
78 return 0;
79 }
80 up(&udev->requests_sem);
81 return -1;
82}
83
84static struct uinput_request* uinput_request_find(struct uinput_device *udev, int id)
85{
86 /* Find an input request, by ID. Returns NULL if the ID isn't valid. */
87 if (id >= UINPUT_NUM_REQUESTS || id < 0)
88 return NULL;
89 if (udev->requests[id]->completed)
90 return NULL;
91 return udev->requests[id];
92}
93
94static void uinput_request_init(struct input_dev *dev, struct uinput_request *request, int code)
95{
96 struct uinput_device *udev = dev->private;
97
98 memset(request, 0, sizeof(struct uinput_request));
99 request->code = code;
100 init_waitqueue_head(&request->waitq);
101
102 /* Allocate an ID. If none are available right away, wait. */
103 request->retval = wait_event_interruptible(udev->requests_waitq,
104 !uinput_request_alloc_id(dev, request));
105}
106
107static void uinput_request_submit(struct input_dev *dev, struct uinput_request *request)
108{
109 struct uinput_device *udev = dev->private;
110 int retval;
111
112 /* Tell our userspace app about this new request by queueing an input event */
113 uinput_dev_event(dev, EV_UINPUT, request->code, request->id);
114
115 /* Wait for the request to complete */
116 retval = wait_event_interruptible(request->waitq, request->completed);
117 if (retval)
118 request->retval = retval;
119
120 /* Release this request's ID, let others know it's available */
121 udev->requests[request->id] = NULL;
122 wake_up_interruptible(&udev->requests_waitq);
123}
124
125static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
126{
127 struct uinput_request request;
128
129 if (!test_bit(EV_FF, dev->evbit))
130 return -ENOSYS;
131
132 uinput_request_init(dev, &request, UI_FF_UPLOAD);
133 if (request.retval)
134 return request.retval;
135 request.u.effect = effect;
136 uinput_request_submit(dev, &request);
137 return request.retval;
138}
139
140static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
141{
142 struct uinput_request request;
143
144 if (!test_bit(EV_FF, dev->evbit))
145 return -ENOSYS;
146
147 uinput_request_init(dev, &request, UI_FF_ERASE);
148 if (request.retval)
149 return request.retval;
150 request.u.effect_id = effect_id;
151 uinput_request_submit(dev, &request);
152 return request.retval;
153}
154
155static int uinput_create_device(struct uinput_device *udev)
156{
157 if (!udev->dev->name) {
158 printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
159 return -EINVAL;
160 }
161
162 udev->dev->open = uinput_dev_open;
163 udev->dev->close = uinput_dev_close;
164 udev->dev->event = uinput_dev_event;
165 udev->dev->upload_effect = uinput_dev_upload_effect;
166 udev->dev->erase_effect = uinput_dev_erase_effect;
167 udev->dev->private = udev;
168
169 init_waitqueue_head(&(udev->waitq));
170
171 input_register_device(udev->dev);
172
173 set_bit(UIST_CREATED, &(udev->state));
174
175 return 0;
176}
177
178static int uinput_destroy_device(struct uinput_device *udev)
179{
180 if (!test_bit(UIST_CREATED, &(udev->state))) {
181 printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME);
182 return -EINVAL;
183 }
184
185 input_unregister_device(udev->dev);
186
187 clear_bit(UIST_CREATED, &(udev->state));
188
189 return 0;
190}
191
192static int uinput_open(struct inode *inode, struct file *file)
193{
194 struct uinput_device *newdev;
195 struct input_dev *newinput;
196
197 newdev = kmalloc(sizeof(struct uinput_device), GFP_KERNEL);
198 if (!newdev)
199 goto error;
200 memset(newdev, 0, sizeof(struct uinput_device));
201 init_MUTEX(&newdev->requests_sem);
202 init_waitqueue_head(&newdev->requests_waitq);
203
204 newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
205 if (!newinput)
206 goto cleanup;
207 memset(newinput, 0, sizeof(struct input_dev));
208
209 newdev->dev = newinput;
210
211 file->private_data = newdev;
212
213 return 0;
214cleanup:
215 kfree(newdev);
216error:
217 return -ENOMEM;
218}
219
220static int uinput_validate_absbits(struct input_dev *dev)
221{
222 unsigned int cnt;
223 int retval = 0;
224
225 for (cnt = 0; cnt < ABS_MAX + 1; cnt++) {
226 if (!test_bit(cnt, dev->absbit))
227 continue;
228
229 if ((dev->absmax[cnt] <= dev->absmin[cnt])) {
230 printk(KERN_DEBUG
231 "%s: invalid abs[%02x] min:%d max:%d\n",
232 UINPUT_NAME, cnt,
233 dev->absmin[cnt], dev->absmax[cnt]);
234 retval = -EINVAL;
235 break;
236 }
237
238 if (dev->absflat[cnt] > (dev->absmax[cnt] - dev->absmin[cnt])) {
239 printk(KERN_DEBUG
240 "%s: absflat[%02x] out of range: %d "
241 "(min:%d/max:%d)\n",
242 UINPUT_NAME, cnt, dev->absflat[cnt],
243 dev->absmin[cnt], dev->absmax[cnt]);
244 retval = -EINVAL;
245 break;
246 }
247 }
248 return retval;
249}
250
251static int uinput_alloc_device(struct file *file, const char __user *buffer, size_t count)
252{
253 struct uinput_user_dev *user_dev;
254 struct input_dev *dev;
255 struct uinput_device *udev;
256 int size,
257 retval;
258
259 retval = count;
260
261 udev = file->private_data;
262 dev = udev->dev;
263
264 user_dev = kmalloc(sizeof(*user_dev), GFP_KERNEL);
265 if (!user_dev) {
266 retval = -ENOMEM;
267 goto exit;
268 }
269
270 if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) {
271 retval = -EFAULT;
272 goto exit;
273 }
274
275 if (NULL != dev->name)
276 kfree(dev->name);
277
278 size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
279 dev->name = kmalloc(size, GFP_KERNEL);
280 if (!dev->name) {
281 retval = -ENOMEM;
282 goto exit;
283 }
284
285 strlcpy(dev->name, user_dev->name, size);
286 dev->id.bustype = user_dev->id.bustype;
287 dev->id.vendor = user_dev->id.vendor;
288 dev->id.product = user_dev->id.product;
289 dev->id.version = user_dev->id.version;
290 dev->ff_effects_max = user_dev->ff_effects_max;
291
292 size = sizeof(int) * (ABS_MAX + 1);
293 memcpy(dev->absmax, user_dev->absmax, size);
294 memcpy(dev->absmin, user_dev->absmin, size);
295 memcpy(dev->absfuzz, user_dev->absfuzz, size);
296 memcpy(dev->absflat, user_dev->absflat, size);
297
298 /* check if absmin/absmax/absfuzz/absflat are filled as
299 * told in Documentation/input/input-programming.txt */
300 if (test_bit(EV_ABS, dev->evbit)) {
301 retval = uinput_validate_absbits(dev);
302 if (retval < 0)
303 kfree(dev->name);
304 }
305
306exit:
307 kfree(user_dev);
308 return retval;
309}
310
311static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
312{
313 struct uinput_device *udev = file->private_data;
314
315 if (test_bit(UIST_CREATED, &(udev->state))) {
316 struct input_event ev;
317
318 if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
319 return -EFAULT;
320 input_event(udev->dev, ev.type, ev.code, ev.value);
321 }
322 else
323 count = uinput_alloc_device(file, buffer, count);
324
325 return count;
326}
327
328static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
329{
330 struct uinput_device *udev = file->private_data;
331 int retval = 0;
332
333 if (!test_bit(UIST_CREATED, &(udev->state)))
334 return -ENODEV;
335
336 if ((udev->head == udev->tail) && (file->f_flags & O_NONBLOCK))
337 return -EAGAIN;
338
339 retval = wait_event_interruptible(udev->waitq,
340 (udev->head != udev->tail) ||
341 !test_bit(UIST_CREATED, &(udev->state)));
342
343 if (retval)
344 return retval;
345
346 if (!test_bit(UIST_CREATED, &(udev->state)))
347 return -ENODEV;
348
349 while ((udev->head != udev->tail) &&
350 (retval + sizeof(struct input_event) <= count)) {
351 if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
352 sizeof(struct input_event))) return -EFAULT;
353 udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
354 retval += sizeof(struct input_event);
355 }
356
357 return retval;
358}
359
360static unsigned int uinput_poll(struct file *file, poll_table *wait)
361{
362 struct uinput_device *udev = file->private_data;
363
364 poll_wait(file, &udev->waitq, wait);
365
366 if (udev->head != udev->tail)
367 return POLLIN | POLLRDNORM;
368
369 return 0;
370}
371
372static int uinput_burn_device(struct uinput_device *udev)
373{
374 if (test_bit(UIST_CREATED, &(udev->state)))
375 uinput_destroy_device(udev);
376
377 if (NULL != udev->dev->name)
378 kfree(udev->dev->name);
379 if (NULL != udev->dev->phys)
380 kfree(udev->dev->phys);
381
382 kfree(udev->dev);
383 kfree(udev);
384
385 return 0;
386}
387
388static int uinput_close(struct inode *inode, struct file *file)
389{
390 return uinput_burn_device(file->private_data);
391}
392
393static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
394{
395 int retval = 0;
396 struct uinput_device *udev;
397 void __user *p = (void __user *)arg;
398 struct uinput_ff_upload ff_up;
399 struct uinput_ff_erase ff_erase;
400 struct uinput_request *req;
401 int length;
402
403 udev = file->private_data;
404
405 /* device attributes can not be changed after the device is created */
406 switch (cmd) {
407 case UI_SET_EVBIT:
408 case UI_SET_KEYBIT:
409 case UI_SET_RELBIT:
410 case UI_SET_ABSBIT:
411 case UI_SET_MSCBIT:
412 case UI_SET_LEDBIT:
413 case UI_SET_SNDBIT:
414 case UI_SET_FFBIT:
415 case UI_SET_PHYS:
416 if (test_bit(UIST_CREATED, &(udev->state)))
417 return -EINVAL;
418 }
419
420 switch (cmd) {
421 case UI_DEV_CREATE:
422 retval = uinput_create_device(udev);
423 break;
424
425 case UI_DEV_DESTROY:
426 retval = uinput_destroy_device(udev);
427 break;
428
429 case UI_SET_EVBIT:
430 if (arg > EV_MAX) {
431 retval = -EINVAL;
432 break;
433 }
434 set_bit(arg, udev->dev->evbit);
435 break;
436
437 case UI_SET_KEYBIT:
438 if (arg > KEY_MAX) {
439 retval = -EINVAL;
440 break;
441 }
442 set_bit(arg, udev->dev->keybit);
443 break;
444
445 case UI_SET_RELBIT:
446 if (arg > REL_MAX) {
447 retval = -EINVAL;
448 break;
449 }
450 set_bit(arg, udev->dev->relbit);
451 break;
452
453 case UI_SET_ABSBIT:
454 if (arg > ABS_MAX) {
455 retval = -EINVAL;
456 break;
457 }
458 set_bit(arg, udev->dev->absbit);
459 break;
460
461 case UI_SET_MSCBIT:
462 if (arg > MSC_MAX) {
463 retval = -EINVAL;
464 break;
465 }
466 set_bit(arg, udev->dev->mscbit);
467 break;
468
469 case UI_SET_LEDBIT:
470 if (arg > LED_MAX) {
471 retval = -EINVAL;
472 break;
473 }
474 set_bit(arg, udev->dev->ledbit);
475 break;
476
477 case UI_SET_SNDBIT:
478 if (arg > SND_MAX) {
479 retval = -EINVAL;
480 break;
481 }
482 set_bit(arg, udev->dev->sndbit);
483 break;
484
485 case UI_SET_FFBIT:
486 if (arg > FF_MAX) {
487 retval = -EINVAL;
488 break;
489 }
490 set_bit(arg, udev->dev->ffbit);
491 break;
492
493 case UI_SET_PHYS:
494 length = strnlen_user(p, 1024);
495 if (length <= 0) {
496 retval = -EFAULT;
497 break;
498 }
499 if (NULL != udev->dev->phys)
500 kfree(udev->dev->phys);
501 udev->dev->phys = kmalloc(length, GFP_KERNEL);
502 if (!udev->dev->phys) {
503 retval = -ENOMEM;
504 break;
505 }
506 if (copy_from_user(udev->dev->phys, p, length)) {
507 retval = -EFAULT;
508 kfree(udev->dev->phys);
509 udev->dev->phys = NULL;
510 break;
511 }
512 udev->dev->phys[length-1] = '\0';
513 break;
514
515 case UI_BEGIN_FF_UPLOAD:
516 if (copy_from_user(&ff_up, p, sizeof(ff_up))) {
517 retval = -EFAULT;
518 break;
519 }
520 req = uinput_request_find(udev, ff_up.request_id);
521 if (!(req && req->code==UI_FF_UPLOAD && req->u.effect)) {
522 retval = -EINVAL;
523 break;
524 }
525 ff_up.retval = 0;
526 memcpy(&ff_up.effect, req->u.effect, sizeof(struct ff_effect));
527 if (copy_to_user(p, &ff_up, sizeof(ff_up))) {
528 retval = -EFAULT;
529 break;
530 }
531 break;
532
533 case UI_BEGIN_FF_ERASE:
534 if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) {
535 retval = -EFAULT;
536 break;
537 }
538 req = uinput_request_find(udev, ff_erase.request_id);
539 if (!(req && req->code==UI_FF_ERASE)) {
540 retval = -EINVAL;
541 break;
542 }
543 ff_erase.retval = 0;
544 ff_erase.effect_id = req->u.effect_id;
545 if (copy_to_user(p, &ff_erase, sizeof(ff_erase))) {
546 retval = -EFAULT;
547 break;
548 }
549 break;
550
551 case UI_END_FF_UPLOAD:
552 if (copy_from_user(&ff_up, p, sizeof(ff_up))) {
553 retval = -EFAULT;
554 break;
555 }
556 req = uinput_request_find(udev, ff_up.request_id);
557 if (!(req && req->code==UI_FF_UPLOAD && req->u.effect)) {
558 retval = -EINVAL;
559 break;
560 }
561 req->retval = ff_up.retval;
562 memcpy(req->u.effect, &ff_up.effect, sizeof(struct ff_effect));
563 req->completed = 1;
564 wake_up_interruptible(&req->waitq);
565 break;
566
567 case UI_END_FF_ERASE:
568 if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) {
569 retval = -EFAULT;
570 break;
571 }
572 req = uinput_request_find(udev, ff_erase.request_id);
573 if (!(req && req->code==UI_FF_ERASE)) {
574 retval = -EINVAL;
575 break;
576 }
577 req->retval = ff_erase.retval;
578 req->completed = 1;
579 wake_up_interruptible(&req->waitq);
580 break;
581
582 default:
583 retval = -EINVAL;
584 }
585 return retval;
586}
587
588static struct file_operations uinput_fops = {
589 .owner = THIS_MODULE,
590 .open = uinput_open,
591 .release = uinput_close,
592 .read = uinput_read,
593 .write = uinput_write,
594 .poll = uinput_poll,
595 .ioctl = uinput_ioctl,
596};
597
598static struct miscdevice uinput_misc = {
599 .fops = &uinput_fops,
600 .minor = UINPUT_MINOR,
601 .name = UINPUT_NAME,
602};
603
604static int __init uinput_init(void)
605{
606 return misc_register(&uinput_misc);
607}
608
609static void __exit uinput_exit(void)
610{
611 misc_deregister(&uinput_misc);
612}
613
614MODULE_AUTHOR("Aristeu Sergio Rozanski Filho");
615MODULE_DESCRIPTION("User level driver support for input subsystem");
616MODULE_LICENSE("GPL");
617
618module_init(uinput_init);
619module_exit(uinput_exit);
620