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