Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[pandora-kernel.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 unsigned int
12 legacy_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                 /* See if we can match the raw key code. */
26                 for (index = 0; index < keymap_size; index++)
27                         if (keymap[index].scancode == scancode)
28                                 break;
29
30                 /* See if there is an unused hole in the map */
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
44 static 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
66 static 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          * FIXME: Currently, it is not possible to increase the size of
78          * scancode table. For it to happen, one possibility
79          * would be to allocate a table with key_map_size + 1,
80          * copying data, appending the new key on it, and freeing
81          * the old one - or maybe just allocating some spare space
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 /* Remote-control poll function - called every dib->rc_query_interval ms to see
104  * whether the remote control has received anything.
105  *
106  * TODO: Fix the repeat rate of the input device.
107  */
108 static 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         /* TODO: need a lock here.  We can simply skip checking for the remote control
116            if we're busy. */
117
118         /* when the parameter has been set to 1 via sysfs while the driver was running */
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 /* improved repeat handling ???
146         switch (state) {
147                 case REMOTE_NO_KEY_PRESSED:
148                         deb_rc("NO KEY PRESSED\n");
149                         if (d->last_state != REMOTE_NO_KEY_PRESSED) {
150                                 deb_rc("releasing event %d\n",d->last_event);
151                                 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
152                                 input_sync(d->rc_input_dev);
153                         }
154                         d->last_state = REMOTE_NO_KEY_PRESSED;
155                         d->last_event = 0;
156                         break;
157                 case REMOTE_KEY_PRESSED:
158                         deb_rc("KEY PRESSED\n");
159                         deb_rc("pressing event %d\n",event);
160
161                         input_event(d->rc_input_dev, EV_KEY, event, 1);
162                         input_sync(d->rc_input_dev);
163
164                         d->last_event = event;
165                         d->last_state = REMOTE_KEY_PRESSED;
166                         break;
167                 case REMOTE_KEY_REPEAT:
168                         deb_rc("KEY_REPEAT\n");
169                         if (d->last_state != REMOTE_NO_KEY_PRESSED) {
170                                 deb_rc("repeating event %d\n",d->last_event);
171                                 input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
172                                 input_sync(d->rc_input_dev);
173                                 d->last_state = REMOTE_KEY_REPEAT;
174                         }
175                 default:
176                         break;
177         }
178 */
179
180 schedule:
181         schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
182 }
183
184 static 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         /* set the bits for the keys */
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         /* setting these two values to non-zero, we have to manage key repeats */
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 /* Remote-control poll function - called every dib->rc_query_interval ms to see
236  * whether the remote control has received anything.
237  *
238  * TODO: Fix the repeat rate of the input device.
239  */
240 static 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         /* TODO: need a lock here.  We can simply skip checking for the remote control
247            if we're busy. */
248
249         /* when the parameter has been set to 1 via sysfs while the
250          * driver was running, or when bulk mode is enabled after IR init
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
263 static 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_protos = 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         /* Polling mode - initialize a work queue for handling it */
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
307 int 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         /* Start the remote-control polling. */
325         if (d->props.rc.legacy.rc_interval < 40)
326                 d->props.rc.legacy.rc_interval = 100; /* default */
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
340 int 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
356 int 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                         /* See if we can match the raw key code. */
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 }
391 EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);