This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / media / video / bttv-input.c
1 /*
2  *
3  * Copyright (c) 2003 Gerd Knorr
4  * Copyright (c) 2003 Pavel Machek
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 #include <linux/module.h>
22 #include <linux/moduleparam.h>
23 #include <linux/init.h>
24 #include <linux/delay.h>
25 #include <linux/interrupt.h>
26 #include <linux/input.h>
27
28 #include "bttv.h"
29 #include "bttvp.h"
30
31 /* ---------------------------------------------------------------------- */
32
33 static IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = {
34         [ 34 ] = KEY_KP0,
35         [ 40 ] = KEY_KP1,
36         [ 24 ] = KEY_KP2,
37         [ 56 ] = KEY_KP3,
38         [ 36 ] = KEY_KP4,
39         [ 20 ] = KEY_KP5,
40         [ 52 ] = KEY_KP6,
41         [ 44 ] = KEY_KP7,
42         [ 28 ] = KEY_KP8,
43         [ 60 ] = KEY_KP9,
44
45         [ 48 ] = KEY_EJECTCD,     // Unmarked on my controller
46         [  0 ] = KEY_POWER,
47         [ 18 ] = BTN_LEFT,        // DISPLAY/L
48         [ 50 ] = BTN_RIGHT,       // LOOP/R
49         [ 10 ] = KEY_MUTE,
50         [ 38 ] = KEY_RECORD,
51         [ 22 ] = KEY_PAUSE,
52         [ 54 ] = KEY_STOP,
53         [ 30 ] = KEY_VOLUMEDOWN,
54         [ 62 ] = KEY_VOLUMEUP,
55
56         [ 32 ] = KEY_TUNER,       // TV/FM
57         [ 16 ] = KEY_CD,
58         [  8 ] = KEY_VIDEO,
59         [  4 ] = KEY_AUDIO,
60         [ 12 ] = KEY_ZOOM,        // full screen
61         [  2 ] = KEY_INFO,        // preview
62         [ 42 ] = KEY_SEARCH,      // autoscan
63         [ 26 ] = KEY_STOP,        // freeze
64         [ 58 ] = KEY_RECORD,      // capture
65         [  6 ] = KEY_PLAY,        // unmarked
66         [ 46 ] = KEY_RED,         // unmarked
67         [ 14 ] = KEY_GREEN,       // unmarked
68
69         [ 33 ] = KEY_YELLOW,      // unmarked
70         [ 17 ] = KEY_CHANNELDOWN,
71         [ 49 ] = KEY_CHANNELUP,
72         [  1 ] = KEY_BLUE,        // unmarked
73 };
74
75 /* Matt Jesson <dvb@jesson.eclipse.co.uk */
76 static IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = {
77         [ 0x28 ] = KEY_KP0,         //'0' / 'enter'
78         [ 0x22 ] = KEY_KP1,         //'1'
79         [ 0x12 ] = KEY_KP2,         //'2' / 'up arrow'
80         [ 0x32 ] = KEY_KP3,         //'3'
81         [ 0x24 ] = KEY_KP4,         //'4' / 'left arrow'
82         [ 0x14 ] = KEY_KP5,         //'5'
83         [ 0x34 ] = KEY_KP6,         //'6' / 'right arrow'
84         [ 0x26 ] = KEY_KP7,         //'7'
85         [ 0x16 ] = KEY_KP8,         //'8' / 'down arrow'
86         [ 0x36 ] = KEY_KP9,         //'9'
87
88         [ 0x20 ] = KEY_LIST,        // 'source'
89         [ 0x10 ] = KEY_TEXT,        // 'teletext'
90         [ 0x00 ] = KEY_POWER,       // 'power'
91         [ 0x04 ] = KEY_AUDIO,       // 'audio'
92         [ 0x06 ] = KEY_ZOOM,        // 'full screen'
93         [ 0x18 ] = KEY_VIDEO,       // 'display'
94         [ 0x38 ] = KEY_SEARCH,      // 'loop'
95         [ 0x08 ] = KEY_INFO,        // 'preview'
96         [ 0x2a ] = KEY_REWIND,      // 'backward <<'
97         [ 0x1a ] = KEY_FASTFORWARD, // 'forward >>'
98         [ 0x3a ] = KEY_RECORD,      // 'capture'
99         [ 0x0a ] = KEY_MUTE,        // 'mute'
100         [ 0x2c ] = KEY_RECORD,      // 'record'
101         [ 0x1c ] = KEY_PAUSE,       // 'pause'
102         [ 0x3c ] = KEY_STOP,        // 'stop'
103         [ 0x0c ] = KEY_PLAY,        // 'play'
104         [ 0x2e ] = KEY_RED,         // 'red'
105         [ 0x01 ] = KEY_BLUE,        // 'blue' / 'cancel'
106         [ 0x0e ] = KEY_YELLOW,      // 'yellow' / 'ok'
107         [ 0x21 ] = KEY_GREEN,       // 'green'
108         [ 0x11 ] = KEY_CHANNELDOWN, // 'channel -'
109         [ 0x31 ] = KEY_CHANNELUP,   // 'channel +'
110         [ 0x1e ] = KEY_VOLUMEDOWN,  // 'volume -'
111         [ 0x3e ] = KEY_VOLUMEUP,    // 'volume +'
112 };
113
114 /* Attila Kondoros <attila.kondoros@chello.hu> */
115 static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
116
117         [  1 ] = KEY_KP1,
118         [  2 ] = KEY_KP2,
119         [  3 ] = KEY_KP3,
120         [  4 ] = KEY_KP4,
121         [  5 ] = KEY_KP5,
122         [  6 ] = KEY_KP6,
123         [  7 ] = KEY_KP7,
124         [  8 ] = KEY_KP8,
125         [  9 ] = KEY_KP9,
126         [  0 ] = KEY_KP0,
127         [ 23 ] = KEY_LAST,        // +100
128         [ 10 ] = KEY_LIST,        // recall
129
130
131         [ 28 ] = KEY_TUNER,       // TV/FM
132         [ 21 ] = KEY_SEARCH,      // scan
133         [ 18 ] = KEY_POWER,       // power
134         [ 31 ] = KEY_VOLUMEDOWN,  // vol up
135         [ 27 ] = KEY_VOLUMEUP,    // vol down
136         [ 30 ] = KEY_CHANNELDOWN, // chn up
137         [ 26 ] = KEY_CHANNELUP,   // chn down
138
139         [ 17 ] = KEY_VIDEO,       // video
140         [ 15 ] = KEY_ZOOM,        // full screen
141         [ 19 ] = KEY_MUTE,        // mute/unmute
142         [ 16 ] = KEY_TEXT,        // min
143
144         [ 13 ] = KEY_STOP,        // freeze
145         [ 14 ] = KEY_RECORD,      // record
146         [ 29 ] = KEY_PLAYPAUSE,   // stop
147         [ 25 ] = KEY_PLAY,        // play
148
149         [ 22 ] = KEY_GOTO,        // osd
150         [ 20 ] = KEY_REFRESH,     // default
151         [ 12 ] = KEY_KPPLUS,      // fine tune >>>>
152         [ 24 ] = KEY_KPMINUS      // fine tune <<<<
153 };
154
155 /* ---------------------------------------------------------------------- */
156
157 static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = {
158
159         [ 30 ] = KEY_POWER,       // power
160         [ 7  ] = KEY_MEDIA,       // source
161         [ 28 ] = KEY_SEARCH,      // scan
162
163 /* FIXME: duplicate keycodes?
164  *
165  * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>>
166  * The GPIO values are
167  * 6397fb for both "Scan <" and "CH -",
168  * 639ffb for "Scan >" and "CH+",
169  * 6384fb for "Tune <" and "<<<",
170  * 638cfb for "Tune >" and ">>>", regardless of the mask.
171  *
172  *      [ 23 ] = KEY_BACK,        // fm scan <<
173  *      [ 31 ] = KEY_FORWARD,     // fm scan >>
174  *
175  *      [ 4  ] = KEY_LEFT,        // fm tuning <
176  *      [ 12 ] = KEY_RIGHT,       // fm tuning >
177  *
178  * For now, these four keys are disabled. Pressing them will generate
179  * the CH+/CH-/<<</>>> events
180  */
181
182         [ 3  ] = KEY_TUNER,       // TV/FM
183
184         [ 0  ] = KEY_RECORD,
185         [ 8  ] = KEY_STOP,
186         [ 17 ] = KEY_PLAY,
187
188         [ 26 ] = KEY_PLAYPAUSE,   // freeze
189         [ 25 ] = KEY_ZOOM,        // zoom
190         [ 15 ] = KEY_TEXT,        // min
191
192         [ 1  ] = KEY_KP1,
193         [ 11 ] = KEY_KP2,
194         [ 27 ] = KEY_KP3,
195         [ 5  ] = KEY_KP4,
196         [ 9  ] = KEY_KP5,
197         [ 21 ] = KEY_KP6,
198         [ 6  ] = KEY_KP7,
199         [ 10 ] = KEY_KP8,
200         [ 18 ] = KEY_KP9,
201         [ 2  ] = KEY_KP0,
202         [ 16 ] = KEY_LAST,        // +100
203         [ 19 ] = KEY_LIST,        // recall
204
205         [ 31 ] = KEY_CHANNELUP,   // chn down
206         [ 23 ] = KEY_CHANNELDOWN, // chn up
207         [ 22 ] = KEY_VOLUMEUP,    // vol down
208         [ 20 ] = KEY_VOLUMEDOWN,  // vol up
209
210         [ 4  ] = KEY_KPMINUS,     // <<<
211         [ 14 ] = KEY_SETUP,       // function
212         [ 12 ] = KEY_KPPLUS,      // >>>
213
214         [ 13 ] = KEY_GOTO,        // mts
215         [ 29 ] = KEY_REFRESH,     // reset
216         [ 24 ] = KEY_MUTE         // mute/unmute
217 };
218
219 static IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = {
220         [0x00] = KEY_KP0,
221         [0x01] = KEY_KP1,
222         [0x02] = KEY_KP2,
223         [0x03] = KEY_KP3,
224         [0x04] = KEY_KP4,
225         [0x05] = KEY_KP5,
226         [0x06] = KEY_KP6,
227         [0x07] = KEY_KP7,
228         [0x08] = KEY_KP8,
229         [0x09] = KEY_KP9,
230         [0x0a] = KEY_TV,
231         [0x0b] = KEY_AUX,
232         [0x0c] = KEY_DVD,
233         [0x0d] = KEY_POWER,
234         [0x0e] = KEY_MHP,       /* labelled 'Picture' */
235         [0x0f] = KEY_AUDIO,
236         [0x10] = KEY_INFO,
237         [0x11] = KEY_F13,       /* 16:9 */
238         [0x12] = KEY_F14,       /* 14:9 */
239         [0x13] = KEY_EPG,
240         [0x14] = KEY_EXIT,
241         [0x15] = KEY_MENU,
242         [0x16] = KEY_UP,
243         [0x17] = KEY_DOWN,
244         [0x18] = KEY_LEFT,
245         [0x19] = KEY_RIGHT,
246         [0x1a] = KEY_ENTER,
247         [0x1b] = KEY_CHANNELUP,
248         [0x1c] = KEY_CHANNELDOWN,
249         [0x1d] = KEY_VOLUMEUP,
250         [0x1e] = KEY_VOLUMEDOWN,
251         [0x1f] = KEY_RED,
252         [0x20] = KEY_GREEN,
253         [0x21] = KEY_YELLOW,
254         [0x22] = KEY_BLUE,
255         [0x23] = KEY_SUBTITLE,
256         [0x24] = KEY_F15,       /* AD */
257         [0x25] = KEY_TEXT,
258         [0x26] = KEY_MUTE,
259         [0x27] = KEY_REWIND,
260         [0x28] = KEY_STOP,
261         [0x29] = KEY_PLAY,
262         [0x2a] = KEY_FASTFORWARD,
263         [0x2b] = KEY_F16,       /* chapter */
264         [0x2c] = KEY_PAUSE,
265         [0x2d] = KEY_PLAY,
266         [0x2e] = KEY_RECORD,
267         [0x2f] = KEY_F17,       /* picture in picture */
268         [0x30] = KEY_KPPLUS,    /* zoom in */
269         [0x31] = KEY_KPMINUS,   /* zoom out */
270         [0x32] = KEY_F18,       /* capture */
271         [0x33] = KEY_F19,       /* web */
272         [0x34] = KEY_EMAIL,
273         [0x35] = KEY_PHONE,
274         [0x36] = KEY_PC
275 };
276
277 static int debug;
278 module_param(debug, int, 0644);    /* debug level (0,1,2) */
279 static int repeat_delay = 500;
280 module_param(repeat_delay, int, 0644);
281 static int repeat_period = 33;
282 module_param(repeat_period, int, 0644);
283
284 #define DEVNAME "bttv-input"
285
286 /* ---------------------------------------------------------------------- */
287
288 static void ir_handle_key(struct bttv *btv)
289 {
290         struct bttv_ir *ir = btv->remote;
291         u32 gpio,data;
292
293         /* read gpio value */
294         gpio = bttv_gpio_read(&btv->c);
295         if (ir->polling) {
296                 if (ir->last_gpio == gpio)
297                         return;
298                 ir->last_gpio = gpio;
299         }
300
301         /* extract data */
302         data = ir_extract_bits(gpio, ir->mask_keycode);
303         dprintk(KERN_INFO DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n",
304                 gpio, data,
305                 ir->polling               ? "poll"  : "irq",
306                 (gpio & ir->mask_keydown) ? " down" : "",
307                 (gpio & ir->mask_keyup)   ? " up"   : "");
308
309         if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
310             (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
311                 ir_input_keydown(ir->dev,&ir->ir,data,data);
312         } else {
313                 ir_input_nokey(ir->dev,&ir->ir);
314         }
315
316 }
317
318 void bttv_input_irq(struct bttv *btv)
319 {
320         struct bttv_ir *ir = btv->remote;
321
322         if (!ir->polling)
323                 ir_handle_key(btv);
324 }
325
326 static void bttv_input_timer(unsigned long data)
327 {
328         struct bttv *btv = (struct bttv*)data;
329         struct bttv_ir *ir = btv->remote;
330         unsigned long timeout;
331
332         ir_handle_key(btv);
333         timeout = jiffies + (ir->polling * HZ / 1000);
334         mod_timer(&ir->timer, timeout);
335 }
336
337 /* ---------------------------------------------------------------*/
338
339 static int rc5_remote_gap = 885;
340 module_param(rc5_remote_gap, int, 0644);
341 static int rc5_key_timeout = 200;
342 module_param(rc5_key_timeout, int, 0644);
343
344 #define RC5_START(x)    (((x)>>12)&3)
345 #define RC5_TOGGLE(x)   (((x)>>11)&1)
346 #define RC5_ADDR(x)     (((x)>>6)&31)
347 #define RC5_INSTR(x)    ((x)&63)
348
349 /* decode raw bit pattern to RC5 code */
350 static u32 rc5_decode(unsigned int code)
351 {
352         unsigned int org_code = code;
353         unsigned int pair;
354         unsigned int rc5 = 0;
355         int i;
356
357         code = (code << 1) | 1;
358         for (i = 0; i < 14; ++i) {
359                 pair = code & 0x3;
360                 code >>= 2;
361
362                 rc5 <<= 1;
363                 switch (pair) {
364                 case 0:
365                 case 2:
366                         break;
367                 case 1:
368                         rc5 |= 1;
369                         break;
370                 case 3:
371                         dprintk(KERN_WARNING "bad code: %x\n", org_code);
372                         return 0;
373                 }
374         }
375         dprintk(KERN_WARNING "code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
376                 "instr=%x\n", rc5, org_code, RC5_START(rc5),
377                 RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
378         return rc5;
379 }
380
381 static int bttv_rc5_irq(struct bttv *btv)
382 {
383         struct bttv_ir *ir = btv->remote;
384         struct timeval tv;
385         u32 gpio;
386         u32 gap;
387         unsigned long current_jiffies, timeout;
388
389         /* read gpio port */
390         gpio = bttv_gpio_read(&btv->c);
391
392         /* remote IRQ? */
393         if (!(gpio & 0x20))
394                 return 0;
395
396         /* get time of bit */
397         current_jiffies = jiffies;
398         do_gettimeofday(&tv);
399
400         /* avoid overflow with gap >1s */
401         if (tv.tv_sec - ir->base_time.tv_sec > 1) {
402                 gap = 200000;
403         } else {
404                 gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
405                     tv.tv_usec - ir->base_time.tv_usec;
406         }
407
408         /* active code => add bit */
409         if (ir->active) {
410                 /* only if in the code (otherwise spurious IRQ or timer
411                    late) */
412                 if (ir->last_bit < 28) {
413                         ir->last_bit = (gap - rc5_remote_gap / 2) /
414                             rc5_remote_gap;
415                         ir->code |= 1 << ir->last_bit;
416                 }
417                 /* starting new code */
418         } else {
419                 ir->active = 1;
420                 ir->code = 0;
421                 ir->base_time = tv;
422                 ir->last_bit = 0;
423
424                 timeout = current_jiffies + (500 + 30 * HZ) / 1000;
425                 mod_timer(&ir->timer_end, timeout);
426         }
427
428         /* toggle GPIO pin 4 to reset the irq */
429         bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
430         bttv_gpio_write(&btv->c, gpio | (1 << 4));
431         return 1;
432 }
433
434
435 static void bttv_rc5_timer_end(unsigned long data)
436 {
437         struct bttv_ir *ir = (struct bttv_ir *)data;
438         struct timeval tv;
439         unsigned long current_jiffies, timeout;
440         u32 gap;
441
442         /* get time */
443         current_jiffies = jiffies;
444         do_gettimeofday(&tv);
445
446         /* avoid overflow with gap >1s */
447         if (tv.tv_sec - ir->base_time.tv_sec > 1) {
448                 gap = 200000;
449         } else {
450                 gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
451                     tv.tv_usec - ir->base_time.tv_usec;
452         }
453
454         /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */
455         if (gap < 28000) {
456                 dprintk(KERN_WARNING "spurious timer_end\n");
457                 return;
458         }
459
460         ir->active = 0;
461         if (ir->last_bit < 20) {
462                 /* ignore spurious codes (caused by light/other remotes) */
463                 dprintk(KERN_WARNING "short code: %x\n", ir->code);
464         } else {
465                 u32 rc5 = rc5_decode(ir->code);
466
467                 /* two start bits? */
468                 if (RC5_START(rc5) != 3) {
469                         dprintk(KERN_WARNING "rc5 start bits invalid: %u\n", RC5_START(rc5));
470
471                         /* right address? */
472                 } else if (RC5_ADDR(rc5) == 0x0) {
473                         u32 toggle = RC5_TOGGLE(rc5);
474                         u32 instr = RC5_INSTR(rc5);
475
476                         /* Good code, decide if repeat/repress */
477                         if (toggle != RC5_TOGGLE(ir->last_rc5) ||
478                             instr != RC5_INSTR(ir->last_rc5)) {
479                                 dprintk(KERN_WARNING "instruction %x, toggle %x\n", instr,
480                                         toggle);
481                                 ir_input_nokey(ir->dev, &ir->ir);
482                                 ir_input_keydown(ir->dev, &ir->ir, instr,
483                                                  instr);
484                         }
485
486                         /* Set/reset key-up timer */
487                         timeout = current_jiffies + (500 + rc5_key_timeout
488                                                      * HZ) / 1000;
489                         mod_timer(&ir->timer_keyup, timeout);
490
491                         /* Save code for repeat test */
492                         ir->last_rc5 = rc5;
493                 }
494         }
495 }
496
497 static void bttv_rc5_timer_keyup(unsigned long data)
498 {
499         struct bttv_ir *ir = (struct bttv_ir *)data;
500
501         dprintk(KERN_DEBUG "key released\n");
502         ir_input_nokey(ir->dev, &ir->ir);
503 }
504
505 /* ---------------------------------------------------------------------- */
506
507 int bttv_input_init(struct bttv *btv)
508 {
509         struct bttv_ir *ir;
510         IR_KEYTAB_TYPE *ir_codes = NULL;
511         struct input_dev *input_dev;
512         int ir_type = IR_TYPE_OTHER;
513
514         if (!btv->has_remote)
515                 return -ENODEV;
516
517         ir = kzalloc(sizeof(*ir),GFP_KERNEL);
518         input_dev = input_allocate_device();
519         if (!ir || !input_dev) {
520                 kfree(ir);
521                 input_free_device(input_dev);
522                 return -ENOMEM;
523         }
524         memset(ir,0,sizeof(*ir));
525
526         /* detect & configure */
527         switch (btv->c.type) {
528         case BTTV_BOARD_AVERMEDIA:
529         case BTTV_BOARD_AVPHONE98:
530         case BTTV_BOARD_AVERMEDIA98:
531                 ir_codes         = ir_codes_avermedia;
532                 ir->mask_keycode = 0xf88000;
533                 ir->mask_keydown = 0x010000;
534                 ir->polling      = 50; // ms
535                 break;
536
537         case BTTV_BOARD_AVDVBT_761:
538         case BTTV_BOARD_AVDVBT_771:
539                 ir_codes         = ir_codes_avermedia_dvbt;
540                 ir->mask_keycode = 0x0f00c0;
541                 ir->mask_keydown = 0x000020;
542                 ir->polling      = 50; // ms
543                 break;
544
545         case BTTV_BOARD_PXELVWPLTVPAK:
546                 ir_codes         = ir_codes_pixelview;
547                 ir->mask_keycode = 0x003e00;
548                 ir->mask_keyup   = 0x010000;
549                 ir->polling      = 50; // ms
550                 break;
551         case BTTV_BOARD_PV_BT878P_9B:
552         case BTTV_BOARD_PV_BT878P_PLUS:
553                 ir_codes         = ir_codes_pixelview;
554                 ir->mask_keycode = 0x001f00;
555                 ir->mask_keyup   = 0x008000;
556                 ir->polling      = 50; // ms
557                 break;
558
559         case BTTV_BOARD_WINFAST2000:
560                 ir_codes         = ir_codes_winfast;
561                 ir->mask_keycode = 0x1f8;
562                 break;
563         case BTTV_BOARD_MAGICTVIEW061:
564         case BTTV_BOARD_MAGICTVIEW063:
565                 ir_codes         = ir_codes_winfast;
566                 ir->mask_keycode = 0x0008e000;
567                 ir->mask_keydown = 0x00200000;
568                 break;
569         case BTTV_BOARD_APAC_VIEWCOMP:
570                 ir_codes         = ir_codes_apac_viewcomp;
571                 ir->mask_keycode = 0x001f00;
572                 ir->mask_keyup   = 0x008000;
573                 ir->polling      = 50; // ms
574                 break;
575         case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
576                 ir_codes         = ir_codes_conceptronic;
577                 ir->mask_keycode = 0x001F00;
578                 ir->mask_keyup   = 0x006000;
579                 ir->polling      = 50; // ms
580                 break;
581         case BTTV_BOARD_NEBULA_DIGITV:
582                 ir_codes = ir_codes_nebula;
583                 btv->custom_irq = bttv_rc5_irq;
584                 ir->rc5_gpio = 1;
585                 break;
586         case BTTV_BOARD_MACHTV_MAGICTV:
587                 ir_codes         = ir_codes_apac_viewcomp;
588                 ir->mask_keycode = 0x001F00;
589                 ir->mask_keyup   = 0x004000;
590                 ir->polling      = 50; /* ms */
591                 break;
592         }
593         if (NULL == ir_codes) {
594                 dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n",btv->c.type);
595                 kfree(ir);
596                 input_free_device(input_dev);
597                 return -ENODEV;
598         }
599
600         if (ir->rc5_gpio) {
601                 u32 gpio;
602                 /* enable remote irq */
603                 bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4);
604                 gpio = bttv_gpio_read(&btv->c);
605                 bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
606                 bttv_gpio_write(&btv->c, gpio | (1 << 4));
607         } else {
608                 /* init hardware-specific stuff */
609                 bttv_gpio_inout(&btv->c, ir->mask_keycode | ir->mask_keydown, 0);
610         }
611
612         /* init input device */
613         ir->dev = input_dev;
614
615         snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
616                  btv->c.type);
617         snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
618                  pci_name(btv->c.pci));
619
620         ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
621         input_dev->name = ir->name;
622         input_dev->phys = ir->phys;
623         input_dev->id.bustype = BUS_PCI;
624         input_dev->id.version = 1;
625         if (btv->c.pci->subsystem_vendor) {
626                 input_dev->id.vendor  = btv->c.pci->subsystem_vendor;
627                 input_dev->id.product = btv->c.pci->subsystem_device;
628         } else {
629                 input_dev->id.vendor  = btv->c.pci->vendor;
630                 input_dev->id.product = btv->c.pci->device;
631         }
632         input_dev->cdev.dev = &btv->c.pci->dev;
633
634         btv->remote = ir;
635         if (ir->polling) {
636                 init_timer(&ir->timer);
637                 ir->timer.function = bttv_input_timer;
638                 ir->timer.data     = (unsigned long)btv;
639                 ir->timer.expires  = jiffies + HZ;
640                 add_timer(&ir->timer);
641         } else if (ir->rc5_gpio) {
642                 /* set timer_end for code completion */
643                 init_timer(&ir->timer_end);
644                 ir->timer_end.function = bttv_rc5_timer_end;
645                 ir->timer_end.data = (unsigned long)ir;
646
647                 init_timer(&ir->timer_keyup);
648                 ir->timer_keyup.function = bttv_rc5_timer_keyup;
649                 ir->timer_keyup.data = (unsigned long)ir;
650         }
651
652         /* all done */
653         input_register_device(btv->remote->dev);
654         printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys);
655
656         /* the remote isn't as bouncy as a keyboard */
657         ir->dev->rep[REP_DELAY] = repeat_delay;
658         ir->dev->rep[REP_PERIOD] = repeat_period;
659
660         return 0;
661 }
662
663 void bttv_input_fini(struct bttv *btv)
664 {
665         if (btv->remote == NULL)
666                 return;
667
668         if (btv->remote->polling) {
669                 del_timer_sync(&btv->remote->timer);
670                 flush_scheduled_work();
671         }
672
673
674         if (btv->remote->rc5_gpio) {
675                 u32 gpio;
676
677                 del_timer_sync(&btv->remote->timer_end);
678                 flush_scheduled_work();
679
680                 gpio = bttv_gpio_read(&btv->c);
681                 bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
682         }
683
684         input_unregister_device(btv->remote->dev);
685         kfree(btv->remote);
686         btv->remote = NULL;
687 }
688
689
690 /*
691  * Local variables:
692  * c-basic-offset: 8
693  * End:
694  */