aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 15:57:44 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 15:57:44 -0500
commit6e5565f949af1322f8f3d3f43d044645ae448499 (patch)
tree92868f6d3dcc6c105a0d35f9412f75c07139402e /drivers/input/misc
parente5a9e8e6890d9b9c7a0f25b03ffdaf28614a9a4c (diff)
parent03366e7b9bf1544cb0b98f1a5cd6d340654f486a (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (34 commits) Input: i8042 - non-x86 build fix Input: pxa27x_keypad - also enable on PXA3xx Input: pxa27x_keypad - add debounce_interval to the keypad platform data Input: pxa27x_keypad - use device resources for I/O memory mapping and IRQ Input: pxa27x_keypad - enable rotary encoders and direct keys Input: pxa27x_keypad - introduce pxa27x_keypad_config() Input: pxa27x_keypad - introduce driver structure and use KEY() to define matrix keys Input: pxa27x_keypad - remove pin configuration from the driver Input: pxa27x_keypad - rename the driver (was pxa27x_keyboard) Input: constify function pointer tables (seq_operations) Input: i8042 - add Fujitsu-Siemens Amilo Pro 2010 to nomux list Input: i8042 - enable DMI quirks on x86-64 Input: i8042 - add Dritek quirk for Acer Aspire 9110 Input: add input event to APM event bridge Input: mousedev - use BIT_MASK instead of BIT Input: remove duplicate includes Input: remove cdev from input_dev structure Input: remove duplicated headers in drivers/char/keyboard.c Input: i8042 - add Dritek keyboard extension quirk Input: add Tosa keyboard driver ...
Diffstat (limited to 'drivers/input/misc')
-rw-r--r--drivers/input/misc/Kconfig14
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/misc/apanel.c378
-rw-r--r--drivers/input/misc/ati_remote.c1
-rw-r--r--drivers/input/misc/atlas_btns.c39
-rw-r--r--drivers/input/misc/cobalt_btns.c73
-rw-r--r--drivers/input/misc/keyspan_remote.c119
7 files changed, 519 insertions, 106 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 8f5c7b90187d..8b10d9f23bef 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -40,6 +40,20 @@ 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_APANEL
44 tristate "Fujitsu Lifebook Application Panel buttons"
45 depends on X86
46 select I2C_I801
47 select INPUT_POLLDEV
48 select CHECK_SIGNATURE
49 help
50 Say Y here for support of the Application Panel buttons, used on
51 Fujitsu Lifebook. These are attached to the mainboard through
52 an SMBus interface managed by the I2C Intel ICH (i801) driver.
53
54 To compile this driver as a module, choose M here: the module will
55 be called apanel.
56
43config INPUT_IXP4XX_BEEPER 57config INPUT_IXP4XX_BEEPER
44 tristate "IXP4XX Beeper support" 58 tristate "IXP4XX Beeper support"
45 depends on ARCH_IXP4XX 59 depends on ARCH_IXP4XX
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 3585b5038418..ebd39f291d25 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
18obj-$(CONFIG_INPUT_YEALINK) += yealink.o 18obj-$(CONFIG_INPUT_YEALINK) += yealink.o
19obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o 19obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
20obj-$(CONFIG_INPUT_UINPUT) += uinput.o 20obj-$(CONFIG_INPUT_UINPUT) += uinput.o
21obj-$(CONFIG_INPUT_APANEL) += apanel.o
diff --git a/drivers/input/misc/apanel.c b/drivers/input/misc/apanel.c
new file mode 100644
index 000000000000..9531d8c7444f
--- /dev/null
+++ b/drivers/input/misc/apanel.c
@@ -0,0 +1,378 @@
1/*
2 * Fujitsu Lifebook Application Panel button drive
3 *
4 * Copyright (C) 2007 Stephen Hemminger <shemminger@linux-foundation.org>
5 * Copyright (C) 2001-2003 Jochen Eisinger <jochen@penguin-breeder.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * Many Fujitsu Lifebook laptops have a small panel of buttons that are
12 * accessible via the i2c/smbus interface. This driver polls those
13 * buttons and generates input events.
14 *
15 * For more details see:
16 * http://apanel.sourceforge.net/tech.php
17 */
18
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/ioport.h>
22#include <linux/io.h>
23#include <linux/module.h>
24#include <linux/input-polldev.h>
25#include <linux/i2c.h>
26#include <linux/workqueue.h>
27#include <linux/leds.h>
28
29#define APANEL_NAME "Fujitsu Application Panel"
30#define APANEL_VERSION "1.3.1"
31#define APANEL "apanel"
32
33/* How often we poll keys - msecs */
34#define POLL_INTERVAL_DEFAULT 1000
35
36/* Magic constants in BIOS that tell about buttons */
37enum apanel_devid {
38 APANEL_DEV_NONE = 0,
39 APANEL_DEV_APPBTN = 1,
40 APANEL_DEV_CDBTN = 2,
41 APANEL_DEV_LCD = 3,
42 APANEL_DEV_LED = 4,
43
44 APANEL_DEV_MAX,
45};
46
47enum apanel_chip {
48 CHIP_NONE = 0,
49 CHIP_OZ992C = 1,
50 CHIP_OZ163T = 2,
51 CHIP_OZ711M3 = 4,
52};
53
54/* Result of BIOS snooping/probing -- what features are supported */
55static enum apanel_chip device_chip[APANEL_DEV_MAX];
56
57#define MAX_PANEL_KEYS 12
58
59struct apanel {
60 struct input_polled_dev *ipdev;
61 struct i2c_client client;
62 unsigned short keymap[MAX_PANEL_KEYS];
63 u16 nkeys;
64 u16 led_bits;
65 struct work_struct led_work;
66 struct led_classdev mail_led;
67};
68
69
70static int apanel_probe(struct i2c_adapter *, int, int);
71
72/* for now, we only support one address */
73static unsigned short normal_i2c[] = {0, I2C_CLIENT_END};
74static unsigned short ignore = I2C_CLIENT_END;
75static struct i2c_client_address_data addr_data = {
76 .normal_i2c = normal_i2c,
77 .probe = &ignore,
78 .ignore = &ignore,
79};
80
81static void report_key(struct input_dev *input, unsigned keycode)
82{
83 pr_debug(APANEL ": report key %#x\n", keycode);
84 input_report_key(input, keycode, 1);
85 input_sync(input);
86
87 input_report_key(input, keycode, 0);
88 input_sync(input);
89}
90
91/* Poll for key changes
92 *
93 * Read Application keys via SMI
94 * A (0x4), B (0x8), Internet (0x2), Email (0x1).
95 *
96 * CD keys:
97 * Forward (0x100), Rewind (0x200), Stop (0x400), Pause (0x800)
98 */
99static void apanel_poll(struct input_polled_dev *ipdev)
100{
101 struct apanel *ap = ipdev->private;
102 struct input_dev *idev = ipdev->input;
103 u8 cmd = device_chip[APANEL_DEV_APPBTN] == CHIP_OZ992C ? 0 : 8;
104 s32 data;
105 int i;
106
107 data = i2c_smbus_read_word_data(&ap->client, cmd);
108 if (data < 0)
109 return; /* ignore errors (due to ACPI??) */
110
111 /* write back to clear latch */
112 i2c_smbus_write_word_data(&ap->client, cmd, 0);
113
114 if (!data)
115 return;
116
117 dev_dbg(&idev->dev, APANEL ": data %#x\n", data);
118 for (i = 0; i < idev->keycodemax; i++)
119 if ((1u << i) & data)
120 report_key(idev, ap->keymap[i]);
121}
122
123/* Track state changes of LED */
124static void led_update(struct work_struct *work)
125{
126 struct apanel *ap = container_of(work, struct apanel, led_work);
127
128 i2c_smbus_write_word_data(&ap->client, 0x10, ap->led_bits);
129}
130
131static void mail_led_set(struct led_classdev *led,
132 enum led_brightness value)
133{
134 struct apanel *ap = container_of(led, struct apanel, mail_led);
135
136 if (value != LED_OFF)
137 ap->led_bits |= 0x8000;
138 else
139 ap->led_bits &= ~0x8000;
140
141 schedule_work(&ap->led_work);
142}
143
144static int apanel_detach_client(struct i2c_client *client)
145{
146 struct apanel *ap = i2c_get_clientdata(client);
147
148 if (device_chip[APANEL_DEV_LED] != CHIP_NONE)
149 led_classdev_unregister(&ap->mail_led);
150
151 input_unregister_polled_device(ap->ipdev);
152 i2c_detach_client(&ap->client);
153 input_free_polled_device(ap->ipdev);
154
155 return 0;
156}
157
158/* Function is invoked for every i2c adapter. */
159static int apanel_attach_adapter(struct i2c_adapter *adap)
160{
161 dev_dbg(&adap->dev, APANEL ": attach adapter id=%d\n", adap->id);
162
163 /* Our device is connected only to i801 on laptop */
164 if (adap->id != I2C_HW_SMBUS_I801)
165 return -ENODEV;
166
167 return i2c_probe(adap, &addr_data, apanel_probe);
168}
169
170static void apanel_shutdown(struct i2c_client *client)
171{
172 apanel_detach_client(client);
173}
174
175static struct i2c_driver apanel_driver = {
176 .driver = {
177 .name = APANEL,
178 },
179 .attach_adapter = &apanel_attach_adapter,
180 .detach_client = &apanel_detach_client,
181 .shutdown = &apanel_shutdown,
182};
183
184static struct apanel apanel = {
185 .client = {
186 .driver = &apanel_driver,
187 .name = APANEL,
188 },
189 .keymap = {
190 [0] = KEY_MAIL,
191 [1] = KEY_WWW,
192 [2] = KEY_PROG2,
193 [3] = KEY_PROG1,
194
195 [8] = KEY_FORWARD,
196 [9] = KEY_REWIND,
197 [10] = KEY_STOPCD,
198 [11] = KEY_PLAYPAUSE,
199
200 },
201 .mail_led = {
202 .name = "mail:blue",
203 .brightness_set = mail_led_set,
204 },
205};
206
207/* NB: Only one panel on the i2c. */
208static int apanel_probe(struct i2c_adapter *bus, int address, int kind)
209{
210 struct apanel *ap;
211 struct input_polled_dev *ipdev;
212 struct input_dev *idev;
213 u8 cmd = device_chip[APANEL_DEV_APPBTN] == CHIP_OZ992C ? 0 : 8;
214 int i, err = -ENOMEM;
215
216 dev_dbg(&bus->dev, APANEL ": probe adapter %p addr %d kind %d\n",
217 bus, address, kind);
218
219 ap = &apanel;
220
221 ipdev = input_allocate_polled_device();
222 if (!ipdev)
223 goto out1;
224
225 ap->ipdev = ipdev;
226 ap->client.adapter = bus;
227 ap->client.addr = address;
228
229 i2c_set_clientdata(&ap->client, ap);
230
231 err = i2c_attach_client(&ap->client);
232 if (err)
233 goto out2;
234
235 err = i2c_smbus_write_word_data(&ap->client, cmd, 0);
236 if (err) {
237 dev_warn(&ap->client.dev, APANEL ": smbus write error %d\n",
238 err);
239 goto out3;
240 }
241
242 ipdev->poll = apanel_poll;
243 ipdev->poll_interval = POLL_INTERVAL_DEFAULT;
244 ipdev->private = ap;
245
246 idev = ipdev->input;
247 idev->name = APANEL_NAME " buttons";
248 idev->phys = "apanel/input0";
249 idev->id.bustype = BUS_HOST;
250 idev->dev.parent = &ap->client.dev;
251
252 set_bit(EV_KEY, idev->evbit);
253
254 idev->keycode = ap->keymap;
255 idev->keycodesize = sizeof(ap->keymap[0]);
256 idev->keycodemax = (device_chip[APANEL_DEV_CDBTN] != CHIP_NONE) ? 12 : 4;
257
258 for (i = 0; i < idev->keycodemax; i++)
259 if (ap->keymap[i])
260 set_bit(ap->keymap[i], idev->keybit);
261
262 err = input_register_polled_device(ipdev);
263 if (err)
264 goto out3;
265
266 INIT_WORK(&ap->led_work, led_update);
267 if (device_chip[APANEL_DEV_LED] != CHIP_NONE) {
268 err = led_classdev_register(&ap->client.dev, &ap->mail_led);
269 if (err)
270 goto out4;
271 }
272
273 return 0;
274out4:
275 input_unregister_polled_device(ipdev);
276out3:
277 i2c_detach_client(&ap->client);
278out2:
279 input_free_polled_device(ipdev);
280out1:
281 return err;
282}
283
284/* Scan the system ROM for the signature "FJKEYINF" */
285static __init const void __iomem *bios_signature(const void __iomem *bios)
286{
287 ssize_t offset;
288 const unsigned char signature[] = "FJKEYINF";
289
290 for (offset = 0; offset < 0x10000; offset += 0x10) {
291 if (check_signature(bios + offset, signature,
292 sizeof(signature)-1))
293 return bios + offset;
294 }
295 pr_notice(APANEL ": Fujitsu BIOS signature '%s' not found...\n",
296 signature);
297 return NULL;
298}
299
300static int __init apanel_init(void)
301{
302 void __iomem *bios;
303 const void __iomem *p;
304 u8 devno;
305 int found = 0;
306
307 bios = ioremap(0xF0000, 0x10000); /* Can't fail */
308
309 p = bios_signature(bios);
310 if (!p) {
311 iounmap(bios);
312 return -ENODEV;
313 }
314
315 /* just use the first address */
316 p += 8;
317 normal_i2c[0] = readb(p+3) >> 1;
318
319 for ( ; (devno = readb(p)) & 0x7f; p += 4) {
320 unsigned char method, slave, chip;
321
322 method = readb(p + 1);
323 chip = readb(p + 2);
324 slave = readb(p + 3) >> 1;
325
326 if (slave != normal_i2c[0]) {
327 pr_notice(APANEL ": only one SMBus slave "
328 "address supported, skiping device...\n");
329 continue;
330 }
331
332 /* translate alternative device numbers */
333 switch (devno) {
334 case 6:
335 devno = APANEL_DEV_APPBTN;
336 break;
337 case 7:
338 devno = APANEL_DEV_LED;
339 break;
340 }
341
342 if (devno >= APANEL_DEV_MAX)
343 pr_notice(APANEL ": unknown device %u found\n", devno);
344 else if (device_chip[devno] != CHIP_NONE)
345 pr_warning(APANEL ": duplicate entry for devno %u\n", devno);
346
347 else if (method != 1 && method != 2 && method != 4) {
348 pr_notice(APANEL ": unknown method %u for devno %u\n",
349 method, devno);
350 } else {
351 device_chip[devno] = (enum apanel_chip) chip;
352 ++found;
353 }
354 }
355 iounmap(bios);
356
357 if (found == 0) {
358 pr_info(APANEL ": no input devices reported by BIOS\n");
359 return -EIO;
360 }
361
362 return i2c_add_driver(&apanel_driver);
363}
364module_init(apanel_init);
365
366static void __exit apanel_cleanup(void)
367{
368 i2c_del_driver(&apanel_driver);
369}
370module_exit(apanel_cleanup);
371
372MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>");
373MODULE_DESCRIPTION(APANEL_NAME " driver");
374MODULE_LICENSE("GPL");
375MODULE_VERSION(APANEL_VERSION);
376
377MODULE_ALIAS("dmi:*:svnFUJITSU:pnLifeBook*:pvr*:rvnFUJITSU:*");
378MODULE_ALIAS("dmi:*:svnFUJITSU:pnLifebook*:pvr*:rvnFUJITSU:*");
diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c
index 3a7937481ad8..f3b86c2b0797 100644
--- a/drivers/input/misc/ati_remote.c
+++ b/drivers/input/misc/ati_remote.c
@@ -90,7 +90,6 @@
90#include <linux/init.h> 90#include <linux/init.h>
91#include <linux/slab.h> 91#include <linux/slab.h>
92#include <linux/module.h> 92#include <linux/module.h>
93#include <linux/moduleparam.h>
94#include <linux/usb/input.h> 93#include <linux/usb/input.h>
95#include <linux/wait.h> 94#include <linux/wait.h>
96#include <linux/jiffies.h> 95#include <linux/jiffies.h>
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c
index 4e3ad657ed80..1b871917340a 100644
--- a/drivers/input/misc/atlas_btns.c
+++ b/drivers/input/misc/atlas_btns.c
@@ -29,9 +29,10 @@
29#include <asm/uaccess.h> 29#include <asm/uaccess.h>
30#include <acpi/acpi_drivers.h> 30#include <acpi/acpi_drivers.h>
31 31
32#define ACPI_ATLAS_NAME "Atlas ACPI" 32#define ACPI_ATLAS_NAME "Atlas ACPI"
33#define ACPI_ATLAS_CLASS "Atlas" 33#define ACPI_ATLAS_CLASS "Atlas"
34 34
35static unsigned short atlas_keymap[16];
35static struct input_dev *input_dev; 36static struct input_dev *input_dev;
36 37
37/* button handling code */ 38/* button handling code */
@@ -50,12 +51,15 @@ static acpi_status acpi_atlas_button_handler(u32 function,
50 void *handler_context, void *region_context) 51 void *handler_context, void *region_context)
51{ 52{
52 acpi_status status; 53 acpi_status status;
53 int keycode;
54 54
55 if (function == ACPI_WRITE) { 55 if (function == ACPI_WRITE) {
56 keycode = KEY_F1 + (address & 0x0F); 56 int code = address & 0x0f;
57 input_report_key(input_dev, keycode, !(address & 0x10)); 57 int key_down = !(address & 0x10);
58
59 input_event(input_dev, EV_MSC, MSC_SCAN, code);
60 input_report_key(input_dev, atlas_keymap[code], key_down);
58 input_sync(input_dev); 61 input_sync(input_dev);
62
59 status = 0; 63 status = 0;
60 } else { 64 } else {
61 printk(KERN_WARNING "atlas: shrugged on unexpected function" 65 printk(KERN_WARNING "atlas: shrugged on unexpected function"
@@ -70,6 +74,7 @@ static acpi_status acpi_atlas_button_handler(u32 function,
70static int atlas_acpi_button_add(struct acpi_device *device) 74static int atlas_acpi_button_add(struct acpi_device *device)
71{ 75{
72 acpi_status status; 76 acpi_status status;
77 int i;
73 int err; 78 int err;
74 79
75 input_dev = input_allocate_device(); 80 input_dev = input_allocate_device();
@@ -81,17 +86,19 @@ static int atlas_acpi_button_add(struct acpi_device *device)
81 input_dev->name = "Atlas ACPI button driver"; 86 input_dev->name = "Atlas ACPI button driver";
82 input_dev->phys = "ASIM0000/atlas/input0"; 87 input_dev->phys = "ASIM0000/atlas/input0";
83 input_dev->id.bustype = BUS_HOST; 88 input_dev->id.bustype = BUS_HOST;
84 input_dev->evbit[BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY); 89 input_dev->keycode = atlas_keymap;
85 90 input_dev->keycodesize = sizeof(unsigned short);
86 set_bit(KEY_F1, input_dev->keybit); 91 input_dev->keycodemax = ARRAY_SIZE(atlas_keymap);
87 set_bit(KEY_F2, input_dev->keybit); 92
88 set_bit(KEY_F3, input_dev->keybit); 93 input_set_capability(input_dev, EV_MSC, MSC_SCAN);
89 set_bit(KEY_F4, input_dev->keybit); 94 __set_bit(EV_KEY, input_dev->evbit);
90 set_bit(KEY_F5, input_dev->keybit); 95 for (i = 0; i < ARRAY_SIZE(atlas_keymap); i++) {
91 set_bit(KEY_F6, input_dev->keybit); 96 if (i < 9) {
92 set_bit(KEY_F7, input_dev->keybit); 97 atlas_keymap[i] = KEY_F1 + i;
93 set_bit(KEY_F8, input_dev->keybit); 98 __set_bit(KEY_F1 + i, input_dev->keybit);
94 set_bit(KEY_F9, input_dev->keybit); 99 } else
100 atlas_keymap[i] = KEY_RESERVED;
101 }
95 102
96 err = input_register_device(input_dev); 103 err = input_register_device(input_dev);
97 if (err) { 104 if (err) {
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c
index 1aef97ed5e84..4833b1a82623 100644
--- a/drivers/input/misc/cobalt_btns.c
+++ b/drivers/input/misc/cobalt_btns.c
@@ -27,55 +27,48 @@
27#define BUTTONS_COUNT_THRESHOLD 3 27#define BUTTONS_COUNT_THRESHOLD 3
28#define BUTTONS_STATUS_MASK 0xfe000000 28#define BUTTONS_STATUS_MASK 0xfe000000
29 29
30static const unsigned short cobalt_map[] = {
31 KEY_RESERVED,
32 KEY_RESTART,
33 KEY_LEFT,
34 KEY_UP,
35 KEY_DOWN,
36 KEY_RIGHT,
37 KEY_ENTER,
38 KEY_SELECT
39};
40
30struct buttons_dev { 41struct buttons_dev {
31 struct input_polled_dev *poll_dev; 42 struct input_polled_dev *poll_dev;
43 unsigned short keymap[ARRAY_SIZE(cobalt_map)];
44 int count[ARRAY_SIZE(cobalt_map)];
32 void __iomem *reg; 45 void __iomem *reg;
33}; 46};
34 47
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) 48static void handle_buttons(struct input_polled_dev *dev)
52{ 49{
53 struct buttons_map *button = buttons_map;
54 struct buttons_dev *bdev = dev->private; 50 struct buttons_dev *bdev = dev->private;
55 struct input_dev *input = dev->input; 51 struct input_dev *input = dev->input;
56 uint32_t status; 52 uint32_t status;
57 int i; 53 int i;
58 54
59 status = readl(bdev->reg); 55 status = ~readl(bdev->reg) >> 24;
60 status = ~status & BUTTONS_STATUS_MASK;
61 56
62 for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { 57 for (i = 0; i < ARRAY_SIZE(bdev->keymap); i++) {
63 if (status & button->mask) { 58 if (status & (1UL << i)) {
64 button->count++; 59 if (++bdev->count[i] == BUTTONS_COUNT_THRESHOLD) {
60 input_event(input, EV_MSC, MSC_SCAN, i);
61 input_report_key(input, bdev->keymap[i], 1);
62 input_sync(input);
63 }
65 } else { 64 } else {
66 if (button->count >= BUTTONS_COUNT_THRESHOLD) { 65 if (bdev->count[i] >= BUTTONS_COUNT_THRESHOLD) {
67 input_report_key(input, button->keycode, 0); 66 input_event(input, EV_MSC, MSC_SCAN, i);
67 input_report_key(input, bdev->keymap[i], 0);
68 input_sync(input); 68 input_sync(input);
69 } 69 }
70 button->count = 0; 70 bdev->count[i] = 0;
71 }
72
73 if (button->count == BUTTONS_COUNT_THRESHOLD) {
74 input_report_key(input, button->keycode, 1);
75 input_sync(input);
76 } 71 }
77
78 button++;
79 } 72 }
80} 73}
81 74
@@ -94,6 +87,8 @@ static int __devinit cobalt_buttons_probe(struct platform_device *pdev)
94 goto err_free_mem; 87 goto err_free_mem;
95 } 88 }
96 89
90 memcpy(bdev->keymap, cobalt_map, sizeof(bdev->keymap));
91
97 poll_dev->private = bdev; 92 poll_dev->private = bdev;
98 poll_dev->poll = handle_buttons; 93 poll_dev->poll = handle_buttons;
99 poll_dev->poll_interval = BUTTONS_POLL_INTERVAL; 94 poll_dev->poll_interval = BUTTONS_POLL_INTERVAL;
@@ -104,11 +99,15 @@ static int __devinit cobalt_buttons_probe(struct platform_device *pdev)
104 input->id.bustype = BUS_HOST; 99 input->id.bustype = BUS_HOST;
105 input->cdev.dev = &pdev->dev; 100 input->cdev.dev = &pdev->dev;
106 101
107 input->evbit[0] = BIT_MASK(EV_KEY); 102 input->keycode = pdev->keymap;
108 for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { 103 input->keycodemax = ARRAY_SIZE(pdev->keymap);
109 set_bit(buttons_map[i].keycode, input->keybit); 104 input->keycodesize = sizeof(unsigned short);
110 buttons_map[i].count = 0; 105
111 } 106 input_set_capability(input, EV_MSC, MSC_SCAN);
107 __set_bit(EV_KEY, input->evbit);
108 for (i = 0; i < ARRAY_SIZE(buttons_map); i++)
109 __set_bit(input->keycode[i], input->keybit);
110 __clear_bit(KEY_RESERVED, input->keybit);
112 111
113 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 112 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
114 if (!res) { 113 if (!res) {
diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c
index fd74347047dd..952938a8e991 100644
--- a/drivers/input/misc/keyspan_remote.c
+++ b/drivers/input/misc/keyspan_remote.c
@@ -16,7 +16,6 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/usb/input.h> 19#include <linux/usb/input.h>
21 20
22#define DRIVER_VERSION "v0.1" 21#define DRIVER_VERSION "v0.1"
@@ -46,53 +45,12 @@ MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
46 45
47#define RECV_SIZE 8 /* The UIA-11 type have a 8 byte limit. */ 46#define RECV_SIZE 8 /* The UIA-11 type have a 8 byte limit. */
48 47
49/* table of devices that work with this driver */
50static struct usb_device_id keyspan_table[] = {
51 { USB_DEVICE(USB_KEYSPAN_VENDOR_ID, USB_KEYSPAN_PRODUCT_UIA11) },
52 { } /* Terminating entry */
53};
54
55/* Structure to store all the real stuff that a remote sends to us. */
56struct keyspan_message {
57 u16 system;
58 u8 button;
59 u8 toggle;
60};
61
62/* Structure used for all the bit testing magic needed to be done. */
63struct bit_tester {
64 u32 tester;
65 int len;
66 int pos;
67 int bits_left;
68 u8 buffer[32];
69};
70
71/* Structure to hold all of our driver specific stuff */
72struct usb_keyspan {
73 char name[128];
74 char phys[64];
75 struct usb_device* udev;
76 struct input_dev *input;
77 struct usb_interface* interface;
78 struct usb_endpoint_descriptor* in_endpoint;
79 struct urb* irq_urb;
80 int open;
81 dma_addr_t in_dma;
82 unsigned char* in_buffer;
83
84 /* variables used to parse messages from remote. */
85 struct bit_tester data;
86 int stage;
87 int toggle;
88};
89
90/* 48/*
91 * Table that maps the 31 possible keycodes to input keys. 49 * Table that maps the 31 possible keycodes to input keys.
92 * Currently there are 15 and 17 button models so RESERVED codes 50 * Currently there are 15 and 17 button models so RESERVED codes
93 * are blank areas in the mapping. 51 * are blank areas in the mapping.
94 */ 52 */
95static const int keyspan_key_table[] = { 53static const unsigned short keyspan_key_table[] = {
96 KEY_RESERVED, /* 0 is just a place holder. */ 54 KEY_RESERVED, /* 0 is just a place holder. */
97 KEY_RESERVED, 55 KEY_RESERVED,
98 KEY_STOP, 56 KEY_STOP,
@@ -127,6 +85,48 @@ static const int keyspan_key_table[] = {
127 KEY_MENU 85 KEY_MENU
128}; 86};
129 87
88/* table of devices that work with this driver */
89static struct usb_device_id keyspan_table[] = {
90 { USB_DEVICE(USB_KEYSPAN_VENDOR_ID, USB_KEYSPAN_PRODUCT_UIA11) },
91 { } /* Terminating entry */
92};
93
94/* Structure to store all the real stuff that a remote sends to us. */
95struct keyspan_message {
96 u16 system;
97 u8 button;
98 u8 toggle;
99};
100
101/* Structure used for all the bit testing magic needed to be done. */
102struct bit_tester {
103 u32 tester;
104 int len;
105 int pos;
106 int bits_left;
107 u8 buffer[32];
108};
109
110/* Structure to hold all of our driver specific stuff */
111struct usb_keyspan {
112 char name[128];
113 char phys[64];
114 unsigned short keymap[ARRAY_SIZE(keyspan_key_table)];
115 struct usb_device *udev;
116 struct input_dev *input;
117 struct usb_interface *interface;
118 struct usb_endpoint_descriptor *in_endpoint;
119 struct urb* irq_urb;
120 int open;
121 dma_addr_t in_dma;
122 unsigned char *in_buffer;
123
124 /* variables used to parse messages from remote. */
125 struct bit_tester data;
126 int stage;
127 int toggle;
128};
129
130static struct usb_driver keyspan_driver; 130static struct usb_driver keyspan_driver;
131 131
132/* 132/*
@@ -173,6 +173,15 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
173 return 0; 173 return 0;
174} 174}
175 175
176static void keyspan_report_button(struct usb_keyspan *remote, int button, int press)
177{
178 struct input_dev *input = remote->input;
179
180 input_event(input, EV_MSC, MSC_SCAN, button);
181 input_report_key(input, remote->keymap[button], press);
182 input_sync(input);
183}
184
176/* 185/*
177 * Routine that handles all the logic needed to parse out the message from the remote. 186 * Routine that handles all the logic needed to parse out the message from the remote.
178 */ 187 */
@@ -311,9 +320,8 @@ static void keyspan_check_data(struct usb_keyspan *remote)
311 __FUNCTION__, message.system, message.button, message.toggle); 320 __FUNCTION__, message.system, message.button, message.toggle);
312 321
313 if (message.toggle != remote->toggle) { 322 if (message.toggle != remote->toggle) {
314 input_report_key(remote->input, keyspan_key_table[message.button], 1); 323 keyspan_report_button(remote, message.button, 1);
315 input_report_key(remote->input, keyspan_key_table[message.button], 0); 324 keyspan_report_button(remote, message.button, 0);
316 input_sync(remote->input);
317 remote->toggle = message.toggle; 325 remote->toggle = message.toggle;
318 } 326 }
319 327
@@ -491,16 +499,21 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
491 499
492 usb_make_path(udev, remote->phys, sizeof(remote->phys)); 500 usb_make_path(udev, remote->phys, sizeof(remote->phys));
493 strlcat(remote->phys, "/input0", sizeof(remote->phys)); 501 strlcat(remote->phys, "/input0", sizeof(remote->phys));
502 memcpy(remote->keymap, keyspan_key_table, sizeof(remote->keymap));
494 503
495 input_dev->name = remote->name; 504 input_dev->name = remote->name;
496 input_dev->phys = remote->phys; 505 input_dev->phys = remote->phys;
497 usb_to_input_id(udev, &input_dev->id); 506 usb_to_input_id(udev, &input_dev->id);
498 input_dev->dev.parent = &interface->dev; 507 input_dev->dev.parent = &interface->dev;
508 input_dev->keycode = remote->keymap;
509 input_dev->keycodesize = sizeof(unsigned short);
510 input_dev->keycodemax = ARRAY_SIZE(remote->keymap);
499 511
500 input_dev->evbit[0] = BIT_MASK(EV_KEY); /* We will only report KEY events. */ 512 input_set_capability(input_dev, EV_MSC, MSC_SCAN);
513 __set_bit(EV_KEY, input_dev->evbit);
501 for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++) 514 for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++)
502 if (keyspan_key_table[i] != KEY_RESERVED) 515 __set_bit(keyspan_key_table[i], input_dev->keybit);
503 set_bit(keyspan_key_table[i], input_dev->keybit); 516 __clear_bit(KEY_RESERVED, input_dev->keybit);
504 517
505 input_set_drvdata(input_dev, remote); 518 input_set_drvdata(input_dev, remote);
506 519
@@ -508,12 +521,14 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
508 input_dev->close = keyspan_close; 521 input_dev->close = keyspan_close;
509 522
510 /* 523 /*
511 * Initialize the URB to access the device. The urb gets sent to the device in keyspan_open() 524 * Initialize the URB to access the device.
525 * The urb gets sent to the device in keyspan_open()
512 */ 526 */
513 usb_fill_int_urb(remote->irq_urb, 527 usb_fill_int_urb(remote->irq_urb,
514 remote->udev, usb_rcvintpipe(remote->udev, remote->in_endpoint->bEndpointAddress), 528 remote->udev,
529 usb_rcvintpipe(remote->udev, endpoint->bEndpointAddress),
515 remote->in_buffer, RECV_SIZE, keyspan_irq_recv, remote, 530 remote->in_buffer, RECV_SIZE, keyspan_irq_recv, remote,
516 remote->in_endpoint->bInterval); 531 endpoint->bInterval);
517 remote->irq_urb->transfer_dma = remote->in_dma; 532 remote->irq_urb->transfer_dma = remote->in_dma;
518 remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 533 remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
519 534