diff options
Diffstat (limited to 'linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c')
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 77 |
1 files changed, 75 insertions, 2 deletions
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index ec95bdf90..76c281b9d 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -12,6 +12,73 @@ #include <linux/usb_input.h> #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) +static int dvb_usb_getkeycode(struct input_dev *dev, + int scancode, int *keycode) +{ + struct dvb_usb_device *d = input_get_drvdata(dev); + + struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + int i; + + /* See if we can match the raw key code. */ + for (i = 0; i < d->props.rc_key_map_size; i++) + if (keymap[i].scan == scancode) { + *keycode = keymap[i].event; + return 0; + } + + /* + * If is there extra space, returns KEY_RESERVED, + * otherwise, input core won't let dvb_usb_setkeycode + * to work + */ + for (i = 0; i < d->props.rc_key_map_size; i++) + if (keymap[i].event == KEY_RESERVED || + keymap[i].event == KEY_UNKNOWN) { + *keycode = KEY_RESERVED; + return 0; + } + + return -EINVAL; +} + +static int dvb_usb_setkeycode(struct input_dev *dev, + int scancode, int keycode) +{ + struct dvb_usb_device *d = input_get_drvdata(dev); + + struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + int i; + + /* Search if it is replacing an existing keycode */ + for (i = 0; i < d->props.rc_key_map_size; i++) + if (keymap[i].scan == scancode) { + keymap[i].event = keycode; + return 0; + } + + /* Search if is there a clean entry. If so, use it */ + for (i = 0; i < d->props.rc_key_map_size; i++) + if (keymap[i].event == KEY_RESERVED || + keymap[i].event == KEY_UNKNOWN) { + keymap[i].scan = scancode; + keymap[i].event = keycode; + return 0; + } + + /* + * FIXME: Currently, it is not possible to increase the size of + * scancode table. For it to happen, one possibility + * would be to allocate a table with key_map_size + 1, + * copying data, appending the new key on it, and freeing + * the old one - or maybe just allocating some spare space + */ + + return -EINVAL; +} +#endif + /* Remote-control poll function - called every dib->rc_query_interval ms to see * whether the remote control has received anything. * @@ -124,6 +191,8 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) usb_to_input_id(d->udev, &input_dev->id); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) input_dev->dev.parent = &d->udev->dev; + input_dev->getkeycode = dvb_usb_getkeycode; + input_dev->setkeycode = dvb_usb_setkeycode; #else input_dev->cdev.dev = &d->udev->dev; #endif @@ -144,6 +213,10 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) input_dev->rep[REP_PERIOD] = d->props.rc_interval; input_dev->rep[REP_DELAY] = d->props.rc_interval + 150; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + input_set_drvdata(input_dev, d); +#endif + err = input_register_device(input_dev); if (err) { input_free_device(input_dev); @@ -198,8 +271,8 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d, } /* See if we can match the raw key code. */ for (i = 0; i < d->props.rc_key_map_size; i++) - if (keymap[i].custom == keybuf[1] && - keymap[i].data == keybuf[3]) { + if (rc5_custom(&keymap[i]) == keybuf[1] && + rc5_data(&keymap[i]) == keybuf[3]) { *event = keymap[i].event; *state = REMOTE_KEY_PRESSED; return 0; |