]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/media/video/saa7134/saa7134-input.c
[PATCH] V4L: 913: saa713x cards with i2c remotes now autoload ir-kbd-i2c
[net-next-2.6.git] / drivers / media / video / saa7134 / saa7134-input.c
CommitLineData
1da177e4 1/*
1da177e4
LT
2 *
3 * handle saa7134 IR remotes via linux kernel input layer.
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
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>
28
29#include "saa7134-reg.h"
30#include "saa7134.h"
31
32static unsigned int disable_ir = 0;
33module_param(disable_ir, int, 0444);
34MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
35
36static unsigned int ir_debug = 0;
37module_param(ir_debug, int, 0644);
38MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
39
40#define dprintk(fmt, arg...) if (ir_debug) \
41 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
ac9cd976
RC
42#define i2cdprintk(fmt, arg...) if (ir_debug) \
43 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
1da177e4
LT
44
45/* ---------------------------------------------------------------------- */
46
47static 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,
58
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
71
1da177e4
LT
72 [ 26 ] = KEY_F22, // Stereo
73 [ 24 ] = KEY_EDIT, // AV Source
1da177e4
LT
74};
75
76static 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,
87
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,
114};
115
116/* Alfons Geser <a.geser@cox.net>
117 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
118static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
4ac97914
MCC
119 [ 18 ] = KEY_POWER,
120 [ 1 ] = KEY_TV, // DVR
121 [ 21 ] = KEY_DVD, // DVD
122 [ 23 ] = KEY_AUDIO, // music
f2421ca3 123 // DVR mode / DVD mode / music mode
4ac97914
MCC
124
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
133
134 [ 49 ] = KEY_HELP, // help
135 [ 50 ] = KEY_MODE, // num/memo
136 [ 51 ] = KEY_ESC, // cancel
1da177e4
LT
137
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
143
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
152
4ac97914
MCC
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,
163
164 [ 42 ] = KEY_VOLUMEUP,
165 [ 17 ] = KEY_VOLUMEDOWN,
166 [ 24 ] = KEY_CHANNELUP, // CH.tracking up
167 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
168
169 [ 19 ] = KEY_KPENTER, // enter
170 [ 33 ] = KEY_KPDOT, // . (decimal dot)
1da177e4
LT
171};
172
173static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
330a115a 174 [ 30 ] = KEY_POWER, // power
1da177e4 175 [ 28 ] = KEY_SEARCH, // scan
330a115a 176 [ 7 ] = KEY_SELECT, // source
1da177e4
LT
177
178 [ 22 ] = KEY_VOLUMEUP,
179 [ 20 ] = KEY_VOLUMEDOWN,
330a115a 180 [ 31 ] = KEY_CHANNELUP,
1da177e4
LT
181 [ 23 ] = KEY_CHANNELDOWN,
182 [ 24 ] = KEY_MUTE,
183
184 [ 2 ] = KEY_KP0,
330a115a
MCC
185 [ 1 ] = KEY_KP1,
186 [ 11 ] = KEY_KP2,
187 [ 27 ] = KEY_KP3,
188 [ 5 ] = KEY_KP4,
189 [ 9 ] = KEY_KP5,
190 [ 21 ] = KEY_KP6,
1da177e4 191 [ 6 ] = KEY_KP7,
330a115a 192 [ 10 ] = KEY_KP8,
1da177e4
LT
193 [ 18 ] = KEY_KP9,
194 [ 16 ] = KEY_KPDOT,
195
196 [ 3 ] = KEY_TUNER, // tv/fm
330a115a
MCC
197 [ 4 ] = KEY_REWIND, // fm tuning left or function left
198 [ 12 ] = KEY_FORWARD, // fm tuning right or function right
1da177e4
LT
199
200 [ 0 ] = KEY_RECORD,
330a115a
MCC
201 [ 8 ] = KEY_STOP,
202 [ 17 ] = KEY_PLAY,
1da177e4
LT
203
204 [ 25 ] = KEY_ZOOM,
205 [ 14 ] = KEY_MENU, // function
206 [ 19 ] = KEY_AGAIN, // recall
207 [ 29 ] = KEY_RESTART, // reset
330a115a 208 [ 26 ] = KEY_SHUFFLE, // snapshot/shuffle
1da177e4
LT
209
210// FIXME
211 [ 13 ] = KEY_F21, // mts
330a115a 212 [ 15 ] = KEY_F22, // min
1da177e4
LT
213};
214
215/* Alex Hermann <gaaf@gmx.net> */
216static 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,
227
228 [ 32 ] = KEY_TV, // TV/FM
229 [ 16 ] = KEY_CD, // CD
230 [ 48 ] = KEY_TEXT, // TELETEXT
231 [ 0 ] = KEY_POWER, // POWER
232
233 [ 8 ] = KEY_VIDEO, // VIDEO
234 [ 4 ] = KEY_AUDIO, // AUDIO
235 [ 12 ] = KEY_ZOOM, // FULL SCREEN
236
237 [ 18 ] = KEY_SUBTITLE, // DISPLAY - ???
238 [ 50 ] = KEY_REWIND, // LOOP - ???
239 [ 2 ] = KEY_PRINT, // PREVIEW - ???
240
241 [ 42 ] = KEY_SEARCH, // AUTOSCAN
242 [ 26 ] = KEY_SLEEP, // FREEZE - ???
243 [ 58 ] = KEY_SHUFFLE, // SNAPSHOT - ???
244 [ 10 ] = KEY_MUTE, // MUTE
245
246 [ 38 ] = KEY_RECORD, // RECORD
247 [ 22 ] = KEY_PAUSE, // PAUSE
248 [ 54 ] = KEY_STOP, // STOP
249 [ 6 ] = KEY_PLAY, // PLAY
250
251 [ 46 ] = KEY_RED, // <RED>
252 [ 33 ] = KEY_GREEN, // <GREEN>
253 [ 14 ] = KEY_YELLOW, // <YELLOW>
254 [ 1 ] = KEY_BLUE, // <BLUE>
255
256 [ 30 ] = KEY_VOLUMEDOWN, // VOLUME-
257 [ 62 ] = KEY_VOLUMEUP, // VOLUME+
258 [ 17 ] = KEY_CHANNELDOWN, // CHANNEL/PAGE-
259 [ 49 ] = KEY_CHANNELUP // CHANNEL/PAGE+
260};
261
262static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = {
263 [ 20 ] = KEY_MUTE,
264 [ 36 ] = KEY_ZOOM,
265
266 [ 1 ] = KEY_DVD,
267 [ 35 ] = KEY_RADIO,
268 [ 0 ] = KEY_TV,
269
270 [ 10 ] = KEY_REWIND,
271 [ 8 ] = KEY_PLAYPAUSE,
272 [ 15 ] = KEY_FORWARD,
273
274 [ 2 ] = KEY_PREVIOUS,
275 [ 7 ] = KEY_STOP,
276 [ 6 ] = KEY_NEXT,
277
278 [ 12 ] = KEY_UP,
279 [ 14 ] = KEY_DOWN,
280 [ 11 ] = KEY_LEFT,
281 [ 13 ] = KEY_RIGHT,
282 [ 17 ] = KEY_OK,
283
284 [ 3 ] = KEY_MENU,
285 [ 9 ] = KEY_SETUP,
286 [ 5 ] = KEY_VIDEO,
287 [ 34 ] = KEY_CHANNEL,
288
289 [ 18 ] = KEY_VOLUMEUP,
290 [ 21 ] = KEY_VOLUMEDOWN,
291 [ 16 ] = KEY_CHANNELUP,
292 [ 19 ] = KEY_CHANNELDOWN,
293
294 [ 4 ] = KEY_RECORD,
295
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,
306
307 [ 32 ] = KEY_LANGUAGE,
308 [ 33 ] = KEY_SLEEP,
309};
ac19ecc6
MCC
310
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.
319 */
320static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
321
322 /* 0x1c 0x12 *
323 * FUNCTION POWER *
324 * FM (|) *
325 * */
326 [ 0x1c ] = KEY_RADIO, /*XXX*/
327 [ 0x12 ] = KEY_POWER,
328
329 /* 0x01 0x02 0x03 *
330 * 1 2 3 *
331 * *
332 * 0x04 0x05 0x06 *
333 * 4 5 6 *
334 * *
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,
347
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*/
355
356 /* 0x14 0x10 *
357 * MENU INFO *
358 * OSD */
359 [ 0x14 ] = KEY_MENU,
360 [ 0x10 ] = KEY_INFO,
361
362 /* 0x0b *
363 * Up *
364 * *
365 * 0x18 0x16 0x0c *
366 * Left Ok Right *
367 * *
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? */
376
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 */
383
384 /* 0x0f 0x1b 0x1a *
385 * AUDIO Vol+ Chan+ *
386 * TIMESHIFT??? *
387 * *
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,
397
398 /* 0x13 0x19 *
399 * MUTE SNAPSHOT*
400 * */
401 [ 0x13 ] = KEY_MUTE,
402 [ 0x19 ] = KEY_RECORD, /*XXX*/
403
404 // 0x1d unused ?
405};
6b961440
NS
406
407
dcd555ec 408/* Mike Baikov <mike@baikov.com> */
6b961440
NS
409static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = {
410
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,
441
442 [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */
443 [ 26 ] = KEY_F22, /* MIN TIMESHIFT */
444 [ 58 ] = KEY_F23, /* TIMESHIFT */
445 [ 112] = KEY_F24, /* NORMAL TIMESHIFT */
446};
447
ac9cd976
RC
448static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
449 [ 0x3 ] = KEY_POWER,
450 [ 0x6f ] = KEY_MUTE,
451 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
452
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+ */
464
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,
474
475 [ 0x1b ] = KEY_VIDEO, /* Video source */
476 [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
477 [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
478
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 ? */
485
486};
487
488static IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
489 [ 0x59 ] = KEY_MUTE,
490 [ 0x4a ] = KEY_POWER,
491
492 [ 0x18 ] = KEY_TEXT,
493 [ 0x26 ] = KEY_TV,
494 [ 0x3d ] = KEY_PRINT,
495
496 [ 0x48 ] = KEY_RED,
497 [ 0x04 ] = KEY_GREEN,
498 [ 0x11 ] = KEY_YELLOW,
499 [ 0x00 ] = KEY_BLUE,
500
501 [ 0x2d ] = KEY_VOLUMEUP,
502 [ 0x1e ] = KEY_VOLUMEDOWN,
503
504 [ 0x49 ] = KEY_MENU,
505
506 [ 0x16 ] = KEY_CHANNELUP,
507 [ 0x17 ] = KEY_CHANNELDOWN,
508
509 [ 0x20 ] = KEY_UP,
510 [ 0x21 ] = KEY_DOWN,
511 [ 0x22 ] = KEY_LEFT,
512 [ 0x23 ] = KEY_RIGHT,
513 [ 0x0d ] = KEY_SELECT,
514
515
516
517 [ 0x08 ] = KEY_BACK,
518 [ 0x07 ] = KEY_REFRESH,
519
520 [ 0x2f ] = KEY_ZOOM,
521 [ 0x29 ] = KEY_RECORD,
522
523 [ 0x4b ] = KEY_PAUSE,
524 [ 0x4d ] = KEY_REWIND,
525 [ 0x2e ] = KEY_PLAY,
526 [ 0x4e ] = KEY_FORWARD,
527 [ 0x53 ] = KEY_PREVIOUS,
528 [ 0x4c ] = KEY_STOP,
529 [ 0x54 ] = KEY_NEXT,
530
531 [ 0x69 ] = KEY_KP0,
532 [ 0x6a ] = KEY_KP1,
533 [ 0x6b ] = KEY_KP2,
534 [ 0x6c ] = KEY_KP3,
535 [ 0x6d ] = KEY_KP4,
536 [ 0x6e ] = KEY_KP5,
537 [ 0x6f ] = KEY_KP6,
538 [ 0x70 ] = KEY_KP7,
539 [ 0x71 ] = KEY_KP8,
540 [ 0x72 ] = KEY_KP9,
541
542 [ 0x74 ] = KEY_CHANNEL,
543 [ 0x0a ] = KEY_BACKSPACE,
544};
545
c3d93192
PM
546/* Mapping for the 28 key remote control as seen at
547 http://www.sednacomputer.com/photo/cardbus-tv.jpg
548 Pavel Mihaylov <bin@bash.info> */
549static IR_KEYTAB_TYPE pctv_cardbus_codes[IR_KEYTAB_SIZE] = {
550 [ 0 ] = KEY_KP0,
551 [ 1 ] = KEY_KP1,
552 [ 2 ] = KEY_KP2,
553 [ 3 ] = KEY_KP3,
554 [ 4 ] = KEY_KP4,
555 [ 5 ] = KEY_KP5,
556 [ 6 ] = KEY_KP6,
557 [ 7 ] = KEY_KP7,
558 [ 8 ] = KEY_KP8,
559 [ 9 ] = KEY_KP9,
560
561 [ 0x0a ] = KEY_AGAIN, /* Recall */
562 [ 0x0b ] = KEY_CHANNELUP,
563 [ 0x0c ] = KEY_VOLUMEUP,
564 [ 0x0d ] = KEY_MODE, /* Stereo */
565 [ 0x0e ] = KEY_STOP,
566 [ 0x0f ] = KEY_PREVIOUSSONG,
567 [ 0x10 ] = KEY_ZOOM,
568 [ 0x11 ] = KEY_TUNER, /* Source */
569 [ 0x12 ] = KEY_POWER,
570 [ 0x13 ] = KEY_MUTE,
571 [ 0x15 ] = KEY_CHANNELDOWN,
572 [ 0x18 ] = KEY_VOLUMEDOWN,
573 [ 0x19 ] = KEY_SHUFFLE, /* Snapshot */
574 [ 0x1a ] = KEY_NEXTSONG,
575 [ 0x1b ] = KEY_TEXT, /* Time Shift */
576 [ 0x1c ] = KEY_RADIO, /* FM Radio */
577 [ 0x1d ] = KEY_RECORD,
578 [ 0x1e ] = KEY_PAUSE,
579};
580
581
ac9cd976 582/* -------------------- GPIO generic keycode builder -------------------- */
1da177e4
LT
583
584static int build_key(struct saa7134_dev *dev)
585{
586 struct saa7134_ir *ir = dev->remote;
587 u32 gpio, data;
588
589 /* rising SAA7134_GPIO_GPRESCAN reads the status */
590 saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
591 saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
592
593 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
4ac97914
MCC
594 if (ir->polling) {
595 if (ir->last_gpio == gpio)
596 return 0;
597 ir->last_gpio = gpio;
598 }
1da177e4 599
4ac97914 600 data = ir_extract_bits(gpio, ir->mask_keycode);
1da177e4
LT
601 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
602 gpio, ir->mask_keycode, data);
603
604 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
605 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
b7df3910 606 ir_input_keydown(ir->dev, &ir->ir, data, data);
1da177e4 607 } else {
b7df3910 608 ir_input_nokey(ir->dev, &ir->ir);
1da177e4
LT
609 }
610 return 0;
611}
612
ac9cd976
RC
613/* --------------------- Chip specific I2C key builders ----------------- */
614
615static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
616{
617 unsigned char b;
618
619 /* poll IR chip */
620 if (1 != i2c_master_recv(&ir->c,&b,1)) {
621 i2cdprintk("read error\n");
622 return -EIO;
623 }
624
625 /* no button press */
626 if (b==0)
627 return 0;
628
629 /* repeating */
630 if (b & 0x80)
631 return 1;
632
633 *ir_key = b;
634 *ir_raw = b;
635 return 1;
636}
637
638/* The new pinnacle PCTV remote (with the colored buttons)
639 *
640 * Ricardo Cerqueira <v4l@cerqueira.org>
641 */
642
643static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
644{
645 unsigned char b[4];
646 unsigned int start = 0,parity = 0,code = 0;
647
648 /* poll IR chip */
649 if (4 != i2c_master_recv(&ir->c,b,4)) {
650 i2cdprintk("read error\n");
651 return -EIO;
652 }
653
654 for (start = 0; start<4; start++) {
655 if (b[start] == 0x80) {
e8b23c02
RC
656 code=b[(start+3)%4];
657 parity=b[(start+2)%4];
ac9cd976
RC
658 }
659 }
660
661 /* Empty Request */
662 if (parity==0)
663 return 0;
664
665 /* Repeating... */
666 if (ir->old == parity)
667 return 0;
668
669
670 ir->old = parity;
671
672 /* Reduce code value to fit inside IR_KEYTAB_SIZE
673 *
674 * this is the only value that results in 42 unique
675 * codes < 128
676 */
677
678 code %= 0x88;
679
680 *ir_raw = code;
681 *ir_key = code;
682
683 i2cdprintk("Pinnacle PCTV key %02x\n", code);
684
685 return 1;
686}
687
1da177e4
LT
688
689void saa7134_input_irq(struct saa7134_dev *dev)
690{
4ac97914 691 struct saa7134_ir *ir = dev->remote;
1da177e4 692
4ac97914 693 if (!ir->polling)
1da177e4
LT
694 build_key(dev);
695}
696
697static void saa7134_input_timer(unsigned long data)
698{
699 struct saa7134_dev *dev = (struct saa7134_dev*)data;
700 struct saa7134_ir *ir = dev->remote;
701 unsigned long timeout;
702
703 build_key(dev);
704 timeout = jiffies + (ir->polling * HZ / 1000);
705 mod_timer(&ir->timer, timeout);
706}
707
708int saa7134_input_init1(struct saa7134_dev *dev)
709{
710 struct saa7134_ir *ir;
b7df3910 711 struct input_dev *input_dev;
1da177e4
LT
712 IR_KEYTAB_TYPE *ir_codes = NULL;
713 u32 mask_keycode = 0;
714 u32 mask_keydown = 0;
715 u32 mask_keyup = 0;
716 int polling = 0;
717 int ir_type = IR_TYPE_OTHER;
718
cb2444df 719 if (dev->has_remote != SAA7134_REMOTE_GPIO)
1da177e4
LT
720 return -ENODEV;
721 if (disable_ir)
722 return -ENODEV;
723
724 /* detect & configure */
725 switch (dev->board) {
726 case SAA7134_BOARD_FLYVIDEO2000:
727 case SAA7134_BOARD_FLYVIDEO3000:
4ac97914 728 case SAA7134_BOARD_FLYTVPLATINUM_FM:
6af90ab5 729 case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
1da177e4
LT
730 ir_codes = flyvideo_codes;
731 mask_keycode = 0xEC00000;
732 mask_keydown = 0x0040000;
733 break;
734 case SAA7134_BOARD_CINERGY400:
735 case SAA7134_BOARD_CINERGY600:
736 case SAA7134_BOARD_CINERGY600_MK3:
737 ir_codes = cinergy_codes;
738 mask_keycode = 0x00003f;
739 mask_keyup = 0x040000;
740 break;
741 case SAA7134_BOARD_ECS_TVP3XP:
742 case SAA7134_BOARD_ECS_TVP3XP_4CB5:
330a115a
MCC
743 ir_codes = eztv_codes;
744 mask_keycode = 0x00017c;
745 mask_keyup = 0x000002;
1da177e4 746 polling = 50; // ms
330a115a
MCC
747 break;
748 case SAA7134_BOARD_KWORLD_XPERT:
1da177e4 749 case SAA7134_BOARD_AVACSSMARTTV:
330a115a 750 ir_codes = avacssmart_codes;
1da177e4
LT
751 mask_keycode = 0x00001F;
752 mask_keyup = 0x000020;
753 polling = 50; // ms
754 break;
755 case SAA7134_BOARD_MD2819:
ac19ecc6 756 case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
1da177e4
LT
757 case SAA7134_BOARD_AVERMEDIA_305:
758 case SAA7134_BOARD_AVERMEDIA_307:
ac19ecc6
MCC
759 case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
760 case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
761 case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
1da177e4
LT
762 ir_codes = md2819_codes;
763 mask_keycode = 0x0007C8;
764 mask_keydown = 0x000010;
765 polling = 50; // ms
766 /* Set GPIO pin2 to high to enable the IR controller */
767 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
768 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
769 break;
4ac97914 770 case SAA7134_BOARD_KWORLD_TERMINATOR:
dc2286cf
JW
771 ir_codes = avacssmart_codes;
772 mask_keycode = 0x00001f;
773 mask_keyup = 0x000060;
774 polling = 50; // ms
775 break;
ac19ecc6
MCC
776 case SAA7134_BOARD_MANLI_MTV001:
777 case SAA7134_BOARD_MANLI_MTV002:
a8ff417e 778 case SAA7134_BOARD_BEHOLD_409FM:
ac19ecc6
MCC
779 ir_codes = manli_codes;
780 mask_keycode = 0x001f00;
781 mask_keyup = 0x004000;
ac19ecc6
MCC
782 polling = 50; // ms
783 break;
c3d93192
PM
784 case SAA7134_BOARD_PCTV_CARDBUS:
785 ir_codes = pctv_cardbus_codes;
786 mask_keycode = 0x001f00;
787 mask_keyup = 0x004000;
788 polling = 50; // ms
789 break;
4ac97914 790 case SAA7134_BOARD_GOTVIEW_7135:
6b961440
NS
791 ir_codes = gotview7135_codes;
792 mask_keycode = 0x0003EC;
793 mask_keyup = 0x008000;
794 mask_keydown = 0x000010;
795 polling = 50; // ms
796 break;
1da177e4 797 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
330a115a 798 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
1da177e4
LT
799 ir_codes = videomate_tv_pvr_codes;
800 mask_keycode = 0x00003F;
801 mask_keyup = 0x400000;
802 polling = 50; // ms
803 break;
4ac97914
MCC
804 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
805 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
fea095fe
NS
806 ir_codes = videomate_tv_pvr_codes;
807 mask_keycode = 0x003F00;
808 mask_keyup = 0x040000;
809 break;
1da177e4
LT
810 }
811 if (NULL == ir_codes) {
812 printk("%s: Oops: IR config error [card=%d]\n",
813 dev->name, dev->board);
814 return -ENODEV;
815 }
816
b7df3910
DT
817 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
818 input_dev = input_allocate_device();
819 if (!ir || !input_dev) {
820 kfree(ir);
821 input_free_device(input_dev);
1da177e4 822 return -ENOMEM;
b7df3910 823 }
1da177e4
LT
824
825 /* init hardware-specific stuff */
826 ir->mask_keycode = mask_keycode;
827 ir->mask_keydown = mask_keydown;
828 ir->mask_keyup = mask_keyup;
4ac97914 829 ir->polling = polling;
1da177e4
LT
830
831 /* init input device */
832 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
833 saa7134_boards[dev->board].name);
834 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
835 pci_name(dev->pci));
836
b7df3910
DT
837 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
838 input_dev->name = ir->name;
839 input_dev->phys = ir->phys;
840 input_dev->id.bustype = BUS_PCI;
841 input_dev->id.version = 1;
1da177e4 842 if (dev->pci->subsystem_vendor) {
b7df3910
DT
843 input_dev->id.vendor = dev->pci->subsystem_vendor;
844 input_dev->id.product = dev->pci->subsystem_device;
1da177e4 845 } else {
b7df3910
DT
846 input_dev->id.vendor = dev->pci->vendor;
847 input_dev->id.product = dev->pci->device;
1da177e4 848 }
b7df3910 849 input_dev->cdev.dev = &dev->pci->dev;
1da177e4
LT
850
851 /* all done */
852 dev->remote = ir;
853 if (ir->polling) {
854 init_timer(&ir->timer);
855 ir->timer.function = saa7134_input_timer;
856 ir->timer.data = (unsigned long)dev;
857 ir->timer.expires = jiffies + HZ;
858 add_timer(&ir->timer);
859 }
860
b7df3910 861 input_register_device(ir->dev);
1da177e4
LT
862 return 0;
863}
864
865void saa7134_input_fini(struct saa7134_dev *dev)
866{
867 if (NULL == dev->remote)
868 return;
869
1da177e4
LT
870 if (dev->remote->polling)
871 del_timer_sync(&dev->remote->timer);
b7df3910 872 input_unregister_device(dev->remote->dev);
1da177e4
LT
873 kfree(dev->remote);
874 dev->remote = NULL;
875}
876
ac9cd976
RC
877void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
878{
879 if (disable_ir) {
cb2444df 880 dprintk("Found supported i2c remote, but IR has been disabled\n");
ac9cd976
RC
881 ir->get_key=NULL;
882 return;
883 }
884
885 switch (dev->board) {
886 case SAA7134_BOARD_PINNACLE_PCTV_110i:
887 snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV");
888 ir->get_key = get_key_pinnacle;
889 ir->ir_codes = ir_codes_pinnacle;
890 break;
891 case SAA7134_BOARD_UPMOST_PURPLE_TV:
892 snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV");
893 ir->get_key = get_key_purpletv;
894 ir->ir_codes = ir_codes_purpletv;
895 break;
896 default:
897 dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
898 break;
899 }
900
901}
1da177e4
LT
902/* ----------------------------------------------------------------------
903 * Local variables:
904 * c-basic-offset: 8
905 * End:
906 */