aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/input/misc
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/input/misc')
-rw-r--r--drivers/input/misc/88pm860x_onkey.c156
-rw-r--r--drivers/input/misc/Kconfig23
-rw-r--r--drivers/input/misc/Makefile2
-rw-r--r--drivers/input/misc/apanel.c2
-rw-r--r--drivers/input/misc/ati_remote.c16
-rw-r--r--drivers/input/misc/ati_remote2.c15
-rw-r--r--drivers/input/misc/atlas_btns.c2
-rw-r--r--drivers/input/misc/bfin_rotary.c3
-rw-r--r--drivers/input/misc/cobalt_btns.c1
-rw-r--r--drivers/input/misc/dm355evm_keys.c151
-rw-r--r--drivers/input/misc/hp_sdc_rtc.c2
-rw-r--r--drivers/input/misc/pcap_keys.c1
-rw-r--r--drivers/input/misc/pcf50633-input.c8
-rw-r--r--drivers/input/misc/pcspkr.c2
-rw-r--r--drivers/input/misc/powermate.c2
-rw-r--r--drivers/input/misc/rotary_encoder.c15
-rw-r--r--drivers/input/misc/sgi_btns.c1
-rw-r--r--drivers/input/misc/sparcspkr.c1
-rw-r--r--drivers/input/misc/twl4030-pwrbutton.c18
-rw-r--r--drivers/input/misc/twl4030-vibra.c298
-rw-r--r--drivers/input/misc/uinput.c4
-rw-r--r--drivers/input/misc/winbond-cir.c228
-rw-r--r--drivers/input/misc/wistron_btns.c259
-rw-r--r--drivers/input/misc/wm831x-on.c10
-rw-r--r--drivers/input/misc/yealink.h2
25 files changed, 791 insertions, 431 deletions
diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c
new file mode 100644
index 000000000000..40dabd8487b5
--- /dev/null
+++ b/drivers/input/misc/88pm860x_onkey.c
@@ -0,0 +1,156 @@
1/*
2 * 88pm860x_onkey.c - Marvell 88PM860x ONKEY driver
3 *
4 * Copyright (C) 2009-2010 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This file is subject to the terms and conditions of the GNU General
8 * Public License. See the file "COPYING" in the main directory of this
9 * archive for more details.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/platform_device.h>
24#include <linux/i2c.h>
25#include <linux/input.h>
26#include <linux/interrupt.h>
27#include <linux/mfd/88pm860x.h>
28#include <linux/slab.h>
29
30#define PM8607_WAKEUP 0x0b
31
32#define LONG_ONKEY_EN (1 << 1)
33#define ONKEY_STATUS (1 << 0)
34
35struct pm860x_onkey_info {
36 struct input_dev *idev;
37 struct pm860x_chip *chip;
38 struct i2c_client *i2c;
39 struct device *dev;
40 int irq;
41};
42
43/* 88PM860x gives us an interrupt when ONKEY is held */
44static irqreturn_t pm860x_onkey_handler(int irq, void *data)
45{
46 struct pm860x_onkey_info *info = data;
47 int ret;
48
49 ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2);
50 ret &= ONKEY_STATUS;
51 input_report_key(info->idev, KEY_POWER, ret);
52 input_sync(info->idev);
53
54 /* Enable 8-second long onkey detection */
55 pm860x_set_bits(info->i2c, PM8607_WAKEUP, 3, LONG_ONKEY_EN);
56 return IRQ_HANDLED;
57}
58
59static int __devinit pm860x_onkey_probe(struct platform_device *pdev)
60{
61 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
62 struct pm860x_onkey_info *info;
63 int irq, ret;
64
65 irq = platform_get_irq(pdev, 0);
66 if (irq < 0) {
67 dev_err(&pdev->dev, "No IRQ resource!\n");
68 return -EINVAL;
69 }
70
71 info = kzalloc(sizeof(struct pm860x_onkey_info), GFP_KERNEL);
72 if (!info)
73 return -ENOMEM;
74 info->chip = chip;
75 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
76 info->dev = &pdev->dev;
77 info->irq = irq + chip->irq_base;
78
79 info->idev = input_allocate_device();
80 if (!info->idev) {
81 dev_err(chip->dev, "Failed to allocate input dev\n");
82 ret = -ENOMEM;
83 goto out;
84 }
85
86 info->idev->name = "88pm860x_on";
87 info->idev->phys = "88pm860x_on/input0";
88 info->idev->id.bustype = BUS_I2C;
89 info->idev->dev.parent = &pdev->dev;
90 info->irq = irq;
91 info->idev->evbit[0] = BIT_MASK(EV_KEY);
92 info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
93
94 ret = input_register_device(info->idev);
95 if (ret) {
96 dev_err(chip->dev, "Can't register input device: %d\n", ret);
97 goto out_reg;
98 }
99
100 ret = request_threaded_irq(info->irq, NULL, pm860x_onkey_handler,
101 IRQF_ONESHOT, "onkey", info);
102 if (ret < 0) {
103 dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
104 info->irq, ret);
105 goto out_irq;
106 }
107
108 platform_set_drvdata(pdev, info);
109 return 0;
110
111out_irq:
112 input_unregister_device(info->idev);
113 kfree(info);
114 return ret;
115
116out_reg:
117 input_free_device(info->idev);
118out:
119 kfree(info);
120 return ret;
121}
122
123static int __devexit pm860x_onkey_remove(struct platform_device *pdev)
124{
125 struct pm860x_onkey_info *info = platform_get_drvdata(pdev);
126
127 free_irq(info->irq, info);
128 input_unregister_device(info->idev);
129 kfree(info);
130 return 0;
131}
132
133static struct platform_driver pm860x_onkey_driver = {
134 .driver = {
135 .name = "88pm860x-onkey",
136 .owner = THIS_MODULE,
137 },
138 .probe = pm860x_onkey_probe,
139 .remove = __devexit_p(pm860x_onkey_remove),
140};
141
142static int __init pm860x_onkey_init(void)
143{
144 return platform_driver_register(&pm860x_onkey_driver);
145}
146module_init(pm860x_onkey_init);
147
148static void __exit pm860x_onkey_exit(void)
149{
150 platform_driver_unregister(&pm860x_onkey_driver);
151}
152module_exit(pm860x_onkey_exit);
153
154MODULE_DESCRIPTION("Marvell 88PM860x ONKEY driver");
155MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
156MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index a9bb2544b2de..23140a3bb8e0 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -12,6 +12,16 @@ menuconfig INPUT_MISC
12 12
13if INPUT_MISC 13if INPUT_MISC
14 14
15config INPUT_88PM860X_ONKEY
16 tristate "88PM860x ONKEY support"
17 depends on MFD_88PM860X
18 help
19 Support the ONKEY of Marvell 88PM860x PMICs as an input device
20 reporting power button status.
21
22 To compile this driver as a module, choose M here: the module
23 will be called 88pm860x_onkey.
24
15config INPUT_PCSPKR 25config INPUT_PCSPKR
16 tristate "PC Speaker support" 26 tristate "PC Speaker support"
17 depends on PCSPKR_PLATFORM 27 depends on PCSPKR_PLATFORM
@@ -80,6 +90,7 @@ config INPUT_WISTRON_BTNS
80 tristate "x86 Wistron laptop button interface" 90 tristate "x86 Wistron laptop button interface"
81 depends on X86 && !X86_64 91 depends on X86 && !X86_64
82 select INPUT_POLLDEV 92 select INPUT_POLLDEV
93 select INPUT_SPARSEKMAP
83 select NEW_LEDS 94 select NEW_LEDS
84 select LEDS_CLASS 95 select LEDS_CLASS
85 select CHECK_SIGNATURE 96 select CHECK_SIGNATURE
@@ -203,6 +214,17 @@ config INPUT_TWL4030_PWRBUTTON
203 To compile this driver as a module, choose M here. The module will 214 To compile this driver as a module, choose M here. The module will
204 be called twl4030_pwrbutton. 215 be called twl4030_pwrbutton.
205 216
217config INPUT_TWL4030_VIBRA
218 tristate "Support for TWL4030 Vibrator"
219 depends on TWL4030_CORE
220 select TWL4030_CODEC
221 select INPUT_FF_MEMLESS
222 help
223 This option enables support for TWL4030 Vibrator Driver.
224
225 To compile this driver as a module, choose M here. The module will
226 be called twl4030_vibra.
227
206config INPUT_UINPUT 228config INPUT_UINPUT
207 tristate "User level driver support" 229 tristate "User level driver support"
208 help 230 help
@@ -281,6 +303,7 @@ config INPUT_RB532_BUTTON
281config INPUT_DM355EVM 303config INPUT_DM355EVM
282 tristate "TI DaVinci DM355 EVM Keypad and IR Remote" 304 tristate "TI DaVinci DM355 EVM Keypad and IR Remote"
283 depends on MFD_DM355EVM_MSP 305 depends on MFD_DM355EVM_MSP
306 select INPUT_SPARSEKMAP
284 help 307 help
285 Supports the pushbuttons and IR remote used with 308 Supports the pushbuttons and IR remote used with
286 the DM355 EVM board. 309 the DM355 EVM board.
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index a8b84854fb7b..7e95a5d474dc 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -4,6 +4,7 @@
4 4
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o
7obj-$(CONFIG_INPUT_APANEL) += apanel.o 8obj-$(CONFIG_INPUT_APANEL) += apanel.o
8obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o 9obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o
9obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o 10obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
@@ -25,6 +26,7 @@ obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o
25obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o 26obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
26obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o 27obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
27obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o 28obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o
29obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o
28obj-$(CONFIG_INPUT_UINPUT) += uinput.o 30obj-$(CONFIG_INPUT_UINPUT) += uinput.o
29obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o 31obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o
30obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o 32obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
diff --git a/drivers/input/misc/apanel.c b/drivers/input/misc/apanel.c
index 71b82434264d..a8d2b8db4e35 100644
--- a/drivers/input/misc/apanel.c
+++ b/drivers/input/misc/apanel.c
@@ -149,7 +149,7 @@ static void apanel_shutdown(struct i2c_client *client)
149 apanel_remove(client); 149 apanel_remove(client);
150} 150}
151 151
152static struct i2c_device_id apanel_id[] = { 152static const struct i2c_device_id apanel_id[] = {
153 { "fujitsu_apanel", 0 }, 153 { "fujitsu_apanel", 0 },
154 { } 154 { }
155}; 155};
diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c
index e290fde35e74..e8bbc619f6df 100644
--- a/drivers/input/misc/ati_remote.c
+++ b/drivers/input/misc/ati_remote.c
@@ -98,10 +98,12 @@
98 * Module and Version Information, Module Parameters 98 * Module and Version Information, Module Parameters
99 */ 99 */
100 100
101#define ATI_REMOTE_VENDOR_ID 0x0bc7 101#define ATI_REMOTE_VENDOR_ID 0x0bc7
102#define ATI_REMOTE_PRODUCT_ID 0x004 102#define LOLA_REMOTE_PRODUCT_ID 0x0002
103#define LOLA_REMOTE_PRODUCT_ID 0x002 103#define LOLA2_REMOTE_PRODUCT_ID 0x0003
104#define MEDION_REMOTE_PRODUCT_ID 0x006 104#define ATI_REMOTE_PRODUCT_ID 0x0004
105#define NVIDIA_REMOTE_PRODUCT_ID 0x0005
106#define MEDION_REMOTE_PRODUCT_ID 0x0006
105 107
106#define DRIVER_VERSION "2.2.1" 108#define DRIVER_VERSION "2.2.1"
107#define DRIVER_AUTHOR "Torrey Hoffman <thoffman@arnor.net>" 109#define DRIVER_AUTHOR "Torrey Hoffman <thoffman@arnor.net>"
@@ -142,8 +144,10 @@ MODULE_PARM_DESC(repeat_delay, "Delay before sending repeats, default = 500 msec
142#define err(format, arg...) printk(KERN_ERR format , ## arg) 144#define err(format, arg...) printk(KERN_ERR format , ## arg)
143 145
144static struct usb_device_id ati_remote_table[] = { 146static struct usb_device_id ati_remote_table[] = {
145 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
146 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) }, 147 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) },
148 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA2_REMOTE_PRODUCT_ID) },
149 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
150 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, NVIDIA_REMOTE_PRODUCT_ID) },
147 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID) }, 151 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID) },
148 {} /* Terminating entry */ 152 {} /* Terminating entry */
149}; 153};
@@ -766,7 +770,7 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
766 ati_remote->interface = interface; 770 ati_remote->interface = interface;
767 771
768 usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys)); 772 usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys));
769 strlcpy(ati_remote->phys, "/input0", sizeof(ati_remote->phys)); 773 strlcat(ati_remote->phys, "/input0", sizeof(ati_remote->phys));
770 774
771 if (udev->manufacturer) 775 if (udev->manufacturer)
772 strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name)); 776 strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name));
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
index 0501f0e65157..2124b99378bb 100644
--- a/drivers/input/misc/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/usb/input.h> 12#include <linux/usb/input.h>
13#include <linux/slab.h>
13 14
14#define DRIVER_DESC "ATI/Philips USB RF remote driver" 15#define DRIVER_DESC "ATI/Philips USB RF remote driver"
15#define DRIVER_VERSION "0.3" 16#define DRIVER_VERSION "0.3"
@@ -474,10 +475,11 @@ static void ati_remote2_complete_key(struct urb *urb)
474} 475}
475 476
476static int ati_remote2_getkeycode(struct input_dev *idev, 477static int ati_remote2_getkeycode(struct input_dev *idev,
477 int scancode, int *keycode) 478 unsigned int scancode, unsigned int *keycode)
478{ 479{
479 struct ati_remote2 *ar2 = input_get_drvdata(idev); 480 struct ati_remote2 *ar2 = input_get_drvdata(idev);
480 int index, mode; 481 unsigned int mode;
482 int index;
481 483
482 mode = scancode >> 8; 484 mode = scancode >> 8;
483 if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) 485 if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
@@ -491,10 +493,12 @@ static int ati_remote2_getkeycode(struct input_dev *idev,
491 return 0; 493 return 0;
492} 494}
493 495
494static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keycode) 496static int ati_remote2_setkeycode(struct input_dev *idev,
497 unsigned int scancode, unsigned int keycode)
495{ 498{
496 struct ati_remote2 *ar2 = input_get_drvdata(idev); 499 struct ati_remote2 *ar2 = input_get_drvdata(idev);
497 int index, mode, old_keycode; 500 unsigned int mode, old_keycode;
501 int index;
498 502
499 mode = scancode >> 8; 503 mode = scancode >> 8;
500 if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) 504 if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
@@ -504,9 +508,6 @@ static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keyc
504 if (index < 0) 508 if (index < 0)
505 return -EINVAL; 509 return -EINVAL;
506 510
507 if (keycode < KEY_RESERVED || keycode > KEY_MAX)
508 return -EINVAL;
509
510 old_keycode = ar2->keycode[mode][index]; 511 old_keycode = ar2->keycode[mode][index];
511 ar2->keycode[mode][index] = keycode; 512 ar2->keycode[mode][index] = keycode;
512 __set_bit(keycode, idev->keybit); 513 __set_bit(keycode, idev->keybit);
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c
index 1b871917340a..dfaa9a045ed8 100644
--- a/drivers/input/misc/atlas_btns.c
+++ b/drivers/input/misc/atlas_btns.c
@@ -47,7 +47,7 @@ static acpi_status acpi_atlas_button_setup(acpi_handle region_handle,
47 47
48static acpi_status acpi_atlas_button_handler(u32 function, 48static acpi_status acpi_atlas_button_handler(u32 function,
49 acpi_physical_address address, 49 acpi_physical_address address,
50 u32 bit_width, acpi_integer *value, 50 u32 bit_width, u64 *value,
51 void *handler_context, void *region_context) 51 void *handler_context, void *region_context)
52{ 52{
53 acpi_status status; 53 acpi_status status;
diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c
index 690f3fafa03b..4f72bdd69410 100644
--- a/drivers/input/misc/bfin_rotary.c
+++ b/drivers/input/misc/bfin_rotary.c
@@ -13,6 +13,7 @@
13#include <linux/pm.h> 13#include <linux/pm.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/input.h> 15#include <linux/input.h>
16#include <linux/slab.h>
16 17
17#include <asm/portmux.h> 18#include <asm/portmux.h>
18#include <asm/bfin_rotary.h> 19#include <asm/bfin_rotary.h>
@@ -247,7 +248,7 @@ static int bfin_rotary_resume(struct device *dev)
247 return 0; 248 return 0;
248} 249}
249 250
250static struct dev_pm_ops bfin_rotary_pm_ops = { 251static const struct dev_pm_ops bfin_rotary_pm_ops = {
251 .suspend = bfin_rotary_suspend, 252 .suspend = bfin_rotary_suspend,
252 .resume = bfin_rotary_resume, 253 .resume = bfin_rotary_resume,
253}; 254};
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c
index ee73d7219c92..fd8407a29631 100644
--- a/drivers/input/misc/cobalt_btns.c
+++ b/drivers/input/misc/cobalt_btns.c
@@ -22,6 +22,7 @@
22#include <linux/ioport.h> 22#include <linux/ioport.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/slab.h>
25 26
26#define BUTTONS_POLL_INTERVAL 30 /* msec */ 27#define BUTTONS_POLL_INTERVAL 30 /* msec */
27#define BUTTONS_COUNT_THRESHOLD 3 28#define BUTTONS_COUNT_THRESHOLD 3
diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c
index f2b67dc81d80..19af682c24fb 100644
--- a/drivers/input/misc/dm355evm_keys.c
+++ b/drivers/input/misc/dm355evm_keys.c
@@ -10,7 +10,9 @@
10 */ 10 */
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/slab.h>
13#include <linux/input.h> 14#include <linux/input.h>
15#include <linux/input/sparse-keymap.h>
14#include <linux/platform_device.h> 16#include <linux/platform_device.h>
15#include <linux/interrupt.h> 17#include <linux/interrupt.h>
16 18
@@ -33,12 +35,8 @@ struct dm355evm_keys {
33 int irq; 35 int irq;
34}; 36};
35 37
36/* These initial keycodes can be remapped by dm355evm_setkeycode(). */ 38/* These initial keycodes can be remapped */
37static struct { 39static const struct key_entry dm355evm_keys[] = {
38 u16 event;
39 u16 keycode;
40} dm355evm_keys[] = {
41
42 /* 40 /*
43 * Pushbuttons on the EVM board ... note that the labels for these 41 * Pushbuttons on the EVM board ... note that the labels for these
44 * are SW10/SW11/etc on the PC board. The left/right orientation 42 * are SW10/SW11/etc on the PC board. The left/right orientation
@@ -47,11 +45,11 @@ static struct {
47 * is to the right. (That is, rotate the board counter-clockwise 45 * is to the right. (That is, rotate the board counter-clockwise
48 * by 90 degrees from the SW10/etc and "DM355 EVM" labels.) 46 * by 90 degrees from the SW10/etc and "DM355 EVM" labels.)
49 */ 47 */
50 { 0x00d8, KEY_OK, }, /* SW12 */ 48 { KE_KEY, 0x00d8, { KEY_OK } }, /* SW12 */
51 { 0x00b8, KEY_UP, }, /* SW13 */ 49 { KE_KEY, 0x00b8, { KEY_UP } }, /* SW13 */
52 { 0x00e8, KEY_DOWN, }, /* SW11 */ 50 { KE_KEY, 0x00e8, { KEY_DOWN } }, /* SW11 */
53 { 0x0078, KEY_LEFT, }, /* SW14 */ 51 { KE_KEY, 0x0078, { KEY_LEFT } }, /* SW14 */
54 { 0x00f0, KEY_RIGHT, }, /* SW10 */ 52 { KE_KEY, 0x00f0, { KEY_RIGHT } }, /* SW10 */
55 53
56 /* 54 /*
57 * IR buttons ... codes assigned to match the universal remote 55 * IR buttons ... codes assigned to match the universal remote
@@ -65,35 +63,35 @@ static struct {
65 * RC5 codes are 14 bits, with two start bits (0x3 prefix) 63 * RC5 codes are 14 bits, with two start bits (0x3 prefix)
66 * and a toggle bit (masked out below). 64 * and a toggle bit (masked out below).
67 */ 65 */
68 { 0x300c, KEY_POWER, }, /* NOTE: docs omit this */ 66 { KE_KEY, 0x300c, { KEY_POWER } }, /* NOTE: docs omit this */
69 { 0x3000, KEY_NUMERIC_0, }, 67 { KE_KEY, 0x3000, { KEY_NUMERIC_0 } },
70 { 0x3001, KEY_NUMERIC_1, }, 68 { KE_KEY, 0x3001, { KEY_NUMERIC_1 } },
71 { 0x3002, KEY_NUMERIC_2, }, 69 { KE_KEY, 0x3002, { KEY_NUMERIC_2 } },
72 { 0x3003, KEY_NUMERIC_3, }, 70 { KE_KEY, 0x3003, { KEY_NUMERIC_3 } },
73 { 0x3004, KEY_NUMERIC_4, }, 71 { KE_KEY, 0x3004, { KEY_NUMERIC_4 } },
74 { 0x3005, KEY_NUMERIC_5, }, 72 { KE_KEY, 0x3005, { KEY_NUMERIC_5 } },
75 { 0x3006, KEY_NUMERIC_6, }, 73 { KE_KEY, 0x3006, { KEY_NUMERIC_6 } },
76 { 0x3007, KEY_NUMERIC_7, }, 74 { KE_KEY, 0x3007, { KEY_NUMERIC_7 } },
77 { 0x3008, KEY_NUMERIC_8, }, 75 { KE_KEY, 0x3008, { KEY_NUMERIC_8 } },
78 { 0x3009, KEY_NUMERIC_9, }, 76 { KE_KEY, 0x3009, { KEY_NUMERIC_9 } },
79 { 0x3022, KEY_ENTER, }, 77 { KE_KEY, 0x3022, { KEY_ENTER } },
80 { 0x30ec, KEY_MODE, }, /* "tv/vcr/..." */ 78 { KE_KEY, 0x30ec, { KEY_MODE } }, /* "tv/vcr/..." */
81 { 0x300f, KEY_SELECT, }, /* "info" */ 79 { KE_KEY, 0x300f, { KEY_SELECT } }, /* "info" */
82 { 0x3020, KEY_CHANNELUP, }, /* "up" */ 80 { KE_KEY, 0x3020, { KEY_CHANNELUP } }, /* "up" */
83 { 0x302e, KEY_MENU, }, /* "in/out" */ 81 { KE_KEY, 0x302e, { KEY_MENU } }, /* "in/out" */
84 { 0x3011, KEY_VOLUMEDOWN, }, /* "left" */ 82 { KE_KEY, 0x3011, { KEY_VOLUMEDOWN } }, /* "left" */
85 { 0x300d, KEY_MUTE, }, /* "ok" */ 83 { KE_KEY, 0x300d, { KEY_MUTE } }, /* "ok" */
86 { 0x3010, KEY_VOLUMEUP, }, /* "right" */ 84 { KE_KEY, 0x3010, { KEY_VOLUMEUP } }, /* "right" */
87 { 0x301e, KEY_SUBTITLE, }, /* "cc" */ 85 { KE_KEY, 0x301e, { KEY_SUBTITLE } }, /* "cc" */
88 { 0x3021, KEY_CHANNELDOWN, }, /* "down" */ 86 { KE_KEY, 0x3021, { KEY_CHANNELDOWN } },/* "down" */
89 { 0x3022, KEY_PREVIOUS, }, 87 { KE_KEY, 0x3022, { KEY_PREVIOUS } },
90 { 0x3026, KEY_SLEEP, }, 88 { KE_KEY, 0x3026, { KEY_SLEEP } },
91 { 0x3172, KEY_REWIND, }, /* NOTE: docs wrongly say 0x30ca */ 89 { KE_KEY, 0x3172, { KEY_REWIND } }, /* NOTE: docs wrongly say 0x30ca */
92 { 0x3175, KEY_PLAY, }, 90 { KE_KEY, 0x3175, { KEY_PLAY } },
93 { 0x3174, KEY_FASTFORWARD, }, 91 { KE_KEY, 0x3174, { KEY_FASTFORWARD } },
94 { 0x3177, KEY_RECORD, }, 92 { KE_KEY, 0x3177, { KEY_RECORD } },
95 { 0x3176, KEY_STOP, }, 93 { KE_KEY, 0x3176, { KEY_STOP } },
96 { 0x3169, KEY_PAUSE, }, 94 { KE_KEY, 0x3169, { KEY_PAUSE } },
97}; 95};
98 96
99/* 97/*
@@ -105,19 +103,18 @@ static struct {
105 */ 103 */
106static irqreturn_t dm355evm_keys_irq(int irq, void *_keys) 104static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
107{ 105{
108 struct dm355evm_keys *keys = _keys; 106 static u16 last_event;
109 int status; 107 struct dm355evm_keys *keys = _keys;
108 const struct key_entry *ke;
109 unsigned int keycode;
110 int status;
111 u16 event;
110 112
111 /* For simplicity we ignore INPUT_COUNT and just read 113 /* For simplicity we ignore INPUT_COUNT and just read
112 * events until we get the "queue empty" indicator. 114 * events until we get the "queue empty" indicator.
113 * Reading INPUT_LOW decrements the count. 115 * Reading INPUT_LOW decrements the count.
114 */ 116 */
115 for (;;) { 117 for (;;) {
116 static u16 last_event;
117 u16 event;
118 int keycode;
119 int i;
120
121 status = dm355evm_msp_read(DM355EVM_MSP_INPUT_HIGH); 118 status = dm355evm_msp_read(DM355EVM_MSP_INPUT_HIGH);
122 if (status < 0) { 119 if (status < 0) {
123 dev_dbg(keys->dev, "input high err %d\n", 120 dev_dbg(keys->dev, "input high err %d\n",
@@ -156,14 +153,9 @@ static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
156 /* ignore the RC5 toggle bit */ 153 /* ignore the RC5 toggle bit */
157 event &= ~0x0800; 154 event &= ~0x0800;
158 155
159 /* find the key, or leave it as unknown */ 156 /* find the key, or report it as unknown */
160 keycode = KEY_UNKNOWN; 157 ke = sparse_keymap_entry_from_scancode(keys->input, event);
161 for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) { 158 keycode = ke ? ke->keycode : KEY_UNKNOWN;
162 if (dm355evm_keys[i].event != event)
163 continue;
164 keycode = dm355evm_keys[i].keycode;
165 break;
166 }
167 dev_dbg(keys->dev, 159 dev_dbg(keys->dev,
168 "input event 0x%04x--> keycode %d\n", 160 "input event 0x%04x--> keycode %d\n",
169 event, keycode); 161 event, keycode);
@@ -174,36 +166,8 @@ static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
174 input_report_key(keys->input, keycode, 0); 166 input_report_key(keys->input, keycode, 0);
175 input_sync(keys->input); 167 input_sync(keys->input);
176 } 168 }
177 return IRQ_HANDLED;
178}
179 169
180static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode) 170 return IRQ_HANDLED;
181{
182 u16 old_keycode;
183 unsigned i;
184
185 if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys))
186 return -EINVAL;
187
188 old_keycode = dm355evm_keys[index].keycode;
189 dm355evm_keys[index].keycode = keycode;
190 set_bit(keycode, dev->keybit);
191
192 for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) {
193 if (dm355evm_keys[index].keycode == old_keycode)
194 goto done;
195 }
196 clear_bit(old_keycode, dev->keybit);
197done:
198 return 0;
199}
200
201static int dm355evm_getkeycode(struct input_dev *dev, int index, int *keycode)
202{
203 if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys))
204 return -EINVAL;
205
206 return dm355evm_keys[index].keycode;
207} 171}
208 172
209/*----------------------------------------------------------------------*/ 173/*----------------------------------------------------------------------*/
@@ -213,7 +177,6 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev)
213 struct dm355evm_keys *keys; 177 struct dm355evm_keys *keys;
214 struct input_dev *input; 178 struct input_dev *input;
215 int status; 179 int status;
216 int i;
217 180
218 /* allocate instance struct and input dev */ 181 /* allocate instance struct and input dev */
219 keys = kzalloc(sizeof *keys, GFP_KERNEL); 182 keys = kzalloc(sizeof *keys, GFP_KERNEL);
@@ -242,31 +205,30 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev)
242 input->id.product = 0x0355; 205 input->id.product = 0x0355;
243 input->id.version = dm355evm_msp_read(DM355EVM_MSP_FIRMREV); 206 input->id.version = dm355evm_msp_read(DM355EVM_MSP_FIRMREV);
244 207
245 input->evbit[0] = BIT(EV_KEY); 208 status = sparse_keymap_setup(input, dm355evm_keys, NULL);
246 for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) 209 if (status)
247 __set_bit(dm355evm_keys[i].keycode, input->keybit); 210 goto fail1;
248
249 input->setkeycode = dm355evm_setkeycode;
250 input->getkeycode = dm355evm_getkeycode;
251 211
252 /* REVISIT: flush the event queue? */ 212 /* REVISIT: flush the event queue? */
253 213
254 status = request_threaded_irq(keys->irq, NULL, dm355evm_keys_irq, 214 status = request_threaded_irq(keys->irq, NULL, dm355evm_keys_irq,
255 IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), keys); 215 IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), keys);
256 if (status < 0) 216 if (status < 0)
257 goto fail1; 217 goto fail2;
258 218
259 /* register */ 219 /* register */
260 status = input_register_device(input); 220 status = input_register_device(input);
261 if (status < 0) 221 if (status < 0)
262 goto fail2; 222 goto fail3;
263 223
264 platform_set_drvdata(pdev, keys); 224 platform_set_drvdata(pdev, keys);
265 225
266 return 0; 226 return 0;
267 227
268fail2: 228fail3:
269 free_irq(keys->irq, keys); 229 free_irq(keys->irq, keys);
230fail2:
231 sparse_keymap_free(input);
270fail1: 232fail1:
271 input_free_device(input); 233 input_free_device(input);
272 kfree(keys); 234 kfree(keys);
@@ -280,6 +242,7 @@ static int __devexit dm355evm_keys_remove(struct platform_device *pdev)
280 struct dm355evm_keys *keys = platform_get_drvdata(pdev); 242 struct dm355evm_keys *keys = platform_get_drvdata(pdev);
281 243
282 free_irq(keys->irq, keys); 244 free_irq(keys->irq, keys);
245 sparse_keymap_free(keys->input);
283 input_unregister_device(keys->input); 246 input_unregister_device(keys->input);
284 kfree(keys); 247 kfree(keys);
285 248
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c
index ea821b546969..ad730e15afc0 100644
--- a/drivers/input/misc/hp_sdc_rtc.c
+++ b/drivers/input/misc/hp_sdc_rtc.c
@@ -35,7 +35,6 @@
35 35
36#include <linux/hp_sdc.h> 36#include <linux/hp_sdc.h>
37#include <linux/errno.h> 37#include <linux/errno.h>
38#include <linux/smp_lock.h>
39#include <linux/types.h> 38#include <linux/types.h>
40#include <linux/init.h> 39#include <linux/init.h>
41#include <linux/module.h> 40#include <linux/module.h>
@@ -409,7 +408,6 @@ static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait)
409 408
410static int hp_sdc_rtc_open(struct inode *inode, struct file *file) 409static int hp_sdc_rtc_open(struct inode *inode, struct file *file)
411{ 410{
412 cycle_kernel_lock();
413 return 0; 411 return 0;
414} 412}
415 413
diff --git a/drivers/input/misc/pcap_keys.c b/drivers/input/misc/pcap_keys.c
index 7ea969347ca9..99335c286250 100644
--- a/drivers/input/misc/pcap_keys.c
+++ b/drivers/input/misc/pcap_keys.c
@@ -17,6 +17,7 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/input.h> 18#include <linux/input.h>
19#include <linux/mfd/ezx-pcap.h> 19#include <linux/mfd/ezx-pcap.h>
20#include <linux/slab.h>
20 21
21struct pcap_keys { 22struct pcap_keys {
22 struct pcap_chip *pcap; 23 struct pcap_chip *pcap;
diff --git a/drivers/input/misc/pcf50633-input.c b/drivers/input/misc/pcf50633-input.c
index 039dcb00ebd9..95562735728d 100644
--- a/drivers/input/misc/pcf50633-input.c
+++ b/drivers/input/misc/pcf50633-input.c
@@ -20,6 +20,7 @@
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/input.h> 22#include <linux/input.h>
23#include <linux/slab.h>
23 24
24#include <linux/mfd/pcf50633/core.h> 25#include <linux/mfd/pcf50633/core.h>
25 26
@@ -55,7 +56,6 @@ pcf50633_input_irq(int irq, void *data)
55static int __devinit pcf50633_input_probe(struct platform_device *pdev) 56static int __devinit pcf50633_input_probe(struct platform_device *pdev)
56{ 57{
57 struct pcf50633_input *input; 58 struct pcf50633_input *input;
58 struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
59 struct input_dev *input_dev; 59 struct input_dev *input_dev;
60 int ret; 60 int ret;
61 61
@@ -71,7 +71,7 @@ static int __devinit pcf50633_input_probe(struct platform_device *pdev)
71 } 71 }
72 72
73 platform_set_drvdata(pdev, input); 73 platform_set_drvdata(pdev, input);
74 input->pcf = pdata->pcf; 74 input->pcf = dev_to_pcf50633(pdev->dev.parent);
75 input->input_dev = input_dev; 75 input->input_dev = input_dev;
76 76
77 input_dev->name = "PCF50633 PMU events"; 77 input_dev->name = "PCF50633 PMU events";
@@ -85,9 +85,9 @@ static int __devinit pcf50633_input_probe(struct platform_device *pdev)
85 kfree(input); 85 kfree(input);
86 return ret; 86 return ret;
87 } 87 }
88 pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYR, 88 pcf50633_register_irq(input->pcf, PCF50633_IRQ_ONKEYR,
89 pcf50633_input_irq, input); 89 pcf50633_input_irq, input);
90 pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYF, 90 pcf50633_register_irq(input->pcf, PCF50633_IRQ_ONKEYF,
91 pcf50633_input_irq, input); 91 pcf50633_input_irq, input);
92 92
93 return 0; 93 return 0;
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
index 21cb755a54fb..ea4e1fd12651 100644
--- a/drivers/input/misc/pcspkr.c
+++ b/drivers/input/misc/pcspkr.c
@@ -127,7 +127,7 @@ static void pcspkr_shutdown(struct platform_device *dev)
127 pcspkr_event(NULL, EV_SND, SND_BELL, 0); 127 pcspkr_event(NULL, EV_SND, SND_BELL, 0);
128} 128}
129 129
130static struct dev_pm_ops pcspkr_pm_ops = { 130static const struct dev_pm_ops pcspkr_pm_ops = {
131 .suspend = pcspkr_suspend, 131 .suspend = pcspkr_suspend,
132}; 132};
133 133
diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c
index a53c4885fbad..668913d12044 100644
--- a/drivers/input/misc/powermate.c
+++ b/drivers/input/misc/powermate.c
@@ -338,7 +338,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
338 pm->input = input_dev; 338 pm->input = input_dev;
339 339
340 usb_make_path(udev, pm->phys, sizeof(pm->phys)); 340 usb_make_path(udev, pm->phys, sizeof(pm->phys));
341 strlcpy(pm->phys, "/input0", sizeof(pm->phys)); 341 strlcat(pm->phys, "/input0", sizeof(pm->phys));
342 342
343 spin_lock_init(&pm->lock); 343 spin_lock_init(&pm->lock);
344 344
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
index 3b9f588fc747..1f8e0108962e 100644
--- a/drivers/input/misc/rotary_encoder.c
+++ b/drivers/input/misc/rotary_encoder.c
@@ -22,6 +22,7 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/gpio.h> 23#include <linux/gpio.h>
24#include <linux/rotary_encoder.h> 24#include <linux/rotary_encoder.h>
25#include <linux/slab.h>
25 26
26#define DRV_NAME "rotary-encoder" 27#define DRV_NAME "rotary-encoder"
27 28
@@ -152,6 +153,13 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
152 goto exit_unregister_input; 153 goto exit_unregister_input;
153 } 154 }
154 155
156 err = gpio_direction_input(pdata->gpio_a);
157 if (err) {
158 dev_err(&pdev->dev, "unable to set GPIO %d for input\n",
159 pdata->gpio_a);
160 goto exit_unregister_input;
161 }
162
155 err = gpio_request(pdata->gpio_b, DRV_NAME); 163 err = gpio_request(pdata->gpio_b, DRV_NAME);
156 if (err) { 164 if (err) {
157 dev_err(&pdev->dev, "unable to request GPIO %d\n", 165 dev_err(&pdev->dev, "unable to request GPIO %d\n",
@@ -159,6 +167,13 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
159 goto exit_free_gpio_a; 167 goto exit_free_gpio_a;
160 } 168 }
161 169
170 err = gpio_direction_input(pdata->gpio_b);
171 if (err) {
172 dev_err(&pdev->dev, "unable to set GPIO %d for input\n",
173 pdata->gpio_b);
174 goto exit_free_gpio_a;
175 }
176
162 /* request the IRQs */ 177 /* request the IRQs */
163 err = request_irq(encoder->irq_a, &rotary_encoder_irq, 178 err = request_irq(encoder->irq_a, &rotary_encoder_irq,
164 IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, 179 IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
diff --git a/drivers/input/misc/sgi_btns.c b/drivers/input/misc/sgi_btns.c
index be3a15f5b25d..1a80c0dab83b 100644
--- a/drivers/input/misc/sgi_btns.c
+++ b/drivers/input/misc/sgi_btns.c
@@ -22,6 +22,7 @@
22#include <linux/ioport.h> 22#include <linux/ioport.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/slab.h>
25 26
26#ifdef CONFIG_SGI_IP22 27#ifdef CONFIG_SGI_IP22
27#include <asm/sgi/ioc.h> 28#include <asm/sgi/ioc.h>
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index b064419b90a2..0d45422f8095 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -9,6 +9,7 @@
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/input.h> 10#include <linux/input.h>
11#include <linux/of_device.h> 11#include <linux/of_device.h>
12#include <linux/slab.h>
12 13
13#include <asm/io.h> 14#include <asm/io.h>
14 15
diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c
index f5fc9974a111..e9069b87fde2 100644
--- a/drivers/input/misc/twl4030-pwrbutton.c
+++ b/drivers/input/misc/twl4030-pwrbutton.c
@@ -27,7 +27,7 @@
27#include <linux/input.h> 27#include <linux/input.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/platform_device.h> 29#include <linux/platform_device.h>
30#include <linux/i2c/twl4030.h> 30#include <linux/i2c/twl.h>
31 31
32#define PWR_PWRON_IRQ (1 << 0) 32#define PWR_PWRON_IRQ (1 << 0)
33 33
@@ -39,18 +39,8 @@ static irqreturn_t powerbutton_irq(int irq, void *_pwr)
39 int err; 39 int err;
40 u8 value; 40 u8 value;
41 41
42#ifdef CONFIG_LOCKDEP 42 err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &value,
43 /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which 43 STS_HW_CONDITIONS);
44 * we don't want and can't tolerate since this is a threaded
45 * IRQ and can sleep due to the i2c reads it has to issue.
46 * Although it might be friendlier not to borrow this thread
47 * context...
48 */
49 local_irq_enable();
50#endif
51
52 err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &value,
53 STS_HW_CONDITIONS);
54 if (!err) { 44 if (!err) {
55 input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ); 45 input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ);
56 input_sync(pwr); 46 input_sync(pwr);
@@ -80,7 +70,7 @@ static int __devinit twl4030_pwrbutton_probe(struct platform_device *pdev)
80 pwr->phys = "twl4030_pwrbutton/input0"; 70 pwr->phys = "twl4030_pwrbutton/input0";
81 pwr->dev.parent = &pdev->dev; 71 pwr->dev.parent = &pdev->dev;
82 72
83 err = request_irq(irq, powerbutton_irq, 73 err = request_threaded_irq(irq, NULL, powerbutton_irq,
84 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 74 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
85 "twl4030_pwrbutton", pwr); 75 "twl4030_pwrbutton", pwr);
86 if (err < 0) { 76 if (err < 0) {
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
new file mode 100644
index 000000000000..fee9eac8e04a
--- /dev/null
+++ b/drivers/input/misc/twl4030-vibra.c
@@ -0,0 +1,298 @@
1/*
2 * twl4030-vibra.c - TWL4030 Vibrator driver
3 *
4 * Copyright (C) 2008-2010 Nokia Corporation
5 *
6 * Written by Henrik Saari <henrik.saari@nokia.com>
7 * Updates by Felipe Balbi <felipe.balbi@nokia.com>
8 * Input by Jari Vanhala <ext-jari.vanhala@nokia.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26#include <linux/module.h>
27#include <linux/jiffies.h>
28#include <linux/platform_device.h>
29#include <linux/workqueue.h>
30#include <linux/i2c/twl.h>
31#include <linux/mfd/twl4030-codec.h>
32#include <linux/input.h>
33#include <linux/slab.h>
34
35/* MODULE ID2 */
36#define LEDEN 0x00
37
38/* ForceFeedback */
39#define EFFECT_DIR_180_DEG 0x8000 /* range is 0 - 0xFFFF */
40
41struct vibra_info {
42 struct device *dev;
43 struct input_dev *input_dev;
44
45 struct workqueue_struct *workqueue;
46 struct work_struct play_work;
47
48 bool enabled;
49 int speed;
50 int direction;
51
52 bool coexist;
53};
54
55static void vibra_disable_leds(void)
56{
57 u8 reg;
58
59 /* Disable LEDA & LEDB, cannot be used with vibra (PWM) */
60 twl_i2c_read_u8(TWL4030_MODULE_LED, &reg, LEDEN);
61 reg &= ~0x03;
62 twl_i2c_write_u8(TWL4030_MODULE_LED, LEDEN, reg);
63}
64
65/* Powers H-Bridge and enables audio clk */
66static void vibra_enable(struct vibra_info *info)
67{
68 u8 reg;
69
70 twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER);
71
72 /* turn H-Bridge on */
73 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
74 &reg, TWL4030_REG_VIBRA_CTL);
75 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
76 (reg | TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
77
78 twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL);
79
80 info->enabled = true;
81}
82
83static void vibra_disable(struct vibra_info *info)
84{
85 u8 reg;
86
87 /* Power down H-Bridge */
88 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
89 &reg, TWL4030_REG_VIBRA_CTL);
90 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
91 (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
92
93 twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
94 twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL);
95
96 info->enabled = false;
97}
98
99static void vibra_play_work(struct work_struct *work)
100{
101 struct vibra_info *info = container_of(work,
102 struct vibra_info, play_work);
103 int dir;
104 int pwm;
105 u8 reg;
106
107 dir = info->direction;
108 pwm = info->speed;
109
110 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
111 &reg, TWL4030_REG_VIBRA_CTL);
112 if (pwm && (!info->coexist || !(reg & TWL4030_VIBRA_SEL))) {
113
114 if (!info->enabled)
115 vibra_enable(info);
116
117 /* set vibra rotation direction */
118 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
119 &reg, TWL4030_REG_VIBRA_CTL);
120 reg = (dir) ? (reg | TWL4030_VIBRA_DIR) :
121 (reg & ~TWL4030_VIBRA_DIR);
122 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
123 reg, TWL4030_REG_VIBRA_CTL);
124
125 /* set PWM, 1 = max, 255 = min */
126 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
127 256 - pwm, TWL4030_REG_VIBRA_SET);
128 } else {
129 if (info->enabled)
130 vibra_disable(info);
131 }
132}
133
134/*** Input/ForceFeedback ***/
135
136static int vibra_play(struct input_dev *input, void *data,
137 struct ff_effect *effect)
138{
139 struct vibra_info *info = input_get_drvdata(input);
140
141 info->speed = effect->u.rumble.strong_magnitude >> 8;
142 if (!info->speed)
143 info->speed = effect->u.rumble.weak_magnitude >> 9;
144 info->direction = effect->direction < EFFECT_DIR_180_DEG ? 0 : 1;
145 queue_work(info->workqueue, &info->play_work);
146 return 0;
147}
148
149static int twl4030_vibra_open(struct input_dev *input)
150{
151 struct vibra_info *info = input_get_drvdata(input);
152
153 info->workqueue = create_singlethread_workqueue("vibra");
154 if (info->workqueue == NULL) {
155 dev_err(&input->dev, "couldn't create workqueue\n");
156 return -ENOMEM;
157 }
158 return 0;
159}
160
161static void twl4030_vibra_close(struct input_dev *input)
162{
163 struct vibra_info *info = input_get_drvdata(input);
164
165 cancel_work_sync(&info->play_work);
166 INIT_WORK(&info->play_work, vibra_play_work); /* cleanup */
167 destroy_workqueue(info->workqueue);
168 info->workqueue = NULL;
169
170 if (info->enabled)
171 vibra_disable(info);
172}
173
174/*** Module ***/
175#if CONFIG_PM
176static int twl4030_vibra_suspend(struct device *dev)
177{
178 struct platform_device *pdev = to_platform_device(dev);
179 struct vibra_info *info = platform_get_drvdata(pdev);
180
181 if (info->enabled)
182 vibra_disable(info);
183
184 return 0;
185}
186
187static int twl4030_vibra_resume(struct device *dev)
188{
189 vibra_disable_leds();
190 return 0;
191}
192
193static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
194 twl4030_vibra_suspend, twl4030_vibra_resume);
195#endif
196
197static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
198{
199 struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data;
200 struct vibra_info *info;
201 int ret;
202
203 if (!pdata) {
204 dev_dbg(&pdev->dev, "platform_data not available\n");
205 return -EINVAL;
206 }
207
208 info = kzalloc(sizeof(*info), GFP_KERNEL);
209 if (!info)
210 return -ENOMEM;
211
212 info->dev = &pdev->dev;
213 info->coexist = pdata->coexist;
214 INIT_WORK(&info->play_work, vibra_play_work);
215
216 info->input_dev = input_allocate_device();
217 if (info->input_dev == NULL) {
218 dev_err(&pdev->dev, "couldn't allocate input device\n");
219 ret = -ENOMEM;
220 goto err_kzalloc;
221 }
222
223 input_set_drvdata(info->input_dev, info);
224
225 info->input_dev->name = "twl4030:vibrator";
226 info->input_dev->id.version = 1;
227 info->input_dev->dev.parent = pdev->dev.parent;
228 info->input_dev->open = twl4030_vibra_open;
229 info->input_dev->close = twl4030_vibra_close;
230 __set_bit(FF_RUMBLE, info->input_dev->ffbit);
231
232 ret = input_ff_create_memless(info->input_dev, NULL, vibra_play);
233 if (ret < 0) {
234 dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n");
235 goto err_ialloc;
236 }
237
238 ret = input_register_device(info->input_dev);
239 if (ret < 0) {
240 dev_dbg(&pdev->dev, "couldn't register input device\n");
241 goto err_iff;
242 }
243
244 vibra_disable_leds();
245
246 platform_set_drvdata(pdev, info);
247 return 0;
248
249err_iff:
250 input_ff_destroy(info->input_dev);
251err_ialloc:
252 input_free_device(info->input_dev);
253err_kzalloc:
254 kfree(info);
255 return ret;
256}
257
258static int __devexit twl4030_vibra_remove(struct platform_device *pdev)
259{
260 struct vibra_info *info = platform_get_drvdata(pdev);
261
262 /* this also free ff-memless and calls close if needed */
263 input_unregister_device(info->input_dev);
264 kfree(info);
265 platform_set_drvdata(pdev, NULL);
266
267 return 0;
268}
269
270static struct platform_driver twl4030_vibra_driver = {
271 .probe = twl4030_vibra_probe,
272 .remove = __devexit_p(twl4030_vibra_remove),
273 .driver = {
274 .name = "twl4030_codec_vibra",
275 .owner = THIS_MODULE,
276#ifdef CONFIG_PM
277 .pm = &twl4030_vibra_pm_ops,
278#endif
279 },
280};
281
282static int __init twl4030_vibra_init(void)
283{
284 return platform_driver_register(&twl4030_vibra_driver);
285}
286module_init(twl4030_vibra_init);
287
288static void __exit twl4030_vibra_exit(void)
289{
290 platform_driver_unregister(&twl4030_vibra_driver);
291}
292module_exit(twl4030_vibra_exit);
293
294MODULE_ALIAS("platform:twl4030_codec_vibra");
295
296MODULE_DESCRIPTION("TWL4030 Vibra driver");
297MODULE_LICENSE("GPL");
298MODULE_AUTHOR("Nokia Corporation");
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index d3f57245420a..1477466076ad 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -34,7 +34,6 @@
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/smp_lock.h>
38#include <linux/fs.h> 37#include <linux/fs.h>
39#include <linux/miscdevice.h> 38#include <linux/miscdevice.h>
40#include <linux/uinput.h> 39#include <linux/uinput.h>
@@ -284,7 +283,6 @@ static int uinput_open(struct inode *inode, struct file *file)
284 if (!newdev) 283 if (!newdev)
285 return -ENOMEM; 284 return -ENOMEM;
286 285
287 lock_kernel();
288 mutex_init(&newdev->mutex); 286 mutex_init(&newdev->mutex);
289 spin_lock_init(&newdev->requests_lock); 287 spin_lock_init(&newdev->requests_lock);
290 init_waitqueue_head(&newdev->requests_waitq); 288 init_waitqueue_head(&newdev->requests_waitq);
@@ -292,7 +290,7 @@ static int uinput_open(struct inode *inode, struct file *file)
292 newdev->state = UIST_NEW_DEVICE; 290 newdev->state = UIST_NEW_DEVICE;
293 291
294 file->private_data = newdev; 292 file->private_data = newdev;
295 unlock_kernel(); 293 nonseekable_open(inode, file);
296 294
297 return 0; 295 return 0;
298} 296}
diff --git a/drivers/input/misc/winbond-cir.c b/drivers/input/misc/winbond-cir.c
index 33309fe44e20..64f1de7960c6 100644
--- a/drivers/input/misc/winbond-cir.c
+++ b/drivers/input/misc/winbond-cir.c
@@ -56,6 +56,7 @@
56#include <linux/io.h> 56#include <linux/io.h>
57#include <linux/bitrev.h> 57#include <linux/bitrev.h>
58#include <linux/bitops.h> 58#include <linux/bitops.h>
59#include <linux/slab.h>
59 60
60#define DRVNAME "winbond-cir" 61#define DRVNAME "winbond-cir"
61 62
@@ -385,26 +386,24 @@ wbcir_do_getkeycode(struct wbcir_data *data, u32 scancode)
385} 386}
386 387
387static int 388static int
388wbcir_getkeycode(struct input_dev *dev, int scancode, int *keycode) 389wbcir_getkeycode(struct input_dev *dev,
390 unsigned int scancode, unsigned int *keycode)
389{ 391{
390 struct wbcir_data *data = input_get_drvdata(dev); 392 struct wbcir_data *data = input_get_drvdata(dev);
391 393
392 *keycode = (int)wbcir_do_getkeycode(data, (u32)scancode); 394 *keycode = wbcir_do_getkeycode(data, scancode);
393 return 0; 395 return 0;
394} 396}
395 397
396static int 398static int
397wbcir_setkeycode(struct input_dev *dev, int sscancode, int keycode) 399wbcir_setkeycode(struct input_dev *dev,
400 unsigned int scancode, unsigned int keycode)
398{ 401{
399 struct wbcir_data *data = input_get_drvdata(dev); 402 struct wbcir_data *data = input_get_drvdata(dev);
400 struct wbcir_keyentry *keyentry; 403 struct wbcir_keyentry *keyentry;
401 struct wbcir_keyentry *new_keyentry; 404 struct wbcir_keyentry *new_keyentry;
402 unsigned long flags; 405 unsigned long flags;
403 unsigned int old_keycode = KEY_RESERVED; 406 unsigned int old_keycode = KEY_RESERVED;
404 u32 scancode = (u32)sscancode;
405
406 if (keycode < 0 || keycode > KEY_MAX)
407 return -EINVAL;
408 407
409 new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL); 408 new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL);
410 if (!new_keyentry) 409 if (!new_keyentry)
@@ -538,6 +537,7 @@ wbcir_reset_irdata(struct wbcir_data *data)
538 data->irdata_count = 0; 537 data->irdata_count = 0;
539 data->irdata_off = 0; 538 data->irdata_off = 0;
540 data->irdata_error = 0; 539 data->irdata_error = 0;
540 data->idle_count = 0;
541} 541}
542 542
543/* Adds one bit of irdata */ 543/* Adds one bit of irdata */
@@ -768,7 +768,7 @@ wbcir_parse_rc6(struct device *dev, struct wbcir_data *data)
768 return; 768 return;
769 } 769 }
770 770
771 dev_info(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X " 771 dev_dbg(dev, "IR-RC6 ad 0x%02X cm 0x%02X cu 0x%04X "
772 "toggle %u mode %u scan 0x%08X\n", 772 "toggle %u mode %u scan 0x%08X\n",
773 address, 773 address,
774 command, 774 command,
@@ -1006,7 +1006,6 @@ wbcir_irq_handler(int irqno, void *cookie)
1006 } 1006 }
1007 1007
1008 wbcir_reset_irdata(data); 1008 wbcir_reset_irdata(data);
1009 data->idle_count = 0;
1010 } 1009 }
1011 1010
1012out: 1011out:
@@ -1018,7 +1017,7 @@ out:
1018 1017
1019/***************************************************************************** 1018/*****************************************************************************
1020 * 1019 *
1021 * SUSPEND/RESUME FUNCTIONS 1020 * SETUP/INIT/SUSPEND/RESUME FUNCTIONS
1022 * 1021 *
1023 *****************************************************************************/ 1022 *****************************************************************************/
1024 1023
@@ -1197,7 +1196,16 @@ finish:
1197 } 1196 }
1198 1197
1199 /* Disable interrupts */ 1198 /* Disable interrupts */
1199 wbcir_select_bank(data, WBCIR_BANK_0);
1200 outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); 1200 outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
1201
1202 /*
1203 * ACPI will set the HW disable bit for SP3 which means that the
1204 * output signals are left in an undefined state which may cause
1205 * spurious interrupts which we need to ignore until the hardware
1206 * is reinitialized.
1207 */
1208 disable_irq(data->irq);
1201} 1209}
1202 1210
1203static int 1211static int
@@ -1207,37 +1215,15 @@ wbcir_suspend(struct pnp_dev *device, pm_message_t state)
1207 return 0; 1215 return 0;
1208} 1216}
1209 1217
1210static int
1211wbcir_resume(struct pnp_dev *device)
1212{
1213 struct wbcir_data *data = pnp_get_drvdata(device);
1214
1215 /* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */
1216 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07);
1217
1218 /* Clear CEIR_EN */
1219 wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01);
1220
1221 /* Enable interrupts */
1222 wbcir_reset_irdata(data);
1223 outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
1224
1225 return 0;
1226}
1227
1228
1229
1230/*****************************************************************************
1231 *
1232 * SETUP/INIT FUNCTIONS
1233 *
1234 *****************************************************************************/
1235
1236static void 1218static void
1237wbcir_cfg_ceir(struct wbcir_data *data) 1219wbcir_init_hw(struct wbcir_data *data)
1238{ 1220{
1239 u8 tmp; 1221 u8 tmp;
1240 1222
1223 /* Disable interrupts */
1224 wbcir_select_bank(data, WBCIR_BANK_0);
1225 outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
1226
1241 /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */ 1227 /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */
1242 tmp = protocol << 4; 1228 tmp = protocol << 4;
1243 if (invert) 1229 if (invert)
@@ -1264,6 +1250,93 @@ wbcir_cfg_ceir(struct wbcir_data *data)
1264 * set SP3_IRRX_SW to binary 01, helpfully not documented 1250 * set SP3_IRRX_SW to binary 01, helpfully not documented
1265 */ 1251 */
1266 outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS); 1252 outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS);
1253
1254 /* Enable extended mode */
1255 wbcir_select_bank(data, WBCIR_BANK_2);
1256 outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1);
1257
1258 /*
1259 * Configure baud generator, IR data will be sampled at
1260 * a bitrate of: (24Mhz * prescaler) / (divisor * 16).
1261 *
1262 * The ECIR registers include a flag to change the
1263 * 24Mhz clock freq to 48Mhz.
1264 *
1265 * It's not documented in the specs, but fifo levels
1266 * other than 16 seems to be unsupported.
1267 */
1268
1269 /* prescaler 1.0, tx/rx fifo lvl 16 */
1270 outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2);
1271
1272 /* Set baud divisor to generate one byte per bit/cell */
1273 switch (protocol) {
1274 case IR_PROTOCOL_RC5:
1275 outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL);
1276 break;
1277 case IR_PROTOCOL_RC6:
1278 outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL);
1279 break;
1280 case IR_PROTOCOL_NEC:
1281 outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL);
1282 break;
1283 }
1284 outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH);
1285
1286 /* Set CEIR mode */
1287 wbcir_select_bank(data, WBCIR_BANK_0);
1288 outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR);
1289 inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */
1290 inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */
1291
1292 /* Disable RX demod, run-length encoding/decoding, set freq span */
1293 wbcir_select_bank(data, WBCIR_BANK_7);
1294 outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG);
1295
1296 /* Disable timer */
1297 wbcir_select_bank(data, WBCIR_BANK_4);
1298 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1);
1299
1300 /* Enable MSR interrupt, Clear AUX_IRX */
1301 wbcir_select_bank(data, WBCIR_BANK_5);
1302 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2);
1303
1304 /* Disable CRC */
1305 wbcir_select_bank(data, WBCIR_BANK_6);
1306 outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3);
1307
1308 /* Set RX/TX (de)modulation freq, not really used */
1309 wbcir_select_bank(data, WBCIR_BANK_7);
1310 outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC);
1311 outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC);
1312
1313 /* Set invert and pin direction */
1314 if (invert)
1315 outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4);
1316 else
1317 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4);
1318
1319 /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */
1320 wbcir_select_bank(data, WBCIR_BANK_0);
1321 outb(0x97, data->sbase + WBCIR_REG_SP3_FCR);
1322
1323 /* Clear AUX status bits */
1324 outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
1325
1326 /* Enable interrupts */
1327 wbcir_reset_irdata(data);
1328 outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
1329}
1330
1331static int
1332wbcir_resume(struct pnp_dev *device)
1333{
1334 struct wbcir_data *data = pnp_get_drvdata(device);
1335
1336 wbcir_init_hw(data);
1337 enable_irq(data->irq);
1338
1339 return 0;
1267} 1340}
1268 1341
1269static int __devinit 1342static int __devinit
@@ -1393,86 +1466,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
1393 1466
1394 device_init_wakeup(&device->dev, 1); 1467 device_init_wakeup(&device->dev, 1);
1395 1468
1396 wbcir_cfg_ceir(data); 1469 wbcir_init_hw(data);
1397
1398 /* Disable interrupts */
1399 wbcir_select_bank(data, WBCIR_BANK_0);
1400 outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
1401
1402 /* Enable extended mode */
1403 wbcir_select_bank(data, WBCIR_BANK_2);
1404 outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1);
1405
1406 /*
1407 * Configure baud generator, IR data will be sampled at
1408 * a bitrate of: (24Mhz * prescaler) / (divisor * 16).
1409 *
1410 * The ECIR registers include a flag to change the
1411 * 24Mhz clock freq to 48Mhz.
1412 *
1413 * It's not documented in the specs, but fifo levels
1414 * other than 16 seems to be unsupported.
1415 */
1416
1417 /* prescaler 1.0, tx/rx fifo lvl 16 */
1418 outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2);
1419
1420 /* Set baud divisor to generate one byte per bit/cell */
1421 switch (protocol) {
1422 case IR_PROTOCOL_RC5:
1423 outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL);
1424 break;
1425 case IR_PROTOCOL_RC6:
1426 outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL);
1427 break;
1428 case IR_PROTOCOL_NEC:
1429 outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL);
1430 break;
1431 }
1432 outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH);
1433
1434 /* Set CEIR mode */
1435 wbcir_select_bank(data, WBCIR_BANK_0);
1436 outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR);
1437 inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */
1438 inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */
1439
1440 /* Disable RX demod, run-length encoding/decoding, set freq span */
1441 wbcir_select_bank(data, WBCIR_BANK_7);
1442 outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG);
1443
1444 /* Disable timer */
1445 wbcir_select_bank(data, WBCIR_BANK_4);
1446 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1);
1447
1448 /* Enable MSR interrupt, Clear AUX_IRX */
1449 wbcir_select_bank(data, WBCIR_BANK_5);
1450 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2);
1451
1452 /* Disable CRC */
1453 wbcir_select_bank(data, WBCIR_BANK_6);
1454 outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3);
1455
1456 /* Set RX/TX (de)modulation freq, not really used */
1457 wbcir_select_bank(data, WBCIR_BANK_7);
1458 outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC);
1459 outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC);
1460
1461 /* Set invert and pin direction */
1462 if (invert)
1463 outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4);
1464 else
1465 outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4);
1466
1467 /* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */
1468 wbcir_select_bank(data, WBCIR_BANK_0);
1469 outb(0x97, data->sbase + WBCIR_REG_SP3_FCR);
1470
1471 /* Clear AUX status bits */
1472 outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
1473
1474 /* Enable interrupts */
1475 outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
1476 1470
1477 return 0; 1471 return 0;
1478 1472
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index a932179c4c9e..04d5a4a3181f 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -21,6 +21,7 @@
21#include <linux/dmi.h> 21#include <linux/dmi.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/input-polldev.h> 23#include <linux/input-polldev.h>
24#include <linux/input/sparse-keymap.h>
24#include <linux/interrupt.h> 25#include <linux/interrupt.h>
25#include <linux/jiffies.h> 26#include <linux/jiffies.h>
26#include <linux/kernel.h> 27#include <linux/kernel.h>
@@ -28,6 +29,7 @@
28#include <linux/module.h> 29#include <linux/module.h>
29#include <linux/preempt.h> 30#include <linux/preempt.h>
30#include <linux/string.h> 31#include <linux/string.h>
32#include <linux/slab.h>
31#include <linux/types.h> 33#include <linux/types.h>
32#include <linux/platform_device.h> 34#include <linux/platform_device.h>
33#include <linux/leds.h> 35#include <linux/leds.h>
@@ -224,19 +226,8 @@ static void bios_set_state(u8 subsys, int enable)
224 226
225/* Hardware database */ 227/* Hardware database */
226 228
227struct key_entry { 229#define KE_WIFI (KE_LAST + 1)
228 char type; /* See KE_* below */ 230#define KE_BLUETOOTH (KE_LAST + 2)
229 u8 code;
230 union {
231 u16 keycode; /* For KE_KEY */
232 struct { /* For KE_SW */
233 u8 code;
234 u8 value;
235 } sw;
236 };
237};
238
239enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH };
240 231
241#define FE_MAIL_LED 0x01 232#define FE_MAIL_LED 0x01
242#define FE_WIFI_LED 0x02 233#define FE_WIFI_LED 0x02
@@ -644,10 +635,10 @@ static struct key_entry keymap_prestigio[] __initdata = {
644 * a list of buttons and their key codes (reported when loading this module 635 * a list of buttons and their key codes (reported when loading this module
645 * with force=1) and the output of dmidecode to $MODULE_AUTHOR. 636 * with force=1) and the output of dmidecode to $MODULE_AUTHOR.
646 */ 637 */
647static struct dmi_system_id dmi_ids[] __initdata = { 638static const struct dmi_system_id __initconst dmi_ids[] = {
648 { 639 {
640 /* Fujitsu-Siemens Amilo Pro V2000 */
649 .callback = dmi_matched, 641 .callback = dmi_matched,
650 .ident = "Fujitsu-Siemens Amilo Pro V2000",
651 .matches = { 642 .matches = {
652 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 643 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
653 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"), 644 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"),
@@ -655,8 +646,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
655 .driver_data = keymap_fs_amilo_pro_v2000 646 .driver_data = keymap_fs_amilo_pro_v2000
656 }, 647 },
657 { 648 {
649 /* Fujitsu-Siemens Amilo Pro Edition V3505 */
658 .callback = dmi_matched, 650 .callback = dmi_matched,
659 .ident = "Fujitsu-Siemens Amilo Pro Edition V3505",
660 .matches = { 651 .matches = {
661 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 652 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
662 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"), 653 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"),
@@ -664,8 +655,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
664 .driver_data = keymap_fs_amilo_pro_v3505 655 .driver_data = keymap_fs_amilo_pro_v3505
665 }, 656 },
666 { 657 {
658 /* Fujitsu-Siemens Amilo M7400 */
667 .callback = dmi_matched, 659 .callback = dmi_matched,
668 .ident = "Fujitsu-Siemens Amilo M7400",
669 .matches = { 660 .matches = {
670 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 661 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
671 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M "), 662 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M "),
@@ -673,8 +664,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
673 .driver_data = keymap_fs_amilo_pro_v2000 664 .driver_data = keymap_fs_amilo_pro_v2000
674 }, 665 },
675 { 666 {
667 /* Maxdata Pro 7000 DX */
676 .callback = dmi_matched, 668 .callback = dmi_matched,
677 .ident = "Maxdata Pro 7000 DX",
678 .matches = { 669 .matches = {
679 DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"), 670 DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"),
680 DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"), 671 DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"),
@@ -682,8 +673,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
682 .driver_data = keymap_fs_amilo_pro_v2000 673 .driver_data = keymap_fs_amilo_pro_v2000
683 }, 674 },
684 { 675 {
676 /* Fujitsu N3510 */
685 .callback = dmi_matched, 677 .callback = dmi_matched,
686 .ident = "Fujitsu N3510",
687 .matches = { 678 .matches = {
688 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 679 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
689 DMI_MATCH(DMI_PRODUCT_NAME, "N3510"), 680 DMI_MATCH(DMI_PRODUCT_NAME, "N3510"),
@@ -691,8 +682,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
691 .driver_data = keymap_fujitsu_n3510 682 .driver_data = keymap_fujitsu_n3510
692 }, 683 },
693 { 684 {
685 /* Acer Aspire 1500 */
694 .callback = dmi_matched, 686 .callback = dmi_matched,
695 .ident = "Acer Aspire 1500",
696 .matches = { 687 .matches = {
697 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 688 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
698 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"), 689 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"),
@@ -700,8 +691,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
700 .driver_data = keymap_acer_aspire_1500 691 .driver_data = keymap_acer_aspire_1500
701 }, 692 },
702 { 693 {
694 /* Acer Aspire 1600 */
703 .callback = dmi_matched, 695 .callback = dmi_matched,
704 .ident = "Acer Aspire 1600",
705 .matches = { 696 .matches = {
706 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 697 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
707 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"), 698 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"),
@@ -709,8 +700,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
709 .driver_data = keymap_acer_aspire_1600 700 .driver_data = keymap_acer_aspire_1600
710 }, 701 },
711 { 702 {
703 /* Acer Aspire 3020 */
712 .callback = dmi_matched, 704 .callback = dmi_matched,
713 .ident = "Acer Aspire 3020",
714 .matches = { 705 .matches = {
715 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 706 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
716 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"), 707 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"),
@@ -718,8 +709,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
718 .driver_data = keymap_acer_aspire_5020 709 .driver_data = keymap_acer_aspire_5020
719 }, 710 },
720 { 711 {
712 /* Acer Aspire 5020 */
721 .callback = dmi_matched, 713 .callback = dmi_matched,
722 .ident = "Acer Aspire 5020",
723 .matches = { 714 .matches = {
724 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 715 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
725 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"), 716 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"),
@@ -727,8 +718,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
727 .driver_data = keymap_acer_aspire_5020 718 .driver_data = keymap_acer_aspire_5020
728 }, 719 },
729 { 720 {
721 /* Acer TravelMate 2100 */
730 .callback = dmi_matched, 722 .callback = dmi_matched,
731 .ident = "Acer TravelMate 2100",
732 .matches = { 723 .matches = {
733 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 724 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
734 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"), 725 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"),
@@ -736,8 +727,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
736 .driver_data = keymap_acer_aspire_5020 727 .driver_data = keymap_acer_aspire_5020
737 }, 728 },
738 { 729 {
730 /* Acer TravelMate 2410 */
739 .callback = dmi_matched, 731 .callback = dmi_matched,
740 .ident = "Acer TravelMate 2410",
741 .matches = { 732 .matches = {
742 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 733 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
743 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"), 734 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"),
@@ -745,8 +736,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
745 .driver_data = keymap_acer_travelmate_2410 736 .driver_data = keymap_acer_travelmate_2410
746 }, 737 },
747 { 738 {
739 /* Acer TravelMate C300 */
748 .callback = dmi_matched, 740 .callback = dmi_matched,
749 .ident = "Acer TravelMate C300",
750 .matches = { 741 .matches = {
751 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 742 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
752 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"), 743 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"),
@@ -754,8 +745,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
754 .driver_data = keymap_acer_travelmate_300 745 .driver_data = keymap_acer_travelmate_300
755 }, 746 },
756 { 747 {
748 /* Acer TravelMate C100 */
757 .callback = dmi_matched, 749 .callback = dmi_matched,
758 .ident = "Acer TravelMate C100",
759 .matches = { 750 .matches = {
760 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 751 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
761 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"), 752 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"),
@@ -763,8 +754,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
763 .driver_data = keymap_acer_travelmate_300 754 .driver_data = keymap_acer_travelmate_300
764 }, 755 },
765 { 756 {
757 /* Acer TravelMate C110 */
766 .callback = dmi_matched, 758 .callback = dmi_matched,
767 .ident = "Acer TravelMate C110",
768 .matches = { 759 .matches = {
769 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 760 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
770 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"), 761 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"),
@@ -772,8 +763,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
772 .driver_data = keymap_acer_travelmate_110 763 .driver_data = keymap_acer_travelmate_110
773 }, 764 },
774 { 765 {
766 /* Acer TravelMate 380 */
775 .callback = dmi_matched, 767 .callback = dmi_matched,
776 .ident = "Acer TravelMate 380",
777 .matches = { 768 .matches = {
778 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 769 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
779 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"), 770 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"),
@@ -781,8 +772,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
781 .driver_data = keymap_acer_travelmate_380 772 .driver_data = keymap_acer_travelmate_380
782 }, 773 },
783 { 774 {
775 /* Acer TravelMate 370 */
784 .callback = dmi_matched, 776 .callback = dmi_matched,
785 .ident = "Acer TravelMate 370",
786 .matches = { 777 .matches = {
787 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 778 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
788 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"), 779 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"),
@@ -790,8 +781,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
790 .driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */ 781 .driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */
791 }, 782 },
792 { 783 {
784 /* Acer TravelMate 220 */
793 .callback = dmi_matched, 785 .callback = dmi_matched,
794 .ident = "Acer TravelMate 220",
795 .matches = { 786 .matches = {
796 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 787 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
797 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"), 788 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"),
@@ -799,8 +790,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
799 .driver_data = keymap_acer_travelmate_220 790 .driver_data = keymap_acer_travelmate_220
800 }, 791 },
801 { 792 {
793 /* Acer TravelMate 260 */
802 .callback = dmi_matched, 794 .callback = dmi_matched,
803 .ident = "Acer TravelMate 260",
804 .matches = { 795 .matches = {
805 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 796 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
806 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"), 797 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"),
@@ -808,8 +799,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
808 .driver_data = keymap_acer_travelmate_220 799 .driver_data = keymap_acer_travelmate_220
809 }, 800 },
810 { 801 {
802 /* Acer TravelMate 230 */
811 .callback = dmi_matched, 803 .callback = dmi_matched,
812 .ident = "Acer TravelMate 230",
813 .matches = { 804 .matches = {
814 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 805 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
815 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"), 806 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"),
@@ -818,8 +809,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
818 .driver_data = keymap_acer_travelmate_230 809 .driver_data = keymap_acer_travelmate_230
819 }, 810 },
820 { 811 {
812 /* Acer TravelMate 280 */
821 .callback = dmi_matched, 813 .callback = dmi_matched,
822 .ident = "Acer TravelMate 280",
823 .matches = { 814 .matches = {
824 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 815 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
825 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"), 816 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"),
@@ -827,8 +818,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
827 .driver_data = keymap_acer_travelmate_230 818 .driver_data = keymap_acer_travelmate_230
828 }, 819 },
829 { 820 {
821 /* Acer TravelMate 240 */
830 .callback = dmi_matched, 822 .callback = dmi_matched,
831 .ident = "Acer TravelMate 240",
832 .matches = { 823 .matches = {
833 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 824 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
834 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"), 825 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"),
@@ -836,8 +827,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
836 .driver_data = keymap_acer_travelmate_240 827 .driver_data = keymap_acer_travelmate_240
837 }, 828 },
838 { 829 {
830 /* Acer TravelMate 250 */
839 .callback = dmi_matched, 831 .callback = dmi_matched,
840 .ident = "Acer TravelMate 250",
841 .matches = { 832 .matches = {
842 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 833 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
843 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"), 834 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"),
@@ -845,8 +836,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
845 .driver_data = keymap_acer_travelmate_240 836 .driver_data = keymap_acer_travelmate_240
846 }, 837 },
847 { 838 {
839 /* Acer TravelMate 2424NWXCi */
848 .callback = dmi_matched, 840 .callback = dmi_matched,
849 .ident = "Acer TravelMate 2424NWXCi",
850 .matches = { 841 .matches = {
851 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 842 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
852 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"), 843 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"),
@@ -854,8 +845,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
854 .driver_data = keymap_acer_travelmate_240 845 .driver_data = keymap_acer_travelmate_240
855 }, 846 },
856 { 847 {
848 /* Acer TravelMate 350 */
857 .callback = dmi_matched, 849 .callback = dmi_matched,
858 .ident = "Acer TravelMate 350",
859 .matches = { 850 .matches = {
860 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 851 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
861 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"), 852 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"),
@@ -863,8 +854,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
863 .driver_data = keymap_acer_travelmate_350 854 .driver_data = keymap_acer_travelmate_350
864 }, 855 },
865 { 856 {
857 /* Acer TravelMate 360 */
866 .callback = dmi_matched, 858 .callback = dmi_matched,
867 .ident = "Acer TravelMate 360",
868 .matches = { 859 .matches = {
869 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 860 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
870 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), 861 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
@@ -872,8 +863,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
872 .driver_data = keymap_acer_travelmate_360 863 .driver_data = keymap_acer_travelmate_360
873 }, 864 },
874 { 865 {
866 /* Acer TravelMate 610 */
875 .callback = dmi_matched, 867 .callback = dmi_matched,
876 .ident = "Acer TravelMate 610",
877 .matches = { 868 .matches = {
878 DMI_MATCH(DMI_SYS_VENDOR, "ACER"), 869 DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
879 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"), 870 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"),
@@ -881,8 +872,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
881 .driver_data = keymap_acer_travelmate_610 872 .driver_data = keymap_acer_travelmate_610
882 }, 873 },
883 { 874 {
875 /* Acer TravelMate 620 */
884 .callback = dmi_matched, 876 .callback = dmi_matched,
885 .ident = "Acer TravelMate 620",
886 .matches = { 877 .matches = {
887 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 878 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
888 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"), 879 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"),
@@ -890,8 +881,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
890 .driver_data = keymap_acer_travelmate_630 881 .driver_data = keymap_acer_travelmate_630
891 }, 882 },
892 { 883 {
884 /* Acer TravelMate 630 */
893 .callback = dmi_matched, 885 .callback = dmi_matched,
894 .ident = "Acer TravelMate 630",
895 .matches = { 886 .matches = {
896 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 887 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
897 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"), 888 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"),
@@ -899,8 +890,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
899 .driver_data = keymap_acer_travelmate_630 890 .driver_data = keymap_acer_travelmate_630
900 }, 891 },
901 { 892 {
893 /* AOpen 1559AS */
902 .callback = dmi_matched, 894 .callback = dmi_matched,
903 .ident = "AOpen 1559AS",
904 .matches = { 895 .matches = {
905 DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), 896 DMI_MATCH(DMI_PRODUCT_NAME, "E2U"),
906 DMI_MATCH(DMI_BOARD_NAME, "E2U"), 897 DMI_MATCH(DMI_BOARD_NAME, "E2U"),
@@ -908,8 +899,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
908 .driver_data = keymap_aopen_1559as 899 .driver_data = keymap_aopen_1559as
909 }, 900 },
910 { 901 {
902 /* Medion MD 9783 */
911 .callback = dmi_matched, 903 .callback = dmi_matched,
912 .ident = "Medion MD 9783",
913 .matches = { 904 .matches = {
914 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), 905 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
915 DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"), 906 DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"),
@@ -917,8 +908,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
917 .driver_data = keymap_wistron_ms2111 908 .driver_data = keymap_wistron_ms2111
918 }, 909 },
919 { 910 {
911 /* Medion MD 40100 */
920 .callback = dmi_matched, 912 .callback = dmi_matched,
921 .ident = "Medion MD 40100",
922 .matches = { 913 .matches = {
923 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), 914 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
924 DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"), 915 DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"),
@@ -926,8 +917,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
926 .driver_data = keymap_wistron_md40100 917 .driver_data = keymap_wistron_md40100
927 }, 918 },
928 { 919 {
920 /* Medion MD 2900 */
929 .callback = dmi_matched, 921 .callback = dmi_matched,
930 .ident = "Medion MD 2900",
931 .matches = { 922 .matches = {
932 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), 923 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
933 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"), 924 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"),
@@ -935,8 +926,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
935 .driver_data = keymap_wistron_md2900 926 .driver_data = keymap_wistron_md2900
936 }, 927 },
937 { 928 {
929 /* Medion MD 42200 */
938 .callback = dmi_matched, 930 .callback = dmi_matched,
939 .ident = "Medion MD 42200",
940 .matches = { 931 .matches = {
941 DMI_MATCH(DMI_SYS_VENDOR, "Medion"), 932 DMI_MATCH(DMI_SYS_VENDOR, "Medion"),
942 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2030"), 933 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2030"),
@@ -944,8 +935,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
944 .driver_data = keymap_fs_amilo_pro_v2000 935 .driver_data = keymap_fs_amilo_pro_v2000
945 }, 936 },
946 { 937 {
938 /* Medion MD 96500 */
947 .callback = dmi_matched, 939 .callback = dmi_matched,
948 .ident = "Medion MD 96500",
949 .matches = { 940 .matches = {
950 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), 941 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
951 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"), 942 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"),
@@ -953,8 +944,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
953 .driver_data = keymap_wistron_md96500 944 .driver_data = keymap_wistron_md96500
954 }, 945 },
955 { 946 {
947 /* Medion MD 95400 */
956 .callback = dmi_matched, 948 .callback = dmi_matched,
957 .ident = "Medion MD 95400",
958 .matches = { 949 .matches = {
959 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), 950 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
960 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"), 951 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"),
@@ -962,8 +953,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
962 .driver_data = keymap_wistron_md96500 953 .driver_data = keymap_wistron_md96500
963 }, 954 },
964 { 955 {
956 /* Fujitsu Siemens Amilo D7820 */
965 .callback = dmi_matched, 957 .callback = dmi_matched,
966 .ident = "Fujitsu Siemens Amilo D7820",
967 .matches = { 958 .matches = {
968 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */ 959 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */
969 DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"), 960 DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"),
@@ -971,8 +962,8 @@ static struct dmi_system_id dmi_ids[] __initdata = {
971 .driver_data = keymap_fs_amilo_d88x0 962 .driver_data = keymap_fs_amilo_d88x0
972 }, 963 },
973 { 964 {
965 /* Fujitsu Siemens Amilo D88x0 */
974 .callback = dmi_matched, 966 .callback = dmi_matched,
975 .ident = "Fujitsu Siemens Amilo D88x0",
976 .matches = { 967 .matches = {
977 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 968 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
978 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"), 969 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"),
@@ -1037,21 +1028,6 @@ static unsigned long jiffies_last_press;
1037static bool wifi_enabled; 1028static bool wifi_enabled;
1038static bool bluetooth_enabled; 1029static bool bluetooth_enabled;
1039 1030
1040static void report_key(struct input_dev *dev, unsigned int keycode)
1041{
1042 input_report_key(dev, keycode, 1);
1043 input_sync(dev);
1044 input_report_key(dev, keycode, 0);
1045 input_sync(dev);
1046}
1047
1048static void report_switch(struct input_dev *dev, unsigned int code, int value)
1049{
1050 input_report_switch(dev, code, value);
1051 input_sync(dev);
1052}
1053
1054
1055 /* led management */ 1031 /* led management */
1056static void wistron_mail_led_set(struct led_classdev *led_cdev, 1032static void wistron_mail_led_set(struct led_classdev *led_cdev,
1057 enum led_brightness value) 1033 enum led_brightness value)
@@ -1128,43 +1104,13 @@ static inline void wistron_led_resume(void)
1128 led_classdev_resume(&wistron_wifi_led); 1104 led_classdev_resume(&wistron_wifi_led);
1129} 1105}
1130 1106
1131static struct key_entry *wistron_get_entry_by_scancode(int code)
1132{
1133 struct key_entry *key;
1134
1135 for (key = keymap; key->type != KE_END; key++)
1136 if (code == key->code)
1137 return key;
1138
1139 return NULL;
1140}
1141
1142static struct key_entry *wistron_get_entry_by_keycode(int keycode)
1143{
1144 struct key_entry *key;
1145
1146 for (key = keymap; key->type != KE_END; key++)
1147 if (key->type == KE_KEY && keycode == key->keycode)
1148 return key;
1149
1150 return NULL;
1151}
1152
1153static void handle_key(u8 code) 1107static void handle_key(u8 code)
1154{ 1108{
1155 const struct key_entry *key = wistron_get_entry_by_scancode(code); 1109 const struct key_entry *key =
1110 sparse_keymap_entry_from_scancode(wistron_idev->input, code);
1156 1111
1157 if (key) { 1112 if (key) {
1158 switch (key->type) { 1113 switch (key->type) {
1159 case KE_KEY:
1160 report_key(wistron_idev->input, key->keycode);
1161 break;
1162
1163 case KE_SW:
1164 report_switch(wistron_idev->input,
1165 key->sw.code, key->sw.value);
1166 break;
1167
1168 case KE_WIFI: 1114 case KE_WIFI:
1169 if (have_wifi) { 1115 if (have_wifi) {
1170 wifi_enabled = !wifi_enabled; 1116 wifi_enabled = !wifi_enabled;
@@ -1180,7 +1126,9 @@ static void handle_key(u8 code)
1180 break; 1126 break;
1181 1127
1182 default: 1128 default:
1183 BUG(); 1129 sparse_keymap_report_entry(wistron_idev->input,
1130 key, 1, true);
1131 break;
1184 } 1132 }
1185 jiffies_last_press = jiffies; 1133 jiffies_last_press = jiffies;
1186 } else 1134 } else
@@ -1220,42 +1168,39 @@ static void wistron_poll(struct input_polled_dev *dev)
1220 dev->poll_interval = POLL_INTERVAL_DEFAULT; 1168 dev->poll_interval = POLL_INTERVAL_DEFAULT;
1221} 1169}
1222 1170
1223static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode) 1171static int __devinit wistron_setup_keymap(struct input_dev *dev,
1172 struct key_entry *entry)
1224{ 1173{
1225 const struct key_entry *key = wistron_get_entry_by_scancode(scancode); 1174 switch (entry->type) {
1226
1227 if (key && key->type == KE_KEY) {
1228 *keycode = key->keycode;
1229 return 0;
1230 }
1231 1175
1232 return -EINVAL; 1176 /* if wifi or bluetooth are not available, create normal keys */
1233} 1177 case KE_WIFI:
1178 if (!have_wifi) {
1179 entry->type = KE_KEY;
1180 entry->keycode = KEY_WLAN;
1181 }
1182 break;
1234 1183
1235static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode) 1184 case KE_BLUETOOTH:
1236{ 1185 if (!have_bluetooth) {
1237 struct key_entry *key; 1186 entry->type = KE_KEY;
1238 int old_keycode; 1187 entry->keycode = KEY_BLUETOOTH;
1239 1188 }
1240 if (keycode < 0 || keycode > KEY_MAX) 1189 break;
1241 return -EINVAL; 1190
1242 1191 case KE_END:
1243 key = wistron_get_entry_by_scancode(scancode); 1192 if (entry->code & FE_UNTESTED)
1244 if (key && key->type == KE_KEY) { 1193 printk(KERN_WARNING "Untested laptop multimedia keys, "
1245 old_keycode = key->keycode; 1194 "please report success or failure to "
1246 key->keycode = keycode; 1195 "eric.piel@tremplin-utc.net\n");
1247 set_bit(keycode, dev->keybit); 1196 break;
1248 if (!wistron_get_entry_by_keycode(old_keycode))
1249 clear_bit(old_keycode, dev->keybit);
1250 return 0;
1251 } 1197 }
1252 1198
1253 return -EINVAL; 1199 return 0;
1254} 1200}
1255 1201
1256static int __devinit setup_input_dev(void) 1202static int __devinit setup_input_dev(void)
1257{ 1203{
1258 struct key_entry *key;
1259 struct input_dev *input_dev; 1204 struct input_dev *input_dev;
1260 int error; 1205 int error;
1261 1206
@@ -1263,7 +1208,7 @@ static int __devinit setup_input_dev(void)
1263 if (!wistron_idev) 1208 if (!wistron_idev)
1264 return -ENOMEM; 1209 return -ENOMEM;
1265 1210
1266 wistron_idev->flush = wistron_flush; 1211 wistron_idev->open = wistron_flush;
1267 wistron_idev->poll = wistron_poll; 1212 wistron_idev->poll = wistron_poll;
1268 wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT; 1213 wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT;
1269 1214
@@ -1273,56 +1218,21 @@ static int __devinit setup_input_dev(void)
1273 input_dev->id.bustype = BUS_HOST; 1218 input_dev->id.bustype = BUS_HOST;
1274 input_dev->dev.parent = &wistron_device->dev; 1219 input_dev->dev.parent = &wistron_device->dev;
1275 1220
1276 input_dev->getkeycode = wistron_getkeycode; 1221 error = sparse_keymap_setup(input_dev, keymap, wistron_setup_keymap);
1277 input_dev->setkeycode = wistron_setkeycode; 1222 if (error)
1278 1223 goto err_free_dev;
1279 for (key = keymap; key->type != KE_END; key++) {
1280 switch (key->type) {
1281 case KE_KEY:
1282 set_bit(EV_KEY, input_dev->evbit);
1283 set_bit(key->keycode, input_dev->keybit);
1284 break;
1285
1286 case KE_SW:
1287 set_bit(EV_SW, input_dev->evbit);
1288 set_bit(key->sw.code, input_dev->swbit);
1289 break;
1290
1291 /* if wifi or bluetooth are not available, create normal keys */
1292 case KE_WIFI:
1293 if (!have_wifi) {
1294 key->type = KE_KEY;
1295 key->keycode = KEY_WLAN;
1296 key--;
1297 }
1298 break;
1299
1300 case KE_BLUETOOTH:
1301 if (!have_bluetooth) {
1302 key->type = KE_KEY;
1303 key->keycode = KEY_BLUETOOTH;
1304 key--;
1305 }
1306 break;
1307
1308 default:
1309 break;
1310 }
1311 }
1312
1313 /* reads information flags on KE_END */
1314 if (key->code & FE_UNTESTED)
1315 printk(KERN_WARNING "Untested laptop multimedia keys, "
1316 "please report success or failure to eric.piel"
1317 "@tremplin-utc.net\n");
1318 1224
1319 error = input_register_polled_device(wistron_idev); 1225 error = input_register_polled_device(wistron_idev);
1320 if (error) { 1226 if (error)
1321 input_free_polled_device(wistron_idev); 1227 goto err_free_keymap;
1322 return error;
1323 }
1324 1228
1325 return 0; 1229 return 0;
1230
1231 err_free_keymap:
1232 sparse_keymap_free(input_dev);
1233 err_free_dev:
1234 input_free_polled_device(wistron_idev);
1235 return error;
1326} 1236}
1327 1237
1328/* Driver core */ 1238/* Driver core */
@@ -1371,6 +1281,7 @@ static int __devexit wistron_remove(struct platform_device *dev)
1371{ 1281{
1372 wistron_led_remove(); 1282 wistron_led_remove();
1373 input_unregister_polled_device(wistron_idev); 1283 input_unregister_polled_device(wistron_idev);
1284 sparse_keymap_free(wistron_idev->input);
1374 input_free_polled_device(wistron_idev); 1285 input_free_polled_device(wistron_idev);
1375 bios_detach(); 1286 bios_detach();
1376 1287
@@ -1418,7 +1329,7 @@ static struct platform_driver wistron_driver = {
1418 .driver = { 1329 .driver = {
1419 .name = "wistron-bios", 1330 .name = "wistron-bios",
1420 .owner = THIS_MODULE, 1331 .owner = THIS_MODULE,
1421#if CONFIG_PM 1332#ifdef CONFIG_PM
1422 .pm = &wistron_pm_ops, 1333 .pm = &wistron_pm_ops,
1423#endif 1334#endif
1424 }, 1335 },
diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c
index ba4f5dd7c60e..c3d7ba5f5b47 100644
--- a/drivers/input/misc/wm831x-on.c
+++ b/drivers/input/misc/wm831x-on.c
@@ -19,6 +19,7 @@
19 19
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/slab.h>
22#include <linux/kernel.h> 23#include <linux/kernel.h>
23#include <linux/errno.h> 24#include <linux/errno.h>
24#include <linux/input.h> 25#include <linux/input.h>
@@ -97,8 +98,9 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev)
97 wm831x_on->dev->phys = "wm831x_on/input0"; 98 wm831x_on->dev->phys = "wm831x_on/input0";
98 wm831x_on->dev->dev.parent = &pdev->dev; 99 wm831x_on->dev->dev.parent = &pdev->dev;
99 100
100 ret = wm831x_request_irq(wm831x, irq, wm831x_on_irq, 101 ret = request_threaded_irq(irq, NULL, wm831x_on_irq,
101 IRQF_TRIGGER_RISING, "wm831x_on", wm831x_on); 102 IRQF_TRIGGER_RISING, "wm831x_on",
103 wm831x_on);
102 if (ret < 0) { 104 if (ret < 0) {
103 dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret); 105 dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret);
104 goto err_input_dev; 106 goto err_input_dev;
@@ -114,7 +116,7 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev)
114 return 0; 116 return 0;
115 117
116err_irq: 118err_irq:
117 wm831x_free_irq(wm831x, irq, NULL); 119 free_irq(irq, wm831x_on);
118err_input_dev: 120err_input_dev:
119 input_free_device(wm831x_on->dev); 121 input_free_device(wm831x_on->dev);
120err: 122err:
@@ -127,7 +129,7 @@ static int __devexit wm831x_on_remove(struct platform_device *pdev)
127 struct wm831x_on *wm831x_on = platform_get_drvdata(pdev); 129 struct wm831x_on *wm831x_on = platform_get_drvdata(pdev);
128 int irq = platform_get_irq(pdev, 0); 130 int irq = platform_get_irq(pdev, 0);
129 131
130 wm831x_free_irq(wm831x_on->wm831x, irq, wm831x_on); 132 free_irq(irq, wm831x_on);
131 cancel_delayed_work_sync(&wm831x_on->work); 133 cancel_delayed_work_sync(&wm831x_on->work);
132 input_unregister_device(wm831x_on->dev); 134 input_unregister_device(wm831x_on->dev);
133 kfree(wm831x_on); 135 kfree(wm831x_on);
diff --git a/drivers/input/misc/yealink.h b/drivers/input/misc/yealink.h
index 48af0be9cbdf..1e0f52397010 100644
--- a/drivers/input/misc/yealink.h
+++ b/drivers/input/misc/yealink.h
@@ -127,7 +127,7 @@ struct yld_ctl_packet {
127 * yld_status struct. 127 * yld_status struct.
128 */ 128 */
129 129
130/* LCD, each segment must be driven seperately. 130/* LCD, each segment must be driven separately.
131 * 131 *
132 * Layout: 132 * Layout:
133 * 133 *