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 | } |
