[PATCH] v4l: SAA7134 Update
[pandora-kernel.git] / drivers / media / video / saa7134 / saa7134-input.c
1 /*
2  * $Id: saa7134-input.c,v 1.21 2005/06/22 23:37:34 nsh Exp $
3  *
4  * handle saa7134 IR remotes via linux kernel input layer.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21
22 #include <linux/module.h>
23 #include <linux/moduleparam.h>
24 #include <linux/init.h>
25 #include <linux/delay.h>
26 #include <linux/sched.h>
27 #include <linux/interrupt.h>
28 #include <linux/input.h>
29
30 #include "saa7134-reg.h"
31 #include "saa7134.h"
32
33 static unsigned int disable_ir = 0;
34 module_param(disable_ir, int, 0444);
35 MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
36
37 static unsigned int ir_debug = 0;
38 module_param(ir_debug, int, 0644);
39 MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
40
41 #define dprintk(fmt, arg...)    if (ir_debug) \
42         printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
43
44 /* ---------------------------------------------------------------------- */
45
46 static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = {
47         [   15 ] = KEY_KP0,
48         [    3 ] = KEY_KP1,
49         [    4 ] = KEY_KP2,
50         [    5 ] = KEY_KP3,
51         [    7 ] = KEY_KP4,
52         [    8 ] = KEY_KP5,
53         [    9 ] = KEY_KP6,
54         [   11 ] = KEY_KP7,
55         [   12 ] = KEY_KP8,
56         [   13 ] = KEY_KP9,
57
58         [   14 ] = KEY_TUNER,        // Air/Cable
59         [   17 ] = KEY_VIDEO,        // Video
60         [   21 ] = KEY_AUDIO,        // Audio
61         [    0 ] = KEY_POWER,        // Pover
62         [    2 ] = KEY_ZOOM,         // Fullscreen
63         [   27 ] = KEY_MUTE,         // Mute
64         [   20 ] = KEY_VOLUMEUP,
65         [   23 ] = KEY_VOLUMEDOWN,
66         [   18 ] = KEY_CHANNELUP,    // Channel +
67         [   19 ] = KEY_CHANNELDOWN,  // Channel -
68         [    6 ] = KEY_AGAIN,        // Recal
69         [   16 ] = KEY_KPENTER,      // Enter
70
71         [   26 ] = KEY_F22,          // Stereo
72         [   24 ] = KEY_EDIT,         // AV Source
73 };
74
75 static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
76         [    0 ] = KEY_KP0,
77         [    1 ] = KEY_KP1,
78         [    2 ] = KEY_KP2,
79         [    3 ] = KEY_KP3,
80         [    4 ] = KEY_KP4,
81         [    5 ] = KEY_KP5,
82         [    6 ] = KEY_KP6,
83         [    7 ] = KEY_KP7,
84         [    8 ] = KEY_KP8,
85         [    9 ] = KEY_KP9,
86
87         [ 0x0a ] = KEY_POWER,
88         [ 0x0b ] = KEY_PROG1,           // app
89         [ 0x0c ] = KEY_ZOOM,            // zoom/fullscreen
90         [ 0x0d ] = KEY_CHANNELUP,       // channel
91         [ 0x0e ] = KEY_CHANNELDOWN,     // channel-
92         [ 0x0f ] = KEY_VOLUMEUP,
93         [ 0x10 ] = KEY_VOLUMEDOWN,
94         [ 0x11 ] = KEY_TUNER,           // AV
95         [ 0x12 ] = KEY_NUMLOCK,         // -/--
96         [ 0x13 ] = KEY_AUDIO,           // audio
97         [ 0x14 ] = KEY_MUTE,
98         [ 0x15 ] = KEY_UP,
99         [ 0x16 ] = KEY_DOWN,
100         [ 0x17 ] = KEY_LEFT,
101         [ 0x18 ] = KEY_RIGHT,
102         [ 0x19 ] = BTN_LEFT,
103         [ 0x1a ] = BTN_RIGHT,
104         [ 0x1b ] = KEY_WWW,             // text
105         [ 0x1c ] = KEY_REWIND,
106         [ 0x1d ] = KEY_FORWARD,
107         [ 0x1e ] = KEY_RECORD,
108         [ 0x1f ] = KEY_PLAY,
109         [ 0x20 ] = KEY_PREVIOUSSONG,
110         [ 0x21 ] = KEY_NEXTSONG,
111         [ 0x22 ] = KEY_PAUSE,
112         [ 0x23 ] = KEY_STOP,
113 };
114
115 /* Alfons Geser <a.geser@cox.net>
116  * updates from Job D. R. Borges <jobdrb@ig.com.br> */
117 static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
118         [ 18 ] = KEY_POWER,
119         [  1 ] = KEY_TV,             // DVR
120         [ 21 ] = KEY_DVD,            // DVD
121         [ 23 ] = KEY_AUDIO,          // music
122                                      // DVR mode / DVD mode / music mode
123
124         [ 27 ] = KEY_MUTE,           // mute
125         [  2 ] = KEY_LANGUAGE,       // MTS/SAP / audio / autoseek
126         [ 30 ] = KEY_SUBTITLE,       // closed captioning / subtitle / seek
127         [ 22 ] = KEY_ZOOM,           // full screen
128         [ 28 ] = KEY_VIDEO,          // video source / eject / delall
129         [ 29 ] = KEY_RESTART,        // playback / angle / del
130         [ 47 ] = KEY_SEARCH,         // scan / menu / playlist
131         [ 48 ] = KEY_CHANNEL,        // CH surfing / bookmark / memo
132
133         [ 49 ] = KEY_HELP,           // help
134         [ 50 ] = KEY_MODE,           // num/memo
135         [ 51 ] = KEY_ESC,            // cancel
136
137         [ 12 ] = KEY_UP,             // up
138         [ 16 ] = KEY_DOWN,           // down
139         [  8 ] = KEY_LEFT,           // left
140         [  4 ] = KEY_RIGHT,          // right
141         [  3 ] = KEY_SELECT,         // select
142
143         [ 31 ] = KEY_REWIND,         // rewind
144         [ 32 ] = KEY_PLAYPAUSE,      // play/pause
145         [ 41 ] = KEY_FORWARD,        // forward
146         [ 20 ] = KEY_AGAIN,          // repeat
147         [ 43 ] = KEY_RECORD,         // recording
148         [ 44 ] = KEY_STOP,           // stop
149         [ 45 ] = KEY_PLAY,           // play
150         [ 46 ] = KEY_SHUFFLE,        // snapshot / shuffle
151
152         [  0 ] = KEY_KP0,
153         [  5 ] = KEY_KP1,
154         [  6 ] = KEY_KP2,
155         [  7 ] = KEY_KP3,
156         [  9 ] = KEY_KP4,
157         [ 10 ] = KEY_KP5,
158         [ 11 ] = KEY_KP6,
159         [ 13 ] = KEY_KP7,
160         [ 14 ] = KEY_KP8,
161         [ 15 ] = KEY_KP9,
162
163         [ 42 ] = KEY_VOLUMEUP,
164         [ 17 ] = KEY_VOLUMEDOWN,
165         [ 24 ] = KEY_CHANNELUP,      // CH.tracking up
166         [ 25 ] = KEY_CHANNELDOWN,    // CH.tracking down
167
168         [ 19 ] = KEY_KPENTER,        // enter
169         [ 33 ] = KEY_KPDOT,          // . (decimal dot)
170 };
171
172 static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
173         [ 30 ] = KEY_POWER,             // power
174         [ 28 ] = KEY_SEARCH,            // scan
175         [  7 ] = KEY_SELECT,            // source
176
177         [ 22 ] = KEY_VOLUMEUP,
178         [ 20 ] = KEY_VOLUMEDOWN,
179         [ 31 ] = KEY_CHANNELUP,
180         [ 23 ] = KEY_CHANNELDOWN,
181         [ 24 ] = KEY_MUTE,
182
183         [  2 ] = KEY_KP0,
184         [  1 ] = KEY_KP1,
185         [ 11 ] = KEY_KP2,
186         [ 27 ] = KEY_KP3,
187         [  5 ] = KEY_KP4,
188         [  9 ] = KEY_KP5,
189         [ 21 ] = KEY_KP6,
190         [  6 ] = KEY_KP7,
191         [ 10 ] = KEY_KP8,
192         [ 18 ] = KEY_KP9,
193         [ 16 ] = KEY_KPDOT,
194
195         [  3 ] = KEY_TUNER,             // tv/fm
196         [  4 ] = KEY_REWIND,            // fm tuning left or function left
197         [ 12 ] = KEY_FORWARD,           // fm tuning right or function right
198
199         [  0 ] = KEY_RECORD,
200         [  8 ] = KEY_STOP,
201         [ 17 ] = KEY_PLAY,
202
203         [ 25 ] = KEY_ZOOM,
204         [ 14 ] = KEY_MENU,              // function
205         [ 19 ] = KEY_AGAIN,             // recall
206         [ 29 ] = KEY_RESTART,           // reset
207         [ 26 ] = KEY_SHUFFLE,           // snapshot/shuffle
208
209 // FIXME
210         [ 13 ] = KEY_F21,               // mts
211         [ 15 ] = KEY_F22,               // min
212 };
213
214 /* Alex Hermann <gaaf@gmx.net> */
215 static IR_KEYTAB_TYPE md2819_codes[IR_KEYTAB_SIZE] = {
216         [ 40 ] = KEY_KP1,
217         [ 24 ] = KEY_KP2,
218         [ 56 ] = KEY_KP3,
219         [ 36 ] = KEY_KP4,
220         [ 20 ] = KEY_KP5,
221         [ 52 ] = KEY_KP6,
222         [ 44 ] = KEY_KP7,
223         [ 28 ] = KEY_KP8,
224         [ 60 ] = KEY_KP9,
225         [ 34 ] = KEY_KP0,
226
227         [ 32 ] = KEY_TV,                // TV/FM
228         [ 16 ] = KEY_CD,                // CD
229         [ 48 ] = KEY_TEXT,              // TELETEXT
230         [  0 ] = KEY_POWER,             // POWER
231
232         [  8 ] = KEY_VIDEO,             // VIDEO
233         [  4 ] = KEY_AUDIO,             // AUDIO
234         [ 12 ] = KEY_ZOOM,              // FULL SCREEN
235
236         [ 18 ] = KEY_SUBTITLE,          // DISPLAY      - ???
237         [ 50 ] = KEY_REWIND,            // LOOP         - ???
238         [  2 ] = KEY_PRINT,             // PREVIEW      - ???
239
240         [ 42 ] = KEY_SEARCH,            // AUTOSCAN
241         [ 26 ] = KEY_SLEEP,             // FREEZE       - ???
242         [ 58 ] = KEY_SHUFFLE,           // SNAPSHOT     - ???
243         [ 10 ] = KEY_MUTE,              // MUTE
244
245         [ 38 ] = KEY_RECORD,            // RECORD
246         [ 22 ] = KEY_PAUSE,             // PAUSE
247         [ 54 ] = KEY_STOP,              // STOP
248         [  6 ] = KEY_PLAY,              // PLAY
249
250         [ 46 ] = KEY_RED,               // <RED>
251         [ 33 ] = KEY_GREEN,             // <GREEN>
252         [ 14 ] = KEY_YELLOW,            // <YELLOW>
253         [  1 ] = KEY_BLUE,              // <BLUE>
254
255         [ 30 ] = KEY_VOLUMEDOWN,        // VOLUME-
256         [ 62 ] = KEY_VOLUMEUP,          // VOLUME+
257         [ 17 ] = KEY_CHANNELDOWN,       // CHANNEL/PAGE-
258         [ 49 ] = KEY_CHANNELUP          // CHANNEL/PAGE+
259 };
260
261 static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = {
262         [ 20 ] = KEY_MUTE,
263         [ 36 ] = KEY_ZOOM,
264
265         [  1 ] = KEY_DVD,
266         [ 35 ] = KEY_RADIO,
267         [  0 ] = KEY_TV,
268
269         [ 10 ] = KEY_REWIND,
270         [  8 ] = KEY_PLAYPAUSE,
271         [ 15 ] = KEY_FORWARD,
272
273         [  2 ] = KEY_PREVIOUS,
274         [  7 ] = KEY_STOP,
275         [  6 ] = KEY_NEXT,
276
277         [ 12 ] = KEY_UP,
278         [ 14 ] = KEY_DOWN,
279         [ 11 ] = KEY_LEFT,
280         [ 13 ] = KEY_RIGHT,
281         [ 17 ] = KEY_OK,
282
283         [  3 ] = KEY_MENU,
284         [  9 ] = KEY_SETUP,
285         [  5 ] = KEY_VIDEO,
286         [ 34 ] = KEY_CHANNEL,
287
288         [ 18 ] = KEY_VOLUMEUP,
289         [ 21 ] = KEY_VOLUMEDOWN,
290         [ 16 ] = KEY_CHANNELUP,
291         [ 19 ] = KEY_CHANNELDOWN,
292
293         [  4 ] = KEY_RECORD,
294
295         [ 22 ] = KEY_KP1,
296         [ 23 ] = KEY_KP2,
297         [ 24 ] = KEY_KP3,
298         [ 25 ] = KEY_KP4,
299         [ 26 ] = KEY_KP5,
300         [ 27 ] = KEY_KP6,
301         [ 28 ] = KEY_KP7,
302         [ 29 ] = KEY_KP8,
303         [ 30 ] = KEY_KP9,
304         [ 31 ] = KEY_KP0,
305
306         [ 32 ] = KEY_LANGUAGE,
307         [ 33 ] = KEY_SLEEP,
308 };
309
310 /* Michael Tokarev <mjt@tls.msk.ru>
311    http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
312    keytable is used by MANLI MTV00[12] and BeholdTV 40[13] at
313    least, and probably other cards too.
314    The "ascii-art picture" below (in comments, first row
315    is the keycode in hex, and subsequent row(s) shows
316    the button labels (several variants when appropriate)
317    helps to descide which keycodes to assign to the buttons.
318  */
319 static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
320
321         /*  0x1c            0x12  *
322          * FUNCTION         POWER *
323          *   FM              (|)  *
324          *                        */
325         [ 0x1c ] = KEY_RADIO,   /*XXX*/
326         [ 0x12 ] = KEY_POWER,
327
328         /*  0x01    0x02    0x03  *
329          *   1       2       3    *
330          *                        *
331          *  0x04    0x05    0x06  *
332          *   4       5       6    *
333          *                        *
334          *  0x07    0x08    0x09  *
335          *   7       8       9    *
336          *                        */
337         [ 0x01 ] = KEY_KP1,
338         [ 0x02 ] = KEY_KP2,
339         [ 0x03 ] = KEY_KP3,
340         [ 0x04 ] = KEY_KP4,
341         [ 0x05 ] = KEY_KP5,
342         [ 0x06 ] = KEY_KP6,
343         [ 0x07 ] = KEY_KP7,
344         [ 0x08 ] = KEY_KP8,
345         [ 0x09 ] = KEY_KP9,
346
347         /*  0x0a    0x00    0x17  *
348          * RECALL    0      +100  *
349          *                  PLUS  *
350          *                        */
351         [ 0x0a ] = KEY_AGAIN,   /*XXX KEY_REWIND? */
352         [ 0x00 ] = KEY_KP0,
353         [ 0x17 ] = KEY_DIGITS,  /*XXX*/
354
355         /*  0x14            0x10  *
356          *  MENU            INFO  *
357          *  OSD                   */
358         [ 0x14 ] = KEY_MENU,
359         [ 0x10 ] = KEY_INFO,
360
361         /*          0x0b          *
362          *           Up           *
363          *                        *
364          *  0x18    0x16    0x0c  *
365          *  Left     Ok     Right *
366          *                        *
367          *         0x015          *
368          *         Down           *
369          *                        */
370         [ 0x0b ] = KEY_UP,      /*XXX KEY_SCROLLUP? */
371         [ 0x18 ] = KEY_LEFT,    /*XXX KEY_BACK? */
372         [ 0x16 ] = KEY_OK,      /*XXX KEY_SELECT? KEY_ENTER? */
373         [ 0x0c ] = KEY_RIGHT,   /*XXX KEY_FORWARD? */
374         [ 0x15 ] = KEY_DOWN,    /*XXX KEY_SCROLLDOWN? */
375
376         /*  0x11            0x0d  *
377          *  TV/AV           MODE  *
378          *  SOURCE         STEREO *
379          *                        */
380         [ 0x11 ] = KEY_TV,      /*XXX*/
381         [ 0x0d ] = KEY_MODE,    /*XXX there's no KEY_STEREO */
382
383         /*  0x0f    0x1b    0x1a  *
384          *  AUDIO   Vol+    Chan+ *
385          *        TIMESHIFT???    *
386          *                        *
387          *  0x0e    0x1f    0x1e  *
388          *  SLEEP   Vol-    Chan- *
389          *                        */
390         [ 0x0f ] = KEY_AUDIO,
391         [ 0x1b ] = KEY_VOLUMEUP,
392         [ 0x1a ] = KEY_CHANNELUP,
393         [ 0x0e ] = KEY_SLEEP,   /*XXX maybe KEY_PAUSE */
394         [ 0x1f ] = KEY_VOLUMEDOWN,
395         [ 0x1e ] = KEY_CHANNELDOWN,
396
397         /*         0x13     0x19  *
398          *         MUTE   SNAPSHOT*
399          *                        */
400         [ 0x13 ] = KEY_MUTE,
401         [ 0x19 ] = KEY_RECORD,  /*XXX*/
402
403         // 0x1d unused ?
404 };
405 /* ---------------------------------------------------------------------- */
406
407 static int build_key(struct saa7134_dev *dev)
408 {
409         struct saa7134_ir *ir = dev->remote;
410         u32 gpio, data;
411
412         /* rising SAA7134_GPIO_GPRESCAN reads the status */
413         saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
414         saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
415
416         gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
417         if (ir->polling) {
418                 if (ir->last_gpio == gpio)
419                         return 0;
420                 ir->last_gpio = gpio;
421         }
422
423         data = ir_extract_bits(gpio, ir->mask_keycode);
424         dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
425                 gpio, ir->mask_keycode, data);
426
427         if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
428             (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
429                 ir_input_keydown(&ir->dev,&ir->ir,data,data);
430         } else {
431                 ir_input_nokey(&ir->dev,&ir->ir);
432         }
433         return 0;
434 }
435
436 /* ---------------------------------------------------------------------- */
437
438 void saa7134_input_irq(struct saa7134_dev *dev)
439 {
440         struct saa7134_ir *ir = dev->remote;
441
442         if (!ir->polling)
443                 build_key(dev);
444 }
445
446 static void saa7134_input_timer(unsigned long data)
447 {
448         struct saa7134_dev *dev = (struct saa7134_dev*)data;
449         struct saa7134_ir *ir = dev->remote;
450         unsigned long timeout;
451
452         build_key(dev);
453         timeout = jiffies + (ir->polling * HZ / 1000);
454         mod_timer(&ir->timer, timeout);
455 }
456
457 int saa7134_input_init1(struct saa7134_dev *dev)
458 {
459         struct saa7134_ir *ir;
460         IR_KEYTAB_TYPE *ir_codes = NULL;
461         u32 mask_keycode = 0;
462         u32 mask_keydown = 0;
463         u32 mask_keyup   = 0;
464         int polling      = 0;
465         int ir_type      = IR_TYPE_OTHER;
466
467         if (!dev->has_remote)
468                 return -ENODEV;
469         if (disable_ir)
470                 return -ENODEV;
471
472         /* detect & configure */
473         switch (dev->board) {
474         case SAA7134_BOARD_FLYVIDEO2000:
475         case SAA7134_BOARD_FLYVIDEO3000:
476         case SAA7134_BOARD_FLYTVPLATINUM_FM:
477                 ir_codes     = flyvideo_codes;
478                 mask_keycode = 0xEC00000;
479                 mask_keydown = 0x0040000;
480                 break;
481         case SAA7134_BOARD_CINERGY400:
482         case SAA7134_BOARD_CINERGY600:
483         case SAA7134_BOARD_CINERGY600_MK3:
484                 ir_codes     = cinergy_codes;
485                 mask_keycode = 0x00003f;
486                 mask_keyup   = 0x040000;
487                 break;
488         case SAA7134_BOARD_ECS_TVP3XP:
489         case SAA7134_BOARD_ECS_TVP3XP_4CB5:
490                 ir_codes     = eztv_codes;
491                 mask_keycode = 0x00017c;
492                 mask_keyup   = 0x000002;
493                 polling      = 50; // ms
494                 break;
495         case SAA7134_BOARD_KWORLD_XPERT:
496         case SAA7134_BOARD_AVACSSMARTTV:
497                 ir_codes     = avacssmart_codes;
498                 mask_keycode = 0x00001F;
499                 mask_keyup   = 0x000020;
500                 polling      = 50; // ms
501                 break;
502         case SAA7134_BOARD_MD2819:
503         case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
504         case SAA7134_BOARD_AVERMEDIA_305:
505         case SAA7134_BOARD_AVERMEDIA_307:
506         case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
507         case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
508         case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
509                 ir_codes     = md2819_codes;
510                 mask_keycode = 0x0007C8;
511                 mask_keydown = 0x000010;
512                 polling      = 50; // ms
513                 /* Set GPIO pin2 to high to enable the IR controller */
514                 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
515                 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
516                 break;
517         case SAA7134_BOARD_MANLI_MTV001:
518         case SAA7134_BOARD_MANLI_MTV002:
519                 ir_codes     = manli_codes;
520                 mask_keycode = 0x001f00;
521                 mask_keyup   = 0x004000;
522                 mask_keydown = 0x002000;
523                 polling      = 50; // ms
524                 break;
525         case SAA7134_BOARD_VIDEOMATE_TV_PVR:
526         case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
527                 ir_codes     = videomate_tv_pvr_codes;
528                 mask_keycode = 0x00003F;
529                 mask_keyup   = 0x400000;
530                 polling      = 50; // ms
531                 break;
532         }
533         if (NULL == ir_codes) {
534                 printk("%s: Oops: IR config error [card=%d]\n",
535                        dev->name, dev->board);
536                 return -ENODEV;
537         }
538
539         ir = kmalloc(sizeof(*ir),GFP_KERNEL);
540         if (NULL == ir)
541                 return -ENOMEM;
542         memset(ir,0,sizeof(*ir));
543
544         /* init hardware-specific stuff */
545         ir->mask_keycode = mask_keycode;
546         ir->mask_keydown = mask_keydown;
547         ir->mask_keyup   = mask_keyup;
548         ir->polling      = polling;
549
550         /* init input device */
551         snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
552                  saa7134_boards[dev->board].name);
553         snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
554                  pci_name(dev->pci));
555
556         ir_input_init(&ir->dev, &ir->ir, ir_type, ir_codes);
557         ir->dev.name = ir->name;
558         ir->dev.phys = ir->phys;
559         ir->dev.id.bustype = BUS_PCI;
560         ir->dev.id.version = 1;
561         if (dev->pci->subsystem_vendor) {
562                 ir->dev.id.vendor  = dev->pci->subsystem_vendor;
563                 ir->dev.id.product = dev->pci->subsystem_device;
564         } else {
565                 ir->dev.id.vendor  = dev->pci->vendor;
566                 ir->dev.id.product = dev->pci->device;
567         }
568
569         /* all done */
570         dev->remote = ir;
571         if (ir->polling) {
572                 init_timer(&ir->timer);
573                 ir->timer.function = saa7134_input_timer;
574                 ir->timer.data     = (unsigned long)dev;
575                 ir->timer.expires  = jiffies + HZ;
576                 add_timer(&ir->timer);
577         }
578
579         input_register_device(&dev->remote->dev);
580         printk("%s: registered input device for IR\n",dev->name);
581         return 0;
582 }
583
584 void saa7134_input_fini(struct saa7134_dev *dev)
585 {
586         if (NULL == dev->remote)
587                 return;
588
589         input_unregister_device(&dev->remote->dev);
590         if (dev->remote->polling)
591                 del_timer_sync(&dev->remote->timer);
592         kfree(dev->remote);
593         dev->remote = NULL;
594 }
595
596 /* ----------------------------------------------------------------------
597  * Local variables:
598  * c-basic-offset: 8
599  * End:
600  */