vserver 2.0 rc7
[linux-2.6.git] / drivers / media / dvb / dibusb / dvb-dibusb-remote.c
1 /*
2  * dvb-dibusb-remote.c is part of the driver for mobile USB Budget DVB-T devices
3  * based on reference design made by DiBcom (http://www.dibcom.fr/)
4  *
5  * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6  *
7  * see dvb-dibusb-core.c for more copyright details.
8  *
9  * This file contains functions for handling the event device on the software
10  * side and the remote control on the hardware side.
11  */
12 #include "dvb-dibusb.h"
13
14 /* Table to map raw key codes to key events.  This should not be hard-wired
15    into the kernel.  */
16 static const struct { u8 c0, c1, c2; uint32_t key; } nec_rc_keys [] =
17 {
18         /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
19         { 0x00, 0xff, 0x16, KEY_POWER },
20         { 0x00, 0xff, 0x10, KEY_MUTE },
21         { 0x00, 0xff, 0x03, KEY_1 },
22         { 0x00, 0xff, 0x01, KEY_2 },
23         { 0x00, 0xff, 0x06, KEY_3 },
24         { 0x00, 0xff, 0x09, KEY_4 },
25         { 0x00, 0xff, 0x1d, KEY_5 },
26         { 0x00, 0xff, 0x1f, KEY_6 },
27         { 0x00, 0xff, 0x0d, KEY_7 },
28         { 0x00, 0xff, 0x19, KEY_8 },
29         { 0x00, 0xff, 0x1b, KEY_9 },
30         { 0x00, 0xff, 0x15, KEY_0 },
31         { 0x00, 0xff, 0x05, KEY_CHANNELUP },
32         { 0x00, 0xff, 0x02, KEY_CHANNELDOWN },
33         { 0x00, 0xff, 0x1e, KEY_VOLUMEUP },
34         { 0x00, 0xff, 0x0a, KEY_VOLUMEDOWN },
35         { 0x00, 0xff, 0x11, KEY_RECORD },
36         { 0x00, 0xff, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
37         { 0x00, 0xff, 0x14, KEY_PLAY },
38         { 0x00, 0xff, 0x1a, KEY_STOP },
39         { 0x00, 0xff, 0x40, KEY_REWIND },
40         { 0x00, 0xff, 0x12, KEY_FASTFORWARD },
41         { 0x00, 0xff, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
42         { 0x00, 0xff, 0x4c, KEY_PAUSE },
43         { 0x00, 0xff, 0x4d, KEY_SCREEN }, /* Full screen mode. */
44         { 0x00, 0xff, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
45         /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
46         { 0x00, 0xff, 0x0c, KEY_CANCEL }, /* Cancel */
47         { 0x00, 0xff, 0x1c, KEY_EPG }, /* EPG */
48         { 0x00, 0xff, 0x00, KEY_TAB }, /* Tab */
49         { 0x00, 0xff, 0x48, KEY_INFO }, /* Preview */
50         { 0x00, 0xff, 0x04, KEY_LIST }, /* RecordList */
51         { 0x00, 0xff, 0x0f, KEY_TEXT }, /* Teletext */
52         /* Key codes for the KWorld/ADSTech/JetWay remote. */
53         { 0x86, 0x6b, 0x12, KEY_POWER },
54         { 0x86, 0x6b, 0x0f, KEY_SELECT }, /* source */
55         { 0x86, 0x6b, 0x0c, KEY_UNKNOWN }, /* scan */
56         { 0x86, 0x6b, 0x0b, KEY_EPG },
57         { 0x86, 0x6b, 0x10, KEY_MUTE },
58         { 0x86, 0x6b, 0x01, KEY_1 },
59         { 0x86, 0x6b, 0x02, KEY_2 },
60         { 0x86, 0x6b, 0x03, KEY_3 },
61         { 0x86, 0x6b, 0x04, KEY_4 },
62         { 0x86, 0x6b, 0x05, KEY_5 },
63         { 0x86, 0x6b, 0x06, KEY_6 },
64         { 0x86, 0x6b, 0x07, KEY_7 },
65         { 0x86, 0x6b, 0x08, KEY_8 },
66         { 0x86, 0x6b, 0x09, KEY_9 },
67         { 0x86, 0x6b, 0x0a, KEY_0 },
68         { 0x86, 0x6b, 0x18, KEY_ZOOM },
69         { 0x86, 0x6b, 0x1c, KEY_UNKNOWN }, /* preview */
70         { 0x86, 0x6b, 0x13, KEY_UNKNOWN }, /* snap */
71         { 0x86, 0x6b, 0x00, KEY_UNDO },
72         { 0x86, 0x6b, 0x1d, KEY_RECORD },
73         { 0x86, 0x6b, 0x0d, KEY_STOP },
74         { 0x86, 0x6b, 0x0e, KEY_PAUSE },
75         { 0x86, 0x6b, 0x16, KEY_PLAY },
76         { 0x86, 0x6b, 0x11, KEY_BACK },
77         { 0x86, 0x6b, 0x19, KEY_FORWARD },
78         { 0x86, 0x6b, 0x14, KEY_UNKNOWN }, /* pip */
79         { 0x86, 0x6b, 0x15, KEY_ESC },
80         { 0x86, 0x6b, 0x1a, KEY_UP },
81         { 0x86, 0x6b, 0x1e, KEY_DOWN },
82         { 0x86, 0x6b, 0x1f, KEY_LEFT },
83         { 0x86, 0x6b, 0x1b, KEY_RIGHT },
84 };
85
86 /* Hauppauge NOVA-T USB2 keys */
87 static const struct { u16 raw; uint32_t key; } haupp_rc_keys [] = {
88         { 0xddf, KEY_GOTO },
89         { 0xdef, KEY_POWER },
90         { 0xce7, KEY_TV },
91         { 0xcc7, KEY_VIDEO },
92         { 0xccf, KEY_AUDIO },
93         { 0xcd7, KEY_MEDIA },
94         { 0xcdf, KEY_EPG },
95         { 0xca7, KEY_UP },
96         { 0xc67, KEY_RADIO },
97         { 0xcb7, KEY_LEFT },
98         { 0xd2f, KEY_OK },
99         { 0xcbf, KEY_RIGHT },
100         { 0xcff, KEY_BACK },
101         { 0xcaf, KEY_DOWN },
102         { 0xc6f, KEY_MENU },
103         { 0xc87, KEY_VOLUMEUP },
104         { 0xc8f, KEY_VOLUMEDOWN },
105         { 0xc97, KEY_CHANNEL },
106         { 0xc7f, KEY_MUTE },
107         { 0xd07, KEY_CHANNELUP },
108         { 0xd0f, KEY_CHANNELDOWN },
109         { 0xdbf, KEY_RECORD },
110         { 0xdb7, KEY_STOP },
111         { 0xd97, KEY_REWIND },
112         { 0xdaf, KEY_PLAY },
113         { 0xda7, KEY_FASTFORWARD },
114         { 0xd27, KEY_LAST }, /* Skip backwards */
115         { 0xd87, KEY_PAUSE },
116         { 0xcf7, KEY_NEXT },
117         { 0xc07, KEY_0 },
118         { 0xc0f, KEY_1 },
119         { 0xc17, KEY_2 },
120         { 0xc1f, KEY_3 },
121         { 0xc27, KEY_4 },
122         { 0xc2f, KEY_5 },
123         { 0xc37, KEY_6 },
124         { 0xc3f, KEY_7 },
125         { 0xc47, KEY_8 },
126         { 0xc4f, KEY_9 },
127         { 0xc57, KEY_KPASTERISK },
128         { 0xc77, KEY_GRAVE }, /* # */
129         { 0xc5f, KEY_RED },
130         { 0xd77, KEY_GREEN },
131         { 0xdc7, KEY_YELLOW },
132         { 0xd4f, KEY_BLUE},
133 };
134
135 static int dibusb_key2event_nec(struct usb_dibusb *dib,u8 rb[5])
136 {
137         int i;
138         switch (rb[0]) {
139                 case DIBUSB_RC_NEC_KEY_PRESSED:
140                         /* rb[1-3] is the actual key, rb[4] is a checksum */
141                         deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
142                                 rb[1], rb[2], rb[3], rb[4]);
143
144                         if ((0xff - rb[3]) != rb[4]) {
145                                 deb_rc("remote control checksum failed.\n");
146                                 break;
147                         }
148
149                         /* See if we can match the raw key code. */
150                         for (i = 0; i < sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++) {
151                                 if (nec_rc_keys[i].c0 == rb[1] &&
152                                         nec_rc_keys[i].c1 == rb[2] &&
153                                         nec_rc_keys[i].c2 == rb[3]) {
154
155                                         dib->last_event = nec_rc_keys[i].key;
156                                         return 1;
157                                 }
158                         }
159                         break;
160                 case DIBUSB_RC_NEC_KEY_REPEATED:
161                         /* rb[1]..rb[4] are always zero.*/
162                         /* Repeats often seem to occur so for the moment just ignore this. */
163                         return 0;
164                 case DIBUSB_RC_NEC_EMPTY: /* No (more) remote control keys. */
165                 default:
166                         break;
167         }
168         return -1;
169 }
170
171 static int dibusb_key2event_hauppauge(struct usb_dibusb *dib,u8 rb[4])
172 {
173         u16 raw;
174         int i,state;
175         switch (rb[0]) {
176                 case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
177                         raw = ((rb[1] & 0x0f) << 8) | rb[2];
178
179                         state = !!(rb[1] & 0x40);
180
181                         deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to %04x state: %d\n",rb[1],rb[2],rb[3],raw,state);
182                         for (i = 0; i < sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++) {
183                                 if (haupp_rc_keys[i].raw == raw) {
184                                         if (dib->last_event == haupp_rc_keys[i].key &&
185                                                 dib->last_state == state) {
186                                                 deb_rc("key repeat\n");
187                                                 return 0;
188                                         } else {
189                                                 dib->last_event = haupp_rc_keys[i].key;
190                                                 dib->last_state = state;
191                                                 return 1;
192                                         }
193                                 }
194                         }
195
196                         break;
197                 case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
198                 default:
199                         break;
200         }
201         return -1;
202 }
203
204 /*
205  * Read the remote control and feed the appropriate event.
206  * NEC protocol is used for remote controls
207  */
208 static int dibusb_read_remote_control(struct usb_dibusb *dib)
209 {
210         u8 b[1] = { DIBUSB_REQ_POLL_REMOTE }, rb[5];
211         int ret,event = 0;
212
213         if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5)))
214                 return ret;
215
216         switch (dib->dibdev->dev_cl->remote_type) {
217                 case DIBUSB_RC_NEC_PROTOCOL:
218                         event = dibusb_key2event_nec(dib,rb);
219                         break;
220                 case DIBUSB_RC_HAUPPAUGE_PROTO:
221                         event = dibusb_key2event_hauppauge(dib,rb);
222                 default:
223                         break;
224         }
225
226         /* key repeat */
227         if (event == 0)
228                 if (++dib->repeat_key_count < dib->rc_key_repeat_count) {
229                         deb_rc("key repeat dropped. (%d)\n",dib->repeat_key_count);
230                         event = -1; /* skip this key repeat */
231                 }
232
233         if (event == 1 || event == 0) {
234                 deb_rc("Translated key 0x%04x\n",event);
235
236                 /* Signal down and up events for this key. */
237                 input_report_key(&dib->rc_input_dev, dib->last_event, 1);
238                 input_report_key(&dib->rc_input_dev, dib->last_event, 0);
239                 input_sync(&dib->rc_input_dev);
240
241                 if (event == 1)
242                         dib->repeat_key_count = 0;
243         }
244         return 0;
245 }
246
247 /* Remote-control poll function - called every dib->rc_query_interval ms to see
248    whether the remote control has received anything. */
249 static void dibusb_remote_query(void *data)
250 {
251         struct usb_dibusb *dib = (struct usb_dibusb *) data;
252         /* TODO: need a lock here.  We can simply skip checking for the remote control
253            if we're busy. */
254         dibusb_read_remote_control(dib);
255         schedule_delayed_work(&dib->rc_query_work,
256                               msecs_to_jiffies(dib->rc_query_interval));
257 }
258
259 int dibusb_remote_init(struct usb_dibusb *dib)
260 {
261         int i;
262
263         if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO)
264                 return 0;
265         
266         /* Initialise the remote-control structures.*/
267         init_input_dev(&dib->rc_input_dev);
268
269         dib->rc_input_dev.evbit[0] = BIT(EV_KEY);
270         dib->rc_input_dev.keycodesize = sizeof(unsigned char);
271         dib->rc_input_dev.keycodemax = KEY_MAX;
272         dib->rc_input_dev.name = DRIVER_DESC " remote control";
273
274         switch (dib->dibdev->dev_cl->remote_type) {
275                 case DIBUSB_RC_NEC_PROTOCOL:
276                         for (i=0; i<sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++)
277                                 set_bit(nec_rc_keys[i].key, dib->rc_input_dev.keybit);
278                         break;
279                 case DIBUSB_RC_HAUPPAUGE_PROTO:
280                         for (i=0; i<sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++)
281                                 set_bit(haupp_rc_keys[i].key, dib->rc_input_dev.keybit);
282                         break;
283                 default:
284                         break;
285         }
286
287
288         input_register_device(&dib->rc_input_dev);
289
290         INIT_WORK(&dib->rc_query_work, dibusb_remote_query, dib);
291
292         /* Start the remote-control polling. */
293         if (dib->rc_query_interval < 40)
294                 dib->rc_query_interval = 100; /* default */
295
296         info("schedule remote query interval to %d msecs.",dib->rc_query_interval);
297         schedule_delayed_work(&dib->rc_query_work,msecs_to_jiffies(dib->rc_query_interval));
298
299         dib->init_state |= DIBUSB_STATE_REMOTE;
300         
301         return 0;
302 }
303
304 int dibusb_remote_exit(struct usb_dibusb *dib)
305 {
306         if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO)
307                 return 0;
308
309         if (dib->init_state & DIBUSB_STATE_REMOTE) {
310                 cancel_delayed_work(&dib->rc_query_work);
311                 flush_scheduled_work();
312                 input_unregister_device(&dib->rc_input_dev);
313         }
314         dib->init_state &= ~DIBUSB_STATE_REMOTE;
315         return 0;
316 }