Merge branch 'for-2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
[cascardo/linux.git] / drivers / media / dvb / dvb-usb / dvb-usb-remote.c
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  *
6  * This file contains functions for initializing the input-device and for handling remote-control-queries.
7  */
8 #include "dvb-usb-common.h"
9 #include <linux/usb/input.h>
10
11 static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
12                                 unsigned int scancode, unsigned int *keycode)
13 {
14         struct dvb_usb_device *d = input_get_drvdata(dev);
15
16         struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
17         int i;
18
19         /* See if we can match the raw key code. */
20         for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
21                 if (keymap[i].scancode == scancode) {
22                         *keycode = keymap[i].keycode;
23                         return 0;
24                 }
25
26         /*
27          * If is there extra space, returns KEY_RESERVED,
28          * otherwise, input core won't let legacy_dvb_usb_setkeycode
29          * to work
30          */
31         for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
32                 if (keymap[i].keycode == KEY_RESERVED ||
33                     keymap[i].keycode == KEY_UNKNOWN) {
34                         *keycode = KEY_RESERVED;
35                         return 0;
36                 }
37
38         return -EINVAL;
39 }
40
41 static int legacy_dvb_usb_setkeycode(struct input_dev *dev,
42                                 unsigned int scancode, unsigned int keycode)
43 {
44         struct dvb_usb_device *d = input_get_drvdata(dev);
45
46         struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
47         int i;
48
49         /* Search if it is replacing an existing keycode */
50         for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
51                 if (keymap[i].scancode == scancode) {
52                         keymap[i].keycode = keycode;
53                         return 0;
54                 }
55
56         /* Search if is there a clean entry. If so, use it */
57         for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
58                 if (keymap[i].keycode == KEY_RESERVED ||
59                     keymap[i].keycode == KEY_UNKNOWN) {
60                         keymap[i].scancode = scancode;
61                         keymap[i].keycode = keycode;
62                         return 0;
63                 }
64
65         /*
66          * FIXME: Currently, it is not possible to increase the size of
67          * scancode table. For it to happen, one possibility
68          * would be to allocate a table with key_map_size + 1,
69          * copying data, appending the new key on it, and freeing
70          * the old one - or maybe just allocating some spare space
71          */
72
73         return -EINVAL;
74 }
75
76 /* Remote-control poll function - called every dib->rc_query_interval ms to see
77  * whether the remote control has received anything.
78  *
79  * TODO: Fix the repeat rate of the input device.
80  */
81 static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
82 {
83         struct dvb_usb_device *d =
84                 container_of(work, struct dvb_usb_device, rc_query_work.work);
85         u32 event;
86         int state;
87
88         /* TODO: need a lock here.  We can simply skip checking for the remote control
89            if we're busy. */
90
91         /* when the parameter has been set to 1 via sysfs while the driver was running */
92         if (dvb_usb_disable_rc_polling)
93                 return;
94
95         if (d->props.rc.legacy.rc_query(d,&event,&state)) {
96                 err("error while querying for an remote control event.");
97                 goto schedule;
98         }
99
100
101         switch (state) {
102                 case REMOTE_NO_KEY_PRESSED:
103                         break;
104                 case REMOTE_KEY_PRESSED:
105                         deb_rc("key pressed\n");
106                         d->last_event = event;
107                 case REMOTE_KEY_REPEAT:
108                         deb_rc("key repeated\n");
109                         input_event(d->input_dev, EV_KEY, event, 1);
110                         input_sync(d->input_dev);
111                         input_event(d->input_dev, EV_KEY, d->last_event, 0);
112                         input_sync(d->input_dev);
113                         break;
114                 default:
115                         break;
116         }
117
118 /* improved repeat handling ???
119         switch (state) {
120                 case REMOTE_NO_KEY_PRESSED:
121                         deb_rc("NO KEY PRESSED\n");
122                         if (d->last_state != REMOTE_NO_KEY_PRESSED) {
123                                 deb_rc("releasing event %d\n",d->last_event);
124                                 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
125                                 input_sync(d->rc_input_dev);
126                         }
127                         d->last_state = REMOTE_NO_KEY_PRESSED;
128                         d->last_event = 0;
129                         break;
130                 case REMOTE_KEY_PRESSED:
131                         deb_rc("KEY PRESSED\n");
132                         deb_rc("pressing event %d\n",event);
133
134                         input_event(d->rc_input_dev, EV_KEY, event, 1);
135                         input_sync(d->rc_input_dev);
136
137                         d->last_event = event;
138                         d->last_state = REMOTE_KEY_PRESSED;
139                         break;
140                 case REMOTE_KEY_REPEAT:
141                         deb_rc("KEY_REPEAT\n");
142                         if (d->last_state != REMOTE_NO_KEY_PRESSED) {
143                                 deb_rc("repeating event %d\n",d->last_event);
144                                 input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
145                                 input_sync(d->rc_input_dev);
146                                 d->last_state = REMOTE_KEY_REPEAT;
147                         }
148                 default:
149                         break;
150         }
151 */
152
153 schedule:
154         schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
155 }
156
157 static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
158 {
159         int i, err, rc_interval;
160         struct input_dev *input_dev;
161
162         input_dev = input_allocate_device();
163         if (!input_dev)
164                 return -ENOMEM;
165
166         input_dev->evbit[0] = BIT_MASK(EV_KEY);
167         input_dev->name = "IR-receiver inside an USB DVB receiver";
168         input_dev->phys = d->rc_phys;
169         usb_to_input_id(d->udev, &input_dev->id);
170         input_dev->dev.parent = &d->udev->dev;
171         d->input_dev = input_dev;
172         d->rc_dev = NULL;
173
174         input_dev->getkeycode = legacy_dvb_usb_getkeycode;
175         input_dev->setkeycode = legacy_dvb_usb_setkeycode;
176
177         /* set the bits for the keys */
178         deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size);
179         for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
180                 deb_rc("setting bit for event %d item %d\n",
181                         d->props.rc.legacy.rc_map_table[i].keycode, i);
182                 set_bit(d->props.rc.legacy.rc_map_table[i].keycode, input_dev->keybit);
183         }
184
185         /* setting these two values to non-zero, we have to manage key repeats */
186         input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval;
187         input_dev->rep[REP_DELAY]  = d->props.rc.legacy.rc_interval + 150;
188
189         input_set_drvdata(input_dev, d);
190
191         err = input_register_device(input_dev);
192         if (err)
193                 input_free_device(input_dev);
194
195         rc_interval = d->props.rc.legacy.rc_interval;
196
197         INIT_DELAYED_WORK(&d->rc_query_work, legacy_dvb_usb_read_remote_control);
198
199         info("schedule remote query interval to %d msecs.", rc_interval);
200         schedule_delayed_work(&d->rc_query_work,
201                               msecs_to_jiffies(rc_interval));
202
203         d->state |= DVB_USB_STATE_REMOTE;
204
205         return err;
206 }
207
208 /* Remote-control poll function - called every dib->rc_query_interval ms to see
209  * whether the remote control has received anything.
210  *
211  * TODO: Fix the repeat rate of the input device.
212  */
213 static void dvb_usb_read_remote_control(struct work_struct *work)
214 {
215         struct dvb_usb_device *d =
216                 container_of(work, struct dvb_usb_device, rc_query_work.work);
217         int err;
218
219         /* TODO: need a lock here.  We can simply skip checking for the remote control
220            if we're busy. */
221
222         /* when the parameter has been set to 1 via sysfs while the
223          * driver was running, or when bulk mode is enabled after IR init
224          */
225         if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode)
226                 return;
227
228         err = d->props.rc.core.rc_query(d);
229         if (err)
230                 err("error %d while querying for an remote control event.", err);
231
232         schedule_delayed_work(&d->rc_query_work,
233                               msecs_to_jiffies(d->props.rc.core.rc_interval));
234 }
235
236 static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
237 {
238         int err, rc_interval;
239         struct rc_dev *dev;
240
241         dev = rc_allocate_device();
242         if (!dev)
243                 return -ENOMEM;
244
245         dev->driver_name = d->props.rc.core.module_name;
246         dev->map_name = d->props.rc.core.rc_codes;
247         dev->change_protocol = d->props.rc.core.change_protocol;
248         dev->allowed_protos = d->props.rc.core.allowed_protos;
249         dev->driver_type = RC_DRIVER_SCANCODE;
250         usb_to_input_id(d->udev, &dev->input_id);
251         dev->input_name = "IR-receiver inside an USB DVB receiver";
252         dev->input_phys = d->rc_phys;
253         dev->dev.parent = &d->udev->dev;
254         dev->priv = d;
255
256         err = rc_register_device(dev);
257         if (err < 0) {
258                 rc_free_device(dev);
259                 return err;
260         }
261
262         d->input_dev = NULL;
263         d->rc_dev = dev;
264
265         if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
266                 return 0;
267
268         /* Polling mode - initialize a work queue for handling it */
269         INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
270
271         rc_interval = d->props.rc.core.rc_interval;
272
273         info("schedule remote query interval to %d msecs.", rc_interval);
274         schedule_delayed_work(&d->rc_query_work,
275                               msecs_to_jiffies(rc_interval));
276
277         return 0;
278 }
279
280 int dvb_usb_remote_init(struct dvb_usb_device *d)
281 {
282         int err;
283
284         if (dvb_usb_disable_rc_polling)
285                 return 0;
286
287         if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query)
288                 d->props.rc.mode = DVB_RC_LEGACY;
289         else if (d->props.rc.core.rc_codes)
290                 d->props.rc.mode = DVB_RC_CORE;
291         else
292                 return 0;
293
294         usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
295         strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
296
297         /* Start the remote-control polling. */
298         if (d->props.rc.legacy.rc_interval < 40)
299                 d->props.rc.legacy.rc_interval = 100; /* default */
300
301         if (d->props.rc.mode == DVB_RC_LEGACY)
302                 err = legacy_dvb_usb_remote_init(d);
303         else
304                 err = rc_core_dvb_usb_remote_init(d);
305         if (err)
306                 return err;
307
308         d->state |= DVB_USB_STATE_REMOTE;
309
310         return 0;
311 }
312
313 int dvb_usb_remote_exit(struct dvb_usb_device *d)
314 {
315         if (d->state & DVB_USB_STATE_REMOTE) {
316                 cancel_delayed_work_sync(&d->rc_query_work);
317                 if (d->props.rc.mode == DVB_RC_LEGACY)
318                         input_unregister_device(d->input_dev);
319                 else
320                         rc_unregister_device(d->rc_dev);
321         }
322         d->state &= ~DVB_USB_STATE_REMOTE;
323         return 0;
324 }
325
326 #define DVB_USB_RC_NEC_EMPTY           0x00
327 #define DVB_USB_RC_NEC_KEY_PRESSED     0x01
328 #define DVB_USB_RC_NEC_KEY_REPEATED    0x02
329 int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
330                 u8 keybuf[5], u32 *event, int *state)
331 {
332         int i;
333         struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
334         *event = 0;
335         *state = REMOTE_NO_KEY_PRESSED;
336         switch (keybuf[0]) {
337                 case DVB_USB_RC_NEC_EMPTY:
338                         break;
339                 case DVB_USB_RC_NEC_KEY_PRESSED:
340                         if ((u8) ~keybuf[1] != keybuf[2] ||
341                                 (u8) ~keybuf[3] != keybuf[4]) {
342                                 deb_err("remote control checksum failed.\n");
343                                 break;
344                         }
345                         /* See if we can match the raw key code. */
346                         for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
347                                 if (rc5_custom(&keymap[i]) == keybuf[1] &&
348                                         rc5_data(&keymap[i]) == keybuf[3]) {
349                                         *event = keymap[i].keycode;
350                                         *state = REMOTE_KEY_PRESSED;
351                                         return 0;
352                                 }
353                         deb_err("key mapping failed - no appropriate key found in 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 }
364 EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);