GIT 7b27f9b80ac750c386989589f96b43bc486a3935 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/dtor/input.git commit Author: Julia Lawall Date: Tue Nov 27 00:45:50 2007 -0500 Input: drop redundant includes of moduleparam.h Drop #include in files that also include linux/module.h, since module.h includes moduleparam.h already. Signed-off-by: Julia Lawall Signed-off-by: Dmitry Torokhov commit 7f5cbe80a1cb8d26160f7bf09b098ddf4757b9ce Author: Steven Whitehouse Date: Tue Nov 27 00:45:34 2007 -0500 Input: fix bug in example code The input example driver uses BTN_0 in the later stages of the example, so this changes the interrupt routine to match. Signed-off-by: Steven Whitehouse Signed-off-by: Dmitry Torokhov commit 314bc9bf0e693eb6e9c0cbe4137b3bad8d43c97f Author: Stephen Hemminger Date: Wed Nov 21 14:03:37 2007 -0500 Input: implement proper timer rounding for polled devices Rounding doesn't matter for the first tick, but we want succeeding ticks to be aligned on second boundary if poll interval is large enough. Also: cancel_rearming_delayed_workqueue is marked as obsolete in workqueue.h so use cancel_delayed_work_sync. Signed-off-by: Stephen Hemminger Acked-by: Arjan van de Ven Signed-off-by: Dmitry Torokhov commit 3af8070afc0f6a30a7a30d37c577136bcdc037b0 Author: Dmitry Torokhov Date: Sun Nov 4 00:50:19 2007 -0400 V4L/DVB: Don't access input_dev->private directly Drivers should use input_{get|set}_drvdata() instead of accessing input_dev->provate directly, but since these drivers do not actually use the data stored there we can simply remove the assignments. Signed-off-by: Dmitry Torokhov Acked-by: Mauro Carvalho Chehab commit 2c073fa3a4c6e06510395c9224f4c96308b478d8 Author: Dmitry Torokhov Date: Sun Nov 4 00:49:54 2007 -0400 Input: iforce - don't access input_dev->private directly input_{get|set}_drvdata() helpers should be used instead. Signed-off-by: Dmitry Torokhov commit fd9085b458ffaa72fae7c8921fda5416c880434b Author: Dmitry Torokhov Date: Sun Nov 4 00:44:31 2007 -0400 Input: i8042 - use synchronize_irq() instead of synchronize_sched() RT guys advised me that in their kernels synchronize_sched() will not work to ensure that all IRQ handlers run to their completion and that synchronize_irq() should be used instead. Signed-off-by: Dmitry Torokhov commit a437c9403cedf66ce79776fa14d2efcb10b87aa5 Author: Dmitry Torokhov Date: Sun Nov 4 00:42:21 2007 -0400 Input: atkbd - remove unneeded synchronize_sched() atkbd_disable() provides all necessary synchronization with atkbd_interrupt(). Signed-off-by: Dmitry Torokhov commit dbcb9e46099211ac0560e3fb61b183960d1022b4 Author: Dmitry Torokhov Date: Sun Nov 4 00:41:36 2007 -0400 Input: cobalt_btns - add support for loadable keymaps Signed-off-by: Dmitry Torokhov commit 09b15195b951442eb89be6b8e45b64bd11ecad4b Author: Dmitry Torokhov Date: Sun Nov 4 00:41:30 2007 -0400 Input: atlas_btns - add support for loadable keymaps Signed-off-by: Dmitry Torokhov commit ae1db0b5d7298a11652359d3c16d1d4e353ffcdf Author: Dmitry Torokhov Date: Sun Nov 4 00:41:24 2007 -0400 Input: keyspan_remote - add support for loadable keymaps Signed-off-by: Dmitry Torokhov commit 0131f0e6e7b0404d46c8632974bd676ec4c00be3 Author: Dmitry Torokhov Date: Sun Nov 4 00:41:12 2007 -0400 Input: Add proper locking when changing device's keymap Take dev->event_lock to make sure that we don't race with input_event() and also force key up event when removing a key from keymap table. Signed-off-by: Dmitry Torokhov commit c82854a492e7493cf5c8d49f4683dcfeca7a262a Author: Giel de Nijs Date: Fri Nov 2 09:08:02 2007 -0400 Input: atkbd - properly handle special keys on Dell Latitudes Most of Fn+F? special keys on (at least) the Dell Latitude laptops don't generate a hardware key release event so the driver has to generate one. Signed-off-by: Giel de Nijs Signed-off-by: Dmitry Torokhov Documentation/input/input-programming.txt | 2 +- drivers/char/keyboard.c | 4 +- drivers/input/evdev.c | 6 +- drivers/input/input-polldev.c | 18 ++-- drivers/input/input.c | 78 +++++++++++++- drivers/input/joystick/amijoy.c | 1 - drivers/input/joystick/analog.c | 1 - drivers/input/joystick/db9.c | 1 - drivers/input/joystick/gamecon.c | 1 - drivers/input/joystick/iforce/iforce-main.c | 17 ++-- drivers/input/joystick/turbografx.c | 1 - drivers/input/joystick/xpad.c | 1 - drivers/input/keyboard/atkbd.c | 91 +++++++++++++---- drivers/input/keyboard/lkkbd.c | 1 - drivers/input/misc/ati_remote.c | 1 - drivers/input/misc/atlas_btns.c | 39 ++++--- drivers/input/misc/cobalt_btns.c | 73 ++++++------- drivers/input/misc/keyspan_remote.c | 119 ++++++++++++--------- drivers/input/mouse/inport.c | 1 - drivers/input/mouse/logibm.c | 1 - drivers/input/mouse/psmouse-base.c | 1 - drivers/input/mouse/trackpoint.c | 1 - drivers/input/mousedev.c | 1 - drivers/input/serio/i8042.c | 10 ++- drivers/input/serio/libps2.c | 1 - drivers/input/touchscreen/mk712.c | 1 - drivers/input/touchscreen/ucb1400_ts.c | 1 - drivers/media/video/usbvideo/konicawc.c | 2 - drivers/media/video/usbvideo/quickcam_messenger.c | 2 - include/linux/input.h | 3 + 30 files changed, 306 insertions(+), 174 deletions(-) diff --git a/Documentation/input/input-programming.txt b/Documentation/input/input-programming.txt index 47fc868..81905e8 100644 --- a/Documentation/input/input-programming.txt +++ b/Documentation/input/input-programming.txt @@ -22,7 +22,7 @@ static struct input_dev *button_dev; static void button_interrupt(int irq, void *dummy, struct pt_regs *fp) { - input_report_key(button_dev, BTN_1, inb(BUTTON_PORT) & 1); + input_report_key(button_dev, BTN_0, inb(BUTTON_PORT) & 1); input_sync(button_dev); } diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index fc54d23..5218d0d 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -194,7 +194,7 @@ int getkeycode(unsigned int scancode) int error = -ENODEV; list_for_each_entry(handle, &kbd_handler.h_list, h_node) { - error = handle->dev->getkeycode(handle->dev, scancode, &keycode); + error = input_get_keycode(handle->dev, scancode, &keycode); if (!error) return keycode; } @@ -208,7 +208,7 @@ int setkeycode(unsigned int scancode, unsigned int keycode) int error = -ENODEV; list_for_each_entry(handle, &kbd_handler.h_list, h_node) { - error = handle->dev->setkeycode(handle->dev, scancode, keycode); + error = input_set_keycode(handle->dev, scancode, keycode); if (!error) break; } diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index e5b4e9b..0727b0a 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -617,7 +617,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, if (get_user(t, ip)) return -EFAULT; - error = dev->getkeycode(dev, t, &v); + error = input_get_keycode(dev, t, &v); if (error) return error; @@ -630,7 +630,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, if (get_user(t, ip) || get_user(v, ip + 1)) return -EFAULT; - return dev->setkeycode(dev, t, v); + return input_set_keycode(dev, t, v); case EVIOCSFF: if (copy_from_user(&effect, p, sizeof(effect))) @@ -683,7 +683,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, case EV_FF: bits = dev->ffbit; len = FF_MAX; break; case EV_SW: bits = dev->swbit; len = SW_MAX; break; default: return -EINVAL; - } + } return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode); } diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c index 92b3598..490918a 100644 --- a/drivers/input/input-polldev.c +++ b/drivers/input/input-polldev.c @@ -60,17 +60,21 @@ static void input_polled_device_work(struct work_struct *work) { struct input_polled_dev *dev = container_of(work, struct input_polled_dev, work.work); + unsigned long delay; dev->poll(dev); - queue_delayed_work(polldev_wq, &dev->work, - msecs_to_jiffies(dev->poll_interval)); + + delay = msecs_to_jiffies(dev->poll_interval); + if (delay >= HZ) + delay = round_jiffies_relative(delay); + + queue_delayed_work(polldev_wq, &dev->work, delay); } static int input_open_polled_device(struct input_dev *input) { struct input_polled_dev *dev = input->private; int error; - unsigned long ticks; error = input_polldev_start_workqueue(); if (error) @@ -79,10 +83,8 @@ static int input_open_polled_device(struct input_dev *input) if (dev->flush) dev->flush(dev); - ticks = msecs_to_jiffies(dev->poll_interval); - if (ticks >= HZ) - ticks = round_jiffies(ticks); - queue_delayed_work(polldev_wq, &dev->work, ticks); + queue_delayed_work(polldev_wq, &dev->work, + msecs_to_jiffies(dev->poll_interval)); return 0; } @@ -91,7 +93,7 @@ static void input_close_polled_device(struct input_dev *input) { struct input_polled_dev *dev = input->private; - cancel_rearming_delayed_workqueue(polldev_wq, &dev->work); + cancel_delayed_work_sync(&dev->work); input_polldev_stop_workqueue(); } diff --git a/drivers/input/input.c b/drivers/input/input.c index 307c7b5..0773236 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -489,7 +489,7 @@ static void input_disconnect_device(struct input_dev *dev) if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) { for (code = 0; code <= KEY_MAX; code++) { if (is_event_supported(code, dev->keybit, KEY_MAX) && - test_bit(code, dev->key)) { + __test_and_clear_bit(code, dev->key)) { input_pass_event(dev, EV_KEY, code, 0); } } @@ -522,7 +522,7 @@ static int input_default_getkeycode(struct input_dev *dev, if (!dev->keycodesize) return -EINVAL; - if (scancode < 0 || scancode >= dev->keycodemax) + if (scancode >= dev->keycodemax) return -EINVAL; *keycode = input_fetch_keycode(dev, scancode); @@ -536,10 +536,7 @@ static int input_default_setkeycode(struct input_dev *dev, int old_keycode; int i; - if (scancode < 0 || scancode >= dev->keycodemax) - return -EINVAL; - - if (keycode < 0 || keycode > KEY_MAX) + if (scancode >= dev->keycodemax) return -EINVAL; if (!dev->keycodesize) @@ -582,6 +579,75 @@ static int input_default_setkeycode(struct input_dev *dev, return 0; } +/** + * input_get_keycode - retrieve keycode currently mapped to a given scancode + * @dev: input device which keymap is being queried + * @scancode: scancode (or its equivalent for device in question) for which + * keycode is needed + * @keycode: result + * + * This function should be called by anyone interested in retrieving current + * keymap. Presently keyboard and evdev handlers use it. + */ +int input_get_keycode(struct input_dev *dev, int scancode, int *keycode) +{ + if (scancode < 0) + return -EINVAL; + + return dev->getkeycode(dev, scancode, keycode); +} +EXPORT_SYMBOL(input_get_keycode); + +/** + * input_get_keycode - assign new keycode to a given scancode + * @dev: input device which keymap is being updated + * @scancode: scancode (or its equivalent for device in question) + * @keycode: new keycode to be assigned to the scancode + * + * This function should be called by anyone needing to update current + * keymap. Presently keyboard and evdev handlers use it. + */ +int input_set_keycode(struct input_dev *dev, int scancode, int keycode) +{ + unsigned long flags; + int old_keycode; + int retval; + + if (scancode < 0) + return -EINVAL; + + if (keycode < 0 || keycode > KEY_MAX) + return -EINVAL; + + spin_lock_irqsave(&dev->event_lock, flags); + + retval = dev->getkeycode(dev, scancode, &old_keycode); + if (retval) + goto out; + + retval = dev->setkeycode(dev, scancode, keycode); + if (retval) + goto out; + + /* + * Simulate keyup event if keycode is not present + * in the keymap anymore + */ + if (test_bit(EV_KEY, dev->evbit) && + !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && + __test_and_clear_bit(old_keycode, dev->key)) { + + input_pass_event(dev, EV_KEY, old_keycode, 0); + if (dev->sync) + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); + } + + out: + spin_unlock_irqrestore(&dev->event_lock, flags); + + return retval; +} +EXPORT_SYMBOL(input_set_keycode); #define MATCH_BIT(bit, max) \ for (i = 0; i < BITS_TO_LONGS(max); i++) \ diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c index 5cf9f36..deb9f82 100644 --- a/drivers/input/joystick/amijoy.c +++ b/drivers/input/joystick/amijoy.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 1573988..f32e031 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index a6ca9d5..960e501 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -33,7 +33,6 @@ #include #include -#include #include #include #include diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index df2a9d0..07a32af 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index 6f826b3..a2517fa 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -85,7 +85,7 @@ static struct iforce_device iforce_device[] = { static int iforce_playback(struct input_dev *dev, int effect_id, int value) { - struct iforce* iforce = dev->private; + struct iforce *iforce = input_get_drvdata(dev); struct iforce_core_effect *core_effect = &iforce->core_effects[effect_id]; if (value > 0) @@ -99,7 +99,7 @@ static int iforce_playback(struct input_dev *dev, int effect_id, int value) static void iforce_set_gain(struct input_dev *dev, u16 gain) { - struct iforce* iforce = dev->private; + struct iforce *iforce = input_get_drvdata(dev); unsigned char data[3]; data[0] = gain >> 9; @@ -108,7 +108,7 @@ static void iforce_set_gain(struct input_dev *dev, u16 gain) static void iforce_set_autocenter(struct input_dev *dev, u16 magnitude) { - struct iforce* iforce = dev->private; + struct iforce *iforce = input_get_drvdata(dev); unsigned char data[3]; data[0] = 0x03; @@ -126,7 +126,7 @@ static void iforce_set_autocenter(struct input_dev *dev, u16 magnitude) */ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old) { - struct iforce* iforce = dev->private; + struct iforce *iforce = input_get_drvdata(dev); struct iforce_core_effect *core_effect = &iforce->core_effects[effect->id]; int ret; @@ -173,7 +173,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) { - struct iforce *iforce = dev->private; + struct iforce *iforce = input_get_drvdata(dev); struct iforce_core_effect *core_effect = &iforce->core_effects[effect_id]; int err = 0; @@ -191,7 +191,7 @@ static int iforce_erase_effect(struct input_dev *dev, int effect_id) static int iforce_open(struct input_dev *dev) { - struct iforce *iforce = dev->private; + struct iforce *iforce = input_get_drvdata(dev); switch (iforce->bus) { #ifdef CONFIG_JOYSTICK_IFORCE_USB @@ -213,7 +213,7 @@ static int iforce_open(struct input_dev *dev) static void iforce_release(struct input_dev *dev) { - struct iforce *iforce = dev->private; + struct iforce *iforce = input_get_drvdata(dev); int i; if (test_bit(EV_FF, dev->evbit)) { @@ -298,7 +298,8 @@ int iforce_init_device(struct iforce *iforce) #endif } - input_dev->private = iforce; + input_set_drvdata(input_dev, iforce); + input_dev->name = "Unknown I-Force device"; input_dev->open = iforce_open; input_dev->close = iforce_release; diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index bbebd4e..989483f 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 6e9d75b..0380597 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -75,7 +75,6 @@ #include #include #include -#include #include #define DRIVER_VERSION "v0.0.6" diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index b39c5b3..4a95adc 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -28,6 +27,7 @@ #include #include #include +#include #define DRIVER_DESC "AT and PS/2 keyboard driver" @@ -201,6 +201,7 @@ struct atkbd { unsigned short id; unsigned char keycode[512]; + DECLARE_BITMAP(force_release_mask, 512); unsigned char set; unsigned char translated; unsigned char extra; @@ -225,6 +226,11 @@ struct atkbd { unsigned long event_mask; }; +/* + * System-specific ketymap fixup routine + */ +static void (*atkbd_platform_fixup)(struct atkbd *); + static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, ssize_t (*handler)(struct atkbd *, char *)); static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, @@ -349,7 +355,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, struct atkbd *atkbd = serio_get_drvdata(serio); struct input_dev *dev = atkbd->dev; unsigned int code = data; - int scroll = 0, hscroll = 0, click = -1, add_release_event = 0; + int scroll = 0, hscroll = 0, click = -1; int value; unsigned char keycode; @@ -414,14 +420,6 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, "Some program might be trying access hardware directly.\n", data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); goto out; - case ATKBD_RET_HANGEUL: - case ATKBD_RET_HANJA: - /* - * These keys do not report release and thus need to be - * flagged properly - */ - add_release_event = 1; - break; case ATKBD_RET_ERR: atkbd->err_count++; #ifdef ATKBD_DEBUG @@ -491,7 +489,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, input_event(dev, EV_KEY, keycode, value); input_sync(dev); - if (value && add_release_event) { + if (value && test_bit(code, atkbd->force_release_mask)) { input_report_key(dev, keycode, 0); input_sync(dev); } @@ -824,7 +822,6 @@ static void atkbd_disconnect(struct serio *serio) atkbd_disable(atkbd); /* make sure we don't have a command in flight */ - synchronize_sched(); /* Allow atkbd_interrupt()s to complete. */ flush_scheduled_work(); sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); @@ -834,6 +831,22 @@ static void atkbd_disconnect(struct serio *serio) kfree(atkbd); } +/* + * Most special keys (Fn+F?) on Dell Latitudes do not generate release + * events so we have to do it ourselves. + */ +static void atkbd_latitude_keymap_fixup(struct atkbd *atkbd) +{ + const unsigned int forced_release_keys[] = { + 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, + }; + int i; + + if (atkbd->set == 2) + for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) + __set_bit(forced_release_keys[i], + atkbd->force_release_mask); +} /* * atkbd_set_keycode_table() initializes keyboard's keycode table @@ -842,17 +855,20 @@ static void atkbd_disconnect(struct serio *serio) static void atkbd_set_keycode_table(struct atkbd *atkbd) { + unsigned int scancode; int i, j; memset(atkbd->keycode, 0, sizeof(atkbd->keycode)); + bitmap_zero(atkbd->force_release_mask, 512); if (atkbd->translated) { for (i = 0; i < 128; i++) { - atkbd->keycode[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]]; - atkbd->keycode[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80]; + scancode = atkbd_unxlate_table[i]; + atkbd->keycode[i] = atkbd_set2_keycode[scancode]; + atkbd->keycode[i | 0x80] = atkbd_set2_keycode[scancode | 0x80]; if (atkbd->scroll) for (j = 0; j < ARRAY_SIZE(atkbd_scroll_keys); j++) - if ((atkbd_unxlate_table[i] | 0x80) == atkbd_scroll_keys[j].set2) + if ((scancode | 0x80) == atkbd_scroll_keys[j].set2) atkbd->keycode[i | 0x80] = atkbd_scroll_keys[j].keycode; } } else if (atkbd->set == 3) { @@ -861,12 +877,29 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd) memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode)); if (atkbd->scroll) - for (i = 0; i < ARRAY_SIZE(atkbd_scroll_keys); i++) - atkbd->keycode[atkbd_scroll_keys[i].set2] = atkbd_scroll_keys[i].keycode; + for (i = 0; i < ARRAY_SIZE(atkbd_scroll_keys); i++) { + scancode = atkbd_scroll_keys[i].set2; + atkbd->keycode[scancode] = 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; +/* + * HANGEUL and HANJA keys do not send release events so we need to + * generate such events ourselves + */ + scancode = atkbd_compat_scancode(atkbd, ATKBD_RET_HANGEUL); + atkbd->keycode[scancode] = KEY_HANGEUL; + __set_bit(scancode, atkbd->force_release_mask); + + scancode = atkbd_compat_scancode(atkbd, ATKBD_RET_HANJA); + atkbd->keycode[scancode] = KEY_HANJA; + __set_bit(scancode, atkbd->force_release_mask); + +/* + * Perform additional fixups + */ + if (atkbd_platform_fixup) + atkbd_platform_fixup(atkbd); } /* @@ -1401,9 +1434,29 @@ static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf) return sprintf(buf, "%lu\n", atkbd->err_count); } +static int __init atkbd_setup_fixup(const struct dmi_system_id *id) +{ + atkbd_platform_fixup = id->driver_data; + return 0; +} + +static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { + { + .ident = "Dell Latitude series", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"), + }, + .callback = atkbd_setup_fixup, + .driver_data = atkbd_latitude_keymap_fixup, + }, + { } +}; static int __init atkbd_init(void) { + dmi_check_system(atkbd_dmi_quirk_table); + return serio_register_driver(&atkbd_drv); } diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index 1b08f4e..32e2c26 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c @@ -64,7 +64,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c index 3a79374..f3b86c2 100644 --- a/drivers/input/misc/ati_remote.c +++ b/drivers/input/misc/ati_remote.c @@ -90,7 +90,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c index 4e3ad65..1b87191 100644 --- a/drivers/input/misc/atlas_btns.c +++ b/drivers/input/misc/atlas_btns.c @@ -29,9 +29,10 @@ #include #include -#define ACPI_ATLAS_NAME "Atlas ACPI" -#define ACPI_ATLAS_CLASS "Atlas" +#define ACPI_ATLAS_NAME "Atlas ACPI" +#define ACPI_ATLAS_CLASS "Atlas" +static unsigned short atlas_keymap[16]; static struct input_dev *input_dev; /* button handling code */ @@ -50,12 +51,15 @@ static acpi_status acpi_atlas_button_handler(u32 function, void *handler_context, void *region_context) { acpi_status status; - int keycode; if (function == ACPI_WRITE) { - keycode = KEY_F1 + (address & 0x0F); - input_report_key(input_dev, keycode, !(address & 0x10)); + int code = address & 0x0f; + int key_down = !(address & 0x10); + + input_event(input_dev, EV_MSC, MSC_SCAN, code); + input_report_key(input_dev, atlas_keymap[code], key_down); input_sync(input_dev); + status = 0; } else { printk(KERN_WARNING "atlas: shrugged on unexpected function" @@ -70,6 +74,7 @@ static acpi_status acpi_atlas_button_handler(u32 function, static int atlas_acpi_button_add(struct acpi_device *device) { acpi_status status; + int i; int err; input_dev = input_allocate_device(); @@ -81,17 +86,19 @@ static int atlas_acpi_button_add(struct acpi_device *device) input_dev->name = "Atlas ACPI button driver"; input_dev->phys = "ASIM0000/atlas/input0"; input_dev->id.bustype = BUS_HOST; - input_dev->evbit[BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY); - - set_bit(KEY_F1, input_dev->keybit); - set_bit(KEY_F2, input_dev->keybit); - set_bit(KEY_F3, input_dev->keybit); - set_bit(KEY_F4, input_dev->keybit); - set_bit(KEY_F5, input_dev->keybit); - set_bit(KEY_F6, input_dev->keybit); - set_bit(KEY_F7, input_dev->keybit); - set_bit(KEY_F8, input_dev->keybit); - set_bit(KEY_F9, input_dev->keybit); + input_dev->keycode = atlas_keymap; + input_dev->keycodesize = sizeof(unsigned short); + input_dev->keycodemax = ARRAY_SIZE(atlas_keymap); + + input_set_capability(input_dev, EV_MSC, MSC_SCAN); + __set_bit(EV_KEY, input_dev->evbit); + for (i = 0; i < ARRAY_SIZE(atlas_keymap); i++) { + if (i < 9) { + atlas_keymap[i] = KEY_F1 + i; + __set_bit(KEY_F1 + i, input_dev->keybit); + } else + atlas_keymap[i] = KEY_RESERVED; + } err = input_register_device(input_dev); if (err) { diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index 1aef97e..4833b1a 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c @@ -27,55 +27,48 @@ #define BUTTONS_COUNT_THRESHOLD 3 #define BUTTONS_STATUS_MASK 0xfe000000 +static const unsigned short cobalt_map[] = { + KEY_RESERVED, + KEY_RESTART, + KEY_LEFT, + KEY_UP, + KEY_DOWN, + KEY_RIGHT, + KEY_ENTER, + KEY_SELECT +}; + struct buttons_dev { struct input_polled_dev *poll_dev; + unsigned short keymap[ARRAY_SIZE(cobalt_map)]; + int count[ARRAY_SIZE(cobalt_map)]; void __iomem *reg; }; -struct buttons_map { - uint32_t mask; - int keycode; - int count; -}; - -static struct buttons_map buttons_map[] = { - { 0x02000000, KEY_RESTART, }, - { 0x04000000, KEY_LEFT, }, - { 0x08000000, KEY_UP, }, - { 0x10000000, KEY_DOWN, }, - { 0x20000000, KEY_RIGHT, }, - { 0x40000000, KEY_ENTER, }, - { 0x80000000, KEY_SELECT, }, -}; - static void handle_buttons(struct input_polled_dev *dev) { - struct buttons_map *button = buttons_map; struct buttons_dev *bdev = dev->private; struct input_dev *input = dev->input; uint32_t status; int i; - status = readl(bdev->reg); - status = ~status & BUTTONS_STATUS_MASK; + status = ~readl(bdev->reg) >> 24; - for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { - if (status & button->mask) { - button->count++; + for (i = 0; i < ARRAY_SIZE(bdev->keymap); i++) { + if (status & (1UL << i)) { + if (++bdev->count[i] == BUTTONS_COUNT_THRESHOLD) { + input_event(input, EV_MSC, MSC_SCAN, i); + input_report_key(input, bdev->keymap[i], 1); + input_sync(input); + } } else { - if (button->count >= BUTTONS_COUNT_THRESHOLD) { - input_report_key(input, button->keycode, 0); + if (bdev->count[i] >= BUTTONS_COUNT_THRESHOLD) { + input_event(input, EV_MSC, MSC_SCAN, i); + input_report_key(input, bdev->keymap[i], 0); input_sync(input); } - button->count = 0; - } - - if (button->count == BUTTONS_COUNT_THRESHOLD) { - input_report_key(input, button->keycode, 1); - input_sync(input); + bdev->count[i] = 0; } - - button++; } } @@ -94,6 +87,8 @@ static int __devinit cobalt_buttons_probe(struct platform_device *pdev) goto err_free_mem; } + memcpy(bdev->keymap, cobalt_map, sizeof(bdev->keymap)); + poll_dev->private = bdev; poll_dev->poll = handle_buttons; poll_dev->poll_interval = BUTTONS_POLL_INTERVAL; @@ -104,11 +99,15 @@ static int __devinit cobalt_buttons_probe(struct platform_device *pdev) input->id.bustype = BUS_HOST; input->cdev.dev = &pdev->dev; - input->evbit[0] = BIT_MASK(EV_KEY); - for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { - set_bit(buttons_map[i].keycode, input->keybit); - buttons_map[i].count = 0; - } + input->keycode = pdev->keymap; + input->keycodemax = ARRAY_SIZE(pdev->keymap); + input->keycodesize = sizeof(unsigned short); + + input_set_capability(input, EV_MSC, MSC_SCAN); + __set_bit(EV_KEY, input->evbit); + for (i = 0; i < ARRAY_SIZE(buttons_map); i++) + __set_bit(input->keycode[i], input->keybit); + __clear_bit(KEY_RESERVED, input->keybit); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c index fd74347..952938a 100644 --- a/drivers/input/misc/keyspan_remote.c +++ b/drivers/input/misc/keyspan_remote.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #define DRIVER_VERSION "v0.1" @@ -46,53 +45,12 @@ MODULE_PARM_DESC(debug, "Enable extra debug messages and information"); #define RECV_SIZE 8 /* The UIA-11 type have a 8 byte limit. */ -/* table of devices that work with this driver */ -static struct usb_device_id keyspan_table[] = { - { USB_DEVICE(USB_KEYSPAN_VENDOR_ID, USB_KEYSPAN_PRODUCT_UIA11) }, - { } /* Terminating entry */ -}; - -/* Structure to store all the real stuff that a remote sends to us. */ -struct keyspan_message { - u16 system; - u8 button; - u8 toggle; -}; - -/* Structure used for all the bit testing magic needed to be done. */ -struct bit_tester { - u32 tester; - int len; - int pos; - int bits_left; - u8 buffer[32]; -}; - -/* Structure to hold all of our driver specific stuff */ -struct usb_keyspan { - char name[128]; - char phys[64]; - struct usb_device* udev; - struct input_dev *input; - struct usb_interface* interface; - struct usb_endpoint_descriptor* in_endpoint; - struct urb* irq_urb; - int open; - dma_addr_t in_dma; - unsigned char* in_buffer; - - /* variables used to parse messages from remote. */ - struct bit_tester data; - int stage; - int toggle; -}; - /* * Table that maps the 31 possible keycodes to input keys. * Currently there are 15 and 17 button models so RESERVED codes * are blank areas in the mapping. */ -static const int keyspan_key_table[] = { +static const unsigned short keyspan_key_table[] = { KEY_RESERVED, /* 0 is just a place holder. */ KEY_RESERVED, KEY_STOP, @@ -127,6 +85,48 @@ static const int keyspan_key_table[] = { KEY_MENU }; +/* table of devices that work with this driver */ +static struct usb_device_id keyspan_table[] = { + { USB_DEVICE(USB_KEYSPAN_VENDOR_ID, USB_KEYSPAN_PRODUCT_UIA11) }, + { } /* Terminating entry */ +}; + +/* Structure to store all the real stuff that a remote sends to us. */ +struct keyspan_message { + u16 system; + u8 button; + u8 toggle; +}; + +/* Structure used for all the bit testing magic needed to be done. */ +struct bit_tester { + u32 tester; + int len; + int pos; + int bits_left; + u8 buffer[32]; +}; + +/* Structure to hold all of our driver specific stuff */ +struct usb_keyspan { + char name[128]; + char phys[64]; + unsigned short keymap[ARRAY_SIZE(keyspan_key_table)]; + struct usb_device *udev; + struct input_dev *input; + struct usb_interface *interface; + struct usb_endpoint_descriptor *in_endpoint; + struct urb* irq_urb; + int open; + dma_addr_t in_dma; + unsigned char *in_buffer; + + /* variables used to parse messages from remote. */ + struct bit_tester data; + int stage; + int toggle; +}; + static struct usb_driver keyspan_driver; /* @@ -173,6 +173,15 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed) return 0; } +static void keyspan_report_button(struct usb_keyspan *remote, int button, int press) +{ + struct input_dev *input = remote->input; + + input_event(input, EV_MSC, MSC_SCAN, button); + input_report_key(input, remote->keymap[button], press); + input_sync(input); +} + /* * Routine that handles all the logic needed to parse out the message from the remote. */ @@ -311,9 +320,8 @@ static void keyspan_check_data(struct usb_keyspan *remote) __FUNCTION__, message.system, message.button, message.toggle); if (message.toggle != remote->toggle) { - input_report_key(remote->input, keyspan_key_table[message.button], 1); - input_report_key(remote->input, keyspan_key_table[message.button], 0); - input_sync(remote->input); + keyspan_report_button(remote, message.button, 1); + keyspan_report_button(remote, message.button, 0); remote->toggle = message.toggle; } @@ -491,16 +499,21 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic usb_make_path(udev, remote->phys, sizeof(remote->phys)); strlcat(remote->phys, "/input0", sizeof(remote->phys)); + memcpy(remote->keymap, keyspan_key_table, sizeof(remote->keymap)); input_dev->name = remote->name; input_dev->phys = remote->phys; usb_to_input_id(udev, &input_dev->id); input_dev->dev.parent = &interface->dev; + input_dev->keycode = remote->keymap; + input_dev->keycodesize = sizeof(unsigned short); + input_dev->keycodemax = ARRAY_SIZE(remote->keymap); - input_dev->evbit[0] = BIT_MASK(EV_KEY); /* We will only report KEY events. */ + input_set_capability(input_dev, EV_MSC, MSC_SCAN); + __set_bit(EV_KEY, input_dev->evbit); for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++) - if (keyspan_key_table[i] != KEY_RESERVED) - set_bit(keyspan_key_table[i], input_dev->keybit); + __set_bit(keyspan_key_table[i], input_dev->keybit); + __clear_bit(KEY_RESERVED, input_dev->keybit); input_set_drvdata(input_dev, remote); @@ -508,12 +521,14 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic input_dev->close = keyspan_close; /* - * Initialize the URB to access the device. The urb gets sent to the device in keyspan_open() + * Initialize the URB to access the device. + * The urb gets sent to the device in keyspan_open() */ usb_fill_int_urb(remote->irq_urb, - remote->udev, usb_rcvintpipe(remote->udev, remote->in_endpoint->bEndpointAddress), + remote->udev, + usb_rcvintpipe(remote->udev, endpoint->bEndpointAddress), remote->in_buffer, RECV_SIZE, keyspan_irq_recv, remote, - remote->in_endpoint->bInterval); + endpoint->bInterval); remote->irq_urb->transfer_dma = remote->in_dma; remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c index 26ec095..06c35fc 100644 --- a/drivers/input/mouse/inport.c +++ b/drivers/input/mouse/inport.c @@ -35,7 +35,6 @@ */ #include -#include #include #include #include diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c index 37e7c75..9ea8955 100644 --- a/drivers/input/mouse/logibm.c +++ b/drivers/input/mouse/logibm.c @@ -36,7 +36,6 @@ */ #include -#include #include #include #include diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 21a9c0b..a1a63ae 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 9ab5b5e..26b845f 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 78c3ea7..e1c1da0 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 1a0cea3..cbe83bf 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include @@ -280,7 +279,14 @@ static void i8042_stop(struct serio *serio) struct i8042_port *port = serio->port_data; port->exists = 0; - synchronize_sched(); + + /* + * We synchronize with both AUX and KBD IRQs because there is + * a (very unlikely) chance that AUX IRQ is raised for KBD port + * and vice versa. + */ + synchronize_irq(I8042_AUX_IRQ); + synchronize_irq(I8042_KBD_IRQ); port->serio = NULL; } diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 10d9d74..b819239 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c index 80a6588..efd3aeb 100644 --- a/drivers/input/touchscreen/mk712.c +++ b/drivers/input/touchscreen/mk712.c @@ -36,7 +36,6 @@ */ #include -#include #include #include #include diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 7549939..35faf46 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c @@ -15,7 +15,6 @@ */ #include -#include #include #include #include diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c index 3e93f80..719b17c 100644 --- a/drivers/media/video/usbvideo/konicawc.c +++ b/drivers/media/video/usbvideo/konicawc.c @@ -241,8 +241,6 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev input_dev->evbit[0] = BIT_MASK(EV_KEY); input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); - input_dev->private = cam; - error = input_register_device(cam->input); if (error) { warn("Failed to register camera's input device, err: %d\n", diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c index d847273..6438bc1 100644 --- a/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/drivers/media/video/usbvideo/quickcam_messenger.c @@ -105,8 +105,6 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev) input_dev->evbit[0] = BIT_MASK(EV_KEY); input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); - input_dev->private = cam; - error = input_register_device(cam->input); if (error) { warn("Failed to register camera's input device, err: %d\n", diff --git a/include/linux/input.h b/include/linux/input.h index 2075d6d..9a963fe 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1309,6 +1309,9 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis); } +int input_get_keycode(struct input_dev *dev, int scancode, int *keycode); +int input_set_keycode(struct input_dev *dev, int scancode, int keycode); + extern struct class input_class; /**