vserver 1.9.5.x5
[linux-2.6.git] / drivers / media / video / ir-kbd-gpio.c
1 /*
2  * $Id: ir-kbd-gpio.c,v 1.11 2004/10/25 11:26:36 kraxel Exp $
3  *
4  * Copyright (c) 2003 Gerd Knorr
5  * Copyright (c) 2003 Pavel Machek
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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/interrupt.h>
27 #include <linux/input.h>
28 #include <linux/pci.h>
29
30 #include <media/ir-common.h>
31
32 #include "bttv.h"
33
34 /* ---------------------------------------------------------------------- */
35
36 static IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = {
37         [ 34 ] = KEY_KP0,
38         [ 40 ] = KEY_KP1,
39         [ 24 ] = KEY_KP2,
40         [ 56 ] = KEY_KP3,
41         [ 36 ] = KEY_KP4,
42         [ 20 ] = KEY_KP5,
43         [ 52 ] = KEY_KP6,
44         [ 44 ] = KEY_KP7,
45         [ 28 ] = KEY_KP8,
46         [ 60 ] = KEY_KP9,
47
48         [ 48 ] = KEY_EJECTCD,     // Unmarked on my controller
49         [  0 ] = KEY_POWER,
50         [ 18 ] = BTN_LEFT,        // DISPLAY/L
51         [ 50 ] = BTN_RIGHT,       // LOOP/R
52         [ 10 ] = KEY_MUTE,
53         [ 38 ] = KEY_RECORD,
54         [ 22 ] = KEY_PAUSE,
55         [ 54 ] = KEY_STOP,
56         [ 30 ] = KEY_VOLUMEDOWN,
57         [ 62 ] = KEY_VOLUMEUP,
58
59         [ 32 ] = KEY_TUNER,       // TV/FM
60         [ 16 ] = KEY_CD,
61         [  8 ] = KEY_VIDEO,
62         [  4 ] = KEY_AUDIO,
63         [ 12 ] = KEY_ZOOM,        // full screen
64         [  2 ] = KEY_INFO,        // preview
65         [ 42 ] = KEY_SEARCH,      // autoscan
66         [ 26 ] = KEY_STOP,        // freeze
67         [ 58 ] = KEY_RECORD,      // capture
68         [  6 ] = KEY_PLAY,        // unmarked
69         [ 46 ] = KEY_RED,         // unmarked
70         [ 14 ] = KEY_GREEN,       // unmarked
71
72         [ 33 ] = KEY_YELLOW,      // unmarked
73         [ 17 ] = KEY_CHANNELDOWN,
74         [ 49 ] = KEY_CHANNELUP,
75         [  1 ] = KEY_BLUE,        // unmarked
76 };
77
78 /* Matt Jesson <dvb@jesson.eclipse.co.uk */
79 static IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = {
80         [ 0x28 ] = KEY_KP0,         //'0' / 'enter'
81         [ 0x22 ] = KEY_KP1,         //'1'
82         [ 0x12 ] = KEY_KP2,         //'2' / 'up arrow'
83         [ 0x32 ] = KEY_KP3,         //'3'
84         [ 0x24 ] = KEY_KP4,         //'4' / 'left arrow'
85         [ 0x14 ] = KEY_KP5,         //'5'
86         [ 0x34 ] = KEY_KP6,         //'6' / 'right arrow'
87         [ 0x26 ] = KEY_KP7,         //'7'
88         [ 0x16 ] = KEY_KP8,         //'8' / 'down arrow'
89         [ 0x36 ] = KEY_KP9,         //'9'
90
91         [ 0x20 ] = KEY_LIST,        // 'source'
92         [ 0x10 ] = KEY_TEXT,        // 'teletext'
93         [ 0x00 ] = KEY_POWER,       // 'power'
94         [ 0x04 ] = KEY_AUDIO,       // 'audio'
95         [ 0x06 ] = KEY_ZOOM,        // 'full screen'
96         [ 0x18 ] = KEY_VIDEO,       // 'display'
97         [ 0x38 ] = KEY_SEARCH,      // 'loop'
98         [ 0x08 ] = KEY_INFO,        // 'preview'
99         [ 0x2a ] = KEY_REWIND,      // 'backward <<'
100         [ 0x1a ] = KEY_FASTFORWARD, // 'forward >>'
101         [ 0x3a ] = KEY_RECORD,      // 'capture'
102         [ 0x0a ] = KEY_MUTE,        // 'mute'
103         [ 0x2c ] = KEY_RECORD,      // 'record'
104         [ 0x1c ] = KEY_PAUSE,       // 'pause'
105         [ 0x3c ] = KEY_STOP,        // 'stop'
106         [ 0x0c ] = KEY_PLAY,        // 'play'
107         [ 0x2e ] = KEY_RED,         // 'red'
108         [ 0x01 ] = KEY_BLUE,        // 'blue' / 'cancel'
109         [ 0x0e ] = KEY_YELLOW,      // 'yellow' / 'ok'
110         [ 0x21 ] = KEY_GREEN,       // 'green'
111         [ 0x11 ] = KEY_CHANNELDOWN, // 'channel -'
112         [ 0x31 ] = KEY_CHANNELUP,   // 'channel +'
113         [ 0x1e ] = KEY_VOLUMEDOWN,  // 'volume -'
114         [ 0x3e ] = KEY_VOLUMEUP,    // 'volume +'
115 };
116
117 static IR_KEYTAB_TYPE winfast_codes[IR_KEYTAB_SIZE] = {
118         [  5 ] = KEY_KP1,
119         [  6 ] = KEY_KP2,
120         [  7 ] = KEY_KP3,
121         [  9 ] = KEY_KP4,
122         [ 10 ] = KEY_KP5,
123         [ 11 ] = KEY_KP6,
124         [ 13 ] = KEY_KP7,
125         [ 14 ] = KEY_KP8,
126         [ 15 ] = KEY_KP9,
127         [ 18 ] = KEY_KP0,
128
129         [  0 ] = KEY_POWER,
130 //      [ 27 ] = MTS button
131         [  2 ] = KEY_TUNER,     // TV/FM
132         [ 30 ] = KEY_VIDEO,
133 //      [ 22 ] = display button
134         [  4 ] = KEY_VOLUMEUP,
135         [  8 ] = KEY_VOLUMEDOWN,
136         [ 12 ] = KEY_CHANNELUP,
137         [ 16 ] = KEY_CHANNELDOWN,
138         [  3 ] = KEY_ZOOM,      // fullscreen
139         [ 31 ] = KEY_SUBTITLE,  // closed caption/teletext
140         [ 32 ] = KEY_SLEEP,
141 //      [ 41 ] = boss key
142         [ 20 ] = KEY_MUTE,
143         [ 43 ] = KEY_RED,
144         [ 44 ] = KEY_GREEN,
145         [ 45 ] = KEY_YELLOW,
146         [ 46 ] = KEY_BLUE,
147         [ 24 ] = KEY_KPPLUS,    //fine tune +
148         [ 25 ] = KEY_KPMINUS,   //fine tune -
149 //      [ 42 ] = picture in picture
150         [ 33 ] = KEY_KPDOT,
151         [ 19 ] = KEY_KPENTER,
152 //      [ 17 ] = recall
153         [ 34 ] = KEY_BACK,
154         [ 35 ] = KEY_PLAYPAUSE,
155         [ 36 ] = KEY_NEXT,
156 //      [ 37 ] = time shifting
157         [ 38 ] = KEY_STOP,
158         [ 39 ] = KEY_RECORD
159 //      [ 40 ] = snapshot
160 };
161
162 static IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
163         [  2 ] = KEY_KP0,
164         [  1 ] = KEY_KP1,
165         [ 11 ] = KEY_KP2,
166         [ 27 ] = KEY_KP3,
167         [  5 ] = KEY_KP4,
168         [  9 ] = KEY_KP5,
169         [ 21 ] = KEY_KP6,
170         [  6 ] = KEY_KP7,
171         [ 10 ] = KEY_KP8,
172         [ 18 ] = KEY_KP9,
173
174         [  3 ] = KEY_TUNER,       // TV/FM
175         [  7 ] = KEY_SEARCH,      // scan
176         [ 28 ] = KEY_ZOOM,        // full screen
177         [ 30 ] = KEY_POWER,
178         [ 23 ] = KEY_VOLUMEDOWN,
179         [ 31 ] = KEY_VOLUMEUP,
180         [ 20 ] = KEY_CHANNELDOWN,
181         [ 22 ] = KEY_CHANNELUP,
182         [ 24 ] = KEY_MUTE,
183
184         [  0 ] = KEY_LIST,        // source
185         [ 19 ] = KEY_INFO,        // loop
186         [ 16 ] = KEY_LAST,        // +100
187         [ 13 ] = KEY_CLEAR,       // reset
188         [ 12 ] = BTN_RIGHT,       // fun++
189         [  4 ] = BTN_LEFT,        // fun--
190         [ 14 ] = KEY_GOTO,        // function
191         [ 15 ] = KEY_STOP,         // freeze
192 };
193
194 /* Attila Kondoros <attila.kondoros@chello.hu> */
195 static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
196
197         [  1 ] = KEY_KP1,
198         [  2 ] = KEY_KP2,
199         [  3 ] = KEY_KP3,
200         [  4 ] = KEY_KP4,
201         [  5 ] = KEY_KP5,
202         [  6 ] = KEY_KP6,
203         [  7 ] = KEY_KP7,
204         [  8 ] = KEY_KP8,
205         [  9 ] = KEY_KP9,
206         [  0 ] = KEY_KP0,
207         [ 23 ] = KEY_LAST,        // +100
208         [ 10 ] = KEY_LIST,        // recall
209
210
211         [ 28 ] = KEY_TUNER,       // TV/FM
212         [ 21 ] = KEY_SEARCH,      // scan
213         [ 18 ] = KEY_POWER,       // power
214         [ 31 ] = KEY_VOLUMEDOWN,  // vol up
215         [ 27 ] = KEY_VOLUMEUP,    // vol down
216         [ 30 ] = KEY_CHANNELDOWN, // chn up
217         [ 26 ] = KEY_CHANNELUP,   // chn down
218
219         [ 17 ] = KEY_VIDEO,       // video
220         [ 15 ] = KEY_ZOOM,        // full screen
221         [ 19 ] = KEY_MUTE,        // mute/unmute
222         [ 16 ] = KEY_TEXT,        // min
223
224         [ 13 ] = KEY_STOP,        // freeze
225         [ 14 ] = KEY_RECORD,      // record
226         [ 29 ] = KEY_PLAYPAUSE,   // stop
227         [ 25 ] = KEY_PLAY,        // play
228
229         [ 22 ] = KEY_GOTO,        // osd
230         [ 20 ] = KEY_REFRESH,     // default
231         [ 12 ] = KEY_KPPLUS,      // fine tune >>>>
232         [ 24 ] = KEY_KPMINUS      // fine tune <<<<
233 };
234
235 /* ---------------------------------------------------------------------- */
236
237 struct IR {
238         struct bttv_sub_device  *sub;
239         struct input_dev        input;
240         struct ir_input_state   ir;
241         char                    name[32];
242         char                    phys[32];
243         u32                     mask_keycode;
244         u32                     mask_keydown;
245         u32                     mask_keyup;
246
247         int                     polling;
248         u32                     last_gpio;
249         struct work_struct      work;
250         struct timer_list       timer;
251 };
252
253 static int debug;
254 module_param(debug, int, 0644);    /* debug level (0,1,2) */
255
256 #define DEVNAME "ir-kbd-gpio"
257 #define dprintk(fmt, arg...)    if (debug) \
258         printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
259
260 static void ir_irq(struct bttv_sub_device *sub);
261 static int ir_probe(struct device *dev);
262 static int ir_remove(struct device *dev);
263
264 static struct bttv_sub_driver driver = {
265         .drv = {
266                 .name   = DEVNAME,
267                 .probe  = ir_probe,
268                 .remove = ir_remove,
269         },
270         .gpio_irq       = ir_irq,
271 };
272
273 /* ---------------------------------------------------------------------- */
274
275 static void ir_handle_key(struct IR *ir)
276 {
277         u32 gpio,data;
278
279         /* read gpio value */
280         gpio = bttv_gpio_read(ir->sub->core);
281         if (ir->polling) {
282                 if (ir->last_gpio == gpio)
283                         return;
284                 ir->last_gpio = gpio;
285         }
286
287         /* extract data */
288         data = ir_extract_bits(gpio, ir->mask_keycode);
289         dprintk(DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n",
290                 gpio, data,
291                 ir->polling               ? "poll"  : "irq",
292                 (gpio & ir->mask_keydown) ? " down" : "",
293                 (gpio & ir->mask_keyup)   ? " up"   : "");
294
295         if (ir->mask_keydown) {
296                 /* bit set on keydown */
297                 if (gpio & ir->mask_keydown) {
298                         ir_input_keydown(&ir->input,&ir->ir,data,data);
299                 } else {
300                         ir_input_nokey(&ir->input,&ir->ir);
301                 }
302
303         } else if (ir->mask_keyup) {
304                 /* bit cleared on keydown */
305                 if (0 == (gpio & ir->mask_keyup)) {
306                         ir_input_keydown(&ir->input,&ir->ir,data,data);
307                 } else {
308                         ir_input_nokey(&ir->input,&ir->ir);
309                 }
310
311         } else {
312                 /* can't disturgissh keydown/up :-/ */
313                 ir_input_keydown(&ir->input,&ir->ir,data,data);
314                 ir_input_nokey(&ir->input,&ir->ir);
315         }
316 }
317
318 static void ir_irq(struct bttv_sub_device *sub)
319 {
320         struct IR *ir = dev_get_drvdata(&sub->dev);
321
322         if (!ir->polling)
323                 ir_handle_key(ir);
324 }
325
326 static void ir_timer(unsigned long data)
327 {
328         struct IR *ir = (struct IR*)data;
329
330         schedule_work(&ir->work);
331 }
332
333 static void ir_work(void *data)
334 {
335         struct IR *ir = data;
336         unsigned long timeout;
337
338         ir_handle_key(ir);
339         timeout = jiffies + (ir->polling * HZ / 1000);
340         mod_timer(&ir->timer, timeout);
341 }
342
343 /* ---------------------------------------------------------------------- */
344
345 static int ir_probe(struct device *dev)
346 {
347         struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
348         struct IR *ir;
349         IR_KEYTAB_TYPE *ir_codes = NULL;
350         int ir_type = IR_TYPE_OTHER;
351
352         ir = kmalloc(sizeof(*ir),GFP_KERNEL);
353         if (NULL == ir)
354                 return -ENOMEM;
355         memset(ir,0,sizeof(*ir));
356
357         /* detect & configure */
358         switch (sub->core->type) {
359         case BTTV_AVERMEDIA:
360         case BTTV_AVPHONE98:
361         case BTTV_AVERMEDIA98:
362                 ir_codes         = ir_codes_avermedia;
363                 ir->mask_keycode = 0xf88000;
364                 ir->mask_keydown = 0x010000;
365                 ir->polling      = 50; // ms
366                 break;
367
368         case BTTV_AVDVBT_761:
369         case BTTV_AVDVBT_771:
370                 ir_codes         = ir_codes_avermedia_dvbt;
371                 ir->mask_keycode = 0x0f00c0;
372                 ir->mask_keydown = 0x000020;
373                 ir->polling      = 50; // ms
374                 break;
375
376         case BTTV_PXELVWPLTVPAK:
377                 ir_codes         = ir_codes_pixelview;
378                 ir->mask_keycode = 0x003e00;
379                 ir->mask_keyup   = 0x010000;
380                 ir->polling      = 50; // ms
381                 break;
382         case BTTV_PV_BT878P_9B:
383         case BTTV_PV_BT878P_PLUS:
384                 ir_codes         = ir_codes_pixelview;
385                 ir->mask_keycode = 0x001f00;
386                 ir->mask_keyup   = 0x008000;
387                 ir->polling      = 50; // ms
388                 break;
389
390         case BTTV_WINFAST2000:
391                 ir_codes         = winfast_codes;
392                 ir->mask_keycode = 0x1f8;
393                 break;
394         case BTTV_MAGICTVIEW061:
395         case BTTV_MAGICTVIEW063:
396                 ir_codes         = winfast_codes;
397                 ir->mask_keycode = 0x0008e000;
398                 ir->mask_keydown = 0x00200000;
399                 break;
400         case BTTV_APAC_VIEWCOMP:
401                 ir_codes         = ir_codes_apac_viewcomp;
402                 ir->mask_keycode = 0x001f00;
403                 ir->mask_keyup   = 0x008000;
404                 ir->polling      = 50; // ms
405                 break;
406         }
407         if (NULL == ir_codes) {
408                 kfree(ir);
409                 return -ENODEV;
410         }
411
412         /* init hardware-specific stuff */
413         bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0);
414         ir->sub = sub;
415
416         /* init input device */
417         snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
418                  sub->core->type);
419         snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
420                  pci_name(sub->core->pci));
421
422         ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
423         ir->input.name = ir->name;
424         ir->input.phys = ir->phys;
425         ir->input.id.bustype = BUS_PCI;
426         ir->input.id.version = 1;
427         if (sub->core->pci->subsystem_vendor) {
428                 ir->input.id.vendor  = sub->core->pci->subsystem_vendor;
429                 ir->input.id.product = sub->core->pci->subsystem_device;
430         } else {
431                 ir->input.id.vendor  = sub->core->pci->vendor;
432                 ir->input.id.product = sub->core->pci->device;
433         }
434
435         if (ir->polling) {
436                 INIT_WORK(&ir->work, ir_work, ir);
437                 init_timer(&ir->timer);
438                 ir->timer.function = ir_timer;
439                 ir->timer.data     = (unsigned long)ir;
440                 schedule_work(&ir->work);
441         }
442
443         /* all done */
444         dev_set_drvdata(dev,ir);
445         input_register_device(&ir->input);
446         printk(DEVNAME ": %s detected at %s\n",ir->input.name,ir->input.phys);
447
448         return 0;
449 }
450
451 static int ir_remove(struct device *dev)
452 {
453         struct IR *ir = dev_get_drvdata(dev);
454
455         if (ir->polling) {
456                 del_timer(&ir->timer);
457                 flush_scheduled_work();
458         }
459
460         input_unregister_device(&ir->input);
461         kfree(ir);
462         return 0;
463 }
464
465 /* ---------------------------------------------------------------------- */
466
467 MODULE_AUTHOR("Gerd Knorr, Pavel Machek");
468 MODULE_DESCRIPTION("input driver for bt8x8 gpio IR remote controls");
469 MODULE_LICENSE("GPL");
470
471 static int ir_init(void)
472 {
473         return bttv_sub_register(&driver, "remote");
474 }
475
476 static void ir_fini(void)
477 {
478         bttv_sub_unregister(&driver);
479 }
480
481 module_init(ir_init);
482 module_exit(ir_fini);
483
484
485 /*
486  * Local variables:
487  * c-basic-offset: 8
488  * End:
489  */