Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* dvb-usb-remote.c is part of the DVB USB library.
0003  *
0004  * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
0005  * see dvb-usb-init.c for copyright information.
0006  *
0007  * This file contains functions for initializing the input-device and for handling remote-control-queries.
0008  */
0009 #include "dvb-usb-common.h"
0010 #include <linux/usb/input.h>
0011 
0012 static unsigned int
0013 legacy_dvb_usb_get_keymap_index(const struct input_keymap_entry *ke,
0014                 struct rc_map_table *keymap,
0015                 unsigned int keymap_size)
0016 {
0017     unsigned int index;
0018     unsigned int scancode;
0019 
0020     if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
0021         index = ke->index;
0022     } else {
0023         if (input_scancode_to_scalar(ke, &scancode))
0024             return keymap_size;
0025 
0026         /* See if we can match the raw key code. */
0027         for (index = 0; index < keymap_size; index++)
0028             if (keymap[index].scancode == scancode)
0029                 break;
0030 
0031         /* See if there is an unused hole in the map */
0032         if (index >= keymap_size) {
0033             for (index = 0; index < keymap_size; index++) {
0034                 if (keymap[index].keycode == KEY_RESERVED ||
0035                     keymap[index].keycode == KEY_UNKNOWN) {
0036                     break;
0037                 }
0038             }
0039         }
0040     }
0041 
0042     return index;
0043 }
0044 
0045 static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
0046                      struct input_keymap_entry *ke)
0047 {
0048     struct dvb_usb_device *d = input_get_drvdata(dev);
0049     struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
0050     unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
0051     unsigned int index;
0052 
0053     index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
0054     if (index >= keymap_size)
0055         return -EINVAL;
0056 
0057     ke->keycode = keymap[index].keycode;
0058     if (ke->keycode == KEY_UNKNOWN)
0059         ke->keycode = KEY_RESERVED;
0060     ke->len = sizeof(keymap[index].scancode);
0061     memcpy(&ke->scancode, &keymap[index].scancode, ke->len);
0062     ke->index = index;
0063 
0064     return 0;
0065 }
0066 
0067 static int legacy_dvb_usb_setkeycode(struct input_dev *dev,
0068                      const struct input_keymap_entry *ke,
0069                      unsigned int *old_keycode)
0070 {
0071     struct dvb_usb_device *d = input_get_drvdata(dev);
0072     struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
0073     unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
0074     unsigned int index;
0075 
0076     index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
0077     /*
0078      * FIXME: Currently, it is not possible to increase the size of
0079      * scancode table. For it to happen, one possibility
0080      * would be to allocate a table with key_map_size + 1,
0081      * copying data, appending the new key on it, and freeing
0082      * the old one - or maybe just allocating some spare space
0083      */
0084     if (index >= keymap_size)
0085         return -EINVAL;
0086 
0087     *old_keycode = keymap[index].keycode;
0088     keymap->keycode = ke->keycode;
0089     __set_bit(ke->keycode, dev->keybit);
0090 
0091     if (*old_keycode != KEY_RESERVED) {
0092         __clear_bit(*old_keycode, dev->keybit);
0093         for (index = 0; index < keymap_size; index++) {
0094             if (keymap[index].keycode == *old_keycode) {
0095                 __set_bit(*old_keycode, dev->keybit);
0096                 break;
0097             }
0098         }
0099     }
0100 
0101     return 0;
0102 }
0103 
0104 /* Remote-control poll function - called every dib->rc_query_interval ms to see
0105  * whether the remote control has received anything.
0106  *
0107  * TODO: Fix the repeat rate of the input device.
0108  */
0109 static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
0110 {
0111     struct dvb_usb_device *d =
0112         container_of(work, struct dvb_usb_device, rc_query_work.work);
0113     u32 event;
0114     int state;
0115 
0116     /* TODO: need a lock here.  We can simply skip checking for the remote control
0117        if we're busy. */
0118 
0119     /* when the parameter has been set to 1 via sysfs while the driver was running */
0120     if (dvb_usb_disable_rc_polling)
0121         return;
0122 
0123     if (d->props.rc.legacy.rc_query(d,&event,&state)) {
0124         err("error while querying for an remote control event.");
0125         goto schedule;
0126     }
0127 
0128 
0129     switch (state) {
0130         case REMOTE_NO_KEY_PRESSED:
0131             break;
0132         case REMOTE_KEY_PRESSED:
0133             deb_rc("key pressed\n");
0134             d->last_event = event;
0135             input_event(d->input_dev, EV_KEY, event, 1);
0136             input_sync(d->input_dev);
0137             input_event(d->input_dev, EV_KEY, d->last_event, 0);
0138             input_sync(d->input_dev);
0139             break;
0140         case REMOTE_KEY_REPEAT:
0141             deb_rc("key repeated\n");
0142             input_event(d->input_dev, EV_KEY, event, 1);
0143             input_sync(d->input_dev);
0144             input_event(d->input_dev, EV_KEY, d->last_event, 0);
0145             input_sync(d->input_dev);
0146             break;
0147         default:
0148             break;
0149     }
0150 
0151 /* improved repeat handling ???
0152     switch (state) {
0153         case REMOTE_NO_KEY_PRESSED:
0154             deb_rc("NO KEY PRESSED\n");
0155             if (d->last_state != REMOTE_NO_KEY_PRESSED) {
0156                 deb_rc("releasing event %d\n",d->last_event);
0157                 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
0158                 input_sync(d->rc_input_dev);
0159             }
0160             d->last_state = REMOTE_NO_KEY_PRESSED;
0161             d->last_event = 0;
0162             break;
0163         case REMOTE_KEY_PRESSED:
0164             deb_rc("KEY PRESSED\n");
0165             deb_rc("pressing event %d\n",event);
0166 
0167             input_event(d->rc_input_dev, EV_KEY, event, 1);
0168             input_sync(d->rc_input_dev);
0169 
0170             d->last_event = event;
0171             d->last_state = REMOTE_KEY_PRESSED;
0172             break;
0173         case REMOTE_KEY_REPEAT:
0174             deb_rc("KEY_REPEAT\n");
0175             if (d->last_state != REMOTE_NO_KEY_PRESSED) {
0176                 deb_rc("repeating event %d\n",d->last_event);
0177                 input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
0178                 input_sync(d->rc_input_dev);
0179                 d->last_state = REMOTE_KEY_REPEAT;
0180             }
0181         default:
0182             break;
0183     }
0184 */
0185 
0186 schedule:
0187     schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
0188 }
0189 
0190 static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
0191 {
0192     int i, err, rc_interval;
0193     struct input_dev *input_dev;
0194 
0195     input_dev = input_allocate_device();
0196     if (!input_dev)
0197         return -ENOMEM;
0198 
0199     input_dev->evbit[0] = BIT_MASK(EV_KEY);
0200     input_dev->name = "IR-receiver inside an USB DVB receiver";
0201     input_dev->phys = d->rc_phys;
0202     usb_to_input_id(d->udev, &input_dev->id);
0203     input_dev->dev.parent = &d->udev->dev;
0204     d->input_dev = input_dev;
0205     d->rc_dev = NULL;
0206 
0207     input_dev->getkeycode = legacy_dvb_usb_getkeycode;
0208     input_dev->setkeycode = legacy_dvb_usb_setkeycode;
0209 
0210     /* set the bits for the keys */
0211     deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size);
0212     for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
0213         deb_rc("setting bit for event %d item %d\n",
0214             d->props.rc.legacy.rc_map_table[i].keycode, i);
0215         set_bit(d->props.rc.legacy.rc_map_table[i].keycode, input_dev->keybit);
0216     }
0217 
0218     /* setting these two values to non-zero, we have to manage key repeats */
0219     input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval;
0220     input_dev->rep[REP_DELAY]  = d->props.rc.legacy.rc_interval + 150;
0221 
0222     input_set_drvdata(input_dev, d);
0223 
0224     err = input_register_device(input_dev);
0225     if (err)
0226         input_free_device(input_dev);
0227 
0228     rc_interval = d->props.rc.legacy.rc_interval;
0229 
0230     INIT_DELAYED_WORK(&d->rc_query_work, legacy_dvb_usb_read_remote_control);
0231 
0232     info("schedule remote query interval to %d msecs.", rc_interval);
0233     schedule_delayed_work(&d->rc_query_work,
0234                   msecs_to_jiffies(rc_interval));
0235 
0236     d->state |= DVB_USB_STATE_REMOTE;
0237 
0238     return err;
0239 }
0240 
0241 /* Remote-control poll function - called every dib->rc_query_interval ms to see
0242  * whether the remote control has received anything.
0243  *
0244  * TODO: Fix the repeat rate of the input device.
0245  */
0246 static void dvb_usb_read_remote_control(struct work_struct *work)
0247 {
0248     struct dvb_usb_device *d =
0249         container_of(work, struct dvb_usb_device, rc_query_work.work);
0250     int err;
0251 
0252     /* TODO: need a lock here.  We can simply skip checking for the remote control
0253        if we're busy. */
0254 
0255     /* when the parameter has been set to 1 via sysfs while the
0256      * driver was running, or when bulk mode is enabled after IR init
0257      */
0258     if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode)
0259         return;
0260 
0261     err = d->props.rc.core.rc_query(d);
0262     if (err)
0263         err("error %d while querying for an remote control event.", err);
0264 
0265     schedule_delayed_work(&d->rc_query_work,
0266                   msecs_to_jiffies(d->props.rc.core.rc_interval));
0267 }
0268 
0269 static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
0270 {
0271     int err, rc_interval;
0272     struct rc_dev *dev;
0273 
0274     dev = rc_allocate_device(d->props.rc.core.driver_type);
0275     if (!dev)
0276         return -ENOMEM;
0277 
0278     dev->driver_name = d->props.rc.core.module_name;
0279     dev->map_name = d->props.rc.core.rc_codes;
0280     dev->change_protocol = d->props.rc.core.change_protocol;
0281     dev->allowed_protocols = d->props.rc.core.allowed_protos;
0282     usb_to_input_id(d->udev, &dev->input_id);
0283     dev->device_name = d->desc->name;
0284     dev->input_phys = d->rc_phys;
0285     dev->dev.parent = &d->udev->dev;
0286     dev->priv = d;
0287     dev->scancode_mask = d->props.rc.core.scancode_mask;
0288 
0289     err = rc_register_device(dev);
0290     if (err < 0) {
0291         rc_free_device(dev);
0292         return err;
0293     }
0294 
0295     d->input_dev = NULL;
0296     d->rc_dev = dev;
0297 
0298     if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
0299         return 0;
0300 
0301     /* Polling mode - initialize a work queue for handling it */
0302     INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
0303 
0304     rc_interval = d->props.rc.core.rc_interval;
0305 
0306     info("schedule remote query interval to %d msecs.", rc_interval);
0307     schedule_delayed_work(&d->rc_query_work,
0308                   msecs_to_jiffies(rc_interval));
0309 
0310     return 0;
0311 }
0312 
0313 int dvb_usb_remote_init(struct dvb_usb_device *d)
0314 {
0315     int err;
0316 
0317     if (dvb_usb_disable_rc_polling)
0318         return 0;
0319 
0320     if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query)
0321         d->props.rc.mode = DVB_RC_LEGACY;
0322     else if (d->props.rc.core.rc_codes)
0323         d->props.rc.mode = DVB_RC_CORE;
0324     else
0325         return 0;
0326 
0327     usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
0328     strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
0329 
0330     /* Start the remote-control polling. */
0331     if (d->props.rc.legacy.rc_interval < 40)
0332         d->props.rc.legacy.rc_interval = 100; /* default */
0333 
0334     if (d->props.rc.mode == DVB_RC_LEGACY)
0335         err = legacy_dvb_usb_remote_init(d);
0336     else
0337         err = rc_core_dvb_usb_remote_init(d);
0338     if (err)
0339         return err;
0340 
0341     d->state |= DVB_USB_STATE_REMOTE;
0342 
0343     return 0;
0344 }
0345 
0346 int dvb_usb_remote_exit(struct dvb_usb_device *d)
0347 {
0348     if (d->state & DVB_USB_STATE_REMOTE) {
0349         cancel_delayed_work_sync(&d->rc_query_work);
0350         if (d->props.rc.mode == DVB_RC_LEGACY)
0351             input_unregister_device(d->input_dev);
0352         else
0353             rc_unregister_device(d->rc_dev);
0354     }
0355     d->state &= ~DVB_USB_STATE_REMOTE;
0356     return 0;
0357 }
0358 
0359 #define DVB_USB_RC_NEC_EMPTY           0x00
0360 #define DVB_USB_RC_NEC_KEY_PRESSED     0x01
0361 #define DVB_USB_RC_NEC_KEY_REPEATED    0x02
0362 int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
0363         u8 keybuf[5], u32 *event, int *state)
0364 {
0365     int i;
0366     struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
0367     *event = 0;
0368     *state = REMOTE_NO_KEY_PRESSED;
0369     switch (keybuf[0]) {
0370         case DVB_USB_RC_NEC_EMPTY:
0371             break;
0372         case DVB_USB_RC_NEC_KEY_PRESSED:
0373             if ((u8) ~keybuf[1] != keybuf[2] ||
0374                 (u8) ~keybuf[3] != keybuf[4]) {
0375                 deb_err("remote control checksum failed.\n");
0376                 break;
0377             }
0378             /* See if we can match the raw key code. */
0379             for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
0380                 if (rc5_custom(&keymap[i]) == keybuf[1] &&
0381                     rc5_data(&keymap[i]) == keybuf[3]) {
0382                     *event = keymap[i].keycode;
0383                     *state = REMOTE_KEY_PRESSED;
0384                     return 0;
0385                 }
0386             deb_err("key mapping failed - no appropriate key found in keymapping\n");
0387             break;
0388         case DVB_USB_RC_NEC_KEY_REPEATED:
0389             *state = REMOTE_KEY_REPEAT;
0390             break;
0391         default:
0392             deb_err("unknown type of remote status: %d\n",keybuf[0]);
0393             break;
0394     }
0395     return 0;
0396 }
0397 EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);