diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-03-31 13:40:35 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-17 23:53:03 -0400 |
commit | 716aab44df8bb9bdf16abea9013890274329b61f (patch) | |
tree | b83baf34bf18d35d51318044d8ea1ae80a275304 | |
parent | e202c15b4209f05fe109dd396463a524f4c2d3d8 (diff) |
V4L/DVB: ir-core: Add callbacks for input/evdev open/close on IR core
Especially when IR needs to do polling, it generates lots of wakeups per
second. This makes no sense, if the input event device is closed.
Adds a callback handler to the IR hardware driver, to allow registering
an open/close ops.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/IR/ir-keytable.c | 17 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-core.c | 2 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-input.c | 89 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134.h | 4 | ||||
-rw-r--r-- | include/media/ir-common.h | 1 | ||||
-rw-r--r-- | include/media/ir-core.h | 2 |
6 files changed, 98 insertions, 17 deletions
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index fcb0f0cb1fe1..99cad829a18a 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c | |||
@@ -446,6 +446,19 @@ void ir_keydown(struct input_dev *dev, int scancode) | |||
446 | } | 446 | } |
447 | EXPORT_SYMBOL_GPL(ir_keydown); | 447 | EXPORT_SYMBOL_GPL(ir_keydown); |
448 | 448 | ||
449 | static int ir_open(struct input_dev *input_dev) | ||
450 | { | ||
451 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | ||
452 | |||
453 | return ir_dev->props->open(ir_dev->props->priv); | ||
454 | } | ||
455 | |||
456 | static void ir_close(struct input_dev *input_dev) | ||
457 | { | ||
458 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | ||
459 | |||
460 | ir_dev->props->close(ir_dev->props->priv); | ||
461 | } | ||
449 | 462 | ||
450 | /** | 463 | /** |
451 | * ir_input_register() - sets the IR keycode table and add the handlers | 464 | * ir_input_register() - sets the IR keycode table and add the handlers |
@@ -495,6 +508,10 @@ int ir_input_register(struct input_dev *input_dev, | |||
495 | 508 | ||
496 | ir_copy_table(&ir_dev->rc_tab, rc_tab); | 509 | ir_copy_table(&ir_dev->rc_tab, rc_tab); |
497 | ir_dev->props = props; | 510 | ir_dev->props = props; |
511 | if (props && props->open) | ||
512 | input_dev->open = ir_open; | ||
513 | if (props && props->close) | ||
514 | input_dev->close = ir_close; | ||
498 | 515 | ||
499 | /* set the bits for the keys */ | 516 | /* set the bits for the keys */ |
500 | IR_dprintk(1, "key map size: %d\n", rc_tab->size); | 517 | IR_dprintk(1, "key map size: %d\n", rc_tab->size); |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index a7ad7810fddc..68cda10e0783 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -1227,7 +1227,7 @@ static int saa7134_resume(struct pci_dev *pci_dev) | |||
1227 | if (card_has_mpeg(dev)) | 1227 | if (card_has_mpeg(dev)) |
1228 | saa7134_ts_init_hw(dev); | 1228 | saa7134_ts_init_hw(dev); |
1229 | if (dev->remote) | 1229 | if (dev->remote) |
1230 | saa7134_ir_start(dev, dev->remote); | 1230 | saa7134_ir_start(dev); |
1231 | saa7134_hw_enable1(dev); | 1231 | saa7134_hw_enable1(dev); |
1232 | 1232 | ||
1233 | msleep(100); | 1233 | msleep(100); |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index e278d7304b3a..ae17b853f957 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -400,7 +400,14 @@ static int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
400 | 400 | ||
401 | void saa7134_input_irq(struct saa7134_dev *dev) | 401 | void saa7134_input_irq(struct saa7134_dev *dev) |
402 | { | 402 | { |
403 | struct card_ir *ir = dev->remote; | 403 | struct card_ir *ir; |
404 | |||
405 | if (!dev || !dev->remote) | ||
406 | return; | ||
407 | |||
408 | ir = dev->remote; | ||
409 | if (!ir->running) | ||
410 | return; | ||
404 | 411 | ||
405 | if (ir->nec_gpio) { | 412 | if (ir->nec_gpio) { |
406 | saa7134_nec_irq(dev); | 413 | saa7134_nec_irq(dev); |
@@ -432,10 +439,20 @@ void ir_raw_decode_timer_end(unsigned long data) | |||
432 | ir->active = 0; | 439 | ir->active = 0; |
433 | } | 440 | } |
434 | 441 | ||
435 | void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) | 442 | static int __saa7134_ir_start(void *priv) |
436 | { | 443 | { |
444 | struct saa7134_dev *dev = priv; | ||
445 | struct card_ir *ir; | ||
446 | |||
447 | if (!dev) | ||
448 | return -EINVAL; | ||
449 | |||
450 | ir = dev->remote; | ||
451 | if (!ir) | ||
452 | return -EINVAL; | ||
453 | |||
437 | if (ir->running) | 454 | if (ir->running) |
438 | return; | 455 | return 0; |
439 | 456 | ||
440 | ir->running = 1; | 457 | ir->running = 1; |
441 | if (ir->polling) { | 458 | if (ir->polling) { |
@@ -467,11 +484,21 @@ void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) | |||
467 | ir->timer_end.data = (unsigned long)dev; | 484 | ir->timer_end.data = (unsigned long)dev; |
468 | ir->active = 0; | 485 | ir->active = 0; |
469 | } | 486 | } |
487 | |||
488 | return 0; | ||
470 | } | 489 | } |
471 | 490 | ||
472 | void saa7134_ir_stop(struct saa7134_dev *dev) | 491 | static void __saa7134_ir_stop(void *priv) |
473 | { | 492 | { |
474 | struct card_ir *ir = dev->remote; | 493 | struct saa7134_dev *dev = priv; |
494 | struct card_ir *ir; | ||
495 | |||
496 | if (!dev) | ||
497 | return; | ||
498 | |||
499 | ir = dev->remote; | ||
500 | if (!ir) | ||
501 | return; | ||
475 | 502 | ||
476 | if (!ir->running) | 503 | if (!ir->running) |
477 | return; | 504 | return; |
@@ -487,8 +514,42 @@ void saa7134_ir_stop(struct saa7134_dev *dev) | |||
487 | } | 514 | } |
488 | 515 | ||
489 | ir->running = 0; | 516 | ir->running = 0; |
517 | |||
518 | return; | ||
519 | } | ||
520 | |||
521 | int saa7134_ir_start(struct saa7134_dev *dev) | ||
522 | { | ||
523 | if (dev->remote->users) | ||
524 | return __saa7134_ir_start(dev); | ||
525 | |||
526 | return 0; | ||
527 | } | ||
528 | |||
529 | void saa7134_ir_stop(struct saa7134_dev *dev) | ||
530 | { | ||
531 | if (dev->remote->users) | ||
532 | __saa7134_ir_stop(dev); | ||
533 | } | ||
534 | |||
535 | static int saa7134_ir_open(void *priv) | ||
536 | { | ||
537 | struct saa7134_dev *dev = priv; | ||
538 | |||
539 | dev->remote->users++; | ||
540 | return __saa7134_ir_start(dev); | ||
541 | } | ||
542 | |||
543 | static void saa7134_ir_close(void *priv) | ||
544 | { | ||
545 | struct saa7134_dev *dev = priv; | ||
546 | |||
547 | dev->remote->users--; | ||
548 | if (!dev->remote->users) | ||
549 | __saa7134_ir_stop(dev); | ||
490 | } | 550 | } |
491 | 551 | ||
552 | |||
492 | int saa7134_ir_change_protocol(void *priv, u64 ir_type) | 553 | int saa7134_ir_change_protocol(void *priv, u64 ir_type) |
493 | { | 554 | { |
494 | struct saa7134_dev *dev = priv; | 555 | struct saa7134_dev *dev = priv; |
@@ -513,7 +574,7 @@ int saa7134_ir_change_protocol(void *priv, u64 ir_type) | |||
513 | saa7134_ir_stop(dev); | 574 | saa7134_ir_stop(dev); |
514 | ir->nec_gpio = nec_gpio; | 575 | ir->nec_gpio = nec_gpio; |
515 | ir->rc5_gpio = rc5_gpio; | 576 | ir->rc5_gpio = rc5_gpio; |
516 | saa7134_ir_start(dev, ir); | 577 | saa7134_ir_start(dev); |
517 | } else { | 578 | } else { |
518 | ir->nec_gpio = nec_gpio; | 579 | ir->nec_gpio = nec_gpio; |
519 | ir->rc5_gpio = rc5_gpio; | 580 | ir->rc5_gpio = rc5_gpio; |
@@ -788,9 +849,13 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
788 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", | 849 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", |
789 | pci_name(dev->pci)); | 850 | pci_name(dev->pci)); |
790 | 851 | ||
852 | |||
853 | ir->props.priv = dev; | ||
854 | ir->props.open = saa7134_ir_open; | ||
855 | ir->props.close = saa7134_ir_close; | ||
856 | |||
791 | if (ir_codes->ir_type != IR_TYPE_OTHER && !raw_decode) { | 857 | if (ir_codes->ir_type != IR_TYPE_OTHER && !raw_decode) { |
792 | ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; | 858 | ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; |
793 | ir->props.priv = dev; | ||
794 | ir->props.change_protocol = saa7134_ir_change_protocol; | 859 | ir->props.change_protocol = saa7134_ir_change_protocol; |
795 | 860 | ||
796 | /* Set IR protocol */ | 861 | /* Set IR protocol */ |
@@ -815,25 +880,21 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
815 | 880 | ||
816 | err = ir_input_register(ir->dev, ir_codes, &ir->props, MODULE_NAME); | 881 | err = ir_input_register(ir->dev, ir_codes, &ir->props, MODULE_NAME); |
817 | if (err) | 882 | if (err) |
818 | goto err_out_stop; | 883 | goto err_out_free; |
819 | if (ir_codes->ir_type != IR_TYPE_OTHER) { | 884 | if (ir_codes->ir_type != IR_TYPE_OTHER) { |
820 | err = ir_raw_event_register(ir->dev); | 885 | err = ir_raw_event_register(ir->dev); |
821 | if (err) | 886 | if (err) |
822 | goto err_out_stop; | 887 | goto err_out_free; |
823 | } | 888 | } |
824 | 889 | ||
825 | saa7134_ir_start(dev, ir); | ||
826 | |||
827 | /* the remote isn't as bouncy as a keyboard */ | 890 | /* the remote isn't as bouncy as a keyboard */ |
828 | ir->dev->rep[REP_DELAY] = repeat_delay; | 891 | ir->dev->rep[REP_DELAY] = repeat_delay; |
829 | ir->dev->rep[REP_PERIOD] = repeat_period; | 892 | ir->dev->rep[REP_PERIOD] = repeat_period; |
830 | 893 | ||
831 | return 0; | 894 | return 0; |
832 | 895 | ||
833 | err_out_stop: | 896 | err_out_free: |
834 | saa7134_ir_stop(dev); | ||
835 | dev->remote = NULL; | 897 | dev->remote = NULL; |
836 | err_out_free: | ||
837 | kfree(ir); | 898 | kfree(ir); |
838 | return err; | 899 | return err; |
839 | } | 900 | } |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index c3a1ae0adca0..cad8aee98e53 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -20,7 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/version.h> | 22 | #include <linux/version.h> |
23 | #define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,15) | 23 | #define SAA7134_VERSION_CODE KERNEL_VERSION(0, 2, 16) |
24 | 24 | ||
25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
26 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
@@ -810,7 +810,7 @@ int saa7134_input_init1(struct saa7134_dev *dev); | |||
810 | void saa7134_input_fini(struct saa7134_dev *dev); | 810 | void saa7134_input_fini(struct saa7134_dev *dev); |
811 | void saa7134_input_irq(struct saa7134_dev *dev); | 811 | void saa7134_input_irq(struct saa7134_dev *dev); |
812 | void saa7134_probe_i2c_ir(struct saa7134_dev *dev); | 812 | void saa7134_probe_i2c_ir(struct saa7134_dev *dev); |
813 | void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir); | 813 | int saa7134_ir_start(struct saa7134_dev *dev); |
814 | void saa7134_ir_stop(struct saa7134_dev *dev); | 814 | void saa7134_ir_stop(struct saa7134_dev *dev); |
815 | 815 | ||
816 | 816 | ||
diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 87f2ec78deb8..e403a9a5281a 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h | |||
@@ -50,6 +50,7 @@ struct card_ir { | |||
50 | struct ir_input_state ir; | 50 | struct ir_input_state ir; |
51 | char name[32]; | 51 | char name[32]; |
52 | char phys[32]; | 52 | char phys[32]; |
53 | int users; | ||
53 | 54 | ||
54 | u32 running:1; | 55 | u32 running:1; |
55 | struct ir_dev_props props; | 56 | struct ir_dev_props props; |
diff --git a/include/media/ir-core.h b/include/media/ir-core.h index c704fa7cc11e..9a2f3084ffec 100644 --- a/include/media/ir-core.h +++ b/include/media/ir-core.h | |||
@@ -56,6 +56,8 @@ struct ir_dev_props { | |||
56 | unsigned long allowed_protos; | 56 | unsigned long allowed_protos; |
57 | void *priv; | 57 | void *priv; |
58 | int (*change_protocol)(void *priv, u64 ir_type); | 58 | int (*change_protocol)(void *priv, u64 ir_type); |
59 | int (*open)(void *priv); | ||
60 | void (*close)(void *priv); | ||
59 | }; | 61 | }; |
60 | 62 | ||
61 | struct ir_raw_event { | 63 | struct ir_raw_event { |