edde87c6aa3a406381b3f88a31731beeea7b4b85
[linux-2.6.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 handling remote-control-queries.
7  */
8 #include "dvb-usb-common.h"
9 #include <linux/usb/input.h>
10
11 static int dvb_usb_getkeycode(struct input_dev *dev,
12                                     int scancode, int *keycode)
13 {
14         struct dvb_usb_device *d = input_get_drvdata(dev);
15
16         struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
17         int i;
18
19         /* See if we can match the raw key code. */
20         for (i = 0; i < d->props.rc_key_map_size; i++)
21                 if (keymap[i].scan == scancode) {
22                         *keycode = keymap[i].event;
23                         return 0;
24                 }
25
26         /*
27          * If is there extra space, returns KEY_RESERVED,
28          * otherwise, input core won't let dvb_usb_setkeycode
29          * to work
30          */
31         for (i = 0; i < d->props.rc_key_map_size; i++)
32                 if (keymap[i].event == KEY_RESERVED ||
33                     keymap[i].event == KEY_UNKNOWN) {
34                         *keycode = KEY_RESERVED;
35                         return 0;
36                 }
37
38         return -EINVAL;
39 }
40
41 static int dvb_usb_setkeycode(struct input_dev *dev,
42                                     int scancode, int keycode)
43 {
44         struct dvb_usb_device *d = input_get_drvdata(dev);
45
46         struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
47         int i;
48
49         /* Search if it is replacing an existing keycode */
50         for (i = 0; i < d->props.rc_key_map_size; i++)
51                 if (keymap[i].scan == scancode) {
52                         keymap[i].event = keycode;
53                         return 0;
54                 }
55
56         /* Search if is there a clean entry. If so, use it */
57         for (i = 0; i < d->props.rc_key_map_size; i++)
58                 if (keymap[i].event == KEY_RESERVED ||
59                     keymap[i].event == KEY_UNKNOWN) {
60                         keymap[i].scan = scancode;
61                         keymap[i].event = keycode;
62                         return 0;
63                 }
64
65         /*
66          * FIXME: Currently, it is not possible to increase the size of
67          * scancode table. For it to happen, one possibility
68          * would be to allocate a table with key_map_size + 1,
69          * copying data, appending the new key on it, and freeing
70          * the old one - or maybe just allocating some spare space
71          */
72
73         return -EINVAL;
74 }
75
76 /* Remote-control poll function - called every dib->rc_query_interval ms to see
77  * whether the remote control has received anything.
78  *
79  * TODO: Fix the repeat rate of the input device.
80  */
81 static void dvb_usb_read_remote_control(struct work_struct *work)
82 {
83         struct dvb_usb_device *d =
84                 container_of(work, struct dvb_usb_device, rc_query_work.work);
85         u32 event;
86         int state;
87
88         /* TODO: need a lock here.  We can simply skip checking for the remote control
89            if we're busy. */
90
91         /* when the parameter has been set to 1 via sysfs while the driver was running */
92         if (dvb_usb_disable_rc_polling)
93                 return;
94
95         if (d->props.rc_query(d,&event,&state)) {
96                 err("error while querying for an remote control event.");
97                 goto schedule;
98         }
99
100
101         switch (state) {
102                 case REMOTE_NO_KEY_PRESSED:
103                         break;
104                 case REMOTE_KEY_PRESSED:
105                         deb_rc("key pressed\n");
106                         d->last_event = event;
107                 case REMOTE_KEY_REPEAT:
108                         deb_rc("key repeated\n");
109                         input_event(d->rc_input_dev, EV_KEY, event, 1);
110                         input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
111                         input_sync(d->rc_input_dev);
112                         break;
113                 default:
114                         break;
115         }
116
117 /* improved repeat handling ???
118         switch (state) {
119                 case REMOTE_NO_KEY_PRESSED:
120                         deb_rc("NO KEY PRESSED\n");
121                         if (d->last_state != REMOTE_NO_KEY_PRESSED) {
122                                 deb_rc("releasing event %d\n",d->last_event);
123                                 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
124                                 input_sync(d->rc_input_dev);
125                         }
126                         d->last_state = REMOTE_NO_KEY_PRESSED;
127                         d->last_event = 0;
128                         break;
129                 case REMOTE_KEY_PRESSED:
130                         deb_rc("KEY PRESSED\n");
131                         deb_rc("pressing event %d\n",event);
132
133                         input_event(d->rc_input_dev, EV_KEY, event, 1);
134                         input_sync(d->rc_input_dev);
135
136                         d->last_event = event;
137                         d->last_state = REMOTE_KEY_PRESSED;
138                         break;
139                 case REMOTE_KEY_REPEAT:
140                         deb_rc("KEY_REPEAT\n");
141                         if (d->last_state != REMOTE_NO_KEY_PRESSED) {
142                                 deb_rc("repeating event %d\n",d->last_event);
143                                 input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
144                                 input_sync(d->rc_input_dev);
145                                 d->last_state = REMOTE_KEY_REPEAT;
146                         }
147                 default:
148                         break;
149         }
150 */
151
152 schedule:
153         schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
154 }
155
156 int dvb_usb_remote_init(struct dvb_usb_device *d)
157 {
158         struct input_dev *input_dev;
159         int i;
160         int err;
161
162         if (d->props.rc_key_map == NULL ||
163                 d->props.rc_query == NULL ||
164                 dvb_usb_disable_rc_polling)
165                 return 0;
166
167         usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
168         strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
169
170         input_dev = input_allocate_device();
171         if (!input_dev)
172                 return -ENOMEM;
173
174         input_dev->evbit[0] = BIT_MASK(EV_KEY);
175         input_dev->name = "IR-receiver inside an USB DVB receiver";
176         input_dev->phys = d->rc_phys;
177         usb_to_input_id(d->udev, &input_dev->id);
178         input_dev->dev.parent = &d->udev->dev;
179         input_dev->getkeycode = dvb_usb_getkeycode;
180         input_dev->setkeycode = dvb_usb_setkeycode;
181
182         /* set the bits for the keys */
183         deb_rc("key map size: %d\n", d->props.rc_key_map_size);
184         for (i = 0; i < d->props.rc_key_map_size; i++) {
185                 deb_rc("setting bit for event %d item %d\n",
186                         d->props.rc_key_map[i].event, i);
187                 set_bit(d->props.rc_key_map[i].event, input_dev->keybit);
188         }
189
190         /* Start the remote-control polling. */
191         if (d->props.rc_interval < 40)
192                 d->props.rc_interval = 100; /* default */
193
194         /* setting these two values to non-zero, we have to manage key repeats */
195         input_dev->rep[REP_PERIOD] = d->props.rc_interval;
196         input_dev->rep[REP_DELAY]  = d->props.rc_interval + 150;
197
198         input_set_drvdata(input_dev, d);
199
200         err = input_register_device(input_dev);
201         if (err) {
202                 input_free_device(input_dev);
203                 return err;
204         }
205
206         d->rc_input_dev = input_dev;
207
208         INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
209
210         info("schedule remote query interval to %d msecs.", d->props.rc_interval);
211         schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
212
213         d->state |= DVB_USB_STATE_REMOTE;
214
215         return 0;
216 }
217
218 int dvb_usb_remote_exit(struct dvb_usb_device *d)
219 {
220         if (d->state & DVB_USB_STATE_REMOTE) {
221                 cancel_rearming_delayed_work(&d->rc_query_work);
222                 flush_scheduled_work();
223                 input_unregister_device(d->rc_input_dev);
224         }
225         d->state &= ~DVB_USB_STATE_REMOTE;
226         return 0;
227 }
228
229 #define DVB_USB_RC_NEC_EMPTY           0x00
230 #define DVB_USB_RC_NEC_KEY_PRESSED     0x01
231 #define DVB_USB_RC_NEC_KEY_REPEATED    0x02
232 int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
233                 u8 keybuf[5], u32 *event, int *state)
234 {
235         int i;
236         struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
237         *event = 0;
238         *state = REMOTE_NO_KEY_PRESSED;
239         switch (keybuf[0]) {
240                 case DVB_USB_RC_NEC_EMPTY:
241                         break;
242                 case DVB_USB_RC_NEC_KEY_PRESSED:
243                         if ((u8) ~keybuf[1] != keybuf[2] ||
244                                 (u8) ~keybuf[3] != keybuf[4]) {
245                                 deb_err("remote control checksum failed.\n");
246                                 break;
247                         }
248                         /* See if we can match the raw key code. */
249                         for (i = 0; i < d->props.rc_key_map_size; i++)
250                                 if (rc5_custom(&keymap[i]) == keybuf[1] &&
251                                         rc5_data(&keymap[i]) == keybuf[3]) {
252                                         *event = keymap[i].event;
253                                         *state = REMOTE_KEY_PRESSED;
254                                         return 0;
255                                 }
256                         deb_err("key mapping failed - no appropriate key found in keymapping\n");
257                         break;
258                 case DVB_USB_RC_NEC_KEY_REPEATED:
259                         *state = REMOTE_KEY_REPEAT;
260                         break;
261                 default:
262                         deb_err("unkown type of remote status: %d\n",keybuf[0]);
263                         break;
264         }
265         return 0;
266 }
267 EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);