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 /drivers/media/video/saa7134 | |
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>
Diffstat (limited to 'drivers/media/video/saa7134')
-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 |
3 files changed, 78 insertions, 17 deletions
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 | ||