GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / media / dvb / dvb-usb / dvb-usb-remote.c
blob36402009048f8f26e954ddbf48e4e7f33a73f755
1 /* dvb-usb-remote.c is part of the DVB USB library.
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
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>
11 static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
12 unsigned int scancode, unsigned int *keycode)
14 struct dvb_usb_device *d = input_get_drvdata(dev);
16 struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
17 int i;
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;
27 * If is there extra space, returns KEY_RESERVED,
28 * otherwise, input core won't let legacy_dvb_usb_setkeycode
29 * to work
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;
38 return -EINVAL;
41 static int legacy_dvb_usb_setkeycode(struct input_dev *dev,
42 unsigned int scancode, unsigned int keycode)
44 struct dvb_usb_device *d = input_get_drvdata(dev);
46 struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
47 int i;
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;
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;
66 return -EINVAL;
69 /* Remote-control poll function - called every dib->rc_query_interval ms to see
70 * whether the remote control has received anything.
72 * TODO: Fix the repeat rate of the input device.
74 static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
76 struct dvb_usb_device *d =
77 container_of(work, struct dvb_usb_device, rc_query_work.work);
78 u32 event;
79 int state;
81 /* TODO: need a lock here. We can simply skip checking for the remote control
82 if we're busy. */
84 /* when the parameter has been set to 1 via sysfs while the driver was running */
85 if (dvb_usb_disable_rc_polling)
86 return;
88 if (d->props.rc.legacy.rc_query(d,&event,&state)) {
89 err("error while querying for an remote control event.");
90 goto schedule;
94 switch (state) {
95 case REMOTE_NO_KEY_PRESSED:
96 break;
97 case REMOTE_KEY_PRESSED:
98 deb_rc("key pressed\n");
99 d->last_event = event;
100 case REMOTE_KEY_REPEAT:
101 deb_rc("key repeated\n");
102 input_event(d->rc_input_dev, EV_KEY, event, 1);
103 input_sync(d->rc_input_dev);
104 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
105 input_sync(d->rc_input_dev);
106 break;
107 default:
108 break;
111 /* improved repeat handling ???
112 switch (state) {
113 case REMOTE_NO_KEY_PRESSED:
114 deb_rc("NO KEY PRESSED\n");
115 if (d->last_state != REMOTE_NO_KEY_PRESSED) {
116 deb_rc("releasing event %d\n",d->last_event);
117 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
118 input_sync(d->rc_input_dev);
120 d->last_state = REMOTE_NO_KEY_PRESSED;
121 d->last_event = 0;
122 break;
123 case REMOTE_KEY_PRESSED:
124 deb_rc("KEY PRESSED\n");
125 deb_rc("pressing event %d\n",event);
127 input_event(d->rc_input_dev, EV_KEY, event, 1);
128 input_sync(d->rc_input_dev);
130 d->last_event = event;
131 d->last_state = REMOTE_KEY_PRESSED;
132 break;
133 case REMOTE_KEY_REPEAT:
134 deb_rc("KEY_REPEAT\n");
135 if (d->last_state != REMOTE_NO_KEY_PRESSED) {
136 deb_rc("repeating event %d\n",d->last_event);
137 input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
138 input_sync(d->rc_input_dev);
139 d->last_state = REMOTE_KEY_REPEAT;
141 default:
142 break;
146 schedule:
147 schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
150 static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d,
151 struct input_dev *input_dev)
153 int i, err, rc_interval;
155 input_dev->getkeycode = legacy_dvb_usb_getkeycode;
156 input_dev->setkeycode = legacy_dvb_usb_setkeycode;
158 /* set the bits for the keys */
159 deb_rc("key map size: %d\n", d->props.rc.legacy.rc_key_map_size);
160 for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
161 deb_rc("setting bit for event %d item %d\n",
162 d->props.rc.legacy.rc_key_map[i].keycode, i);
163 set_bit(d->props.rc.legacy.rc_key_map[i].keycode, input_dev->keybit);
166 /* setting these two values to non-zero, we have to manage key repeats */
167 input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval;
168 input_dev->rep[REP_DELAY] = d->props.rc.legacy.rc_interval + 150;
170 input_set_drvdata(input_dev, d);
172 err = input_register_device(input_dev);
173 if (err)
174 input_free_device(input_dev);
176 rc_interval = d->props.rc.legacy.rc_interval;
178 INIT_DELAYED_WORK(&d->rc_query_work, legacy_dvb_usb_read_remote_control);
180 info("schedule remote query interval to %d msecs.", rc_interval);
181 schedule_delayed_work(&d->rc_query_work,
182 msecs_to_jiffies(rc_interval));
184 d->state |= DVB_USB_STATE_REMOTE;
186 return err;
189 /* Remote-control poll function - called every dib->rc_query_interval ms to see
190 * whether the remote control has received anything.
192 * TODO: Fix the repeat rate of the input device.
194 static void dvb_usb_read_remote_control(struct work_struct *work)
196 struct dvb_usb_device *d =
197 container_of(work, struct dvb_usb_device, rc_query_work.work);
198 int err;
200 /* TODO: need a lock here. We can simply skip checking for the remote control
201 if we're busy. */
203 /* when the parameter has been set to 1 via sysfs while the
204 * driver was running, or when bulk mode is enabled after IR init
206 if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode)
207 return;
209 err = d->props.rc.core.rc_query(d);
210 if (err)
211 err("error %d while querying for an remote control event.", err);
213 schedule_delayed_work(&d->rc_query_work,
214 msecs_to_jiffies(d->props.rc.core.rc_interval));
217 static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d,
218 struct input_dev *input_dev)
220 int err, rc_interval;
222 d->props.rc.core.rc_props.priv = d;
223 err = ir_input_register(input_dev,
224 d->props.rc.core.rc_codes,
225 &d->props.rc.core.rc_props,
226 d->props.rc.core.module_name);
227 if (err < 0)
228 return err;
230 if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
231 return 0;
233 /* Polling mode - initialize a work queue for handling it */
234 INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
236 rc_interval = d->props.rc.core.rc_interval;
238 info("schedule remote query interval to %d msecs.", rc_interval);
239 schedule_delayed_work(&d->rc_query_work,
240 msecs_to_jiffies(rc_interval));
242 return 0;
245 int dvb_usb_remote_init(struct dvb_usb_device *d)
247 struct input_dev *input_dev;
248 int err;
250 if (dvb_usb_disable_rc_polling)
251 return 0;
253 if (d->props.rc.legacy.rc_key_map && d->props.rc.legacy.rc_query)
254 d->props.rc.mode = DVB_RC_LEGACY;
255 else if (d->props.rc.core.rc_codes)
256 d->props.rc.mode = DVB_RC_CORE;
257 else
258 return 0;
260 usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
261 strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
263 input_dev = input_allocate_device();
264 if (!input_dev)
265 return -ENOMEM;
267 input_dev->evbit[0] = BIT_MASK(EV_KEY);
268 input_dev->name = "IR-receiver inside an USB DVB receiver";
269 input_dev->phys = d->rc_phys;
270 usb_to_input_id(d->udev, &input_dev->id);
271 input_dev->dev.parent = &d->udev->dev;
273 /* Start the remote-control polling. */
274 if (d->props.rc.legacy.rc_interval < 40)
275 d->props.rc.legacy.rc_interval = 100; /* default */
277 d->rc_input_dev = input_dev;
279 if (d->props.rc.mode == DVB_RC_LEGACY)
280 err = legacy_dvb_usb_remote_init(d, input_dev);
281 else
282 err = rc_core_dvb_usb_remote_init(d, input_dev);
283 if (err)
284 return err;
286 d->state |= DVB_USB_STATE_REMOTE;
288 return 0;
291 int dvb_usb_remote_exit(struct dvb_usb_device *d)
293 if (d->state & DVB_USB_STATE_REMOTE) {
294 cancel_rearming_delayed_work(&d->rc_query_work);
295 flush_scheduled_work();
296 if (d->props.rc.mode == DVB_RC_LEGACY)
297 input_unregister_device(d->rc_input_dev);
298 else
299 ir_input_unregister(d->rc_input_dev);
301 d->state &= ~DVB_USB_STATE_REMOTE;
302 return 0;
305 #define DVB_USB_RC_NEC_EMPTY 0x00
306 #define DVB_USB_RC_NEC_KEY_PRESSED 0x01
307 #define DVB_USB_RC_NEC_KEY_REPEATED 0x02
308 int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
309 u8 keybuf[5], u32 *event, int *state)
311 int i;
312 struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
313 *event = 0;
314 *state = REMOTE_NO_KEY_PRESSED;
315 switch (keybuf[0]) {
316 case DVB_USB_RC_NEC_EMPTY:
317 break;
318 case DVB_USB_RC_NEC_KEY_PRESSED:
319 if ((u8) ~keybuf[1] != keybuf[2] ||
320 (u8) ~keybuf[3] != keybuf[4]) {
321 deb_err("remote control checksum failed.\n");
322 break;
324 /* See if we can match the raw key code. */
325 for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
326 if (rc5_custom(&keymap[i]) == keybuf[1] &&
327 rc5_data(&keymap[i]) == keybuf[3]) {
328 *event = keymap[i].keycode;
329 *state = REMOTE_KEY_PRESSED;
330 return 0;
332 deb_err("key mapping failed - no appropriate key found in keymapping\n");
333 break;
334 case DVB_USB_RC_NEC_KEY_REPEATED:
335 *state = REMOTE_KEY_REPEAT;
336 break;
337 default:
338 deb_err("unknown type of remote status: %d\n",keybuf[0]);
339 break;
341 return 0;
343 EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);