dvb_usb_remote.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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
  7. * handling remote-control-queries.
  8. */
  9. #include "dvb_usb_common.h"
  10. #include <linux/usb/input.h>
  11. /* Remote-control poll function - called every dib->rc_query_interval ms to see
  12. * whether the remote control has received anything.
  13. *
  14. * TODO: Fix the repeat rate of the input device.
  15. */
  16. static void dvb_usb_read_remote_control(struct work_struct *work)
  17. {
  18. struct dvb_usb_device *d = container_of(work,
  19. struct dvb_usb_device, rc_query_work.work);
  20. int ret;
  21. /* TODO: need a lock here. We can simply skip checking for the remote
  22. control if we're busy. */
  23. /* when the parameter has been set to 1 via sysfs while the
  24. * driver was running, or when bulk mode is enabled after IR init
  25. */
  26. if (dvb_usbv2_disable_rc_polling || d->rc.bulk_mode)
  27. return;
  28. ret = d->rc.query(d);
  29. if (ret < 0)
  30. pr_err("%s: error %d while querying for an remote control " \
  31. "event\n", KBUILD_MODNAME, ret);
  32. schedule_delayed_work(&d->rc_query_work,
  33. msecs_to_jiffies(d->rc.interval));
  34. }
  35. int dvb_usbv2_remote_init(struct dvb_usb_device *d)
  36. {
  37. int ret;
  38. struct rc_dev *dev;
  39. if (dvb_usbv2_disable_rc_polling || !d->props->get_rc_config)
  40. return 0;
  41. ret = d->props->get_rc_config(d, &d->rc);
  42. if (ret < 0)
  43. goto err;
  44. dev = rc_allocate_device();
  45. if (!dev) {
  46. ret = -ENOMEM;
  47. goto err;
  48. }
  49. dev->dev.parent = &d->udev->dev;
  50. dev->input_name = "IR-receiver inside an USB DVB receiver";
  51. usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
  52. strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
  53. dev->input_phys = d->rc_phys;
  54. usb_to_input_id(d->udev, &dev->input_id);
  55. /* TODO: likely RC-core should took const char * */
  56. dev->driver_name = (char *) d->props->driver_name;
  57. dev->driver_type = d->rc.driver_type;
  58. dev->allowed_protos = d->rc.allowed_protos;
  59. dev->change_protocol = d->rc.change_protocol;
  60. dev->priv = d;
  61. /* select used keymap */
  62. if (d->rc.map_name)
  63. dev->map_name = d->rc.map_name;
  64. else if (d->rc_map)
  65. dev->map_name = d->rc_map;
  66. else
  67. dev->map_name = RC_MAP_EMPTY; /* keep rc enabled */
  68. ret = rc_register_device(dev);
  69. if (ret < 0) {
  70. rc_free_device(dev);
  71. goto err;
  72. }
  73. d->input_dev = NULL;
  74. d->rc_dev = dev;
  75. /* start polling if needed */
  76. if (d->rc.query && !d->rc.bulk_mode) {
  77. /* initialize a work queue for handling polling */
  78. INIT_DELAYED_WORK(&d->rc_query_work,
  79. dvb_usb_read_remote_control);
  80. pr_info("%s: schedule remote query interval to %d msecs\n",
  81. KBUILD_MODNAME, d->rc.interval);
  82. schedule_delayed_work(&d->rc_query_work,
  83. msecs_to_jiffies(d->rc.interval));
  84. }
  85. d->state |= DVB_USB_STATE_REMOTE;
  86. return 0;
  87. err:
  88. pr_debug("%s: failed=%d\n", __func__, ret);
  89. return ret;
  90. }
  91. int dvb_usbv2_remote_exit(struct dvb_usb_device *d)
  92. {
  93. if (d->state & DVB_USB_STATE_REMOTE) {
  94. cancel_delayed_work_sync(&d->rc_query_work);
  95. rc_unregister_device(d->rc_dev);
  96. }
  97. d->state &= ~DVB_USB_STATE_REMOTE;
  98. return 0;
  99. }