diff options
49 files changed, 2477 insertions, 750 deletions
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl index 94a20fe8fedf..e994d1d9fbe6 100644 --- a/Documentation/DocBook/device-drivers.tmpl +++ b/Documentation/DocBook/device-drivers.tmpl | |||
@@ -293,10 +293,19 @@ 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> | ||
300 | </chapter> | 309 | </chapter> |
301 | 310 | ||
302 | <chapter id="spi"> | 311 | <chapter id="spi"> |
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 332b784050b2..a5a4eb19fbbe 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c | |||
@@ -810,6 +810,57 @@ static void __init at91_add_device_rtc(void) {} | |||
810 | 810 | ||
811 | 811 | ||
812 | /* -------------------------------------------------------------------- | 812 | /* -------------------------------------------------------------------- |
813 | * Touchscreen | ||
814 | * -------------------------------------------------------------------- */ | ||
815 | |||
816 | #if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE) | ||
817 | static u64 tsadcc_dmamask = DMA_BIT_MASK(32); | ||
818 | static struct at91_tsadcc_data tsadcc_data; | ||
819 | |||
820 | static struct resource tsadcc_resources[] = { | ||
821 | [0] = { | ||
822 | .start = AT91SAM9G45_BASE_TSC, | ||
823 | .end = AT91SAM9G45_BASE_TSC + SZ_16K - 1, | ||
824 | .flags = IORESOURCE_MEM, | ||
825 | }, | ||
826 | [1] = { | ||
827 | .start = AT91SAM9G45_ID_TSC, | ||
828 | .end = AT91SAM9G45_ID_TSC, | ||
829 | .flags = IORESOURCE_IRQ, | ||
830 | } | ||
831 | }; | ||
832 | |||
833 | static struct platform_device at91sam9g45_tsadcc_device = { | ||
834 | .name = "atmel_tsadcc", | ||
835 | .id = -1, | ||
836 | .dev = { | ||
837 | .dma_mask = &tsadcc_dmamask, | ||
838 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
839 | .platform_data = &tsadcc_data, | ||
840 | }, | ||
841 | .resource = tsadcc_resources, | ||
842 | .num_resources = ARRAY_SIZE(tsadcc_resources), | ||
843 | }; | ||
844 | |||
845 | void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) | ||
846 | { | ||
847 | if (!data) | ||
848 | return; | ||
849 | |||
850 | at91_set_gpio_input(AT91_PIN_PD20, 0); /* AD0_XR */ | ||
851 | at91_set_gpio_input(AT91_PIN_PD21, 0); /* AD1_XL */ | ||
852 | at91_set_gpio_input(AT91_PIN_PD22, 0); /* AD2_YT */ | ||
853 | at91_set_gpio_input(AT91_PIN_PD23, 0); /* AD3_TB */ | ||
854 | |||
855 | tsadcc_data = *data; | ||
856 | platform_device_register(&at91sam9g45_tsadcc_device); | ||
857 | } | ||
858 | #else | ||
859 | void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {} | ||
860 | #endif | ||
861 | |||
862 | |||
863 | /* -------------------------------------------------------------------- | ||
813 | * RTT | 864 | * RTT |
814 | * -------------------------------------------------------------------- */ | 865 | * -------------------------------------------------------------------- */ |
815 | 866 | ||
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 64c3843f323d..3d6764b3ad7a 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) |
@@ -378,6 +388,8 @@ static void __init ek_board_init(void) | |||
378 | at91_add_device_i2c(0, NULL, 0); | 388 | at91_add_device_i2c(0, NULL, 0); |
379 | /* LCD Controller */ | 389 | /* LCD Controller */ |
380 | at91_add_device_lcdc(&ek_lcdc_data); | 390 | at91_add_device_lcdc(&ek_lcdc_data); |
391 | /* Touch Screen */ | ||
392 | at91_add_device_tsadcc(&ek_tsadcc_data); | ||
381 | /* Push Buttons */ | 393 | /* Push Buttons */ |
382 | ek_add_device_buttons(); | 394 | ek_add_device_buttons(); |
383 | /* AC97 */ | 395 | /* 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 2f4fcedc02ba..6f1579f8abdd 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h | |||
@@ -186,7 +186,12 @@ extern void __init at91_add_device_ac97(struct ac97c_platform_data *data); | |||
186 | extern void __init at91_add_device_isi(void); | 186 | extern void __init at91_add_device_isi(void); |
187 | 187 | ||
188 | /* Touchscreen Controller */ | 188 | /* Touchscreen Controller */ |
189 | extern void __init at91_add_device_tsadcc(void); | 189 | struct at91_tsadcc_data { |
190 | unsigned int adc_clock; | ||
191 | u8 pendet_debounce; | ||
192 | u8 ts_sample_hold_time; | ||
193 | }; | ||
194 | extern void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data); | ||
190 | 195 | ||
191 | /* CAN */ | 196 | /* CAN */ |
192 | struct at91_can_data { | 197 | 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/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/ff-core.c b/drivers/input/ff-core.c index 38df81fcdc3a..572d0a712d2a 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 |
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c index 0d3ce7a50fb1..6a2eb399b988 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); | ||
107 | } | ||
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); | ||
98 | } | 161 | } |
99 | 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 | * |
@@ -150,15 +236,29 @@ 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 | return 0; | ||
162 | } | 262 | } |
163 | EXPORT_SYMBOL(input_register_polled_device); | 263 | EXPORT_SYMBOL(input_register_polled_device); |
164 | 264 | ||
@@ -174,6 +274,9 @@ EXPORT_SYMBOL(input_register_polled_device); | |||
174 | */ | 274 | */ |
175 | void input_unregister_polled_device(struct input_polled_dev *dev) | 275 | void input_unregister_polled_device(struct input_polled_dev *dev) |
176 | { | 276 | { |
277 | sysfs_remove_group(&dev->input->dev.kobj, | ||
278 | &input_polldev_attribute_group); | ||
279 | |||
177 | input_unregister_device(dev->input); | 280 | input_unregister_device(dev->input); |
178 | dev->input = NULL; | 281 | dev->input = NULL; |
179 | } | 282 | } |
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/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/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/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..00eb9d651d97 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -1263,7 +1263,7 @@ static int __devinit setup_input_dev(void) | |||
1263 | if (!wistron_idev) | 1263 | if (!wistron_idev) |
1264 | return -ENOMEM; | 1264 | return -ENOMEM; |
1265 | 1265 | ||
1266 | wistron_idev->flush = wistron_flush; | 1266 | wistron_idev->open = wistron_flush; |
1267 | wistron_idev->poll = wistron_poll; | 1267 | wistron_idev->poll = wistron_poll; |
1268 | wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT; | 1268 | wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT; |
1269 | 1269 | ||
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..54b7f64d6e62 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
@@ -198,10 +198,10 @@ static int lifebook_absolute_mode(struct psmouse *psmouse) | |||
198 | return -1; | 198 | return -1; |
199 | 199 | ||
200 | /* | 200 | /* |
201 | Enable absolute output -- ps2_command fails always but if | 201 | * Enable absolute output -- ps2_command fails always but if |
202 | you leave this call out the touchsreen will never send | 202 | * you leave this call out the touchsreen will never send |
203 | absolute coordinates | 203 | * absolute coordinates |
204 | */ | 204 | */ |
205 | param = lifebook_use_6byte_proto ? 0x08 : 0x07; | 205 | param = lifebook_use_6byte_proto ? 0x08 : 0x07; |
206 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); | 206 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); |
207 | 207 | ||
@@ -283,8 +283,8 @@ static int lifebook_create_relative_device(struct psmouse *psmouse) | |||
283 | 283 | ||
284 | dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | 284 | 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); | 285 | 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) | | 286 | dev2->keybit[BIT_WORD(BTN_LEFT)] = |
287 | BIT_MASK(BTN_RIGHT); | 287 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); |
288 | 288 | ||
289 | error = input_register_device(priv->dev2); | 289 | error = input_register_device(priv->dev2); |
290 | if (error) | 290 | if (error) |
@@ -309,6 +309,7 @@ int lifebook_init(struct psmouse *psmouse) | |||
309 | 309 | ||
310 | dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); | 310 | dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); |
311 | dev1->relbit[0] = 0; | 311 | dev1->relbit[0] = 0; |
312 | dev1->keybit[BIT_WORD(BTN_MOUSE)] = 0; | ||
312 | dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 313 | dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
313 | input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0); | 314 | 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); | 315 | input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0); |
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..acd16707696e 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 | ||
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_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/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 c2b1a7d244d9..7be8a6537b57 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
@@ -595,6 +595,8 @@ struct input_absinfo { | |||
595 | #define KEY_NUMERIC_STAR 0x20a | 595 | #define KEY_NUMERIC_STAR 0x20a |
596 | #define KEY_NUMERIC_POUND 0x20b | 596 | #define KEY_NUMERIC_POUND 0x20b |
597 | 597 | ||
598 | #define KEY_CAMERA_FOCUS 0x210 | ||
599 | |||
598 | /* We avoid low common keys in module aliases so they don't get huge. */ | 600 | /* We avoid low common keys in module aliases so they don't get huge. */ |
599 | #define KEY_MIN_INTERESTING KEY_MUTE | 601 | #define KEY_MIN_INTERESTING KEY_MUTE |
600 | #define KEY_MAX 0x2ff | 602 | #define KEY_MAX 0x2ff |
@@ -677,6 +679,9 @@ struct input_absinfo { | |||
677 | #define SW_LINEOUT_INSERT 0x06 /* set = inserted */ | 679 | #define SW_LINEOUT_INSERT 0x06 /* set = inserted */ |
678 | #define SW_JACK_PHYSICAL_INSERT 0x07 /* set = mechanical switch set */ | 680 | #define SW_JACK_PHYSICAL_INSERT 0x07 /* set = mechanical switch set */ |
679 | #define SW_VIDEOOUT_INSERT 0x08 /* set = inserted */ | 681 | #define SW_VIDEOOUT_INSERT 0x08 /* set = inserted */ |
682 | #define SW_CAMERA_LENS_COVER 0x09 /* set = lens covered */ | ||
683 | #define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */ | ||
684 | #define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */ | ||
680 | #define SW_MAX 0x0f | 685 | #define SW_MAX 0x0f |
681 | #define SW_CNT (SW_MAX+1) | 686 | #define SW_CNT (SW_MAX+1) |
682 | 687 | ||
@@ -890,7 +895,7 @@ struct ff_periodic_effect { | |||
890 | struct ff_envelope envelope; | 895 | struct ff_envelope envelope; |
891 | 896 | ||
892 | __u32 custom_len; | 897 | __u32 custom_len; |
893 | __s16 *custom_data; | 898 | __s16 __user *custom_data; |
894 | }; | 899 | }; |
895 | 900 | ||
896 | /** | 901 | /** |
@@ -1016,9 +1021,12 @@ struct ff_effect { | |||
1016 | * @keycodesize: size of elements in keycode table | 1021 | * @keycodesize: size of elements in keycode table |
1017 | * @keycode: map of scancodes to keycodes for this device | 1022 | * @keycode: map of scancodes to keycodes for this device |
1018 | * @setkeycode: optional method to alter current keymap, used to implement | 1023 | * @setkeycode: optional method to alter current keymap, used to implement |
1019 | * 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 | ||
1020 | * @getkeycode: optional method to retrieve current keymap. If not supplied | 1027 | * @getkeycode: optional method to retrieve current keymap. If not supplied |
1021 | * 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 | ||
1022 | * @ff: force feedback structure associated with the device if device | 1030 | * @ff: force feedback structure associated with the device if device |
1023 | * supports force feedback effects | 1031 | * supports force feedback effects |
1024 | * @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 |
@@ -1035,6 +1043,7 @@ struct ff_effect { | |||
1035 | * @absmin: minimum values for events coming from absolute axes | 1043 | * @absmin: minimum values for events coming from absolute axes |
1036 | * @absfuzz: describes noisiness for axes | 1044 | * @absfuzz: describes noisiness for axes |
1037 | * @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 | ||
1038 | * @open: this method is called when the very first user calls | 1047 | * @open: this method is called when the very first user calls |
1039 | * input_open_device(). The driver must prepare the device | 1048 | * input_open_device(). The driver must prepare the device |
1040 | * to start generating events (start polling thread, | 1049 | * to start generating events (start polling thread, |
@@ -1289,6 +1298,9 @@ void input_unregister_device(struct input_dev *); | |||
1289 | int __must_check input_register_handler(struct input_handler *); | 1298 | int __must_check input_register_handler(struct input_handler *); |
1290 | void input_unregister_handler(struct input_handler *); | 1299 | void input_unregister_handler(struct input_handler *); |
1291 | 1300 | ||
1301 | int input_handler_for_each_handle(struct input_handler *, void *data, | ||
1302 | int (*fn)(struct input_handle *, void *)); | ||
1303 | |||
1292 | int input_register_handle(struct input_handle *); | 1304 | int input_register_handle(struct input_handle *); |
1293 | void input_unregister_handle(struct input_handle *); | 1305 | void input_unregister_handle(struct input_handle *); |
1294 | 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/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); |