Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platf...
[sfrench/cifs-2.6.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 ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
17         int i;
18
19         /* See if we can match the raw key code. */
20         for (i = 0; i < d->props.rc.legacy.rc_key_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_key_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 ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
47         int i;
48
49         /* Search if it is replacing an existing keycode */
50         for (i = 0; i < d->props.rc.legacy.rc_key_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_key_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->rc_input_dev, EV_KEY, event, 1);
110                         input_sync(d->rc_input_dev);
111                         input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
112                         input_sync(d->rc_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                                       struct input_dev *input_dev)
159 {
160         int i, err, rc_interval;
161
162         input_dev->getkeycode = legacy_dvb_usb_getkeycode;
163         input_dev->setkeycode = legacy_dvb_usb_setkeycode;
164
165         /* set the bits for the keys */
166         deb_rc("key map size: %d\n", d->props.rc.legacy.rc_key_map_size);
167         for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
168                 deb_rc("setting bit for event %d item %d\n",
169                         d->props.rc.legacy.rc_key_map[i].keycode, i);
170                 set_bit(d->props.rc.legacy.rc_key_map[i].keycode, input_dev->keybit);
171         }
172
173         /* setting these two values to non-zero, we have to manage key repeats */
174         input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval;
175         input_dev->rep[REP_DELAY]  = d->props.rc.legacy.rc_interval + 150;
176
177         input_set_drvdata(input_dev, d);
178
179         err = input_register_device(input_dev);
180         if (err)
181                 input_free_device(input_dev);
182
183         rc_interval = d->props.rc.legacy.rc_interval;
184
185         INIT_DELAYED_WORK(&d->rc_query_work, legacy_dvb_usb_read_remote_control);
186
187         info("schedule remote query interval to %d msecs.", rc_interval);
188         schedule_delayed_work(&d->rc_query_work,
189                               msecs_to_jiffies(rc_interval));
190
191         d->state |= DVB_USB_STATE_REMOTE;
192
193         return err;
194 }
195
196 /* Remote-control poll function - called every dib->rc_query_interval ms to see
197  * whether the remote control has received anything.
198  *
199  * TODO: Fix the repeat rate of the input device.
200  */
201 static void dvb_usb_read_remote_control(struct work_struct *work)
202 {
203         struct dvb_usb_device *d =
204                 container_of(work, struct dvb_usb_device, rc_query_work.work);
205         int err;
206
207         /* TODO: need a lock here.  We can simply skip checking for the remote control
208            if we're busy. */
209
210         /* when the parameter has been set to 1 via sysfs while the
211          * driver was running, or when bulk mode is enabled after IR init
212          */
213         if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode)
214                 return;
215
216         err = d->props.rc.core.rc_query(d);
217         if (err)
218                 err("error %d while querying for an remote control event.", err);
219
220         schedule_delayed_work(&d->rc_query_work,
221                               msecs_to_jiffies(d->props.rc.core.rc_interval));
222 }
223
224 static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d,
225                                        struct input_dev *input_dev)
226 {
227         int err, rc_interval;
228
229         d->props.rc.core.rc_props.priv = d;
230         err = ir_input_register(input_dev,
231                                  d->props.rc.core.rc_codes,
232                                  &d->props.rc.core.rc_props,
233                                  d->props.rc.core.module_name);
234         if (err < 0)
235                 return err;
236
237         if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
238                 return 0;
239
240         /* Polling mode - initialize a work queue for handling it */
241         INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
242
243         rc_interval = d->props.rc.core.rc_interval;
244
245         info("schedule remote query interval to %d msecs.", rc_interval);
246         schedule_delayed_work(&d->rc_query_work,
247                               msecs_to_jiffies(rc_interval));
248
249         return 0;
250 }
251
252 int dvb_usb_remote_init(struct dvb_usb_device *d)
253 {
254         struct input_dev *input_dev;
255         int err;
256
257         if (dvb_usb_disable_rc_polling)
258                 return 0;
259
260         if (d->props.rc.legacy.rc_key_map && d->props.rc.legacy.rc_query)
261                 d->props.rc.mode = DVB_RC_LEGACY;
262         else if (d->props.rc.core.rc_codes)
263                 d->props.rc.mode = DVB_RC_CORE;
264         else
265                 return 0;
266
267         usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
268         strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
269
270         input_dev = input_allocate_device();
271         if (!input_dev)
272                 return -ENOMEM;
273
274         input_dev->evbit[0] = BIT_MASK(EV_KEY);
275         input_dev->name = "IR-receiver inside an USB DVB receiver";
276         input_dev->phys = d->rc_phys;
277         usb_to_input_id(d->udev, &input_dev->id);
278         input_dev->dev.parent = &d->udev->dev;
279
280         /* Start the remote-control polling. */
281         if (d->props.rc.legacy.rc_interval < 40)
282                 d->props.rc.legacy.rc_interval = 100; /* default */
283
284         d->rc_input_dev = input_dev;
285
286         if (d->props.rc.mode == DVB_RC_LEGACY)
287                 err = legacy_dvb_usb_remote_init(d, input_dev);
288         else
289                 err = rc_core_dvb_usb_remote_init(d, input_dev);
290         if (err)
291                 return err;
292
293         d->state |= DVB_USB_STATE_REMOTE;
294
295         return 0;
296 }
297
298 int dvb_usb_remote_exit(struct dvb_usb_device *d)
299 {
300         if (d->state & DVB_USB_STATE_REMOTE) {
301                 cancel_rearming_delayed_work(&d->rc_query_work);
302                 flush_scheduled_work();
303                 if (d->props.rc.mode == DVB_RC_LEGACY)
304                         input_unregister_device(d->rc_input_dev);
305                 else
306                         ir_input_unregister(d->rc_input_dev);
307         }
308         d->state &= ~DVB_USB_STATE_REMOTE;
309         return 0;
310 }
311
312 #define DVB_USB_RC_NEC_EMPTY           0x00
313 #define DVB_USB_RC_NEC_KEY_PRESSED     0x01
314 #define DVB_USB_RC_NEC_KEY_REPEATED    0x02
315 int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
316                 u8 keybuf[5], u32 *event, int *state)
317 {
318         int i;
319         struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
320         *event = 0;
321         *state = REMOTE_NO_KEY_PRESSED;
322         switch (keybuf[0]) {
323                 case DVB_USB_RC_NEC_EMPTY:
324                         break;
325                 case DVB_USB_RC_NEC_KEY_PRESSED:
326                         if ((u8) ~keybuf[1] != keybuf[2] ||
327                                 (u8) ~keybuf[3] != keybuf[4]) {
328                                 deb_err("remote control checksum failed.\n");
329                                 break;
330                         }
331                         /* See if we can match the raw key code. */
332                         for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
333                                 if (rc5_custom(&keymap[i]) == keybuf[1] &&
334                                         rc5_data(&keymap[i]) == keybuf[3]) {
335                                         *event = keymap[i].keycode;
336                                         *state = REMOTE_KEY_PRESSED;
337                                         return 0;
338                                 }
339                         deb_err("key mapping failed - no appropriate key found in keymapping\n");
340                         break;
341                 case DVB_USB_RC_NEC_KEY_REPEATED:
342                         *state = REMOTE_KEY_REPEAT;
343                         break;
344                 default:
345                         deb_err("unknown type of remote status: %d\n",keybuf[0]);
346                         break;
347         }
348         return 0;
349 }
350 EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);