]> git.hungrycats.org Git - linux/commitdiff
This (re)implements getkeycode/setkeycode, kbd_rate and kd_mksound
authorVojtech Pavlik <vojtech@suse.cz>
Sun, 25 Aug 2002 17:21:22 +0000 (19:21 +0200)
committerVojtech Pavlik <vojtech@suse.cz>
Sun, 25 Aug 2002 17:21:22 +0000 (19:21 +0200)
as functions interfacing to the input core. PC-Speaker handling is
moved to a separate file. Uinput is moved to a input/misc directory.

19 files changed:
drivers/char/keyboard.c
drivers/char/vt.c
drivers/input/Config.help
drivers/input/Config.in
drivers/input/Makefile
drivers/input/input.c
drivers/input/keyboard/amikbd.c
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/newtonkbd.c
drivers/input/keyboard/sunkbd.c
drivers/input/keyboard/xtkbd.c
drivers/input/misc/Config.help [new file with mode: 0644]
drivers/input/misc/Config.in [new file with mode: 0644]
drivers/input/misc/Makefile [new file with mode: 0644]
drivers/input/misc/pcspkr.c [new file with mode: 0644]
drivers/input/misc/uinput.c [new file with mode: 0644]
drivers/input/uinput.c [deleted file]
include/linux/input.h
include/linux/vt_kern.h

index e745830426607609c471a82a954c644d27ce0550..d773e736e427f314b7220590c088f53ba7d320db 100644 (file)
@@ -80,7 +80,7 @@ static fn_handler_fn FN_HANDLERS;
 static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
 
 /*
- * Variables/functions exported for vt_ioctl.c
+ * Variables exported for vt_ioctl.c
  */
 
 /* maximum values each key_handler can handle */
@@ -98,21 +98,7 @@ static struct kbd_struct *kbd = kbd_table;
 int spawnpid, spawnsig;
 
 /*
- * Translation of scancodes to keycodes.
- */
-
-int getkeycode(unsigned int scancode)
-{
-       return 0; /* FIXME */
-}
-
-int setkeycode(unsigned int scancode, unsigned int keycode)
-{
-       return 0; /* FIXME */
-}
-
-/*
- * Variables/function exported for vt.c
+ * Variables exported for vt.c
  */
 
 int shift_state = 0;
@@ -138,6 +124,114 @@ static struct ledptr {
        unsigned char valid:1;
 } ledptrs[3];
 
+/*
+ * Translation of scancodes to keycodes. We set them on only the first attached
+ * keyboard - for per-keyboard setting, /dev/input/event is more useful.
+ */
+int getkeycode(unsigned int scancode)
+{
+       struct input_handle *handle;
+       unsigned int keycode;
+
+       for (handle = kbd_handler.handle; handle; handle = handle->hnext) 
+               if (handle->dev->keycodesize) break;
+
+       if (!handle->dev->keycodesize)
+               return -ENODEV;
+
+       switch (handle->dev->keycodesize) {
+               case 1: keycode = *(u8*)(handle->dev->keycode + scancode); break;
+               case 2: keycode = *(u16*)(handle->dev->keycode + scancode * 2); break;
+               case 4: keycode = *(u32*)(handle->dev->keycode + scancode * 4); break;
+               default: return -EINVAL;
+       }
+
+       return keycode;
+}
+
+int setkeycode(unsigned int scancode, unsigned int keycode)
+{
+       struct input_handle *handle;
+
+       for (handle = kbd_handler.handle; handle; handle = handle->hnext) 
+               if (handle->dev->keycodesize) break;
+
+       if (!handle->dev->keycodesize)
+               return -ENODEV;
+
+       switch (handle->dev->keycodesize) {
+               case 1: *(u8*)(handle->dev->keycode + scancode) = keycode; break;
+               case 2: *(u16*)(handle->dev->keycode + scancode * 2) = keycode; break;
+               case 4: *(u32*)(handle->dev->keycode + scancode * 4) = keycode; break;
+       }
+       
+       return 0;
+}
+
+/*
+ * Making beeps and bells. 
+ */
+static void kd_nosound(unsigned long ignored)
+{
+       struct input_handle *handle;
+
+       for (handle = kbd_handler.handle; handle; handle = handle->hnext)
+               if (test_bit(EV_SND, handle->dev->evbit)) {
+                       if (test_bit(SND_TONE, handle->dev->sndbit))
+                               input_event(handle->dev, EV_SND, SND_TONE, 0);
+                       if (test_bit(SND_BELL, handle->dev->sndbit))
+                               input_event(handle->dev, EV_SND, SND_BELL, 0);
+               }
+}
+
+static struct timer_list kd_mksound_timer = { function: kd_nosound };
+
+void kd_mksound(unsigned int hz, unsigned int ticks)
+{
+       struct input_handle *handle;
+
+       del_timer(&kd_mksound_timer);
+
+       if (hz) {
+               for (handle = kbd_handler.handle; handle; handle = handle->hnext)
+                       if (test_bit(EV_SND, handle->dev->evbit)) {
+                               if (test_bit(SND_TONE, handle->dev->sndbit)) {
+                                       input_event(handle->dev, EV_SND, SND_TONE, hz);
+                                       break;
+                               }
+                               if (test_bit(SND_BELL, handle->dev->sndbit)) {
+                                       input_event(handle->dev, EV_SND, SND_BELL, 1);
+                                       break;
+                               }
+                       }
+               if (ticks)
+                       mod_timer(&kd_mksound_timer, jiffies + ticks);
+       } else
+               kd_nosound(0);
+}
+
+/*
+ * Setting the keyboard rate.
+ */
+int kbd_rate(struct kbd_repeat *rep)
+{
+       struct input_handle *handle;
+
+       if (rep->rate < 0 || rep->delay < 0)
+               return -EINVAL;
+
+       for (handle = kbd_handler.handle; handle; handle = handle->hnext)
+               if (test_bit(EV_REP, handle->dev->evbit)) {
+                       if (rep->rate > HZ) rep->rate = HZ;
+                       handle->dev->rep[REP_PERIOD] = rep->rate ? (HZ / rep->rate) : 0;
+                       handle->dev->rep[REP_DELAY] = rep->delay * HZ / 1000;
+                       if (handle->dev->rep[REP_DELAY] < handle->dev->rep[REP_PERIOD])
+                               handle->dev->rep[REP_DELAY] = handle->dev->rep[REP_PERIOD];
+               }
+       
+       return 0;
+}
+
 /*
  * Helper Functions.
  */
index a432564866bfcb61a5ffbe70f32f75c7bbba5db9..a932da89770eafe138a04d40783b77a46cfdeb5b 100644 (file)
@@ -75,78 +75,6 @@ unsigned int video_scan_lines;
 #define GPLAST 0x3df
 #define GPNUM (GPLAST - GPFIRST + 1)
 
-/*
- * Generates sound of some frequency for some number of clock ticks
- *
- * If freq is 0, will turn off sound, else will turn it on for that time.
- * If msec is 0, will return immediately, else will sleep for msec time, then
- * turn sound off.
- *
- * We also return immediately, which is what was implied within the X
- * comments - KDMKTONE doesn't put the process to sleep.
- */
-
-#if defined(__i386__) || defined(__alpha__) || defined(__powerpc__) \
-    || (defined(__mips__) && defined(CONFIG_ISA)) \
-    || (defined(__arm__) && defined(CONFIG_HOST_FOOTBRIDGE)) \
-    || defined(__x86_64__)
-
-static void
-kd_nosound(unsigned long ignored)
-{
-       /* disable counter 2 */
-       outb(inb_p(0x61)&0xFC, 0x61);
-       return;
-}
-
-void
-_kd_mksound(unsigned int hz, unsigned int ticks)
-{
-       static struct timer_list sound_timer = { function: kd_nosound };
-       unsigned int count = 0;
-       unsigned long flags;
-
-       if (hz > 20 && hz < 32767)
-               count = 1193180 / hz;
-       
-       local_irq_save(flags); // FIXME: is this safe?
-       del_timer(&sound_timer);
-       if (count) {
-               /* enable counter 2 */
-               outb_p(inb_p(0x61)|3, 0x61);
-               /* set command for counter 2, 2 byte write */
-               outb_p(0xB6, 0x43);
-               /* select desired HZ */
-               outb_p(count & 0xff, 0x42);
-               outb((count >> 8) & 0xff, 0x42);
-
-               if (ticks) {
-                       sound_timer.expires = jiffies+ticks;
-                       add_timer(&sound_timer);
-               }
-       } else
-               kd_nosound(0);
-       local_irq_restore(flags);
-       return;
-}
-
-#else
-
-void
-_kd_mksound(unsigned int hz, unsigned int ticks)
-{
-}
-
-#endif
-
-int _kbd_rate(struct kbd_repeat *rep)
-{
-       return -EINVAL;
-}
-
-void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound;
-int (*kbd_rate)(struct kbd_repeat *rep) = _kbd_rate;
-
 #define i (tmp.kb_index)
 #define s (tmp.kb_table)
 #define v (tmp.kb_value)
index 8ebdeaea24a76dfcaba072a6b86ed813d8d85b20..2e3ff3acd8c915b04073a0eb2cc55cd2178d4676 100644 (file)
@@ -88,12 +88,3 @@ CONFIG_INPUT_EVBUG
   inserted in and removed from the running kernel whenever you want).
   The module will be called joydev.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
-
-CONFIG_INPUT_UINPUT
-  Say Y here if you want to support user level drivers for input
-  subsystem accessible under char device 10:223 - /dev/input/uinput.
-
-  This driver is also available as a module ( = code which can be
-  inserted in and removed from the running kernel whenever you want).
-  The module will be called uinput.o.  If you want to compile it as a
-  module, say M here and read <file:Documentation/modules.txt>.            
index f1c79594f0410bd4fe26e2ad06ddb8cad568098a..0568cfd77e2d07571c0fd404e9032d0e6f8dccc9 100644 (file)
@@ -22,7 +22,6 @@ if [ "$CONFIG_INPUT_TSDEV" != "n" ]; then
 fi
 dep_tristate '  Event interface' CONFIG_INPUT_EVDEV $CONFIG_INPUT
 dep_tristate '  Event debugging' CONFIG_INPUT_EVBUG $CONFIG_INPUT
-dep_tristate '  User level driver support' CONFIG_INPUT_UINPUT $CONFIG_INPUT $CONFIG_EXPERIMENTAL
 
 comment 'Input I/O drivers'
 source drivers/input/gameport/Config.in
@@ -34,6 +33,7 @@ if [ "$CONFIG_INPUT" != "n" ]; then
    source drivers/input/mouse/Config.in
    source drivers/input/joystick/Config.in
    source drivers/input/touchscreen/Config.in
+   source drivers/input/misc/Config.in
 fi
 
 endmenu
index 64983696a66ff963e6fa0b7cc48f9cedfaa30c79..f7232ccdf1ec84bdb105ccd34ca24771b7d7e4a5 100644 (file)
@@ -15,12 +15,12 @@ obj-$(CONFIG_INPUT_EVDEV)   += evdev.o
 obj-$(CONFIG_INPUT_TSDEV)      += tsdev.o
 obj-$(CONFIG_INPUT_POWER)      += power.o
 obj-$(CONFIG_INPUT_EVBUG)      += evbug.o
-obj-$(CONFIG_INPUT_UINPUT)     += uinput.o
 
 obj-$(CONFIG_INPUT_KEYBOARD)   += keyboard/
 obj-$(CONFIG_INPUT_MOUSE)      += mouse/
 obj-$(CONFIG_INPUT_JOYSTICK)   += joystick/
 obj-$(CONFIG_INPUT_TOUCHSCREEN)        += touchscreen/
+obj-$(CONFIG_INPUT_MISC)       += misc/
 
 # The global Rules.make.
 
index 0bd17fbd49fd4f4456a2cb2bafde56afc59867ca..da4ed6e6dcf52b8d8487bc2fe66327ad4b60d11d 100644 (file)
@@ -105,7 +105,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
 
                        change_bit(code, dev->key);
 
-                       if (test_bit(EV_REP, dev->evbit) && value) {
+                       if (test_bit(EV_REP, dev->evbit) && dev->rep[REP_PERIOD] && value) {
                                dev->repeat_key = code;
                                mod_timer(&dev->timer, jiffies + dev->rep[REP_DELAY]);
                        }
@@ -165,10 +165,9 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
 
                case EV_SND:
        
-                       if (code > SND_MAX || !test_bit(code, dev->sndbit) || !!test_bit(code, dev->snd) == value)
+                       if (code > SND_MAX || !test_bit(code, dev->sndbit))
                                return;
 
-                       change_bit(code, dev->snd);
                        if (dev->event) dev->event(dev, type, code, value);     
        
                        break;
index c3ea9648ec592d9056a4694cf03d57d120601e56..d9db20739a26e5b83c570a3e31c2475f3c7c1a09 100644 (file)
@@ -114,6 +114,8 @@ static int __init amikbd_init(void)
 
        amikbd_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
        amikbd_dev.keycode = amikbd_keycode;
+       amikbd_dev.keycodesize = sizeof(unsigned char);
+       amikbd_dev.keycodemax = ARRAY_SIZE(amikbd_keycode);
 
        for (i = 0; i < 0x78; i++)
                if (amikbd_keycode[i])
index 479e0ab9fe5dd9028129a8eda101aaded4e08b97..63ae062f92a6488dc40b18f72cbe641d3e4bb706 100644 (file)
@@ -470,6 +470,8 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
        atkbd->serio = serio;
 
        atkbd->dev.keycode = atkbd->keycode;
+       atkbd->dev.keycodesize = sizeof(unsigned char);
+       atkbd->dev.keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
        atkbd->dev.event = atkbd_event;
        atkbd->dev.private = atkbd;
 
index 2c7fff08b1ab4bdc4fbc0d33e4a69a77615b5f94..11e08e58d9acce6c105bc546f91650c244d34496 100644 (file)
@@ -94,6 +94,8 @@ void nkbd_connect(struct serio *serio, struct serio_dev *dev)
        nkbd->serio = serio;
 
        nkbd->dev.keycode = nkbd->keycode;
+       nkbd->dev.keycodesize = sizeof(unsigned char);
+       nkbd->dev.keycodemax = ARRAY_SIZE(nkbd_keycode);
        nkbd->dev.private = nkbd;
 
        serio->private = nkbd;
index 8e41f20ad5906d049ddf46c638d606e0f380316f..4145d5a04ecb2114f8f5a018c720f52dd7c178c5 100644 (file)
@@ -245,6 +245,9 @@ static void sunkbd_connect(struct serio *serio, struct serio_dev *dev)
        sunkbd->tq.data = sunkbd;
 
        sunkbd->dev.keycode = sunkbd->keycode;
+       sunkbd->dev.keycodesize = sizeof(unsigned char);
+       sunkbd->dev.keycodemax = ARRAY_SIZE(sunkbd_keycode);
+
        sunkbd->dev.event = sunkbd_event;
        sunkbd->dev.private = sunkbd;
 
index bcf4eb098fdf1c97950ddf1a11d6da361bbf53fb..57c6a06afba9e851af9459dfd3db2a9a82cb7dc7 100644 (file)
@@ -101,6 +101,8 @@ void xtkbd_connect(struct serio *serio, struct serio_dev *dev)
        xtkbd->serio = serio;
 
        xtkbd->dev.keycode = xtkbd->keycode;
+       xtkbd->dev.keycodesize = sizeof(unsigned char);
+       xtkbd->dev.keycodemax = ARRAY_SIZE(xtkbd_keycode);
        xtkbd->dev.private = xtkbd;
 
        serio->private = xtkbd;
diff --git a/drivers/input/misc/Config.help b/drivers/input/misc/Config.help
new file mode 100644 (file)
index 0000000..8aa138c
--- /dev/null
@@ -0,0 +1,28 @@
+CONFIG_INPUT_MISC
+
+  Say Y here, and a list of miscellaneous input drivers will be displayed.
+  Everything that didn't fit into the other categories is here. This option
+  doesn't affect the kernel.
+
+  If unsure, say Y.
+
+CONFIG_INPUT_PCSPKR
+  Say Y here if you want the standard PC Speaker to be used for
+  bells and whistles.
+
+  If unsure, say Y.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called pcspkr.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+
+
+CONFIG_INPUT_UINPUT
+  Say Y here if you want to support user level drivers for input
+  subsystem accessible under char device 10:223 - /dev/input/uinput.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called uinput.o.  If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.            
diff --git a/drivers/input/misc/Config.in b/drivers/input/misc/Config.in
new file mode 100644 (file)
index 0000000..ac5ff78
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Input misc drivers configuration
+#
+
+bool 'Misc' CONFIG_INPUT_MISC
+
+dep_tristate '  PC Speaker support' CONFIG_INPUT_PCSPKR $CONFIG_INPUT $CONFIG_INPUT_MISC
+dep_tristate '  User level driver support' CONFIG_INPUT_UINPUT $CONFIG_INPUT $CONFIG_INPUT_MISC
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
new file mode 100644 (file)
index 0000000..9d8fc29
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# Makefile for the input misc drivers.
+#
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_INPUT_PCSPKR)             += pcspkr.o
+obj-$(CONFIG_INPUT_UINPUT)             += uinput.o
+
+# The global Rules.make.
+
+include $(TOPDIR)/Rules.make
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
new file mode 100644 (file)
index 0000000..198fee2
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ *  PC Speaker beeper driver for Linux
+ *
+ *  Copyright (c) 2002 Vojtech Pavlik
+ *  Copyright (c) 1992 Orest Zborowski
+ *
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <asm/io.h>
+
+MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
+MODULE_DESCRIPTION("PC Speaker beeper driver");
+MODULE_LICENSE("GPL");
+
+static char *pcspkr_name = "PC Speaker";
+static char *pcspkr_phys = "isa0061/input0";
+static struct input_dev pcspkr_dev;
+
+spinlock_t i8253_beep_lock = SPIN_LOCK_UNLOCKED;
+
+static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+{
+       unsigned int count = 0;
+       unsigned long flags;
+
+       if (type != EV_SND)
+               return -1;
+
+       switch (code) {
+               case SND_BELL: if (value) value = 1000;
+               case SND_TONE: break;
+               default: return -1;
+       } 
+
+       if (value > 20 && value < 32767)
+               count = 1193182 / value;
+       
+       spin_lock_irqsave(&i8253_beep_lock, flags);
+
+       if (count) {
+               /* enable counter 2 */
+               outb_p(inb_p(0x61) | 3, 0x61);
+               /* set command for counter 2, 2 byte write */
+               outb_p(0xB6, 0x43);
+               /* select desired HZ */
+               outb_p(count & 0xff, 0x42);
+               outb((count >> 8) & 0xff, 0x42);
+       } else {
+               /* disable counter 2 */
+               outb(inb_p(0x61) & 0xFC, 0x61);
+       }
+
+       spin_unlock_irqrestore(&i8253_beep_lock, flags);
+
+       return 0;
+}
+
+static int __init pcspkr_init(void)
+{
+       pcspkr_dev.evbit[0] = BIT(EV_SND);
+       pcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+       pcspkr_dev.event = pcspkr_event;
+
+       pcspkr_dev.name = pcspkr_name;
+       pcspkr_dev.phys = pcspkr_phys;
+       pcspkr_dev.id.bustype = BUS_ISA;
+       pcspkr_dev.id.vendor = 0x001f;
+       pcspkr_dev.id.product = 0x0001;
+       pcspkr_dev.id.version = 0x0100;
+
+       input_register_device(&pcspkr_dev);
+
+        printk(KERN_INFO "input: %s\n", pcspkr_name);
+
+       return 0;
+}
+
+static void __exit pcspkr_exit(void)
+{
+        input_unregister_device(&pcspkr_dev);
+}
+
+module_init(pcspkr_init);
+module_exit(pcspkr_exit);
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
new file mode 100644 (file)
index 0000000..dc72f6b
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ *  User level driver support for input subsystem
+ *
+ * Heavily based on evdev.c by Vojtech Pavlik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
+ * 
+ * Changes/Revisions:
+ *     0.1     20/06/2002
+ *             - first public version
+ */
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/smp_lock.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uinput.h>
+
+static int uinput_dev_open(struct input_dev *dev)
+{
+       return 0;
+}
+
+static void uinput_dev_close(struct input_dev *dev)
+{
+
+}
+
+static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+{
+       struct uinput_device    *udev;
+
+       udev = (struct uinput_device *)dev->private;
+
+       udev->head = (udev->head + 1) & 0xF;
+       udev->buff[udev->head].type = type;
+       udev->buff[udev->head].code = code;
+       udev->buff[udev->head].value = value;
+       do_gettimeofday(&udev->buff[udev->head].time);
+
+       wake_up_interruptible(&udev->waitq);
+
+       return 0;
+}
+
+static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
+{
+       return 0;
+}
+
+static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
+{
+       return 0;
+}                                      
+
+static int uinput_create_device(struct uinput_device *udev)
+{
+       if (!udev->dev->name) {
+               printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
+               return -EINVAL;
+       }
+
+       udev->dev->open = uinput_dev_open;
+       udev->dev->close = uinput_dev_close;
+       udev->dev->event = uinput_dev_event;
+       udev->dev->upload_effect = uinput_dev_upload_effect;
+       udev->dev->erase_effect = uinput_dev_erase_effect;
+
+       init_waitqueue_head(&(udev->waitq));
+
+       input_register_device(udev->dev);
+
+       udev->state |= UIST_CREATED;
+
+       return 0;
+}
+
+static int uinput_destroy_device(struct uinput_device *udev)
+{
+       if (!(udev->state & UIST_CREATED)) {
+               printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME);
+               return -EINVAL;
+       }
+
+       input_unregister_device(udev->dev);
+
+       clear_bit(UIST_CREATED, &(udev->state));
+
+       return 0;
+}
+
+static int uinput_open(struct inode *inode, struct file *file)
+{
+       struct uinput_device    *newdev;
+       struct input_dev        *newinput;
+
+       MOD_INC_USE_COUNT;
+
+       newdev = kmalloc(sizeof(struct uinput_device), GFP_KERNEL);
+       if (!newdev)
+               goto error;
+       memset(newdev, 0, sizeof(struct uinput_device));
+
+       newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
+       if (!newinput)
+               goto cleanup;
+       memset(newinput, 0, sizeof(struct input_dev));
+
+       newdev->dev = newinput;
+       
+       file->private_data = newdev;
+
+       return 0;
+cleanup:
+       kfree(newdev);
+error:
+       MOD_DEC_USE_COUNT;
+       return -ENOMEM;
+}
+
+static int uinput_alloc_device(struct file *file, const char *buffer, size_t count)
+{
+       struct uinput_user_dev  user_dev;
+       struct input_dev        *dev;
+       struct uinput_device    *udev;
+       int                     size,
+                               retval;
+
+       retval = count;
+
+       if (copy_from_user(&user_dev, buffer, sizeof(struct uinput_user_dev))) {
+               retval = -EFAULT;
+               goto exit;
+       }
+
+       udev = (struct uinput_device *)file->private_data;
+       dev = udev->dev;
+
+       size = strnlen(user_dev.name, UINPUT_MAX_NAME_SIZE);
+       dev->name = kmalloc(size + 1, GFP_KERNEL);
+       if (!dev->name) {
+               retval = -ENOMEM;
+               goto exit;
+       }
+
+       strncpy(dev->name, user_dev.name, size);
+       dev->name[size] = '\0';
+       dev->id.bustype = user_dev.id.bustype;
+       dev->id.vendor  = user_dev.id.vendor;
+       dev->id.product = user_dev.id.product;
+       dev->id.version = user_dev.id.version;
+       dev->ff_effects_max = user_dev.ff_effects_max;
+
+       size = sizeof(unsigned long) * NBITS(ABS_MAX + 1);
+       memcpy(dev->absmax, user_dev.absmax, size);
+       memcpy(dev->absmin, user_dev.absmin, size);
+       memcpy(dev->absfuzz, user_dev.absfuzz, size);
+       memcpy(dev->absflat, user_dev.absflat, size);
+
+       /* check if absmin/absmax/absfuzz/absflat are filled as
+        * told in Documentation/input/input-programming.txt */
+       if (test_bit(EV_ABS, dev->evbit)) {
+               unsigned int cnt;
+               for (cnt = 1; cnt < ABS_MAX; cnt++)
+                       if (test_bit(cnt, dev->absbit) &&
+                                       (!dev->absmin[cnt] ||
+                                        !dev->absmax[cnt] ||
+                                        !dev->absfuzz[cnt] ||
+                                        !dev->absflat[cnt])) {
+                               printk(KERN_DEBUG "%s: set abs fields "
+                                       "first\n", UINPUT_NAME);
+                               retval = -EINVAL;
+                               goto free_name;
+                       }
+       }
+
+exit:
+       return retval;
+free_name:
+       kfree(dev->name);
+       goto exit;
+}
+
+static int uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+{
+       struct uinput_device    *udev = file->private_data;
+       
+
+       if (udev->state & UIST_CREATED) {
+               struct input_event      ev;
+
+               if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
+                       return -EFAULT;
+               input_event(udev->dev, ev.type, ev.code, ev.value);
+       }
+       else
+               count = uinput_alloc_device(file, buffer, count);
+
+       return count;
+}
+
+static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+       struct uinput_device    *udev;
+       int retval = 0;
+       DECLARE_WAITQUEUE(waitq, current);
+
+       udev = (struct uinput_device *)file->private_data;
+
+       if (udev->head == udev->tail) {
+               add_wait_queue(&udev->waitq, &waitq);
+               current->state = TASK_INTERRUPTIBLE;
+
+               while (udev->head == udev->tail) {
+                       if (!(udev->state & UIST_CREATED)) {
+                               retval = -ENODEV;
+                               break;
+                       }
+                       if (file->f_flags & O_NONBLOCK) {
+                               retval = -EAGAIN;
+                               break;
+                       }
+                       if (signal_pending(current)) {
+                               retval = -ERESTARTSYS;
+                               break;
+                       }
+                       schedule();
+               }
+               current->state = TASK_RUNNING;
+               remove_wait_queue(&udev->waitq, &waitq);
+       }
+
+       if (retval)
+               return retval;
+
+       while (udev->head != udev->tail && retval + sizeof(struct uinput_device) <= count) {
+               if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
+                   sizeof(struct input_event)))
+                       return -EFAULT;
+               udev->tail = (udev->tail + 1)%(UINPUT_BUFFER_SIZE - 1);
+               retval += sizeof(struct input_event);
+       }
+
+       return retval;
+}
+
+static unsigned int uinput_poll(struct file *file, poll_table *wait)
+{
+        struct uinput_device *udev = file->private_data;
+
+       poll_wait(file, &udev->waitq, wait);
+
+       if (udev->head != udev->tail)
+               return POLLIN | POLLRDNORM;
+
+       return 0;                       
+}
+
+static int uinput_burn_device(struct uinput_device *udev)
+{
+       if (udev->state & UIST_CREATED)
+               uinput_destroy_device(udev);
+
+       kfree(udev->dev);
+       kfree(udev);
+
+       return 0;
+}
+
+static int uinput_close(struct inode *inode, struct file *file)
+{
+       int     retval;
+
+       retval = uinput_burn_device((struct uinput_device *)file->private_data);
+       MOD_DEC_USE_COUNT;
+       return retval;
+}
+
+static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+       int                     retval = 0;
+       struct uinput_device    *udev;
+
+       udev = (struct uinput_device *)file->private_data;
+
+       if (cmd >= UI_SET_EVBIT && (udev->state & UIST_CREATED))
+               return -EINVAL;
+
+       switch (cmd) {
+               case UI_DEV_CREATE:
+                       retval = uinput_create_device(udev);
+
+                       break;
+               case UI_DEV_DESTROY:
+                       retval = uinput_destroy_device(udev);
+
+                       break;
+               case UI_SET_EVBIT:
+                       set_bit(arg, udev->dev->evbit);
+
+               break;
+               case UI_SET_KEYBIT:
+                       set_bit(arg, udev->dev->keybit);
+
+               break;
+               case UI_SET_RELBIT:
+                       set_bit(arg, udev->dev->relbit);
+
+               break;
+               case UI_SET_ABSBIT:
+                       set_bit(arg, udev->dev->absbit);
+
+               break;
+               case UI_SET_MSCBIT:
+                       set_bit(arg, udev->dev->mscbit);
+
+               break;
+               case UI_SET_LEDBIT:
+                       set_bit(arg, udev->dev->ledbit);
+
+               break;
+               case UI_SET_SNDBIT:
+                       set_bit(arg, udev->dev->sndbit);
+
+               break;
+               case UI_SET_FFBIT:
+                       set_bit(arg, udev->dev->ffbit);
+
+               break;
+               default:
+                       retval = -EFAULT;
+       }
+       return retval;
+}
+
+struct file_operations uinput_fops = {
+       .owner =        THIS_MODULE,
+       .open =         uinput_open,
+       .release =      uinput_close,
+       .read =         uinput_read,
+       .write =        uinput_write,
+       .poll =         uinput_poll,
+       .ioctl =        uinput_ioctl,
+};
+
+static struct miscdevice uinput_misc = {
+       .fops =         &uinput_fops,
+       .minor =        UINPUT_MINOR,
+       .name =         UINPUT_NAME,
+};
+
+static int __init uinput_init(void)
+{
+       return misc_register(&uinput_misc);
+}
+
+static void __exit uinput_exit(void)
+{
+       misc_deregister(&uinput_misc);
+}
+
+MODULE_AUTHOR("Aristeu Sergio Rozanski Filho");
+MODULE_DESCRIPTION("User level driver support for input subsystem");
+MODULE_LICENSE("GPL");
+
+module_init(uinput_init);
+module_exit(uinput_exit);
+
diff --git a/drivers/input/uinput.c b/drivers/input/uinput.c
deleted file mode 100644 (file)
index dc72f6b..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- *  User level driver support for input subsystem
- *
- * Heavily based on evdev.c by Vojtech Pavlik
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
- * 
- * Changes/Revisions:
- *     0.1     20/06/2002
- *             - first public version
- */
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/smp_lock.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/uinput.h>
-
-static int uinput_dev_open(struct input_dev *dev)
-{
-       return 0;
-}
-
-static void uinput_dev_close(struct input_dev *dev)
-{
-
-}
-
-static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
-{
-       struct uinput_device    *udev;
-
-       udev = (struct uinput_device *)dev->private;
-
-       udev->head = (udev->head + 1) & 0xF;
-       udev->buff[udev->head].type = type;
-       udev->buff[udev->head].code = code;
-       udev->buff[udev->head].value = value;
-       do_gettimeofday(&udev->buff[udev->head].time);
-
-       wake_up_interruptible(&udev->waitq);
-
-       return 0;
-}
-
-static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
-{
-       return 0;
-}
-
-static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
-{
-       return 0;
-}                                      
-
-static int uinput_create_device(struct uinput_device *udev)
-{
-       if (!udev->dev->name) {
-               printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
-               return -EINVAL;
-       }
-
-       udev->dev->open = uinput_dev_open;
-       udev->dev->close = uinput_dev_close;
-       udev->dev->event = uinput_dev_event;
-       udev->dev->upload_effect = uinput_dev_upload_effect;
-       udev->dev->erase_effect = uinput_dev_erase_effect;
-
-       init_waitqueue_head(&(udev->waitq));
-
-       input_register_device(udev->dev);
-
-       udev->state |= UIST_CREATED;
-
-       return 0;
-}
-
-static int uinput_destroy_device(struct uinput_device *udev)
-{
-       if (!(udev->state & UIST_CREATED)) {
-               printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME);
-               return -EINVAL;
-       }
-
-       input_unregister_device(udev->dev);
-
-       clear_bit(UIST_CREATED, &(udev->state));
-
-       return 0;
-}
-
-static int uinput_open(struct inode *inode, struct file *file)
-{
-       struct uinput_device    *newdev;
-       struct input_dev        *newinput;
-
-       MOD_INC_USE_COUNT;
-
-       newdev = kmalloc(sizeof(struct uinput_device), GFP_KERNEL);
-       if (!newdev)
-               goto error;
-       memset(newdev, 0, sizeof(struct uinput_device));
-
-       newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
-       if (!newinput)
-               goto cleanup;
-       memset(newinput, 0, sizeof(struct input_dev));
-
-       newdev->dev = newinput;
-       
-       file->private_data = newdev;
-
-       return 0;
-cleanup:
-       kfree(newdev);
-error:
-       MOD_DEC_USE_COUNT;
-       return -ENOMEM;
-}
-
-static int uinput_alloc_device(struct file *file, const char *buffer, size_t count)
-{
-       struct uinput_user_dev  user_dev;
-       struct input_dev        *dev;
-       struct uinput_device    *udev;
-       int                     size,
-                               retval;
-
-       retval = count;
-
-       if (copy_from_user(&user_dev, buffer, sizeof(struct uinput_user_dev))) {
-               retval = -EFAULT;
-               goto exit;
-       }
-
-       udev = (struct uinput_device *)file->private_data;
-       dev = udev->dev;
-
-       size = strnlen(user_dev.name, UINPUT_MAX_NAME_SIZE);
-       dev->name = kmalloc(size + 1, GFP_KERNEL);
-       if (!dev->name) {
-               retval = -ENOMEM;
-               goto exit;
-       }
-
-       strncpy(dev->name, user_dev.name, size);
-       dev->name[size] = '\0';
-       dev->id.bustype = user_dev.id.bustype;
-       dev->id.vendor  = user_dev.id.vendor;
-       dev->id.product = user_dev.id.product;
-       dev->id.version = user_dev.id.version;
-       dev->ff_effects_max = user_dev.ff_effects_max;
-
-       size = sizeof(unsigned long) * NBITS(ABS_MAX + 1);
-       memcpy(dev->absmax, user_dev.absmax, size);
-       memcpy(dev->absmin, user_dev.absmin, size);
-       memcpy(dev->absfuzz, user_dev.absfuzz, size);
-       memcpy(dev->absflat, user_dev.absflat, size);
-
-       /* check if absmin/absmax/absfuzz/absflat are filled as
-        * told in Documentation/input/input-programming.txt */
-       if (test_bit(EV_ABS, dev->evbit)) {
-               unsigned int cnt;
-               for (cnt = 1; cnt < ABS_MAX; cnt++)
-                       if (test_bit(cnt, dev->absbit) &&
-                                       (!dev->absmin[cnt] ||
-                                        !dev->absmax[cnt] ||
-                                        !dev->absfuzz[cnt] ||
-                                        !dev->absflat[cnt])) {
-                               printk(KERN_DEBUG "%s: set abs fields "
-                                       "first\n", UINPUT_NAME);
-                               retval = -EINVAL;
-                               goto free_name;
-                       }
-       }
-
-exit:
-       return retval;
-free_name:
-       kfree(dev->name);
-       goto exit;
-}
-
-static int uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
-{
-       struct uinput_device    *udev = file->private_data;
-       
-
-       if (udev->state & UIST_CREATED) {
-               struct input_event      ev;
-
-               if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
-                       return -EFAULT;
-               input_event(udev->dev, ev.type, ev.code, ev.value);
-       }
-       else
-               count = uinput_alloc_device(file, buffer, count);
-
-       return count;
-}
-
-static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
-{
-       struct uinput_device    *udev;
-       int retval = 0;
-       DECLARE_WAITQUEUE(waitq, current);
-
-       udev = (struct uinput_device *)file->private_data;
-
-       if (udev->head == udev->tail) {
-               add_wait_queue(&udev->waitq, &waitq);
-               current->state = TASK_INTERRUPTIBLE;
-
-               while (udev->head == udev->tail) {
-                       if (!(udev->state & UIST_CREATED)) {
-                               retval = -ENODEV;
-                               break;
-                       }
-                       if (file->f_flags & O_NONBLOCK) {
-                               retval = -EAGAIN;
-                               break;
-                       }
-                       if (signal_pending(current)) {
-                               retval = -ERESTARTSYS;
-                               break;
-                       }
-                       schedule();
-               }
-               current->state = TASK_RUNNING;
-               remove_wait_queue(&udev->waitq, &waitq);
-       }
-
-       if (retval)
-               return retval;
-
-       while (udev->head != udev->tail && retval + sizeof(struct uinput_device) <= count) {
-               if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
-                   sizeof(struct input_event)))
-                       return -EFAULT;
-               udev->tail = (udev->tail + 1)%(UINPUT_BUFFER_SIZE - 1);
-               retval += sizeof(struct input_event);
-       }
-
-       return retval;
-}
-
-static unsigned int uinput_poll(struct file *file, poll_table *wait)
-{
-        struct uinput_device *udev = file->private_data;
-
-       poll_wait(file, &udev->waitq, wait);
-
-       if (udev->head != udev->tail)
-               return POLLIN | POLLRDNORM;
-
-       return 0;                       
-}
-
-static int uinput_burn_device(struct uinput_device *udev)
-{
-       if (udev->state & UIST_CREATED)
-               uinput_destroy_device(udev);
-
-       kfree(udev->dev);
-       kfree(udev);
-
-       return 0;
-}
-
-static int uinput_close(struct inode *inode, struct file *file)
-{
-       int     retval;
-
-       retval = uinput_burn_device((struct uinput_device *)file->private_data);
-       MOD_DEC_USE_COUNT;
-       return retval;
-}
-
-static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       int                     retval = 0;
-       struct uinput_device    *udev;
-
-       udev = (struct uinput_device *)file->private_data;
-
-       if (cmd >= UI_SET_EVBIT && (udev->state & UIST_CREATED))
-               return -EINVAL;
-
-       switch (cmd) {
-               case UI_DEV_CREATE:
-                       retval = uinput_create_device(udev);
-
-                       break;
-               case UI_DEV_DESTROY:
-                       retval = uinput_destroy_device(udev);
-
-                       break;
-               case UI_SET_EVBIT:
-                       set_bit(arg, udev->dev->evbit);
-
-               break;
-               case UI_SET_KEYBIT:
-                       set_bit(arg, udev->dev->keybit);
-
-               break;
-               case UI_SET_RELBIT:
-                       set_bit(arg, udev->dev->relbit);
-
-               break;
-               case UI_SET_ABSBIT:
-                       set_bit(arg, udev->dev->absbit);
-
-               break;
-               case UI_SET_MSCBIT:
-                       set_bit(arg, udev->dev->mscbit);
-
-               break;
-               case UI_SET_LEDBIT:
-                       set_bit(arg, udev->dev->ledbit);
-
-               break;
-               case UI_SET_SNDBIT:
-                       set_bit(arg, udev->dev->sndbit);
-
-               break;
-               case UI_SET_FFBIT:
-                       set_bit(arg, udev->dev->ffbit);
-
-               break;
-               default:
-                       retval = -EFAULT;
-       }
-       return retval;
-}
-
-struct file_operations uinput_fops = {
-       .owner =        THIS_MODULE,
-       .open =         uinput_open,
-       .release =      uinput_close,
-       .read =         uinput_read,
-       .write =        uinput_write,
-       .poll =         uinput_poll,
-       .ioctl =        uinput_ioctl,
-};
-
-static struct miscdevice uinput_misc = {
-       .fops =         &uinput_fops,
-       .minor =        UINPUT_MINOR,
-       .name =         UINPUT_NAME,
-};
-
-static int __init uinput_init(void)
-{
-       return misc_register(&uinput_misc);
-}
-
-static void __exit uinput_exit(void)
-{
-       misc_deregister(&uinput_misc);
-}
-
-MODULE_AUTHOR("Aristeu Sergio Rozanski Filho");
-MODULE_DESCRIPTION("User level driver support for input subsystem");
-MODULE_LICENSE("GPL");
-
-module_init(uinput_init);
-module_exit(uinput_exit);
-
index 30eb4d242b3beb2aae851a012124396eb1193cde..cd2a6856e2a95f68bfa5e00a74c4a27153a3e635 100644 (file)
@@ -570,6 +570,7 @@ struct input_absinfo {
 
 #define SND_CLICK              0x00
 #define SND_BELL               0x01
+#define SND_TONE               0x02
 #define SND_MAX                        0x07
 
 /*
index 6f668c171107a66ea94e8b2559f80a40c969fa4f..6d0b234f5a6198aebebbdb598ab7bbdaabfbb5cb 100644 (file)
@@ -32,8 +32,8 @@ extern struct vt_struct {
        wait_queue_head_t paste_wait;
 } *vt_cons[MAX_NR_CONSOLES];
 
-extern void (*kd_mksound)(unsigned int hz, unsigned int ticks);
-extern int (*kbd_rate)(struct kbd_repeat *rep);
+extern void kd_mksound(unsigned int hz, unsigned int ticks);
+extern int kbd_rate(struct kbd_repeat *rep);
 
 /* console.c */