aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorJohannes Stezenbach <js@linuxtv.org>2005-09-09 16:03:05 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 16:57:44 -0400
commit6d78933c291bd0b6292e2c631e2f5e346c14d3fa (patch)
tree213258393d3cc5973b6ac2c890cf7ad9035febf8 /drivers/media
parent2d6e7322b5f63d62ec8785c5fbf469c9a233baff (diff)
[PATCH] dvb: cinergyT2: remote control fixes
IR RC fixes: - EVIOCSKEYCODE is not supported by this driver, fix potential crash when it is used by not setting rc_input_dev->keycodesize - fix key repeat handling (hopefully) - reduce default poll internal to 50msec (necessary for key repeat handling) Signed-off-by: Johannes Stezenbach <js@linuxtv.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/cinergyT2/Kconfig2
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c93
2 files changed, 57 insertions, 38 deletions
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig
index 226714085f58..7cf4c4a888ec 100644
--- a/drivers/media/dvb/cinergyT2/Kconfig
+++ b/drivers/media/dvb/cinergyT2/Kconfig
@@ -77,7 +77,7 @@ config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
77config DVB_CINERGYT2_RC_QUERY_INTERVAL 77config DVB_CINERGYT2_RC_QUERY_INTERVAL
78 int "Infrared Remote Controller update interval [milliseconds]" 78 int "Infrared Remote Controller update interval [milliseconds]"
79 depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE 79 depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
80 default "100" 80 default "50"
81 help 81 help
82 If you have a very fast-repeating remote control you can try lower 82 If you have a very fast-repeating remote control you can try lower
83 values, for normal consumer receivers the default value should be 83 values, for normal consumer receivers the default value should be
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index c52e9d5c3d96..6db0929ef53d 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -35,7 +35,6 @@
35#include "dvb_demux.h" 35#include "dvb_demux.h"
36#include "dvb_net.h" 36#include "dvb_net.h"
37 37
38
39#ifdef CONFIG_DVB_CINERGYT2_TUNING 38#ifdef CONFIG_DVB_CINERGYT2_TUNING
40 #define STREAM_URB_COUNT (CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT) 39 #define STREAM_URB_COUNT (CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT)
41 #define STREAM_BUF_SIZE (CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE) 40 #define STREAM_BUF_SIZE (CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE)
@@ -48,7 +47,7 @@
48 #define STREAM_URB_COUNT (32) 47 #define STREAM_URB_COUNT (32)
49 #define STREAM_BUF_SIZE (512) /* bytes */ 48 #define STREAM_BUF_SIZE (512) /* bytes */
50 #define ENABLE_RC (1) 49 #define ENABLE_RC (1)
51 #define RC_QUERY_INTERVAL (100) /* milliseconds */ 50 #define RC_QUERY_INTERVAL (50) /* milliseconds */
52 #define QUERY_INTERVAL (333) /* milliseconds */ 51 #define QUERY_INTERVAL (333) /* milliseconds */
53#endif 52#endif
54 53
@@ -141,6 +140,8 @@ struct cinergyt2 {
141 struct input_dev rc_input_dev; 140 struct input_dev rc_input_dev;
142 struct work_struct rc_query_work; 141 struct work_struct rc_query_work;
143 int rc_input_event; 142 int rc_input_event;
143 u32 rc_last_code;
144 unsigned long last_event_jiffies;
144#endif 145#endif
145}; 146};
146 147
@@ -155,7 +156,7 @@ struct cinergyt2_rc_event {
155 uint32_t value; 156 uint32_t value;
156} __attribute__((packed)); 157} __attribute__((packed));
157 158
158static const uint32_t rc_keys [] = { 159static const uint32_t rc_keys[] = {
159 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfe01eb04, KEY_POWER, 160 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfe01eb04, KEY_POWER,
160 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfd02eb04, KEY_1, 161 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfd02eb04, KEY_1,
161 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfc03eb04, KEY_2, 162 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfc03eb04, KEY_2,
@@ -684,52 +685,68 @@ static struct dvb_device cinergyt2_fe_template = {
684#ifdef ENABLE_RC 685#ifdef ENABLE_RC
685static void cinergyt2_query_rc (void *data) 686static void cinergyt2_query_rc (void *data)
686{ 687{
687 struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data; 688 struct cinergyt2 *cinergyt2 = data;
688 char buf [1] = { CINERGYT2_EP1_GET_RC_EVENTS }; 689 char buf[1] = { CINERGYT2_EP1_GET_RC_EVENTS };
689 struct cinergyt2_rc_event rc_events[12]; 690 struct cinergyt2_rc_event rc_events[12];
690 int n, len; 691 int n, len, i;
691 692
692 if (down_interruptible(&cinergyt2->sem)) 693 if (down_interruptible(&cinergyt2->sem))
693 return; 694 return;
694 695
695 len = cinergyt2_command(cinergyt2, buf, sizeof(buf), 696 len = cinergyt2_command(cinergyt2, buf, sizeof(buf),
696 (char *) rc_events, sizeof(rc_events)); 697 (char *) rc_events, sizeof(rc_events));
697 698 if (len < 0)
698 for (n=0; len>0 && n<(len/sizeof(rc_events[0])); n++) { 699 goto out;
699 int i; 700 if (len == 0) {
701 if (time_after(jiffies, cinergyt2->last_event_jiffies +
702 msecs_to_jiffies(150))) {
703 /* stop key repeat */
704 if (cinergyt2->rc_input_event != KEY_MAX) {
705 dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event);
706 input_report_key(&cinergyt2->rc_input_dev,
707 cinergyt2->rc_input_event, 0);
708 cinergyt2->rc_input_event = KEY_MAX;
709 }
710 cinergyt2->rc_last_code = ~0;
711 }
712 goto out;
713 }
714 cinergyt2->last_event_jiffies = jiffies;
700 715
701/* dprintk(1,"rc_events[%d].value = %x, type=%x\n",n,le32_to_cpu(rc_events[n].value),rc_events[n].type);*/ 716 for (n = 0; n < (len / sizeof(rc_events[0])); n++) {
717 dprintk(1, "rc_events[%d].value = %x, type=%x\n",
718 n, le32_to_cpu(rc_events[n].value), rc_events[n].type);
702 719
703 if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC && 720 if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC &&
704 rc_events[n].value == ~0) 721 rc_events[n].value == ~0) {
705 { 722 /* keyrepeat bit -> just repeat last rc_input_event */
706 /**
707 * keyrepeat bit. If we would handle this properly
708 * we would need to emit down events as long the
709 * keyrepeat goes, a up event if no further
710 * repeat bits occur. Would need a timer to implement
711 * and no other driver does this, so we simply
712 * emit the last key up/down sequence again.
713 */
714 } else { 723 } else {
715 cinergyt2->rc_input_event = KEY_MAX; 724 cinergyt2->rc_input_event = KEY_MAX;
716 for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3) { 725 for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3) {
717 if (rc_keys[i+0] == rc_events[n].type && 726 if (rc_keys[i + 0] == rc_events[n].type &&
718 rc_keys[i+1] == le32_to_cpu(rc_events[n].value)) 727 rc_keys[i + 1] == le32_to_cpu(rc_events[n].value)) {
719 { 728 cinergyt2->rc_input_event = rc_keys[i + 2];
720 cinergyt2->rc_input_event = rc_keys[i+2];
721 break; 729 break;
722 } 730 }
723 } 731 }
724 } 732 }
725 733
726 if (cinergyt2->rc_input_event != KEY_MAX) { 734 if (cinergyt2->rc_input_event != KEY_MAX) {
727 input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 1); 735 if (rc_events[n].value == cinergyt2->rc_last_code &&
728 input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 0); 736 cinergyt2->rc_last_code != ~0) {
729 input_sync(&cinergyt2->rc_input_dev); 737 /* emit a key-up so the double event is recognized */
738 dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event);
739 input_report_key(&cinergyt2->rc_input_dev,
740 cinergyt2->rc_input_event, 0);
741 }
742 dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event);
743 input_report_key(&cinergyt2->rc_input_dev,
744 cinergyt2->rc_input_event, 1);
745 cinergyt2->rc_last_code = rc_events[n].value;
730 } 746 }
731 } 747 }
732 748
749out:
733 schedule_delayed_work(&cinergyt2->rc_query_work, 750 schedule_delayed_work(&cinergyt2->rc_query_work,
734 msecs_to_jiffies(RC_QUERY_INTERVAL)); 751 msecs_to_jiffies(RC_QUERY_INTERVAL));
735 752
@@ -771,7 +788,10 @@ static int cinergyt2_probe (struct usb_interface *intf,
771 const struct usb_device_id *id) 788 const struct usb_device_id *id)
772{ 789{
773 struct cinergyt2 *cinergyt2; 790 struct cinergyt2 *cinergyt2;
774 int i, err; 791 int err;
792#ifdef ENABLE_RC
793 int i;
794#endif
775 795
776 if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) { 796 if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) {
777 dprintk(1, "out of memory?!?\n"); 797 dprintk(1, "out of memory?!?\n");
@@ -827,19 +847,18 @@ static int cinergyt2_probe (struct usb_interface *intf,
827 DVB_DEVICE_FRONTEND); 847 DVB_DEVICE_FRONTEND);
828 848
829#ifdef ENABLE_RC 849#ifdef ENABLE_RC
830 init_input_dev(&cinergyt2->rc_input_dev); 850 cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
831 851 cinergyt2->rc_input_dev.keycodesize = 0;
832 cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY); 852 cinergyt2->rc_input_dev.keycodemax = 0;
833 cinergyt2->rc_input_dev.keycodesize = sizeof(unsigned char);
834 cinergyt2->rc_input_dev.keycodemax = KEY_MAX;
835 cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control"; 853 cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control";
836 854
837 for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3) 855 for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3)
838 set_bit(rc_keys[i+2], cinergyt2->rc_input_dev.keybit); 856 set_bit(rc_keys[i + 2], cinergyt2->rc_input_dev.keybit);
839 857
840 input_register_device(&cinergyt2->rc_input_dev); 858 input_register_device(&cinergyt2->rc_input_dev);
841 859
842 cinergyt2->rc_input_event = KEY_MAX; 860 cinergyt2->rc_input_event = KEY_MAX;
861 cinergyt2->rc_last_code = ~0;
843 862
844 INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2); 863 INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
845 schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); 864 schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);