Fix an OOPS when initializing IR remote on saa7134
[usb.git] / drivers / media / video / saa7134 / saa7134-input.c
blobab75ca5ac356b16862b0957f9a85d56dd5f650b4
1 /*
3 * handle saa7134 IR remotes via linux kernel input layer.
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.
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.
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
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>
29 #include "saa7134-reg.h"
30 #include "saa7134.h"
32 static unsigned int disable_ir = 0;
33 module_param(disable_ir, int, 0444);
34 MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
36 static unsigned int ir_debug = 0;
37 module_param(ir_debug, int, 0644);
38 MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
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)
45 /* ---------------------------------------------------------------------- */
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,
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
72 [ 26 ] = KEY_F22, // Stereo
73 [ 24 ] = KEY_EDIT, // AV Source
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,
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,
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
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
134 [ 49 ] = KEY_HELP, // help
135 [ 50 ] = KEY_MODE, // num/memo
136 [ 51 ] = KEY_ESC, // cancel
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
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
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,
164 [ 42 ] = KEY_VOLUMEUP,
165 [ 17 ] = KEY_VOLUMEDOWN,
166 [ 24 ] = KEY_CHANNELUP, // CH.tracking up
167 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
169 [ 19 ] = KEY_KPENTER, // enter
170 [ 33 ] = KEY_KPDOT, // . (decimal dot)
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
178 [ 22 ] = KEY_VOLUMEUP,
179 [ 20 ] = KEY_VOLUMEDOWN,
180 [ 31 ] = KEY_CHANNELUP,
181 [ 23 ] = KEY_CHANNELDOWN,
182 [ 24 ] = KEY_MUTE,
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,
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
200 [ 0 ] = KEY_RECORD,
201 [ 8 ] = KEY_STOP,
202 [ 17 ] = KEY_PLAY,
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
210 // FIXME
211 [ 13 ] = KEY_F21, // mts
212 [ 15 ] = KEY_F22, // min
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,
228 [ 32 ] = KEY_TV, // TV/FM
229 [ 16 ] = KEY_CD, // CD
230 [ 48 ] = KEY_TEXT, // TELETEXT
231 [ 0 ] = KEY_POWER, // POWER
233 [ 8 ] = KEY_VIDEO, // VIDEO
234 [ 4 ] = KEY_AUDIO, // AUDIO
235 [ 12 ] = KEY_ZOOM, // FULL SCREEN
237 [ 18 ] = KEY_SUBTITLE, // DISPLAY - ???
238 [ 50 ] = KEY_REWIND, // LOOP - ???
239 [ 2 ] = KEY_PRINT, // PREVIEW - ???
241 [ 42 ] = KEY_SEARCH, // AUTOSCAN
242 [ 26 ] = KEY_SLEEP, // FREEZE - ???
243 [ 58 ] = KEY_SHUFFLE, // SNAPSHOT - ???
244 [ 10 ] = KEY_MUTE, // MUTE
246 [ 38 ] = KEY_RECORD, // RECORD
247 [ 22 ] = KEY_PAUSE, // PAUSE
248 [ 54 ] = KEY_STOP, // STOP
249 [ 6 ] = KEY_PLAY, // PLAY
251 [ 46 ] = KEY_RED, // <RED>
252 [ 33 ] = KEY_GREEN, // <GREEN>
253 [ 14 ] = KEY_YELLOW, // <YELLOW>
254 [ 1 ] = KEY_BLUE, // <BLUE>
256 [ 30 ] = KEY_VOLUMEDOWN, // VOLUME-
257 [ 62 ] = KEY_VOLUMEUP, // VOLUME+
258 [ 17 ] = KEY_CHANNELDOWN, // CHANNEL/PAGE-
259 [ 49 ] = KEY_CHANNELUP // CHANNEL/PAGE+
262 static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = {
263 [ 20 ] = KEY_MUTE,
264 [ 36 ] = KEY_ZOOM,
266 [ 1 ] = KEY_DVD,
267 [ 35 ] = KEY_RADIO,
268 [ 0 ] = KEY_TV,
270 [ 10 ] = KEY_REWIND,
271 [ 8 ] = KEY_PLAYPAUSE,
272 [ 15 ] = KEY_FORWARD,
274 [ 2 ] = KEY_PREVIOUS,
275 [ 7 ] = KEY_STOP,
276 [ 6 ] = KEY_NEXT,
278 [ 12 ] = KEY_UP,
279 [ 14 ] = KEY_DOWN,
280 [ 11 ] = KEY_LEFT,
281 [ 13 ] = KEY_RIGHT,
282 [ 17 ] = KEY_OK,
284 [ 3 ] = KEY_MENU,
285 [ 9 ] = KEY_SETUP,
286 [ 5 ] = KEY_VIDEO,
287 [ 34 ] = KEY_CHANNEL,
289 [ 18 ] = KEY_VOLUMEUP,
290 [ 21 ] = KEY_VOLUMEDOWN,
291 [ 16 ] = KEY_CHANNELUP,
292 [ 19 ] = KEY_CHANNELDOWN,
294 [ 4 ] = KEY_RECORD,
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,
307 [ 32 ] = KEY_LANGUAGE,
308 [ 33 ] = KEY_SLEEP,
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.
320 static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
322 /* 0x1c 0x12 *
323 * FUNCTION POWER *
324 * FM (|) *
325 * */
326 [ 0x1c ] = KEY_RADIO, /*XXX*/
327 [ 0x12 ] = KEY_POWER,
329 /* 0x01 0x02 0x03 *
330 * 1 2 3 *
332 * 0x04 0x05 0x06 *
333 * 4 5 6 *
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,
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*/
356 /* 0x14 0x10 *
357 * MENU INFO *
358 * OSD */
359 [ 0x14 ] = KEY_MENU,
360 [ 0x10 ] = KEY_INFO,
362 /* 0x0b *
363 * Up *
365 * 0x18 0x16 0x0c *
366 * Left Ok Right *
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? */
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 */
384 /* 0x0f 0x1b 0x1a *
385 * AUDIO Vol+ Chan+ *
386 * TIMESHIFT??? *
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,
398 /* 0x13 0x19 *
399 * MUTE SNAPSHOT*
400 * */
401 [ 0x13 ] = KEY_MUTE,
402 [ 0x19 ] = KEY_RECORD, /*XXX*/
404 // 0x1d unused ?
408 /* Mike Baikov <mike@baikov.com> */
409 static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = {
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,
442 [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */
443 [ 26 ] = KEY_F22, /* MIN TIMESHIFT */
444 [ 58 ] = KEY_F23, /* TIMESHIFT */
445 [ 112] = KEY_F24, /* NORMAL TIMESHIFT */
448 static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
449 [ 0x3 ] = KEY_POWER,
450 [ 0x6f ] = KEY_MUTE,
451 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
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+ */
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,
475 [ 0x1b ] = KEY_VIDEO, /* Video source */
476 [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
477 [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
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 ? */
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,
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,
524 /* -------------------- GPIO generic keycode builder -------------------- */
526 static int build_key(struct saa7134_dev *dev)
528 struct saa7134_ir *ir = dev->remote;
529 u32 gpio, data;
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);
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;
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);
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);
552 return 0;
555 /* --------------------- Chip specific I2C key builders ----------------- */
557 static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
559 unsigned char b;
561 /* poll IR chip */
562 if (1 != i2c_master_recv(&ir->c,&b,1)) {
563 i2cdprintk("read error\n");
564 return -EIO;
567 /* no button press */
568 if (b==0)
569 return 0;
571 /* repeating */
572 if (b & 0x80)
573 return 1;
575 *ir_key = b;
576 *ir_raw = b;
577 return 1;
580 void saa7134_input_irq(struct saa7134_dev *dev)
582 struct saa7134_ir *ir = dev->remote;
584 if (!ir->polling)
585 build_key(dev);
588 static void saa7134_input_timer(unsigned long data)
590 struct saa7134_dev *dev = (struct saa7134_dev*)data;
591 struct saa7134_ir *ir = dev->remote;
592 unsigned long timeout;
594 build_key(dev);
595 timeout = jiffies + (ir->polling * HZ / 1000);
596 mod_timer(&ir->timer, timeout);
599 int saa7134_input_init1(struct saa7134_dev *dev)
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;
610 if (dev->has_remote != SAA7134_REMOTE_GPIO)
611 return -ENODEV;
612 if (disable_ir)
613 return -ENODEV;
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;
702 if (NULL == ir_codes) {
703 printk("%s: Oops: IR config error [card=%d]\n",
704 dev->name, dev->board);
705 return -ENODEV;
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;
716 ir->dev = input_dev;
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;
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));
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;
742 input_dev->cdev.dev = &dev->pci->dev;
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);
754 input_register_device(ir->dev);
755 return 0;
758 void saa7134_input_fini(struct saa7134_dev *dev)
760 if (NULL == dev->remote)
761 return;
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;
770 void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
772 if (disable_ir) {
773 dprintk("Found supported i2c remote, but IR has been disabled\n");
774 ir->get_key=NULL;
775 return;
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;
795 /* ----------------------------------------------------------------------
796 * Local variables:
797 * c-basic-offset: 8
798 * End: