aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb/dvb_usb_remote.c
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2012-05-25 09:19:03 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-04 06:56:22 -0400
commit649216704aaa1148c638346ec4c0dc71b164f521 (patch)
treef5b30b2eea03ddb9bf95dd230bb0ed666056be0d /drivers/media/dvb/dvb-usb/dvb_usb_remote.c
parent43402bbde52e96f950994bc55700814db8d5bc81 (diff)
[media] dvb_usb_v2: remote controller
* remove old legacy code totally * move default RC keymap definition the the (struct dvb_usb_driver_info) Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/dvb-usb/dvb_usb_remote.c')
-rw-r--r--drivers/media/dvb/dvb-usb/dvb_usb_remote.c278
1 files changed, 17 insertions, 261 deletions
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_remote.c b/drivers/media/dvb/dvb-usb/dvb_usb_remote.c
index b445990644a..b8d2cb193bb 100644
--- a/drivers/media/dvb/dvb-usb/dvb_usb_remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb_usb_remote.c
@@ -9,200 +9,6 @@
9#include "dvb_usb_common.h" 9#include "dvb_usb_common.h"
10#include <linux/usb/input.h> 10#include <linux/usb/input.h>
11 11
12static unsigned int
13legacy_dvb_usb_get_keymap_index(const struct input_keymap_entry *ke,
14 struct rc_map_table *keymap,
15 unsigned int keymap_size)
16{
17 unsigned int index;
18 unsigned int scancode;
19
20 if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
21 index = ke->index;
22 } else {
23 if (input_scancode_to_scalar(ke, &scancode))
24 return keymap_size;
25
26 /* See if we can match the raw key code. */
27 for (index = 0; index < keymap_size; index++)
28 if (keymap[index].scancode == scancode)
29 break;
30
31 /* See if there is an unused hole in the map */
32 if (index >= keymap_size) {
33 for (index = 0; index < keymap_size; index++) {
34 if (keymap[index].keycode == KEY_RESERVED ||
35 keymap[index].keycode == KEY_UNKNOWN) {
36 break;
37 }
38 }
39 }
40 }
41
42 return index;
43}
44
45static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
46 struct input_keymap_entry *ke)
47{
48 struct dvb_usb_device *d = input_get_drvdata(dev);
49 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
50 unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
51 unsigned int index;
52
53 index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
54 if (index >= keymap_size)
55 return -EINVAL;
56
57 ke->keycode = keymap[index].keycode;
58 if (ke->keycode == KEY_UNKNOWN)
59 ke->keycode = KEY_RESERVED;
60 ke->len = sizeof(keymap[index].scancode);
61 memcpy(&ke->scancode, &keymap[index].scancode, ke->len);
62 ke->index = index;
63
64 return 0;
65}
66
67static int legacy_dvb_usb_setkeycode(struct input_dev *dev,
68 const struct input_keymap_entry *ke,
69 unsigned int *old_keycode)
70{
71 struct dvb_usb_device *d = input_get_drvdata(dev);
72 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
73 unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
74 unsigned int index;
75
76 index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
77 /*
78 * FIXME: Currently, it is not possible to increase the size of
79 * scancode table. For it to happen, one possibility
80 * would be to allocate a table with key_map_size + 1,
81 * copying data, appending the new key on it, and freeing
82 * the old one - or maybe just allocating some spare space
83 */
84 if (index >= keymap_size)
85 return -EINVAL;
86
87 *old_keycode = keymap[index].keycode;
88 keymap->keycode = ke->keycode;
89 __set_bit(ke->keycode, dev->keybit);
90
91 if (*old_keycode != KEY_RESERVED) {
92 __clear_bit(*old_keycode, dev->keybit);
93 for (index = 0; index < keymap_size; index++) {
94 if (keymap[index].keycode == *old_keycode) {
95 __set_bit(*old_keycode, dev->keybit);
96 break;
97 }
98 }
99 }
100
101 return 0;
102}
103
104/* Remote-control poll function - called every dib->rc_query_interval ms to see
105 * whether the remote control has received anything.
106 *
107 * TODO: Fix the repeat rate of the input device.
108 */
109static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
110{
111 struct dvb_usb_device *d =
112 container_of(work, struct dvb_usb_device, rc_query_work.work);
113 u32 event;
114 int state;
115
116 /* TODO: need a lock here. We can simply skip checking for the remote
117 control if we're busy. */
118
119 /* when the parameter has been set to 1 via sysfs while the driver
120 was running */
121 if (dvb_usb_disable_rc_polling)
122 return;
123
124 if (d->props.rc.legacy.rc_query(d, &event, &state)) {
125 err("error while querying for an remote control event.");
126 goto schedule;
127 }
128
129
130 switch (state) {
131 case REMOTE_NO_KEY_PRESSED:
132 break;
133 case REMOTE_KEY_PRESSED:
134 deb_rc("key pressed\n");
135 d->last_event = event;
136 case REMOTE_KEY_REPEAT:
137 deb_rc("key repeated\n");
138 input_event(d->input_dev, EV_KEY, event, 1);
139 input_sync(d->input_dev);
140 input_event(d->input_dev, EV_KEY, d->last_event, 0);
141 input_sync(d->input_dev);
142 break;
143 default:
144 break;
145 }
146
147schedule:
148 schedule_delayed_work(&d->rc_query_work,
149 msecs_to_jiffies(d->props.rc.legacy.rc_interval));
150}
151
152static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
153{
154 int i, err, rc_interval;
155 struct input_dev *input_dev;
156
157 input_dev = input_allocate_device();
158 if (!input_dev)
159 return -ENOMEM;
160
161 input_dev->evbit[0] = BIT_MASK(EV_KEY);
162 input_dev->name = "IR-receiver inside an USB DVB receiver";
163 input_dev->phys = d->rc_phys;
164 usb_to_input_id(d->udev, &input_dev->id);
165 input_dev->dev.parent = &d->udev->dev;
166 d->input_dev = input_dev;
167 d->rc_dev = NULL;
168
169 input_dev->getkeycode = legacy_dvb_usb_getkeycode;
170 input_dev->setkeycode = legacy_dvb_usb_setkeycode;
171
172 /* set the bits for the keys */
173 deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size);
174 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
175 deb_rc("setting bit for event %d item %d\n",
176 d->props.rc.legacy.rc_map_table[i].keycode, i);
177 set_bit(d->props.rc.legacy.rc_map_table[i].keycode,
178 input_dev->keybit);
179 }
180
181 /* setting these two values to non-zero, we have to manage key
182 repeats */
183 input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval;
184 input_dev->rep[REP_DELAY] = d->props.rc.legacy.rc_interval + 150;
185
186 input_set_drvdata(input_dev, d);
187
188 err = input_register_device(input_dev);
189 if (err)
190 input_free_device(input_dev);
191
192 rc_interval = d->props.rc.legacy.rc_interval;
193
194 INIT_DELAYED_WORK(&d->rc_query_work,
195 legacy_dvb_usb_read_remote_control);
196
197 info("schedule remote query interval to %d msecs.", rc_interval);
198 schedule_delayed_work(&d->rc_query_work,
199 msecs_to_jiffies(rc_interval));
200
201 d->state |= DVB_USB_STATE_REMOTE;
202
203 return err;
204}
205
206/* Remote-control poll function - called every dib->rc_query_interval ms to see 12/* Remote-control poll function - called every dib->rc_query_interval ms to see
207 * whether the remote control has received anything. 13 * whether the remote control has received anything.
208 * 14 *
@@ -220,16 +26,16 @@ static void dvb_usb_read_remote_control(struct work_struct *work)
220 /* when the parameter has been set to 1 via sysfs while the 26 /* when the parameter has been set to 1 via sysfs while the
221 * driver was running, or when bulk mode is enabled after IR init 27 * driver was running, or when bulk mode is enabled after IR init
222 */ 28 */
223 if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode) 29 if (dvb_usb_disable_rc_polling || d->props.rc.bulk_mode)
224 return; 30 return;
225 31
226 err = d->props.rc.core.rc_query(d); 32 err = d->props.rc.rc_query(d);
227 if (err) 33 if (err)
228 err("error %d while querying for an remote control event.", 34 err("error %d while querying for an remote control event.",
229 err); 35 err);
230 36
231 schedule_delayed_work(&d->rc_query_work, 37 schedule_delayed_work(&d->rc_query_work,
232 msecs_to_jiffies(d->props.rc.core.rc_interval)); 38 msecs_to_jiffies(d->props.rc.rc_interval));
233} 39}
234 40
235static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) 41static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
@@ -241,17 +47,21 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
241 if (!dev) 47 if (!dev)
242 return -ENOMEM; 48 return -ENOMEM;
243 49
244 dev->driver_name = d->props.rc.core.module_name; 50 dev->driver_name = d->props.rc.module_name;
245 dev->map_name = d->props.rc.core.rc_codes; 51 dev->map_name = d->rc_map;
246 dev->change_protocol = d->props.rc.core.change_protocol; 52 dev->change_protocol = d->props.rc.change_protocol;
247 dev->allowed_protos = d->props.rc.core.allowed_protos; 53 dev->allowed_protos = d->props.rc.allowed_protos;
248 dev->driver_type = d->props.rc.core.driver_type; 54 dev->driver_type = d->props.rc.driver_type;
249 usb_to_input_id(d->udev, &dev->input_id); 55 usb_to_input_id(d->udev, &dev->input_id);
250 dev->input_name = "IR-receiver inside an USB DVB receiver"; 56 dev->input_name = "IR-receiver inside an USB DVB receiver";
251 dev->input_phys = d->rc_phys; 57 dev->input_phys = d->rc_phys;
252 dev->dev.parent = &d->udev->dev; 58 dev->dev.parent = &d->udev->dev;
253 dev->priv = d; 59 dev->priv = d;
254 60
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
255 err = rc_register_device(dev); 65 err = rc_register_device(dev);
256 if (err < 0) { 66 if (err < 0) {
257 rc_free_device(dev); 67 rc_free_device(dev);
@@ -261,13 +71,13 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
261 d->input_dev = NULL; 71 d->input_dev = NULL;
262 d->rc_dev = dev; 72 d->rc_dev = dev;
263 73
264 if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode) 74 if (!d->props.rc.rc_query || d->props.rc.bulk_mode)
265 return 0; 75 return 0;
266 76
267 /* Polling mode - initialize a work queue for handling it */ 77 /* Polling mode - initialize a work queue for handling it */
268 INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control); 78 INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
269 79
270 rc_interval = d->props.rc.core.rc_interval; 80 rc_interval = d->props.rc.rc_interval;
271 81
272 info("schedule remote query interval to %d msecs.", rc_interval); 82 info("schedule remote query interval to %d msecs.", rc_interval);
273 schedule_delayed_work(&d->rc_query_work, 83 schedule_delayed_work(&d->rc_query_work,
@@ -283,24 +93,14 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
283 if (dvb_usb_disable_rc_polling) 93 if (dvb_usb_disable_rc_polling)
284 return 0; 94 return 0;
285 95
286 if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query) 96 if (d->props.rc.module_name == NULL)
287 d->props.rc.mode = DVB_RC_LEGACY;
288 else if (d->props.rc.core.rc_codes)
289 d->props.rc.mode = DVB_RC_CORE;
290 else
291 return 0; 97 return 0;
292 98
293 usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys)); 99 usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
294 strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys)); 100 strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
295 101
296 /* Start the remote-control polling. */ 102 /* Start the remote-control polling. */
297 if (d->props.rc.legacy.rc_interval < 40) 103 err = rc_core_dvb_usb_remote_init(d);
298 d->props.rc.legacy.rc_interval = 100; /* default */
299
300 if (d->props.rc.mode == DVB_RC_LEGACY)
301 err = legacy_dvb_usb_remote_init(d);
302 else
303 err = rc_core_dvb_usb_remote_init(d);
304 if (err) 104 if (err)
305 return err; 105 return err;
306 106
@@ -313,52 +113,8 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d)
313{ 113{
314 if (d->state & DVB_USB_STATE_REMOTE) { 114 if (d->state & DVB_USB_STATE_REMOTE) {
315 cancel_delayed_work_sync(&d->rc_query_work); 115 cancel_delayed_work_sync(&d->rc_query_work);
316 if (d->props.rc.mode == DVB_RC_LEGACY) 116 rc_unregister_device(d->rc_dev);
317 input_unregister_device(d->input_dev);
318 else
319 rc_unregister_device(d->rc_dev);
320 } 117 }
321 d->state &= ~DVB_USB_STATE_REMOTE; 118 d->state &= ~DVB_USB_STATE_REMOTE;
322 return 0; 119 return 0;
323} 120}
324
325#define DVB_USB_RC_NEC_EMPTY 0x00
326#define DVB_USB_RC_NEC_KEY_PRESSED 0x01
327#define DVB_USB_RC_NEC_KEY_REPEATED 0x02
328int dvb_usbv2_nec_rc_key_to_event(struct dvb_usb_device *d,
329 u8 keybuf[5], u32 *event, int *state)
330{
331 int i;
332 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
333 *event = 0;
334 *state = REMOTE_NO_KEY_PRESSED;
335 switch (keybuf[0]) {
336 case DVB_USB_RC_NEC_EMPTY:
337 break;
338 case DVB_USB_RC_NEC_KEY_PRESSED:
339 if ((u8) ~keybuf[1] != keybuf[2] ||
340 (u8) ~keybuf[3] != keybuf[4]) {
341 deb_err("remote control checksum failed.\n");
342 break;
343 }
344 /* See if we can match the raw key code. */
345 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
346 if (rc5_custom(&keymap[i]) == keybuf[1] &&
347 rc5_data(&keymap[i]) == keybuf[3]) {
348 *event = keymap[i].keycode;
349 *state = REMOTE_KEY_PRESSED;
350 return 0;
351 }
352 deb_err("key mapping failed - no appropriate key found in" \
353 " keymapping\n");
354 break;
355 case DVB_USB_RC_NEC_KEY_REPEATED:
356 *state = REMOTE_KEY_REPEAT;
357 break;
358 default:
359 deb_err("unknown type of remote status: %d\n", keybuf[0]);
360 break;
361 }
362 return 0;
363}
364EXPORT_SYMBOL(dvb_usbv2_nec_rc_key_to_event);