diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-09 22:52:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-09 22:52:01 -0500 |
commit | fa395aaec823b9d1a5800913a6b5d0e6d1c5ced2 (patch) | |
tree | d599abe9f4f48f1737da50fa9a48dadfd08100e3 /drivers/input/keyboard/lkkbd.c | |
parent | 3e7468313758913c5e4d372f35b271b96bad1298 (diff) | |
parent | 1f26978afd123deb22dd3c7dc75771a02f6e03f6 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (51 commits)
Input: appletouch - give up maintainership
Input: dm355evm_kbd - switch to using sparse keymap library
Input: wistron_btns - switch to using sparse keymap library
Input: add generic support for sparse keymaps
Input: fix memory leak in force feedback core
Input: wistron - remove identification strings from DMI table
Input: psmouse - remove identification strings from DMI tables
Input: atkbd - remove identification strings from DMI table
Input: i8042 - remove identification strings from DMI tables
DMI: allow omitting ident strings in DMI tables
Input: psmouse - do not carry DMI data around
Input: matrix-keypad - switch to using dev_pm_ops
Input: keyboard - fix lack of locking when traversing handler->h_list
Input: gpio_keys - scan gpio state at probe and resume time
Input: keyboard - add locking around event handling
Input: usbtouchscreen - add support for ET&T TC5UH touchscreen controller
Input: xpad - add two new Xbox 360 devices
Input: polled device - do not start polling if interval is zero
Input: polled device - schedule first poll immediately
Input: add S3C24XX touchscreen driver
...
Diffstat (limited to 'drivers/input/keyboard/lkkbd.c')
-rw-r--r-- | drivers/input/keyboard/lkkbd.c | 496 |
1 files changed, 238 insertions, 258 deletions
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 | ||