1 /* dvb-usb-remote.c is part of the DVB USB library. 2 * 3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.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 input_event(d->input_dev, EV_KEY, event, 1); 135 input_sync(d->input_dev); 136 input_event(d->input_dev, EV_KEY, d->last_event, 0); 137 input_sync(d->input_dev); 138 break; 139 case REMOTE_KEY_REPEAT: 140 deb_rc("key repeated\n"); 141 input_event(d->input_dev, EV_KEY, event, 1); 142 input_sync(d->input_dev); 143 input_event(d->input_dev, EV_KEY, d->last_event, 0); 144 input_sync(d->input_dev); 145 break; 146 default: 147 break; 148 } 149 150 /* improved repeat handling ??? 151 switch (state) { 152 case REMOTE_NO_KEY_PRESSED: 153 deb_rc("NO KEY PRESSED\n"); 154 if (d->last_state != REMOTE_NO_KEY_PRESSED) { 155 deb_rc("releasing event %d\n",d->last_event); 156 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0); 157 input_sync(d->rc_input_dev); 158 } 159 d->last_state = REMOTE_NO_KEY_PRESSED; 160 d->last_event = 0; 161 break; 162 case REMOTE_KEY_PRESSED: 163 deb_rc("KEY PRESSED\n"); 164 deb_rc("pressing event %d\n",event); 165 166 input_event(d->rc_input_dev, EV_KEY, event, 1); 167 input_sync(d->rc_input_dev); 168 169 d->last_event = event; 170 d->last_state = REMOTE_KEY_PRESSED; 171 break; 172 case REMOTE_KEY_REPEAT: 173 deb_rc("KEY_REPEAT\n"); 174 if (d->last_state != REMOTE_NO_KEY_PRESSED) { 175 deb_rc("repeating event %d\n",d->last_event); 176 input_event(d->rc_input_dev, EV_KEY, d->last_event, 2); 177 input_sync(d->rc_input_dev); 178 d->last_state = REMOTE_KEY_REPEAT; 179 } 180 default: 181 break; 182 } 183 */ 184 185 schedule: 186 schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval)); 187 } 188 189 static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d) 190 { 191 int i, err, rc_interval; 192 struct input_dev *input_dev; 193 194 input_dev = input_allocate_device(); 195 if (!input_dev) 196 return -ENOMEM; 197 198 input_dev->evbit[0] = BIT_MASK(EV_KEY); 199 input_dev->name = "IR-receiver inside an USB DVB receiver"; 200 input_dev->phys = d->rc_phys; 201 usb_to_input_id(d->udev, &input_dev->id); 202 input_dev->dev.parent = &d->udev->dev; 203 d->input_dev = input_dev; 204 d->rc_dev = NULL; 205 206 input_dev->getkeycode = legacy_dvb_usb_getkeycode; 207 input_dev->setkeycode = legacy_dvb_usb_setkeycode; 208 209 /* set the bits for the keys */ 210 deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size); 211 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) { 212 deb_rc("setting bit for event %d item %d\n", 213 d->props.rc.legacy.rc_map_table[i].keycode, i); 214 set_bit(d->props.rc.legacy.rc_map_table[i].keycode, input_dev->keybit); 215 } 216 217 /* setting these two values to non-zero, we have to manage key repeats */ 218 input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval; 219 input_dev->rep[REP_DELAY] = d->props.rc.legacy.rc_interval + 150; 220 221 input_set_drvdata(input_dev, d); 222 223 err = input_register_device(input_dev); 224 if (err) 225 input_free_device(input_dev); 226 227 rc_interval = d->props.rc.legacy.rc_interval; 228 229 INIT_DELAYED_WORK(&d->rc_query_work, legacy_dvb_usb_read_remote_control); 230 231 info("schedule remote query interval to %d msecs.", rc_interval); 232 schedule_delayed_work(&d->rc_query_work, 233 msecs_to_jiffies(rc_interval)); 234 235 d->state |= DVB_USB_STATE_REMOTE; 236 237 return err; 238 } 239 240 /* Remote-control poll function - called every dib->rc_query_interval ms to see 241 * whether the remote control has received anything. 242 * 243 * TODO: Fix the repeat rate of the input device. 244 */ 245 static void dvb_usb_read_remote_control(struct work_struct *work) 246 { 247 struct dvb_usb_device *d = 248 container_of(work, struct dvb_usb_device, rc_query_work.work); 249 int err; 250 251 /* TODO: need a lock here. We can simply skip checking for the remote control 252 if we're busy. */ 253 254 /* when the parameter has been set to 1 via sysfs while the 255 * driver was running, or when bulk mode is enabled after IR init 256 */ 257 if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode) 258 return; 259 260 err = d->props.rc.core.rc_query(d); 261 if (err) 262 err("error %d while querying for an remote control event.", err); 263 264 schedule_delayed_work(&d->rc_query_work, 265 msecs_to_jiffies(d->props.rc.core.rc_interval)); 266 } 267 268 static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) 269 { 270 int err, rc_interval; 271 struct rc_dev *dev; 272 273 dev = rc_allocate_device(d->props.rc.core.driver_type); 274 if (!dev) 275 return -ENOMEM; 276 277 dev->driver_name = d->props.rc.core.module_name; 278 dev->map_name = d->props.rc.core.rc_codes; 279 dev->change_protocol = d->props.rc.core.change_protocol; 280 dev->allowed_protocols = d->props.rc.core.allowed_protos; 281 usb_to_input_id(d->udev, &dev->input_id); 282 dev->device_name = "IR-receiver inside an USB DVB receiver"; 283 dev->input_phys = d->rc_phys; 284 dev->dev.parent = &d->udev->dev; 285 dev->priv = d; 286 287 err = rc_register_device(dev); 288 if (err < 0) { 289 rc_free_device(dev); 290 return err; 291 } 292 293 d->input_dev = NULL; 294 d->rc_dev = dev; 295 296 if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode) 297 return 0; 298 299 /* Polling mode - initialize a work queue for handling it */ 300 INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control); 301 302 rc_interval = d->props.rc.core.rc_interval; 303 304 info("schedule remote query interval to %d msecs.", rc_interval); 305 schedule_delayed_work(&d->rc_query_work, 306 msecs_to_jiffies(rc_interval)); 307 308 return 0; 309 } 310 311 int dvb_usb_remote_init(struct dvb_usb_device *d) 312 { 313 int err; 314 315 if (dvb_usb_disable_rc_polling) 316 return 0; 317 318 if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query) 319 d->props.rc.mode = DVB_RC_LEGACY; 320 else if (d->props.rc.core.rc_codes) 321 d->props.rc.mode = DVB_RC_CORE; 322 else 323 return 0; 324 325 usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys)); 326 strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys)); 327 328 /* Start the remote-control polling. */ 329 if (d->props.rc.legacy.rc_interval < 40) 330 d->props.rc.legacy.rc_interval = 100; /* default */ 331 332 if (d->props.rc.mode == DVB_RC_LEGACY) 333 err = legacy_dvb_usb_remote_init(d); 334 else 335 err = rc_core_dvb_usb_remote_init(d); 336 if (err) 337 return err; 338 339 d->state |= DVB_USB_STATE_REMOTE; 340 341 return 0; 342 } 343 344 int dvb_usb_remote_exit(struct dvb_usb_device *d) 345 { 346 if (d->state & DVB_USB_STATE_REMOTE) { 347 cancel_delayed_work_sync(&d->rc_query_work); 348 if (d->props.rc.mode == DVB_RC_LEGACY) 349 input_unregister_device(d->input_dev); 350 else 351 rc_unregister_device(d->rc_dev); 352 } 353 d->state &= ~DVB_USB_STATE_REMOTE; 354 return 0; 355 } 356 357 #define DVB_USB_RC_NEC_EMPTY 0x00 358 #define DVB_USB_RC_NEC_KEY_PRESSED 0x01 359 #define DVB_USB_RC_NEC_KEY_REPEATED 0x02 360 int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d, 361 u8 keybuf[5], u32 *event, int *state) 362 { 363 int i; 364 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; 365 *event = 0; 366 *state = REMOTE_NO_KEY_PRESSED; 367 switch (keybuf[0]) { 368 case DVB_USB_RC_NEC_EMPTY: 369 break; 370 case DVB_USB_RC_NEC_KEY_PRESSED: 371 if ((u8) ~keybuf[1] != keybuf[2] || 372 (u8) ~keybuf[3] != keybuf[4]) { 373 deb_err("remote control checksum failed.\n"); 374 break; 375 } 376 /* See if we can match the raw key code. */ 377 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) 378 if (rc5_custom(&keymap[i]) == keybuf[1] && 379 rc5_data(&keymap[i]) == keybuf[3]) { 380 *event = keymap[i].keycode; 381 *state = REMOTE_KEY_PRESSED; 382 return 0; 383 } 384 deb_err("key mapping failed - no appropriate key found in keymapping\n"); 385 break; 386 case DVB_USB_RC_NEC_KEY_REPEATED: 387 *state = REMOTE_KEY_REPEAT; 388 break; 389 default: 390 deb_err("unknown type of remote status: %d\n",keybuf[0]); 391 break; 392 } 393 return 0; 394 } 395 EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event); 396