diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 12:57:44 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 12:57:44 -0800 |
commit | 6e5565f949af1322f8f3d3f43d044645ae448499 (patch) | |
tree | 92868f6d3dcc6c105a0d35f9412f75c07139402e | |
parent | e5a9e8e6890d9b9c7a0f25b03ffdaf28614a9a4c (diff) | |
parent | 03366e7b9bf1544cb0b98f1a5cd6d340654f486a (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (34 commits)
Input: i8042 - non-x86 build fix
Input: pxa27x_keypad - also enable on PXA3xx
Input: pxa27x_keypad - add debounce_interval to the keypad platform data
Input: pxa27x_keypad - use device resources for I/O memory mapping and IRQ
Input: pxa27x_keypad - enable rotary encoders and direct keys
Input: pxa27x_keypad - introduce pxa27x_keypad_config()
Input: pxa27x_keypad - introduce driver structure and use KEY() to define matrix keys
Input: pxa27x_keypad - remove pin configuration from the driver
Input: pxa27x_keypad - rename the driver (was pxa27x_keyboard)
Input: constify function pointer tables (seq_operations)
Input: i8042 - add Fujitsu-Siemens Amilo Pro 2010 to nomux list
Input: i8042 - enable DMI quirks on x86-64
Input: i8042 - add Dritek quirk for Acer Aspire 9110
Input: add input event to APM event bridge
Input: mousedev - use BIT_MASK instead of BIT
Input: remove duplicate includes
Input: remove cdev from input_dev structure
Input: remove duplicated headers in drivers/char/keyboard.c
Input: i8042 - add Dritek keyboard extension quirk
Input: add Tosa keyboard driver
...
47 files changed, 2073 insertions, 484 deletions
diff --git a/Documentation/input/input-programming.txt b/Documentation/input/input-programming.txt index 47fc86830cd..81905e81585 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/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 9b26fa5edad..f99112d50b4 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -21,6 +21,8 @@ #include <linux/mmc/host.h> #include <linux/pm.h> #include <linux/delay.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> #include <asm/setup.h> #include <asm/memory.h> @@ -246,6 +248,46 @@ static struct platform_device tosakbd_device = { .id = -1, }; +static struct gpio_keys_button tosa_gpio_keys[] = { + { + .type = EV_PWR, + .code = KEY_SUSPEND, + .gpio = TOSA_GPIO_ON_KEY, + .desc = "On key", + .wakeup = 1, + .active_low = 1, + }, + { + .type = EV_KEY, + .code = TOSA_KEY_RECORD, + .gpio = TOSA_GPIO_RECORD_BTN, + .desc = "Record Button", + .wakeup = 1, + .active_low = 1, + }, + { + .type = EV_KEY, + .code = TOSA_KEY_SYNC, + .gpio = TOSA_GPIO_SYNC, + .desc = "Sync Button", + .wakeup = 1, + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data tosa_gpio_keys_platform_data = { + .buttons = tosa_gpio_keys, + .nbuttons = ARRAY_SIZE(tosa_gpio_keys), +}; + +static struct platform_device tosa_gpio_keys_device = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &tosa_gpio_keys_platform_data, + }, +}; + /* * Tosa LEDs */ @@ -258,6 +300,7 @@ static struct platform_device *devices[] __initdata = { &tosascoop_device, &tosascoop_jc_device, &tosakbd_device, + &tosa_gpio_keys_device, &tosaled_device, }; diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index fc54d234507..4dbd3425e92 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -38,7 +38,6 @@ #include <linux/kbd_kern.h> #include <linux/kbd_diacr.h> #include <linux/vt_kern.h> -#include <linux/consolemap.h> #include <linux/sysrq.h> #include <linux/input.h> #include <linux/reboot.h> @@ -194,7 +193,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 +207,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/Kconfig b/drivers/input/Kconfig index 63512d906f0..9dea14db724 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -137,6 +137,18 @@ config INPUT_EVBUG To compile this driver as a module, choose M here: the module will be called evbug. +config INPUT_APMPOWER + tristate "Input Power Event -> APM Bridge" if EMBEDDED + depends on INPUT && APM_EMULATION + ---help--- + Say Y here if you want suspend key events to trigger a user + requested suspend through APM. This is useful on embedded + systems where such behviour is desired without userspace + interaction. If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called apm-power. + comment "Input Device Drivers" source "drivers/input/keyboard/Kconfig" diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 99af903bd3c..2ae87b19caa 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -22,3 +22,4 @@ obj-$(CONFIG_INPUT_TABLET) += tablet/ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/ obj-$(CONFIG_INPUT_MISC) += misc/ +obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o diff --git a/drivers/input/apm-power.c b/drivers/input/apm-power.c new file mode 100644 index 00000000000..c36d110b349 --- /dev/null +++ b/drivers/input/apm-power.c @@ -0,0 +1,131 @@ +/* + * Input Power Event -> APM Bridge + * + * Copyright (c) 2007 Richard Purdie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/module.h> +#include <linux/input.h> +#include <linux/slab.h> +#include <linux/init.h> +#include <linux/tty.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/apm-emulation.h> + +static void system_power_event(unsigned int keycode) +{ + switch (keycode) { + case KEY_SUSPEND: + apm_queue_event(APM_USER_SUSPEND); + + printk(KERN_INFO "apm-power: Requesting system suspend...\n"); + break; + default: + break; + } +} + +static void apmpower_event(struct input_handle *handle, unsigned int type, + unsigned int code, int value) +{ + /* only react on key down events */ + if (value != 1) + return; + + switch (type) { + case EV_PWR: + system_power_event(code); + break; + + default: + break; + } +} + +static int apmpower_connect(struct input_handler *handler, + struct input_dev *dev, + const struct input_device_id *id) +{ + struct input_handle *handle; + int error; + + handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); + if (!handle) + return -ENOMEM; + + handle->dev = dev; + handle->handler = handler; + handle->name = "apm-power"; + + handler->private = handle; + + error = input_register_handle(handle); + if (error) { + printk(KERN_ERR + "apm-power: Failed to register input power handler, " + "error %d\n", error); + kfree(handle); + return error; + } + + error = input_open_device(handle); + if (error) { + printk(KERN_ERR + "apm-power: Failed to open input power device, " + "error %d\n", error); + input_unregister_handle(handle); + kfree(handle); + return error; + } + + return 0; +} + +static void apmpower_disconnect(struct input_handle *handler) +{ + struct input_handle *handle = handler->private; + + input_close_device(handle); + kfree(handle); +} + +static const struct input_device_id apmpower_ids[] = { + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT, + .evbit = { BIT_MASK(EV_PWR) }, + }, + { }, +}; + +MODULE_DEVICE_TABLE(input, apmpower_ids); + +static struct input_handler apmpower_handler = { + .event = apmpower_event, + .connect = apmpower_connect, + .disconnect = apmpower_disconnect, + .name = "apm-power", + .id_table = apmpower_ids, +}; + +static int __init apmpower_init(void) +{ + return input_register_handler(&apmpower_handler); +} + +static void __exit apmpower_exit(void) +{ + input_unregister_handler(&apmpower_handler); +} + +module_init(apmpower_init); +module_exit(apmpower_exit); + +MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); +MODULE_DESCRIPTION("Input Power Event -> APM Bridge"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index e5b4e9bfbdc..0727b0a1255 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 92b359894e8..490918a5d19 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 a0be978501f..f02c242c311 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -493,7 +493,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); } } @@ -526,7 +526,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); @@ -540,10 +540,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) @@ -586,6 +583,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++) \ @@ -755,7 +821,7 @@ static int input_devices_seq_show(struct seq_file *seq, void *v) return 0; } -static struct seq_operations input_devices_seq_ops = { +static const struct seq_operations input_devices_seq_ops = { .start = input_devices_seq_start, .next = input_devices_seq_next, .stop = input_devices_seq_stop, @@ -808,7 +874,7 @@ static int input_handlers_seq_show(struct seq_file *seq, void *v) return 0; } -static struct seq_operations input_handlers_seq_ops = { +static const struct seq_operations input_handlers_seq_ops = { .start = input_handlers_seq_start, .next = input_handlers_seq_next, .stop = input_handlers_seq_stop, @@ -1329,9 +1395,6 @@ int input_register_device(struct input_dev *dev) snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1); - if (dev->cdev.dev) - dev->dev.parent = dev->cdev.dev; - error = device_add(&dev->dev); if (error) return error; diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c index 5cf9f3610e6..deb9f825f92 100644 --- a/drivers/input/joystick/amijoy.c +++ b/drivers/input/joystick/amijoy.c @@ -32,7 +32,6 @@ #include <linux/errno.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/moduleparam.h> #include <linux/init.h> #include <linux/input.h> #include <linux/interrupt.h> diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 15739880afc..f32e031dcb2 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -31,7 +31,6 @@ #include <linux/delay.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/moduleparam.h> #include <linux/slab.h> #include <linux/bitops.h> #include <linux/init.h> diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index a6ca9d5e252..960e501c60c 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -33,7 +33,6 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/moduleparam.h> #include <linux/delay.h> #include <linux/init.h> #include <linux/parport.h> diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index df2a9d02ca6..07a32aff5a3 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -33,7 +33,6 @@ #include <linux/kernel.h> #include <linux/delay.h> #include <linux/module.h> -#include <linux/moduleparam.h> #include <linux/init.h> #include <linux/parport.h> #include <linux/input.h> diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index 6f826b37d9a..a2517fa72eb 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 bbebd4e2ad7..989483f5316 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c @@ -35,7 +35,6 @@ #include <linux/parport.h> #include <linux/input.h> #include <linux/module.h> -#include <linux/moduleparam.h> #include <linux/init.h> #include <linux/mutex.h> diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 6e9d75bd2b1..0380597249b 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -75,7 +75,6 @@ #include <linux/slab.h> #include <linux/stat.h> #include <linux/module.h> -#include <linux/moduleparam.h> #include <linux/usb/input.h> #define DRIVER_VERSION "v0.0.6" diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 086d58c0ccb..8ea709be330 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -154,6 +154,27 @@ config KEYBOARD_SPITZ To compile this driver as a module, choose M here: the module will be called spitzkbd. +config KEYBOARD_TOSA + tristate "Tosa keyboard" + depends on MACH_TOSA + default y + help + Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa) + + To compile this driver as a module, choose M here: the + module will be called tosakbd. + +config KEYBOARD_TOSA_USE_EXT_KEYCODES + bool "Tosa keyboa |