Commit cdf4f383 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/dtor/input

* master.kernel.org:/pub/scm/linux/kernel/git/dtor/input:
  Input: iforce - remove some pointless casts
  Input: psmouse - add support for Intellimouse 4.0
  Input: atkbd - fix HANGEUL/HANJA keys
  Input: fix misspelling of Hangeul key
  Input: via-pmu - add input device support
  Input: rearrange exports
  Input: fix formatting to better follow CodingStyle
  Input: reset name, phys and uniq when unregistering
  Input: return correct size when reading modalias attribute
  Input: change my e-mail address in MAINTAINERS file
  Input: fix potential overflows in driver/input/keyboard
  Input: fix potential overflows in driver/input/touchscreen
  Input: fix potential overflows in driver/input/joystick
  Input: fix potential overflows in driver/input/mouse
  Input: fix accuracy of fixp-arith.h
  Input: iforce - use ENOSPC instead of ENOMEM
  Input: constify drivers/char/keyboard.c
parents 954b36d4 e2e8115b
...@@ -1401,7 +1401,8 @@ S: Supported ...@@ -1401,7 +1401,8 @@ S: Supported
INPUT (KEYBOARD, MOUSE, JOYSTICK) DRIVERS INPUT (KEYBOARD, MOUSE, JOYSTICK) DRIVERS
P: Dmitry Torokhov P: Dmitry Torokhov
M: dtor_core@ameritech.net M: dmitry.torokhov@gmail.com
M: dtor@mail.ru
L: linux-input@atrey.karlin.mff.cuni.cz L: linux-input@atrey.karlin.mff.cuni.cz
L: linux-joystick@atrey.karlin.mff.cuni.cz L: linux-joystick@atrey.karlin.mff.cuni.cz
T: git kernel.org:/pub/scm/linux/kernel/git/dtor/input.git T: git kernel.org:/pub/scm/linux/kernel/git/dtor/input.git
......
...@@ -674,7 +674,7 @@ static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag, struc ...@@ -674,7 +674,7 @@ static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag, struc
*/ */
static void k_dead(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) static void k_dead(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
{ {
static unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' }; static const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' };
value = ret_diacr[value]; value = ret_diacr[value];
k_deadunicode(vc, value, up_flag, regs); k_deadunicode(vc, value, up_flag, regs);
} }
...@@ -711,8 +711,8 @@ static void k_cur(struct vc_data *vc, unsigned char value, char up_flag, struct ...@@ -711,8 +711,8 @@ static void k_cur(struct vc_data *vc, unsigned char value, char up_flag, struct
static void k_pad(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) static void k_pad(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
{ {
static const char *pad_chars = "0123456789+-*/\015,.?()#"; static const char pad_chars[] = "0123456789+-*/\015,.?()#";
static const char *app_map = "pqrstuvwxylSRQMnnmPQS"; static const char app_map[] = "pqrstuvwxylSRQMnnmPQS";
if (up_flag) if (up_flag)
return; /* no action, if this is a key release */ return; /* no action, if this is a key release */
...@@ -1037,7 +1037,7 @@ static void kbd_refresh_leds(struct input_handle *handle) ...@@ -1037,7 +1037,7 @@ static void kbd_refresh_leds(struct input_handle *handle)
#define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\ #define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001)) ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
static unsigned short x86_keycodes[256] = static const 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,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
...@@ -1075,11 +1075,13 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, ...@@ -1075,11 +1075,13 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode,
put_queue(vc, 0x1d | up_flag); put_queue(vc, 0x1d | up_flag);
put_queue(vc, 0x45 | up_flag); put_queue(vc, 0x45 | up_flag);
return 0; return 0;
case KEY_HANGUEL: case KEY_HANGEUL:
if (!up_flag) put_queue(vc, 0xf1); if (!up_flag)
put_queue(vc, 0xf2);
return 0; return 0;
case KEY_HANJA: case KEY_HANJA:
if (!up_flag) put_queue(vc, 0xf2); if (!up_flag)
put_queue(vc, 0xf1);
return 0; return 0;
} }
......
...@@ -78,14 +78,19 @@ static int evdev_fasync(int fd, struct file *file, int on) ...@@ -78,14 +78,19 @@ static int evdev_fasync(int fd, struct file *file, int on)
{ {
int retval; int retval;
struct evdev_list *list = file->private_data; struct evdev_list *list = file->private_data;
retval = fasync_helper(fd, file, on, &list->fasync); retval = fasync_helper(fd, file, on, &list->fasync);
return retval < 0 ? retval : 0; return retval < 0 ? retval : 0;
} }
static int evdev_flush(struct file * file, fl_owner_t id) static int evdev_flush(struct file *file, fl_owner_t id)
{ {
struct evdev_list *list = file->private_data; struct evdev_list *list = file->private_data;
if (!list->evdev->exist) return -ENODEV;
if (!list->evdev->exist)
return -ENODEV;
return input_flush_device(&list->evdev->handle, file); return input_flush_device(&list->evdev->handle, file);
} }
...@@ -300,6 +305,7 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count ...@@ -300,6 +305,7 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count
static unsigned int evdev_poll(struct file *file, poll_table *wait) static unsigned int evdev_poll(struct file *file, poll_table *wait)
{ {
struct evdev_list *list = file->private_data; struct evdev_list *list = file->private_data;
poll_wait(file, &list->evdev->wait, wait); poll_wait(file, &list->evdev->wait, wait);
return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) |
(list->evdev->exist ? 0 : (POLLHUP | POLLERR)); (list->evdev->exist ? 0 : (POLLHUP | POLLERR));
......
...@@ -28,20 +28,6 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); ...@@ -28,20 +28,6 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("Input core"); MODULE_DESCRIPTION("Input core");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
EXPORT_SYMBOL(input_allocate_device);
EXPORT_SYMBOL(input_register_device);
EXPORT_SYMBOL(input_unregister_device);
EXPORT_SYMBOL(input_register_handler);
EXPORT_SYMBOL(input_unregister_handler);
EXPORT_SYMBOL(input_grab_device);
EXPORT_SYMBOL(input_release_device);
EXPORT_SYMBOL(input_open_device);
EXPORT_SYMBOL(input_close_device);
EXPORT_SYMBOL(input_accept_process);
EXPORT_SYMBOL(input_flush_device);
EXPORT_SYMBOL(input_event);
EXPORT_SYMBOL_GPL(input_class);
#define INPUT_DEVICES 256 #define INPUT_DEVICES 256
static LIST_HEAD(input_dev_list); static LIST_HEAD(input_dev_list);
...@@ -63,11 +49,13 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in ...@@ -63,11 +49,13 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
case EV_SYN: case EV_SYN:
switch (code) { switch (code) {
case SYN_CONFIG: case SYN_CONFIG:
if (dev->event) dev->event(dev, type, code, value); if (dev->event)
dev->event(dev, type, code, value);
break; break;
case SYN_REPORT: case SYN_REPORT:
if (dev->sync) return; if (dev->sync)
return;
dev->sync = 1; dev->sync = 1;
break; break;
} }
...@@ -136,7 +124,8 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in ...@@ -136,7 +124,8 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
if (code > MSC_MAX || !test_bit(code, dev->mscbit)) if (code > MSC_MAX || !test_bit(code, dev->mscbit))
return; return;
if (dev->event) dev->event(dev, type, code, value); if (dev->event)
dev->event(dev, type, code, value);
break; break;
...@@ -146,7 +135,9 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in ...@@ -146,7 +135,9 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
return; return;
change_bit(code, dev->led); change_bit(code, dev->led);
if (dev->event) dev->event(dev, type, code, value);
if (dev->event)
dev->event(dev, type, code, value);
break; break;
...@@ -158,21 +149,25 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in ...@@ -158,21 +149,25 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
if (!!test_bit(code, dev->snd) != !!value) if (!!test_bit(code, dev->snd) != !!value)
change_bit(code, dev->snd); change_bit(code, dev->snd);
if (dev->event) dev->event(dev, type, code, value); if (dev->event)
dev->event(dev, type, code, value);
break; break;
case EV_REP: case EV_REP:
if (code > REP_MAX || value < 0 || dev->rep[code] == value) return; if (code > REP_MAX || value < 0 || dev->rep[code] == value)
return;
dev->rep[code] = value; dev->rep[code] = value;
if (dev->event) dev->event(dev, type, code, value); if (dev->event)
dev->event(dev, type, code, value);
break; break;
case EV_FF: case EV_FF:
if (dev->event) dev->event(dev, type, code, value); if (dev->event)
dev->event(dev, type, code, value);
break; break;
} }
...@@ -186,6 +181,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in ...@@ -186,6 +181,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
if (handle->open) if (handle->open)
handle->handler->event(handle, type, code, value); handle->handler->event(handle, type, code, value);
} }
EXPORT_SYMBOL(input_event);
static void input_repeat_key(unsigned long data) static void input_repeat_key(unsigned long data)
{ {
...@@ -208,6 +204,7 @@ int input_accept_process(struct input_handle *handle, struct file *file) ...@@ -208,6 +204,7 @@ int input_accept_process(struct input_handle *handle, struct file *file)
return 0; return 0;
} }
EXPORT_SYMBOL(input_accept_process);
int input_grab_device(struct input_handle *handle) int input_grab_device(struct input_handle *handle)
{ {
...@@ -217,12 +214,14 @@ int input_grab_device(struct input_handle *handle) ...@@ -217,12 +214,14 @@ int input_grab_device(struct input_handle *handle)
handle->dev->grab = handle; handle->dev->grab = handle;
return 0; return 0;
} }
EXPORT_SYMBOL(input_grab_device);
void input_release_device(struct input_handle *handle) void input_release_device(struct input_handle *handle)
{ {
if (handle->dev->grab == handle) if (handle->dev->grab == handle)
handle->dev->grab = NULL; handle->dev->grab = NULL;
} }
EXPORT_SYMBOL(input_release_device);
int input_open_device(struct input_handle *handle) int input_open_device(struct input_handle *handle)
{ {
...@@ -245,6 +244,7 @@ int input_open_device(struct input_handle *handle) ...@@ -245,6 +244,7 @@ int input_open_device(struct input_handle *handle)
return err; return err;
} }
EXPORT_SYMBOL(input_open_device);
int input_flush_device(struct input_handle* handle, struct file* file) int input_flush_device(struct input_handle* handle, struct file* file)
{ {
...@@ -253,6 +253,7 @@ int input_flush_device(struct input_handle* handle, struct file* file) ...@@ -253,6 +253,7 @@ int input_flush_device(struct input_handle* handle, struct file* file)
return 0; return 0;
} }
EXPORT_SYMBOL(input_flush_device);
void input_close_device(struct input_handle *handle) void input_close_device(struct input_handle *handle)
{ {
...@@ -268,6 +269,7 @@ void input_close_device(struct input_handle *handle) ...@@ -268,6 +269,7 @@ void input_close_device(struct input_handle *handle)
mutex_unlock(&dev->mutex); mutex_unlock(&dev->mutex);
} }
EXPORT_SYMBOL(input_close_device);
static void input_link_handle(struct input_handle *handle) static void input_link_handle(struct input_handle *handle)
{ {
...@@ -335,9 +337,11 @@ static inline void input_wakeup_procfs_readers(void) ...@@ -335,9 +337,11 @@ static inline void input_wakeup_procfs_readers(void)
static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait) static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait)
{ {
int state = input_devices_state; int state = input_devices_state;
poll_wait(file, &input_devices_poll_wait, wait); poll_wait(file, &input_devices_poll_wait, wait);
if (state != input_devices_state) if (state != input_devices_state)
return POLLIN | POLLRDNORM; return POLLIN | POLLRDNORM;
return 0; return 0;
} }
...@@ -629,7 +633,7 @@ static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf) ...@@ -629,7 +633,7 @@ static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
len = input_print_modalias(buf, PAGE_SIZE, id, 1); len = input_print_modalias(buf, PAGE_SIZE, id, 1);
return max_t(int, len, PAGE_SIZE); return min_t(int, len, PAGE_SIZE);
} }
static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
...@@ -862,6 +866,7 @@ struct class input_class = { ...@@ -862,6 +866,7 @@ struct class input_class = {
.release = input_dev_release, .release = input_dev_release,
.uevent = input_dev_uevent, .uevent = input_dev_uevent,
}; };
EXPORT_SYMBOL_GPL(input_class);
struct input_dev *input_allocate_device(void) struct input_dev *input_allocate_device(void)
{ {
...@@ -872,12 +877,27 @@ struct input_dev *input_allocate_device(void) ...@@ -872,12 +877,27 @@ struct input_dev *input_allocate_device(void)
dev->dynalloc = 1; dev->dynalloc = 1;
dev->cdev.class = &input_class; dev->cdev.class = &input_class;
class_device_initialize(&dev->cdev); class_device_initialize(&dev->cdev);
mutex_init(&dev->mutex);
INIT_LIST_HEAD(&dev->h_list); INIT_LIST_HEAD(&dev->h_list);
INIT_LIST_HEAD(&dev->node); INIT_LIST_HEAD(&dev->node);
} }
return dev; return dev;
} }
EXPORT_SYMBOL(input_allocate_device);
void input_free_device(struct input_dev *dev)
{
if (dev) {
mutex_lock(&dev->mutex);
dev->name = dev->phys = dev->uniq = NULL;
mutex_unlock(&dev->mutex);
input_put_device(dev);
}
}
EXPORT_SYMBOL(input_free_device);
int input_register_device(struct input_dev *dev) int input_register_device(struct input_dev *dev)
{ {
...@@ -895,7 +915,6 @@ int input_register_device(struct input_dev *dev) ...@@ -895,7 +915,6 @@ int input_register_device(struct input_dev *dev)
return -EINVAL; return -EINVAL;
} }
mutex_init(&dev->mutex);
set_bit(EV_SYN, dev->evbit); set_bit(EV_SYN, dev->evbit);
/* /*
...@@ -956,12 +975,14 @@ int input_register_device(struct input_dev *dev) ...@@ -956,12 +975,14 @@ int input_register_device(struct input_dev *dev)
fail1: class_device_del(&dev->cdev); fail1: class_device_del(&dev->cdev);
return error; return error;
} }
EXPORT_SYMBOL(input_register_device);
void input_unregister_device(struct input_dev *dev) void input_unregister_device(struct input_dev *dev)
{ {
struct list_head * node, * next; struct list_head *node, *next;
if (!dev) return; if (!dev)
return;
del_timer_sync(&dev->timer); del_timer_sync(&dev->timer);
...@@ -979,8 +1000,13 @@ void input_unregister_device(struct input_dev *dev) ...@@ -979,8 +1000,13 @@ void input_unregister_device(struct input_dev *dev)
sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
class_device_unregister(&dev->cdev); class_device_unregister(&dev->cdev);
mutex_lock(&dev->mutex);
dev->name = dev->phys = dev->uniq = NULL;
mutex_unlock(&dev->mutex);
input_wakeup_procfs_readers(); input_wakeup_procfs_readers();
} }
EXPORT_SYMBOL(input_unregister_device);
void input_register_handler(struct input_handler *handler) void input_register_handler(struct input_handler *handler)
{ {
...@@ -988,7 +1014,8 @@ void input_register_handler(struct input_handler *handler) ...@@ -988,7 +1014,8 @@ void input_register_handler(struct input_handler *handler)
struct input_handle *handle; struct input_handle *handle;
struct input_device_id *id; struct input_device_id *id;
if (!handler) return; if (!handler)
return;
INIT_LIST_HEAD(&handler->h_list); INIT_LIST_HEAD(&handler->h_list);
...@@ -1005,10 +1032,11 @@ void input_register_handler(struct input_handler *handler) ...@@ -1005,10 +1032,11 @@ void input_register_handler(struct input_handler *handler)
input_wakeup_procfs_readers(); input_wakeup_procfs_readers();
} }
EXPORT_SYMBOL(input_register_handler);
void input_unregister_handler(struct input_handler *handler) void input_unregister_handler(struct input_handler *handler)
{ {
struct list_head * node, * next; struct list_head *node, *next;
list_for_each_safe(node, next, &handler->h_list) { list_for_each_safe(node, next, &handler->h_list) {
struct input_handle * handle = to_handle_h(node); struct input_handle * handle = to_handle_h(node);
...@@ -1024,6 +1052,7 @@ void input_unregister_handler(struct input_handler *handler) ...@@ -1024,6 +1052,7 @@ void input_unregister_handler(struct input_handler *handler)
input_wakeup_procfs_readers(); input_wakeup_procfs_readers();
} }
EXPORT_SYMBOL(input_unregister_handler);
static int input_open_file(struct inode *inode, struct file *file) static int input_open_file(struct inode *inode, struct file *file)
{ {
......
...@@ -81,10 +81,7 @@ static int joydev_correct(int value, struct js_corr *corr) ...@@ -81,10 +81,7 @@ static int joydev_correct(int value, struct js_corr *corr)
return 0; return 0;
} }
if (value < -32767) return -32767; return value < -32767 ? -32767 : (value > 32767 ? 32767 : value);
if (value > 32767) return 32767;
return value;
} }
static void joydev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) static void joydev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
...@@ -96,7 +93,8 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne ...@@ -96,7 +93,8 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne
switch (type) { switch (type) {
case EV_KEY: case EV_KEY:
if (code < BTN_MISC || value == 2) return; if (code < BTN_MISC || value == 2)
return;
event.type = JS_EVENT_BUTTON; event.type = JS_EVENT_BUTTON;
event.number = joydev->keymap[code - BTN_MISC]; event.number = joydev->keymap[code - BTN_MISC];
event.value = value; event.value = value;
...@@ -106,7 +104,8 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne ...@@ -106,7 +104,8 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne
event.type = JS_EVENT_AXIS; event.type = JS_EVENT_AXIS;
event.number = joydev->absmap[code]; event.number = joydev->absmap[code];
event.value = joydev_correct(value, joydev->corr + event.number); event.value = joydev_correct(value, joydev->corr + event.number);
if (event.value == joydev->abs[event.number]) return; if (event.value == joydev->abs[event.number])
return;
joydev->abs[event.number] = event.value; joydev->abs[event.number] = event.value;
break; break;
...@@ -134,7 +133,9 @@ static int joydev_fasync(int fd, struct file *file, int on) ...@@ -134,7 +133,9 @@ static int joydev_fasync(int fd, struct file *file, int on)
{ {
int retval; int retval;
struct joydev_list *list = file->private_data; struct joydev_list *list = file->private_data;
retval = fasync_helper(fd, file, on, &list->fasync); retval = fasync_helper(fd, file, on, &list->fasync);
return retval < 0 ? retval : 0; return retval < 0 ? retval : 0;
} }
...@@ -222,8 +223,8 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo ...@@ -222,8 +223,8 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo
return sizeof(struct JS_DATA_TYPE); return sizeof(struct JS_DATA_TYPE);
} }
if (list->startup == joydev->nabs + joydev->nkey if (list->startup == joydev->nabs + joydev->nkey &&
&& list->head == list->tail && (file->f_flags & O_NONBLOCK)) list->head == list->tail && (file->f_flags & O_NONBLOCK))
return -EAGAIN; return -EAGAIN;
retval = wait_event_interruptible(list->joydev->wait, retval = wait_event_interruptible(list->joydev->wait,
...@@ -276,6 +277,7 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo ...@@ -276,6 +277,7 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo
static unsigned int joydev_poll(struct file *file, poll_table *wait) static unsigned int joydev_poll(struct file *file, poll_table *wait)
{ {
struct joydev_list *list = file->private_data; struct joydev_list *list = file->private_data;
poll_wait(file, &list->joydev->wait, wait); poll_wait(file, &list->joydev->wait, wait);
return ((list->head != list->tail || list->startup < list->joydev->nabs + list->joydev->nkey) ? return ((list->head != list->tail || list->startup < list->joydev->nabs + list->joydev->nkey) ?
(POLLIN | POLLRDNORM) : 0) | (list->joydev->exist ? 0 : (POLLHUP | POLLERR)); (POLLIN | POLLRDNORM) : 0) | (list->joydev->exist ? 0 : (POLLHUP | POLLERR));
...@@ -291,20 +293,26 @@ static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __u ...@@ -291,20 +293,26 @@ static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __u
case JS_SET_CAL: case JS_SET_CAL:
return copy_from_user(&joydev->glue.JS_CORR, argp, return copy_from_user(&joydev->glue.JS_CORR, argp,
sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0; sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
case JS_GET_CAL: case JS_GET_CAL:
return copy_to_user(argp, &joydev->glue.JS_CORR, return copy_to_user(argp, &joydev->glue.JS_CORR,
sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0; sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
case JS_SET_TIMEOUT: case JS_SET_TIMEOUT:
return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp); return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
case JS_GET_TIMEOUT: case JS_GET_TIMEOUT:
return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp); return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
case JSIOCGVERSION: case JSIOCGVERSION:
return put_user(JS_VERSION, (__u32 __user *) argp); return put_user(JS_VERSION, (__u32 __user *) argp);
case JSIOCGAXES: case JSIOCGAXES:
return put_user(joydev->nabs, (__u8 __user *) argp); return put_user(joydev->nabs, (__u8 __user *) argp);
case JSIOCGBUTTONS: case JSIOCGBUTTONS:
return put_user(joydev->nkey, (__u8 __user *) argp); return put_user(joydev->nkey, (__u8 __user *) argp);
case JSIOCSCORR: case JSIOCSCORR:
if (copy_from_user(joydev->corr, argp, if (copy_from_user(joydev->corr, argp,
sizeof(joydev->corr[0]) * joydev->nabs)) sizeof(joydev->corr[0]) * joydev->nabs))
...@@ -314,38 +322,49 @@ static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __u ...@@ -314,38 +322,49 @@ static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __u
joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i); joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i);
} }
return 0; return 0;
case JSIOCGCORR: case JSIOCGCORR:
return copy_to_user(argp, joydev->corr, return copy_to_user(argp, joydev->corr,
sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0; sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
case JSIOCSAXMAP: case JSIOCSAXMAP:
if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * (ABS_MAX + 1))) if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * (ABS_MAX + 1)))
return -EFAULT; return -EFAULT;
for (i = 0; i < joydev->nabs; 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;
} }
return 0; return 0;
case JSIOCGAXMAP: case JSIOCGAXMAP:
return copy_to_user(argp, joydev->abspam, return copy_to_user(argp, joydev->abspam,
sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0; sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0;
case JSIOCSBTNMAP: case JSIOCSBTNMAP:
if (copy_from_user(joydev->keypam, argp, sizeof(__u16) * (KEY_MAX - BTN_MISC + 1))) if (copy_from_user(joydev->keypam, argp, sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)))
return -EFAULT; return -EFAULT;
for (i = 0; i < joydev->nkey; 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->keypam[i] - BTN_MISC] = i; joydev->keymap[joydev->keypam[i] - BTN_MISC] = i;
} }
return 0; return 0;
case JSIOCGBTNMAP: case JSIOCGBTNMAP:
return copy_to_user(argp, joydev->keypam, return copy_to_user(argp, joydev->keypam,
sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0; sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0;
default: default:
if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) { if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) {
int len; int len;
if (!dev->name) return 0; if (!dev->name)
return 0;
len = strlen(dev->name) + 1; len = strlen(dev->name) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); if (len > _IOC_SIZE(cmd))
if (copy_to_user(argp, dev->name, len)) return -EFAULT; len = _IOC_SIZE(cmd);
if (copy_to_user(argp, dev->name, len))
return -EFAULT;
return len; return len;
} }
} }
...@@ -362,7 +381,9 @@ static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo ...@@ -362,7 +381,9 @@ static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo
struct JS_DATA_SAVE_TYPE_32 ds32; struct JS_DATA_SAVE_TYPE_32 ds32;
int err; int err;
if (!joydev->exist) return -ENODEV; if (!joydev->exist)
return -ENODEV;
switch(cmd) { switch(cmd) {
case JS_SET_TIMELIMIT: case JS_SET_TIMELIMIT:
err = get_user(tmp32, (s32 __user *) arg); err = get_user(tmp32, (s32 __user *) arg);
...@@ -395,8 +416,7 @@ static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo ...@@ -395,8 +416,7 @@ static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo
ds32.JS_SAVE = joydev->glue.JS_SAVE; ds32.JS_SAVE = joydev->glue.JS_SAVE;
ds32.JS_CORR = joydev->glue.JS_CORR; ds32.JS_CORR = joydev->glue.JS_CORR;
err = copy_to_user(argp, &ds32, err = copy_to_user(argp, &ds32, sizeof(ds32)) ? -EFAULT : 0;
sizeof(ds32)) ? -EFAULT : 0;
break; break;
default: default:
...@@ -412,7 +432,8 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -412,7 +432,8 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
struct joydev *joydev = list->joydev; struct joydev *joydev = list->joydev;
void __user *argp = (void __user *)arg; void __user *argp = (void __user *)arg;
if (!joydev->exist) return -ENODEV; if (!joydev->exist)
return -ENODEV;
switch(cmd) { switch(cmd) {
case JS_SET_TIMELIMIT: case JS_SET_TIMELIMIT:
...@@ -547,7 +568,7 @@ static struct input_device_id joydev_blacklist[] = { ...@@ -547,7 +568,7 @@ static struct input_device_id joydev_blacklist[] = {
.evbit = { BIT(EV_KEY) }, .evbit = { BIT(EV_KEY) },
.keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
}, /* Avoid itouchpads, touchscreens and tablets */ }, /* Avoid itouchpads, touchscreens and tablets */
{ }, /* Terminating entry */ { } /* Terminating entry */
}; };
static struct input_device_id joydev_ids[] = { static struct input_device_id joydev_ids[] = {
...@@ -566,7 +587,7 @@ static struct input_device_id joydev_ids[] = { ...@@ -566,7 +587,7 @@ static struct input_device_id joydev_ids[] = {
.evbit = { BIT(EV_ABS) }, .evbit = { BIT(EV_ABS) },
.absbit = { BIT(ABS_THROTTLE) }, .absbit = { BIT(ABS_THROTTLE) },
}, },
{ }, /* Terminating entry */ { } /* Terminating entry */
}; };
MODULE_DEVICE_TABLE(input, joydev_ids); MODULE_DEVICE_TABLE(input, joydev_ids);
......
...@@ -306,7 +306,7 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) ...@@ -306,7 +306,7 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv)
gameport_set_poll_handler(gameport, a3d_poll); gameport_set_poll_handler(gameport, a3d_poll);
gameport_set_poll_interval(gameport, 20); gameport_set_poll_interval(gameport, 20);
sprintf(a3d->phys, "%s/input0", gameport->phys); snprintf(a3d->phys, sizeof(a3d->phys), "%s/input0", gameport->phys);
input_dev->name = a3d_names[a3d->mode]; input_dev->name = a3d_names[a3d->mode];
input_dev->phys = a3d->phys; input_dev->phys = a3d->phys;
......
...@@ -408,21 +408,23 @@ static void analog_calibrate_timer(struct analog_port *port) ...@@ -408,21 +408,23 @@ static void analog_calibrate_timer(struct analog_port *port)
static void analog_name(struct analog *analog) static void analog_name(struct analog *analog)
{ {
sprintf(analog->name, "Analog %d-axis %d-button", snprintf(analog->name, sizeof(analog->name), "Analog %d-axis %d-button",
hweight8(analog->mask & ANALOG_AXES_STD), hweight8(analog->mask & ANALOG_AXES_STD),
hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTNS_CHF) * 2 + hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTNS_CHF) * 2 +
hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4); hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4);
if (analog->mask & ANALOG_HATS_ALL) if (analog->mask & ANALOG_HATS_ALL)
sprintf(analog->name, "%s %d-hat", snprintf(analog->name, sizeof(analog->name), "%s %d-hat",
analog->name, hweight16(analog->mask & ANALOG_HATS_ALL)); analog->name, hweight16(analog->mask & ANALOG_HATS_ALL));
if (analog->mask & ANALOG_HAT_FCS) if (analog->mask & ANALOG_HAT_FCS)
strcat(analog->name, " FCS"); strlcat(analog->name, " FCS", sizeof(analog->name));
if (analog->mask & ANALOG_ANY_CHF) if (analog->mask & ANALOG_ANY_CHF)
strcat(analog->name, (analog->mask & ANALOG_SAITEK) ? " Saitek" : " CHF"); strlcat(analog->name, (analog->mask & ANALOG_SAITEK) ? " Saitek" : " CHF",
sizeof(analog->name));
strcat(analog->name, (analog->mask & ANALOG_GAMEPAD) ? " gamepad": " joystick"); strlcat(analog->name, (analog->mask & ANALOG_GAMEPAD) ? " gamepad": " joystick",
sizeof(analog->name));
} }
/* /*
...@@ -435,7 +437,8 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i ...@@ -435,7 +437,8 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i
int i, j, t, v, w, x, y, z; int i, j, t, v, w, x, y, z;
analog_name(analog); analog_name(analog);
sprintf(analog->phys, "%s/input%d", port->gameport->phys, index); snprintf(analog->phys, sizeof(analog->phys),
"%s/input%d", port->gameport->phys, index);
analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn; analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn;
analog->dev = input_dev = input_allocate_device(); analog->dev = input_dev = input_allocate_device();
......
...@@ -202,7 +202,8 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) ...@@ -202,7 +202,8 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv)
goto fail3; goto fail3;
} }
sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i); snprintf(cobra->phys[i], sizeof(cobra->phys[i]),
"%s/input%d", gameport->phys, i);
input_dev->name = "Creative Labs Blaster GamePad Cobra"; input_dev->name = "Creative Labs Blaster GamePad Cobra";
input_dev->phys = cobra->phys[i]; input_dev->phys = cobra->phys[i];
......
...@@ -620,7 +620,8 @@ static struct db9 __init *db9_probe(int parport, int mode) ...@@ -620,7 +620,8 @@ static struct db9 __init *db9_probe(int parport, int mode)
goto err_unreg_devs; goto err_unreg_devs;
} }
sprintf(db9->phys[i], "%s/input%d", db9->pd->port->name, i); snprintf(db9->phys[i], sizeof(db9->phys[i]),
"%s/input%d", db9->pd->port->name, i);
input_dev->name = db9_mode->name; input_dev->name = db9_mode->name;
input_dev->phys = db9->phys[i]; input_dev->phys = db9->phys[i];
......
...@@ -761,7 +761,8 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) ...@@ -761,7 +761,8 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads)
if (!pads[i]) if (!pads[i])
continue; continue;
sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i); snprintf(gc->phys[i], sizeof(gc->phys[i]),
"%s/input%d", gc->pd->port->name, i);
err = gc_setup_pad(gc, i, pads[i]); err = gc_setup_pad(gc, i, pads[i]);
if (err) if (err)
goto err_unreg_devs; goto err_unreg_devs;
......
...@@ -298,7 +298,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) ...@@ -298,7 +298,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv)
gameport_set_poll_handler(gameport, gf2k_poll); gameport_set_poll_handler(gameport, gf2k_poll);
gameport_set_poll_interval(gameport, 20); gameport_set_poll_interval(gameport, 20);
sprintf(gf2k->phys, "%s/input0", gameport->phys); snprintf(gf2k->phys, sizeof(gf2k->phys), "%s/input0", gameport->phys);
gf2k->length = gf2k_lens[gf2k->id]; gf2k->length = gf2k_lens[gf2k->id];
......
...@@ -354,7 +354,8 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) ...@@ -354,7 +354,8 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
goto fail3; goto fail3;
} }
sprintf(grip->phys[i], "%s/input%d", gameport->phys, i); snprintf(grip->phys[i], sizeof(grip->phys[i]),
"%s/input%d", gameport->phys, i);
input_dev->name = grip_name[grip->mode[i]]; input_dev->name = grip_name[grip->mode[i]];
input_dev->phys = grip->phys[i]; input_dev->phys = grip->phys[i];
......
...@@ -222,7 +222,7 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver * ...@@ -222,7 +222,7 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver *
gameport_set_poll_handler(gameport, guillemot_poll); gameport_set_poll_handler(gameport, guillemot_poll);
gameport_set_poll_interval(gameport, 20); gameport_set_poll_interval(gameport, 20);
sprintf(guillemot->phys, "%s/input0", gameport->phys); snprintf(guillemot->phys, sizeof(guillemot->phys), "%s/input0", gameport->phys);
guillemot->type = guillemot_type + i; guillemot->type = guillemot_type + i;
input_dev->name = guillemot_type[i].name; input_dev->name = guillemot_type[i].name;
......
...@@ -47,7 +47,7 @@ static int make_magnitude_modifier(struct iforce* iforce, ...@@ -47,7 +47,7 @@ static int make_magnitude_modifier(struct iforce* iforce,
iforce->device_memory.start, iforce->device_memory.end, 2L, iforce->device_memory.start, iforce->device_memory.end, 2L,
NULL, NULL)) { NULL, NULL)) {
mutex_unlock(&iforce->mem_mutex); mutex_unlock(&iforce->mem_mutex);
return -ENOMEM; return -ENOSPC;
} }
mutex_unlock(&iforce->mem_mutex); mutex_unlock(&iforce->mem_mutex);
} }
...@@ -80,7 +80,7 @@ static int make_period_modifier(struct iforce* iforce, ...@@ -80,7 +80,7 @@ static int make_period_modifier(struct iforce* iforce,
iforce->device_memory.start, iforce->device_memory.end, 2L, iforce->device_memory.start, iforce->device_memory.end, 2L,
NULL, NULL)) { NULL, NULL)) {
mutex_unlock(&iforce->mem_mutex); mutex_unlock(&iforce->mem_mutex);
return -ENOMEM; return -ENOSPC;
} }
mutex_unlock(&iforce->mem_mutex); mutex_unlock(&iforce->mem_mutex);
} }
...@@ -120,7 +120,7 @@ static int make_envelope_modifier(struct iforce* iforce, ...@@ -120,7 +120,7 @@ static int make_envelope_modifier(struct iforce* iforce,
iforce->device_memory.start, iforce->device_memory.end, 2L, iforce->device_memory.start, iforce->device_memory.end, 2L,
NULL, NULL)) { NULL, NULL)) {
mutex_unlock(&iforce->mem_mutex); mutex_unlock(&iforce->mem_mutex);
return -ENOMEM; return -ENOSPC;
} }
mutex_unlock(&iforce->mem_mutex); mutex_unlock(&iforce->mem_mutex);
} }
...@@ -157,7 +157,7 @@ static int make_condition_modifier(struct iforce* iforce, ...@@ -157,7 +157,7 @@ static int make_condition_modifier(struct iforce* iforce,
iforce->device_memory.start, iforce->device_memory.end, 2L, iforce->device_memory.start, iforce->device_memory.end, 2L,
NULL, NULL)) { NULL, NULL)) {
mutex_unlock(&iforce->mem_mutex); mutex_unlock(&iforce->mem_mutex);
return -ENOMEM; return -ENOSPC;
} }
mutex_unlock(&iforce->mem_mutex); mutex_unlock(&iforce->mem_mutex);
} }
......
...@@ -86,7 +86,7 @@ static struct iforce_device iforce_device[] = { ...@@ -86,7 +86,7 @@ static struct iforce_device iforce_device[] = {
static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{ {
struct iforce* iforce = (struct iforce*)(dev->private); struct iforce* iforce = dev->private;
unsigned char data[3]; unsigned char data[3];
if (type != EV_FF) if (type != EV_FF)
...@@ -138,7 +138,7 @@ static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned ...@@ -138,7 +138,7 @@ static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned
*/ */
static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect) static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
{ {
struct iforce* iforce = (struct iforce*)(dev->private); struct iforce* iforce = dev->private;
int id; int id;
int ret; int ret;
int is_update; int is_update;
...@@ -218,7 +218,7 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect) ...@@ -218,7 +218,7 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
*/ */
static int iforce_erase_effect(struct input_dev *dev, int effect_id) static int iforce_erase_effect(struct input_dev *dev, int effect_id)
{ {
struct iforce* iforce = (struct iforce*)(dev->private); struct iforce* iforce = dev->private;
int err = 0; int err = 0;
struct iforce_core_effect* core_effect; struct iforce_core_effect* core_effect;
......
...@@ -251,7 +251,7 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d ...@@ -251,7 +251,7 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d
gameport_set_poll_handler(gameport, interact_poll); gameport_set_poll_handler(gameport, interact_poll);
gameport_set_poll_interval(gameport, 20); gameport_set_poll_interval(gameport, 20);
sprintf(interact->phys, "%s/input0", gameport->phys); snprintf(interact->phys, sizeof(interact->phys), "%s/input0", gameport->phys);
interact->type = i; interact->type = i;
interact->length = interact_type[i].length; interact->length = interact_type[i].length;
......
...@@ -162,7 +162,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) ...@@ -162,7 +162,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv)
goto fail; goto fail;
magellan->dev = input_dev; magellan->dev = input_dev;
sprintf(magellan->phys, "%s/input0", serio->phys); snprintf(magellan->phys, sizeof(magellan->phys), "%s/input0", serio->phys);
input_dev->name = "LogiCad3D Magellan / SpaceMouse"; input_dev->name = "LogiCad3D Magellan / SpaceMouse";
input_dev->phys = magellan->phys; input_dev->phys = magellan->phys;
......
...@@ -541,7 +541,7 @@ static void sw_print_packet(char *name, int length, unsigned char *buf, char bit ...@@ -541,7 +541,7 @@ static void sw_print_packet(char *name, int length, unsigned char *buf, char bit
* Unfortunately I don't know how to do this for the other SW types. * Unfortunately I don't know how to do this for the other SW types.
*/ */
static void sw_3dp_id(unsigned char *buf, char *comment) static void sw_3dp_id(unsigned char *buf, char *comment, size_t size)
{ {
int i; int i;
char pnp[8], rev[9]; char pnp[8], rev[9];
...@@ -554,7 +554,7 @@ static void sw_3dp_id(unsigned char *buf, char *comment) ...@@ -554,7 +554,7 @@ static void sw_3dp_id(unsigned char *buf, char *comment)
pnp[7] = rev[8] = 0; pnp[7] = rev[8] = 0;
sprintf(comment, " [PnP %d.%02d id %s rev %s]", snprintf(comment, size, " [PnP %d.%02d id %s rev %s]",
(int) ((sw_get_bits(buf, 8, 6, 1) << 6) | /* Two 6-bit values */ (int) ((sw_get_bits(buf, 8, 6, 1) << 6) | /* Two 6-bit values */
sw_get_bits(buf, 16, 6, 1)) / 100, sw_get_bits(buf, 16, 6, 1)) / 100,
(int) ((sw_get_bits(buf, 8, 6, 1) << 6) | (int) ((sw_get_bits(buf, 8, 6, 1) << 6) |
...@@ -703,7 +703,8 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) ...@@ -703,7 +703,8 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
sw->length = 22; sw->length = 22;
case 64: case 64:
sw->type = SW_ID_3DP; sw->type = SW_ID_3DP;
if (j == 160) sw_3dp_id(idbuf, comment); if (j == 160)
sw_3dp_id(idbuf, comment, sizeof(comment));
break; break;
} }
} }
...@@ -733,8 +734,10 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) ...@@ -733,8 +734,10 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
for (i = 0; i < sw->number; i++) { for (i = 0; i < sw->number; i++) {
int bits, code; int bits, code;
sprintf(sw->name, "Microsoft SideWinder %s", sw_name[sw->type]); snprintf(sw->name, sizeof(sw->name),
sprintf(sw->phys[i], "%s/input%d", gameport->phys, i); "Microsoft SideWinder %s", sw_name[sw->type]);
snprintf(sw->phys[i], sizeof(sw->phys[i]),
"%s/input%d", gameport->phys, i);
sw->dev[i] = input_dev = input_allocate_device(); sw->dev[i] = input_dev = input_allocate_device();
if (!input_dev) { if (!input_dev) {
......
...@@ -220,7 +220,7 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) ...@@ -220,7 +220,7 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv)
goto fail; goto fail;
spaceball->dev = input_dev; spaceball->dev = input_dev;
sprintf(spaceball->phys, "%s/input0", serio->phys); snprintf(spaceball->phys, sizeof(spaceball->phys), "%s/input0", serio->phys);
input_dev->name = spaceball_names[id]; input_dev->name = spaceball_names[id];
input_dev->phys = spaceball->phys; input_dev->phys = spaceball->phys;
......
...@@ -177,7 +177,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) ...@@ -177,7 +177,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv)
goto fail; goto fail;
spaceorb->dev = input_dev; spaceorb->dev = input_dev;
sprintf(spaceorb->phys, "%s/input0", serio->phys); snprintf(spaceorb->phys, sizeof(spaceorb->phys), "%s/input0", serio->phys);
input_dev->name = "SpaceTec SpaceOrb 360 / Avenger"; input_dev->name = "SpaceTec SpaceOrb 360 / Avenger";
input_dev->phys = spaceorb->phys; input_dev->phys = spaceorb->phys;
......
...@@ -148,7 +148,7 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) ...@@ -148,7 +148,7 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv)
goto fail; goto fail;
stinger->dev = input_dev; stinger->dev = input_dev;
sprintf(stinger->phys, "%s/serio0", serio->phys); snprintf(stinger->phys, sizeof(stinger->phys), "%s/serio0", serio->phys);
input_dev->name = "Gravis Stinger"; input_dev->name = "Gravis Stinger";
input_dev->phys = stinger->phys; input_dev->phys = stinger->phys;
......
...@@ -199,7 +199,7 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) ...@@ -199,7 +199,7 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv)
goto fail; goto fail;
twidjoy->dev = input_dev; twidjoy->dev = input_dev;
sprintf(twidjoy->phys, "%s/input0", serio->phys); snprintf(twidjoy->phys, sizeof(twidjoy->phys), "%s/input0", serio->phys);
input_dev->name = "Handykey Twiddler"; input_dev->name = "Handykey Twiddler";
input_dev->phys = twidjoy->phys; input_dev->phys = twidjoy->phys;
......
...@@ -154,7 +154,7 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) ...@@ -154,7 +154,7 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv)
goto fail; goto fail;
warrior->dev = input_dev; warrior->dev = input_dev;
sprintf(warrior->phys, "%s/input0", serio->phys); snprintf(warrior->phys, sizeof(warrior->phys), "%s/input0", serio->phys);
input_dev->name = "Logitech WingMan Warrior"; input_dev->name = "Logitech WingMan Warrior";
input_dev->phys = warrior->phys; input_dev->phys = warrior->phys;
......
...@@ -55,7 +55,7 @@ static int atkbd_softraw = 1; ...@@ -55,7 +55,7 @@ static int atkbd_softraw = 1;
module_param_named(softraw, atkbd_softraw, bool, 0); module_param_named(softraw, atkbd_softraw, bool, 0);
MODULE_PARM_DESC(softraw, "Use software generated rawmode"); MODULE_PARM_DESC(softraw, "Use software generated rawmode");
static int atkbd_scroll = 0; static int atkbd_scroll;
module_param_named(scroll, atkbd_scroll, bool, 0); module_param_named(scroll, atkbd_scroll, bool, 0);
MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards");
...@@ -150,8 +150,8 @@ static unsigned char atkbd_unxlate_table[128] = { ...@@ -150,8 +150,8 @@ static unsigned char atkbd_unxlate_table[128] = {
#define ATKBD_RET_EMUL0 0xe0 #define ATKBD_RET_EMUL0 0xe0
#define ATKBD_RET_EMUL1 0xe1 #define ATKBD_RET_EMUL1 0xe1
#define ATKBD_RET_RELEASE 0xf0 #define ATKBD_RET_RELEASE 0xf0
#define ATKBD_RET_HANGUEL 0xf1 #define ATKBD_RET_HANJA 0xf1
#define ATKBD_RET_HANJA 0xf2 #define ATKBD_RET_HANGEUL 0xf2
#define ATKBD_RET_ERR 0xff #define ATKBD_RET_ERR 0xff
#define ATKBD_KEY_UNKNOWN 0 #define ATKBD_KEY_UNKNOWN 0
...@@ -170,6 +170,13 @@ static unsigned char atkbd_unxlate_table[128] = { ...@@ -170,6 +170,13 @@ static unsigned char atkbd_unxlate_table[128] = {
#define ATKBD_LED_EVENT_BIT 0 #define ATKBD_LED_EVENT_BIT 0
#define ATKBD_REP_EVENT_BIT 1 #define ATKBD_REP_EVENT_BIT 1
#define ATKBD_XL_ERR 0x01
#define ATKBD_XL_BAT 0x02
#define ATKBD_XL_ACK 0x04
#define ATKBD_XL_NAK 0x08
#define ATKBD_XL_HANGEUL 0x10
#define ATKBD_XL_HANJA 0x20
static struct { static struct {
unsigned char keycode; unsigned char keycode;
unsigned char set2; unsigned char set2;
...@@ -211,8 +218,7 @@ struct atkbd { ...@@ -211,8 +218,7 @@ struct atkbd {
unsigned char emul; unsigned char emul;
unsigned char resend; unsigned char resend;
unsigned char release; unsigned char release;
unsigned char bat_xl; unsigned long xl_bit;
unsigned char err_xl;
unsigned int last; unsigned int last;
unsigned long time; unsigned long time;
...@@ -245,17 +251,65 @@ ATKBD_DEFINE_ATTR(set); ...@@ -245,17 +251,65 @@ ATKBD_DEFINE_ATTR(set);
ATKBD_DEFINE_ATTR(softrepeat); ATKBD_DEFINE_ATTR(softrepeat);
ATKBD_DEFINE_ATTR(softraw); ATKBD_DEFINE_ATTR(softraw);
static const unsigned int xl_table[] = {
ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK,
ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL,
};
static void atkbd_report_key(struct input_dev *dev, struct pt_regs *regs, int code, int value) /*
* Checks if we should mangle the scancode to extract 'release' bit
* in translated mode.
*/
static int atkbd_need_xlate(unsigned long xl_bit, unsigned char code)
{ {
input_regs(dev, regs); int i;
if (value == 3) {
input_report_key(dev, code, 1); if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1)
input_sync(dev); return 0;
input_report_key(dev, code, 0);
} else for (i = 0; i < ARRAY_SIZE(xl_table); i++)
input_event(dev, EV_KEY, code, value); if (code == xl_table[i])
input_sync(dev); return test_bit(i, &xl_bit);
return 1;
}
/*
* Calculates new value of xl_bit so the driver can distinguish
* between make/break pair of scancodes for select keys and PS/2
* protocol responses.
*/
static void atkbd_calculate_xl_bit(struct atkbd *atkbd, unsigned char code)
{
int i;
for (i = 0; i < ARRAY_SIZE(xl_table); i++) {
if (!((code ^ xl_table[i]) & 0x7f)) {
if (code & 0x80)
__clear_bit(i, &atkbd->xl_bit);
else
__set_bit(i, &atkbd->xl_bit);
break;
}
}
}
/*
* Encode the scancode, 0xe0 prefix, and high bit into a single integer,
* keeping kernel 2.4 compatibility for set 2
*/
static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code)
{
if (atkbd->set == 3) {
if (atkbd->emul == 1)
code |= 0x100;
} else {
code = (code & 0x7f) | ((code & 0x80) << 1);
if (atkbd->emul == 1)
code |= 0x80;
}
return code;
} }
/* /*
...@@ -267,9 +321,11 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -267,9 +321,11 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
unsigned int flags, struct pt_regs *regs) unsigned int flags, struct pt_regs *regs)
{ {
struct atkbd *atkbd = serio_get_drvdata(serio); struct atkbd *atkbd = serio_get_drvdata(serio);
struct input_dev *dev = atkbd->dev;
unsigned int code = data; unsigned int code = data;
int scroll = 0, hscroll = 0, click = -1; int scroll = 0, hscroll = 0, click = -1, add_release_event = 0;
int value; int value;
unsigned char keycode;
#ifdef ATKBD_DEBUG #ifdef ATKBD_DEBUG
printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags); printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
...@@ -298,25 +354,17 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -298,25 +354,17 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
if (!atkbd->enabled) if (!atkbd->enabled)
goto out; goto out;
input_event(atkbd->dev, EV_MSC, MSC_RAW, code); input_event(dev, EV_MSC, MSC_RAW, code);
if (atkbd->translated) { if (atkbd->translated) {
if (atkbd->emul || if (atkbd->emul || atkbd_need_xlate(atkbd->xl_bit, code)) {
(code != ATKBD_RET_EMUL0 && code != ATKBD_RET_EMUL1 &&
code != ATKBD_RET_HANGUEL && code != ATKBD_RET_HANJA &&
(code != ATKBD_RET_ERR || atkbd->err_xl) &&
(code != ATKBD_RET_BAT || atkbd->bat_xl))) {
atkbd->release = code >> 7; atkbd->release = code >> 7;
code &= 0x7f; code &= 0x7f;
} }
if (!atkbd->emul) { if (!atkbd->emul)
if ((code & 0x7f) == (ATKBD_RET_BAT & 0x7f)) atkbd_calculate_xl_bit(atkbd, data);
atkbd->bat_xl = !(data >> 7);
if ((code & 0x7f) == (ATKBD_RET_ERR & 0x7f))
atkbd->err_xl = !(data >> 7);
}
} }
switch (code) { switch (code) {
...@@ -333,47 +381,48 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -333,47 +381,48 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
case ATKBD_RET_RELEASE: case ATKBD_RET_RELEASE:
atkbd->release = 1; atkbd->release = 1;
goto out; goto out;
case ATKBD_RET_HANGUEL: case ATKBD_RET_ACK:
atkbd_report_key(atkbd->dev, regs, KEY_HANGUEL, 3); case ATKBD_RET_NAK:
printk(KERN_WARNING "atkbd.c: Spurious %s on %s. "
"Some program might be trying access hardware directly.\n",
data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
goto out; goto out;
case ATKBD_RET_HANGEUL:
case ATKBD_RET_HANJA: case ATKBD_RET_HANJA:
atkbd_report_key(atkbd->dev, regs, KEY_HANJA, 3); /*
goto out; * These keys do not report release and thus need to be
* flagged properly
*/
add_release_event = 1;
break;
case ATKBD_RET_ERR: case ATKBD_RET_ERR:
printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
goto out; goto out;
} }
if (atkbd->set != 3) code = atkbd_compat_scancode(atkbd, code);
code = (code & 0x7f) | ((code & 0x80) << 1);
if (atkbd->emul) { if (atkbd->emul && --atkbd->emul)
if (--atkbd->emul)
goto out; goto out;
code |= (atkbd->set != 3) ? 0x80 : 0x100;
}
if (atkbd->keycode[code] != ATKBD_KEY_NULL) keycode = atkbd->keycode[code];
input_event(atkbd->dev, EV_MSC, MSC_SCAN, code);
if (keycode != ATKBD_KEY_NULL)
input_event(dev, EV_MSC, MSC_SCAN, code);
switch (atkbd->keycode[code]) { switch (keycode) {
case ATKBD_KEY_NULL: case ATKBD_KEY_NULL:
break; break;
case ATKBD_KEY_UNKNOWN: case ATKBD_KEY_UNKNOWN:
if (data == ATKBD_RET_ACK || data == ATKBD_RET_NAK) { printk(KERN_WARNING
printk(KERN_WARNING "atkbd.c: Spurious %s on %s. Some program, " "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n",
"like XFree86, might be trying access hardware directly.\n",
data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
} else {
printk(KERN_WARNING "atkbd.c: Unknown key %s "
"(%s set %d, code %#x on %s).\n",
atkbd->release ? "released" : "pressed", atkbd->release ? "released" : "pressed",
atkbd->translated ? "translated" : "raw", atkbd->translated ? "translated" : "raw",
atkbd->set, code, serio->phys); atkbd->set, code, serio->phys);
printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x <keycode>' " printk(KERN_WARNING
"to make it known.\n", "atkbd.c: Use 'setkeycodes %s%02x <keycode>' to make it known.\n",
code & 0x80 ? "e0" : "", code & 0x7f); code & 0x80 ? "e0" : "", code & 0x7f);
} input_sync(dev);
input_sync(atkbd->dev);
break; break;
case ATKBD_SCR_1: case ATKBD_SCR_1:
scroll = 1 - atkbd->release * 2; scroll = 1 - atkbd->release * 2;
...@@ -397,33 +446,35 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -397,33 +446,35 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
hscroll = 1; hscroll = 1;
break; break;
default: default:
value = atkbd->release ? 0 : if (atkbd->release) {
(1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev->key))); value = 0;
switch (value) { /* Workaround Toshiba laptop multiple keypress */
case 0:
atkbd->last = 0; atkbd->last = 0;
break; } else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) {
case 1: /* Workaround Toshiba laptop multiple keypress */
atkbd->last = code; value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2;
atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev->rep[REP_DELAY]) / 2; } else {
break;
case 2:
if (!time_after(jiffies, atkbd->time) && atkbd->last == code)
value = 1; value = 1;
break; atkbd->last = code;
atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2;
} }
atkbd_report_key(atkbd->dev, regs, atkbd->keycode[code], value); input_regs(dev, regs);
input_report_key(dev, keycode, value);
input_sync(dev);
if (value && add_release_event) {
input_report_key(dev, keycode, 0);
input_sync(dev);
}
} }
if (atkbd->scroll) { if (atkbd->scroll) {
input_regs(atkbd->dev, regs); input_regs(dev, regs);
if (click != -1) if (click != -1)
input_report_key(atkbd->dev, BTN_MIDDLE, click); input_report_key(dev, BTN_MIDDLE, click);
input_report_rel(atkbd->dev, REL_WHEEL, scroll); input_report_rel(dev, REL_WHEEL, scroll);
input_report_rel(atkbd->dev, REL_HWHEEL, hscroll); input_report_rel(dev, REL_HWHEEL, hscroll);
input_sync(atkbd->dev); input_sync(dev);
} }
atkbd->release = 0; atkbd->release = 0;
...@@ -764,6 +815,9 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd) ...@@ -764,6 +815,9 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd)
for (i = 0; i < ARRAY_SIZE(atkbd_scroll_keys); i++) for (i = 0; i < ARRAY_SIZE(atkbd_scroll_keys); i++)
atkbd->keycode[atkbd_scroll_keys[i].set2] = atkbd_scroll_keys[i].keycode; atkbd->keycode[atkbd_scroll_keys[i].set2] = atkbd_scroll_keys[i].keycode;
} }
atkbd->keycode[atkbd_compat_scancode(atkbd, ATKBD_RET_HANGEUL)] = KEY_HANGUEL;
atkbd->keycode[atkbd_compat_scancode(atkbd, ATKBD_RET_HANJA)] = KEY_HANJA;
} }
/* /*
...@@ -776,12 +830,15 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) ...@@ -776,12 +830,15 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
int i; int i;
if (atkbd->extra) if (atkbd->extra)
sprintf(atkbd->name, "AT Set 2 Extra keyboard"); snprintf(atkbd->name, sizeof(atkbd->name),
"AT Set 2 Extra keyboard");
else else
sprintf(atkbd->name, "AT %s Set %d keyboard", snprintf(atkbd->name, sizeof(atkbd->name),
"AT %s Set %d keyboard",
atkbd->translated ? "Translated" : "Raw", atkbd->set); atkbd->translated ? "Translated" : "Raw", atkbd->set);
sprintf(atkbd->phys, "%s/input0", atkbd->ps2dev.serio->phys); snprintf(atkbd->phys, sizeof(atkbd->phys),
"%s/input0", atkbd->ps2dev.serio->phys);
input_dev->name = atkbd->name; input_dev->name = atkbd->name;
input_dev->phys = atkbd->phys; input_dev->phys = atkbd->phys;
......
...@@ -384,18 +384,21 @@ lkkbd_detection_done (struct lkkbd *lk) ...@@ -384,18 +384,21 @@ lkkbd_detection_done (struct lkkbd *lk)
*/ */
switch (lk->id[4]) { switch (lk->id[4]) {
case 1: case 1:
sprintf (lk->name, "DEC LK201 keyboard"); strlcpy (lk->name, "DEC LK201 keyboard",
sizeof (lk->name));
if (lk201_compose_is_alt) if (lk201_compose_is_alt)
lk->keycode[0xb1] = KEY_LEFTALT; lk->keycode[0xb1] = KEY_LEFTALT;
break; break;
case 2: case 2:
sprintf (lk->name, "DEC LK401 keyboard"); strlcpy (lk->name, "DEC LK401 keyboard",
sizeof (lk->name));
break; break;
default: default:
sprintf (lk->name, "Unknown DEC keyboard"); strlcpy (lk->name, "Unknown DEC keyboard",
sizeof (lk->name));
printk (KERN_ERR "lkkbd: keyboard on %s is unknown, " printk (KERN_ERR "lkkbd: keyboard on %s is unknown, "
"please report to Jan-Benedict Glaw " "please report to Jan-Benedict Glaw "
"<jbglaw@lug-owl.de>\n", lk->phys); "<jbglaw@lug-owl.de>\n", lk->phys);
......
...@@ -96,7 +96,7 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv) ...@@ -96,7 +96,7 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv)
nkbd->serio = serio; nkbd->serio = serio;
nkbd->dev = input_dev; nkbd->dev = input_dev;
sprintf(nkbd->phys, "%s/input0", serio->phys); snprintf(nkbd->phys, sizeof(nkbd->phys), "%s/input0", serio->phys);
memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode)); memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode));
input_dev->name = "Newton Keyboard"; input_dev->name = "Newton Keyboard";
......
...@@ -263,7 +263,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) ...@@ -263,7 +263,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
goto fail; goto fail;
} }
sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type); snprintf(sunkbd->name, sizeof(sunkbd->name), "Sun Type %d keyboard", sunkbd->type);
memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode)); memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode));
input_dev->name = sunkbd->name; input_dev->name = sunkbd->name;
......
...@@ -100,7 +100,7 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv) ...@@ -100,7 +100,7 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv)
xtkbd->serio = serio; xtkbd->serio = serio;
xtkbd->dev = input_dev; xtkbd->dev = input_dev;
sprintf(xtkbd->phys, "%s/input0", serio->phys); snprintf(xtkbd->phys, sizeof(xtkbd->phys), "%s/input0", serio->phys);
memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode)); memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode));
input_dev->name = "XT Keyboard"; input_dev->name = "XT Keyboard";
......
...@@ -470,7 +470,7 @@ int alps_init(struct psmouse *psmouse) ...@@ -470,7 +470,7 @@ int alps_init(struct psmouse *psmouse)
dev1->keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK); dev1->keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
} }
sprintf(priv->phys, "%s/input1", psmouse->ps2dev.serio->phys); snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys);
dev2->phys = priv->phys; dev2->phys = priv->phys;
dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse"; dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
dev2->id.bustype = BUS_I8042; dev2->id.bustype = BUS_I8042;
......
...@@ -150,9 +150,20 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_reg ...@@ -150,9 +150,20 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_reg
*/ */
if (psmouse->type == PSMOUSE_IMEX) { if (psmouse->type == PSMOUSE_IMEX) {
switch (packet[3] & 0xC0) {
case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */
input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31));
break;
case 0x40: /* horizontal scroll on IntelliMouse Explorer 4.0 */
input_report_rel(dev, REL_HWHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31));
break;
case 0x00:
case 0xC0:
input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7)); input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7));
input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1); input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1);
input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1);
break;
}
} }
/* /*
...@@ -466,9 +477,25 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties) ...@@ -466,9 +477,25 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties)
if (param[0] != 4) if (param[0] != 4)
return -1; return -1;
/* Magic to enable horizontal scrolling on IntelliMouse 4.0 */
param[0] = 200;
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
param[0] = 80;
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
param[0] = 40;
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
param[0] = 200;
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
param[0] = 200;
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
param[0] = 60;
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
if (set_properties) { if (set_properties) {
set_bit(BTN_MIDDLE, psmouse->dev->keybit); set_bit(BTN_MIDDLE, psmouse->dev->keybit);
set_bit(REL_WHEEL, psmouse->dev->relbit); set_bit(REL_WHEEL, psmouse->dev->relbit);
set_bit(REL_HWHEEL, psmouse->dev->relbit);
set_bit(BTN_SIDE, psmouse->dev->keybit); set_bit(BTN_SIDE, psmouse->dev->keybit);
set_bit(BTN_EXTRA, psmouse->dev->keybit); set_bit(BTN_EXTRA, psmouse->dev->keybit);
...@@ -1057,7 +1084,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto ...@@ -1057,7 +1084,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto
if (psmouse->resync_time && psmouse->poll(psmouse)) if (psmouse->resync_time && psmouse->poll(psmouse))
psmouse->resync_time = 0; psmouse->resync_time = 0;
sprintf(psmouse->devname, "%s %s %s", snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s",
psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);
input_dev->name = psmouse->devname; input_dev->name = psmouse->devname;
...@@ -1099,7 +1126,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) ...@@ -1099,7 +1126,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
ps2_init(&psmouse->ps2dev, serio); ps2_init(&psmouse->ps2dev, serio);
INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse); INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse);
psmouse->dev = input_dev; psmouse->dev = input_dev;
sprintf(psmouse->phys, "%s/input0", serio->phys); snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys);
psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
......
...@@ -254,7 +254,7 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) ...@@ -254,7 +254,7 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv)
goto fail; goto fail;
sermouse->dev = input_dev; sermouse->dev = input_dev;
sprintf(sermouse->phys, "%s/input0", serio->phys); snprintf(sermouse->phys, sizeof(sermouse->phys), "%s/input0", serio->phys);
sermouse->type = serio->id.proto; sermouse->type = serio->id.proto;
input_dev->name = sermouse_protocols[sermouse->type]; input_dev->name = sermouse_protocols[sermouse->type];
......
...@@ -153,22 +153,25 @@ vsxxxaa_detection_done (struct vsxxxaa *mouse) ...@@ -153,22 +153,25 @@ vsxxxaa_detection_done (struct vsxxxaa *mouse)
{ {
switch (mouse->type) { switch (mouse->type) {
case 0x02: case 0x02:
sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse"); strlcpy (mouse->name, "DEC VSXXX-AA/-GA mouse",
sizeof (mouse->name));
break; break;
case 0x04: case 0x04:
sprintf (mouse->name, "DEC VSXXX-AB digitizer"); strlcpy (mouse->name, "DEC VSXXX-AB digitizer",
sizeof (mouse->name));
break; break;
default: default:
sprintf (mouse->name, "unknown DEC pointer device " snprintf (mouse->name, sizeof (mouse->name),
"(type = 0x%02x)", mouse->type); "unknown DEC pointer device (type = 0x%02x)",
mouse->type);
break; break;
} }
printk (KERN_INFO "Found %s version 0x%02x from country 0x%02x " printk (KERN_INFO
"on port %s\n", mouse->name, mouse->version, "Found %s version 0x%02x from country 0x%02x on port %s\n",
mouse->country, mouse->phys); mouse->name, mouse->version, mouse->country, mouse->phys);
} }
/* /*
...@@ -503,8 +506,9 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) ...@@ -503,8 +506,9 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
mouse->dev = input_dev; mouse->dev = input_dev;
mouse->serio = serio; mouse->serio = serio;
sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer"); strlcat (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer",
sprintf (mouse->phys, "%s/input0", serio->phys); sizeof (mouse->name));
snprintf (mouse->phys, sizeof (mouse->phys), "%s/input0", serio->phys);
input_dev->name = mouse->name; input_dev->name = mouse->name;
input_dev->phys = mouse->phys; input_dev->phys = mouse->phys;
......
...@@ -123,7 +123,9 @@ static void mousedev_touchpad_event(struct input_dev *dev, struct mousedev *mous ...@@ -123,7 +123,9 @@ static void mousedev_touchpad_event(struct input_dev *dev, struct mousedev *mous
if (mousedev->touch) { if (mousedev->touch) {
size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
if (size == 0) size = 256 * 2; if (size == 0)
size = 256 * 2;
switch (code) { switch (code) {
case ABS_X: case ABS_X:
fx(0) = value; fx(0) = value;
...@@ -155,18 +157,24 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, ...@@ -155,18 +157,24 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
switch (code) { switch (code) {
case ABS_X: case ABS_X:
size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
if (size == 0) size = xres ? : 1; if (size == 0)
if (value > dev->absmax[ABS_X]) value = dev->absmax[ABS_X]; size = xres ? : 1;
if (value < dev->absmin[ABS_X]) value = dev->absmin[ABS_X]; if (value > dev->absmax[ABS_X])
value = dev->absmax[ABS_X];
if (value < dev->absmin[ABS_X])
value = dev->absmin[ABS_X];
mousedev->packet.x = ((value - dev->absmin[ABS_X]) * xres) / size; mousedev->packet.x = ((value - dev->absmin[ABS_X]) * xres) / size;
mousedev->packet.abs_event = 1; mousedev->packet.abs_event = 1;
break; break;
case ABS_Y: case ABS_Y:
size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y]; size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y];
if (size == 0) size = yres ? : 1; if (size == 0)
if (value > dev->absmax[ABS_Y]) value = dev->absmax[ABS_Y]; size = yres ? : 1;
if (value < dev->absmin[ABS_Y]) value = dev->absmin[ABS_Y]; if (value > dev->absmax[ABS_Y])
value = dev->absmax[ABS_Y];
if (value < dev->absmin[ABS_Y])
value = dev->absmin[ABS_Y];
mousedev->packet.y = yres - ((value - dev->absmin[ABS_Y]) * yres) / size; mousedev->packet.y = yres - ((value - dev->absmin[ABS_Y]) * yres) / size;
mousedev->packet.abs_event = 1; mousedev->packet.abs_event = 1;
break; break;
...@@ -285,9 +293,8 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value) ...@@ -285,9 +293,8 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
mousedev->touch = mousedev->pkt_count = 0; mousedev->touch = mousedev->pkt_count = 0;
mousedev->frac_dx = 0; mousedev->frac_dx = 0;
mousedev->frac_dy = 0; mousedev->frac_dy = 0;
}
else } else if (!mousedev->touch)
if (!mousedev->touch)
mousedev->touch = jiffies; mousedev->touch = jiffies;
} }
...@@ -346,7 +353,9 @@ static int mousedev_fasync(int fd, struct file *file, int on) ...@@ -346,7 +353,9 @@ static int mousedev_fasync(int fd, struct file *file, int on)
{ {
int retval; int retval;
struct mousedev_list *list = file->private_data; struct mousedev_list *list = file->private_data;
retval = fasync_helper(fd, file, on, &list->fasync); retval = fasync_helper(fd, file, on, &list->fasync);
return retval < 0 ? retval : 0; return retval < 0 ? retval : 0;
} }
...@@ -507,14 +516,16 @@ static ssize_t mousedev_write(struct file * file, const char __user * buffer, si ...@@ -507,14 +516,16 @@ static ssize_t mousedev_write(struct file * file, const char __user * buffer, si
list->imexseq = 0; list->imexseq = 0;
list->mode = MOUSEDEV_EMUL_EXPS; list->mode = MOUSEDEV_EMUL_EXPS;
} }
} else list->imexseq = 0; } else
list->imexseq = 0;
if (c == mousedev_imps_seq[list->impsseq]) { if (c == mousedev_imps_seq[list->impsseq]) {
if (++list->impsseq == MOUSEDEV_SEQ_LEN) { if (++list->impsseq == MOUSEDEV_SEQ_LEN) {
list->impsseq = 0; list->impsseq = 0;
list->mode = MOUSEDEV_EMUL_IMPS; list->mode = MOUSEDEV_EMUL_IMPS;
} }
} else list->impsseq = 0; } else
list->impsseq = 0;
list->ps2[0] = 0xfa; list->ps2[0] = 0xfa;
...@@ -598,6 +609,7 @@ static ssize_t mousedev_read(struct file * file, char __user * buffer, size_t co ...@@ -598,6 +609,7 @@ static ssize_t mousedev_read(struct file * file, char __user * buffer, size_t co
static unsigned int mousedev_poll(struct file *file, poll_table *wait) static unsigned int mousedev_poll(struct file *file, poll_table *wait)
{ {
struct mousedev_list *list = file->private_data; struct mousedev_list *list = file->private_data;
poll_wait(file, &list->mousedev->wait, wait); poll_wait(file, &list->mousedev->wait, wait);
return ((list->ready || list->buffer) ? (POLLIN | POLLRDNORM) : 0) | return ((list->ready || list->buffer) ? (POLLIN | POLLRDNORM) : 0) |
(list->mousedev->exist ? 0 : (POLLHUP | POLLERR)); (list->mousedev->exist ? 0 : (POLLHUP | POLLERR));
......
...@@ -129,7 +129,7 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) ...@@ -129,7 +129,7 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv)
gunze->serio = serio; gunze->serio = serio;
gunze->dev = input_dev; gunze->dev = input_dev;
sprintf(gunze->phys, "%s/input0", serio->phys); snprintf(gunze->phys, sizeof(serio->phys), "%s/input0", serio->phys);
input_dev->private = gunze; input_dev->private = gunze;
input_dev->name = "Gunze AHL-51S TouchScreen"; input_dev->name = "Gunze AHL-51S TouchScreen";
......
...@@ -363,7 +363,7 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) ...@@ -363,7 +363,7 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv)
ts->serio = serio; ts->serio = serio;
ts->dev = input_dev; ts->dev = input_dev;
sprintf(ts->phys, "%s/input0", serio->phys); snprintf(ts->phys, sizeof(ts->phys), "%s/input0", serio->phys);
input_dev->name = "H3600 TouchScreen"; input_dev->name = "H3600 TouchScreen";
input_dev->phys = ts->phys; input_dev->phys = ts->phys;
......
...@@ -143,7 +143,7 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) ...@@ -143,7 +143,7 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv)
mtouch->serio = serio; mtouch->serio = serio;
mtouch->dev = input_dev; mtouch->dev = input_dev;
sprintf(mtouch->phys, "%s/input0", serio->phys); snprintf(mtouch->phys, sizeof(mtouch->phys), "%s/input0", serio->phys);
input_dev->private = mtouch; input_dev->private = mtouch;
input_dev->name = "MicroTouch Serial TouchScreen"; input_dev->name = "MicroTouch Serial TouchScreen";
......
...@@ -230,6 +230,7 @@ static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count, ...@@ -230,6 +230,7 @@ static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count,
static unsigned int tsdev_poll(struct file *file, poll_table * wait) static unsigned int tsdev_poll(struct file *file, poll_table * wait)
{ {
struct tsdev_list *list = file->private_data; struct tsdev_list *list = file->private_data;
poll_wait(file, &list->tsdev->wait, wait); poll_wait(file, &list->tsdev->wait, wait);
return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) |
(list->tsdev->exist ? 0 : (POLLHUP | POLLERR)); (list->tsdev->exist ? 0 : (POLLHUP | POLLERR));
...@@ -248,11 +249,13 @@ static int tsdev_ioctl(struct inode *inode, struct file *file, ...@@ -248,11 +249,13 @@ static int tsdev_ioctl(struct inode *inode, struct file *file,
sizeof (struct ts_calibration))) sizeof (struct ts_calibration)))
retval = -EFAULT; retval = -EFAULT;
break; break;
case TS_SET_CAL: case TS_SET_CAL:
if (copy_from_user (&tsdev->cal, (void __user *)arg, if (copy_from_user (&tsdev->cal, (void __user *)arg,
sizeof (struct ts_calibration))) sizeof (struct ts_calibration)))
retval = -EFAULT; retval = -EFAULT;
break; break;
default: default:
retval = -EINVAL; retval = -EINVAL;
break; break;
...@@ -284,9 +287,11 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, ...@@ -284,9 +287,11 @@ static void tsdev_event(struct input_handle *handle, unsigned int type,
case ABS_X: case ABS_X:
tsdev->x = value; tsdev->x = value;
break; break;
case ABS_Y: case ABS_Y:
tsdev->y = value; tsdev->y = value;
break; break;
case ABS_PRESSURE: case ABS_PRESSURE:
if (value > handle->dev->absmax[ABS_PRESSURE]) if (value > handle->dev->absmax[ABS_PRESSURE])
value = handle->dev->absmax[ABS_PRESSURE]; value = handle->dev->absmax[ABS_PRESSURE];
...@@ -307,6 +312,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, ...@@ -307,6 +312,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type,
else if (tsdev->x > xres) else if (tsdev->x > xres)
tsdev->x = xres; tsdev->x = xres;
break; break;
case REL_Y: case REL_Y:
tsdev->y += value; tsdev->y += value;
if (tsdev->y < 0) if (tsdev->y < 0)
...@@ -323,6 +329,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, ...@@ -323,6 +329,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type,
case 0: case 0:
tsdev->pressure = 0; tsdev->pressure = 0;
break; break;
case 1: case 1:
if (!tsdev->pressure) if (!tsdev->pressure)
tsdev->pressure = 1; tsdev->pressure = 1;
...@@ -370,9 +377,8 @@ static struct input_handle *tsdev_connect(struct input_handler *handler, ...@@ -370,9 +377,8 @@ static struct input_handle *tsdev_connect(struct input_handler *handler,
struct class_device *cdev; struct class_device *cdev;
int minor, delta; int minor, delta;
for (minor = 0; minor < TSDEV_MINORS/2 && tsdev_table[minor]; for (minor = 0; minor < TSDEV_MINORS / 2 && tsdev_table[minor]; minor++);
minor++); if (minor >= TSDEV_MINORS / 2) {
if (minor >= TSDEV_MINORS/2) {
printk(KERN_ERR printk(KERN_ERR
"tsdev: You have way too many touchscreens\n"); "tsdev: You have way too many touchscreens\n");
return NULL; return NULL;
...@@ -444,22 +450,22 @@ static struct input_device_id tsdev_ids[] = { ...@@ -444,22 +450,22 @@ static struct input_device_id tsdev_ids[] = {
.evbit = { BIT(EV_KEY) | BIT(EV_REL) }, .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
.keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) }, .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) },
.relbit = { BIT(REL_X) | BIT(REL_Y) }, .relbit = { BIT(REL_X) | BIT(REL_Y) },
},/* A mouse like device, at least one button, two relative axes */ }, /* 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, .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
.evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, .evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
.keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
.absbit = { BIT(ABS_X) | BIT(ABS_Y) }, .absbit = { BIT(ABS_X) | BIT(ABS_Y) },
},/* A tablet like device, at least touch detection, two absolute axes */ }, /* A tablet like device, at least touch detection, two absolute axes */
{ {
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
.evbit = { BIT(EV_ABS) }, .evbit = { BIT(EV_ABS) },
.absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) }, .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) },
},/* A tablet like device with several gradations of pressure */ }, /* A tablet like device with several gradations of pressure */
{},/* Terminating entry */ {} /* Terminating entry */
}; };
MODULE_DEVICE_TABLE(input, tsdev_ids); MODULE_DEVICE_TABLE(input, tsdev_ids);
......
...@@ -11,7 +11,7 @@ obj-$(CONFIG_MAC_EMUMOUSEBTN) += mac_hid.o ...@@ -11,7 +11,7 @@ obj-$(CONFIG_MAC_EMUMOUSEBTN) += mac_hid.o
obj-$(CONFIG_INPUT_ADBHID) += adbhid.o obj-$(CONFIG_INPUT_ADBHID) += adbhid.o
obj-$(CONFIG_ANSLCD) += ans-lcd.o obj-$(CONFIG_ANSLCD) += ans-lcd.o
obj-$(CONFIG_ADB_PMU) += via-pmu.o obj-$(CONFIG_ADB_PMU) += via-pmu.o via-pmu-event.o
obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-backlight.o obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-backlight.o
obj-$(CONFIG_ADB_CUDA) += via-cuda.o obj-$(CONFIG_ADB_CUDA) += via-cuda.o
obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o
......
...@@ -179,7 +179,7 @@ u8 adb_to_linux_keycodes[128] = { ...@@ -179,7 +179,7 @@ u8 adb_to_linux_keycodes[128] = {
/* 0x65 */ KEY_F9, /* 67 */ /* 0x65 */ KEY_F9, /* 67 */
/* 0x66 */ KEY_HANJA, /* 123 */ /* 0x66 */ KEY_HANJA, /* 123 */
/* 0x67 */ KEY_F11, /* 87 */ /* 0x67 */ KEY_F11, /* 87 */
/* 0x68 */ KEY_HANGUEL, /* 122 */ /* 0x68 */ KEY_HANGEUL, /* 122 */
/* 0x69 */ KEY_SYSRQ, /* 99 */ /* 0x69 */ KEY_SYSRQ, /* 99 */
/* 0x6a */ 0, /* 0x6a */ 0,
/* 0x6b */ KEY_SCROLLLOCK, /* 70 */ /* 0x6b */ KEY_SCROLLLOCK, /* 70 */
......
/*
* via-pmu event device for reporting some events that come through the PMU
*
* Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <linux/input.h>
#include <linux/adb.h>
#include <linux/pmu.h>
#include "via-pmu-event.h"
static struct input_dev *pmu_input_dev;
static int __init via_pmu_event_init(void)
{
int err;
/* do other models report button/lid status? */
if (pmu_get_model() != PMU_KEYLARGO_BASED)
return -ENODEV;
pmu_input_dev = input_allocate_device();
if (!pmu_input_dev)
return -ENOMEM;
pmu_input_dev->name = "PMU";
pmu_input_dev->id.bustype = BUS_HOST;
pmu_input_dev->id.vendor = 0x0001;
pmu_input_dev->id.product = 0x0001;
pmu_input_dev->id.version = 0x0100;
set_bit(EV_KEY, pmu_input_dev->evbit);
set_bit(EV_SW, pmu_input_dev->evbit);
set_bit(KEY_POWER, pmu_input_dev->keybit);
set_bit(SW_LID, pmu_input_dev->swbit);
err = input_register_device(pmu_input_dev);
if (err)
input_free_device(pmu_input_dev);
return err;
}
void via_pmu_event(int key, int down)
{
if (unlikely(!pmu_input_dev))
return;
switch (key) {
case PMU_EVT_POWER:
input_report_key(pmu_input_dev, KEY_POWER, down);
break;
case PMU_EVT_LID:
input_report_switch(pmu_input_dev, SW_LID, down);
break;
default:
/* no such key handled */
return;
}
input_sync(pmu_input_dev);
}
late_initcall(via_pmu_event_init);
#ifndef __VIA_PMU_EVENT_H
#define __VIA_PMU_EVENT_H
#define PMU_EVT_POWER 0
#define PMU_EVT_LID 1
extern void via_pmu_event(int key, int down);
#endif /* __VIA_PMU_EVENT_H */
...@@ -69,6 +69,8 @@ ...@@ -69,6 +69,8 @@
#include <asm/open_pic.h> #include <asm/open_pic.h>
#endif #endif
#include "via-pmu-event.h"
/* Some compile options */ /* Some compile options */
#undef SUSPEND_USES_PMU #undef SUSPEND_USES_PMU
#define DEBUG_SLEEP #define DEBUG_SLEEP
...@@ -1427,6 +1429,12 @@ pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) ...@@ -1427,6 +1429,12 @@ pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs)
if (pmu_battery_count) if (pmu_battery_count)
query_battery_state(); query_battery_state();
pmu_pass_intr(data, len); pmu_pass_intr(data, len);
/* len == 6 is probably a bad check. But how do I
* know what PMU versions send what events here? */
if (len == 6) {
via_pmu_event(PMU_EVT_POWER, !!(data[1]&8));
via_pmu_event(PMU_EVT_LID, data[1]&1);
}
} else { } else {
pmu_pass_intr(data, len); pmu_pass_intr(data, len);
} }
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
#define _FIXP_ARITH_H #define _FIXP_ARITH_H
/* /*
* $$
*
* Simplistic fixed-point arithmetics. * Simplistic fixed-point arithmetics.
* Hmm, I'm probably duplicating some code :( * Hmm, I'm probably duplicating some code :(
* *
...@@ -31,20 +29,20 @@ ...@@ -31,20 +29,20 @@
#include <linux/types.h> #include <linux/types.h>
// The type representing fixed-point values /* The type representing fixed-point values */
typedef s16 fixp_t; typedef s16 fixp_t;
#define FRAC_N 8 #define FRAC_N 8
#define FRAC_MASK ((1<<FRAC_N)-1) #define FRAC_MASK ((1<<FRAC_N)-1)
// Not to be used directly. Use fixp_{cos,sin} /* Not to be used directly. Use fixp_{cos,sin} */
static const fixp_t cos_table[45] = { static const fixp_t cos_table[46] = {
0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8, 0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8,
0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD, 0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD,
0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1, 0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1,
0x00AB, 0x00A4, 0x009D, 0x0096, 0x008F, 0x0087, 0x0080, 0x0078, 0x00AB, 0x00A4, 0x009D, 0x0096, 0x008F, 0x0087, 0x0080, 0x0078,
0x0070, 0x0068, 0x005F, 0x0057, 0x004F, 0x0046, 0x003D, 0x0035, 0x0070, 0x0068, 0x005F, 0x0057, 0x004F, 0x0046, 0x003D, 0x0035,
0x002C, 0x0023, 0x001A, 0x0011, 0x0008 0x002C, 0x0023, 0x001A, 0x0011, 0x0008, 0x0000
}; };
...@@ -68,9 +66,8 @@ static inline fixp_t fixp_cos(unsigned int degrees) ...@@ -68,9 +66,8 @@ static inline fixp_t fixp_cos(unsigned int degrees)
int quadrant = (degrees / 90) & 3; int quadrant = (degrees / 90) & 3;
unsigned int i = degrees % 90; unsigned int i = degrees % 90;
if (quadrant == 1 || quadrant == 3) { if (quadrant == 1 || quadrant == 3)
i = 89 - i; i = 90 - i;
}
i >>= 1; i >>= 1;
......
...@@ -563,7 +563,7 @@ static char *keys[KEY_MAX + 1] = { ...@@ -563,7 +563,7 @@ static char *keys[KEY_MAX + 1] = {
[KEY_VOLUMEUP] = "VolumeUp", [KEY_POWER] = "Power", [KEY_VOLUMEUP] = "VolumeUp", [KEY_POWER] = "Power",
[KEY_KPEQUAL] = "KPEqual", [KEY_KPPLUSMINUS] = "KPPlusMinus", [KEY_KPEQUAL] = "KPEqual", [KEY_KPPLUSMINUS] = "KPPlusMinus",
[KEY_PAUSE] = "Pause", [KEY_KPCOMMA] = "KPComma", [KEY_PAUSE] = "Pause", [KEY_KPCOMMA] = "KPComma",
[KEY_HANGUEL] = "Hanguel", [KEY_HANJA] = "Hanja", [KEY_HANGUEL] = "Hangeul", [KEY_HANJA] = "Hanja",
[KEY_YEN] = "Yen", [KEY_LEFTMETA] = "LeftMeta", [KEY_YEN] = "Yen", [KEY_LEFTMETA] = "LeftMeta",
[KEY_RIGHTMETA] = "RightMeta", [KEY_COMPOSE] = "Compose", [KEY_RIGHTMETA] = "RightMeta", [KEY_COMPOSE] = "Compose",
[KEY_STOP] = "Stop", [KEY_AGAIN] = "Again", [KEY_STOP] = "Stop", [KEY_AGAIN] = "Again",
......
...@@ -232,7 +232,8 @@ struct input_absinfo { ...@@ -232,7 +232,8 @@ struct input_absinfo {
#define KEY_PAUSE 119 #define KEY_PAUSE 119
#define KEY_KPCOMMA 121 #define KEY_KPCOMMA 121
#define KEY_HANGUEL 122 #define KEY_HANGEUL 122
#define KEY_HANGUEL KEY_HANGEUL
#define KEY_HANJA 123 #define KEY_HANJA 123
#define KEY_YEN 124 #define KEY_YEN 124
#define KEY_LEFTMETA 125 #define KEY_LEFTMETA 125
...@@ -1005,6 +1006,7 @@ static inline void init_input_dev(struct input_dev *dev) ...@@ -1005,6 +1006,7 @@ static inline void init_input_dev(struct input_dev *dev)
} }
struct input_dev *input_allocate_device(void); struct input_dev *input_allocate_device(void);
void input_free_device(struct input_dev *dev);
static inline struct input_dev *input_get_device(struct input_dev *dev) static inline struct input_dev *input_get_device(struct input_dev *dev)
{ {
...@@ -1016,12 +1018,6 @@ static inline void input_put_device(struct input_dev *dev) ...@@ -1016,12 +1018,6 @@ static inline void input_put_device(struct input_dev *dev)
class_device_put(&dev->cdev); class_device_put(&dev->cdev);
} }
static inline void input_free_device(struct input_dev *dev)
{
if (dev)
input_put_device(dev);
}
int input_register_device(struct input_dev *); int input_register_device(struct input_dev *);
void input_unregister_device(struct input_dev *); void input_unregister_device(struct input_dev *);
......
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