diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-09 22:52:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-09 22:52:01 -0500 |
commit | fa395aaec823b9d1a5800913a6b5d0e6d1c5ced2 (patch) | |
tree | d599abe9f4f48f1737da50fa9a48dadfd08100e3 | |
parent | 3e7468313758913c5e4d372f35b271b96bad1298 (diff) | |
parent | 1f26978afd123deb22dd3c7dc75771a02f6e03f6 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (51 commits)
Input: appletouch - give up maintainership
Input: dm355evm_kbd - switch to using sparse keymap library
Input: wistron_btns - switch to using sparse keymap library
Input: add generic support for sparse keymaps
Input: fix memory leak in force feedback core
Input: wistron - remove identification strings from DMI table
Input: psmouse - remove identification strings from DMI tables
Input: atkbd - remove identification strings from DMI table
Input: i8042 - remove identification strings from DMI tables
DMI: allow omitting ident strings in DMI tables
Input: psmouse - do not carry DMI data around
Input: matrix-keypad - switch to using dev_pm_ops
Input: keyboard - fix lack of locking when traversing handler->h_list
Input: gpio_keys - scan gpio state at probe and resume time
Input: keyboard - add locking around event handling
Input: usbtouchscreen - add support for ET&T TC5UH touchscreen controller
Input: xpad - add two new Xbox 360 devices
Input: polled device - do not start polling if interval is zero
Input: polled device - schedule first poll immediately
Input: add S3C24XX touchscreen driver
...
63 files changed, 3110 insertions, 1167 deletions
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl index 94a20fe8fedf..f9a6e2c75f12 100644 --- a/Documentation/DocBook/device-drivers.tmpl +++ b/Documentation/DocBook/device-drivers.tmpl | |||
@@ -293,10 +293,23 @@ X!Idrivers/video/console/fonts.c | |||
293 | 293 | ||
294 | <chapter id="input_subsystem"> | 294 | <chapter id="input_subsystem"> |
295 | <title>Input Subsystem</title> | 295 | <title>Input Subsystem</title> |
296 | <sect1><title>Input core</title> | ||
296 | !Iinclude/linux/input.h | 297 | !Iinclude/linux/input.h |
297 | !Edrivers/input/input.c | 298 | !Edrivers/input/input.c |
298 | !Edrivers/input/ff-core.c | 299 | !Edrivers/input/ff-core.c |
299 | !Edrivers/input/ff-memless.c | 300 | !Edrivers/input/ff-memless.c |
301 | </sect1> | ||
302 | <sect1><title>Polled input devices</title> | ||
303 | !Iinclude/linux/input-polldev.h | ||
304 | !Edrivers/input/input-polldev.c | ||
305 | </sect1> | ||
306 | <sect1><title>Matrix keyboars/keypads</title> | ||
307 | !Iinclude/linux/input/matrix_keypad.h | ||
308 | </sect1> | ||
309 | <sect1><title>Sparse keymap support</title> | ||
310 | !Iinclude/linux/input/sparse-keymap.h | ||
311 | !Edrivers/input/sparse-keymap.c | ||
312 | </sect1> | ||
300 | </chapter> | 313 | </chapter> |
301 | 314 | ||
302 | <chapter id="spi"> | 315 | <chapter id="spi"> |
diff --git a/MAINTAINERS b/MAINTAINERS index f7b0ced81116..107a5a5a0174 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -486,13 +486,6 @@ S: Maintained | |||
486 | F: drivers/net/appletalk/ | 486 | F: drivers/net/appletalk/ |
487 | F: net/appletalk/ | 487 | F: net/appletalk/ |
488 | 488 | ||
489 | APPLETOUCH TOUCHPAD DRIVER | ||
490 | M: Johannes Berg <johannes@sipsolutions.net> | ||
491 | L: linux-input@vger.kernel.org | ||
492 | S: Maintained | ||
493 | F: Documentation/input/appletouch.txt | ||
494 | F: drivers/input/mouse/appletouch.c | ||
495 | |||
496 | ARC FRAMEBUFFER DRIVER | 489 | ARC FRAMEBUFFER DRIVER |
497 | M: Jaya Kumar <jayalk@intworks.biz> | 490 | M: Jaya Kumar <jayalk@intworks.biz> |
498 | S: Maintained | 491 | S: Maintained |
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index a57af3e99c7c..809114d5a5a6 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c | |||
@@ -866,6 +866,57 @@ static void __init at91_add_device_rtc(void) {} | |||
866 | 866 | ||
867 | 867 | ||
868 | /* -------------------------------------------------------------------- | 868 | /* -------------------------------------------------------------------- |
869 | * Touchscreen | ||
870 | * -------------------------------------------------------------------- */ | ||
871 | |||
872 | #if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE) | ||
873 | static u64 tsadcc_dmamask = DMA_BIT_MASK(32); | ||
874 | static struct at91_tsadcc_data tsadcc_data; | ||
875 | |||
876 | static struct resource tsadcc_resources[] = { | ||
877 | [0] = { | ||
878 | .start = AT91SAM9G45_BASE_TSC, | ||
879 | .end = AT91SAM9G45_BASE_TSC + SZ_16K - 1, | ||
880 | .flags = IORESOURCE_MEM, | ||
881 | }, | ||
882 | [1] = { | ||
883 | .start = AT91SAM9G45_ID_TSC, | ||
884 | .end = AT91SAM9G45_ID_TSC, | ||
885 | .flags = IORESOURCE_IRQ, | ||
886 | } | ||
887 | }; | ||
888 | |||
889 | static struct platform_device at91sam9g45_tsadcc_device = { | ||
890 | .name = "atmel_tsadcc", | ||
891 | .id = -1, | ||
892 | .dev = { | ||
893 | .dma_mask = &tsadcc_dmamask, | ||
894 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
895 | .platform_data = &tsadcc_data, | ||
896 | }, | ||
897 | .resource = tsadcc_resources, | ||
898 | .num_resources = ARRAY_SIZE(tsadcc_resources), | ||
899 | }; | ||
900 | |||
901 | void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) | ||
902 | { | ||
903 | if (!data) | ||
904 | return; | ||
905 | |||
906 | at91_set_gpio_input(AT91_PIN_PD20, 0); /* AD0_XR */ | ||
907 | at91_set_gpio_input(AT91_PIN_PD21, 0); /* AD1_XL */ | ||
908 | at91_set_gpio_input(AT91_PIN_PD22, 0); /* AD2_YT */ | ||
909 | at91_set_gpio_input(AT91_PIN_PD23, 0); /* AD3_TB */ | ||
910 | |||
911 | tsadcc_data = *data; | ||
912 | platform_device_register(&at91sam9g45_tsadcc_device); | ||
913 | } | ||
914 | #else | ||
915 | void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {} | ||
916 | #endif | ||
917 | |||
918 | |||
919 | /* -------------------------------------------------------------------- | ||
869 | * RTT | 920 | * RTT |
870 | * -------------------------------------------------------------------- */ | 921 | * -------------------------------------------------------------------- */ |
871 | 922 | ||
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index d345f5453dbe..53aaa94df75a 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c | |||
@@ -622,6 +622,7 @@ static void __init at91_add_device_tc(void) { } | |||
622 | 622 | ||
623 | #if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE) | 623 | #if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE) |
624 | static u64 tsadcc_dmamask = DMA_BIT_MASK(32); | 624 | static u64 tsadcc_dmamask = DMA_BIT_MASK(32); |
625 | static struct at91_tsadcc_data tsadcc_data; | ||
625 | 626 | ||
626 | static struct resource tsadcc_resources[] = { | 627 | static struct resource tsadcc_resources[] = { |
627 | [0] = { | 628 | [0] = { |
@@ -642,22 +643,27 @@ static struct platform_device at91sam9rl_tsadcc_device = { | |||
642 | .dev = { | 643 | .dev = { |
643 | .dma_mask = &tsadcc_dmamask, | 644 | .dma_mask = &tsadcc_dmamask, |
644 | .coherent_dma_mask = DMA_BIT_MASK(32), | 645 | .coherent_dma_mask = DMA_BIT_MASK(32), |
646 | .platform_data = &tsadcc_data, | ||
645 | }, | 647 | }, |
646 | .resource = tsadcc_resources, | 648 | .resource = tsadcc_resources, |
647 | .num_resources = ARRAY_SIZE(tsadcc_resources), | 649 | .num_resources = ARRAY_SIZE(tsadcc_resources), |
648 | }; | 650 | }; |
649 | 651 | ||
650 | void __init at91_add_device_tsadcc(void) | 652 | void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) |
651 | { | 653 | { |
654 | if (!data) | ||
655 | return; | ||
656 | |||
652 | at91_set_A_periph(AT91_PIN_PA17, 0); /* AD0_XR */ | 657 | at91_set_A_periph(AT91_PIN_PA17, 0); /* AD0_XR */ |
653 | at91_set_A_periph(AT91_PIN_PA18, 0); /* AD1_XL */ | 658 | at91_set_A_periph(AT91_PIN_PA18, 0); /* AD1_XL */ |
654 | at91_set_A_periph(AT91_PIN_PA19, 0); /* AD2_YT */ | 659 | at91_set_A_periph(AT91_PIN_PA19, 0); /* AD2_YT */ |
655 | at91_set_A_periph(AT91_PIN_PA20, 0); /* AD3_TB */ | 660 | at91_set_A_periph(AT91_PIN_PA20, 0); /* AD3_TB */ |
656 | 661 | ||
662 | tsadcc_data = *data; | ||
657 | platform_device_register(&at91sam9rl_tsadcc_device); | 663 | platform_device_register(&at91sam9rl_tsadcc_device); |
658 | } | 664 | } |
659 | #else | 665 | #else |
660 | void __init at91_add_device_tsadcc(void) {} | 666 | void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {} |
661 | #endif | 667 | #endif |
662 | 668 | ||
663 | 669 | ||
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index 1cf4d8681078..98f9f4bc9396 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c | |||
@@ -229,6 +229,16 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data; | |||
229 | 229 | ||
230 | 230 | ||
231 | /* | 231 | /* |
232 | * Touchscreen | ||
233 | */ | ||
234 | static struct at91_tsadcc_data ek_tsadcc_data = { | ||
235 | .adc_clock = 300000, | ||
236 | .pendet_debounce = 0x0d, | ||
237 | .ts_sample_hold_time = 0x0a, | ||
238 | }; | ||
239 | |||
240 | |||
241 | /* | ||
232 | * GPIO Buttons | 242 | * GPIO Buttons |
233 | */ | 243 | */ |
234 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | 244 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) |
@@ -379,6 +389,8 @@ static void __init ek_board_init(void) | |||
379 | at91_add_device_i2c(0, NULL, 0); | 389 | at91_add_device_i2c(0, NULL, 0); |
380 | /* LCD Controller */ | 390 | /* LCD Controller */ |
381 | at91_add_device_lcdc(&ek_lcdc_data); | 391 | at91_add_device_lcdc(&ek_lcdc_data); |
392 | /* Touch Screen */ | ||
393 | at91_add_device_tsadcc(&ek_tsadcc_data); | ||
382 | /* Push Buttons */ | 394 | /* Push Buttons */ |
383 | ek_add_device_buttons(); | 395 | ek_add_device_buttons(); |
384 | /* AC97 */ | 396 | /* AC97 */ |
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index bd28e989e54e..7ac20f3a2067 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c | |||
@@ -243,6 +243,16 @@ static struct gpio_led ek_leds[] = { | |||
243 | 243 | ||
244 | 244 | ||
245 | /* | 245 | /* |
246 | * Touchscreen | ||
247 | */ | ||
248 | static struct at91_tsadcc_data ek_tsadcc_data = { | ||
249 | .adc_clock = 1000000, | ||
250 | .pendet_debounce = 0x0f, | ||
251 | .ts_sample_hold_time = 0x03, | ||
252 | }; | ||
253 | |||
254 | |||
255 | /* | ||
246 | * GPIO Buttons | 256 | * GPIO Buttons |
247 | */ | 257 | */ |
248 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | 258 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) |
@@ -310,7 +320,7 @@ static void __init ek_board_init(void) | |||
310 | /* AC97 */ | 320 | /* AC97 */ |
311 | at91_add_device_ac97(&ek_ac97_data); | 321 | at91_add_device_ac97(&ek_ac97_data); |
312 | /* Touch Screen Controller */ | 322 | /* Touch Screen Controller */ |
313 | at91_add_device_tsadcc(); | 323 | at91_add_device_tsadcc(&ek_tsadcc_data); |
314 | /* LEDs */ | 324 | /* LEDs */ |
315 | at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); | 325 | at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); |
316 | /* Push Buttons */ | 326 | /* Push Buttons */ |
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index 2295d80dd893..bb6f6a7ba5e0 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h | |||
@@ -187,7 +187,12 @@ extern void __init at91_add_device_ac97(struct ac97c_platform_data *data); | |||
187 | extern void __init at91_add_device_isi(void); | 187 | extern void __init at91_add_device_isi(void); |
188 | 188 | ||
189 | /* Touchscreen Controller */ | 189 | /* Touchscreen Controller */ |
190 | extern void __init at91_add_device_tsadcc(void); | 190 | struct at91_tsadcc_data { |
191 | unsigned int adc_clock; | ||
192 | u8 pendet_debounce; | ||
193 | u8 ts_sample_hold_time; | ||
194 | }; | ||
195 | extern void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data); | ||
191 | 196 | ||
192 | /* CAN */ | 197 | /* CAN */ |
193 | struct at91_can_data { | 198 | struct at91_can_data { |
diff --git a/arch/arm/mach-davinci/include/mach/keyscan.h b/arch/arm/mach-davinci/include/mach/keyscan.h new file mode 100644 index 000000000000..b4e21a2976d1 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/keyscan.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Texas Instruments, Inc | ||
3 | * | ||
4 | * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef DAVINCI_KEYSCAN_H | ||
22 | #define DAVINCI_KEYSCAN_H | ||
23 | |||
24 | #include <linux/io.h> | ||
25 | |||
26 | enum davinci_matrix_types { | ||
27 | DAVINCI_KEYSCAN_MATRIX_4X4, | ||
28 | DAVINCI_KEYSCAN_MATRIX_5X3, | ||
29 | }; | ||
30 | |||
31 | struct davinci_ks_platform_data { | ||
32 | unsigned short *keymap; | ||
33 | u32 keymapsize; | ||
34 | u8 rep:1; | ||
35 | u8 strobe; | ||
36 | u8 interval; | ||
37 | u8 matrix_type; | ||
38 | }; | ||
39 | |||
40 | #endif | ||
41 | |||
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 950837cf9e9c..5619007e7e05 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -46,8 +46,6 @@ | |||
46 | 46 | ||
47 | extern void ctrl_alt_del(void); | 47 | extern void ctrl_alt_del(void); |
48 | 48 | ||
49 | #define to_handle_h(n) container_of(n, struct input_handle, h_node) | ||
50 | |||
51 | /* | 49 | /* |
52 | * Exported functions/variables | 50 | * Exported functions/variables |
53 | */ | 51 | */ |
@@ -132,6 +130,7 @@ int shift_state = 0; | |||
132 | */ | 130 | */ |
133 | 131 | ||
134 | static struct input_handler kbd_handler; | 132 | static struct input_handler kbd_handler; |
133 | static DEFINE_SPINLOCK(kbd_event_lock); | ||
135 | static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ | 134 | static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ |
136 | static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ | 135 | static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ |
137 | static int dead_key_next; | 136 | static int dead_key_next; |
@@ -190,78 +189,85 @@ EXPORT_SYMBOL_GPL(unregister_keyboard_notifier); | |||
190 | * etc.). So this means that scancodes for the extra function keys won't | 189 | * etc.). So this means that scancodes for the extra function keys won't |
191 | * be valid for the first event device, but will be for the second. | 190 | * be valid for the first event device, but will be for the second. |
192 | */ | 191 | */ |
192 | |||
193 | struct getset_keycode_data { | ||
194 | unsigned int scancode; | ||
195 | unsigned int keycode; | ||
196 | int error; | ||
197 | }; | ||
198 | |||
199 | static int getkeycode_helper(struct input_handle *handle, void *data) | ||
200 | { | ||
201 | struct getset_keycode_data *d = data; | ||
202 | |||
203 | d->error = input_get_keycode(handle->dev, d->scancode, &d->keycode); | ||
204 | |||
205 | return d->error == 0; /* stop as soon as we successfully get one */ | ||
206 | } | ||
207 | |||
193 | int getkeycode(unsigned int scancode) | 208 | int getkeycode(unsigned int scancode) |
194 | { | 209 | { |
195 | struct input_handle *handle; | 210 | struct getset_keycode_data d = { scancode, 0, -ENODEV }; |
196 | int keycode; | ||
197 | int error = -ENODEV; | ||
198 | 211 | ||
199 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { | 212 | input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper); |
200 | error = input_get_keycode(handle->dev, scancode, &keycode); | ||
201 | if (!error) | ||
202 | return keycode; | ||
203 | } | ||
204 | 213 | ||
205 | return error; | 214 | return d.error ?: d.keycode; |
215 | } | ||
216 | |||
217 | static int setkeycode_helper(struct input_handle *handle, void *data) | ||
218 | { | ||
219 | struct getset_keycode_data *d = data; | ||
220 | |||
221 | d->error = input_set_keycode(handle->dev, d->scancode, d->keycode); | ||
222 | |||
223 | return d->error == 0; /* stop as soon as we successfully set one */ | ||
206 | } | 224 | } |
207 | 225 | ||
208 | int setkeycode(unsigned int scancode, unsigned int keycode) | 226 | int setkeycode(unsigned int scancode, unsigned int keycode) |
209 | { | 227 | { |
210 | struct input_handle *handle; | 228 | struct getset_keycode_data d = { scancode, keycode, -ENODEV }; |
211 | int error = -ENODEV; | ||
212 | 229 | ||
213 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { | 230 | input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper); |
214 | error = input_set_keycode(handle->dev, scancode, keycode); | ||
215 | if (!error) | ||
216 | break; | ||
217 | } | ||
218 | 231 | ||
219 | return error; | 232 | return d.error; |
220 | } | 233 | } |
221 | 234 | ||
222 | /* | 235 | /* |
223 | * Making beeps and bells. | 236 | * Making beeps and bells. |
224 | */ | 237 | */ |
225 | static void kd_nosound(unsigned long ignored) | 238 | |
239 | static int kd_sound_helper(struct input_handle *handle, void *data) | ||
226 | { | 240 | { |
227 | struct input_handle *handle; | 241 | unsigned int *hz = data; |
242 | struct input_dev *dev = handle->dev; | ||
228 | 243 | ||
229 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { | 244 | if (test_bit(EV_SND, dev->evbit)) { |
230 | if (test_bit(EV_SND, handle->dev->evbit)) { | 245 | if (test_bit(SND_TONE, dev->sndbit)) |
231 | if (test_bit(SND_TONE, handle->dev->sndbit)) | 246 | input_inject_event(handle, EV_SND, SND_TONE, *hz); |
232 | input_inject_event(handle, EV_SND, SND_TONE, 0); | 247 | if (test_bit(SND_BELL, handle->dev->sndbit)) |
233 | if (test_bit(SND_BELL, handle->dev->sndbit)) | 248 | input_inject_event(handle, EV_SND, SND_BELL, *hz ? 1 : 0); |
234 | input_inject_event(handle, EV_SND, SND_BELL, 0); | ||
235 | } | ||
236 | } | 249 | } |
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | static void kd_nosound(unsigned long ignored) | ||
255 | { | ||
256 | static unsigned int zero; | ||
257 | |||
258 | input_handler_for_each_handle(&kbd_handler, &zero, kd_sound_helper); | ||
237 | } | 259 | } |
238 | 260 | ||
239 | static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0); | 261 | static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0); |
240 | 262 | ||
241 | void kd_mksound(unsigned int hz, unsigned int ticks) | 263 | void kd_mksound(unsigned int hz, unsigned int ticks) |
242 | { | 264 | { |
243 | struct list_head *node; | 265 | del_timer_sync(&kd_mksound_timer); |
244 | 266 | ||
245 | del_timer(&kd_mksound_timer); | 267 | input_handler_for_each_handle(&kbd_handler, &hz, kd_sound_helper); |
246 | 268 | ||
247 | if (hz) { | 269 | if (hz && ticks) |
248 | list_for_each_prev(node, &kbd_handler.h_list) { | 270 | mod_timer(&kd_mksound_timer, jiffies + ticks); |
249 | struct input_handle *handle = to_handle_h(node); | ||
250 | if (test_bit(EV_SND, handle->dev->evbit)) { | ||
251 | if (test_bit(SND_TONE, handle->dev->sndbit)) { | ||
252 | input_inject_event(handle, EV_SND, SND_TONE, hz); | ||
253 | break; | ||
254 | } | ||
255 | if (test_bit(SND_BELL, handle->dev->sndbit)) { | ||
256 | input_inject_event(handle, EV_SND, SND_BELL, 1); | ||
257 | break; | ||
258 | } | ||
259 | } | ||
260 | } | ||
261 | if (ticks) | ||
262 | mod_timer(&kd_mksound_timer, jiffies + ticks); | ||
263 | } else | ||
264 | kd_nosound(0); | ||
265 | } | 271 | } |
266 | EXPORT_SYMBOL(kd_mksound); | 272 | EXPORT_SYMBOL(kd_mksound); |
267 | 273 | ||
@@ -269,27 +275,34 @@ EXPORT_SYMBOL(kd_mksound); | |||
269 | * Setting the keyboard rate. | 275 | * Setting the keyboard rate. |
270 | */ | 276 | */ |
271 | 277 | ||
272 | int kbd_rate(struct kbd_repeat *rep) | 278 | static int kbd_rate_helper(struct input_handle *handle, void *data) |
273 | { | 279 | { |
274 | struct list_head *node; | 280 | struct input_dev *dev = handle->dev; |
275 | unsigned int d = 0; | 281 | struct kbd_repeat *rep = data; |
276 | unsigned int p = 0; | 282 | |
277 | 283 | if (test_bit(EV_REP, dev->evbit)) { | |
278 | list_for_each(node, &kbd_handler.h_list) { | 284 | |
279 | struct input_handle *handle = to_handle_h(node); | 285 | if (rep[0].delay > 0) |
280 | struct input_dev *dev = handle->dev; | 286 | input_inject_event(handle, |
281 | 287 | EV_REP, REP_DELAY, rep[0].delay); | |
282 | if (test_bit(EV_REP, dev->evbit)) { | 288 | if (rep[0].period > 0) |
283 | if (rep->delay > 0) | 289 | input_inject_event(handle, |
284 | input_inject_event(handle, EV_REP, REP_DELAY, rep->delay); | 290 | EV_REP, REP_PERIOD, rep[0].period); |
285 | if (rep->period > 0) | 291 | |
286 | input_inject_event(handle, EV_REP, REP_PERIOD, rep->period); | 292 | rep[1].delay = dev->rep[REP_DELAY]; |
287 | d = dev->rep[REP_DELAY]; | 293 | rep[1].period = dev->rep[REP_PERIOD]; |
288 | p = dev->rep[REP_PERIOD]; | ||
289 | } | ||
290 | } | 294 | } |
291 | rep->delay = d; | 295 | |
292 | rep->period = p; | 296 | return 0; |
297 | } | ||
298 | |||
299 | int kbd_rate(struct kbd_repeat *rep) | ||
300 | { | ||
301 | struct kbd_repeat data[2] = { *rep }; | ||
302 | |||
303 | input_handler_for_each_handle(&kbd_handler, data, kbd_rate_helper); | ||
304 | *rep = data[1]; /* Copy currently used settings */ | ||
305 | |||
293 | return 0; | 306 | return 0; |
294 | } | 307 | } |
295 | 308 | ||
@@ -997,36 +1010,36 @@ static inline unsigned char getleds(void) | |||
997 | return leds; | 1010 | return leds; |
998 | } | 1011 | } |
999 | 1012 | ||
1013 | static int kbd_update_leds_helper(struct input_handle *handle, void *data) | ||
1014 | { | ||
1015 | unsigned char leds = *(unsigned char *)data; | ||
1016 | |||
1017 | if (test_bit(EV_LED, handle->dev->evbit)) { | ||
1018 | input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | ||
1019 | input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02)); | ||
1020 | input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04)); | ||
1021 | input_inject_event(handle, EV_SYN, SYN_REPORT, 0); | ||
1022 | } | ||
1023 | |||
1024 | return 0; | ||
1025 | } | ||
1026 | |||
1000 | /* | 1027 | /* |
1001 | * This routine is the bottom half of the keyboard interrupt | 1028 | * This is the tasklet that updates LED state on all keyboards |
1002 | * routine, and runs with all interrupts enabled. It does | 1029 | * attached to the box. The reason we use tasklet is that we |
1003 | * console changing, led setting and copy_to_cooked, which can | 1030 | * need to handle the scenario when keyboard handler is not |
1004 | * take a reasonably long time. | 1031 | * registered yet but we already getting updates form VT to |
1005 | * | 1032 | * update led state. |
1006 | * Aside from timing (which isn't really that important for | ||
1007 | * keyboard interrupts as they happen often), using the software | ||
1008 | * interrupt routines for this thing allows us to easily mask | ||
1009 | * this when we don't want any of the above to happen. | ||
1010 | * This allows for easy and efficient race-condition prevention | ||
1011 | * for kbd_start => input_inject_event(dev, EV_LED, ...) => ... | ||
1012 | */ | 1033 | */ |
1013 | |||
1014 | static void kbd_bh(unsigned long dummy) | 1034 | static void kbd_bh(unsigned long dummy) |
1015 | { | 1035 | { |
1016 | struct list_head *node; | ||
1017 | unsigned char leds = getleds(); | 1036 | unsigned char leds = getleds(); |
1018 | 1037 | ||
1019 | if (leds != ledstate) { | 1038 | if (leds != ledstate) { |
1020 | list_for_each(node, &kbd_handler.h_list) { | 1039 | input_handler_for_each_handle(&kbd_handler, &leds, |
1021 | struct input_handle *handle = to_handle_h(node); | 1040 | kbd_update_leds_helper); |
1022 | input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | 1041 | ledstate = leds; |
1023 | input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02)); | ||
1024 | input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04)); | ||
1025 | input_inject_event(handle, EV_SYN, SYN_REPORT, 0); | ||
1026 | } | ||
1027 | } | 1042 | } |
1028 | |||
1029 | ledstate = leds; | ||
1030 | } | 1043 | } |
1031 | 1044 | ||
1032 | DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); | 1045 | DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); |
@@ -1136,7 +1149,7 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char u | |||
1136 | static void kbd_rawcode(unsigned char data) | 1149 | static void kbd_rawcode(unsigned char data) |
1137 | { | 1150 | { |
1138 | struct vc_data *vc = vc_cons[fg_console].d; | 1151 | struct vc_data *vc = vc_cons[fg_console].d; |
1139 | kbd = kbd_table + fg_console; | 1152 | kbd = kbd_table + vc->vc_num; |
1140 | if (kbd->kbdmode == VC_RAW) | 1153 | if (kbd->kbdmode == VC_RAW) |
1141 | put_queue(vc, data); | 1154 | put_queue(vc, data); |
1142 | } | 1155 | } |
@@ -1157,7 +1170,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) | |||
1157 | tty->driver_data = vc; | 1170 | tty->driver_data = vc; |
1158 | } | 1171 | } |
1159 | 1172 | ||
1160 | kbd = kbd_table + fg_console; | 1173 | kbd = kbd_table + vc->vc_num; |
1161 | 1174 | ||
1162 | if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT) | 1175 | if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT) |
1163 | sysrq_alt = down ? keycode : 0; | 1176 | sysrq_alt = down ? keycode : 0; |
@@ -1296,10 +1309,16 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) | |||
1296 | static void kbd_event(struct input_handle *handle, unsigned int event_type, | 1309 | static void kbd_event(struct input_handle *handle, unsigned int event_type, |
1297 | unsigned int event_code, int value) | 1310 | unsigned int event_code, int value) |
1298 | { | 1311 | { |
1312 | /* We are called with interrupts disabled, just take the lock */ | ||
1313 | spin_lock(&kbd_event_lock); | ||
1314 | |||
1299 | if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev)) | 1315 | if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev)) |
1300 | kbd_rawcode(value); | 1316 | kbd_rawcode(value); |
1301 | if (event_type == EV_KEY) | 1317 | if (event_type == EV_KEY) |
1302 | kbd_keycode(event_code, value, HW_RAW(handle->dev)); | 1318 | kbd_keycode(event_code, value, HW_RAW(handle->dev)); |
1319 | |||
1320 | spin_unlock(&kbd_event_lock); | ||
1321 | |||
1303 | tasklet_schedule(&keyboard_tasklet); | 1322 | tasklet_schedule(&keyboard_tasklet); |
1304 | do_poke_blanked_console = 1; | 1323 | do_poke_blanked_console = 1; |
1305 | schedule_console_callback(); | 1324 | schedule_console_callback(); |
@@ -1363,15 +1382,11 @@ static void kbd_disconnect(struct input_handle *handle) | |||
1363 | */ | 1382 | */ |
1364 | static void kbd_start(struct input_handle *handle) | 1383 | static void kbd_start(struct input_handle *handle) |
1365 | { | 1384 | { |
1366 | unsigned char leds = ledstate; | ||
1367 | |||
1368 | tasklet_disable(&keyboard_tasklet); | 1385 | tasklet_disable(&keyboard_tasklet); |
1369 | if (leds != 0xff) { | 1386 | |
1370 | input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | 1387 | if (ledstate != 0xff) |
1371 | input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02)); | 1388 | kbd_update_leds_helper(handle, &ledstate); |
1372 | input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04)); | 1389 | |
1373 | input_inject_event(handle, EV_SYN, SYN_REPORT, 0); | ||
1374 | } | ||
1375 | tasklet_enable(&keyboard_tasklet); | 1390 | tasklet_enable(&keyboard_tasklet); |
1376 | } | 1391 | } |
1377 | 1392 | ||
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 938100f14b16..3a2ccb09e2f8 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
@@ -429,7 +429,7 @@ static bool dmi_matches(const struct dmi_system_id *dmi) | |||
429 | for (i = 0; i < ARRAY_SIZE(dmi->matches); i++) { | 429 | for (i = 0; i < ARRAY_SIZE(dmi->matches); i++) { |
430 | int s = dmi->matches[i].slot; | 430 | int s = dmi->matches[i].slot; |
431 | if (s == DMI_NONE) | 431 | if (s == DMI_NONE) |
432 | continue; | 432 | break; |
433 | if (dmi_ident[s] | 433 | if (dmi_ident[s] |
434 | && strstr(dmi_ident[s], dmi->matches[i].substr)) | 434 | && strstr(dmi_ident[s], dmi->matches[i].substr)) |
435 | continue; | 435 | continue; |
@@ -440,6 +440,15 @@ static bool dmi_matches(const struct dmi_system_id *dmi) | |||
440 | } | 440 | } |
441 | 441 | ||
442 | /** | 442 | /** |
443 | * dmi_is_end_of_table - check for end-of-table marker | ||
444 | * @dmi: pointer to the dmi_system_id structure to check | ||
445 | */ | ||
446 | static bool dmi_is_end_of_table(const struct dmi_system_id *dmi) | ||
447 | { | ||
448 | return dmi->matches[0].slot == DMI_NONE; | ||
449 | } | ||
450 | |||
451 | /** | ||
443 | * dmi_check_system - check system DMI data | 452 | * dmi_check_system - check system DMI data |
444 | * @list: array of dmi_system_id structures to match against | 453 | * @list: array of dmi_system_id structures to match against |
445 | * All non-null elements of the list must match | 454 | * All non-null elements of the list must match |
@@ -457,7 +466,7 @@ int dmi_check_system(const struct dmi_system_id *list) | |||
457 | int count = 0; | 466 | int count = 0; |
458 | const struct dmi_system_id *d; | 467 | const struct dmi_system_id *d; |
459 | 468 | ||
460 | for (d = list; d->ident; d++) | 469 | for (d = list; !dmi_is_end_of_table(d); d++) |
461 | if (dmi_matches(d)) { | 470 | if (dmi_matches(d)) { |
462 | count++; | 471 | count++; |
463 | if (d->callback && d->callback(d)) | 472 | if (d->callback && d->callback(d)) |
@@ -484,7 +493,7 @@ const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list) | |||
484 | { | 493 | { |
485 | const struct dmi_system_id *d; | 494 | const struct dmi_system_id *d; |
486 | 495 | ||
487 | for (d = list; d->ident; d++) | 496 | for (d = list; !dmi_is_end_of_table(d); d++) |
488 | if (dmi_matches(d)) | 497 | if (dmi_matches(d)) |
489 | return d; | 498 | return d; |
490 | 499 | ||
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c index b342926dd7fc..f843443ba5c3 100644 --- a/drivers/hid/usbhid/usbkbd.c +++ b/drivers/hid/usbhid/usbkbd.c | |||
@@ -266,7 +266,7 @@ static int usb_kbd_probe(struct usb_interface *iface, | |||
266 | le16_to_cpu(dev->descriptor.idProduct)); | 266 | le16_to_cpu(dev->descriptor.idProduct)); |
267 | 267 | ||
268 | usb_make_path(dev, kbd->phys, sizeof(kbd->phys)); | 268 | usb_make_path(dev, kbd->phys, sizeof(kbd->phys)); |
269 | strlcpy(kbd->phys, "/input0", sizeof(kbd->phys)); | 269 | strlcat(kbd->phys, "/input0", sizeof(kbd->phys)); |
270 | 270 | ||
271 | input_dev->name = kbd->name; | 271 | input_dev->name = kbd->name; |
272 | input_dev->phys = kbd->phys; | 272 | input_dev->phys = kbd->phys; |
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index cd50c00ab20f..50af91ebd075 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig | |||
@@ -8,7 +8,7 @@ menu "Input device support" | |||
8 | config INPUT | 8 | config INPUT |
9 | tristate "Generic input layer (needed for keyboard, mouse, ...)" if EMBEDDED | 9 | tristate "Generic input layer (needed for keyboard, mouse, ...)" if EMBEDDED |
10 | default y | 10 | default y |
11 | ---help--- | 11 | help |
12 | Say Y here if you have any input device (mouse, keyboard, tablet, | 12 | Say Y here if you have any input device (mouse, keyboard, tablet, |
13 | joystick, steering wheel ...) connected to your system and want | 13 | joystick, steering wheel ...) connected to your system and want |
14 | it to be available to applications. This includes standard PS/2 | 14 | it to be available to applications. This includes standard PS/2 |
@@ -27,8 +27,7 @@ if INPUT | |||
27 | 27 | ||
28 | config INPUT_FF_MEMLESS | 28 | config INPUT_FF_MEMLESS |
29 | tristate "Support for memoryless force-feedback devices" | 29 | tristate "Support for memoryless force-feedback devices" |
30 | default n | 30 | help |
31 | ---help--- | ||
32 | Say Y here if you have memoryless force-feedback input device | 31 | Say Y here if you have memoryless force-feedback input device |
33 | such as Logitech WingMan Force 3D, ThrustMaster FireStorm Dual | 32 | such as Logitech WingMan Force 3D, ThrustMaster FireStorm Dual |
34 | Power 2, or similar. You will also need to enable hardware-specific | 33 | Power 2, or similar. You will also need to enable hardware-specific |
@@ -52,12 +51,25 @@ config INPUT_POLLDEV | |||
52 | To compile this driver as a module, choose M here: the | 51 | To compile this driver as a module, choose M here: the |
53 | module will be called input-polldev. | 52 | module will be called input-polldev. |
54 | 53 | ||
54 | config INPUT_SPARSEKMAP | ||
55 | tristate "Sparse keymap support library" | ||
56 | help | ||
57 | Say Y here if you are using a driver for an input | ||
58 | device that uses sparse keymap. This option is only | ||
59 | useful for out-of-tree drivers since in-tree drivers | ||
60 | select it automatically. | ||
61 | |||
62 | If unsure, say N. | ||
63 | |||
64 | To compile this driver as a module, choose M here: the | ||
65 | module will be called sparse-keymap. | ||
66 | |||
55 | comment "Userland interfaces" | 67 | comment "Userland interfaces" |
56 | 68 | ||
57 | config INPUT_MOUSEDEV | 69 | config INPUT_MOUSEDEV |
58 | tristate "Mouse interface" if EMBEDDED | 70 | tristate "Mouse interface" if EMBEDDED |
59 | default y | 71 | default y |
60 | ---help--- | 72 | help |
61 | Say Y here if you want your mouse to be accessible as char devices | 73 | Say Y here if you want your mouse to be accessible as char devices |
62 | 13:32+ - /dev/input/mouseX and 13:63 - /dev/input/mice as an | 74 | 13:32+ - /dev/input/mouseX and 13:63 - /dev/input/mice as an |
63 | emulated IntelliMouse Explorer PS/2 mouse. That way, all user space | 75 | emulated IntelliMouse Explorer PS/2 mouse. That way, all user space |
@@ -73,7 +85,7 @@ config INPUT_MOUSEDEV_PSAUX | |||
73 | bool "Provide legacy /dev/psaux device" | 85 | bool "Provide legacy /dev/psaux device" |
74 | default y | 86 | default y |
75 | depends on INPUT_MOUSEDEV | 87 | depends on INPUT_MOUSEDEV |
76 | ---help--- | 88 | help |
77 | Say Y here if you want your mouse also be accessible as char device | 89 | Say Y here if you want your mouse also be accessible as char device |
78 | 10:1 - /dev/psaux. The data available through /dev/psaux is exactly | 90 | 10:1 - /dev/psaux. The data available through /dev/psaux is exactly |
79 | the same as the data from /dev/input/mice. | 91 | the same as the data from /dev/input/mice. |
@@ -103,7 +115,7 @@ config INPUT_MOUSEDEV_SCREEN_Y | |||
103 | 115 | ||
104 | config INPUT_JOYDEV | 116 | config INPUT_JOYDEV |
105 | tristate "Joystick interface" | 117 | tristate "Joystick interface" |
106 | ---help--- | 118 | help |
107 | Say Y here if you want your joystick or gamepad to be | 119 | Say Y here if you want your joystick or gamepad to be |
108 | accessible as char device 13:0+ - /dev/input/jsX device. | 120 | accessible as char device 13:0+ - /dev/input/jsX device. |
109 | 121 | ||
@@ -125,7 +137,7 @@ config INPUT_EVDEV | |||
125 | 137 | ||
126 | config INPUT_EVBUG | 138 | config INPUT_EVBUG |
127 | tristate "Event debugging" | 139 | tristate "Event debugging" |
128 | ---help--- | 140 | help |
129 | Say Y here if you have a problem with the input subsystem and | 141 | Say Y here if you have a problem with the input subsystem and |
130 | want all events (keypresses, mouse movements), to be output to | 142 | want all events (keypresses, mouse movements), to be output to |
131 | the system log. While this is useful for debugging, it's also | 143 | the system log. While this is useful for debugging, it's also |
@@ -140,7 +152,7 @@ config INPUT_EVBUG | |||
140 | config INPUT_APMPOWER | 152 | config INPUT_APMPOWER |
141 | tristate "Input Power Event -> APM Bridge" if EMBEDDED | 153 | tristate "Input Power Event -> APM Bridge" if EMBEDDED |
142 | depends on INPUT && APM_EMULATION | 154 | depends on INPUT && APM_EMULATION |
143 | ---help--- | 155 | help |
144 | Say Y here if you want suspend key events to trigger a user | 156 | Say Y here if you want suspend key events to trigger a user |
145 | requested suspend through APM. This is useful on embedded | 157 | requested suspend through APM. This is useful on embedded |
146 | systems where such behaviour is desired without userspace | 158 | systems where such behaviour is desired without userspace |
diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 4c9c745a7020..7ad212d31f99 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile | |||
@@ -9,6 +9,7 @@ input-core-objs := input.o input-compat.o ff-core.o | |||
9 | 9 | ||
10 | obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o | 10 | obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o |
11 | obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o | 11 | obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o |
12 | obj-$(CONFIG_INPUT_SPARSEKMAP) += sparse-keymap.o | ||
12 | 13 | ||
13 | obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o | 14 | obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o |
14 | obj-$(CONFIG_INPUT_JOYDEV) += joydev.o | 15 | obj-$(CONFIG_INPUT_JOYDEV) += joydev.o |
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index 38df81fcdc3a..b2f07aa1604b 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c | |||
@@ -353,7 +353,7 @@ int input_ff_create(struct input_dev *dev, int max_effects) | |||
353 | EXPORT_SYMBOL_GPL(input_ff_create); | 353 | EXPORT_SYMBOL_GPL(input_ff_create); |
354 | 354 | ||
355 | /** | 355 | /** |
356 | * input_ff_free() - frees force feedback portion of input device | 356 | * input_ff_destroy() - frees force feedback portion of input device |
357 | * @dev: input device supporting force feedback | 357 | * @dev: input device supporting force feedback |
358 | * | 358 | * |
359 | * This function is only needed in error path as input core will | 359 | * This function is only needed in error path as input core will |
@@ -369,6 +369,7 @@ void input_ff_destroy(struct input_dev *dev) | |||
369 | if (ff->destroy) | 369 | if (ff->destroy) |
370 | ff->destroy(ff); | 370 | ff->destroy(ff); |
371 | kfree(ff->private); | 371 | kfree(ff->private); |
372 | kfree(ff->effects); | ||
372 | kfree(ff); | 373 | kfree(ff); |
373 | dev->ff = NULL; | 374 | dev->ff = NULL; |
374 | } | 375 | } |
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c index 0d3ce7a50fb1..aa6713b4a988 100644 --- a/drivers/input/input-polldev.c +++ b/drivers/input/input-polldev.c | |||
@@ -56,14 +56,10 @@ static void input_polldev_stop_workqueue(void) | |||
56 | mutex_unlock(&polldev_mutex); | 56 | mutex_unlock(&polldev_mutex); |
57 | } | 57 | } |
58 | 58 | ||
59 | static void input_polled_device_work(struct work_struct *work) | 59 | static void input_polldev_queue_work(struct input_polled_dev *dev) |
60 | { | 60 | { |
61 | struct input_polled_dev *dev = | ||
62 | container_of(work, struct input_polled_dev, work.work); | ||
63 | unsigned long delay; | 61 | unsigned long delay; |
64 | 62 | ||
65 | dev->poll(dev); | ||
66 | |||
67 | delay = msecs_to_jiffies(dev->poll_interval); | 63 | delay = msecs_to_jiffies(dev->poll_interval); |
68 | if (delay >= HZ) | 64 | if (delay >= HZ) |
69 | delay = round_jiffies_relative(delay); | 65 | delay = round_jiffies_relative(delay); |
@@ -71,6 +67,15 @@ static void input_polled_device_work(struct work_struct *work) | |||
71 | queue_delayed_work(polldev_wq, &dev->work, delay); | 67 | queue_delayed_work(polldev_wq, &dev->work, delay); |
72 | } | 68 | } |
73 | 69 | ||
70 | static void input_polled_device_work(struct work_struct *work) | ||
71 | { | ||
72 | struct input_polled_dev *dev = | ||
73 | container_of(work, struct input_polled_dev, work.work); | ||
74 | |||
75 | dev->poll(dev); | ||
76 | input_polldev_queue_work(dev); | ||
77 | } | ||
78 | |||
74 | static int input_open_polled_device(struct input_dev *input) | 79 | static int input_open_polled_device(struct input_dev *input) |
75 | { | 80 | { |
76 | struct input_polled_dev *dev = input_get_drvdata(input); | 81 | struct input_polled_dev *dev = input_get_drvdata(input); |
@@ -80,11 +85,12 @@ static int input_open_polled_device(struct input_dev *input) | |||
80 | if (error) | 85 | if (error) |
81 | return error; | 86 | return error; |
82 | 87 | ||
83 | if (dev->flush) | 88 | if (dev->open) |
84 | dev->flush(dev); | 89 | dev->open(dev); |
85 | 90 | ||
86 | queue_delayed_work(polldev_wq, &dev->work, | 91 | /* Only start polling if polling is enabled */ |
87 | msecs_to_jiffies(dev->poll_interval)); | 92 | if (dev->poll_interval > 0) |
93 | queue_delayed_work(polldev_wq, &dev->work, 0); | ||
88 | 94 | ||
89 | return 0; | 95 | return 0; |
90 | } | 96 | } |
@@ -95,8 +101,88 @@ static void input_close_polled_device(struct input_dev *input) | |||
95 | 101 | ||
96 | cancel_delayed_work_sync(&dev->work); | 102 | cancel_delayed_work_sync(&dev->work); |
97 | input_polldev_stop_workqueue(); | 103 | input_polldev_stop_workqueue(); |
104 | |||
105 | if (dev->close) | ||
106 | dev->close(dev); | ||
98 | } | 107 | } |
99 | 108 | ||
109 | /* SYSFS interface */ | ||
110 | |||
111 | static ssize_t input_polldev_get_poll(struct device *dev, | ||
112 | struct device_attribute *attr, char *buf) | ||
113 | { | ||
114 | struct input_polled_dev *polldev = dev_get_drvdata(dev); | ||
115 | |||
116 | return sprintf(buf, "%d\n", polldev->poll_interval); | ||
117 | } | ||
118 | |||
119 | static ssize_t input_polldev_set_poll(struct device *dev, | ||
120 | struct device_attribute *attr, const char *buf, | ||
121 | size_t count) | ||
122 | { | ||
123 | struct input_polled_dev *polldev = dev_get_drvdata(dev); | ||
124 | struct input_dev *input = polldev->input; | ||
125 | unsigned long interval; | ||
126 | |||
127 | if (strict_strtoul(buf, 0, &interval)) | ||
128 | return -EINVAL; | ||
129 | |||
130 | if (interval < polldev->poll_interval_min) | ||
131 | return -EINVAL; | ||
132 | |||
133 | if (interval > polldev->poll_interval_max) | ||
134 | return -EINVAL; | ||
135 | |||
136 | mutex_lock(&input->mutex); | ||
137 | |||
138 | polldev->poll_interval = interval; | ||
139 | |||
140 | if (input->users) { | ||
141 | cancel_delayed_work_sync(&polldev->work); | ||
142 | if (polldev->poll_interval > 0) | ||
143 | input_polldev_queue_work(polldev); | ||
144 | } | ||
145 | |||
146 | mutex_unlock(&input->mutex); | ||
147 | |||
148 | return count; | ||
149 | } | ||
150 | |||
151 | static DEVICE_ATTR(poll, S_IRUGO | S_IWUSR, input_polldev_get_poll, | ||
152 | input_polldev_set_poll); | ||
153 | |||
154 | |||
155 | static ssize_t input_polldev_get_max(struct device *dev, | ||
156 | struct device_attribute *attr, char *buf) | ||
157 | { | ||
158 | struct input_polled_dev *polldev = dev_get_drvdata(dev); | ||
159 | |||
160 | return sprintf(buf, "%d\n", polldev->poll_interval_max); | ||
161 | } | ||
162 | |||
163 | static DEVICE_ATTR(max, S_IRUGO, input_polldev_get_max, NULL); | ||
164 | |||
165 | static ssize_t input_polldev_get_min(struct device *dev, | ||
166 | struct device_attribute *attr, char *buf) | ||
167 | { | ||
168 | struct input_polled_dev *polldev = dev_get_drvdata(dev); | ||
169 | |||
170 | return sprintf(buf, "%d\n", polldev->poll_interval_min); | ||
171 | } | ||
172 | |||
173 | static DEVICE_ATTR(min, S_IRUGO, input_polldev_get_min, NULL); | ||
174 | |||
175 | static struct attribute *sysfs_attrs[] = { | ||
176 | &dev_attr_poll.attr, | ||
177 | &dev_attr_max.attr, | ||
178 | &dev_attr_min.attr, | ||
179 | NULL | ||
180 | }; | ||
181 | |||
182 | static struct attribute_group input_polldev_attribute_group = { | ||
183 | .attrs = sysfs_attrs | ||
184 | }; | ||
185 | |||
100 | /** | 186 | /** |
101 | * input_allocate_polled_device - allocated memory polled device | 187 | * input_allocate_polled_device - allocated memory polled device |
102 | * | 188 | * |
@@ -126,7 +212,7 @@ EXPORT_SYMBOL(input_allocate_polled_device); | |||
126 | * @dev: device to free | 212 | * @dev: device to free |
127 | * | 213 | * |
128 | * The function frees memory allocated for polling device and drops | 214 | * The function frees memory allocated for polling device and drops |
129 | * reference to the associated input device (if present). | 215 | * reference to the associated input device. |
130 | */ | 216 | */ |
131 | void input_free_polled_device(struct input_polled_dev *dev) | 217 | void input_free_polled_device(struct input_polled_dev *dev) |
132 | { | 218 | { |
@@ -150,15 +236,38 @@ EXPORT_SYMBOL(input_free_polled_device); | |||
150 | int input_register_polled_device(struct input_polled_dev *dev) | 236 | int input_register_polled_device(struct input_polled_dev *dev) |
151 | { | 237 | { |
152 | struct input_dev *input = dev->input; | 238 | struct input_dev *input = dev->input; |
239 | int error; | ||
153 | 240 | ||
154 | input_set_drvdata(input, dev); | 241 | input_set_drvdata(input, dev); |
155 | INIT_DELAYED_WORK(&dev->work, input_polled_device_work); | 242 | INIT_DELAYED_WORK(&dev->work, input_polled_device_work); |
156 | if (!dev->poll_interval) | 243 | if (!dev->poll_interval) |
157 | dev->poll_interval = 500; | 244 | dev->poll_interval = 500; |
245 | if (!dev->poll_interval_max) | ||
246 | dev->poll_interval_max = dev->poll_interval; | ||
158 | input->open = input_open_polled_device; | 247 | input->open = input_open_polled_device; |
159 | input->close = input_close_polled_device; | 248 | input->close = input_close_polled_device; |
160 | 249 | ||
161 | return input_register_device(input); | 250 | error = input_register_device(input); |
251 | if (error) | ||
252 | return error; | ||
253 | |||
254 | error = sysfs_create_group(&input->dev.kobj, | ||
255 | &input_polldev_attribute_group); | ||
256 | if (error) { | ||
257 | input_unregister_device(input); | ||
258 | return error; | ||
259 | } | ||
260 | |||
261 | /* | ||
262 | * Take extra reference to the underlying input device so | ||
263 | * that it survives call to input_unregister_polled_device() | ||
264 | * and is deleted only after input_free_polled_device() | ||
265 | * has been invoked. This is needed to ease task of freeing | ||
266 | * sparse keymaps. | ||
267 | */ | ||
268 | input_get_device(input); | ||
269 | |||
270 | return 0; | ||
162 | } | 271 | } |
163 | EXPORT_SYMBOL(input_register_polled_device); | 272 | EXPORT_SYMBOL(input_register_polled_device); |
164 | 273 | ||
@@ -169,13 +278,13 @@ EXPORT_SYMBOL(input_register_polled_device); | |||
169 | * The function unregisters previously registered polled input | 278 | * The function unregisters previously registered polled input |
170 | * device from input layer. Polling is stopped and device is | 279 | * device from input layer. Polling is stopped and device is |
171 | * ready to be freed with call to input_free_polled_device(). | 280 | * ready to be freed with call to input_free_polled_device(). |
172 | * Callers should not attempt to access dev->input pointer | ||
173 | * after calling this function. | ||
174 | */ | 281 | */ |
175 | void input_unregister_polled_device(struct input_polled_dev *dev) | 282 | void input_unregister_polled_device(struct input_polled_dev *dev) |
176 | { | 283 | { |
284 | sysfs_remove_group(&dev->input->dev.kobj, | ||
285 | &input_polldev_attribute_group); | ||
286 | |||
177 | input_unregister_device(dev->input); | 287 | input_unregister_device(dev->input); |
178 | dev->input = NULL; | ||
179 | } | 288 | } |
180 | EXPORT_SYMBOL(input_unregister_polled_device); | 289 | EXPORT_SYMBOL(input_unregister_polled_device); |
181 | 290 | ||
diff --git a/drivers/input/input.c b/drivers/input/input.c index 2266ecbfbc01..5c16001959cc 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -1658,6 +1658,38 @@ void input_unregister_handler(struct input_handler *handler) | |||
1658 | EXPORT_SYMBOL(input_unregister_handler); | 1658 | EXPORT_SYMBOL(input_unregister_handler); |
1659 | 1659 | ||
1660 | /** | 1660 | /** |
1661 | * input_handler_for_each_handle - handle iterator | ||
1662 | * @handler: input handler to iterate | ||
1663 | * @data: data for the callback | ||
1664 | * @fn: function to be called for each handle | ||
1665 | * | ||
1666 | * Iterate over @bus's list of devices, and call @fn for each, passing | ||
1667 | * it @data and stop when @fn returns a non-zero value. The function is | ||
1668 | * using RCU to traverse the list and therefore may be usind in atonic | ||
1669 | * contexts. The @fn callback is invoked from RCU critical section and | ||
1670 | * thus must not sleep. | ||
1671 | */ | ||
1672 | int input_handler_for_each_handle(struct input_handler *handler, void *data, | ||
1673 | int (*fn)(struct input_handle *, void *)) | ||
1674 | { | ||
1675 | struct input_handle *handle; | ||
1676 | int retval = 0; | ||
1677 | |||
1678 | rcu_read_lock(); | ||
1679 | |||
1680 | list_for_each_entry_rcu(handle, &handler->h_list, h_node) { | ||
1681 | retval = fn(handle, data); | ||
1682 | if (retval) | ||
1683 | break; | ||
1684 | } | ||
1685 | |||
1686 | rcu_read_unlock(); | ||
1687 | |||
1688 | return retval; | ||
1689 | } | ||
1690 | EXPORT_SYMBOL(input_handler_for_each_handle); | ||
1691 | |||
1692 | /** | ||
1661 | * input_register_handle - register a new input handle | 1693 | * input_register_handle - register a new input handle |
1662 | * @handle: handle to register | 1694 | * @handle: handle to register |
1663 | * | 1695 | * |
@@ -1690,7 +1722,7 @@ int input_register_handle(struct input_handle *handle) | |||
1690 | * we can't be racing with input_unregister_handle() | 1722 | * we can't be racing with input_unregister_handle() |
1691 | * and so separate lock is not needed here. | 1723 | * and so separate lock is not needed here. |
1692 | */ | 1724 | */ |
1693 | list_add_tail(&handle->h_node, &handler->h_list); | 1725 | list_add_tail_rcu(&handle->h_node, &handler->h_list); |
1694 | 1726 | ||
1695 | if (handler->start) | 1727 | if (handler->start) |
1696 | handler->start(handle); | 1728 | handler->start(handle); |
@@ -1713,7 +1745,7 @@ void input_unregister_handle(struct input_handle *handle) | |||
1713 | { | 1745 | { |
1714 | struct input_dev *dev = handle->dev; | 1746 | struct input_dev *dev = handle->dev; |
1715 | 1747 | ||
1716 | list_del_init(&handle->h_node); | 1748 | list_del_rcu(&handle->h_node); |
1717 | 1749 | ||
1718 | /* | 1750 | /* |
1719 | * Take dev->mutex to prevent race with input_release_device(). | 1751 | * Take dev->mutex to prevent race with input_release_device(). |
@@ -1721,6 +1753,7 @@ void input_unregister_handle(struct input_handle *handle) | |||
1721 | mutex_lock(&dev->mutex); | 1753 | mutex_lock(&dev->mutex); |
1722 | list_del_rcu(&handle->d_node); | 1754 | list_del_rcu(&handle->d_node); |
1723 | mutex_unlock(&dev->mutex); | 1755 | mutex_unlock(&dev->mutex); |
1756 | |||
1724 | synchronize_rcu(); | 1757 | synchronize_rcu(); |
1725 | } | 1758 | } |
1726 | EXPORT_SYMBOL(input_unregister_handle); | 1759 | EXPORT_SYMBOL(input_unregister_handle); |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 79e3edcced1a..482cb1204e43 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -125,6 +125,7 @@ static const struct xpad_device { | |||
125 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 125 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
126 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 126 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
127 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 127 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, |
128 | { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | ||
128 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 129 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
129 | { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 130 | { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
130 | { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 131 | { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
@@ -146,6 +147,7 @@ static const struct xpad_device { | |||
146 | { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 147 | { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, |
147 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 148 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, |
148 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, | 149 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, |
150 | { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | ||
149 | { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 151 | { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
150 | { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN } | 152 | { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN } |
151 | }; | 153 | }; |
@@ -212,6 +214,7 @@ static struct usb_device_id xpad_table [] = { | |||
212 | XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ | 214 | XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ |
213 | XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */ | 215 | XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */ |
214 | XPAD_XBOX360_VENDOR(0x1bad), /* Rock Band Drums */ | 216 | XPAD_XBOX360_VENDOR(0x1bad), /* Rock Band Drums */ |
217 | XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ | ||
215 | { } | 218 | { } |
216 | }; | 219 | }; |
217 | 220 | ||
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index ee98b1bc5d89..203b88a82b56 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -361,6 +361,16 @@ config KEYBOARD_SH_KEYSC | |||
361 | To compile this driver as a module, choose M here: the | 361 | To compile this driver as a module, choose M here: the |
362 | module will be called sh_keysc. | 362 | module will be called sh_keysc. |
363 | 363 | ||
364 | config KEYBOARD_DAVINCI | ||
365 | tristate "TI DaVinci Key Scan" | ||
366 | depends on ARCH_DAVINCI_DM365 | ||
367 | help | ||
368 | Say Y to enable keypad module support for the TI DaVinci | ||
369 | platforms (DM365). | ||
370 | |||
371 | To compile this driver as a module, choose M here: the | ||
372 | module will be called davinci_keyscan. | ||
373 | |||
364 | config KEYBOARD_OMAP | 374 | config KEYBOARD_OMAP |
365 | tristate "TI OMAP keypad support" | 375 | tristate "TI OMAP keypad support" |
366 | depends on (ARCH_OMAP1 || ARCH_OMAP2) | 376 | depends on (ARCH_OMAP1 || ARCH_OMAP2) |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index babad5e58b77..68c017235ce9 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -11,6 +11,7 @@ obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o | |||
11 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o | 11 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o |
12 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | 12 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o |
13 | obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o | 13 | obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o |
14 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o | ||
14 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o | 15 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o |
15 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | 16 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o |
16 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 17 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 28e6110d1ff8..a3573570c52f 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -1567,9 +1567,8 @@ static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id) | |||
1567 | return 0; | 1567 | return 0; |
1568 | } | 1568 | } |
1569 | 1569 | ||
1570 | static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | 1570 | static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = { |
1571 | { | 1571 | { |
1572 | .ident = "Dell Laptop", | ||
1573 | .matches = { | 1572 | .matches = { |
1574 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 1573 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
1575 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 1574 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ |
@@ -1578,7 +1577,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1578 | .driver_data = atkbd_dell_laptop_forced_release_keys, | 1577 | .driver_data = atkbd_dell_laptop_forced_release_keys, |
1579 | }, | 1578 | }, |
1580 | { | 1579 | { |
1581 | .ident = "Dell Laptop", | ||
1582 | .matches = { | 1580 | .matches = { |
1583 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), | 1581 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), |
1584 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 1582 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ |
@@ -1587,7 +1585,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1587 | .driver_data = atkbd_dell_laptop_forced_release_keys, | 1585 | .driver_data = atkbd_dell_laptop_forced_release_keys, |
1588 | }, | 1586 | }, |
1589 | { | 1587 | { |
1590 | .ident = "HP 2133", | ||
1591 | .matches = { | 1588 | .matches = { |
1592 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1589 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1593 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), | 1590 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), |
@@ -1596,7 +1593,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1596 | .driver_data = atkbd_hp_forced_release_keys, | 1593 | .driver_data = atkbd_hp_forced_release_keys, |
1597 | }, | 1594 | }, |
1598 | { | 1595 | { |
1599 | .ident = "HP Pavilion ZV6100", | ||
1600 | .matches = { | 1596 | .matches = { |
1601 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1597 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1602 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), | 1598 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), |
@@ -1605,7 +1601,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1605 | .driver_data = atkbd_volume_forced_release_keys, | 1601 | .driver_data = atkbd_volume_forced_release_keys, |
1606 | }, | 1602 | }, |
1607 | { | 1603 | { |
1608 | .ident = "HP Presario R4000", | ||
1609 | .matches = { | 1604 | .matches = { |
1610 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1605 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1611 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"), | 1606 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"), |
@@ -1614,7 +1609,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1614 | .driver_data = atkbd_volume_forced_release_keys, | 1609 | .driver_data = atkbd_volume_forced_release_keys, |
1615 | }, | 1610 | }, |
1616 | { | 1611 | { |
1617 | .ident = "HP Presario R4100", | ||
1618 | .matches = { | 1612 | .matches = { |
1619 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1613 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1620 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"), | 1614 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"), |
@@ -1623,7 +1617,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1623 | .driver_data = atkbd_volume_forced_release_keys, | 1617 | .driver_data = atkbd_volume_forced_release_keys, |
1624 | }, | 1618 | }, |
1625 | { | 1619 | { |
1626 | .ident = "HP Presario R4200", | ||
1627 | .matches = { | 1620 | .matches = { |
1628 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1621 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1629 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"), | 1622 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"), |
@@ -1632,7 +1625,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1632 | .driver_data = atkbd_volume_forced_release_keys, | 1625 | .driver_data = atkbd_volume_forced_release_keys, |
1633 | }, | 1626 | }, |
1634 | { | 1627 | { |
1635 | .ident = "Inventec Symphony", | 1628 | /* Inventec Symphony */ |
1636 | .matches = { | 1629 | .matches = { |
1637 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), | 1630 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), |
1638 | DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), | 1631 | DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), |
@@ -1641,7 +1634,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1641 | .driver_data = atkbd_volume_forced_release_keys, | 1634 | .driver_data = atkbd_volume_forced_release_keys, |
1642 | }, | 1635 | }, |
1643 | { | 1636 | { |
1644 | .ident = "Samsung NC10", | 1637 | /* Samsung NC10 */ |
1645 | .matches = { | 1638 | .matches = { |
1646 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 1639 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
1647 | DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), | 1640 | DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), |
@@ -1650,7 +1643,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1650 | .driver_data = atkbd_samsung_forced_release_keys, | 1643 | .driver_data = atkbd_samsung_forced_release_keys, |
1651 | }, | 1644 | }, |
1652 | { | 1645 | { |
1653 | .ident = "Samsung NC20", | 1646 | /* Samsung NC20 */ |
1654 | .matches = { | 1647 | .matches = { |
1655 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 1648 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
1656 | DMI_MATCH(DMI_PRODUCT_NAME, "NC20"), | 1649 | DMI_MATCH(DMI_PRODUCT_NAME, "NC20"), |
@@ -1659,7 +1652,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1659 | .driver_data = atkbd_samsung_forced_release_keys, | 1652 | .driver_data = atkbd_samsung_forced_release_keys, |
1660 | }, | 1653 | }, |
1661 | { | 1654 | { |
1662 | .ident = "Samsung SQ45S70S", | 1655 | /* Samsung SQ45S70S */ |
1663 | .matches = { | 1656 | .matches = { |
1664 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 1657 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
1665 | DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"), | 1658 | DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"), |
@@ -1668,7 +1661,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1668 | .driver_data = atkbd_samsung_forced_release_keys, | 1661 | .driver_data = atkbd_samsung_forced_release_keys, |
1669 | }, | 1662 | }, |
1670 | { | 1663 | { |
1671 | .ident = "Fujitsu Amilo PA 1510", | 1664 | /* Fujitsu Amilo PA 1510 */ |
1672 | .matches = { | 1665 | .matches = { |
1673 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1666 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
1674 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"), | 1667 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"), |
@@ -1677,7 +1670,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1677 | .driver_data = atkbd_volume_forced_release_keys, | 1670 | .driver_data = atkbd_volume_forced_release_keys, |
1678 | }, | 1671 | }, |
1679 | { | 1672 | { |
1680 | .ident = "Fujitsu Amilo Pi 3525", | 1673 | /* Fujitsu Amilo Pi 3525 */ |
1681 | .matches = { | 1674 | .matches = { |
1682 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1675 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
1683 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 3525"), | 1676 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 3525"), |
@@ -1686,7 +1679,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1686 | .driver_data = atkbd_amilo_pi3525_forced_release_keys, | 1679 | .driver_data = atkbd_amilo_pi3525_forced_release_keys, |
1687 | }, | 1680 | }, |
1688 | { | 1681 | { |
1689 | .ident = "Fujitsu Amilo Xi 3650", | 1682 | /* Fujitsu Amilo Xi 3650 */ |
1690 | .matches = { | 1683 | .matches = { |
1691 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1684 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
1692 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"), | 1685 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"), |
@@ -1695,7 +1688,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1695 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, | 1688 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, |
1696 | }, | 1689 | }, |
1697 | { | 1690 | { |
1698 | .ident = "Soltech Corporation TA12", | ||
1699 | .matches = { | 1691 | .matches = { |
1700 | DMI_MATCH(DMI_SYS_VENDOR, "Soltech Corporation"), | 1692 | DMI_MATCH(DMI_SYS_VENDOR, "Soltech Corporation"), |
1701 | DMI_MATCH(DMI_PRODUCT_NAME, "TA12"), | 1693 | DMI_MATCH(DMI_PRODUCT_NAME, "TA12"), |
@@ -1704,7 +1696,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1704 | .driver_data = atkdb_soltech_ta12_forced_release_keys, | 1696 | .driver_data = atkdb_soltech_ta12_forced_release_keys, |
1705 | }, | 1697 | }, |
1706 | { | 1698 | { |
1707 | .ident = "OQO Model 01+", | 1699 | /* OQO Model 01+ */ |
1708 | .matches = { | 1700 | .matches = { |
1709 | DMI_MATCH(DMI_SYS_VENDOR, "OQO"), | 1701 | DMI_MATCH(DMI_SYS_VENDOR, "OQO"), |
1710 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), | 1702 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), |
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c new file mode 100644 index 000000000000..6e52d855f637 --- /dev/null +++ b/drivers/input/keyboard/davinci_keyscan.c | |||
@@ -0,0 +1,337 @@ | |||
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 | |||
34 | #include <asm/irq.h> | ||
35 | |||
36 | #include <mach/hardware.h> | ||
37 | #include <mach/irqs.h> | ||
38 | #include <mach/keyscan.h> | ||
39 | |||
40 | /* Key scan registers */ | ||
41 | #define DAVINCI_KEYSCAN_KEYCTRL 0x0000 | ||
42 | #define DAVINCI_KEYSCAN_INTENA 0x0004 | ||
43 | #define DAVINCI_KEYSCAN_INTFLAG 0x0008 | ||
44 | #define DAVINCI_KEYSCAN_INTCLR 0x000c | ||
45 | #define DAVINCI_KEYSCAN_STRBWIDTH 0x0010 | ||
46 | #define DAVINCI_KEYSCAN_INTERVAL 0x0014 | ||
47 | #define DAVINCI_KEYSCAN_CONTTIME 0x0018 | ||
48 | #define DAVINCI_KEYSCAN_CURRENTST 0x001c | ||
49 | #define DAVINCI_KEYSCAN_PREVSTATE 0x0020 | ||
50 | #define DAVINCI_KEYSCAN_EMUCTRL 0x0024 | ||
51 | #define DAVINCI_KEYSCAN_IODFTCTRL 0x002c | ||
52 | |||
53 | /* Key Control Register (KEYCTRL) */ | ||
54 | #define DAVINCI_KEYSCAN_KEYEN 0x00000001 | ||
55 | #define DAVINCI_KEYSCAN_PREVMODE 0x00000002 | ||
56 | #define DAVINCI_KEYSCAN_CHATOFF 0x00000004 | ||
57 | #define DAVINCI_KEYSCAN_AUTODET 0x00000008 | ||
58 | #define DAVINCI_KEYSCAN_SCANMODE 0x00000010 | ||
59 | #define DAVINCI_KEYSCAN_OUTTYPE 0x00000020 | ||
60 | |||
61 | /* Masks for the interrupts */ | ||
62 | #define DAVINCI_KEYSCAN_INT_CONT 0x00000008 | ||
63 | #define DAVINCI_KEYSCAN_INT_OFF 0x00000004 | ||
64 | #define DAVINCI_KEYSCAN_INT_ON 0x00000002 | ||
65 | #define DAVINCI_KEYSCAN_INT_CHANGE 0x00000001 | ||
66 | #define DAVINCI_KEYSCAN_INT_ALL 0x0000000f | ||
67 | |||
68 | struct davinci_ks { | ||
69 | struct input_dev *input; | ||
70 | struct davinci_ks_platform_data *pdata; | ||
71 | int irq; | ||
72 | void __iomem *base; | ||
73 | resource_size_t pbase; | ||
74 | size_t base_size; | ||
75 | unsigned short keymap[]; | ||
76 | }; | ||
77 | |||
78 | /* Initializing the kp Module */ | ||
79 | static int __init davinci_ks_initialize(struct davinci_ks *davinci_ks) | ||
80 | { | ||
81 | struct device *dev = &davinci_ks->input->dev; | ||
82 | struct davinci_ks_platform_data *pdata = davinci_ks->pdata; | ||
83 | u32 matrix_ctrl; | ||
84 | |||
85 | /* Enable all interrupts */ | ||
86 | __raw_writel(DAVINCI_KEYSCAN_INT_ALL, | ||
87 | davinci_ks->base + DAVINCI_KEYSCAN_INTENA); | ||
88 | |||
89 | /* Clear interrupts if any */ | ||
90 | __raw_writel(DAVINCI_KEYSCAN_INT_ALL, | ||
91 | davinci_ks->base + DAVINCI_KEYSCAN_INTCLR); | ||
92 | |||
93 | /* Setup the scan period = strobe + interval */ | ||
94 | __raw_writel(pdata->strobe, | ||
95 | davinci_ks->base + DAVINCI_KEYSCAN_STRBWIDTH); | ||
96 | __raw_writel(pdata->interval, | ||
97 | davinci_ks->base + DAVINCI_KEYSCAN_INTERVAL); | ||
98 | __raw_writel(0x01, | ||
99 | davinci_ks->base + DAVINCI_KEYSCAN_CONTTIME); | ||
100 | |||
101 | /* Define matrix type */ | ||
102 | switch (pdata->matrix_type) { | ||
103 | case DAVINCI_KEYSCAN_MATRIX_4X4: | ||
104 | matrix_ctrl = 0; | ||
105 | break; | ||
106 | case DAVINCI_KEYSCAN_MATRIX_5X3: | ||
107 | matrix_ctrl = (1 << 6); | ||
108 | break; | ||
109 | default: | ||
110 | dev_err(dev->parent, "wrong matrix type\n"); | ||
111 | return -EINVAL; | ||
112 | } | ||
113 | |||
114 | /* Enable key scan module and set matrix type */ | ||
115 | __raw_writel(DAVINCI_KEYSCAN_AUTODET | DAVINCI_KEYSCAN_KEYEN | | ||
116 | matrix_ctrl, davinci_ks->base + DAVINCI_KEYSCAN_KEYCTRL); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static irqreturn_t davinci_ks_interrupt(int irq, void *dev_id) | ||
122 | { | ||
123 | struct davinci_ks *davinci_ks = dev_id; | ||
124 | struct device *dev = &davinci_ks->input->dev; | ||
125 | unsigned short *keymap = davinci_ks->keymap; | ||
126 | int keymapsize = davinci_ks->pdata->keymapsize; | ||
127 | u32 prev_status, new_status, changed; | ||
128 | bool release; | ||
129 | int keycode = KEY_UNKNOWN; | ||
130 | int i; | ||
131 | |||
132 | /* Disable interrupt */ | ||
133 | __raw_writel(0x0, davinci_ks->base + DAVINCI_KEYSCAN_INTENA); | ||
134 | |||
135 | /* Reading previous and new status of the key scan */ | ||
136 | prev_status = __raw_readl(davinci_ks->base + DAVINCI_KEYSCAN_PREVSTATE); | ||
137 | new_status = __raw_readl(davinci_ks->base + DAVINCI_KEYSCAN_CURRENTST); | ||
138 | |||
139 | changed = prev_status ^ new_status; | ||
140 | |||
141 | if (changed) { | ||
142 | /* | ||
143 | * It goes through all bits in 'changed' to ensure | ||
144 | * that no key changes are being missed | ||
145 | */ | ||
146 | for (i = 0 ; i < keymapsize; i++) { | ||
147 | if ((changed>>i) & 0x1) { | ||
148 | keycode = keymap[i]; | ||
149 | release = (new_status >> i) & 0x1; | ||
150 | dev_dbg(dev->parent, "key %d %s\n", keycode, | ||
151 | release ? "released" : "pressed"); | ||
152 | input_report_key(davinci_ks->input, keycode, | ||
153 | !release); | ||
154 | input_sync(davinci_ks->input); | ||
155 | } | ||
156 | } | ||
157 | /* Clearing interrupt */ | ||
158 | __raw_writel(DAVINCI_KEYSCAN_INT_ALL, | ||
159 | davinci_ks->base + DAVINCI_KEYSCAN_INTCLR); | ||
160 | } | ||
161 | |||
162 | /* Enable interrupts */ | ||
163 | __raw_writel(0x1, davinci_ks->base + DAVINCI_KEYSCAN_INTENA); | ||
164 | |||
165 | return IRQ_HANDLED; | ||
166 | } | ||
167 | |||
168 | static int __init davinci_ks_probe(struct platform_device *pdev) | ||
169 | { | ||
170 | struct davinci_ks *davinci_ks; | ||
171 | struct input_dev *key_dev; | ||
172 | struct resource *res, *mem; | ||
173 | struct device *dev = &pdev->dev; | ||
174 | struct davinci_ks_platform_data *pdata = pdev->dev.platform_data; | ||
175 | int error, i; | ||
176 | |||
177 | if (!pdata->keymap) { | ||
178 | dev_dbg(dev, "no keymap from pdata\n"); | ||
179 | return -EINVAL; | ||
180 | } | ||
181 | |||
182 | davinci_ks = kzalloc(sizeof(struct davinci_ks) + | ||
183 | sizeof(unsigned short) * pdata->keymapsize, GFP_KERNEL); | ||
184 | if (!davinci_ks) { | ||
185 | dev_dbg(dev, "could not allocate memory for private data\n"); | ||
186 | return -ENOMEM; | ||
187 | } | ||
188 | |||
189 | memcpy(davinci_ks->keymap, pdata->keymap, | ||
190 | sizeof(unsigned short) * pdata->keymapsize); | ||
191 | |||
192 | key_dev = input_allocate_device(); | ||
193 | if (!key_dev) { | ||
194 | dev_dbg(dev, "could not allocate input device\n"); | ||
195 | error = -ENOMEM; | ||
196 | goto fail1; | ||
197 | } | ||
198 | |||
199 | davinci_ks->input = key_dev; | ||
200 | |||
201 | davinci_ks->irq = platform_get_irq(pdev, 0); | ||
202 | if (davinci_ks->irq < 0) { | ||
203 | dev_err(dev, "no key scan irq\n"); | ||
204 | error = davinci_ks->irq; | ||
205 | goto fail2; | ||
206 | } | ||
207 | |||
208 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
209 | if (!res) { | ||
210 | dev_err(dev, "no mem resource\n"); | ||
211 | error = -EINVAL; | ||
212 | goto fail2; | ||
213 | } | ||
214 | |||
215 | davinci_ks->pbase = res->start; | ||
216 | davinci_ks->base_size = resource_size(res); | ||
217 | |||
218 | mem = request_mem_region(davinci_ks->pbase, davinci_ks->base_size, | ||
219 | pdev->name); | ||
220 | if (!mem) { | ||
221 | dev_err(dev, "key scan registers at %08x are not free\n", | ||
222 | davinci_ks->pbase); | ||
223 | error = -EBUSY; | ||
224 | goto fail2; | ||
225 | } | ||
226 | |||
227 | davinci_ks->base = ioremap(davinci_ks->pbase, davinci_ks->base_size); | ||
228 | if (!davinci_ks->base) { | ||
229 | dev_err(dev, "can't ioremap MEM resource.\n"); | ||
230 | error = -ENOMEM; | ||
231 | goto fail3; | ||
232 | } | ||
233 | |||
234 | /* Enable auto repeat feature of Linux input subsystem */ | ||
235 | if (pdata->rep) | ||
236 | __set_bit(EV_REP, key_dev->evbit); | ||
237 | |||
238 | /* Setup input device */ | ||
239 | __set_bit(EV_KEY, key_dev->evbit); | ||
240 | |||
241 | /* Setup the platform data */ | ||
242 | davinci_ks->pdata = pdata; | ||
243 | |||
244 | for (i = 0; i < davinci_ks->pdata->keymapsize; i++) | ||
245 | __set_bit(davinci_ks->pdata->keymap[i], key_dev->keybit); | ||
246 | |||
247 | key_dev->name = "davinci_keyscan"; | ||
248 | key_dev->phys = "davinci_keyscan/input0"; | ||
249 | key_dev->dev.parent = &pdev->dev; | ||
250 | key_dev->id.bustype = BUS_HOST; | ||
251 | key_dev->id.vendor = 0x0001; | ||
252 | key_dev->id.product = 0x0001; | ||
253 | key_dev->id.version = 0x0001; | ||
254 | key_dev->keycode = davinci_ks->keymap; | ||
255 | key_dev->keycodesize = sizeof(davinci_ks->keymap[0]); | ||
256 | key_dev->keycodemax = davinci_ks->pdata->keymapsize; | ||
257 | |||
258 | error = input_register_device(davinci_ks->input); | ||
259 | if (error < 0) { | ||
260 | dev_err(dev, "unable to register davinci key scan device\n"); | ||
261 | goto fail4; | ||
262 | } | ||
263 | |||
264 | error = request_irq(davinci_ks->irq, davinci_ks_interrupt, | ||
265 | IRQF_DISABLED, pdev->name, davinci_ks); | ||
266 | if (error < 0) { | ||
267 | dev_err(dev, "unable to register davinci key scan interrupt\n"); | ||
268 | goto fail5; | ||
269 | } | ||
270 | |||
271 | error = davinci_ks_initialize(davinci_ks); | ||
272 | if (error < 0) { | ||
273 | dev_err(dev, "unable to initialize davinci key scan device\n"); | ||
274 | goto fail6; | ||
275 | } | ||
276 | |||
277 | platform_set_drvdata(pdev, davinci_ks); | ||
278 | return 0; | ||
279 | |||
280 | fail6: | ||
281 | free_irq(davinci_ks->irq, davinci_ks); | ||
282 | fail5: | ||
283 | input_unregister_device(davinci_ks->input); | ||
284 | key_dev = NULL; | ||
285 | fail4: | ||
286 | iounmap(davinci_ks->base); | ||
287 | fail3: | ||
288 | release_mem_region(davinci_ks->pbase, davinci_ks->base_size); | ||
289 | fail2: | ||
290 | input_free_device(key_dev); | ||
291 | fail1: | ||
292 | kfree(davinci_ks); | ||
293 | |||
294 | return error; | ||
295 | } | ||
296 | |||
297 | static int __devexit davinci_ks_remove(struct platform_device *pdev) | ||
298 | { | ||
299 | struct davinci_ks *davinci_ks = platform_get_drvdata(pdev); | ||
300 | |||
301 | free_irq(davinci_ks->irq, davinci_ks); | ||
302 | |||
303 | input_unregister_device(davinci_ks->input); | ||
304 | |||
305 | iounmap(davinci_ks->base); | ||
306 | release_mem_region(davinci_ks->pbase, davinci_ks->base_size); | ||
307 | |||
308 | platform_set_drvdata(pdev, NULL); | ||
309 | |||
310 | kfree(davinci_ks); | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static struct platform_driver davinci_ks_driver = { | ||
316 | .driver = { | ||
317 | .name = "davinci_keyscan", | ||
318 | .owner = THIS_MODULE, | ||
319 | }, | ||
320 | .remove = __devexit_p(davinci_ks_remove), | ||
321 | }; | ||
322 | |||
323 | static int __init davinci_ks_init(void) | ||
324 | { | ||
325 | return platform_driver_probe(&davinci_ks_driver, davinci_ks_probe); | ||
326 | } | ||
327 | module_init(davinci_ks_init); | ||
328 | |||
329 | static void __exit davinci_ks_exit(void) | ||
330 | { | ||
331 | platform_driver_unregister(&davinci_ks_driver); | ||
332 | } | ||
333 | module_exit(davinci_ks_exit); | ||
334 | |||
335 | MODULE_AUTHOR("Miguel Aguilar"); | ||
336 | MODULE_DESCRIPTION("Texas Instruments DaVinci Key Scan Driver"); | ||
337 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 77d130914259..1aff3b76effd 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -23,8 +23,7 @@ | |||
23 | #include <linux/input.h> | 23 | #include <linux/input.h> |
24 | #include <linux/gpio_keys.h> | 24 | #include <linux/gpio_keys.h> |
25 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
26 | 26 | #include <linux/gpio.h> | |
27 | #include <asm/gpio.h> | ||
28 | 27 | ||
29 | struct gpio_button_data { | 28 | struct gpio_button_data { |
30 | struct gpio_keys_button *button; | 29 | struct gpio_keys_button *button; |
@@ -38,10 +37,8 @@ struct gpio_keys_drvdata { | |||
38 | struct gpio_button_data data[0]; | 37 | struct gpio_button_data data[0]; |
39 | }; | 38 | }; |
40 | 39 | ||
41 | static void gpio_keys_report_event(struct work_struct *work) | 40 | static void gpio_keys_report_event(struct gpio_button_data *bdata) |
42 | { | 41 | { |
43 | struct gpio_button_data *bdata = | ||
44 | container_of(work, struct gpio_button_data, work); | ||
45 | struct gpio_keys_button *button = bdata->button; | 42 | struct gpio_keys_button *button = bdata->button; |
46 | struct input_dev *input = bdata->input; | 43 | struct input_dev *input = bdata->input; |
47 | unsigned int type = button->type ?: EV_KEY; | 44 | unsigned int type = button->type ?: EV_KEY; |
@@ -51,6 +48,14 @@ static void gpio_keys_report_event(struct work_struct *work) | |||
51 | input_sync(input); | 48 | input_sync(input); |
52 | } | 49 | } |
53 | 50 | ||
51 | static void gpio_keys_work_func(struct work_struct *work) | ||
52 | { | ||
53 | struct gpio_button_data *bdata = | ||
54 | container_of(work, struct gpio_button_data, work); | ||
55 | |||
56 | gpio_keys_report_event(bdata); | ||
57 | } | ||
58 | |||
54 | static void gpio_keys_timer(unsigned long _data) | 59 | static void gpio_keys_timer(unsigned long _data) |
55 | { | 60 | { |
56 | struct gpio_button_data *data = (struct gpio_button_data *)_data; | 61 | struct gpio_button_data *data = (struct gpio_button_data *)_data; |
@@ -74,10 +79,62 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | |||
74 | return IRQ_HANDLED; | 79 | return IRQ_HANDLED; |
75 | } | 80 | } |
76 | 81 | ||
82 | static int __devinit gpio_keys_setup_key(struct device *dev, | ||
83 | struct gpio_button_data *bdata, | ||
84 | struct gpio_keys_button *button) | ||
85 | { | ||
86 | char *desc = button->desc ? button->desc : "gpio_keys"; | ||
87 | int irq, error; | ||
88 | |||
89 | setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata); | ||
90 | INIT_WORK(&bdata->work, gpio_keys_work_func); | ||
91 | |||
92 | error = gpio_request(button->gpio, desc); | ||
93 | if (error < 0) { | ||
94 | dev_err(dev, "failed to request GPIO %d, error %d\n", | ||
95 | button->gpio, error); | ||
96 | goto fail2; | ||
97 | } | ||
98 | |||
99 | error = gpio_direction_input(button->gpio); | ||
100 | if (error < 0) { | ||
101 | dev_err(dev, "failed to configure" | ||
102 | " direction for GPIO %d, error %d\n", | ||
103 | button->gpio, error); | ||
104 | goto fail3; | ||
105 | } | ||
106 | |||
107 | irq = gpio_to_irq(button->gpio); | ||
108 | if (irq < 0) { | ||
109 | error = irq; | ||
110 | dev_err(dev, "Unable to get irq number for GPIO %d, error %d\n", | ||
111 | button->gpio, error); | ||
112 | goto fail3; | ||
113 | } | ||
114 | |||
115 | error = request_irq(irq, gpio_keys_isr, | ||
116 | IRQF_SHARED | | ||
117 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
118 | desc, bdata); | ||
119 | if (error) { | ||
120 | dev_err(dev, "Unable to claim irq %d; error %d\n", | ||
121 | irq, error); | ||
122 | goto fail3; | ||
123 | } | ||
124 | |||
125 | return 0; | ||
126 | |||
127 | fail3: | ||
128 | gpio_free(button->gpio); | ||
129 | fail2: | ||
130 | return error; | ||
131 | } | ||
132 | |||
77 | static int __devinit gpio_keys_probe(struct platform_device *pdev) | 133 | static int __devinit gpio_keys_probe(struct platform_device *pdev) |
78 | { | 134 | { |
79 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 135 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
80 | struct gpio_keys_drvdata *ddata; | 136 | struct gpio_keys_drvdata *ddata; |
137 | struct device *dev = &pdev->dev; | ||
81 | struct input_dev *input; | 138 | struct input_dev *input; |
82 | int i, error; | 139 | int i, error; |
83 | int wakeup = 0; | 140 | int wakeup = 0; |
@@ -87,6 +144,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
87 | GFP_KERNEL); | 144 | GFP_KERNEL); |
88 | input = input_allocate_device(); | 145 | input = input_allocate_device(); |
89 | if (!ddata || !input) { | 146 | if (!ddata || !input) { |
147 | dev_err(dev, "failed to allocate state\n"); | ||
90 | error = -ENOMEM; | 148 | error = -ENOMEM; |
91 | goto fail1; | 149 | goto fail1; |
92 | } | 150 | } |
@@ -111,52 +169,14 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
111 | for (i = 0; i < pdata->nbuttons; i++) { | 169 | for (i = 0; i < pdata->nbuttons; i++) { |
112 | struct gpio_keys_button *button = &pdata->buttons[i]; | 170 | struct gpio_keys_button *button = &pdata->buttons[i]; |
113 | struct gpio_button_data *bdata = &ddata->data[i]; | 171 | struct gpio_button_data *bdata = &ddata->data[i]; |
114 | int irq; | ||
115 | unsigned int type = button->type ?: EV_KEY; | 172 | unsigned int type = button->type ?: EV_KEY; |
116 | 173 | ||
117 | bdata->input = input; | 174 | bdata->input = input; |
118 | bdata->button = button; | 175 | 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 | |||
130 | error = gpio_direction_input(button->gpio); | ||
131 | if (error < 0) { | ||
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; | ||
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 | 176 | ||
149 | error = request_irq(irq, gpio_keys_isr, | 177 | error = gpio_keys_setup_key(dev, bdata, button); |
150 | IRQF_SHARED | | 178 | if (error) |
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; | 179 | goto fail2; |
159 | } | ||
160 | 180 | ||
161 | if (button->wakeup) | 181 | if (button->wakeup) |
162 | wakeup = 1; | 182 | wakeup = 1; |
@@ -166,11 +186,16 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
166 | 186 | ||
167 | error = input_register_device(input); | 187 | error = input_register_device(input); |
168 | if (error) { | 188 | if (error) { |
169 | pr_err("gpio-keys: Unable to register input device, " | 189 | dev_err(dev, "Unable to register input device, " |
170 | "error: %d\n", error); | 190 | "error: %d\n", error); |
171 | goto fail2; | 191 | goto fail2; |
172 | } | 192 | } |
173 | 193 | ||
194 | /* get current state of buttons */ | ||
195 | for (i = 0; i < pdata->nbuttons; i++) | ||
196 | gpio_keys_report_event(&ddata->data[i]); | ||
197 | input_sync(input); | ||
198 | |||
174 | device_init_wakeup(&pdev->dev, wakeup); | 199 | device_init_wakeup(&pdev->dev, wakeup); |
175 | 200 | ||
176 | return 0; | 201 | return 0; |
@@ -239,18 +264,21 @@ static int gpio_keys_suspend(struct device *dev) | |||
239 | static int gpio_keys_resume(struct device *dev) | 264 | static int gpio_keys_resume(struct device *dev) |
240 | { | 265 | { |
241 | struct platform_device *pdev = to_platform_device(dev); | 266 | struct platform_device *pdev = to_platform_device(dev); |
267 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); | ||
242 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 268 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
243 | int i; | 269 | int i; |
244 | 270 | ||
245 | if (device_may_wakeup(&pdev->dev)) { | 271 | for (i = 0; i < pdata->nbuttons; i++) { |
246 | for (i = 0; i < pdata->nbuttons; i++) { | 272 | |
247 | struct gpio_keys_button *button = &pdata->buttons[i]; | 273 | struct gpio_keys_button *button = &pdata->buttons[i]; |
248 | if (button->wakeup) { | 274 | if (button->wakeup && device_may_wakeup(&pdev->dev)) { |
249 | int irq = gpio_to_irq(button->gpio); | 275 | int irq = gpio_to_irq(button->gpio); |
250 | disable_irq_wake(irq); | 276 | disable_irq_wake(irq); |
251 | } | ||
252 | } | 277 | } |
278 | |||
279 | gpio_keys_report_event(&ddata->data[i]); | ||
253 | } | 280 | } |
281 | input_sync(ddata->input); | ||
254 | 282 | ||
255 | return 0; | 283 | return 0; |
256 | } | 284 | } |
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/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 91cfe5170265..34f4a29d4973 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c | |||
@@ -213,8 +213,9 @@ static void matrix_keypad_stop(struct input_dev *dev) | |||
213 | } | 213 | } |
214 | 214 | ||
215 | #ifdef CONFIG_PM | 215 | #ifdef CONFIG_PM |
216 | static int matrix_keypad_suspend(struct platform_device *pdev, pm_message_t state) | 216 | static int matrix_keypad_suspend(struct device *dev) |
217 | { | 217 | { |
218 | struct platform_device *pdev = to_platform_device(dev); | ||
218 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | 219 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); |
219 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 220 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
220 | int i; | 221 | int i; |
@@ -228,8 +229,9 @@ static int matrix_keypad_suspend(struct platform_device *pdev, pm_message_t stat | |||
228 | return 0; | 229 | return 0; |
229 | } | 230 | } |
230 | 231 | ||
231 | static int matrix_keypad_resume(struct platform_device *pdev) | 232 | static int matrix_keypad_resume(struct device *dev) |
232 | { | 233 | { |
234 | struct platform_device *pdev = to_platform_device(dev); | ||
233 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | 235 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); |
234 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 236 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
235 | int i; | 237 | int i; |
@@ -242,9 +244,9 @@ static int matrix_keypad_resume(struct platform_device *pdev) | |||
242 | 244 | ||
243 | return 0; | 245 | return 0; |
244 | } | 246 | } |
245 | #else | 247 | |
246 | #define matrix_keypad_suspend NULL | 248 | static const SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops, |
247 | #define matrix_keypad_resume NULL | 249 | matrix_keypad_suspend, matrix_keypad_resume); |
248 | #endif | 250 | #endif |
249 | 251 | ||
250 | static int __devinit init_matrix_gpio(struct platform_device *pdev, | 252 | static int __devinit init_matrix_gpio(struct platform_device *pdev, |
@@ -417,11 +419,12 @@ static int __devexit matrix_keypad_remove(struct platform_device *pdev) | |||
417 | static struct platform_driver matrix_keypad_driver = { | 419 | static struct platform_driver matrix_keypad_driver = { |
418 | .probe = matrix_keypad_probe, | 420 | .probe = matrix_keypad_probe, |
419 | .remove = __devexit_p(matrix_keypad_remove), | 421 | .remove = __devexit_p(matrix_keypad_remove), |
420 | .suspend = matrix_keypad_suspend, | ||
421 | .resume = matrix_keypad_resume, | ||
422 | .driver = { | 422 | .driver = { |
423 | .name = "matrix-keypad", | 423 | .name = "matrix-keypad", |
424 | .owner = THIS_MODULE, | 424 | .owner = THIS_MODULE, |
425 | #ifdef CONFIG_PM | ||
426 | .pm = &matrix_keypad_pm_ops, | ||
427 | #endif | ||
425 | }, | 428 | }, |
426 | }; | 429 | }; |
427 | 430 | ||
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index a9bb2544b2de..16ec5233441c 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -80,6 +80,7 @@ config INPUT_WISTRON_BTNS | |||
80 | tristate "x86 Wistron laptop button interface" | 80 | tristate "x86 Wistron laptop button interface" |
81 | depends on X86 && !X86_64 | 81 | depends on X86 && !X86_64 |
82 | select INPUT_POLLDEV | 82 | select INPUT_POLLDEV |
83 | select INPUT_SPARSEKMAP | ||
83 | select NEW_LEDS | 84 | select NEW_LEDS |
84 | select LEDS_CLASS | 85 | select LEDS_CLASS |
85 | select CHECK_SIGNATURE | 86 | select CHECK_SIGNATURE |
@@ -281,6 +282,7 @@ config INPUT_RB532_BUTTON | |||
281 | config INPUT_DM355EVM | 282 | config INPUT_DM355EVM |
282 | tristate "TI DaVinci DM355 EVM Keypad and IR Remote" | 283 | tristate "TI DaVinci DM355 EVM Keypad and IR Remote" |
283 | depends on MFD_DM355EVM_MSP | 284 | depends on MFD_DM355EVM_MSP |
285 | select INPUT_SPARSEKMAP | ||
284 | help | 286 | help |
285 | Supports the pushbuttons and IR remote used with | 287 | Supports the pushbuttons and IR remote used with |
286 | the DM355 EVM board. | 288 | the DM355 EVM board. |
diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c index e290fde35e74..614b65d78fe9 100644 --- a/drivers/input/misc/ati_remote.c +++ b/drivers/input/misc/ati_remote.c | |||
@@ -766,7 +766,7 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de | |||
766 | ati_remote->interface = interface; | 766 | ati_remote->interface = interface; |
767 | 767 | ||
768 | usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys)); | 768 | usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys)); |
769 | strlcpy(ati_remote->phys, "/input0", sizeof(ati_remote->phys)); | 769 | strlcat(ati_remote->phys, "/input0", sizeof(ati_remote->phys)); |
770 | 770 | ||
771 | if (udev->manufacturer) | 771 | if (udev->manufacturer) |
772 | strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name)); | 772 | strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name)); |
diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c index f2b67dc81d80..766c06911f41 100644 --- a/drivers/input/misc/dm355evm_keys.c +++ b/drivers/input/misc/dm355evm_keys.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/input.h> | 13 | #include <linux/input.h> |
14 | #include <linux/input/sparse-keymap.h> | ||
14 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
15 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
16 | 17 | ||
@@ -33,12 +34,8 @@ struct dm355evm_keys { | |||
33 | int irq; | 34 | int irq; |
34 | }; | 35 | }; |
35 | 36 | ||
36 | /* These initial keycodes can be remapped by dm355evm_setkeycode(). */ | 37 | /* These initial keycodes can be remapped */ |
37 | static struct { | 38 | static const struct key_entry dm355evm_keys[] = { |
38 | u16 event; | ||
39 | u16 keycode; | ||
40 | } dm355evm_keys[] = { | ||
41 | |||
42 | /* | 39 | /* |
43 | * Pushbuttons on the EVM board ... note that the labels for these | 40 | * Pushbuttons on the EVM board ... note that the labels for these |
44 | * are SW10/SW11/etc on the PC board. The left/right orientation | 41 | * are SW10/SW11/etc on the PC board. The left/right orientation |
@@ -47,11 +44,11 @@ static struct { | |||
47 | * is to the right. (That is, rotate the board counter-clockwise | 44 | * is to the right. (That is, rotate the board counter-clockwise |
48 | * by 90 degrees from the SW10/etc and "DM355 EVM" labels.) | 45 | * by 90 degrees from the SW10/etc and "DM355 EVM" labels.) |
49 | */ | 46 | */ |
50 | { 0x00d8, KEY_OK, }, /* SW12 */ | 47 | { KE_KEY, 0x00d8, { KEY_OK } }, /* SW12 */ |
51 | { 0x00b8, KEY_UP, }, /* SW13 */ | 48 | { KE_KEY, 0x00b8, { KEY_UP } }, /* SW13 */ |
52 | { 0x00e8, KEY_DOWN, }, /* SW11 */ | 49 | { KE_KEY, 0x00e8, { KEY_DOWN } }, /* SW11 */ |
53 | { 0x0078, KEY_LEFT, }, /* SW14 */ | 50 | { KE_KEY, 0x0078, { KEY_LEFT } }, /* SW14 */ |
54 | { 0x00f0, KEY_RIGHT, }, /* SW10 */ | 51 | { KE_KEY, 0x00f0, { KEY_RIGHT } }, /* SW10 */ |
55 | 52 | ||
56 | /* | 53 | /* |
57 | * IR buttons ... codes assigned to match the universal remote | 54 | * IR buttons ... codes assigned to match the universal remote |
@@ -65,35 +62,35 @@ static struct { | |||
65 | * RC5 codes are 14 bits, with two start bits (0x3 prefix) | 62 | * RC5 codes are 14 bits, with two start bits (0x3 prefix) |
66 | * and a toggle bit (masked out below). | 63 | * and a toggle bit (masked out below). |
67 | */ | 64 | */ |
68 | { 0x300c, KEY_POWER, }, /* NOTE: docs omit this */ | 65 | { KE_KEY, 0x300c, { KEY_POWER } }, /* NOTE: docs omit this */ |
69 | { 0x3000, KEY_NUMERIC_0, }, | 66 | { KE_KEY, 0x3000, { KEY_NUMERIC_0 } }, |
70 | { 0x3001, KEY_NUMERIC_1, }, | 67 | { KE_KEY, 0x3001, { KEY_NUMERIC_1 } }, |
71 | { 0x3002, KEY_NUMERIC_2, }, | 68 | { KE_KEY, 0x3002, { KEY_NUMERIC_2 } }, |
72 | { 0x3003, KEY_NUMERIC_3, }, | 69 | { KE_KEY, 0x3003, { KEY_NUMERIC_3 } }, |
73 | { 0x3004, KEY_NUMERIC_4, }, | 70 | { KE_KEY, 0x3004, { KEY_NUMERIC_4 } }, |
74 | { 0x3005, KEY_NUMERIC_5, }, | 71 | { KE_KEY, 0x3005, { KEY_NUMERIC_5 } }, |
75 | { 0x3006, KEY_NUMERIC_6, }, | 72 | { KE_KEY, 0x3006, { KEY_NUMERIC_6 } }, |
76 | { 0x3007, KEY_NUMERIC_7, }, | 73 | { KE_KEY, 0x3007, { KEY_NUMERIC_7 } }, |
77 | { 0x3008, KEY_NUMERIC_8, }, | 74 | { KE_KEY, 0x3008, { KEY_NUMERIC_8 } }, |
78 | { 0x3009, KEY_NUMERIC_9, }, | 75 | { KE_KEY, 0x3009, { KEY_NUMERIC_9 } }, |
79 | { 0x3022, KEY_ENTER, }, | 76 | { KE_KEY, 0x3022, { KEY_ENTER } }, |
80 | { 0x30ec, KEY_MODE, }, /* "tv/vcr/..." */ | 77 | { KE_KEY, 0x30ec, { KEY_MODE } }, /* "tv/vcr/..." */ |
81 | { 0x300f, KEY_SELECT, }, /* "info" */ | 78 | { KE_KEY, 0x300f, { KEY_SELECT } }, /* "info" */ |
82 | { 0x3020, KEY_CHANNELUP, }, /* "up" */ | 79 | { KE_KEY, 0x3020, { KEY_CHANNELUP } }, /* "up" */ |
83 | { 0x302e, KEY_MENU, }, /* "in/out" */ | 80 | { KE_KEY, 0x302e, { KEY_MENU } }, /* "in/out" */ |
84 | { 0x3011, KEY_VOLUMEDOWN, }, /* "left" */ | 81 | { KE_KEY, 0x3011, { KEY_VOLUMEDOWN } }, /* "left" */ |
85 | { 0x300d, KEY_MUTE, }, /* "ok" */ | 82 | { KE_KEY, 0x300d, { KEY_MUTE } }, /* "ok" */ |
86 | { 0x3010, KEY_VOLUMEUP, }, /* "right" */ | 83 | { KE_KEY, 0x3010, { KEY_VOLUMEUP } }, /* "right" */ |
87 | { 0x301e, KEY_SUBTITLE, }, /* "cc" */ | 84 | { KE_KEY, 0x301e, { KEY_SUBTITLE } }, /* "cc" */ |
88 | { 0x3021, KEY_CHANNELDOWN, }, /* "down" */ | 85 | { KE_KEY, 0x3021, { KEY_CHANNELDOWN } },/* "down" */ |
89 | { 0x3022, KEY_PREVIOUS, }, | 86 | { KE_KEY, 0x3022, { KEY_PREVIOUS } }, |
90 | { 0x3026, KEY_SLEEP, }, | 87 | { KE_KEY, 0x3026, { KEY_SLEEP } }, |
91 | { 0x3172, KEY_REWIND, }, /* NOTE: docs wrongly say 0x30ca */ | 88 | { KE_KEY, 0x3172, { KEY_REWIND } }, /* NOTE: docs wrongly say 0x30ca */ |
92 | { 0x3175, KEY_PLAY, }, | 89 | { KE_KEY, 0x3175, { KEY_PLAY } }, |
93 | { 0x3174, KEY_FASTFORWARD, }, | 90 | { KE_KEY, 0x3174, { KEY_FASTFORWARD } }, |
94 | { 0x3177, KEY_RECORD, }, | 91 | { KE_KEY, 0x3177, { KEY_RECORD } }, |
95 | { 0x3176, KEY_STOP, }, | 92 | { KE_KEY, 0x3176, { KEY_STOP } }, |
96 | { 0x3169, KEY_PAUSE, }, | 93 | { KE_KEY, 0x3169, { KEY_PAUSE } }, |
97 | }; | 94 | }; |
98 | 95 | ||
99 | /* | 96 | /* |
@@ -105,19 +102,18 @@ static struct { | |||
105 | */ | 102 | */ |
106 | static irqreturn_t dm355evm_keys_irq(int irq, void *_keys) | 103 | static irqreturn_t dm355evm_keys_irq(int irq, void *_keys) |
107 | { | 104 | { |
108 | struct dm355evm_keys *keys = _keys; | 105 | static u16 last_event; |
109 | int status; | 106 | struct dm355evm_keys *keys = _keys; |
107 | const struct key_entry *ke; | ||
108 | unsigned int keycode; | ||
109 | int status; | ||
110 | u16 event; | ||
110 | 111 | ||
111 | /* For simplicity we ignore INPUT_COUNT and just read | 112 | /* For simplicity we ignore INPUT_COUNT and just read |
112 | * events until we get the "queue empty" indicator. | 113 | * events until we get the "queue empty" indicator. |
113 | * Reading INPUT_LOW decrements the count. | 114 | * Reading INPUT_LOW decrements the count. |
114 | */ | 115 | */ |
115 | for (;;) { | 116 | for (;;) { |
116 | static u16 last_event; | ||
117 | u16 event; | ||
118 | int keycode; | ||
119 | int i; | ||
120 | |||
121 | status = dm355evm_msp_read(DM355EVM_MSP_INPUT_HIGH); | 117 | status = dm355evm_msp_read(DM355EVM_MSP_INPUT_HIGH); |
122 | if (status < 0) { | 118 | if (status < 0) { |
123 | dev_dbg(keys->dev, "input high err %d\n", | 119 | dev_dbg(keys->dev, "input high err %d\n", |
@@ -156,14 +152,9 @@ static irqreturn_t dm355evm_keys_irq(int irq, void *_keys) | |||
156 | /* ignore the RC5 toggle bit */ | 152 | /* ignore the RC5 toggle bit */ |
157 | event &= ~0x0800; | 153 | event &= ~0x0800; |
158 | 154 | ||
159 | /* find the key, or leave it as unknown */ | 155 | /* find the key, or report it as unknown */ |
160 | keycode = KEY_UNKNOWN; | 156 | ke = sparse_keymap_entry_from_scancode(keys->input, event); |
161 | for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) { | 157 | keycode = ke ? ke->keycode : KEY_UNKNOWN; |
162 | if (dm355evm_keys[i].event != event) | ||
163 | continue; | ||
164 | keycode = dm355evm_keys[i].keycode; | ||
165 | break; | ||
166 | } | ||
167 | dev_dbg(keys->dev, | 158 | dev_dbg(keys->dev, |
168 | "input event 0x%04x--> keycode %d\n", | 159 | "input event 0x%04x--> keycode %d\n", |
169 | event, keycode); | 160 | event, keycode); |
@@ -174,36 +165,8 @@ static irqreturn_t dm355evm_keys_irq(int irq, void *_keys) | |||
174 | input_report_key(keys->input, keycode, 0); | 165 | input_report_key(keys->input, keycode, 0); |
175 | input_sync(keys->input); | 166 | input_sync(keys->input); |
176 | } | 167 | } |
177 | return IRQ_HANDLED; | ||
178 | } | ||
179 | 168 | ||
180 | static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode) | 169 | return IRQ_HANDLED; |
181 | { | ||
182 | u16 old_keycode; | ||
183 | unsigned i; | ||
184 | |||
185 | if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys)) | ||
186 | return -EINVAL; | ||
187 | |||
188 | old_keycode = dm355evm_keys[index].keycode; | ||
189 | dm355evm_keys[index].keycode = keycode; | ||
190 | set_bit(keycode, dev->keybit); | ||
191 | |||
192 | for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) { | ||
193 | if (dm355evm_keys[index].keycode == old_keycode) | ||
194 | goto done; | ||
195 | } | ||
196 | clear_bit(old_keycode, dev->keybit); | ||
197 | done: | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | static int dm355evm_getkeycode(struct input_dev *dev, int index, int *keycode) | ||
202 | { | ||
203 | if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys)) | ||
204 | return -EINVAL; | ||
205 | |||
206 | return dm355evm_keys[index].keycode; | ||
207 | } | 170 | } |
208 | 171 | ||
209 | /*----------------------------------------------------------------------*/ | 172 | /*----------------------------------------------------------------------*/ |
@@ -213,7 +176,6 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev) | |||
213 | struct dm355evm_keys *keys; | 176 | struct dm355evm_keys *keys; |
214 | struct input_dev *input; | 177 | struct input_dev *input; |
215 | int status; | 178 | int status; |
216 | int i; | ||
217 | 179 | ||
218 | /* allocate instance struct and input dev */ | 180 | /* allocate instance struct and input dev */ |
219 | keys = kzalloc(sizeof *keys, GFP_KERNEL); | 181 | keys = kzalloc(sizeof *keys, GFP_KERNEL); |
@@ -242,31 +204,30 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev) | |||
242 | input->id.product = 0x0355; | 204 | input->id.product = 0x0355; |
243 | input->id.version = dm355evm_msp_read(DM355EVM_MSP_FIRMREV); | 205 | input->id.version = dm355evm_msp_read(DM355EVM_MSP_FIRMREV); |
244 | 206 | ||
245 | input->evbit[0] = BIT(EV_KEY); | 207 | status = sparse_keymap_setup(input, dm355evm_keys, NULL); |
246 | for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) | 208 | if (status) |
247 | __set_bit(dm355evm_keys[i].keycode, input->keybit); | 209 | goto fail1; |
248 | |||
249 | input->setkeycode = dm355evm_setkeycode; | ||
250 | input->getkeycode = dm355evm_getkeycode; | ||
251 | 210 | ||
252 | /* REVISIT: flush the event queue? */ | 211 | /* REVISIT: flush the event queue? */ |
253 | 212 | ||
254 | status = request_threaded_irq(keys->irq, NULL, dm355evm_keys_irq, | 213 | status = request_threaded_irq(keys->irq, NULL, dm355evm_keys_irq, |
255 | IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), keys); | 214 | IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), keys); |
256 | if (status < 0) | 215 | if (status < 0) |
257 | goto fail1; | 216 | goto fail2; |
258 | 217 | ||
259 | /* register */ | 218 | /* register */ |
260 | status = input_register_device(input); | 219 | status = input_register_device(input); |
261 | if (status < 0) | 220 | if (status < 0) |
262 | goto fail2; | 221 | goto fail3; |
263 | 222 | ||
264 | platform_set_drvdata(pdev, keys); | 223 | platform_set_drvdata(pdev, keys); |
265 | 224 | ||
266 | return 0; | 225 | return 0; |
267 | 226 | ||
268 | fail2: | 227 | fail3: |
269 | free_irq(keys->irq, keys); | 228 | free_irq(keys->irq, keys); |
229 | fail2: | ||
230 | sparse_keymap_free(input); | ||
270 | fail1: | 231 | fail1: |
271 | input_free_device(input); | 232 | input_free_device(input); |
272 | kfree(keys); | 233 | kfree(keys); |
@@ -280,6 +241,7 @@ static int __devexit dm355evm_keys_remove(struct platform_device *pdev) | |||
280 | struct dm355evm_keys *keys = platform_get_drvdata(pdev); | 241 | struct dm355evm_keys *keys = platform_get_drvdata(pdev); |
281 | 242 | ||
282 | free_irq(keys->irq, keys); | 243 | free_irq(keys->irq, keys); |
244 | sparse_keymap_free(keys->input); | ||
283 | input_unregister_device(keys->input); | 245 | input_unregister_device(keys->input); |
284 | kfree(keys); | 246 | kfree(keys); |
285 | 247 | ||
diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c index a53c4885fbad..668913d12044 100644 --- a/drivers/input/misc/powermate.c +++ b/drivers/input/misc/powermate.c | |||
@@ -338,7 +338,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i | |||
338 | pm->input = input_dev; | 338 | pm->input = input_dev; |
339 | 339 | ||
340 | usb_make_path(udev, pm->phys, sizeof(pm->phys)); | 340 | usb_make_path(udev, pm->phys, sizeof(pm->phys)); |
341 | strlcpy(pm->phys, "/input0", sizeof(pm->phys)); | 341 | strlcat(pm->phys, "/input0", sizeof(pm->phys)); |
342 | 342 | ||
343 | spin_lock_init(&pm->lock); | 343 | spin_lock_init(&pm->lock); |
344 | 344 | ||
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index a932179c4c9e..38da6ab04384 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/dmi.h> | 21 | #include <linux/dmi.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/input-polldev.h> | 23 | #include <linux/input-polldev.h> |
24 | #include <linux/input/sparse-keymap.h> | ||
24 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
25 | #include <linux/jiffies.h> | 26 | #include <linux/jiffies.h> |
26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
@@ -224,19 +225,8 @@ static void bios_set_state(u8 subsys, int enable) | |||
224 | 225 | ||
225 | /* Hardware database */ | 226 | /* Hardware database */ |
226 | 227 | ||
227 | struct key_entry { | 228 | #define KE_WIFI (KE_LAST + 1) |
228 | char type; /* See KE_* below */ | 229 | #define KE_BLUETOOTH (KE_LAST + 2) |
229 | u8 code; | ||
230 | union { | ||
231 | u16 keycode; /* For KE_KEY */ | ||
232 | struct { /* For KE_SW */ | ||
233 | u8 code; | ||
234 | u8 value; | ||
235 | } sw; | ||
236 | }; | ||
237 | }; | ||
238 | |||
239 | enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH }; | ||
240 | 230 | ||
241 | #define FE_MAIL_LED 0x01 | 231 | #define FE_MAIL_LED 0x01 |
242 | #define FE_WIFI_LED 0x02 | 232 | #define FE_WIFI_LED 0x02 |
@@ -644,10 +634,10 @@ static struct key_entry keymap_prestigio[] __initdata = { | |||
644 | * a list of buttons and their key codes (reported when loading this module | 634 | * a list of buttons and their key codes (reported when loading this module |
645 | * with force=1) and the output of dmidecode to $MODULE_AUTHOR. | 635 | * with force=1) and the output of dmidecode to $MODULE_AUTHOR. |
646 | */ | 636 | */ |
647 | static struct dmi_system_id dmi_ids[] __initdata = { | 637 | static const struct dmi_system_id __initconst dmi_ids[] = { |
648 | { | 638 | { |
639 | /* Fujitsu-Siemens Amilo Pro V2000 */ | ||
649 | .callback = dmi_matched, | 640 | .callback = dmi_matched, |
650 | .ident = "Fujitsu-Siemens Amilo Pro V2000", | ||
651 | .matches = { | 641 | .matches = { |
652 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 642 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
653 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"), | 643 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"), |
@@ -655,8 +645,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
655 | .driver_data = keymap_fs_amilo_pro_v2000 | 645 | .driver_data = keymap_fs_amilo_pro_v2000 |
656 | }, | 646 | }, |
657 | { | 647 | { |
648 | /* Fujitsu-Siemens Amilo Pro Edition V3505 */ | ||
658 | .callback = dmi_matched, | 649 | .callback = dmi_matched, |
659 | .ident = "Fujitsu-Siemens Amilo Pro Edition V3505", | ||
660 | .matches = { | 650 | .matches = { |
661 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 651 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
662 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"), | 652 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"), |
@@ -664,8 +654,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
664 | .driver_data = keymap_fs_amilo_pro_v3505 | 654 | .driver_data = keymap_fs_amilo_pro_v3505 |
665 | }, | 655 | }, |
666 | { | 656 | { |
657 | /* Fujitsu-Siemens Amilo M7400 */ | ||
667 | .callback = dmi_matched, | 658 | .callback = dmi_matched, |
668 | .ident = "Fujitsu-Siemens Amilo M7400", | ||
669 | .matches = { | 659 | .matches = { |
670 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 660 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
671 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M "), | 661 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M "), |
@@ -673,8 +663,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
673 | .driver_data = keymap_fs_amilo_pro_v2000 | 663 | .driver_data = keymap_fs_amilo_pro_v2000 |
674 | }, | 664 | }, |
675 | { | 665 | { |
666 | /* Maxdata Pro 7000 DX */ | ||
676 | .callback = dmi_matched, | 667 | .callback = dmi_matched, |
677 | .ident = "Maxdata Pro 7000 DX", | ||
678 | .matches = { | 668 | .matches = { |
679 | DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"), | 669 | DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"), |
680 | DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"), | 670 | DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"), |
@@ -682,8 +672,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
682 | .driver_data = keymap_fs_amilo_pro_v2000 | 672 | .driver_data = keymap_fs_amilo_pro_v2000 |
683 | }, | 673 | }, |
684 | { | 674 | { |
675 | /* Fujitsu N3510 */ | ||
685 | .callback = dmi_matched, | 676 | .callback = dmi_matched, |
686 | .ident = "Fujitsu N3510", | ||
687 | .matches = { | 677 | .matches = { |
688 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 678 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
689 | DMI_MATCH(DMI_PRODUCT_NAME, "N3510"), | 679 | DMI_MATCH(DMI_PRODUCT_NAME, "N3510"), |
@@ -691,8 +681,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
691 | .driver_data = keymap_fujitsu_n3510 | 681 | .driver_data = keymap_fujitsu_n3510 |
692 | }, | 682 | }, |
693 | { | 683 | { |
684 | /* Acer Aspire 1500 */ | ||
694 | .callback = dmi_matched, | 685 | .callback = dmi_matched, |
695 | .ident = "Acer Aspire 1500", | ||
696 | .matches = { | 686 | .matches = { |
697 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 687 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
698 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"), | 688 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"), |
@@ -700,8 +690,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
700 | .driver_data = keymap_acer_aspire_1500 | 690 | .driver_data = keymap_acer_aspire_1500 |
701 | }, | 691 | }, |
702 | { | 692 | { |
693 | /* Acer Aspire 1600 */ | ||
703 | .callback = dmi_matched, | 694 | .callback = dmi_matched, |
704 | .ident = "Acer Aspire 1600", | ||
705 | .matches = { | 695 | .matches = { |
706 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 696 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
707 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"), | 697 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"), |
@@ -709,8 +699,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
709 | .driver_data = keymap_acer_aspire_1600 | 699 | .driver_data = keymap_acer_aspire_1600 |
710 | }, | 700 | }, |
711 | { | 701 | { |
702 | /* Acer Aspire 3020 */ | ||
712 | .callback = dmi_matched, | 703 | .callback = dmi_matched, |
713 | .ident = "Acer Aspire 3020", | ||
714 | .matches = { | 704 | .matches = { |
715 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 705 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
716 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"), | 706 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"), |
@@ -718,8 +708,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
718 | .driver_data = keymap_acer_aspire_5020 | 708 | .driver_data = keymap_acer_aspire_5020 |
719 | }, | 709 | }, |
720 | { | 710 | { |
711 | /* Acer Aspire 5020 */ | ||
721 | .callback = dmi_matched, | 712 | .callback = dmi_matched, |
722 | .ident = "Acer Aspire 5020", | ||
723 | .matches = { | 713 | .matches = { |
724 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 714 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
725 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"), | 715 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"), |
@@ -727,8 +717,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
727 | .driver_data = keymap_acer_aspire_5020 | 717 | .driver_data = keymap_acer_aspire_5020 |
728 | }, | 718 | }, |
729 | { | 719 | { |
720 | /* Acer TravelMate 2100 */ | ||
730 | .callback = dmi_matched, | 721 | .callback = dmi_matched, |
731 | .ident = "Acer TravelMate 2100", | ||
732 | .matches = { | 722 | .matches = { |
733 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 723 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
734 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"), | 724 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"), |
@@ -736,8 +726,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
736 | .driver_data = keymap_acer_aspire_5020 | 726 | .driver_data = keymap_acer_aspire_5020 |
737 | }, | 727 | }, |
738 | { | 728 | { |
729 | /* Acer TravelMate 2410 */ | ||
739 | .callback = dmi_matched, | 730 | .callback = dmi_matched, |
740 | .ident = "Acer TravelMate 2410", | ||
741 | .matches = { | 731 | .matches = { |
742 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 732 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
743 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"), | 733 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"), |
@@ -745,8 +735,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
745 | .driver_data = keymap_acer_travelmate_2410 | 735 | .driver_data = keymap_acer_travelmate_2410 |
746 | }, | 736 | }, |
747 | { | 737 | { |
738 | /* Acer TravelMate C300 */ | ||
748 | .callback = dmi_matched, | 739 | .callback = dmi_matched, |
749 | .ident = "Acer TravelMate C300", | ||
750 | .matches = { | 740 | .matches = { |
751 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 741 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
752 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"), | 742 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"), |
@@ -754,8 +744,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
754 | .driver_data = keymap_acer_travelmate_300 | 744 | .driver_data = keymap_acer_travelmate_300 |
755 | }, | 745 | }, |
756 | { | 746 | { |
747 | /* Acer TravelMate C100 */ | ||
757 | .callback = dmi_matched, | 748 | .callback = dmi_matched, |
758 | .ident = "Acer TravelMate C100", | ||
759 | .matches = { | 749 | .matches = { |
760 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 750 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
761 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"), | 751 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"), |
@@ -763,8 +753,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
763 | .driver_data = keymap_acer_travelmate_300 | 753 | .driver_data = keymap_acer_travelmate_300 |
764 | }, | 754 | }, |
765 | { | 755 | { |
756 | /* Acer TravelMate C110 */ | ||
766 | .callback = dmi_matched, | 757 | .callback = dmi_matched, |
767 | .ident = "Acer TravelMate C110", | ||
768 | .matches = { | 758 | .matches = { |
769 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 759 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
770 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"), | 760 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"), |
@@ -772,8 +762,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
772 | .driver_data = keymap_acer_travelmate_110 | 762 | .driver_data = keymap_acer_travelmate_110 |
773 | }, | 763 | }, |
774 | { | 764 | { |
765 | /* Acer TravelMate 380 */ | ||
775 | .callback = dmi_matched, | 766 | .callback = dmi_matched, |
776 | .ident = "Acer TravelMate 380", | ||
777 | .matches = { | 767 | .matches = { |
778 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 768 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
779 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"), | 769 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"), |
@@ -781,8 +771,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
781 | .driver_data = keymap_acer_travelmate_380 | 771 | .driver_data = keymap_acer_travelmate_380 |
782 | }, | 772 | }, |
783 | { | 773 | { |
774 | /* Acer TravelMate 370 */ | ||
784 | .callback = dmi_matched, | 775 | .callback = dmi_matched, |
785 | .ident = "Acer TravelMate 370", | ||
786 | .matches = { | 776 | .matches = { |
787 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 777 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
788 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"), | 778 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"), |
@@ -790,8 +780,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
790 | .driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */ | 780 | .driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */ |
791 | }, | 781 | }, |
792 | { | 782 | { |
783 | /* Acer TravelMate 220 */ | ||
793 | .callback = dmi_matched, | 784 | .callback = dmi_matched, |
794 | .ident = "Acer TravelMate 220", | ||
795 | .matches = { | 785 | .matches = { |
796 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 786 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
797 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"), | 787 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"), |
@@ -799,8 +789,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
799 | .driver_data = keymap_acer_travelmate_220 | 789 | .driver_data = keymap_acer_travelmate_220 |
800 | }, | 790 | }, |
801 | { | 791 | { |
792 | /* Acer TravelMate 260 */ | ||
802 | .callback = dmi_matched, | 793 | .callback = dmi_matched, |
803 | .ident = "Acer TravelMate 260", | ||
804 | .matches = { | 794 | .matches = { |
805 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 795 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
806 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"), | 796 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"), |
@@ -808,8 +798,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
808 | .driver_data = keymap_acer_travelmate_220 | 798 | .driver_data = keymap_acer_travelmate_220 |
809 | }, | 799 | }, |
810 | { | 800 | { |
801 | /* Acer TravelMate 230 */ | ||
811 | .callback = dmi_matched, | 802 | .callback = dmi_matched, |
812 | .ident = "Acer TravelMate 230", | ||
813 | .matches = { | 803 | .matches = { |
814 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 804 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
815 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"), | 805 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"), |
@@ -818,8 +808,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
818 | .driver_data = keymap_acer_travelmate_230 | 808 | .driver_data = keymap_acer_travelmate_230 |
819 | }, | 809 | }, |
820 | { | 810 | { |
811 | /* Acer TravelMate 280 */ | ||
821 | .callback = dmi_matched, | 812 | .callback = dmi_matched, |
822 | .ident = "Acer TravelMate 280", | ||
823 | .matches = { | 813 | .matches = { |
824 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 814 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
825 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"), | 815 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"), |
@@ -827,8 +817,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
827 | .driver_data = keymap_acer_travelmate_230 | 817 | .driver_data = keymap_acer_travelmate_230 |
828 | }, | 818 | }, |
829 | { | 819 | { |
820 | /* Acer TravelMate 240 */ | ||
830 | .callback = dmi_matched, | 821 | .callback = dmi_matched, |
831 | .ident = "Acer TravelMate 240", | ||
832 | .matches = { | 822 | .matches = { |
833 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 823 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
834 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"), | 824 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"), |
@@ -836,8 +826,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
836 | .driver_data = keymap_acer_travelmate_240 | 826 | .driver_data = keymap_acer_travelmate_240 |
837 | }, | 827 | }, |
838 | { | 828 | { |
829 | /* Acer TravelMate 250 */ | ||
839 | .callback = dmi_matched, | 830 | .callback = dmi_matched, |
840 | .ident = "Acer TravelMate 250", | ||
841 | .matches = { | 831 | .matches = { |
842 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 832 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
843 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"), | 833 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"), |
@@ -845,8 +835,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
845 | .driver_data = keymap_acer_travelmate_240 | 835 | .driver_data = keymap_acer_travelmate_240 |
846 | }, | 836 | }, |
847 | { | 837 | { |
838 | /* Acer TravelMate 2424NWXCi */ | ||
848 | .callback = dmi_matched, | 839 | .callback = dmi_matched, |
849 | .ident = "Acer TravelMate 2424NWXCi", | ||
850 | .matches = { | 840 | .matches = { |
851 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 841 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
852 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"), | 842 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"), |
@@ -854,8 +844,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
854 | .driver_data = keymap_acer_travelmate_240 | 844 | .driver_data = keymap_acer_travelmate_240 |
855 | }, | 845 | }, |
856 | { | 846 | { |
847 | /* Acer TravelMate 350 */ | ||
857 | .callback = dmi_matched, | 848 | .callback = dmi_matched, |
858 | .ident = "Acer TravelMate 350", | ||
859 | .matches = { | 849 | .matches = { |
860 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 850 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
861 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"), | 851 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"), |
@@ -863,8 +853,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
863 | .driver_data = keymap_acer_travelmate_350 | 853 | .driver_data = keymap_acer_travelmate_350 |
864 | }, | 854 | }, |
865 | { | 855 | { |
856 | /* Acer TravelMate 360 */ | ||
866 | .callback = dmi_matched, | 857 | .callback = dmi_matched, |
867 | .ident = "Acer TravelMate 360", | ||
868 | .matches = { | 858 | .matches = { |
869 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 859 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
870 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), | 860 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), |
@@ -872,8 +862,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
872 | .driver_data = keymap_acer_travelmate_360 | 862 | .driver_data = keymap_acer_travelmate_360 |
873 | }, | 863 | }, |
874 | { | 864 | { |
865 | /* Acer TravelMate 610 */ | ||
875 | .callback = dmi_matched, | 866 | .callback = dmi_matched, |
876 | .ident = "Acer TravelMate 610", | ||
877 | .matches = { | 867 | .matches = { |
878 | DMI_MATCH(DMI_SYS_VENDOR, "ACER"), | 868 | DMI_MATCH(DMI_SYS_VENDOR, "ACER"), |
879 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"), | 869 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"), |
@@ -881,8 +871,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
881 | .driver_data = keymap_acer_travelmate_610 | 871 | .driver_data = keymap_acer_travelmate_610 |
882 | }, | 872 | }, |
883 | { | 873 | { |
874 | /* Acer TravelMate 620 */ | ||
884 | .callback = dmi_matched, | 875 | .callback = dmi_matched, |
885 | .ident = "Acer TravelMate 620", | ||
886 | .matches = { | 876 | .matches = { |
887 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 877 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
888 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"), | 878 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"), |
@@ -890,8 +880,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
890 | .driver_data = keymap_acer_travelmate_630 | 880 | .driver_data = keymap_acer_travelmate_630 |
891 | }, | 881 | }, |
892 | { | 882 | { |
883 | /* Acer TravelMate 630 */ | ||
893 | .callback = dmi_matched, | 884 | .callback = dmi_matched, |
894 | .ident = "Acer TravelMate 630", | ||
895 | .matches = { | 885 | .matches = { |
896 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 886 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
897 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"), | 887 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"), |
@@ -899,8 +889,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
899 | .driver_data = keymap_acer_travelmate_630 | 889 | .driver_data = keymap_acer_travelmate_630 |
900 | }, | 890 | }, |
901 | { | 891 | { |
892 | /* AOpen 1559AS */ | ||
902 | .callback = dmi_matched, | 893 | .callback = dmi_matched, |
903 | .ident = "AOpen 1559AS", | ||
904 | .matches = { | 894 | .matches = { |
905 | DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), | 895 | DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), |
906 | DMI_MATCH(DMI_BOARD_NAME, "E2U"), | 896 | DMI_MATCH(DMI_BOARD_NAME, "E2U"), |
@@ -908,8 +898,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
908 | .driver_data = keymap_aopen_1559as | 898 | .driver_data = keymap_aopen_1559as |
909 | }, | 899 | }, |
910 | { | 900 | { |
901 | /* Medion MD 9783 */ | ||
911 | .callback = dmi_matched, | 902 | .callback = dmi_matched, |
912 | .ident = "Medion MD 9783", | ||
913 | .matches = { | 903 | .matches = { |
914 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), | 904 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), |
915 | DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"), | 905 | DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"), |
@@ -917,8 +907,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
917 | .driver_data = keymap_wistron_ms2111 | 907 | .driver_data = keymap_wistron_ms2111 |
918 | }, | 908 | }, |
919 | { | 909 | { |
910 | /* Medion MD 40100 */ | ||
920 | .callback = dmi_matched, | 911 | .callback = dmi_matched, |
921 | .ident = "Medion MD 40100", | ||
922 | .matches = { | 912 | .matches = { |
923 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), | 913 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), |
924 | DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"), | 914 | DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"), |
@@ -926,8 +916,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
926 | .driver_data = keymap_wistron_md40100 | 916 | .driver_data = keymap_wistron_md40100 |
927 | }, | 917 | }, |
928 | { | 918 | { |
919 | /* Medion MD 2900 */ | ||
929 | .callback = dmi_matched, | 920 | .callback = dmi_matched, |
930 | .ident = "Medion MD 2900", | ||
931 | .matches = { | 921 | .matches = { |
932 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), | 922 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), |
933 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"), | 923 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"), |
@@ -935,8 +925,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
935 | .driver_data = keymap_wistron_md2900 | 925 | .driver_data = keymap_wistron_md2900 |
936 | }, | 926 | }, |
937 | { | 927 | { |
928 | /* Medion MD 42200 */ | ||
938 | .callback = dmi_matched, | 929 | .callback = dmi_matched, |
939 | .ident = "Medion MD 42200", | ||
940 | .matches = { | 930 | .matches = { |
941 | DMI_MATCH(DMI_SYS_VENDOR, "Medion"), | 931 | DMI_MATCH(DMI_SYS_VENDOR, "Medion"), |
942 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2030"), | 932 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2030"), |
@@ -944,8 +934,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
944 | .driver_data = keymap_fs_amilo_pro_v2000 | 934 | .driver_data = keymap_fs_amilo_pro_v2000 |
945 | }, | 935 | }, |
946 | { | 936 | { |
937 | /* Medion MD 96500 */ | ||
947 | .callback = dmi_matched, | 938 | .callback = dmi_matched, |
948 | .ident = "Medion MD 96500", | ||
949 | .matches = { | 939 | .matches = { |
950 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), | 940 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), |
951 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"), | 941 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"), |
@@ -953,8 +943,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
953 | .driver_data = keymap_wistron_md96500 | 943 | .driver_data = keymap_wistron_md96500 |
954 | }, | 944 | }, |
955 | { | 945 | { |
946 | /* Medion MD 95400 */ | ||
956 | .callback = dmi_matched, | 947 | .callback = dmi_matched, |
957 | .ident = "Medion MD 95400", | ||
958 | .matches = { | 948 | .matches = { |
959 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), | 949 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), |
960 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"), | 950 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"), |
@@ -962,8 +952,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
962 | .driver_data = keymap_wistron_md96500 | 952 | .driver_data = keymap_wistron_md96500 |
963 | }, | 953 | }, |
964 | { | 954 | { |
955 | /* Fujitsu Siemens Amilo D7820 */ | ||
965 | .callback = dmi_matched, | 956 | .callback = dmi_matched, |
966 | .ident = "Fujitsu Siemens Amilo D7820", | ||
967 | .matches = { | 957 | .matches = { |
968 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */ | 958 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */ |
969 | DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"), | 959 | DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"), |
@@ -971,8 +961,8 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
971 | .driver_data = keymap_fs_amilo_d88x0 | 961 | .driver_data = keymap_fs_amilo_d88x0 |
972 | }, | 962 | }, |
973 | { | 963 | { |
964 | /* Fujitsu Siemens Amilo D88x0 */ | ||
974 | .callback = dmi_matched, | 965 | .callback = dmi_matched, |
975 | .ident = "Fujitsu Siemens Amilo D88x0", | ||
976 | .matches = { | 966 | .matches = { |
977 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 967 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
978 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"), | 968 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"), |
@@ -1037,21 +1027,6 @@ static unsigned long jiffies_last_press; | |||
1037 | static bool wifi_enabled; | 1027 | static bool wifi_enabled; |
1038 | static bool bluetooth_enabled; | 1028 | static bool bluetooth_enabled; |
1039 | 1029 | ||
1040 | static void report_key(struct input_dev *dev, unsigned int keycode) | ||
1041 | { | ||
1042 | input_report_key(dev, keycode, 1); | ||
1043 | input_sync(dev); | ||
1044 | input_report_key(dev, keycode, 0); | ||
1045 | input_sync(dev); | ||
1046 | } | ||
1047 | |||
1048 | static void report_switch(struct input_dev *dev, unsigned int code, int value) | ||
1049 | { | ||
1050 | input_report_switch(dev, code, value); | ||
1051 | input_sync(dev); | ||
1052 | } | ||
1053 | |||
1054 | |||
1055 | /* led management */ | 1030 | /* led management */ |
1056 | static void wistron_mail_led_set(struct led_classdev *led_cdev, | 1031 | static void wistron_mail_led_set(struct led_classdev *led_cdev, |
1057 | enum led_brightness value) | 1032 | enum led_brightness value) |
@@ -1128,43 +1103,13 @@ static inline void wistron_led_resume(void) | |||
1128 | led_classdev_resume(&wistron_wifi_led); | 1103 | led_classdev_resume(&wistron_wifi_led); |
1129 | } | 1104 | } |
1130 | 1105 | ||
1131 | static struct key_entry *wistron_get_entry_by_scancode(int code) | ||
1132 | { | ||
1133 | struct key_entry *key; | ||
1134 | |||
1135 | for (key = keymap; key->type != KE_END; key++) | ||
1136 | if (code == key->code) | ||
1137 | return key; | ||
1138 | |||
1139 | return NULL; | ||
1140 | } | ||
1141 | |||
1142 | static struct key_entry *wistron_get_entry_by_keycode(int keycode) | ||
1143 | { | ||
1144 | struct key_entry *key; | ||
1145 | |||
1146 | for (key = keymap; key->type != KE_END; key++) | ||
1147 | if (key->type == KE_KEY && keycode == key->keycode) | ||
1148 | return key; | ||
1149 | |||
1150 | return NULL; | ||
1151 | } | ||
1152 | |||
1153 | static void handle_key(u8 code) | 1106 | static void handle_key(u8 code) |
1154 | { | 1107 | { |
1155 | const struct key_entry *key = wistron_get_entry_by_scancode(code); | 1108 | const struct key_entry *key = |
1109 | sparse_keymap_entry_from_scancode(wistron_idev->input, code); | ||
1156 | 1110 | ||
1157 | if (key) { | 1111 | if (key) { |
1158 | switch (key->type) { | 1112 | switch (key->type) { |
1159 | case KE_KEY: | ||
1160 | report_key(wistron_idev->input, key->keycode); | ||
1161 | break; | ||
1162 | |||
1163 | case KE_SW: | ||
1164 | report_switch(wistron_idev->input, | ||
1165 | key->sw.code, key->sw.value); | ||
1166 | break; | ||
1167 | |||
1168 | case KE_WIFI: | 1113 | case KE_WIFI: |
1169 | if (have_wifi) { | 1114 | if (have_wifi) { |
1170 | wifi_enabled = !wifi_enabled; | 1115 | wifi_enabled = !wifi_enabled; |
@@ -1180,7 +1125,9 @@ static void handle_key(u8 code) | |||
1180 | break; | 1125 | break; |
1181 | 1126 | ||
1182 | default: | 1127 | default: |
1183 | BUG(); | 1128 | sparse_keymap_report_entry(wistron_idev->input, |
1129 | key, 1, true); | ||
1130 | break; | ||
1184 | } | 1131 | } |
1185 | jiffies_last_press = jiffies; | 1132 | jiffies_last_press = jiffies; |
1186 | } else | 1133 | } else |
@@ -1220,42 +1167,39 @@ static void wistron_poll(struct input_polled_dev *dev) | |||
1220 | dev->poll_interval = POLL_INTERVAL_DEFAULT; | 1167 | dev->poll_interval = POLL_INTERVAL_DEFAULT; |
1221 | } | 1168 | } |
1222 | 1169 | ||
1223 | static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode) | 1170 | static int __devinit wistron_setup_keymap(struct input_dev *dev, |
1171 | struct key_entry *entry) | ||
1224 | { | 1172 | { |
1225 | const struct key_entry *key = wistron_get_entry_by_scancode(scancode); | 1173 | switch (entry->type) { |
1226 | 1174 | ||
1227 | if (key && key->type == KE_KEY) { | 1175 | /* if wifi or bluetooth are not available, create normal keys */ |
1228 | *keycode = key->keycode; | 1176 | case KE_WIFI: |
1229 | return 0; | 1177 | if (!have_wifi) { |
1230 | } | 1178 | entry->type = KE_KEY; |
1231 | 1179 | entry->keycode = KEY_WLAN; | |
1232 | return -EINVAL; | 1180 | } |
1233 | } | 1181 | break; |
1234 | 1182 | ||
1235 | static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode) | 1183 | case KE_BLUETOOTH: |
1236 | { | 1184 | if (!have_bluetooth) { |
1237 | struct key_entry *key; | 1185 | entry->type = KE_KEY; |
1238 | int old_keycode; | 1186 | entry->keycode = KEY_BLUETOOTH; |
1239 | 1187 | } | |
1240 | if (keycode < 0 || keycode > KEY_MAX) | 1188 | break; |
1241 | return -EINVAL; | 1189 | |
1242 | 1190 | case KE_END: | |
1243 | key = wistron_get_entry_by_scancode(scancode); | 1191 | if (entry->code & FE_UNTESTED) |
1244 | if (key && key->type == KE_KEY) { | 1192 | printk(KERN_WARNING "Untested laptop multimedia keys, " |
1245 | old_keycode = key->keycode; | 1193 | "please report success or failure to " |
1246 | key->keycode = keycode; | 1194 | "eric.piel@tremplin-utc.net\n"); |
1247 | set_bit(keycode, dev->keybit); | 1195 | break; |
1248 | if (!wistron_get_entry_by_keycode(old_keycode)) | ||
1249 | clear_bit(old_keycode, dev->keybit); | ||
1250 | return 0; | ||
1251 | } | 1196 | } |
1252 | 1197 | ||
1253 | return -EINVAL; | 1198 | return 0; |
1254 | } | 1199 | } |
1255 | 1200 | ||
1256 | static int __devinit setup_input_dev(void) | 1201 | static int __devinit setup_input_dev(void) |
1257 | { | 1202 | { |
1258 | struct key_entry *key; | ||
1259 | struct input_dev *input_dev; | 1203 | struct input_dev *input_dev; |
1260 | int error; | 1204 | int error; |
1261 | 1205 | ||
@@ -1263,7 +1207,7 @@ static int __devinit setup_input_dev(void) | |||
1263 | if (!wistron_idev) | 1207 | if (!wistron_idev) |
1264 | return -ENOMEM; | 1208 | return -ENOMEM; |
1265 | 1209 | ||
1266 | wistron_idev->flush = wistron_flush; | 1210 | wistron_idev->open = wistron_flush; |
1267 | wistron_idev->poll = wistron_poll; | 1211 | wistron_idev->poll = wistron_poll; |
1268 | wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT; | 1212 | wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT; |
1269 | 1213 | ||
@@ -1273,56 +1217,21 @@ static int __devinit setup_input_dev(void) | |||
1273 | input_dev->id.bustype = BUS_HOST; | 1217 | input_dev->id.bustype = BUS_HOST; |
1274 | input_dev->dev.parent = &wistron_device->dev; | 1218 | input_dev->dev.parent = &wistron_device->dev; |
1275 | 1219 | ||
1276 | input_dev->getkeycode = wistron_getkeycode; | 1220 | error = sparse_keymap_setup(input_dev, keymap, wistron_setup_keymap); |
1277 | input_dev->setkeycode = wistron_setkeycode; | 1221 | if (error) |
1278 | 1222 | goto err_free_dev; | |
1279 | for (key = keymap; key->type != KE_END; key++) { | ||
1280 | switch (key->type) { | ||
1281 | case KE_KEY: | ||
1282 | set_bit(EV_KEY, input_dev->evbit); | ||
1283 | set_bit(key->keycode, input_dev->keybit); | ||
1284 | break; | ||
1285 | |||
1286 | case KE_SW: | ||
1287 | set_bit(EV_SW, input_dev->evbit); | ||
1288 | set_bit(key->sw.code, input_dev->swbit); | ||
1289 | break; | ||
1290 | |||
1291 | /* if wifi or bluetooth are not available, create normal keys */ | ||
1292 | case KE_WIFI: | ||
1293 | if (!have_wifi) { | ||
1294 | key->type = KE_KEY; | ||
1295 | key->keycode = KEY_WLAN; | ||
1296 | key--; | ||
1297 | } | ||
1298 | break; | ||
1299 | |||
1300 | case KE_BLUETOOTH: | ||
1301 | if (!have_bluetooth) { | ||
1302 | key->type = KE_KEY; | ||
1303 | key->keycode = KEY_BLUETOOTH; | ||
1304 | key--; | ||
1305 | } | ||
1306 | break; | ||
1307 | |||
1308 | default: | ||
1309 | break; | ||
1310 | } | ||
1311 | } | ||
1312 | |||
1313 | /* reads information flags on KE_END */ | ||
1314 | if (key->code & FE_UNTESTED) | ||
1315 | printk(KERN_WARNING "Untested laptop multimedia keys, " | ||
1316 | "please report success or failure to eric.piel" | ||
1317 | "@tremplin-utc.net\n"); | ||
1318 | 1223 | ||
1319 | error = input_register_polled_device(wistron_idev); | 1224 | error = input_register_polled_device(wistron_idev); |
1320 | if (error) { | 1225 | if (error) |
1321 | input_free_polled_device(wistron_idev); | 1226 | goto err_free_keymap; |
1322 | return error; | ||
1323 | } | ||
1324 | 1227 | ||
1325 | return 0; | 1228 | return 0; |
1229 | |||
1230 | err_free_keymap: | ||
1231 | sparse_keymap_free(input_dev); | ||
1232 | err_free_dev: | ||
1233 | input_free_polled_device(wistron_idev); | ||
1234 | return error; | ||
1326 | } | 1235 | } |
1327 | 1236 | ||
1328 | /* Driver core */ | 1237 | /* Driver core */ |
@@ -1371,6 +1280,7 @@ static int __devexit wistron_remove(struct platform_device *dev) | |||
1371 | { | 1280 | { |
1372 | wistron_led_remove(); | 1281 | wistron_led_remove(); |
1373 | input_unregister_polled_device(wistron_idev); | 1282 | input_unregister_polled_device(wistron_idev); |
1283 | sparse_keymap_free(wistron_idev->input); | ||
1374 | input_free_polled_device(wistron_idev); | 1284 | input_free_polled_device(wistron_idev); |
1375 | bios_detach(); | 1285 | bios_detach(); |
1376 | 1286 | ||
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index f36110689aae..a3f492a50850 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -28,13 +28,16 @@ | |||
28 | #define dbg(format, arg...) do {} while (0) | 28 | #define dbg(format, arg...) do {} while (0) |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | #define ALPS_DUALPOINT 0x01 | 31 | |
32 | #define ALPS_WHEEL 0x02 | 32 | #define ALPS_OLDPROTO 0x01 /* old style input */ |
33 | #define ALPS_FW_BK_1 0x04 | 33 | #define ALPS_DUALPOINT 0x02 /* touchpad has trackstick */ |
34 | #define ALPS_4BTN 0x08 | 34 | #define ALPS_PASS 0x04 /* device has a pass-through port */ |
35 | #define ALPS_OLDPROTO 0x10 | 35 | |
36 | #define ALPS_PASS 0x20 | 36 | #define ALPS_WHEEL 0x08 /* hardware wheel present */ |
37 | #define ALPS_FW_BK_2 0x40 | 37 | #define ALPS_FW_BK_1 0x10 /* front & back buttons present */ |
38 | #define ALPS_FW_BK_2 0x20 /* front & back buttons present */ | ||
39 | #define ALPS_FOUR_BUTTONS 0x40 /* 4 direction button present */ | ||
40 | |||
38 | 41 | ||
39 | static const struct alps_model_info alps_model_data[] = { | 42 | static const struct alps_model_info alps_model_data[] = { |
40 | { { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */ | 43 | { { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */ |
@@ -56,7 +59,7 @@ static const struct alps_model_info alps_model_data[] = { | |||
56 | { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, | 59 | { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, |
57 | { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ | 60 | { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ |
58 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */ | 61 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */ |
59 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 }, /* Dell Vostro 1400 */ | 62 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ |
60 | }; | 63 | }; |
61 | 64 | ||
62 | /* | 65 | /* |
@@ -83,6 +86,7 @@ static const struct alps_model_info alps_model_data[] = { | |||
83 | static void alps_process_packet(struct psmouse *psmouse) | 86 | static void alps_process_packet(struct psmouse *psmouse) |
84 | { | 87 | { |
85 | struct alps_data *priv = psmouse->private; | 88 | struct alps_data *priv = psmouse->private; |
89 | const struct alps_model_info *model = priv->i; | ||
86 | unsigned char *packet = psmouse->packet; | 90 | unsigned char *packet = psmouse->packet; |
87 | struct input_dev *dev = psmouse->dev; | 91 | struct input_dev *dev = psmouse->dev; |
88 | struct input_dev *dev2 = priv->dev2; | 92 | struct input_dev *dev2 = priv->dev2; |
@@ -101,7 +105,7 @@ static void alps_process_packet(struct psmouse *psmouse) | |||
101 | return; | 105 | return; |
102 | } | 106 | } |
103 | 107 | ||
104 | if (priv->i->flags & ALPS_OLDPROTO) { | 108 | if (model->flags & ALPS_OLDPROTO) { |
105 | left = packet[2] & 0x10; | 109 | left = packet[2] & 0x10; |
106 | right = packet[2] & 0x08; | 110 | right = packet[2] & 0x08; |
107 | middle = 0; | 111 | middle = 0; |
@@ -117,12 +121,12 @@ static void alps_process_packet(struct psmouse *psmouse) | |||
117 | z = packet[5]; | 121 | z = packet[5]; |
118 | } | 122 | } |
119 | 123 | ||
120 | if (priv->i->flags & ALPS_FW_BK_1) { | 124 | if (model->flags & ALPS_FW_BK_1) { |
121 | back = packet[0] & 0x10; | 125 | back = packet[0] & 0x10; |
122 | forward = packet[2] & 4; | 126 | forward = packet[2] & 4; |
123 | } | 127 | } |
124 | 128 | ||
125 | if (priv->i->flags & ALPS_FW_BK_2) { | 129 | if (model->flags & ALPS_FW_BK_2) { |
126 | back = packet[3] & 4; | 130 | back = packet[3] & 4; |
127 | forward = packet[2] & 4; | 131 | forward = packet[2] & 4; |
128 | if ((middle = forward && back)) | 132 | if ((middle = forward && back)) |
@@ -132,7 +136,7 @@ static void alps_process_packet(struct psmouse *psmouse) | |||
132 | ges = packet[2] & 1; | 136 | ges = packet[2] & 1; |
133 | fin = packet[2] & 2; | 137 | fin = packet[2] & 2; |
134 | 138 | ||
135 | if ((priv->i->flags & ALPS_DUALPOINT) && z == 127) { | 139 | if ((model->flags & ALPS_DUALPOINT) && z == 127) { |
136 | input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x)); | 140 | input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x)); |
137 | input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y)); | 141 | input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y)); |
138 | 142 | ||
@@ -150,7 +154,8 @@ static void alps_process_packet(struct psmouse *psmouse) | |||
150 | input_report_key(dev, BTN_MIDDLE, middle); | 154 | input_report_key(dev, BTN_MIDDLE, middle); |
151 | 155 | ||
152 | /* Convert hardware tap to a reasonable Z value */ | 156 | /* Convert hardware tap to a reasonable Z value */ |
153 | if (ges && !fin) z = 40; | 157 | if (ges && !fin) |
158 | z = 40; | ||
154 | 159 | ||
155 | /* | 160 | /* |
156 | * A "tap and drag" operation is reported by the hardware as a transition | 161 | * A "tap and drag" operation is reported by the hardware as a transition |
@@ -166,8 +171,10 @@ static void alps_process_packet(struct psmouse *psmouse) | |||
166 | } | 171 | } |
167 | priv->prev_fin = fin; | 172 | priv->prev_fin = fin; |
168 | 173 | ||
169 | if (z > 30) input_report_key(dev, BTN_TOUCH, 1); | 174 | if (z > 30) |
170 | if (z < 25) input_report_key(dev, BTN_TOUCH, 0); | 175 | input_report_key(dev, BTN_TOUCH, 1); |
176 | if (z < 25) | ||
177 | input_report_key(dev, BTN_TOUCH, 0); | ||
171 | 178 | ||
172 | if (z > 0) { | 179 | if (z > 0) { |
173 | input_report_abs(dev, ABS_X, x); | 180 | input_report_abs(dev, ABS_X, x); |
@@ -177,14 +184,21 @@ static void alps_process_packet(struct psmouse *psmouse) | |||
177 | input_report_abs(dev, ABS_PRESSURE, z); | 184 | input_report_abs(dev, ABS_PRESSURE, z); |
178 | input_report_key(dev, BTN_TOOL_FINGER, z > 0); | 185 | input_report_key(dev, BTN_TOOL_FINGER, z > 0); |
179 | 186 | ||
180 | if (priv->i->flags & ALPS_WHEEL) | 187 | if (model->flags & ALPS_WHEEL) |
181 | input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07)); | 188 | input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07)); |
182 | 189 | ||
183 | if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { | 190 | if (model->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { |
184 | input_report_key(dev, BTN_FORWARD, forward); | 191 | input_report_key(dev, BTN_FORWARD, forward); |
185 | input_report_key(dev, BTN_BACK, back); | 192 | input_report_key(dev, BTN_BACK, back); |
186 | } | 193 | } |
187 | 194 | ||
195 | if (model->flags & ALPS_FOUR_BUTTONS) { | ||
196 | input_report_key(dev, BTN_0, packet[2] & 4); | ||
197 | input_report_key(dev, BTN_1, packet[0] & 0x10); | ||
198 | input_report_key(dev, BTN_2, packet[3] & 4); | ||
199 | input_report_key(dev, BTN_3, packet[0] & 0x20); | ||
200 | } | ||
201 | |||
188 | input_sync(dev); | 202 | input_sync(dev); |
189 | } | 203 | } |
190 | 204 | ||
@@ -393,15 +407,12 @@ static int alps_poll(struct psmouse *psmouse) | |||
393 | return 0; | 407 | return 0; |
394 | } | 408 | } |
395 | 409 | ||
396 | static int alps_hw_init(struct psmouse *psmouse, int *version) | 410 | static int alps_hw_init(struct psmouse *psmouse) |
397 | { | 411 | { |
398 | struct alps_data *priv = psmouse->private; | 412 | struct alps_data *priv = psmouse->private; |
413 | const struct alps_model_info *model = priv->i; | ||
399 | 414 | ||
400 | priv->i = alps_get_model(psmouse, version); | 415 | if ((model->flags & ALPS_PASS) && |
401 | if (!priv->i) | ||
402 | return -1; | ||
403 | |||
404 | if ((priv->i->flags & ALPS_PASS) && | ||
405 | alps_passthrough_mode(psmouse, true)) { | 416 | alps_passthrough_mode(psmouse, true)) { |
406 | return -1; | 417 | return -1; |
407 | } | 418 | } |
@@ -416,7 +427,7 @@ static int alps_hw_init(struct psmouse *psmouse, int *version) | |||
416 | return -1; | 427 | return -1; |
417 | } | 428 | } |
418 | 429 | ||
419 | if ((priv->i->flags & ALPS_PASS) && | 430 | if ((model->flags & ALPS_PASS) && |
420 | alps_passthrough_mode(psmouse, false)) { | 431 | alps_passthrough_mode(psmouse, false)) { |
421 | return -1; | 432 | return -1; |
422 | } | 433 | } |
@@ -432,12 +443,15 @@ static int alps_hw_init(struct psmouse *psmouse, int *version) | |||
432 | 443 | ||
433 | static int alps_reconnect(struct psmouse *psmouse) | 444 | static int alps_reconnect(struct psmouse *psmouse) |
434 | { | 445 | { |
446 | const struct alps_model_info *model; | ||
447 | |||
435 | psmouse_reset(psmouse); | 448 | psmouse_reset(psmouse); |
436 | 449 | ||
437 | if (alps_hw_init(psmouse, NULL)) | 450 | model = alps_get_model(psmouse, NULL); |
451 | if (!model) | ||
438 | return -1; | 452 | return -1; |
439 | 453 | ||
440 | return 0; | 454 | return alps_hw_init(psmouse); |
441 | } | 455 | } |
442 | 456 | ||
443 | static void alps_disconnect(struct psmouse *psmouse) | 457 | static void alps_disconnect(struct psmouse *psmouse) |
@@ -452,6 +466,7 @@ static void alps_disconnect(struct psmouse *psmouse) | |||
452 | int alps_init(struct psmouse *psmouse) | 466 | int alps_init(struct psmouse *psmouse) |
453 | { | 467 | { |
454 | struct alps_data *priv; | 468 | struct alps_data *priv; |
469 | const struct alps_model_info *model; | ||
455 | struct input_dev *dev1 = psmouse->dev, *dev2; | 470 | struct input_dev *dev1 = psmouse->dev, *dev2; |
456 | int version; | 471 | int version; |
457 | 472 | ||
@@ -463,33 +478,48 @@ int alps_init(struct psmouse *psmouse) | |||
463 | priv->dev2 = dev2; | 478 | priv->dev2 = dev2; |
464 | psmouse->private = priv; | 479 | psmouse->private = priv; |
465 | 480 | ||
466 | if (alps_hw_init(psmouse, &version)) | 481 | model = alps_get_model(psmouse, &version); |
482 | if (!model) | ||
483 | goto init_fail; | ||
484 | |||
485 | priv->i = model; | ||
486 | |||
487 | if (alps_hw_init(psmouse)) | ||
467 | goto init_fail; | 488 | goto init_fail; |
468 | 489 | ||
469 | dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY); | 490 | dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY); |
470 | dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH); | 491 | dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH); |
471 | dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER); | 492 | dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER); |
472 | dev1->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | | 493 | dev1->keybit[BIT_WORD(BTN_LEFT)] |= |
473 | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); | 494 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); |
474 | 495 | ||
475 | dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); | 496 | dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); |
476 | input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0); | 497 | input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0); |
477 | input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0); | 498 | input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0); |
478 | input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0); | 499 | input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0); |
479 | 500 | ||
480 | if (priv->i->flags & ALPS_WHEEL) { | 501 | if (model->flags & ALPS_WHEEL) { |
481 | dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL); | 502 | dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL); |
482 | dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL); | 503 | dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL); |
483 | } | 504 | } |
484 | 505 | ||
485 | if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { | 506 | if (model->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { |
486 | dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD); | 507 | dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD); |
487 | dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK); | 508 | dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK); |
488 | } | 509 | } |
489 | 510 | ||
511 | if (model->flags & ALPS_FOUR_BUTTONS) { | ||
512 | dev1->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0); | ||
513 | dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1); | ||
514 | dev1->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2); | ||
515 | dev1->keybit[BIT_WORD(BTN_3)] |= BIT_MASK(BTN_3); | ||
516 | } else { | ||
517 | dev1->keybit[BIT_WORD(BTN_MIDDLE)] |= BIT_MASK(BTN_MIDDLE); | ||
518 | } | ||
519 | |||
490 | snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); | 520 | snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); |
491 | dev2->phys = priv->phys; | 521 | dev2->phys = priv->phys; |
492 | dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse"; | 522 | dev2->name = (model->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse"; |
493 | dev2->id.bustype = BUS_I8042; | 523 | dev2->id.bustype = BUS_I8042; |
494 | dev2->id.vendor = 0x0002; | 524 | dev2->id.vendor = 0x0002; |
495 | dev2->id.product = PSMOUSE_ALPS; | 525 | dev2->id.product = PSMOUSE_ALPS; |
@@ -497,9 +527,9 @@ int alps_init(struct psmouse *psmouse) | |||
497 | dev2->dev.parent = &psmouse->ps2dev.serio->dev; | 527 | dev2->dev.parent = &psmouse->ps2dev.serio->dev; |
498 | 528 | ||
499 | dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | 529 | dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); |
500 | dev2->relbit[BIT_WORD(REL_X)] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y); | 530 | dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); |
501 | dev2->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | | 531 | dev2->keybit[BIT_WORD(BTN_LEFT)] = |
502 | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); | 532 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); |
503 | 533 | ||
504 | if (input_register_device(priv->dev2)) | 534 | if (input_register_device(priv->dev2)) |
505 | goto init_fail; | 535 | goto init_fail; |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index fda35e615abf..b27684f267bf 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -420,6 +420,7 @@ static void elantech_set_input_params(struct psmouse *psmouse) | |||
420 | 420 | ||
421 | __set_bit(EV_KEY, dev->evbit); | 421 | __set_bit(EV_KEY, dev->evbit); |
422 | __set_bit(EV_ABS, dev->evbit); | 422 | __set_bit(EV_ABS, dev->evbit); |
423 | __clear_bit(EV_REL, dev->evbit); | ||
423 | 424 | ||
424 | __set_bit(BTN_LEFT, dev->keybit); | 425 | __set_bit(BTN_LEFT, dev->keybit); |
425 | __set_bit(BTN_RIGHT, dev->keybit); | 426 | __set_bit(BTN_RIGHT, dev->keybit); |
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index de1e553028b7..b146237266d8 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c | |||
@@ -430,19 +430,6 @@ static int hgpk_register(struct psmouse *psmouse) | |||
430 | struct input_dev *dev = psmouse->dev; | 430 | struct input_dev *dev = psmouse->dev; |
431 | int err; | 431 | int err; |
432 | 432 | ||
433 | /* unset the things that psmouse-base sets which we don't have */ | ||
434 | __clear_bit(BTN_MIDDLE, dev->keybit); | ||
435 | |||
436 | /* set the things we do have */ | ||
437 | __set_bit(EV_KEY, dev->evbit); | ||
438 | __set_bit(EV_REL, dev->evbit); | ||
439 | |||
440 | __set_bit(REL_X, dev->relbit); | ||
441 | __set_bit(REL_Y, dev->relbit); | ||
442 | |||
443 | __set_bit(BTN_LEFT, dev->keybit); | ||
444 | __set_bit(BTN_RIGHT, dev->keybit); | ||
445 | |||
446 | /* register handlers */ | 433 | /* register handlers */ |
447 | psmouse->protocol_handler = hgpk_process_byte; | 434 | psmouse->protocol_handler = hgpk_process_byte; |
448 | psmouse->poll = hgpk_poll; | 435 | psmouse->poll = hgpk_poll; |
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 82811558ec33..2e6bdfea0165 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
@@ -25,11 +25,13 @@ struct lifebook_data { | |||
25 | char phys[32]; | 25 | char phys[32]; |
26 | }; | 26 | }; |
27 | 27 | ||
28 | static bool lifebook_present; | ||
29 | |||
28 | static const char *desired_serio_phys; | 30 | static const char *desired_serio_phys; |
29 | 31 | ||
30 | static int lifebook_set_serio_phys(const struct dmi_system_id *d) | 32 | static int lifebook_limit_serio3(const struct dmi_system_id *d) |
31 | { | 33 | { |
32 | desired_serio_phys = d->driver_data; | 34 | desired_serio_phys = "isa0060/serio3"; |
33 | return 0; | 35 | return 0; |
34 | } | 36 | } |
35 | 37 | ||
@@ -41,53 +43,53 @@ static int lifebook_set_6byte_proto(const struct dmi_system_id *d) | |||
41 | return 0; | 43 | return 0; |
42 | } | 44 | } |
43 | 45 | ||
44 | static const struct dmi_system_id lifebook_dmi_table[] = { | 46 | static const struct dmi_system_id __initconst lifebook_dmi_table[] = { |
47 | #if defined(CONFIG_DMI) && defined(CONFIG_X86) | ||
45 | { | 48 | { |
46 | .ident = "FLORA-ie 55mi", | 49 | /* FLORA-ie 55mi */ |
47 | .matches = { | 50 | .matches = { |
48 | DMI_MATCH(DMI_PRODUCT_NAME, "FLORA-ie 55mi"), | 51 | DMI_MATCH(DMI_PRODUCT_NAME, "FLORA-ie 55mi"), |
49 | }, | 52 | }, |
50 | }, | 53 | }, |
51 | { | 54 | { |
52 | .ident = "LifeBook B", | 55 | /* LifeBook B */ |
53 | .matches = { | 56 | .matches = { |
54 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B Series"), | 57 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B Series"), |
55 | }, | 58 | }, |
56 | }, | 59 | }, |
57 | { | 60 | { |
58 | .ident = "Lifebook B", | 61 | /* Lifebook B */ |
59 | .matches = { | 62 | .matches = { |
60 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"), | 63 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"), |
61 | }, | 64 | }, |
62 | }, | 65 | }, |
63 | { | 66 | { |
64 | .ident = "Lifebook B-2130", | 67 | /* Lifebook B-2130 */ |
65 | .matches = { | 68 | .matches = { |
66 | DMI_MATCH(DMI_BOARD_NAME, "ZEPHYR"), | 69 | DMI_MATCH(DMI_BOARD_NAME, "ZEPHYR"), |
67 | }, | 70 | }, |
68 | }, | 71 | }, |
69 | { | 72 | { |
70 | .ident = "Lifebook B213x/B2150", | 73 | /* Lifebook B213x/B2150 */ |
71 | .matches = { | 74 | .matches = { |
72 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"), | 75 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"), |
73 | }, | 76 | }, |
74 | }, | 77 | }, |
75 | { | 78 | { |
76 | .ident = "Zephyr", | 79 | /* Zephyr */ |
77 | .matches = { | 80 | .matches = { |
78 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPHYR"), | 81 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPHYR"), |
79 | }, | 82 | }, |
80 | }, | 83 | }, |
81 | { | 84 | { |
82 | .ident = "CF-18", | 85 | /* Panasonic CF-18 */ |
83 | .matches = { | 86 | .matches = { |
84 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), | 87 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), |
85 | }, | 88 | }, |
86 | .callback = lifebook_set_serio_phys, | 89 | .callback = lifebook_limit_serio3, |
87 | .driver_data = "isa0060/serio3", | ||
88 | }, | 90 | }, |
89 | { | 91 | { |
90 | .ident = "Panasonic CF-28", | 92 | /* Panasonic CF-28 */ |
91 | .matches = { | 93 | .matches = { |
92 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), | 94 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), |
93 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-28"), | 95 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-28"), |
@@ -95,7 +97,7 @@ static const struct dmi_system_id lifebook_dmi_table[] = { | |||
95 | .callback = lifebook_set_6byte_proto, | 97 | .callback = lifebook_set_6byte_proto, |
96 | }, | 98 | }, |
97 | { | 99 | { |
98 | .ident = "Panasonic CF-29", | 100 | /* Panasonic CF-29 */ |
99 | .matches = { | 101 | .matches = { |
100 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), | 102 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), |
101 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), | 103 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), |
@@ -103,21 +105,27 @@ static const struct dmi_system_id lifebook_dmi_table[] = { | |||
103 | .callback = lifebook_set_6byte_proto, | 105 | .callback = lifebook_set_6byte_proto, |
104 | }, | 106 | }, |
105 | { | 107 | { |
106 | .ident = "CF-72", | 108 | /* Panasonic CF-72 */ |
107 | .matches = { | 109 | .matches = { |
108 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-72"), | 110 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-72"), |
109 | }, | 111 | }, |
110 | .callback = lifebook_set_6byte_proto, | 112 | .callback = lifebook_set_6byte_proto, |
111 | }, | 113 | }, |
112 | { | 114 | { |
113 | .ident = "Lifebook B142", | 115 | /* Lifebook B142 */ |
114 | .matches = { | 116 | .matches = { |
115 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"), | 117 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"), |
116 | }, | 118 | }, |
117 | }, | 119 | }, |
118 | { } | 120 | { } |
121 | #endif | ||
119 | }; | 122 | }; |
120 | 123 | ||
124 | void __init lifebook_module_init(void) | ||
125 | { | ||
126 | lifebook_present = dmi_check_system(lifebook_dmi_table); | ||
127 | } | ||
128 | |||
121 | static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) | 129 | static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) |
122 | { | 130 | { |
123 | struct lifebook_data *priv = psmouse->private; | 131 | struct lifebook_data *priv = psmouse->private; |
@@ -198,10 +206,10 @@ static int lifebook_absolute_mode(struct psmouse *psmouse) | |||
198 | return -1; | 206 | return -1; |
199 | 207 | ||
200 | /* | 208 | /* |
201 | Enable absolute output -- ps2_command fails always but if | 209 | * Enable absolute output -- ps2_command fails always but if |
202 | you leave this call out the touchsreen will never send | 210 | * you leave this call out the touchsreen will never send |
203 | absolute coordinates | 211 | * absolute coordinates |
204 | */ | 212 | */ |
205 | param = lifebook_use_6byte_proto ? 0x08 : 0x07; | 213 | param = lifebook_use_6byte_proto ? 0x08 : 0x07; |
206 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); | 214 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); |
207 | 215 | ||
@@ -243,7 +251,7 @@ static void lifebook_disconnect(struct psmouse *psmouse) | |||
243 | 251 | ||
244 | int lifebook_detect(struct psmouse *psmouse, bool set_properties) | 252 | int lifebook_detect(struct psmouse *psmouse, bool set_properties) |
245 | { | 253 | { |
246 | if (!dmi_check_system(lifebook_dmi_table)) | 254 | if (!lifebook_present) |
247 | return -1; | 255 | return -1; |
248 | 256 | ||
249 | if (desired_serio_phys && | 257 | if (desired_serio_phys && |
@@ -283,8 +291,8 @@ static int lifebook_create_relative_device(struct psmouse *psmouse) | |||
283 | 291 | ||
284 | dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | 292 | dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); |
285 | dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); | 293 | dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); |
286 | dev2->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | | 294 | dev2->keybit[BIT_WORD(BTN_LEFT)] = |
287 | BIT_MASK(BTN_RIGHT); | 295 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); |
288 | 296 | ||
289 | error = input_register_device(priv->dev2); | 297 | error = input_register_device(priv->dev2); |
290 | if (error) | 298 | if (error) |
@@ -309,6 +317,7 @@ int lifebook_init(struct psmouse *psmouse) | |||
309 | 317 | ||
310 | dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); | 318 | dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); |
311 | dev1->relbit[0] = 0; | 319 | dev1->relbit[0] = 0; |
320 | dev1->keybit[BIT_WORD(BTN_MOUSE)] = 0; | ||
312 | dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 321 | dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
313 | input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0); | 322 | input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0); |
314 | input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0); | 323 | input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0); |
diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h index 407cb226bc0a..4c4326c6f504 100644 --- a/drivers/input/mouse/lifebook.h +++ b/drivers/input/mouse/lifebook.h | |||
@@ -12,9 +12,13 @@ | |||
12 | #define _LIFEBOOK_H | 12 | #define _LIFEBOOK_H |
13 | 13 | ||
14 | #ifdef CONFIG_MOUSE_PS2_LIFEBOOK | 14 | #ifdef CONFIG_MOUSE_PS2_LIFEBOOK |
15 | void lifebook_module_init(void); | ||
15 | int lifebook_detect(struct psmouse *psmouse, bool set_properties); | 16 | int lifebook_detect(struct psmouse *psmouse, bool set_properties); |
16 | int lifebook_init(struct psmouse *psmouse); | 17 | int lifebook_init(struct psmouse *psmouse); |
17 | #else | 18 | #else |
19 | inline void lifebook_module_init(void) | ||
20 | { | ||
21 | } | ||
18 | inline int lifebook_detect(struct psmouse *psmouse, bool set_properties) | 22 | inline int lifebook_detect(struct psmouse *psmouse, bool set_properties) |
19 | { | 23 | { |
20 | return -ENOSYS; | 24 | return -ENOSYS; |
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index ab5dc5f5fd83..543c240a85f2 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
@@ -404,8 +404,8 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) | |||
404 | } | 404 | } |
405 | } | 405 | } |
406 | 406 | ||
407 | if (buttons < 3) | 407 | if (buttons >= 3) |
408 | __clear_bit(BTN_MIDDLE, psmouse->dev->keybit); | 408 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); |
409 | 409 | ||
410 | if (model_info) | 410 | if (model_info) |
411 | ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); | 411 | ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 07c53798301a..fd0bc094616a 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -425,6 +425,7 @@ static int genius_detect(struct psmouse *psmouse, bool set_properties) | |||
425 | return -1; | 425 | return -1; |
426 | 426 | ||
427 | if (set_properties) { | 427 | if (set_properties) { |
428 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | ||
428 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); | 429 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); |
429 | __set_bit(BTN_SIDE, psmouse->dev->keybit); | 430 | __set_bit(BTN_SIDE, psmouse->dev->keybit); |
430 | __set_bit(REL_WHEEL, psmouse->dev->relbit); | 431 | __set_bit(REL_WHEEL, psmouse->dev->relbit); |
@@ -460,8 +461,10 @@ static int intellimouse_detect(struct psmouse *psmouse, bool set_properties) | |||
460 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | 461 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); |
461 | __set_bit(REL_WHEEL, psmouse->dev->relbit); | 462 | __set_bit(REL_WHEEL, psmouse->dev->relbit); |
462 | 463 | ||
463 | if (!psmouse->vendor) psmouse->vendor = "Generic"; | 464 | if (!psmouse->vendor) |
464 | if (!psmouse->name) psmouse->name = "Wheel Mouse"; | 465 | psmouse->vendor = "Generic"; |
466 | if (!psmouse->name) | ||
467 | psmouse->name = "Wheel Mouse"; | ||
465 | psmouse->pktsize = 4; | 468 | psmouse->pktsize = 4; |
466 | } | 469 | } |
467 | 470 | ||
@@ -504,8 +507,10 @@ static int im_explorer_detect(struct psmouse *psmouse, bool set_properties) | |||
504 | __set_bit(BTN_SIDE, psmouse->dev->keybit); | 507 | __set_bit(BTN_SIDE, psmouse->dev->keybit); |
505 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); | 508 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); |
506 | 509 | ||
507 | if (!psmouse->vendor) psmouse->vendor = "Generic"; | 510 | if (!psmouse->vendor) |
508 | if (!psmouse->name) psmouse->name = "Explorer Mouse"; | 511 | psmouse->vendor = "Generic"; |
512 | if (!psmouse->name) | ||
513 | psmouse->name = "Explorer Mouse"; | ||
509 | psmouse->pktsize = 4; | 514 | psmouse->pktsize = 4; |
510 | } | 515 | } |
511 | 516 | ||
@@ -536,6 +541,7 @@ static int thinking_detect(struct psmouse *psmouse, bool set_properties) | |||
536 | return -1; | 541 | return -1; |
537 | 542 | ||
538 | if (set_properties) { | 543 | if (set_properties) { |
544 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | ||
539 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); | 545 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); |
540 | 546 | ||
541 | psmouse->vendor = "Kensington"; | 547 | psmouse->vendor = "Kensington"; |
@@ -551,8 +557,16 @@ static int thinking_detect(struct psmouse *psmouse, bool set_properties) | |||
551 | static int ps2bare_detect(struct psmouse *psmouse, bool set_properties) | 557 | static int ps2bare_detect(struct psmouse *psmouse, bool set_properties) |
552 | { | 558 | { |
553 | if (set_properties) { | 559 | if (set_properties) { |
554 | if (!psmouse->vendor) psmouse->vendor = "Generic"; | 560 | if (!psmouse->vendor) |
555 | if (!psmouse->name) psmouse->name = "Mouse"; | 561 | psmouse->vendor = "Generic"; |
562 | if (!psmouse->name) | ||
563 | psmouse->name = "Mouse"; | ||
564 | |||
565 | /* | ||
566 | * We have no way of figuring true number of buttons so let's | ||
567 | * assume that the device has 3. | ||
568 | */ | ||
569 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | ||
556 | } | 570 | } |
557 | 571 | ||
558 | return 0; | 572 | return 0; |
@@ -567,6 +581,8 @@ static int cortron_detect(struct psmouse *psmouse, bool set_properties) | |||
567 | if (set_properties) { | 581 | if (set_properties) { |
568 | psmouse->vendor = "Cortron"; | 582 | psmouse->vendor = "Cortron"; |
569 | psmouse->name = "PS/2 Trackball"; | 583 | psmouse->name = "PS/2 Trackball"; |
584 | |||
585 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | ||
570 | __set_bit(BTN_SIDE, psmouse->dev->keybit); | 586 | __set_bit(BTN_SIDE, psmouse->dev->keybit); |
571 | } | 587 | } |
572 | 588 | ||
@@ -1184,15 +1200,16 @@ static void psmouse_disconnect(struct serio *serio) | |||
1184 | mutex_unlock(&psmouse_mutex); | 1200 | mutex_unlock(&psmouse_mutex); |
1185 | } | 1201 | } |
1186 | 1202 | ||
1187 | static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse_protocol *proto) | 1203 | static int psmouse_switch_protocol(struct psmouse *psmouse, |
1204 | const struct psmouse_protocol *proto) | ||
1188 | { | 1205 | { |
1189 | struct input_dev *input_dev = psmouse->dev; | 1206 | struct input_dev *input_dev = psmouse->dev; |
1190 | 1207 | ||
1191 | input_dev->dev.parent = &psmouse->ps2dev.serio->dev; | 1208 | input_dev->dev.parent = &psmouse->ps2dev.serio->dev; |
1192 | 1209 | ||
1193 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | 1210 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); |
1194 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | | 1211 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] = |
1195 | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); | 1212 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); |
1196 | input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); | 1213 | input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); |
1197 | 1214 | ||
1198 | psmouse->set_rate = psmouse_set_rate; | 1215 | psmouse->set_rate = psmouse_set_rate; |
@@ -1209,8 +1226,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse | |||
1209 | return -1; | 1226 | return -1; |
1210 | 1227 | ||
1211 | psmouse->type = proto->type; | 1228 | psmouse->type = proto->type; |
1212 | } | 1229 | } else |
1213 | else | ||
1214 | psmouse->type = psmouse_extensions(psmouse, | 1230 | psmouse->type = psmouse_extensions(psmouse, |
1215 | psmouse_max_proto, true); | 1231 | psmouse_max_proto, true); |
1216 | 1232 | ||
@@ -1680,6 +1696,9 @@ static int __init psmouse_init(void) | |||
1680 | { | 1696 | { |
1681 | int err; | 1697 | int err; |
1682 | 1698 | ||
1699 | lifebook_module_init(); | ||
1700 | synaptics_module_init(); | ||
1701 | |||
1683 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); | 1702 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); |
1684 | if (!kpsmoused_wq) { | 1703 | if (!kpsmoused_wq) { |
1685 | printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n"); | 1704 | printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n"); |
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index f84cbd97c884..77b9fd0b3fbf 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
@@ -836,6 +836,7 @@ int fsp_init(struct psmouse *psmouse) | |||
836 | priv->flags |= FSPDRV_FLAG_EN_OPC; | 836 | priv->flags |= FSPDRV_FLAG_EN_OPC; |
837 | 837 | ||
838 | /* Set up various supported input event bits */ | 838 | /* Set up various supported input event bits */ |
839 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | ||
839 | __set_bit(BTN_BACK, psmouse->dev->keybit); | 840 | __set_bit(BTN_BACK, psmouse->dev->keybit); |
840 | __set_bit(BTN_FORWARD, psmouse->dev->keybit); | 841 | __set_bit(BTN_FORWARD, psmouse->dev->keybit); |
841 | __set_bit(REL_WHEEL, psmouse->dev->relbit); | 842 | __set_bit(REL_WHEEL, psmouse->dev->relbit); |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index f4a61252bcc9..05689e732191 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -24,6 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/dmi.h> | ||
27 | #include <linux/input.h> | 28 | #include <linux/input.h> |
28 | #include <linux/serio.h> | 29 | #include <linux/serio.h> |
29 | #include <linux/libps2.h> | 30 | #include <linux/libps2.h> |
@@ -629,25 +630,26 @@ static int synaptics_reconnect(struct psmouse *psmouse) | |||
629 | return 0; | 630 | return 0; |
630 | } | 631 | } |
631 | 632 | ||
632 | #if defined(__i386__) | 633 | static bool impaired_toshiba_kbc; |
633 | #include <linux/dmi.h> | 634 | |
634 | static const struct dmi_system_id toshiba_dmi_table[] = { | 635 | static const struct dmi_system_id __initconst toshiba_dmi_table[] = { |
636 | #if defined(CONFIG_DMI) && defined(CONFIG_X86) | ||
635 | { | 637 | { |
636 | .ident = "Toshiba Satellite", | 638 | /* Toshiba Satellite */ |
637 | .matches = { | 639 | .matches = { |
638 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 640 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
639 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"), | 641 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"), |
640 | }, | 642 | }, |
641 | }, | 643 | }, |
642 | { | 644 | { |
643 | .ident = "Toshiba Dynabook", | 645 | /* Toshiba Dynabook */ |
644 | .matches = { | 646 | .matches = { |
645 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 647 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
646 | DMI_MATCH(DMI_PRODUCT_NAME, "dynabook"), | 648 | DMI_MATCH(DMI_PRODUCT_NAME, "dynabook"), |
647 | }, | 649 | }, |
648 | }, | 650 | }, |
649 | { | 651 | { |
650 | .ident = "Toshiba Portege M300", | 652 | /* Toshiba Portege M300 */ |
651 | .matches = { | 653 | .matches = { |
652 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 654 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
653 | DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"), | 655 | DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"), |
@@ -655,7 +657,7 @@ static const struct dmi_system_id toshiba_dmi_table[] = { | |||
655 | 657 | ||
656 | }, | 658 | }, |
657 | { | 659 | { |
658 | .ident = "Toshiba Portege M300", | 660 | /* Toshiba Portege M300 */ |
659 | .matches = { | 661 | .matches = { |
660 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 662 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
661 | DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"), | 663 | DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"), |
@@ -664,8 +666,13 @@ static const struct dmi_system_id toshiba_dmi_table[] = { | |||
664 | 666 | ||
665 | }, | 667 | }, |
666 | { } | 668 | { } |
667 | }; | ||
668 | #endif | 669 | #endif |
670 | }; | ||
671 | |||
672 | void __init synaptics_module_init(void) | ||
673 | { | ||
674 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); | ||
675 | } | ||
669 | 676 | ||
670 | int synaptics_init(struct psmouse *psmouse) | 677 | int synaptics_init(struct psmouse *psmouse) |
671 | { | 678 | { |
@@ -718,18 +725,16 @@ int synaptics_init(struct psmouse *psmouse) | |||
718 | if (SYN_CAP_PASS_THROUGH(priv->capabilities)) | 725 | if (SYN_CAP_PASS_THROUGH(priv->capabilities)) |
719 | synaptics_pt_create(psmouse); | 726 | synaptics_pt_create(psmouse); |
720 | 727 | ||
721 | #if defined(__i386__) | ||
722 | /* | 728 | /* |
723 | * Toshiba's KBC seems to have trouble handling data from | 729 | * Toshiba's KBC seems to have trouble handling data from |
724 | * Synaptics as full rate, switch to lower rate which is roughly | 730 | * Synaptics as full rate, switch to lower rate which is roughly |
725 | * thye same as rate of standard PS/2 mouse. | 731 | * thye same as rate of standard PS/2 mouse. |
726 | */ | 732 | */ |
727 | if (psmouse->rate >= 80 && dmi_check_system(toshiba_dmi_table)) { | 733 | if (psmouse->rate >= 80 && impaired_toshiba_kbc) { |
728 | printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n", | 734 | printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n", |
729 | dmi_get_system_info(DMI_PRODUCT_NAME)); | 735 | dmi_get_system_info(DMI_PRODUCT_NAME)); |
730 | psmouse->rate = 40; | 736 | psmouse->rate = 40; |
731 | } | 737 | } |
732 | #endif | ||
733 | 738 | ||
734 | return 0; | 739 | return 0; |
735 | 740 | ||
@@ -740,6 +745,10 @@ int synaptics_init(struct psmouse *psmouse) | |||
740 | 745 | ||
741 | #else /* CONFIG_MOUSE_PS2_SYNAPTICS */ | 746 | #else /* CONFIG_MOUSE_PS2_SYNAPTICS */ |
742 | 747 | ||
748 | void __init synaptics_module_init(void) | ||
749 | { | ||
750 | } | ||
751 | |||
743 | int synaptics_init(struct psmouse *psmouse) | 752 | int synaptics_init(struct psmouse *psmouse) |
744 | { | 753 | { |
745 | return -ENOSYS; | 754 | return -ENOSYS; |
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 871f6fe377f9..838e7f2c9b30 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -105,6 +105,7 @@ struct synaptics_data { | |||
105 | int scroll; | 105 | int scroll; |
106 | }; | 106 | }; |
107 | 107 | ||
108 | void synaptics_module_init(void); | ||
108 | int synaptics_detect(struct psmouse *psmouse, bool set_properties); | 109 | int synaptics_detect(struct psmouse *psmouse, bool set_properties); |
109 | int synaptics_init(struct psmouse *psmouse); | 110 | int synaptics_init(struct psmouse *psmouse); |
110 | void synaptics_reset(struct psmouse *psmouse); | 111 | void synaptics_reset(struct psmouse *psmouse); |
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index 7283c78044af..9867dfe2a638 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c | |||
@@ -420,8 +420,8 @@ static void synaptics_i2c_check_params(struct synaptics_i2c *touch) | |||
420 | } | 420 | } |
421 | 421 | ||
422 | /* Control the Device polling rate / Work Handler sleep time */ | 422 | /* Control the Device polling rate / Work Handler sleep time */ |
423 | unsigned long synaptics_i2c_adjust_delay(struct synaptics_i2c *touch, | 423 | static unsigned long synaptics_i2c_adjust_delay(struct synaptics_i2c *touch, |
424 | bool have_data) | 424 | bool have_data) |
425 | { | 425 | { |
426 | unsigned long delay, nodata_count_thres; | 426 | unsigned long delay, nodata_count_thres; |
427 | 427 | ||
@@ -520,7 +520,7 @@ static void synaptics_i2c_set_input_params(struct synaptics_i2c *touch) | |||
520 | __set_bit(BTN_LEFT, input->keybit); | 520 | __set_bit(BTN_LEFT, input->keybit); |
521 | } | 521 | } |
522 | 522 | ||
523 | struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *client) | 523 | static struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *client) |
524 | { | 524 | { |
525 | struct synaptics_i2c *touch; | 525 | struct synaptics_i2c *touch; |
526 | 526 | ||
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c index 0308a0faa94d..909431c31ab4 100644 --- a/drivers/input/mouse/touchkit_ps2.c +++ b/drivers/input/mouse/touchkit_ps2.c | |||
@@ -86,7 +86,8 @@ int touchkit_ps2_detect(struct psmouse *psmouse, bool set_properties) | |||
86 | 86 | ||
87 | if (set_properties) { | 87 | if (set_properties) { |
88 | dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 88 | dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
89 | __set_bit(BTN_TOUCH, dev->keybit); | 89 | dev->keybit[BIT_WORD(BTN_MOUSE)] = 0; |
90 | dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
90 | input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0); | 91 | input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0); |
91 | input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0); | 92 | input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0); |
92 | 93 | ||
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index e354362f2971..63d4a67830f2 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
@@ -284,7 +284,6 @@ static int trackpoint_reconnect(struct psmouse *psmouse) | |||
284 | 284 | ||
285 | int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | 285 | int trackpoint_detect(struct psmouse *psmouse, bool set_properties) |
286 | { | 286 | { |
287 | struct trackpoint_data *priv; | ||
288 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 287 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
289 | unsigned char firmware_id; | 288 | unsigned char firmware_id; |
290 | unsigned char button_info; | 289 | unsigned char button_info; |
@@ -301,8 +300,8 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
301 | button_info = 0; | 300 | button_info = 0; |
302 | } | 301 | } |
303 | 302 | ||
304 | psmouse->private = priv = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); | 303 | psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); |
305 | if (!priv) | 304 | if (!psmouse->private) |
306 | return -1; | 305 | return -1; |
307 | 306 | ||
308 | psmouse->vendor = "IBM"; | 307 | psmouse->vendor = "IBM"; |
@@ -311,7 +310,10 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
311 | psmouse->reconnect = trackpoint_reconnect; | 310 | psmouse->reconnect = trackpoint_reconnect; |
312 | psmouse->disconnect = trackpoint_disconnect; | 311 | psmouse->disconnect = trackpoint_disconnect; |
313 | 312 | ||
314 | trackpoint_defaults(priv); | 313 | if ((button_info & 0x0f) >= 3) |
314 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | ||
315 | |||
316 | trackpoint_defaults(psmouse->private); | ||
315 | trackpoint_sync(psmouse); | 317 | trackpoint_sync(psmouse); |
316 | 318 | ||
317 | error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); | 319 | error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); |
@@ -319,7 +321,8 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
319 | printk(KERN_ERR | 321 | printk(KERN_ERR |
320 | "trackpoint.c: failed to create sysfs attributes, error: %d\n", | 322 | "trackpoint.c: failed to create sysfs attributes, error: %d\n", |
321 | error); | 323 | error); |
322 | kfree(priv); | 324 | kfree(psmouse->private); |
325 | psmouse->private = NULL; | ||
323 | return -1; | 326 | return -1; |
324 | } | 327 | } |
325 | 328 | ||
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index 70111443678e..bf2c0c80d6cc 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c | |||
@@ -86,27 +86,28 @@ | |||
86 | 86 | ||
87 | #define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet" | 87 | #define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet" |
88 | 88 | ||
89 | MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>"); | 89 | MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>"); |
90 | MODULE_DESCRIPTION (DRIVER_DESC); | 90 | MODULE_DESCRIPTION(DRIVER_DESC); |
91 | MODULE_LICENSE ("GPL"); | 91 | MODULE_LICENSE("GPL"); |
92 | 92 | ||
93 | #undef VSXXXAA_DEBUG | 93 | #undef VSXXXAA_DEBUG |
94 | #ifdef VSXXXAA_DEBUG | 94 | #ifdef VSXXXAA_DEBUG |
95 | #define DBG(x...) printk (x) | 95 | #define DBG(x...) printk(x) |
96 | #else | 96 | #else |
97 | #define DBG(x...) do {} while (0) | 97 | #define DBG(x...) do {} while (0) |
98 | #endif | 98 | #endif |
99 | 99 | ||
100 | #define VSXXXAA_INTRO_MASK 0x80 | 100 | #define VSXXXAA_INTRO_MASK 0x80 |
101 | #define VSXXXAA_INTRO_HEAD 0x80 | 101 | #define VSXXXAA_INTRO_HEAD 0x80 |
102 | #define IS_HDR_BYTE(x) (((x) & VSXXXAA_INTRO_MASK) \ | 102 | #define IS_HDR_BYTE(x) \ |
103 | == VSXXXAA_INTRO_HEAD) | 103 | (((x) & VSXXXAA_INTRO_MASK) == VSXXXAA_INTRO_HEAD) |
104 | 104 | ||
105 | #define VSXXXAA_PACKET_MASK 0xe0 | 105 | #define VSXXXAA_PACKET_MASK 0xe0 |
106 | #define VSXXXAA_PACKET_REL 0x80 | 106 | #define VSXXXAA_PACKET_REL 0x80 |
107 | #define VSXXXAA_PACKET_ABS 0xc0 | 107 | #define VSXXXAA_PACKET_ABS 0xc0 |
108 | #define VSXXXAA_PACKET_POR 0xa0 | 108 | #define VSXXXAA_PACKET_POR 0xa0 |
109 | #define MATCH_PACKET_TYPE(data, type) (((data) & VSXXXAA_PACKET_MASK) == (type)) | 109 | #define MATCH_PACKET_TYPE(data, type) \ |
110 | (((data) & VSXXXAA_PACKET_MASK) == (type)) | ||
110 | 111 | ||
111 | 112 | ||
112 | 113 | ||
@@ -123,52 +124,50 @@ struct vsxxxaa { | |||
123 | char phys[32]; | 124 | char phys[32]; |
124 | }; | 125 | }; |
125 | 126 | ||
126 | static void | 127 | static void vsxxxaa_drop_bytes(struct vsxxxaa *mouse, int num) |
127 | vsxxxaa_drop_bytes (struct vsxxxaa *mouse, int num) | ||
128 | { | 128 | { |
129 | if (num >= mouse->count) | 129 | if (num >= mouse->count) { |
130 | mouse->count = 0; | 130 | mouse->count = 0; |
131 | else { | 131 | } else { |
132 | memmove (mouse->buf, mouse->buf + num - 1, BUFLEN - num); | 132 | memmove(mouse->buf, mouse->buf + num - 1, BUFLEN - num); |
133 | mouse->count -= num; | 133 | mouse->count -= num; |
134 | } | 134 | } |
135 | } | 135 | } |
136 | 136 | ||
137 | static void | 137 | static void vsxxxaa_queue_byte(struct vsxxxaa *mouse, unsigned char byte) |
138 | vsxxxaa_queue_byte (struct vsxxxaa *mouse, unsigned char byte) | ||
139 | { | 138 | { |
140 | if (mouse->count == BUFLEN) { | 139 | if (mouse->count == BUFLEN) { |
141 | printk (KERN_ERR "%s on %s: Dropping a byte of full buffer.\n", | 140 | printk(KERN_ERR "%s on %s: Dropping a byte of full buffer.\n", |
142 | mouse->name, mouse->phys); | 141 | mouse->name, mouse->phys); |
143 | vsxxxaa_drop_bytes (mouse, 1); | 142 | vsxxxaa_drop_bytes(mouse, 1); |
144 | } | 143 | } |
145 | DBG (KERN_INFO "Queueing byte 0x%02x\n", byte); | 144 | |
145 | DBG(KERN_INFO "Queueing byte 0x%02x\n", byte); | ||
146 | 146 | ||
147 | mouse->buf[mouse->count++] = byte; | 147 | mouse->buf[mouse->count++] = byte; |
148 | } | 148 | } |
149 | 149 | ||
150 | static void | 150 | static void vsxxxaa_detection_done(struct vsxxxaa *mouse) |
151 | vsxxxaa_detection_done (struct vsxxxaa *mouse) | ||
152 | { | 151 | { |
153 | switch (mouse->type) { | 152 | switch (mouse->type) { |
154 | case 0x02: | 153 | case 0x02: |
155 | strlcpy (mouse->name, "DEC VSXXX-AA/-GA mouse", | 154 | strlcpy(mouse->name, "DEC VSXXX-AA/-GA mouse", |
156 | sizeof (mouse->name)); | 155 | sizeof(mouse->name)); |
157 | break; | 156 | break; |
158 | 157 | ||
159 | case 0x04: | 158 | case 0x04: |
160 | strlcpy (mouse->name, "DEC VSXXX-AB digitizer", | 159 | strlcpy(mouse->name, "DEC VSXXX-AB digitizer", |
161 | sizeof (mouse->name)); | 160 | sizeof(mouse->name)); |
162 | break; | 161 | break; |
163 | 162 | ||
164 | default: | 163 | default: |
165 | snprintf (mouse->name, sizeof (mouse->name), | 164 | snprintf(mouse->name, sizeof(mouse->name), |
166 | "unknown DEC pointer device (type = 0x%02x)", | 165 | "unknown DEC pointer device (type = 0x%02x)", |
167 | mouse->type); | 166 | mouse->type); |
168 | break; | 167 | break; |
169 | } | 168 | } |
170 | 169 | ||
171 | printk (KERN_INFO | 170 | printk(KERN_INFO |
172 | "Found %s version 0x%02x from country 0x%02x on port %s\n", | 171 | "Found %s version 0x%02x from country 0x%02x on port %s\n", |
173 | mouse->name, mouse->version, mouse->country, mouse->phys); | 172 | mouse->name, mouse->version, mouse->country, mouse->phys); |
174 | } | 173 | } |
@@ -176,42 +175,38 @@ vsxxxaa_detection_done (struct vsxxxaa *mouse) | |||
176 | /* | 175 | /* |
177 | * Returns number of bytes to be dropped, 0 if packet is okay. | 176 | * Returns number of bytes to be dropped, 0 if packet is okay. |
178 | */ | 177 | */ |
179 | static int | 178 | static int vsxxxaa_check_packet(struct vsxxxaa *mouse, int packet_len) |
180 | vsxxxaa_check_packet (struct vsxxxaa *mouse, int packet_len) | ||
181 | { | 179 | { |
182 | int i; | 180 | int i; |
183 | 181 | ||
184 | /* First byte must be a header byte */ | 182 | /* First byte must be a header byte */ |
185 | if (!IS_HDR_BYTE (mouse->buf[0])) { | 183 | if (!IS_HDR_BYTE(mouse->buf[0])) { |
186 | DBG ("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]); | 184 | DBG("vsck: len=%d, 1st=0x%02x\n", packet_len, mouse->buf[0]); |
187 | return 1; | 185 | return 1; |
188 | } | 186 | } |
189 | 187 | ||
190 | /* Check all following bytes */ | 188 | /* Check all following bytes */ |
191 | if (packet_len > 1) { | 189 | for (i = 1; i < packet_len; i++) { |
192 | for (i = 1; i < packet_len; i++) { | 190 | if (IS_HDR_BYTE(mouse->buf[i])) { |
193 | if (IS_HDR_BYTE (mouse->buf[i])) { | 191 | printk(KERN_ERR |
194 | printk (KERN_ERR "Need to drop %d bytes " | 192 | "Need to drop %d bytes of a broken packet.\n", |
195 | "of a broken packet.\n", | 193 | i - 1); |
196 | i - 1); | 194 | DBG(KERN_INFO "check: len=%d, b[%d]=0x%02x\n", |
197 | DBG (KERN_INFO "check: len=%d, b[%d]=0x%02x\n", | 195 | packet_len, i, mouse->buf[i]); |
198 | packet_len, i, mouse->buf[i]); | 196 | return i - 1; |
199 | return i - 1; | ||
200 | } | ||
201 | } | 197 | } |
202 | } | 198 | } |
203 | 199 | ||
204 | return 0; | 200 | return 0; |
205 | } | 201 | } |
206 | 202 | ||
207 | static __inline__ int | 203 | static inline int vsxxxaa_smells_like_packet(struct vsxxxaa *mouse, |
208 | vsxxxaa_smells_like_packet (struct vsxxxaa *mouse, unsigned char type, size_t len) | 204 | unsigned char type, size_t len) |
209 | { | 205 | { |
210 | return (mouse->count >= len) && MATCH_PACKET_TYPE (mouse->buf[0], type); | 206 | return mouse->count >= len && MATCH_PACKET_TYPE(mouse->buf[0], type); |
211 | } | 207 | } |
212 | 208 | ||
213 | static void | 209 | static void vsxxxaa_handle_REL_packet(struct vsxxxaa *mouse) |
214 | vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse) | ||
215 | { | 210 | { |
216 | struct input_dev *dev = mouse->dev; | 211 | struct input_dev *dev = mouse->dev; |
217 | unsigned char *buf = mouse->buf; | 212 | unsigned char *buf = mouse->buf; |
@@ -232,43 +227,42 @@ vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse) | |||
232 | * 0, bit 4 of byte 0 is direction. | 227 | * 0, bit 4 of byte 0 is direction. |
233 | */ | 228 | */ |
234 | dx = buf[1] & 0x7f; | 229 | dx = buf[1] & 0x7f; |
235 | dx *= ((buf[0] >> 4) & 0x01)? 1: -1; | 230 | dx *= ((buf[0] >> 4) & 0x01) ? 1 : -1; |
236 | 231 | ||
237 | /* | 232 | /* |
238 | * Low 7 bit of byte 2 are abs(dy), bit 7 is | 233 | * Low 7 bit of byte 2 are abs(dy), bit 7 is |
239 | * 0, bit 3 of byte 0 is direction. | 234 | * 0, bit 3 of byte 0 is direction. |
240 | */ | 235 | */ |
241 | dy = buf[2] & 0x7f; | 236 | dy = buf[2] & 0x7f; |
242 | dy *= ((buf[0] >> 3) & 0x01)? -1: 1; | 237 | dy *= ((buf[0] >> 3) & 0x01) ? -1 : 1; |
243 | 238 | ||
244 | /* | 239 | /* |
245 | * Get button state. It's the low three bits | 240 | * Get button state. It's the low three bits |
246 | * (for three buttons) of byte 0. | 241 | * (for three buttons) of byte 0. |
247 | */ | 242 | */ |
248 | left = (buf[0] & 0x04)? 1: 0; | 243 | left = buf[0] & 0x04; |
249 | middle = (buf[0] & 0x02)? 1: 0; | 244 | middle = buf[0] & 0x02; |
250 | right = (buf[0] & 0x01)? 1: 0; | 245 | right = buf[0] & 0x01; |
251 | 246 | ||
252 | vsxxxaa_drop_bytes (mouse, 3); | 247 | vsxxxaa_drop_bytes(mouse, 3); |
253 | 248 | ||
254 | DBG (KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n", | 249 | DBG(KERN_INFO "%s on %s: dx=%d, dy=%d, buttons=%s%s%s\n", |
255 | mouse->name, mouse->phys, dx, dy, | 250 | mouse->name, mouse->phys, dx, dy, |
256 | left? "L": "l", middle? "M": "m", right? "R": "r"); | 251 | left ? "L" : "l", middle ? "M" : "m", right ? "R" : "r"); |
257 | 252 | ||
258 | /* | 253 | /* |
259 | * Report what we've found so far... | 254 | * Report what we've found so far... |
260 | */ | 255 | */ |
261 | input_report_key (dev, BTN_LEFT, left); | 256 | input_report_key(dev, BTN_LEFT, left); |
262 | input_report_key (dev, BTN_MIDDLE, middle); | 257 | input_report_key(dev, BTN_MIDDLE, middle); |
263 | input_report_key (dev, BTN_RIGHT, right); | 258 | input_report_key(dev, BTN_RIGHT, right); |
264 | input_report_key (dev, BTN_TOUCH, 0); | 259 | input_report_key(dev, BTN_TOUCH, 0); |
265 | input_report_rel (dev, REL_X, dx); | 260 | input_report_rel(dev, REL_X, dx); |
266 | input_report_rel (dev, REL_Y, dy); | 261 | input_report_rel(dev, REL_Y, dy); |
267 | input_sync (dev); | 262 | input_sync(dev); |
268 | } | 263 | } |
269 | 264 | ||
270 | static void | 265 | static void vsxxxaa_handle_ABS_packet(struct vsxxxaa *mouse) |
271 | vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse) | ||
272 | { | 266 | { |
273 | struct input_dev *dev = mouse->dev; | 267 | struct input_dev *dev = mouse->dev; |
274 | unsigned char *buf = mouse->buf; | 268 | unsigned char *buf = mouse->buf; |
@@ -296,32 +290,31 @@ vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse) | |||
296 | /* | 290 | /* |
297 | * Get button state. It's bits <4..1> of byte 0. | 291 | * Get button state. It's bits <4..1> of byte 0. |
298 | */ | 292 | */ |
299 | left = (buf[0] & 0x02)? 1: 0; | 293 | left = buf[0] & 0x02; |
300 | middle = (buf[0] & 0x04)? 1: 0; | 294 | middle = buf[0] & 0x04; |
301 | right = (buf[0] & 0x08)? 1: 0; | 295 | right = buf[0] & 0x08; |
302 | touch = (buf[0] & 0x10)? 1: 0; | 296 | touch = buf[0] & 0x10; |
303 | 297 | ||
304 | vsxxxaa_drop_bytes (mouse, 5); | 298 | vsxxxaa_drop_bytes(mouse, 5); |
305 | 299 | ||
306 | DBG (KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n", | 300 | DBG(KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n", |
307 | mouse->name, mouse->phys, x, y, | 301 | mouse->name, mouse->phys, x, y, |
308 | left? "L": "l", middle? "M": "m", | 302 | left ? "L" : "l", middle ? "M" : "m", |
309 | right? "R": "r", touch? "T": "t"); | 303 | right ? "R" : "r", touch ? "T" : "t"); |
310 | 304 | ||
311 | /* | 305 | /* |
312 | * Report what we've found so far... | 306 | * Report what we've found so far... |
313 | */ | 307 | */ |
314 | input_report_key (dev, BTN_LEFT, left); | 308 | input_report_key(dev, BTN_LEFT, left); |
315 | input_report_key (dev, BTN_MIDDLE, middle); | 309 | input_report_key(dev, BTN_MIDDLE, middle); |
316 | input_report_key (dev, BTN_RIGHT, right); | 310 | input_report_key(dev, BTN_RIGHT, right); |
317 | input_report_key (dev, BTN_TOUCH, touch); | 311 | input_report_key(dev, BTN_TOUCH, touch); |
318 | input_report_abs (dev, ABS_X, x); | 312 | input_report_abs(dev, ABS_X, x); |
319 | input_report_abs (dev, ABS_Y, y); | 313 | input_report_abs(dev, ABS_Y, y); |
320 | input_sync (dev); | 314 | input_sync(dev); |
321 | } | 315 | } |
322 | 316 | ||
323 | static void | 317 | static void vsxxxaa_handle_POR_packet(struct vsxxxaa *mouse) |
324 | vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse) | ||
325 | { | 318 | { |
326 | struct input_dev *dev = mouse->dev; | 319 | struct input_dev *dev = mouse->dev; |
327 | unsigned char *buf = mouse->buf; | 320 | unsigned char *buf = mouse->buf; |
@@ -356,24 +349,24 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse) | |||
356 | * (for three buttons) of byte 0. Maybe even the bit <3> | 349 | * (for three buttons) of byte 0. Maybe even the bit <3> |
357 | * has some meaning if a tablet is attached. | 350 | * has some meaning if a tablet is attached. |
358 | */ | 351 | */ |
359 | left = (buf[0] & 0x04)? 1: 0; | 352 | left = buf[0] & 0x04; |
360 | middle = (buf[0] & 0x02)? 1: 0; | 353 | middle = buf[0] & 0x02; |
361 | right = (buf[0] & 0x01)? 1: 0; | 354 | right = buf[0] & 0x01; |
362 | 355 | ||
363 | vsxxxaa_drop_bytes (mouse, 4); | 356 | vsxxxaa_drop_bytes(mouse, 4); |
364 | vsxxxaa_detection_done (mouse); | 357 | vsxxxaa_detection_done(mouse); |
365 | 358 | ||
366 | if (error <= 0x1f) { | 359 | if (error <= 0x1f) { |
367 | /* No (serious) error. Report buttons */ | 360 | /* No (serious) error. Report buttons */ |
368 | input_report_key (dev, BTN_LEFT, left); | 361 | input_report_key(dev, BTN_LEFT, left); |
369 | input_report_key (dev, BTN_MIDDLE, middle); | 362 | input_report_key(dev, BTN_MIDDLE, middle); |
370 | input_report_key (dev, BTN_RIGHT, right); | 363 | input_report_key(dev, BTN_RIGHT, right); |
371 | input_report_key (dev, BTN_TOUCH, 0); | 364 | input_report_key(dev, BTN_TOUCH, 0); |
372 | input_sync (dev); | 365 | input_sync(dev); |
373 | 366 | ||
374 | if (error != 0) | 367 | if (error != 0) |
375 | printk (KERN_INFO "Your %s on %s reports error=0x%02x\n", | 368 | printk(KERN_INFO "Your %s on %s reports error=0x%02x\n", |
376 | mouse->name, mouse->phys, error); | 369 | mouse->name, mouse->phys, error); |
377 | 370 | ||
378 | } | 371 | } |
379 | 372 | ||
@@ -381,18 +374,18 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse) | |||
381 | * If the mouse was hot-plugged, we need to force differential mode | 374 | * If the mouse was hot-plugged, we need to force differential mode |
382 | * now... However, give it a second to recover from it's reset. | 375 | * now... However, give it a second to recover from it's reset. |
383 | */ | 376 | */ |
384 | printk (KERN_NOTICE "%s on %s: Forceing standard packet format, " | 377 | printk(KERN_NOTICE |
385 | "incremental streaming mode and 72 samples/sec\n", | 378 | "%s on %s: Forcing standard packet format, " |
386 | mouse->name, mouse->phys); | 379 | "incremental streaming mode and 72 samples/sec\n", |
387 | serio_write (mouse->serio, 'S'); /* Standard format */ | 380 | mouse->name, mouse->phys); |
388 | mdelay (50); | 381 | serio_write(mouse->serio, 'S'); /* Standard format */ |
389 | serio_write (mouse->serio, 'R'); /* Incremental */ | 382 | mdelay(50); |
390 | mdelay (50); | 383 | serio_write(mouse->serio, 'R'); /* Incremental */ |
391 | serio_write (mouse->serio, 'L'); /* 72 samples/sec */ | 384 | mdelay(50); |
385 | serio_write(mouse->serio, 'L'); /* 72 samples/sec */ | ||
392 | } | 386 | } |
393 | 387 | ||
394 | static void | 388 | static void vsxxxaa_parse_buffer(struct vsxxxaa *mouse) |
395 | vsxxxaa_parse_buffer (struct vsxxxaa *mouse) | ||
396 | { | 389 | { |
397 | unsigned char *buf = mouse->buf; | 390 | unsigned char *buf = mouse->buf; |
398 | int stray_bytes; | 391 | int stray_bytes; |
@@ -409,122 +402,107 @@ vsxxxaa_parse_buffer (struct vsxxxaa *mouse) | |||
409 | * activity on the mouse. | 402 | * activity on the mouse. |
410 | */ | 403 | */ |
411 | while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) { | 404 | while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) { |
412 | printk (KERN_ERR "%s on %s: Dropping a byte to regain " | 405 | printk(KERN_ERR "%s on %s: Dropping a byte to regain " |
413 | "sync with mouse data stream...\n", | 406 | "sync with mouse data stream...\n", |
414 | mouse->name, mouse->phys); | 407 | mouse->name, mouse->phys); |
415 | vsxxxaa_drop_bytes (mouse, 1); | 408 | vsxxxaa_drop_bytes(mouse, 1); |
416 | } | 409 | } |
417 | 410 | ||
418 | /* | 411 | /* |
419 | * Check for packets we know about. | 412 | * Check for packets we know about. |
420 | */ | 413 | */ |
421 | 414 | ||
422 | if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_REL, 3)) { | 415 | if (vsxxxaa_smells_like_packet(mouse, VSXXXAA_PACKET_REL, 3)) { |
423 | /* Check for broken packet */ | 416 | /* Check for broken packet */ |
424 | stray_bytes = vsxxxaa_check_packet (mouse, 3); | 417 | stray_bytes = vsxxxaa_check_packet(mouse, 3); |
425 | if (stray_bytes > 0) { | 418 | if (!stray_bytes) |
426 | printk (KERN_ERR "Dropping %d bytes now...\n", | 419 | vsxxxaa_handle_REL_packet(mouse); |
427 | stray_bytes); | ||
428 | vsxxxaa_drop_bytes (mouse, stray_bytes); | ||
429 | continue; | ||
430 | } | ||
431 | |||
432 | vsxxxaa_handle_REL_packet (mouse); | ||
433 | continue; /* More to parse? */ | ||
434 | } | ||
435 | 420 | ||
436 | if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_ABS, 5)) { | 421 | } else if (vsxxxaa_smells_like_packet(mouse, |
422 | VSXXXAA_PACKET_ABS, 5)) { | ||
437 | /* Check for broken packet */ | 423 | /* Check for broken packet */ |
438 | stray_bytes = vsxxxaa_check_packet (mouse, 5); | 424 | stray_bytes = vsxxxaa_check_packet(mouse, 5); |
439 | if (stray_bytes > 0) { | 425 | if (!stray_bytes) |
440 | printk (KERN_ERR "Dropping %d bytes now...\n", | 426 | vsxxxaa_handle_ABS_packet(mouse); |
441 | stray_bytes); | ||
442 | vsxxxaa_drop_bytes (mouse, stray_bytes); | ||
443 | continue; | ||
444 | } | ||
445 | |||
446 | vsxxxaa_handle_ABS_packet (mouse); | ||
447 | continue; /* More to parse? */ | ||
448 | } | ||
449 | 427 | ||
450 | if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_POR, 4)) { | 428 | } else if (vsxxxaa_smells_like_packet(mouse, |
429 | VSXXXAA_PACKET_POR, 4)) { | ||
451 | /* Check for broken packet */ | 430 | /* Check for broken packet */ |
452 | stray_bytes = vsxxxaa_check_packet (mouse, 4); | 431 | stray_bytes = vsxxxaa_check_packet(mouse, 4); |
453 | if (stray_bytes > 0) { | 432 | if (!stray_bytes) |
454 | printk (KERN_ERR "Dropping %d bytes now...\n", | 433 | vsxxxaa_handle_POR_packet(mouse); |
455 | stray_bytes); | 434 | |
456 | vsxxxaa_drop_bytes (mouse, stray_bytes); | 435 | } else { |
457 | continue; | 436 | break; /* No REL, ABS or POR packet found */ |
458 | } | 437 | } |
459 | 438 | ||
460 | vsxxxaa_handle_POR_packet (mouse); | 439 | if (stray_bytes > 0) { |
461 | continue; /* More to parse? */ | 440 | printk(KERN_ERR "Dropping %d bytes now...\n", |
441 | stray_bytes); | ||
442 | vsxxxaa_drop_bytes(mouse, stray_bytes); | ||
462 | } | 443 | } |
463 | 444 | ||
464 | break; /* No REL, ABS or POR packet found */ | ||
465 | } while (1); | 445 | } while (1); |
466 | } | 446 | } |
467 | 447 | ||
468 | static irqreturn_t | 448 | static irqreturn_t vsxxxaa_interrupt(struct serio *serio, |
469 | vsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags) | 449 | unsigned char data, unsigned int flags) |
470 | { | 450 | { |
471 | struct vsxxxaa *mouse = serio_get_drvdata (serio); | 451 | struct vsxxxaa *mouse = serio_get_drvdata(serio); |
472 | 452 | ||
473 | vsxxxaa_queue_byte (mouse, data); | 453 | vsxxxaa_queue_byte(mouse, data); |
474 | vsxxxaa_parse_buffer (mouse); | 454 | vsxxxaa_parse_buffer(mouse); |
475 | 455 | ||
476 | return IRQ_HANDLED; | 456 | return IRQ_HANDLED; |
477 | } | 457 | } |
478 | 458 | ||
479 | static void | 459 | static void vsxxxaa_disconnect(struct serio *serio) |
480 | vsxxxaa_disconnect (struct serio *serio) | ||
481 | { | 460 | { |
482 | struct vsxxxaa *mouse = serio_get_drvdata (serio); | 461 | struct vsxxxaa *mouse = serio_get_drvdata(serio); |
483 | 462 | ||
484 | serio_close (serio); | 463 | serio_close(serio); |
485 | serio_set_drvdata (serio, NULL); | 464 | serio_set_drvdata(serio, NULL); |
486 | input_unregister_device (mouse->dev); | 465 | input_unregister_device(mouse->dev); |
487 | kfree (mouse); | 466 | kfree(mouse); |
488 | } | 467 | } |
489 | 468 | ||
490 | static int | 469 | static int vsxxxaa_connect(struct serio *serio, struct serio_driver *drv) |
491 | vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) | ||
492 | { | 470 | { |
493 | struct vsxxxaa *mouse; | 471 | struct vsxxxaa *mouse; |
494 | struct input_dev *input_dev; | 472 | struct input_dev *input_dev; |
495 | int err = -ENOMEM; | 473 | int err = -ENOMEM; |
496 | 474 | ||
497 | mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL); | 475 | mouse = kzalloc(sizeof(struct vsxxxaa), GFP_KERNEL); |
498 | input_dev = input_allocate_device (); | 476 | input_dev = input_allocate_device(); |
499 | if (!mouse || !input_dev) | 477 | if (!mouse || !input_dev) |
500 | goto fail1; | 478 | goto fail1; |
501 | 479 | ||
502 | mouse->dev = input_dev; | 480 | mouse->dev = input_dev; |
503 | mouse->serio = serio; | 481 | mouse->serio = serio; |
504 | strlcat (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer", | 482 | strlcat(mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer", |
505 | sizeof (mouse->name)); | 483 | sizeof(mouse->name)); |
506 | snprintf (mouse->phys, sizeof (mouse->phys), "%s/input0", serio->phys); | 484 | snprintf(mouse->phys, sizeof(mouse->phys), "%s/input0", serio->phys); |
507 | 485 | ||
508 | input_dev->name = mouse->name; | 486 | input_dev->name = mouse->name; |
509 | input_dev->phys = mouse->phys; | 487 | input_dev->phys = mouse->phys; |
510 | input_dev->id.bustype = BUS_RS232; | 488 | input_dev->id.bustype = BUS_RS232; |
511 | input_dev->dev.parent = &serio->dev; | 489 | input_dev->dev.parent = &serio->dev; |
512 | 490 | ||
513 | set_bit (EV_KEY, input_dev->evbit); /* We have buttons */ | 491 | __set_bit(EV_KEY, input_dev->evbit); /* We have buttons */ |
514 | set_bit (EV_REL, input_dev->evbit); | 492 | __set_bit(EV_REL, input_dev->evbit); |
515 | set_bit (EV_ABS, input_dev->evbit); | 493 | __set_bit(EV_ABS, input_dev->evbit); |
516 | set_bit (BTN_LEFT, input_dev->keybit); /* We have 3 buttons */ | 494 | __set_bit(BTN_LEFT, input_dev->keybit); /* We have 3 buttons */ |
517 | set_bit (BTN_MIDDLE, input_dev->keybit); | 495 | __set_bit(BTN_MIDDLE, input_dev->keybit); |
518 | set_bit (BTN_RIGHT, input_dev->keybit); | 496 | __set_bit(BTN_RIGHT, input_dev->keybit); |
519 | set_bit (BTN_TOUCH, input_dev->keybit); /* ...and Tablet */ | 497 | __set_bit(BTN_TOUCH, input_dev->keybit); /* ...and Tablet */ |
520 | set_bit (REL_X, input_dev->relbit); | 498 | __set_bit(REL_X, input_dev->relbit); |
521 | set_bit (REL_Y, input_dev->relbit); | 499 | __set_bit(REL_Y, input_dev->relbit); |
522 | input_set_abs_params (input_dev, ABS_X, 0, 1023, 0, 0); | 500 | input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0); |
523 | input_set_abs_params (input_dev, ABS_Y, 0, 1023, 0, 0); | 501 | input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0); |
524 | 502 | ||
525 | serio_set_drvdata (serio, mouse); | 503 | serio_set_drvdata(serio, mouse); |
526 | 504 | ||
527 | err = serio_open (serio, drv); | 505 | err = serio_open(serio, drv); |
528 | if (err) | 506 | if (err) |
529 | goto fail2; | 507 | goto fail2; |
530 | 508 | ||
@@ -532,18 +510,18 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) | |||
532 | * Request selftest. Standard packet format and differential | 510 | * Request selftest. Standard packet format and differential |
533 | * mode will be requested after the device ID'ed successfully. | 511 | * mode will be requested after the device ID'ed successfully. |
534 | */ | 512 | */ |
535 | serio_write (serio, 'T'); /* Test */ | 513 | serio_write(serio, 'T'); /* Test */ |
536 | 514 | ||
537 | err = input_register_device (input_dev); | 515 | err = input_register_device(input_dev); |
538 | if (err) | 516 | if (err) |
539 | goto fail3; | 517 | goto fail3; |
540 | 518 | ||
541 | return 0; | 519 | return 0; |
542 | 520 | ||
543 | fail3: serio_close (serio); | 521 | fail3: serio_close(serio); |
544 | fail2: serio_set_drvdata (serio, NULL); | 522 | fail2: serio_set_drvdata(serio, NULL); |
545 | fail1: input_free_device (input_dev); | 523 | fail1: input_free_device(input_dev); |
546 | kfree (mouse); | 524 | kfree(mouse); |
547 | return err; | 525 | return err; |
548 | } | 526 | } |
549 | 527 | ||
@@ -570,18 +548,16 @@ static struct serio_driver vsxxxaa_drv = { | |||
570 | .disconnect = vsxxxaa_disconnect, | 548 | .disconnect = vsxxxaa_disconnect, |
571 | }; | 549 | }; |
572 | 550 | ||
573 | static int __init | 551 | static int __init vsxxxaa_init(void) |
574 | vsxxxaa_init (void) | ||
575 | { | 552 | { |
576 | return serio_register_driver(&vsxxxaa_drv); | 553 | return serio_register_driver(&vsxxxaa_drv); |
577 | } | 554 | } |
578 | 555 | ||
579 | static void __exit | 556 | static void __exit vsxxxaa_exit(void) |
580 | vsxxxaa_exit (void) | ||
581 | { | 557 | { |
582 | serio_unregister_driver(&vsxxxaa_drv); | 558 | serio_unregister_driver(&vsxxxaa_drv); |
583 | } | 559 | } |
584 | 560 | ||
585 | module_init (vsxxxaa_init); | 561 | module_init(vsxxxaa_init); |
586 | module_exit (vsxxxaa_exit); | 562 | module_exit(vsxxxaa_exit); |
587 | 563 | ||
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index aa533ceffe34..7e319d65ec57 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -201,4 +201,12 @@ config SERIO_XILINX_XPS_PS2 | |||
201 | To compile this driver as a module, choose M here: the | 201 | To compile this driver as a module, choose M here: the |
202 | module will be called xilinx_ps2. | 202 | module will be called xilinx_ps2. |
203 | 203 | ||
204 | config SERIO_ALTERA_PS2 | ||
205 | tristate "Altera UP PS/2 controller" | ||
206 | help | ||
207 | Say Y here if you have Altera University Program PS/2 ports. | ||
208 | |||
209 | To compile this driver as a module, choose M here: the | ||
210 | module will be called altera_ps2. | ||
211 | |||
204 | endif | 212 | endif |
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index 9b6c8135955f..bf945f789d05 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile | |||
@@ -22,3 +22,4 @@ obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o | |||
22 | obj-$(CONFIG_SERIO_LIBPS2) += libps2.o | 22 | obj-$(CONFIG_SERIO_LIBPS2) += libps2.o |
23 | obj-$(CONFIG_SERIO_RAW) += serio_raw.o | 23 | obj-$(CONFIG_SERIO_RAW) += serio_raw.o |
24 | obj-$(CONFIG_SERIO_XILINX_XPS_PS2) += xilinx_ps2.o | 24 | obj-$(CONFIG_SERIO_XILINX_XPS_PS2) += xilinx_ps2.o |
25 | obj-$(CONFIG_SERIO_ALTERA_PS2) += altera_ps2.o | ||
diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c new file mode 100644 index 000000000000..f479ea50919f --- /dev/null +++ b/drivers/input/serio/altera_ps2.c | |||
@@ -0,0 +1,200 @@ | |||
1 | /* | ||
2 | * Altera University Program PS2 controller driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Thomas Chou <thomas@wytron.com.tw> | ||
5 | * | ||
6 | * Based on sa1111ps2.c, which is: | ||
7 | * Copyright (C) 2002 Russell King | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/input.h> | ||
17 | #include <linux/serio.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/io.h> | ||
21 | |||
22 | #define DRV_NAME "altera_ps2" | ||
23 | |||
24 | struct ps2if { | ||
25 | struct serio *io; | ||
26 | struct resource *iomem_res; | ||
27 | void __iomem *base; | ||
28 | unsigned irq; | ||
29 | }; | ||
30 | |||
31 | /* | ||
32 | * Read all bytes waiting in the PS2 port. There should be | ||
33 | * at the most one, but we loop for safety. | ||
34 | */ | ||
35 | static irqreturn_t altera_ps2_rxint(int irq, void *dev_id) | ||
36 | { | ||
37 | struct ps2if *ps2if = dev_id; | ||
38 | unsigned int status; | ||
39 | int handled = IRQ_NONE; | ||
40 | |||
41 | while ((status = readl(ps2if->base)) & 0xffff0000) { | ||
42 | serio_interrupt(ps2if->io, status & 0xff, 0); | ||
43 | handled = IRQ_HANDLED; | ||
44 | } | ||
45 | |||
46 | return handled; | ||
47 | } | ||
48 | |||
49 | /* | ||
50 | * Write a byte to the PS2 port. | ||
51 | */ | ||
52 | static int altera_ps2_write(struct serio *io, unsigned char val) | ||
53 | { | ||
54 | struct ps2if *ps2if = io->port_data; | ||
55 | |||
56 | writel(val, ps2if->base); | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static int altera_ps2_open(struct serio *io) | ||
61 | { | ||
62 | struct ps2if *ps2if = io->port_data; | ||
63 | |||
64 | /* clear fifo */ | ||
65 | while (readl(ps2if->base) & 0xffff0000) | ||
66 | /* empty */; | ||
67 | |||
68 | writel(1, ps2if->base + 4); /* enable rx irq */ | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static void altera_ps2_close(struct serio *io) | ||
73 | { | ||
74 | struct ps2if *ps2if = io->port_data; | ||
75 | |||
76 | writel(0, ps2if->base); /* disable rx irq */ | ||
77 | } | ||
78 | |||
79 | /* | ||
80 | * Add one device to this driver. | ||
81 | */ | ||
82 | static int altera_ps2_probe(struct platform_device *pdev) | ||
83 | { | ||
84 | struct ps2if *ps2if; | ||
85 | struct serio *serio; | ||
86 | int error; | ||
87 | |||
88 | ps2if = kzalloc(sizeof(struct ps2if), GFP_KERNEL); | ||
89 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); | ||
90 | if (!ps2if || !serio) { | ||
91 | error = -ENOMEM; | ||
92 | goto err_free_mem; | ||
93 | } | ||
94 | |||
95 | serio->id.type = SERIO_8042; | ||
96 | serio->write = altera_ps2_write; | ||
97 | serio->open = altera_ps2_open; | ||
98 | serio->close = altera_ps2_close; | ||
99 | strlcpy(serio->name, dev_name(&pdev->dev), sizeof(serio->name)); | ||
100 | strlcpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys)); | ||
101 | serio->port_data = ps2if; | ||
102 | serio->dev.parent = &pdev->dev; | ||
103 | ps2if->io = serio; | ||
104 | |||
105 | ps2if->iomem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
106 | if (ps2if->iomem_res == NULL) { | ||
107 | error = -ENOENT; | ||
108 | goto err_free_mem; | ||
109 | } | ||
110 | |||
111 | ps2if->irq = platform_get_irq(pdev, 0); | ||
112 | if (ps2if->irq < 0) { | ||
113 | error = -ENXIO; | ||
114 | goto err_free_mem; | ||
115 | } | ||
116 | |||
117 | if (!request_mem_region(ps2if->iomem_res->start, | ||
118 | resource_size(ps2if->iomem_res), pdev->name)) { | ||
119 | error = -EBUSY; | ||
120 | goto err_free_mem; | ||
121 | } | ||
122 | |||
123 | ps2if->base = ioremap(ps2if->iomem_res->start, | ||
124 | resource_size(ps2if->iomem_res)); | ||
125 | if (!ps2if->base) { | ||
126 | error = -ENOMEM; | ||
127 | goto err_free_res; | ||
128 | } | ||
129 | |||
130 | error = request_irq(ps2if->irq, altera_ps2_rxint, 0, pdev->name, ps2if); | ||
131 | if (error) { | ||
132 | dev_err(&pdev->dev, "could not allocate IRQ %d: %d\n", | ||
133 | ps2if->irq, error); | ||
134 | goto err_unmap; | ||
135 | } | ||
136 | |||
137 | dev_info(&pdev->dev, "base %p, irq %d\n", ps2if->base, ps2if->irq); | ||
138 | |||
139 | serio_register_port(ps2if->io); | ||
140 | platform_set_drvdata(pdev, ps2if); | ||
141 | |||
142 | return 0; | ||
143 | |||
144 | err_unmap: | ||
145 | iounmap(ps2if->base); | ||
146 | err_free_res: | ||
147 | release_mem_region(ps2if->iomem_res->start, | ||
148 | resource_size(ps2if->iomem_res)); | ||
149 | err_free_mem: | ||
150 | kfree(ps2if); | ||
151 | kfree(serio); | ||
152 | return error; | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * Remove one device from this driver. | ||
157 | */ | ||
158 | static int altera_ps2_remove(struct platform_device *pdev) | ||
159 | { | ||
160 | struct ps2if *ps2if = platform_get_drvdata(pdev); | ||
161 | |||
162 | platform_set_drvdata(pdev, NULL); | ||
163 | serio_unregister_port(ps2if->io); | ||
164 | free_irq(ps2if->irq, ps2if); | ||
165 | iounmap(ps2if->base); | ||
166 | release_mem_region(ps2if->iomem_res->start, | ||
167 | resource_size(ps2if->iomem_res)); | ||
168 | kfree(ps2if); | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * Our device driver structure | ||
175 | */ | ||
176 | static struct platform_driver altera_ps2_driver = { | ||
177 | .probe = altera_ps2_probe, | ||
178 | .remove = altera_ps2_remove, | ||
179 | .driver = { | ||
180 | .name = DRV_NAME, | ||
181 | }, | ||
182 | }; | ||
183 | |||
184 | static int __init altera_ps2_init(void) | ||
185 | { | ||
186 | return platform_driver_register(&altera_ps2_driver); | ||
187 | } | ||
188 | |||
189 | static void __exit altera_ps2_exit(void) | ||
190 | { | ||
191 | platform_driver_unregister(&altera_ps2_driver); | ||
192 | } | ||
193 | |||
194 | module_init(altera_ps2_init); | ||
195 | module_exit(altera_ps2_exit); | ||
196 | |||
197 | MODULE_DESCRIPTION("Altera University Program PS2 controller driver"); | ||
198 | MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); | ||
199 | MODULE_LICENSE("GPL"); | ||
200 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 2bcf1ace27c0..7fbffe431bc5 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -67,10 +67,12 @@ static inline void i8042_write_command(int val) | |||
67 | 67 | ||
68 | #include <linux/dmi.h> | 68 | #include <linux/dmi.h> |
69 | 69 | ||
70 | static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | 70 | static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { |
71 | { | 71 | { |
72 | /* AUX LOOP command does not raise AUX IRQ */ | 72 | /* |
73 | .ident = "Arima-Rioworks HDAMB", | 73 | * Arima-Rioworks HDAMB - |
74 | * AUX LOOP command does not raise AUX IRQ | ||
75 | */ | ||
74 | .matches = { | 76 | .matches = { |
75 | DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"), | 77 | DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"), |
76 | DMI_MATCH(DMI_BOARD_NAME, "HDAMB"), | 78 | DMI_MATCH(DMI_BOARD_NAME, "HDAMB"), |
@@ -78,7 +80,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
78 | }, | 80 | }, |
79 | }, | 81 | }, |
80 | { | 82 | { |
81 | .ident = "ASUS G1S", | 83 | /* ASUS G1S */ |
82 | .matches = { | 84 | .matches = { |
83 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."), | 85 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."), |
84 | DMI_MATCH(DMI_BOARD_NAME, "G1S"), | 86 | DMI_MATCH(DMI_BOARD_NAME, "G1S"), |
@@ -86,8 +88,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
86 | }, | 88 | }, |
87 | }, | 89 | }, |
88 | { | 90 | { |
89 | /* AUX LOOP command does not raise AUX IRQ */ | 91 | /* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */ |
90 | .ident = "ASUS P65UP5", | ||
91 | .matches = { | 92 | .matches = { |
92 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | 93 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), |
93 | DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"), | 94 | DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"), |
@@ -95,7 +96,6 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
95 | }, | 96 | }, |
96 | }, | 97 | }, |
97 | { | 98 | { |
98 | .ident = "Compaq Proliant 8500", | ||
99 | .matches = { | 99 | .matches = { |
100 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), | 100 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), |
101 | DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), | 101 | DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), |
@@ -103,7 +103,6 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
103 | }, | 103 | }, |
104 | }, | 104 | }, |
105 | { | 105 | { |
106 | .ident = "Compaq Proliant DL760", | ||
107 | .matches = { | 106 | .matches = { |
108 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), | 107 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), |
109 | DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), | 108 | DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), |
@@ -111,7 +110,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
111 | }, | 110 | }, |
112 | }, | 111 | }, |
113 | { | 112 | { |
114 | .ident = "OQO Model 01", | 113 | /* OQO Model 01 */ |
115 | .matches = { | 114 | .matches = { |
116 | DMI_MATCH(DMI_SYS_VENDOR, "OQO"), | 115 | DMI_MATCH(DMI_SYS_VENDOR, "OQO"), |
117 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), | 116 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), |
@@ -119,8 +118,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
119 | }, | 118 | }, |
120 | }, | 119 | }, |
121 | { | 120 | { |
122 | /* AUX LOOP does not work properly */ | 121 | /* ULI EV4873 - AUX LOOP does not work properly */ |
123 | .ident = "ULI EV4873", | ||
124 | .matches = { | 122 | .matches = { |
125 | DMI_MATCH(DMI_SYS_VENDOR, "ULI"), | 123 | DMI_MATCH(DMI_SYS_VENDOR, "ULI"), |
126 | DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"), | 124 | DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"), |
@@ -128,7 +126,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
128 | }, | 126 | }, |
129 | }, | 127 | }, |
130 | { | 128 | { |
131 | .ident = "Microsoft Virtual Machine", | 129 | /* Microsoft Virtual Machine */ |
132 | .matches = { | 130 | .matches = { |
133 | DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), | 131 | DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), |
134 | DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), | 132 | DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), |
@@ -136,7 +134,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
136 | }, | 134 | }, |
137 | }, | 135 | }, |
138 | { | 136 | { |
139 | .ident = "Medion MAM 2070", | 137 | /* Medion MAM 2070 */ |
140 | .matches = { | 138 | .matches = { |
141 | DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), | 139 | DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), |
142 | DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"), | 140 | DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"), |
@@ -144,7 +142,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
144 | }, | 142 | }, |
145 | }, | 143 | }, |
146 | { | 144 | { |
147 | .ident = "Blue FB5601", | 145 | /* Blue FB5601 */ |
148 | .matches = { | 146 | .matches = { |
149 | DMI_MATCH(DMI_SYS_VENDOR, "blue"), | 147 | DMI_MATCH(DMI_SYS_VENDOR, "blue"), |
150 | DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"), | 148 | DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"), |
@@ -152,7 +150,7 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
152 | }, | 150 | }, |
153 | }, | 151 | }, |
154 | { | 152 | { |
155 | .ident = "Gigabyte M912", | 153 | /* Gigabyte M912 */ |
156 | .matches = { | 154 | .matches = { |
157 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), | 155 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), |
158 | DMI_MATCH(DMI_PRODUCT_NAME, "M912"), | 156 | DMI_MATCH(DMI_PRODUCT_NAME, "M912"), |
@@ -160,7 +158,6 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
160 | }, | 158 | }, |
161 | }, | 159 | }, |
162 | { | 160 | { |
163 | .ident = "HP DV9700", | ||
164 | .matches = { | 161 | .matches = { |
165 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 162 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
166 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), | 163 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), |
@@ -177,72 +174,72 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
177 | * ... apparently some Toshibas don't like MUX mode either and | 174 | * ... apparently some Toshibas don't like MUX mode either and |
178 | * die horrible death on reboot. | 175 | * die horrible death on reboot. |
179 | */ | 176 | */ |
180 | static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | 177 | static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { |
181 | { | 178 | { |
182 | .ident = "Fujitsu Lifebook P7010/P7010D", | 179 | /* Fujitsu Lifebook P7010/P7010D */ |
183 | .matches = { | 180 | .matches = { |
184 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 181 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
185 | DMI_MATCH(DMI_PRODUCT_NAME, "P7010"), | 182 | DMI_MATCH(DMI_PRODUCT_NAME, "P7010"), |
186 | }, | 183 | }, |
187 | }, | 184 | }, |
188 | { | 185 | { |
189 | .ident = "Fujitsu Lifebook P7010", | 186 | /* Fujitsu Lifebook P7010 */ |
190 | .matches = { | 187 | .matches = { |
191 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 188 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
192 | DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"), | 189 | DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"), |
193 | }, | 190 | }, |
194 | }, | 191 | }, |
195 | { | 192 | { |
196 | .ident = "Fujitsu Lifebook P5020D", | 193 | /* Fujitsu Lifebook P5020D */ |
197 | .matches = { | 194 | .matches = { |
198 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 195 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
199 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"), | 196 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"), |
200 | }, | 197 | }, |
201 | }, | 198 | }, |
202 | { | 199 | { |
203 | .ident = "Fujitsu Lifebook S2000", | 200 | /* Fujitsu Lifebook S2000 */ |
204 | .matches = { | 201 | .matches = { |
205 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 202 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
206 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"), | 203 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"), |
207 | }, | 204 | }, |
208 | }, | 205 | }, |
209 | { | 206 | { |
210 | .ident = "Fujitsu Lifebook S6230", | 207 | /* Fujitsu Lifebook S6230 */ |
211 | .matches = { | 208 | .matches = { |
212 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 209 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
213 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), | 210 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), |
214 | }, | 211 | }, |
215 | }, | 212 | }, |
216 | { | 213 | { |
217 | .ident = "Fujitsu T70H", | 214 | /* Fujitsu T70H */ |
218 | .matches = { | 215 | .matches = { |
219 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 216 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
220 | DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), | 217 | DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), |
221 | }, | 218 | }, |
222 | }, | 219 | }, |
223 | { | 220 | { |
224 | .ident = "Fujitsu-Siemens Lifebook T3010", | 221 | /* Fujitsu-Siemens Lifebook T3010 */ |
225 | .matches = { | 222 | .matches = { |
226 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 223 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
227 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), | 224 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), |
228 | }, | 225 | }, |
229 | }, | 226 | }, |
230 | { | 227 | { |
231 | .ident = "Fujitsu-Siemens Lifebook E4010", | 228 | /* Fujitsu-Siemens Lifebook E4010 */ |
232 | .matches = { | 229 | .matches = { |
233 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 230 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
234 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"), | 231 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"), |
235 | }, | 232 | }, |
236 | }, | 233 | }, |
237 | { | 234 | { |
238 | .ident = "Fujitsu-Siemens Amilo Pro 2010", | 235 | /* Fujitsu-Siemens Amilo Pro 2010 */ |
239 | .matches = { | 236 | .matches = { |
240 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 237 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
241 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"), | 238 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"), |
242 | }, | 239 | }, |
243 | }, | 240 | }, |
244 | { | 241 | { |
245 | .ident = "Fujitsu-Siemens Amilo Pro 2030", | 242 | /* Fujitsu-Siemens Amilo Pro 2030 */ |
246 | .matches = { | 243 | .matches = { |
247 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 244 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
248 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), | 245 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), |
@@ -253,7 +250,7 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
253 | * No data is coming from the touchscreen unless KBC | 250 | * No data is coming from the touchscreen unless KBC |
254 | * is in legacy mode. | 251 | * is in legacy mode. |
255 | */ | 252 | */ |
256 | .ident = "Panasonic CF-29", | 253 | /* Panasonic CF-29 */ |
257 | .matches = { | 254 | .matches = { |
258 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), | 255 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), |
259 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), | 256 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), |
@@ -261,10 +258,10 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
261 | }, | 258 | }, |
262 | { | 259 | { |
263 | /* | 260 | /* |
264 | * Errors on MUX ports are reported without raising AUXDATA | 261 | * HP Pavilion DV4017EA - |
262 | * errors on MUX ports are reported without raising AUXDATA | ||
265 | * causing "spurious NAK" messages. | 263 | * causing "spurious NAK" messages. |
266 | */ | 264 | */ |
267 | .ident = "HP Pavilion DV4017EA", | ||
268 | .matches = { | 265 | .matches = { |
269 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 266 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
270 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), | 267 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), |
@@ -272,9 +269,9 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
272 | }, | 269 | }, |
273 | { | 270 | { |
274 | /* | 271 | /* |
275 | * Like DV4017EA does not raise AUXERR for errors on MUX ports. | 272 | * HP Pavilion ZT1000 - |
273 | * like DV4017EA does not raise AUXERR for errors on MUX ports. | ||
276 | */ | 274 | */ |
277 | .ident = "HP Pavilion ZT1000", | ||
278 | .matches = { | 275 | .matches = { |
279 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 276 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
280 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"), | 277 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"), |
@@ -283,44 +280,41 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
283 | }, | 280 | }, |
284 | { | 281 | { |
285 | /* | 282 | /* |
286 | * Like DV4017EA does not raise AUXERR for errors on MUX ports. | 283 | * HP Pavilion DV4270ca - |
284 | * like DV4017EA does not raise AUXERR for errors on MUX ports. | ||
287 | */ | 285 | */ |
288 | .ident = "HP Pavilion DV4270ca", | ||
289 | .matches = { | 286 | .matches = { |
290 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 287 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
291 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"), | 288 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"), |
292 | }, | 289 | }, |
293 | }, | 290 | }, |
294 | { | 291 | { |
295 | .ident = "Toshiba P10", | ||
296 | .matches = { | 292 | .matches = { |
297 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 293 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
298 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), | 294 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), |
299 | }, | 295 | }, |
300 | }, | 296 | }, |
301 | { | 297 | { |
302 | .ident = "Toshiba Equium A110", | ||
303 | .matches = { | 298 | .matches = { |
304 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 299 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
305 | DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"), | 300 | DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"), |
306 | }, | 301 | }, |
307 | }, | 302 | }, |
308 | { | 303 | { |
309 | .ident = "Alienware Sentia", | ||
310 | .matches = { | 304 | .matches = { |
311 | DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), | 305 | DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), |
312 | DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), | 306 | DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), |
313 | }, | 307 | }, |
314 | }, | 308 | }, |
315 | { | 309 | { |
316 | .ident = "Sharp Actius MM20", | 310 | /* Sharp Actius MM20 */ |
317 | .matches = { | 311 | .matches = { |
318 | DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), | 312 | DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), |
319 | DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), | 313 | DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), |
320 | }, | 314 | }, |
321 | }, | 315 | }, |
322 | { | 316 | { |
323 | .ident = "Sony Vaio FS-115b", | 317 | /* Sony Vaio FS-115b */ |
324 | .matches = { | 318 | .matches = { |
325 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | 319 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), |
326 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), | 320 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), |
@@ -328,73 +322,72 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
328 | }, | 322 | }, |
329 | { | 323 | { |
330 | /* | 324 | /* |
331 | * Reset and GET ID commands issued via KBD port are | 325 | * Sony Vaio FZ-240E - |
326 | * reset and GET ID commands issued via KBD port are | ||
332 | * sometimes being delivered to AUX3. | 327 | * sometimes being delivered to AUX3. |
333 | */ | 328 | */ |
334 | .ident = "Sony Vaio FZ-240E", | ||
335 | .matches = { | 329 | .matches = { |
336 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | 330 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), |
337 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"), | 331 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"), |
338 | }, | 332 | }, |
339 | }, | 333 | }, |
340 | { | 334 | { |
341 | .ident = "Amoi M636/A737", | 335 | /* Amoi M636/A737 */ |
342 | .matches = { | 336 | .matches = { |
343 | DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), | 337 | DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), |
344 | DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), | 338 | DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), |
345 | }, | 339 | }, |
346 | }, | 340 | }, |
347 | { | 341 | { |
348 | .ident = "Lenovo 3000 n100", | 342 | /* Lenovo 3000 n100 */ |
349 | .matches = { | 343 | .matches = { |
350 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 344 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
351 | DMI_MATCH(DMI_PRODUCT_NAME, "076804U"), | 345 | DMI_MATCH(DMI_PRODUCT_NAME, "076804U"), |
352 | }, | 346 | }, |
353 | }, | 347 | }, |
354 | { | 348 | { |
355 | .ident = "Acer Aspire 1360", | ||
356 | .matches = { | 349 | .matches = { |
357 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 350 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
358 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), | 351 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), |
359 | }, | 352 | }, |
360 | }, | 353 | }, |
361 | { | 354 | { |
362 | .ident = "Gericom Bellagio", | 355 | /* Gericom Bellagio */ |
363 | .matches = { | 356 | .matches = { |
364 | DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), | 357 | DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), |
365 | DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), | 358 | DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), |
366 | }, | 359 | }, |
367 | }, | 360 | }, |
368 | { | 361 | { |
369 | .ident = "IBM 2656", | 362 | /* IBM 2656 */ |
370 | .matches = { | 363 | .matches = { |
371 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), | 364 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), |
372 | DMI_MATCH(DMI_PRODUCT_NAME, "2656"), | 365 | DMI_MATCH(DMI_PRODUCT_NAME, "2656"), |
373 | }, | 366 | }, |
374 | }, | 367 | }, |
375 | { | 368 | { |
376 | .ident = "Dell XPS M1530", | 369 | /* Dell XPS M1530 */ |
377 | .matches = { | 370 | .matches = { |
378 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 371 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
379 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"), | 372 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"), |
380 | }, | 373 | }, |
381 | }, | 374 | }, |
382 | { | 375 | { |
383 | .ident = "Compal HEL80I", | 376 | /* Compal HEL80I */ |
384 | .matches = { | 377 | .matches = { |
385 | DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"), | 378 | DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"), |
386 | DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), | 379 | DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), |
387 | }, | 380 | }, |
388 | }, | 381 | }, |
389 | { | 382 | { |
390 | .ident = "Dell Vostro 1510", | 383 | /* Dell Vostro 1510 */ |
391 | .matches = { | 384 | .matches = { |
392 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 385 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
393 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"), | 386 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"), |
394 | }, | 387 | }, |
395 | }, | 388 | }, |
396 | { | 389 | { |
397 | .ident = "Acer Aspire 5536", | 390 | /* Acer Aspire 5536 */ |
398 | .matches = { | 391 | .matches = { |
399 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 392 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
400 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"), | 393 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"), |
@@ -404,65 +397,65 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
404 | { } | 397 | { } |
405 | }; | 398 | }; |
406 | 399 | ||
407 | static struct dmi_system_id __initdata i8042_dmi_reset_table[] = { | 400 | static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { |
408 | { | 401 | { |
409 | .ident = "MSI Wind U-100", | 402 | /* MSI Wind U-100 */ |
410 | .matches = { | 403 | .matches = { |
411 | DMI_MATCH(DMI_BOARD_NAME, "U-100"), | 404 | DMI_MATCH(DMI_BOARD_NAME, "U-100"), |
412 | DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), | 405 | DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), |
413 | }, | 406 | }, |
414 | }, | 407 | }, |
415 | { | 408 | { |
416 | .ident = "LG Electronics X110", | 409 | /* LG Electronics X110 */ |
417 | .matches = { | 410 | .matches = { |
418 | DMI_MATCH(DMI_BOARD_NAME, "X110"), | 411 | DMI_MATCH(DMI_BOARD_NAME, "X110"), |
419 | DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."), | 412 | DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."), |
420 | }, | 413 | }, |
421 | }, | 414 | }, |
422 | { | 415 | { |
423 | .ident = "Acer Aspire One 150", | 416 | /* Acer Aspire One 150 */ |
424 | .matches = { | 417 | .matches = { |
425 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 418 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
426 | DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), | 419 | DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), |
427 | }, | 420 | }, |
428 | }, | 421 | }, |
429 | { | 422 | { |
430 | .ident = "Advent 4211", | 423 | /* Advent 4211 */ |
431 | .matches = { | 424 | .matches = { |
432 | DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"), | 425 | DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"), |
433 | DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"), | 426 | DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"), |
434 | }, | 427 | }, |
435 | }, | 428 | }, |
436 | { | 429 | { |
437 | .ident = "Medion Akoya Mini E1210", | 430 | /* Medion Akoya Mini E1210 */ |
438 | .matches = { | 431 | .matches = { |
439 | DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), | 432 | DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), |
440 | DMI_MATCH(DMI_PRODUCT_NAME, "E1210"), | 433 | DMI_MATCH(DMI_PRODUCT_NAME, "E1210"), |
441 | }, | 434 | }, |
442 | }, | 435 | }, |
443 | { | 436 | { |
444 | .ident = "Mivvy M310", | 437 | /* Mivvy M310 */ |
445 | .matches = { | 438 | .matches = { |
446 | DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), | 439 | DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), |
447 | DMI_MATCH(DMI_PRODUCT_NAME, "N10"), | 440 | DMI_MATCH(DMI_PRODUCT_NAME, "N10"), |
448 | }, | 441 | }, |
449 | }, | 442 | }, |
450 | { | 443 | { |
451 | .ident = "Dell Vostro 1320", | 444 | /* Dell Vostro 1320 */ |
452 | .matches = { | 445 | .matches = { |
453 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 446 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
454 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"), | 447 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"), |
455 | }, | 448 | }, |
456 | }, | 449 | }, |
457 | { | 450 | { |
458 | .ident = "Dell Vostro 1520", | 451 | /* Dell Vostro 1520 */ |
459 | .matches = { | 452 | .matches = { |
460 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 453 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
461 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"), | 454 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"), |
462 | }, | 455 | }, |
463 | }, | 456 | }, |
464 | { | 457 | { |
465 | .ident = "Dell Vostro 1720", | 458 | /* Dell Vostro 1720 */ |
466 | .matches = { | 459 | .matches = { |
467 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 460 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
468 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"), | 461 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"), |
@@ -472,16 +465,16 @@ static struct dmi_system_id __initdata i8042_dmi_reset_table[] = { | |||
472 | }; | 465 | }; |
473 | 466 | ||
474 | #ifdef CONFIG_PNP | 467 | #ifdef CONFIG_PNP |
475 | static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { | 468 | static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = { |
476 | { | 469 | { |
477 | .ident = "Intel MBO Desktop D845PESV", | 470 | /* Intel MBO Desktop D845PESV */ |
478 | .matches = { | 471 | .matches = { |
479 | DMI_MATCH(DMI_BOARD_NAME, "D845PESV"), | 472 | DMI_MATCH(DMI_BOARD_NAME, "D845PESV"), |
480 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), | 473 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), |
481 | }, | 474 | }, |
482 | }, | 475 | }, |
483 | { | 476 | { |
484 | .ident = "MSI Wind U-100", | 477 | /* MSI Wind U-100 */ |
485 | .matches = { | 478 | .matches = { |
486 | DMI_MATCH(DMI_BOARD_NAME, "U-100"), | 479 | DMI_MATCH(DMI_BOARD_NAME, "U-100"), |
487 | DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), | 480 | DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), |
@@ -490,27 +483,23 @@ static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { | |||
490 | { } | 483 | { } |
491 | }; | 484 | }; |
492 | 485 | ||
493 | static struct dmi_system_id __initdata i8042_dmi_laptop_table[] = { | 486 | static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = { |
494 | { | 487 | { |
495 | .ident = "Portable", | ||
496 | .matches = { | 488 | .matches = { |
497 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 489 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ |
498 | }, | 490 | }, |
499 | }, | 491 | }, |
500 | { | 492 | { |
501 | .ident = "Laptop", | ||
502 | .matches = { | 493 | .matches = { |
503 | DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */ | 494 | DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */ |
504 | }, | 495 | }, |
505 | }, | 496 | }, |
506 | { | 497 | { |
507 | .ident = "Notebook", | ||
508 | .matches = { | 498 | .matches = { |
509 | DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ | 499 | DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ |
510 | }, | 500 | }, |
511 | }, | 501 | }, |
512 | { | 502 | { |
513 | .ident = "Sub-Notebook", | ||
514 | .matches = { | 503 | .matches = { |
515 | DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */ | 504 | DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */ |
516 | }, | 505 | }, |
@@ -525,58 +514,58 @@ static struct dmi_system_id __initdata i8042_dmi_laptop_table[] = { | |||
525 | * Originally, this was just confined to older laptops, but a few Acer laptops | 514 | * Originally, this was just confined to older laptops, but a few Acer laptops |
526 | * have turned up in 2007 that also need this again. | 515 | * have turned up in 2007 that also need this again. |
527 | */ | 516 | */ |
528 | static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = { | 517 | static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { |
529 | { | 518 | { |
530 | .ident = "Acer Aspire 5630", | 519 | /* Acer Aspire 5630 */ |
531 | .matches = { | 520 | .matches = { |
532 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 521 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
533 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), | 522 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), |
534 | }, | 523 | }, |
535 | }, | 524 | }, |
536 | { | 525 | { |
537 | .ident = "Acer Aspire 5650", | 526 | /* Acer Aspire 5650 */ |
538 | .matches = { | 527 | .matches = { |
539 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 528 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
540 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), | 529 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), |
541 | }, | 530 | }, |
542 | }, | 531 | }, |
543 | { | 532 | { |
544 | .ident = "Acer Aspire 5680", | 533 | /* Acer Aspire 5680 */ |
545 | .matches = { | 534 | .matches = { |
546 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 535 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
547 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), | 536 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), |
548 | }, | 537 | }, |
549 | }, | 538 | }, |
550 | { | 539 | { |
551 | .ident = "Acer Aspire 5720", | 540 | /* Acer Aspire 5720 */ |
552 | .matches = { | 541 | .matches = { |
553 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 542 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
554 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), | 543 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), |
555 | }, | 544 | }, |
556 | }, | 545 | }, |
557 | { | 546 | { |
558 | .ident = "Acer Aspire 9110", | 547 | /* Acer Aspire 9110 */ |
559 | .matches = { | 548 | .matches = { |
560 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 549 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
561 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), | 550 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), |
562 | }, | 551 | }, |
563 | }, | 552 | }, |
564 | { | 553 | { |
565 | .ident = "Acer TravelMate 660", | 554 | /* Acer TravelMate 660 */ |
566 | .matches = { | 555 | .matches = { |
567 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 556 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
568 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"), | 557 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"), |
569 | }, | 558 | }, |
570 | }, | 559 | }, |
571 | { | 560 | { |
572 | .ident = "Acer TravelMate 2490", | 561 | /* Acer TravelMate 2490 */ |
573 | .matches = { | 562 | .matches = { |
574 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 563 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
575 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), | 564 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), |
576 | }, | 565 | }, |
577 | }, | 566 | }, |
578 | { | 567 | { |
579 | .ident = "Acer TravelMate 4280", | 568 | /* Acer TravelMate 4280 */ |
580 | .matches = { | 569 | .matches = { |
581 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 570 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
582 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"), | 571 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"), |
diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c new file mode 100644 index 000000000000..fbd3987af57f --- /dev/null +++ b/drivers/input/sparse-keymap.c | |||
@@ -0,0 +1,250 @@ | |||
1 | /* | ||
2 | * Generic support for sparse keymaps | ||
3 | * | ||
4 | * Copyright (c) 2009 Dmitry Torokhov | ||
5 | * | ||
6 | * Derived from wistron button driver: | ||
7 | * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz> | ||
8 | * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org> | ||
9 | * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License version 2 as published by | ||
13 | * the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/input.h> | ||
17 | #include <linux/input/sparse-keymap.h> | ||
18 | |||
19 | MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); | ||
20 | MODULE_DESCRIPTION("Generic support for sparse keymaps"); | ||
21 | MODULE_LICENSE("GPL v2"); | ||
22 | MODULE_VERSION("0.1"); | ||
23 | |||
24 | /** | ||
25 | * sparse_keymap_entry_from_scancode - perform sparse keymap lookup | ||
26 | * @dev: Input device using sparse keymap | ||
27 | * @code: Scan code | ||
28 | * | ||
29 | * This function is used to perform &struct key_entry lookup in an | ||
30 | * input device using sparse keymap. | ||
31 | */ | ||
32 | struct key_entry *sparse_keymap_entry_from_scancode(struct input_dev *dev, | ||
33 | unsigned int code) | ||
34 | { | ||
35 | struct key_entry *key; | ||
36 | |||
37 | for (key = dev->keycode; key->type != KE_END; key++) | ||
38 | if (code == key->code) | ||
39 | return key; | ||
40 | |||
41 | return NULL; | ||
42 | } | ||
43 | EXPORT_SYMBOL(sparse_keymap_entry_from_scancode); | ||
44 | |||
45 | /** | ||
46 | * sparse_keymap_entry_from_keycode - perform sparse keymap lookup | ||
47 | * @dev: Input device using sparse keymap | ||
48 | * @keycode: Key code | ||
49 | * | ||
50 | * This function is used to perform &struct key_entry lookup in an | ||
51 | * input device using sparse keymap. | ||
52 | */ | ||
53 | struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev, | ||
54 | unsigned int keycode) | ||
55 | { | ||
56 | struct key_entry *key; | ||
57 | |||
58 | for (key = dev->keycode; key->type != KE_END; key++) | ||
59 | if (key->type == KE_KEY && keycode == key->keycode) | ||
60 | return key; | ||
61 | |||
62 | return NULL; | ||
63 | } | ||
64 | EXPORT_SYMBOL(sparse_keymap_entry_from_keycode); | ||
65 | |||
66 | static int sparse_keymap_getkeycode(struct input_dev *dev, | ||
67 | int scancode, int *keycode) | ||
68 | { | ||
69 | const struct key_entry *key = | ||
70 | sparse_keymap_entry_from_scancode(dev, scancode); | ||
71 | |||
72 | if (key && key->type == KE_KEY) { | ||
73 | *keycode = key->keycode; | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | return -EINVAL; | ||
78 | } | ||
79 | |||
80 | static int sparse_keymap_setkeycode(struct input_dev *dev, | ||
81 | int scancode, int keycode) | ||
82 | { | ||
83 | struct key_entry *key; | ||
84 | int old_keycode; | ||
85 | |||
86 | if (keycode < 0 || keycode > KEY_MAX) | ||
87 | return -EINVAL; | ||
88 | |||
89 | key = sparse_keymap_entry_from_scancode(dev, scancode); | ||
90 | if (key && key->type == KE_KEY) { | ||
91 | old_keycode = key->keycode; | ||
92 | key->keycode = keycode; | ||
93 | set_bit(keycode, dev->keybit); | ||
94 | if (!sparse_keymap_entry_from_keycode(dev, old_keycode)) | ||
95 | clear_bit(old_keycode, dev->keybit); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | return -EINVAL; | ||
100 | } | ||
101 | |||
102 | /** | ||
103 | * sparse_keymap_setup - set up sparse keymap for an input device | ||
104 | * @dev: Input device | ||
105 | * @keymap: Keymap in form of array of &key_entry structures ending | ||
106 | * with %KE_END type entry | ||
107 | * @setup: Function that can be used to adjust keymap entries | ||
108 | * depending on device's deeds, may be %NULL | ||
109 | * | ||
110 | * The function calculates size and allocates copy of the original | ||
111 | * keymap after which sets up input device event bits appropriately. | ||
112 | * Before destroying input device allocated keymap should be freed | ||
113 | * with a call to sparse_keymap_free(). | ||
114 | */ | ||
115 | int sparse_keymap_setup(struct input_dev *dev, | ||
116 | const struct key_entry *keymap, | ||
117 | int (*setup)(struct input_dev *, struct key_entry *)) | ||
118 | { | ||
119 | size_t map_size = 1; /* to account for the last KE_END entry */ | ||
120 | const struct key_entry *e; | ||
121 | struct key_entry *map, *entry; | ||
122 | int i; | ||
123 | int error; | ||
124 | |||
125 | for (e = keymap; e->type != KE_END; e++) | ||
126 | map_size++; | ||
127 | |||
128 | map = kcalloc(map_size, sizeof (struct key_entry), GFP_KERNEL); | ||
129 | if (!map) | ||
130 | return -ENOMEM; | ||
131 | |||
132 | memcpy(map, keymap, map_size * sizeof (struct key_entry)); | ||
133 | |||
134 | for (i = 0; i < map_size; i++) { | ||
135 | entry = &map[i]; | ||
136 | |||
137 | if (setup) { | ||
138 | error = setup(dev, entry); | ||
139 | if (error) | ||
140 | goto err_out; | ||
141 | } | ||
142 | |||
143 | switch (entry->type) { | ||
144 | case KE_KEY: | ||
145 | __set_bit(EV_KEY, dev->evbit); | ||
146 | __set_bit(entry->keycode, dev->keybit); | ||
147 | break; | ||
148 | |||
149 | case KE_SW: | ||
150 | __set_bit(EV_SW, dev->evbit); | ||
151 | __set_bit(entry->sw.code, dev->swbit); | ||
152 | break; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | dev->keycode = map; | ||
157 | dev->keycodemax = map_size; | ||
158 | dev->getkeycode = sparse_keymap_getkeycode; | ||
159 | dev->setkeycode = sparse_keymap_setkeycode; | ||
160 | |||
161 | return 0; | ||
162 | |||
163 | err_out: | ||
164 | kfree(keymap); | ||
165 | return error; | ||
166 | |||
167 | } | ||
168 | EXPORT_SYMBOL(sparse_keymap_setup); | ||
169 | |||
170 | /** | ||
171 | * sparse_keymap_free - free memory allocated for sparse keymap | ||
172 | * @dev: Input device using sparse keymap | ||
173 | * | ||
174 | * This function is used to free memory allocated by sparse keymap | ||
175 | * in an input device that was set up by sparse_keymap_setup(). | ||
176 | */ | ||
177 | void sparse_keymap_free(struct input_dev *dev) | ||
178 | { | ||
179 | kfree(dev->keycode); | ||
180 | dev->keycode = NULL; | ||
181 | dev->keycodemax = 0; | ||
182 | dev->getkeycode = NULL; | ||
183 | dev->setkeycode = NULL; | ||
184 | } | ||
185 | EXPORT_SYMBOL(sparse_keymap_free); | ||
186 | |||
187 | /** | ||
188 | * sparse_keymap_report_entry - report event corresponding to given key entry | ||
189 | * @dev: Input device for which event should be reported | ||
190 | * @ke: key entry describing event | ||
191 | * @value: Value that should be reported (ignored by %KE_SW entries) | ||
192 | * @autorelease: Signals whether release event should be emitted for %KE_KEY | ||
193 | * entries right after reporting press event, ignored by all other | ||
194 | * entries | ||
195 | * | ||
196 | * This function is used to report input event described by given | ||
197 | * &struct key_entry. | ||
198 | */ | ||
199 | void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke, | ||
200 | unsigned int value, bool autorelease) | ||
201 | { | ||
202 | switch (ke->type) { | ||
203 | case KE_KEY: | ||
204 | input_report_key(dev, ke->keycode, value); | ||
205 | input_sync(dev); | ||
206 | if (value && autorelease) { | ||
207 | input_report_key(dev, ke->keycode, 0); | ||
208 | input_sync(dev); | ||
209 | } | ||
210 | break; | ||
211 | |||
212 | case KE_SW: | ||
213 | value = ke->sw.value; | ||
214 | /* fall through */ | ||
215 | |||
216 | case KE_VSW: | ||
217 | input_report_switch(dev, ke->sw.code, value); | ||
218 | break; | ||
219 | } | ||
220 | } | ||
221 | EXPORT_SYMBOL(sparse_keymap_report_entry); | ||
222 | |||
223 | /** | ||
224 | * sparse_keymap_report_event - report event corresponding to given scancode | ||
225 | * @dev: Input device using sparse keymap | ||
226 | * @code: Scan code | ||
227 | * @value: Value that should be reported (ignored by %KE_SW entries) | ||
228 | * @autorelease: Signals whether release event should be emitted for %KE_KEY | ||
229 | * entries right after reporting press event, ignored by all other | ||
230 | * entries | ||
231 | * | ||
232 | * This function is used to perform lookup in an input device using sparse | ||
233 | * keymap and report corresponding event. Returns %true if lookup was | ||
234 | * successful and %false otherwise. | ||
235 | */ | ||
236 | bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code, | ||
237 | unsigned int value, bool autorelease) | ||
238 | { | ||
239 | const struct key_entry *ke = | ||
240 | sparse_keymap_entry_from_scancode(dev, code); | ||
241 | |||
242 | if (ke) { | ||
243 | sparse_keymap_report_entry(dev, ke, value, autorelease); | ||
244 | return true; | ||
245 | } | ||
246 | |||
247 | return false; | ||
248 | } | ||
249 | EXPORT_SYMBOL(sparse_keymap_report_event); | ||
250 | |||
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 8cc453c85ea7..32fc8ba039aa 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -111,6 +111,18 @@ config TOUCHSCREEN_DA9034 | |||
111 | Say Y here to enable the support for the touchscreen found | 111 | Say Y here to enable the support for the touchscreen found |
112 | on Dialog Semiconductor DA9034 PMIC. | 112 | on Dialog Semiconductor DA9034 PMIC. |
113 | 113 | ||
114 | config TOUCHSCREEN_DYNAPRO | ||
115 | tristate "Dynapro serial touchscreen" | ||
116 | select SERIO | ||
117 | help | ||
118 | Say Y here if you have a Dynapro serial touchscreen connected to | ||
119 | your system. | ||
120 | |||
121 | If unsure, say N. | ||
122 | |||
123 | To compile this driver as a module, choose M here: the | ||
124 | module will be called dynapro. | ||
125 | |||
114 | config TOUCHSCREEN_EETI | 126 | config TOUCHSCREEN_EETI |
115 | tristate "EETI touchscreen panel support" | 127 | tristate "EETI touchscreen panel support" |
116 | depends on I2C | 128 | depends on I2C |
@@ -133,6 +145,18 @@ config TOUCHSCREEN_FUJITSU | |||
133 | To compile this driver as a module, choose M here: the | 145 | To compile this driver as a module, choose M here: the |
134 | module will be called fujitsu-ts. | 146 | module will be called fujitsu-ts. |
135 | 147 | ||
148 | config TOUCHSCREEN_S3C2410 | ||
149 | tristate "Samsung S3C2410 touchscreen input driver" | ||
150 | depends on ARCH_S3C2410 | ||
151 | select S3C24XX_ADC | ||
152 | help | ||
153 | Say Y here if you have the s3c2410 touchscreen. | ||
154 | |||
155 | If unsure, say N. | ||
156 | |||
157 | To compile this driver as a module, choose M here: the | ||
158 | module will be called s3c2410_ts. | ||
159 | |||
136 | config TOUCHSCREEN_GUNZE | 160 | config TOUCHSCREEN_GUNZE |
137 | tristate "Gunze AHL-51S touchscreen" | 161 | tristate "Gunze AHL-51S touchscreen" |
138 | select SERIO | 162 | select SERIO |
@@ -297,7 +321,7 @@ config TOUCHSCREEN_TOUCHWIN | |||
297 | 321 | ||
298 | config TOUCHSCREEN_ATMEL_TSADCC | 322 | config TOUCHSCREEN_ATMEL_TSADCC |
299 | tristate "Atmel Touchscreen Interface" | 323 | tristate "Atmel Touchscreen Interface" |
300 | depends on ARCH_AT91SAM9RL | 324 | depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 |
301 | help | 325 | help |
302 | Say Y here if you have a 4-wire touchscreen connected to the | 326 | Say Y here if you have a 4-wire touchscreen connected to the |
303 | ADC Controller on your Atmel SoC (such as the AT91SAM9RL). | 327 | ADC Controller on your Atmel SoC (such as the AT91SAM9RL). |
@@ -418,6 +442,7 @@ config TOUCHSCREEN_USB_COMPOSITE | |||
418 | - IdealTEK URTC1000 | 442 | - IdealTEK URTC1000 |
419 | - GoTop Super_Q2/GogoPen/PenPower tablets | 443 | - GoTop Super_Q2/GogoPen/PenPower tablets |
420 | - JASTEC USB Touch Controller/DigiTech DTR-02U | 444 | - JASTEC USB Touch Controller/DigiTech DTR-02U |
445 | - Zytronic controllers | ||
421 | 446 | ||
422 | Have a look at <http://linux.chapter7.ch/touchkit/> for | 447 | Have a look at <http://linux.chapter7.ch/touchkit/> for |
423 | a usage description and the required user-space stuff. | 448 | a usage description and the required user-space stuff. |
@@ -490,6 +515,16 @@ config TOUCHSCREEN_USB_E2I | |||
490 | bool "e2i Touchscreen controller (e.g. from Mimo 740)" | 515 | bool "e2i Touchscreen controller (e.g. from Mimo 740)" |
491 | depends on TOUCHSCREEN_USB_COMPOSITE | 516 | depends on TOUCHSCREEN_USB_COMPOSITE |
492 | 517 | ||
518 | config TOUCHSCREEN_USB_ZYTRONIC | ||
519 | default y | ||
520 | bool "Zytronic controller" if EMBEDDED | ||
521 | depends on TOUCHSCREEN_USB_COMPOSITE | ||
522 | |||
523 | config TOUCHSCREEN_USB_ETT_TC5UH | ||
524 | default y | ||
525 | bool "ET&T TC5UH touchscreen controler support" if EMBEDDED | ||
526 | depends on TOUCHSCREEN_USB_COMPOSITE | ||
527 | |||
493 | config TOUCHSCREEN_TOUCHIT213 | 528 | config TOUCHSCREEN_TOUCHIT213 |
494 | tristate "Sahara TouchIT-213 touchscreen" | 529 | tristate "Sahara TouchIT-213 touchscreen" |
495 | select SERIO | 530 | select SERIO |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 15fa62cffc77..f1f59c9e1211 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -12,6 +12,7 @@ obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o | |||
12 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o | 12 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o |
13 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o | 13 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o |
14 | obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o | 14 | obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o |
15 | obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o | ||
15 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o | 16 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o |
16 | obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o | 17 | obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o |
17 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o | 18 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o |
@@ -25,7 +26,9 @@ obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o | |||
25 | obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o | 26 | obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o |
26 | obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o | 27 | obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o |
27 | obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o | 28 | obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o |
29 | obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o | ||
28 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o | 30 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o |
31 | obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o | ||
29 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o | 32 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o |
30 | obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o | 33 | obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o |
31 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o | 34 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o |
@@ -41,4 +44,3 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o | |||
41 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o | 44 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o |
42 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o | 45 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o |
43 | obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o | 46 | obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o |
44 | obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o | ||
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 09c810999b92..52d2ca147d8f 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -29,10 +29,9 @@ | |||
29 | #include <linux/spi/ads7846.h> | 29 | #include <linux/spi/ads7846.h> |
30 | #include <asm/irq.h> | 30 | #include <asm/irq.h> |
31 | 31 | ||
32 | |||
33 | /* | 32 | /* |
34 | * This code has been heavily tested on a Nokia 770, and lightly | 33 | * This code has been heavily tested on a Nokia 770, and lightly |
35 | * tested on other ads7846 devices (OSK/Mistral, Lubbock). | 34 | * tested on other ads7846 devices (OSK/Mistral, Lubbock, Spitz). |
36 | * TSC2046 is just newer ads7846 silicon. | 35 | * TSC2046 is just newer ads7846 silicon. |
37 | * Support for ads7843 tested on Atmel at91sam926x-EK. | 36 | * Support for ads7843 tested on Atmel at91sam926x-EK. |
38 | * Support for ads7845 has only been stubbed in. | 37 | * Support for ads7845 has only been stubbed in. |
@@ -43,7 +42,7 @@ | |||
43 | * have to maintain our own SW IRQ disabled status. This should be | 42 | * have to maintain our own SW IRQ disabled status. This should be |
44 | * removed as soon as the affected platform's IRQ handling is fixed. | 43 | * removed as soon as the affected platform's IRQ handling is fixed. |
45 | * | 44 | * |
46 | * app note sbaa036 talks in more detail about accurate sampling... | 45 | * App note sbaa036 talks in more detail about accurate sampling... |
47 | * that ought to help in situations like LCDs inducing noise (which | 46 | * that ought to help in situations like LCDs inducing noise (which |
48 | * can also be helped by using synch signals) and more generally. | 47 | * can also be helped by using synch signals) and more generally. |
49 | * This driver tries to utilize the measures described in the app | 48 | * This driver tries to utilize the measures described in the app |
@@ -566,10 +565,8 @@ static void ads7846_rx(void *ads) | |||
566 | * once more the measurement | 565 | * once more the measurement |
567 | */ | 566 | */ |
568 | if (packet->tc.ignore || Rt > ts->pressure_max) { | 567 | if (packet->tc.ignore || Rt > ts->pressure_max) { |
569 | #ifdef VERBOSE | 568 | dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n", |
570 | pr_debug("%s: ignored %d pressure %d\n", | 569 | packet->tc.ignore, Rt); |
571 | dev_name(&ts->spi->dev), packet->tc.ignore, Rt); | ||
572 | #endif | ||
573 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), | 570 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), |
574 | HRTIMER_MODE_REL); | 571 | HRTIMER_MODE_REL); |
575 | return; | 572 | return; |
@@ -598,9 +595,7 @@ static void ads7846_rx(void *ads) | |||
598 | if (!ts->pendown) { | 595 | if (!ts->pendown) { |
599 | input_report_key(input, BTN_TOUCH, 1); | 596 | input_report_key(input, BTN_TOUCH, 1); |
600 | ts->pendown = 1; | 597 | ts->pendown = 1; |
601 | #ifdef VERBOSE | 598 | dev_vdbg(&ts->spi->dev, "DOWN\n"); |
602 | dev_dbg(&ts->spi->dev, "DOWN\n"); | ||
603 | #endif | ||
604 | } | 599 | } |
605 | 600 | ||
606 | if (ts->swap_xy) | 601 | if (ts->swap_xy) |
@@ -608,12 +603,10 @@ static void ads7846_rx(void *ads) | |||
608 | 603 | ||
609 | input_report_abs(input, ABS_X, x); | 604 | input_report_abs(input, ABS_X, x); |
610 | input_report_abs(input, ABS_Y, y); | 605 | input_report_abs(input, ABS_Y, y); |
611 | input_report_abs(input, ABS_PRESSURE, Rt); | 606 | input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt); |
612 | 607 | ||
613 | input_sync(input); | 608 | input_sync(input); |
614 | #ifdef VERBOSE | 609 | dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); |
615 | dev_dbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); | ||
616 | #endif | ||
617 | } | 610 | } |
618 | 611 | ||
619 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), | 612 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), |
@@ -723,9 +716,7 @@ static enum hrtimer_restart ads7846_timer(struct hrtimer *handle) | |||
723 | input_sync(input); | 716 | input_sync(input); |
724 | 717 | ||
725 | ts->pendown = 0; | 718 | ts->pendown = 0; |
726 | #ifdef VERBOSE | 719 | dev_vdbg(&ts->spi->dev, "UP\n"); |
727 | dev_dbg(&ts->spi->dev, "UP\n"); | ||
728 | #endif | ||
729 | } | 720 | } |
730 | 721 | ||
731 | /* measurement cycle ended */ | 722 | /* measurement cycle ended */ |
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c index 9c7fce4d74d0..3d9b5166ebe9 100644 --- a/drivers/input/touchscreen/atmel_tsadcc.c +++ b/drivers/input/touchscreen/atmel_tsadcc.c | |||
@@ -22,6 +22,8 @@ | |||
22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <mach/board.h> | ||
26 | #include <mach/cpu.h> | ||
25 | 27 | ||
26 | /* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */ | 28 | /* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */ |
27 | 29 | ||
@@ -36,7 +38,9 @@ | |||
36 | #define ATMEL_TSADCC_LOWRES (1 << 4) /* Resolution selection */ | 38 | #define ATMEL_TSADCC_LOWRES (1 << 4) /* Resolution selection */ |
37 | #define ATMEL_TSADCC_SLEEP (1 << 5) /* Sleep mode */ | 39 | #define ATMEL_TSADCC_SLEEP (1 << 5) /* Sleep mode */ |
38 | #define ATMEL_TSADCC_PENDET (1 << 6) /* Pen Detect selection */ | 40 | #define ATMEL_TSADCC_PENDET (1 << 6) /* Pen Detect selection */ |
41 | #define ATMEL_TSADCC_PRES (1 << 7) /* Pressure Measurement Selection */ | ||
39 | #define ATMEL_TSADCC_PRESCAL (0x3f << 8) /* Prescalar Rate Selection */ | 42 | #define ATMEL_TSADCC_PRESCAL (0x3f << 8) /* Prescalar Rate Selection */ |
43 | #define ATMEL_TSADCC_EPRESCAL (0xff << 8) /* Prescalar Rate Selection (Extended) */ | ||
40 | #define ATMEL_TSADCC_STARTUP (0x7f << 16) /* Start Up time */ | 44 | #define ATMEL_TSADCC_STARTUP (0x7f << 16) /* Start Up time */ |
41 | #define ATMEL_TSADCC_SHTIM (0xf << 24) /* Sample & Hold time */ | 45 | #define ATMEL_TSADCC_SHTIM (0xf << 24) /* Sample & Hold time */ |
42 | #define ATMEL_TSADCC_PENDBC (0xf << 28) /* Pen Detect debouncing time */ | 46 | #define ATMEL_TSADCC_PENDBC (0xf << 28) /* Pen Detect debouncing time */ |
@@ -84,7 +88,13 @@ | |||
84 | #define ATMEL_TSADCC_CDR4 0x40 /* Channel Data 4 */ | 88 | #define ATMEL_TSADCC_CDR4 0x40 /* Channel Data 4 */ |
85 | #define ATMEL_TSADCC_CDR5 0x44 /* Channel Data 5 */ | 89 | #define ATMEL_TSADCC_CDR5 0x44 /* Channel Data 5 */ |
86 | 90 | ||
87 | #define ADC_CLOCK 1000000 | 91 | #define ATMEL_TSADCC_XPOS 0x50 |
92 | #define ATMEL_TSADCC_Z1DAT 0x54 | ||
93 | #define ATMEL_TSADCC_Z2DAT 0x58 | ||
94 | |||
95 | #define PRESCALER_VAL(x) ((x) >> 8) | ||
96 | |||
97 | #define ADC_DEFAULT_CLOCK 100000 | ||
88 | 98 | ||
89 | struct atmel_tsadcc { | 99 | struct atmel_tsadcc { |
90 | struct input_dev *input; | 100 | struct input_dev *input; |
@@ -172,6 +182,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev) | |||
172 | struct atmel_tsadcc *ts_dev; | 182 | struct atmel_tsadcc *ts_dev; |
173 | struct input_dev *input_dev; | 183 | struct input_dev *input_dev; |
174 | struct resource *res; | 184 | struct resource *res; |
185 | struct at91_tsadcc_data *pdata = pdev->dev.platform_data; | ||
175 | int err = 0; | 186 | int err = 0; |
176 | unsigned int prsc; | 187 | unsigned int prsc; |
177 | unsigned int reg; | 188 | unsigned int reg; |
@@ -242,31 +253,49 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev) | |||
242 | input_dev->phys = ts_dev->phys; | 253 | input_dev->phys = ts_dev->phys; |
243 | input_dev->dev.parent = &pdev->dev; | 254 | input_dev->dev.parent = &pdev->dev; |
244 | 255 | ||
245 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 256 | __set_bit(EV_ABS, input_dev->evbit); |
246 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
247 | |||
248 | input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0); | 257 | input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0); |
249 | input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0); | 258 | input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0); |
250 | 259 | ||
260 | input_set_capability(input_dev, EV_KEY, BTN_TOUCH); | ||
261 | |||
251 | /* clk_enable() always returns 0, no need to check it */ | 262 | /* clk_enable() always returns 0, no need to check it */ |
252 | clk_enable(ts_dev->clk); | 263 | clk_enable(ts_dev->clk); |
253 | 264 | ||
254 | prsc = clk_get_rate(ts_dev->clk); | 265 | prsc = clk_get_rate(ts_dev->clk); |
255 | dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc); | 266 | dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc); |
256 | 267 | ||
257 | prsc = prsc / ADC_CLOCK / 2 - 1; | 268 | if (!pdata) |
269 | goto err_fail; | ||
270 | |||
271 | if (!pdata->adc_clock) | ||
272 | pdata->adc_clock = ADC_DEFAULT_CLOCK; | ||
273 | |||
274 | prsc = (prsc / (2 * pdata->adc_clock)) - 1; | ||
275 | |||
276 | /* saturate if this value is too high */ | ||
277 | if (cpu_is_at91sam9rl()) { | ||
278 | if (prsc > PRESCALER_VAL(ATMEL_TSADCC_PRESCAL)) | ||
279 | prsc = PRESCALER_VAL(ATMEL_TSADCC_PRESCAL); | ||
280 | } else { | ||
281 | if (prsc > PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL)) | ||
282 | prsc = PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL); | ||
283 | } | ||
284 | |||
285 | dev_info(&pdev->dev, "Prescaler is set at: %d\n", prsc); | ||
258 | 286 | ||
259 | reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE | | 287 | reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE | |
260 | ((0x00 << 5) & ATMEL_TSADCC_SLEEP) | /* Normal Mode */ | 288 | ((0x00 << 5) & ATMEL_TSADCC_SLEEP) | /* Normal Mode */ |
261 | ((0x01 << 6) & ATMEL_TSADCC_PENDET) | /* Enable Pen Detect */ | 289 | ((0x01 << 6) & ATMEL_TSADCC_PENDET) | /* Enable Pen Detect */ |
262 | ((prsc << 8) & ATMEL_TSADCC_PRESCAL) | /* PRESCAL */ | 290 | (prsc << 8) | |
263 | ((0x13 << 16) & ATMEL_TSADCC_STARTUP) | /* STARTUP */ | 291 | ((0x26 << 16) & ATMEL_TSADCC_STARTUP) | |
264 | ((0x0F << 28) & ATMEL_TSADCC_PENDBC); /* PENDBC */ | 292 | ((pdata->pendet_debounce << 28) & ATMEL_TSADCC_PENDBC); |
265 | 293 | ||
266 | atmel_tsadcc_write(ATMEL_TSADCC_CR, ATMEL_TSADCC_SWRST); | 294 | atmel_tsadcc_write(ATMEL_TSADCC_CR, ATMEL_TSADCC_SWRST); |
267 | atmel_tsadcc_write(ATMEL_TSADCC_MR, reg); | 295 | atmel_tsadcc_write(ATMEL_TSADCC_MR, reg); |
268 | atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE); | 296 | atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE); |
269 | atmel_tsadcc_write(ATMEL_TSADCC_TSR, (0x3 << 24) & ATMEL_TSADCC_TSSHTIM); | 297 | atmel_tsadcc_write(ATMEL_TSADCC_TSR, |
298 | (pdata->ts_sample_hold_time << 24) & ATMEL_TSADCC_TSSHTIM); | ||
270 | 299 | ||
271 | atmel_tsadcc_read(ATMEL_TSADCC_SR); | 300 | atmel_tsadcc_read(ATMEL_TSADCC_SR); |
272 | atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT); | 301 | atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT); |
diff --git a/drivers/input/touchscreen/dynapro.c b/drivers/input/touchscreen/dynapro.c new file mode 100644 index 000000000000..455353908bdf --- /dev/null +++ b/drivers/input/touchscreen/dynapro.c | |||
@@ -0,0 +1,206 @@ | |||
1 | /* | ||
2 | * Dynapro serial touchscreen driver | ||
3 | * | ||
4 | * Copyright (c) 2009 Tias Guns | ||
5 | * Based on the inexio driver (c) Vojtech Pavlik and Dan Streetman and | ||
6 | * Richard Lemon | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License version 2 as published by | ||
13 | * the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | * 2009/09/19 Tias Guns <tias@ulyssis.org> | ||
18 | * Copied inexio.c and edited for Dynapro protocol (from retired Xorg module) | ||
19 | */ | ||
20 | |||
21 | #include <linux/errno.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/input.h> | ||
26 | #include <linux/serio.h> | ||
27 | #include <linux/init.h> | ||
28 | |||
29 | #define DRIVER_DESC "Dynapro serial touchscreen driver" | ||
30 | |||
31 | MODULE_AUTHOR("Tias Guns <tias@ulyssis.org>"); | ||
32 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
33 | MODULE_LICENSE("GPL"); | ||
34 | |||
35 | /* | ||
36 | * Definitions & global arrays. | ||
37 | */ | ||
38 | |||
39 | #define DYNAPRO_FORMAT_TOUCH_BIT 0x40 | ||
40 | #define DYNAPRO_FORMAT_LENGTH 3 | ||
41 | #define DYNAPRO_RESPONSE_BEGIN_BYTE 0x80 | ||
42 | |||
43 | #define DYNAPRO_MIN_XC 0 | ||
44 | #define DYNAPRO_MAX_XC 0x3ff | ||
45 | #define DYNAPRO_MIN_YC 0 | ||
46 | #define DYNAPRO_MAX_YC 0x3ff | ||
47 | |||
48 | #define DYNAPRO_GET_XC(data) (data[1] | ((data[0] & 0x38) << 4)) | ||
49 | #define DYNAPRO_GET_YC(data) (data[2] | ((data[0] & 0x07) << 7)) | ||
50 | #define DYNAPRO_GET_TOUCHED(data) (DYNAPRO_FORMAT_TOUCH_BIT & data[0]) | ||
51 | |||
52 | /* | ||
53 | * Per-touchscreen data. | ||
54 | */ | ||
55 | |||
56 | struct dynapro { | ||
57 | struct input_dev *dev; | ||
58 | struct serio *serio; | ||
59 | int idx; | ||
60 | unsigned char data[DYNAPRO_FORMAT_LENGTH]; | ||
61 | char phys[32]; | ||
62 | }; | ||
63 | |||
64 | static void dynapro_process_data(struct dynapro *pdynapro) | ||
65 | { | ||
66 | struct input_dev *dev = pdynapro->dev; | ||
67 | |||
68 | if (DYNAPRO_FORMAT_LENGTH == ++pdynapro->idx) { | ||
69 | input_report_abs(dev, ABS_X, DYNAPRO_GET_XC(pdynapro->data)); | ||
70 | input_report_abs(dev, ABS_Y, DYNAPRO_GET_YC(pdynapro->data)); | ||
71 | input_report_key(dev, BTN_TOUCH, | ||
72 | DYNAPRO_GET_TOUCHED(pdynapro->data)); | ||
73 | input_sync(dev); | ||
74 | |||
75 | pdynapro->idx = 0; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | static irqreturn_t dynapro_interrupt(struct serio *serio, | ||
80 | unsigned char data, unsigned int flags) | ||
81 | { | ||
82 | struct dynapro *pdynapro = serio_get_drvdata(serio); | ||
83 | |||
84 | pdynapro->data[pdynapro->idx] = data; | ||
85 | |||
86 | if (DYNAPRO_RESPONSE_BEGIN_BYTE & pdynapro->data[0]) | ||
87 | dynapro_process_data(pdynapro); | ||
88 | else | ||
89 | dev_dbg(&serio->dev, "unknown/unsynchronized data: %x\n", | ||
90 | pdynapro->data[0]); | ||
91 | |||
92 | return IRQ_HANDLED; | ||
93 | } | ||
94 | |||
95 | static void dynapro_disconnect(struct serio *serio) | ||
96 | { | ||
97 | struct dynapro *pdynapro = serio_get_drvdata(serio); | ||
98 | |||
99 | input_get_device(pdynapro->dev); | ||
100 | input_unregister_device(pdynapro->dev); | ||
101 | serio_close(serio); | ||
102 | serio_set_drvdata(serio, NULL); | ||
103 | input_put_device(pdynapro->dev); | ||
104 | kfree(pdynapro); | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | * dynapro_connect() is the routine that is called when someone adds a | ||
109 | * new serio device that supports dynapro protocol and registers it as | ||
110 | * an input device. This is usually accomplished using inputattach. | ||
111 | */ | ||
112 | |||
113 | static int dynapro_connect(struct serio *serio, struct serio_driver *drv) | ||
114 | { | ||
115 | struct dynapro *pdynapro; | ||
116 | struct input_dev *input_dev; | ||
117 | int err; | ||
118 | |||
119 | pdynapro = kzalloc(sizeof(struct dynapro), GFP_KERNEL); | ||
120 | input_dev = input_allocate_device(); | ||
121 | if (!pdynapro || !input_dev) { | ||
122 | err = -ENOMEM; | ||
123 | goto fail1; | ||
124 | } | ||
125 | |||
126 | pdynapro->serio = serio; | ||
127 | pdynapro->dev = input_dev; | ||
128 | snprintf(pdynapro->phys, sizeof(pdynapro->phys), | ||
129 | "%s/input0", serio->phys); | ||
130 | |||
131 | input_dev->name = "Dynapro Serial TouchScreen"; | ||
132 | input_dev->phys = pdynapro->phys; | ||
133 | input_dev->id.bustype = BUS_RS232; | ||
134 | input_dev->id.vendor = SERIO_DYNAPRO; | ||
135 | input_dev->id.product = 0; | ||
136 | input_dev->id.version = 0x0001; | ||
137 | input_dev->dev.parent = &serio->dev; | ||
138 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
139 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
140 | input_set_abs_params(pdynapro->dev, ABS_X, | ||
141 | DYNAPRO_MIN_XC, DYNAPRO_MAX_XC, 0, 0); | ||
142 | input_set_abs_params(pdynapro->dev, ABS_Y, | ||
143 | DYNAPRO_MIN_YC, DYNAPRO_MAX_YC, 0, 0); | ||
144 | |||
145 | serio_set_drvdata(serio, pdynapro); | ||
146 | |||
147 | err = serio_open(serio, drv); | ||
148 | if (err) | ||
149 | goto fail2; | ||
150 | |||
151 | err = input_register_device(pdynapro->dev); | ||
152 | if (err) | ||
153 | goto fail3; | ||
154 | |||
155 | return 0; | ||
156 | |||
157 | fail3: serio_close(serio); | ||
158 | fail2: serio_set_drvdata(serio, NULL); | ||
159 | fail1: input_free_device(input_dev); | ||
160 | kfree(pdynapro); | ||
161 | return err; | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * The serio driver structure. | ||
166 | */ | ||
167 | |||
168 | static struct serio_device_id dynapro_serio_ids[] = { | ||
169 | { | ||
170 | .type = SERIO_RS232, | ||
171 | .proto = SERIO_DYNAPRO, | ||
172 | .id = SERIO_ANY, | ||
173 | .extra = SERIO_ANY, | ||
174 | }, | ||
175 | { 0 } | ||
176 | }; | ||
177 | |||
178 | MODULE_DEVICE_TABLE(serio, dynapro_serio_ids); | ||
179 | |||
180 | static struct serio_driver dynapro_drv = { | ||
181 | .driver = { | ||
182 | .name = "dynapro", | ||
183 | }, | ||
184 | .description = DRIVER_DESC, | ||
185 | .id_table = dynapro_serio_ids, | ||
186 | .interrupt = dynapro_interrupt, | ||
187 | .connect = dynapro_connect, | ||
188 | .disconnect = dynapro_disconnect, | ||
189 | }; | ||
190 | |||
191 | /* | ||
192 | * The functions for inserting/removing us as a module. | ||
193 | */ | ||
194 | |||
195 | static int __init dynapro_init(void) | ||
196 | { | ||
197 | return serio_register_driver(&dynapro_drv); | ||
198 | } | ||
199 | |||
200 | static void __exit dynapro_exit(void) | ||
201 | { | ||
202 | serio_unregister_driver(&dynapro_drv); | ||
203 | } | ||
204 | |||
205 | module_init(dynapro_init); | ||
206 | module_exit(dynapro_exit); | ||
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c new file mode 100644 index 000000000000..6386b441ef85 --- /dev/null +++ b/drivers/input/touchscreen/s3c2410_ts.c | |||
@@ -0,0 +1,457 @@ | |||
1 | /* | ||
2 | * Samsung S3C24XX touchscreen driver | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the term of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | * | ||
18 | * Copyright 2004 Arnaud Patard <arnaud.patard@rtp-net.org> | ||
19 | * Copyright 2008 Ben Dooks <ben-linux@fluff.org> | ||
20 | * Copyright 2009 Simtec Electronics <linux@simtec.co.uk> | ||
21 | * | ||
22 | * Additional work by Herbert Pötzl <herbert@13thfloor.at> and | ||
23 | * Harald Welte <laforge@openmoko.org> | ||
24 | */ | ||
25 | |||
26 | #include <linux/errno.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/gpio.h> | ||
31 | #include <linux/input.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/interrupt.h> | ||
35 | #include <linux/platform_device.h> | ||
36 | #include <linux/clk.h> | ||
37 | #include <linux/io.h> | ||
38 | |||
39 | #include <plat/adc.h> | ||
40 | #include <plat/regs-adc.h> | ||
41 | |||
42 | #include <mach/regs-gpio.h> | ||
43 | #include <mach/ts.h> | ||
44 | |||
45 | #define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0)) | ||
46 | |||
47 | #define INT_DOWN (0) | ||
48 | #define INT_UP (1 << 8) | ||
49 | |||
50 | #define WAIT4INT (S3C2410_ADCTSC_YM_SEN | \ | ||
51 | S3C2410_ADCTSC_YP_SEN | \ | ||
52 | S3C2410_ADCTSC_XP_SEN | \ | ||
53 | S3C2410_ADCTSC_XY_PST(3)) | ||
54 | |||
55 | #define AUTOPST (S3C2410_ADCTSC_YM_SEN | \ | ||
56 | S3C2410_ADCTSC_YP_SEN | \ | ||
57 | S3C2410_ADCTSC_XP_SEN | \ | ||
58 | S3C2410_ADCTSC_AUTO_PST | \ | ||
59 | S3C2410_ADCTSC_XY_PST(0)) | ||
60 | |||
61 | /* Per-touchscreen data. */ | ||
62 | |||
63 | /** | ||
64 | * struct s3c2410ts - driver touchscreen state. | ||
65 | * @client: The ADC client we registered with the core driver. | ||
66 | * @dev: The device we are bound to. | ||
67 | * @input: The input device we registered with the input subsystem. | ||
68 | * @clock: The clock for the adc. | ||
69 | * @io: Pointer to the IO base. | ||
70 | * @xp: The accumulated X position data. | ||
71 | * @yp: The accumulated Y position data. | ||
72 | * @irq_tc: The interrupt number for pen up/down interrupt | ||
73 | * @count: The number of samples collected. | ||
74 | * @shift: The log2 of the maximum count to read in one go. | ||
75 | */ | ||
76 | struct s3c2410ts { | ||
77 | struct s3c_adc_client *client; | ||
78 | struct device *dev; | ||
79 | struct input_dev *input; | ||
80 | struct clk *clock; | ||
81 | void __iomem *io; | ||
82 | unsigned long xp; | ||
83 | unsigned long yp; | ||
84 | int irq_tc; | ||
85 | int count; | ||
86 | int shift; | ||
87 | }; | ||
88 | |||
89 | static struct s3c2410ts ts; | ||
90 | |||
91 | /** | ||
92 | * s3c2410_ts_connect - configure gpio for s3c2410 systems | ||
93 | * | ||
94 | * Configure the GPIO for the S3C2410 system, where we have external FETs | ||
95 | * connected to the device (later systems such as the S3C2440 integrate | ||
96 | * these into the device). | ||
97 | */ | ||
98 | static inline void s3c2410_ts_connect(void) | ||
99 | { | ||
100 | s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON); | ||
101 | s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON); | ||
102 | s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON); | ||
103 | s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON); | ||
104 | } | ||
105 | |||
106 | /** | ||
107 | * get_down - return the down state of the pen | ||
108 | * @data0: The data read from ADCDAT0 register. | ||
109 | * @data1: The data read from ADCDAT1 register. | ||
110 | * | ||
111 | * Return non-zero if both readings show that the pen is down. | ||
112 | */ | ||
113 | static inline bool get_down(unsigned long data0, unsigned long data1) | ||
114 | { | ||
115 | /* returns true if both data values show stylus down */ | ||
116 | return (!(data0 & S3C2410_ADCDAT0_UPDOWN) && | ||
117 | !(data1 & S3C2410_ADCDAT0_UPDOWN)); | ||
118 | } | ||
119 | |||
120 | static void touch_timer_fire(unsigned long data) | ||
121 | { | ||
122 | unsigned long data0; | ||
123 | unsigned long data1; | ||
124 | bool down; | ||
125 | |||
126 | data0 = readl(ts.io + S3C2410_ADCDAT0); | ||
127 | data1 = readl(ts.io + S3C2410_ADCDAT1); | ||
128 | |||
129 | down = get_down(data0, data1); | ||
130 | |||
131 | if (ts.count == (1 << ts.shift)) { | ||
132 | ts.xp >>= ts.shift; | ||
133 | ts.yp >>= ts.shift; | ||
134 | |||
135 | dev_dbg(ts.dev, "%s: X=%lu, Y=%lu, count=%d\n", | ||
136 | __func__, ts.xp, ts.yp, ts.count); | ||
137 | |||
138 | input_report_abs(ts.input, ABS_X, ts.xp); | ||
139 | input_report_abs(ts.input, ABS_Y, ts.yp); | ||
140 | |||
141 | input_report_key(ts.input, BTN_TOUCH, 1); | ||
142 | input_sync(ts.input); | ||
143 | |||
144 | ts.xp = 0; | ||
145 | ts.yp = 0; | ||
146 | ts.count = 0; | ||
147 | } | ||
148 | |||
149 | if (down) { | ||
150 | s3c_adc_start(ts.client, 0, 1 << ts.shift); | ||
151 | } else { | ||
152 | ts.count = 0; | ||
153 | |||
154 | input_report_key(ts.input, BTN_TOUCH, 0); | ||
155 | input_sync(ts.input); | ||
156 | |||
157 | writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | static DEFINE_TIMER(touch_timer, touch_timer_fire, 0, 0); | ||
162 | |||
163 | /** | ||
164 | * stylus_irq - touchscreen stylus event interrupt | ||
165 | * @irq: The interrupt number | ||
166 | * @dev_id: The device ID. | ||
167 | * | ||
168 | * Called when the IRQ_TC is fired for a pen up or down event. | ||
169 | */ | ||
170 | static irqreturn_t stylus_irq(int irq, void *dev_id) | ||
171 | { | ||
172 | unsigned long data0; | ||
173 | unsigned long data1; | ||
174 | bool down; | ||
175 | |||
176 | data0 = readl(ts.io + S3C2410_ADCDAT0); | ||
177 | data1 = readl(ts.io + S3C2410_ADCDAT1); | ||
178 | |||
179 | down = get_down(data0, data1); | ||
180 | |||
181 | /* TODO we should never get an interrupt with down set while | ||
182 | * the timer is running, but maybe we ought to verify that the | ||
183 | * timer isn't running anyways. */ | ||
184 | |||
185 | if (down) | ||
186 | s3c_adc_start(ts.client, 0, 1 << ts.shift); | ||
187 | else | ||
188 | dev_info(ts.dev, "%s: count=%d\n", __func__, ts.count); | ||
189 | |||
190 | return IRQ_HANDLED; | ||
191 | } | ||
192 | |||
193 | /** | ||
194 | * s3c24xx_ts_conversion - ADC conversion callback | ||
195 | * @client: The client that was registered with the ADC core. | ||
196 | * @data0: The reading from ADCDAT0. | ||
197 | * @data1: The reading from ADCDAT1. | ||
198 | * @left: The number of samples left. | ||
199 | * | ||
200 | * Called when a conversion has finished. | ||
201 | */ | ||
202 | static void s3c24xx_ts_conversion(struct s3c_adc_client *client, | ||
203 | unsigned data0, unsigned data1, | ||
204 | unsigned *left) | ||
205 | { | ||
206 | dev_dbg(ts.dev, "%s: %d,%d\n", __func__, data0, data1); | ||
207 | |||
208 | ts.xp += data0; | ||
209 | ts.yp += data1; | ||
210 | |||
211 | ts.count++; | ||
212 | |||
213 | /* From tests, it seems that it is unlikely to get a pen-up | ||
214 | * event during the conversion process which means we can | ||
215 | * ignore any pen-up events with less than the requisite | ||
216 | * count done. | ||
217 | * | ||
218 | * In several thousand conversions, no pen-ups where detected | ||
219 | * before count completed. | ||
220 | */ | ||
221 | } | ||
222 | |||
223 | /** | ||
224 | * s3c24xx_ts_select - ADC selection callback. | ||
225 | * @client: The client that was registered with the ADC core. | ||
226 | * @select: The reason for select. | ||
227 | * | ||
228 | * Called when the ADC core selects (or deslects) us as a client. | ||
229 | */ | ||
230 | static void s3c24xx_ts_select(struct s3c_adc_client *client, unsigned select) | ||
231 | { | ||
232 | if (select) { | ||
233 | writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, | ||
234 | ts.io + S3C2410_ADCTSC); | ||
235 | } else { | ||
236 | mod_timer(&touch_timer, jiffies+1); | ||
237 | writel(WAIT4INT | INT_UP, ts.io + S3C2410_ADCTSC); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | /** | ||
242 | * s3c2410ts_probe - device core probe entry point | ||
243 | * @pdev: The device we are being bound to. | ||
244 | * | ||
245 | * Initialise, find and allocate any resources we need to run and then | ||
246 | * register with the ADC and input systems. | ||
247 | */ | ||
248 | static int __devinit s3c2410ts_probe(struct platform_device *pdev) | ||
249 | { | ||
250 | struct s3c2410_ts_mach_info *info; | ||
251 | struct device *dev = &pdev->dev; | ||
252 | struct input_dev *input_dev; | ||
253 | struct resource *res; | ||
254 | int ret = -EINVAL; | ||
255 | |||
256 | /* Initialise input stuff */ | ||
257 | memset(&ts, 0, sizeof(struct s3c2410ts)); | ||
258 | |||
259 | ts.dev = dev; | ||
260 | |||
261 | info = pdev->dev.platform_data; | ||
262 | if (!info) { | ||
263 | dev_err(dev, "no platform data, cannot attach\n"); | ||
264 | return -EINVAL; | ||
265 | } | ||
266 | |||
267 | dev_dbg(dev, "initialising touchscreen\n"); | ||
268 | |||
269 | ts.clock = clk_get(dev, "adc"); | ||
270 | if (IS_ERR(ts.clock)) { | ||
271 | dev_err(dev, "cannot get adc clock source\n"); | ||
272 | return -ENOENT; | ||
273 | } | ||
274 | |||
275 | clk_enable(ts.clock); | ||
276 | dev_dbg(dev, "got and enabled clocks\n"); | ||
277 | |||
278 | ts.irq_tc = ret = platform_get_irq(pdev, 0); | ||
279 | if (ret < 0) { | ||
280 | dev_err(dev, "no resource for interrupt\n"); | ||
281 | goto err_clk; | ||
282 | } | ||
283 | |||
284 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
285 | if (!res) { | ||
286 | dev_err(dev, "no resource for registers\n"); | ||
287 | ret = -ENOENT; | ||
288 | goto err_clk; | ||
289 | } | ||
290 | |||
291 | ts.io = ioremap(res->start, resource_size(res)); | ||
292 | if (ts.io == NULL) { | ||
293 | dev_err(dev, "cannot map registers\n"); | ||
294 | ret = -ENOMEM; | ||
295 | goto err_clk; | ||
296 | } | ||
297 | |||
298 | /* Configure the touchscreen external FETs on the S3C2410 */ | ||
299 | if (!platform_get_device_id(pdev)->driver_data) | ||
300 | s3c2410_ts_connect(); | ||
301 | |||
302 | ts.client = s3c_adc_register(pdev, s3c24xx_ts_select, | ||
303 | s3c24xx_ts_conversion, 1); | ||
304 | if (IS_ERR(ts.client)) { | ||
305 | dev_err(dev, "failed to register adc client\n"); | ||
306 | ret = PTR_ERR(ts.client); | ||
307 | goto err_iomap; | ||
308 | } | ||
309 | |||
310 | /* Initialise registers */ | ||
311 | if ((info->delay & 0xffff) > 0) | ||
312 | writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY); | ||
313 | |||
314 | writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC); | ||
315 | |||
316 | input_dev = input_allocate_device(); | ||
317 | if (!input_dev) { | ||
318 | dev_err(dev, "Unable to allocate the input device !!\n"); | ||
319 | ret = -ENOMEM; | ||
320 | goto err_iomap; | ||
321 | } | ||
322 | |||
323 | ts.input = input_dev; | ||
324 | ts.input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
325 | ts.input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
326 | input_set_abs_params(ts.input, ABS_X, 0, 0x3FF, 0, 0); | ||
327 | input_set_abs_params(ts.input, ABS_Y, 0, 0x3FF, 0, 0); | ||
328 | |||
329 | ts.input->name = "S3C24XX TouchScreen"; | ||
330 | ts.input->id.bustype = BUS_HOST; | ||
331 | ts.input->id.vendor = 0xDEAD; | ||
332 | ts.input->id.product = 0xBEEF; | ||
333 | ts.input->id.version = 0x0102; | ||
334 | |||
335 | ts.shift = info->oversampling_shift; | ||
336 | |||
337 | ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED, | ||
338 | "s3c2410_ts_pen", ts.input); | ||
339 | if (ret) { | ||
340 | dev_err(dev, "cannot get TC interrupt\n"); | ||
341 | goto err_inputdev; | ||
342 | } | ||
343 | |||
344 | dev_info(dev, "driver attached, registering input device\n"); | ||
345 | |||
346 | /* All went ok, so register to the input system */ | ||
347 | ret = input_register_device(ts.input); | ||
348 | if (ret < 0) { | ||
349 | dev_err(dev, "failed to register input device\n"); | ||
350 | ret = -EIO; | ||
351 | goto err_tcirq; | ||
352 | } | ||
353 | |||
354 | return 0; | ||
355 | |||
356 | err_tcirq: | ||
357 | free_irq(ts.irq_tc, ts.input); | ||
358 | err_inputdev: | ||
359 | input_unregister_device(ts.input); | ||
360 | err_iomap: | ||
361 | iounmap(ts.io); | ||
362 | err_clk: | ||
363 | del_timer_sync(&touch_timer); | ||
364 | clk_put(ts.clock); | ||
365 | return ret; | ||
366 | } | ||
367 | |||
368 | /** | ||
369 | * s3c2410ts_remove - device core removal entry point | ||
370 | * @pdev: The device we are being removed from. | ||
371 | * | ||
372 | * Free up our state ready to be removed. | ||
373 | */ | ||
374 | static int __devexit s3c2410ts_remove(struct platform_device *pdev) | ||
375 | { | ||
376 | free_irq(ts.irq_tc, ts.input); | ||
377 | del_timer_sync(&touch_timer); | ||
378 | |||
379 | clk_disable(ts.clock); | ||
380 | clk_put(ts.clock); | ||
381 | |||
382 | input_unregister_device(ts.input); | ||
383 | iounmap(ts.io); | ||
384 | |||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | #ifdef CONFIG_PM | ||
389 | static int s3c2410ts_suspend(struct device *dev) | ||
390 | { | ||
391 | writel(TSC_SLEEP, ts.io + S3C2410_ADCTSC); | ||
392 | disable_irq(ts.irq_tc); | ||
393 | clk_disable(ts.clock); | ||
394 | |||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int s3c2410ts_resume(struct device *dev) | ||
399 | { | ||
400 | struct platform_device *pdev = to_platform_device(dev); | ||
401 | struct s3c2410_ts_mach_info *info = pdev->dev.platform_data; | ||
402 | |||
403 | clk_enable(ts.clock); | ||
404 | |||
405 | /* Initialise registers */ | ||
406 | if ((info->delay & 0xffff) > 0) | ||
407 | writel(info->delay & 0xffff, ts.io + S3C2410_ADCDLY); | ||
408 | |||
409 | writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC); | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | static struct dev_pm_ops s3c_ts_pmops = { | ||
415 | .suspend = s3c2410ts_suspend, | ||
416 | .resume = s3c2410ts_resume, | ||
417 | }; | ||
418 | #endif | ||
419 | |||
420 | static struct platform_device_id s3cts_driver_ids[] = { | ||
421 | { "s3c2410-ts", 0 }, | ||
422 | { "s3c2440-ts", 1 }, | ||
423 | { } | ||
424 | }; | ||
425 | MODULE_DEVICE_TABLE(platform, s3cts_driver_ids); | ||
426 | |||
427 | static struct platform_driver s3c_ts_driver = { | ||
428 | .driver = { | ||
429 | .name = "s3c24xx-ts", | ||
430 | .owner = THIS_MODULE, | ||
431 | #ifdef CONFIG_PM | ||
432 | .pm = &s3c_ts_pmops, | ||
433 | #endif | ||
434 | }, | ||
435 | .id_table = s3cts_driver_ids, | ||
436 | .probe = s3c2410ts_probe, | ||
437 | .remove = __devexit_p(s3c2410ts_remove), | ||
438 | }; | ||
439 | |||
440 | static int __init s3c2410ts_init(void) | ||
441 | { | ||
442 | return platform_driver_register(&s3c_ts_driver); | ||
443 | } | ||
444 | |||
445 | static void __exit s3c2410ts_exit(void) | ||
446 | { | ||
447 | platform_driver_unregister(&s3c_ts_driver); | ||
448 | } | ||
449 | |||
450 | module_init(s3c2410ts_init); | ||
451 | module_exit(s3c2410ts_exit); | ||
452 | |||
453 | MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, " | ||
454 | "Ben Dooks <ben@simtec.co.uk>, " | ||
455 | "Simtec Electronics <linux@simtec.co.uk>"); | ||
456 | MODULE_DESCRIPTION("S3C24XX Touchscreen driver"); | ||
457 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 095f84b1f56e..89dcbe7b4b02 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c | |||
@@ -355,10 +355,13 @@ static int ucb1400_ts_probe(struct platform_device *dev) | |||
355 | goto err; | 355 | goto err; |
356 | } | 356 | } |
357 | 357 | ||
358 | error = ucb1400_ts_detect_irq(ucb); | 358 | /* Only in case the IRQ line wasn't supplied, try detecting it */ |
359 | if (error) { | 359 | if (ucb->irq < 0) { |
360 | printk(KERN_ERR "UCB1400: IRQ probe failed\n"); | 360 | error = ucb1400_ts_detect_irq(ucb); |
361 | goto err_free_devs; | 361 | if (error) { |
362 | printk(KERN_ERR "UCB1400: IRQ probe failed\n"); | ||
363 | goto err_free_devs; | ||
364 | } | ||
362 | } | 365 | } |
363 | 366 | ||
364 | init_waitqueue_head(&ucb->ts_wait); | 367 | init_waitqueue_head(&ucb->ts_wait); |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 68ece5801a58..09a5e7341bd5 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
@@ -14,6 +14,7 @@ | |||
14 | * - General Touch | 14 | * - General Touch |
15 | * - GoTop Super_Q2/GogoPen/PenPower tablets | 15 | * - GoTop Super_Q2/GogoPen/PenPower tablets |
16 | * - JASTEC USB touch controller/DigiTech DTR-02U | 16 | * - JASTEC USB touch controller/DigiTech DTR-02U |
17 | * - Zytronic capacitive touchscreen | ||
17 | * | 18 | * |
18 | * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch> | 19 | * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch> |
19 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) | 20 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) |
@@ -73,6 +74,15 @@ struct usbtouch_device_info { | |||
73 | int min_press, max_press; | 74 | int min_press, max_press; |
74 | int rept_size; | 75 | int rept_size; |
75 | 76 | ||
77 | /* | ||
78 | * Always service the USB devices irq not just when the input device is | ||
79 | * open. This is useful when devices have a watchdog which prevents us | ||
80 | * from periodically polling the device. Leave this unset unless your | ||
81 | * touchscreen device requires it, as it does consume more of the USB | ||
82 | * bandwidth. | ||
83 | */ | ||
84 | bool irq_always; | ||
85 | |||
76 | void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len); | 86 | void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len); |
77 | 87 | ||
78 | /* | 88 | /* |
@@ -121,6 +131,8 @@ enum { | |||
121 | DEVTYPE_GOTOP, | 131 | DEVTYPE_GOTOP, |
122 | DEVTYPE_JASTEC, | 132 | DEVTYPE_JASTEC, |
123 | DEVTYPE_E2I, | 133 | DEVTYPE_E2I, |
134 | DEVTYPE_ZYTRONIC, | ||
135 | DEVTYPE_TC5UH, | ||
124 | }; | 136 | }; |
125 | 137 | ||
126 | #define USB_DEVICE_HID_CLASS(vend, prod) \ | 138 | #define USB_DEVICE_HID_CLASS(vend, prod) \ |
@@ -201,6 +213,15 @@ static struct usb_device_id usbtouch_devices[] = { | |||
201 | #ifdef CONFIG_TOUCHSCREEN_USB_E2I | 213 | #ifdef CONFIG_TOUCHSCREEN_USB_E2I |
202 | {USB_DEVICE(0x1ac7, 0x0001), .driver_info = DEVTYPE_E2I}, | 214 | {USB_DEVICE(0x1ac7, 0x0001), .driver_info = DEVTYPE_E2I}, |
203 | #endif | 215 | #endif |
216 | |||
217 | #ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC | ||
218 | {USB_DEVICE(0x14c8, 0x0003), .driver_info = DEVTYPE_ZYTRONIC}, | ||
219 | #endif | ||
220 | |||
221 | #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH | ||
222 | {USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH}, | ||
223 | #endif | ||
224 | |||
204 | {} | 225 | {} |
205 | }; | 226 | }; |
206 | 227 | ||
@@ -538,6 +559,19 @@ static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
538 | } | 559 | } |
539 | #endif | 560 | #endif |
540 | 561 | ||
562 | /***************************************************************************** | ||
563 | * ET&T TC5UH part | ||
564 | */ | ||
565 | #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH | ||
566 | static int tc5uh_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | ||
567 | { | ||
568 | dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1]; | ||
569 | dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3]; | ||
570 | dev->touch = pkt[0] & 0x01; | ||
571 | |||
572 | return 1; | ||
573 | } | ||
574 | #endif | ||
541 | 575 | ||
542 | /***************************************************************************** | 576 | /***************************************************************************** |
543 | * IdealTEK URTC1000 Part | 577 | * IdealTEK URTC1000 Part |
@@ -621,6 +655,39 @@ static int jastec_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
621 | } | 655 | } |
622 | #endif | 656 | #endif |
623 | 657 | ||
658 | /***************************************************************************** | ||
659 | * Zytronic Part | ||
660 | */ | ||
661 | #ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC | ||
662 | static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | ||
663 | { | ||
664 | switch (pkt[0]) { | ||
665 | case 0x3A: /* command response */ | ||
666 | dbg("%s: Command response %d", __func__, pkt[1]); | ||
667 | break; | ||
668 | |||
669 | case 0xC0: /* down */ | ||
670 | dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7); | ||
671 | dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7); | ||
672 | dev->touch = 1; | ||
673 | dbg("%s: down %d,%d", __func__, dev->x, dev->y); | ||
674 | return 1; | ||
675 | |||
676 | case 0x80: /* up */ | ||
677 | dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7); | ||
678 | dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7); | ||
679 | dev->touch = 0; | ||
680 | dbg("%s: up %d,%d", __func__, dev->x, dev->y); | ||
681 | return 1; | ||
682 | |||
683 | default: | ||
684 | dbg("%s: Unknown return %d", __func__, pkt[0]); | ||
685 | break; | ||
686 | } | ||
687 | |||
688 | return 0; | ||
689 | } | ||
690 | #endif | ||
624 | 691 | ||
625 | /***************************************************************************** | 692 | /***************************************************************************** |
626 | * the different device descriptors | 693 | * the different device descriptors |
@@ -783,6 +850,29 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { | |||
783 | .read_data = e2i_read_data, | 850 | .read_data = e2i_read_data, |
784 | }, | 851 | }, |
785 | #endif | 852 | #endif |
853 | |||
854 | #ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC | ||
855 | [DEVTYPE_ZYTRONIC] = { | ||
856 | .min_xc = 0x0, | ||
857 | .max_xc = 0x03ff, | ||
858 | .min_yc = 0x0, | ||
859 | .max_yc = 0x03ff, | ||
860 | .rept_size = 5, | ||
861 | .read_data = zytronic_read_data, | ||
862 | .irq_always = true, | ||
863 | }, | ||
864 | #endif | ||
865 | |||
866 | #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH | ||
867 | [DEVTYPE_TC5UH] = { | ||
868 | .min_xc = 0x0, | ||
869 | .max_xc = 0x0fff, | ||
870 | .min_yc = 0x0, | ||
871 | .max_yc = 0x0fff, | ||
872 | .rept_size = 5, | ||
873 | .read_data = tc5uh_read_data, | ||
874 | }, | ||
875 | #endif | ||
786 | }; | 876 | }; |
787 | 877 | ||
788 | 878 | ||
@@ -933,8 +1023,10 @@ static int usbtouch_open(struct input_dev *input) | |||
933 | 1023 | ||
934 | usbtouch->irq->dev = usbtouch->udev; | 1024 | usbtouch->irq->dev = usbtouch->udev; |
935 | 1025 | ||
936 | if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) | 1026 | if (!usbtouch->type->irq_always) { |
937 | return -EIO; | 1027 | if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) |
1028 | return -EIO; | ||
1029 | } | ||
938 | 1030 | ||
939 | return 0; | 1031 | return 0; |
940 | } | 1032 | } |
@@ -943,7 +1035,8 @@ static void usbtouch_close(struct input_dev *input) | |||
943 | { | 1035 | { |
944 | struct usbtouch_usb *usbtouch = input_get_drvdata(input); | 1036 | struct usbtouch_usb *usbtouch = input_get_drvdata(input); |
945 | 1037 | ||
946 | usb_kill_urb(usbtouch->irq); | 1038 | if (!usbtouch->type->irq_always) |
1039 | usb_kill_urb(usbtouch->irq); | ||
947 | } | 1040 | } |
948 | 1041 | ||
949 | 1042 | ||
@@ -1066,6 +1159,9 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
1066 | 1159 | ||
1067 | usb_set_intfdata(intf, usbtouch); | 1160 | usb_set_intfdata(intf, usbtouch); |
1068 | 1161 | ||
1162 | if (usbtouch->type->irq_always) | ||
1163 | usb_submit_urb(usbtouch->irq, GFP_KERNEL); | ||
1164 | |||
1069 | return 0; | 1165 | return 0; |
1070 | 1166 | ||
1071 | out_free_buffers: | 1167 | out_free_buffers: |
@@ -1087,7 +1183,7 @@ static void usbtouch_disconnect(struct usb_interface *intf) | |||
1087 | 1183 | ||
1088 | dbg("%s - usbtouch is initialized, cleaning up", __func__); | 1184 | dbg("%s - usbtouch is initialized, cleaning up", __func__); |
1089 | usb_set_intfdata(intf, NULL); | 1185 | usb_set_intfdata(intf, NULL); |
1090 | usb_kill_urb(usbtouch->irq); | 1186 | /* this will stop IO via close */ |
1091 | input_unregister_device(usbtouch->input); | 1187 | input_unregister_device(usbtouch->input); |
1092 | usb_free_urb(usbtouch->irq); | 1188 | usb_free_urb(usbtouch->irq); |
1093 | usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); | 1189 | usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); |
diff --git a/drivers/mfd/ucb1400_core.c b/drivers/mfd/ucb1400_core.c index fa294b6d600a..85fd9421be94 100644 --- a/drivers/mfd/ucb1400_core.c +++ b/drivers/mfd/ucb1400_core.c | |||
@@ -51,6 +51,7 @@ static int ucb1400_core_probe(struct device *dev) | |||
51 | struct ucb1400_ts ucb_ts; | 51 | struct ucb1400_ts ucb_ts; |
52 | struct ucb1400_gpio ucb_gpio; | 52 | struct ucb1400_gpio ucb_gpio; |
53 | struct snd_ac97 *ac97; | 53 | struct snd_ac97 *ac97; |
54 | struct ucb1400_pdata *pdata = dev->platform_data; | ||
54 | 55 | ||
55 | memset(&ucb_ts, 0, sizeof(ucb_ts)); | 56 | memset(&ucb_ts, 0, sizeof(ucb_ts)); |
56 | memset(&ucb_gpio, 0, sizeof(ucb_gpio)); | 57 | memset(&ucb_gpio, 0, sizeof(ucb_gpio)); |
@@ -88,6 +89,12 @@ static int ucb1400_core_probe(struct device *dev) | |||
88 | 89 | ||
89 | /* TOUCHSCREEN */ | 90 | /* TOUCHSCREEN */ |
90 | ucb_ts.ac97 = ac97; | 91 | ucb_ts.ac97 = ac97; |
92 | |||
93 | if (pdata != NULL && pdata->irq >= 0) | ||
94 | ucb_ts.irq = pdata->irq; | ||
95 | else | ||
96 | ucb_ts.irq = -1; | ||
97 | |||
91 | ucb->ucb1400_ts = platform_device_alloc("ucb1400_ts", -1); | 98 | ucb->ucb1400_ts = platform_device_alloc("ucb1400_ts", -1); |
92 | if (!ucb->ucb1400_ts) { | 99 | if (!ucb->ucb1400_ts) { |
93 | err = -ENOMEM; | 100 | err = -ENOMEM; |
diff --git a/include/linux/input-polldev.h b/include/linux/input-polldev.h index 597a0077b3c5..5e3dddf8f562 100644 --- a/include/linux/input-polldev.h +++ b/include/linux/input-polldev.h | |||
@@ -14,12 +14,19 @@ | |||
14 | 14 | ||
15 | /** | 15 | /** |
16 | * struct input_polled_dev - simple polled input device | 16 | * struct input_polled_dev - simple polled input device |
17 | * @private: private driver data | 17 | * @private: private driver data. |
18 | * @flush: driver-supplied method that flushes device's state upon | 18 | * @open: driver-supplied method that prepares device for polling |
19 | * opening (optional) | 19 | * (enabled the device and maybe flushes device state). |
20 | * @close: driver-supplied method that is called when device is no | ||
21 | * longer being polled. Used to put device into low power mode. | ||
20 | * @poll: driver-supplied method that polls the device and posts | 22 | * @poll: driver-supplied method that polls the device and posts |
21 | * input events (mandatory). | 23 | * input events (mandatory). |
22 | * @poll_interval: specifies how often the poll() method shoudl be called. | 24 | * @poll_interval: specifies how often the poll() method should be called. |
25 | * Defaults to 500 msec unless overriden when registering the device. | ||
26 | * @poll_interval_max: specifies upper bound for the poll interval. | ||
27 | * Defaults to the initial value of @poll_interval. | ||
28 | * @poll_interval_min: specifies lower bound for the poll interval. | ||
29 | * Defaults to 0. | ||
23 | * @input: input device structire associated with the polled device. | 30 | * @input: input device structire associated with the polled device. |
24 | * Must be properly initialized by the driver (id, name, phys, bits). | 31 | * Must be properly initialized by the driver (id, name, phys, bits). |
25 | * | 32 | * |
@@ -30,11 +37,16 @@ | |||
30 | struct input_polled_dev { | 37 | struct input_polled_dev { |
31 | void *private; | 38 | void *private; |
32 | 39 | ||
33 | void (*flush)(struct input_polled_dev *dev); | 40 | void (*open)(struct input_polled_dev *dev); |
41 | void (*close)(struct input_polled_dev *dev); | ||
34 | void (*poll)(struct input_polled_dev *dev); | 42 | void (*poll)(struct input_polled_dev *dev); |
35 | unsigned int poll_interval; /* msec */ | 43 | unsigned int poll_interval; /* msec */ |
44 | unsigned int poll_interval_max; /* msec */ | ||
45 | unsigned int poll_interval_min; /* msec */ | ||
36 | 46 | ||
37 | struct input_dev *input; | 47 | struct input_dev *input; |
48 | |||
49 | /* private: */ | ||
38 | struct delayed_work work; | 50 | struct delayed_work work; |
39 | }; | 51 | }; |
40 | 52 | ||
diff --git a/include/linux/input.h b/include/linux/input.h index 84b501ab0d8f..7be8a6537b57 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
@@ -895,7 +895,7 @@ struct ff_periodic_effect { | |||
895 | struct ff_envelope envelope; | 895 | struct ff_envelope envelope; |
896 | 896 | ||
897 | __u32 custom_len; | 897 | __u32 custom_len; |
898 | __s16 *custom_data; | 898 | __s16 __user *custom_data; |
899 | }; | 899 | }; |
900 | 900 | ||
901 | /** | 901 | /** |
@@ -1021,9 +1021,12 @@ struct ff_effect { | |||
1021 | * @keycodesize: size of elements in keycode table | 1021 | * @keycodesize: size of elements in keycode table |
1022 | * @keycode: map of scancodes to keycodes for this device | 1022 | * @keycode: map of scancodes to keycodes for this device |
1023 | * @setkeycode: optional method to alter current keymap, used to implement | 1023 | * @setkeycode: optional method to alter current keymap, used to implement |
1024 | * sparse keymaps. If not supplied default mechanism will be used | 1024 | * sparse keymaps. If not supplied default mechanism will be used. |
1025 | * The method is being called while holding event_lock and thus must | ||
1026 | * not sleep | ||
1025 | * @getkeycode: optional method to retrieve current keymap. If not supplied | 1027 | * @getkeycode: optional method to retrieve current keymap. If not supplied |
1026 | * default mechanism will be used | 1028 | * default mechanism will be used. The method is being called while |
1029 | * holding event_lock and thus must not sleep | ||
1027 | * @ff: force feedback structure associated with the device if device | 1030 | * @ff: force feedback structure associated with the device if device |
1028 | * supports force feedback effects | 1031 | * supports force feedback effects |
1029 | * @repeat_key: stores key code of the last key pressed; used to implement | 1032 | * @repeat_key: stores key code of the last key pressed; used to implement |
@@ -1040,6 +1043,7 @@ struct ff_effect { | |||
1040 | * @absmin: minimum values for events coming from absolute axes | 1043 | * @absmin: minimum values for events coming from absolute axes |
1041 | * @absfuzz: describes noisiness for axes | 1044 | * @absfuzz: describes noisiness for axes |
1042 | * @absflat: size of the center flat position (used by joydev) | 1045 | * @absflat: size of the center flat position (used by joydev) |
1046 | * @absres: resolution used for events coming form absolute axes | ||
1043 | * @open: this method is called when the very first user calls | 1047 | * @open: this method is called when the very first user calls |
1044 | * input_open_device(). The driver must prepare the device | 1048 | * input_open_device(). The driver must prepare the device |
1045 | * to start generating events (start polling thread, | 1049 | * to start generating events (start polling thread, |
@@ -1294,6 +1298,9 @@ void input_unregister_device(struct input_dev *); | |||
1294 | int __must_check input_register_handler(struct input_handler *); | 1298 | int __must_check input_register_handler(struct input_handler *); |
1295 | void input_unregister_handler(struct input_handler *); | 1299 | void input_unregister_handler(struct input_handler *); |
1296 | 1300 | ||
1301 | int input_handler_for_each_handle(struct input_handler *, void *data, | ||
1302 | int (*fn)(struct input_handle *, void *)); | ||
1303 | |||
1297 | int input_register_handle(struct input_handle *); | 1304 | int input_register_handle(struct input_handle *); |
1298 | void input_unregister_handle(struct input_handle *); | 1305 | void input_unregister_handle(struct input_handle *); |
1299 | 1306 | ||
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h index b3cd42d50e16..3bd018baae20 100644 --- a/include/linux/input/matrix_keypad.h +++ b/include/linux/input/matrix_keypad.h | |||
@@ -41,6 +41,9 @@ struct matrix_keymap_data { | |||
41 | * @col_scan_delay_us: delay, measured in microseconds, that is | 41 | * @col_scan_delay_us: delay, measured in microseconds, that is |
42 | * needed before we can keypad after activating column gpio | 42 | * needed before we can keypad after activating column gpio |
43 | * @debounce_ms: debounce interval in milliseconds | 43 | * @debounce_ms: debounce interval in milliseconds |
44 | * @active_low: gpio polarity | ||
45 | * @wakeup: controls whether the device should be set up as wakeup | ||
46 | * source | ||
44 | * | 47 | * |
45 | * This structure represents platform-specific data that use used by | 48 | * This structure represents platform-specific data that use used by |
46 | * matrix_keypad driver to perform proper initialization. | 49 | * matrix_keypad driver to perform proper initialization. |
diff --git a/include/linux/input/sparse-keymap.h b/include/linux/input/sparse-keymap.h new file mode 100644 index 000000000000..52db62064c6e --- /dev/null +++ b/include/linux/input/sparse-keymap.h | |||
@@ -0,0 +1,62 @@ | |||
1 | #ifndef _SPARSE_KEYMAP_H | ||
2 | #define _SPARSE_KEYMAP_H | ||
3 | |||
4 | /* | ||
5 | * Copyright (c) 2009 Dmitry Torokhov | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #define KE_END 0 /* Indicates end of keymap */ | ||
13 | #define KE_KEY 1 /* Ordinary key/button */ | ||
14 | #define KE_SW 2 /* Switch (predetermined value) */ | ||
15 | #define KE_VSW 3 /* Switch (value supplied at runtime) */ | ||
16 | #define KE_IGNORE 4 /* Known entry that should be ignored */ | ||
17 | #define KE_LAST KE_IGNORE | ||
18 | |||
19 | /** | ||
20 | * struct key_entry - keymap entry for use in sparse keymap | ||
21 | * @type: Type of the key entry (KE_KEY, KE_SW, KE_VSW, KE_END); | ||
22 | * drivers are allowed to extend the list with their own | ||
23 | * private definitions. | ||
24 | * @code: Device-specific data identifying the button/switch | ||
25 | * @keycode: KEY_* code assigned to a key/button | ||
26 | * @sw.code: SW_* code assigned to a switch | ||
27 | * @sw.value: Value that should be sent in an input even when KE_SW | ||
28 | * switch is toggled. KE_VSW switches ignore this field and | ||
29 | * expect driver to supply value for the event. | ||
30 | * | ||
31 | * This structure defines an entry in a sparse keymap used by some | ||
32 | * input devices for which traditional table-based approach is not | ||
33 | * suitable. | ||
34 | */ | ||
35 | struct key_entry { | ||
36 | int type; /* See KE_* above */ | ||
37 | u32 code; | ||
38 | union { | ||
39 | u16 keycode; /* For KE_KEY */ | ||
40 | struct { /* For KE_SW, KE_VSW */ | ||
41 | u8 code; | ||
42 | u8 value; /* For KE_SW, ignored by KE_VSW */ | ||
43 | } sw; | ||
44 | }; | ||
45 | }; | ||
46 | |||
47 | struct key_entry *sparse_keymap_entry_from_scancode(struct input_dev *dev, | ||
48 | unsigned int code); | ||
49 | struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev, | ||
50 | unsigned int code); | ||
51 | int sparse_keymap_setup(struct input_dev *dev, | ||
52 | const struct key_entry *keymap, | ||
53 | int (*setup)(struct input_dev *, struct key_entry *)); | ||
54 | void sparse_keymap_free(struct input_dev *dev); | ||
55 | |||
56 | void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke, | ||
57 | unsigned int value, bool autorelease); | ||
58 | |||
59 | bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code, | ||
60 | unsigned int value, bool autorelease); | ||
61 | |||
62 | #endif /* _SPARSE_KEYMAP_H */ | ||
diff --git a/include/linux/serio.h b/include/linux/serio.h index a640bc2afe76..e2f3044d4a4a 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h | |||
@@ -215,5 +215,6 @@ static inline void serio_unpin_driver(struct serio *serio) | |||
215 | #define SERIO_INEXIO 0x37 | 215 | #define SERIO_INEXIO 0x37 |
216 | #define SERIO_TOUCHIT213 0x38 | 216 | #define SERIO_TOUCHIT213 0x38 |
217 | #define SERIO_W8001 0x39 | 217 | #define SERIO_W8001 0x39 |
218 | #define SERIO_DYNAPRO 0x3a | ||
218 | 219 | ||
219 | #endif | 220 | #endif |
diff --git a/include/linux/ucb1400.h b/include/linux/ucb1400.h index adb44066680c..1b4790911052 100644 --- a/include/linux/ucb1400.h +++ b/include/linux/ucb1400.h | |||
@@ -110,6 +110,10 @@ struct ucb1400 { | |||
110 | struct platform_device *ucb1400_gpio; | 110 | struct platform_device *ucb1400_gpio; |
111 | }; | 111 | }; |
112 | 112 | ||
113 | struct ucb1400_pdata { | ||
114 | int irq; | ||
115 | }; | ||
116 | |||
113 | static inline u16 ucb1400_reg_read(struct snd_ac97 *ac97, u16 reg) | 117 | static inline u16 ucb1400_reg_read(struct snd_ac97 *ac97, u16 reg) |
114 | { | 118 | { |
115 | return ac97->bus->ops->read(ac97, reg); | 119 | return ac97->bus->ops->read(ac97, reg); |