patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / drivers / media / video / ir-kbd-gpio.c
1 /*
2  * Copyright (c) 2003 Gerd Knorr
3  * Copyright (c) 2003 Pavel Machek
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 #include <linux/module.h>
21 #include <linux/moduleparam.h>
22 #include <linux/init.h>
23 #include <linux/delay.h>
24 #include <linux/interrupt.h>
25 #include <linux/input.h>
26 #include <linux/pci.h>
27
28 #include <media/ir-common.h>
29
30 #include "bttv.h"
31
32 /* ---------------------------------------------------------------------- */
33
34 static IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = {
35         [ 17 ] = KEY_KP0, 
36         [ 20 ] = KEY_KP1, 
37         [ 12 ] = KEY_KP2, 
38         [ 28 ] = KEY_KP3, 
39         [ 18 ] = KEY_KP4, 
40         [ 10 ] = KEY_KP5, 
41         [ 26 ] = KEY_KP6, 
42         [ 22 ] = KEY_KP7, 
43         [ 14 ] = KEY_KP8, 
44         [ 30 ] = KEY_KP9, 
45
46         [ 24 ] = KEY_EJECTCD,     // Unmarked on my controller
47         [  0 ] = KEY_POWER, 
48         [  9 ] = BTN_LEFT,        // DISPLAY/L
49         [ 25 ] = BTN_RIGHT,       // LOOP/R
50         [  5 ] = KEY_MUTE, 
51         [ 19 ] = KEY_RECORD, 
52         [ 11 ] = KEY_PAUSE, 
53         [ 27 ] = KEY_STOP, 
54         [ 15 ] = KEY_VOLUMEDOWN, 
55         [ 31 ] = KEY_VOLUMEUP, 
56
57         [ 16 ] = KEY_TUNER,       // TV/FM
58         [  8 ] = KEY_CD, 
59         [  4 ] = KEY_VIDEO, 
60         [  2 ] = KEY_AUDIO, 
61         [  6 ] = KEY_ZOOM,        // full screen
62         [  1 ] = KEY_INFO,        // preview 
63         [ 21 ] = KEY_SEARCH,      // autoscan
64         [ 13 ] = KEY_STOP,        // freeze 
65         [ 29 ] = KEY_RECORD,      // capture 
66         [  3 ] = KEY_PLAY,        // unmarked
67         [ 23 ] = KEY_RED,         // unmarked
68         [  7 ] = KEY_GREEN,       // unmarked
69
70 #if 0
71         [ 16 ] = KEY_YELLOW,      // unmarked
72         [  8 ] = KEY_CHANNELDOWN, 
73         [ 24 ] = KEY_CHANNELUP, 
74         [  0 ] = KEY_BLUE,        // unmarked
75 #endif
76 };
77
78 static IR_KEYTAB_TYPE winfast_codes[IR_KEYTAB_SIZE] = {
79         [  5 ] = KEY_KP1,
80         [  6 ] = KEY_KP2,
81         [  7 ] = KEY_KP3,
82         [  9 ] = KEY_KP4,
83         [ 10 ] = KEY_KP5,
84         [ 11 ] = KEY_KP6,
85         [ 13 ] = KEY_KP7,
86         [ 14 ] = KEY_KP8,
87         [ 15 ] = KEY_KP9,
88         [ 18 ] = KEY_KP0,
89
90         [  0 ] = KEY_POWER,
91 //      [ 27 ] = MTS button
92         [  2 ] = KEY_TUNER,     // TV/FM
93         [ 30 ] = KEY_VIDEO,
94 //      [ 22 ] = display button
95         [  4 ] = KEY_VOLUMEUP,
96         [  8 ] = KEY_VOLUMEDOWN,
97         [ 12 ] = KEY_CHANNELUP,
98         [ 16 ] = KEY_CHANNELDOWN,
99         [  3 ] = KEY_ZOOM,      // fullscreen
100         [ 31 ] = KEY_SUBTITLE,  // closed caption/teletext
101         [ 32 ] = KEY_SLEEP,
102 //      [ 41 ] = boss key
103         [ 20 ] = KEY_MUTE,
104         [ 43 ] = KEY_RED,
105         [ 44 ] = KEY_GREEN,
106         [ 45 ] = KEY_YELLOW,
107         [ 46 ] = KEY_BLUE,
108         [ 24 ] = KEY_KPPLUS,    //fine tune +
109         [ 25 ] = KEY_KPMINUS,   //fine tune -
110 //      [ 42 ] = picture in picture
111         [ 33 ] = KEY_KPDOT,
112         [ 19 ] = KEY_KPENTER,
113 //      [ 17 ] = recall
114         [ 34 ] = KEY_BACK,
115         [ 35 ] = KEY_PLAYPAUSE,
116         [ 36 ] = KEY_NEXT,
117 //      [ 37 ] = time shifting
118         [ 38 ] = KEY_STOP,
119         [ 39 ] = KEY_RECORD
120 //      [ 40 ] = snapshot
121 };
122
123 static IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
124         [  2 ] = KEY_KP0,
125         [  1 ] = KEY_KP1,
126         [ 11 ] = KEY_KP2,
127         [ 27 ] = KEY_KP3,
128         [  5 ] = KEY_KP4,
129         [  9 ] = KEY_KP5,
130         [ 21 ] = KEY_KP6,
131         [  6 ] = KEY_KP7,
132         [ 10 ] = KEY_KP8,
133         [ 18 ] = KEY_KP9,
134         
135         [  3 ] = KEY_TUNER,       // TV/FM
136         [  7 ] = KEY_SEARCH,      // scan
137         [ 28 ] = KEY_ZOOM,        // full screen
138         [ 30 ] = KEY_POWER,
139         [ 23 ] = KEY_VOLUMEDOWN,
140         [ 31 ] = KEY_VOLUMEUP,
141         [ 20 ] = KEY_CHANNELDOWN,
142         [ 22 ] = KEY_CHANNELUP,
143         [ 24 ] = KEY_MUTE,
144         
145         [  0 ] = KEY_LIST,        // source
146         [ 19 ] = KEY_INFO,        // loop
147         [ 16 ] = KEY_LAST,        // +100
148         [ 13 ] = KEY_CLEAR,       // reset
149         [ 12 ] = BTN_RIGHT,       // fun++
150         [  4 ] = BTN_LEFT,        // fun--
151         [ 14 ] = KEY_GOTO,        // function
152         [ 15 ] = KEY_STOP,         // freeze
153 };
154
155 /* ---------------------------------------------------------------------- */
156
157 struct IR {
158         struct bttv_sub_device  *sub;
159         struct input_dev        input;
160         struct ir_input_state   ir;
161         char                    name[32];
162         char                    phys[32];
163         u32                     mask_keycode;
164         u32                     mask_keydown;
165         u32                     mask_keyup;
166
167         int                     polling;
168         u32                     last_gpio;
169         struct work_struct      work;
170         struct timer_list       timer;
171 };
172
173 static int debug;
174 module_param(debug, int, 0644);    /* debug level (0,1,2) */
175
176 #define DEVNAME "ir-kbd-gpio"
177 #define dprintk(fmt, arg...)    if (debug) \
178         printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
179
180 static void ir_irq(struct bttv_sub_device *sub);
181 static int ir_probe(struct device *dev);
182 static int ir_remove(struct device *dev);
183
184 static struct bttv_sub_driver driver = {
185         .drv = {
186                 .name   = DEVNAME,
187                 .probe  = ir_probe,
188                 .remove = ir_remove,
189         },
190         .gpio_irq       = ir_irq,
191 };
192
193 /* ---------------------------------------------------------------------- */
194
195 static void ir_handle_key(struct IR *ir)
196 {
197         u32 gpio,data;
198
199         /* read gpio value */
200         gpio = bttv_gpio_read(ir->sub->core);
201         if (ir->polling) {
202                 if (ir->last_gpio == gpio)
203                         return;
204                 ir->last_gpio = gpio;
205         }
206         
207         /* extract data */
208         data = ir_extract_bits(gpio, ir->mask_keycode);
209         dprintk(DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n",
210                 gpio, data,
211                 ir->polling               ? "poll"  : "irq",
212                 (gpio & ir->mask_keydown) ? " down" : "",
213                 (gpio & ir->mask_keyup)   ? " up"   : "");
214
215         if (ir->mask_keydown) {
216                 /* bit set on keydown */
217                 if (gpio & ir->mask_keydown) {
218                         ir_input_keydown(&ir->input,&ir->ir,data,data);
219                 } else {
220                         ir_input_nokey(&ir->input,&ir->ir);
221                 }
222
223         } else if (ir->mask_keyup) {
224                 /* bit cleared on keydown */
225                 if (0 == (gpio & ir->mask_keyup)) {
226                         ir_input_keydown(&ir->input,&ir->ir,data,data);
227                 } else {
228                         ir_input_nokey(&ir->input,&ir->ir);
229                 }
230
231         } else {
232                 /* can't disturgissh keydown/up :-/ */
233                 ir_input_keydown(&ir->input,&ir->ir,data,data);
234                 ir_input_nokey(&ir->input,&ir->ir);
235         }
236 }
237
238 static void ir_irq(struct bttv_sub_device *sub)
239 {
240         struct IR *ir = dev_get_drvdata(&sub->dev);
241
242         if (!ir->polling)
243                 ir_handle_key(ir);
244 }
245
246 static void ir_timer(unsigned long data)
247 {
248         struct IR *ir = (struct IR*)data;
249
250         schedule_work(&ir->work);
251 }
252
253 static void ir_work(void *data)
254 {
255         struct IR *ir = data;
256         unsigned long timeout;
257
258         ir_handle_key(ir);
259         timeout = jiffies + (ir->polling * HZ / 1000);
260         mod_timer(&ir->timer, timeout);
261 }
262
263 /* ---------------------------------------------------------------------- */
264
265 static int ir_probe(struct device *dev)
266 {
267         struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
268         struct IR *ir;
269         IR_KEYTAB_TYPE *ir_codes = NULL;
270         int ir_type = IR_TYPE_OTHER;
271
272         ir = kmalloc(sizeof(*ir),GFP_KERNEL);
273         if (NULL == ir)
274                 return -ENOMEM;
275         memset(ir,0,sizeof(*ir));
276
277         /* detect & configure */
278         switch (sub->core->type) {
279         case BTTV_AVERMEDIA:
280         case BTTV_AVPHONE98:
281         case BTTV_AVERMEDIA98:
282                 ir_codes         = ir_codes_avermedia;
283                 ir->mask_keycode = 0xf80000;
284                 ir->mask_keydown = 0x010000;
285                 break;
286
287         case BTTV_PXELVWPLTVPAK:
288                 ir_codes         = ir_codes_pixelview;
289                 ir->mask_keycode = 0x003e00;
290                 ir->mask_keyup   = 0x010000;
291                 ir->polling      = 50; // ms
292                 break;
293         case BTTV_PV_BT878P_9B:
294         case BTTV_PV_BT878P_PLUS:
295                 ir_codes         = ir_codes_pixelview;
296                 ir->mask_keycode = 0x001f00;
297                 ir->mask_keyup   = 0x008000;
298                 ir->polling      = 50; // ms
299                 break;
300
301         case BTTV_WINFAST2000:
302                 ir_codes         = winfast_codes;
303                 ir->mask_keycode = 0x8f8;
304                 break;
305         case BTTV_MAGICTVIEW061:
306         case BTTV_MAGICTVIEW063:
307                 ir_codes         = winfast_codes;
308                 ir->mask_keycode = 0x0008e000;
309                 ir->mask_keydown = 0x00200000;
310                 break;
311         }
312         if (NULL == ir_codes) {
313                 kfree(ir);
314                 return -ENODEV;
315         }
316
317         /* init hardware-specific stuff */
318         bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0);
319         ir->sub = sub;
320         
321         /* init input device */
322         snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
323                  sub->core->type);
324         snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
325                  pci_name(sub->core->pci));
326
327         ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
328         ir->input.name = ir->name;
329         ir->input.phys = ir->phys;
330         ir->input.id.bustype = BUS_PCI;
331         ir->input.id.version = 1;
332         if (sub->core->pci->subsystem_vendor) {
333                 ir->input.id.vendor  = sub->core->pci->subsystem_vendor;
334                 ir->input.id.product = sub->core->pci->subsystem_device;
335         } else {
336                 ir->input.id.vendor  = sub->core->pci->vendor;
337                 ir->input.id.product = sub->core->pci->device;
338         }
339
340         if (ir->polling) {
341                 INIT_WORK(&ir->work, ir_work, ir);
342                 init_timer(&ir->timer);
343                 ir->timer.function = ir_timer;
344                 ir->timer.data     = (unsigned long)ir;
345                 schedule_work(&ir->work);
346         }
347
348         /* all done */
349         dev_set_drvdata(dev,ir);
350         input_register_device(&ir->input);
351         printk(DEVNAME ": %s detected at %s\n",ir->input.name,ir->input.phys);
352
353         return 0;
354 }
355
356 static int ir_remove(struct device *dev)
357 {
358         struct IR *ir = dev_get_drvdata(dev);
359
360         if (ir->polling) {
361                 del_timer(&ir->timer);
362                 flush_scheduled_work();
363         }
364
365         input_unregister_device(&ir->input);
366         kfree(ir);
367         return 0;
368 }
369
370 /* ---------------------------------------------------------------------- */
371
372 MODULE_AUTHOR("Gerd Knorr, Pavel Machek");
373 MODULE_DESCRIPTION("input driver for bt8x8 gpio IR remote controls");
374 MODULE_LICENSE("GPL");
375
376 static int ir_init(void)
377 {
378         return bttv_sub_register(&driver, "remote");
379 }
380
381 static void ir_fini(void)
382 {
383         bttv_sub_unregister(&driver);
384 }
385
386 module_init(ir_init);
387 module_exit(ir_fini);
388
389
390 /*
391  * Local variables:
392  * c-basic-offset: 8
393  * End:
394  */