linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / media / video / saa7134 / saa7134-input.c
1 /*
2  *
3  * handle saa7134 IR remotes via linux kernel input layer.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  */
20
21 #include <linux/module.h>
22 #include <linux/moduleparam.h>
23 #include <linux/init.h>
24 #include <linux/delay.h>
25 #include <linux/sched.h>
26 #include <linux/interrupt.h>
27 #include <linux/input.h>
28
29 #include "saa7134-reg.h"
30 #include "saa7134.h"
31
32 static unsigned int disable_ir = 0;
33 module_param(disable_ir, int, 0444);
34 MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
35
36 static unsigned int ir_debug = 0;
37 module_param(ir_debug, int, 0644);
38 MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
39
40 #define dprintk(fmt, arg...)    if (ir_debug) \
41         printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
42 #define i2cdprintk(fmt, arg...)    if (ir_debug) \
43         printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
44
45 /* ---------------------------------------------------------------------- */
46
47 static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = {
48         [   15 ] = KEY_KP0,
49         [    3 ] = KEY_KP1,
50         [    4 ] = KEY_KP2,
51         [    5 ] = KEY_KP3,
52         [    7 ] = KEY_KP4,
53         [    8 ] = KEY_KP5,
54         [    9 ] = KEY_KP6,
55         [   11 ] = KEY_KP7,
56         [   12 ] = KEY_KP8,
57         [   13 ] = KEY_KP9,
58
59         [   14 ] = KEY_MODE,         // Air/Cable
60         [   17 ] = KEY_VIDEO,        // Video
61         [   21 ] = KEY_AUDIO,        // Audio
62         [    0 ] = KEY_POWER,        // Power
63         [   24 ] = KEY_TUNER,        // AV Source
64         [    2 ] = KEY_ZOOM,         // Fullscreen
65         [   26 ] = KEY_LANGUAGE,     // Stereo
66         [   27 ] = KEY_MUTE,         // Mute
67         [   20 ] = KEY_VOLUMEUP,     // Volume +
68         [   23 ] = KEY_VOLUMEDOWN,   // Volume -
69         [   18 ] = KEY_CHANNELUP,    // Channel +
70         [   19 ] = KEY_CHANNELDOWN,  // Channel -
71         [    6 ] = KEY_AGAIN,        // Recall
72         [   16 ] = KEY_ENTER,      // Enter
73 };
74
75 static IR_KEYTAB_TYPE flydvb_codes[IR_KEYTAB_SIZE] = {
76         [ 0x01 ] = KEY_ZOOM,            // Full Screen
77         [ 0x00 ] = KEY_POWER,           // Power
78
79         [ 0x03 ] = KEY_1,
80         [ 0x04 ] = KEY_2,
81         [ 0x05 ] = KEY_3,
82         [ 0x07 ] = KEY_4,
83         [ 0x08 ] = KEY_5,
84         [ 0x09 ] = KEY_6,
85         [ 0x0b ] = KEY_7,
86         [ 0x0c ] = KEY_8,
87         [ 0x0d ] = KEY_9,
88         [ 0x06 ] = KEY_AGAIN,           // Recall
89         [ 0x0f ] = KEY_0,
90         [ 0x10 ] = KEY_MUTE,            // Mute
91         [ 0x02 ] = KEY_RADIO,           // TV/Radio
92         [ 0x1b ] = KEY_LANGUAGE,                // SAP (Second Audio Program)
93
94         [ 0x14 ] = KEY_VOLUMEUP,                // VOL+
95         [ 0x17 ] = KEY_VOLUMEDOWN,      // VOL-
96         [ 0x12 ] = KEY_CHANNELUP,               // CH+
97         [ 0x13 ] = KEY_CHANNELDOWN,     // CH-
98         [ 0x1d ] = KEY_ENTER,           // Enter
99
100         [ 0x1a ] = KEY_MODE,            // PIP
101         [ 0x18 ] = KEY_TUNER,           // Source
102
103         [ 0x1e ] = KEY_RECORD,          // Record/Pause
104         [ 0x15 ] = KEY_ANGLE,           // Swap (no label on key)
105         [ 0x1c ] = KEY_PAUSE,           // Timeshift/Pause
106         [ 0x19 ] = KEY_BACK,            // Rewind <<
107         [ 0x0a ] = KEY_PLAYPAUSE,               // Play/Pause
108         [ 0x1f ] = KEY_FORWARD,         // Forward >>
109         [ 0x16 ] = KEY_PREVIOUS,                // Back |<<
110         [ 0x11 ] = KEY_STOP,            // Stop
111         [ 0x0e ] = KEY_NEXT,            // End >>|
112 };
113
114 static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
115         [    0 ] = KEY_KP0,
116         [    1 ] = KEY_KP1,
117         [    2 ] = KEY_KP2,
118         [    3 ] = KEY_KP3,
119         [    4 ] = KEY_KP4,
120         [    5 ] = KEY_KP5,
121         [    6 ] = KEY_KP6,
122         [    7 ] = KEY_KP7,
123         [    8 ] = KEY_KP8,
124         [    9 ] = KEY_KP9,
125
126         [ 0x0a ] = KEY_POWER,
127         [ 0x0b ] = KEY_PROG1,           // app
128         [ 0x0c ] = KEY_ZOOM,            // zoom/fullscreen
129         [ 0x0d ] = KEY_CHANNELUP,       // channel
130         [ 0x0e ] = KEY_CHANNELDOWN,     // channel-
131         [ 0x0f ] = KEY_VOLUMEUP,
132         [ 0x10 ] = KEY_VOLUMEDOWN,
133         [ 0x11 ] = KEY_TUNER,           // AV
134         [ 0x12 ] = KEY_NUMLOCK,         // -/--
135         [ 0x13 ] = KEY_AUDIO,           // audio
136         [ 0x14 ] = KEY_MUTE,
137         [ 0x15 ] = KEY_UP,
138         [ 0x16 ] = KEY_DOWN,
139         [ 0x17 ] = KEY_LEFT,
140         [ 0x18 ] = KEY_RIGHT,
141         [ 0x19 ] = BTN_LEFT,
142         [ 0x1a ] = BTN_RIGHT,
143         [ 0x1b ] = KEY_WWW,             // text
144         [ 0x1c ] = KEY_REWIND,
145         [ 0x1d ] = KEY_FORWARD,
146         [ 0x1e ] = KEY_RECORD,
147         [ 0x1f ] = KEY_PLAY,
148         [ 0x20 ] = KEY_PREVIOUSSONG,
149         [ 0x21 ] = KEY_NEXTSONG,
150         [ 0x22 ] = KEY_PAUSE,
151         [ 0x23 ] = KEY_STOP,
152 };
153
154 /* Alfons Geser <a.geser@cox.net>
155  * updates from Job D. R. Borges <jobdrb@ig.com.br> */
156 static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
157         [ 18 ] = KEY_POWER,
158         [  1 ] = KEY_TV,             // DVR
159         [ 21 ] = KEY_DVD,            // DVD
160         [ 23 ] = KEY_AUDIO,          // music
161                                      // DVR mode / DVD mode / music mode
162
163         [ 27 ] = KEY_MUTE,           // mute
164         [  2 ] = KEY_LANGUAGE,       // MTS/SAP / audio / autoseek
165         [ 30 ] = KEY_SUBTITLE,       // closed captioning / subtitle / seek
166         [ 22 ] = KEY_ZOOM,           // full screen
167         [ 28 ] = KEY_VIDEO,          // video source / eject / delall
168         [ 29 ] = KEY_RESTART,        // playback / angle / del
169         [ 47 ] = KEY_SEARCH,         // scan / menu / playlist
170         [ 48 ] = KEY_CHANNEL,        // CH surfing / bookmark / memo
171
172         [ 49 ] = KEY_HELP,           // help
173         [ 50 ] = KEY_MODE,           // num/memo
174         [ 51 ] = KEY_ESC,            // cancel
175
176         [ 12 ] = KEY_UP,             // up
177         [ 16 ] = KEY_DOWN,           // down
178         [  8 ] = KEY_LEFT,           // left
179         [  4 ] = KEY_RIGHT,          // right
180         [  3 ] = KEY_SELECT,         // select
181
182         [ 31 ] = KEY_REWIND,         // rewind
183         [ 32 ] = KEY_PLAYPAUSE,      // play/pause
184         [ 41 ] = KEY_FORWARD,        // forward
185         [ 20 ] = KEY_AGAIN,          // repeat
186         [ 43 ] = KEY_RECORD,         // recording
187         [ 44 ] = KEY_STOP,           // stop
188         [ 45 ] = KEY_PLAY,           // play
189         [ 46 ] = KEY_SHUFFLE,        // snapshot / shuffle
190
191         [  0 ] = KEY_KP0,
192         [  5 ] = KEY_KP1,
193         [  6 ] = KEY_KP2,
194         [  7 ] = KEY_KP3,
195         [  9 ] = KEY_KP4,
196         [ 10 ] = KEY_KP5,
197         [ 11 ] = KEY_KP6,
198         [ 13 ] = KEY_KP7,
199         [ 14 ] = KEY_KP8,
200         [ 15 ] = KEY_KP9,
201
202         [ 42 ] = KEY_VOLUMEUP,
203         [ 17 ] = KEY_VOLUMEDOWN,
204         [ 24 ] = KEY_CHANNELUP,      // CH.tracking up
205         [ 25 ] = KEY_CHANNELDOWN,    // CH.tracking down
206
207         [ 19 ] = KEY_KPENTER,        // enter
208         [ 33 ] = KEY_KPDOT,          // . (decimal dot)
209 };
210
211 static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
212         [ 30 ] = KEY_POWER,             // power
213         [ 28 ] = KEY_SEARCH,            // scan
214         [  7 ] = KEY_SELECT,            // source
215
216         [ 22 ] = KEY_VOLUMEUP,
217         [ 20 ] = KEY_VOLUMEDOWN,
218         [ 31 ] = KEY_CHANNELUP,
219         [ 23 ] = KEY_CHANNELDOWN,
220         [ 24 ] = KEY_MUTE,
221
222         [  2 ] = KEY_KP0,
223         [  1 ] = KEY_KP1,
224         [ 11 ] = KEY_KP2,
225         [ 27 ] = KEY_KP3,
226         [  5 ] = KEY_KP4,
227         [  9 ] = KEY_KP5,
228         [ 21 ] = KEY_KP6,
229         [  6 ] = KEY_KP7,
230         [ 10 ] = KEY_KP8,
231         [ 18 ] = KEY_KP9,
232         [ 16 ] = KEY_KPDOT,
233
234         [  3 ] = KEY_TUNER,             // tv/fm
235         [  4 ] = KEY_REWIND,            // fm tuning left or function left
236         [ 12 ] = KEY_FORWARD,           // fm tuning right or function right
237
238         [  0 ] = KEY_RECORD,
239         [  8 ] = KEY_STOP,
240         [ 17 ] = KEY_PLAY,
241
242         [ 25 ] = KEY_ZOOM,
243         [ 14 ] = KEY_MENU,              // function
244         [ 19 ] = KEY_AGAIN,             // recall
245         [ 29 ] = KEY_RESTART,           // reset
246         [ 26 ] = KEY_SHUFFLE,           // snapshot/shuffle
247
248 // FIXME
249         [ 13 ] = KEY_F21,               // mts
250         [ 15 ] = KEY_F22,               // min
251 };
252
253 /* Alex Hermann <gaaf@gmx.net> */
254 static IR_KEYTAB_TYPE md2819_codes[IR_KEYTAB_SIZE] = {
255         [ 40 ] = KEY_KP1,
256         [ 24 ] = KEY_KP2,
257         [ 56 ] = KEY_KP3,
258         [ 36 ] = KEY_KP4,
259         [ 20 ] = KEY_KP5,
260         [ 52 ] = KEY_KP6,
261         [ 44 ] = KEY_KP7,
262         [ 28 ] = KEY_KP8,
263         [ 60 ] = KEY_KP9,
264         [ 34 ] = KEY_KP0,
265
266         [ 32 ] = KEY_TV,                // TV/FM
267         [ 16 ] = KEY_CD,                // CD
268         [ 48 ] = KEY_TEXT,              // TELETEXT
269         [  0 ] = KEY_POWER,             // POWER
270
271         [  8 ] = KEY_VIDEO,             // VIDEO
272         [  4 ] = KEY_AUDIO,             // AUDIO
273         [ 12 ] = KEY_ZOOM,              // FULL SCREEN
274
275         [ 18 ] = KEY_SUBTITLE,          // DISPLAY      - ???
276         [ 50 ] = KEY_REWIND,            // LOOP         - ???
277         [  2 ] = KEY_PRINT,             // PREVIEW      - ???
278
279         [ 42 ] = KEY_SEARCH,            // AUTOSCAN
280         [ 26 ] = KEY_SLEEP,             // FREEZE       - ???
281         [ 58 ] = KEY_SHUFFLE,           // SNAPSHOT     - ???
282         [ 10 ] = KEY_MUTE,              // MUTE
283
284         [ 38 ] = KEY_RECORD,            // RECORD
285         [ 22 ] = KEY_PAUSE,             // PAUSE
286         [ 54 ] = KEY_STOP,              // STOP
287         [  6 ] = KEY_PLAY,              // PLAY
288
289         [ 46 ] = KEY_RED,               // <RED>
290         [ 33 ] = KEY_GREEN,             // <GREEN>
291         [ 14 ] = KEY_YELLOW,            // <YELLOW>
292         [  1 ] = KEY_BLUE,              // <BLUE>
293
294         [ 30 ] = KEY_VOLUMEDOWN,        // VOLUME-
295         [ 62 ] = KEY_VOLUMEUP,          // VOLUME+
296         [ 17 ] = KEY_CHANNELDOWN,       // CHANNEL/PAGE-
297         [ 49 ] = KEY_CHANNELUP          // CHANNEL/PAGE+
298 };
299
300 static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = {
301         [ 20 ] = KEY_MUTE,
302         [ 36 ] = KEY_ZOOM,
303
304         [  1 ] = KEY_DVD,
305         [ 35 ] = KEY_RADIO,
306         [  0 ] = KEY_TV,
307
308         [ 10 ] = KEY_REWIND,
309         [  8 ] = KEY_PLAYPAUSE,
310         [ 15 ] = KEY_FORWARD,
311
312         [  2 ] = KEY_PREVIOUS,
313         [  7 ] = KEY_STOP,
314         [  6 ] = KEY_NEXT,
315
316         [ 12 ] = KEY_UP,
317         [ 14 ] = KEY_DOWN,
318         [ 11 ] = KEY_LEFT,
319         [ 13 ] = KEY_RIGHT,
320         [ 17 ] = KEY_OK,
321
322         [  3 ] = KEY_MENU,
323         [  9 ] = KEY_SETUP,
324         [  5 ] = KEY_VIDEO,
325         [ 34 ] = KEY_CHANNEL,
326
327         [ 18 ] = KEY_VOLUMEUP,
328         [ 21 ] = KEY_VOLUMEDOWN,
329         [ 16 ] = KEY_CHANNELUP,
330         [ 19 ] = KEY_CHANNELDOWN,
331
332         [  4 ] = KEY_RECORD,
333
334         [ 22 ] = KEY_KP1,
335         [ 23 ] = KEY_KP2,
336         [ 24 ] = KEY_KP3,
337         [ 25 ] = KEY_KP4,
338         [ 26 ] = KEY_KP5,
339         [ 27 ] = KEY_KP6,
340         [ 28 ] = KEY_KP7,
341         [ 29 ] = KEY_KP8,
342         [ 30 ] = KEY_KP9,
343         [ 31 ] = KEY_KP0,
344
345         [ 32 ] = KEY_LANGUAGE,
346         [ 33 ] = KEY_SLEEP,
347 };
348
349 /* Michael Tokarev <mjt@tls.msk.ru>
350    http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
351    keytable is used by MANLI MTV00[12] and BeholdTV 40[13] at
352    least, and probably other cards too.
353    The "ascii-art picture" below (in comments, first row
354    is the keycode in hex, and subsequent row(s) shows
355    the button labels (several variants when appropriate)
356    helps to descide which keycodes to assign to the buttons.
357  */
358 static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
359
360         /*  0x1c            0x12  *
361          * FUNCTION         POWER *
362          *   FM              (|)  *
363          *                        */
364         [ 0x1c ] = KEY_RADIO,   /*XXX*/
365         [ 0x12 ] = KEY_POWER,
366
367         /*  0x01    0x02    0x03  *
368          *   1       2       3    *
369          *                        *
370          *  0x04    0x05    0x06  *
371          *   4       5       6    *
372          *                        *
373          *  0x07    0x08    0x09  *
374          *   7       8       9    *
375          *                        */
376         [ 0x01 ] = KEY_KP1,
377         [ 0x02 ] = KEY_KP2,
378         [ 0x03 ] = KEY_KP3,
379         [ 0x04 ] = KEY_KP4,
380         [ 0x05 ] = KEY_KP5,
381         [ 0x06 ] = KEY_KP6,
382         [ 0x07 ] = KEY_KP7,
383         [ 0x08 ] = KEY_KP8,
384         [ 0x09 ] = KEY_KP9,
385
386         /*  0x0a    0x00    0x17  *
387          * RECALL    0      +100  *
388          *                  PLUS  *
389          *                        */
390         [ 0x0a ] = KEY_AGAIN,   /*XXX KEY_REWIND? */
391         [ 0x00 ] = KEY_KP0,
392         [ 0x17 ] = KEY_DIGITS,  /*XXX*/
393
394         /*  0x14            0x10  *
395          *  MENU            INFO  *
396          *  OSD                   */
397         [ 0x14 ] = KEY_MENU,
398         [ 0x10 ] = KEY_INFO,
399
400         /*          0x0b          *
401          *           Up           *
402          *                        *
403          *  0x18    0x16    0x0c  *
404          *  Left     Ok     Right *
405          *                        *
406          *         0x015          *
407          *         Down           *
408          *                        */
409         [ 0x0b ] = KEY_UP,      /*XXX KEY_SCROLLUP? */
410         [ 0x18 ] = KEY_LEFT,    /*XXX KEY_BACK? */
411         [ 0x16 ] = KEY_OK,      /*XXX KEY_SELECT? KEY_ENTER? */
412         [ 0x0c ] = KEY_RIGHT,   /*XXX KEY_FORWARD? */
413         [ 0x15 ] = KEY_DOWN,    /*XXX KEY_SCROLLDOWN? */
414
415         /*  0x11            0x0d  *
416          *  TV/AV           MODE  *
417          *  SOURCE         STEREO *
418          *                        */
419         [ 0x11 ] = KEY_TV,      /*XXX*/
420         [ 0x0d ] = KEY_MODE,    /*XXX there's no KEY_STEREO */
421
422         /*  0x0f    0x1b    0x1a  *
423          *  AUDIO   Vol+    Chan+ *
424          *        TIMESHIFT???    *
425          *                        *
426          *  0x0e    0x1f    0x1e  *
427          *  SLEEP   Vol-    Chan- *
428          *                        */
429         [ 0x0f ] = KEY_AUDIO,
430         [ 0x1b ] = KEY_VOLUMEUP,
431         [ 0x1a ] = KEY_CHANNELUP,
432         [ 0x0e ] = KEY_SLEEP,   /*XXX maybe KEY_PAUSE */
433         [ 0x1f ] = KEY_VOLUMEDOWN,
434         [ 0x1e ] = KEY_CHANNELDOWN,
435
436         /*         0x13     0x19  *
437          *         MUTE   SNAPSHOT*
438          *                        */
439         [ 0x13 ] = KEY_MUTE,
440         [ 0x19 ] = KEY_RECORD,  /*XXX*/
441
442         // 0x1d unused ?
443 };
444
445
446 /* Mike Baikov <mike@baikov.com> */
447 static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = {
448
449         [ 33 ] = KEY_POWER,
450         [ 105] = KEY_TV,
451         [ 51 ] = KEY_KP0,
452         [ 81 ] = KEY_KP1,
453         [ 49 ] = KEY_KP2,
454         [ 113] = KEY_KP3,
455         [ 59 ] = KEY_KP4,
456         [ 88 ] = KEY_KP5,
457         [ 65 ] = KEY_KP6,
458         [ 72 ] = KEY_KP7,
459         [ 48 ] = KEY_KP8,
460         [ 83 ] = KEY_KP9,
461         [ 115] = KEY_AGAIN, /* LOOP */
462         [ 10 ] = KEY_AUDIO,
463         [ 97 ] = KEY_PRINT, /* PREVIEW */
464         [ 122] = KEY_VIDEO,
465         [ 32 ] = KEY_CHANNELUP,
466         [ 64 ] = KEY_CHANNELDOWN,
467         [ 24 ] = KEY_VOLUMEDOWN,
468         [ 80 ] = KEY_VOLUMEUP,
469         [ 16 ] = KEY_MUTE,
470         [ 74 ] = KEY_SEARCH,
471         [ 123] = KEY_SHUFFLE, /* SNAPSHOT */
472         [ 34 ] = KEY_RECORD,
473         [ 98 ] = KEY_STOP,
474         [ 120] = KEY_PLAY,
475         [ 57 ] = KEY_REWIND,
476         [ 89 ] = KEY_PAUSE,
477         [ 25 ] = KEY_FORWARD,
478         [  9 ] = KEY_ZOOM,
479
480         [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */
481         [ 26 ] = KEY_F22, /* MIN TIMESHIFT */
482         [ 58 ] = KEY_F23, /* TIMESHIFT */
483         [ 112] = KEY_F24, /* NORMAL TIMESHIFT */
484 };
485
486 static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
487         [ 0x3  ] = KEY_POWER,
488         [ 0x6f ] = KEY_MUTE,
489         [ 0x10 ] = KEY_BACKSPACE,       /* Recall */
490
491         [ 0x11 ] = KEY_KP0,
492         [ 0x4  ] = KEY_KP1,
493         [ 0x5  ] = KEY_KP2,
494         [ 0x6  ] = KEY_KP3,
495         [ 0x8  ] = KEY_KP4,
496         [ 0x9  ] = KEY_KP5,
497         [ 0xa  ] = KEY_KP6,
498         [ 0xc  ] = KEY_KP7,
499         [ 0xd  ] = KEY_KP8,
500         [ 0xe  ] = KEY_KP9,
501         [ 0x12 ] = KEY_KPDOT,           /* 100+ */
502
503         [ 0x7  ] = KEY_VOLUMEUP,
504         [ 0xb  ] = KEY_VOLUMEDOWN,
505         [ 0x1a ] = KEY_KPPLUS,
506         [ 0x18 ] = KEY_KPMINUS,
507         [ 0x15 ] = KEY_UP,
508         [ 0x1d ] = KEY_DOWN,
509         [ 0xf  ] = KEY_CHANNELUP,
510         [ 0x13 ] = KEY_CHANNELDOWN,
511         [ 0x48 ] = KEY_ZOOM,
512
513         [ 0x1b ] = KEY_VIDEO,           /* Video source */
514         [ 0x49 ] = KEY_LANGUAGE,        /* MTS Select */
515         [ 0x19 ] = KEY_SEARCH,          /* Auto Scan */
516
517         [ 0x4b ] = KEY_RECORD,
518         [ 0x46 ] = KEY_PLAY,
519         [ 0x45 ] = KEY_PAUSE,           /* Pause */
520         [ 0x44 ] = KEY_STOP,
521         [ 0x40 ] = KEY_FORWARD,         /* Forward ? */
522         [ 0x42 ] = KEY_REWIND,          /* Backward ? */
523
524 };
525
526 /* Mapping for the 28 key remote control as seen at
527    http://www.sednacomputer.com/photo/cardbus-tv.jpg
528    Pavel Mihaylov <bin@bash.info> */
529 static IR_KEYTAB_TYPE pctv_sedna_codes[IR_KEYTAB_SIZE] = {
530         [    0 ] = KEY_KP0,
531         [    1 ] = KEY_KP1,
532         [    2 ] = KEY_KP2,
533         [    3 ] = KEY_KP3,
534         [    4 ] = KEY_KP4,
535         [    5 ] = KEY_KP5,
536         [    6 ] = KEY_KP6,
537         [    7 ] = KEY_KP7,
538         [    8 ] = KEY_KP8,
539         [    9 ] = KEY_KP9,
540
541         [ 0x0a ] = KEY_AGAIN,          /* Recall */
542         [ 0x0b ] = KEY_CHANNELUP,
543         [ 0x0c ] = KEY_VOLUMEUP,
544         [ 0x0d ] = KEY_MODE,           /* Stereo */
545         [ 0x0e ] = KEY_STOP,
546         [ 0x0f ] = KEY_PREVIOUSSONG,
547         [ 0x10 ] = KEY_ZOOM,
548         [ 0x11 ] = KEY_TUNER,          /* Source */
549         [ 0x12 ] = KEY_POWER,
550         [ 0x13 ] = KEY_MUTE,
551         [ 0x15 ] = KEY_CHANNELDOWN,
552         [ 0x18 ] = KEY_VOLUMEDOWN,
553         [ 0x19 ] = KEY_SHUFFLE,        /* Snapshot */
554         [ 0x1a ] = KEY_NEXTSONG,
555         [ 0x1b ] = KEY_TEXT,           /* Time Shift */
556         [ 0x1c ] = KEY_RADIO,          /* FM Radio */
557         [ 0x1d ] = KEY_RECORD,
558         [ 0x1e ] = KEY_PAUSE,
559 };
560
561
562 /* -------------------- GPIO generic keycode builder -------------------- */
563
564 static int build_key(struct saa7134_dev *dev)
565 {
566         struct saa7134_ir *ir = dev->remote;
567         u32 gpio, data;
568
569         /* rising SAA7134_GPIO_GPRESCAN reads the status */
570         saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
571         saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
572
573         gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
574         if (ir->polling) {
575                 if (ir->last_gpio == gpio)
576                         return 0;
577                 ir->last_gpio = gpio;
578         }
579
580         data = ir_extract_bits(gpio, ir->mask_keycode);
581         dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
582                 gpio, ir->mask_keycode, data);
583
584         if (ir->polling) {
585                 if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
586                     (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
587                         ir_input_keydown(ir->dev, &ir->ir, data, data);
588                 } else {
589                         ir_input_nokey(ir->dev, &ir->ir);
590                 }
591         }
592         else {  /* IRQ driven mode - handle key press and release in one go */
593                 if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
594                     (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
595                         ir_input_keydown(ir->dev, &ir->ir, data, data);
596                         ir_input_nokey(ir->dev, &ir->ir);
597                 }
598         }
599
600         return 0;
601 }
602
603 /* --------------------- Chip specific I2C key builders ----------------- */
604
605 static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
606 {
607         unsigned char b;
608
609         /* poll IR chip */
610         if (1 != i2c_master_recv(&ir->c,&b,1)) {
611                 i2cdprintk("read error\n");
612                 return -EIO;
613         }
614
615         /* no button press */
616         if (b==0)
617                 return 0;
618
619         /* repeating */
620         if (b & 0x80)
621                 return 1;
622
623         *ir_key = b;
624         *ir_raw = b;
625         return 1;
626 }
627
628 void saa7134_input_irq(struct saa7134_dev *dev)
629 {
630         struct saa7134_ir *ir = dev->remote;
631
632         if (!ir->polling)
633                 build_key(dev);
634 }
635
636 static void saa7134_input_timer(unsigned long data)
637 {
638         struct saa7134_dev *dev = (struct saa7134_dev*)data;
639         struct saa7134_ir *ir = dev->remote;
640         unsigned long timeout;
641
642         build_key(dev);
643         timeout = jiffies + (ir->polling * HZ / 1000);
644         mod_timer(&ir->timer, timeout);
645 }
646
647 int saa7134_input_init1(struct saa7134_dev *dev)
648 {
649         struct saa7134_ir *ir;
650         struct input_dev *input_dev;
651         IR_KEYTAB_TYPE *ir_codes = NULL;
652         u32 mask_keycode = 0;
653         u32 mask_keydown = 0;
654         u32 mask_keyup   = 0;
655         int polling      = 0;
656         int ir_type      = IR_TYPE_OTHER;
657
658         if (dev->has_remote != SAA7134_REMOTE_GPIO)
659                 return -ENODEV;
660         if (disable_ir)
661                 return -ENODEV;
662
663         /* detect & configure */
664         switch (dev->board) {
665         case SAA7134_BOARD_FLYVIDEO2000:
666         case SAA7134_BOARD_FLYVIDEO3000:
667         case SAA7134_BOARD_FLYTVPLATINUM_FM:
668         case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
669                 ir_codes     = flyvideo_codes;
670                 mask_keycode = 0xEC00000;
671                 mask_keydown = 0x0040000;
672                 break;
673         case SAA7134_BOARD_CINERGY400:
674         case SAA7134_BOARD_CINERGY600:
675         case SAA7134_BOARD_CINERGY600_MK3:
676                 ir_codes     = cinergy_codes;
677                 mask_keycode = 0x00003f;
678                 mask_keyup   = 0x040000;
679                 break;
680         case SAA7134_BOARD_ECS_TVP3XP:
681         case SAA7134_BOARD_ECS_TVP3XP_4CB5:
682                 ir_codes     = eztv_codes;
683                 mask_keycode = 0x00017c;
684                 mask_keyup   = 0x000002;
685                 polling      = 50; // ms
686                 break;
687         case SAA7134_BOARD_KWORLD_XPERT:
688         case SAA7134_BOARD_AVACSSMARTTV:
689                 ir_codes     = avacssmart_codes;
690                 mask_keycode = 0x00001F;
691                 mask_keyup   = 0x000020;
692                 polling      = 50; // ms
693                 break;
694         case SAA7134_BOARD_MD2819:
695         case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
696         case SAA7134_BOARD_AVERMEDIA_305:
697         case SAA7134_BOARD_AVERMEDIA_307:
698         case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
699         case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
700         case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
701                 ir_codes     = md2819_codes;
702                 mask_keycode = 0x0007C8;
703                 mask_keydown = 0x000010;
704                 polling      = 50; // ms
705                 /* Set GPIO pin2 to high to enable the IR controller */
706                 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
707                 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
708                 break;
709         case SAA7134_BOARD_KWORLD_TERMINATOR:
710                 ir_codes     = avacssmart_codes;
711                 mask_keycode = 0x00001f;
712                 mask_keyup   = 0x000060;
713                 polling      = 50; // ms
714                 break;
715         case SAA7134_BOARD_MANLI_MTV001:
716         case SAA7134_BOARD_MANLI_MTV002:
717         case SAA7134_BOARD_BEHOLD_409FM:
718                 ir_codes     = manli_codes;
719                 mask_keycode = 0x001f00;
720                 mask_keyup   = 0x004000;
721                 polling      = 50; // ms
722                 break;
723         case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
724                 ir_codes     = pctv_sedna_codes;
725                 mask_keycode = 0x001f00;
726                 mask_keyup   = 0x004000;
727                 polling      = 50; // ms
728                 break;
729         case SAA7134_BOARD_GOTVIEW_7135:
730                 ir_codes     = gotview7135_codes;
731                 mask_keycode = 0x0003EC;
732                 mask_keyup   = 0x008000;
733                 mask_keydown = 0x000010;
734                 polling      = 50; // ms
735                 break;
736         case SAA7134_BOARD_VIDEOMATE_TV_PVR:
737         case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
738         case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
739                 ir_codes     = videomate_tv_pvr_codes;
740                 mask_keycode = 0x00003F;
741                 mask_keyup   = 0x400000;
742                 polling      = 50; // ms
743                 break;
744         case SAA7134_BOARD_VIDEOMATE_DVBT_300:
745         case SAA7134_BOARD_VIDEOMATE_DVBT_200:
746                 ir_codes     = videomate_tv_pvr_codes;
747                 mask_keycode = 0x003F00;
748                 mask_keyup   = 0x040000;
749                 break;
750         case SAA7134_BOARD_FLYDVBT_LR301:
751                 ir_codes     = flydvb_codes;
752                 mask_keycode = 0x0001F00;
753                 mask_keydown = 0x0040000;
754                 break;
755         }
756         if (NULL == ir_codes) {
757                 printk("%s: Oops: IR config error [card=%d]\n",
758                        dev->name, dev->board);
759                 return -ENODEV;
760         }
761
762         ir = kzalloc(sizeof(*ir), GFP_KERNEL);
763         input_dev = input_allocate_device();
764         if (!ir || !input_dev) {
765                 kfree(ir);
766                 input_free_device(input_dev);
767                 return -ENOMEM;
768         }
769
770         ir->dev = input_dev;
771
772         /* init hardware-specific stuff */
773         ir->mask_keycode = mask_keycode;
774         ir->mask_keydown = mask_keydown;
775         ir->mask_keyup   = mask_keyup;
776         ir->polling      = polling;
777
778         /* init input device */
779         snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
780                  saa7134_boards[dev->board].name);
781         snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
782                  pci_name(dev->pci));
783
784         ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
785         input_dev->name = ir->name;
786         input_dev->phys = ir->phys;
787         input_dev->id.bustype = BUS_PCI;
788         input_dev->id.version = 1;
789         if (dev->pci->subsystem_vendor) {
790                 input_dev->id.vendor  = dev->pci->subsystem_vendor;
791                 input_dev->id.product = dev->pci->subsystem_device;
792         } else {
793                 input_dev->id.vendor  = dev->pci->vendor;
794                 input_dev->id.product = dev->pci->device;
795         }
796         input_dev->cdev.dev = &dev->pci->dev;
797
798         /* all done */
799         dev->remote = ir;
800         if (ir->polling) {
801                 init_timer(&ir->timer);
802                 ir->timer.function = saa7134_input_timer;
803                 ir->timer.data     = (unsigned long)dev;
804                 ir->timer.expires  = jiffies + HZ;
805                 add_timer(&ir->timer);
806         }
807
808         input_register_device(ir->dev);
809         return 0;
810 }
811
812 void saa7134_input_fini(struct saa7134_dev *dev)
813 {
814         if (NULL == dev->remote)
815                 return;
816
817         if (dev->remote->polling)
818                 del_timer_sync(&dev->remote->timer);
819         input_unregister_device(dev->remote->dev);
820         kfree(dev->remote);
821         dev->remote = NULL;
822 }
823
824 void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
825 {
826         if (disable_ir) {
827                 dprintk("Found supported i2c remote, but IR has been disabled\n");
828                 ir->get_key=NULL;
829                 return;
830         }
831
832         switch (dev->board) {
833         case SAA7134_BOARD_PINNACLE_PCTV_110i:
834                 snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV");
835                 ir->get_key   = get_key_pinnacle;
836                 ir->ir_codes  = ir_codes_pinnacle;
837                 break;
838         case SAA7134_BOARD_UPMOST_PURPLE_TV:
839                 snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV");
840                 ir->get_key   = get_key_purpletv;
841                 ir->ir_codes  = ir_codes_purpletv;
842                 break;
843         default:
844                 dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
845                 break;
846         }
847
848 }
849 /* ----------------------------------------------------------------------
850  * Local variables:
851  * c-basic-offset: 8
852  * End:
853  */