Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dvb-usb-remote.c
Go to the documentation of this file.
1 /* dvb-usb-remote.c is part of the DVB USB library.
2  *
3  * Copyright (C) 2004-6 Patrick Boettcher ([email protected])
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 */
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) {
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);
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);
228  msecs_to_jiffies(rc_interval));
229 
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 
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);
302  msecs_to_jiffies(rc_interval));
303 
304  return 0;
305 }
306 
308 {
309  int err;
310 
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 
336 
337  return 0;
338 }
339 
341 {
342  if (d->state & DVB_USB_STATE_REMOTE) {
344  if (d->props.rc.mode == DVB_RC_LEGACY)
345  input_unregister_device(d->input_dev);
346  else
348  }
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
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]) {
365  break;
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;
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 }