diff options
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-input.c')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-input.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c new file mode 100644 index 000000000000..32c49df58adc --- /dev/null +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -0,0 +1,184 @@ | |||
1 | /* | ||
2 | handle em28xx IR remotes via linux kernel input layer. | ||
3 | |||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | ||
5 | Markus Rechberger <mrechberger@gmail.com> | ||
6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | ||
7 | Sascha Sommer <saschasommer@freenet.de> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/moduleparam.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/sched.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/input.h> | ||
31 | #include <linux/usb.h> | ||
32 | |||
33 | #include "em28xx.h" | ||
34 | |||
35 | static unsigned int disable_ir = 0; | ||
36 | module_param(disable_ir, int, 0444); | ||
37 | MODULE_PARM_DESC(disable_ir,"disable infrared remote support"); | ||
38 | |||
39 | static unsigned int ir_debug = 0; | ||
40 | module_param(ir_debug, int, 0644); | ||
41 | MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); | ||
42 | |||
43 | #define dprintk(fmt, arg...) if (ir_debug) \ | ||
44 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) | ||
45 | |||
46 | /* ---------------------------------------------------------------------- */ | ||
47 | |||
48 | static IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = { | ||
49 | [ 0x01 ] = KEY_CHANNEL, | ||
50 | [ 0x02 ] = KEY_SELECT, | ||
51 | [ 0x03 ] = KEY_MUTE, | ||
52 | [ 0x04 ] = KEY_POWER, | ||
53 | [ 0x05 ] = KEY_KP1, | ||
54 | [ 0x06 ] = KEY_KP2, | ||
55 | [ 0x07 ] = KEY_KP3, | ||
56 | [ 0x08 ] = KEY_CHANNELUP, | ||
57 | [ 0x09 ] = KEY_KP4, | ||
58 | [ 0x0a ] = KEY_KP5, | ||
59 | [ 0x0b ] = KEY_KP6, | ||
60 | [ 0x0c ] = KEY_CHANNELDOWN, | ||
61 | [ 0x0d ] = KEY_KP7, | ||
62 | [ 0x0e ] = KEY_KP8, | ||
63 | [ 0x0f ] = KEY_KP9, | ||
64 | [ 0x10 ] = KEY_VOLUMEUP, | ||
65 | [ 0x11 ] = KEY_KP0, | ||
66 | [ 0x12 ] = KEY_MENU, | ||
67 | [ 0x13 ] = KEY_PRINT, | ||
68 | [ 0x14 ] = KEY_VOLUMEDOWN, | ||
69 | [ 0x16 ] = KEY_PAUSE, | ||
70 | [ 0x18 ] = KEY_RECORD, | ||
71 | [ 0x19 ] = KEY_REWIND, | ||
72 | [ 0x1a ] = KEY_PLAY, | ||
73 | [ 0x1b ] = KEY_FORWARD, | ||
74 | [ 0x1c ] = KEY_BACKSPACE, | ||
75 | [ 0x1e ] = KEY_STOP, | ||
76 | [ 0x40 ] = KEY_ZOOM, | ||
77 | }; | ||
78 | |||
79 | /* ----------------------------------------------------------------------- */ | ||
80 | |||
81 | static int get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
82 | { | ||
83 | unsigned char b; | ||
84 | |||
85 | /* poll IR chip */ | ||
86 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | ||
87 | dprintk("read error\n"); | ||
88 | return -EIO; | ||
89 | } | ||
90 | |||
91 | /* it seems that 0xFE indicates that a button is still hold | ||
92 | down, while 0xff indicates that no button is hold | ||
93 | down. 0xfe sequences are sometimes interrupted by 0xFF */ | ||
94 | |||
95 | dprintk("key %02x\n", b); | ||
96 | |||
97 | if (b == 0xff) | ||
98 | return 0; | ||
99 | |||
100 | if (b == 0xfe) | ||
101 | /* keep old data */ | ||
102 | return 1; | ||
103 | |||
104 | *ir_key = b; | ||
105 | *ir_raw = b; | ||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | |||
110 | static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
111 | { | ||
112 | unsigned char buf[2]; | ||
113 | unsigned char code; | ||
114 | |||
115 | /* poll IR chip */ | ||
116 | if (2 != i2c_master_recv(&ir->c,buf,2)) | ||
117 | return -EIO; | ||
118 | |||
119 | /* Does eliminate repeated parity code */ | ||
120 | if (buf[1]==0xff) | ||
121 | return 0; | ||
122 | |||
123 | /* avoid fast reapeating */ | ||
124 | if (buf[1]==ir->old) | ||
125 | return 0; | ||
126 | ir->old=buf[1]; | ||
127 | |||
128 | /* Rearranges bits to the right order */ | ||
129 | code= ((buf[0]&0x01)<<5) | /* 0010 0000 */ | ||
130 | ((buf[0]&0x02)<<3) | /* 0001 0000 */ | ||
131 | ((buf[0]&0x04)<<1) | /* 0000 1000 */ | ||
132 | ((buf[0]&0x08)>>1) | /* 0000 0100 */ | ||
133 | ((buf[0]&0x10)>>3) | /* 0000 0010 */ | ||
134 | ((buf[0]&0x20)>>5); /* 0000 0001 */ | ||
135 | |||
136 | dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n",code,buf[0]); | ||
137 | |||
138 | /* return key */ | ||
139 | *ir_key = code; | ||
140 | *ir_raw = code; | ||
141 | return 1; | ||
142 | } | ||
143 | |||
144 | /* ----------------------------------------------------------------------- */ | ||
145 | void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir) | ||
146 | { | ||
147 | if (disable_ir) { | ||
148 | ir->get_key=NULL; | ||
149 | return ; | ||
150 | } | ||
151 | |||
152 | /* detect & configure */ | ||
153 | switch (dev->model) { | ||
154 | case (EM2800_BOARD_UNKNOWN): | ||
155 | break; | ||
156 | case (EM2820_BOARD_UNKNOWN): | ||
157 | break; | ||
158 | case (EM2800_BOARD_TERRATEC_CINERGY_200): | ||
159 | case (EM2820_BOARD_TERRATEC_CINERGY_250): | ||
160 | ir->ir_codes = ir_codes_em_terratec; | ||
161 | ir->get_key = get_key_terratec; | ||
162 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)"); | ||
163 | break; | ||
164 | case (EM2820_BOARD_PINNACLE_USB_2): | ||
165 | break; | ||
166 | case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): | ||
167 | ir->ir_codes = ir_codes_hauppauge_new; | ||
168 | ir->get_key = get_key_em_haup; | ||
169 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM2840 Hauppauge)"); | ||
170 | break; | ||
171 | case (EM2820_BOARD_MSI_VOX_USB_2): | ||
172 | break; | ||
173 | case (EM2800_BOARD_LEADTEK_WINFAST_USBII): | ||
174 | break; | ||
175 | case (EM2800_BOARD_KWORLD_USB2800): | ||
176 | break; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | /* ---------------------------------------------------------------------- | ||
181 | * Local variables: | ||
182 | * c-basic-offset: 8 | ||
183 | * End: | ||
184 | */ | ||