[media] dvb_usb_v2: remote controller
[deliverable/linux.git] / drivers / media / dvb / dvb-usb / dvb_usb_remote.c
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
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 {
19 struct dvb_usb_device *d =
20 container_of(work, struct dvb_usb_device, rc_query_work.work);
21 int err;
22
23 /* TODO: need a lock here. We can simply skip checking for the remote
24 control if we're busy. */
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 */
29 if (dvb_usb_disable_rc_polling || d->props.rc.bulk_mode)
30 return;
31
32 err = d->props.rc.rc_query(d);
33 if (err)
34 err("error %d while querying for an remote control event.",
35 err);
36
37 schedule_delayed_work(&d->rc_query_work,
38 msecs_to_jiffies(d->props.rc.rc_interval));
39 }
40
41 static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
42 {
43 int err, rc_interval;
44 struct rc_dev *dev;
45
46 dev = rc_allocate_device();
47 if (!dev)
48 return -ENOMEM;
49
50 dev->driver_name = d->props.rc.module_name;
51 dev->map_name = d->rc_map;
52 dev->change_protocol = d->props.rc.change_protocol;
53 dev->allowed_protos = d->props.rc.allowed_protos;
54 dev->driver_type = d->props.rc.driver_type;
55 usb_to_input_id(d->udev, &dev->input_id);
56 dev->input_name = "IR-receiver inside an USB DVB receiver";
57 dev->input_phys = d->rc_phys;
58 dev->dev.parent = &d->udev->dev;
59 dev->priv = d;
60
61 /* leave remote controller enabled even there is no default map */
62 if (dev->map_name == NULL)
63 dev->map_name = RC_MAP_EMPTY;
64
65 err = rc_register_device(dev);
66 if (err < 0) {
67 rc_free_device(dev);
68 return err;
69 }
70
71 d->input_dev = NULL;
72 d->rc_dev = dev;
73
74 if (!d->props.rc.rc_query || d->props.rc.bulk_mode)
75 return 0;
76
77 /* Polling mode - initialize a work queue for handling it */
78 INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
79
80 rc_interval = d->props.rc.rc_interval;
81
82 info("schedule remote query interval to %d msecs.", rc_interval);
83 schedule_delayed_work(&d->rc_query_work,
84 msecs_to_jiffies(rc_interval));
85
86 return 0;
87 }
88
89 int dvb_usb_remote_init(struct dvb_usb_device *d)
90 {
91 int err;
92
93 if (dvb_usb_disable_rc_polling)
94 return 0;
95
96 if (d->props.rc.module_name == NULL)
97 return 0;
98
99 usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
100 strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
101
102 /* Start the remote-control polling. */
103 err = rc_core_dvb_usb_remote_init(d);
104 if (err)
105 return err;
106
107 d->state |= DVB_USB_STATE_REMOTE;
108
109 return 0;
110 }
111
112 int dvb_usb_remote_exit(struct dvb_usb_device *d)
113 {
114 if (d->state & DVB_USB_STATE_REMOTE) {
115 cancel_delayed_work_sync(&d->rc_query_work);
116 rc_unregister_device(d->rc_dev);
117 }
118 d->state &= ~DVB_USB_STATE_REMOTE;
119 return 0;
120 }
This page took 0.036841 seconds and 6 git commands to generate.