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