Commit 51847e22 authored by Vojtech Pavlik's avatar Vojtech Pavlik Committed by Linus Torvalds

[PATCH] Input drivers, step #3

This patch updates the input core to the current version, fixing a bunch
of bugs, adding hotplug support and a listing of available input devices
in /proc. The later is very useful for troubleshooting.

Vojtech Pavlik
SuSE Labs
parent 3ba2a466
/* /*
* $Id: evdev.c,v 1.27 2001/05/28 09:06:44 vojtech Exp $ * $Id: evdev.c,v 1.42 2002/01/02 11:59:56 vojtech Exp $
* *
* Copyright (c) 1999-2001 Vojtech Pavlik * Copyright (c) 1999-2001 Vojtech Pavlik
* *
* Event char devices, giving access to raw input device events. * Event char devices, giving access to raw input device events.
*
* Sponsored by SuSE
*/ */
/* /*
...@@ -24,8 +22,8 @@ ...@@ -24,8 +22,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/ */
#define EVDEV_MINOR_BASE 64 #define EVDEV_MINOR_BASE 64
...@@ -42,7 +40,9 @@ ...@@ -42,7 +40,9 @@
struct evdev { struct evdev {
int exist; int exist;
int open; int open;
int open_for_write;
int minor; int minor;
char name[16];
struct input_handle handle; struct input_handle handle;
wait_queue_head_t wait; wait_queue_head_t wait;
devfs_handle_t devfs; devfs_handle_t devfs;
...@@ -89,6 +89,11 @@ static int evdev_fasync(int fd, struct file *file, int on) ...@@ -89,6 +89,11 @@ static int evdev_fasync(int fd, struct file *file, int on)
return retval < 0 ? retval : 0; return retval < 0 ? retval : 0;
} }
static int evdev_flush(struct file * file)
{
return input_flush_device(&((struct evdev_list*)file->private_data)->evdev->handle, file);
}
static int evdev_release(struct inode * inode, struct file * file) static int evdev_release(struct inode * inode, struct file * file)
{ {
struct evdev_list *list = file->private_data; struct evdev_list *list = file->private_data;
...@@ -120,10 +125,16 @@ static int evdev_open(struct inode * inode, struct file * file) ...@@ -120,10 +125,16 @@ static int evdev_open(struct inode * inode, struct file * file)
{ {
struct evdev_list *list; struct evdev_list *list;
int i = minor(inode->i_rdev) - EVDEV_MINOR_BASE; int i = minor(inode->i_rdev) - EVDEV_MINOR_BASE;
int accept_err;
if (i >= EVDEV_MINORS || !evdev_table[i]) if (i >= EVDEV_MINORS || !evdev_table[i])
return -ENODEV; return -ENODEV;
/* Ask the driver if he wishes to accept the open() */
if ((accept_err = input_accept_process(&(evdev_table[i]->handle), file))) {
return accept_err;
}
if (!(list = kmalloc(sizeof(struct evdev_list), GFP_KERNEL))) if (!(list = kmalloc(sizeof(struct evdev_list), GFP_KERNEL)))
return -ENOMEM; return -ENOMEM;
memset(list, 0, sizeof(struct evdev_list)); memset(list, 0, sizeof(struct evdev_list));
...@@ -167,7 +178,7 @@ static ssize_t evdev_read(struct file * file, char * buffer, size_t count, loff_ ...@@ -167,7 +178,7 @@ static ssize_t evdev_read(struct file * file, char * buffer, size_t count, loff_
if (list->head == list->tail) { if (list->head == list->tail) {
add_wait_queue(&list->evdev->wait, &wait); add_wait_queue(&list->evdev->wait, &wait);
current->state = TASK_INTERRUPTIBLE; set_current_state(TASK_INTERRUPTIBLE);
while (list->head == list->tail) { while (list->head == list->tail) {
...@@ -187,7 +198,7 @@ static ssize_t evdev_read(struct file * file, char * buffer, size_t count, loff_ ...@@ -187,7 +198,7 @@ static ssize_t evdev_read(struct file * file, char * buffer, size_t count, loff_
schedule(); schedule();
} }
current->state = TASK_RUNNING; set_current_state(TASK_RUNNING);
remove_wait_queue(&list->evdev->wait, &wait); remove_wait_queue(&list->evdev->wait, &wait);
} }
...@@ -219,7 +230,7 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -219,7 +230,7 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
struct evdev_list *list = file->private_data; struct evdev_list *list = file->private_data;
struct evdev *evdev = list->evdev; struct evdev *evdev = list->evdev;
struct input_dev *dev = evdev->handle.dev; struct input_dev *dev = evdev->handle.dev;
int retval; int retval, t, u;
switch (cmd) { switch (cmd) {
...@@ -232,6 +243,40 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -232,6 +243,40 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if ((retval = put_user(dev->idproduct, ((short *) arg) + 2))) return retval; if ((retval = put_user(dev->idproduct, ((short *) arg) + 2))) return retval;
if ((retval = put_user(dev->idversion, ((short *) arg) + 3))) return retval; if ((retval = put_user(dev->idversion, ((short *) arg) + 3))) return retval;
return 0; return 0;
case EVIOCGREP:
if ((retval = put_user(dev->rep[0], ((int *) arg) + 0))) return retval;
if ((retval = put_user(dev->rep[1], ((int *) arg) + 1))) return retval;
return 0;
case EVIOCSREP:
if ((retval = get_user(dev->rep[0], ((int *) arg) + 0))) return retval;
if ((retval = get_user(dev->rep[1], ((int *) arg) + 1))) return retval;
return 0;
case EVIOCGKEYCODE:
if ((retval = get_user(t, ((int *) arg) + 0))) return retval;
if (t < 0 || t > dev->keycodemax) return -EINVAL;
switch (dev->keycodesize) {
case 1: u = *(u8*)(dev->keycode + t); break;
case 2: u = *(u16*)(dev->keycode + t * 2); break;
case 4: u = *(u32*)(dev->keycode + t * 4); break;
default: return -EINVAL;
}
if ((retval = put_user(u, ((int *) arg) + 1))) return retval;
return 0;
case EVIOCSKEYCODE:
if ((retval = get_user(t, ((int *) arg) + 0))) return retval;
if (t < 0 || t > dev->keycodemax) return -EINVAL;
if ((retval = get_user(u, ((int *) arg) + 1))) return retval;
switch (dev->keycodesize) {
case 1: *(u8*)(dev->keycode + t) = u; break;
case 2: *(u16*)(dev->keycode + t * 2) = u; break;
case 4: *(u32*)(dev->keycode + t * 4) = u; break;
default: return -EINVAL;
}
return 0;
case EVIOCSFF: case EVIOCSFF:
if (dev->upload_effect) { if (dev->upload_effect) {
...@@ -280,22 +325,55 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -280,22 +325,55 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
default: return -EINVAL; default: return -EINVAL;
} }
len = NBITS(len) * sizeof(long); len = NBITS(len) * sizeof(long);
if (len > _IOC_SIZE(cmd)) { if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
printk(KERN_WARNING "evdev.c: Truncating bitfield length from %d to %d\n",
len, _IOC_SIZE(cmd));
len = _IOC_SIZE(cmd);
}
return copy_to_user((char *) arg, bits, len) ? -EFAULT : len; return copy_to_user((char *) arg, bits, len) ? -EFAULT : len;
} }
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) {
int len;
len = NBITS(KEY_MAX) * sizeof(long);
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user((char *) arg, dev->key, len) ? -EFAULT : len;
}
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) {
int len;
len = NBITS(LED_MAX) * sizeof(long);
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user((char *) arg, dev->led, len) ? -EFAULT : len;
}
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) {
int len;
len = NBITS(SND_MAX) * sizeof(long);
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user((char *) arg, dev->snd, len) ? -EFAULT : len;
}
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) { if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
int len; int len;
if (!dev->name) return 0; if (!dev->name) return -ENOENT;
len = strlen(dev->name) + 1; len = strlen(dev->name) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user((char *) arg, dev->name, len) ? -EFAULT : len; return copy_to_user((char *) arg, dev->name, len) ? -EFAULT : len;
} }
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
int len;
if (!dev->phys) return -ENOENT;
len = strlen(dev->phys) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user((char *) arg, dev->phys, len) ? -EFAULT : len;
}
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
int len;
if (!dev->uniq) return -ENOENT;
len = strlen(dev->uniq) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user((char *) arg, dev->uniq, len) ? -EFAULT : len;
}
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
int t = _IOC_NR(cmd) & ABS_MAX; int t = _IOC_NR(cmd) & ABS_MAX;
...@@ -321,9 +399,10 @@ static struct file_operations evdev_fops = { ...@@ -321,9 +399,10 @@ static struct file_operations evdev_fops = {
release: evdev_release, release: evdev_release,
ioctl: evdev_ioctl, ioctl: evdev_ioctl,
fasync: evdev_fasync, fasync: evdev_fasync,
flush: evdev_flush
}; };
static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev) static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
{ {
struct evdev *evdev; struct evdev *evdev;
int minor; int minor;
...@@ -342,16 +421,17 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct ...@@ -342,16 +421,17 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct
evdev->minor = minor; evdev->minor = minor;
evdev_table[minor] = evdev; evdev_table[minor] = evdev;
sprintf(evdev->name, "event%d", minor);
evdev->handle.dev = dev; evdev->handle.dev = dev;
evdev->handle.name = evdev->name;
evdev->handle.handler = handler; evdev->handle.handler = handler;
evdev->handle.private = evdev; evdev->handle.private = evdev;
evdev->exist = 1;
evdev->devfs = input_register_minor("event%d", minor, EVDEV_MINOR_BASE); evdev->devfs = input_register_minor("event%d", minor, EVDEV_MINOR_BASE);
// printk(KERN_INFO "event%d: Event device for input%d\n", minor, dev->number); evdev->exist = 1;
return &evdev->handle; return &evdev->handle;
} }
...@@ -372,12 +452,21 @@ static void evdev_disconnect(struct input_handle *handle) ...@@ -372,12 +452,21 @@ static void evdev_disconnect(struct input_handle *handle)
} }
} }
static struct input_device_id evdev_ids[] = {
{ driver_info: 1 }, /* Matches all devices */
{ }, /* Terminating zero entry */
};
MODULE_DEVICE_TABLE(input, evdev_ids);
static struct input_handler evdev_handler = { static struct input_handler evdev_handler = {
event: evdev_event, event: evdev_event,
connect: evdev_connect, connect: evdev_connect,
disconnect: evdev_disconnect, disconnect: evdev_disconnect,
fops: &evdev_fops, fops: &evdev_fops,
minor: EVDEV_MINOR_BASE, minor: EVDEV_MINOR_BASE,
name: "evdev",
id_table: evdev_ids,
}; };
static int __init evdev_init(void) static int __init evdev_init(void)
...@@ -394,7 +483,6 @@ static void __exit evdev_exit(void) ...@@ -394,7 +483,6 @@ static void __exit evdev_exit(void)
module_init(evdev_init); module_init(evdev_init);
module_exit(evdev_exit); module_exit(evdev_exit);
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Event character device driver"); MODULE_DESCRIPTION("Input driver event char devices");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
This diff is collapsed.
/* /*
* $Id: joydev.c,v 1.19 2001/01/10 19:49:40 vojtech Exp $ * $Id: joydev.c,v 1.38 2001/12/27 10:37:41 vojtech Exp $
* *
* Copyright (c) 1999-2000 Vojtech Pavlik * Copyright (c) 1999-2001 Vojtech Pavlik
* Copyright (c) 1999 Colin Van Dyke * Copyright (c) 1999 Colin Van Dyke
* *
* Joystick device driver for the input driver suite. * Joystick device driver for the input driver suite.
*
* Sponsored by SuSE and Intel
*/ */
/* /*
...@@ -25,8 +23,8 @@ ...@@ -25,8 +23,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/ */
#include <asm/io.h> #include <asm/io.h>
...@@ -45,14 +43,22 @@ ...@@ -45,14 +43,22 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Joystick device interfaces");
MODULE_SUPPORTED_DEVICE("input/js");
MODULE_LICENSE("GPL");
#define JOYDEV_MINOR_BASE 0 #define JOYDEV_MINOR_BASE 0
#define JOYDEV_MINORS 32 #define JOYDEV_MINORS 32
#define JOYDEV_BUFFER_SIZE 64 #define JOYDEV_BUFFER_SIZE 64
#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
struct joydev { struct joydev {
int exist; int exist;
int open; int open;
int minor; int minor;
char name[16];
struct input_handle handle; struct input_handle handle;
wait_queue_head_t wait; wait_queue_head_t wait;
devfs_handle_t devfs; devfs_handle_t devfs;
...@@ -81,11 +87,6 @@ struct joydev_list { ...@@ -81,11 +87,6 @@ struct joydev_list {
static struct joydev *joydev_table[JOYDEV_MINORS]; static struct joydev *joydev_table[JOYDEV_MINORS];
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("Joystick device driver");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("input/js");
static int joydev_correct(int value, struct js_corr *corr) static int joydev_correct(int value, struct js_corr *corr)
{ {
switch (corr->type) { switch (corr->type) {
...@@ -133,7 +134,7 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne ...@@ -133,7 +134,7 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne
return; return;
} }
event.time = jiffies * (1000 / HZ); event.time = MSECS(jiffies);
while (list) { while (list) {
...@@ -163,7 +164,7 @@ static int joydev_release(struct inode * inode, struct file * file) ...@@ -163,7 +164,7 @@ static int joydev_release(struct inode * inode, struct file * file)
{ {
struct joydev_list *list = file->private_data; struct joydev_list *list = file->private_data;
struct joydev_list **listptr; struct joydev_list **listptr;
listptr = &list->joydev->list; listptr = &list->joydev->list;
joydev_fasync(-1, file, 0); joydev_fasync(-1, file, 0);
...@@ -249,7 +250,7 @@ static ssize_t joydev_read(struct file *file, char *buf, size_t count, loff_t *p ...@@ -249,7 +250,7 @@ static ssize_t joydev_read(struct file *file, char *buf, size_t count, loff_t *p
if (list->head == list->tail && list->startup == joydev->nabs + joydev->nkey) { if (list->head == list->tail && list->startup == joydev->nabs + joydev->nkey) {
add_wait_queue(&list->joydev->wait, &wait); add_wait_queue(&list->joydev->wait, &wait);
current->state = TASK_INTERRUPTIBLE; set_current_state(TASK_INTERRUPTIBLE);
while (list->head == list->tail) { while (list->head == list->tail) {
...@@ -265,7 +266,7 @@ static ssize_t joydev_read(struct file *file, char *buf, size_t count, loff_t *p ...@@ -265,7 +266,7 @@ static ssize_t joydev_read(struct file *file, char *buf, size_t count, loff_t *p
schedule(); schedule();
} }
current->state = TASK_RUNNING; set_current_state(TASK_RUNNING);
remove_wait_queue(&list->joydev->wait, &wait); remove_wait_queue(&list->joydev->wait, &wait);
} }
...@@ -276,7 +277,7 @@ static ssize_t joydev_read(struct file *file, char *buf, size_t count, loff_t *p ...@@ -276,7 +277,7 @@ static ssize_t joydev_read(struct file *file, char *buf, size_t count, loff_t *p
struct js_event event; struct js_event event;
event.time = jiffies * (1000/HZ); event.time = MSECS(jiffies);
if (list->startup < joydev->nkey) { if (list->startup < joydev->nkey) {
event.type = JS_EVENT_BUTTON | JS_EVENT_INIT; event.type = JS_EVENT_BUTTON | JS_EVENT_INIT;
...@@ -360,9 +361,9 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -360,9 +361,9 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
return copy_to_user((struct js_corr *) arg, joydev->corr, return copy_to_user((struct js_corr *) arg, joydev->corr,
sizeof(struct js_corr) * joydev->nabs) ? -EFAULT : 0; sizeof(struct js_corr) * joydev->nabs) ? -EFAULT : 0;
case JSIOCSAXMAP: case JSIOCSAXMAP:
if (copy_from_user((__u8 *) arg, joydev->abspam, sizeof(__u8) * ABS_MAX)) if (copy_from_user(joydev->abspam, (__u8 *) arg, sizeof(__u8) * ABS_MAX))
return -EFAULT; return -EFAULT;
for (i = 0; i < ABS_MAX; i++) { for (i = 0; i < joydev->nabs; i++) {
if (joydev->abspam[i] > ABS_MAX) return -EINVAL; if (joydev->abspam[i] > ABS_MAX) return -EINVAL;
joydev->absmap[joydev->abspam[i]] = i; joydev->absmap[joydev->abspam[i]] = i;
} }
...@@ -371,11 +372,11 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -371,11 +372,11 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
return copy_to_user((__u8 *) arg, joydev->abspam, return copy_to_user((__u8 *) arg, joydev->abspam,
sizeof(__u8) * ABS_MAX) ? -EFAULT : 0; sizeof(__u8) * ABS_MAX) ? -EFAULT : 0;
case JSIOCSBTNMAP: case JSIOCSBTNMAP:
if (copy_from_user((__u16 *) arg, joydev->absmap, sizeof(__u16) * (KEY_MAX - BTN_MISC))) if (copy_from_user(joydev->keypam, (__u16 *) arg, sizeof(__u16) * (KEY_MAX - BTN_MISC)))
return -EFAULT; return -EFAULT;
for (i = 0; i < KEY_MAX - BTN_MISC; i++); { for (i = 0; i < joydev->nkey; i++); {
if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL; if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL;
joydev->keymap[joydev->abspam[i - BTN_MISC]] = i; joydev->keymap[joydev->keypam[i] - BTN_MISC] = i;
} }
return 0; return 0;
case JSIOCGBTNMAP: case JSIOCGBTNMAP:
...@@ -405,15 +406,13 @@ static struct file_operations joydev_fops = { ...@@ -405,15 +406,13 @@ static struct file_operations joydev_fops = {
fasync: joydev_fasync, fasync: joydev_fasync,
}; };
static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev) static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
{ {
struct joydev *joydev; struct joydev *joydev;
int i, j, minor; int i, j, t, minor;
if (!(test_bit(EV_KEY, dev->evbit) && test_bit(EV_ABS, dev->evbit) && if (test_bit(BTN_TOUCH, dev->keybit))
(test_bit(ABS_X, dev->absbit) || test_bit(ABS_Y, dev->absbit)) && return NULL;
(test_bit(BTN_TRIGGER, dev->keybit) || test_bit(BTN_A, dev->keybit)
|| test_bit(BTN_1, dev->keybit)))) return NULL;
for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
if (minor == JOYDEV_MINORS) { if (minor == JOYDEV_MINORS) {
...@@ -430,12 +429,13 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct ...@@ -430,12 +429,13 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
joydev->minor = minor; joydev->minor = minor;
joydev_table[minor] = joydev; joydev_table[minor] = joydev;
sprintf(joydev->name, "js%d", minor);
joydev->handle.dev = dev; joydev->handle.dev = dev;
joydev->handle.name = joydev->name;
joydev->handle.handler = handler; joydev->handle.handler = handler;
joydev->handle.private = joydev; joydev->handle.private = joydev;
joydev->exist = 1;
for (i = 0; i < ABS_MAX; i++) for (i = 0; i < ABS_MAX; i++)
if (test_bit(i, dev->absbit)) { if (test_bit(i, dev->absbit)) {
joydev->absmap[i] = joydev->nabs; joydev->absmap[i] = joydev->nabs;
...@@ -467,15 +467,17 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct ...@@ -467,15 +467,17 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
joydev->corr[i].prec = dev->absfuzz[j]; joydev->corr[i].prec = dev->absfuzz[j];
joydev->corr[i].coef[0] = (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j]; joydev->corr[i].coef[0] = (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j];
joydev->corr[i].coef[1] = (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j]; joydev->corr[i].coef[1] = (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j];
joydev->corr[i].coef[2] = (1 << 29) / ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j]); if (!(t = ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j])))
joydev->corr[i].coef[3] = (1 << 29) / ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j]); continue;
joydev->corr[i].coef[2] = (1 << 29) / t;
joydev->corr[i].coef[3] = (1 << 29) / t;
joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i); joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i);
} }
joydev->devfs = input_register_minor("js%d", minor, JOYDEV_MINOR_BASE); joydev->devfs = input_register_minor("js%d", minor, JOYDEV_MINOR_BASE);
// printk(KERN_INFO "js%d: Joystick device for input%d\n", minor, dev->number); joydev->exist = 1;
return &joydev->handle; return &joydev->handle;
} }
...@@ -495,12 +497,35 @@ static void joydev_disconnect(struct input_handle *handle) ...@@ -495,12 +497,35 @@ static void joydev_disconnect(struct input_handle *handle)
} }
} }
static struct input_device_id joydev_ids[] = {
{
flags: INPUT_DEVICE_ID_MATCH_EVBIT,
evbit: { BIT(EV_KEY) | BIT(EV_ABS) },
absbit: { BIT(ABS_X) },
},
{
flags: INPUT_DEVICE_ID_MATCH_EVBIT,
evbit: { BIT(EV_KEY) | BIT(EV_ABS) },
absbit: { BIT(ABS_WHEEL) },
},
{
flags: INPUT_DEVICE_ID_MATCH_EVBIT,
evbit: { BIT(EV_KEY) | BIT(EV_ABS) },
absbit: { BIT(ABS_THROTTLE) },
},
{ }, /* Terminating entry */
};
MODULE_DEVICE_TABLE(input, joydev_ids);
static struct input_handler joydev_handler = { static struct input_handler joydev_handler = {
event: joydev_event, event: joydev_event,
connect: joydev_connect, connect: joydev_connect,
disconnect: joydev_disconnect, disconnect: joydev_disconnect,
fops: &joydev_fops, fops: &joydev_fops,
minor: JOYDEV_MINOR_BASE, minor: JOYDEV_MINOR_BASE,
name: "joydev",
id_table: joydev_ids,
}; };
static int __init joydev_init(void) static int __init joydev_init(void)
......
...@@ -641,7 +641,7 @@ static int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effec ...@@ -641,7 +641,7 @@ static int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effec
effect->replay.delay, effect->replay.delay,
effect->trigger.button, effect->trigger.button,
effect->trigger.interval, effect->trigger.interval,
effect->u.periodic.direction); effect->direction);
return err; return err;
} }
...@@ -680,7 +680,7 @@ static int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effec ...@@ -680,7 +680,7 @@ static int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effec
effect->replay.delay, effect->replay.delay,
effect->trigger.button, effect->trigger.button,
effect->trigger.interval, effect->trigger.interval,
effect->u.constant.direction); effect->direction);
return err; return err;
} }
...@@ -722,7 +722,7 @@ static int iforce_upload_interactive(struct iforce* iforce, struct ff_effect* ef ...@@ -722,7 +722,7 @@ static int iforce_upload_interactive(struct iforce* iforce, struct ff_effect* ef
case 0: /* Only one axis, choose orientation */ case 0: /* Only one axis, choose orientation */
mod1 = mod_chunk->start; mod1 = mod_chunk->start;
mod2 = 0xffff; mod2 = 0xffff;
direction = effect->u.interactive.direction; direction = effect->direction;
axes = 0x20; axes = 0x20;
break; break;
......
/* /*
* $Id: keybdev.c,v 1.3 2000/05/28 17:31:36 vojtech Exp $ * $Id: keybdev.c,v 1.16 2002/01/09 04:21:41 lethal Exp $
* *
* Copyright (c) 1999-2000 Vojtech Pavlik * Copyright (c) 1999-2001 Vojtech Pavlik
* *
* Input driver to keyboard driver binding. * Input core to console keyboard binding.
*
* Sponsored by SuSE
*/ */
/* /*
...@@ -24,8 +22,8 @@ ...@@ -24,8 +22,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -37,10 +35,16 @@ ...@@ -37,10 +35,16 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/kbd_kern.h> #include <linux/kbd_kern.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Input core to console keyboard binding");
MODULE_LICENSE("GPL");
char keybdev_name[] = "keyboard";
#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(__alpha__) || \ #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(__alpha__) || \
defined(__mips__) || defined(CONFIG_SPARC64) || defined(CONFIG_SUPERH) || \ defined(__mips__) || defined(CONFIG_SPARC64) || defined(CONFIG_SUPERH) || \
defined(CONFIG_PPC) || defined(__mc68000__) || defined(__hppa__) || \ defined(CONFIG_PPC) || defined(__mc68000__) || defined(__hppa__) || \
defined(__arm__) defined(__arm__) || defined(__x86_64__)
static int x86_sysrq_alt = 0; static int x86_sysrq_alt = 0;
#ifdef CONFIG_SPARC64 #ifdef CONFIG_SPARC64
...@@ -48,8 +52,6 @@ static int sparc_l1_a_state = 0; ...@@ -48,8 +52,6 @@ static int sparc_l1_a_state = 0;
extern void batten_down_hatches(void); extern void batten_down_hatches(void);
#endif #endif
static int jp_kbd_109 = 1; /* Yes, .jp is the default. See 51142. */
static unsigned short x86_keycodes[256] = static unsigned short x86_keycodes[256] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
...@@ -62,7 +64,7 @@ static unsigned short x86_keycodes[256] = ...@@ -62,7 +64,7 @@ static unsigned short x86_keycodes[256] =
360, 93, 94, 95, 98,376,100,101,357,316,354,304,289,102,351,355, 360, 93, 94, 95, 98,376,100,101,357,316,354,304,289,102,351,355,
103,104,105,275,281,272,306,106,274,107,288,364,358,363,362,361, 103,104,105,275,281,272,306,106,274,107,288,364,358,363,362,361,
291,108,381,290,287,292,279,305,280, 99,112,257,258,113,270,114, 291,108,381,290,287,292,279,305,280, 99,112,257,258,113,270,114,
118,117,125,374,379,259,260,261,262,263,264,265,266,267,268,269, 118,117,125,374,379,115,112,125,121,123,264,265,266,267,268,269,
271,273,276,277,278,282,283,295,296,297,299,300,301,302,303,307, 271,273,276,277,278,282,283,295,296,297,299,300,301,302,303,307,
308,310,313,314,315,317,318,319,320,321,322,323,324,325,326,330, 308,310,313,314,315,317,318,319,320,321,322,323,324,325,326,330,
332,340,341,342,343,344,345,346,356,359,365,368,369,370,371,372 }; 332,340,341,342,343,344,345,346,356,359,365,368,369,370,371,372 };
...@@ -167,26 +169,38 @@ void keybdev_ledfunc(unsigned int led) ...@@ -167,26 +169,38 @@ void keybdev_ledfunc(unsigned int led)
} }
} }
/* Tell the user who may be running in X and not see the console that we have
panic'ed. This is to distingush panics from "real" lockups.
Could in theory send the panic message as morse, but that is left as an
exercise for the reader. */
void panic_blink(void)
{
static unsigned long last_jiffie;
static char led;
/* Roughly 1/2s frequency. KDB uses about 1s. Make sure it is different. */
if (jiffies - last_jiffie > HZ/2) {
led ^= 0x01 | 0x04;
keybdev_ledfunc(led);
last_jiffie = jiffies;
}
}
void keybdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int down) void keybdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int down)
{ {
if (type != EV_KEY) return; if (type != EV_KEY) return;
emulate_raw(code, down);
if (emulate_raw(code, down))
printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", code);
tasklet_schedule(&keyboard_tasklet); tasklet_schedule(&keyboard_tasklet);
} }
static struct input_handle *keybdev_connect(struct input_handler *handler, struct input_dev *dev) static struct input_handle *keybdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
{ {
struct input_handle *handle; struct input_handle *handle;
int i; int i;
if (!test_bit(EV_KEY, dev->evbit)) for (i = KEY_ESC; i < BTN_MISC; i++)
return NULL; if (test_bit(i, dev->keybit))
break;
for (i = KEY_RESERVED; i < BTN_MISC; i++)
if (test_bit(i, dev->keybit)) break;
if (i == BTN_MISC) if (i == BTN_MISC)
return NULL; return NULL;
...@@ -196,41 +210,42 @@ static struct input_handle *keybdev_connect(struct input_handler *handler, struc ...@@ -196,41 +210,42 @@ static struct input_handle *keybdev_connect(struct input_handler *handler, struc
memset(handle, 0, sizeof(struct input_handle)); memset(handle, 0, sizeof(struct input_handle));
handle->dev = dev; handle->dev = dev;
handle->name = keybdev_name;
handle->handler = handler; handle->handler = handler;
input_open_device(handle); input_open_device(handle);
// printk(KERN_INFO "keybdev.c: Adding keyboard: input%d\n", dev->number);
return handle; return handle;
} }
static void keybdev_disconnect(struct input_handle *handle) static void keybdev_disconnect(struct input_handle *handle)
{ {
// printk(KERN_INFO "keybdev.c: Removing keyboard: input%d\n", handle->dev->number);
input_close_device(handle); input_close_device(handle);
kfree(handle); kfree(handle);
} }
static struct input_device_id keybdev_ids[] = {
{
flags: INPUT_DEVICE_ID_MATCH_EVBIT,
evbit: { BIT(EV_KEY) },
},
{ }, /* Terminating entry */
};
MODULE_DEVICE_TABLE(input, keybdev_ids);
static struct input_handler keybdev_handler = { static struct input_handler keybdev_handler = {
event: keybdev_event, event: keybdev_event,
connect: keybdev_connect, connect: keybdev_connect,
disconnect: keybdev_disconnect, disconnect: keybdev_disconnect,
name: "keybdev",
id_table: keybdev_ids,
}; };
static int __init keybdev_init(void) static int __init keybdev_init(void)
{ {
input_register_handler(&keybdev_handler); input_register_handler(&keybdev_handler);
kbd_ledfunc = keybdev_ledfunc; kbd_ledfunc = keybdev_ledfunc;
if (jp_kbd_109) {
x86_keycodes[0xb5] = 0x73; /* backslash, underscore */
x86_keycodes[0xb6] = 0x70;
x86_keycodes[0xb7] = 0x7d; /* Yen, pipe */
x86_keycodes[0xb8] = 0x79;
x86_keycodes[0xb9] = 0x7b;
}
return 0; return 0;
} }
...@@ -243,7 +258,3 @@ static void __exit keybdev_exit(void) ...@@ -243,7 +258,3 @@ static void __exit keybdev_exit(void)
module_init(keybdev_init); module_init(keybdev_init);
module_exit(keybdev_exit); module_exit(keybdev_exit);
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("Input driver to keyboard driver binding");
MODULE_PARM(jp_kbd_109, "i");
MODULE_LICENSE("GPL");
/* /*
* $Id: mousedev.c,v 1.24 2000/11/15 10:57:45 vojtech Exp $ * $Id: mousedev.c,v 1.38 2001/12/26 21:08:33 jsimmons Exp $
* *
* Copyright (c) 1999-2000 Vojtech Pavlik * Copyright (c) 1999-2001 Vojtech Pavlik
* *
* Input driver to ImExPS/2 device driver module. * Input driver to ExplorerPS/2 device driver module.
*
* Sponsored by SuSE
*/ */
/* /*
...@@ -24,8 +22,8 @@ ...@@ -24,8 +22,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/ */
#define MOUSEDEV_MINOR_BASE 32 #define MOUSEDEV_MINOR_BASE 32
...@@ -41,6 +39,10 @@ ...@@ -41,6 +39,10 @@
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/random.h> #include <linux/random.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Mouse (ExplorerPS/2) device interfaces");
MODULE_LICENSE("GPL");
#ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X #ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X
#define CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024 #define CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024
#endif #endif
...@@ -52,6 +54,7 @@ struct mousedev { ...@@ -52,6 +54,7 @@ struct mousedev {
int exist; int exist;
int open; int open;
int minor; int minor;
char name[16];
wait_queue_head_t wait; wait_queue_head_t wait;
struct mousedev_list *list; struct mousedev_list *list;
struct input_handle handle; struct input_handle handle;
...@@ -89,8 +92,6 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig ...@@ -89,8 +92,6 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig
struct mousedev_list *list; struct mousedev_list *list;
int index, size; int index, size;
add_mouse_randomness((type << 4) ^ code ^ (code >> 4) ^ value);
while (*mousedev) { while (*mousedev) {
list = (*mousedev)->list; list = (*mousedev)->list;
while (list) { while (list) {
...@@ -101,13 +102,23 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig ...@@ -101,13 +102,23 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig
switch (code) { switch (code) {
case ABS_X: case ABS_X:
size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X]; size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
list->dx += (value * xres - list->oldx) / size; if (size != 0) {
list->oldx += list->dx * size; list->dx += (value * xres - list->oldx) / size;
list->oldx += list->dx * size;
} else {
list->dx += value - list->oldx;
list->oldx += list->dx;
}
break; break;
case ABS_Y: case ABS_Y:
size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y]; size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
list->dy -= (value * yres - list->oldy) / size; if (size != 0) {
list->oldy -= list->dy * size; list->dy -= (value * yres - list->oldy) / size;
list->oldy -= list->dy * size;
} else {
list->dy -= value - list->oldy;
list->oldy -= list->dy;
}
break; break;
} }
break; break;
...@@ -169,7 +180,7 @@ static int mousedev_release(struct inode * inode, struct file * file) ...@@ -169,7 +180,7 @@ static int mousedev_release(struct inode * inode, struct file * file)
{ {
struct mousedev_list *list = file->private_data; struct mousedev_list *list = file->private_data;
struct mousedev_list **listptr; struct mousedev_list **listptr;
listptr = &list->mousedev->list; listptr = &list->mousedev->list;
mousedev_fasync(-1, file, 0); mousedev_fasync(-1, file, 0);
...@@ -344,7 +355,7 @@ static ssize_t mousedev_read(struct file * file, char * buffer, size_t count, lo ...@@ -344,7 +355,7 @@ static ssize_t mousedev_read(struct file * file, char * buffer, size_t count, lo
if (!list->ready && !list->buffer) { if (!list->ready && !list->buffer) {
add_wait_queue(&list->mousedev->wait, &wait); add_wait_queue(&list->mousedev->wait, &wait);
current->state = TASK_INTERRUPTIBLE; set_current_state(TASK_INTERRUPTIBLE);
while (!list->ready) { while (!list->ready) {
...@@ -360,7 +371,7 @@ static ssize_t mousedev_read(struct file * file, char * buffer, size_t count, lo ...@@ -360,7 +371,7 @@ static ssize_t mousedev_read(struct file * file, char * buffer, size_t count, lo
schedule(); schedule();
} }
current->state = TASK_RUNNING; set_current_state(TASK_RUNNING);
remove_wait_queue(&list->mousedev->wait, &wait); remove_wait_queue(&list->mousedev->wait, &wait);
} }
...@@ -401,19 +412,11 @@ struct file_operations mousedev_fops = { ...@@ -401,19 +412,11 @@ struct file_operations mousedev_fops = {
fasync: mousedev_fasync, fasync: mousedev_fasync,
}; };
static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev) static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
{ {
struct mousedev *mousedev; struct mousedev *mousedev;
int minor = 0; int minor = 0;
if (!test_bit(EV_KEY, dev->evbit) ||
(!test_bit(BTN_LEFT, dev->keybit) && !test_bit(BTN_TOUCH, dev->keybit)))
return NULL;
if ((!test_bit(EV_REL, dev->evbit) || !test_bit(REL_X, dev->relbit)) &&
(!test_bit(EV_ABS, dev->evbit) || !test_bit(ABS_X, dev->absbit)))
return NULL;
for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++); for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
if (minor == MOUSEDEV_MINORS) { if (minor == MOUSEDEV_MINORS) {
printk(KERN_ERR "mousedev: no more free mousedev devices\n"); printk(KERN_ERR "mousedev: no more free mousedev devices\n");
...@@ -425,11 +428,12 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru ...@@ -425,11 +428,12 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru
memset(mousedev, 0, sizeof(struct mousedev)); memset(mousedev, 0, sizeof(struct mousedev));
init_waitqueue_head(&mousedev->wait); init_waitqueue_head(&mousedev->wait);
mousedev->exist = 1;
mousedev->minor = minor; mousedev->minor = minor;
mousedev_table[minor] = mousedev; mousedev_table[minor] = mousedev;
sprintf(mousedev->name, "mouse%d", minor);
mousedev->handle.dev = dev; mousedev->handle.dev = dev;
mousedev->handle.name = mousedev->name;
mousedev->handle.handler = handler; mousedev->handle.handler = handler;
mousedev->handle.private = mousedev; mousedev->handle.private = mousedev;
...@@ -438,7 +442,7 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru ...@@ -438,7 +442,7 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru
if (mousedev_mix.open) if (mousedev_mix.open)
input_open_device(&mousedev->handle); input_open_device(&mousedev->handle);
// printk(KERN_INFO "mouse%d: PS/2 mouse device for input%d\n", minor, dev->number); mousedev->exist = 1;
return &mousedev->handle; return &mousedev->handle;
} }
...@@ -459,6 +463,26 @@ static void mousedev_disconnect(struct input_handle *handle) ...@@ -459,6 +463,26 @@ static void mousedev_disconnect(struct input_handle *handle)
kfree(mousedev); kfree(mousedev);
} }
} }
static struct input_device_id mousedev_ids[] = {
{
flags: INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
evbit: { BIT(EV_KEY) | BIT(EV_REL) },
keybit: { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) },
relbit: { BIT(REL_X) | BIT(REL_Y) },
}, /* A mouse like device, at least one button, two relative axes */
{
flags: INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
evbit: { BIT(EV_KEY) | BIT(EV_ABS) },
keybit: { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
absbit: { BIT(ABS_X) | BIT(ABS_Y) },
}, /* A tablet like device, at least touch detection, two absolute axes */
{ }, /* Terminating entry */
};
MODULE_DEVICE_TABLE(input, mousedev_ids);
static struct input_handler mousedev_handler = { static struct input_handler mousedev_handler = {
event: mousedev_event, event: mousedev_event,
...@@ -466,6 +490,8 @@ static struct input_handler mousedev_handler = { ...@@ -466,6 +490,8 @@ static struct input_handler mousedev_handler = {
disconnect: mousedev_disconnect, disconnect: mousedev_disconnect,
fops: &mousedev_fops, fops: &mousedev_fops,
minor: MOUSEDEV_MINOR_BASE, minor: MOUSEDEV_MINOR_BASE,
name: "mousedev",
id_table: mousedev_ids,
}; };
static int __init mousedev_init(void) static int __init mousedev_init(void)
...@@ -493,10 +519,6 @@ static void __exit mousedev_exit(void) ...@@ -493,10 +519,6 @@ static void __exit mousedev_exit(void)
module_init(mousedev_init); module_init(mousedev_init);
module_exit(mousedev_exit); module_exit(mousedev_exit);
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("Input driver to PS/2 or ImPS/2 device driver");
MODULE_LICENSE("GPL");
MODULE_PARM(xres, "i"); MODULE_PARM(xres, "i");
MODULE_PARM_DESC(xres, "Horizontal screen resolution"); MODULE_PARM_DESC(xres, "Horizontal screen resolution");
MODULE_PARM(yres, "i"); MODULE_PARM(yres, "i");
......
...@@ -2,11 +2,9 @@ ...@@ -2,11 +2,9 @@
#define _GAMEPORT_H #define _GAMEPORT_H
/* /*
* $Id: gameport.h,v 1.11 2001/04/26 10:24:46 vojtech Exp $ * $Id: gameport.h,v 1.20 2002/01/03 08:55:05 vojtech Exp $
* *
* Copyright (c) 1999-2000 Vojtech Pavlik * Copyright (c) 1999-2001 Vojtech Pavlik
*
* Sponsored by SuSE
*/ */
/* /*
...@@ -26,21 +24,27 @@ ...@@ -26,21 +24,27 @@
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/ */
#include <linux/sched.h>
#include <linux/delay.h>
#include <asm/io.h> #include <asm/io.h>
#include <linux/input.h>
struct gameport; struct gameport;
struct gameport { struct gameport {
void *private; void *private; /* Private pointer for joystick drivers */
void *driver; /* Private pointer for gameport drivers */
char *name;
char *phys;
int number; int number;
unsigned short idbus;
unsigned short idvendor;
unsigned short idproduct;
unsigned short idversion;
int io; int io;
int speed; int speed;
int fuzz; int fuzz;
...@@ -59,6 +63,7 @@ struct gameport { ...@@ -59,6 +63,7 @@ struct gameport {
struct gameport_dev { struct gameport_dev {
void *private; void *private;
char *name;
void (*connect)(struct gameport *, struct gameport_dev *dev); void (*connect)(struct gameport *, struct gameport_dev *dev);
void (*disconnect)(struct gameport *); void (*disconnect)(struct gameport *);
...@@ -74,8 +79,8 @@ void gameport_rescan(struct gameport *gameport); ...@@ -74,8 +79,8 @@ void gameport_rescan(struct gameport *gameport);
void gameport_register_port(struct gameport *gameport); void gameport_register_port(struct gameport *gameport);
void gameport_unregister_port(struct gameport *gameport); void gameport_unregister_port(struct gameport *gameport);
#else #else
static void __inline__ gameport_register_port(struct gameport *gameport) { return; } void __inline__ gameport_register_port(struct gameport *gameport) { return; }
static void __inline__ gameport_unregister_port(struct gameport *gameport) { return; } void __inline__ gameport_unregister_port(struct gameport *gameport) { return; }
#endif #endif
void gameport_register_device(struct gameport_dev *dev); void gameport_register_device(struct gameport_dev *dev);
...@@ -94,6 +99,7 @@ void gameport_unregister_device(struct gameport_dev *dev); ...@@ -94,6 +99,7 @@ void gameport_unregister_device(struct gameport_dev *dev);
#define GAMEPORT_ID_VENDOR_MICROSOFT 0x0007 #define GAMEPORT_ID_VENDOR_MICROSOFT 0x0007
#define GAMEPORT_ID_VENDOR_THRUSTMASTER 0x0008 #define GAMEPORT_ID_VENDOR_THRUSTMASTER 0x0008
#define GAMEPORT_ID_VENDOR_GRAVIS 0x0009 #define GAMEPORT_ID_VENDOR_GRAVIS 0x0009
#define GAMEPORT_ID_VENDOR_GUILLEMOT 0x000a
static __inline__ void gameport_trigger(struct gameport *gameport) static __inline__ void gameport_trigger(struct gameport *gameport)
{ {
...@@ -134,7 +140,7 @@ static __inline__ int gameport_time(struct gameport *gameport, int time) ...@@ -134,7 +140,7 @@ static __inline__ int gameport_time(struct gameport *gameport, int time)
static __inline__ void wait_ms(unsigned int ms) static __inline__ void wait_ms(unsigned int ms)
{ {
current->state = TASK_UNINTERRUPTIBLE; set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1 + ms * HZ / 1000); schedule_timeout(1 + ms * HZ / 1000);
} }
......
This diff is collapsed.
...@@ -2,31 +2,29 @@ ...@@ -2,31 +2,29 @@
#define _SERIO_H #define _SERIO_H
/* /*
* $Id: serio.h,v 1.11 2001/05/29 02:58:50 jsimmons Exp $ * $Id: serio.h,v 1.21 2001/12/19 05:15:21 skids Exp $
* *
* Copyright (C) 1999 Vojtech Pavlik * Copyright (C) 1999-2001 Vojtech Pavlik
*
* Sponsored by SuSE
*/ */
/* /*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/ */
/* /*
...@@ -42,23 +40,31 @@ struct serio { ...@@ -42,23 +40,31 @@ struct serio {
void *private; void *private;
void *driver; void *driver;
char *name;
char *phys;
int number;
unsigned short idbus;
unsigned short idvendor;
unsigned short idproduct;
unsigned short idversion;
unsigned long type; unsigned long type;
int number;
int (*write)(struct serio *, unsigned char); int (*write)(struct serio *, unsigned char);
int (*open)(struct serio *); int (*open)(struct serio *);
void (*close)(struct serio *); void (*close)(struct serio *);
struct serio_dev *dev; struct serio_dev *dev;
struct serio *next; struct serio *next;
}; };
struct serio_dev { struct serio_dev {
void *private; void *private;
char *name;
void (*write_wakeup)(struct serio *);
void (*interrupt)(struct serio *, unsigned char, unsigned int); void (*interrupt)(struct serio *, unsigned char, unsigned int);
void (*connect)(struct serio *, struct serio_dev *dev); void (*connect)(struct serio *, struct serio_dev *dev);
void (*disconnect)(struct serio *); void (*disconnect)(struct serio *);
...@@ -80,6 +86,13 @@ static __inline__ int serio_write(struct serio *serio, unsigned char data) ...@@ -80,6 +86,13 @@ static __inline__ int serio_write(struct serio *serio, unsigned char data)
return serio->write(serio, data); return serio->write(serio, data);
} }
static __inline__ void serio_dev_write_wakeup(struct serio *serio)
{
if (serio->dev && serio->dev->write_wakeup) {
serio->dev->write_wakeup(serio);
}
}
#define SERIO_TIMEOUT 1 #define SERIO_TIMEOUT 1
#define SERIO_PARITY 2 #define SERIO_PARITY 2
...@@ -87,6 +100,7 @@ static __inline__ int serio_write(struct serio *serio, unsigned char data) ...@@ -87,6 +100,7 @@ static __inline__ int serio_write(struct serio *serio, unsigned char data)
#define SERIO_XT 0x00000000UL #define SERIO_XT 0x00000000UL
#define SERIO_8042 0x01000000UL #define SERIO_8042 0x01000000UL
#define SERIO_RS232 0x02000000UL #define SERIO_RS232 0x02000000UL
#define SERIO_HIL_MLC 0x03000000UL
#define SERIO_PROTO 0xFFUL #define SERIO_PROTO 0xFFUL
#define SERIO_MSC 0x01 #define SERIO_MSC 0x01
...@@ -108,6 +122,9 @@ static __inline__ int serio_write(struct serio *serio, unsigned char data) ...@@ -108,6 +122,9 @@ static __inline__ int serio_write(struct serio *serio, unsigned char data)
#define SERIO_STOWAWAY 0x20 #define SERIO_STOWAWAY 0x20
#define SERIO_H3600 0x21 #define SERIO_H3600 0x21
#define SERIO_PS2SER 0x22 #define SERIO_PS2SER 0x22
#define SERIO_TWIDKBD 0x23
#define SERIO_TWIDJOY 0x24
#define SERIO_HIL 0x25
#define SERIO_ID 0xff00UL #define SERIO_ID 0xff00UL
#define SERIO_EXTRA 0xff0000UL #define SERIO_EXTRA 0xff0000UL
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment