diff options
Diffstat (limited to 'drivers/media/dvb/cinergyT2/cinergyT2.c')
-rw-r--r-- | drivers/media/dvb/cinergyT2/cinergyT2.c | 108 |
1 files changed, 70 insertions, 38 deletions
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index 6db0929ef53d..a1607e7d6d6b 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c | |||
@@ -137,7 +137,8 @@ struct cinergyt2 { | |||
137 | struct urb *stream_urb [STREAM_URB_COUNT]; | 137 | struct urb *stream_urb [STREAM_URB_COUNT]; |
138 | 138 | ||
139 | #ifdef ENABLE_RC | 139 | #ifdef ENABLE_RC |
140 | struct input_dev rc_input_dev; | 140 | struct input_dev *rc_input_dev; |
141 | char phys[64]; | ||
141 | struct work_struct rc_query_work; | 142 | struct work_struct rc_query_work; |
142 | int rc_input_event; | 143 | int rc_input_event; |
143 | u32 rc_last_code; | 144 | u32 rc_last_code; |
@@ -683,6 +684,7 @@ static struct dvb_device cinergyt2_fe_template = { | |||
683 | }; | 684 | }; |
684 | 685 | ||
685 | #ifdef ENABLE_RC | 686 | #ifdef ENABLE_RC |
687 | |||
686 | static void cinergyt2_query_rc (void *data) | 688 | static void cinergyt2_query_rc (void *data) |
687 | { | 689 | { |
688 | struct cinergyt2 *cinergyt2 = data; | 690 | struct cinergyt2 *cinergyt2 = data; |
@@ -703,7 +705,7 @@ static void cinergyt2_query_rc (void *data) | |||
703 | /* stop key repeat */ | 705 | /* stop key repeat */ |
704 | if (cinergyt2->rc_input_event != KEY_MAX) { | 706 | if (cinergyt2->rc_input_event != KEY_MAX) { |
705 | dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event); | 707 | dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event); |
706 | input_report_key(&cinergyt2->rc_input_dev, | 708 | input_report_key(cinergyt2->rc_input_dev, |
707 | cinergyt2->rc_input_event, 0); | 709 | cinergyt2->rc_input_event, 0); |
708 | cinergyt2->rc_input_event = KEY_MAX; | 710 | cinergyt2->rc_input_event = KEY_MAX; |
709 | } | 711 | } |
@@ -722,7 +724,7 @@ static void cinergyt2_query_rc (void *data) | |||
722 | /* keyrepeat bit -> just repeat last rc_input_event */ | 724 | /* keyrepeat bit -> just repeat last rc_input_event */ |
723 | } else { | 725 | } else { |
724 | cinergyt2->rc_input_event = KEY_MAX; | 726 | cinergyt2->rc_input_event = KEY_MAX; |
725 | for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3) { | 727 | for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3) { |
726 | if (rc_keys[i + 0] == rc_events[n].type && | 728 | if (rc_keys[i + 0] == rc_events[n].type && |
727 | rc_keys[i + 1] == le32_to_cpu(rc_events[n].value)) { | 729 | rc_keys[i + 1] == le32_to_cpu(rc_events[n].value)) { |
728 | cinergyt2->rc_input_event = rc_keys[i + 2]; | 730 | cinergyt2->rc_input_event = rc_keys[i + 2]; |
@@ -736,11 +738,11 @@ static void cinergyt2_query_rc (void *data) | |||
736 | cinergyt2->rc_last_code != ~0) { | 738 | cinergyt2->rc_last_code != ~0) { |
737 | /* emit a key-up so the double event is recognized */ | 739 | /* emit a key-up so the double event is recognized */ |
738 | dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event); | 740 | dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event); |
739 | input_report_key(&cinergyt2->rc_input_dev, | 741 | input_report_key(cinergyt2->rc_input_dev, |
740 | cinergyt2->rc_input_event, 0); | 742 | cinergyt2->rc_input_event, 0); |
741 | } | 743 | } |
742 | dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event); | 744 | dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event); |
743 | input_report_key(&cinergyt2->rc_input_dev, | 745 | input_report_key(cinergyt2->rc_input_dev, |
744 | cinergyt2->rc_input_event, 1); | 746 | cinergyt2->rc_input_event, 1); |
745 | cinergyt2->rc_last_code = rc_events[n].value; | 747 | cinergyt2->rc_last_code = rc_events[n].value; |
746 | } | 748 | } |
@@ -752,7 +754,59 @@ out: | |||
752 | 754 | ||
753 | up(&cinergyt2->sem); | 755 | up(&cinergyt2->sem); |
754 | } | 756 | } |
755 | #endif | 757 | |
758 | static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) | ||
759 | { | ||
760 | struct input_dev *input_dev; | ||
761 | int i; | ||
762 | |||
763 | cinergyt2->rc_input_dev = input_dev = input_allocate_device(); | ||
764 | if (!input_dev) | ||
765 | return -ENOMEM; | ||
766 | |||
767 | usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys)); | ||
768 | strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys)); | ||
769 | cinergyt2->rc_input_event = KEY_MAX; | ||
770 | cinergyt2->rc_last_code = ~0; | ||
771 | INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2); | ||
772 | |||
773 | input_dev->name = DRIVER_NAME " remote control"; | ||
774 | input_dev->phys = cinergyt2->phys; | ||
775 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | ||
776 | for (i = 0; ARRAY_SIZE(rc_keys); i += 3) | ||
777 | set_bit(rc_keys[i + 2], input_dev->keybit); | ||
778 | input_dev->keycodesize = 0; | ||
779 | input_dev->keycodemax = 0; | ||
780 | |||
781 | input_register_device(cinergyt2->rc_input_dev); | ||
782 | schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); | ||
783 | } | ||
784 | |||
785 | static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) | ||
786 | { | ||
787 | cancel_delayed_work(&cinergyt2->rc_query_work); | ||
788 | flush_scheduled_work(); | ||
789 | input_unregister_device(cinergyt2->rc_input_dev); | ||
790 | } | ||
791 | |||
792 | static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) | ||
793 | { | ||
794 | cancel_delayed_work(&cinergyt2->rc_query_work); | ||
795 | } | ||
796 | |||
797 | static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) | ||
798 | { | ||
799 | schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); | ||
800 | } | ||
801 | |||
802 | #else | ||
803 | |||
804 | static inline int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) { return 0; } | ||
805 | static inline void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) { } | ||
806 | static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) { } | ||
807 | static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) { } | ||
808 | |||
809 | #endif /* ENABLE_RC */ | ||
756 | 810 | ||
757 | static void cinergyt2_query (void *data) | 811 | static void cinergyt2_query (void *data) |
758 | { | 812 | { |
@@ -789,9 +843,6 @@ static int cinergyt2_probe (struct usb_interface *intf, | |||
789 | { | 843 | { |
790 | struct cinergyt2 *cinergyt2; | 844 | struct cinergyt2 *cinergyt2; |
791 | int err; | 845 | int err; |
792 | #ifdef ENABLE_RC | ||
793 | int i; | ||
794 | #endif | ||
795 | 846 | ||
796 | if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) { | 847 | if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) { |
797 | dprintk(1, "out of memory?!?\n"); | 848 | dprintk(1, "out of memory?!?\n"); |
@@ -846,30 +897,17 @@ static int cinergyt2_probe (struct usb_interface *intf, | |||
846 | &cinergyt2_fe_template, cinergyt2, | 897 | &cinergyt2_fe_template, cinergyt2, |
847 | DVB_DEVICE_FRONTEND); | 898 | DVB_DEVICE_FRONTEND); |
848 | 899 | ||
849 | #ifdef ENABLE_RC | 900 | err = cinergyt2_register_rc(cinergyt2); |
850 | cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | 901 | if (err) |
851 | cinergyt2->rc_input_dev.keycodesize = 0; | 902 | goto bailout; |
852 | cinergyt2->rc_input_dev.keycodemax = 0; | ||
853 | cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control"; | ||
854 | |||
855 | for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3) | ||
856 | set_bit(rc_keys[i + 2], cinergyt2->rc_input_dev.keybit); | ||
857 | |||
858 | input_register_device(&cinergyt2->rc_input_dev); | ||
859 | |||
860 | cinergyt2->rc_input_event = KEY_MAX; | ||
861 | cinergyt2->rc_last_code = ~0; | ||
862 | 903 | ||
863 | INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2); | ||
864 | schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); | ||
865 | #endif | ||
866 | return 0; | 904 | return 0; |
867 | 905 | ||
868 | bailout: | 906 | bailout: |
869 | dvb_dmxdev_release(&cinergyt2->dmxdev); | 907 | dvb_dmxdev_release(&cinergyt2->dmxdev); |
870 | dvb_dmx_release(&cinergyt2->demux); | 908 | dvb_dmx_release(&cinergyt2->demux); |
871 | dvb_unregister_adapter (&cinergyt2->adapter); | 909 | dvb_unregister_adapter(&cinergyt2->adapter); |
872 | cinergyt2_free_stream_urbs (cinergyt2); | 910 | cinergyt2_free_stream_urbs(cinergyt2); |
873 | kfree(cinergyt2); | 911 | kfree(cinergyt2); |
874 | return -ENOMEM; | 912 | return -ENOMEM; |
875 | } | 913 | } |
@@ -881,11 +919,7 @@ static void cinergyt2_disconnect (struct usb_interface *intf) | |||
881 | if (down_interruptible(&cinergyt2->sem)) | 919 | if (down_interruptible(&cinergyt2->sem)) |
882 | return; | 920 | return; |
883 | 921 | ||
884 | #ifdef ENABLE_RC | 922 | cinergyt2_unregister_rc(cinergyt2); |
885 | cancel_delayed_work(&cinergyt2->rc_query_work); | ||
886 | flush_scheduled_work(); | ||
887 | input_unregister_device(&cinergyt2->rc_input_dev); | ||
888 | #endif | ||
889 | 923 | ||
890 | cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx); | 924 | cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx); |
891 | dvb_net_release(&cinergyt2->dvbnet); | 925 | dvb_net_release(&cinergyt2->dvbnet); |
@@ -908,9 +942,8 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) | |||
908 | 942 | ||
909 | if (state.event > PM_EVENT_ON) { | 943 | if (state.event > PM_EVENT_ON) { |
910 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); | 944 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); |
911 | #ifdef ENABLE_RC | 945 | |
912 | cancel_delayed_work(&cinergyt2->rc_query_work); | 946 | cinergyt2_suspend_rc(cinergyt2); |
913 | #endif | ||
914 | cancel_delayed_work(&cinergyt2->query_work); | 947 | cancel_delayed_work(&cinergyt2->query_work); |
915 | if (cinergyt2->streaming) | 948 | if (cinergyt2->streaming) |
916 | cinergyt2_stop_stream_xfer(cinergyt2); | 949 | cinergyt2_stop_stream_xfer(cinergyt2); |
@@ -938,9 +971,8 @@ static int cinergyt2_resume (struct usb_interface *intf) | |||
938 | schedule_delayed_work(&cinergyt2->query_work, HZ/2); | 971 | schedule_delayed_work(&cinergyt2->query_work, HZ/2); |
939 | } | 972 | } |
940 | 973 | ||
941 | #ifdef ENABLE_RC | 974 | cinergyt2_resume_rc(cinergyt2); |
942 | schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2); | 975 | |
943 | #endif | ||
944 | up(&cinergyt2->sem); | 976 | up(&cinergyt2->sem); |
945 | return 0; | 977 | return 0; |
946 | } | 978 | } |