1
2
3
4
5
6
7
8#include "dvb-usb-common.h"
9#include <linux/usb/input.h>
10
11static unsigned int
12legacy_dvb_usb_get_keymap_index(const struct input_keymap_entry *ke,
13 struct rc_map_table *keymap,
14 unsigned int keymap_size)
15{
16 unsigned int index;
17 unsigned int scancode;
18
19 if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
20 index = ke->index;
21 } else {
22 if (input_scancode_to_scalar(ke, &scancode))
23 return keymap_size;
24
25
26 for (index = 0; index < keymap_size; index++)
27 if (keymap[index].scancode == scancode)
28 break;
29
30
31 if (index >= keymap_size) {
32 for (index = 0; index < keymap_size; index++) {
33 if (keymap[index].keycode == KEY_RESERVED ||
34 keymap[index].keycode == KEY_UNKNOWN) {
35 break;
36 }
37 }
38 }
39 }
40
41 return index;
42}
43
44static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
45 struct input_keymap_entry *ke)
46{
47 struct dvb_usb_device *d = input_get_drvdata(dev);
48 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
49 unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
50 unsigned int index;
51
52 index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
53 if (index >= keymap_size)
54 return -EINVAL;
55
56 ke->keycode = keymap[index].keycode;
57 if (ke->keycode == KEY_UNKNOWN)
58 ke->keycode = KEY_RESERVED;
59 ke->len = sizeof(keymap[index].scancode);
60 memcpy(&ke->scancode, &keymap[index].scancode, ke->len);
61 ke->index = index;
62
63 return 0;
64}
65
66static int legacy_dvb_usb_setkeycode(struct input_dev *dev,
67 const struct input_keymap_entry *ke,
68 unsigned int *old_keycode)
69{
70 struct dvb_usb_device *d = input_get_drvdata(dev);
71 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
72 unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
73 unsigned int index;
74
75 index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
76
77
78
79
80
81
82
83 if (index >= keymap_size)
84 return -EINVAL;
85
86 *old_keycode = keymap[index].keycode;
87 keymap->keycode = ke->keycode;
88 __set_bit(ke->keycode, dev->keybit);
89
90 if (*old_keycode != KEY_RESERVED) {
91 __clear_bit(*old_keycode, dev->keybit);
92 for (index = 0; index < keymap_size; index++) {
93 if (keymap[index].keycode == *old_keycode) {
94 __set_bit(*old_keycode, dev->keybit);
95 break;
96 }
97 }
98 }
99
100 return 0;
101}
102
103
104
105
106
107
108static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
109{
110 struct dvb_usb_device *d =
111 container_of(work, struct dvb_usb_device, rc_query_work.work);
112 u32 event;
113 int state;
114
115
116
117
118
119 if (dvb_usb_disable_rc_polling)
120 return;
121
122 if (d->props.rc.legacy.rc_query(d,&event,&state)) {
123 err("error while querying for an remote control event.");
124 goto schedule;
125 }
126
127
128 switch (state) {
129 case REMOTE_NO_KEY_PRESSED:
130 break;
131 case REMOTE_KEY_PRESSED:
132 deb_rc("key pressed\n");
133 d->last_event = event;
134 input_event(d->input_dev, EV_KEY, event, 1);
135 input_sync(d->input_dev);
136 input_event(d->input_dev, EV_KEY, d->last_event, 0);
137 input_sync(d->input_dev);
138 break;
139 case REMOTE_KEY_REPEAT:
140 deb_rc("key repeated\n");
141 input_event(d->input_dev, EV_KEY, event, 1);
142 input_sync(d->input_dev);
143 input_event(d->input_dev, EV_KEY, d->last_event, 0);
144 input_sync(d->input_dev);
145 break;
146 default:
147 break;
148 }
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185schedule:
186 schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
187}
188
189static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
190{
191 int i, err, rc_interval;
192 struct input_dev *input_dev;
193
194 input_dev = input_allocate_device();
195 if (!input_dev)
196 return -ENOMEM;
197
198 input_dev->evbit[0] = BIT_MASK(EV_KEY);
199 input_dev->name = "IR-receiver inside an USB DVB receiver";
200 input_dev->phys = d->rc_phys;
201 usb_to_input_id(d->udev, &input_dev->id);
202 input_dev->dev.parent = &d->udev->dev;
203 d->input_dev = input_dev;
204 d->rc_dev = NULL;
205
206 input_dev->getkeycode = legacy_dvb_usb_getkeycode;
207 input_dev->setkeycode = legacy_dvb_usb_setkeycode;
208
209
210 deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size);
211 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
212 deb_rc("setting bit for event %d item %d\n",
213 d->props.rc.legacy.rc_map_table[i].keycode, i);
214 set_bit(d->props.rc.legacy.rc_map_table[i].keycode, input_dev->keybit);
215 }
216
217
218 input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval;
219 input_dev->rep[REP_DELAY] = d->props.rc.legacy.rc_interval + 150;
220
221 input_set_drvdata(input_dev, d);
222
223 err = input_register_device(input_dev);
224 if (err)
225 input_free_device(input_dev);
226
227 rc_interval = d->props.rc.legacy.rc_interval;
228
229 INIT_DELAYED_WORK(&d->rc_query_work, legacy_dvb_usb_read_remote_control);
230
231 info("schedule remote query interval to %d msecs.", rc_interval);
232 schedule_delayed_work(&d->rc_query_work,
233 msecs_to_jiffies(rc_interval));
234
235 d->state |= DVB_USB_STATE_REMOTE;
236
237 return err;
238}
239
240
241
242
243
244
245static void dvb_usb_read_remote_control(struct work_struct *work)
246{
247 struct dvb_usb_device *d =
248 container_of(work, struct dvb_usb_device, rc_query_work.work);
249 int err;
250
251
252
253
254
255
256
257 if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode)
258 return;
259
260 err = d->props.rc.core.rc_query(d);
261 if (err)
262 err("error %d while querying for an remote control event.", err);
263
264 schedule_delayed_work(&d->rc_query_work,
265 msecs_to_jiffies(d->props.rc.core.rc_interval));
266}
267
268static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
269{
270 int err, rc_interval;
271 struct rc_dev *dev;
272
273 dev = rc_allocate_device(d->props.rc.core.driver_type);
274 if (!dev)
275 return -ENOMEM;
276
277 dev->driver_name = d->props.rc.core.module_name;
278 dev->map_name = d->props.rc.core.rc_codes;
279 dev->change_protocol = d->props.rc.core.change_protocol;
280 dev->allowed_protocols = d->props.rc.core.allowed_protos;
281 usb_to_input_id(d->udev, &dev->input_id);
282 dev->input_name = "IR-receiver inside an USB DVB receiver";
283 dev->input_phys = d->rc_phys;
284 dev->dev.parent = &d->udev->dev;
285 dev->priv = d;
286
287 err = rc_register_device(dev);
288 if (err < 0) {
289 rc_free_device(dev);
290 return err;
291 }
292
293 d->input_dev = NULL;
294 d->rc_dev = dev;
295
296 if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
297 return 0;
298
299
300 INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
301
302 rc_interval = d->props.rc.core.rc_interval;
303
304 info("schedule remote query interval to %d msecs.", rc_interval);
305 schedule_delayed_work(&d->rc_query_work,
306 msecs_to_jiffies(rc_interval));
307
308 return 0;
309}
310
311int dvb_usb_remote_init(struct dvb_usb_device *d)
312{
313 int err;
314
315 if (dvb_usb_disable_rc_polling)
316 return 0;
317
318 if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query)
319 d->props.rc.mode = DVB_RC_LEGACY;
320 else if (d->props.rc.core.rc_codes)
321 d->props.rc.mode = DVB_RC_CORE;
322 else
323 return 0;
324
325 usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
326 strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
327
328
329 if (d->props.rc.legacy.rc_interval < 40)
330 d->props.rc.legacy.rc_interval = 100;
331
332 if (d->props.rc.mode == DVB_RC_LEGACY)
333 err = legacy_dvb_usb_remote_init(d);
334 else
335 err = rc_core_dvb_usb_remote_init(d);
336 if (err)
337 return err;
338
339 d->state |= DVB_USB_STATE_REMOTE;
340
341 return 0;
342}
343
344int dvb_usb_remote_exit(struct dvb_usb_device *d)
345{
346 if (d->state & DVB_USB_STATE_REMOTE) {
347 cancel_delayed_work_sync(&d->rc_query_work);
348 if (d->props.rc.mode == DVB_RC_LEGACY)
349 input_unregister_device(d->input_dev);
350 else
351 rc_unregister_device(d->rc_dev);
352 }
353 d->state &= ~DVB_USB_STATE_REMOTE;
354 return 0;
355}
356
357#define DVB_USB_RC_NEC_EMPTY 0x00
358#define DVB_USB_RC_NEC_KEY_PRESSED 0x01
359#define DVB_USB_RC_NEC_KEY_REPEATED 0x02
360int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
361 u8 keybuf[5], u32 *event, int *state)
362{
363 int i;
364 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
365 *event = 0;
366 *state = REMOTE_NO_KEY_PRESSED;
367 switch (keybuf[0]) {
368 case DVB_USB_RC_NEC_EMPTY:
369 break;
370 case DVB_USB_RC_NEC_KEY_PRESSED:
371 if ((u8) ~keybuf[1] != keybuf[2] ||
372 (u8) ~keybuf[3] != keybuf[4]) {
373 deb_err("remote control checksum failed.\n");
374 break;
375 }
376
377 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
378 if (rc5_custom(&keymap[i]) == keybuf[1] &&
379 rc5_data(&keymap[i]) == keybuf[3]) {
380 *event = keymap[i].keycode;
381 *state = REMOTE_KEY_PRESSED;
382 return 0;
383 }
384 deb_err("key mapping failed - no appropriate key found in keymapping\n");
385 break;
386 case DVB_USB_RC_NEC_KEY_REPEATED:
387 *state = REMOTE_KEY_REPEAT;
388 break;
389 default:
390 deb_err("unknown type of remote status: %d\n",keybuf[0]);
391 break;
392 }
393 return 0;
394}
395EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);
396