Commit | Line | Data |
---|---|---|
c79b339f AP |
1 | /* dvb-usb-remote.c is part of the DVB USB library. |
2 | * | |
3 | * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de) | |
4 | * see dvb-usb-init.c for copyright information. | |
5 | * | |
4e60d951 AP |
6 | * This file contains functions for initializing the input-device and for |
7 | * handling remote-control-queries. | |
c79b339f AP |
8 | */ |
9 | #include "dvb_usb_common.h" | |
10 | #include <linux/usb/input.h> | |
11 | ||
c79b339f AP |
12 | /* Remote-control poll function - called every dib->rc_query_interval ms to see |
13 | * whether the remote control has received anything. | |
14 | * | |
15 | * TODO: Fix the repeat rate of the input device. | |
16 | */ | |
17 | static void dvb_usb_read_remote_control(struct work_struct *work) | |
18 | { | |
19 | struct dvb_usb_device *d = | |
20 | container_of(work, struct dvb_usb_device, rc_query_work.work); | |
21 | int err; | |
22 | ||
4e60d951 AP |
23 | /* TODO: need a lock here. We can simply skip checking for the remote |
24 | control if we're busy. */ | |
c79b339f AP |
25 | |
26 | /* when the parameter has been set to 1 via sysfs while the | |
27 | * driver was running, or when bulk mode is enabled after IR init | |
28 | */ | |
64921670 | 29 | if (dvb_usb_disable_rc_polling || d->props.rc.bulk_mode) |
c79b339f AP |
30 | return; |
31 | ||
64921670 | 32 | err = d->props.rc.rc_query(d); |
c79b339f | 33 | if (err) |
4e60d951 AP |
34 | err("error %d while querying for an remote control event.", |
35 | err); | |
c79b339f AP |
36 | |
37 | schedule_delayed_work(&d->rc_query_work, | |
64921670 | 38 | msecs_to_jiffies(d->props.rc.rc_interval)); |
c79b339f AP |
39 | } |
40 | ||
41 | static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) | |
42 | { | |
43 | int err, rc_interval; | |
44 | struct rc_dev *dev; | |
45 | ||
46 | dev = rc_allocate_device(); | |
47 | if (!dev) | |
48 | return -ENOMEM; | |
49 | ||
64921670 AP |
50 | dev->driver_name = d->props.rc.module_name; |
51 | dev->map_name = d->rc_map; | |
52 | dev->change_protocol = d->props.rc.change_protocol; | |
53 | dev->allowed_protos = d->props.rc.allowed_protos; | |
54 | dev->driver_type = d->props.rc.driver_type; | |
c79b339f AP |
55 | usb_to_input_id(d->udev, &dev->input_id); |
56 | dev->input_name = "IR-receiver inside an USB DVB receiver"; | |
57 | dev->input_phys = d->rc_phys; | |
58 | dev->dev.parent = &d->udev->dev; | |
59 | dev->priv = d; | |
60 | ||
64921670 AP |
61 | /* leave remote controller enabled even there is no default map */ |
62 | if (dev->map_name == NULL) | |
63 | dev->map_name = RC_MAP_EMPTY; | |
64 | ||
c79b339f AP |
65 | err = rc_register_device(dev); |
66 | if (err < 0) { | |
67 | rc_free_device(dev); | |
68 | return err; | |
69 | } | |
70 | ||
71 | d->input_dev = NULL; | |
72 | d->rc_dev = dev; | |
73 | ||
64921670 | 74 | if (!d->props.rc.rc_query || d->props.rc.bulk_mode) |
c79b339f AP |
75 | return 0; |
76 | ||
77 | /* Polling mode - initialize a work queue for handling it */ | |
78 | INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control); | |
79 | ||
64921670 | 80 | rc_interval = d->props.rc.rc_interval; |
c79b339f AP |
81 | |
82 | info("schedule remote query interval to %d msecs.", rc_interval); | |
83 | schedule_delayed_work(&d->rc_query_work, | |
84 | msecs_to_jiffies(rc_interval)); | |
85 | ||
86 | return 0; | |
87 | } | |
88 | ||
89 | int dvb_usb_remote_init(struct dvb_usb_device *d) | |
90 | { | |
91 | int err; | |
92 | ||
93 | if (dvb_usb_disable_rc_polling) | |
94 | return 0; | |
95 | ||
64921670 | 96 | if (d->props.rc.module_name == NULL) |
c79b339f AP |
97 | return 0; |
98 | ||
99 | usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys)); | |
100 | strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys)); | |
101 | ||
102 | /* Start the remote-control polling. */ | |
64921670 | 103 | err = rc_core_dvb_usb_remote_init(d); |
c79b339f AP |
104 | if (err) |
105 | return err; | |
106 | ||
107 | d->state |= DVB_USB_STATE_REMOTE; | |
108 | ||
109 | return 0; | |
110 | } | |
111 | ||
112 | int dvb_usb_remote_exit(struct dvb_usb_device *d) | |
113 | { | |
114 | if (d->state & DVB_USB_STATE_REMOTE) { | |
115 | cancel_delayed_work_sync(&d->rc_query_work); | |
64921670 | 116 | rc_unregister_device(d->rc_dev); |
c79b339f AP |
117 | } |
118 | d->state &= ~DVB_USB_STATE_REMOTE; | |
119 | return 0; | |
120 | } |