• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
legacy_dvb_usb_get_keymap_index(const struct input_keymap_entry * ke,struct rc_map_table * keymap,unsigned int keymap_size)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 
legacy_dvb_usb_getkeycode(struct input_dev * dev,struct input_keymap_entry * ke)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 
legacy_dvb_usb_setkeycode(struct input_dev * dev,const struct input_keymap_entry * ke,unsigned int * old_keycode)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  */
legacy_dvb_usb_read_remote_control(struct work_struct * work)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 
legacy_dvb_usb_remote_init(struct dvb_usb_device * d)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  */
dvb_usb_read_remote_control(struct work_struct * work)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 
rc_core_dvb_usb_remote_init(struct dvb_usb_device * d)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_protocols = 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 
dvb_usb_remote_init(struct dvb_usb_device * d)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 
dvb_usb_remote_exit(struct dvb_usb_device * d)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
dvb_usb_nec_rc_key_to_event(struct dvb_usb_device * d,u8 keybuf[5],u32 * event,int * state)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);
392