diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/input/keyboard | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/input/keyboard')
26 files changed, 2281 insertions, 737 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index ee98b1bc5d89..64c102355f53 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -24,11 +24,21 @@ config KEYBOARD_AAED2000 | |||
24 | To compile this driver as a module, choose M here: the | 24 | To compile this driver as a module, choose M here: the |
25 | module will be called aaed2000_kbd. | 25 | module will be called aaed2000_kbd. |
26 | 26 | ||
27 | config KEYBOARD_ADP5520 | ||
28 | tristate "Keypad Support for ADP5520 PMIC" | ||
29 | depends on PMIC_ADP5520 | ||
30 | help | ||
31 | This option enables support for the keypad scan matrix | ||
32 | on Analog Devices ADP5520 PMICs. | ||
33 | |||
34 | To compile this driver as a module, choose M here: the module will | ||
35 | be called adp5520-keys. | ||
36 | |||
27 | config KEYBOARD_ADP5588 | 37 | config KEYBOARD_ADP5588 |
28 | tristate "ADP5588 I2C QWERTY Keypad and IO Expander" | 38 | tristate "ADP5588/87 I2C QWERTY Keypad and IO Expander" |
29 | depends on I2C | 39 | depends on I2C |
30 | help | 40 | help |
31 | Say Y here if you want to use a ADP5588 attached to your | 41 | Say Y here if you want to use a ADP5588/87 attached to your |
32 | system I2C bus. | 42 | system I2C bus. |
33 | 43 | ||
34 | To compile this driver as a module, choose M here: the | 44 | To compile this driver as a module, choose M here: the |
@@ -134,13 +144,15 @@ config KEYBOARD_BFIN | |||
134 | module will be called bf54x-keys. | 144 | module will be called bf54x-keys. |
135 | 145 | ||
136 | config KEYBOARD_CORGI | 146 | config KEYBOARD_CORGI |
137 | tristate "Corgi keyboard" | 147 | tristate "Corgi keyboard (deprecated)" |
138 | depends on PXA_SHARPSL | 148 | depends on PXA_SHARPSL |
139 | default y | ||
140 | help | 149 | help |
141 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx | 150 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx |
142 | series of PDAs. | 151 | series of PDAs. |
143 | 152 | ||
153 | This driver is now deprecated, use generic GPIO based matrix | ||
154 | keyboard driver instead. | ||
155 | |||
144 | To compile this driver as a module, choose M here: the | 156 | To compile this driver as a module, choose M here: the |
145 | module will be called corgikbd. | 157 | module will be called corgikbd. |
146 | 158 | ||
@@ -282,6 +294,15 @@ config KEYBOARD_MAX7359 | |||
282 | To compile this driver as a module, choose M here: the | 294 | To compile this driver as a module, choose M here: the |
283 | module will be called max7359_keypad. | 295 | module will be called max7359_keypad. |
284 | 296 | ||
297 | config KEYBOARD_IMX | ||
298 | tristate "IMX keypad support" | ||
299 | depends on ARCH_MXC | ||
300 | help | ||
301 | Enable support for IMX keypad port. | ||
302 | |||
303 | To compile this driver as a module, choose M here: the | ||
304 | module will be called imx_keypad. | ||
305 | |||
285 | config KEYBOARD_NEWTON | 306 | config KEYBOARD_NEWTON |
286 | tristate "Newton keyboard" | 307 | tristate "Newton keyboard" |
287 | select SERIO | 308 | select SERIO |
@@ -319,13 +340,15 @@ config KEYBOARD_PXA930_ROTARY | |||
319 | module will be called pxa930_rotary. | 340 | module will be called pxa930_rotary. |
320 | 341 | ||
321 | config KEYBOARD_SPITZ | 342 | config KEYBOARD_SPITZ |
322 | tristate "Spitz keyboard" | 343 | tristate "Spitz keyboard (deprecated)" |
323 | depends on PXA_SHARPSL | 344 | depends on PXA_SHARPSL |
324 | default y | ||
325 | help | 345 | help |
326 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000, | 346 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000, |
327 | SL-C3000 and Sl-C3100 series of PDAs. | 347 | SL-C3000 and Sl-C3100 series of PDAs. |
328 | 348 | ||
349 | This driver is now deprecated, use generic GPIO based matrix | ||
350 | keyboard driver instead. | ||
351 | |||
329 | To compile this driver as a module, choose M here: the | 352 | To compile this driver as a module, choose M here: the |
330 | module will be called spitzkbd. | 353 | module will be called spitzkbd. |
331 | 354 | ||
@@ -353,7 +376,7 @@ config KEYBOARD_SUNKBD | |||
353 | 376 | ||
354 | config KEYBOARD_SH_KEYSC | 377 | config KEYBOARD_SH_KEYSC |
355 | tristate "SuperH KEYSC keypad support" | 378 | tristate "SuperH KEYSC keypad support" |
356 | depends on SUPERH | 379 | depends on SUPERH || ARCH_SHMOBILE |
357 | help | 380 | help |
358 | Say Y here if you want to use a keypad attached to the KEYSC block | 381 | Say Y here if you want to use a keypad attached to the KEYSC block |
359 | on SuperH processors such as sh7722 and sh7343. | 382 | on SuperH processors such as sh7722 and sh7343. |
@@ -361,6 +384,16 @@ config KEYBOARD_SH_KEYSC | |||
361 | To compile this driver as a module, choose M here: the | 384 | To compile this driver as a module, choose M here: the |
362 | module will be called sh_keysc. | 385 | module will be called sh_keysc. |
363 | 386 | ||
387 | config KEYBOARD_DAVINCI | ||
388 | tristate "TI DaVinci Key Scan" | ||
389 | depends on ARCH_DAVINCI_DM365 | ||
390 | help | ||
391 | Say Y to enable keypad module support for the TI DaVinci | ||
392 | platforms (DM365). | ||
393 | |||
394 | To compile this driver as a module, choose M here: the | ||
395 | module will be called davinci_keyscan. | ||
396 | |||
364 | config KEYBOARD_OMAP | 397 | config KEYBOARD_OMAP |
365 | tristate "TI OMAP keypad support" | 398 | tristate "TI OMAP keypad support" |
366 | depends on (ARCH_OMAP1 || ARCH_OMAP2) | 399 | depends on (ARCH_OMAP1 || ARCH_OMAP2) |
@@ -382,12 +415,14 @@ config KEYBOARD_TWL4030 | |||
382 | module will be called twl4030_keypad. | 415 | module will be called twl4030_keypad. |
383 | 416 | ||
384 | config KEYBOARD_TOSA | 417 | config KEYBOARD_TOSA |
385 | tristate "Tosa keyboard" | 418 | tristate "Tosa keyboard (deprecated)" |
386 | depends on MACH_TOSA | 419 | depends on MACH_TOSA |
387 | default y | ||
388 | help | 420 | help |
389 | Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa) | 421 | Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa) |
390 | 422 | ||
423 | This driver is now deprecated, use generic GPIO based matrix | ||
424 | keyboard driver instead. | ||
425 | |||
391 | To compile this driver as a module, choose M here: the | 426 | To compile this driver as a module, choose M here: the |
392 | module will be called tosakbd. | 427 | module will be called tosakbd. |
393 | 428 | ||
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index babad5e58b77..706c6b5ed5f4 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -5,16 +5,19 @@ | |||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o | 7 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o |
8 | obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o | ||
8 | obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o | 9 | obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o |
9 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o | 10 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o |
10 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o | 11 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o |
11 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o | 12 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o |
12 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | 13 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o |
13 | obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o | 14 | obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o |
15 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o | ||
14 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o | 16 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o |
15 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | 17 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o |
16 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 18 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
17 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o | 19 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o |
20 | obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o | ||
18 | obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o | 21 | obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o |
19 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o | 22 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o |
20 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o | 23 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o |
diff --git a/drivers/input/keyboard/adp5520-keys.c b/drivers/input/keyboard/adp5520-keys.c new file mode 100644 index 000000000000..3db8006dac3a --- /dev/null +++ b/drivers/input/keyboard/adp5520-keys.c | |||
@@ -0,0 +1,221 @@ | |||
1 | /* | ||
2 | * Keypad driver for Analog Devices ADP5520 MFD PMICs | ||
3 | * | ||
4 | * Copyright 2009 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/input.h> | ||
14 | #include <linux/mfd/adp5520.h> | ||
15 | #include <linux/slab.h> | ||
16 | |||
17 | struct adp5520_keys { | ||
18 | struct input_dev *input; | ||
19 | struct notifier_block notifier; | ||
20 | struct device *master; | ||
21 | unsigned short keycode[ADP5520_KEYMAPSIZE]; | ||
22 | }; | ||
23 | |||
24 | static void adp5520_keys_report_event(struct adp5520_keys *dev, | ||
25 | unsigned short keymask, int value) | ||
26 | { | ||
27 | int i; | ||
28 | |||
29 | for (i = 0; i < ADP5520_MAXKEYS; i++) | ||
30 | if (keymask & (1 << i)) | ||
31 | input_report_key(dev->input, dev->keycode[i], value); | ||
32 | |||
33 | input_sync(dev->input); | ||
34 | } | ||
35 | |||
36 | static int adp5520_keys_notifier(struct notifier_block *nb, | ||
37 | unsigned long event, void *data) | ||
38 | { | ||
39 | struct adp5520_keys *dev; | ||
40 | uint8_t reg_val_lo, reg_val_hi; | ||
41 | unsigned short keymask; | ||
42 | |||
43 | dev = container_of(nb, struct adp5520_keys, notifier); | ||
44 | |||
45 | if (event & ADP5520_KP_INT) { | ||
46 | adp5520_read(dev->master, ADP5520_KP_INT_STAT_1, ®_val_lo); | ||
47 | adp5520_read(dev->master, ADP5520_KP_INT_STAT_2, ®_val_hi); | ||
48 | |||
49 | keymask = (reg_val_hi << 8) | reg_val_lo; | ||
50 | /* Read twice to clear */ | ||
51 | adp5520_read(dev->master, ADP5520_KP_INT_STAT_1, ®_val_lo); | ||
52 | adp5520_read(dev->master, ADP5520_KP_INT_STAT_2, ®_val_hi); | ||
53 | keymask |= (reg_val_hi << 8) | reg_val_lo; | ||
54 | adp5520_keys_report_event(dev, keymask, 1); | ||
55 | } | ||
56 | |||
57 | if (event & ADP5520_KR_INT) { | ||
58 | adp5520_read(dev->master, ADP5520_KR_INT_STAT_1, ®_val_lo); | ||
59 | adp5520_read(dev->master, ADP5520_KR_INT_STAT_2, ®_val_hi); | ||
60 | |||
61 | keymask = (reg_val_hi << 8) | reg_val_lo; | ||
62 | /* Read twice to clear */ | ||
63 | adp5520_read(dev->master, ADP5520_KR_INT_STAT_1, ®_val_lo); | ||
64 | adp5520_read(dev->master, ADP5520_KR_INT_STAT_2, ®_val_hi); | ||
65 | keymask |= (reg_val_hi << 8) | reg_val_lo; | ||
66 | adp5520_keys_report_event(dev, keymask, 0); | ||
67 | } | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static int __devinit adp5520_keys_probe(struct platform_device *pdev) | ||
73 | { | ||
74 | struct adp5520_keys_platform_data *pdata = pdev->dev.platform_data; | ||
75 | struct input_dev *input; | ||
76 | struct adp5520_keys *dev; | ||
77 | int ret, i; | ||
78 | unsigned char en_mask, ctl_mask = 0; | ||
79 | |||
80 | if (pdev->id != ID_ADP5520) { | ||
81 | dev_err(&pdev->dev, "only ADP5520 supports Keypad\n"); | ||
82 | return -EINVAL; | ||
83 | } | ||
84 | |||
85 | if (pdata == NULL) { | ||
86 | dev_err(&pdev->dev, "missing platform data\n"); | ||
87 | return -EINVAL; | ||
88 | } | ||
89 | |||
90 | if (!(pdata->rows_en_mask && pdata->cols_en_mask)) | ||
91 | return -EINVAL; | ||
92 | |||
93 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
94 | if (dev == NULL) { | ||
95 | dev_err(&pdev->dev, "failed to alloc memory\n"); | ||
96 | return -ENOMEM; | ||
97 | } | ||
98 | |||
99 | input = input_allocate_device(); | ||
100 | if (!input) { | ||
101 | ret = -ENOMEM; | ||
102 | goto err; | ||
103 | } | ||
104 | |||
105 | dev->master = pdev->dev.parent; | ||
106 | dev->input = input; | ||
107 | |||
108 | input->name = pdev->name; | ||
109 | input->phys = "adp5520-keys/input0"; | ||
110 | input->dev.parent = &pdev->dev; | ||
111 | |||
112 | input_set_drvdata(input, dev); | ||
113 | |||
114 | input->id.bustype = BUS_I2C; | ||
115 | input->id.vendor = 0x0001; | ||
116 | input->id.product = 0x5520; | ||
117 | input->id.version = 0x0001; | ||
118 | |||
119 | input->keycodesize = sizeof(dev->keycode[0]); | ||
120 | input->keycodemax = pdata->keymapsize; | ||
121 | input->keycode = dev->keycode; | ||
122 | |||
123 | memcpy(dev->keycode, pdata->keymap, | ||
124 | pdata->keymapsize * input->keycodesize); | ||
125 | |||
126 | /* setup input device */ | ||
127 | __set_bit(EV_KEY, input->evbit); | ||
128 | |||
129 | if (pdata->repeat) | ||
130 | __set_bit(EV_REP, input->evbit); | ||
131 | |||
132 | for (i = 0; i < input->keycodemax; i++) | ||
133 | __set_bit(dev->keycode[i], input->keybit); | ||
134 | __clear_bit(KEY_RESERVED, input->keybit); | ||
135 | |||
136 | ret = input_register_device(input); | ||
137 | if (ret) { | ||
138 | dev_err(&pdev->dev, "unable to register input device\n"); | ||
139 | goto err; | ||
140 | } | ||
141 | |||
142 | en_mask = pdata->rows_en_mask | pdata->cols_en_mask; | ||
143 | |||
144 | ret = adp5520_set_bits(dev->master, ADP5520_GPIO_CFG_1, en_mask); | ||
145 | |||
146 | if (en_mask & ADP5520_COL_C3) | ||
147 | ctl_mask |= ADP5520_C3_MODE; | ||
148 | |||
149 | if (en_mask & ADP5520_ROW_R3) | ||
150 | ctl_mask |= ADP5520_R3_MODE; | ||
151 | |||
152 | if (ctl_mask) | ||
153 | ret |= adp5520_set_bits(dev->master, ADP5520_LED_CONTROL, | ||
154 | ctl_mask); | ||
155 | |||
156 | ret |= adp5520_set_bits(dev->master, ADP5520_GPIO_PULLUP, | ||
157 | pdata->rows_en_mask); | ||
158 | |||
159 | if (ret) { | ||
160 | dev_err(&pdev->dev, "failed to write\n"); | ||
161 | ret = -EIO; | ||
162 | goto err1; | ||
163 | } | ||
164 | |||
165 | dev->notifier.notifier_call = adp5520_keys_notifier; | ||
166 | ret = adp5520_register_notifier(dev->master, &dev->notifier, | ||
167 | ADP5520_KP_IEN | ADP5520_KR_IEN); | ||
168 | if (ret) { | ||
169 | dev_err(&pdev->dev, "failed to register notifier\n"); | ||
170 | goto err1; | ||
171 | } | ||
172 | |||
173 | platform_set_drvdata(pdev, dev); | ||
174 | return 0; | ||
175 | |||
176 | err1: | ||
177 | input_unregister_device(input); | ||
178 | input = NULL; | ||
179 | err: | ||
180 | input_free_device(input); | ||
181 | kfree(dev); | ||
182 | return ret; | ||
183 | } | ||
184 | |||
185 | static int __devexit adp5520_keys_remove(struct platform_device *pdev) | ||
186 | { | ||
187 | struct adp5520_keys *dev = platform_get_drvdata(pdev); | ||
188 | |||
189 | adp5520_unregister_notifier(dev->master, &dev->notifier, | ||
190 | ADP5520_KP_IEN | ADP5520_KR_IEN); | ||
191 | |||
192 | input_unregister_device(dev->input); | ||
193 | kfree(dev); | ||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | static struct platform_driver adp5520_keys_driver = { | ||
198 | .driver = { | ||
199 | .name = "adp5520-keys", | ||
200 | .owner = THIS_MODULE, | ||
201 | }, | ||
202 | .probe = adp5520_keys_probe, | ||
203 | .remove = __devexit_p(adp5520_keys_remove), | ||
204 | }; | ||
205 | |||
206 | static int __init adp5520_keys_init(void) | ||
207 | { | ||
208 | return platform_driver_register(&adp5520_keys_driver); | ||
209 | } | ||
210 | module_init(adp5520_keys_init); | ||
211 | |||
212 | static void __exit adp5520_keys_exit(void) | ||
213 | { | ||
214 | platform_driver_unregister(&adp5520_keys_driver); | ||
215 | } | ||
216 | module_exit(adp5520_keys_exit); | ||
217 | |||
218 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
219 | MODULE_DESCRIPTION("Keys ADP5520 Driver"); | ||
220 | MODULE_LICENSE("GPL"); | ||
221 | MODULE_ALIAS("platform:adp5520-keys"); | ||
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index d48c808d5928..4771ab172b59 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * File: drivers/input/keyboard/adp5588_keys.c | 2 | * File: drivers/input/keyboard/adp5588_keys.c |
3 | * Description: keypad driver for ADP5588 I2C QWERTY Keypad and IO Expander | 3 | * Description: keypad driver for ADP5588 and ADP5587 |
4 | * I2C QWERTY Keypad and IO Expander | ||
4 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 5 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
5 | * | 6 | * |
6 | * Copyright (C) 2008-2009 Analog Devices Inc. | 7 | * Copyright (C) 2008-2009 Analog Devices Inc. |
@@ -18,6 +19,7 @@ | |||
18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
19 | #include <linux/input.h> | 20 | #include <linux/input.h> |
20 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
22 | #include <linux/slab.h> | ||
21 | 23 | ||
22 | #include <linux/i2c/adp5588.h> | 24 | #include <linux/i2c/adp5588.h> |
23 | 25 | ||
@@ -319,7 +321,7 @@ static int adp5588_resume(struct device *dev) | |||
319 | return 0; | 321 | return 0; |
320 | } | 322 | } |
321 | 323 | ||
322 | static struct dev_pm_ops adp5588_dev_pm_ops = { | 324 | static const struct dev_pm_ops adp5588_dev_pm_ops = { |
323 | .suspend = adp5588_suspend, | 325 | .suspend = adp5588_suspend, |
324 | .resume = adp5588_resume, | 326 | .resume = adp5588_resume, |
325 | }; | 327 | }; |
@@ -327,6 +329,7 @@ static struct dev_pm_ops adp5588_dev_pm_ops = { | |||
327 | 329 | ||
328 | static const struct i2c_device_id adp5588_id[] = { | 330 | static const struct i2c_device_id adp5588_id[] = { |
329 | { KBUILD_MODNAME, 0 }, | 331 | { KBUILD_MODNAME, 0 }, |
332 | { "adp5587-keys", 0 }, | ||
330 | { } | 333 | { } |
331 | }; | 334 | }; |
332 | MODULE_DEVICE_TABLE(i2c, adp5588_id); | 335 | MODULE_DEVICE_TABLE(i2c, adp5588_id); |
@@ -357,5 +360,5 @@ module_exit(adp5588_exit); | |||
357 | 360 | ||
358 | MODULE_LICENSE("GPL"); | 361 | MODULE_LICENSE("GPL"); |
359 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 362 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
360 | MODULE_DESCRIPTION("ADP5588 Keypad driver"); | 363 | MODULE_DESCRIPTION("ADP5588/87 Keypad driver"); |
361 | MODULE_ALIAS("platform:adp5588-keys"); | 364 | MODULE_ALIAS("platform:adp5588-keys"); |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 28e6110d1ff8..d358ef8623f4 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -40,26 +40,26 @@ module_param_named(set, atkbd_set, int, 0); | |||
40 | MODULE_PARM_DESC(set, "Select keyboard code set (2 = default, 3 = PS/2 native)"); | 40 | MODULE_PARM_DESC(set, "Select keyboard code set (2 = default, 3 = PS/2 native)"); |
41 | 41 | ||
42 | #if defined(__i386__) || defined(__x86_64__) || defined(__hppa__) | 42 | #if defined(__i386__) || defined(__x86_64__) || defined(__hppa__) |
43 | static int atkbd_reset; | 43 | static bool atkbd_reset; |
44 | #else | 44 | #else |
45 | static int atkbd_reset = 1; | 45 | static bool atkbd_reset = true; |
46 | #endif | 46 | #endif |
47 | module_param_named(reset, atkbd_reset, bool, 0); | 47 | module_param_named(reset, atkbd_reset, bool, 0); |
48 | MODULE_PARM_DESC(reset, "Reset keyboard during initialization"); | 48 | MODULE_PARM_DESC(reset, "Reset keyboard during initialization"); |
49 | 49 | ||
50 | static int atkbd_softrepeat; | 50 | static bool atkbd_softrepeat; |
51 | module_param_named(softrepeat, atkbd_softrepeat, bool, 0); | 51 | module_param_named(softrepeat, atkbd_softrepeat, bool, 0); |
52 | MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat"); | 52 | MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat"); |
53 | 53 | ||
54 | static int atkbd_softraw = 1; | 54 | static bool atkbd_softraw = true; |
55 | module_param_named(softraw, atkbd_softraw, bool, 0); | 55 | module_param_named(softraw, atkbd_softraw, bool, 0); |
56 | MODULE_PARM_DESC(softraw, "Use software generated rawmode"); | 56 | MODULE_PARM_DESC(softraw, "Use software generated rawmode"); |
57 | 57 | ||
58 | static int atkbd_scroll; | 58 | static bool atkbd_scroll; |
59 | module_param_named(scroll, atkbd_scroll, bool, 0); | 59 | module_param_named(scroll, atkbd_scroll, bool, 0); |
60 | MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); | 60 | MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); |
61 | 61 | ||
62 | static int atkbd_extra; | 62 | static bool atkbd_extra; |
63 | module_param_named(extra, atkbd_extra, bool, 0); | 63 | module_param_named(extra, atkbd_extra, bool, 0); |
64 | MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); | 64 | MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); |
65 | 65 | ||
@@ -134,7 +134,8 @@ static const unsigned short atkbd_unxlate_table[128] = { | |||
134 | #define ATKBD_CMD_GETID 0x02f2 | 134 | #define ATKBD_CMD_GETID 0x02f2 |
135 | #define ATKBD_CMD_SETREP 0x10f3 | 135 | #define ATKBD_CMD_SETREP 0x10f3 |
136 | #define ATKBD_CMD_ENABLE 0x00f4 | 136 | #define ATKBD_CMD_ENABLE 0x00f4 |
137 | #define ATKBD_CMD_RESET_DIS 0x00f5 | 137 | #define ATKBD_CMD_RESET_DIS 0x00f5 /* Reset to defaults and disable */ |
138 | #define ATKBD_CMD_RESET_DEF 0x00f6 /* Reset to defaults */ | ||
138 | #define ATKBD_CMD_SETALL_MBR 0x00fa | 139 | #define ATKBD_CMD_SETALL_MBR 0x00fa |
139 | #define ATKBD_CMD_RESET_BAT 0x02ff | 140 | #define ATKBD_CMD_RESET_BAT 0x02ff |
140 | #define ATKBD_CMD_RESEND 0x00fe | 141 | #define ATKBD_CMD_RESEND 0x00fe |
@@ -152,16 +153,16 @@ static const unsigned short atkbd_unxlate_table[128] = { | |||
152 | #define ATKBD_RET_HANGEUL 0xf2 | 153 | #define ATKBD_RET_HANGEUL 0xf2 |
153 | #define ATKBD_RET_ERR 0xff | 154 | #define ATKBD_RET_ERR 0xff |
154 | 155 | ||
155 | #define ATKBD_KEY_UNKNOWN 0 | 156 | #define ATKBD_KEY_UNKNOWN 0 |
156 | #define ATKBD_KEY_NULL 255 | 157 | #define ATKBD_KEY_NULL 255 |
157 | 158 | ||
158 | #define ATKBD_SCR_1 254 | 159 | #define ATKBD_SCR_1 0xfffe |
159 | #define ATKBD_SCR_2 253 | 160 | #define ATKBD_SCR_2 0xfffd |
160 | #define ATKBD_SCR_4 252 | 161 | #define ATKBD_SCR_4 0xfffc |
161 | #define ATKBD_SCR_8 251 | 162 | #define ATKBD_SCR_8 0xfffb |
162 | #define ATKBD_SCR_CLICK 250 | 163 | #define ATKBD_SCR_CLICK 0xfffa |
163 | #define ATKBD_SCR_LEFT 249 | 164 | #define ATKBD_SCR_LEFT 0xfff9 |
164 | #define ATKBD_SCR_RIGHT 248 | 165 | #define ATKBD_SCR_RIGHT 0xfff8 |
165 | 166 | ||
166 | #define ATKBD_SPECIAL ATKBD_SCR_RIGHT | 167 | #define ATKBD_SPECIAL ATKBD_SCR_RIGHT |
167 | 168 | ||
@@ -176,7 +177,7 @@ static const unsigned short atkbd_unxlate_table[128] = { | |||
176 | #define ATKBD_XL_HANJA 0x20 | 177 | #define ATKBD_XL_HANJA 0x20 |
177 | 178 | ||
178 | static const struct { | 179 | static const struct { |
179 | unsigned char keycode; | 180 | unsigned short keycode; |
180 | unsigned char set2; | 181 | unsigned char set2; |
181 | } atkbd_scroll_keys[] = { | 182 | } atkbd_scroll_keys[] = { |
182 | { ATKBD_SCR_1, 0xc5 }, | 183 | { ATKBD_SCR_1, 0xc5 }, |
@@ -205,18 +206,18 @@ struct atkbd { | |||
205 | unsigned short keycode[ATKBD_KEYMAP_SIZE]; | 206 | unsigned short keycode[ATKBD_KEYMAP_SIZE]; |
206 | DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE); | 207 | DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE); |
207 | unsigned char set; | 208 | unsigned char set; |
208 | unsigned char translated; | 209 | bool translated; |
209 | unsigned char extra; | 210 | bool extra; |
210 | unsigned char write; | 211 | bool write; |
211 | unsigned char softrepeat; | 212 | bool softrepeat; |
212 | unsigned char softraw; | 213 | bool softraw; |
213 | unsigned char scroll; | 214 | bool scroll; |
214 | unsigned char enabled; | 215 | bool enabled; |
215 | 216 | ||
216 | /* Accessed only from interrupt */ | 217 | /* Accessed only from interrupt */ |
217 | unsigned char emul; | 218 | unsigned char emul; |
218 | unsigned char resend; | 219 | bool resend; |
219 | unsigned char release; | 220 | bool release; |
220 | unsigned long xl_bit; | 221 | unsigned long xl_bit; |
221 | unsigned int last; | 222 | unsigned int last; |
222 | unsigned long time; | 223 | unsigned long time; |
@@ -224,8 +225,10 @@ struct atkbd { | |||
224 | 225 | ||
225 | struct delayed_work event_work; | 226 | struct delayed_work event_work; |
226 | unsigned long event_jiffies; | 227 | unsigned long event_jiffies; |
227 | struct mutex event_mutex; | ||
228 | unsigned long event_mask; | 228 | unsigned long event_mask; |
229 | |||
230 | /* Serializes reconnect(), attr->set() and event work */ | ||
231 | struct mutex mutex; | ||
229 | }; | 232 | }; |
230 | 233 | ||
231 | /* | 234 | /* |
@@ -298,18 +301,18 @@ static const unsigned int xl_table[] = { | |||
298 | * Checks if we should mangle the scancode to extract 'release' bit | 301 | * Checks if we should mangle the scancode to extract 'release' bit |
299 | * in translated mode. | 302 | * in translated mode. |
300 | */ | 303 | */ |
301 | static int atkbd_need_xlate(unsigned long xl_bit, unsigned char code) | 304 | static bool atkbd_need_xlate(unsigned long xl_bit, unsigned char code) |
302 | { | 305 | { |
303 | int i; | 306 | int i; |
304 | 307 | ||
305 | if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1) | 308 | if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1) |
306 | return 0; | 309 | return false; |
307 | 310 | ||
308 | for (i = 0; i < ARRAY_SIZE(xl_table); i++) | 311 | for (i = 0; i < ARRAY_SIZE(xl_table); i++) |
309 | if (code == xl_table[i]) | 312 | if (code == xl_table[i]) |
310 | return test_bit(i, &xl_bit); | 313 | return test_bit(i, &xl_bit); |
311 | 314 | ||
312 | return 1; | 315 | return true; |
313 | } | 316 | } |
314 | 317 | ||
315 | /* | 318 | /* |
@@ -356,7 +359,7 @@ static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code | |||
356 | */ | 359 | */ |
357 | 360 | ||
358 | static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | 361 | static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, |
359 | unsigned int flags) | 362 | unsigned int flags) |
360 | { | 363 | { |
361 | struct atkbd *atkbd = serio_get_drvdata(serio); | 364 | struct atkbd *atkbd = serio_get_drvdata(serio); |
362 | struct input_dev *dev = atkbd->dev; | 365 | struct input_dev *dev = atkbd->dev; |
@@ -365,20 +368,18 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
365 | int value; | 368 | int value; |
366 | unsigned short keycode; | 369 | unsigned short keycode; |
367 | 370 | ||
368 | #ifdef ATKBD_DEBUG | 371 | dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, flags); |
369 | printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags); | ||
370 | #endif | ||
371 | 372 | ||
372 | #if !defined(__i386__) && !defined (__x86_64__) | 373 | #if !defined(__i386__) && !defined (__x86_64__) |
373 | if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) { | 374 | if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) { |
374 | printk(KERN_WARNING "atkbd.c: frame/parity error: %02x\n", flags); | 375 | dev_warn(&serio->dev, "Frame/parity error: %02x\n", flags); |
375 | serio_write(serio, ATKBD_CMD_RESEND); | 376 | serio_write(serio, ATKBD_CMD_RESEND); |
376 | atkbd->resend = 1; | 377 | atkbd->resend = true; |
377 | goto out; | 378 | goto out; |
378 | } | 379 | } |
379 | 380 | ||
380 | if (!flags && data == ATKBD_RET_ACK) | 381 | if (!flags && data == ATKBD_RET_ACK) |
381 | atkbd->resend = 0; | 382 | atkbd->resend = false; |
382 | #endif | 383 | #endif |
383 | 384 | ||
384 | if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_ACK)) | 385 | if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_ACK)) |
@@ -409,32 +410,32 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
409 | } | 410 | } |
410 | 411 | ||
411 | switch (code) { | 412 | switch (code) { |
412 | case ATKBD_RET_BAT: | 413 | case ATKBD_RET_BAT: |
413 | atkbd->enabled = 0; | 414 | atkbd->enabled = false; |
414 | serio_reconnect(atkbd->ps2dev.serio); | 415 | serio_reconnect(atkbd->ps2dev.serio); |
415 | goto out; | 416 | goto out; |
416 | case ATKBD_RET_EMUL0: | 417 | case ATKBD_RET_EMUL0: |
417 | atkbd->emul = 1; | 418 | atkbd->emul = 1; |
418 | goto out; | 419 | goto out; |
419 | case ATKBD_RET_EMUL1: | 420 | case ATKBD_RET_EMUL1: |
420 | atkbd->emul = 2; | 421 | atkbd->emul = 2; |
421 | goto out; | 422 | goto out; |
422 | case ATKBD_RET_RELEASE: | 423 | case ATKBD_RET_RELEASE: |
423 | atkbd->release = 1; | 424 | atkbd->release = true; |
424 | goto out; | 425 | goto out; |
425 | case ATKBD_RET_ACK: | 426 | case ATKBD_RET_ACK: |
426 | case ATKBD_RET_NAK: | 427 | case ATKBD_RET_NAK: |
427 | if (printk_ratelimit()) | 428 | if (printk_ratelimit()) |
428 | printk(KERN_WARNING "atkbd.c: Spurious %s on %s. " | 429 | dev_warn(&serio->dev, |
429 | "Some program might be trying access hardware directly.\n", | 430 | "Spurious %s on %s. " |
430 | data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); | 431 | "Some program might be trying access hardware directly.\n", |
431 | goto out; | 432 | data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); |
432 | case ATKBD_RET_ERR: | 433 | goto out; |
433 | atkbd->err_count++; | 434 | case ATKBD_RET_ERR: |
434 | #ifdef ATKBD_DEBUG | 435 | atkbd->err_count++; |
435 | printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); | 436 | dev_dbg(&serio->dev, "Keyboard on %s reports too many keys pressed.\n", |
436 | #endif | 437 | serio->phys); |
437 | goto out; | 438 | goto out; |
438 | } | 439 | } |
439 | 440 | ||
440 | code = atkbd_compat_scancode(atkbd, code); | 441 | code = atkbd_compat_scancode(atkbd, code); |
@@ -448,71 +449,72 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
448 | input_event(dev, EV_MSC, MSC_SCAN, code); | 449 | input_event(dev, EV_MSC, MSC_SCAN, code); |
449 | 450 | ||
450 | switch (keycode) { | 451 | switch (keycode) { |
451 | case ATKBD_KEY_NULL: | 452 | case ATKBD_KEY_NULL: |
452 | break; | 453 | break; |
453 | case ATKBD_KEY_UNKNOWN: | 454 | case ATKBD_KEY_UNKNOWN: |
454 | printk(KERN_WARNING | 455 | dev_warn(&serio->dev, |
455 | "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n", | 456 | "Unknown key %s (%s set %d, code %#x on %s).\n", |
456 | atkbd->release ? "released" : "pressed", | 457 | atkbd->release ? "released" : "pressed", |
457 | atkbd->translated ? "translated" : "raw", | 458 | atkbd->translated ? "translated" : "raw", |
458 | atkbd->set, code, serio->phys); | 459 | atkbd->set, code, serio->phys); |
459 | printk(KERN_WARNING | 460 | dev_warn(&serio->dev, |
460 | "atkbd.c: Use 'setkeycodes %s%02x <keycode>' to make it known.\n", | 461 | "Use 'setkeycodes %s%02x <keycode>' to make it known.\n", |
461 | code & 0x80 ? "e0" : "", code & 0x7f); | 462 | code & 0x80 ? "e0" : "", code & 0x7f); |
462 | input_sync(dev); | 463 | input_sync(dev); |
463 | break; | 464 | break; |
464 | case ATKBD_SCR_1: | 465 | case ATKBD_SCR_1: |
465 | scroll = 1 - atkbd->release * 2; | 466 | scroll = 1; |
466 | break; | 467 | break; |
467 | case ATKBD_SCR_2: | 468 | case ATKBD_SCR_2: |
468 | scroll = 2 - atkbd->release * 4; | 469 | scroll = 2; |
469 | break; | 470 | break; |
470 | case ATKBD_SCR_4: | 471 | case ATKBD_SCR_4: |
471 | scroll = 4 - atkbd->release * 8; | 472 | scroll = 4; |
472 | break; | 473 | break; |
473 | case ATKBD_SCR_8: | 474 | case ATKBD_SCR_8: |
474 | scroll = 8 - atkbd->release * 16; | 475 | scroll = 8; |
475 | break; | 476 | break; |
476 | case ATKBD_SCR_CLICK: | 477 | case ATKBD_SCR_CLICK: |
477 | click = !atkbd->release; | 478 | click = !atkbd->release; |
478 | break; | 479 | break; |
479 | case ATKBD_SCR_LEFT: | 480 | case ATKBD_SCR_LEFT: |
480 | hscroll = -1; | 481 | hscroll = -1; |
481 | break; | 482 | break; |
482 | case ATKBD_SCR_RIGHT: | 483 | case ATKBD_SCR_RIGHT: |
483 | hscroll = 1; | 484 | hscroll = 1; |
484 | break; | 485 | break; |
485 | default: | 486 | default: |
486 | if (atkbd->release) { | 487 | if (atkbd->release) { |
487 | value = 0; | 488 | value = 0; |
488 | atkbd->last = 0; | 489 | atkbd->last = 0; |
489 | } else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) { | 490 | } else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) { |
490 | /* Workaround Toshiba laptop multiple keypress */ | 491 | /* Workaround Toshiba laptop multiple keypress */ |
491 | value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2; | 492 | value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2; |
492 | } else { | 493 | } else { |
493 | value = 1; | 494 | value = 1; |
494 | atkbd->last = code; | 495 | atkbd->last = code; |
495 | atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2; | 496 | atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2; |
496 | } | 497 | } |
497 | 498 | ||
498 | input_event(dev, EV_KEY, keycode, value); | 499 | input_event(dev, EV_KEY, keycode, value); |
499 | input_sync(dev); | 500 | input_sync(dev); |
500 | 501 | ||
501 | if (value && test_bit(code, atkbd->force_release_mask)) { | 502 | if (value && test_bit(code, atkbd->force_release_mask)) { |
502 | input_report_key(dev, keycode, 0); | 503 | input_report_key(dev, keycode, 0); |
503 | input_sync(dev); | 504 | input_sync(dev); |
504 | } | 505 | } |
505 | } | 506 | } |
506 | 507 | ||
507 | if (atkbd->scroll) { | 508 | if (atkbd->scroll) { |
508 | if (click != -1) | 509 | if (click != -1) |
509 | input_report_key(dev, BTN_MIDDLE, click); | 510 | input_report_key(dev, BTN_MIDDLE, click); |
510 | input_report_rel(dev, REL_WHEEL, scroll); | 511 | input_report_rel(dev, REL_WHEEL, |
512 | atkbd->release ? -scroll : scroll); | ||
511 | input_report_rel(dev, REL_HWHEEL, hscroll); | 513 | input_report_rel(dev, REL_HWHEEL, hscroll); |
512 | input_sync(dev); | 514 | input_sync(dev); |
513 | } | 515 | } |
514 | 516 | ||
515 | atkbd->release = 0; | 517 | atkbd->release = false; |
516 | out: | 518 | out: |
517 | return IRQ_HANDLED; | 519 | return IRQ_HANDLED; |
518 | } | 520 | } |
@@ -576,7 +578,7 @@ static void atkbd_event_work(struct work_struct *work) | |||
576 | { | 578 | { |
577 | struct atkbd *atkbd = container_of(work, struct atkbd, event_work.work); | 579 | struct atkbd *atkbd = container_of(work, struct atkbd, event_work.work); |
578 | 580 | ||
579 | mutex_lock(&atkbd->event_mutex); | 581 | mutex_lock(&atkbd->mutex); |
580 | 582 | ||
581 | if (!atkbd->enabled) { | 583 | if (!atkbd->enabled) { |
582 | /* | 584 | /* |
@@ -595,7 +597,7 @@ static void atkbd_event_work(struct work_struct *work) | |||
595 | atkbd_set_repeat_rate(atkbd); | 597 | atkbd_set_repeat_rate(atkbd); |
596 | } | 598 | } |
597 | 599 | ||
598 | mutex_unlock(&atkbd->event_mutex); | 600 | mutex_unlock(&atkbd->mutex); |
599 | } | 601 | } |
600 | 602 | ||
601 | /* | 603 | /* |
@@ -611,7 +613,7 @@ static void atkbd_schedule_event_work(struct atkbd *atkbd, int event_bit) | |||
611 | 613 | ||
612 | atkbd->event_jiffies = jiffies; | 614 | atkbd->event_jiffies = jiffies; |
613 | set_bit(event_bit, &atkbd->event_mask); | 615 | set_bit(event_bit, &atkbd->event_mask); |
614 | wmb(); | 616 | mb(); |
615 | schedule_delayed_work(&atkbd->event_work, delay); | 617 | schedule_delayed_work(&atkbd->event_work, delay); |
616 | } | 618 | } |
617 | 619 | ||
@@ -631,17 +633,18 @@ static int atkbd_event(struct input_dev *dev, | |||
631 | 633 | ||
632 | switch (type) { | 634 | switch (type) { |
633 | 635 | ||
634 | case EV_LED: | 636 | case EV_LED: |
635 | atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT); | 637 | atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT); |
636 | return 0; | 638 | return 0; |
637 | 639 | ||
638 | case EV_REP: | 640 | case EV_REP: |
639 | if (!atkbd->softrepeat) | 641 | if (!atkbd->softrepeat) |
640 | atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT); | 642 | atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT); |
641 | return 0; | 643 | return 0; |
642 | } | ||
643 | 644 | ||
644 | return -1; | 645 | default: |
646 | return -1; | ||
647 | } | ||
645 | } | 648 | } |
646 | 649 | ||
647 | /* | 650 | /* |
@@ -652,7 +655,7 @@ static int atkbd_event(struct input_dev *dev, | |||
652 | static inline void atkbd_enable(struct atkbd *atkbd) | 655 | static inline void atkbd_enable(struct atkbd *atkbd) |
653 | { | 656 | { |
654 | serio_pause_rx(atkbd->ps2dev.serio); | 657 | serio_pause_rx(atkbd->ps2dev.serio); |
655 | atkbd->enabled = 1; | 658 | atkbd->enabled = true; |
656 | serio_continue_rx(atkbd->ps2dev.serio); | 659 | serio_continue_rx(atkbd->ps2dev.serio); |
657 | } | 660 | } |
658 | 661 | ||
@@ -664,7 +667,7 @@ static inline void atkbd_enable(struct atkbd *atkbd) | |||
664 | static inline void atkbd_disable(struct atkbd *atkbd) | 667 | static inline void atkbd_disable(struct atkbd *atkbd) |
665 | { | 668 | { |
666 | serio_pause_rx(atkbd->ps2dev.serio); | 669 | serio_pause_rx(atkbd->ps2dev.serio); |
667 | atkbd->enabled = 0; | 670 | atkbd->enabled = false; |
668 | serio_continue_rx(atkbd->ps2dev.serio); | 671 | serio_continue_rx(atkbd->ps2dev.serio); |
669 | } | 672 | } |
670 | 673 | ||
@@ -685,7 +688,9 @@ static int atkbd_probe(struct atkbd *atkbd) | |||
685 | 688 | ||
686 | if (atkbd_reset) | 689 | if (atkbd_reset) |
687 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_BAT)) | 690 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_BAT)) |
688 | printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", ps2dev->serio->phys); | 691 | dev_warn(&ps2dev->serio->dev, |
692 | "keyboard reset failed on %s\n", | ||
693 | ps2dev->serio->phys); | ||
689 | 694 | ||
690 | /* | 695 | /* |
691 | * Then we check the keyboard ID. We should get 0xab83 under normal conditions. | 696 | * Then we check the keyboard ID. We should get 0xab83 under normal conditions. |
@@ -715,8 +720,9 @@ static int atkbd_probe(struct atkbd *atkbd) | |||
715 | atkbd->id = (param[0] << 8) | param[1]; | 720 | atkbd->id = (param[0] << 8) | param[1]; |
716 | 721 | ||
717 | if (atkbd->id == 0xaca1 && atkbd->translated) { | 722 | if (atkbd->id == 0xaca1 && atkbd->translated) { |
718 | printk(KERN_ERR "atkbd.c: NCD terminal keyboards are only supported on non-translating\n"); | 723 | dev_err(&ps2dev->serio->dev, |
719 | printk(KERN_ERR "atkbd.c: controllers. Use i8042.direct=1 to disable translation.\n"); | 724 | "NCD terminal keyboards are only supported on non-translating controlelrs. " |
725 | "Use i8042.direct=1 to disable translation.\n"); | ||
720 | return -1; | 726 | return -1; |
721 | } | 727 | } |
722 | 728 | ||
@@ -734,7 +740,7 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra | |||
734 | struct ps2dev *ps2dev = &atkbd->ps2dev; | 740 | struct ps2dev *ps2dev = &atkbd->ps2dev; |
735 | unsigned char param[2]; | 741 | unsigned char param[2]; |
736 | 742 | ||
737 | atkbd->extra = 0; | 743 | atkbd->extra = false; |
738 | /* | 744 | /* |
739 | * For known special keyboards we can go ahead and set the correct set. | 745 | * For known special keyboards we can go ahead and set the correct set. |
740 | * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and | 746 | * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and |
@@ -753,7 +759,7 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra | |||
753 | if (allow_extra) { | 759 | if (allow_extra) { |
754 | param[0] = 0x71; | 760 | param[0] = 0x71; |
755 | if (!ps2_command(ps2dev, param, ATKBD_CMD_EX_ENABLE)) { | 761 | if (!ps2_command(ps2dev, param, ATKBD_CMD_EX_ENABLE)) { |
756 | atkbd->extra = 1; | 762 | atkbd->extra = true; |
757 | return 2; | 763 | return 2; |
758 | } | 764 | } |
759 | } | 765 | } |
@@ -818,7 +824,8 @@ static int atkbd_activate(struct atkbd *atkbd) | |||
818 | */ | 824 | */ |
819 | 825 | ||
820 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) { | 826 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) { |
821 | printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n", | 827 | dev_err(&ps2dev->serio->dev, |
828 | "Failed to enable keyboard on %s\n", | ||
822 | ps2dev->serio->phys); | 829 | ps2dev->serio->phys); |
823 | return -1; | 830 | return -1; |
824 | } | 831 | } |
@@ -836,7 +843,7 @@ static void atkbd_cleanup(struct serio *serio) | |||
836 | struct atkbd *atkbd = serio_get_drvdata(serio); | 843 | struct atkbd *atkbd = serio_get_drvdata(serio); |
837 | 844 | ||
838 | atkbd_disable(atkbd); | 845 | atkbd_disable(atkbd); |
839 | ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_BAT); | 846 | ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_DEF); |
840 | } | 847 | } |
841 | 848 | ||
842 | 849 | ||
@@ -848,13 +855,20 @@ static void atkbd_disconnect(struct serio *serio) | |||
848 | { | 855 | { |
849 | struct atkbd *atkbd = serio_get_drvdata(serio); | 856 | struct atkbd *atkbd = serio_get_drvdata(serio); |
850 | 857 | ||
858 | sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); | ||
859 | |||
851 | atkbd_disable(atkbd); | 860 | atkbd_disable(atkbd); |
852 | 861 | ||
853 | /* make sure we don't have a command in flight */ | 862 | input_unregister_device(atkbd->dev); |
863 | |||
864 | /* | ||
865 | * Make sure we don't have a command in flight. | ||
866 | * Note that since atkbd->enabled is false event work will keep | ||
867 | * rescheduling itself until it gets canceled and will not try | ||
868 | * accessing freed input device or serio port. | ||
869 | */ | ||
854 | cancel_delayed_work_sync(&atkbd->event_work); | 870 | cancel_delayed_work_sync(&atkbd->event_work); |
855 | 871 | ||
856 | sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); | ||
857 | input_unregister_device(atkbd->dev); | ||
858 | serio_close(serio); | 872 | serio_close(serio); |
859 | serio_set_drvdata(serio, NULL); | 873 | serio_set_drvdata(serio, NULL); |
860 | kfree(atkbd); | 874 | kfree(atkbd); |
@@ -1060,9 +1074,13 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) | |||
1060 | input_dev->keycodesize = sizeof(unsigned short); | 1074 | input_dev->keycodesize = sizeof(unsigned short); |
1061 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); | 1075 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); |
1062 | 1076 | ||
1063 | for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) | 1077 | for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) { |
1064 | if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) | 1078 | if (atkbd->keycode[i] != KEY_RESERVED && |
1079 | atkbd->keycode[i] != ATKBD_KEY_NULL && | ||
1080 | atkbd->keycode[i] < ATKBD_SPECIAL) { | ||
1065 | __set_bit(atkbd->keycode[i], input_dev->keybit); | 1081 | __set_bit(atkbd->keycode[i], input_dev->keybit); |
1082 | } | ||
1083 | } | ||
1066 | } | 1084 | } |
1067 | 1085 | ||
1068 | /* | 1086 | /* |
@@ -1086,16 +1104,18 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
1086 | atkbd->dev = dev; | 1104 | atkbd->dev = dev; |
1087 | ps2_init(&atkbd->ps2dev, serio); | 1105 | ps2_init(&atkbd->ps2dev, serio); |
1088 | INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work); | 1106 | INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work); |
1089 | mutex_init(&atkbd->event_mutex); | 1107 | mutex_init(&atkbd->mutex); |
1090 | 1108 | ||
1091 | switch (serio->id.type) { | 1109 | switch (serio->id.type) { |
1092 | 1110 | ||
1093 | case SERIO_8042_XL: | 1111 | case SERIO_8042_XL: |
1094 | atkbd->translated = 1; | 1112 | atkbd->translated = true; |
1095 | case SERIO_8042: | 1113 | /* Fall through */ |
1096 | if (serio->write) | 1114 | |
1097 | atkbd->write = 1; | 1115 | case SERIO_8042: |
1098 | break; | 1116 | if (serio->write) |
1117 | atkbd->write = true; | ||
1118 | break; | ||
1099 | } | 1119 | } |
1100 | 1120 | ||
1101 | atkbd->softraw = atkbd_softraw; | 1121 | atkbd->softraw = atkbd_softraw; |
@@ -1103,7 +1123,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
1103 | atkbd->scroll = atkbd_scroll; | 1123 | atkbd->scroll = atkbd_scroll; |
1104 | 1124 | ||
1105 | if (atkbd->softrepeat) | 1125 | if (atkbd->softrepeat) |
1106 | atkbd->softraw = 1; | 1126 | atkbd->softraw = true; |
1107 | 1127 | ||
1108 | serio_set_drvdata(serio, atkbd); | 1128 | serio_set_drvdata(serio, atkbd); |
1109 | 1129 | ||
@@ -1159,19 +1179,24 @@ static int atkbd_reconnect(struct serio *serio) | |||
1159 | { | 1179 | { |
1160 | struct atkbd *atkbd = serio_get_drvdata(serio); | 1180 | struct atkbd *atkbd = serio_get_drvdata(serio); |
1161 | struct serio_driver *drv = serio->drv; | 1181 | struct serio_driver *drv = serio->drv; |
1182 | int retval = -1; | ||
1162 | 1183 | ||
1163 | if (!atkbd || !drv) { | 1184 | if (!atkbd || !drv) { |
1164 | printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); | 1185 | dev_dbg(&serio->dev, |
1186 | "reconnect request, but serio is disconnected, ignoring...\n"); | ||
1165 | return -1; | 1187 | return -1; |
1166 | } | 1188 | } |
1167 | 1189 | ||
1190 | mutex_lock(&atkbd->mutex); | ||
1191 | |||
1168 | atkbd_disable(atkbd); | 1192 | atkbd_disable(atkbd); |
1169 | 1193 | ||
1170 | if (atkbd->write) { | 1194 | if (atkbd->write) { |
1171 | if (atkbd_probe(atkbd)) | 1195 | if (atkbd_probe(atkbd)) |
1172 | return -1; | 1196 | goto out; |
1197 | |||
1173 | if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) | 1198 | if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) |
1174 | return -1; | 1199 | goto out; |
1175 | 1200 | ||
1176 | atkbd_activate(atkbd); | 1201 | atkbd_activate(atkbd); |
1177 | 1202 | ||
@@ -1189,8 +1214,11 @@ static int atkbd_reconnect(struct serio *serio) | |||
1189 | } | 1214 | } |
1190 | 1215 | ||
1191 | atkbd_enable(atkbd); | 1216 | atkbd_enable(atkbd); |
1217 | retval = 0; | ||
1192 | 1218 | ||
1193 | return 0; | 1219 | out: |
1220 | mutex_unlock(&atkbd->mutex); | ||
1221 | return retval; | ||
1194 | } | 1222 | } |
1195 | 1223 | ||
1196 | static struct serio_device_id atkbd_serio_ids[] = { | 1224 | static struct serio_device_id atkbd_serio_ids[] = { |
@@ -1234,47 +1262,28 @@ static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, | |||
1234 | ssize_t (*handler)(struct atkbd *, char *)) | 1262 | ssize_t (*handler)(struct atkbd *, char *)) |
1235 | { | 1263 | { |
1236 | struct serio *serio = to_serio_port(dev); | 1264 | struct serio *serio = to_serio_port(dev); |
1237 | int retval; | 1265 | struct atkbd *atkbd = serio_get_drvdata(serio); |
1238 | |||
1239 | retval = serio_pin_driver(serio); | ||
1240 | if (retval) | ||
1241 | return retval; | ||
1242 | |||
1243 | if (serio->drv != &atkbd_drv) { | ||
1244 | retval = -ENODEV; | ||
1245 | goto out; | ||
1246 | } | ||
1247 | |||
1248 | retval = handler((struct atkbd *)serio_get_drvdata(serio), buf); | ||
1249 | 1266 | ||
1250 | out: | 1267 | return handler(atkbd, buf); |
1251 | serio_unpin_driver(serio); | ||
1252 | return retval; | ||
1253 | } | 1268 | } |
1254 | 1269 | ||
1255 | static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, | 1270 | static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, |
1256 | ssize_t (*handler)(struct atkbd *, const char *, size_t)) | 1271 | ssize_t (*handler)(struct atkbd *, const char *, size_t)) |
1257 | { | 1272 | { |
1258 | struct serio *serio = to_serio_port(dev); | 1273 | struct serio *serio = to_serio_port(dev); |
1259 | struct atkbd *atkbd; | 1274 | struct atkbd *atkbd = serio_get_drvdata(serio); |
1260 | int retval; | 1275 | int retval; |
1261 | 1276 | ||
1262 | retval = serio_pin_driver(serio); | 1277 | retval = mutex_lock_interruptible(&atkbd->mutex); |
1263 | if (retval) | 1278 | if (retval) |
1264 | return retval; | 1279 | return retval; |
1265 | 1280 | ||
1266 | if (serio->drv != &atkbd_drv) { | ||
1267 | retval = -ENODEV; | ||
1268 | goto out; | ||
1269 | } | ||
1270 | |||
1271 | atkbd = serio_get_drvdata(serio); | ||
1272 | atkbd_disable(atkbd); | 1281 | atkbd_disable(atkbd); |
1273 | retval = handler(atkbd, buf, count); | 1282 | retval = handler(atkbd, buf, count); |
1274 | atkbd_enable(atkbd); | 1283 | atkbd_enable(atkbd); |
1275 | 1284 | ||
1276 | out: | 1285 | mutex_unlock(&atkbd->mutex); |
1277 | serio_unpin_driver(serio); | 1286 | |
1278 | return retval; | 1287 | return retval; |
1279 | } | 1288 | } |
1280 | 1289 | ||
@@ -1288,7 +1297,8 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun | |||
1288 | struct input_dev *old_dev, *new_dev; | 1297 | struct input_dev *old_dev, *new_dev; |
1289 | unsigned long value; | 1298 | unsigned long value; |
1290 | int err; | 1299 | int err; |
1291 | unsigned char old_extra, old_set; | 1300 | bool old_extra; |
1301 | unsigned char old_set; | ||
1292 | 1302 | ||
1293 | if (!atkbd->write) | 1303 | if (!atkbd->write) |
1294 | return -EIO; | 1304 | return -EIO; |
@@ -1371,7 +1381,7 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou | |||
1371 | struct input_dev *old_dev, *new_dev; | 1381 | struct input_dev *old_dev, *new_dev; |
1372 | unsigned long value; | 1382 | unsigned long value; |
1373 | int err; | 1383 | int err; |
1374 | unsigned char old_scroll; | 1384 | bool old_scroll; |
1375 | 1385 | ||
1376 | if (strict_strtoul(buf, 10, &value) || value > 1) | 1386 | if (strict_strtoul(buf, 10, &value) || value > 1) |
1377 | return -EINVAL; | 1387 | return -EINVAL; |
@@ -1415,7 +1425,8 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) | |||
1415 | struct input_dev *old_dev, *new_dev; | 1425 | struct input_dev *old_dev, *new_dev; |
1416 | unsigned long value; | 1426 | unsigned long value; |
1417 | int err; | 1427 | int err; |
1418 | unsigned char old_set, old_extra; | 1428 | unsigned char old_set; |
1429 | bool old_extra; | ||
1419 | 1430 | ||
1420 | if (!atkbd->write) | 1431 | if (!atkbd->write) |
1421 | return -EIO; | 1432 | return -EIO; |
@@ -1465,7 +1476,7 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t | |||
1465 | struct input_dev *old_dev, *new_dev; | 1476 | struct input_dev *old_dev, *new_dev; |
1466 | unsigned long value; | 1477 | unsigned long value; |
1467 | int err; | 1478 | int err; |
1468 | unsigned char old_softrepeat, old_softraw; | 1479 | bool old_softrepeat, old_softraw; |
1469 | 1480 | ||
1470 | if (!atkbd->write) | 1481 | if (!atkbd->write) |
1471 | return -EIO; | 1482 | return -EIO; |
@@ -1485,7 +1496,7 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t | |||
1485 | atkbd->dev = new_dev; | 1496 | atkbd->dev = new_dev; |
1486 | atkbd->softrepeat = value; | 1497 | atkbd->softrepeat = value; |
1487 | if (atkbd->softrepeat) | 1498 | if (atkbd->softrepeat) |
1488 | atkbd->softraw = 1; | 1499 | atkbd->softraw = true; |
1489 | atkbd_set_device_attrs(atkbd); | 1500 | atkbd_set_device_attrs(atkbd); |
1490 | 1501 | ||
1491 | err = input_register_device(atkbd->dev); | 1502 | err = input_register_device(atkbd->dev); |
@@ -1515,7 +1526,7 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co | |||
1515 | struct input_dev *old_dev, *new_dev; | 1526 | struct input_dev *old_dev, *new_dev; |
1516 | unsigned long value; | 1527 | unsigned long value; |
1517 | int err; | 1528 | int err; |
1518 | unsigned char old_softraw; | 1529 | bool old_softraw; |
1519 | 1530 | ||
1520 | if (strict_strtoul(buf, 10, &value) || value > 1) | 1531 | if (strict_strtoul(buf, 10, &value) || value > 1) |
1521 | return -EINVAL; | 1532 | return -EINVAL; |
@@ -1567,9 +1578,8 @@ static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id) | |||
1567 | return 0; | 1578 | return 0; |
1568 | } | 1579 | } |
1569 | 1580 | ||
1570 | static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | 1581 | static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = { |
1571 | { | 1582 | { |
1572 | .ident = "Dell Laptop", | ||
1573 | .matches = { | 1583 | .matches = { |
1574 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 1584 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
1575 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 1585 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ |
@@ -1578,7 +1588,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1578 | .driver_data = atkbd_dell_laptop_forced_release_keys, | 1588 | .driver_data = atkbd_dell_laptop_forced_release_keys, |
1579 | }, | 1589 | }, |
1580 | { | 1590 | { |
1581 | .ident = "Dell Laptop", | ||
1582 | .matches = { | 1591 | .matches = { |
1583 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), | 1592 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), |
1584 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 1593 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ |
@@ -1587,7 +1596,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1587 | .driver_data = atkbd_dell_laptop_forced_release_keys, | 1596 | .driver_data = atkbd_dell_laptop_forced_release_keys, |
1588 | }, | 1597 | }, |
1589 | { | 1598 | { |
1590 | .ident = "HP 2133", | ||
1591 | .matches = { | 1599 | .matches = { |
1592 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1600 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1593 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), | 1601 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), |
@@ -1596,7 +1604,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1596 | .driver_data = atkbd_hp_forced_release_keys, | 1604 | .driver_data = atkbd_hp_forced_release_keys, |
1597 | }, | 1605 | }, |
1598 | { | 1606 | { |
1599 | .ident = "HP Pavilion ZV6100", | ||
1600 | .matches = { | 1607 | .matches = { |
1601 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1608 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1602 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), | 1609 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), |
@@ -1605,7 +1612,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1605 | .driver_data = atkbd_volume_forced_release_keys, | 1612 | .driver_data = atkbd_volume_forced_release_keys, |
1606 | }, | 1613 | }, |
1607 | { | 1614 | { |
1608 | .ident = "HP Presario R4000", | ||
1609 | .matches = { | 1615 | .matches = { |
1610 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1616 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1611 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"), | 1617 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"), |
@@ -1614,7 +1620,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1614 | .driver_data = atkbd_volume_forced_release_keys, | 1620 | .driver_data = atkbd_volume_forced_release_keys, |
1615 | }, | 1621 | }, |
1616 | { | 1622 | { |
1617 | .ident = "HP Presario R4100", | ||
1618 | .matches = { | 1623 | .matches = { |
1619 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1624 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1620 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"), | 1625 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"), |
@@ -1623,7 +1628,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1623 | .driver_data = atkbd_volume_forced_release_keys, | 1628 | .driver_data = atkbd_volume_forced_release_keys, |
1624 | }, | 1629 | }, |
1625 | { | 1630 | { |
1626 | .ident = "HP Presario R4200", | ||
1627 | .matches = { | 1631 | .matches = { |
1628 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1632 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1629 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"), | 1633 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"), |
@@ -1632,7 +1636,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1632 | .driver_data = atkbd_volume_forced_release_keys, | 1636 | .driver_data = atkbd_volume_forced_release_keys, |
1633 | }, | 1637 | }, |
1634 | { | 1638 | { |
1635 | .ident = "Inventec Symphony", | 1639 | /* Inventec Symphony */ |
1636 | .matches = { | 1640 | .matches = { |
1637 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), | 1641 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), |
1638 | DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), | 1642 | DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), |
@@ -1641,7 +1645,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1641 | .driver_data = atkbd_volume_forced_release_keys, | 1645 | .driver_data = atkbd_volume_forced_release_keys, |
1642 | }, | 1646 | }, |
1643 | { | 1647 | { |
1644 | .ident = "Samsung NC10", | 1648 | /* Samsung NC10 */ |
1645 | .matches = { | 1649 | .matches = { |
1646 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 1650 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
1647 | DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), | 1651 | DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), |
@@ -1650,7 +1654,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1650 | .driver_data = atkbd_samsung_forced_release_keys, | 1654 | .driver_data = atkbd_samsung_forced_release_keys, |
1651 | }, | 1655 | }, |
1652 | { | 1656 | { |
1653 | .ident = "Samsung NC20", | 1657 | /* Samsung NC20 */ |
1654 | .matches = { | 1658 | .matches = { |
1655 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 1659 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
1656 | DMI_MATCH(DMI_PRODUCT_NAME, "NC20"), | 1660 | DMI_MATCH(DMI_PRODUCT_NAME, "NC20"), |
@@ -1659,7 +1663,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1659 | .driver_data = atkbd_samsung_forced_release_keys, | 1663 | .driver_data = atkbd_samsung_forced_release_keys, |
1660 | }, | 1664 | }, |
1661 | { | 1665 | { |
1662 | .ident = "Samsung SQ45S70S", | 1666 | /* Samsung SQ45S70S */ |
1663 | .matches = { | 1667 | .matches = { |
1664 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 1668 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
1665 | DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"), | 1669 | DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"), |
@@ -1668,7 +1672,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1668 | .driver_data = atkbd_samsung_forced_release_keys, | 1672 | .driver_data = atkbd_samsung_forced_release_keys, |
1669 | }, | 1673 | }, |
1670 | { | 1674 | { |
1671 | .ident = "Fujitsu Amilo PA 1510", | 1675 | /* Fujitsu Amilo PA 1510 */ |
1672 | .matches = { | 1676 | .matches = { |
1673 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1677 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
1674 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"), | 1678 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"), |
@@ -1677,7 +1681,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1677 | .driver_data = atkbd_volume_forced_release_keys, | 1681 | .driver_data = atkbd_volume_forced_release_keys, |
1678 | }, | 1682 | }, |
1679 | { | 1683 | { |
1680 | .ident = "Fujitsu Amilo Pi 3525", | 1684 | /* Fujitsu Amilo Pi 3525 */ |
1681 | .matches = { | 1685 | .matches = { |
1682 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1686 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
1683 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 3525"), | 1687 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 3525"), |
@@ -1686,7 +1690,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1686 | .driver_data = atkbd_amilo_pi3525_forced_release_keys, | 1690 | .driver_data = atkbd_amilo_pi3525_forced_release_keys, |
1687 | }, | 1691 | }, |
1688 | { | 1692 | { |
1689 | .ident = "Fujitsu Amilo Xi 3650", | 1693 | /* Fujitsu Amilo Xi 3650 */ |
1690 | .matches = { | 1694 | .matches = { |
1691 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1695 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
1692 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"), | 1696 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"), |
@@ -1695,7 +1699,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1695 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, | 1699 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, |
1696 | }, | 1700 | }, |
1697 | { | 1701 | { |
1698 | .ident = "Soltech Corporation TA12", | ||
1699 | .matches = { | 1702 | .matches = { |
1700 | DMI_MATCH(DMI_SYS_VENDOR, "Soltech Corporation"), | 1703 | DMI_MATCH(DMI_SYS_VENDOR, "Soltech Corporation"), |
1701 | DMI_MATCH(DMI_PRODUCT_NAME, "TA12"), | 1704 | DMI_MATCH(DMI_PRODUCT_NAME, "TA12"), |
@@ -1704,7 +1707,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1704 | .driver_data = atkdb_soltech_ta12_forced_release_keys, | 1707 | .driver_data = atkdb_soltech_ta12_forced_release_keys, |
1705 | }, | 1708 | }, |
1706 | { | 1709 | { |
1707 | .ident = "OQO Model 01+", | 1710 | /* OQO Model 01+ */ |
1708 | .matches = { | 1711 | .matches = { |
1709 | DMI_MATCH(DMI_SYS_VENDOR, "OQO"), | 1712 | DMI_MATCH(DMI_SYS_VENDOR, "OQO"), |
1710 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), | 1713 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), |
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index fe376a27fe57..7d989603f875 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/fs.h> | 34 | #include <linux/fs.h> |
35 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
36 | #include <linux/irq.h> | 36 | #include <linux/irq.h> |
37 | #include <linux/slab.h> | ||
37 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
38 | #include <linux/pm.h> | 39 | #include <linux/pm.h> |
39 | #include <linux/sysctl.h> | 40 | #include <linux/sysctl.h> |
@@ -162,7 +163,7 @@ static irqreturn_t bfin_kpad_isr(int irq, void *dev_id) | |||
162 | input_sync(input); | 163 | input_sync(input); |
163 | 164 | ||
164 | if (bfin_kpad_get_keypressed(bf54x_kpad)) { | 165 | if (bfin_kpad_get_keypressed(bf54x_kpad)) { |
165 | disable_irq(bf54x_kpad->irq); | 166 | disable_irq_nosync(bf54x_kpad->irq); |
166 | bf54x_kpad->lastkey = key; | 167 | bf54x_kpad->lastkey = key; |
167 | mod_timer(&bf54x_kpad->timer, | 168 | mod_timer(&bf54x_kpad->timer, |
168 | jiffies + bf54x_kpad->keyup_test_jiffies); | 169 | jiffies + bf54x_kpad->keyup_test_jiffies); |
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c new file mode 100644 index 000000000000..a91ee941b5c1 --- /dev/null +++ b/drivers/input/keyboard/davinci_keyscan.c | |||
@@ -0,0 +1,346 @@ | |||
1 | /* | ||
2 | * DaVinci Key Scan Driver for TI platforms | ||
3 | * | ||
4 | * Copyright (C) 2009 Texas Instruments, Inc | ||
5 | * | ||
6 | * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> | ||
7 | * | ||
8 | * Intial Code: Sandeep Paulraj <s-paulraj@ti.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 as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | */ | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/input.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/errno.h> | ||
33 | #include <linux/slab.h> | ||
34 | |||
35 | #include <asm/irq.h> | ||
36 | |||
37 | #include <mach/hardware.h> | ||
38 | #include <mach/irqs.h> | ||
39 | #include <mach/keyscan.h> | ||
40 | |||
41 | /* Key scan registers */ | ||
42 | #define DAVINCI_KEYSCAN_KEYCTRL 0x0000 | ||
43 | #define DAVINCI_KEYSCAN_INTENA 0x0004 | ||
44 | #define DAVINCI_KEYSCAN_INTFLAG 0x0008 | ||
45 | #define DAVINCI_KEYSCAN_INTCLR 0x000c | ||
46 | #define DAVINCI_KEYSCAN_STRBWIDTH 0x0010 | ||
47 | #define DAVINCI_KEYSCAN_INTERVAL 0x0014 | ||
48 | #define DAVINCI_KEYSCAN_CONTTIME 0x0018 | ||
49 | #define DAVINCI_KEYSCAN_CURRENTST 0x001c | ||
50 | #define DAVINCI_KEYSCAN_PREVSTATE 0x0020 | ||
51 | #define DAVINCI_KEYSCAN_EMUCTRL 0x0024 | ||
52 | #define DAVINCI_KEYSCAN_IODFTCTRL 0x002c | ||
53 | |||
54 | /* Key Control Register (KEYCTRL) */ | ||
55 | #define DAVINCI_KEYSCAN_KEYEN 0x00000001 | ||
56 | #define DAVINCI_KEYSCAN_PREVMODE 0x00000002 | ||
57 | #define DAVINCI_KEYSCAN_CHATOFF 0x00000004 | ||
58 | #define DAVINCI_KEYSCAN_AUTODET 0x00000008 | ||
59 | #define DAVINCI_KEYSCAN_SCANMODE 0x00000010 | ||
60 | #define DAVINCI_KEYSCAN_OUTTYPE 0x00000020 | ||
61 | |||
62 | /* Masks for the interrupts */ | ||
63 | #define DAVINCI_KEYSCAN_INT_CONT 0x00000008 | ||
64 | #define DAVINCI_KEYSCAN_INT_OFF 0x00000004 | ||
65 | #define DAVINCI_KEYSCAN_INT_ON 0x00000002 | ||
66 | #define DAVINCI_KEYSCAN_INT_CHANGE 0x00000001 | ||
67 | #define DAVINCI_KEYSCAN_INT_ALL 0x0000000f | ||
68 | |||
69 | struct davinci_ks { | ||
70 | struct input_dev *input; | ||
71 | struct davinci_ks_platform_data *pdata; | ||
72 | int irq; | ||
73 | void __iomem *base; | ||
74 | resource_size_t pbase; | ||
75 | size_t base_size; | ||
76 | unsigned short keymap[]; | ||
77 | }; | ||
78 | |||
79 | /* Initializing the kp Module */ | ||
80 | static int __init davinci_ks_initialize(struct davinci_ks *davinci_ks) | ||
81 | { | ||
82 | struct device *dev = &davinci_ks->input->dev; | ||
83 | struct davinci_ks_platform_data *pdata = davinci_ks->pdata; | ||
84 | u32 matrix_ctrl; | ||
85 | |||
86 | /* Enable all interrupts */ | ||
87 | __raw_writel(DAVINCI_KEYSCAN_INT_ALL, | ||
88 | davinci_ks->base + DAVINCI_KEYSCAN_INTENA); | ||
89 | |||
90 | /* Clear interrupts if any */ | ||
91 | __raw_writel(DAVINCI_KEYSCAN_INT_ALL, | ||
92 | davinci_ks->base + DAVINCI_KEYSCAN_INTCLR); | ||
93 | |||
94 | /* Setup the scan period = strobe + interval */ | ||
95 | __raw_writel(pdata->strobe, | ||
96 | davinci_ks->base + DAVINCI_KEYSCAN_STRBWIDTH); | ||
97 | __raw_writel(pdata->interval, | ||
98 | davinci_ks->base + DAVINCI_KEYSCAN_INTERVAL); | ||
99 | __raw_writel(0x01, | ||
100 | davinci_ks->base + DAVINCI_KEYSCAN_CONTTIME); | ||
101 | |||
102 | /* Define matrix type */ | ||
103 | switch (pdata->matrix_type) { | ||
104 | case DAVINCI_KEYSCAN_MATRIX_4X4: | ||
105 | matrix_ctrl = 0; | ||
106 | break; | ||
107 | case DAVINCI_KEYSCAN_MATRIX_5X3: | ||
108 | matrix_ctrl = (1 << 6); | ||
109 | break; | ||
110 | default: | ||
111 | dev_err(dev->parent, "wrong matrix type\n"); | ||
112 | return -EINVAL; | ||
113 | } | ||
114 | |||
115 | /* Enable key scan module and set matrix type */ | ||
116 | __raw_writel(DAVINCI_KEYSCAN_AUTODET | DAVINCI_KEYSCAN_KEYEN | | ||
117 | matrix_ctrl, davinci_ks->base + DAVINCI_KEYSCAN_KEYCTRL); | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static irqreturn_t davinci_ks_interrupt(int irq, void *dev_id) | ||
123 | { | ||
124 | struct davinci_ks *davinci_ks = dev_id; | ||
125 | struct device *dev = &davinci_ks->input->dev; | ||
126 | unsigned short *keymap = davinci_ks->keymap; | ||
127 | int keymapsize = davinci_ks->pdata->keymapsize; | ||
128 | u32 prev_status, new_status, changed; | ||
129 | bool release; | ||
130 | int keycode = KEY_UNKNOWN; | ||
131 | int i; | ||
132 | |||
133 | /* Disable interrupt */ | ||
134 | __raw_writel(0x0, davinci_ks->base + DAVINCI_KEYSCAN_INTENA); | ||
135 | |||
136 | /* Reading previous and new status of the key scan */ | ||
137 | prev_status = __raw_readl(davinci_ks->base + DAVINCI_KEYSCAN_PREVSTATE); | ||
138 | new_status = __raw_readl(davinci_ks->base + DAVINCI_KEYSCAN_CURRENTST); | ||
139 | |||
140 | changed = prev_status ^ new_status; | ||
141 | |||
142 | if (changed) { | ||
143 | /* | ||
144 | * It goes through all bits in 'changed' to ensure | ||
145 | * that no key changes are being missed | ||
146 | */ | ||
147 | for (i = 0 ; i < keymapsize; i++) { | ||
148 | if ((changed>>i) & 0x1) { | ||
149 | keycode = keymap[i]; | ||
150 | release = (new_status >> i) & 0x1; | ||
151 | dev_dbg(dev->parent, "key %d %s\n", keycode, | ||
152 | release ? "released" : "pressed"); | ||
153 | input_report_key(davinci_ks->input, keycode, | ||
154 | !release); | ||
155 | input_sync(davinci_ks->input); | ||
156 | } | ||
157 | } | ||
158 | /* Clearing interrupt */ | ||
159 | __raw_writel(DAVINCI_KEYSCAN_INT_ALL, | ||
160 | davinci_ks->base + DAVINCI_KEYSCAN_INTCLR); | ||
161 | } | ||
162 | |||
163 | /* Enable interrupts */ | ||
164 | __raw_writel(0x1, davinci_ks->base + DAVINCI_KEYSCAN_INTENA); | ||
165 | |||
166 | return IRQ_HANDLED; | ||
167 | } | ||
168 | |||
169 | static int __init davinci_ks_probe(struct platform_device *pdev) | ||
170 | { | ||
171 | struct davinci_ks *davinci_ks; | ||
172 | struct input_dev *key_dev; | ||
173 | struct resource *res, *mem; | ||
174 | struct device *dev = &pdev->dev; | ||
175 | struct davinci_ks_platform_data *pdata = pdev->dev.platform_data; | ||
176 | int error, i; | ||
177 | |||
178 | if (pdata->device_enable) { | ||
179 | error = pdata->device_enable(dev); | ||
180 | if (error < 0) { | ||
181 | dev_dbg(dev, "device enable function failed\n"); | ||
182 | return error; | ||
183 | } | ||
184 | } | ||
185 | |||
186 | if (!pdata->keymap) { | ||
187 | dev_dbg(dev, "no keymap from pdata\n"); | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | |||
191 | davinci_ks = kzalloc(sizeof(struct davinci_ks) + | ||
192 | sizeof(unsigned short) * pdata->keymapsize, GFP_KERNEL); | ||
193 | if (!davinci_ks) { | ||
194 | dev_dbg(dev, "could not allocate memory for private data\n"); | ||
195 | return -ENOMEM; | ||
196 | } | ||
197 | |||
198 | memcpy(davinci_ks->keymap, pdata->keymap, | ||
199 | sizeof(unsigned short) * pdata->keymapsize); | ||
200 | |||
201 | key_dev = input_allocate_device(); | ||
202 | if (!key_dev) { | ||
203 | dev_dbg(dev, "could not allocate input device\n"); | ||
204 | error = -ENOMEM; | ||
205 | goto fail1; | ||
206 | } | ||
207 | |||
208 | davinci_ks->input = key_dev; | ||
209 | |||
210 | davinci_ks->irq = platform_get_irq(pdev, 0); | ||
211 | if (davinci_ks->irq < 0) { | ||
212 | dev_err(dev, "no key scan irq\n"); | ||
213 | error = davinci_ks->irq; | ||
214 | goto fail2; | ||
215 | } | ||
216 | |||
217 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
218 | if (!res) { | ||
219 | dev_err(dev, "no mem resource\n"); | ||
220 | error = -EINVAL; | ||
221 | goto fail2; | ||
222 | } | ||
223 | |||
224 | davinci_ks->pbase = res->start; | ||
225 | davinci_ks->base_size = resource_size(res); | ||
226 | |||
227 | mem = request_mem_region(davinci_ks->pbase, davinci_ks->base_size, | ||
228 | pdev->name); | ||
229 | if (!mem) { | ||
230 | dev_err(dev, "key scan registers at %08x are not free\n", | ||
231 | davinci_ks->pbase); | ||
232 | error = -EBUSY; | ||
233 | goto fail2; | ||
234 | } | ||
235 | |||
236 | davinci_ks->base = ioremap(davinci_ks->pbase, davinci_ks->base_size); | ||
237 | if (!davinci_ks->base) { | ||
238 | dev_err(dev, "can't ioremap MEM resource.\n"); | ||
239 | error = -ENOMEM; | ||
240 | goto fail3; | ||
241 | } | ||
242 | |||
243 | /* Enable auto repeat feature of Linux input subsystem */ | ||
244 | if (pdata->rep) | ||
245 | __set_bit(EV_REP, key_dev->evbit); | ||
246 | |||
247 | /* Setup input device */ | ||
248 | __set_bit(EV_KEY, key_dev->evbit); | ||
249 | |||
250 | /* Setup the platform data */ | ||
251 | davinci_ks->pdata = pdata; | ||
252 | |||
253 | for (i = 0; i < davinci_ks->pdata->keymapsize; i++) | ||
254 | __set_bit(davinci_ks->pdata->keymap[i], key_dev->keybit); | ||
255 | |||
256 | key_dev->name = "davinci_keyscan"; | ||
257 | key_dev->phys = "davinci_keyscan/input0"; | ||
258 | key_dev->dev.parent = &pdev->dev; | ||
259 | key_dev->id.bustype = BUS_HOST; | ||
260 | key_dev->id.vendor = 0x0001; | ||
261 | key_dev->id.product = 0x0001; | ||
262 | key_dev->id.version = 0x0001; | ||
263 | key_dev->keycode = davinci_ks->keymap; | ||
264 | key_dev->keycodesize = sizeof(davinci_ks->keymap[0]); | ||
265 | key_dev->keycodemax = davinci_ks->pdata->keymapsize; | ||
266 | |||
267 | error = input_register_device(davinci_ks->input); | ||
268 | if (error < 0) { | ||
269 | dev_err(dev, "unable to register davinci key scan device\n"); | ||
270 | goto fail4; | ||
271 | } | ||
272 | |||
273 | error = request_irq(davinci_ks->irq, davinci_ks_interrupt, | ||
274 | IRQF_DISABLED, pdev->name, davinci_ks); | ||
275 | if (error < 0) { | ||
276 | dev_err(dev, "unable to register davinci key scan interrupt\n"); | ||
277 | goto fail5; | ||
278 | } | ||
279 | |||
280 | error = davinci_ks_initialize(davinci_ks); | ||
281 | if (error < 0) { | ||
282 | dev_err(dev, "unable to initialize davinci key scan device\n"); | ||
283 | goto fail6; | ||
284 | } | ||
285 | |||
286 | platform_set_drvdata(pdev, davinci_ks); | ||
287 | return 0; | ||
288 | |||
289 | fail6: | ||
290 | free_irq(davinci_ks->irq, davinci_ks); | ||
291 | fail5: | ||
292 | input_unregister_device(davinci_ks->input); | ||
293 | key_dev = NULL; | ||
294 | fail4: | ||
295 | iounmap(davinci_ks->base); | ||
296 | fail3: | ||
297 | release_mem_region(davinci_ks->pbase, davinci_ks->base_size); | ||
298 | fail2: | ||
299 | input_free_device(key_dev); | ||
300 | fail1: | ||
301 | kfree(davinci_ks); | ||
302 | |||
303 | return error; | ||
304 | } | ||
305 | |||
306 | static int __devexit davinci_ks_remove(struct platform_device *pdev) | ||
307 | { | ||
308 | struct davinci_ks *davinci_ks = platform_get_drvdata(pdev); | ||
309 | |||
310 | free_irq(davinci_ks->irq, davinci_ks); | ||
311 | |||
312 | input_unregister_device(davinci_ks->input); | ||
313 | |||
314 | iounmap(davinci_ks->base); | ||
315 | release_mem_region(davinci_ks->pbase, davinci_ks->base_size); | ||
316 | |||
317 | platform_set_drvdata(pdev, NULL); | ||
318 | |||
319 | kfree(davinci_ks); | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static struct platform_driver davinci_ks_driver = { | ||
325 | .driver = { | ||
326 | .name = "davinci_keyscan", | ||
327 | .owner = THIS_MODULE, | ||
328 | }, | ||
329 | .remove = __devexit_p(davinci_ks_remove), | ||
330 | }; | ||
331 | |||
332 | static int __init davinci_ks_init(void) | ||
333 | { | ||
334 | return platform_driver_probe(&davinci_ks_driver, davinci_ks_probe); | ||
335 | } | ||
336 | module_init(davinci_ks_init); | ||
337 | |||
338 | static void __exit davinci_ks_exit(void) | ||
339 | { | ||
340 | platform_driver_unregister(&davinci_ks_driver); | ||
341 | } | ||
342 | module_exit(davinci_ks_exit); | ||
343 | |||
344 | MODULE_AUTHOR("Miguel Aguilar"); | ||
345 | MODULE_DESCRIPTION("Texas Instruments DaVinci Key Scan Driver"); | ||
346 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index 181d30e3018e..c8242dd190d0 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c | |||
@@ -22,11 +22,12 @@ | |||
22 | 22 | ||
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/input.h> | ||
26 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
26 | #include <linux/io.h> | ||
27 | #include <linux/input/matrix_keypad.h> | ||
28 | #include <linux/slab.h> | ||
27 | 29 | ||
28 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
29 | #include <mach/gpio.h> | ||
30 | #include <mach/ep93xx_keypad.h> | 31 | #include <mach/ep93xx_keypad.h> |
31 | 32 | ||
32 | /* | 33 | /* |
@@ -60,56 +61,39 @@ | |||
60 | #define KEY_REG_KEY1_MASK (0x0000003f) | 61 | #define KEY_REG_KEY1_MASK (0x0000003f) |
61 | #define KEY_REG_KEY1_SHIFT (0) | 62 | #define KEY_REG_KEY1_SHIFT (0) |
62 | 63 | ||
63 | #define keypad_readl(off) __raw_readl(keypad->mmio_base + (off)) | 64 | #define EP93XX_MATRIX_SIZE (EP93XX_MATRIX_ROWS * EP93XX_MATRIX_COLS) |
64 | #define keypad_writel(v, off) __raw_writel((v), keypad->mmio_base + (off)) | ||
65 | |||
66 | #define MAX_MATRIX_KEY_NUM (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS) | ||
67 | 65 | ||
68 | struct ep93xx_keypad { | 66 | struct ep93xx_keypad { |
69 | struct ep93xx_keypad_platform_data *pdata; | 67 | struct ep93xx_keypad_platform_data *pdata; |
70 | |||
71 | struct clk *clk; | ||
72 | struct input_dev *input_dev; | 68 | struct input_dev *input_dev; |
69 | struct clk *clk; | ||
70 | |||
73 | void __iomem *mmio_base; | 71 | void __iomem *mmio_base; |
74 | 72 | ||
75 | int irq; | 73 | unsigned short keycodes[EP93XX_MATRIX_SIZE]; |
76 | int enabled; | ||
77 | 74 | ||
78 | int key1; | 75 | int key1; |
79 | int key2; | 76 | int key2; |
80 | 77 | ||
81 | unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM]; | 78 | int irq; |
82 | }; | ||
83 | |||
84 | static void ep93xx_keypad_build_keycode(struct ep93xx_keypad *keypad) | ||
85 | { | ||
86 | struct ep93xx_keypad_platform_data *pdata = keypad->pdata; | ||
87 | struct input_dev *input_dev = keypad->input_dev; | ||
88 | int i; | ||
89 | |||
90 | for (i = 0; i < pdata->matrix_key_map_size; i++) { | ||
91 | unsigned int key = pdata->matrix_key_map[i]; | ||
92 | int row = (key >> 28) & 0xf; | ||
93 | int col = (key >> 24) & 0xf; | ||
94 | int code = key & 0xffffff; | ||
95 | 79 | ||
96 | keypad->matrix_keycodes[(row << 3) + col] = code; | 80 | bool enabled; |
97 | __set_bit(code, input_dev->keybit); | 81 | }; |
98 | } | ||
99 | } | ||
100 | 82 | ||
101 | static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) | 83 | static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) |
102 | { | 84 | { |
103 | struct ep93xx_keypad *keypad = dev_id; | 85 | struct ep93xx_keypad *keypad = dev_id; |
104 | struct input_dev *input_dev = keypad->input_dev; | 86 | struct input_dev *input_dev = keypad->input_dev; |
105 | unsigned int status = keypad_readl(KEY_REG); | 87 | unsigned int status; |
106 | int keycode, key1, key2; | 88 | int keycode, key1, key2; |
107 | 89 | ||
90 | status = __raw_readl(keypad->mmio_base + KEY_REG); | ||
91 | |||
108 | keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT; | 92 | keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT; |
109 | key1 = keypad->matrix_keycodes[keycode]; | 93 | key1 = keypad->keycodes[keycode]; |
110 | 94 | ||
111 | keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT; | 95 | keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT; |
112 | key2 = keypad->matrix_keycodes[keycode]; | 96 | key2 = keypad->keycodes[keycode]; |
113 | 97 | ||
114 | if (status & KEY_REG_2KEYS) { | 98 | if (status & KEY_REG_2KEYS) { |
115 | if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1) | 99 | if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1) |
@@ -152,7 +136,10 @@ static void ep93xx_keypad_config(struct ep93xx_keypad *keypad) | |||
152 | struct ep93xx_keypad_platform_data *pdata = keypad->pdata; | 136 | struct ep93xx_keypad_platform_data *pdata = keypad->pdata; |
153 | unsigned int val = 0; | 137 | unsigned int val = 0; |
154 | 138 | ||
155 | clk_set_rate(keypad->clk, pdata->flags & EP93XX_KEYPAD_KDIV); | 139 | if (pdata->flags & EP93XX_KEYPAD_KDIV) |
140 | clk_set_rate(keypad->clk, EP93XX_KEYTCHCLK_DIV4); | ||
141 | else | ||
142 | clk_set_rate(keypad->clk, EP93XX_KEYTCHCLK_DIV16); | ||
156 | 143 | ||
157 | if (pdata->flags & EP93XX_KEYPAD_DISABLE_3_KEY) | 144 | if (pdata->flags & EP93XX_KEYPAD_DISABLE_3_KEY) |
158 | val |= KEY_INIT_DIS3KY; | 145 | val |= KEY_INIT_DIS3KY; |
@@ -167,7 +154,7 @@ static void ep93xx_keypad_config(struct ep93xx_keypad *keypad) | |||
167 | 154 | ||
168 | val |= ((pdata->prescale << KEY_INIT_PRSCL_SHIFT) & KEY_INIT_PRSCL_MASK); | 155 | val |= ((pdata->prescale << KEY_INIT_PRSCL_SHIFT) & KEY_INIT_PRSCL_MASK); |
169 | 156 | ||
170 | keypad_writel(val, KEY_INIT); | 157 | __raw_writel(val, keypad->mmio_base + KEY_INIT); |
171 | } | 158 | } |
172 | 159 | ||
173 | static int ep93xx_keypad_open(struct input_dev *pdev) | 160 | static int ep93xx_keypad_open(struct input_dev *pdev) |
@@ -177,7 +164,7 @@ static int ep93xx_keypad_open(struct input_dev *pdev) | |||
177 | if (!keypad->enabled) { | 164 | if (!keypad->enabled) { |
178 | ep93xx_keypad_config(keypad); | 165 | ep93xx_keypad_config(keypad); |
179 | clk_enable(keypad->clk); | 166 | clk_enable(keypad->clk); |
180 | keypad->enabled = 1; | 167 | keypad->enabled = true; |
181 | } | 168 | } |
182 | 169 | ||
183 | return 0; | 170 | return 0; |
@@ -189,7 +176,7 @@ static void ep93xx_keypad_close(struct input_dev *pdev) | |||
189 | 176 | ||
190 | if (keypad->enabled) { | 177 | if (keypad->enabled) { |
191 | clk_disable(keypad->clk); | 178 | clk_disable(keypad->clk); |
192 | keypad->enabled = 0; | 179 | keypad->enabled = false; |
193 | } | 180 | } |
194 | } | 181 | } |
195 | 182 | ||
@@ -211,7 +198,7 @@ static int ep93xx_keypad_suspend(struct platform_device *pdev, | |||
211 | 198 | ||
212 | if (keypad->enabled) { | 199 | if (keypad->enabled) { |
213 | clk_disable(keypad->clk); | 200 | clk_disable(keypad->clk); |
214 | keypad->enabled = 0; | 201 | keypad->enabled = false; |
215 | } | 202 | } |
216 | 203 | ||
217 | mutex_unlock(&input_dev->mutex); | 204 | mutex_unlock(&input_dev->mutex); |
@@ -236,7 +223,7 @@ static int ep93xx_keypad_resume(struct platform_device *pdev) | |||
236 | if (!keypad->enabled) { | 223 | if (!keypad->enabled) { |
237 | ep93xx_keypad_config(keypad); | 224 | ep93xx_keypad_config(keypad); |
238 | clk_enable(keypad->clk); | 225 | clk_enable(keypad->clk); |
239 | keypad->enabled = 1; | 226 | keypad->enabled = true; |
240 | } | 227 | } |
241 | } | 228 | } |
242 | 229 | ||
@@ -252,88 +239,63 @@ static int ep93xx_keypad_resume(struct platform_device *pdev) | |||
252 | static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | 239 | static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) |
253 | { | 240 | { |
254 | struct ep93xx_keypad *keypad; | 241 | struct ep93xx_keypad *keypad; |
255 | struct ep93xx_keypad_platform_data *pdata = pdev->dev.platform_data; | 242 | const struct matrix_keymap_data *keymap_data; |
256 | struct input_dev *input_dev; | 243 | struct input_dev *input_dev; |
257 | struct resource *res; | 244 | struct resource *res; |
258 | int irq, err, i, gpio; | 245 | int err; |
259 | |||
260 | if (!pdata || | ||
261 | !pdata->matrix_key_rows || | ||
262 | pdata->matrix_key_rows > MAX_MATRIX_KEY_ROWS || | ||
263 | !pdata->matrix_key_cols || | ||
264 | pdata->matrix_key_cols > MAX_MATRIX_KEY_COLS) { | ||
265 | dev_err(&pdev->dev, "invalid or missing platform data\n"); | ||
266 | return -EINVAL; | ||
267 | } | ||
268 | 246 | ||
269 | keypad = kzalloc(sizeof(struct ep93xx_keypad), GFP_KERNEL); | 247 | keypad = kzalloc(sizeof(struct ep93xx_keypad), GFP_KERNEL); |
270 | if (!keypad) { | 248 | if (!keypad) |
271 | dev_err(&pdev->dev, "failed to allocate driver data\n"); | ||
272 | return -ENOMEM; | 249 | return -ENOMEM; |
250 | |||
251 | keypad->pdata = pdev->dev.platform_data; | ||
252 | if (!keypad->pdata) { | ||
253 | err = -EINVAL; | ||
254 | goto failed_free; | ||
273 | } | 255 | } |
274 | 256 | ||
275 | keypad->pdata = pdata; | 257 | keymap_data = keypad->pdata->keymap_data; |
258 | if (!keymap_data) { | ||
259 | err = -EINVAL; | ||
260 | goto failed_free; | ||
261 | } | ||
276 | 262 | ||
277 | irq = platform_get_irq(pdev, 0); | 263 | keypad->irq = platform_get_irq(pdev, 0); |
278 | if (irq < 0) { | 264 | if (!keypad->irq) { |
279 | dev_err(&pdev->dev, "failed to get keypad irq\n"); | ||
280 | err = -ENXIO; | 265 | err = -ENXIO; |
281 | goto failed_free; | 266 | goto failed_free; |
282 | } | 267 | } |
283 | 268 | ||
284 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 269 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
285 | if (!res) { | 270 | if (!res) { |
286 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | ||
287 | err = -ENXIO; | 271 | err = -ENXIO; |
288 | goto failed_free; | 272 | goto failed_free; |
289 | } | 273 | } |
290 | 274 | ||
291 | res = request_mem_region(res->start, resource_size(res), pdev->name); | 275 | res = request_mem_region(res->start, resource_size(res), pdev->name); |
292 | if (!res) { | 276 | if (!res) { |
293 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
294 | err = -EBUSY; | 277 | err = -EBUSY; |
295 | goto failed_free; | 278 | goto failed_free; |
296 | } | 279 | } |
297 | 280 | ||
298 | keypad->mmio_base = ioremap(res->start, resource_size(res)); | 281 | keypad->mmio_base = ioremap(res->start, resource_size(res)); |
299 | if (keypad->mmio_base == NULL) { | 282 | if (keypad->mmio_base == NULL) { |
300 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
301 | err = -ENXIO; | 283 | err = -ENXIO; |
302 | goto failed_free_mem; | 284 | goto failed_free_mem; |
303 | } | 285 | } |
304 | 286 | ||
305 | /* Request the needed GPIO's */ | 287 | err = ep93xx_keypad_acquire_gpio(pdev); |
306 | gpio = EP93XX_GPIO_LINE_ROW0; | 288 | if (err) |
307 | for (i = 0; i < keypad->pdata->matrix_key_rows; i++, gpio++) { | 289 | goto failed_free_io; |
308 | err = gpio_request(gpio, pdev->name); | ||
309 | if (err) { | ||
310 | dev_err(&pdev->dev, "failed to request gpio-%d\n", | ||
311 | gpio); | ||
312 | goto failed_free_rows; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | gpio = EP93XX_GPIO_LINE_COL0; | ||
317 | for (i = 0; i < keypad->pdata->matrix_key_cols; i++, gpio++) { | ||
318 | err = gpio_request(gpio, pdev->name); | ||
319 | if (err) { | ||
320 | dev_err(&pdev->dev, "failed to request gpio-%d\n", | ||
321 | gpio); | ||
322 | goto failed_free_cols; | ||
323 | } | ||
324 | } | ||
325 | 290 | ||
326 | keypad->clk = clk_get(&pdev->dev, "key_clk"); | 291 | keypad->clk = clk_get(&pdev->dev, NULL); |
327 | if (IS_ERR(keypad->clk)) { | 292 | if (IS_ERR(keypad->clk)) { |
328 | dev_err(&pdev->dev, "failed to get keypad clock\n"); | ||
329 | err = PTR_ERR(keypad->clk); | 293 | err = PTR_ERR(keypad->clk); |
330 | goto failed_free_io; | 294 | goto failed_free_gpio; |
331 | } | 295 | } |
332 | 296 | ||
333 | /* Create and register the input driver */ | ||
334 | input_dev = input_allocate_device(); | 297 | input_dev = input_allocate_device(); |
335 | if (!input_dev) { | 298 | if (!input_dev) { |
336 | dev_err(&pdev->dev, "failed to allocate input device\n"); | ||
337 | err = -ENOMEM; | 299 | err = -ENOMEM; |
338 | goto failed_put_clk; | 300 | goto failed_put_clk; |
339 | } | 301 | } |
@@ -345,9 +307,9 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | |||
345 | input_dev->open = ep93xx_keypad_open; | 307 | input_dev->open = ep93xx_keypad_open; |
346 | input_dev->close = ep93xx_keypad_close; | 308 | input_dev->close = ep93xx_keypad_close; |
347 | input_dev->dev.parent = &pdev->dev; | 309 | input_dev->dev.parent = &pdev->dev; |
348 | input_dev->keycode = keypad->matrix_keycodes; | 310 | input_dev->keycode = keypad->keycodes; |
349 | input_dev->keycodesize = sizeof(keypad->matrix_keycodes[0]); | 311 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); |
350 | input_dev->keycodemax = ARRAY_SIZE(keypad->matrix_keycodes); | 312 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); |
351 | 313 | ||
352 | input_set_drvdata(input_dev, keypad); | 314 | input_set_drvdata(input_dev, keypad); |
353 | 315 | ||
@@ -355,47 +317,33 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | |||
355 | if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) | 317 | if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) |
356 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | 318 | input_dev->evbit[0] |= BIT_MASK(EV_REP); |
357 | 319 | ||
358 | ep93xx_keypad_build_keycode(keypad); | 320 | matrix_keypad_build_keymap(keymap_data, 3, |
321 | input_dev->keycode, input_dev->keybit); | ||
359 | platform_set_drvdata(pdev, keypad); | 322 | platform_set_drvdata(pdev, keypad); |
360 | 323 | ||
361 | err = request_irq(irq, ep93xx_keypad_irq_handler, IRQF_DISABLED, | 324 | err = request_irq(keypad->irq, ep93xx_keypad_irq_handler, |
362 | pdev->name, keypad); | 325 | IRQF_DISABLED, pdev->name, keypad); |
363 | if (err) { | 326 | if (err) |
364 | dev_err(&pdev->dev, "failed to request IRQ\n"); | ||
365 | goto failed_free_dev; | 327 | goto failed_free_dev; |
366 | } | ||
367 | 328 | ||
368 | keypad->irq = irq; | ||
369 | |||
370 | /* Register the input device */ | ||
371 | err = input_register_device(input_dev); | 329 | err = input_register_device(input_dev); |
372 | if (err) { | 330 | if (err) |
373 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
374 | goto failed_free_irq; | 331 | goto failed_free_irq; |
375 | } | ||
376 | 332 | ||
377 | device_init_wakeup(&pdev->dev, 1); | 333 | device_init_wakeup(&pdev->dev, 1); |
378 | 334 | ||
379 | return 0; | 335 | return 0; |
380 | 336 | ||
381 | failed_free_irq: | 337 | failed_free_irq: |
382 | free_irq(irq, pdev); | 338 | free_irq(keypad->irq, pdev); |
383 | platform_set_drvdata(pdev, NULL); | 339 | platform_set_drvdata(pdev, NULL); |
384 | failed_free_dev: | 340 | failed_free_dev: |
385 | input_free_device(input_dev); | 341 | input_free_device(input_dev); |
386 | failed_put_clk: | 342 | failed_put_clk: |
387 | clk_put(keypad->clk); | 343 | clk_put(keypad->clk); |
344 | failed_free_gpio: | ||
345 | ep93xx_keypad_release_gpio(pdev); | ||
388 | failed_free_io: | 346 | failed_free_io: |
389 | i = keypad->pdata->matrix_key_cols - 1; | ||
390 | gpio = EP93XX_GPIO_LINE_COL0 + i; | ||
391 | failed_free_cols: | ||
392 | for ( ; i >= 0; i--, gpio--) | ||
393 | gpio_free(gpio); | ||
394 | i = keypad->pdata->matrix_key_rows - 1; | ||
395 | gpio = EP93XX_GPIO_LINE_ROW0 + i; | ||
396 | failed_free_rows: | ||
397 | for ( ; i >= 0; i--, gpio--) | ||
398 | gpio_free(gpio); | ||
399 | iounmap(keypad->mmio_base); | 347 | iounmap(keypad->mmio_base); |
400 | failed_free_mem: | 348 | failed_free_mem: |
401 | release_mem_region(res->start, resource_size(res)); | 349 | release_mem_region(res->start, resource_size(res)); |
@@ -408,7 +356,6 @@ static int __devexit ep93xx_keypad_remove(struct platform_device *pdev) | |||
408 | { | 356 | { |
409 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); | 357 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); |
410 | struct resource *res; | 358 | struct resource *res; |
411 | int i, gpio; | ||
412 | 359 | ||
413 | free_irq(keypad->irq, pdev); | 360 | free_irq(keypad->irq, pdev); |
414 | 361 | ||
@@ -420,15 +367,7 @@ static int __devexit ep93xx_keypad_remove(struct platform_device *pdev) | |||
420 | 367 | ||
421 | input_unregister_device(keypad->input_dev); | 368 | input_unregister_device(keypad->input_dev); |
422 | 369 | ||
423 | i = keypad->pdata->matrix_key_cols - 1; | 370 | ep93xx_keypad_release_gpio(pdev); |
424 | gpio = EP93XX_GPIO_LINE_COL0 + i; | ||
425 | for ( ; i >= 0; i--, gpio--) | ||
426 | gpio_free(gpio); | ||
427 | |||
428 | i = keypad->pdata->matrix_key_rows - 1; | ||
429 | gpio = EP93XX_GPIO_LINE_ROW0 + i; | ||
430 | for ( ; i >= 0; i--, gpio--) | ||
431 | gpio_free(gpio); | ||
432 | 371 | ||
433 | iounmap(keypad->mmio_base); | 372 | iounmap(keypad->mmio_base); |
434 | 373 | ||
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 77d130914259..b8213fd13c3f 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
17 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
18 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
19 | #include <linux/slab.h> | ||
19 | #include <linux/sysctl.h> | 20 | #include <linux/sysctl.h> |
20 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
21 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
@@ -23,25 +24,298 @@ | |||
23 | #include <linux/input.h> | 24 | #include <linux/input.h> |
24 | #include <linux/gpio_keys.h> | 25 | #include <linux/gpio_keys.h> |
25 | #include <linux/workqueue.h> | 26 | #include <linux/workqueue.h> |
26 | 27 | #include <linux/gpio.h> | |
27 | #include <asm/gpio.h> | ||
28 | 28 | ||
29 | struct gpio_button_data { | 29 | struct gpio_button_data { |
30 | struct gpio_keys_button *button; | 30 | struct gpio_keys_button *button; |
31 | struct input_dev *input; | 31 | struct input_dev *input; |
32 | struct timer_list timer; | 32 | struct timer_list timer; |
33 | struct work_struct work; | 33 | struct work_struct work; |
34 | bool disabled; | ||
34 | }; | 35 | }; |
35 | 36 | ||
36 | struct gpio_keys_drvdata { | 37 | struct gpio_keys_drvdata { |
37 | struct input_dev *input; | 38 | struct input_dev *input; |
39 | struct mutex disable_lock; | ||
40 | unsigned int n_buttons; | ||
38 | struct gpio_button_data data[0]; | 41 | struct gpio_button_data data[0]; |
39 | }; | 42 | }; |
40 | 43 | ||
41 | static void gpio_keys_report_event(struct work_struct *work) | 44 | /* |
45 | * SYSFS interface for enabling/disabling keys and switches: | ||
46 | * | ||
47 | * There are 4 attributes under /sys/devices/platform/gpio-keys/ | ||
48 | * keys [ro] - bitmap of keys (EV_KEY) which can be | ||
49 | * disabled | ||
50 | * switches [ro] - bitmap of switches (EV_SW) which can be | ||
51 | * disabled | ||
52 | * disabled_keys [rw] - bitmap of keys currently disabled | ||
53 | * disabled_switches [rw] - bitmap of switches currently disabled | ||
54 | * | ||
55 | * Userland can change these values and hence disable event generation | ||
56 | * for each key (or switch). Disabling a key means its interrupt line | ||
57 | * is disabled. | ||
58 | * | ||
59 | * For example, if we have following switches set up as gpio-keys: | ||
60 | * SW_DOCK = 5 | ||
61 | * SW_CAMERA_LENS_COVER = 9 | ||
62 | * SW_KEYPAD_SLIDE = 10 | ||
63 | * SW_FRONT_PROXIMITY = 11 | ||
64 | * This is read from switches: | ||
65 | * 11-9,5 | ||
66 | * Next we want to disable proximity (11) and dock (5), we write: | ||
67 | * 11,5 | ||
68 | * to file disabled_switches. Now proximity and dock IRQs are disabled. | ||
69 | * This can be verified by reading the file disabled_switches: | ||
70 | * 11,5 | ||
71 | * If we now want to enable proximity (11) switch we write: | ||
72 | * 5 | ||
73 | * to disabled_switches. | ||
74 | * | ||
75 | * We can disable only those keys which don't allow sharing the irq. | ||
76 | */ | ||
77 | |||
78 | /** | ||
79 | * get_n_events_by_type() - returns maximum number of events per @type | ||
80 | * @type: type of button (%EV_KEY, %EV_SW) | ||
81 | * | ||
82 | * Return value of this function can be used to allocate bitmap | ||
83 | * large enough to hold all bits for given type. | ||
84 | */ | ||
85 | static inline int get_n_events_by_type(int type) | ||
86 | { | ||
87 | BUG_ON(type != EV_SW && type != EV_KEY); | ||
88 | |||
89 | return (type == EV_KEY) ? KEY_CNT : SW_CNT; | ||
90 | } | ||
91 | |||
92 | /** | ||
93 | * gpio_keys_disable_button() - disables given GPIO button | ||
94 | * @bdata: button data for button to be disabled | ||
95 | * | ||
96 | * Disables button pointed by @bdata. This is done by masking | ||
97 | * IRQ line. After this function is called, button won't generate | ||
98 | * input events anymore. Note that one can only disable buttons | ||
99 | * that don't share IRQs. | ||
100 | * | ||
101 | * Make sure that @bdata->disable_lock is locked when entering | ||
102 | * this function to avoid races when concurrent threads are | ||
103 | * disabling buttons at the same time. | ||
104 | */ | ||
105 | static void gpio_keys_disable_button(struct gpio_button_data *bdata) | ||
106 | { | ||
107 | if (!bdata->disabled) { | ||
108 | /* | ||
109 | * Disable IRQ and possible debouncing timer. | ||
110 | */ | ||
111 | disable_irq(gpio_to_irq(bdata->button->gpio)); | ||
112 | if (bdata->button->debounce_interval) | ||
113 | del_timer_sync(&bdata->timer); | ||
114 | |||
115 | bdata->disabled = true; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * gpio_keys_enable_button() - enables given GPIO button | ||
121 | * @bdata: button data for button to be disabled | ||
122 | * | ||
123 | * Enables given button pointed by @bdata. | ||
124 | * | ||
125 | * Make sure that @bdata->disable_lock is locked when entering | ||
126 | * this function to avoid races with concurrent threads trying | ||
127 | * to enable the same button at the same time. | ||
128 | */ | ||
129 | static void gpio_keys_enable_button(struct gpio_button_data *bdata) | ||
130 | { | ||
131 | if (bdata->disabled) { | ||
132 | enable_irq(gpio_to_irq(bdata->button->gpio)); | ||
133 | bdata->disabled = false; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | /** | ||
138 | * gpio_keys_attr_show_helper() - fill in stringified bitmap of buttons | ||
139 | * @ddata: pointer to drvdata | ||
140 | * @buf: buffer where stringified bitmap is written | ||
141 | * @type: button type (%EV_KEY, %EV_SW) | ||
142 | * @only_disabled: does caller want only those buttons that are | ||
143 | * currently disabled or all buttons that can be | ||
144 | * disabled | ||
145 | * | ||
146 | * This function writes buttons that can be disabled to @buf. If | ||
147 | * @only_disabled is true, then @buf contains only those buttons | ||
148 | * that are currently disabled. Returns 0 on success or negative | ||
149 | * errno on failure. | ||
150 | */ | ||
151 | static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata, | ||
152 | char *buf, unsigned int type, | ||
153 | bool only_disabled) | ||
154 | { | ||
155 | int n_events = get_n_events_by_type(type); | ||
156 | unsigned long *bits; | ||
157 | ssize_t ret; | ||
158 | int i; | ||
159 | |||
160 | bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); | ||
161 | if (!bits) | ||
162 | return -ENOMEM; | ||
163 | |||
164 | for (i = 0; i < ddata->n_buttons; i++) { | ||
165 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
166 | |||
167 | if (bdata->button->type != type) | ||
168 | continue; | ||
169 | |||
170 | if (only_disabled && !bdata->disabled) | ||
171 | continue; | ||
172 | |||
173 | __set_bit(bdata->button->code, bits); | ||
174 | } | ||
175 | |||
176 | ret = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, bits, n_events); | ||
177 | buf[ret++] = '\n'; | ||
178 | buf[ret] = '\0'; | ||
179 | |||
180 | kfree(bits); | ||
181 | |||
182 | return ret; | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * gpio_keys_attr_store_helper() - enable/disable buttons based on given bitmap | ||
187 | * @ddata: pointer to drvdata | ||
188 | * @buf: buffer from userspace that contains stringified bitmap | ||
189 | * @type: button type (%EV_KEY, %EV_SW) | ||
190 | * | ||
191 | * This function parses stringified bitmap from @buf and disables/enables | ||
192 | * GPIO buttons accordinly. Returns 0 on success and negative error | ||
193 | * on failure. | ||
194 | */ | ||
195 | static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, | ||
196 | const char *buf, unsigned int type) | ||
197 | { | ||
198 | int n_events = get_n_events_by_type(type); | ||
199 | unsigned long *bits; | ||
200 | ssize_t error; | ||
201 | int i; | ||
202 | |||
203 | bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); | ||
204 | if (!bits) | ||
205 | return -ENOMEM; | ||
206 | |||
207 | error = bitmap_parselist(buf, bits, n_events); | ||
208 | if (error) | ||
209 | goto out; | ||
210 | |||
211 | /* First validate */ | ||
212 | for (i = 0; i < ddata->n_buttons; i++) { | ||
213 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
214 | |||
215 | if (bdata->button->type != type) | ||
216 | continue; | ||
217 | |||
218 | if (test_bit(bdata->button->code, bits) && | ||
219 | !bdata->button->can_disable) { | ||
220 | error = -EINVAL; | ||
221 | goto out; | ||
222 | } | ||
223 | } | ||
224 | |||
225 | mutex_lock(&ddata->disable_lock); | ||
226 | |||
227 | for (i = 0; i < ddata->n_buttons; i++) { | ||
228 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
229 | |||
230 | if (bdata->button->type != type) | ||
231 | continue; | ||
232 | |||
233 | if (test_bit(bdata->button->code, bits)) | ||
234 | gpio_keys_disable_button(bdata); | ||
235 | else | ||
236 | gpio_keys_enable_button(bdata); | ||
237 | } | ||
238 | |||
239 | mutex_unlock(&ddata->disable_lock); | ||
240 | |||
241 | out: | ||
242 | kfree(bits); | ||
243 | return error; | ||
244 | } | ||
245 | |||
246 | #define ATTR_SHOW_FN(name, type, only_disabled) \ | ||
247 | static ssize_t gpio_keys_show_##name(struct device *dev, \ | ||
248 | struct device_attribute *attr, \ | ||
249 | char *buf) \ | ||
250 | { \ | ||
251 | struct platform_device *pdev = to_platform_device(dev); \ | ||
252 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ | ||
253 | \ | ||
254 | return gpio_keys_attr_show_helper(ddata, buf, \ | ||
255 | type, only_disabled); \ | ||
256 | } | ||
257 | |||
258 | ATTR_SHOW_FN(keys, EV_KEY, false); | ||
259 | ATTR_SHOW_FN(switches, EV_SW, false); | ||
260 | ATTR_SHOW_FN(disabled_keys, EV_KEY, true); | ||
261 | ATTR_SHOW_FN(disabled_switches, EV_SW, true); | ||
262 | |||
263 | /* | ||
264 | * ATTRIBUTES: | ||
265 | * | ||
266 | * /sys/devices/platform/gpio-keys/keys [ro] | ||
267 | * /sys/devices/platform/gpio-keys/switches [ro] | ||
268 | */ | ||
269 | static DEVICE_ATTR(keys, S_IRUGO, gpio_keys_show_keys, NULL); | ||
270 | static DEVICE_ATTR(switches, S_IRUGO, gpio_keys_show_switches, NULL); | ||
271 | |||
272 | #define ATTR_STORE_FN(name, type) \ | ||
273 | static ssize_t gpio_keys_store_##name(struct device *dev, \ | ||
274 | struct device_attribute *attr, \ | ||
275 | const char *buf, \ | ||
276 | size_t count) \ | ||
277 | { \ | ||
278 | struct platform_device *pdev = to_platform_device(dev); \ | ||
279 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ | ||
280 | ssize_t error; \ | ||
281 | \ | ||
282 | error = gpio_keys_attr_store_helper(ddata, buf, type); \ | ||
283 | if (error) \ | ||
284 | return error; \ | ||
285 | \ | ||
286 | return count; \ | ||
287 | } | ||
288 | |||
289 | ATTR_STORE_FN(disabled_keys, EV_KEY); | ||
290 | ATTR_STORE_FN(disabled_switches, EV_SW); | ||
291 | |||
292 | /* | ||
293 | * ATTRIBUTES: | ||
294 | * | ||
295 | * /sys/devices/platform/gpio-keys/disabled_keys [rw] | ||
296 | * /sys/devices/platform/gpio-keys/disables_switches [rw] | ||
297 | */ | ||
298 | static DEVICE_ATTR(disabled_keys, S_IWUSR | S_IRUGO, | ||
299 | gpio_keys_show_disabled_keys, | ||
300 | gpio_keys_store_disabled_keys); | ||
301 | static DEVICE_ATTR(disabled_switches, S_IWUSR | S_IRUGO, | ||
302 | gpio_keys_show_disabled_switches, | ||
303 | gpio_keys_store_disabled_switches); | ||
304 | |||
305 | static struct attribute *gpio_keys_attrs[] = { | ||
306 | &dev_attr_keys.attr, | ||
307 | &dev_attr_switches.attr, | ||
308 | &dev_attr_disabled_keys.attr, | ||
309 | &dev_attr_disabled_switches.attr, | ||
310 | NULL, | ||
311 | }; | ||
312 | |||
313 | static struct attribute_group gpio_keys_attr_group = { | ||
314 | .attrs = gpio_keys_attrs, | ||
315 | }; | ||
316 | |||
317 | static void gpio_keys_report_event(struct gpio_button_data *bdata) | ||
42 | { | 318 | { |
43 | struct gpio_button_data *bdata = | ||
44 | container_of(work, struct gpio_button_data, work); | ||
45 | struct gpio_keys_button *button = bdata->button; | 319 | struct gpio_keys_button *button = bdata->button; |
46 | struct input_dev *input = bdata->input; | 320 | struct input_dev *input = bdata->input; |
47 | unsigned int type = button->type ?: EV_KEY; | 321 | unsigned int type = button->type ?: EV_KEY; |
@@ -51,6 +325,14 @@ static void gpio_keys_report_event(struct work_struct *work) | |||
51 | input_sync(input); | 325 | input_sync(input); |
52 | } | 326 | } |
53 | 327 | ||
328 | static void gpio_keys_work_func(struct work_struct *work) | ||
329 | { | ||
330 | struct gpio_button_data *bdata = | ||
331 | container_of(work, struct gpio_button_data, work); | ||
332 | |||
333 | gpio_keys_report_event(bdata); | ||
334 | } | ||
335 | |||
54 | static void gpio_keys_timer(unsigned long _data) | 336 | static void gpio_keys_timer(unsigned long _data) |
55 | { | 337 | { |
56 | struct gpio_button_data *data = (struct gpio_button_data *)_data; | 338 | struct gpio_button_data *data = (struct gpio_button_data *)_data; |
@@ -74,10 +356,69 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | |||
74 | return IRQ_HANDLED; | 356 | return IRQ_HANDLED; |
75 | } | 357 | } |
76 | 358 | ||
359 | static int __devinit gpio_keys_setup_key(struct platform_device *pdev, | ||
360 | struct gpio_button_data *bdata, | ||
361 | struct gpio_keys_button *button) | ||
362 | { | ||
363 | char *desc = button->desc ? button->desc : "gpio_keys"; | ||
364 | struct device *dev = &pdev->dev; | ||
365 | unsigned long irqflags; | ||
366 | int irq, error; | ||
367 | |||
368 | setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata); | ||
369 | INIT_WORK(&bdata->work, gpio_keys_work_func); | ||
370 | |||
371 | error = gpio_request(button->gpio, desc); | ||
372 | if (error < 0) { | ||
373 | dev_err(dev, "failed to request GPIO %d, error %d\n", | ||
374 | button->gpio, error); | ||
375 | goto fail2; | ||
376 | } | ||
377 | |||
378 | error = gpio_direction_input(button->gpio); | ||
379 | if (error < 0) { | ||
380 | dev_err(dev, "failed to configure" | ||
381 | " direction for GPIO %d, error %d\n", | ||
382 | button->gpio, error); | ||
383 | goto fail3; | ||
384 | } | ||
385 | |||
386 | irq = gpio_to_irq(button->gpio); | ||
387 | if (irq < 0) { | ||
388 | error = irq; | ||
389 | dev_err(dev, "Unable to get irq number for GPIO %d, error %d\n", | ||
390 | button->gpio, error); | ||
391 | goto fail3; | ||
392 | } | ||
393 | |||
394 | irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; | ||
395 | /* | ||
396 | * If platform has specified that the button can be disabled, | ||
397 | * we don't want it to share the interrupt line. | ||
398 | */ | ||
399 | if (!button->can_disable) | ||
400 | irqflags |= IRQF_SHARED; | ||
401 | |||
402 | error = request_irq(irq, gpio_keys_isr, irqflags, desc, bdata); | ||
403 | if (error) { | ||
404 | dev_err(dev, "Unable to claim irq %d; error %d\n", | ||
405 | irq, error); | ||
406 | goto fail3; | ||
407 | } | ||
408 | |||
409 | return 0; | ||
410 | |||
411 | fail3: | ||
412 | gpio_free(button->gpio); | ||
413 | fail2: | ||
414 | return error; | ||
415 | } | ||
416 | |||
77 | static int __devinit gpio_keys_probe(struct platform_device *pdev) | 417 | static int __devinit gpio_keys_probe(struct platform_device *pdev) |
78 | { | 418 | { |
79 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 419 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
80 | struct gpio_keys_drvdata *ddata; | 420 | struct gpio_keys_drvdata *ddata; |
421 | struct device *dev = &pdev->dev; | ||
81 | struct input_dev *input; | 422 | struct input_dev *input; |
82 | int i, error; | 423 | int i, error; |
83 | int wakeup = 0; | 424 | int wakeup = 0; |
@@ -87,10 +428,15 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
87 | GFP_KERNEL); | 428 | GFP_KERNEL); |
88 | input = input_allocate_device(); | 429 | input = input_allocate_device(); |
89 | if (!ddata || !input) { | 430 | if (!ddata || !input) { |
431 | dev_err(dev, "failed to allocate state\n"); | ||
90 | error = -ENOMEM; | 432 | error = -ENOMEM; |
91 | goto fail1; | 433 | goto fail1; |
92 | } | 434 | } |
93 | 435 | ||
436 | ddata->input = input; | ||
437 | ddata->n_buttons = pdata->nbuttons; | ||
438 | mutex_init(&ddata->disable_lock); | ||
439 | |||
94 | platform_set_drvdata(pdev, ddata); | 440 | platform_set_drvdata(pdev, ddata); |
95 | 441 | ||
96 | input->name = pdev->name; | 442 | input->name = pdev->name; |
@@ -106,57 +452,17 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
106 | if (pdata->rep) | 452 | if (pdata->rep) |
107 | __set_bit(EV_REP, input->evbit); | 453 | __set_bit(EV_REP, input->evbit); |
108 | 454 | ||
109 | ddata->input = input; | ||
110 | |||
111 | for (i = 0; i < pdata->nbuttons; i++) { | 455 | for (i = 0; i < pdata->nbuttons; i++) { |
112 | struct gpio_keys_button *button = &pdata->buttons[i]; | 456 | struct gpio_keys_button *button = &pdata->buttons[i]; |
113 | struct gpio_button_data *bdata = &ddata->data[i]; | 457 | struct gpio_button_data *bdata = &ddata->data[i]; |
114 | int irq; | ||
115 | unsigned int type = button->type ?: EV_KEY; | 458 | unsigned int type = button->type ?: EV_KEY; |
116 | 459 | ||
117 | bdata->input = input; | 460 | bdata->input = input; |
118 | bdata->button = button; | 461 | bdata->button = button; |
119 | setup_timer(&bdata->timer, | ||
120 | gpio_keys_timer, (unsigned long)bdata); | ||
121 | INIT_WORK(&bdata->work, gpio_keys_report_event); | ||
122 | |||
123 | error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); | ||
124 | if (error < 0) { | ||
125 | pr_err("gpio-keys: failed to request GPIO %d," | ||
126 | " error %d\n", button->gpio, error); | ||
127 | goto fail2; | ||
128 | } | ||
129 | 462 | ||
130 | error = gpio_direction_input(button->gpio); | 463 | error = gpio_keys_setup_key(pdev, bdata, button); |
131 | if (error < 0) { | 464 | if (error) |
132 | pr_err("gpio-keys: failed to configure input" | ||
133 | " direction for GPIO %d, error %d\n", | ||
134 | button->gpio, error); | ||
135 | gpio_free(button->gpio); | ||
136 | goto fail2; | 465 | goto fail2; |
137 | } | ||
138 | |||
139 | irq = gpio_to_irq(button->gpio); | ||
140 | if (irq < 0) { | ||
141 | error = irq; | ||
142 | pr_err("gpio-keys: Unable to get irq number" | ||
143 | " for GPIO %d, error %d\n", | ||
144 | button->gpio, error); | ||
145 | gpio_free(button->gpio); | ||
146 | goto fail2; | ||
147 | } | ||
148 | |||
149 | error = request_irq(irq, gpio_keys_isr, | ||
150 | IRQF_SHARED | | ||
151 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
152 | button->desc ? button->desc : "gpio_keys", | ||
153 | bdata); | ||
154 | if (error) { | ||
155 | pr_err("gpio-keys: Unable to claim irq %d; error %d\n", | ||
156 | irq, error); | ||
157 | gpio_free(button->gpio); | ||
158 | goto fail2; | ||
159 | } | ||
160 | 466 | ||
161 | if (button->wakeup) | 467 | if (button->wakeup) |
162 | wakeup = 1; | 468 | wakeup = 1; |
@@ -164,17 +470,31 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
164 | input_set_capability(input, type, button->code); | 470 | input_set_capability(input, type, button->code); |
165 | } | 471 | } |
166 | 472 | ||
167 | error = input_register_device(input); | 473 | error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group); |
168 | if (error) { | 474 | if (error) { |
169 | pr_err("gpio-keys: Unable to register input device, " | 475 | dev_err(dev, "Unable to export keys/switches, error: %d\n", |
170 | "error: %d\n", error); | 476 | error); |
171 | goto fail2; | 477 | goto fail2; |
172 | } | 478 | } |
173 | 479 | ||
480 | error = input_register_device(input); | ||
481 | if (error) { | ||
482 | dev_err(dev, "Unable to register input device, error: %d\n", | ||
483 | error); | ||
484 | goto fail3; | ||
485 | } | ||
486 | |||
487 | /* get current state of buttons */ | ||
488 | for (i = 0; i < pdata->nbuttons; i++) | ||
489 | gpio_keys_report_event(&ddata->data[i]); | ||
490 | input_sync(input); | ||
491 | |||
174 | device_init_wakeup(&pdev->dev, wakeup); | 492 | device_init_wakeup(&pdev->dev, wakeup); |
175 | 493 | ||
176 | return 0; | 494 | return 0; |
177 | 495 | ||
496 | fail3: | ||
497 | sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); | ||
178 | fail2: | 498 | fail2: |
179 | while (--i >= 0) { | 499 | while (--i >= 0) { |
180 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); | 500 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); |
@@ -199,6 +519,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) | |||
199 | struct input_dev *input = ddata->input; | 519 | struct input_dev *input = ddata->input; |
200 | int i; | 520 | int i; |
201 | 521 | ||
522 | sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); | ||
523 | |||
202 | device_init_wakeup(&pdev->dev, 0); | 524 | device_init_wakeup(&pdev->dev, 0); |
203 | 525 | ||
204 | for (i = 0; i < pdata->nbuttons; i++) { | 526 | for (i = 0; i < pdata->nbuttons; i++) { |
@@ -239,18 +561,21 @@ static int gpio_keys_suspend(struct device *dev) | |||
239 | static int gpio_keys_resume(struct device *dev) | 561 | static int gpio_keys_resume(struct device *dev) |
240 | { | 562 | { |
241 | struct platform_device *pdev = to_platform_device(dev); | 563 | struct platform_device *pdev = to_platform_device(dev); |
564 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); | ||
242 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 565 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
243 | int i; | 566 | int i; |
244 | 567 | ||
245 | if (device_may_wakeup(&pdev->dev)) { | 568 | for (i = 0; i < pdata->nbuttons; i++) { |
246 | for (i = 0; i < pdata->nbuttons; i++) { | 569 | |
247 | struct gpio_keys_button *button = &pdata->buttons[i]; | 570 | struct gpio_keys_button *button = &pdata->buttons[i]; |
248 | if (button->wakeup) { | 571 | if (button->wakeup && device_may_wakeup(&pdev->dev)) { |
249 | int irq = gpio_to_irq(button->gpio); | 572 | int irq = gpio_to_irq(button->gpio); |
250 | disable_irq_wake(irq); | 573 | disable_irq_wake(irq); |
251 | } | ||
252 | } | 574 | } |
575 | |||
576 | gpio_keys_report_event(&ddata->data[i]); | ||
253 | } | 577 | } |
578 | input_sync(ddata->input); | ||
254 | 579 | ||
255 | return 0; | 580 | return 0; |
256 | } | 581 | } |
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c new file mode 100644 index 000000000000..d92c15c39e68 --- /dev/null +++ b/drivers/input/keyboard/imx_keypad.c | |||
@@ -0,0 +1,595 @@ | |||
1 | /* | ||
2 | * Driver for the IMX keypad port. | ||
3 | * Copyright (C) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * <<Power management needs to be implemented>>. | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/input/matrix_keypad.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/jiffies.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/timer.h> | ||
26 | |||
27 | /* | ||
28 | * Keypad Controller registers (halfword) | ||
29 | */ | ||
30 | #define KPCR 0x00 /* Keypad Control Register */ | ||
31 | |||
32 | #define KPSR 0x02 /* Keypad Status Register */ | ||
33 | #define KBD_STAT_KPKD (0x1 << 0) /* Key Press Interrupt Status bit (w1c) */ | ||
34 | #define KBD_STAT_KPKR (0x1 << 1) /* Key Release Interrupt Status bit (w1c) */ | ||
35 | #define KBD_STAT_KDSC (0x1 << 2) /* Key Depress Synch Chain Status bit (w1c)*/ | ||
36 | #define KBD_STAT_KRSS (0x1 << 3) /* Key Release Synch Status bit (w1c)*/ | ||
37 | #define KBD_STAT_KDIE (0x1 << 8) /* Key Depress Interrupt Enable Status bit */ | ||
38 | #define KBD_STAT_KRIE (0x1 << 9) /* Key Release Interrupt Enable */ | ||
39 | #define KBD_STAT_KPPEN (0x1 << 10) /* Keypad Clock Enable */ | ||
40 | |||
41 | #define KDDR 0x04 /* Keypad Data Direction Register */ | ||
42 | #define KPDR 0x06 /* Keypad Data Register */ | ||
43 | |||
44 | #define MAX_MATRIX_KEY_ROWS 8 | ||
45 | #define MAX_MATRIX_KEY_COLS 8 | ||
46 | #define MATRIX_ROW_SHIFT 3 | ||
47 | |||
48 | #define MAX_MATRIX_KEY_NUM (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS) | ||
49 | |||
50 | struct imx_keypad { | ||
51 | |||
52 | struct clk *clk; | ||
53 | struct input_dev *input_dev; | ||
54 | void __iomem *mmio_base; | ||
55 | |||
56 | int irq; | ||
57 | struct timer_list check_matrix_timer; | ||
58 | |||
59 | /* | ||
60 | * The matrix is stable only if no changes are detected after | ||
61 | * IMX_KEYPAD_SCANS_FOR_STABILITY scans | ||
62 | */ | ||
63 | #define IMX_KEYPAD_SCANS_FOR_STABILITY 3 | ||
64 | int stable_count; | ||
65 | |||
66 | bool enabled; | ||
67 | |||
68 | /* Masks for enabled rows/cols */ | ||
69 | unsigned short rows_en_mask; | ||
70 | unsigned short cols_en_mask; | ||
71 | |||
72 | unsigned short keycodes[MAX_MATRIX_KEY_NUM]; | ||
73 | |||
74 | /* | ||
75 | * Matrix states: | ||
76 | * -stable: achieved after a complete debounce process. | ||
77 | * -unstable: used in the debouncing process. | ||
78 | */ | ||
79 | unsigned short matrix_stable_state[MAX_MATRIX_KEY_COLS]; | ||
80 | unsigned short matrix_unstable_state[MAX_MATRIX_KEY_COLS]; | ||
81 | }; | ||
82 | |||
83 | /* Scan the matrix and return the new state in *matrix_volatile_state. */ | ||
84 | static void imx_keypad_scan_matrix(struct imx_keypad *keypad, | ||
85 | unsigned short *matrix_volatile_state) | ||
86 | { | ||
87 | int col; | ||
88 | unsigned short reg_val; | ||
89 | |||
90 | for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) { | ||
91 | if ((keypad->cols_en_mask & (1 << col)) == 0) | ||
92 | continue; | ||
93 | /* | ||
94 | * Discharge keypad capacitance: | ||
95 | * 2. write 1s on column data. | ||
96 | * 3. configure columns as totem-pole to discharge capacitance. | ||
97 | * 4. configure columns as open-drain. | ||
98 | */ | ||
99 | reg_val = readw(keypad->mmio_base + KPDR); | ||
100 | reg_val |= 0xff00; | ||
101 | writew(reg_val, keypad->mmio_base + KPDR); | ||
102 | |||
103 | reg_val = readw(keypad->mmio_base + KPCR); | ||
104 | reg_val &= ~((keypad->cols_en_mask & 0xff) << 8); | ||
105 | writew(reg_val, keypad->mmio_base + KPCR); | ||
106 | |||
107 | udelay(2); | ||
108 | |||
109 | reg_val = readw(keypad->mmio_base + KPCR); | ||
110 | reg_val |= (keypad->cols_en_mask & 0xff) << 8; | ||
111 | writew(reg_val, keypad->mmio_base + KPCR); | ||
112 | |||
113 | /* | ||
114 | * 5. Write a single column to 0, others to 1. | ||
115 | * 6. Sample row inputs and save data. | ||
116 | * 7. Repeat steps 2 - 6 for remaining columns. | ||
117 | */ | ||
118 | reg_val = readw(keypad->mmio_base + KPDR); | ||
119 | reg_val &= ~(1 << (8 + col)); | ||
120 | writew(reg_val, keypad->mmio_base + KPDR); | ||
121 | |||
122 | /* | ||
123 | * Delay added to avoid propagating the 0 from column to row | ||
124 | * when scanning. | ||
125 | */ | ||
126 | udelay(5); | ||
127 | |||
128 | /* | ||
129 | * 1s in matrix_volatile_state[col] means key pressures | ||
130 | * throw data from non enabled rows. | ||
131 | */ | ||
132 | reg_val = readw(keypad->mmio_base + KPDR); | ||
133 | matrix_volatile_state[col] = (~reg_val) & keypad->rows_en_mask; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * Return in standby mode: | ||
138 | * 9. write 0s to columns | ||
139 | */ | ||
140 | reg_val = readw(keypad->mmio_base + KPDR); | ||
141 | reg_val &= 0x00ff; | ||
142 | writew(reg_val, keypad->mmio_base + KPDR); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * Compare the new matrix state (volatile) with the stable one stored in | ||
147 | * keypad->matrix_stable_state and fire events if changes are detected. | ||
148 | */ | ||
149 | static void imx_keypad_fire_events(struct imx_keypad *keypad, | ||
150 | unsigned short *matrix_volatile_state) | ||
151 | { | ||
152 | struct input_dev *input_dev = keypad->input_dev; | ||
153 | int row, col; | ||
154 | |||
155 | for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) { | ||
156 | unsigned short bits_changed; | ||
157 | int code; | ||
158 | |||
159 | if ((keypad->cols_en_mask & (1 << col)) == 0) | ||
160 | continue; /* Column is not enabled */ | ||
161 | |||
162 | bits_changed = keypad->matrix_stable_state[col] ^ | ||
163 | matrix_volatile_state[col]; | ||
164 | |||
165 | if (bits_changed == 0) | ||
166 | continue; /* Column does not contain changes */ | ||
167 | |||
168 | for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) { | ||
169 | if ((keypad->rows_en_mask & (1 << row)) == 0) | ||
170 | continue; /* Row is not enabled */ | ||
171 | if ((bits_changed & (1 << row)) == 0) | ||
172 | continue; /* Row does not contain changes */ | ||
173 | |||
174 | code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT); | ||
175 | input_event(input_dev, EV_MSC, MSC_SCAN, code); | ||
176 | input_report_key(input_dev, keypad->keycodes[code], | ||
177 | matrix_volatile_state[col] & (1 << row)); | ||
178 | dev_dbg(&input_dev->dev, "Event code: %d, val: %d", | ||
179 | keypad->keycodes[code], | ||
180 | matrix_volatile_state[col] & (1 << row)); | ||
181 | } | ||
182 | } | ||
183 | input_sync(input_dev); | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * imx_keypad_check_for_events is the timer handler. | ||
188 | */ | ||
189 | static void imx_keypad_check_for_events(unsigned long data) | ||
190 | { | ||
191 | struct imx_keypad *keypad = (struct imx_keypad *) data; | ||
192 | unsigned short matrix_volatile_state[MAX_MATRIX_KEY_COLS]; | ||
193 | unsigned short reg_val; | ||
194 | bool state_changed, is_zero_matrix; | ||
195 | int i; | ||
196 | |||
197 | memset(matrix_volatile_state, 0, sizeof(matrix_volatile_state)); | ||
198 | |||
199 | imx_keypad_scan_matrix(keypad, matrix_volatile_state); | ||
200 | |||
201 | state_changed = false; | ||
202 | for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) { | ||
203 | if ((keypad->cols_en_mask & (1 << i)) == 0) | ||
204 | continue; | ||
205 | |||
206 | if (keypad->matrix_unstable_state[i] ^ matrix_volatile_state[i]) { | ||
207 | state_changed = true; | ||
208 | break; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | /* | ||
213 | * If the matrix state is changed from the previous scan | ||
214 | * (Re)Begin the debouncing process, saving the new state in | ||
215 | * keypad->matrix_unstable_state. | ||
216 | * else | ||
217 | * Increase the count of number of scans with a stable state. | ||
218 | */ | ||
219 | if (state_changed) { | ||
220 | memcpy(keypad->matrix_unstable_state, matrix_volatile_state, | ||
221 | sizeof(matrix_volatile_state)); | ||
222 | keypad->stable_count = 0; | ||
223 | } else | ||
224 | keypad->stable_count++; | ||
225 | |||
226 | /* | ||
227 | * If the matrix is not as stable as we want reschedule scan | ||
228 | * in the near future. | ||
229 | */ | ||
230 | if (keypad->stable_count < IMX_KEYPAD_SCANS_FOR_STABILITY) { | ||
231 | mod_timer(&keypad->check_matrix_timer, | ||
232 | jiffies + msecs_to_jiffies(10)); | ||
233 | return; | ||
234 | } | ||
235 | |||
236 | /* | ||
237 | * If the matrix state is stable, fire the events and save the new | ||
238 | * stable state. Note, if the matrix is kept stable for longer | ||
239 | * (keypad->stable_count > IMX_KEYPAD_SCANS_FOR_STABILITY) all | ||
240 | * events have already been generated. | ||
241 | */ | ||
242 | if (keypad->stable_count == IMX_KEYPAD_SCANS_FOR_STABILITY) { | ||
243 | imx_keypad_fire_events(keypad, matrix_volatile_state); | ||
244 | |||
245 | memcpy(keypad->matrix_stable_state, matrix_volatile_state, | ||
246 | sizeof(matrix_volatile_state)); | ||
247 | } | ||
248 | |||
249 | is_zero_matrix = true; | ||
250 | for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) { | ||
251 | if (matrix_volatile_state[i] != 0) { | ||
252 | is_zero_matrix = false; | ||
253 | break; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | |||
258 | if (is_zero_matrix) { | ||
259 | /* | ||
260 | * All keys have been released. Enable only the KDI | ||
261 | * interrupt for future key presses (clear the KDI | ||
262 | * status bit and its sync chain before that). | ||
263 | */ | ||
264 | reg_val = readw(keypad->mmio_base + KPSR); | ||
265 | reg_val |= KBD_STAT_KPKD | KBD_STAT_KDSC; | ||
266 | writew(reg_val, keypad->mmio_base + KPSR); | ||
267 | |||
268 | reg_val = readw(keypad->mmio_base + KPSR); | ||
269 | reg_val |= KBD_STAT_KDIE; | ||
270 | reg_val &= ~KBD_STAT_KRIE; | ||
271 | writew(reg_val, keypad->mmio_base + KPSR); | ||
272 | } else { | ||
273 | /* | ||
274 | * Some keys are still pressed. Schedule a rescan in | ||
275 | * attempt to detect multiple key presses and enable | ||
276 | * the KRI interrupt to react quickly to key release | ||
277 | * event. | ||
278 | */ | ||
279 | mod_timer(&keypad->check_matrix_timer, | ||
280 | jiffies + msecs_to_jiffies(60)); | ||
281 | |||
282 | reg_val = readw(keypad->mmio_base + KPSR); | ||
283 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KRSS; | ||
284 | writew(reg_val, keypad->mmio_base + KPSR); | ||
285 | |||
286 | reg_val = readw(keypad->mmio_base + KPSR); | ||
287 | reg_val |= KBD_STAT_KRIE; | ||
288 | reg_val &= ~KBD_STAT_KDIE; | ||
289 | writew(reg_val, keypad->mmio_base + KPSR); | ||
290 | } | ||
291 | } | ||
292 | |||
293 | static irqreturn_t imx_keypad_irq_handler(int irq, void *dev_id) | ||
294 | { | ||
295 | struct imx_keypad *keypad = dev_id; | ||
296 | unsigned short reg_val; | ||
297 | |||
298 | reg_val = readw(keypad->mmio_base + KPSR); | ||
299 | |||
300 | /* Disable both interrupt types */ | ||
301 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); | ||
302 | /* Clear interrupts status bits */ | ||
303 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD; | ||
304 | writew(reg_val, keypad->mmio_base + KPSR); | ||
305 | |||
306 | if (keypad->enabled) { | ||
307 | /* The matrix is supposed to be changed */ | ||
308 | keypad->stable_count = 0; | ||
309 | |||
310 | /* Schedule the scanning procedure near in the future */ | ||
311 | mod_timer(&keypad->check_matrix_timer, | ||
312 | jiffies + msecs_to_jiffies(2)); | ||
313 | } | ||
314 | |||
315 | return IRQ_HANDLED; | ||
316 | } | ||
317 | |||
318 | static void imx_keypad_config(struct imx_keypad *keypad) | ||
319 | { | ||
320 | unsigned short reg_val; | ||
321 | |||
322 | /* | ||
323 | * Include enabled rows in interrupt generation (KPCR[7:0]) | ||
324 | * Configure keypad columns as open-drain (KPCR[15:8]) | ||
325 | */ | ||
326 | reg_val = readw(keypad->mmio_base + KPCR); | ||
327 | reg_val |= keypad->rows_en_mask & 0xff; /* rows */ | ||
328 | reg_val |= (keypad->cols_en_mask & 0xff) << 8; /* cols */ | ||
329 | writew(reg_val, keypad->mmio_base + KPCR); | ||
330 | |||
331 | /* Write 0's to KPDR[15:8] (Colums) */ | ||
332 | reg_val = readw(keypad->mmio_base + KPDR); | ||
333 | reg_val &= 0x00ff; | ||
334 | writew(reg_val, keypad->mmio_base + KPDR); | ||
335 | |||
336 | /* Configure columns as output, rows as input (KDDR[15:0]) */ | ||
337 | writew(0xff00, keypad->mmio_base + KDDR); | ||
338 | |||
339 | /* | ||
340 | * Clear Key Depress and Key Release status bit. | ||
341 | * Clear both synchronizer chain. | ||
342 | */ | ||
343 | reg_val = readw(keypad->mmio_base + KPSR); | ||
344 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD | | ||
345 | KBD_STAT_KDSC | KBD_STAT_KRSS; | ||
346 | writew(reg_val, keypad->mmio_base + KPSR); | ||
347 | |||
348 | /* Enable KDI and disable KRI (avoid false release events). */ | ||
349 | reg_val |= KBD_STAT_KDIE; | ||
350 | reg_val &= ~KBD_STAT_KRIE; | ||
351 | writew(reg_val, keypad->mmio_base + KPSR); | ||
352 | } | ||
353 | |||
354 | static void imx_keypad_inhibit(struct imx_keypad *keypad) | ||
355 | { | ||
356 | unsigned short reg_val; | ||
357 | |||
358 | /* Inhibit KDI and KRI interrupts. */ | ||
359 | reg_val = readw(keypad->mmio_base + KPSR); | ||
360 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); | ||
361 | writew(reg_val, keypad->mmio_base + KPSR); | ||
362 | |||
363 | /* Colums as open drain and disable all rows */ | ||
364 | writew(0xff00, keypad->mmio_base + KPCR); | ||
365 | } | ||
366 | |||
367 | static void imx_keypad_close(struct input_dev *dev) | ||
368 | { | ||
369 | struct imx_keypad *keypad = input_get_drvdata(dev); | ||
370 | |||
371 | dev_dbg(&dev->dev, ">%s\n", __func__); | ||
372 | |||
373 | /* Mark keypad as being inactive */ | ||
374 | keypad->enabled = false; | ||
375 | synchronize_irq(keypad->irq); | ||
376 | del_timer_sync(&keypad->check_matrix_timer); | ||
377 | |||
378 | imx_keypad_inhibit(keypad); | ||
379 | |||
380 | /* Disable clock unit */ | ||
381 | clk_disable(keypad->clk); | ||
382 | } | ||
383 | |||
384 | static int imx_keypad_open(struct input_dev *dev) | ||
385 | { | ||
386 | struct imx_keypad *keypad = input_get_drvdata(dev); | ||
387 | |||
388 | dev_dbg(&dev->dev, ">%s\n", __func__); | ||
389 | |||
390 | /* We became active from now */ | ||
391 | keypad->enabled = true; | ||
392 | |||
393 | /* Enable the kpp clock */ | ||
394 | clk_enable(keypad->clk); | ||
395 | imx_keypad_config(keypad); | ||
396 | |||
397 | /* Sanity control, not all the rows must be actived now. */ | ||
398 | if ((readw(keypad->mmio_base + KPDR) & keypad->rows_en_mask) == 0) { | ||
399 | dev_err(&dev->dev, | ||
400 | "too many keys pressed, control pins initialisation\n"); | ||
401 | goto open_err; | ||
402 | } | ||
403 | |||
404 | return 0; | ||
405 | |||
406 | open_err: | ||
407 | imx_keypad_close(dev); | ||
408 | return -EIO; | ||
409 | } | ||
410 | |||
411 | static int __devinit imx_keypad_probe(struct platform_device *pdev) | ||
412 | { | ||
413 | const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data; | ||
414 | struct imx_keypad *keypad; | ||
415 | struct input_dev *input_dev; | ||
416 | struct resource *res; | ||
417 | int irq, error, i; | ||
418 | |||
419 | if (keymap_data == NULL) { | ||
420 | dev_err(&pdev->dev, "no keymap defined\n"); | ||
421 | return -EINVAL; | ||
422 | } | ||
423 | |||
424 | irq = platform_get_irq(pdev, 0); | ||
425 | if (irq < 0) { | ||
426 | dev_err(&pdev->dev, "no irq defined in platform data\n"); | ||
427 | return -EINVAL; | ||
428 | } | ||
429 | |||
430 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
431 | if (res == NULL) { | ||
432 | dev_err(&pdev->dev, "no I/O memory defined in platform data\n"); | ||
433 | return -EINVAL; | ||
434 | } | ||
435 | |||
436 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
437 | if (res == NULL) { | ||
438 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
439 | return -EBUSY; | ||
440 | } | ||
441 | |||
442 | input_dev = input_allocate_device(); | ||
443 | if (!input_dev) { | ||
444 | dev_err(&pdev->dev, "failed to allocate the input device\n"); | ||
445 | error = -ENOMEM; | ||
446 | goto failed_rel_mem; | ||
447 | } | ||
448 | |||
449 | keypad = kzalloc(sizeof(struct imx_keypad), GFP_KERNEL); | ||
450 | if (!keypad) { | ||
451 | dev_err(&pdev->dev, "not enough memory for driver data\n"); | ||
452 | error = -ENOMEM; | ||
453 | goto failed_free_input; | ||
454 | } | ||
455 | |||
456 | keypad->input_dev = input_dev; | ||
457 | keypad->irq = irq; | ||
458 | keypad->stable_count = 0; | ||
459 | |||
460 | setup_timer(&keypad->check_matrix_timer, | ||
461 | imx_keypad_check_for_events, (unsigned long) keypad); | ||
462 | |||
463 | keypad->mmio_base = ioremap(res->start, resource_size(res)); | ||
464 | if (keypad->mmio_base == NULL) { | ||
465 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
466 | error = -ENOMEM; | ||
467 | goto failed_free_priv; | ||
468 | } | ||
469 | |||
470 | keypad->clk = clk_get(&pdev->dev, "kpp"); | ||
471 | if (IS_ERR(keypad->clk)) { | ||
472 | dev_err(&pdev->dev, "failed to get keypad clock\n"); | ||
473 | error = PTR_ERR(keypad->clk); | ||
474 | goto failed_unmap; | ||
475 | } | ||
476 | |||
477 | /* Search for rows and cols enabled */ | ||
478 | for (i = 0; i < keymap_data->keymap_size; i++) { | ||
479 | keypad->rows_en_mask |= 1 << KEY_ROW(keymap_data->keymap[i]); | ||
480 | keypad->cols_en_mask |= 1 << KEY_COL(keymap_data->keymap[i]); | ||
481 | } | ||
482 | |||
483 | if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) || | ||
484 | keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) { | ||
485 | dev_err(&pdev->dev, | ||
486 | "invalid key data (too many rows or colums)\n"); | ||
487 | error = -EINVAL; | ||
488 | goto failed_clock_put; | ||
489 | } | ||
490 | dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask); | ||
491 | dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask); | ||
492 | |||
493 | /* Init the Input device */ | ||
494 | input_dev->name = pdev->name; | ||
495 | input_dev->id.bustype = BUS_HOST; | ||
496 | input_dev->dev.parent = &pdev->dev; | ||
497 | input_dev->open = imx_keypad_open; | ||
498 | input_dev->close = imx_keypad_close; | ||
499 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
500 | input_dev->keycode = keypad->keycodes; | ||
501 | input_dev->keycodesize = sizeof(keypad->keycodes[0]); | ||
502 | input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); | ||
503 | |||
504 | matrix_keypad_build_keymap(keymap_data, MATRIX_ROW_SHIFT, | ||
505 | keypad->keycodes, input_dev->keybit); | ||
506 | |||
507 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
508 | input_set_drvdata(input_dev, keypad); | ||
509 | |||
510 | /* Ensure that the keypad will stay dormant until opened */ | ||
511 | imx_keypad_inhibit(keypad); | ||
512 | |||
513 | error = request_irq(irq, imx_keypad_irq_handler, IRQF_DISABLED, | ||
514 | pdev->name, keypad); | ||
515 | if (error) { | ||
516 | dev_err(&pdev->dev, "failed to request IRQ\n"); | ||
517 | goto failed_clock_put; | ||
518 | } | ||
519 | |||
520 | /* Register the input device */ | ||
521 | error = input_register_device(input_dev); | ||
522 | if (error) { | ||
523 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
524 | goto failed_free_irq; | ||
525 | } | ||
526 | |||
527 | platform_set_drvdata(pdev, keypad); | ||
528 | device_init_wakeup(&pdev->dev, 1); | ||
529 | |||
530 | return 0; | ||
531 | |||
532 | failed_free_irq: | ||
533 | free_irq(irq, pdev); | ||
534 | failed_clock_put: | ||
535 | clk_put(keypad->clk); | ||
536 | failed_unmap: | ||
537 | iounmap(keypad->mmio_base); | ||
538 | failed_free_priv: | ||
539 | kfree(keypad); | ||
540 | failed_free_input: | ||
541 | input_free_device(input_dev); | ||
542 | failed_rel_mem: | ||
543 | release_mem_region(res->start, resource_size(res)); | ||
544 | return error; | ||
545 | } | ||
546 | |||
547 | static int __devexit imx_keypad_remove(struct platform_device *pdev) | ||
548 | { | ||
549 | struct imx_keypad *keypad = platform_get_drvdata(pdev); | ||
550 | struct resource *res; | ||
551 | |||
552 | dev_dbg(&pdev->dev, ">%s\n", __func__); | ||
553 | |||
554 | platform_set_drvdata(pdev, NULL); | ||
555 | |||
556 | input_unregister_device(keypad->input_dev); | ||
557 | |||
558 | free_irq(keypad->irq, keypad); | ||
559 | clk_put(keypad->clk); | ||
560 | |||
561 | iounmap(keypad->mmio_base); | ||
562 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
563 | release_mem_region(res->start, resource_size(res)); | ||
564 | |||
565 | kfree(keypad); | ||
566 | |||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | static struct platform_driver imx_keypad_driver = { | ||
571 | .driver = { | ||
572 | .name = "imx-keypad", | ||
573 | .owner = THIS_MODULE, | ||
574 | }, | ||
575 | .probe = imx_keypad_probe, | ||
576 | .remove = __devexit_p(imx_keypad_remove), | ||
577 | }; | ||
578 | |||
579 | static int __init imx_keypad_init(void) | ||
580 | { | ||
581 | return platform_driver_register(&imx_keypad_driver); | ||
582 | } | ||
583 | |||
584 | static void __exit imx_keypad_exit(void) | ||
585 | { | ||
586 | platform_driver_unregister(&imx_keypad_driver); | ||
587 | } | ||
588 | |||
589 | module_init(imx_keypad_init); | ||
590 | module_exit(imx_keypad_exit); | ||
591 | |||
592 | MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>"); | ||
593 | MODULE_DESCRIPTION("IMX Keypad Port Driver"); | ||
594 | MODULE_LICENSE("GPL v2"); | ||
595 | MODULE_ALIAS("platform:imx-keypad"); | ||
diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index 781fc6102860..5fc976dbce0b 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/slab.h> | ||
27 | 28 | ||
28 | #include <asm/delay.h> | 29 | #include <asm/delay.h> |
29 | #include <asm/io.h> | 30 | #include <asm/io.h> |
diff --git a/drivers/input/keyboard/jornada720_kbd.c b/drivers/input/keyboard/jornada720_kbd.c index 4e016d823069..2cd3e1d56ea4 100644 --- a/drivers/input/keyboard/jornada720_kbd.c +++ b/drivers/input/keyboard/jornada720_kbd.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/slab.h> | ||
26 | 27 | ||
27 | #include <mach/jornada720.h> | 28 | #include <mach/jornada720.h> |
28 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index f9847e0fb553..fa9bb6d235e2 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c | |||
@@ -72,9 +72,9 @@ | |||
72 | 72 | ||
73 | #define DRIVER_DESC "LK keyboard driver" | 73 | #define DRIVER_DESC "LK keyboard driver" |
74 | 74 | ||
75 | MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>"); | 75 | MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>"); |
76 | MODULE_DESCRIPTION (DRIVER_DESC); | 76 | MODULE_DESCRIPTION(DRIVER_DESC); |
77 | MODULE_LICENSE ("GPL"); | 77 | MODULE_LICENSE("GPL"); |
78 | 78 | ||
79 | /* | 79 | /* |
80 | * Known parameters: | 80 | * Known parameters: |
@@ -85,27 +85,27 @@ MODULE_LICENSE ("GPL"); | |||
85 | * Please notice that there's not yet an API to set these at runtime. | 85 | * Please notice that there's not yet an API to set these at runtime. |
86 | */ | 86 | */ |
87 | static int bell_volume = 100; /* % */ | 87 | static int bell_volume = 100; /* % */ |
88 | module_param (bell_volume, int, 0); | 88 | module_param(bell_volume, int, 0); |
89 | MODULE_PARM_DESC (bell_volume, "Bell volume (in %). default is 100%"); | 89 | MODULE_PARM_DESC(bell_volume, "Bell volume (in %). default is 100%"); |
90 | 90 | ||
91 | static int keyclick_volume = 100; /* % */ | 91 | static int keyclick_volume = 100; /* % */ |
92 | module_param (keyclick_volume, int, 0); | 92 | module_param(keyclick_volume, int, 0); |
93 | MODULE_PARM_DESC (keyclick_volume, "Keyclick volume (in %), default is 100%"); | 93 | MODULE_PARM_DESC(keyclick_volume, "Keyclick volume (in %), default is 100%"); |
94 | 94 | ||
95 | static int ctrlclick_volume = 100; /* % */ | 95 | static int ctrlclick_volume = 100; /* % */ |
96 | module_param (ctrlclick_volume, int, 0); | 96 | module_param(ctrlclick_volume, int, 0); |
97 | MODULE_PARM_DESC (ctrlclick_volume, "Ctrlclick volume (in %), default is 100%"); | 97 | MODULE_PARM_DESC(ctrlclick_volume, "Ctrlclick volume (in %), default is 100%"); |
98 | 98 | ||
99 | static int lk201_compose_is_alt; | 99 | static int lk201_compose_is_alt; |
100 | module_param (lk201_compose_is_alt, int, 0); | 100 | module_param(lk201_compose_is_alt, int, 0); |
101 | MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key " | 101 | MODULE_PARM_DESC(lk201_compose_is_alt, |
102 | "will act as an Alt key"); | 102 | "If set non-zero, LK201' Compose key will act as an Alt key"); |
103 | 103 | ||
104 | 104 | ||
105 | 105 | ||
106 | #undef LKKBD_DEBUG | 106 | #undef LKKBD_DEBUG |
107 | #ifdef LKKBD_DEBUG | 107 | #ifdef LKKBD_DEBUG |
108 | #define DBG(x...) printk (x) | 108 | #define DBG(x...) printk(x) |
109 | #else | 109 | #else |
110 | #define DBG(x...) do {} while (0) | 110 | #define DBG(x...) do {} while (0) |
111 | #endif | 111 | #endif |
@@ -122,7 +122,7 @@ MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key " | |||
122 | #define LK_MODE_DOWN 0x80 | 122 | #define LK_MODE_DOWN 0x80 |
123 | #define LK_MODE_AUTODOWN 0x82 | 123 | #define LK_MODE_AUTODOWN 0x82 |
124 | #define LK_MODE_UPDOWN 0x86 | 124 | #define LK_MODE_UPDOWN 0x86 |
125 | #define LK_CMD_SET_MODE(mode,div) ((mode) | ((div) << 3)) | 125 | #define LK_CMD_SET_MODE(mode, div) ((mode) | ((div) << 3)) |
126 | 126 | ||
127 | /* Misc commands */ | 127 | /* Misc commands */ |
128 | #define LK_CMD_ENABLE_KEYCLICK 0x1b | 128 | #define LK_CMD_ENABLE_KEYCLICK 0x1b |
@@ -152,11 +152,8 @@ MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key " | |||
152 | 152 | ||
153 | #define LK_NUM_KEYCODES 256 | 153 | #define LK_NUM_KEYCODES 256 |
154 | #define LK_NUM_IGNORE_BYTES 6 | 154 | #define LK_NUM_IGNORE_BYTES 6 |
155 | typedef u_int16_t lk_keycode_t; | ||
156 | 155 | ||
157 | 156 | static unsigned short lkkbd_keycode[LK_NUM_KEYCODES] = { | |
158 | |||
159 | static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = { | ||
160 | [0x56] = KEY_F1, | 157 | [0x56] = KEY_F1, |
161 | [0x57] = KEY_F2, | 158 | [0x57] = KEY_F2, |
162 | [0x58] = KEY_F3, | 159 | [0x58] = KEY_F3, |
@@ -268,7 +265,7 @@ static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = { | |||
268 | }; | 265 | }; |
269 | 266 | ||
270 | #define CHECK_LED(LK, VAR_ON, VAR_OFF, LED, BITS) do { \ | 267 | #define CHECK_LED(LK, VAR_ON, VAR_OFF, LED, BITS) do { \ |
271 | if (test_bit (LED, (LK)->dev->led)) \ | 268 | if (test_bit(LED, (LK)->dev->led)) \ |
272 | VAR_ON |= BITS; \ | 269 | VAR_ON |= BITS; \ |
273 | else \ | 270 | else \ |
274 | VAR_OFF |= BITS; \ | 271 | VAR_OFF |= BITS; \ |
@@ -278,7 +275,7 @@ static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = { | |||
278 | * Per-keyboard data | 275 | * Per-keyboard data |
279 | */ | 276 | */ |
280 | struct lkkbd { | 277 | struct lkkbd { |
281 | lk_keycode_t keycode[LK_NUM_KEYCODES]; | 278 | unsigned short keycode[LK_NUM_KEYCODES]; |
282 | int ignore_bytes; | 279 | int ignore_bytes; |
283 | unsigned char id[LK_NUM_IGNORE_BYTES]; | 280 | unsigned char id[LK_NUM_IGNORE_BYTES]; |
284 | struct input_dev *dev; | 281 | struct input_dev *dev; |
@@ -301,26 +298,25 @@ static struct { | |||
301 | unsigned char *name; | 298 | unsigned char *name; |
302 | } lk_response[] = { | 299 | } lk_response[] = { |
303 | #define RESPONSE(x) { .value = (x), .name = #x, } | 300 | #define RESPONSE(x) { .value = (x), .name = #x, } |
304 | RESPONSE (LK_STUCK_KEY), | 301 | RESPONSE(LK_STUCK_KEY), |
305 | RESPONSE (LK_SELFTEST_FAILED), | 302 | RESPONSE(LK_SELFTEST_FAILED), |
306 | RESPONSE (LK_ALL_KEYS_UP), | 303 | RESPONSE(LK_ALL_KEYS_UP), |
307 | RESPONSE (LK_METRONOME), | 304 | RESPONSE(LK_METRONOME), |
308 | RESPONSE (LK_OUTPUT_ERROR), | 305 | RESPONSE(LK_OUTPUT_ERROR), |
309 | RESPONSE (LK_INPUT_ERROR), | 306 | RESPONSE(LK_INPUT_ERROR), |
310 | RESPONSE (LK_KBD_LOCKED), | 307 | RESPONSE(LK_KBD_LOCKED), |
311 | RESPONSE (LK_KBD_TEST_MODE_ACK), | 308 | RESPONSE(LK_KBD_TEST_MODE_ACK), |
312 | RESPONSE (LK_PREFIX_KEY_DOWN), | 309 | RESPONSE(LK_PREFIX_KEY_DOWN), |
313 | RESPONSE (LK_MODE_CHANGE_ACK), | 310 | RESPONSE(LK_MODE_CHANGE_ACK), |
314 | RESPONSE (LK_RESPONSE_RESERVED), | 311 | RESPONSE(LK_RESPONSE_RESERVED), |
315 | #undef RESPONSE | 312 | #undef RESPONSE |
316 | }; | 313 | }; |
317 | 314 | ||
318 | static unsigned char * | 315 | static unsigned char *response_name(unsigned char value) |
319 | response_name (unsigned char value) | ||
320 | { | 316 | { |
321 | int i; | 317 | int i; |
322 | 318 | ||
323 | for (i = 0; i < ARRAY_SIZE (lk_response); i++) | 319 | for (i = 0; i < ARRAY_SIZE(lk_response); i++) |
324 | if (lk_response[i].value == value) | 320 | if (lk_response[i].value == value) |
325 | return lk_response[i].name; | 321 | return lk_response[i].name; |
326 | 322 | ||
@@ -331,8 +327,7 @@ response_name (unsigned char value) | |||
331 | /* | 327 | /* |
332 | * Calculate volume parameter byte for a given volume. | 328 | * Calculate volume parameter byte for a given volume. |
333 | */ | 329 | */ |
334 | static unsigned char | 330 | static unsigned char volume_to_hw(int volume_percent) |
335 | volume_to_hw (int volume_percent) | ||
336 | { | 331 | { |
337 | unsigned char ret = 0; | 332 | unsigned char ret = 0; |
338 | 333 | ||
@@ -363,8 +358,7 @@ volume_to_hw (int volume_percent) | |||
363 | return ret; | 358 | return ret; |
364 | } | 359 | } |
365 | 360 | ||
366 | static void | 361 | static void lkkbd_detection_done(struct lkkbd *lk) |
367 | lkkbd_detection_done (struct lkkbd *lk) | ||
368 | { | 362 | { |
369 | int i; | 363 | int i; |
370 | 364 | ||
@@ -377,190 +371,202 @@ lkkbd_detection_done (struct lkkbd *lk) | |||
377 | * Print keyboard name and modify Compose=Alt on user's request. | 371 | * Print keyboard name and modify Compose=Alt on user's request. |
378 | */ | 372 | */ |
379 | switch (lk->id[4]) { | 373 | switch (lk->id[4]) { |
380 | case 1: | 374 | case 1: |
381 | strlcpy (lk->name, "DEC LK201 keyboard", | 375 | strlcpy(lk->name, "DEC LK201 keyboard", sizeof(lk->name)); |
382 | sizeof (lk->name)); | 376 | |
383 | 377 | if (lk201_compose_is_alt) | |
384 | if (lk201_compose_is_alt) | 378 | lk->keycode[0xb1] = KEY_LEFTALT; |
385 | lk->keycode[0xb1] = KEY_LEFTALT; | 379 | break; |
386 | break; | 380 | |
387 | 381 | case 2: | |
388 | case 2: | 382 | strlcpy(lk->name, "DEC LK401 keyboard", sizeof(lk->name)); |
389 | strlcpy (lk->name, "DEC LK401 keyboard", | 383 | break; |
390 | sizeof (lk->name)); | 384 | |
391 | break; | 385 | default: |
392 | 386 | strlcpy(lk->name, "Unknown DEC keyboard", sizeof(lk->name)); | |
393 | default: | 387 | printk(KERN_ERR |
394 | strlcpy (lk->name, "Unknown DEC keyboard", | 388 | "lkkbd: keyboard on %s is unknown, please report to " |
395 | sizeof (lk->name)); | 389 | "Jan-Benedict Glaw <jbglaw@lug-owl.de>\n", lk->phys); |
396 | printk (KERN_ERR "lkkbd: keyboard on %s is unknown, " | 390 | printk(KERN_ERR "lkkbd: keyboard ID'ed as:"); |
397 | "please report to Jan-Benedict Glaw " | 391 | for (i = 0; i < LK_NUM_IGNORE_BYTES; i++) |
398 | "<jbglaw@lug-owl.de>\n", lk->phys); | 392 | printk(" 0x%02x", lk->id[i]); |
399 | printk (KERN_ERR "lkkbd: keyboard ID'ed as:"); | 393 | printk("\n"); |
400 | for (i = 0; i < LK_NUM_IGNORE_BYTES; i++) | 394 | break; |
401 | printk (" 0x%02x", lk->id[i]); | ||
402 | printk ("\n"); | ||
403 | break; | ||
404 | } | 395 | } |
405 | printk (KERN_INFO "lkkbd: keyboard on %s identified as: %s\n", | 396 | |
406 | lk->phys, lk->name); | 397 | printk(KERN_INFO "lkkbd: keyboard on %s identified as: %s\n", |
398 | lk->phys, lk->name); | ||
407 | 399 | ||
408 | /* | 400 | /* |
409 | * Report errors during keyboard boot-up. | 401 | * Report errors during keyboard boot-up. |
410 | */ | 402 | */ |
411 | switch (lk->id[2]) { | 403 | switch (lk->id[2]) { |
412 | case 0x00: | 404 | case 0x00: |
413 | /* All okay */ | 405 | /* All okay */ |
414 | break; | 406 | break; |
415 | 407 | ||
416 | case LK_STUCK_KEY: | 408 | case LK_STUCK_KEY: |
417 | printk (KERN_ERR "lkkbd: Stuck key on keyboard at " | 409 | printk(KERN_ERR "lkkbd: Stuck key on keyboard at %s\n", |
418 | "%s\n", lk->phys); | 410 | lk->phys); |
419 | break; | 411 | break; |
420 | 412 | ||
421 | case LK_SELFTEST_FAILED: | 413 | case LK_SELFTEST_FAILED: |
422 | printk (KERN_ERR "lkkbd: Selftest failed on keyboard " | 414 | printk(KERN_ERR |
423 | "at %s, keyboard may not work " | 415 | "lkkbd: Selftest failed on keyboard at %s, " |
424 | "properly\n", lk->phys); | 416 | "keyboard may not work properly\n", lk->phys); |
425 | break; | 417 | break; |
426 | 418 | ||
427 | default: | 419 | default: |
428 | printk (KERN_ERR "lkkbd: Unknown error %02x on " | 420 | printk(KERN_ERR |
429 | "keyboard at %s\n", lk->id[2], | 421 | "lkkbd: Unknown error %02x on keyboard at %s\n", |
430 | lk->phys); | 422 | lk->id[2], lk->phys); |
431 | break; | 423 | break; |
432 | } | 424 | } |
433 | 425 | ||
434 | /* | 426 | /* |
435 | * Try to hint user if there's a stuck key. | 427 | * Try to hint user if there's a stuck key. |
436 | */ | 428 | */ |
437 | if (lk->id[2] == LK_STUCK_KEY && lk->id[3] != 0) | 429 | if (lk->id[2] == LK_STUCK_KEY && lk->id[3] != 0) |
438 | printk (KERN_ERR "Scancode of stuck key is 0x%02x, keycode " | 430 | printk(KERN_ERR |
439 | "is 0x%04x\n", lk->id[3], | 431 | "Scancode of stuck key is 0x%02x, keycode is 0x%04x\n", |
440 | lk->keycode[lk->id[3]]); | 432 | lk->id[3], lk->keycode[lk->id[3]]); |
441 | |||
442 | return; | ||
443 | } | 433 | } |
444 | 434 | ||
445 | /* | 435 | /* |
446 | * lkkbd_interrupt() is called by the low level driver when a character | 436 | * lkkbd_interrupt() is called by the low level driver when a character |
447 | * is received. | 437 | * is received. |
448 | */ | 438 | */ |
449 | static irqreturn_t | 439 | static irqreturn_t lkkbd_interrupt(struct serio *serio, |
450 | lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags) | 440 | unsigned char data, unsigned int flags) |
451 | { | 441 | { |
452 | struct lkkbd *lk = serio_get_drvdata (serio); | 442 | struct lkkbd *lk = serio_get_drvdata(serio); |
443 | struct input_dev *input_dev = lk->dev; | ||
444 | unsigned int keycode; | ||
453 | int i; | 445 | int i; |
454 | 446 | ||
455 | DBG (KERN_INFO "Got byte 0x%02x\n", data); | 447 | DBG(KERN_INFO "Got byte 0x%02x\n", data); |
456 | 448 | ||
457 | if (lk->ignore_bytes > 0) { | 449 | if (lk->ignore_bytes > 0) { |
458 | DBG (KERN_INFO "Ignoring a byte on %s\n", lk->name); | 450 | DBG(KERN_INFO "Ignoring a byte on %s\n", lk->name); |
459 | lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; | 451 | lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; |
460 | 452 | ||
461 | if (lk->ignore_bytes == 0) | 453 | if (lk->ignore_bytes == 0) |
462 | lkkbd_detection_done (lk); | 454 | lkkbd_detection_done(lk); |
463 | 455 | ||
464 | return IRQ_HANDLED; | 456 | return IRQ_HANDLED; |
465 | } | 457 | } |
466 | 458 | ||
467 | switch (data) { | 459 | switch (data) { |
468 | case LK_ALL_KEYS_UP: | 460 | case LK_ALL_KEYS_UP: |
469 | for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++) | 461 | for (i = 0; i < ARRAY_SIZE(lkkbd_keycode); i++) |
470 | if (lk->keycode[i] != KEY_RESERVED) | 462 | input_report_key(input_dev, lk->keycode[i], 0); |
471 | input_report_key (lk->dev, lk->keycode[i], 0); | 463 | input_sync(input_dev); |
472 | input_sync (lk->dev); | 464 | break; |
473 | break; | 465 | |
474 | 466 | case 0x01: | |
475 | case 0x01: | 467 | DBG(KERN_INFO "Got 0x01, scheduling re-initialization\n"); |
476 | DBG (KERN_INFO "Got 0x01, scheduling re-initialization\n"); | 468 | lk->ignore_bytes = LK_NUM_IGNORE_BYTES; |
477 | lk->ignore_bytes = LK_NUM_IGNORE_BYTES; | 469 | lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; |
478 | lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; | 470 | schedule_work(&lk->tq); |
479 | schedule_work (&lk->tq); | 471 | break; |
480 | break; | 472 | |
481 | 473 | case LK_METRONOME: | |
482 | case LK_METRONOME: | 474 | case LK_OUTPUT_ERROR: |
483 | case LK_OUTPUT_ERROR: | 475 | case LK_INPUT_ERROR: |
484 | case LK_INPUT_ERROR: | 476 | case LK_KBD_LOCKED: |
485 | case LK_KBD_LOCKED: | 477 | case LK_KBD_TEST_MODE_ACK: |
486 | case LK_KBD_TEST_MODE_ACK: | 478 | case LK_PREFIX_KEY_DOWN: |
487 | case LK_PREFIX_KEY_DOWN: | 479 | case LK_MODE_CHANGE_ACK: |
488 | case LK_MODE_CHANGE_ACK: | 480 | case LK_RESPONSE_RESERVED: |
489 | case LK_RESPONSE_RESERVED: | 481 | DBG(KERN_INFO "Got %s and don't know how to handle...\n", |
490 | DBG (KERN_INFO "Got %s and don't know how to handle...\n", | 482 | response_name(data)); |
491 | response_name (data)); | 483 | break; |
492 | break; | 484 | |
493 | 485 | default: | |
494 | default: | 486 | keycode = lk->keycode[data]; |
495 | if (lk->keycode[data] != KEY_RESERVED) { | 487 | if (keycode != KEY_RESERVED) { |
496 | if (!test_bit (lk->keycode[data], lk->dev->key)) | 488 | input_report_key(input_dev, keycode, |
497 | input_report_key (lk->dev, lk->keycode[data], 1); | 489 | !test_bit(keycode, input_dev->key)); |
498 | else | 490 | input_sync(input_dev); |
499 | input_report_key (lk->dev, lk->keycode[data], 0); | 491 | } else { |
500 | input_sync (lk->dev); | 492 | printk(KERN_WARNING |
501 | } else | 493 | "%s: Unknown key with scancode 0x%02x on %s.\n", |
502 | printk (KERN_WARNING "%s: Unknown key with " | 494 | __FILE__, data, lk->name); |
503 | "scancode 0x%02x on %s.\n", | 495 | } |
504 | __FILE__, data, lk->name); | ||
505 | } | 496 | } |
506 | 497 | ||
507 | return IRQ_HANDLED; | 498 | return IRQ_HANDLED; |
508 | } | 499 | } |
509 | 500 | ||
501 | static void lkkbd_toggle_leds(struct lkkbd *lk) | ||
502 | { | ||
503 | struct serio *serio = lk->serio; | ||
504 | unsigned char leds_on = 0; | ||
505 | unsigned char leds_off = 0; | ||
506 | |||
507 | CHECK_LED(lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK); | ||
508 | CHECK_LED(lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE); | ||
509 | CHECK_LED(lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK); | ||
510 | CHECK_LED(lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT); | ||
511 | if (leds_on != 0) { | ||
512 | serio_write(serio, LK_CMD_LED_ON); | ||
513 | serio_write(serio, leds_on); | ||
514 | } | ||
515 | if (leds_off != 0) { | ||
516 | serio_write(serio, LK_CMD_LED_OFF); | ||
517 | serio_write(serio, leds_off); | ||
518 | } | ||
519 | } | ||
520 | |||
521 | static void lkkbd_toggle_keyclick(struct lkkbd *lk, bool on) | ||
522 | { | ||
523 | struct serio *serio = lk->serio; | ||
524 | |||
525 | if (on) { | ||
526 | DBG("%s: Activating key clicks\n", __func__); | ||
527 | serio_write(serio, LK_CMD_ENABLE_KEYCLICK); | ||
528 | serio_write(serio, volume_to_hw(lk->keyclick_volume)); | ||
529 | serio_write(serio, LK_CMD_ENABLE_CTRCLICK); | ||
530 | serio_write(serio, volume_to_hw(lk->ctrlclick_volume)); | ||
531 | } else { | ||
532 | DBG("%s: Deactivating key clicks\n", __func__); | ||
533 | serio_write(serio, LK_CMD_DISABLE_KEYCLICK); | ||
534 | serio_write(serio, LK_CMD_DISABLE_CTRCLICK); | ||
535 | } | ||
536 | |||
537 | } | ||
538 | |||
510 | /* | 539 | /* |
511 | * lkkbd_event() handles events from the input module. | 540 | * lkkbd_event() handles events from the input module. |
512 | */ | 541 | */ |
513 | static int | 542 | static int lkkbd_event(struct input_dev *dev, |
514 | lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, | 543 | unsigned int type, unsigned int code, int value) |
515 | int value) | ||
516 | { | 544 | { |
517 | struct lkkbd *lk = input_get_drvdata (dev); | 545 | struct lkkbd *lk = input_get_drvdata(dev); |
518 | unsigned char leds_on = 0; | ||
519 | unsigned char leds_off = 0; | ||
520 | 546 | ||
521 | switch (type) { | 547 | switch (type) { |
522 | case EV_LED: | 548 | case EV_LED: |
523 | CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK); | 549 | lkkbd_toggle_leds(lk); |
524 | CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE); | 550 | return 0; |
525 | CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK); | 551 | |
526 | CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT); | 552 | case EV_SND: |
527 | if (leds_on != 0) { | 553 | switch (code) { |
528 | serio_write (lk->serio, LK_CMD_LED_ON); | 554 | case SND_CLICK: |
529 | serio_write (lk->serio, leds_on); | 555 | lkkbd_toggle_keyclick(lk, value); |
530 | } | ||
531 | if (leds_off != 0) { | ||
532 | serio_write (lk->serio, LK_CMD_LED_OFF); | ||
533 | serio_write (lk->serio, leds_off); | ||
534 | } | ||
535 | return 0; | 556 | return 0; |
536 | 557 | ||
537 | case EV_SND: | 558 | case SND_BELL: |
538 | switch (code) { | 559 | if (value != 0) |
539 | case SND_CLICK: | 560 | serio_write(lk->serio, LK_CMD_SOUND_BELL); |
540 | if (value == 0) { | 561 | |
541 | DBG ("%s: Deactivating key clicks\n", __func__); | 562 | return 0; |
542 | serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK); | 563 | } |
543 | serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK); | 564 | |
544 | } else { | 565 | break; |
545 | DBG ("%s: Activating key clicks\n", __func__); | 566 | |
546 | serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK); | 567 | default: |
547 | serio_write (lk->serio, volume_to_hw (lk->keyclick_volume)); | 568 | printk(KERN_ERR "%s(): Got unknown type %d, code %d, value %d\n", |
548 | serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK); | 569 | __func__, type, code, value); |
549 | serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume)); | ||
550 | } | ||
551 | return 0; | ||
552 | |||
553 | case SND_BELL: | ||
554 | if (value != 0) | ||
555 | serio_write (lk->serio, LK_CMD_SOUND_BELL); | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | break; | ||
560 | |||
561 | default: | ||
562 | printk (KERN_ERR "%s (): Got unknown type %d, code %d, value %d\n", | ||
563 | __func__, type, code, value); | ||
564 | } | 570 | } |
565 | 571 | ||
566 | return -1; | 572 | return -1; |
@@ -570,79 +576,56 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, | |||
570 | * lkkbd_reinit() sets leds and beeps to a state the computer remembers they | 576 | * lkkbd_reinit() sets leds and beeps to a state the computer remembers they |
571 | * were in. | 577 | * were in. |
572 | */ | 578 | */ |
573 | static void | 579 | static void lkkbd_reinit(struct work_struct *work) |
574 | lkkbd_reinit (struct work_struct *work) | ||
575 | { | 580 | { |
576 | struct lkkbd *lk = container_of(work, struct lkkbd, tq); | 581 | struct lkkbd *lk = container_of(work, struct lkkbd, tq); |
577 | int division; | 582 | int division; |
578 | unsigned char leds_on = 0; | ||
579 | unsigned char leds_off = 0; | ||
580 | 583 | ||
581 | /* Ask for ID */ | 584 | /* Ask for ID */ |
582 | serio_write (lk->serio, LK_CMD_REQUEST_ID); | 585 | serio_write(lk->serio, LK_CMD_REQUEST_ID); |
583 | 586 | ||
584 | /* Reset parameters */ | 587 | /* Reset parameters */ |
585 | serio_write (lk->serio, LK_CMD_SET_DEFAULTS); | 588 | serio_write(lk->serio, LK_CMD_SET_DEFAULTS); |
586 | 589 | ||
587 | /* Set LEDs */ | 590 | /* Set LEDs */ |
588 | CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK); | 591 | lkkbd_toggle_leds(lk); |
589 | CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE); | ||
590 | CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK); | ||
591 | CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT); | ||
592 | if (leds_on != 0) { | ||
593 | serio_write (lk->serio, LK_CMD_LED_ON); | ||
594 | serio_write (lk->serio, leds_on); | ||
595 | } | ||
596 | if (leds_off != 0) { | ||
597 | serio_write (lk->serio, LK_CMD_LED_OFF); | ||
598 | serio_write (lk->serio, leds_off); | ||
599 | } | ||
600 | 592 | ||
601 | /* | 593 | /* |
602 | * Try to activate extended LK401 mode. This command will | 594 | * Try to activate extended LK401 mode. This command will |
603 | * only work with a LK401 keyboard and grants access to | 595 | * only work with a LK401 keyboard and grants access to |
604 | * LAlt, RAlt, RCompose and RShift. | 596 | * LAlt, RAlt, RCompose and RShift. |
605 | */ | 597 | */ |
606 | serio_write (lk->serio, LK_CMD_ENABLE_LK401); | 598 | serio_write(lk->serio, LK_CMD_ENABLE_LK401); |
607 | 599 | ||
608 | /* Set all keys to UPDOWN mode */ | 600 | /* Set all keys to UPDOWN mode */ |
609 | for (division = 1; division <= 14; division++) | 601 | for (division = 1; division <= 14; division++) |
610 | serio_write (lk->serio, LK_CMD_SET_MODE (LK_MODE_UPDOWN, | 602 | serio_write(lk->serio, |
611 | division)); | 603 | LK_CMD_SET_MODE(LK_MODE_UPDOWN, division)); |
612 | 604 | ||
613 | /* Enable bell and set volume */ | 605 | /* Enable bell and set volume */ |
614 | serio_write (lk->serio, LK_CMD_ENABLE_BELL); | 606 | serio_write(lk->serio, LK_CMD_ENABLE_BELL); |
615 | serio_write (lk->serio, volume_to_hw (lk->bell_volume)); | 607 | serio_write(lk->serio, volume_to_hw(lk->bell_volume)); |
616 | 608 | ||
617 | /* Enable/disable keyclick (and possibly set volume) */ | 609 | /* Enable/disable keyclick (and possibly set volume) */ |
618 | if (test_bit (SND_CLICK, lk->dev->snd)) { | 610 | lkkbd_toggle_keyclick(lk, test_bit(SND_CLICK, lk->dev->snd)); |
619 | serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK); | ||
620 | serio_write (lk->serio, volume_to_hw (lk->keyclick_volume)); | ||
621 | serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK); | ||
622 | serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume)); | ||
623 | } else { | ||
624 | serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK); | ||
625 | serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK); | ||
626 | } | ||
627 | 611 | ||
628 | /* Sound the bell if needed */ | 612 | /* Sound the bell if needed */ |
629 | if (test_bit (SND_BELL, lk->dev->snd)) | 613 | if (test_bit(SND_BELL, lk->dev->snd)) |
630 | serio_write (lk->serio, LK_CMD_SOUND_BELL); | 614 | serio_write(lk->serio, LK_CMD_SOUND_BELL); |
631 | } | 615 | } |
632 | 616 | ||
633 | /* | 617 | /* |
634 | * lkkbd_connect() probes for a LK keyboard and fills the necessary structures. | 618 | * lkkbd_connect() probes for a LK keyboard and fills the necessary structures. |
635 | */ | 619 | */ |
636 | static int | 620 | static int lkkbd_connect(struct serio *serio, struct serio_driver *drv) |
637 | lkkbd_connect (struct serio *serio, struct serio_driver *drv) | ||
638 | { | 621 | { |
639 | struct lkkbd *lk; | 622 | struct lkkbd *lk; |
640 | struct input_dev *input_dev; | 623 | struct input_dev *input_dev; |
641 | int i; | 624 | int i; |
642 | int err; | 625 | int err; |
643 | 626 | ||
644 | lk = kzalloc (sizeof (struct lkkbd), GFP_KERNEL); | 627 | lk = kzalloc(sizeof(struct lkkbd), GFP_KERNEL); |
645 | input_dev = input_allocate_device (); | 628 | input_dev = input_allocate_device(); |
646 | if (!lk || !input_dev) { | 629 | if (!lk || !input_dev) { |
647 | err = -ENOMEM; | 630 | err = -ENOMEM; |
648 | goto fail1; | 631 | goto fail1; |
@@ -650,14 +633,14 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) | |||
650 | 633 | ||
651 | lk->serio = serio; | 634 | lk->serio = serio; |
652 | lk->dev = input_dev; | 635 | lk->dev = input_dev; |
653 | INIT_WORK (&lk->tq, lkkbd_reinit); | 636 | INIT_WORK(&lk->tq, lkkbd_reinit); |
654 | lk->bell_volume = bell_volume; | 637 | lk->bell_volume = bell_volume; |
655 | lk->keyclick_volume = keyclick_volume; | 638 | lk->keyclick_volume = keyclick_volume; |
656 | lk->ctrlclick_volume = ctrlclick_volume; | 639 | lk->ctrlclick_volume = ctrlclick_volume; |
657 | memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES); | 640 | memcpy(lk->keycode, lkkbd_keycode, sizeof(lk->keycode)); |
658 | 641 | ||
659 | strlcpy (lk->name, "DEC LK keyboard", sizeof(lk->name)); | 642 | strlcpy(lk->name, "DEC LK keyboard", sizeof(lk->name)); |
660 | snprintf (lk->phys, sizeof(lk->phys), "%s/input0", serio->phys); | 643 | snprintf(lk->phys, sizeof(lk->phys), "%s/input0", serio->phys); |
661 | 644 | ||
662 | input_dev->name = lk->name; | 645 | input_dev->name = lk->name; |
663 | input_dev->phys = lk->phys; | 646 | input_dev->phys = lk->phys; |
@@ -668,62 +651,61 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) | |||
668 | input_dev->dev.parent = &serio->dev; | 651 | input_dev->dev.parent = &serio->dev; |
669 | input_dev->event = lkkbd_event; | 652 | input_dev->event = lkkbd_event; |
670 | 653 | ||
671 | input_set_drvdata (input_dev, lk); | 654 | input_set_drvdata(input_dev, lk); |
672 | 655 | ||
673 | set_bit (EV_KEY, input_dev->evbit); | 656 | __set_bit(EV_KEY, input_dev->evbit); |
674 | set_bit (EV_LED, input_dev->evbit); | 657 | __set_bit(EV_LED, input_dev->evbit); |
675 | set_bit (EV_SND, input_dev->evbit); | 658 | __set_bit(EV_SND, input_dev->evbit); |
676 | set_bit (EV_REP, input_dev->evbit); | 659 | __set_bit(EV_REP, input_dev->evbit); |
677 | set_bit (LED_CAPSL, input_dev->ledbit); | 660 | __set_bit(LED_CAPSL, input_dev->ledbit); |
678 | set_bit (LED_SLEEP, input_dev->ledbit); | 661 | __set_bit(LED_SLEEP, input_dev->ledbit); |
679 | set_bit (LED_COMPOSE, input_dev->ledbit); | 662 | __set_bit(LED_COMPOSE, input_dev->ledbit); |
680 | set_bit (LED_SCROLLL, input_dev->ledbit); | 663 | __set_bit(LED_SCROLLL, input_dev->ledbit); |
681 | set_bit (SND_BELL, input_dev->sndbit); | 664 | __set_bit(SND_BELL, input_dev->sndbit); |
682 | set_bit (SND_CLICK, input_dev->sndbit); | 665 | __set_bit(SND_CLICK, input_dev->sndbit); |
683 | 666 | ||
684 | input_dev->keycode = lk->keycode; | 667 | input_dev->keycode = lk->keycode; |
685 | input_dev->keycodesize = sizeof (lk_keycode_t); | 668 | input_dev->keycodesize = sizeof(lk->keycode[0]); |
686 | input_dev->keycodemax = LK_NUM_KEYCODES; | 669 | input_dev->keycodemax = ARRAY_SIZE(lk->keycode); |
687 | 670 | ||
688 | for (i = 0; i < LK_NUM_KEYCODES; i++) | 671 | for (i = 0; i < LK_NUM_KEYCODES; i++) |
689 | __set_bit (lk->keycode[i], input_dev->keybit); | 672 | __set_bit(lk->keycode[i], input_dev->keybit); |
690 | __clear_bit(KEY_RESERVED, input_dev->keybit); | 673 | __clear_bit(KEY_RESERVED, input_dev->keybit); |
691 | 674 | ||
692 | serio_set_drvdata (serio, lk); | 675 | serio_set_drvdata(serio, lk); |
693 | 676 | ||
694 | err = serio_open (serio, drv); | 677 | err = serio_open(serio, drv); |
695 | if (err) | 678 | if (err) |
696 | goto fail2; | 679 | goto fail2; |
697 | 680 | ||
698 | err = input_register_device (lk->dev); | 681 | err = input_register_device(lk->dev); |
699 | if (err) | 682 | if (err) |
700 | goto fail3; | 683 | goto fail3; |
701 | 684 | ||
702 | serio_write (lk->serio, LK_CMD_POWERCYCLE_RESET); | 685 | serio_write(lk->serio, LK_CMD_POWERCYCLE_RESET); |
703 | 686 | ||
704 | return 0; | 687 | return 0; |
705 | 688 | ||
706 | fail3: serio_close (serio); | 689 | fail3: serio_close(serio); |
707 | fail2: serio_set_drvdata (serio, NULL); | 690 | fail2: serio_set_drvdata(serio, NULL); |
708 | fail1: input_free_device (input_dev); | 691 | fail1: input_free_device(input_dev); |
709 | kfree (lk); | 692 | kfree(lk); |
710 | return err; | 693 | return err; |
711 | } | 694 | } |
712 | 695 | ||
713 | /* | 696 | /* |
714 | * lkkbd_disconnect() unregisters and closes behind us. | 697 | * lkkbd_disconnect() unregisters and closes behind us. |
715 | */ | 698 | */ |
716 | static void | 699 | static void lkkbd_disconnect(struct serio *serio) |
717 | lkkbd_disconnect (struct serio *serio) | ||
718 | { | 700 | { |
719 | struct lkkbd *lk = serio_get_drvdata (serio); | 701 | struct lkkbd *lk = serio_get_drvdata(serio); |
720 | 702 | ||
721 | input_get_device (lk->dev); | 703 | input_get_device(lk->dev); |
722 | input_unregister_device (lk->dev); | 704 | input_unregister_device(lk->dev); |
723 | serio_close (serio); | 705 | serio_close(serio); |
724 | serio_set_drvdata (serio, NULL); | 706 | serio_set_drvdata(serio, NULL); |
725 | input_put_device (lk->dev); | 707 | input_put_device(lk->dev); |
726 | kfree (lk); | 708 | kfree(lk); |
727 | } | 709 | } |
728 | 710 | ||
729 | static struct serio_device_id lkkbd_serio_ids[] = { | 711 | static struct serio_device_id lkkbd_serio_ids[] = { |
@@ -752,18 +734,16 @@ static struct serio_driver lkkbd_drv = { | |||
752 | /* | 734 | /* |
753 | * The functions for insering/removing us as a module. | 735 | * The functions for insering/removing us as a module. |
754 | */ | 736 | */ |
755 | static int __init | 737 | static int __init lkkbd_init(void) |
756 | lkkbd_init (void) | ||
757 | { | 738 | { |
758 | return serio_register_driver(&lkkbd_drv); | 739 | return serio_register_driver(&lkkbd_drv); |
759 | } | 740 | } |
760 | 741 | ||
761 | static void __exit | 742 | static void __exit lkkbd_exit(void) |
762 | lkkbd_exit (void) | ||
763 | { | 743 | { |
764 | serio_unregister_driver(&lkkbd_drv); | 744 | serio_unregister_driver(&lkkbd_drv); |
765 | } | 745 | } |
766 | 746 | ||
767 | module_init (lkkbd_init); | 747 | module_init(lkkbd_init); |
768 | module_exit (lkkbd_exit); | 748 | module_exit(lkkbd_exit); |
769 | 749 | ||
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index 574eda2a4957..60ac4684f875 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/input.h> | 31 | #include <linux/input.h> |
32 | #include <linux/leds.h> | 32 | #include <linux/leds.h> |
33 | #include <linux/i2c/lm8323.h> | 33 | #include <linux/i2c/lm8323.h> |
34 | #include <linux/slab.h> | ||
34 | 35 | ||
35 | /* Commands to send to the chip. */ | 36 | /* Commands to send to the chip. */ |
36 | #define LM8323_CMD_READ_ID 0x80 /* Read chip ID. */ | 37 | #define LM8323_CMD_READ_ID 0x80 /* Read chip ID. */ |
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c index 9caed30f3bbb..b1ab29861e1c 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c | |||
@@ -192,11 +192,18 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) | |||
192 | static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) | 192 | static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) |
193 | { | 193 | { |
194 | struct locomokbd *locomokbd = dev_id; | 194 | struct locomokbd *locomokbd = dev_id; |
195 | u16 r; | ||
196 | |||
197 | r = locomo_readl(locomokbd->base + LOCOMO_KIC); | ||
198 | if ((r & 0x0001) == 0) | ||
199 | return IRQ_HANDLED; | ||
200 | |||
201 | locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */ | ||
202 | |||
195 | /** wait chattering delay **/ | 203 | /** wait chattering delay **/ |
196 | udelay(100); | 204 | udelay(100); |
197 | 205 | ||
198 | locomokbd_scankeyboard(locomokbd); | 206 | locomokbd_scankeyboard(locomokbd); |
199 | |||
200 | return IRQ_HANDLED; | 207 | return IRQ_HANDLED; |
201 | } | 208 | } |
202 | 209 | ||
@@ -210,6 +217,25 @@ static void locomokbd_timer_callback(unsigned long data) | |||
210 | locomokbd_scankeyboard(locomokbd); | 217 | locomokbd_scankeyboard(locomokbd); |
211 | } | 218 | } |
212 | 219 | ||
220 | static int locomokbd_open(struct input_dev *dev) | ||
221 | { | ||
222 | struct locomokbd *locomokbd = input_get_drvdata(dev); | ||
223 | u16 r; | ||
224 | |||
225 | r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010; | ||
226 | locomo_writel(r, locomokbd->base + LOCOMO_KIC); | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static void locomokbd_close(struct input_dev *dev) | ||
231 | { | ||
232 | struct locomokbd *locomokbd = input_get_drvdata(dev); | ||
233 | u16 r; | ||
234 | |||
235 | r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010; | ||
236 | locomo_writel(r, locomokbd->base + LOCOMO_KIC); | ||
237 | } | ||
238 | |||
213 | static int __devinit locomokbd_probe(struct locomo_dev *dev) | 239 | static int __devinit locomokbd_probe(struct locomo_dev *dev) |
214 | { | 240 | { |
215 | struct locomokbd *locomokbd; | 241 | struct locomokbd *locomokbd; |
@@ -253,6 +279,8 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev) | |||
253 | input_dev->id.vendor = 0x0001; | 279 | input_dev->id.vendor = 0x0001; |
254 | input_dev->id.product = 0x0001; | 280 | input_dev->id.product = 0x0001; |
255 | input_dev->id.version = 0x0100; | 281 | input_dev->id.version = 0x0100; |
282 | input_dev->open = locomokbd_open; | ||
283 | input_dev->close = locomokbd_close; | ||
256 | input_dev->dev.parent = &dev->dev; | 284 | input_dev->dev.parent = &dev->dev; |
257 | 285 | ||
258 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | | 286 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | |
@@ -261,6 +289,8 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev) | |||
261 | input_dev->keycodesize = sizeof(locomokbd_keycode[0]); | 289 | input_dev->keycodesize = sizeof(locomokbd_keycode[0]); |
262 | input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); | 290 | input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); |
263 | 291 | ||
292 | input_set_drvdata(input_dev, locomokbd); | ||
293 | |||
264 | memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); | 294 | memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); |
265 | for (i = 0; i < LOCOMOKBD_NUMKEYS; i++) | 295 | for (i = 0; i < LOCOMOKBD_NUMKEYS; i++) |
266 | set_bit(locomokbd->keycode[i], input_dev->keybit); | 296 | set_bit(locomokbd->keycode[i], input_dev->keybit); |
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 91cfe5170265..b443e088fd3c 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
24 | #include <linux/input/matrix_keypad.h> | 24 | #include <linux/input/matrix_keypad.h> |
25 | #include <linux/slab.h> | ||
25 | 26 | ||
26 | struct matrix_keypad { | 27 | struct matrix_keypad { |
27 | const struct matrix_keypad_platform_data *pdata; | 28 | const struct matrix_keypad_platform_data *pdata; |
@@ -29,11 +30,13 @@ struct matrix_keypad { | |||
29 | unsigned short *keycodes; | 30 | unsigned short *keycodes; |
30 | unsigned int row_shift; | 31 | unsigned int row_shift; |
31 | 32 | ||
33 | DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS); | ||
34 | |||
32 | uint32_t last_key_state[MATRIX_MAX_COLS]; | 35 | uint32_t last_key_state[MATRIX_MAX_COLS]; |
33 | struct delayed_work work; | 36 | struct delayed_work work; |
37 | spinlock_t lock; | ||
34 | bool scan_pending; | 38 | bool scan_pending; |
35 | bool stopped; | 39 | bool stopped; |
36 | spinlock_t lock; | ||
37 | }; | 40 | }; |
38 | 41 | ||
39 | /* | 42 | /* |
@@ -213,38 +216,53 @@ static void matrix_keypad_stop(struct input_dev *dev) | |||
213 | } | 216 | } |
214 | 217 | ||
215 | #ifdef CONFIG_PM | 218 | #ifdef CONFIG_PM |
216 | static int matrix_keypad_suspend(struct platform_device *pdev, pm_message_t state) | 219 | static int matrix_keypad_suspend(struct device *dev) |
217 | { | 220 | { |
221 | struct platform_device *pdev = to_platform_device(dev); | ||
218 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | 222 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); |
219 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 223 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
220 | int i; | 224 | int i; |
221 | 225 | ||
222 | matrix_keypad_stop(keypad->input_dev); | 226 | matrix_keypad_stop(keypad->input_dev); |
223 | 227 | ||
224 | if (device_may_wakeup(&pdev->dev)) | 228 | if (device_may_wakeup(&pdev->dev)) { |
225 | for (i = 0; i < pdata->num_row_gpios; i++) | 229 | for (i = 0; i < pdata->num_row_gpios; i++) { |
226 | enable_irq_wake(gpio_to_irq(pdata->row_gpios[i])); | 230 | if (!test_bit(i, keypad->disabled_gpios)) { |
231 | unsigned int gpio = pdata->row_gpios[i]; | ||
232 | |||
233 | if (enable_irq_wake(gpio_to_irq(gpio)) == 0) | ||
234 | __set_bit(i, keypad->disabled_gpios); | ||
235 | } | ||
236 | } | ||
237 | } | ||
227 | 238 | ||
228 | return 0; | 239 | return 0; |
229 | } | 240 | } |
230 | 241 | ||
231 | static int matrix_keypad_resume(struct platform_device *pdev) | 242 | static int matrix_keypad_resume(struct device *dev) |
232 | { | 243 | { |
244 | struct platform_device *pdev = to_platform_device(dev); | ||
233 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | 245 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); |
234 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 246 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
235 | int i; | 247 | int i; |
236 | 248 | ||
237 | if (device_may_wakeup(&pdev->dev)) | 249 | if (device_may_wakeup(&pdev->dev)) { |
238 | for (i = 0; i < pdata->num_row_gpios; i++) | 250 | for (i = 0; i < pdata->num_row_gpios; i++) { |
239 | disable_irq_wake(gpio_to_irq(pdata->row_gpios[i])); | 251 | if (test_and_clear_bit(i, keypad->disabled_gpios)) { |
252 | unsigned int gpio = pdata->row_gpios[i]; | ||
253 | |||
254 | disable_irq_wake(gpio_to_irq(gpio)); | ||
255 | } | ||
256 | } | ||
257 | } | ||
240 | 258 | ||
241 | matrix_keypad_start(keypad->input_dev); | 259 | matrix_keypad_start(keypad->input_dev); |
242 | 260 | ||
243 | return 0; | 261 | return 0; |
244 | } | 262 | } |
245 | #else | 263 | |
246 | #define matrix_keypad_suspend NULL | 264 | static const SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops, |
247 | #define matrix_keypad_resume NULL | 265 | matrix_keypad_suspend, matrix_keypad_resume); |
248 | #endif | 266 | #endif |
249 | 267 | ||
250 | static int __devinit init_matrix_gpio(struct platform_device *pdev, | 268 | static int __devinit init_matrix_gpio(struct platform_device *pdev, |
@@ -356,7 +374,9 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev) | |||
356 | input_dev->name = pdev->name; | 374 | input_dev->name = pdev->name; |
357 | input_dev->id.bustype = BUS_HOST; | 375 | input_dev->id.bustype = BUS_HOST; |
358 | input_dev->dev.parent = &pdev->dev; | 376 | input_dev->dev.parent = &pdev->dev; |
359 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 377 | input_dev->evbit[0] = BIT_MASK(EV_KEY); |
378 | if (!pdata->no_autorepeat) | ||
379 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
360 | input_dev->open = matrix_keypad_start; | 380 | input_dev->open = matrix_keypad_start; |
361 | input_dev->close = matrix_keypad_stop; | 381 | input_dev->close = matrix_keypad_stop; |
362 | 382 | ||
@@ -417,11 +437,12 @@ static int __devexit matrix_keypad_remove(struct platform_device *pdev) | |||
417 | static struct platform_driver matrix_keypad_driver = { | 437 | static struct platform_driver matrix_keypad_driver = { |
418 | .probe = matrix_keypad_probe, | 438 | .probe = matrix_keypad_probe, |
419 | .remove = __devexit_p(matrix_keypad_remove), | 439 | .remove = __devexit_p(matrix_keypad_remove), |
420 | .suspend = matrix_keypad_suspend, | ||
421 | .resume = matrix_keypad_resume, | ||
422 | .driver = { | 440 | .driver = { |
423 | .name = "matrix-keypad", | 441 | .name = "matrix-keypad", |
424 | .owner = THIS_MODULE, | 442 | .owner = THIS_MODULE, |
443 | #ifdef CONFIG_PM | ||
444 | .pm = &matrix_keypad_pm_ops, | ||
445 | #endif | ||
425 | }, | 446 | }, |
426 | }; | 447 | }; |
427 | 448 | ||
diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c index 3b5b948eba39..7fc8185e5c1b 100644 --- a/drivers/input/keyboard/max7359_keypad.c +++ b/drivers/input/keyboard/max7359_keypad.c | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/slab.h> | ||
18 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
19 | #include <linux/input.h> | 20 | #include <linux/input.h> |
20 | #include <linux/input/matrix_keypad.h> | 21 | #include <linux/input/matrix_keypad.h> |
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index bba85add35a3..a72e61ddca91 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c | |||
@@ -34,13 +34,14 @@ | |||
34 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
35 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
36 | #include <linux/errno.h> | 36 | #include <linux/errno.h> |
37 | #include <linux/slab.h> | ||
37 | #include <mach/gpio.h> | 38 | #include <mach/gpio.h> |
38 | #include <mach/keypad.h> | 39 | #include <plat/keypad.h> |
39 | #include <mach/menelaus.h> | 40 | #include <plat/menelaus.h> |
40 | #include <asm/irq.h> | 41 | #include <asm/irq.h> |
41 | #include <mach/hardware.h> | 42 | #include <mach/hardware.h> |
42 | #include <asm/io.h> | 43 | #include <asm/io.h> |
43 | #include <mach/mux.h> | 44 | #include <plat/mux.h> |
44 | 45 | ||
45 | #undef NEW_BOARD_LEARNING_MODE | 46 | #undef NEW_BOARD_LEARNING_MODE |
46 | 47 | ||
diff --git a/drivers/input/keyboard/opencores-kbd.c b/drivers/input/keyboard/opencores-kbd.c index 78cccddbf551..1f1a5563f60a 100644 --- a/drivers/input/keyboard/opencores-kbd.c +++ b/drivers/input/keyboard/opencores-kbd.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/slab.h> | ||
17 | 18 | ||
18 | struct opencores_kbd { | 19 | struct opencores_kbd { |
19 | struct input_dev *input; | 20 | struct input_dev *input; |
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 79cd3e9fdf2e..0e53b3bc39af 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/input/matrix_keypad.h> | 28 | #include <linux/input/matrix_keypad.h> |
29 | #include <linux/slab.h> | ||
29 | 30 | ||
30 | #include <asm/mach/arch.h> | 31 | #include <asm/mach/arch.h> |
31 | #include <asm/mach/map.h> | 32 | #include <asm/mach/map.h> |
diff --git a/drivers/input/keyboard/pxa930_rotary.c b/drivers/input/keyboard/pxa930_rotary.c index 95fbba470e65..b7123a44b6ec 100644 --- a/drivers/input/keyboard/pxa930_rotary.c +++ b/drivers/input/keyboard/pxa930_rotary.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/input.h> | 13 | #include <linux/input.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/slab.h> | ||
16 | 17 | ||
17 | #include <mach/pxa930_rotary.h> | 18 | #include <mach/pxa930_rotary.h> |
18 | 19 | ||
diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c index 191cc51d6cf8..31f30087b591 100644 --- a/drivers/input/keyboard/qt2160.c +++ b/drivers/input/keyboard/qt2160.c | |||
@@ -362,7 +362,7 @@ static int __devexit qt2160_remove(struct i2c_client *client) | |||
362 | return 0; | 362 | return 0; |
363 | } | 363 | } |
364 | 364 | ||
365 | static struct i2c_device_id qt2160_idtable[] = { | 365 | static const struct i2c_device_id qt2160_idtable[] = { |
366 | { "qt2160", 0, }, | 366 | { "qt2160", 0, }, |
367 | { } | 367 | { } |
368 | }; | 368 | }; |
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 887af79b7bff..d7dafd9425b6 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c | |||
@@ -18,17 +18,11 @@ | |||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/input.h> | 20 | #include <linux/input.h> |
21 | #include <linux/input/sh_keysc.h> | ||
22 | #include <linux/bitmap.h> | ||
21 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
22 | #include <linux/io.h> | 24 | #include <linux/io.h> |
23 | #include <asm/sh_keysc.h> | 25 | #include <linux/slab.h> |
24 | |||
25 | #define KYCR1_OFFS 0x00 | ||
26 | #define KYCR2_OFFS 0x04 | ||
27 | #define KYINDR_OFFS 0x08 | ||
28 | #define KYOUTDR_OFFS 0x0c | ||
29 | |||
30 | #define KYCR2_IRQ_LEVEL 0x10 | ||
31 | #define KYCR2_IRQ_DISABLED 0x00 | ||
32 | 26 | ||
33 | static const struct { | 27 | static const struct { |
34 | unsigned char kymd, keyout, keyin; | 28 | unsigned char kymd, keyout, keyin; |
@@ -36,84 +30,131 @@ static const struct { | |||
36 | [SH_KEYSC_MODE_1] = { 0, 6, 5 }, | 30 | [SH_KEYSC_MODE_1] = { 0, 6, 5 }, |
37 | [SH_KEYSC_MODE_2] = { 1, 5, 6 }, | 31 | [SH_KEYSC_MODE_2] = { 1, 5, 6 }, |
38 | [SH_KEYSC_MODE_3] = { 2, 4, 7 }, | 32 | [SH_KEYSC_MODE_3] = { 2, 4, 7 }, |
33 | [SH_KEYSC_MODE_4] = { 3, 6, 6 }, | ||
34 | [SH_KEYSC_MODE_5] = { 4, 6, 7 }, | ||
35 | [SH_KEYSC_MODE_6] = { 5, 7, 7 }, | ||
39 | }; | 36 | }; |
40 | 37 | ||
41 | struct sh_keysc_priv { | 38 | struct sh_keysc_priv { |
42 | void __iomem *iomem_base; | 39 | void __iomem *iomem_base; |
43 | struct clk *clk; | 40 | struct clk *clk; |
44 | unsigned long last_keys; | 41 | DECLARE_BITMAP(last_keys, SH_KEYSC_MAXKEYS); |
45 | struct input_dev *input; | 42 | struct input_dev *input; |
46 | struct sh_keysc_info pdata; | 43 | struct sh_keysc_info pdata; |
47 | }; | 44 | }; |
48 | 45 | ||
46 | #define KYCR1 0 | ||
47 | #define KYCR2 1 | ||
48 | #define KYINDR 2 | ||
49 | #define KYOUTDR 3 | ||
50 | |||
51 | #define KYCR2_IRQ_LEVEL 0x10 | ||
52 | #define KYCR2_IRQ_DISABLED 0x00 | ||
53 | |||
54 | static unsigned long sh_keysc_read(struct sh_keysc_priv *p, int reg_nr) | ||
55 | { | ||
56 | return ioread16(p->iomem_base + (reg_nr << 2)); | ||
57 | } | ||
58 | |||
59 | static void sh_keysc_write(struct sh_keysc_priv *p, int reg_nr, | ||
60 | unsigned long value) | ||
61 | { | ||
62 | iowrite16(value, p->iomem_base + (reg_nr << 2)); | ||
63 | } | ||
64 | |||
65 | static void sh_keysc_level_mode(struct sh_keysc_priv *p, | ||
66 | unsigned long keys_set) | ||
67 | { | ||
68 | struct sh_keysc_info *pdata = &p->pdata; | ||
69 | |||
70 | sh_keysc_write(p, KYOUTDR, 0); | ||
71 | sh_keysc_write(p, KYCR2, KYCR2_IRQ_LEVEL | (keys_set << 8)); | ||
72 | |||
73 | if (pdata->kycr2_delay) | ||
74 | udelay(pdata->kycr2_delay); | ||
75 | } | ||
76 | |||
77 | static void sh_keysc_map_dbg(struct device *dev, unsigned long *map, | ||
78 | const char *str) | ||
79 | { | ||
80 | int k; | ||
81 | |||
82 | for (k = 0; k < BITS_TO_LONGS(SH_KEYSC_MAXKEYS); k++) | ||
83 | dev_dbg(dev, "%s[%d] 0x%lx\n", str, k, map[k]); | ||
84 | } | ||
85 | |||
49 | static irqreturn_t sh_keysc_isr(int irq, void *dev_id) | 86 | static irqreturn_t sh_keysc_isr(int irq, void *dev_id) |
50 | { | 87 | { |
51 | struct platform_device *pdev = dev_id; | 88 | struct platform_device *pdev = dev_id; |
52 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); | 89 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); |
53 | struct sh_keysc_info *pdata = &priv->pdata; | 90 | struct sh_keysc_info *pdata = &priv->pdata; |
54 | unsigned long keys, keys1, keys0, mask; | 91 | int keyout_nr = sh_keysc_mode[pdata->mode].keyout; |
92 | int keyin_nr = sh_keysc_mode[pdata->mode].keyin; | ||
93 | DECLARE_BITMAP(keys, SH_KEYSC_MAXKEYS); | ||
94 | DECLARE_BITMAP(keys0, SH_KEYSC_MAXKEYS); | ||
95 | DECLARE_BITMAP(keys1, SH_KEYSC_MAXKEYS); | ||
55 | unsigned char keyin_set, tmp; | 96 | unsigned char keyin_set, tmp; |
56 | int i, k; | 97 | int i, k, n; |
57 | 98 | ||
58 | dev_dbg(&pdev->dev, "isr!\n"); | 99 | dev_dbg(&pdev->dev, "isr!\n"); |
59 | 100 | ||
60 | keys1 = ~0; | 101 | bitmap_fill(keys1, SH_KEYSC_MAXKEYS); |
61 | keys0 = 0; | 102 | bitmap_zero(keys0, SH_KEYSC_MAXKEYS); |
62 | 103 | ||
63 | do { | 104 | do { |
64 | keys = 0; | 105 | bitmap_zero(keys, SH_KEYSC_MAXKEYS); |
65 | keyin_set = 0; | 106 | keyin_set = 0; |
66 | 107 | ||
67 | iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); | 108 | sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED); |
109 | |||
110 | for (i = 0; i < keyout_nr; i++) { | ||
111 | n = keyin_nr * i; | ||
68 | 112 | ||
69 | for (i = 0; i < sh_keysc_mode[pdata->mode].keyout; i++) { | 113 | /* drive one KEYOUT pin low, read KEYIN pins */ |
70 | iowrite16(0xfff ^ (3 << (i * 2)), | 114 | sh_keysc_write(priv, KYOUTDR, 0xffff ^ (3 << (i * 2))); |
71 | priv->iomem_base + KYOUTDR_OFFS); | ||
72 | udelay(pdata->delay); | 115 | udelay(pdata->delay); |
73 | tmp = ioread16(priv->iomem_base + KYINDR_OFFS); | 116 | tmp = sh_keysc_read(priv, KYINDR); |
74 | keys |= tmp << (sh_keysc_mode[pdata->mode].keyin * i); | ||
75 | tmp ^= (1 << sh_keysc_mode[pdata->mode].keyin) - 1; | ||
76 | keyin_set |= tmp; | ||
77 | } | ||
78 | 117 | ||
79 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); | 118 | /* set bit if key press has been detected */ |
80 | iowrite16(KYCR2_IRQ_LEVEL | (keyin_set << 8), | 119 | for (k = 0; k < keyin_nr; k++) { |
81 | priv->iomem_base + KYCR2_OFFS); | 120 | if (tmp & (1 << k)) |
121 | __set_bit(n + k, keys); | ||
122 | } | ||
82 | 123 | ||
83 | if (pdata->kycr2_delay) | 124 | /* keep track of which KEYIN bits that have been set */ |
84 | udelay(pdata->kycr2_delay); | 125 | keyin_set |= tmp ^ ((1 << keyin_nr) - 1); |
126 | } | ||
85 | 127 | ||
86 | keys ^= ~0; | 128 | sh_keysc_level_mode(priv, keyin_set); |
87 | keys &= (1 << (sh_keysc_mode[pdata->mode].keyin * | ||
88 | sh_keysc_mode[pdata->mode].keyout)) - 1; | ||
89 | keys1 &= keys; | ||
90 | keys0 |= keys; | ||
91 | 129 | ||
92 | dev_dbg(&pdev->dev, "keys 0x%08lx\n", keys); | 130 | bitmap_complement(keys, keys, SH_KEYSC_MAXKEYS); |
131 | bitmap_and(keys1, keys1, keys, SH_KEYSC_MAXKEYS); | ||
132 | bitmap_or(keys0, keys0, keys, SH_KEYSC_MAXKEYS); | ||
93 | 133 | ||
94 | } while (ioread16(priv->iomem_base + KYCR2_OFFS) & 0x01); | 134 | sh_keysc_map_dbg(&pdev->dev, keys, "keys"); |
95 | 135 | ||
96 | dev_dbg(&pdev->dev, "last_keys 0x%08lx keys0 0x%08lx keys1 0x%08lx\n", | 136 | } while (sh_keysc_read(priv, KYCR2) & 0x01); |
97 | priv->last_keys, keys0, keys1); | 137 | |
138 | sh_keysc_map_dbg(&pdev->dev, priv->last_keys, "last_keys"); | ||
139 | sh_keysc_map_dbg(&pdev->dev, keys0, "keys0"); | ||
140 | sh_keysc_map_dbg(&pdev->dev, keys1, "keys1"); | ||
98 | 141 | ||
99 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { | 142 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { |
100 | k = pdata->keycodes[i]; | 143 | k = pdata->keycodes[i]; |
101 | if (!k) | 144 | if (!k) |
102 | continue; | 145 | continue; |
103 | 146 | ||
104 | mask = 1 << i; | 147 | if (test_bit(i, keys0) == test_bit(i, priv->last_keys)) |
105 | |||
106 | if (!((priv->last_keys ^ keys0) & mask)) | ||
107 | continue; | 148 | continue; |
108 | 149 | ||
109 | if ((keys1 | keys0) & mask) { | 150 | if (test_bit(i, keys1) || test_bit(i, keys0)) { |
110 | input_event(priv->input, EV_KEY, k, 1); | 151 | input_event(priv->input, EV_KEY, k, 1); |
111 | priv->last_keys |= mask; | 152 | __set_bit(i, priv->last_keys); |
112 | } | 153 | } |
113 | 154 | ||
114 | if (!(keys1 & mask)) { | 155 | if (!test_bit(i, keys1)) { |
115 | input_event(priv->input, EV_KEY, k, 0); | 156 | input_event(priv->input, EV_KEY, k, 0); |
116 | priv->last_keys &= ~mask; | 157 | __clear_bit(i, priv->last_keys); |
117 | } | 158 | } |
118 | 159 | ||
119 | } | 160 | } |
@@ -122,8 +163,6 @@ static irqreturn_t sh_keysc_isr(int irq, void *dev_id) | |||
122 | return IRQ_HANDLED; | 163 | return IRQ_HANDLED; |
123 | } | 164 | } |
124 | 165 | ||
125 | #define res_size(res) ((res)->end - (res)->start + 1) | ||
126 | |||
127 | static int __devinit sh_keysc_probe(struct platform_device *pdev) | 166 | static int __devinit sh_keysc_probe(struct platform_device *pdev) |
128 | { | 167 | { |
129 | struct sh_keysc_priv *priv; | 168 | struct sh_keysc_priv *priv; |
@@ -164,7 +203,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
164 | memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); | 203 | memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); |
165 | pdata = &priv->pdata; | 204 | pdata = &priv->pdata; |
166 | 205 | ||
167 | priv->iomem_base = ioremap_nocache(res->start, res_size(res)); | 206 | priv->iomem_base = ioremap_nocache(res->start, resource_size(res)); |
168 | if (priv->iomem_base == NULL) { | 207 | if (priv->iomem_base == NULL) { |
169 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | 208 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); |
170 | error = -ENXIO; | 209 | error = -ENXIO; |
@@ -220,10 +259,9 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
220 | 259 | ||
221 | clk_enable(priv->clk); | 260 | clk_enable(priv->clk); |
222 | 261 | ||
223 | iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) | | 262 | sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) | |
224 | pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); | 263 | pdata->scan_timing); |
225 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); | 264 | sh_keysc_level_mode(priv, 0); |
226 | iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); | ||
227 | 265 | ||
228 | device_init_wakeup(&pdev->dev, 1); | 266 | device_init_wakeup(&pdev->dev, 1); |
229 | 267 | ||
@@ -248,7 +286,7 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) | |||
248 | { | 286 | { |
249 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); | 287 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); |
250 | 288 | ||
251 | iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); | 289 | sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED); |
252 | 290 | ||
253 | input_unregister_device(priv->input); | 291 | input_unregister_device(priv->input); |
254 | free_irq(platform_get_irq(pdev, 0), pdev); | 292 | free_irq(platform_get_irq(pdev, 0), pdev); |
@@ -270,7 +308,7 @@ static int sh_keysc_suspend(struct device *dev) | |||
270 | int irq = platform_get_irq(pdev, 0); | 308 | int irq = platform_get_irq(pdev, 0); |
271 | unsigned short value; | 309 | unsigned short value; |
272 | 310 | ||
273 | value = ioread16(priv->iomem_base + KYCR1_OFFS); | 311 | value = sh_keysc_read(priv, KYCR1); |
274 | 312 | ||
275 | if (device_may_wakeup(dev)) { | 313 | if (device_may_wakeup(dev)) { |
276 | value |= 0x80; | 314 | value |= 0x80; |
@@ -279,7 +317,7 @@ static int sh_keysc_suspend(struct device *dev) | |||
279 | value &= ~0x80; | 317 | value &= ~0x80; |
280 | } | 318 | } |
281 | 319 | ||
282 | iowrite16(value, priv->iomem_base + KYCR1_OFFS); | 320 | sh_keysc_write(priv, KYCR1, value); |
283 | 321 | ||
284 | return 0; | 322 | return 0; |
285 | } | 323 | } |
@@ -295,7 +333,7 @@ static int sh_keysc_resume(struct device *dev) | |||
295 | return 0; | 333 | return 0; |
296 | } | 334 | } |
297 | 335 | ||
298 | static struct dev_pm_ops sh_keysc_dev_pm_ops = { | 336 | static const struct dev_pm_ops sh_keysc_dev_pm_ops = { |
299 | .suspend = sh_keysc_suspend, | 337 | .suspend = sh_keysc_suspend, |
300 | .resume = sh_keysc_resume, | 338 | .resume = sh_keysc_resume, |
301 | }; | 339 | }; |
diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c index 42cb3faf7336..3910f269cfc8 100644 --- a/drivers/input/keyboard/tosakbd.c +++ b/drivers/input/keyboard/tosakbd.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/slab.h> | ||
21 | 22 | ||
22 | #include <mach/gpio.h> | 23 | #include <mach/gpio.h> |
23 | #include <mach/tosa.h> | 24 | #include <mach/tosa.h> |
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 9a2977c21696..7aa59e07b689 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c | |||
@@ -31,7 +31,8 @@ | |||
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/input.h> | 32 | #include <linux/input.h> |
33 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
34 | #include <linux/i2c/twl4030.h> | 34 | #include <linux/i2c/twl.h> |
35 | #include <linux/slab.h> | ||
35 | 36 | ||
36 | 37 | ||
37 | /* | 38 | /* |
@@ -133,7 +134,7 @@ struct twl4030_keypad { | |||
133 | static int twl4030_kpread(struct twl4030_keypad *kp, | 134 | static int twl4030_kpread(struct twl4030_keypad *kp, |
134 | u8 *data, u32 reg, u8 num_bytes) | 135 | u8 *data, u32 reg, u8 num_bytes) |
135 | { | 136 | { |
136 | int ret = twl4030_i2c_read(TWL4030_MODULE_KEYPAD, data, reg, num_bytes); | 137 | int ret = twl_i2c_read(TWL4030_MODULE_KEYPAD, data, reg, num_bytes); |
137 | 138 | ||
138 | if (ret < 0) | 139 | if (ret < 0) |
139 | dev_warn(kp->dbg_dev, | 140 | dev_warn(kp->dbg_dev, |
@@ -145,7 +146,7 @@ static int twl4030_kpread(struct twl4030_keypad *kp, | |||
145 | 146 | ||
146 | static int twl4030_kpwrite_u8(struct twl4030_keypad *kp, u8 data, u32 reg) | 147 | static int twl4030_kpwrite_u8(struct twl4030_keypad *kp, u8 data, u32 reg) |
147 | { | 148 | { |
148 | int ret = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, data, reg); | 149 | int ret = twl_i2c_write_u8(TWL4030_MODULE_KEYPAD, data, reg); |
149 | 150 | ||
150 | if (ret < 0) | 151 | if (ret < 0) |
151 | dev_warn(kp->dbg_dev, | 152 | dev_warn(kp->dbg_dev, |
@@ -253,14 +254,6 @@ static irqreturn_t do_kp_irq(int irq, void *_kp) | |||
253 | u8 reg; | 254 | u8 reg; |
254 | int ret; | 255 | int ret; |
255 | 256 | ||
256 | #ifdef CONFIG_LOCKDEP | ||
257 | /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which | ||
258 | * we don't want and can't tolerate. Although it might be | ||
259 | * friendlier not to borrow this thread context... | ||
260 | */ | ||
261 | local_irq_enable(); | ||
262 | #endif | ||
263 | |||
264 | /* Read & Clear TWL4030 pending interrupt */ | 257 | /* Read & Clear TWL4030 pending interrupt */ |
265 | ret = twl4030_kpread(kp, ®, KEYP_ISR1, 1); | 258 | ret = twl4030_kpread(kp, ®, KEYP_ISR1, 1); |
266 | 259 | ||
@@ -403,7 +396,8 @@ static int __devinit twl4030_kp_probe(struct platform_device *pdev) | |||
403 | * | 396 | * |
404 | * NOTE: we assume this host is wired to TWL4040 INT1, not INT2 ... | 397 | * NOTE: we assume this host is wired to TWL4040 INT1, not INT2 ... |
405 | */ | 398 | */ |
406 | error = request_irq(kp->irq, do_kp_irq, 0, pdev->name, kp); | 399 | error = request_threaded_irq(kp->irq, NULL, do_kp_irq, |
400 | 0, pdev->name, kp); | ||
407 | if (error) { | 401 | if (error) { |
408 | dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", | 402 | dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", |
409 | kp->irq); | 403 | kp->irq); |
diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c index 6032def03707..4ef764cc493c 100644 --- a/drivers/input/keyboard/w90p910_keypad.c +++ b/drivers/input/keyboard/w90p910_keypad.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/slab.h> | ||
22 | 23 | ||
23 | #include <mach/w90p910_keypad.h> | 24 | #include <mach/w90p910_keypad.h> |
24 | 25 | ||