diff options
Diffstat (limited to 'drivers/media/IR/ir-keytable.c')
-rw-r--r-- | drivers/media/IR/ir-keytable.c | 110 |
1 files changed, 83 insertions, 27 deletions
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index f60107c3b091..8039110350d3 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c | |||
@@ -431,13 +431,13 @@ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) | |||
431 | EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); | 431 | EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); |
432 | 432 | ||
433 | /** | 433 | /** |
434 | * ir_keyup() - generates input event to cleanup a key press | 434 | * ir_do_keyup() - internal function to signal the release of a keypress |
435 | * @ir: the struct ir_input_dev descriptor of the device | 435 | * @ir: the struct ir_input_dev descriptor of the device |
436 | * | 436 | * |
437 | * This routine is used to signal that a key has been released on the | 437 | * This function is used internally to release a keypress, it must be |
438 | * remote control. It reports a keyup input event via input_report_key(). | 438 | * called with keylock held. |
439 | */ | 439 | */ |
440 | void ir_keyup(struct ir_input_dev *ir) | 440 | static void ir_do_keyup(struct ir_input_dev *ir) |
441 | { | 441 | { |
442 | if (!ir->keypressed) | 442 | if (!ir->keypressed) |
443 | return; | 443 | return; |
@@ -447,6 +447,23 @@ void ir_keyup(struct ir_input_dev *ir) | |||
447 | input_sync(ir->input_dev); | 447 | input_sync(ir->input_dev); |
448 | ir->keypressed = false; | 448 | ir->keypressed = false; |
449 | } | 449 | } |
450 | |||
451 | /** | ||
452 | * ir_keyup() - generates input event to signal the release of a keypress | ||
453 | * @dev: the struct input_dev descriptor of the device | ||
454 | * | ||
455 | * This routine is used to signal that a key has been released on the | ||
456 | * remote control. | ||
457 | */ | ||
458 | void ir_keyup(struct input_dev *dev) | ||
459 | { | ||
460 | unsigned long flags; | ||
461 | struct ir_input_dev *ir = input_get_drvdata(dev); | ||
462 | |||
463 | spin_lock_irqsave(&ir->keylock, flags); | ||
464 | ir_do_keyup(ir); | ||
465 | spin_unlock_irqrestore(&ir->keylock, flags); | ||
466 | } | ||
450 | EXPORT_SYMBOL_GPL(ir_keyup); | 467 | EXPORT_SYMBOL_GPL(ir_keyup); |
451 | 468 | ||
452 | /** | 469 | /** |
@@ -473,7 +490,7 @@ static void ir_timer_keyup(unsigned long cookie) | |||
473 | */ | 490 | */ |
474 | spin_lock_irqsave(&ir->keylock, flags); | 491 | spin_lock_irqsave(&ir->keylock, flags); |
475 | if (time_is_before_eq_jiffies(ir->keyup_jiffies)) | 492 | if (time_is_before_eq_jiffies(ir->keyup_jiffies)) |
476 | ir_keyup(ir); | 493 | ir_do_keyup(ir); |
477 | spin_unlock_irqrestore(&ir->keylock, flags); | 494 | spin_unlock_irqrestore(&ir->keylock, flags); |
478 | } | 495 | } |
479 | 496 | ||
@@ -506,44 +523,37 @@ out: | |||
506 | EXPORT_SYMBOL_GPL(ir_repeat); | 523 | EXPORT_SYMBOL_GPL(ir_repeat); |
507 | 524 | ||
508 | /** | 525 | /** |
509 | * ir_keydown() - generates input event for a key press | 526 | * ir_do_keydown() - internal function to process a keypress |
510 | * @dev: the struct input_dev descriptor of the device | 527 | * @dev: the struct input_dev descriptor of the device |
511 | * @scancode: the scancode that we're seeking | 528 | * @scancode: the scancode of the keypress |
512 | * @toggle: the toggle value (protocol dependent, if the protocol doesn't | 529 | * @keycode: the keycode of the keypress |
513 | * support toggle values, this should be set to zero) | 530 | * @toggle: the toggle value of the keypress |
514 | * | 531 | * |
515 | * This routine is used by the input routines when a key is pressed at the | 532 | * This function is used internally to register a keypress, it must be |
516 | * IR. It gets the keycode for a scancode and reports an input event via | 533 | * called with keylock held. |
517 | * input_report_key(). | ||
518 | */ | 534 | */ |
519 | void ir_keydown(struct input_dev *dev, int scancode, u8 toggle) | 535 | static void ir_do_keydown(struct input_dev *dev, int scancode, |
536 | u32 keycode, u8 toggle) | ||
520 | { | 537 | { |
521 | unsigned long flags; | ||
522 | struct ir_input_dev *ir = input_get_drvdata(dev); | 538 | struct ir_input_dev *ir = input_get_drvdata(dev); |
523 | 539 | ||
524 | u32 keycode = ir_g_keycode_from_table(dev, scancode); | ||
525 | |||
526 | spin_lock_irqsave(&ir->keylock, flags); | ||
527 | |||
528 | input_event(dev, EV_MSC, MSC_SCAN, scancode); | 540 | input_event(dev, EV_MSC, MSC_SCAN, scancode); |
529 | 541 | ||
530 | /* Repeat event? */ | 542 | /* Repeat event? */ |
531 | if (ir->keypressed && | 543 | if (ir->keypressed && |
532 | ir->last_scancode == scancode && | 544 | ir->last_scancode == scancode && |
533 | ir->last_toggle == toggle) | 545 | ir->last_toggle == toggle) |
534 | goto set_timer; | 546 | return; |
535 | 547 | ||
536 | /* Release old keypress */ | 548 | /* Release old keypress */ |
537 | ir_keyup(ir); | 549 | ir_do_keyup(ir); |
538 | 550 | ||
539 | ir->last_scancode = scancode; | 551 | ir->last_scancode = scancode; |
540 | ir->last_toggle = toggle; | 552 | ir->last_toggle = toggle; |
541 | ir->last_keycode = keycode; | 553 | ir->last_keycode = keycode; |
542 | 554 | ||
543 | |||
544 | if (keycode == KEY_RESERVED) | 555 | if (keycode == KEY_RESERVED) |
545 | goto out; | 556 | return; |
546 | |||
547 | 557 | ||
548 | /* Register a keypress */ | 558 | /* Register a keypress */ |
549 | ir->keypressed = true; | 559 | ir->keypressed = true; |
@@ -551,15 +561,61 @@ void ir_keydown(struct input_dev *dev, int scancode, u8 toggle) | |||
551 | dev->name, keycode, scancode); | 561 | dev->name, keycode, scancode); |
552 | input_report_key(dev, ir->last_keycode, 1); | 562 | input_report_key(dev, ir->last_keycode, 1); |
553 | input_sync(dev); | 563 | input_sync(dev); |
564 | } | ||
554 | 565 | ||
555 | set_timer: | 566 | /** |
556 | ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); | 567 | * ir_keydown() - generates input event for a key press |
557 | mod_timer(&ir->timer_keyup, ir->keyup_jiffies); | 568 | * @dev: the struct input_dev descriptor of the device |
558 | out: | 569 | * @scancode: the scancode that we're seeking |
570 | * @toggle: the toggle value (protocol dependent, if the protocol doesn't | ||
571 | * support toggle values, this should be set to zero) | ||
572 | * | ||
573 | * This routine is used by the input routines when a key is pressed at the | ||
574 | * IR. It gets the keycode for a scancode and reports an input event via | ||
575 | * input_report_key(). | ||
576 | */ | ||
577 | void ir_keydown(struct input_dev *dev, int scancode, u8 toggle) | ||
578 | { | ||
579 | unsigned long flags; | ||
580 | struct ir_input_dev *ir = input_get_drvdata(dev); | ||
581 | u32 keycode = ir_g_keycode_from_table(dev, scancode); | ||
582 | |||
583 | spin_lock_irqsave(&ir->keylock, flags); | ||
584 | ir_do_keydown(dev, scancode, keycode, toggle); | ||
585 | |||
586 | if (ir->keypressed) { | ||
587 | ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); | ||
588 | mod_timer(&ir->timer_keyup, ir->keyup_jiffies); | ||
589 | } | ||
559 | spin_unlock_irqrestore(&ir->keylock, flags); | 590 | spin_unlock_irqrestore(&ir->keylock, flags); |
560 | } | 591 | } |
561 | EXPORT_SYMBOL_GPL(ir_keydown); | 592 | EXPORT_SYMBOL_GPL(ir_keydown); |
562 | 593 | ||
594 | /** | ||
595 | * ir_keydown_notimeout() - generates input event for a key press without | ||
596 | * an automatic keyup event at a later time | ||
597 | * @dev: the struct input_dev descriptor of the device | ||
598 | * @scancode: the scancode that we're seeking | ||
599 | * @toggle: the toggle value (protocol dependent, if the protocol doesn't | ||
600 | * support toggle values, this should be set to zero) | ||
601 | * | ||
602 | * This routine is used by the input routines when a key is pressed at the | ||
603 | * IR. It gets the keycode for a scancode and reports an input event via | ||
604 | * input_report_key(). The driver must manually call ir_keyup() at a later | ||
605 | * stage. | ||
606 | */ | ||
607 | void ir_keydown_notimeout(struct input_dev *dev, int scancode, u8 toggle) | ||
608 | { | ||
609 | unsigned long flags; | ||
610 | struct ir_input_dev *ir = input_get_drvdata(dev); | ||
611 | u32 keycode = ir_g_keycode_from_table(dev, scancode); | ||
612 | |||
613 | spin_lock_irqsave(&ir->keylock, flags); | ||
614 | ir_do_keydown(dev, scancode, keycode, toggle); | ||
615 | spin_unlock_irqrestore(&ir->keylock, flags); | ||
616 | } | ||
617 | EXPORT_SYMBOL_GPL(ir_keydown_notimeout); | ||
618 | |||
563 | static int ir_open(struct input_dev *input_dev) | 619 | static int ir_open(struct input_dev *input_dev) |
564 | { | 620 | { |
565 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 621 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |