root/drivers/media/usb/dvb-usb/dvb-usb-remote.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. legacy_dvb_usb_get_keymap_index
  2. legacy_dvb_usb_getkeycode
  3. legacy_dvb_usb_setkeycode
  4. legacy_dvb_usb_read_remote_control
  5. legacy_dvb_usb_remote_init
  6. dvb_usb_read_remote_control
  7. rc_core_dvb_usb_remote_init
  8. dvb_usb_remote_init
  9. dvb_usb_remote_exit
  10. dvb_usb_nec_rc_key_to_event

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* dvb-usb-remote.c is part of the DVB USB library.
   3  *
   4  * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
   5  * see dvb-usb-init.c for copyright information.
   6  *
   7  * This file contains functions for initializing the input-device and for handling remote-control-queries.
   8  */
   9 #include "dvb-usb-common.h"
  10 #include <linux/usb/input.h>
  11 
  12 static unsigned int
  13 legacy_dvb_usb_get_keymap_index(const struct input_keymap_entry *ke,
  14                                 struct rc_map_table *keymap,
  15                                 unsigned int keymap_size)
  16 {
  17         unsigned int index;
  18         unsigned int scancode;
  19 
  20         if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
  21                 index = ke->index;
  22         } else {
  23                 if (input_scancode_to_scalar(ke, &scancode))
  24                         return keymap_size;
  25 
  26                 /* See if we can match the raw key code. */
  27                 for (index = 0; index < keymap_size; index++)
  28                         if (keymap[index].scancode == scancode)
  29                                 break;
  30 
  31                 /* See if there is an unused hole in the map */
  32                 if (index >= keymap_size) {
  33                         for (index = 0; index < keymap_size; index++) {
  34                                 if (keymap[index].keycode == KEY_RESERVED ||
  35                                     keymap[index].keycode == KEY_UNKNOWN) {
  36                                         break;
  37                                 }
  38                         }
  39                 }
  40         }
  41 
  42         return index;
  43 }
  44 
  45 static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
  46                                      struct input_keymap_entry *ke)
  47 {
  48         struct dvb_usb_device *d = input_get_drvdata(dev);
  49         struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
  50         unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
  51         unsigned int index;
  52 
  53         index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
  54         if (index >= keymap_size)
  55                 return -EINVAL;
  56 
  57         ke->keycode = keymap[index].keycode;
  58         if (ke->keycode == KEY_UNKNOWN)
  59                 ke->keycode = KEY_RESERVED;
  60         ke->len = sizeof(keymap[index].scancode);
  61         memcpy(&ke->scancode, &keymap[index].scancode, ke->len);
  62         ke->index = index;
  63 
  64         return 0;
  65 }
  66 
  67 static int legacy_dvb_usb_setkeycode(struct input_dev *dev,
  68                                      const struct input_keymap_entry *ke,
  69                                      unsigned int *old_keycode)
  70 {
  71         struct dvb_usb_device *d = input_get_drvdata(dev);
  72         struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
  73         unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
  74         unsigned int index;
  75 
  76         index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
  77         /*
  78          * FIXME: Currently, it is not possible to increase the size of
  79          * scancode table. For it to happen, one possibility
  80          * would be to allocate a table with key_map_size + 1,
  81          * copying data, appending the new key on it, and freeing
  82          * the old one - or maybe just allocating some spare space
  83          */
  84         if (index >= keymap_size)
  85                 return -EINVAL;
  86 
  87         *old_keycode = keymap[index].keycode;
  88         keymap->keycode = ke->keycode;
  89         __set_bit(ke->keycode, dev->keybit);
  90 
  91         if (*old_keycode != KEY_RESERVED) {
  92                 __clear_bit(*old_keycode, dev->keybit);
  93                 for (index = 0; index < keymap_size; index++) {
  94                         if (keymap[index].keycode == *old_keycode) {
  95                                 __set_bit(*old_keycode, dev->keybit);
  96                                 break;
  97                         }
  98                 }
  99         }
 100 
 101         return 0;
 102 }
 103 
 104 /* Remote-control poll function - called every dib->rc_query_interval ms to see
 105  * whether the remote control has received anything.
 106  *
 107  * TODO: Fix the repeat rate of the input device.
 108  */
 109 static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
 110 {
 111         struct dvb_usb_device *d =
 112                 container_of(work, struct dvb_usb_device, rc_query_work.work);
 113         u32 event;
 114         int state;
 115 
 116         /* TODO: need a lock here.  We can simply skip checking for the remote control
 117            if we're busy. */
 118 
 119         /* when the parameter has been set to 1 via sysfs while the driver was running */
 120         if (dvb_usb_disable_rc_polling)
 121                 return;
 122 
 123         if (d->props.rc.legacy.rc_query(d,&event,&state)) {
 124                 err("error while querying for an remote control event.");
 125                 goto schedule;
 126         }
 127 
 128 
 129         switch (state) {
 130                 case REMOTE_NO_KEY_PRESSED:
 131                         break;
 132                 case REMOTE_KEY_PRESSED:
 133                         deb_rc("key pressed\n");
 134                         d->last_event = event;
 135                         input_event(d->input_dev, EV_KEY, event, 1);
 136                         input_sync(d->input_dev);
 137                         input_event(d->input_dev, EV_KEY, d->last_event, 0);
 138                         input_sync(d->input_dev);
 139                         break;
 140                 case REMOTE_KEY_REPEAT:
 141                         deb_rc("key repeated\n");
 142                         input_event(d->input_dev, EV_KEY, event, 1);
 143                         input_sync(d->input_dev);
 144                         input_event(d->input_dev, EV_KEY, d->last_event, 0);
 145                         input_sync(d->input_dev);
 146                         break;
 147                 default:
 148                         break;
 149         }
 150 
 151 /* improved repeat handling ???
 152         switch (state) {
 153                 case REMOTE_NO_KEY_PRESSED:
 154                         deb_rc("NO KEY PRESSED\n");
 155                         if (d->last_state != REMOTE_NO_KEY_PRESSED) {
 156                                 deb_rc("releasing event %d\n",d->last_event);
 157                                 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
 158                                 input_sync(d->rc_input_dev);
 159                         }
 160                         d->last_state = REMOTE_NO_KEY_PRESSED;
 161                         d->last_event = 0;
 162                         break;
 163                 case REMOTE_KEY_PRESSED:
 164                         deb_rc("KEY PRESSED\n");
 165                         deb_rc("pressing event %d\n",event);
 166 
 167                         input_event(d->rc_input_dev, EV_KEY, event, 1);
 168                         input_sync(d->rc_input_dev);
 169 
 170                         d->last_event = event;
 171                         d->last_state = REMOTE_KEY_PRESSED;
 172                         break;
 173                 case REMOTE_KEY_REPEAT:
 174                         deb_rc("KEY_REPEAT\n");
 175                         if (d->last_state != REMOTE_NO_KEY_PRESSED) {
 176                                 deb_rc("repeating event %d\n",d->last_event);
 177                                 input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
 178                                 input_sync(d->rc_input_dev);
 179                                 d->last_state = REMOTE_KEY_REPEAT;
 180                         }
 181                 default:
 182                         break;
 183         }
 184 */
 185 
 186 schedule:
 187         schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
 188 }
 189 
 190 static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
 191 {
 192         int i, err, rc_interval;
 193         struct input_dev *input_dev;
 194 
 195         input_dev = input_allocate_device();
 196         if (!input_dev)
 197                 return -ENOMEM;
 198 
 199         input_dev->evbit[0] = BIT_MASK(EV_KEY);
 200         input_dev->name = "IR-receiver inside an USB DVB receiver";
 201         input_dev->phys = d->rc_phys;
 202         usb_to_input_id(d->udev, &input_dev->id);
 203         input_dev->dev.parent = &d->udev->dev;
 204         d->input_dev = input_dev;
 205         d->rc_dev = NULL;
 206 
 207         input_dev->getkeycode = legacy_dvb_usb_getkeycode;
 208         input_dev->setkeycode = legacy_dvb_usb_setkeycode;
 209 
 210         /* set the bits for the keys */
 211         deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size);
 212         for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
 213                 deb_rc("setting bit for event %d item %d\n",
 214                         d->props.rc.legacy.rc_map_table[i].keycode, i);
 215                 set_bit(d->props.rc.legacy.rc_map_table[i].keycode, input_dev->keybit);
 216         }
 217 
 218         /* setting these two values to non-zero, we have to manage key repeats */
 219         input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval;
 220         input_dev->rep[REP_DELAY]  = d->props.rc.legacy.rc_interval + 150;
 221 
 222         input_set_drvdata(input_dev, d);
 223 
 224         err = input_register_device(input_dev);
 225         if (err)
 226                 input_free_device(input_dev);
 227 
 228         rc_interval = d->props.rc.legacy.rc_interval;
 229 
 230         INIT_DELAYED_WORK(&d->rc_query_work, legacy_dvb_usb_read_remote_control);
 231 
 232         info("schedule remote query interval to %d msecs.", rc_interval);
 233         schedule_delayed_work(&d->rc_query_work,
 234                               msecs_to_jiffies(rc_interval));
 235 
 236         d->state |= DVB_USB_STATE_REMOTE;
 237 
 238         return err;
 239 }
 240 
 241 /* Remote-control poll function - called every dib->rc_query_interval ms to see
 242  * whether the remote control has received anything.
 243  *
 244  * TODO: Fix the repeat rate of the input device.
 245  */
 246 static void dvb_usb_read_remote_control(struct work_struct *work)
 247 {
 248         struct dvb_usb_device *d =
 249                 container_of(work, struct dvb_usb_device, rc_query_work.work);
 250         int err;
 251 
 252         /* TODO: need a lock here.  We can simply skip checking for the remote control
 253            if we're busy. */
 254 
 255         /* when the parameter has been set to 1 via sysfs while the
 256          * driver was running, or when bulk mode is enabled after IR init
 257          */
 258         if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode)
 259                 return;
 260 
 261         err = d->props.rc.core.rc_query(d);
 262         if (err)
 263                 err("error %d while querying for an remote control event.", err);
 264 
 265         schedule_delayed_work(&d->rc_query_work,
 266                               msecs_to_jiffies(d->props.rc.core.rc_interval));
 267 }
 268 
 269 static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
 270 {
 271         int err, rc_interval;
 272         struct rc_dev *dev;
 273 
 274         dev = rc_allocate_device(d->props.rc.core.driver_type);
 275         if (!dev)
 276                 return -ENOMEM;
 277 
 278         dev->driver_name = d->props.rc.core.module_name;
 279         dev->map_name = d->props.rc.core.rc_codes;
 280         dev->change_protocol = d->props.rc.core.change_protocol;
 281         dev->allowed_protocols = d->props.rc.core.allowed_protos;
 282         usb_to_input_id(d->udev, &dev->input_id);
 283         dev->device_name = d->desc->name;
 284         dev->input_phys = d->rc_phys;
 285         dev->dev.parent = &d->udev->dev;
 286         dev->priv = d;
 287         dev->scancode_mask = d->props.rc.core.scancode_mask;
 288 
 289         err = rc_register_device(dev);
 290         if (err < 0) {
 291                 rc_free_device(dev);
 292                 return err;
 293         }
 294 
 295         d->input_dev = NULL;
 296         d->rc_dev = dev;
 297 
 298         if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
 299                 return 0;
 300 
 301         /* Polling mode - initialize a work queue for handling it */
 302         INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
 303 
 304         rc_interval = d->props.rc.core.rc_interval;
 305 
 306         info("schedule remote query interval to %d msecs.", rc_interval);
 307         schedule_delayed_work(&d->rc_query_work,
 308                               msecs_to_jiffies(rc_interval));
 309 
 310         return 0;
 311 }
 312 
 313 int dvb_usb_remote_init(struct dvb_usb_device *d)
 314 {
 315         int err;
 316 
 317         if (dvb_usb_disable_rc_polling)
 318                 return 0;
 319 
 320         if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query)
 321                 d->props.rc.mode = DVB_RC_LEGACY;
 322         else if (d->props.rc.core.rc_codes)
 323                 d->props.rc.mode = DVB_RC_CORE;
 324         else
 325                 return 0;
 326 
 327         usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
 328         strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
 329 
 330         /* Start the remote-control polling. */
 331         if (d->props.rc.legacy.rc_interval < 40)
 332                 d->props.rc.legacy.rc_interval = 100; /* default */
 333 
 334         if (d->props.rc.mode == DVB_RC_LEGACY)
 335                 err = legacy_dvb_usb_remote_init(d);
 336         else
 337                 err = rc_core_dvb_usb_remote_init(d);
 338         if (err)
 339                 return err;
 340 
 341         d->state |= DVB_USB_STATE_REMOTE;
 342 
 343         return 0;
 344 }
 345 
 346 int dvb_usb_remote_exit(struct dvb_usb_device *d)
 347 {
 348         if (d->state & DVB_USB_STATE_REMOTE) {
 349                 cancel_delayed_work_sync(&d->rc_query_work);
 350                 if (d->props.rc.mode == DVB_RC_LEGACY)
 351                         input_unregister_device(d->input_dev);
 352                 else
 353                         rc_unregister_device(d->rc_dev);
 354         }
 355         d->state &= ~DVB_USB_STATE_REMOTE;
 356         return 0;
 357 }
 358 
 359 #define DVB_USB_RC_NEC_EMPTY           0x00
 360 #define DVB_USB_RC_NEC_KEY_PRESSED     0x01
 361 #define DVB_USB_RC_NEC_KEY_REPEATED    0x02
 362 int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
 363                 u8 keybuf[5], u32 *event, int *state)
 364 {
 365         int i;
 366         struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
 367         *event = 0;
 368         *state = REMOTE_NO_KEY_PRESSED;
 369         switch (keybuf[0]) {
 370                 case DVB_USB_RC_NEC_EMPTY:
 371                         break;
 372                 case DVB_USB_RC_NEC_KEY_PRESSED:
 373                         if ((u8) ~keybuf[1] != keybuf[2] ||
 374                                 (u8) ~keybuf[3] != keybuf[4]) {
 375                                 deb_err("remote control checksum failed.\n");
 376                                 break;
 377                         }
 378                         /* See if we can match the raw key code. */
 379                         for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
 380                                 if (rc5_custom(&keymap[i]) == keybuf[1] &&
 381                                         rc5_data(&keymap[i]) == keybuf[3]) {
 382                                         *event = keymap[i].keycode;
 383                                         *state = REMOTE_KEY_PRESSED;
 384                                         return 0;
 385                                 }
 386                         deb_err("key mapping failed - no appropriate key found in keymapping\n");
 387                         break;
 388                 case DVB_USB_RC_NEC_KEY_REPEATED:
 389                         *state = REMOTE_KEY_REPEAT;
 390                         break;
 391                 default:
 392                         deb_err("unknown type of remote status: %d\n",keybuf[0]);
 393                         break;
 394         }
 395         return 0;
 396 }
 397 EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);

/* [<][>][^][v][top][bottom][index][help] */