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 case REMOTE_KEY_REPEAT:
135 deb_rc("key repeated\n");
136 input_event(d->input_dev, EV_KEY, event, 1);
137 input_sync(d->input_dev);
138 input_event(d->input_dev, EV_KEY, d->last_event, 0);
139 input_sync(d->input_dev);
140 break;
141 default:
142 break;
143 }
144
145
146
147
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
180schedule:
181 schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
182}
183
184static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
185{
186 int i, err, rc_interval;
187 struct input_dev *input_dev;
188
189 input_dev = input_allocate_device();
190 if (!input_dev)
191 return -ENOMEM;
192
193 input_dev->evbit[0] = BIT_MASK(EV_KEY);
194 input_dev->name = "IR-receiver inside an USB DVB receiver";
195 input_dev->phys = d->rc_phys;
196 usb_to_input_id(d->udev, &input_dev->id);
197 input_dev->dev.parent = &d->udev->dev;
198 d->input_dev = input_dev;
199 d->rc_dev = NULL;
200
201 input_dev->getkeycode = legacy_dvb_usb_getkeycode;
202 input_dev->setkeycode = legacy_dvb_usb_setkeycode;
203
204
205 deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size);
206 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
207 deb_rc("setting bit for event %d item %d\n",
208 d->props.rc.legacy.rc_map_table[i].keycode, i);
209 set_bit(d->props.rc.legacy.rc_map_table[i].keycode, input_dev->keybit);
210 }
211
212
213 input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval;
214 input_dev->rep[REP_DELAY] = d->props.rc.legacy.rc_interval + 150;
215
216 input_set_drvdata(input_dev, d);
217
218 err = input_register_device(input_dev);
219 if (err)
220 input_free_device(input_dev);
221
222 rc_interval = d->props.rc.legacy.rc_interval;
223
224 INIT_DELAYED_WORK(&d->rc_query_work, legacy_dvb_usb_read_remote_control);
225
226 info("schedule remote query interval to %d msecs.", rc_interval);
227 schedule_delayed_work(&d->rc_query_work,
228 msecs_to_jiffies(rc_interval));
229
230 d->state |= DVB_USB_STATE_REMOTE;
231
232 return err;
233}
234
235
236
237
238
239
240static void dvb_usb_read_remote_control(struct work_struct *work)
241{
242 struct dvb_usb_device *d =
243 container_of(work, struct dvb_usb_device, rc_query_work.work);
244 int err;
245
246
247
248
249
250
251
252 if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode)
253 return;
254
255 err = d->props.rc.core.rc_query(d);
256 if (err)
257 err("error %d while querying for an remote control event.", err);
258
259 schedule_delayed_work(&d->rc_query_work,
260 msecs_to_jiffies(d->props.rc.core.rc_interval));
261}
262
263static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
264{
265 int err, rc_interval;
266 struct rc_dev *dev;
267
268 dev = rc_allocate_device();
269 if (!dev)
270 return -ENOMEM;
271
272 dev->driver_name = d->props.rc.core.module_name;
273 dev->map_name = d->props.rc.core.rc_codes;
274 dev->change_protocol = d->props.rc.core.change_protocol;
275 dev->allowed_protocols = d->props.rc.core.allowed_protos;
276 dev->driver_type = d->props.rc.core.driver_type;
277 usb_to_input_id(d->udev, &dev->input_id);
278 dev->input_name = "IR-receiver inside an USB DVB receiver";
279 dev->input_phys = d->rc_phys;
280 dev->dev.parent = &d->udev->dev;
281 dev->priv = d;
282
283 err = rc_register_device(dev);
284 if (err < 0) {
285 rc_free_device(dev);
286 return err;
287 }
288
289 d->input_dev = NULL;
290 d->rc_dev = dev;
291
292 if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
293 return 0;
294
295
296 INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
297
298 rc_interval = d->props.rc.core.rc_interval;
299
300 info("schedule remote query interval to %d msecs.", rc_interval);
301 schedule_delayed_work(&d->rc_query_work,
302 msecs_to_jiffies(rc_interval));
303
304 return 0;
305}
306
307int dvb_usb_remote_init(struct dvb_usb_device *d)
308{
309 int err;
310
311 if (dvb_usb_disable_rc_polling)
312 return 0;
313
314 if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query)
315 d->props.rc.mode = DVB_RC_LEGACY;
316 else if (d->props.rc.core.rc_codes)
317 d->props.rc.mode = DVB_RC_CORE;
318 else
319 return 0;
320
321 usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
322 strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
323
324
325 if (d->props.rc.legacy.rc_interval < 40)
326 d->props.rc.legacy.rc_interval = 100;
327
328 if (d->props.rc.mode == DVB_RC_LEGACY)
329 err = legacy_dvb_usb_remote_init(d);
330 else
331 err = rc_core_dvb_usb_remote_init(d);
332 if (err)
333 return err;
334
335 d->state |= DVB_USB_STATE_REMOTE;
336
337 return 0;
338}
339
340int dvb_usb_remote_exit(struct dvb_usb_device *d)
341{
342 if (d->state & DVB_USB_STATE_REMOTE) {
343 cancel_delayed_work_sync(&d->rc_query_work);
344 if (d->props.rc.mode == DVB_RC_LEGACY)
345 input_unregister_device(d->input_dev);
346 else
347 rc_unregister_device(d->rc_dev);
348 }
349 d->state &= ~DVB_USB_STATE_REMOTE;
350 return 0;
351}
352
353#define DVB_USB_RC_NEC_EMPTY 0x00
354#define DVB_USB_RC_NEC_KEY_PRESSED 0x01
355#define DVB_USB_RC_NEC_KEY_REPEATED 0x02
356int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
357 u8 keybuf[5], u32 *event, int *state)
358{
359 int i;
360 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
361 *event = 0;
362 *state = REMOTE_NO_KEY_PRESSED;
363 switch (keybuf[0]) {
364 case DVB_USB_RC_NEC_EMPTY:
365 break;
366 case DVB_USB_RC_NEC_KEY_PRESSED:
367 if ((u8) ~keybuf[1] != keybuf[2] ||
368 (u8) ~keybuf[3] != keybuf[4]) {
369 deb_err("remote control checksum failed.\n");
370 break;
371 }
372
373 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
374 if (rc5_custom(&keymap[i]) == keybuf[1] &&
375 rc5_data(&keymap[i]) == keybuf[3]) {
376 *event = keymap[i].keycode;
377 *state = REMOTE_KEY_PRESSED;
378 return 0;
379 }
380 deb_err("key mapping failed - no appropriate key found in keymapping\n");
381 break;
382 case DVB_USB_RC_NEC_KEY_REPEATED:
383 *state = REMOTE_KEY_REPEAT;
384 break;
385 default:
386 deb_err("unknown type of remote status: %d\n",keybuf[0]);
387 break;
388 }
389 return 0;
390}
391EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);
392