aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-04-13 11:37:23 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-13 11:37:23 -0700
commitb534d388c268ad051c72b187106a3c99021be006 (patch)
treeccfe40792b52366ce237c2043256d28916a0122e /drivers
parentc751085943362143f84346d274e0011419c84202 (diff)
parentba28f22e7cf16cb310bb491cbb3f7d0d5d1f5c5d (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: (22 commits) Input: i8042 - add HP DV9700 to the noloop list Input: arrange drivers/input/misc/Makefile in alphabetical order Input: add AD7879 Touchscreen driver Input: add AD7877 touchscreen driver Input: bf54x-keys - fix typo in warning Input: add driver for S1 button of rb532 Input: generic driver for rotary encoders on GPIOs Input: hilkbd - fix crash when removing hilkbd module Input: atkbd - add quirk for Fujitsu Siemens Amilo PA 1510 Input: atkbd - consolidate force release quirk setup Input: add accelerated touchscreen support for Marvell Zylonite Input: ucb1400_ts, mainstone-wm97xx - add BTN_TOUCH events Input: wm97xx - use disable_irq_nosync() for Mainstone Input: wm97xx - add BTN_TOUCH event to wm97xx to use it with Android Input: fix polling of /proc/bus/input/devices Input: psmouse - add newline to OLPC HGPK touchpad debugging Input: ati_remote2 - check module params Input: ati_remote2 - add per device attrs Input: ati_remote2 - complete suspend support Input: stop autorepeat timer on key release ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/input.c13
-rw-r--r--drivers/input/keyboard/atkbd.c135
-rw-r--r--drivers/input/keyboard/bf54x-keys.c4
-rw-r--r--drivers/input/keyboard/hilkbd.c140
-rw-r--r--drivers/input/misc/Kconfig23
-rw-r--r--drivers/input/misc/Makefile28
-rw-r--r--drivers/input/misc/ati_remote2.c277
-rw-r--r--drivers/input/misc/rb532_button.c120
-rw-r--r--drivers/input/misc/rotary_encoder.c221
-rw-r--r--drivers/input/mouse/Kconfig11
-rw-r--r--drivers/input/mouse/Makefile9
-rw-r--r--drivers/input/mouse/hgpk.c2
-rw-r--r--drivers/input/mouse/maplemouse.c147
-rw-r--r--drivers/input/mouse/pc110pad.c5
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h8
-rw-r--r--drivers/input/touchscreen/Kconfig58
-rw-r--r--drivers/input/touchscreen/Makefile3
-rw-r--r--drivers/input/touchscreen/ad7877.c844
-rw-r--r--drivers/input/touchscreen/ad7879.c782
-rw-r--r--drivers/input/touchscreen/mainstone-wm97xx.c3
-rw-r--r--drivers/input/touchscreen/ucb1400_ts.c5
-rw-r--r--drivers/input/touchscreen/wm97xx-core.c13
-rw-r--r--drivers/input/touchscreen/zylonite-wm97xx.c240
23 files changed, 2909 insertions, 182 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index ec3db3ade11..d44065d2e66 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -132,6 +132,11 @@ static void input_start_autorepeat(struct input_dev *dev, int code)
}
}
+static void input_stop_autorepeat(struct input_dev *dev)
+{
+ del_timer(&dev->timer);
+}
+
#define INPUT_IGNORE_EVENT 0
#define INPUT_PASS_TO_HANDLERS 1
#define INPUT_PASS_TO_DEVICE 2
@@ -167,6 +172,8 @@ static void input_handle_event(struct input_dev *dev,
__change_bit(code, dev->key);
if (value)
input_start_autorepeat(dev, code);
+ else
+ input_stop_autorepeat(dev);
}
disposition = INPUT_PASS_TO_HANDLERS;
@@ -737,11 +744,11 @@ static inline void input_wakeup_procfs_readers(void)
static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait)
{
- int state = input_devices_state;
-
poll_wait(file, &input_devices_poll_wait, wait);
- if (state != input_devices_state)
+ if (file->f_version != input_devices_state) {
+ file->f_version = input_devices_state;
return POLLIN | POLLRDNORM;
+ }
return 0;
}
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 45470f18d7e..f999dc60c3b 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -229,7 +229,8 @@ struct atkbd {
/*
* System-specific ketymap fixup routine
*/
-static void (*atkbd_platform_fixup)(struct atkbd *);
+static void (*atkbd_platform_fixup)(struct atkbd *, const void *data);
+static void *atkbd_platform_fixup_data;
static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
ssize_t (*handler)(struct atkbd *, char *));
@@ -834,87 +835,64 @@ static void atkbd_disconnect(struct serio *serio)
}
/*
- * Most special keys (Fn+F?) on Dell laptops do not generate release
- * events so we have to do it ourselves.
+ * generate release events for the keycodes given in data
*/
-static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
+static void atkbd_apply_forced_release_keylist(struct atkbd* atkbd,
+ const void *data)
{
- static const unsigned int forced_release_keys[] = {
- 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,
- };
- int i;
+ const unsigned int *keys = data;
+ unsigned 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);
+ for (i = 0; keys[i] != -1U; i++)
+ __set_bit(keys[i], atkbd->force_release_mask);
}
/*
+ * Most special keys (Fn+F?) on Dell laptops do not generate release
+ * events so we have to do it ourselves.
+ */
+static unsigned int atkbd_dell_laptop_forced_release_keys[] = {
+ 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, -1U
+};
+
+/*
* Perform fixup for HP system that doesn't generate release
* for its video switch
*/
-static void atkbd_hp_keymap_fixup(struct atkbd *atkbd)
-{
- static const unsigned int forced_release_keys[] = {
- 0x94,
- };
- 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);
-}
+static unsigned int atkbd_hp_forced_release_keys[] = {
+ 0x94, -1U
+};
/*
* Inventec system with broken key release on volume keys
*/
-static void atkbd_inventec_keymap_fixup(struct atkbd *atkbd)
-{
- const unsigned int forced_release_keys[] = {
- 0xae, 0xb0,
- };
- 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);
-}
+static unsigned int atkbd_inventec_forced_release_keys[] = {
+ 0xae, 0xb0, -1U
+};
/*
* Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release
* for its volume buttons
*/
-static void atkbd_hp_zv6100_keymap_fixup(struct atkbd *atkbd)
-{
- const unsigned int forced_release_keys[] = {
- 0xae, 0xb0,
- };
- 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);
-}
+static unsigned int atkbd_hp_zv6100_forced_release_keys[] = {
+ 0xae, 0xb0, -1U
+};
/*
* Samsung NC10 with Fn+F? key release not working
*/
-static void atkbd_samsung_keymap_fixup(struct atkbd *atkbd)
-{
- const unsigned int forced_release_keys[] = {
- 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9,
- };
- int i;
+static unsigned int atkbd_samsung_forced_release_keys[] = {
+ 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U
+};
- if (atkbd->set == 2)
- for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
- __set_bit(forced_release_keys[i],
- atkbd->force_release_mask);
-}
+/*
+ * The volume up and volume down special keys on a Fujitsu Amilo PA 1510 laptop
+ * do not generate release events so we have to do it ourselves.
+ */
+static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = {
+ 0xb0, 0xae, -1U
+};
/*
* atkbd_set_keycode_table() initializes keyboard's keycode table
@@ -967,7 +945,7 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd)
* Perform additional fixups
*/
if (atkbd_platform_fixup)
- atkbd_platform_fixup(atkbd);
+ atkbd_platform_fixup(atkbd, atkbd_platform_fixup_data);
}
/*
@@ -1492,9 +1470,11 @@ 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)
+static int __init atkbd_setup_forced_release(const struct dmi_system_id *id)
{
- atkbd_platform_fixup = id->driver_data;
+ atkbd_platform_fixup = atkbd_apply_forced_release_keylist;
+ atkbd_platform_fixup_data = id->driver_data;
+
return 0;
}
@@ -1505,8 +1485,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
},
- .callback = atkbd_setup_fixup,
- .driver_data = atkbd_dell_laptop_keymap_fixup,
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_dell_laptop_forced_release_keys,
},
{
.ident = "Dell Laptop",
@@ -1514,8 +1494,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
},
- .callback = atkbd_setup_fixup,
- .driver_data = atkbd_dell_laptop_keymap_fixup,
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_dell_laptop_forced_release_keys,
},
{
.ident = "HP 2133",
@@ -1523,8 +1503,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"),
},
- .callback = atkbd_setup_fixup,
- .driver_data = atkbd_hp_keymap_fixup,
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_hp_forced_release_keys,
},
{
.ident = "HP Pavilion ZV6100",
@@ -1532,8 +1512,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"),
},
- .callback = atkbd_setup_fixup,
- .driver_data = atkbd_hp_zv6100_keymap_fixup,
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_hp_zv6100_forced_release_keys,
},
{
.ident = "Inventec Symphony",
@@ -1541,8 +1521,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"),
DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),
},
- .callback = atkbd_setup_fixup,
- .driver_data = atkbd_inventec_keymap_fixup,
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_inventec_forced_release_keys,
},
{
.ident = "Samsung NC10",
@@ -1550,8 +1530,17 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
DMI_MATCH(DMI_PRODUCT_NAME, "NC10"),
},
- .callback = atkbd_setup_fixup,
- .driver_data = atkbd_samsung_keymap_fixup,
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_samsung_forced_release_keys,
+ },
+ {
+ .ident = "Fujitsu Amilo PA 1510",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"),
+ },
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_amilo_pa1510_forced_release_keys,
},
{ }
};
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c
index ee855c5202e..e94b7d735ac 100644
--- a/drivers/input/keyboard/bf54x-keys.c
+++ b/drivers/input/keyboard/bf54x-keys.c
@@ -211,8 +211,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT ||
!pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) {
- printk(KERN_ERR DRV_NAME
- ": Invalid Debounce/Columdrive Time from pdata\n");
+ printk(KERN_WARNING DRV_NAME
+ ": Invalid Debounce/Columndrive Time in platform data\n");
bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */
} else {
bfin_write_KPAD_MSEL(
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
index aacf71f3cd4..e9d639ec283 100644
--- a/drivers/input/keyboard/hilkbd.c
+++ b/drivers/input/keyboard/hilkbd.c
@@ -198,45 +198,28 @@ static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len)
}
-/* initialise HIL */
-static int __init
-hil_keyb_init(void)
+/* initialize HIL */
+static int __devinit hil_keyb_init(void)
{
unsigned char c;
unsigned int i, kbid;
wait_queue_head_t hil_wait;
int err;
- if (hil_dev.dev) {
+ if (hil_dev.dev)
return -ENODEV; /* already initialized */
- }
+ init_waitqueue_head(&hil_wait);
spin_lock_init(&hil_dev.lock);
+
hil_dev.dev = input_allocate_device();
if (!hil_dev.dev)
return -ENOMEM;
-#if defined(CONFIG_HP300)
- if (!MACH_IS_HP300) {
- err = -ENODEV;
- goto err1;
- }
- if (!hwreg_present((void *)(HILBASE + HIL_DATA))) {
- printk(KERN_ERR "HIL: hardware register was not found\n");
- err = -ENODEV;
- goto err1;
- }
- if (!request_region(HILBASE + HIL_DATA, 2, "hil")) {
- printk(KERN_ERR "HIL: IOPORT region already used\n");
- err = -EIO;
- goto err1;
- }
-#endif
-
err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id);
if (err) {
printk(KERN_ERR "HIL: Can't get IRQ\n");
- goto err2;
+ goto err1;
}
/* Turn on interrupts */
@@ -246,11 +229,9 @@ hil_keyb_init(void)
hil_dev.valid = 0; /* clear any pending data */
hil_do(HIL_READKBDSADR, NULL, 0);
- init_waitqueue_head(&hil_wait);
- wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ);
- if (!hil_dev.valid) {
+ wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3 * HZ);
+ if (!hil_dev.valid)
printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n");
- }
c = hil_dev.c;
hil_dev.valid = 0;
@@ -268,7 +249,7 @@ hil_keyb_init(void)
for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++)
if (hphilkeyb_keycode[i] != KEY_RESERVED)
- set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
+ __set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
hil_dev.dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
hil_dev.dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
@@ -287,34 +268,45 @@ hil_keyb_init(void)
err = input_register_device(hil_dev.dev);
if (err) {
printk(KERN_ERR "HIL: Can't register device\n");
- goto err3;
+ goto err2;
}
+
printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n",
hil_dev.dev->name, kbid, HILBASE, HIL_IRQ);
return 0;
-err3:
+err2:
hil_do(HIL_INTOFF, NULL, 0);
- disable_irq(HIL_IRQ);
free_irq(HIL_IRQ, hil_dev.dev_id);
-err2:
-#if defined(CONFIG_HP300)
- release_region(HILBASE + HIL_DATA, 2);
err1:
-#endif
input_free_device(hil_dev.dev);
hil_dev.dev = NULL;
return err;
}
+static void __devexit hil_keyb_exit(void)
+{
+ if (HIL_IRQ)
+ free_irq(HIL_IRQ, hil_dev.dev_id);
+
+ /* Turn off interrupts */
+ hil_do(HIL_INTOFF, NULL, 0);
+
+ input_unregister_device(hil_dev.dev);
+ hil_dev.dev = NULL;
+}
#if defined(CONFIG_PARISC)
-static int __init
-hil_init_chip(struct parisc_device *dev)
+static int __devinit hil_probe_chip(struct parisc_device *dev)
{
+ /* Only allow one HIL keyboard */
+ if (hil_dev.dev)
+ return -ENODEV;
+
if (!dev->irq) {
- printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa.start);
+ printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%p\n",
+ (void *)dev->hpa.start);
return -ENODEV;
}
@@ -327,51 +319,79 @@ hil_init_chip(struct parisc_device *dev)
return hil_keyb_init();
}
+static int __devexit hil_remove_chip(struct parisc_device *dev)
+{
+ hil_keyb_exit();
+
+ return 0;
+}
+
static struct parisc_device_id hil_tbl[] = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 },
{ 0, }
};
+#if 0
+/* Disabled to avoid conflicts with the HP SDC HIL drivers */
MODULE_DEVICE_TABLE(parisc, hil_tbl);
+#endif
static struct parisc_driver hil_driver = {
- .name = "hil",
- .id_table = hil_tbl,
- .probe = hil_init_chip,
+ .name = "hil",
+ .id_table = hil_tbl,
+ .probe = hil_probe_chip,
+ .remove = __devexit_p(hil_remove_chip),
};
-#endif /* CONFIG_PARISC */
-
static int __init hil_init(void)
{
-#if defined(CONFIG_PARISC)
return register_parisc_driver(&hil_driver);
-#else
- return hil_keyb_init();
-#endif
}
-
static void __exit hil_exit(void)
{
- if (HIL_IRQ) {
- disable_irq(HIL_IRQ);
- free_irq(HIL_IRQ, hil_dev.dev_id);
+ unregister_parisc_driver(&hil_driver);
+}
+
+#else /* !CONFIG_PARISC */
+
+static int __init hil_init(void)
+{
+ int error;
+
+ /* Only allow one HIL keyboard */
+ if (hil_dev.dev)
+ return -EBUSY;
+
+ if (!MACH_IS_HP300)
+ return -ENODEV;
+
+ if (!hwreg_present((void *)(HILBASE + HIL_DATA))) {
+ printk(KERN_ERR "HIL: hardware register was not found\n");
+ return -ENODEV;
}
- /* Turn off interrupts */
- hil_do(HIL_INTOFF, NULL, 0);
+ if (!request_region(HILBASE + HIL_DATA, 2, "hil")) {
+ printk(KERN_ERR "HIL: IOPORT region already used\n");
+ return -EIO;
+ }
- input_unregister_device(hil_dev.dev);
+ error = hil_keyb_init();
+ if (error) {
+ release_region(HILBASE + HIL_DATA, 2);
+ return error;
+ }
- hil_dev.dev = NULL;
+ return 0;
+}
-#if defined(CONFIG_PARISC)
- unregister_parisc_driver(&hil_driver);
-#else
- release_region(HILBASE+HIL_DATA, 2);
-#endif
+static void __exit hil_exit(void)
+{
+ hil_keyb_exit();
+ release_region(HILBASE + HIL_DATA, 2);
}
+#endif /* CONFIG_PARISC */
+
module_init(hil_init);
module_exit(hil_exit);
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 67e5553f699..203abac1e23 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -227,4 +227,27 @@ config INPUT_PCF50633_PMU
Say Y to include support for delivering PMU events via input
layer on NXP PCF50633.
+config INPUT_GPIO_ROTARY_ENCODER
+ tristate "Rotary encoders connected to GPIO pins"
+ depends on GPIOLIB && GENERIC_GPIO
+ help
+ Say Y here to add support for rotary encoders connected to GPIO lines.
+ Check file:Documentation/incput/rotary_encoder.txt for more
+ information.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rotary_encoder.
+
+config INPUT_RB532_BUTTON
+ tristate "Mikrotik Routerboard 532 button interface"
+ depends on MIKROTIK_RB532
+ depends on GPIOLIB && GENERIC_GPIO
+ select INPUT_POLLDEV
+ help
+ Say Y here if you want support for the S1 button built into
+ Mikrotik's Routerboard 532.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rb532_button.
+
endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index bb62e6efacf..eb3f407baed 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -4,21 +4,23 @@
# Each configuration option enables a list of files.
-obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
-obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
-obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
-obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
-obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o
-obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
-obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
+obj-$(CONFIG_INPUT_APANEL) += apanel.o
obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o
obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
-obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
-obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
-obj-$(CONFIG_INPUT_YEALINK) += yealink.o
+obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
obj-$(CONFIG_INPUT_CM109) += cm109.o
+obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
-obj-$(CONFIG_INPUT_UINPUT) += uinput.o
-obj-$(CONFIG_INPUT_APANEL) += apanel.o
-obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
+obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
+obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
+obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o
+obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
+obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
+obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o
+obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o
+obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
+obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
+obj-$(CONFIG_INPUT_UINPUT) += uinput.o
+obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
+obj-$(CONFIG_INPUT_YEALINK) += yealink.o
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
index 3c9988dc0e9..922c0514158 100644
--- a/drivers/input/misc/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -31,12 +31,73 @@ MODULE_LICENSE("GPL");
* newly configured "channel".
*/
-static unsigned int channel_mask = 0xFFFF;
-module_param(channel_mask, uint, 0644);
+enum {
+ ATI_REMOTE2_MAX_CHANNEL_MASK = 0xFFFF,
+ ATI_REMOTE2_MAX_MODE_MASK = 0x1F,
+};
+
+static int ati_remote2_set_mask(const char *val,
+ struct kernel_param *kp, unsigned int max)
+{
+ unsigned long mask;
+ int ret;
+
+ if (!val)
+ return -EINVAL;
+
+ ret = strict_strtoul(val, 0, &mask);
+ if (ret)
+ return ret;
+
+ if (mask & ~max)
+ return -EINVAL;
+
+ *(unsigned int *)kp->arg = mask;
+
+ return 0;
+}
+
+static int ati_remote2_set_channel_mask(const char *val,
+ struct kernel_param *kp)
+{
+ pr_debug("%s()\n", __func__);
+
+ return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK);
+}
+
+static int ati_remote2_get_channel_mask(char *buffer, struct kernel_param *kp)
+{
+ pr_debug("%s()\n", __func__);
+
+ return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg);
+}
+
+static int ati_remote2_set_mode_mask(const char *val, struct kernel_param *kp)
+{
+ pr_debug("%s()\n", __func__);
+
+ return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK);
+}
+
+static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp)
+{
+ pr_debug("%s()\n", __func__);
+
+ return sprintf(buffer, "0x%02x", *(unsigned int *)kp->arg);
+}
+
+static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK;
+#define param_check_channel_mask(name, p) __param_check(name, p, unsigned int)
+#define param_set_channel_mask ati_remote2_set_channel_mask
+#define param_get_channel_mask ati_remote2_get_channel_mask
+module_param(channel_mask, channel_mask, 0644);
MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>");
-static unsigned int mode_mask = 0x1F;
-module_param(mode_mask, uint, 0644);
+static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK;
+#define param_check_mode_mask(name, p) __param_check(name, p, unsigned int)
+#define param_set_mode_mask ati_remote2_set_mode_mask
+#define param_get_mode_mask ati_remote2_get_mode_mask
+module_param(mode_mask, mode_mask, 0644);
MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>");
static struct usb_device_id ati_remote2_id_table[] = {
@@ -133,12 +194,18 @@ struct ati_remote2 {
u16 keycode[ATI_REMOTE2_MODES][ARRAY_SIZE(ati_remote2_key_table)];
unsigned int flags;
+
+ unsigned int channel_mask;
+ unsigned int mode_mask;
};
static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id);
static void ati_remote2_disconnect(struct usb_interface *interface);
static int ati_remote2_suspend(struct usb_interface *interface, pm_message_t message);
static int ati_remote2_resume(struct usb_interface *interface);
+static int ati_remote2_reset_resume(struct usb_interface *interface);
+static int ati_remote2_pre_reset(struct usb_interface *interface);
+static int ati_remote2_post_reset(struct usb_interface *interface);
static struct usb_driver ati_remote2_driver = {
.name = "ati_remote2",
@@ -147,6 +214,9 @@ static struct usb_driver ati_remote2_driver = {
.id_table = ati_remote2_id_table,
.suspend = ati_remote2_suspend,
.resume = ati_remote2_resume,
+ .reset_resume = ati_remote2_reset_resume,
+ .pre_reset = ati_remote2_pre_reset,
+ .post_reset = ati_remote2_post_reset,
.supports_autosuspend = 1,
};
@@ -238,7 +308,7 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
channel = data[0] >> 4;
- if (!((1 << channel) & channel_mask))
+ if (!((1 << channel) & ar2->channel_mask))
return;
mode = data[0] & 0x0F;
@@ -250,7 +320,7 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
return;
}
- if (!((1 << mode) & mode_mask))
+ if (!((1 << mode) & ar2->mode_mask))
return;
input_event(idev, EV_REL, REL_X, (s8) data[1]);
@@ -277,7 +347,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
channel = data[0] >> 4;
- if (!((1 << channel) & channel_mask))
+ if (!((1 << channel) & ar2->channel_mask))
return;
mode = data[0] & 0x0F;
@@ -305,7 +375,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
ar2->mode = mode;
}
- if (!((1 << mode) & mode_mask))
+ if (!((1 << mode) & ar2->mode_mask))
return;
index = ati_remote2_lookup(hw_code);
@@ -410,7 +480,7 @@ static int ati_remote2_getkeycode(struct input_dev *idev,
int index, mode;
mode = scancode >> 8;
- if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))
+ if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
return -EINVAL;
index = ati_remote2_lookup(scancode & 0xFF);
@@ -427,7 +497,7 @@ static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keyc
int index, mode, old_keycode;
mode = scancode >> 8;
- if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))
+ if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
return -EINVAL;
index = ati_remote2_lookup(scancode & 0xFF);
@@ -550,7 +620,7 @@ static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2)
}
}
-static int ati_remote2_setup(struct ati_remote2 *ar2)
+static int ati_remote2_setup(struct ati_remote2 *ar2, unsigned int ch_mask)
{
int r, i, channel;
@@ -565,8 +635,8 @@ static int ati_remote2_setup(struct ati_remote2 *ar2)
channel = 0;
for (i = 0; i < 16; i++) {
- if ((1 << i) & channel_mask) {
- if (!(~(1 << i) & 0xFFFF & channel_mask))
+ if ((1 << i) & ch_mask) {
+ if (!(~(1 << i) & ch_mask))
channel = i + 1;
break;
}
@@ -585,6 +655,99 @@ static int ati_remote2_setup(struct ati_remote2 *ar2)
return 0;
}
+static ssize_t ati_remote2_show_channel_mask(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_device *udev = to_usb_device(dev);
+ struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+ struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+
+ return sprintf(buf, "0x%04x\n", ar2->channel_mask);
+}
+
+static ssize_t ati_remote2_store_channel_mask(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_device *udev = to_usb_device(dev);
+ struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+ struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+ unsigned long mask;
+ int r;
+
+ if (strict_strtoul(buf, 0, &mask))
+ return -EINVAL;
+
+ if (mask & ~ATI_REMOTE2_MAX_CHANNEL_MASK)
+ return -EINVAL;
+
+ r = usb_autopm_get_interface(ar2->intf[0]);
+ if (r) {
+ dev_err(&ar2->intf[0]->dev,
+ "%s(): usb_autopm_get_interface() = %d\n", __func__, r);
+ return r;
+ }
+
+ mutex_lock(&ati_remote2_mutex);
+
+ if (mask != ar2->channel_mask && !ati_remote2_setup(ar2, mask))
+ ar2->channel_mask = mask;
+
+ mutex_unlock(&ati_remote2_mutex);
+
+ usb_autopm_put_interface(ar2->intf[0]);
+
+ return count;
+}
+
+static ssize_t ati_remote2_show_mode_mask(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_device *udev = to_usb_device(dev);
+ struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+ struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+
+ return sprintf(buf, "0x%02x\n", ar2->mode_mask);
+}
+
+static ssize_t ati_remote2_store_mode_mask(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_device *udev = to_usb_device(dev);
+ struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+ struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+ unsigned long mask;
+
+ if (strict_strtoul(buf, 0, &mask))
+ return -EINVAL;
+
+ if (mask & ~ATI_REMOTE2_MAX_MODE_MASK)
+ return -EINVAL;
+
+ ar2->mode_mask = mask;
+
+ return count;
+}
+
+static DEVICE_ATTR(channel_mask, 0644, ati_remote2_show_channel_mask,
+ ati_remote2_store_channel_mask);
+
+static DEVICE_ATTR(mode_mask, 0644, ati_remote2_show_mode_mask,
+ ati_remote2_store_mode_mask);
+
+static struct attribute *ati_remote2_attrs[] = {
+ &dev_attr_channel_mask.attr,
+ &dev_attr_mode_mask.attr,
+ NULL,
+};
+
+static struct attribute_group ati_remote2_attr_group = {
+ .attrs = ati_remote2_attrs,
+};
+
static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(interface);
@@ -615,7 +778,10 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
if (r)
goto fail2;
- r = ati_remote2_setup(ar2);
+ ar2->channel_mask = channel_mask;
+ ar2->mode_mask = mode_mask;
+
+ r = ati_remote2_setup(ar2, ar2->channel_mask);
if (r)
goto fail2;
@@ -624,19 +790,24 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name));