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(d->props.rc.core.driver_type);
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 usb_to_input_id(d->udev, &dev->input_id);
277 dev->input_name = "IR-receiver inside an USB DVB receiver";
278 dev->input_phys = d->rc_phys;
279 dev->dev.parent = &d->udev->dev;
280 dev->priv = d;
281
282 err = rc_register_device(dev);
283 if (err < 0) {
284 rc_free_device(dev);
285 return err;
286 }
287
288 d->input_dev = NULL;
289 d->rc_dev = dev;
290
291 if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
292 return 0;
293
294
295 INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
296
297 rc_interval = d->props.rc.core.rc_interval;
298
299 info("schedule remote query interval to %d msecs.", rc_interval);
300 schedule_delayed_work(&d->rc_query_work,
301 msecs_to_jiffies(rc_interval));
302
303 return 0;
304}
305
306int dvb_usb_remote_init(struct dvb_usb_device *d)
307{
308 int err;
309
310 if (dvb_usb_disable_rc_polling)
311 return 0;
312
313 if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query)
314 d->props.rc.mode = DVB_RC_LEGACY;
315 else if (d->props.rc.core.rc_codes)
316 d->props.rc.mode = DVB_RC_CORE;
317 else
318 return 0;
319
320 usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
321 strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
322
323
324 if (d->props.rc.legacy.rc_interval < 40)
325 d->props.rc.legacy.rc_interval = 100;
326
327 if (d->props.rc.mode == DVB_RC_LEGACY)
328 err = legacy_dvb_usb_remote_init(d);
329 else
330 err = rc_core_dvb_usb_remote_init(d);
331 if (err)
332 return err;
333
334 d->state |= DVB_USB_STATE_REMOTE;
335
336 return 0;
337}
338
339int dvb_usb_remote_exit(struct dvb_usb_device *d)
340{
341 if (d->state & DVB_USB_STATE_REMOTE) {
342 cancel_delayed_work_sync(&d->rc_query_work);
343 if (d->props.rc.mode == DVB_RC_LEGACY)
344 input_unregister_device(d->input_dev);
345 else
346 rc_unregister_device(d->rc_dev);
347 }
348 d->state &= ~DVB_USB_STATE_REMOTE;
349 return 0;
350}
351
352#define DVB_USB_RC_NEC_EMPTY 0x00
353#define DVB_USB_RC_NEC_KEY_PRESSED 0x01
354#define DVB_USB_RC_NEC_KEY_REPEATED 0x02
355int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
356 u8 keybuf[5], u32 *event, int *state)
357{
358 int i;
359 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
360 *event = 0;
361 *state = REMOTE_NO_KEY_PRESSED;
362 switch (keybuf[0]) {
363 case DVB_USB_RC_NEC_EMPTY:
364 break;
365 case DVB_USB_RC_NEC_KEY_PRESSED:
366 if ((u8) ~keybuf[1] != keybuf[2] ||
367 (u8) ~keybuf[3] != keybuf[4]) {
368 deb_err("remote control checksum failed.\n");
369 break;
370 }
371
372 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
373 if (rc5_custom(&keymap[i]) == keybuf[1] &&
374 rc5_data(&keymap[i]) == keybuf[3]) {
375 *event = keymap[i].keycode;
376 *state = REMOTE_KEY_PRESSED;
377 return 0;
378 }
379 deb_err("key mapping failed - no appropriate key found in keymapping\n");
380 break;
381 case DVB_USB_RC_NEC_KEY_REPEATED:
382 *state = REMOTE_KEY_REPEAT;
383 break;
384 default:
385 deb_err("unknown type of remote status: %d\n",keybuf[0]);
386 break;
387 }
388 return 0;
389}
390EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);
391