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_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 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); 392