[PATCH] v4l: 636: don t enable gpioirq until after card probe
[deliverable/linux.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)
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
1da177e4
LT
70 [ 26 ] = KEY_F22, // Stereo
71 [ 24 ] = KEY_EDIT, // AV Source
1da177e4
LT
72};
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] = {
117 [ 18 ] = KEY_POWER,
118 [ 1 ] = KEY_TV, // DVR
119 [ 21 ] = KEY_DVD, // DVD
120 [ 23 ] = KEY_AUDIO, // music
121 // DVR mode / DVD mode / music mode
122
123 [ 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
131
132 [ 49 ] = KEY_HELP, // help
133 [ 50 ] = KEY_MODE, // num/memo
134 [ 51 ] = KEY_ESC, // cancel
135
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
151 [ 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,
161
162 [ 42 ] = KEY_VOLUMEUP,
163 [ 17 ] = KEY_VOLUMEDOWN,
164 [ 24 ] = KEY_CHANNELUP, // CH.tracking up
165 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
166
167 [ 19 ] = KEY_KPENTER, // enter
168 [ 33 ] = KEY_KPDOT, // . (decimal dot)
169};
170
171static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
330a115a 172 [ 30 ] = KEY_POWER, // power
1da177e4 173 [ 28 ] = KEY_SEARCH, // scan
330a115a 174 [ 7 ] = KEY_SELECT, // source
1da177e4
LT
175
176 [ 22 ] = KEY_VOLUMEUP,
177 [ 20 ] = KEY_VOLUMEDOWN,
330a115a 178 [ 31 ] = KEY_CHANNELUP,
1da177e4
LT
179 [ 23 ] = KEY_CHANNELDOWN,
180 [ 24 ] = KEY_MUTE,
181
182 [ 2 ] = KEY_KP0,
330a115a
MCC
183 [ 1 ] = KEY_KP1,
184 [ 11 ] = KEY_KP2,
185 [ 27 ] = KEY_KP3,
186 [ 5 ] = KEY_KP4,
187 [ 9 ] = KEY_KP5,
188 [ 21 ] = KEY_KP6,
1da177e4 189 [ 6 ] = KEY_KP7,
330a115a 190 [ 10 ] = KEY_KP8,
1da177e4
LT
191 [ 18 ] = KEY_KP9,
192 [ 16 ] = KEY_KPDOT,
193
194 [ 3 ] = KEY_TUNER, // tv/fm
330a115a
MCC
195 [ 4 ] = KEY_REWIND, // fm tuning left or function left
196 [ 12 ] = KEY_FORWARD, // fm tuning right or function right
1da177e4
LT
197
198 [ 0 ] = KEY_RECORD,
330a115a
MCC
199 [ 8 ] = KEY_STOP,
200 [ 17 ] = KEY_PLAY,
1da177e4
LT
201
202 [ 25 ] = KEY_ZOOM,
203 [ 14 ] = KEY_MENU, // function
204 [ 19 ] = KEY_AGAIN, // recall
205 [ 29 ] = KEY_RESTART, // reset
330a115a 206 [ 26 ] = KEY_SHUFFLE, // snapshot/shuffle
1da177e4
LT
207
208// FIXME
209 [ 13 ] = KEY_F21, // mts
330a115a 210 [ 15 ] = KEY_F22, // min
1da177e4
LT
211};
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};
ac19ecc6
MCC
308
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};
1da177e4
LT
404/* ---------------------------------------------------------------------- */
405
406static int build_key(struct saa7134_dev *dev)
407{
408 struct saa7134_ir *ir = dev->remote;
409 u32 gpio, data;
410
411 /* rising SAA7134_GPIO_GPRESCAN reads the status */
412 saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
413 saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
414
415 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
416 if (ir->polling) {
417 if (ir->last_gpio == gpio)
418 return 0;
419 ir->last_gpio = gpio;
420 }
421
422 data = ir_extract_bits(gpio, ir->mask_keycode);
423 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
424 gpio, ir->mask_keycode, data);
425
426 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
427 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
b7df3910 428 ir_input_keydown(ir->dev, &ir->ir, data, data);
1da177e4 429 } else {
b7df3910 430 ir_input_nokey(ir->dev, &ir->ir);
1da177e4
LT
431 }
432 return 0;
433}
434
435/* ---------------------------------------------------------------------- */
436
437void saa7134_input_irq(struct saa7134_dev *dev)
438{
439 struct saa7134_ir *ir = dev->remote;
440
441 if (!ir->polling)
442 build_key(dev);
443}
444
445static void saa7134_input_timer(unsigned long data)
446{
447 struct saa7134_dev *dev = (struct saa7134_dev*)data;
448 struct saa7134_ir *ir = dev->remote;
449 unsigned long timeout;
450
451 build_key(dev);
452 timeout = jiffies + (ir->polling * HZ / 1000);
453 mod_timer(&ir->timer, timeout);
454}
455
456int saa7134_input_init1(struct saa7134_dev *dev)
457{
458 struct saa7134_ir *ir;
b7df3910 459 struct input_dev *input_dev;
1da177e4
LT
460 IR_KEYTAB_TYPE *ir_codes = NULL;
461 u32 mask_keycode = 0;
462 u32 mask_keydown = 0;
463 u32 mask_keyup = 0;
464 int polling = 0;
465 int ir_type = IR_TYPE_OTHER;
466
467 if (!dev->has_remote)
468 return -ENODEV;
469 if (disable_ir)
470 return -ENODEV;
471
472 /* detect & configure */
473 switch (dev->board) {
474 case SAA7134_BOARD_FLYVIDEO2000:
475 case SAA7134_BOARD_FLYVIDEO3000:
ac19ecc6 476 case SAA7134_BOARD_FLYTVPLATINUM_FM:
1da177e4
LT
477 ir_codes = flyvideo_codes;
478 mask_keycode = 0xEC00000;
479 mask_keydown = 0x0040000;
480 break;
481 case SAA7134_BOARD_CINERGY400:
482 case SAA7134_BOARD_CINERGY600:
483 case SAA7134_BOARD_CINERGY600_MK3:
484 ir_codes = cinergy_codes;
485 mask_keycode = 0x00003f;
486 mask_keyup = 0x040000;
487 break;
488 case SAA7134_BOARD_ECS_TVP3XP:
489 case SAA7134_BOARD_ECS_TVP3XP_4CB5:
330a115a
MCC
490 ir_codes = eztv_codes;
491 mask_keycode = 0x00017c;
492 mask_keyup = 0x000002;
1da177e4 493 polling = 50; // ms
330a115a
MCC
494 break;
495 case SAA7134_BOARD_KWORLD_XPERT:
1da177e4 496 case SAA7134_BOARD_AVACSSMARTTV:
330a115a 497 ir_codes = avacssmart_codes;
1da177e4
LT
498 mask_keycode = 0x00001F;
499 mask_keyup = 0x000020;
500 polling = 50; // ms
501 break;
502 case SAA7134_BOARD_MD2819:
ac19ecc6 503 case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
1da177e4
LT
504 case SAA7134_BOARD_AVERMEDIA_305:
505 case SAA7134_BOARD_AVERMEDIA_307:
ac19ecc6
MCC
506 case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
507 case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
508 case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
1da177e4
LT
509 ir_codes = md2819_codes;
510 mask_keycode = 0x0007C8;
511 mask_keydown = 0x000010;
512 polling = 50; // ms
513 /* Set GPIO pin2 to high to enable the IR controller */
514 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
515 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
516 break;
ac19ecc6
MCC
517 case SAA7134_BOARD_MANLI_MTV001:
518 case SAA7134_BOARD_MANLI_MTV002:
a8ff417e 519 case SAA7134_BOARD_BEHOLD_409FM:
ac19ecc6
MCC
520 ir_codes = manli_codes;
521 mask_keycode = 0x001f00;
522 mask_keyup = 0x004000;
523 mask_keydown = 0x002000;
524 polling = 50; // ms
525 break;
1da177e4 526 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
330a115a 527 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
1da177e4
LT
528 ir_codes = videomate_tv_pvr_codes;
529 mask_keycode = 0x00003F;
530 mask_keyup = 0x400000;
531 polling = 50; // ms
532 break;
533 }
534 if (NULL == ir_codes) {
535 printk("%s: Oops: IR config error [card=%d]\n",
536 dev->name, dev->board);
537 return -ENODEV;
538 }
539
b7df3910
DT
540 ir = kzalloc(sizeof(*ir), GFP_KERNEL);
541 input_dev = input_allocate_device();
542 if (!ir || !input_dev) {
543 kfree(ir);
544 input_free_device(input_dev);
1da177e4 545 return -ENOMEM;
b7df3910 546 }
1da177e4
LT
547
548 /* init hardware-specific stuff */
549 ir->mask_keycode = mask_keycode;
550 ir->mask_keydown = mask_keydown;
551 ir->mask_keyup = mask_keyup;
552 ir->polling = polling;
553
554 /* init input device */
555 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
556 saa7134_boards[dev->board].name);
557 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
558 pci_name(dev->pci));
559
b7df3910
DT
560 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
561 input_dev->name = ir->name;
562 input_dev->phys = ir->phys;
563 input_dev->id.bustype = BUS_PCI;
564 input_dev->id.version = 1;
1da177e4 565 if (dev->pci->subsystem_vendor) {
b7df3910
DT
566 input_dev->id.vendor = dev->pci->subsystem_vendor;
567 input_dev->id.product = dev->pci->subsystem_device;
1da177e4 568 } else {
b7df3910
DT
569 input_dev->id.vendor = dev->pci->vendor;
570 input_dev->id.product = dev->pci->device;
1da177e4 571 }
b7df3910 572 input_dev->cdev.dev = &dev->pci->dev;
1da177e4
LT
573
574 /* all done */
575 dev->remote = ir;
576 if (ir->polling) {
577 init_timer(&ir->timer);
578 ir->timer.function = saa7134_input_timer;
579 ir->timer.data = (unsigned long)dev;
580 ir->timer.expires = jiffies + HZ;
581 add_timer(&ir->timer);
582 }
583
b7df3910 584 input_register_device(ir->dev);
1da177e4
LT
585 return 0;
586}
587
588void saa7134_input_fini(struct saa7134_dev *dev)
589{
590 if (NULL == dev->remote)
591 return;
592
1da177e4
LT
593 if (dev->remote->polling)
594 del_timer_sync(&dev->remote->timer);
b7df3910 595 input_unregister_device(dev->remote->dev);
1da177e4
LT
596 kfree(dev->remote);
597 dev->remote = NULL;
598}
599
600/* ----------------------------------------------------------------------
601 * Local variables:
602 * c-basic-offset: 8
603 * End:
604 */
This page took 0.486178 seconds and 5 git commands to generate.