aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-04 21:13:17 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-04 21:16:12 -0400
commita3d52136ee8f7399859f9a0824470fd49b1d1a00 (patch)
treeac0fd3d1efc356029cbbc5e413f778f7231cd909 /drivers/input/misc
parent5b339915762d30b21995aa7263e74081f2f1110a (diff)
parent84767d00a8fd54dd97866561f6e2ee246c8e1cdc (diff)
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input: (65 commits) Input: gpio_keys - add support for switches (EV_SW) Input: cobalt_btns - convert to use polldev library Input: add skeleton for simple polled devices Input: update some documentation Input: wistron - fix typo in keymap for Acer TM610 Input: add input_set_capability() helper Input: i8042 - add Fujitsu touchscreen/touchpad PNP IDs Input: i8042 - add Panasonic CF-29 to nomux list Input: lifebook - split into 2 devices Input: lifebook - add signature of Panasonic CF-29 Input: lifebook - activate 6-byte protocol on select models Input: lifebook - work properly on Panasonic CF-18 Input: cobalt buttons - separate device and driver registration Input: ati_remote - make button repeat sensitivity configurable Input: pxa27x - do not use deprecated SA_INTERRUPT flag Input: ucb1400 - make delays configurable Input: misc devices - switch to using input_dev->dev.parent Input: joysticks - switch to using input_dev->dev.parent Input: touchscreens - switch to using input_dev->dev.parent Input: mice - switch to using input_dev->dev.parent ... Fixed up conflicts with core device model removal of "struct subsystem" manually. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/input/misc')
-rw-r--r--drivers/input/misc/Kconfig23
-rw-r--r--drivers/input/misc/Makefile2
-rw-r--r--drivers/input/misc/cobalt_btns.c172
-rw-r--r--drivers/input/misc/input-polldev.c171
-rw-r--r--drivers/input/misc/ixp4xx-beeper.c11
-rw-r--r--drivers/input/misc/m68kspkr.c2
-rw-r--r--drivers/input/misc/pcspkr.c2
-rw-r--r--drivers/input/misc/sparcspkr.c6
-rw-r--r--drivers/input/misc/uinput.c10
-rw-r--r--drivers/input/misc/wistron_btns.c685
10 files changed, 992 insertions, 92 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 41b42587f5e..1d0d3e765db 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -40,6 +40,16 @@ config INPUT_M68K_BEEP
40 tristate "M68k Beeper support" 40 tristate "M68k Beeper support"
41 depends on M68K 41 depends on M68K
42 42
43config INPUT_COBALT_BTNS
44 tristate "Cobalt button interface"
45 depends on MIPS_COBALT
46 select INPUT_POLLDEV
47 help
48 Say Y here if you want to support MIPS Cobalt button interface.
49
50 To compile this driver as a module, choose M here: the
51 module will be called cobalt_btns.
52
43config INPUT_WISTRON_BTNS 53config INPUT_WISTRON_BTNS
44 tristate "x86 Wistron laptop button interface" 54 tristate "x86 Wistron laptop button interface"
45 depends on X86 && !X86_64 55 depends on X86 && !X86_64
@@ -81,8 +91,19 @@ config INPUT_UINPUT
81 To compile this driver as a module, choose M here: the 91 To compile this driver as a module, choose M here: the
82 module will be called uinput. 92 module will be called uinput.
83 93
94config INPUT_POLLDEV
95 tristate "Polled input device skeleton"
96 help
97 Say Y here if you are using a driver for an input
98 device that periodically polls hardware state. This
99 option is only useful for out-of-tree drivers since
100 in-tree drivers select it automatically.
101
102 To compile this driver as a module, choose M here: the
103 module will be called input-polldev.
104
84config HP_SDC_RTC 105config HP_SDC_RTC
85 tristate "HP SDC Real Time Clock" 106 tristate "HP SDC Real Time Clock"
86 depends on GSC || HP300 107 depends on GSC || HP300
87 select HP_SDC 108 select HP_SDC
88 help 109 help
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index e0a8d58c9e9..21e3cca0d33 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -4,10 +4,12 @@
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_POLLDEV) += input-polldev.o
7obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o 8obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
8obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o 9obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
9obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o 10obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
10obj-$(CONFIG_INPUT_UINPUT) += uinput.o 11obj-$(CONFIG_INPUT_UINPUT) += uinput.o
12obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o
11obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o 13obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
12obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o 14obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
13obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o 15obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c
new file mode 100644
index 00000000000..064b0793601
--- /dev/null
+++ b/drivers/input/misc/cobalt_btns.c
@@ -0,0 +1,172 @@
1/*
2 * Cobalt button interface driver.
3 *
4 * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/init.h>
21#include <linux/input-polldev.h>
22#include <linux/ioport.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25
26#define BUTTONS_POLL_INTERVAL 30 /* msec */
27#define BUTTONS_COUNT_THRESHOLD 3
28#define BUTTONS_STATUS_MASK 0xfe000000
29
30struct buttons_dev {
31 struct input_polled_dev *poll_dev;
32 void __iomem *reg;
33};
34
35struct buttons_map {
36 uint32_t mask;
37 int keycode;
38 int count;
39};
40
41static struct buttons_map buttons_map[] = {
42 { 0x02000000, KEY_RESTART, },
43 { 0x04000000, KEY_LEFT, },
44 { 0x08000000, KEY_UP, },
45 { 0x10000000, KEY_DOWN, },
46 { 0x20000000, KEY_RIGHT, },
47 { 0x40000000, KEY_ENTER, },
48 { 0x80000000, KEY_SELECT, },
49};
50
51static void handle_buttons(struct input_polled_dev *dev)
52{
53 struct buttons_map *button = buttons_map;
54 struct buttons_dev *bdev = dev->private;
55 struct input_dev *input = dev->input;
56 uint32_t status;
57 int i;
58
59 status = readl(bdev->reg);
60 status = ~status & BUTTONS_STATUS_MASK;
61
62 for (i = 0; i < ARRAY_SIZE(buttons_map); i++) {
63 if (status & button->mask) {
64 button->count++;
65 } else {
66 if (button->count >= BUTTONS_COUNT_THRESHOLD) {
67 input_report_key(input, button->keycode, 0);
68 input_sync(input);
69 }
70 button->count = 0;
71 }
72
73 if (button->count == BUTTONS_COUNT_THRESHOLD) {
74 input_report_key(input, button->keycode, 1);
75 input_sync(input);
76 }
77
78 button++;
79 }
80}
81
82static int __devinit cobalt_buttons_probe(struct platform_device *pdev)
83{
84 struct buttons_dev *bdev;
85 struct input_polled_dev *poll_dev;
86 struct input_dev *input;
87 struct resource *res;
88 int error, i;
89
90 bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL);
91 poll_dev = input_allocate_polled_device();
92 if (!bdev || !poll_dev) {
93 error = -ENOMEM;
94 goto err_free_mem;
95 }
96
97 poll_dev->private = bdev;
98 poll_dev->poll = handle_buttons;
99 poll_dev->poll_interval = BUTTONS_POLL_INTERVAL;
100
101 input = poll_dev->input;
102 input->name = "Cobalt buttons";
103 input->phys = "cobalt/input0";
104 input->id.bustype = BUS_HOST;
105 input->cdev.dev = &pdev->dev;
106
107 input->evbit[0] = BIT(EV_KEY);
108 for (i = 0; i < ARRAY_SIZE(buttons_map); i++) {
109 set_bit(buttons_map[i].keycode, input->keybit);
110 buttons_map[i].count = 0;
111 }
112
113 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
114 if (!res) {
115 error = -EBUSY;
116 goto err_free_mem;
117 }
118
119 bdev->poll_dev = poll_dev;
120 bdev->reg = ioremap(res->start, res->end - res->start + 1);
121 dev_set_drvdata(&pdev->dev, bdev);
122
123 error = input_register_polled_device(poll_dev);
124 if (error)
125 goto err_iounmap;
126
127 return 0;
128
129 err_iounmap:
130 iounmap(bdev->reg);
131 err_free_mem:
132 input_free_polled_device(poll_dev);
133 kfree(bdev);
134 dev_set_drvdata(&pdev->dev, NULL);
135 return error;
136}
137
138static int __devexit cobalt_buttons_remove(struct platform_device *pdev)
139{
140 struct device *dev = &pdev->dev;
141 struct buttons_dev *bdev = dev_get_drvdata(dev);
142
143 input_unregister_polled_device(bdev->poll_dev);
144 input_free_polled_device(bdev->poll_dev);
145 iounmap(bdev->reg);
146 kfree(bdev);
147 dev_set_drvdata(dev, NULL);
148
149 return 0;
150}
151
152static struct platform_driver cobalt_buttons_driver = {
153 .probe = cobalt_buttons_probe,
154 .remove = __devexit_p(cobalt_buttons_remove),
155 .driver = {
156 .name = "Cobalt buttons",
157 .owner = THIS_MODULE,
158 },
159};
160
161static int __init cobalt_buttons_init(void)
162{
163 return platform_driver_register(&cobalt_buttons_driver);
164}
165
166static void __exit cobalt_buttons_exit(void)
167{
168 platform_driver_unregister(&cobalt_buttons_driver);
169}
170
171module_init(cobalt_buttons_init);
172module_exit(cobalt_buttons_exit);
diff --git a/drivers/input/misc/input-polldev.c b/drivers/input/misc/input-polldev.c
new file mode 100644
index 00000000000..1b2b9c9c5d8
--- /dev/null
+++ b/drivers/input/misc/input-polldev.c
@@ -0,0 +1,171 @@
1/*
2 * Generic implementation of a polled input device
3
4 * Copyright (c) 2007 Dmitry Torokhov
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 */
10
11#include <linux/jiffies.h>
12#include <linux/mutex.h>
13#include <linux/input-polldev.h>
14
15static DEFINE_MUTEX(polldev_mutex);
16static int polldev_users;
17static struct workqueue_struct *polldev_wq;
18
19static int input_polldev_start_workqueue(void)
20{
21 int retval;
22
23 retval = mutex_lock_interruptible(&polldev_mutex);
24 if (retval)
25 return retval;
26
27 if (!polldev_users) {
28 polldev_wq = create_singlethread_workqueue("ipolldevd");
29 if (!polldev_wq) {
30 printk(KERN_ERR "input-polldev: failed to create "
31 "ipolldevd workqueue\n");
32 retval = -ENOMEM;
33 goto out;
34 }
35 }
36
37 polldev_users++;
38
39 out:
40 mutex_unlock(&polldev_mutex);
41 return retval;
42}
43
44static void input_polldev_stop_workqueue(void)
45{
46 mutex_lock(&polldev_mutex);
47
48 if (!--polldev_users)
49 destroy_workqueue(polldev_wq);
50
51 mutex_unlock(&polldev_mutex);
52}
53
54static void input_polled_device_work(struct work_struct *work)
55{
56 struct input_polled_dev *dev =
57 container_of(work, struct input_polled_dev, work.work);
58
59 dev->poll(dev);
60 queue_delayed_work(polldev_wq, &dev->work,
61 msecs_to_jiffies(dev->poll_interval));
62}
63
64static int input_open_polled_device(struct input_dev *input)
65{
66 struct input_polled_dev *dev = input->private;
67 int error;
68
69 error = input_polldev_start_workqueue();
70 if (error)
71 return error;
72
73 if (dev->flush)
74 dev->flush(dev);
75
76 queue_delayed_work(polldev_wq, &dev->work,
77 msecs_to_jiffies(dev->poll_interval));
78
79 return 0;
80}
81
82static void input_close_polled_device(struct input_dev *input)
83{
84 struct input_polled_dev *dev = input->private;
85
86 cancel_rearming_delayed_workqueue(polldev_wq, &dev->work);
87 input_polldev_stop_workqueue();
88}
89
90/**
91 * input_allocate_polled_device - allocated memory polled device
92 *
93 * The function allocates memory for a polled device and also
94 * for an input device associated with this polled device.
95 */
96struct input_polled_dev *input_allocate_polled_device(void)
97{
98 struct input_polled_dev *dev;
99
100 dev = kzalloc(sizeof(struct input_polled_dev), GFP_KERNEL);
101 if (!dev)
102 return NULL;
103
104 dev->input = input_allocate_device();
105 if (!dev->input) {
106 kfree(dev);
107 return NULL;
108 }
109
110 return dev;
111}
112EXPORT_SYMBOL(input_allocate_polled_device);
113
114/**
115 * input_free_polled_device - free memory allocated for polled device
116 * @dev: device to free
117 *
118 * The function frees memory allocated for polling device and drops
119 * reference to the associated input device (if present).
120 */
121void input_free_polled_device(struct input_polled_dev *dev)
122{
123 if (dev) {
124 input_free_device(dev->input);
125 kfree(dev);
126 }
127}
128EXPORT_SYMBOL(input_free_polled_device);
129
130/**
131 * input_register_polled_device - register polled device
132 * @dev: device to register
133 *
134 * The function registers previously initialized polled input device
135 * with input layer. The device should be allocated with call to
136 * input_allocate_polled_device(). Callers should also set up poll()
137 * method and set up capabilities (id, name, phys, bits) of the
138 * corresponing input_dev structure.
139 */
140int input_register_polled_device(struct input_polled_dev *dev)
141{
142 struct input_dev *input = dev->input;
143
144 INIT_DELAYED_WORK(&dev->work, input_polled_device_work);
145 if (!dev->poll_interval)
146 dev->poll_interval = 500;
147 input->private = dev;
148 input->open = input_open_polled_device;
149 input->close = input_close_polled_device;
150
151 return input_register_device(input);
152}
153EXPORT_SYMBOL(input_register_polled_device);
154
155/**
156 * input_unregister_polled_device - unregister polled device
157 * @dev: device to unregister
158 *
159 * The function unregisters previously registered polled input
160 * device from input layer. Polling is stopped and device is
161 * ready to be freed with call to input_free_polled_device().
162 * Callers should not attempt to access dev->input pointer
163 * after calling this function.
164 */
165void input_unregister_polled_device(struct input_polled_dev *dev)
166{
167 input_unregister_device(dev->input);
168 dev->input = NULL;
169}
170EXPORT_SYMBOL(input_unregister_polled_device);
171
diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c
index 105c6fc2782..3d4b619dada 100644
--- a/drivers/input/misc/ixp4xx-beeper.c
+++ b/drivers/input/misc/ixp4xx-beeper.c
@@ -51,7 +51,7 @@ static void ixp4xx_spkr_control(unsigned int pin, unsigned int count)
51 51
52static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 52static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
53{ 53{
54 unsigned int pin = (unsigned int) dev->private; 54 unsigned int pin = (unsigned int) input_get_drvdata(input_dev);
55 unsigned int count = 0; 55 unsigned int count = 0;
56 56
57 if (type != EV_SND) 57 if (type != EV_SND)
@@ -99,14 +99,15 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev)
99 if (!input_dev) 99 if (!input_dev)
100 return -ENOMEM; 100 return -ENOMEM;
101 101
102 input_dev->private = (void *) dev->id; 102 input_set_drvdata(input_dev, (void *) dev->id);
103
103 input_dev->name = "ixp4xx beeper", 104 input_dev->name = "ixp4xx beeper",
104 input_dev->phys = "ixp4xx/gpio"; 105 input_dev->phys = "ixp4xx/gpio";
105 input_dev->id.bustype = BUS_HOST; 106 input_dev->id.bustype = BUS_HOST;
106 input_dev->id.vendor = 0x001f; 107 input_dev->id.vendor = 0x001f;
107 input_dev->id.product = 0x0001; 108 input_dev->id.product = 0x0001;
108 input_dev->id.version = 0x0100; 109 input_dev->id.version = 0x0100;
109 input_dev->cdev.dev = &dev->dev; 110 input_dev->dev.parent = &dev->dev;
110 111
111 input_dev->evbit[0] = BIT(EV_SND); 112 input_dev->evbit[0] = BIT(EV_SND);
112 input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); 113 input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
@@ -136,7 +137,7 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev)
136static int __devexit ixp4xx_spkr_remove(struct platform_device *dev) 137static int __devexit ixp4xx_spkr_remove(struct platform_device *dev)
137{ 138{
138 struct input_dev *input_dev = platform_get_drvdata(dev); 139 struct input_dev *input_dev = platform_get_drvdata(dev);
139 unsigned int pin = (unsigned int) input_dev->private; 140 unsigned int pin = (unsigned int) input_get_drvdata(input_dev);
140 141
141 input_unregister_device(input_dev); 142 input_unregister_device(input_dev);
142 platform_set_drvdata(dev, NULL); 143 platform_set_drvdata(dev, NULL);
@@ -153,7 +154,7 @@ static int __devexit ixp4xx_spkr_remove(struct platform_device *dev)
153static void ixp4xx_spkr_shutdown(struct platform_device *dev) 154static void ixp4xx_spkr_shutdown(struct platform_device *dev)
154{ 155{
155 struct input_dev *input_dev = platform_get_drvdata(dev); 156 struct input_dev *input_dev = platform_get_drvdata(dev);
156 unsigned int pin = (unsigned int) input_dev->private; 157 unsigned int pin = (unsigned int) input_get_drvdata(input_dev);
157 158
158 /* turn off the speaker */ 159 /* turn off the speaker */
159 disable_irq(IRQ_IXP4XX_TIMER2); 160 disable_irq(IRQ_IXP4XX_TIMER2);
diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c
index 8d6c3837bad..e9f26e766b4 100644
--- a/drivers/input/misc/m68kspkr.c
+++ b/drivers/input/misc/m68kspkr.c
@@ -63,7 +63,7 @@ static int __devinit m68kspkr_probe(struct platform_device *dev)
63 input_dev->id.vendor = 0x001f; 63 input_dev->id.vendor = 0x001f;
64 input_dev->id.product = 0x0001; 64 input_dev->id.product = 0x0001;
65 input_dev->id.version = 0x0100; 65 input_dev->id.version = 0x0100;
66 input_dev->cdev.dev = &dev->dev; 66 input_dev->dev.parent = &dev->dev;
67 67
68 input_dev->evbit[0] = BIT(EV_SND); 68 input_dev->evbit[0] = BIT(EV_SND);
69 input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); 69 input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
index afd322185bb..31989dcd922 100644
--- a/drivers/input/misc/pcspkr.c
+++ b/drivers/input/misc/pcspkr.c
@@ -78,7 +78,7 @@ static int __devinit pcspkr_probe(struct platform_device *dev)
78 pcspkr_dev->id.vendor = 0x001f; 78 pcspkr_dev->id.vendor = 0x001f;
79 pcspkr_dev->id.product = 0x0001; 79 pcspkr_dev->id.product = 0x0001;
80 pcspkr_dev->id.version = 0x0100; 80 pcspkr_dev->id.version = 0x0100;
81 pcspkr_dev->cdev.dev = &dev->dev; 81 pcspkr_dev->dev.parent = &dev->dev;
82 82
83 pcspkr_dev->evbit[0] = BIT(EV_SND); 83 pcspkr_dev->evbit[0] = BIT(EV_SND);
84 pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); 84 pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index 106c94f33b9..e36ec1d92be 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -28,7 +28,7 @@ struct sparcspkr_state {
28 28
29static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 29static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
30{ 30{
31 struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); 31 struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent);
32 unsigned int count = 0; 32 unsigned int count = 0;
33 unsigned long flags; 33 unsigned long flags;
34 34
@@ -61,7 +61,7 @@ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned in
61 61
62static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 62static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
63{ 63{
64 struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); 64 struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent);
65 unsigned int count = 0; 65 unsigned int count = 0;
66 unsigned long flags; 66 unsigned long flags;
67 67
@@ -113,7 +113,7 @@ static int __devinit sparcspkr_probe(struct device *dev)
113 input_dev->id.vendor = 0x001f; 113 input_dev->id.vendor = 0x001f;
114 input_dev->id.product = 0x0001; 114 input_dev->id.product = 0x0001;
115 input_dev->id.version = 0x0100; 115 input_dev->id.version = 0x0100;
116 input_dev->cdev.dev = dev; 116 input_dev->dev.parent = dev;
117 117
118 input_dev->evbit[0] = BIT(EV_SND); 118 input_dev->evbit[0] = BIT(EV_SND);
119 input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); 119 input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 42556232c52..031467eadd3 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -41,9 +41,7 @@
41 41
42static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 42static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
43{ 43{
44 struct uinput_device *udev; 44 struct uinput_device *udev = input_get_drvdata(dev);
45
46 udev = dev->private;
47 45
48 udev->buff[udev->head].type = type; 46 udev->buff[udev->head].type = type;
49 udev->buff[udev->head].code = code; 47 udev->buff[udev->head].code = code;
@@ -136,7 +134,7 @@ static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *eff
136 request.u.upload.effect = effect; 134 request.u.upload.effect = effect;
137 request.u.upload.old = old; 135 request.u.upload.old = old;
138 136
139 retval = uinput_request_reserve_slot(dev->private, &request); 137 retval = uinput_request_reserve_slot(input_get_drvdata(dev), &request);
140 if (!retval) 138 if (!retval)
141 retval = uinput_request_submit(dev, &request); 139 retval = uinput_request_submit(dev, &request);
142 140
@@ -156,7 +154,7 @@ static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
156 request.code = UI_FF_ERASE; 154 request.code = UI_FF_ERASE;
157 request.u.effect_id = effect_id; 155 request.u.effect_id = effect_id;
158 156
159 retval = uinput_request_reserve_slot(dev->private, &request); 157 retval = uinput_request_reserve_slot(input_get_drvdata(dev), &request);
160 if (!retval) 158 if (!retval)
161 retval = uinput_request_submit(dev, &request); 159 retval = uinput_request_submit(dev, &request);
162 160
@@ -274,7 +272,7 @@ static int uinput_allocate_device(struct uinput_device *udev)
274 return -ENOMEM; 272 return -ENOMEM;
275 273
276 udev->dev->event = uinput_dev_event; 274 udev->dev->event = uinput_dev_event;
277 udev->dev->private = udev; 275 input_set_drvdata(udev->dev, udev);
278 276
279 return 0; 277 return 0;
280} 278}
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index e1183aeb8ed..961aad7a047 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -50,7 +50,7 @@
50MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>"); 50MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
51MODULE_DESCRIPTION("Wistron laptop button driver"); 51MODULE_DESCRIPTION("Wistron laptop button driver");
52MODULE_LICENSE("GPL v2"); 52MODULE_LICENSE("GPL v2");
53MODULE_VERSION("0.1"); 53MODULE_VERSION("0.2");
54 54
55static int force; /* = 0; */ 55static int force; /* = 0; */
56module_param(force, bool, 0); 56module_param(force, bool, 0);
@@ -58,7 +58,7 @@ MODULE_PARM_DESC(force, "Load even if computer is not in database");
58 58
59static char *keymap_name; /* = NULL; */ 59static char *keymap_name; /* = NULL; */
60module_param_named(keymap, keymap_name, charp, 0); 60module_param_named(keymap, keymap_name, charp, 0);
61MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected"); 61MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected [generic, 1557/MS2141]");
62 62
63static struct platform_device *wistron_device; 63static struct platform_device *wistron_device;
64 64
@@ -233,10 +233,20 @@ static void bios_set_state(u8 subsys, int enable)
233struct key_entry { 233struct key_entry {
234 char type; /* See KE_* below */ 234 char type; /* See KE_* below */
235 u8 code; 235 u8 code;
236 unsigned keycode; /* For KE_KEY */ 236 union {
237 u16 keycode; /* For KE_KEY */
238 struct { /* For KE_SW */
239 u8 code;
240 u8 value;
241 } sw;
242 };
237}; 243};
238 244
239enum { KE_END, KE_KEY, KE_WIFI, KE_BLUETOOTH }; 245enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH };
246
247#define FE_MAIL_LED 0x01
248#define FE_WIFI_LED 0x02
249#define FE_UNTESTED 0x80
240 250
241static const struct key_entry *keymap; /* = NULL; Current key map */ 251static const struct key_entry *keymap; /* = NULL; Current key map */
242static int have_wifi; 252static int have_wifi;
@@ -256,93 +266,341 @@ static int __init dmi_matched(struct dmi_system_id *dmi)
256 return 1; 266 return 1;
257} 267}
258 268
259static struct key_entry keymap_empty[] = { 269static struct key_entry keymap_empty[] __initdata = {
260 { KE_END, 0 } 270 { KE_END, 0 }
261}; 271};
262 272
263static struct key_entry keymap_fs_amilo_pro_v2000[] = { 273static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = {
264 { KE_KEY, 0x01, KEY_HELP }, 274 { KE_KEY, 0x01, {KEY_HELP} },
265 { KE_KEY, 0x11, KEY_PROG1 }, 275 { KE_KEY, 0x11, {KEY_PROG1} },
266 { KE_KEY, 0x12, KEY_PROG2 }, 276 { KE_KEY, 0x12, {KEY_PROG2} },
267 { KE_WIFI, 0x30, 0 }, 277 { KE_WIFI, 0x30 },
268 { KE_KEY, 0x31, KEY_MAIL }, 278 { KE_KEY, 0x31, {KEY_MAIL} },
269 { KE_KEY, 0x36, KEY_WWW }, 279 { KE_KEY, 0x36, {KEY_WWW} },
270 { KE_END, 0 } 280 { KE_END, 0 }
271}; 281};
272 282
273static struct key_entry keymap_fujitsu_n3510[] = { 283static struct key_entry keymap_fujitsu_n3510[] __initdata = {
274 { KE_KEY, 0x11, KEY_PROG1 }, 284 { KE_KEY, 0x11, {KEY_PROG1} },
275 { KE_KEY, 0x12, KEY_PROG2 }, 285 { KE_KEY, 0x12, {KEY_PROG2} },
276 { KE_KEY, 0x36, KEY_WWW }, 286 { KE_KEY, 0x36, {KEY_WWW} },
277 { KE_KEY, 0x31, KEY_MAIL }, 287 { KE_KEY, 0x31, {KEY_MAIL} },
278 { KE_KEY, 0x71, KEY_STOPCD }, 288 { KE_KEY, 0x71, {KEY_STOPCD} },
279 { KE_KEY, 0x72, KEY_PLAYPAUSE }, 289 { KE_KEY, 0x72, {KEY_PLAYPAUSE} },
280 { KE_KEY, 0x74, KEY_REWIND }, 290 { KE_KEY, 0x74, {KEY_REWIND} },
281 { KE_KEY, 0x78, KEY_FORWARD }, 291 { KE_KEY, 0x78, {KEY_FORWARD} },
282 { KE_END, 0 } 292 { KE_END, 0 }
283}; 293};
284 294
285static struct key_entry keymap_wistron_ms2111[] = { 295static struct key_entry keymap_wistron_ms2111[] __initdata = {
286 { KE_KEY, 0x11, KEY_PROG1 }, 296 { KE_KEY, 0x11, {KEY_PROG1} },
287 { KE_KEY, 0x12, KEY_PROG2 }, 297 { KE_KEY, 0x12, {KEY_PROG2} },
288 { KE_KEY, 0x13, KEY_PROG3 }, 298 { KE_KEY, 0x13, {KEY_PROG3} },
289 { KE_KEY, 0x31, KEY_MAIL }, 299 { KE_KEY, 0x31, {KEY_MAIL} },
290 { KE_KEY, 0x36, KEY_WWW }, 300 { KE_KEY, 0x36, {KEY_WWW} },
291 { KE_END, 0 } 301 { KE_END, FE_MAIL_LED }
302};
303
304static struct key_entry keymap_wistron_md40100[] __initdata = {
305 { KE_KEY, 0x01, {KEY_HELP} },
306 { KE_KEY, 0x02, {KEY_CONFIG} },
307 { KE_KEY, 0x31, {KEY_MAIL} },
308 { KE_KEY, 0x36, {KEY_WWW} },
309 { KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} }, /* Display on/off */
310 { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED }
292}; 311};
293 312
294static struct key_entry keymap_wistron_ms2141[] = { 313static struct key_entry keymap_wistron_ms2141[] __initdata = {
295 { KE_KEY, 0x11, KEY_PROG1 }, 314 { KE_KEY, 0x11, {KEY_PROG1} },
296 { KE_KEY, 0x12, KEY_PROG2 }, 315 { KE_KEY, 0x12, {KEY_PROG2} },
297 { KE_WIFI, 0x30, 0 }, 316 { KE_WIFI, 0x30 },
298 { KE_KEY, 0x22, KEY_REWIND }, 317 { KE_KEY, 0x22, {KEY_REWIND} },
299 { KE_KEY, 0x23, KEY_FORWARD }, 318 { KE_KEY, 0x23, {KEY_FORWARD} },
300 { KE_KEY, 0x24, KEY_PLAYPAUSE }, 319 { KE_KEY, 0x24, {KEY_PLAYPAUSE} },
301 { KE_KEY, 0x25, KEY_STOPCD }, 320 { KE_KEY, 0x25, {KEY_STOPCD} },
302 { KE_KEY, 0x31, KEY_MAIL }, 321 { KE_KEY, 0x31, {KEY_MAIL} },
303 { KE_KEY, 0x36, KEY_WWW }, 322 { KE_KEY, 0x36, {KEY_WWW} },
304 { KE_END, 0 } 323 { KE_END, 0 }
305}; 324};
306 325
307static struct key_entry keymap_acer_aspire_1500[] = { 326static struct key_entry keymap_acer_aspire_1500[] __initdata = {
308 { KE_KEY, 0x11, KEY_PROG1 }, 327 { KE_KEY, 0x01, {KEY_HELP} },
309 { KE_KEY, 0x12, KEY_PROG2 }, 328 { KE_KEY, 0x03, {KEY_POWER} },
310 { KE_WIFI, 0x30, 0 }, 329 { KE_KEY, 0x11, {KEY_PROG1} },
311 { KE_KEY, 0x31, KEY_MAIL }, 330 { KE_KEY, 0x12, {KEY_PROG2} },
312 { KE_KEY, 0x36, KEY_WWW }, 331 { KE_WIFI, 0x30 },
313 { KE_BLUETOOTH, 0x44, 0 }, 332 { KE_KEY, 0x31, {KEY_MAIL} },
314 { KE_END, 0 } 333 { KE_KEY, 0x36, {KEY_WWW} },
334 { KE_KEY, 0x49, {KEY_CONFIG} },
335 { KE_BLUETOOTH, 0x44 },
336 { KE_END, FE_UNTESTED }
315}; 337};
316 338
317static struct key_entry keymap_acer_travelmate_240[] = { 339static struct key_entry keymap_acer_aspire_1600[] __initdata = {
318 { KE_KEY, 0x31, KEY_MAIL }, 340 { KE_KEY, 0x01, {KEY_HELP} },
319 { KE_KEY, 0x36, KEY_WWW }, 341 { KE_KEY, 0x03, {KEY_POWER} },
320 { KE_KEY, 0x11, KEY_PROG1 }, 342 { KE_KEY, 0x08, {KEY_MUTE} },
321 { KE_KEY, 0x12, KEY_PROG2 }, 343 { KE_KEY, 0x11, {KEY_PROG1} },
322 { KE_BLUETOOTH, 0x44, 0 }, 344 { KE_KEY, 0x12, {KEY_PROG2} },
323 { KE_WIFI, 0x30, 0 }, 345 { KE_KEY, 0x13, {KEY_PROG3} },
324 { KE_END, 0 } 346 { KE_KEY, 0x31, {KEY_MAIL} },
347 { KE_KEY, 0x36, {KEY_WWW} },
348 { KE_KEY, 0x49, {KEY_CONFIG} },
349 { KE_WIFI, 0x30 },
350 { KE_BLUETOOTH, 0x44 },
351 { KE_END, FE_MAIL_LED | FE_UNTESTED }
352};
353
354/* 3020 has been tested */
355static struct key_entry keymap_acer_aspire_5020[] __initdata = {
356 { KE_KEY, 0x01, {KEY_HELP} },
357 { KE_KEY, 0x03, {KEY_POWER} },
358 { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */
359 { KE_KEY, 0x11, {KEY_PROG1} },
360 { KE_KEY, 0x12, {KEY_PROG2} },
361 { KE_KEY, 0x31, {KEY_MAIL} },
362 { KE_KEY, 0x36, {KEY_WWW} },
363 { KE_KEY, 0x6a, {KEY_CONFIG} },
364 { KE_WIFI, 0x30 },
365 { KE_BLUETOOTH, 0x44 },
366 { KE_END, FE_MAIL_LED | FE_UNTESTED }
367};
368
369static struct key_entry keymap_acer_travelmate_2410[] __initdata = {
370 { KE_KEY, 0x01, {KEY_HELP} },
371 { KE_KEY, 0x6d, {KEY_POWER} },
372 { KE_KEY, 0x11, {KEY_PROG1} },
373 { KE_KEY, 0x12, {KEY_PROG2} },
374 { KE_KEY, 0x31, {KEY_MAIL} },
375 { KE_KEY, 0x36, {KEY_WWW} },
376 { KE_KEY, 0x6a, {KEY_CONFIG} },
377 { KE_WIFI, 0x30 },
378 { KE_BLUETOOTH, 0x44 },
379 { KE_END, FE_MAIL_LED | FE_UNTESTED }
380};
381
382static struct key_entry keymap_acer_travelmate_110[] __initdata = {
383 { KE_KEY, 0x01, {KEY_HELP} },
384 { KE_KEY, 0x02, {KEY_CONFIG} },
385 { KE_KEY, 0x03, {KEY_POWER} },
386 { KE_KEY, 0x08, {KEY_MUTE} },
387 { KE_KEY, 0x11, {KEY_PROG1} },
388 { KE_KEY, 0x12, {KEY_PROG2} },
389 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
390 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
391 { KE_KEY, 0x31, {KEY_MAIL} },
392 { KE_KEY, 0x36, {KEY_WWW} },
393 { KE_SW, 0x4a, {.sw = {SW_LID, 1}} }, /* lid close */
394 { KE_SW, 0x4b, {.sw = {SW_LID, 0}} }, /* lid open */
395 { KE_WIFI, 0x30 },
396 { KE_END, FE_MAIL_LED | FE_UNTESTED }
397};
398
399static struct key_entry keymap_acer_travelmate_300[] __initdata = {
400 { KE_KEY, 0x01, {KEY_HELP} },
401 { KE_KEY, 0x02, {KEY_CONFIG} },
402 { KE_KEY, 0x03, {KEY_POWER} },
403 { KE_KEY, 0x08, {KEY_MUTE} },
404 { KE_KEY, 0x11, {KEY_PROG1} },
405 { KE_KEY, 0x12, {KEY_PROG2} },
406 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
407 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
408 { KE_KEY, 0x31, {KEY_MAIL} },
409 { KE_KEY, 0x36, {KEY_WWW} },
410 { KE_WIFI, 0x30 },
411 { KE_BLUETOOTH, 0x44 },
412 { KE_END, FE_MAIL_LED | FE_UNTESTED }
325}; 413};
326 414
327static struct key_entry keymap_aopen_1559as[] = { 415static struct key_entry keymap_acer_travelmate_380[] __initdata = {
328 { KE_KEY, 0x01, KEY_HELP }, 416 { KE_KEY, 0x01, {KEY_HELP} },
329 { KE_KEY, 0x06, KEY_PROG3 }, 417 { KE_KEY, 0x02, {KEY_CONFIG} },
330 { KE_KEY, 0x11, KEY_PROG1 }, 418 { KE_KEY, 0x03, {KEY_POWER} }, /* not 370 */
331 { KE_KEY, 0x12, KEY_PROG2 }, 419 { KE_KEY, 0x11, {KEY_PROG1} },
332 { KE_WIFI, 0x30, 0 }, 420 { KE_KEY, 0x12, {KEY_PROG2} },
333 { KE_KEY, 0x31, KEY_MAIL }, 421 { KE_KEY, 0x13, {KEY_PROG3} },
334 { KE_KEY, 0x36, KEY_WWW }, 422 { KE_KEY, 0x31, {KEY_MAIL} },
423 { KE_KEY, 0x36, {KEY_WWW} },
424 { KE_WIFI, 0x30 },
425 { KE_END, FE_MAIL_LED | FE_UNTESTED }
426};
427
428/* unusual map */
429static struct key_entry keymap_acer_travelmate_220[] __initdata = {
430 { KE_KEY, 0x01, {KEY_HELP} },
431 { KE_KEY, 0x02, {KEY_CONFIG} },
432 { KE_KEY, 0x11, {KEY_MAIL} },
433 { KE_KEY, 0x12, {KEY_WWW} },
434 { KE_KEY, 0x13, {KEY_PROG2} },
435 { KE_KEY, 0x31, {KEY_PROG1} },
436 { KE_END, FE_WIFI_LED | FE_UNTESTED }
437};
438
439static struct key_entry keymap_acer_travelmate_230[] __initdata = {
440 { KE_KEY, 0x01, {KEY_HELP} },
441 { KE_KEY, 0x02, {KEY_CONFIG} },
442 { KE_KEY, 0x11, {KEY_PROG1} },
443 { KE_KEY, 0x12, {KEY_PROG2} },
444 { KE_KEY, 0x31, {KEY_MAIL} },
445 { KE_KEY, 0x36, {KEY_WWW} },
446 { KE_END, FE_WIFI_LED | FE_UNTESTED }
447};
448
449static struct key_entry keymap_acer_travelmate_240[] __initdata = {
450 { KE_KEY, 0x01, {KEY_HELP} },
451 { KE_KEY, 0x02, {KEY_CONFIG} },
452 { KE_KEY, 0x03, {KEY_POWER} },
453 { KE_KEY, 0x08, {KEY_MUTE} },
454 { KE_KEY, 0x31, {KEY_MAIL} },
455 { KE_KEY, 0x36, {KEY_WWW} },
456 { KE_KEY, 0x11, {KEY_PROG1} },
457 { KE_KEY, 0x12, {KEY_PROG2} },
458 { KE_BLUETOOTH, 0x44 },
459 { KE_WIFI, 0x30 },
460 { KE_END, FE_UNTESTED }
461};
462
463static struct key_entry keymap_acer_travelmate_350[] __initdata = {
464 { KE_KEY, 0x01, {KEY_HELP} },
465 { KE_KEY, 0x02, {KEY_CONFIG} },
466 { KE_KEY, 0x11, {KEY_PROG1} },
467 { KE_KEY, 0x12, {KEY_PROG2} },
468 { KE_KEY, 0x13, {KEY_MAIL} },
469 { KE_KEY, 0x14, {KEY_PROG3} },
470 { KE_KEY, 0x15, {KEY_WWW} },
471 { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED }
472};
473
474static struct key_entry keymap_acer_travelmate_360[] __initdata = {
475 { KE_KEY, 0x01, {KEY_HELP} },
476 { KE_KEY, 0x02, {KEY_CONFIG} },
477 { KE_KEY, 0x11, {KEY_PROG1} },
478 { KE_KEY, 0x12, {KEY_PROG2} },
479 { KE_KEY, 0x13, {KEY_MAIL} },
480 { KE_KEY, 0x14, {KEY_PROG3} },
481 { KE_KEY, 0x15, {KEY_WWW} },
482 { KE_KEY, 0x40, {KEY_WLAN} },
483 { KE_END, FE_WIFI_LED | FE_UNTESTED } /* no mail led */
484};
485
486/* Wifi subsystem only activates the led. Therefore we need to pass
487 * wifi event as a normal key, then userspace can really change the wifi state.
488 * TODO we need to export led state to userspace (wifi and mail) */
489static struct key_entry keymap_acer_travelmate_610[] __initdata = {
490 { KE_KEY, 0x01, {KEY_HELP} },
491 { KE_KEY, 0x02, {KEY_CONFIG} },
492 { KE_KEY, 0x11, {KEY_PROG1} },
493 { KE_KEY, 0x12, {KEY_PROG2} },
494 { KE_KEY, 0x13, {KEY_PROG3} },
495 { KE_KEY, 0x14, {KEY_MAIL} },
496 { KE_KEY, 0x15, {KEY_WWW} },
497 { KE_KEY, 0x40, {KEY_WLAN} },
498 { KE_END, FE_MAIL_LED | FE_WIFI_LED }
499};
500
501static struct key_entry keymap_acer_travelmate_630[] __initdata = {
502 { KE_KEY, 0x01, {KEY_HELP} },
503 { KE_KEY, 0x02, {KEY_CONFIG} },
504 { KE_KEY, 0x03, {KEY_POWER} },
505 { KE_KEY, 0x08, {KEY_MUTE} }, /* not 620 */
506 { KE_KEY, 0x11, {KEY_PROG1} },
507 { KE_KEY, 0x12, {KEY_PROG2} },
508 { KE_KEY, 0x13, {KEY_PROG3} },
509 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
510 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
511 { KE_KEY, 0x31, {KEY_MAIL} },
512 { KE_KEY, 0x36, {KEY_WWW} },
513 { KE_WIFI, 0x30 },
514 { KE_END, FE_MAIL_LED | FE_UNTESTED }
515};
516
517static struct key_entry keymap_aopen_1559as[] __initdata = {
518 { KE_KEY, 0x01, {KEY_HELP} },
519 { KE_KEY, 0x06, {KEY_PROG3} },
520 { KE_KEY, 0x11, {KEY_PROG1} },
521 { KE_KEY, 0x12, {KEY_PROG2} },
522 { KE_WIFI, 0x30 },
523 { KE_KEY, 0x31, {KEY_MAIL} },
524 { KE_KEY, 0x36, {KEY_WWW} },
335 { KE_END, 0 }, 525 { KE_END, 0 },
336}; 526};
337 527
338static struct key_entry keymap_fs_amilo_d88x0[] = { 528static struct key_entry keymap_fs_amilo_d88x0[] __initdata = {
339 { KE_KEY, 0x01, KEY_HELP }, 529 { KE_KEY, 0x01, {KEY_HELP} },
340 { KE_KEY, 0x08, KEY_MUTE }, 530 { KE_KEY, 0x08, {KEY_MUTE} },
341 { KE_KEY, 0x31, KEY_MAIL }, 531 { KE_KEY, 0x31, {KEY_MAIL} },
342 { KE_KEY, 0x36, KEY_WWW }, 532 { KE_KEY, 0x36, {KEY_WWW} },
343 { KE_KEY, 0x11, KEY_PROG1 }, 533 { KE_KEY, 0x11, {KEY_PROG1} },
344 { KE_KEY, 0x12, KEY_PROG2 }, 534 { KE_KEY, 0x12, {KEY_PROG2} },
345 { KE_KEY, 0x13, KEY_PROG3 }, 535 { KE_KEY, 0x13, {KEY_PROG3} },
536 { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED }
537};
538
539static struct key_entry keymap_wistron_md2900[] __initdata = {
540 { KE_KEY, 0x01, {KEY_HELP} },
541 { KE_KEY, 0x02, {KEY_CONFIG} },
542 { KE_KEY, 0x11, {KEY_PROG1} },
543 { KE_KEY, 0x12, {KEY_PROG2} },
544 { KE_KEY, 0x31, {KEY_MAIL} },
545 { KE_KEY, 0x36, {KEY_WWW} },
546 { KE_WIFI, 0x30 },
547 { KE_END, FE_MAIL_LED | FE_UNTESTED }
548};
549
550static struct key_entry keymap_wistron_md96500[] __initdata = {
551 { KE_KEY, 0x01, {KEY_HELP} },
552 { KE_KEY, 0x02, {KEY_CONFIG} },
553 { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */
554 { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Display on/off */
555 { KE_KEY, 0x08, {KEY_MUTE} },
556 { KE_KEY, 0x11, {KEY_PROG1} },
557 { KE_KEY, 0x12, {KEY_PROG2} },
558 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
559 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
560 { KE_KEY, 0x22, {KEY_REWIND} },
561 { KE_KEY, 0x23, {KEY_FORWARD} },
562 { KE_KEY, 0x24, {KEY_PLAYPAUSE} },
563 { KE_KEY, 0x25, {KEY_STOPCD} },
564 { KE_KEY, 0x31, {KEY_MAIL} },
565 { KE_KEY, 0x36, {KEY_WWW} },
566 { KE_WIFI, 0x30 },
567 { KE_BLUETOOTH, 0x44 },
568 { KE_END, FE_UNTESTED }
569};
570
571static struct key_entry keymap_wistron_generic[] __initdata = {
572 { KE_KEY, 0x01, {KEY_HELP} },
573 { KE_KEY, 0x02, {KEY_CONFIG} },
574 { KE_KEY, 0x03, {KEY_POWER} },
575 { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */
576 { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Display on/off */
577 { KE_KEY, 0x08, {KEY_MUTE} },
578 { KE_KEY, 0x11, {KEY_PROG1} },
579 { KE_KEY, 0x12, {KEY_PROG2} },
580 { KE_KEY, 0x13, {KEY_PROG3} },
581 { KE_KEY, 0x14, {KEY_MAIL} },
582 { KE_KEY, 0x15, {KEY_WWW} },
583 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
584 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
585 { KE_KEY, 0x22, {KEY_REWIND} },
586 { KE_KEY, 0x23, {KEY_FORWARD} },
587 { KE_KEY, 0x24, {KEY_PLAYPAUSE} },
588 { KE_KEY, 0x25, {KEY_STOPCD} },
589 { KE_KEY, 0x31, {KEY_MAIL} },
590 { KE_KEY, 0x36, {KEY_WWW} },
591 { KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} }, /* Display on/off */
592 { KE_KEY, 0x40, {KEY_WLAN} },
593 { KE_KEY, 0x49, {KEY_CONFIG} },
594 { KE_SW, 0x4a, {.sw = {SW_LID, 1}} }, /* lid close */
595 { KE_SW, 0x4b, {.sw = {SW_LID, 0}} }, /* lid open */
596 { KE_KEY, 0x6a, {KEY_CONFIG} },
597 { KE_KEY, 0x6d, {KEY_POWER} },
598 { KE_KEY, 0x71, {KEY_STOPCD} },
599 { KE_KEY, 0x72, {KEY_PLAYPAUSE} },
600 { KE_KEY, 0x74, {KEY_REWIND} },
601 { KE_KEY, 0x78, {KEY_FORWARD} },
602 { KE_WIFI, 0x30 },
603 { KE_BLUETOOTH, 0x44 },
346 { KE_END, 0 } 604 { KE_END, 0 }
347}; 605};
348 606
@@ -390,6 +648,133 @@ static struct dmi_system_id dmi_ids[] __initdata = {
390 }, 648 },
391 { 649 {
392 .callback = dmi_matched, 650 .callback = dmi_matched,
651 .ident = "Acer Aspire 1600",
652 .matches = {
653 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
654 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"),
655 },
656 .driver_data = keymap_acer_aspire_1600
657 },
658 {
659 .callback = dmi_matched,
660 .ident = "Acer Aspire 3020",
661 .matches = {
662 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
663 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"),
664 },
665 .driver_data = keymap_acer_aspire_5020
666 },
667 {
668 .callback = dmi_matched,
669 .ident = "Acer Aspire 5020",
670 .matches = {
671 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
672 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"),
673 },
674 .driver_data = keymap_acer_aspire_5020
675 },
676 {
677 .callback = dmi_matched,
678 .ident = "Acer TravelMate 2100",
679 .matches = {
680 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
681 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"),
682 },
683 .driver_data = keymap_acer_aspire_5020
684 },
685 {
686 .callback = dmi_matched,
687 .ident = "Acer TravelMate 2410",
688 .matches = {
689 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
690 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"),
691 },
692 .driver_data = keymap_acer_travelmate_2410
693 },
694 {
695 .callback = dmi_matched,
696 .ident = "Acer TravelMate C300",
697 .matches = {
698 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
699 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"),
700 },
701 .driver_data = keymap_acer_travelmate_300
702 },
703 {
704 .callback = dmi_matched,
705 .ident = "Acer TravelMate C100",
706 .matches = {
707 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
708 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"),
709 },
710 .driver_data = keymap_acer_travelmate_300
711 },
712 {
713 .callback = dmi_matched,
714 .ident = "Acer TravelMate C110",
715 .matches = {
716 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
717 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"),
718 },
719 .driver_data = keymap_acer_travelmate_110
720 },
721 {
722 .callback = dmi_matched,
723 .ident = "Acer TravelMate 380",
724 .matches = {
725 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
726 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"),
727 },
728 .driver_data = keymap_acer_travelmate_380
729 },
730 {
731 .callback = dmi_matched,
732 .ident = "Acer TravelMate 370",
733 .matches = {
734 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
735 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"),
736 },
737 .driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */
738 },
739 {
740 .callback = dmi_matched,
741 .ident = "Acer TravelMate 220",
742 .matches = {
743 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
744 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"),
745 },
746 .driver_data = keymap_acer_travelmate_220
747 },
748 {
749 .callback = dmi_matched,
750 .ident = "Acer TravelMate 260",
751 .matches = {
752 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
753 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"),
754 },
755 .driver_data = keymap_acer_travelmate_220
756 },
757 {
758 .callback = dmi_matched,
759 .ident = "Acer TravelMate 230",
760 .matches = {
761 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
762 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"),
763 /* acerhk looks for "TravelMate F4..." ?! */
764 },
765 .driver_data = keymap_acer_travelmate_230
766 },
767 {
768 .callback = dmi_matched,
769 .ident = "Acer TravelMate 280",
770 .matches = {
771 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
772 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"),
773 },
774 .driver_data = keymap_acer_travelmate_230
775 },
776 {
777 .callback = dmi_matched,
393 .ident = "Acer TravelMate 240", 778 .ident = "Acer TravelMate 240",
394 .matches = { 779 .matches = {
395 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 780 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -399,6 +784,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {
399 }, 784 },
400 { 785 {
401 .callback = dmi_matched, 786 .callback = dmi_matched,
787 .ident = "Acer TravelMate 250",
788 .matches = {
789 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
790 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"),
791 },
792 .driver_data = keymap_acer_travelmate_240
793 },
794 {
795 .callback = dmi_matched,
402 .ident = "Acer TravelMate 2424NWXCi", 796 .ident = "Acer TravelMate 2424NWXCi",
403 .matches = { 797 .matches = {
404 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 798 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -408,6 +802,51 @@ static struct dmi_system_id dmi_ids[] __initdata = {
408 }, 802 },
409 { 803 {
410 .callback = dmi_matched, 804 .callback = dmi_matched,
805 .ident = "Acer TravelMate 350",
806 .matches = {
807 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
808 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"),
809 },
810 .driver_data = keymap_acer_travelmate_350
811 },
812 {
813 .callback = dmi_matched,
814 .ident = "Acer TravelMate 360",
815 .matches = {
816 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
817 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
818 },
819 .driver_data = keymap_acer_travelmate_360
820 },
821 {
822 .callback = dmi_matched,
823 .ident = "Acer TravelMate 610",
824 .matches = {
825 DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
826 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"),
827 },
828 .driver_data = keymap_acer_travelmate_610
829 },
830 {
831 .callback = dmi_matched,
832 .ident = "Acer TravelMate 620",
833 .matches = {
834 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
835 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"),
836 },
837 .driver_data = keymap_acer_travelmate_630
838 },
839 {
840 .callback = dmi_matched,
841 .ident = "Acer TravelMate 630",
842 .matches = {
843 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
844 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"),
845 },
846 .driver_data = keymap_acer_travelmate_630
847 },
848 {
849 .callback = dmi_matched,
411 .ident = "AOpen 1559AS", 850 .ident = "AOpen 1559AS",
412 .matches = { 851 .matches = {
413 DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), 852 DMI_MATCH(DMI_PRODUCT_NAME, "E2U"),
@@ -426,6 +865,51 @@ static struct dmi_system_id dmi_ids[] __initdata = {
426 }, 865 },
427 { 866 {
428 .callback = dmi_matched, 867 .callback = dmi_matched,
868 .ident = "Medion MD 40100",
869 .matches = {
870 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
871 DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"),
872 },
873 .driver_data = keymap_wistron_md40100
874 },
875 {
876 .callback = dmi_matched,
877 .ident = "Medion MD 2900",
878 .matches = {
879 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
880 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"),
881 },
882 .driver_data = keymap_wistron_md2900
883 },
884 {
885 .callback = dmi_matched,
886 .ident = "Medion MD 96500",
887 .matches = {
888 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
889 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"),
890 },
891 .driver_data = keymap_wistron_md96500
892 },
893 {
894 .callback = dmi_matched,
895 .ident = "Medion MD 95400",
896 .matches = {
897 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
898 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"),
899 },
900 .driver_data = keymap_wistron_md96500
901 },
902 {
903 .callback = dmi_matched,
904 .ident = "Fujitsu Siemens Amilo D7820",
905 .matches = {
906 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */
907 DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"),
908 },
909 .driver_data = keymap_fs_amilo_d88x0
910 },
911 {
912 .callback = dmi_matched,
429 .ident = "Fujitsu Siemens Amilo D88x0", 913 .ident = "Fujitsu Siemens Amilo D88x0",
430 .matches = { 914 .matches = {
431 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 915 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
@@ -436,17 +920,39 @@ static struct dmi_system_id dmi_ids[] __initdata = {
436 { NULL, } 920 { NULL, }
437}; 921};
438 922
923/* Copy the good keymap, as the original ones are free'd */
924static int __init copy_keymap(void)
925{
926 const struct key_entry *key;
927 struct key_entry *new_keymap;
928 unsigned int length = 1;
929
930 for (key = keymap; key->type != KE_END; key++)
931 length++;
932
933 new_keymap = kmalloc(length * sizeof(struct key_entry), GFP_KERNEL);
934 if (!new_keymap)
935 return -ENOMEM;
936
937 memcpy(new_keymap, keymap, length * sizeof(struct key_entry));
938 keymap = new_keymap;
939
940 return 0;
941}
942
439static int __init select_keymap(void) 943static int __init select_keymap(void)
440{ 944{
945 dmi_check_system(dmi_ids);
441 if (keymap_name != NULL) { 946 if (keymap_name != NULL) {
442 if (strcmp (keymap_name, "1557/MS2141") == 0) 947 if (strcmp (keymap_name, "1557/MS2141") == 0)
443 keymap = keymap_wistron_ms2141; 948 keymap = keymap_wistron_ms2141;
949 else if (strcmp (keymap_name, "generic") == 0)
950 keymap = keymap_wistron_generic;
444 else { 951 else {
445 printk(KERN_ERR "wistron_btns: Keymap unknown\n"); 952 printk(KERN_ERR "wistron_btns: Keymap unknown\n");
446 return -EINVAL; 953 return -EINVAL;
447 } 954 }
448 } 955 }
449 dmi_check_system(dmi_ids);
450 if (keymap == NULL) { 956 if (keymap == NULL) {
451 if (!force) { 957 if (!force) {
452 printk(KERN_ERR "wistron_btns: System unknown\n"); 958 printk(KERN_ERR "wistron_btns: System unknown\n");
@@ -454,7 +960,8 @@ static int __init select_keymap(void)
454 } 960 }
455 keymap = keymap_empty; 961 keymap = keymap_empty;
456 } 962 }
457 return 0; 963
964 return copy_keymap();
458} 965}
459 966
460 /* Input layer interface */ 967 /* Input layer interface */
@@ -476,12 +983,28 @@ static int __devinit setup_input_dev(void)
476 input_dev->cdev.dev = &wistron_device->dev; 983 input_dev->cdev.dev = &wistron_device->dev;
477 984
478 for (key = keymap; key->type != KE_END; key++) { 985 for (key = keymap; key->type != KE_END; key++) {
479 if (key->type == KE_KEY) { 986 switch (key->type) {
480 input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY); 987 case KE_KEY:
481 set_bit(key->keycode, input_dev->keybit); 988 set_bit(EV_KEY, input_dev->evbit);
989 set_bit(key->keycode, input_dev->keybit);
990 break;
991
992 case KE_SW:
993 set_bit(EV_SW, input_dev->evbit);
994 set_bit(key->sw.code, input_dev->swbit);
995 break;
996
997 default:
998 ;
482 } 999 }
483 } 1000 }
484 1001
1002 /* reads information flags on KE_END */
1003 if (key->code & FE_UNTESTED)
1004 printk(KERN_WARNING "Untested laptop multimedia keys, "
1005 "please report success or failure to eric.piel"
1006 "@tremplin-utc.net\n");
1007
485 error = input_register_device(input_dev); 1008 error = input_register_device(input_dev);
486 if (error) { 1009 if (error) {
487 input_free_device(input_dev); 1010 input_free_device(input_dev);
@@ -499,6 +1022,12 @@ static void report_key(unsigned keycode)
499 input_sync(input_dev); 1022 input_sync(input_dev);
500} 1023}
501 1024
1025static void report_switch(unsigned code, int value)
1026{
1027 input_report_switch(input_dev, code, value);
1028 input_sync(input_dev);
1029}
1030
502 /* Driver core */ 1031 /* Driver core */
503 1032
504static int wifi_enabled; 1033static int wifi_enabled;
@@ -519,6 +1048,10 @@ static void handle_key(u8 code)
519 report_key(key->keycode); 1048 report_key(key->keycode);
520 break; 1049 break;
521 1050
1051 case KE_SW:
1052 report_switch(key->sw.code, key->sw.value);
1053 break;
1054
522 case KE_WIFI: 1055 case KE_WIFI:
523 if (have_wifi) { 1056 if (have_wifi) {
524 wifi_enabled = !wifi_enabled; 1057 wifi_enabled = !wifi_enabled;
@@ -534,6 +1067,7 @@ static void handle_key(u8 code)
534 break; 1067 break;
535 1068
536 case KE_END: 1069 case KE_END:
1070 break;
537 default: 1071 default:
538 BUG(); 1072 BUG();
539 } 1073 }
@@ -690,6 +1224,7 @@ static void __exit wb_module_exit(void)
690 platform_device_unregister(wistron_device); 1224 platform_device_unregister(wistron_device);
691 platform_driver_unregister(&wistron_driver); 1225 platform_driver_unregister(&wistron_driver);
692 unmap_bios(); 1226 unmap_bios();
1227 kfree(keymap);
693} 1228}
694 1229
695module_init(wb_module_init); 1230module_init(wb_module_init);