blob: f99dbb729555673f1ed045b0fe90e9f492616608 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 *
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)
42
43/* ---------------------------------------------------------------------- */
44
45static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = {
46 [ 15 ] = KEY_KP0,
47 [ 3 ] = KEY_KP1,
48 [ 4 ] = KEY_KP2,
49 [ 5 ] = KEY_KP3,
50 [ 7 ] = KEY_KP4,
51 [ 8 ] = KEY_KP5,
52 [ 9 ] = KEY_KP6,
53 [ 11 ] = KEY_KP7,
54 [ 12 ] = KEY_KP8,
55 [ 13 ] = KEY_KP9,
56
57 [ 14 ] = KEY_TUNER, // Air/Cable
58 [ 17 ] = KEY_VIDEO, // Video
59 [ 21 ] = KEY_AUDIO, // Audio
60 [ 0 ] = KEY_POWER, // Pover
61 [ 2 ] = KEY_ZOOM, // Fullscreen
62 [ 27 ] = KEY_MUTE, // Mute
63 [ 20 ] = KEY_VOLUMEUP,
64 [ 23 ] = KEY_VOLUMEDOWN,
65 [ 18 ] = KEY_CHANNELUP, // Channel +
66 [ 19 ] = KEY_CHANNELDOWN, // Channel -
67 [ 6 ] = KEY_AGAIN, // Recal
68 [ 16 ] = KEY_KPENTER, // Enter
69
Linus Torvalds1da177e2005-04-16 15:20:36 -070070 [ 26 ] = KEY_F22, // Stereo
71 [ 24 ] = KEY_EDIT, // AV Source
Linus Torvalds1da177e2005-04-16 15:20:36 -070072};
73
74static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
75 [ 0 ] = KEY_KP0,
76 [ 1 ] = KEY_KP1,
77 [ 2 ] = KEY_KP2,
78 [ 3 ] = KEY_KP3,
79 [ 4 ] = KEY_KP4,
80 [ 5 ] = KEY_KP5,
81 [ 6 ] = KEY_KP6,
82 [ 7 ] = KEY_KP7,
83 [ 8 ] = KEY_KP8,
84 [ 9 ] = KEY_KP9,
85
86 [ 0x0a ] = KEY_POWER,
87 [ 0x0b ] = KEY_PROG1, // app
88 [ 0x0c ] = KEY_ZOOM, // zoom/fullscreen
89 [ 0x0d ] = KEY_CHANNELUP, // channel
90 [ 0x0e ] = KEY_CHANNELDOWN, // channel-
91 [ 0x0f ] = KEY_VOLUMEUP,
92 [ 0x10 ] = KEY_VOLUMEDOWN,
93 [ 0x11 ] = KEY_TUNER, // AV
94 [ 0x12 ] = KEY_NUMLOCK, // -/--
95 [ 0x13 ] = KEY_AUDIO, // audio
96 [ 0x14 ] = KEY_MUTE,
97 [ 0x15 ] = KEY_UP,
98 [ 0x16 ] = KEY_DOWN,
99 [ 0x17 ] = KEY_LEFT,
100 [ 0x18 ] = KEY_RIGHT,
101 [ 0x19 ] = BTN_LEFT,
102 [ 0x1a ] = BTN_RIGHT,
103 [ 0x1b ] = KEY_WWW, // text
104 [ 0x1c ] = KEY_REWIND,
105 [ 0x1d ] = KEY_FORWARD,
106 [ 0x1e ] = KEY_RECORD,
107 [ 0x1f ] = KEY_PLAY,
108 [ 0x20 ] = KEY_PREVIOUSSONG,
109 [ 0x21 ] = KEY_NEXTSONG,
110 [ 0x22 ] = KEY_PAUSE,
111 [ 0x23 ] = KEY_STOP,
112};
113
114/* Alfons Geser <a.geser@cox.net>
115 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
116static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800117 [ 18 ] = KEY_POWER,
118 [ 1 ] = KEY_TV, // DVR
119 [ 21 ] = KEY_DVD, // DVD
120 [ 23 ] = KEY_AUDIO, // music
Mauro Carvalho Chehabf2421ca2005-11-08 21:37:45 -0800121 // DVR mode / DVD mode / music mode
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800123 [ 27 ] = KEY_MUTE, // mute
124 [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek
125 [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek
126 [ 22 ] = KEY_ZOOM, // full screen
127 [ 28 ] = KEY_VIDEO, // video source / eject / delall
128 [ 29 ] = KEY_RESTART, // playback / angle / del
129 [ 47 ] = KEY_SEARCH, // scan / menu / playlist
130 [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800132 [ 49 ] = KEY_HELP, // help
133 [ 50 ] = KEY_MODE, // num/memo
134 [ 51 ] = KEY_ESC, // cancel
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
136 [ 12 ] = KEY_UP, // up
137 [ 16 ] = KEY_DOWN, // down
138 [ 8 ] = KEY_LEFT, // left
139 [ 4 ] = KEY_RIGHT, // right
140 [ 3 ] = KEY_SELECT, // select
141
142 [ 31 ] = KEY_REWIND, // rewind
143 [ 32 ] = KEY_PLAYPAUSE, // play/pause
144 [ 41 ] = KEY_FORWARD, // forward
145 [ 20 ] = KEY_AGAIN, // repeat
146 [ 43 ] = KEY_RECORD, // recording
147 [ 44 ] = KEY_STOP, // stop
148 [ 45 ] = KEY_PLAY, // play
149 [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle
150
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800151 [ 0 ] = KEY_KP0,
152 [ 5 ] = KEY_KP1,
153 [ 6 ] = KEY_KP2,
154 [ 7 ] = KEY_KP3,
155 [ 9 ] = KEY_KP4,
156 [ 10 ] = KEY_KP5,
157 [ 11 ] = KEY_KP6,
158 [ 13 ] = KEY_KP7,
159 [ 14 ] = KEY_KP8,
160 [ 15 ] = KEY_KP9,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800162 [ 42 ] = KEY_VOLUMEUP,
163 [ 17 ] = KEY_VOLUMEDOWN,
164 [ 24 ] = KEY_CHANNELUP, // CH.tracking up
165 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800167 [ 19 ] = KEY_KPENTER, // enter
168 [ 33 ] = KEY_KPDOT, // . (decimal dot)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169};
170
171static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700172 [ 30 ] = KEY_POWER, // power
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173 [ 28 ] = KEY_SEARCH, // scan
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700174 [ 7 ] = KEY_SELECT, // source
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175
176 [ 22 ] = KEY_VOLUMEUP,
177 [ 20 ] = KEY_VOLUMEDOWN,
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700178 [ 31 ] = KEY_CHANNELUP,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 [ 23 ] = KEY_CHANNELDOWN,
180 [ 24 ] = KEY_MUTE,
181
182 [ 2 ] = KEY_KP0,
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700183 [ 1 ] = KEY_KP1,
184 [ 11 ] = KEY_KP2,
185 [ 27 ] = KEY_KP3,
186 [ 5 ] = KEY_KP4,
187 [ 9 ] = KEY_KP5,
188 [ 21 ] = KEY_KP6,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 [ 6 ] = KEY_KP7,
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700190 [ 10 ] = KEY_KP8,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 [ 18 ] = KEY_KP9,
192 [ 16 ] = KEY_KPDOT,
193
194 [ 3 ] = KEY_TUNER, // tv/fm
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700195 [ 4 ] = KEY_REWIND, // fm tuning left or function left
196 [ 12 ] = KEY_FORWARD, // fm tuning right or function right
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197
198 [ 0 ] = KEY_RECORD,
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700199 [ 8 ] = KEY_STOP,
200 [ 17 ] = KEY_PLAY,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201
202 [ 25 ] = KEY_ZOOM,
203 [ 14 ] = KEY_MENU, // function
204 [ 19 ] = KEY_AGAIN, // recall
205 [ 29 ] = KEY_RESTART, // reset
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700206 [ 26 ] = KEY_SHUFFLE, // snapshot/shuffle
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207
208// FIXME
209 [ 13 ] = KEY_F21, // mts
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700210 [ 15 ] = KEY_F22, // min
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211};
212
213/* Alex Hermann <gaaf@gmx.net> */
214static IR_KEYTAB_TYPE md2819_codes[IR_KEYTAB_SIZE] = {
215 [ 40 ] = KEY_KP1,
216 [ 24 ] = KEY_KP2,
217 [ 56 ] = KEY_KP3,
218 [ 36 ] = KEY_KP4,
219 [ 20 ] = KEY_KP5,
220 [ 52 ] = KEY_KP6,
221 [ 44 ] = KEY_KP7,
222 [ 28 ] = KEY_KP8,
223 [ 60 ] = KEY_KP9,
224 [ 34 ] = KEY_KP0,
225
226 [ 32 ] = KEY_TV, // TV/FM
227 [ 16 ] = KEY_CD, // CD
228 [ 48 ] = KEY_TEXT, // TELETEXT
229 [ 0 ] = KEY_POWER, // POWER
230
231 [ 8 ] = KEY_VIDEO, // VIDEO
232 [ 4 ] = KEY_AUDIO, // AUDIO
233 [ 12 ] = KEY_ZOOM, // FULL SCREEN
234
235 [ 18 ] = KEY_SUBTITLE, // DISPLAY - ???
236 [ 50 ] = KEY_REWIND, // LOOP - ???
237 [ 2 ] = KEY_PRINT, // PREVIEW - ???
238
239 [ 42 ] = KEY_SEARCH, // AUTOSCAN
240 [ 26 ] = KEY_SLEEP, // FREEZE - ???
241 [ 58 ] = KEY_SHUFFLE, // SNAPSHOT - ???
242 [ 10 ] = KEY_MUTE, // MUTE
243
244 [ 38 ] = KEY_RECORD, // RECORD
245 [ 22 ] = KEY_PAUSE, // PAUSE
246 [ 54 ] = KEY_STOP, // STOP
247 [ 6 ] = KEY_PLAY, // PLAY
248
249 [ 46 ] = KEY_RED, // <RED>
250 [ 33 ] = KEY_GREEN, // <GREEN>
251 [ 14 ] = KEY_YELLOW, // <YELLOW>
252 [ 1 ] = KEY_BLUE, // <BLUE>
253
254 [ 30 ] = KEY_VOLUMEDOWN, // VOLUME-
255 [ 62 ] = KEY_VOLUMEUP, // VOLUME+
256 [ 17 ] = KEY_CHANNELDOWN, // CHANNEL/PAGE-
257 [ 49 ] = KEY_CHANNELUP // CHANNEL/PAGE+
258};
259
260static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = {
261 [ 20 ] = KEY_MUTE,
262 [ 36 ] = KEY_ZOOM,
263
264 [ 1 ] = KEY_DVD,
265 [ 35 ] = KEY_RADIO,
266 [ 0 ] = KEY_TV,
267
268 [ 10 ] = KEY_REWIND,
269 [ 8 ] = KEY_PLAYPAUSE,
270 [ 15 ] = KEY_FORWARD,
271
272 [ 2 ] = KEY_PREVIOUS,
273 [ 7 ] = KEY_STOP,
274 [ 6 ] = KEY_NEXT,
275
276 [ 12 ] = KEY_UP,
277 [ 14 ] = KEY_DOWN,
278 [ 11 ] = KEY_LEFT,
279 [ 13 ] = KEY_RIGHT,
280 [ 17 ] = KEY_OK,
281
282 [ 3 ] = KEY_MENU,
283 [ 9 ] = KEY_SETUP,
284 [ 5 ] = KEY_VIDEO,
285 [ 34 ] = KEY_CHANNEL,
286
287 [ 18 ] = KEY_VOLUMEUP,
288 [ 21 ] = KEY_VOLUMEDOWN,
289 [ 16 ] = KEY_CHANNELUP,
290 [ 19 ] = KEY_CHANNELDOWN,
291
292 [ 4 ] = KEY_RECORD,
293
294 [ 22 ] = KEY_KP1,
295 [ 23 ] = KEY_KP2,
296 [ 24 ] = KEY_KP3,
297 [ 25 ] = KEY_KP4,
298 [ 26 ] = KEY_KP5,
299 [ 27 ] = KEY_KP6,
300 [ 28 ] = KEY_KP7,
301 [ 29 ] = KEY_KP8,
302 [ 30 ] = KEY_KP9,
303 [ 31 ] = KEY_KP0,
304
305 [ 32 ] = KEY_LANGUAGE,
306 [ 33 ] = KEY_SLEEP,
307};
Mauro Carvalho Chehabac19ecc2005-06-23 22:05:09 -0700308
309/* Michael Tokarev <mjt@tls.msk.ru>
310 http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
311 keytable is used by MANLI MTV00[12] and BeholdTV 40[13] at
312 least, and probably other cards too.
313 The "ascii-art picture" below (in comments, first row
314 is the keycode in hex, and subsequent row(s) shows
315 the button labels (several variants when appropriate)
316 helps to descide which keycodes to assign to the buttons.
317 */
318static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
319
320 /* 0x1c 0x12 *
321 * FUNCTION POWER *
322 * FM (|) *
323 * */
324 [ 0x1c ] = KEY_RADIO, /*XXX*/
325 [ 0x12 ] = KEY_POWER,
326
327 /* 0x01 0x02 0x03 *
328 * 1 2 3 *
329 * *
330 * 0x04 0x05 0x06 *
331 * 4 5 6 *
332 * *
333 * 0x07 0x08 0x09 *
334 * 7 8 9 *
335 * */
336 [ 0x01 ] = KEY_KP1,
337 [ 0x02 ] = KEY_KP2,
338 [ 0x03 ] = KEY_KP3,
339 [ 0x04 ] = KEY_KP4,
340 [ 0x05 ] = KEY_KP5,
341 [ 0x06 ] = KEY_KP6,
342 [ 0x07 ] = KEY_KP7,
343 [ 0x08 ] = KEY_KP8,
344 [ 0x09 ] = KEY_KP9,
345
346 /* 0x0a 0x00 0x17 *
347 * RECALL 0 +100 *
348 * PLUS *
349 * */
350 [ 0x0a ] = KEY_AGAIN, /*XXX KEY_REWIND? */
351 [ 0x00 ] = KEY_KP0,
352 [ 0x17 ] = KEY_DIGITS, /*XXX*/
353
354 /* 0x14 0x10 *
355 * MENU INFO *
356 * OSD */
357 [ 0x14 ] = KEY_MENU,
358 [ 0x10 ] = KEY_INFO,
359
360 /* 0x0b *
361 * Up *
362 * *
363 * 0x18 0x16 0x0c *
364 * Left Ok Right *
365 * *
366 * 0x015 *
367 * Down *
368 * */
369 [ 0x0b ] = KEY_UP, /*XXX KEY_SCROLLUP? */
370 [ 0x18 ] = KEY_LEFT, /*XXX KEY_BACK? */
371 [ 0x16 ] = KEY_OK, /*XXX KEY_SELECT? KEY_ENTER? */
372 [ 0x0c ] = KEY_RIGHT, /*XXX KEY_FORWARD? */
373 [ 0x15 ] = KEY_DOWN, /*XXX KEY_SCROLLDOWN? */
374
375 /* 0x11 0x0d *
376 * TV/AV MODE *
377 * SOURCE STEREO *
378 * */
379 [ 0x11 ] = KEY_TV, /*XXX*/
380 [ 0x0d ] = KEY_MODE, /*XXX there's no KEY_STEREO */
381
382 /* 0x0f 0x1b 0x1a *
383 * AUDIO Vol+ Chan+ *
384 * TIMESHIFT??? *
385 * *
386 * 0x0e 0x1f 0x1e *
387 * SLEEP Vol- Chan- *
388 * */
389 [ 0x0f ] = KEY_AUDIO,
390 [ 0x1b ] = KEY_VOLUMEUP,
391 [ 0x1a ] = KEY_CHANNELUP,
392 [ 0x0e ] = KEY_SLEEP, /*XXX maybe KEY_PAUSE */
393 [ 0x1f ] = KEY_VOLUMEDOWN,
394 [ 0x1e ] = KEY_CHANNELDOWN,
395
396 /* 0x13 0x19 *
397 * MUTE SNAPSHOT*
398 * */
399 [ 0x13 ] = KEY_MUTE,
400 [ 0x19 ] = KEY_RECORD, /*XXX*/
401
402 // 0x1d unused ?
403};
Nickolay V. Shmyrev6b961442005-11-08 21:36:22 -0800404
405
Nickolay V. Shmyrevdcd555e2005-11-08 21:36:23 -0800406/* Mike Baikov <mike@baikov.com> */
Nickolay V. Shmyrev6b961442005-11-08 21:36:22 -0800407static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = {
408
409 [ 33 ] = KEY_POWER,
410 [ 105] = KEY_TV,
411 [ 51 ] = KEY_KP0,
412 [ 81 ] = KEY_KP1,
413 [ 49 ] = KEY_KP2,
414 [ 113] = KEY_KP3,
415 [ 59 ] = KEY_KP4,
416 [ 88 ] = KEY_KP5,
417 [ 65 ] = KEY_KP6,
418 [ 72 ] = KEY_KP7,
419 [ 48 ] = KEY_KP8,
420 [ 83 ] = KEY_KP9,
421 [ 115] = KEY_AGAIN, /* LOOP */
422 [ 10 ] = KEY_AUDIO,
423 [ 97 ] = KEY_PRINT, /* PREVIEW */
424 [ 122] = KEY_VIDEO,
425 [ 32 ] = KEY_CHANNELUP,
426 [ 64 ] = KEY_CHANNELDOWN,
427 [ 24 ] = KEY_VOLUMEDOWN,
428 [ 80 ] = KEY_VOLUMEUP,
429 [ 16 ] = KEY_MUTE,
430 [ 74 ] = KEY_SEARCH,
431 [ 123] = KEY_SHUFFLE, /* SNAPSHOT */
432 [ 34 ] = KEY_RECORD,
433 [ 98 ] = KEY_STOP,
434 [ 120] = KEY_PLAY,
435 [ 57 ] = KEY_REWIND,
436 [ 89 ] = KEY_PAUSE,
437 [ 25 ] = KEY_FORWARD,
438 [ 9 ] = KEY_ZOOM,
439
440 [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */
441 [ 26 ] = KEY_F22, /* MIN TIMESHIFT */
442 [ 58 ] = KEY_F23, /* TIMESHIFT */
443 [ 112] = KEY_F24, /* NORMAL TIMESHIFT */
444};
445
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446/* ---------------------------------------------------------------------- */
447
448static int build_key(struct saa7134_dev *dev)
449{
450 struct saa7134_ir *ir = dev->remote;
451 u32 gpio, data;
452
453 /* rising SAA7134_GPIO_GPRESCAN reads the status */
454 saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
455 saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
456
457 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800458 if (ir->polling) {
459 if (ir->last_gpio == gpio)
460 return 0;
461 ir->last_gpio = gpio;
462 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800464 data = ir_extract_bits(gpio, ir->mask_keycode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
466 gpio, ir->mask_keycode, data);
467
468 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
469 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500470 ir_input_keydown(ir->dev, &ir->ir, data, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 } else {
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500472 ir_input_nokey(ir->dev, &ir->ir);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 }
474 return 0;
475}
476
477/* ---------------------------------------------------------------------- */
478
479void saa7134_input_irq(struct saa7134_dev *dev)
480{
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800481 struct saa7134_ir *ir = dev->remote;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800483 if (!ir->polling)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 build_key(dev);
485}
486
487static void saa7134_input_timer(unsigned long data)
488{
489 struct saa7134_dev *dev = (struct saa7134_dev*)data;
490 struct saa7134_ir *ir = dev->remote;
491 unsigned long timeout;
492
493 build_key(dev);
494 timeout = jiffies + (ir->polling * HZ / 1000);
495 mod_timer(&ir->timer, timeout);
496}
497
498int saa7134_input_init1(struct saa7134_dev *dev)
499{
500 struct saa7134_ir *ir;
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500501 struct input_dev *input_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502 IR_KEYTAB_TYPE *ir_codes = NULL;
503 u32 mask_keycode = 0;
504 u32 mask_keydown = 0;
505 u32 mask_keyup = 0;
506 int polling = 0;
507 int ir_type = IR_TYPE_OTHER;
508
509 if (!dev->has_remote)
510 return -ENODEV;
511 if (disable_ir)
512 return -ENODEV;
513
514 /* detect & configure */
515 switch (dev->board) {
516 case SAA7134_BOARD_FLYVIDEO2000:
517 case SAA7134_BOARD_FLYVIDEO3000:
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800518 case SAA7134_BOARD_FLYTVPLATINUM_FM:
Arnaud Patard6af90ab2005-11-08 21:36:55 -0800519 case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 ir_codes = flyvideo_codes;
521 mask_keycode = 0xEC00000;
522 mask_keydown = 0x0040000;
523 break;
524 case SAA7134_BOARD_CINERGY400:
525 case SAA7134_BOARD_CINERGY600:
526 case SAA7134_BOARD_CINERGY600_MK3:
527 ir_codes = cinergy_codes;
528 mask_keycode = 0x00003f;
529 mask_keyup = 0x040000;
530 break;
531 case SAA7134_BOARD_ECS_TVP3XP:
532 case SAA7134_BOARD_ECS_TVP3XP_4CB5:
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700533 ir_codes = eztv_codes;
534 mask_keycode = 0x00017c;
535 mask_keyup = 0x000002;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 polling = 50; // ms
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700537 break;
538 case SAA7134_BOARD_KWORLD_XPERT:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 case SAA7134_BOARD_AVACSSMARTTV:
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700540 ir_codes = avacssmart_codes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 mask_keycode = 0x00001F;
542 mask_keyup = 0x000020;
543 polling = 50; // ms
544 break;
545 case SAA7134_BOARD_MD2819:
Mauro Carvalho Chehabac19ecc2005-06-23 22:05:09 -0700546 case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 case SAA7134_BOARD_AVERMEDIA_305:
548 case SAA7134_BOARD_AVERMEDIA_307:
Mauro Carvalho Chehabac19ecc2005-06-23 22:05:09 -0700549 case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
550 case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
551 case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 ir_codes = md2819_codes;
553 mask_keycode = 0x0007C8;
554 mask_keydown = 0x000010;
555 polling = 50; // ms
556 /* Set GPIO pin2 to high to enable the IR controller */
557 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
558 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
559 break;
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800560 case SAA7134_BOARD_KWORLD_TERMINATOR:
James R. Webbdc2286c2005-11-08 21:37:00 -0800561 ir_codes = avacssmart_codes;
562 mask_keycode = 0x00001f;
563 mask_keyup = 0x000060;
564 polling = 50; // ms
565 break;
Mauro Carvalho Chehabac19ecc2005-06-23 22:05:09 -0700566 case SAA7134_BOARD_MANLI_MTV001:
567 case SAA7134_BOARD_MANLI_MTV002:
Nickolay V. Shmyreva8ff4172005-11-08 21:36:16 -0800568 case SAA7134_BOARD_BEHOLD_409FM:
Mauro Carvalho Chehabac19ecc2005-06-23 22:05:09 -0700569 ir_codes = manli_codes;
570 mask_keycode = 0x001f00;
571 mask_keyup = 0x004000;
Mauro Carvalho Chehabac19ecc2005-06-23 22:05:09 -0700572 polling = 50; // ms
573 break;
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800574 case SAA7134_BOARD_GOTVIEW_7135:
Nickolay V. Shmyrev6b961442005-11-08 21:36:22 -0800575 ir_codes = gotview7135_codes;
576 mask_keycode = 0x0003EC;
577 mask_keyup = 0x008000;
578 mask_keydown = 0x000010;
579 polling = 50; // ms
580 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700582 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 ir_codes = videomate_tv_pvr_codes;
584 mask_keycode = 0x00003F;
585 mask_keyup = 0x400000;
586 polling = 50; // ms
587 break;
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800588 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
589 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
Nickolay V. Shmyrevfea095f2005-11-08 21:36:47 -0800590 ir_codes = videomate_tv_pvr_codes;
591 mask_keycode = 0x003F00;
592 mask_keyup = 0x040000;
593 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 }
595 if (NULL == ir_codes) {
596 printk("%s: Oops: IR config error [card=%d]\n",
597 dev->name, dev->board);
598 return -ENODEV;
599 }
600
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500601 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
602 input_dev = input_allocate_device();
603 if (!ir || !input_dev) {
604 kfree(ir);
605 input_free_device(input_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 return -ENOMEM;
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500607 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
609 /* init hardware-specific stuff */
610 ir->mask_keycode = mask_keycode;
611 ir->mask_keydown = mask_keydown;
612 ir->mask_keyup = mask_keyup;
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800613 ir->polling = polling;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614
615 /* init input device */
616 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
617 saa7134_boards[dev->board].name);
618 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
619 pci_name(dev->pci));
620
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500621 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
622 input_dev->name = ir->name;
623 input_dev->phys = ir->phys;
624 input_dev->id.bustype = BUS_PCI;
625 input_dev->id.version = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 if (dev->pci->subsystem_vendor) {
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500627 input_dev->id.vendor = dev->pci->subsystem_vendor;
628 input_dev->id.product = dev->pci->subsystem_device;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 } else {
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500630 input_dev->id.vendor = dev->pci->vendor;
631 input_dev->id.product = dev->pci->device;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632 }
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500633 input_dev->cdev.dev = &dev->pci->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634
635 /* all done */
636 dev->remote = ir;
637 if (ir->polling) {
638 init_timer(&ir->timer);
639 ir->timer.function = saa7134_input_timer;
640 ir->timer.data = (unsigned long)dev;
641 ir->timer.expires = jiffies + HZ;
642 add_timer(&ir->timer);
643 }
644
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500645 input_register_device(ir->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 return 0;
647}
648
649void saa7134_input_fini(struct saa7134_dev *dev)
650{
651 if (NULL == dev->remote)
652 return;
653
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 if (dev->remote->polling)
655 del_timer_sync(&dev->remote->timer);
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500656 input_unregister_device(dev->remote->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 kfree(dev->remote);
658 dev->remote = NULL;
659}
660
661/* ----------------------------------------------------------------------
662 * Local variables:
663 * c-basic-offset: 8
664 * End:
665 */