aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/IR')
-rw-r--r--drivers/media/IR/Kconfig4
-rw-r--r--drivers/media/IR/Makefile3
-rw-r--r--drivers/media/IR/ir-functions.c373
-rw-r--r--drivers/media/IR/ir-keymaps.c3395
-rw-r--r--drivers/media/IR/ir-keytable.c433
5 files changed, 4208 insertions, 0 deletions
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig
new file mode 100644
index 000000000000..5b4ac969a586
--- /dev/null
+++ b/drivers/media/IR/Kconfig
@@ -0,0 +1,4 @@
1config VIDEO_IR
2 tristate
3 depends on INPUT
4 default INPUT
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile
new file mode 100644
index 000000000000..2781f430c6e1
--- /dev/null
+++ b/drivers/media/IR/Makefile
@@ -0,0 +1,3 @@
1ir-common-objs := ir-functions.o ir-keymaps.o ir-keytable.o
2
3obj-$(CONFIG_VIDEO_IR) += ir-common.o
diff --git a/drivers/media/IR/ir-functions.c b/drivers/media/IR/ir-functions.c
new file mode 100644
index 000000000000..e616f624ceaa
--- /dev/null
+++ b/drivers/media/IR/ir-functions.c
@@ -0,0 +1,373 @@
1/*
2 *
3 * some common structs and functions to handle infrared remotes via
4 * input layer ...
5 *
6 * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/module.h>
24#include <linux/string.h>
25#include <linux/jiffies.h>
26#include <media/ir-common.h>
27
28/* -------------------------------------------------------------------------- */
29
30MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
31MODULE_LICENSE("GPL");
32
33static int repeat = 1;
34module_param(repeat, int, 0444);
35MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
36
37int media_ir_debug; /* media_ir_debug level (0,1,2) */
38module_param_named(debug, media_ir_debug, int, 0644);
39
40/* -------------------------------------------------------------------------- */
41
42static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
43{
44 if (KEY_RESERVED == ir->keycode) {
45 printk(KERN_INFO "%s: unknown key: key=0x%02x down=%d\n",
46 dev->name, ir->ir_key, ir->keypressed);
47 return;
48 }
49 IR_dprintk(1,"%s: key event code=%d down=%d\n",
50 dev->name,ir->keycode,ir->keypressed);
51 input_report_key(dev,ir->keycode,ir->keypressed);
52 input_sync(dev);
53}
54
55/* -------------------------------------------------------------------------- */
56
57int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
58 int ir_type, struct ir_scancode_table *ir_codes)
59{
60 ir->ir_type = ir_type;
61
62 ir->keytable.size = ir_roundup_tablesize(ir_codes->size);
63 ir->keytable.scan = kzalloc(ir->keytable.size *
64 sizeof(struct ir_scancode), GFP_KERNEL);
65 if (!ir->keytable.scan)
66 return -ENOMEM;
67
68 IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n",
69 ir->keytable.size,
70 ir->keytable.size * sizeof(ir->keytable.scan));
71
72 ir_copy_table(&ir->keytable, ir_codes);
73 ir_set_keycode_table(dev, &ir->keytable);
74
75 clear_bit(0, dev->keybit);
76 set_bit(EV_KEY, dev->evbit);
77 if (repeat)
78 set_bit(EV_REP, dev->evbit);
79
80 return 0;
81}
82EXPORT_SYMBOL_GPL(ir_input_init);
83
84
85void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
86{
87 if (ir->keypressed) {
88 ir->keypressed = 0;
89 ir_input_key_event(dev,ir);
90 }
91}
92EXPORT_SYMBOL_GPL(ir_input_nokey);
93
94void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
95 u32 ir_key)
96{
97 u32 keycode = ir_g_keycode_from_table(dev, ir_key);
98
99 if (ir->keypressed && ir->keycode != keycode) {
100 ir->keypressed = 0;
101 ir_input_key_event(dev,ir);
102 }
103 if (!ir->keypressed) {
104 ir->ir_key = ir_key;
105 ir->keycode = keycode;
106 ir->keypressed = 1;
107 ir_input_key_event(dev,ir);
108 }
109}
110EXPORT_SYMBOL_GPL(ir_input_keydown);
111
112/* -------------------------------------------------------------------------- */
113/* extract mask bits out of data and pack them into the result */
114u32 ir_extract_bits(u32 data, u32 mask)
115{
116 u32 vbit = 1, value = 0;
117
118 do {
119 if (mask&1) {
120 if (data&1)
121 value |= vbit;
122 vbit<<=1;
123 }
124 data>>=1;
125 } while (mask>>=1);
126
127 return value;
128}
129EXPORT_SYMBOL_GPL(ir_extract_bits);
130
131static int inline getbit(u32 *samples, int bit)
132{
133 return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0;
134}
135
136/* sump raw samples for visual debugging ;) */
137int ir_dump_samples(u32 *samples, int count)
138{
139 int i, bit, start;
140
141 printk(KERN_DEBUG "ir samples: ");
142 start = 0;
143 for (i = 0; i < count * 32; i++) {
144 bit = getbit(samples,i);
145 if (bit)
146 start = 1;
147 if (0 == start)
148 continue;
149 printk("%s", bit ? "#" : "_");
150 }
151 printk("\n");
152 return 0;
153}
154EXPORT_SYMBOL_GPL(ir_dump_samples);
155
156/* decode raw samples, pulse distance coding used by NEC remotes */
157int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
158{
159 int i,last,bit,len;
160 u32 curBit;
161 u32 value;
162
163 /* find start burst */
164 for (i = len = 0; i < count * 32; i++) {
165 bit = getbit(samples,i);
166 if (bit) {
167 len++;
168 } else {
169 if (len >= 29)
170 break;
171 len = 0;
172 }
173 }
174
175 /* start burst to short */
176 if (len < 29)
177 return 0xffffffff;
178
179 /* find start silence */
180 for (len = 0; i < count * 32; i++) {
181 bit = getbit(samples,i);
182 if (bit) {
183 break;
184 } else {
185 len++;
186 }
187 }
188
189 /* silence to short */
190 if (len < 7)
191 return 0xffffffff;
192
193 /* go decoding */
194 len = 0;
195 last = 1;
196 value = 0; curBit = 1;
197 for (; i < count * 32; i++) {
198 bit = getbit(samples,i);
199 if (last) {
200 if(bit) {
201 continue;
202 } else {
203 len = 1;
204 }
205 } else {
206 if (bit) {
207 if (len > (low + high) /2)
208 value |= curBit;
209 curBit <<= 1;
210 if (curBit == 1)
211 break;
212 } else {
213 len++;
214 }
215 }
216 last = bit;
217 }
218
219 return value;
220}
221EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
222
223/* decode raw samples, biphase coding, used by rc5 for example */
224int ir_decode_biphase(u32 *samples, int count, int low, int high)
225{
226 int i,last,bit,len,flips;
227 u32 value;
228
229 /* find start bit (1) */
230 for (i = 0; i < 32; i++) {
231 bit = getbit(samples,i);
232 if (bit)
233 break;
234 }
235
236 /* go decoding */
237 len = 0;
238 flips = 0;
239 value = 1;
240 for (; i < count * 32; i++) {
241 if (len > high)
242 break;
243 if (flips > 1)
244 break;
245 last = bit;
246 bit = getbit(samples,i);
247 if (last == bit) {
248 len++;
249 continue;
250 }
251 if (len < low) {
252 len++;
253 flips++;
254 continue;
255 }
256 value <<= 1;
257 value |= bit;
258 flips = 0;
259 len = 1;
260 }
261 return value;
262}
263EXPORT_SYMBOL_GPL(ir_decode_biphase);
264
265/* RC5 decoding stuff, moved from bttv-input.c to share it with
266 * saa7134 */
267
268/* decode raw bit pattern to RC5 code */
269u32 ir_rc5_decode(unsigned int code)
270{
271 unsigned int org_code = code;
272 unsigned int pair;
273 unsigned int rc5 = 0;
274 int i;
275
276 for (i = 0; i < 14; ++i) {
277 pair = code & 0x3;
278 code >>= 2;
279
280 rc5 <<= 1;
281 switch (pair) {
282 case 0:
283 case 2:
284 break;
285 case 1:
286 rc5 |= 1;
287 break;
288 case 3:
289 IR_dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);
290 return 0;
291 }
292 }
293 IR_dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
294 "instr=%x\n", rc5, org_code, RC5_START(rc5),
295 RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
296 return rc5;
297}
298EXPORT_SYMBOL_GPL(ir_rc5_decode);
299
300void ir_rc5_timer_end(unsigned long data)
301{
302 struct card_ir *ir = (struct card_ir *)data;
303 struct timeval tv;
304 unsigned long current_jiffies, timeout;
305 u32 gap;
306 u32 rc5 = 0;
307
308 /* get time */
309 current_jiffies = jiffies;
310 do_gettimeofday(&tv);
311
312 /* avoid overflow with gap >1s */
313 if (tv.tv_sec - ir->base_time.tv_sec > 1) {
314 gap = 200000;
315 } else {
316 gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
317 tv.tv_usec - ir->base_time.tv_usec;
318 }
319
320 /* signal we're ready to start a new code */
321 ir->active = 0;
322
323 /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
324 if (gap < 28000) {
325 IR_dprintk(1, "ir-common: spurious timer_end\n");
326 return;
327 }
328
329 if (ir->last_bit < 20) {
330 /* ignore spurious codes (caused by light/other remotes) */
331 IR_dprintk(1, "ir-common: short code: %x\n", ir->code);
332 } else {
333 ir->code = (ir->code << ir->shift_by) | 1;
334 rc5 = ir_rc5_decode(ir->code);
335
336 /* two start bits? */
337 if (RC5_START(rc5) != ir->start) {
338 IR_dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5));
339
340 /* right address? */
341 } else if (RC5_ADDR(rc5) == ir->addr) {
342 u32 toggle = RC5_TOGGLE(rc5);
343 u32 instr = RC5_INSTR(rc5);
344
345 /* Good code, decide if repeat/repress */
346 if (toggle != RC5_TOGGLE(ir->last_rc5) ||
347 instr != RC5_INSTR(ir->last_rc5)) {
348 IR_dprintk(1, "ir-common: instruction %x, toggle %x\n", instr,
349 toggle);
350 ir_input_nokey(ir->dev, &ir->ir);
351 ir_input_keydown(ir->dev, &ir->ir, instr);
352 }
353
354 /* Set/reset key-up timer */
355 timeout = current_jiffies +
356 msecs_to_jiffies(ir->rc5_key_timeout);
357 mod_timer(&ir->timer_keyup, timeout);
358
359 /* Save code for repeat test */
360 ir->last_rc5 = rc5;
361 }
362 }
363}
364EXPORT_SYMBOL_GPL(ir_rc5_timer_end);
365
366void ir_rc5_timer_keyup(unsigned long data)
367{
368 struct card_ir *ir = (struct card_ir *)data;
369
370 IR_dprintk(1, "ir-common: key released\n");
371 ir_input_nokey(ir->dev, &ir->ir);
372}
373EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup);
diff --git a/drivers/media/IR/ir-keymaps.c b/drivers/media/IR/ir-keymaps.c
new file mode 100644
index 000000000000..9bbe6b1e9871
--- /dev/null
+++ b/drivers/media/IR/ir-keymaps.c
@@ -0,0 +1,3395 @@
1/*
2 Keytables for supported remote controls, used on drivers/media
3 devices.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20/*
21 * NOTICE FOR DEVELOPERS:
22 * The IR mappings should be as close as possible to what's
23 * specified at:
24 * http://linuxtv.org/wiki/index.php/Remote_Controllers
25 */
26#include <linux/module.h>
27
28#include <linux/input.h>
29#include <media/ir-common.h>
30
31/* empty keytable, can be used as placeholder for not-yet created keytables */
32static struct ir_scancode ir_codes_empty[] = {
33 { 0x2a, KEY_COFFEE },
34};
35
36struct ir_scancode_table ir_codes_empty_table = {
37 .scan = ir_codes_empty,
38 .size = ARRAY_SIZE(ir_codes_empty),
39};
40EXPORT_SYMBOL_GPL(ir_codes_empty_table);
41
42/* Michal Majchrowicz <mmajchrowicz@gmail.com> */
43static struct ir_scancode ir_codes_proteus_2309[] = {
44 /* numeric */
45 { 0x00, KEY_0 },
46 { 0x01, KEY_1 },
47 { 0x02, KEY_2 },
48 { 0x03, KEY_3 },
49 { 0x04, KEY_4 },
50 { 0x05, KEY_5 },
51 { 0x06, KEY_6 },
52 { 0x07, KEY_7 },
53 { 0x08, KEY_8 },
54 { 0x09, KEY_9 },
55
56 { 0x5c, KEY_POWER }, /* power */
57 { 0x20, KEY_ZOOM }, /* full screen */
58 { 0x0f, KEY_BACKSPACE }, /* recall */
59 { 0x1b, KEY_ENTER }, /* mute */
60 { 0x41, KEY_RECORD }, /* record */
61 { 0x43, KEY_STOP }, /* stop */
62 { 0x16, KEY_S },
63 { 0x1a, KEY_POWER2 }, /* off */
64 { 0x2e, KEY_RED },
65 { 0x1f, KEY_CHANNELDOWN }, /* channel - */
66 { 0x1c, KEY_CHANNELUP }, /* channel + */
67 { 0x10, KEY_VOLUMEDOWN }, /* volume - */
68 { 0x1e, KEY_VOLUMEUP }, /* volume + */
69 { 0x14, KEY_F1 },
70};
71
72struct ir_scancode_table ir_codes_proteus_2309_table = {
73 .scan = ir_codes_proteus_2309,
74 .size = ARRAY_SIZE(ir_codes_proteus_2309),
75};
76EXPORT_SYMBOL_GPL(ir_codes_proteus_2309_table);
77
78/* Matt Jesson <dvb@jesson.eclipse.co.uk */
79static struct ir_scancode ir_codes_avermedia_dvbt[] = {
80 { 0x28, KEY_0 }, /* '0' / 'enter' */
81 { 0x22, KEY_1 }, /* '1' */
82 { 0x12, KEY_2 }, /* '2' / 'up arrow' */
83 { 0x32, KEY_3 }, /* '3' */
84 { 0x24, KEY_4 }, /* '4' / 'left arrow' */
85 { 0x14, KEY_5 }, /* '5' */
86 { 0x34, KEY_6 }, /* '6' / 'right arrow' */
87 { 0x26, KEY_7 }, /* '7' */
88 { 0x16, KEY_8 }, /* '8' / 'down arrow' */
89 { 0x36, KEY_9 }, /* '9' */
90
91 { 0x20, KEY_LIST }, /* 'source' */
92 { 0x10, KEY_TEXT }, /* 'teletext' */
93 { 0x00, KEY_POWER }, /* 'power' */
94 { 0x04, KEY_AUDIO }, /* 'audio' */
95 { 0x06, KEY_ZOOM }, /* 'full screen' */
96 { 0x18, KEY_VIDEO }, /* 'display' */
97 { 0x38, KEY_SEARCH }, /* 'loop' */
98 { 0x08, KEY_INFO }, /* 'preview' */
99 { 0x2a, KEY_REWIND }, /* 'backward <<' */
100 { 0x1a, KEY_FASTFORWARD }, /* 'forward >>' */
101 { 0x3a, KEY_RECORD }, /* 'capture' */
102 { 0x0a, KEY_MUTE }, /* 'mute' */
103 { 0x2c, KEY_RECORD }, /* 'record' */
104 { 0x1c, KEY_PAUSE }, /* 'pause' */
105 { 0x3c, KEY_STOP }, /* 'stop' */
106 { 0x0c, KEY_PLAY }, /* 'play' */
107 { 0x2e, KEY_RED }, /* 'red' */
108 { 0x01, KEY_BLUE }, /* 'blue' / 'cancel' */
109 { 0x0e, KEY_YELLOW }, /* 'yellow' / 'ok' */
110 { 0x21, KEY_GREEN }, /* 'green' */
111 { 0x11, KEY_CHANNELDOWN }, /* 'channel -' */
112 { 0x31, KEY_CHANNELUP }, /* 'channel +' */
113 { 0x1e, KEY_VOLUMEDOWN }, /* 'volume -' */
114 { 0x3e, KEY_VOLUMEUP }, /* 'volume +' */
115};
116
117struct ir_scancode_table ir_codes_avermedia_dvbt_table = {
118 .scan = ir_codes_avermedia_dvbt,
119 .size = ARRAY_SIZE(ir_codes_avermedia_dvbt),
120};
121EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt_table);
122
123/* Mauro Carvalho Chehab <mchehab@infradead.org> */
124static struct ir_scancode ir_codes_avermedia_m135a[] = {
125 { 0x00, KEY_POWER2 },
126 { 0x2e, KEY_DOT }, /* '.' */
127 { 0x01, KEY_MODE }, /* TV/FM */
128
129 { 0x05, KEY_1 },
130 { 0x06, KEY_2 },
131 { 0x07, KEY_3 },
132 { 0x09, KEY_4 },
133 { 0x0a, KEY_5 },
134 { 0x0b, KEY_6 },
135 { 0x0d, KEY_7 },
136 { 0x0e, KEY_8 },
137 { 0x0f, KEY_9 },
138 { 0x11, KEY_0 },
139
140 { 0x13, KEY_RIGHT }, /* -> */
141 { 0x12, KEY_LEFT }, /* <- */
142
143 { 0x17, KEY_SLEEP }, /* Capturar Imagem */
144 { 0x10, KEY_SHUFFLE }, /* Amostra */
145
146 /* FIXME: The keys bellow aren't ok */
147
148 { 0x43, KEY_CHANNELUP },
149 { 0x42, KEY_CHANNELDOWN },
150 { 0x1f, KEY_VOLUMEUP },
151 { 0x1e, KEY_VOLUMEDOWN },
152 { 0x0c, KEY_ENTER },
153
154 { 0x14, KEY_MUTE },
155 { 0x08, KEY_AUDIO },
156
157 { 0x03, KEY_TEXT },
158 { 0x04, KEY_EPG },
159 { 0x2b, KEY_TV2 }, /* TV2 */
160
161 { 0x1d, KEY_RED },
162 { 0x1c, KEY_YELLOW },
163 { 0x41, KEY_GREEN },
164 { 0x40, KEY_BLUE },
165
166 { 0x1a, KEY_PLAYPAUSE },
167 { 0x19, KEY_RECORD },
168 { 0x18, KEY_PLAY },
169 { 0x1b, KEY_STOP },
170};
171
172struct ir_scancode_table ir_codes_avermedia_m135a_table = {
173 .scan = ir_codes_avermedia_m135a,
174 .size = ARRAY_SIZE(ir_codes_avermedia_m135a),
175};
176EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a_table);
177
178/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
179static struct ir_scancode ir_codes_avermedia_cardbus[] = {
180 { 0x00, KEY_POWER },
181 { 0x01, KEY_TUNER }, /* TV/FM */
182 { 0x03, KEY_TEXT }, /* Teletext */
183 { 0x04, KEY_EPG },
184 { 0x05, KEY_1 },
185 { 0x06, KEY_2 },
186 { 0x07, KEY_3 },
187 { 0x08, KEY_AUDIO },
188 { 0x09, KEY_4 },
189 { 0x0a, KEY_5 },
190 { 0x0b, KEY_6 },
191 { 0x0c, KEY_ZOOM }, /* Full screen */
192 { 0x0d, KEY_7 },
193 { 0x0e, KEY_8 },
194 { 0x0f, KEY_9 },
195 { 0x10, KEY_PAGEUP }, /* 16-CH PREV */
196 { 0x11, KEY_0 },
197 { 0x12, KEY_INFO },
198 { 0x13, KEY_AGAIN }, /* CH RTN - channel return */
199 { 0x14, KEY_MUTE },
200 { 0x15, KEY_EDIT }, /* Autoscan */
201 { 0x17, KEY_SAVE }, /* Screenshot */
202 { 0x18, KEY_PLAYPAUSE },
203 { 0x19, KEY_RECORD },
204 { 0x1a, KEY_PLAY },
205 { 0x1b, KEY_STOP },
206 { 0x1c, KEY_FASTFORWARD },
207 { 0x1d, KEY_REWIND },
208 { 0x1e, KEY_VOLUMEDOWN },
209 { 0x1f, KEY_VOLUMEUP },
210 { 0x22, KEY_SLEEP }, /* Sleep */
211 { 0x23, KEY_ZOOM }, /* Aspect */
212 { 0x26, KEY_SCREEN }, /* Pos */
213 { 0x27, KEY_ANGLE }, /* Size */
214 { 0x28, KEY_SELECT }, /* Select */
215 { 0x29, KEY_BLUE }, /* Blue/Picture */
216 { 0x2a, KEY_BACKSPACE }, /* Back */
217 { 0x2b, KEY_MEDIA }, /* PIP (Picture-in-picture) */
218 { 0x2c, KEY_DOWN },
219 { 0x2e, KEY_DOT },
220 { 0x2f, KEY_TV }, /* Live TV */
221 { 0x32, KEY_LEFT },
222 { 0x33, KEY_CLEAR }, /* Clear */
223 { 0x35, KEY_RED }, /* Red/TV */
224 { 0x36, KEY_UP },
225 { 0x37, KEY_HOME }, /* Home */
226 { 0x39, KEY_GREEN }, /* Green/Video */
227 { 0x3d, KEY_YELLOW }, /* Yellow/Music */
228 { 0x3e, KEY_OK }, /* Ok */
229 { 0x3f, KEY_RIGHT },
230 { 0x40, KEY_NEXT }, /* Next */
231 { 0x41, KEY_PREVIOUS }, /* Previous */
232 { 0x42, KEY_CHANNELDOWN }, /* Channel down */
233 { 0x43, KEY_CHANNELUP }, /* Channel up */
234};
235
236struct ir_scancode_table ir_codes_avermedia_cardbus_table = {
237 .scan = ir_codes_avermedia_cardbus,
238 .size = ARRAY_SIZE(ir_codes_avermedia_cardbus),
239};
240EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus_table);
241
242/* Attila Kondoros <attila.kondoros@chello.hu> */
243static struct ir_scancode ir_codes_apac_viewcomp[] = {
244
245 { 0x01, KEY_1 },
246 { 0x02, KEY_2 },
247 { 0x03, KEY_3 },
248 { 0x04, KEY_4 },
249 { 0x05, KEY_5 },
250 { 0x06, KEY_6 },
251 { 0x07, KEY_7 },
252 { 0x08, KEY_8 },
253 { 0x09, KEY_9 },
254 { 0x00, KEY_0 },
255 { 0x17, KEY_LAST }, /* +100 */
256 { 0x0a, KEY_LIST }, /* recall */
257
258
259 { 0x1c, KEY_TUNER }, /* TV/FM */
260 { 0x15, KEY_SEARCH }, /* scan */
261 { 0x12, KEY_POWER }, /* power */
262 { 0x1f, KEY_VOLUMEDOWN }, /* vol up */
263 { 0x1b, KEY_VOLUMEUP }, /* vol down */
264 { 0x1e, KEY_CHANNELDOWN }, /* chn up */
265 { 0x1a, KEY_CHANNELUP }, /* chn down */
266
267 { 0x11, KEY_VIDEO }, /* video */
268 { 0x0f, KEY_ZOOM }, /* full screen */
269 { 0x13, KEY_MUTE }, /* mute/unmute */
270 { 0x10, KEY_TEXT }, /* min */
271
272 { 0x0d, KEY_STOP }, /* freeze */
273 { 0x0e, KEY_RECORD }, /* record */
274 { 0x1d, KEY_PLAYPAUSE }, /* stop */
275 { 0x19, KEY_PLAY }, /* play */
276
277 { 0x16, KEY_GOTO }, /* osd */
278 { 0x14, KEY_REFRESH }, /* default */
279 { 0x0c, KEY_KPPLUS }, /* fine tune >>>> */
280 { 0x18, KEY_KPMINUS }, /* fine tune <<<< */
281};
282
283struct ir_scancode_table ir_codes_apac_viewcomp_table = {
284 .scan = ir_codes_apac_viewcomp,
285 .size = ARRAY_SIZE(ir_codes_apac_viewcomp),
286};
287EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp_table);
288
289/* ---------------------------------------------------------------------- */
290
291static struct ir_scancode ir_codes_pixelview[] = {
292
293 { 0x1e, KEY_POWER }, /* power */
294 { 0x07, KEY_MEDIA }, /* source */
295 { 0x1c, KEY_SEARCH }, /* scan */
296
297
298 { 0x03, KEY_TUNER }, /* TV/FM */
299
300 { 0x00, KEY_RECORD },
301 { 0x08, KEY_STOP },
302 { 0x11, KEY_PLAY },
303
304 { 0x1a, KEY_PLAYPAUSE }, /* freeze */
305 { 0x19, KEY_ZOOM }, /* zoom */
306 { 0x0f, KEY_TEXT }, /* min */
307
308 { 0x01, KEY_1 },
309 { 0x0b, KEY_2 },
310 { 0x1b, KEY_3 },
311 { 0x05, KEY_4 },
312 { 0x09, KEY_5 },
313 { 0x15, KEY_6 },
314 { 0x06, KEY_7 },
315 { 0x0a, KEY_8 },
316 { 0x12, KEY_9 },
317 { 0x02, KEY_0 },
318 { 0x10, KEY_LAST }, /* +100 */
319 { 0x13, KEY_LIST }, /* recall */
320
321 { 0x1f, KEY_CHANNELUP }, /* chn down */
322 { 0x17, KEY_CHANNELDOWN }, /* chn up */
323 { 0x16, KEY_VOLUMEUP }, /* vol down */
324 { 0x14, KEY_VOLUMEDOWN }, /* vol up */
325
326 { 0x04, KEY_KPMINUS }, /* <<< */
327 { 0x0e, KEY_SETUP }, /* function */
328 { 0x0c, KEY_KPPLUS }, /* >>> */
329
330 { 0x0d, KEY_GOTO }, /* mts */
331 { 0x1d, KEY_REFRESH }, /* reset */
332 { 0x18, KEY_MUTE }, /* mute/unmute */
333};
334
335struct ir_scancode_table ir_codes_pixelview_table = {
336 .scan = ir_codes_pixelview,
337 .size = ARRAY_SIZE(ir_codes_pixelview),
338};
339EXPORT_SYMBOL_GPL(ir_codes_pixelview_table);
340
341/*
342 Mauro Carvalho Chehab <mchehab@infradead.org>
343 present on PV MPEG 8000GT
344 */
345static struct ir_scancode ir_codes_pixelview_new[] = {
346 { 0x3c, KEY_TIME }, /* Timeshift */
347 { 0x12, KEY_POWER },
348
349 { 0x3d, KEY_1 },
350 { 0x38, KEY_2 },
351 { 0x18, KEY_3 },
352 { 0x35, KEY_4 },
353 { 0x39, KEY_5 },
354 { 0x15, KEY_6 },
355 { 0x36, KEY_7 },
356 { 0x3a, KEY_8 },
357 { 0x1e, KEY_9 },
358 { 0x3e, KEY_0 },
359
360 { 0x1c, KEY_AGAIN }, /* LOOP */
361 { 0x3f, KEY_MEDIA }, /* Source */
362 { 0x1f, KEY_LAST }, /* +100 */
363 { 0x1b, KEY_MUTE },
364
365 { 0x17, KEY_CHANNELDOWN },
366 { 0x16, KEY_CHANNELUP },
367 { 0x10, KEY_VOLUMEUP },
368 { 0x14, KEY_VOLUMEDOWN },
369 { 0x13, KEY_ZOOM },
370
371 { 0x19, KEY_CAMERA }, /* SNAPSHOT */
372 { 0x1a, KEY_SEARCH }, /* scan */
373
374 { 0x37, KEY_REWIND }, /* << */
375 { 0x32, KEY_RECORD }, /* o (red) */
376 { 0x33, KEY_FORWARD }, /* >> */
377 { 0x11, KEY_STOP }, /* square */
378 { 0x3b, KEY_PLAY }, /* > */
379 { 0x30, KEY_PLAYPAUSE }, /* || */
380
381 { 0x31, KEY_TV },
382 { 0x34, KEY_RADIO },
383};
384
385struct ir_scancode_table ir_codes_pixelview_new_table = {
386 .scan = ir_codes_pixelview_new,
387 .size = ARRAY_SIZE(ir_codes_pixelview_new),
388};
389EXPORT_SYMBOL_GPL(ir_codes_pixelview_new_table);
390
391static struct ir_scancode ir_codes_nebula[] = {
392 { 0x00, KEY_0 },
393 { 0x01, KEY_1 },
394 { 0x02, KEY_2 },
395 { 0x03, KEY_3 },
396 { 0x04, KEY_4 },
397 { 0x05, KEY_5 },
398 { 0x06, KEY_6 },
399 { 0x07, KEY_7 },
400 { 0x08, KEY_8 },
401 { 0x09, KEY_9 },
402 { 0x0a, KEY_TV },
403 { 0x0b, KEY_AUX },
404 { 0x0c, KEY_DVD },
405 { 0x0d, KEY_POWER },
406 { 0x0e, KEY_MHP }, /* labelled 'Picture' */
407 { 0x0f, KEY_AUDIO },
408 { 0x10, KEY_INFO },
409 { 0x11, KEY_F13 }, /* 16:9 */
410 { 0x12, KEY_F14 }, /* 14:9 */
411 { 0x13, KEY_EPG },
412 { 0x14, KEY_EXIT },
413 { 0x15, KEY_MENU },
414 { 0x16, KEY_UP },
415 { 0x17, KEY_DOWN },
416 { 0x18, KEY_LEFT },
417 { 0x19, KEY_RIGHT },
418 { 0x1a, KEY_ENTER },
419 { 0x1b, KEY_CHANNELUP },
420 { 0x1c, KEY_CHANNELDOWN },
421 { 0x1d, KEY_VOLUMEUP },
422 { 0x1e, KEY_VOLUMEDOWN },
423 { 0x1f, KEY_RED },
424 { 0x20, KEY_GREEN },
425 { 0x21, KEY_YELLOW },
426 { 0x22, KEY_BLUE },
427 { 0x23, KEY_SUBTITLE },
428 { 0x24, KEY_F15 }, /* AD */
429 { 0x25, KEY_TEXT },
430 { 0x26, KEY_MUTE },
431 { 0x27, KEY_REWIND },
432 { 0x28, KEY_STOP },
433 { 0x29, KEY_PLAY },
434 { 0x2a, KEY_FASTFORWARD },
435 { 0x2b, KEY_F16 }, /* chapter */
436 { 0x2c, KEY_PAUSE },
437 { 0x2d, KEY_PLAY },
438 { 0x2e, KEY_RECORD },
439 { 0x2f, KEY_F17 }, /* picture in picture */
440 { 0x30, KEY_KPPLUS }, /* zoom in */
441 { 0x31, KEY_KPMINUS }, /* zoom out */
442 { 0x32, KEY_F18 }, /* capture */
443 { 0x33, KEY_F19 }, /* web */
444 { 0x34, KEY_EMAIL },
445 { 0x35, KEY_PHONE },
446 { 0x36, KEY_PC },
447};
448
449struct ir_scancode_table ir_codes_nebula_table = {
450 .scan = ir_codes_nebula,
451 .size = ARRAY_SIZE(ir_codes_nebula),
452};
453EXPORT_SYMBOL_GPL(ir_codes_nebula_table);
454
455/* DigitalNow DNTV Live DVB-T Remote */
456static struct ir_scancode ir_codes_dntv_live_dvb_t[] = {
457 { 0x00, KEY_ESC }, /* 'go up a level?' */
458 /* Keys 0 to 9 */
459 { 0x0a, KEY_0 },
460 { 0x01, KEY_1 },
461 { 0x02, KEY_2 },
462 { 0x03, KEY_3 },
463 { 0x04, KEY_4 },
464 { 0x05, KEY_5 },
465 { 0x06, KEY_6 },
466 { 0x07, KEY_7 },
467 { 0x08, KEY_8 },
468 { 0x09, KEY_9 },
469
470 { 0x0b, KEY_TUNER }, /* tv/fm */
471 { 0x0c, KEY_SEARCH }, /* scan */
472 { 0x0d, KEY_STOP },
473 { 0x0e, KEY_PAUSE },
474 { 0x0f, KEY_LIST }, /* source */
475
476 { 0x10, KEY_MUTE },
477 { 0x11, KEY_REWIND }, /* backward << */
478 { 0x12, KEY_POWER },
479 { 0x13, KEY_CAMERA }, /* snap */
480 { 0x14, KEY_AUDIO }, /* stereo */
481 { 0x15, KEY_CLEAR }, /* reset */
482 { 0x16, KEY_PLAY },
483 { 0x17, KEY_ENTER },
484 { 0x18, KEY_ZOOM }, /* full screen */
485 { 0x19, KEY_FASTFORWARD }, /* forward >> */
486 { 0x1a, KEY_CHANNELUP },
487 { 0x1b, KEY_VOLUMEUP },
488 { 0x1c, KEY_INFO }, /* preview */
489 { 0x1d, KEY_RECORD }, /* record */
490 { 0x1e, KEY_CHANNELDOWN },
491 { 0x1f, KEY_VOLUMEDOWN },
492};
493
494struct ir_scancode_table ir_codes_dntv_live_dvb_t_table = {
495 .scan = ir_codes_dntv_live_dvb_t,
496 .size = ARRAY_SIZE(ir_codes_dntv_live_dvb_t),
497};
498EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t_table);
499
500/* ---------------------------------------------------------------------- */
501
502/* IO-DATA BCTV7E Remote */
503static struct ir_scancode ir_codes_iodata_bctv7e[] = {
504 { 0x40, KEY_TV },
505 { 0x20, KEY_RADIO }, /* FM */
506 { 0x60, KEY_EPG },
507 { 0x00, KEY_POWER },
508
509 /* Keys 0 to 9 */
510 { 0x44, KEY_0 }, /* 10 */
511 { 0x50, KEY_1 },
512 { 0x30, KEY_2 },
513 { 0x70, KEY_3 },
514 { 0x48, KEY_4 },
515 { 0x28, KEY_5 },
516 { 0x68, KEY_6 },
517 { 0x58, KEY_7 },
518 { 0x38, KEY_8 },
519 { 0x78, KEY_9 },
520
521 { 0x10, KEY_L }, /* Live */
522 { 0x08, KEY_TIME }, /* Time Shift */
523
524 { 0x18, KEY_PLAYPAUSE }, /* Play */
525
526 { 0x24, KEY_ENTER }, /* 11 */
527 { 0x64, KEY_ESC }, /* 12 */
528 { 0x04, KEY_M }, /* Multi */
529
530 { 0x54, KEY_VIDEO },
531 { 0x34, KEY_CHANNELUP },
532 { 0x74, KEY_VOLUMEUP },
533 { 0x14, KEY_MUTE },
534
535 { 0x4c, KEY_VCR }, /* SVIDEO */
536 { 0x2c, KEY_CHANNELDOWN },
537 { 0x6c, KEY_VOLUMEDOWN },
538 { 0x0c, KEY_ZOOM },
539
540 { 0x5c, KEY_PAUSE },
541 { 0x3c, KEY_RED }, /* || (red) */
542 { 0x7c, KEY_RECORD }, /* recording */
543 { 0x1c, KEY_STOP },
544
545 { 0x41, KEY_REWIND }, /* backward << */
546 { 0x21, KEY_PLAY },
547 { 0x61, KEY_FASTFORWARD }, /* forward >> */
548 { 0x01, KEY_NEXT }, /* skip >| */
549};
550
551struct ir_scancode_table ir_codes_iodata_bctv7e_table = {
552 .scan = ir_codes_iodata_bctv7e,
553 .size = ARRAY_SIZE(ir_codes_iodata_bctv7e),
554};
555EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e_table);
556
557/* ---------------------------------------------------------------------- */
558
559/* ADS Tech Instant TV DVB-T PCI Remote */
560static struct ir_scancode ir_codes_adstech_dvb_t_pci[] = {
561 /* Keys 0 to 9 */
562 { 0x4d, KEY_0 },
563 { 0x57, KEY_1 },
564 { 0x4f, KEY_2 },
565 { 0x53, KEY_3 },
566 { 0x56, KEY_4 },
567 { 0x4e, KEY_5 },
568 { 0x5e, KEY_6 },
569 { 0x54, KEY_7 },
570 { 0x4c, KEY_8 },
571 { 0x5c, KEY_9 },
572
573 { 0x5b, KEY_POWER },
574 { 0x5f, KEY_MUTE },
575 { 0x55, KEY_GOTO },
576 { 0x5d, KEY_SEARCH },
577 { 0x17, KEY_EPG }, /* Guide */
578 { 0x1f, KEY_MENU },
579 { 0x0f, KEY_UP },
580 { 0x46, KEY_DOWN },
581 { 0x16, KEY_LEFT },
582 { 0x1e, KEY_RIGHT },
583 { 0x0e, KEY_SELECT }, /* Enter */
584 { 0x5a, KEY_INFO },
585 { 0x52, KEY_EXIT },
586 { 0x59, KEY_PREVIOUS },
587 { 0x51, KEY_NEXT },
588 { 0x58, KEY_REWIND },
589 { 0x50, KEY_FORWARD },
590 { 0x44, KEY_PLAYPAUSE },
591 { 0x07, KEY_STOP },
592 { 0x1b, KEY_RECORD },
593 { 0x13, KEY_TUNER }, /* Live */
594 { 0x0a, KEY_A },
595 { 0x12, KEY_B },
596 { 0x03, KEY_PROG1 }, /* 1 */
597 { 0x01, KEY_PROG2 }, /* 2 */
598 { 0x00, KEY_PROG3 }, /* 3 */
599 { 0x06, KEY_DVD },
600 { 0x48, KEY_AUX }, /* Photo */
601 { 0x40, KEY_VIDEO },
602 { 0x19, KEY_AUDIO }, /* Music */
603 { 0x0b, KEY_CHANNELUP },
604 { 0x08, KEY_CHANNELDOWN },
605 { 0x15, KEY_VOLUMEUP },
606 { 0x1c, KEY_VOLUMEDOWN },
607};
608
609struct ir_scancode_table ir_codes_adstech_dvb_t_pci_table = {
610 .scan = ir_codes_adstech_dvb_t_pci,
611 .size = ARRAY_SIZE(ir_codes_adstech_dvb_t_pci),
612};
613EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci_table);
614
615/* ---------------------------------------------------------------------- */
616
617/* MSI TV@nywhere MASTER remote */
618
619static struct ir_scancode ir_codes_msi_tvanywhere[] = {
620 /* Keys 0 to 9 */
621 { 0x00, KEY_0 },
622 { 0x01, KEY_1 },
623 { 0x02, KEY_2 },
624 { 0x03, KEY_3 },
625 { 0x04, KEY_4 },
626 { 0x05, KEY_5 },
627 { 0x06, KEY_6 },
628 { 0x07, KEY_7 },
629 { 0x08, KEY_8 },
630 { 0x09, KEY_9 },
631
632 { 0x0c, KEY_MUTE },
633 { 0x0f, KEY_SCREEN }, /* Full Screen */
634 { 0x10, KEY_FN }, /* Funtion */
635 { 0x11, KEY_TIME }, /* Time shift */
636 { 0x12, KEY_POWER },
637 { 0x13, KEY_MEDIA }, /* MTS */
638 { 0x14, KEY_SLOW },
639 { 0x16, KEY_REWIND }, /* backward << */
640 { 0x17, KEY_ENTER }, /* Return */
641 { 0x18, KEY_FASTFORWARD }, /* forward >> */
642 { 0x1a, KEY_CHANNELUP },
643 { 0x1b, KEY_VOLUMEUP },
644 { 0x1e, KEY_CHANNELDOWN },
645 { 0x1f, KEY_VOLUMEDOWN },
646};
647
648struct ir_scancode_table ir_codes_msi_tvanywhere_table = {
649 .scan = ir_codes_msi_tvanywhere,
650 .size = ARRAY_SIZE(ir_codes_msi_tvanywhere),
651};
652EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_table);
653
654/* ---------------------------------------------------------------------- */
655
656/*
657 Keycodes for remote on the MSI TV@nywhere Plus. The controller IC on the card
658 is marked "KS003". The controller is I2C at address 0x30, but does not seem
659 to respond to probes until a read is performed from a valid device.
660 I don't know why...
661
662 Note: This remote may be of similar or identical design to the
663 Pixelview remote (?). The raw codes and duplicate button codes
664 appear to be the same.
665
666 Henry Wong <henry@stuffedcow.net>
667 Some changes to formatting and keycodes by Mark Schultz <n9xmj@yahoo.com>
668
669*/
670
671static struct ir_scancode ir_codes_msi_tvanywhere_plus[] = {
672
673/* ---- Remote Button Layout ----
674
675 POWER SOURCE SCAN MUTE
676 TV/FM 1 2 3
677 |> 4 5 6
678 <| 7 8 9
679 ^^UP 0 + RECALL
680 vvDN RECORD STOP PLAY
681
682 MINIMIZE ZOOM
683
684 CH+
685 VOL- VOL+
686 CH-
687
688 SNAPSHOT MTS
689
690 << FUNC >> RESET
691*/
692
693 { 0x01, KEY_1 }, /* 1 */
694 { 0x0b, KEY_2 }, /* 2 */
695 { 0x1b, KEY_3 }, /* 3 */
696 { 0x05, KEY_4 }, /* 4 */
697 { 0x09, KEY_5 }, /* 5 */
698 { 0x15, KEY_6 }, /* 6 */
699 { 0x06, KEY_7 }, /* 7 */
700 { 0x0a, KEY_8 }, /* 8 */
701 { 0x12, KEY_9 }, /* 9 */
702 { 0x02, KEY_0 }, /* 0 */
703 { 0x10, KEY_KPPLUS }, /* + */
704 { 0x13, KEY_AGAIN }, /* Recall */
705
706 { 0x1e, KEY_POWER }, /* Power */
707 { 0x07, KEY_TUNER }, /* Source */
708 { 0x1c, KEY_SEARCH }, /* Scan */
709 { 0x18, KEY_MUTE }, /* Mute */
710
711 { 0x03, KEY_RADIO }, /* TV/FM */
712 /* The next four keys are duplicates that appear to send the
713 same IR code as Ch+, Ch-, >>, and << . The raw code assigned
714 to them is the actual code + 0x20 - they will never be
715 detected as such unless some way is discovered to distinguish
716 these buttons from those that have the same code. */
717 { 0x3f, KEY_RIGHT }, /* |> and Ch+ */
718 { 0x37, KEY_LEFT }, /* <| and Ch- */
719 { 0x2c, KEY_UP }, /* ^^Up and >> */
720 { 0x24, KEY_DOWN }, /* vvDn and << */
721
722 { 0x00, KEY_RECORD }, /* Record */
723 { 0x08, KEY_STOP }, /* Stop */
724 { 0x11, KEY_PLAY }, /* Play */
725
726 { 0x0f, KEY_CLOSE }, /* Minimize */
727 { 0x19, KEY_ZOOM }, /* Zoom */
728 { 0x1a, KEY_CAMERA }, /* Snapshot */
729 { 0x0d, KEY_LANGUAGE }, /* MTS */
730
731 { 0x14, KEY_VOLUMEDOWN }, /* Vol- */
732 { 0x16, KEY_VOLUMEUP }, /* Vol+ */
733 { 0x17, KEY_CHANNELDOWN }, /* Ch- */
734 { 0x1f, KEY_CHANNELUP }, /* Ch+ */
735
736 { 0x04, KEY_REWIND }, /* << */
737 { 0x0e, KEY_MENU }, /* Function */
738 { 0x0c, KEY_FASTFORWARD }, /* >> */
739 { 0x1d, KEY_RESTART }, /* Reset */
740};
741
742struct ir_scancode_table ir_codes_msi_tvanywhere_plus_table = {
743 .scan = ir_codes_msi_tvanywhere_plus,
744 .size = ARRAY_SIZE(ir_codes_msi_tvanywhere_plus),
745};
746EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus_table);
747
748/* ---------------------------------------------------------------------- */
749
750/* Cinergy 1400 DVB-T */
751static struct ir_scancode ir_codes_cinergy_1400[] = {
752 { 0x01, KEY_POWER },
753 { 0x02, KEY_1 },
754 { 0x03, KEY_2 },
755 { 0x04, KEY_3 },
756 { 0x05, KEY_4 },
757 { 0x06, KEY_5 },
758 { 0x07, KEY_6 },
759 { 0x08, KEY_7 },
760 { 0x09, KEY_8 },
761 { 0x0a, KEY_9 },
762 { 0x0c, KEY_0 },
763
764 { 0x0b, KEY_VIDEO },
765 { 0x0d, KEY_REFRESH },
766 { 0x0e, KEY_SELECT },
767 { 0x0f, KEY_EPG },
768 { 0x10, KEY_UP },
769 { 0x11, KEY_LEFT },
770 { 0x12, KEY_OK },
771 { 0x13, KEY_RIGHT },
772 { 0x14, KEY_DOWN },
773 { 0x15, KEY_TEXT },
774 { 0x16, KEY_INFO },
775
776 { 0x17, KEY_RED },
777 { 0x18, KEY_GREEN },
778 { 0x19, KEY_YELLOW },
779 { 0x1a, KEY_BLUE },
780
781 { 0x1b, KEY_CHANNELUP },
782 { 0x1c, KEY_VOLUMEUP },
783 { 0x1d, KEY_MUTE },
784 { 0x1e, KEY_VOLUMEDOWN },
785 { 0x1f, KEY_CHANNELDOWN },
786
787 { 0x40, KEY_PAUSE },
788 { 0x4c, KEY_PLAY },
789 { 0x58, KEY_RECORD },
790 { 0x54, KEY_PREVIOUS },
791 { 0x48, KEY_STOP },
792 { 0x5c, KEY_NEXT },
793};
794
795struct ir_scancode_table ir_codes_cinergy_1400_table = {
796 .scan = ir_codes_cinergy_1400,
797 .size = ARRAY_SIZE(ir_codes_cinergy_1400),
798};
799EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400_table);
800
801/* ---------------------------------------------------------------------- */
802
803/* AVERTV STUDIO 303 Remote */
804static struct ir_scancode ir_codes_avertv_303[] = {
805 { 0x2a, KEY_1 },
806 { 0x32, KEY_2 },
807 { 0x3a, KEY_3 },
808 { 0x4a, KEY_4 },
809 { 0x52, KEY_5 },
810 { 0x5a, KEY_6 },
811 { 0x6a, KEY_7 },
812 { 0x72, KEY_8 },
813 { 0x7a, KEY_9 },
814 { 0x0e, KEY_0 },
815
816 { 0x02, KEY_POWER },
817 { 0x22, KEY_VIDEO },
818 { 0x42, KEY_AUDIO },
819 { 0x62, KEY_ZOOM },
820 { 0x0a, KEY_TV },
821 { 0x12, KEY_CD },
822 { 0x1a, KEY_TEXT },
823
824 { 0x16, KEY_SUBTITLE },
825 { 0x1e, KEY_REWIND },
826 { 0x06, KEY_PRINT },
827
828 { 0x2e, KEY_SEARCH },
829 { 0x36, KEY_SLEEP },
830 { 0x3e, KEY_SHUFFLE },
831 { 0x26, KEY_MUTE },
832
833 { 0x4e, KEY_RECORD },
834 { 0x56, KEY_PAUSE },
835 { 0x5e, KEY_STOP },
836 { 0x46, KEY_PLAY },
837
838 { 0x6e, KEY_RED },
839 { 0x0b, KEY_GREEN },
840 { 0x66, KEY_YELLOW },
841 { 0x03, KEY_BLUE },
842
843 { 0x76, KEY_LEFT },
844 { 0x7e, KEY_RIGHT },
845 { 0x13, KEY_DOWN },
846 { 0x1b, KEY_UP },
847};
848
849struct ir_scancode_table ir_codes_avertv_303_table = {
850 .scan = ir_codes_avertv_303,
851 .size = ARRAY_SIZE(ir_codes_avertv_303),
852};
853EXPORT_SYMBOL_GPL(ir_codes_avertv_303_table);
854
855/* ---------------------------------------------------------------------- */
856
857/* DigitalNow DNTV Live! DVB-T Pro Remote */
858static struct ir_scancode ir_codes_dntv_live_dvbt_pro[] = {
859 { 0x16, KEY_POWER },
860 { 0x5b, KEY_HOME },
861
862 { 0x55, KEY_TV }, /* live tv */
863 { 0x58, KEY_TUNER }, /* digital Radio */
864 { 0x5a, KEY_RADIO }, /* FM radio */
865 { 0x59, KEY_DVD }, /* dvd menu */
866 { 0x03, KEY_1 },
867 { 0x01, KEY_2 },
868 { 0x06, KEY_3 },
869 { 0x09, KEY_4 },
870 { 0x1d, KEY_5 },
871 { 0x1f, KEY_6 },
872 { 0x0d, KEY_7 },
873 { 0x19, KEY_8 },
874 { 0x1b, KEY_9 },
875 { 0x0c, KEY_CANCEL },
876 { 0x15, KEY_0 },
877 { 0x4a, KEY_CLEAR },
878 { 0x13, KEY_BACK },
879 { 0x00, KEY_TAB },
880 { 0x4b, KEY_UP },
881 { 0x4e, KEY_LEFT },
882 { 0x4f, KEY_OK },
883 { 0x52, KEY_RIGHT },
884 { 0x51, KEY_DOWN },
885 { 0x1e, KEY_VOLUMEUP },
886 { 0x0a, KEY_VOLUMEDOWN },
887 { 0x02, KEY_CHANNELDOWN },
888 { 0x05, KEY_CHANNELUP },
889 { 0x11, KEY_RECORD },
890 { 0x14, KEY_PLAY },
891 { 0x4c, KEY_PAUSE },
892 { 0x1a, KEY_STOP },
893 { 0x40, KEY_REWIND },
894 { 0x12, KEY_FASTFORWARD },
895 { 0x41, KEY_PREVIOUSSONG }, /* replay |< */
896 { 0x42, KEY_NEXTSONG }, /* skip >| */
897 { 0x54, KEY_CAMERA }, /* capture */
898 { 0x50, KEY_LANGUAGE }, /* sap */
899 { 0x47, KEY_TV2 }, /* pip */
900 { 0x4d, KEY_SCREEN },
901 { 0x43, KEY_SUBTITLE },
902 { 0x10, KEY_MUTE },
903 { 0x49, KEY_AUDIO }, /* l/r */
904 { 0x07, KEY_SLEEP },
905 { 0x08, KEY_VIDEO }, /* a/v */
906 { 0x0e, KEY_PREVIOUS }, /* recall */
907 { 0x45, KEY_ZOOM }, /* zoom + */
908 { 0x46, KEY_ANGLE }, /* zoom - */
909 { 0x56, KEY_RED },
910 { 0x57, KEY_GREEN },
911 { 0x5c, KEY_YELLOW },
912 { 0x5d, KEY_BLUE },
913};
914
915struct ir_scancode_table ir_codes_dntv_live_dvbt_pro_table = {
916 .scan = ir_codes_dntv_live_dvbt_pro,
917 .size = ARRAY_SIZE(ir_codes_dntv_live_dvbt_pro),
918};
919EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro_table);
920
921static struct ir_scancode ir_codes_em_terratec[] = {
922 { 0x01, KEY_CHANNEL },
923 { 0x02, KEY_SELECT },
924 { 0x03, KEY_MUTE },
925 { 0x04, KEY_POWER },
926 { 0x05, KEY_1 },
927 { 0x06, KEY_2 },
928 { 0x07, KEY_3 },
929 { 0x08, KEY_CHANNELUP },
930 { 0x09, KEY_4 },
931 { 0x0a, KEY_5 },
932 { 0x0b, KEY_6 },
933 { 0x0c, KEY_CHANNELDOWN },
934 { 0x0d, KEY_7 },
935 { 0x0e, KEY_8 },
936 { 0x0f, KEY_9 },
937 { 0x10, KEY_VOLUMEUP },
938 { 0x11, KEY_0 },
939 { 0x12, KEY_MENU },
940 { 0x13, KEY_PRINT },
941 { 0x14, KEY_VOLUMEDOWN },
942 { 0x16, KEY_PAUSE },
943 { 0x18, KEY_RECORD },
944 { 0x19, KEY_REWIND },
945 { 0x1a, KEY_PLAY },
946 { 0x1b, KEY_FORWARD },
947 { 0x1c, KEY_BACKSPACE },
948 { 0x1e, KEY_STOP },
949 { 0x40, KEY_ZOOM },
950};
951
952struct ir_scancode_table ir_codes_em_terratec_table = {
953 .scan = ir_codes_em_terratec,
954 .size = ARRAY_SIZE(ir_codes_em_terratec),
955};
956EXPORT_SYMBOL_GPL(ir_codes_em_terratec_table);
957
958static struct ir_scancode ir_codes_pinnacle_grey[] = {
959 { 0x3a, KEY_0 },
960 { 0x31, KEY_1 },
961 { 0x32, KEY_2 },
962 { 0x33, KEY_3 },
963 { 0x34, KEY_4 },
964 { 0x35, KEY_5 },
965 { 0x36, KEY_6 },
966 { 0x37, KEY_7 },
967 { 0x38, KEY_8 },
968 { 0x39, KEY_9 },
969
970 { 0x2f, KEY_POWER },
971
972 { 0x2e, KEY_P },
973 { 0x1f, KEY_L },
974 { 0x2b, KEY_I },
975
976 { 0x2d, KEY_SCREEN },
977 { 0x1e, KEY_ZOOM },
978 { 0x1b, KEY_VOLUMEUP },
979 { 0x0f, KEY_VOLUMEDOWN },
980 { 0x17, KEY_CHANNELUP },
981 { 0x1c, KEY_CHANNELDOWN },
982 { 0x25, KEY_INFO },
983
984 { 0x3c, KEY_MUTE },
985
986 { 0x3d, KEY_LEFT },
987 { 0x3b, KEY_RIGHT },
988
989 { 0x3f, KEY_UP },
990 { 0x3e, KEY_DOWN },
991 { 0x1a, KEY_ENTER },
992
993 { 0x1d, KEY_MENU },
994 { 0x19, KEY_AGAIN },
995 { 0x16, KEY_PREVIOUSSONG },
996 { 0x13, KEY_NEXTSONG },
997 { 0x15, KEY_PAUSE },
998 { 0x0e, KEY_REWIND },
999 { 0x0d, KEY_PLAY },
1000 { 0x0b, KEY_STOP },
1001 { 0x07, KEY_FORWARD },
1002 { 0x27, KEY_RECORD },
1003 { 0x26, KEY_TUNER },
1004 { 0x29, KEY_TEXT },
1005 { 0x2a, KEY_MEDIA },
1006 { 0x18, KEY_EPG },
1007};
1008
1009struct ir_scancode_table ir_codes_pinnacle_grey_table = {
1010 .scan = ir_codes_pinnacle_grey,
1011 .size = ARRAY_SIZE(ir_codes_pinnacle_grey),
1012};
1013EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey_table);
1014
1015static struct ir_scancode ir_codes_flyvideo[] = {
1016 { 0x0f, KEY_0 },
1017 { 0x03, KEY_1 },
1018 { 0x04, KEY_2 },
1019 { 0x05, KEY_3 },
1020 { 0x07, KEY_4 },
1021 { 0x08, KEY_5 },
1022 { 0x09, KEY_6 },
1023 { 0x0b, KEY_7 },
1024 { 0x0c, KEY_8 },
1025 { 0x0d, KEY_9 },
1026
1027 { 0x0e, KEY_MODE }, /* Air/Cable */
1028 { 0x11, KEY_VIDEO }, /* Video */
1029 { 0x15, KEY_AUDIO }, /* Audio */
1030 { 0x00, KEY_POWER }, /* Power */
1031 { 0x18, KEY_TUNER }, /* AV Source */
1032 { 0x02, KEY_ZOOM }, /* Fullscreen */
1033 { 0x1a, KEY_LANGUAGE }, /* Stereo */
1034 { 0x1b, KEY_MUTE }, /* Mute */
1035 { 0x14, KEY_VOLUMEUP }, /* Volume + */
1036 { 0x17, KEY_VOLUMEDOWN },/* Volume - */
1037 { 0x12, KEY_CHANNELUP },/* Channel + */
1038 { 0x13, KEY_CHANNELDOWN },/* Channel - */
1039 { 0x06, KEY_AGAIN }, /* Recall */
1040 { 0x10, KEY_ENTER }, /* Enter */
1041
1042 { 0x19, KEY_BACK }, /* Rewind ( <<< ) */
1043 { 0x1f, KEY_FORWARD }, /* Forward ( >>> ) */
1044 { 0x0a, KEY_ANGLE }, /* no label, may be used as the PAUSE button */
1045};
1046
1047struct ir_scancode_table ir_codes_flyvideo_table = {
1048 .scan = ir_codes_flyvideo,
1049 .size = ARRAY_SIZE(ir_codes_flyvideo),
1050};
1051EXPORT_SYMBOL_GPL(ir_codes_flyvideo_table);
1052
1053static struct ir_scancode ir_codes_flydvb[] = {
1054 { 0x01, KEY_ZOOM }, /* Full Screen */
1055 { 0x00, KEY_POWER }, /* Power */
1056
1057 { 0x03, KEY_1 },
1058 { 0x04, KEY_2 },
1059 { 0x05, KEY_3 },
1060 { 0x07, KEY_4 },
1061 { 0x08, KEY_5 },
1062 { 0x09, KEY_6 },
1063 { 0x0b, KEY_7 },
1064 { 0x0c, KEY_8 },
1065 { 0x0d, KEY_9 },
1066 { 0x06, KEY_AGAIN }, /* Recall */
1067 { 0x0f, KEY_0 },
1068 { 0x10, KEY_MUTE }, /* Mute */
1069 { 0x02, KEY_RADIO }, /* TV/Radio */
1070 { 0x1b, KEY_LANGUAGE }, /* SAP (Second Audio Program) */
1071
1072 { 0x14, KEY_VOLUMEUP }, /* VOL+ */
1073 { 0x17, KEY_VOLUMEDOWN }, /* VOL- */
1074 { 0x12, KEY_CHANNELUP }, /* CH+ */
1075 { 0x13, KEY_CHANNELDOWN }, /* CH- */
1076 { 0x1d, KEY_ENTER }, /* Enter */
1077
1078 { 0x1a, KEY_MODE }, /* PIP */
1079 { 0x18, KEY_TUNER }, /* Source */
1080
1081 { 0x1e, KEY_RECORD }, /* Record/Pause */
1082 { 0x15, KEY_ANGLE }, /* Swap (no label on key) */
1083 { 0x1c, KEY_PAUSE }, /* Timeshift/Pause */
1084 { 0x19, KEY_BACK }, /* Rewind << */
1085 { 0x0a, KEY_PLAYPAUSE }, /* Play/Pause */
1086 { 0x1f, KEY_FORWARD }, /* Forward >> */
1087 { 0x16, KEY_PREVIOUS }, /* Back |<< */
1088 { 0x11, KEY_STOP }, /* Stop */
1089 { 0x0e, KEY_NEXT }, /* End >>| */
1090};
1091
1092struct ir_scancode_table ir_codes_flydvb_table = {
1093 .scan = ir_codes_flydvb,
1094 .size = ARRAY_SIZE(ir_codes_flydvb),
1095};
1096EXPORT_SYMBOL_GPL(ir_codes_flydvb_table);
1097
1098static struct ir_scancode ir_codes_cinergy[] = {
1099 { 0x00, KEY_0 },
1100 { 0x01, KEY_1 },
1101 { 0x02, KEY_2 },
1102 { 0x03, KEY_3 },
1103 { 0x04, KEY_4 },
1104 { 0x05, KEY_5 },
1105 { 0x06, KEY_6 },
1106 { 0x07, KEY_7 },
1107 { 0x08, KEY_8 },
1108 { 0x09, KEY_9 },
1109
1110 { 0x0a, KEY_POWER },
1111 { 0x0b, KEY_PROG1 }, /* app */
1112 { 0x0c, KEY_ZOOM }, /* zoom/fullscreen */
1113 { 0x0d, KEY_CHANNELUP }, /* channel */
1114 { 0x0e, KEY_CHANNELDOWN }, /* channel- */
1115 { 0x0f, KEY_VOLUMEUP },
1116 { 0x10, KEY_VOLUMEDOWN },
1117 { 0x11, KEY_TUNER }, /* AV */
1118 { 0x12, KEY_NUMLOCK }, /* -/-- */
1119 { 0x13, KEY_AUDIO }, /* audio */
1120 { 0x14, KEY_MUTE },
1121 { 0x15, KEY_UP },
1122 { 0x16, KEY_DOWN },
1123 { 0x17, KEY_LEFT },
1124 { 0x18, KEY_RIGHT },
1125 { 0x19, BTN_LEFT, },
1126 { 0x1a, BTN_RIGHT, },
1127 { 0x1b, KEY_WWW }, /* text */
1128 { 0x1c, KEY_REWIND },
1129 { 0x1d, KEY_FORWARD },
1130 { 0x1e, KEY_RECORD },
1131 { 0x1f, KEY_PLAY },
1132 { 0x20, KEY_PREVIOUSSONG },
1133 { 0x21, KEY_NEXTSONG },
1134 { 0x22, KEY_PAUSE },
1135 { 0x23, KEY_STOP },
1136};
1137
1138struct ir_scancode_table ir_codes_cinergy_table = {
1139 .scan = ir_codes_cinergy,
1140 .size = ARRAY_SIZE(ir_codes_cinergy),
1141};
1142EXPORT_SYMBOL_GPL(ir_codes_cinergy_table);
1143
1144/* Alfons Geser <a.geser@cox.net>
1145 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
1146static struct ir_scancode ir_codes_eztv[] = {
1147 { 0x12, KEY_POWER },
1148 { 0x01, KEY_TV }, /* DVR */
1149 { 0x15, KEY_DVD }, /* DVD */
1150 { 0x17, KEY_AUDIO }, /* music */
1151 /* DVR mode / DVD mode / music mode */
1152
1153 { 0x1b, KEY_MUTE }, /* mute */
1154 { 0x02, KEY_LANGUAGE }, /* MTS/SAP / audio / autoseek */
1155 { 0x1e, KEY_SUBTITLE }, /* closed captioning / subtitle / seek */
1156 { 0x16, KEY_ZOOM }, /* full screen */
1157 { 0x1c, KEY_VIDEO }, /* video source / eject / delall */
1158 { 0x1d, KEY_RESTART }, /* playback / angle / del */
1159 { 0x2f, KEY_SEARCH }, /* scan / menu / playlist */
1160 { 0x30, KEY_CHANNEL }, /* CH surfing / bookmark / memo */
1161
1162 { 0x31, KEY_HELP }, /* help */
1163 { 0x32, KEY_MODE }, /* num/memo */
1164 { 0x33, KEY_ESC }, /* cancel */
1165
1166 { 0x0c, KEY_UP }, /* up */
1167 { 0x10, KEY_DOWN }, /* down */
1168 { 0x08, KEY_LEFT }, /* left */
1169 { 0x04, KEY_RIGHT }, /* right */
1170 { 0x03, KEY_SELECT }, /* select */
1171
1172 { 0x1f, KEY_REWIND }, /* rewind */
1173 { 0x20, KEY_PLAYPAUSE },/* play/pause */
1174 { 0x29, KEY_FORWARD }, /* forward */
1175 { 0x14, KEY_AGAIN }, /* repeat */
1176 { 0x2b, KEY_RECORD }, /* recording */
1177 { 0x2c, KEY_STOP }, /* stop */
1178 { 0x2d, KEY_PLAY }, /* play */
1179 { 0x2e, KEY_CAMERA }, /* snapshot / shuffle */
1180
1181 { 0x00, KEY_0 },
1182 { 0x05, KEY_1 },
1183 { 0x06, KEY_2 },
1184 { 0x07, KEY_3 },
1185 { 0x09, KEY_4 },
1186 { 0x0a, KEY_5 },
1187 { 0x0b, KEY_6 },
1188 { 0x0d, KEY_7 },
1189 { 0x0e, KEY_8 },
1190 { 0x0f, KEY_9 },
1191
1192 { 0x2a, KEY_VOLUMEUP },
1193 { 0x11, KEY_VOLUMEDOWN },
1194 { 0x18, KEY_CHANNELUP },/* CH.tracking up */
1195 { 0x19, KEY_CHANNELDOWN },/* CH.tracking down */
1196
1197 { 0x13, KEY_ENTER }, /* enter */
1198 { 0x21, KEY_DOT }, /* . (decimal dot) */
1199};
1200
1201struct ir_scancode_table ir_codes_eztv_table = {
1202 .scan = ir_codes_eztv,
1203 .size = ARRAY_SIZE(ir_codes_eztv),
1204};
1205EXPORT_SYMBOL_GPL(ir_codes_eztv_table);
1206
1207/* Alex Hermann <gaaf@gmx.net> */
1208static struct ir_scancode ir_codes_avermedia[] = {
1209 { 0x28, KEY_1 },
1210 { 0x18, KEY_2 },
1211 { 0x38, KEY_3 },
1212 { 0x24, KEY_4 },
1213 { 0x14, KEY_5 },
1214 { 0x34, KEY_6 },
1215 { 0x2c, KEY_7 },
1216 { 0x1c, KEY_8 },
1217 { 0x3c, KEY_9 },
1218 { 0x22, KEY_0 },
1219
1220 { 0x20, KEY_TV }, /* TV/FM */
1221 { 0x10, KEY_CD }, /* CD */
1222 { 0x30, KEY_TEXT }, /* TELETEXT */
1223 { 0x00, KEY_POWER }, /* POWER */
1224
1225 { 0x08, KEY_VIDEO }, /* VIDEO */
1226 { 0x04, KEY_AUDIO }, /* AUDIO */
1227 { 0x0c, KEY_ZOOM }, /* FULL SCREEN */
1228
1229 { 0x12, KEY_SUBTITLE }, /* DISPLAY */
1230 { 0x32, KEY_REWIND }, /* LOOP */
1231 { 0x02, KEY_PRINT }, /* PREVIEW */
1232
1233 { 0x2a, KEY_SEARCH }, /* AUTOSCAN */
1234 { 0x1a, KEY_SLEEP }, /* FREEZE */
1235 { 0x3a, KEY_CAMERA }, /* SNAPSHOT */
1236 { 0x0a, KEY_MUTE }, /* MUTE */
1237
1238 { 0x26, KEY_RECORD }, /* RECORD */
1239 { 0x16, KEY_PAUSE }, /* PAUSE */
1240 { 0x36, KEY_STOP }, /* STOP */
1241 { 0x06, KEY_PLAY }, /* PLAY */
1242
1243 { 0x2e, KEY_RED }, /* RED */
1244 { 0x21, KEY_GREEN }, /* GREEN */
1245 { 0x0e, KEY_YELLOW }, /* YELLOW */
1246 { 0x01, KEY_BLUE }, /* BLUE */
1247
1248 { 0x1e, KEY_VOLUMEDOWN }, /* VOLUME- */
1249 { 0x3e, KEY_VOLUMEUP }, /* VOLUME+ */
1250 { 0x11, KEY_CHANNELDOWN }, /* CHANNEL/PAGE- */
1251 { 0x31, KEY_CHANNELUP } /* CHANNEL/PAGE+ */
1252};
1253
1254struct ir_scancode_table ir_codes_avermedia_table = {
1255 .scan = ir_codes_avermedia,
1256 .size = ARRAY_SIZE(ir_codes_avermedia),
1257};
1258EXPORT_SYMBOL_GPL(ir_codes_avermedia_table);
1259
1260static struct ir_scancode ir_codes_videomate_tv_pvr[] = {
1261 { 0x14, KEY_MUTE },
1262 { 0x24, KEY_ZOOM },
1263
1264 { 0x01, KEY_DVD },
1265 { 0x23, KEY_RADIO },
1266 { 0x00, KEY_TV },
1267
1268 { 0x0a, KEY_REWIND },
1269 { 0x08, KEY_PLAYPAUSE },
1270 { 0x0f, KEY_FORWARD },
1271
1272 { 0x02, KEY_PREVIOUS },
1273 { 0x07, KEY_STOP },
1274 { 0x06, KEY_NEXT },
1275
1276 { 0x0c, KEY_UP },
1277 { 0x0e, KEY_DOWN },
1278 { 0x0b, KEY_LEFT },
1279 { 0x0d, KEY_RIGHT },
1280 { 0x11, KEY_OK },
1281
1282 { 0x03, KEY_MENU },
1283 { 0x09, KEY_SETUP },
1284 { 0x05, KEY_VIDEO },
1285 { 0x22, KEY_CHANNEL },
1286
1287 { 0x12, KEY_VOLUMEUP },
1288 { 0x15, KEY_VOLUMEDOWN },
1289 { 0x10, KEY_CHANNELUP },
1290 { 0x13, KEY_CHANNELDOWN },
1291
1292 { 0x04, KEY_RECORD },
1293
1294 { 0x16, KEY_1 },
1295 { 0x17, KEY_2 },
1296 { 0x18, KEY_3 },
1297 { 0x19, KEY_4 },
1298 { 0x1a, KEY_5 },
1299 { 0x1b, KEY_6 },
1300 { 0x1c, KEY_7 },
1301 { 0x1d, KEY_8 },
1302 { 0x1e, KEY_9 },
1303 { 0x1f, KEY_0 },
1304
1305 { 0x20, KEY_LANGUAGE },
1306 { 0x21, KEY_SLEEP },
1307};
1308
1309struct ir_scancode_table ir_codes_videomate_tv_pvr_table = {
1310 .scan = ir_codes_videomate_tv_pvr,
1311 .size = ARRAY_SIZE(ir_codes_videomate_tv_pvr),
1312};
1313EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr_table);
1314
1315/* Michael Tokarev <mjt@tls.msk.ru>
1316 http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
1317 keytable is used by MANLI MTV00[0x0c] and BeholdTV 40[13] at
1318 least, and probably other cards too.
1319 The "ascii-art picture" below (in comments, first row
1320 is the keycode in hex, and subsequent row(s) shows
1321 the button labels (several variants when appropriate)
1322 helps to descide which keycodes to assign to the buttons.
1323 */
1324static struct ir_scancode ir_codes_manli[] = {
1325
1326 /* 0x1c 0x12 *
1327 * FUNCTION POWER *
1328 * FM (|) *
1329 * */
1330 { 0x1c, KEY_RADIO }, /*XXX*/
1331 { 0x12, KEY_POWER },
1332
1333 /* 0x01 0x02 0x03 *
1334 * 1 2 3 *
1335 * *
1336 * 0x04 0x05 0x06 *
1337 * 4 5 6 *
1338 * *
1339 * 0x07 0x08 0x09 *
1340 * 7 8 9 *
1341 * */
1342 { 0x01, KEY_1 },
1343 { 0x02, KEY_2 },
1344 { 0x03, KEY_3 },
1345 { 0x04, KEY_4 },
1346 { 0x05, KEY_5 },
1347 { 0x06, KEY_6 },
1348 { 0x07, KEY_7 },
1349 { 0x08, KEY_8 },
1350 { 0x09, KEY_9 },
1351
1352 /* 0x0a 0x00 0x17 *
1353 * RECALL 0 +100 *
1354 * PLUS *
1355 * */
1356 { 0x0a, KEY_AGAIN }, /*XXX KEY_REWIND? */
1357 { 0x00, KEY_0 },
1358 { 0x17, KEY_DIGITS }, /*XXX*/
1359
1360 /* 0x14 0x10 *
1361 * MENU INFO *
1362 * OSD */
1363 { 0x14, KEY_MENU },
1364 { 0x10, KEY_INFO },
1365
1366 /* 0x0b *
1367 * Up *
1368 * *
1369 * 0x18 0x16 0x0c *
1370 * Left Ok Right *
1371 * *
1372 * 0x015 *
1373 * Down *
1374 * */
1375 { 0x0b, KEY_UP },
1376 { 0x18, KEY_LEFT },
1377 { 0x16, KEY_OK }, /*XXX KEY_SELECT? KEY_ENTER? */
1378 { 0x0c, KEY_RIGHT },
1379 { 0x15, KEY_DOWN },
1380
1381 /* 0x11 0x0d *
1382 * TV/AV MODE *
1383 * SOURCE STEREO *
1384 * */
1385 { 0x11, KEY_TV }, /*XXX*/
1386 { 0x0d, KEY_MODE }, /*XXX there's no KEY_STEREO */
1387
1388 /* 0x0f 0x1b 0x1a *
1389 * AUDIO Vol+ Chan+ *
1390 * TIMESHIFT??? *
1391 * *
1392 * 0x0e 0x1f 0x1e *
1393 * SLEEP Vol- Chan- *
1394 * */
1395 { 0x0f, KEY_AUDIO },
1396 { 0x1b, KEY_VOLUMEUP },
1397 { 0x1a, KEY_CHANNELUP },
1398 { 0x0e, KEY_TIME },
1399 { 0x1f, KEY_VOLUMEDOWN },
1400 { 0x1e, KEY_CHANNELDOWN },
1401
1402 /* 0x13 0x19 *
1403 * MUTE SNAPSHOT*
1404 * */
1405 { 0x13, KEY_MUTE },
1406 { 0x19, KEY_CAMERA },
1407
1408 /* 0x1d unused ? */
1409};
1410
1411struct ir_scancode_table ir_codes_manli_table = {
1412 .scan = ir_codes_manli,
1413 .size = ARRAY_SIZE(ir_codes_manli),
1414};
1415EXPORT_SYMBOL_GPL(ir_codes_manli_table);
1416
1417/* Mike Baikov <mike@baikov.com> */
1418static struct ir_scancode ir_codes_gotview7135[] = {
1419
1420 { 0x11, KEY_POWER },
1421 { 0x35, KEY_TV },
1422 { 0x1b, KEY_0 },
1423 { 0x29, KEY_1 },
1424 { 0x19, KEY_2 },
1425 { 0x39, KEY_3 },
1426 { 0x1f, KEY_4 },
1427 { 0x2c, KEY_5 },
1428 { 0x21, KEY_6 },
1429 { 0x24, KEY_7 },
1430 { 0x18, KEY_8 },
1431 { 0x2b, KEY_9 },
1432 { 0x3b, KEY_AGAIN }, /* LOOP */
1433 { 0x06, KEY_AUDIO },
1434 { 0x31, KEY_PRINT }, /* PREVIEW */
1435 { 0x3e, KEY_VIDEO },
1436 { 0x10, KEY_CHANNELUP },
1437 { 0x20, KEY_CHANNELDOWN },
1438 { 0x0c, KEY_VOLUMEDOWN },
1439 { 0x28, KEY_VOLUMEUP },
1440 { 0x08, KEY_MUTE },
1441 { 0x26, KEY_SEARCH }, /* SCAN */
1442 { 0x3f, KEY_CAMERA }, /* SNAPSHOT */
1443 { 0x12, KEY_RECORD },
1444 { 0x32, KEY_STOP },
1445 { 0x3c, KEY_PLAY },
1446 { 0x1d, KEY_REWIND },
1447 { 0x2d, KEY_PAUSE },
1448 { 0x0d, KEY_FORWARD },
1449 { 0x05, KEY_ZOOM }, /*FULL*/
1450
1451 { 0x2a, KEY_F21 }, /* LIVE TIMESHIFT */
1452 { 0x0e, KEY_F22 }, /* MIN TIMESHIFT */
1453 { 0x1e, KEY_TIME }, /* TIMESHIFT */
1454 { 0x38, KEY_F24 }, /* NORMAL TIMESHIFT */
1455};
1456
1457struct ir_scancode_table ir_codes_gotview7135_table = {
1458 .scan = ir_codes_gotview7135,
1459 .size = ARRAY_SIZE(ir_codes_gotview7135),
1460};
1461EXPORT_SYMBOL_GPL(ir_codes_gotview7135_table);
1462
1463static struct ir_scancode ir_codes_purpletv[] = {
1464 { 0x03, KEY_POWER },
1465 { 0x6f, KEY_MUTE },
1466 { 0x10, KEY_BACKSPACE }, /* Recall */
1467
1468 { 0x11, KEY_0 },
1469 { 0x04, KEY_1 },
1470 { 0x05, KEY_2 },
1471 { 0x06, KEY_3 },
1472 { 0x08, KEY_4 },
1473 { 0x09, KEY_5 },
1474 { 0x0a, KEY_6 },
1475 { 0x0c, KEY_7 },
1476 { 0x0d, KEY_8 },
1477 { 0x0e, KEY_9 },
1478 { 0x12, KEY_DOT }, /* 100+ */
1479
1480 { 0x07, KEY_VOLUMEUP },
1481 { 0x0b, KEY_VOLUMEDOWN },
1482 { 0x1a, KEY_KPPLUS },
1483 { 0x18, KEY_KPMINUS },
1484 { 0x15, KEY_UP },
1485 { 0x1d, KEY_DOWN },
1486 { 0x0f, KEY_CHANNELUP },
1487 { 0x13, KEY_CHANNELDOWN },
1488 { 0x48, KEY_ZOOM },
1489
1490 { 0x1b, KEY_VIDEO }, /* Video source */
1491 { 0x1f, KEY_CAMERA }, /* Snapshot */
1492 { 0x49, KEY_LANGUAGE }, /* MTS Select */
1493 { 0x19, KEY_SEARCH }, /* Auto Scan */
1494
1495 { 0x4b, KEY_RECORD },
1496 { 0x46, KEY_PLAY },
1497 { 0x45, KEY_PAUSE }, /* Pause */
1498 { 0x44, KEY_STOP },
1499 { 0x43, KEY_TIME }, /* Time Shift */
1500 { 0x17, KEY_CHANNEL }, /* SURF CH */
1501 { 0x40, KEY_FORWARD }, /* Forward ? */
1502 { 0x42, KEY_REWIND }, /* Backward ? */
1503
1504};
1505
1506struct ir_scancode_table ir_codes_purpletv_table = {
1507 .scan = ir_codes_purpletv,
1508 .size = ARRAY_SIZE(ir_codes_purpletv),
1509};
1510EXPORT_SYMBOL_GPL(ir_codes_purpletv_table);
1511
1512/* Mapping for the 28 key remote control as seen at
1513 http://www.sednacomputer.com/photo/cardbus-tv.jpg
1514 Pavel Mihaylov <bin@bash.info>
1515 Also for the remote bundled with Kozumi KTV-01C card */
1516static struct ir_scancode ir_codes_pctv_sedna[] = {
1517 { 0x00, KEY_0 },
1518 { 0x01, KEY_1 },
1519 { 0x02, KEY_2 },
1520 { 0x03, KEY_3 },
1521 { 0x04, KEY_4 },
1522 { 0x05, KEY_5 },
1523 { 0x06, KEY_6 },
1524 { 0x07, KEY_7 },
1525 { 0x08, KEY_8 },
1526 { 0x09, KEY_9 },
1527
1528 { 0x0a, KEY_AGAIN }, /* Recall */
1529 { 0x0b, KEY_CHANNELUP },
1530 { 0x0c, KEY_VOLUMEUP },
1531 { 0x0d, KEY_MODE }, /* Stereo */
1532 { 0x0e, KEY_STOP },
1533 { 0x0f, KEY_PREVIOUSSONG },
1534 { 0x10, KEY_ZOOM },
1535 { 0x11, KEY_TUNER }, /* Source */
1536 { 0x12, KEY_POWER },
1537 { 0x13, KEY_MUTE },
1538 { 0x15, KEY_CHANNELDOWN },
1539 { 0x18, KEY_VOLUMEDOWN },
1540 { 0x19, KEY_CAMERA }, /* Snapshot */
1541 { 0x1a, KEY_NEXTSONG },
1542 { 0x1b, KEY_TIME }, /* Time Shift */
1543 { 0x1c, KEY_RADIO }, /* FM Radio */
1544 { 0x1d, KEY_RECORD },
1545 { 0x1e, KEY_PAUSE },
1546 /* additional codes for Kozumi's remote */
1547 { 0x14, KEY_INFO }, /* OSD */
1548 { 0x16, KEY_OK }, /* OK */
1549 { 0x17, KEY_DIGITS }, /* Plus */
1550 { 0x1f, KEY_PLAY }, /* Play */
1551};
1552
1553struct ir_scancode_table ir_codes_pctv_sedna_table = {
1554 .scan = ir_codes_pctv_sedna,
1555 .size = ARRAY_SIZE(ir_codes_pctv_sedna),
1556};
1557EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna_table);
1558
1559/* Mark Phalan <phalanm@o2.ie> */
1560static struct ir_scancode ir_codes_pv951[] = {
1561 { 0x00, KEY_0 },
1562 { 0x01, KEY_1 },
1563 { 0x02, KEY_2 },
1564 { 0x03, KEY_3 },
1565 { 0x04, KEY_4 },
1566 { 0x05, KEY_5 },
1567 { 0x06, KEY_6 },
1568 { 0x07, KEY_7 },
1569 { 0x08, KEY_8 },
1570 { 0x09, KEY_9 },
1571
1572 { 0x12, KEY_POWER },
1573 { 0x10, KEY_MUTE },
1574 { 0x1f, KEY_VOLUMEDOWN },
1575 { 0x1b, KEY_VOLUMEUP },
1576 { 0x1a, KEY_CHANNELUP },
1577 { 0x1e, KEY_CHANNELDOWN },
1578 { 0x0e, KEY_PAGEUP },
1579 { 0x1d, KEY_PAGEDOWN },
1580 { 0x13, KEY_SOUND },
1581
1582 { 0x18, KEY_KPPLUSMINUS }, /* CH +/- */
1583 { 0x16, KEY_SUBTITLE }, /* CC */
1584 { 0x0d, KEY_TEXT }, /* TTX */
1585 { 0x0b, KEY_TV }, /* AIR/CBL */
1586 { 0x11, KEY_PC }, /* PC/TV */
1587 { 0x17, KEY_OK }, /* CH RTN */
1588 { 0x19, KEY_MODE }, /* FUNC */
1589 { 0x0c, KEY_SEARCH }, /* AUTOSCAN */
1590
1591 /* Not sure what to do with these ones! */
1592 { 0x0f, KEY_SELECT }, /* SOURCE */
1593 { 0x0a, KEY_KPPLUS }, /* +100 */
1594 { 0x14, KEY_EQUAL }, /* SYNC */
1595 { 0x1c, KEY_MEDIA }, /* PC/TV */
1596};
1597
1598struct ir_scancode_table ir_codes_pv951_table = {
1599 .scan = ir_codes_pv951,
1600 .size = ARRAY_SIZE(ir_codes_pv951),
1601};
1602EXPORT_SYMBOL_GPL(ir_codes_pv951_table);
1603
1604/* generic RC5 keytable */
1605/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
1606/* used by old (black) Hauppauge remotes */
1607static struct ir_scancode ir_codes_rc5_tv[] = {
1608 /* Keys 0 to 9 */
1609 { 0x00, KEY_0 },
1610 { 0x01, KEY_1 },
1611 { 0x02, KEY_2 },
1612 { 0x03, KEY_3 },
1613 { 0x04, KEY_4 },
1614 { 0x05, KEY_5 },
1615 { 0x06, KEY_6 },
1616 { 0x07, KEY_7 },
1617 { 0x08, KEY_8 },
1618 { 0x09, KEY_9 },
1619
1620 { 0x0b, KEY_CHANNEL }, /* channel / program (japan: 11) */
1621 { 0x0c, KEY_POWER }, /* standby */
1622 { 0x0d, KEY_MUTE }, /* mute / demute */
1623 { 0x0f, KEY_TV }, /* display */
1624 { 0x10, KEY_VOLUMEUP },
1625 { 0x11, KEY_VOLUMEDOWN },
1626 { 0x12, KEY_BRIGHTNESSUP },
1627 { 0x13, KEY_BRIGHTNESSDOWN },
1628 { 0x1e, KEY_SEARCH }, /* search + */
1629 { 0x20, KEY_CHANNELUP }, /* channel / program + */
1630 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
1631 { 0x22, KEY_CHANNEL }, /* alt / channel */
1632 { 0x23, KEY_LANGUAGE }, /* 1st / 2nd language */
1633 { 0x26, KEY_SLEEP }, /* sleeptimer */
1634 { 0x2e, KEY_MENU }, /* 2nd controls (USA: menu) */
1635 { 0x30, KEY_PAUSE },
1636 { 0x32, KEY_REWIND },
1637 { 0x33, KEY_GOTO },
1638 { 0x35, KEY_PLAY },
1639 { 0x36, KEY_STOP },
1640 { 0x37, KEY_RECORD }, /* recording */
1641 { 0x3c, KEY_TEXT }, /* teletext submode (Japan: 12) */
1642 { 0x3d, KEY_SUSPEND }, /* system standby */
1643
1644};
1645
1646struct ir_scancode_table ir_codes_rc5_tv_table = {
1647 .scan = ir_codes_rc5_tv,
1648 .size = ARRAY_SIZE(ir_codes_rc5_tv),
1649};
1650EXPORT_SYMBOL_GPL(ir_codes_rc5_tv_table);
1651
1652/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
1653static struct ir_scancode ir_codes_winfast[] = {
1654 /* Keys 0 to 9 */
1655 { 0x12, KEY_0 },
1656 { 0x05, KEY_1 },
1657 { 0x06, KEY_2 },
1658 { 0x07, KEY_3 },
1659 { 0x09, KEY_4 },
1660 { 0x0a, KEY_5 },
1661 { 0x0b, KEY_6 },
1662 { 0x0d, KEY_7 },
1663 { 0x0e, KEY_8 },
1664 { 0x0f, KEY_9 },
1665
1666 { 0x00, KEY_POWER },
1667 { 0x1b, KEY_AUDIO }, /* Audio Source */
1668 { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */
1669 { 0x1e, KEY_VIDEO }, /* Video Source */
1670 { 0x16, KEY_INFO }, /* Display information */
1671 { 0x04, KEY_VOLUMEUP },
1672 { 0x08, KEY_VOLUMEDOWN },
1673 { 0x0c, KEY_CHANNELUP },
1674 { 0x10, KEY_CHANNELDOWN },
1675 { 0x03, KEY_ZOOM }, /* fullscreen */
1676 { 0x1f, KEY_TEXT }, /* closed caption/teletext */
1677 { 0x20, KEY_SLEEP },
1678 { 0x29, KEY_CLEAR }, /* boss key */
1679 { 0x14, KEY_MUTE },
1680 { 0x2b, KEY_RED },
1681 { 0x2c, KEY_GREEN },
1682 { 0x2d, KEY_YELLOW },
1683 { 0x2e, KEY_BLUE },
1684 { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */
1685 { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */
1686 { 0x2a, KEY_MEDIA }, /* PIP (Picture in picture */
1687 { 0x21, KEY_DOT },
1688 { 0x13, KEY_ENTER },
1689 { 0x11, KEY_LAST }, /* Recall (last channel */
1690 { 0x22, KEY_PREVIOUS },
1691 { 0x23, KEY_PLAYPAUSE },
1692 { 0x24, KEY_NEXT },
1693 { 0x25, KEY_TIME }, /* Time Shifting */
1694 { 0x26, KEY_STOP },
1695 { 0x27, KEY_RECORD },
1696 { 0x28, KEY_SAVE }, /* Screenshot */
1697 { 0x2f, KEY_MENU },
1698 { 0x30, KEY_CANCEL },
1699 { 0x31, KEY_CHANNEL }, /* Channel Surf */
1700 { 0x32, KEY_SUBTITLE },
1701 { 0x33, KEY_LANGUAGE },
1702 { 0x34, KEY_REWIND },
1703 { 0x35, KEY_FASTFORWARD },
1704 { 0x36, KEY_TV },
1705 { 0x37, KEY_RADIO }, /* FM */
1706 { 0x38, KEY_DVD },
1707
1708 { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */
1709 { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */
1710 { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */
1711 { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */
1712 { 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */
1713};
1714
1715struct ir_scancode_table ir_codes_winfast_table = {
1716 .scan = ir_codes_winfast,
1717 .size = ARRAY_SIZE(ir_codes_winfast),
1718};
1719EXPORT_SYMBOL_GPL(ir_codes_winfast_table);
1720
1721static struct ir_scancode ir_codes_pinnacle_color[] = {
1722 { 0x59, KEY_MUTE },
1723 { 0x4a, KEY_POWER },
1724
1725 { 0x18, KEY_TEXT },
1726 { 0x26, KEY_TV },
1727 { 0x3d, KEY_PRINT },
1728
1729 { 0x48, KEY_RED },
1730 { 0x04, KEY_GREEN },
1731 { 0x11, KEY_YELLOW },
1732 { 0x00, KEY_BLUE },
1733
1734 { 0x2d, KEY_VOLUMEUP },
1735 { 0x1e, KEY_VOLUMEDOWN },
1736
1737 { 0x49, KEY_MENU },
1738
1739 { 0x16, KEY_CHANNELUP },
1740 { 0x17, KEY_CHANNELDOWN },
1741
1742 { 0x20, KEY_UP },
1743 { 0x21, KEY_DOWN },
1744 { 0x22, KEY_LEFT },
1745 { 0x23, KEY_RIGHT },
1746 { 0x0d, KEY_SELECT },
1747
1748 { 0x08, KEY_BACK },
1749 { 0x07, KEY_REFRESH },
1750
1751 { 0x2f, KEY_ZOOM },
1752 { 0x29, KEY_RECORD },
1753
1754 { 0x4b, KEY_PAUSE },
1755 { 0x4d, KEY_REWIND },
1756 { 0x2e, KEY_PLAY },
1757 { 0x4e, KEY_FORWARD },
1758 { 0x53, KEY_PREVIOUS },
1759 { 0x4c, KEY_STOP },
1760 { 0x54, KEY_NEXT },
1761
1762 { 0x69, KEY_0 },
1763 { 0x6a, KEY_1 },
1764 { 0x6b, KEY_2 },
1765 { 0x6c, KEY_3 },
1766 { 0x6d, KEY_4 },
1767 { 0x6e, KEY_5 },
1768 { 0x6f, KEY_6 },
1769 { 0x70, KEY_7 },
1770 { 0x71, KEY_8 },
1771 { 0x72, KEY_9 },
1772
1773 { 0x74, KEY_CHANNEL },
1774 { 0x0a, KEY_BACKSPACE },
1775};
1776
1777struct ir_scancode_table ir_codes_pinnacle_color_table = {
1778 .scan = ir_codes_pinnacle_color,
1779 .size = ARRAY_SIZE(ir_codes_pinnacle_color),
1780};
1781EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color_table);
1782
1783/* Hauppauge: the newer, gray remotes (seems there are multiple
1784 * slightly different versions), shipped with cx88+ivtv cards.
1785 * almost rc5 coding, but some non-standard keys */
1786static struct ir_scancode ir_codes_hauppauge_new[] = {
1787 /* Keys 0 to 9 */
1788 { 0x00, KEY_0 },
1789 { 0x01, KEY_1 },
1790 { 0x02, KEY_2 },
1791 { 0x03, KEY_3 },
1792 { 0x04, KEY_4 },
1793 { 0x05, KEY_5 },
1794 { 0x06, KEY_6 },
1795 { 0x07, KEY_7 },
1796 { 0x08, KEY_8 },
1797 { 0x09, KEY_9 },
1798
1799 { 0x0a, KEY_TEXT }, /* keypad asterisk as well */
1800 { 0x0b, KEY_RED }, /* red button */
1801 { 0x0c, KEY_RADIO },
1802 { 0x0d, KEY_MENU },
1803 { 0x0e, KEY_SUBTITLE }, /* also the # key */
1804 { 0x0f, KEY_MUTE },
1805 { 0x10, KEY_VOLUMEUP },
1806 { 0x11, KEY_VOLUMEDOWN },
1807 { 0x12, KEY_PREVIOUS }, /* previous channel */
1808 { 0x14, KEY_UP },
1809 { 0x15, KEY_DOWN },
1810 { 0x16, KEY_LEFT },
1811 { 0x17, KEY_RIGHT },
1812 { 0x18, KEY_VIDEO }, /* Videos */
1813 { 0x19, KEY_AUDIO }, /* Music */
1814 /* 0x1a: Pictures - presume this means
1815 "Multimedia Home Platform" -
1816 no "PICTURES" key in input.h
1817 */
1818 { 0x1a, KEY_MHP },
1819
1820 { 0x1b, KEY_EPG }, /* Guide */
1821 { 0x1c, KEY_TV },
1822 { 0x1e, KEY_NEXTSONG }, /* skip >| */
1823 { 0x1f, KEY_EXIT }, /* back/exit */
1824 { 0x20, KEY_CHANNELUP }, /* channel / program + */
1825 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
1826 { 0x22, KEY_CHANNEL }, /* source (old black remote) */
1827 { 0x24, KEY_PREVIOUSSONG }, /* replay |< */
1828 { 0x25, KEY_ENTER }, /* OK */
1829 { 0x26, KEY_SLEEP }, /* minimize (old black remote) */
1830 { 0x29, KEY_BLUE }, /* blue key */
1831 { 0x2e, KEY_GREEN }, /* green button */
1832 { 0x30, KEY_PAUSE }, /* pause */
1833 { 0x32, KEY_REWIND }, /* backward << */
1834 { 0x34, KEY_FASTFORWARD }, /* forward >> */
1835 { 0x35, KEY_PLAY },
1836 { 0x36, KEY_STOP },
1837 { 0x37, KEY_RECORD }, /* recording */
1838 { 0x38, KEY_YELLOW }, /* yellow key */
1839 { 0x3b, KEY_SELECT }, /* top right button */
1840 { 0x3c, KEY_ZOOM }, /* full */
1841 { 0x3d, KEY_POWER }, /* system power (green button) */
1842};
1843
1844struct ir_scancode_table ir_codes_hauppauge_new_table = {
1845 .scan = ir_codes_hauppauge_new,
1846 .size = ARRAY_SIZE(ir_codes_hauppauge_new),
1847};
1848EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table);
1849
1850static struct ir_scancode ir_codes_npgtech[] = {
1851 { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */
1852 { 0x2a, KEY_FRONT },
1853
1854 { 0x3e, KEY_1 },
1855 { 0x02, KEY_2 },
1856 { 0x06, KEY_3 },
1857 { 0x0a, KEY_4 },
1858 { 0x0e, KEY_5 },
1859 { 0x12, KEY_6 },
1860 { 0x16, KEY_7 },
1861 { 0x1a, KEY_8 },
1862 { 0x1e, KEY_9 },
1863 { 0x3a, KEY_0 },
1864 { 0x22, KEY_NUMLOCK }, /* -/-- */
1865 { 0x20, KEY_REFRESH },
1866
1867 { 0x03, KEY_BRIGHTNESSDOWN },
1868 { 0x28, KEY_AUDIO },
1869 { 0x3c, KEY_CHANNELUP },
1870 { 0x3f, KEY_VOLUMEDOWN },
1871 { 0x2e, KEY_MUTE },
1872 { 0x3b, KEY_VOLUMEUP },
1873 { 0x00, KEY_CHANNELDOWN },
1874 { 0x07, KEY_BRIGHTNESSUP },
1875 { 0x2c, KEY_TEXT },
1876
1877 { 0x37, KEY_RECORD },
1878 { 0x17, KEY_PLAY },
1879 { 0x13, KEY_PAUSE },
1880 { 0x26, KEY_STOP },
1881 { 0x18, KEY_FASTFORWARD },
1882 { 0x14, KEY_REWIND },
1883 { 0x33, KEY_ZOOM },
1884 { 0x32, KEY_KEYBOARD },
1885 { 0x30, KEY_GOTO }, /* Pointing arrow */
1886 { 0x36, KEY_MACRO }, /* Maximize/Minimize (yellow) */
1887 { 0x0b, KEY_RADIO },
1888 { 0x10, KEY_POWER },
1889
1890};
1891
1892struct ir_scancode_table ir_codes_npgtech_table = {
1893 .scan = ir_codes_npgtech,
1894 .size = ARRAY_SIZE(ir_codes_npgtech),
1895};
1896EXPORT_SYMBOL_GPL(ir_codes_npgtech_table);
1897
1898/* Norwood Micro (non-Pro) TV Tuner
1899 By Peter Naulls <peter@chocky.org>
1900 Key comments are the functions given in the manual */
1901static struct ir_scancode ir_codes_norwood[] = {
1902 /* Keys 0 to 9 */
1903 { 0x20, KEY_0 },
1904 { 0x21, KEY_1 },
1905 { 0x22, KEY_2 },
1906 { 0x23, KEY_3 },
1907 { 0x24, KEY_4 },
1908 { 0x25, KEY_5 },
1909 { 0x26, KEY_6 },
1910 { 0x27, KEY_7 },
1911 { 0x28, KEY_8 },
1912 { 0x29, KEY_9 },
1913
1914 { 0x78, KEY_TUNER }, /* Video Source */
1915 { 0x2c, KEY_EXIT }, /* Open/Close software */
1916 { 0x2a, KEY_SELECT }, /* 2 Digit Select */
1917 { 0x69, KEY_AGAIN }, /* Recall */
1918
1919 { 0x32, KEY_BRIGHTNESSUP }, /* Brightness increase */
1920 { 0x33, KEY_BRIGHTNESSDOWN }, /* Brightness decrease */
1921 { 0x6b, KEY_KPPLUS }, /* (not named >>>>>) */
1922 { 0x6c, KEY_KPMINUS }, /* (not named <<<<<) */
1923
1924 { 0x2d, KEY_MUTE }, /* Mute */
1925 { 0x30, KEY_VOLUMEUP }, /* Volume up */
1926 { 0x31, KEY_VOLUMEDOWN }, /* Volume down */
1927 { 0x60, KEY_CHANNELUP }, /* Channel up */
1928 { 0x61, KEY_CHANNELDOWN }, /* Channel down */
1929
1930 { 0x3f, KEY_RECORD }, /* Record */
1931 { 0x37, KEY_PLAY }, /* Play */
1932 { 0x36, KEY_PAUSE }, /* Pause */
1933 { 0x2b, KEY_STOP }, /* Stop */
1934 { 0x67, KEY_FASTFORWARD }, /* Foward */
1935 { 0x66, KEY_REWIND }, /* Rewind */
1936 { 0x3e, KEY_SEARCH }, /* Auto Scan */
1937 { 0x2e, KEY_CAMERA }, /* Capture Video */
1938 { 0x6d, KEY_MENU }, /* Show/Hide Control */
1939 { 0x2f, KEY_ZOOM }, /* Full Screen */
1940 { 0x34, KEY_RADIO }, /* FM */
1941 { 0x65, KEY_POWER }, /* Computer power */
1942};
1943
1944struct ir_scancode_table ir_codes_norwood_table = {
1945 .scan = ir_codes_norwood,
1946 .size = ARRAY_SIZE(ir_codes_norwood),
1947};
1948EXPORT_SYMBOL_GPL(ir_codes_norwood_table);
1949
1950/* From reading the following remotes:
1951 * Zenith Universal 7 / TV Mode 807 / VCR Mode 837
1952 * Hauppauge (from NOVA-CI-s box product)
1953 * This is a "middle of the road" approach, differences are noted
1954 */
1955static struct ir_scancode ir_codes_budget_ci_old[] = {
1956 { 0x00, KEY_0 },
1957 { 0x01, KEY_1 },
1958 { 0x02, KEY_2 },
1959 { 0x03, KEY_3 },
1960 { 0x04, KEY_4 },
1961 { 0x05, KEY_5 },
1962 { 0x06, KEY_6 },
1963 { 0x07, KEY_7 },
1964 { 0x08, KEY_8 },
1965 { 0x09, KEY_9 },
1966 { 0x0a, KEY_ENTER },
1967 { 0x0b, KEY_RED },
1968 { 0x0c, KEY_POWER }, /* RADIO on Hauppauge */
1969 { 0x0d, KEY_MUTE },
1970 { 0x0f, KEY_A }, /* TV on Hauppauge */
1971 { 0x10, KEY_VOLUMEUP },
1972 { 0x11, KEY_VOLUMEDOWN },
1973 { 0x14, KEY_B },
1974 { 0x1c, KEY_UP },
1975 { 0x1d, KEY_DOWN },
1976 { 0x1e, KEY_OPTION }, /* RESERVED on Hauppauge */
1977 { 0x1f, KEY_BREAK },
1978 { 0x20, KEY_CHANNELUP },
1979 { 0x21, KEY_CHANNELDOWN },
1980 { 0x22, KEY_PREVIOUS }, /* Prev Ch on Zenith, SOURCE on Hauppauge */
1981 { 0x24, KEY_RESTART },
1982 { 0x25, KEY_OK },
1983 { 0x26, KEY_CYCLEWINDOWS }, /* MINIMIZE on Hauppauge */
1984 { 0x28, KEY_ENTER }, /* VCR mode on Zenith */
1985 { 0x29, KEY_PAUSE },
1986 { 0x2b, KEY_RIGHT },
1987 { 0x2c, KEY_LEFT },
1988 { 0x2e, KEY_MENU }, /* FULL SCREEN on Hauppauge */
1989 { 0x30, KEY_SLOW },
1990 { 0x31, KEY_PREVIOUS }, /* VCR mode on Zenith */
1991 { 0x32, KEY_REWIND },
1992 { 0x34, KEY_FASTFORWARD },
1993 { 0x35, KEY_PLAY },
1994 { 0x36, KEY_STOP },
1995 { 0x37, KEY_RECORD },
1996 { 0x38, KEY_TUNER }, /* TV/VCR on Zenith */
1997 { 0x3a, KEY_C },
1998 { 0x3c, KEY_EXIT },
1999 { 0x3d, KEY_POWER2 },
2000 { 0x3e, KEY_TUNER },
2001};
2002
2003struct ir_scancode_table ir_codes_budget_ci_old_table = {
2004 .scan = ir_codes_budget_ci_old,
2005 .size = ARRAY_SIZE(ir_codes_budget_ci_old),
2006};
2007EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old_table);
2008
2009/*
2010 * Marc Fargas <telenieko@telenieko.com>
2011 * this is the remote control that comes with the asus p7131
2012 * which has a label saying is "Model PC-39"
2013 */
2014static struct ir_scancode ir_codes_asus_pc39[] = {
2015 /* Keys 0 to 9 */
2016 { 0x15, KEY_0 },
2017 { 0x29, KEY_1 },
2018 { 0x2d, KEY_2 },
2019 { 0x2b, KEY_3 },
2020 { 0x09, KEY_4 },
2021 { 0x0d, KEY_5 },
2022 { 0x0b, KEY_6 },
2023 { 0x31, KEY_7 },
2024 { 0x35, KEY_8 },
2025 { 0x33, KEY_9 },
2026
2027 { 0x3e, KEY_RADIO }, /* radio */
2028 { 0x03, KEY_MENU }, /* dvd/menu */
2029 { 0x2a, KEY_VOLUMEUP },
2030 { 0x19, KEY_VOLUMEDOWN },
2031 { 0x37, KEY_UP },
2032 { 0x3b, KEY_DOWN },
2033 { 0x27, KEY_LEFT },
2034 { 0x2f, KEY_RIGHT },
2035 { 0x25, KEY_VIDEO }, /* video */
2036 { 0x39, KEY_AUDIO }, /* music */
2037
2038 { 0x21, KEY_TV }, /* tv */
2039 { 0x1d, KEY_EXIT }, /* back */
2040 { 0x0a, KEY_CHANNELUP }, /* channel / program + */
2041 { 0x1b, KEY_CHANNELDOWN }, /* channel / program - */
2042 { 0x1a, KEY_ENTER }, /* enter */
2043
2044 { 0x06, KEY_PAUSE }, /* play/pause */
2045 { 0x1e, KEY_PREVIOUS }, /* rew */
2046 { 0x26, KEY_NEXT }, /* forward */
2047 { 0x0e, KEY_REWIND }, /* backward << */
2048 { 0x3a, KEY_FASTFORWARD }, /* forward >> */
2049 { 0x36, KEY_STOP },
2050 { 0x2e, KEY_RECORD }, /* recording */
2051 { 0x16, KEY_POWER }, /* the button that reads "close" */
2052
2053 { 0x11, KEY_ZOOM }, /* full screen */
2054 { 0x13, KEY_MACRO }, /* recall */
2055 { 0x23, KEY_HOME }, /* home */
2056 { 0x05, KEY_PVR }, /* picture */
2057 { 0x3d, KEY_MUTE }, /* mute */
2058 { 0x01, KEY_DVD }, /* dvd */
2059};
2060
2061struct ir_scancode_table ir_codes_asus_pc39_table = {
2062 .scan = ir_codes_asus_pc39,
2063 .size = ARRAY_SIZE(ir_codes_asus_pc39),
2064};
2065EXPORT_SYMBOL_GPL(ir_codes_asus_pc39_table);
2066
2067
2068/* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons
2069 Juan Pablo Sormani <sorman@gmail.com> */
2070static struct ir_scancode ir_codes_encore_enltv[] = {
2071
2072 /* Power button does nothing, neither in Windows app,
2073 although it sends data (used for BIOS wakeup?) */
2074 { 0x0d, KEY_MUTE },
2075
2076 { 0x1e, KEY_TV },
2077 { 0x00, KEY_VIDEO },
2078 { 0x01, KEY_AUDIO }, /* music */
2079 { 0x02, KEY_MHP }, /* picture */
2080
2081 { 0x1f, KEY_1 },
2082 { 0x03, KEY_2 },
2083 { 0x04, KEY_3 },
2084 { 0x05, KEY_4 },
2085 { 0x1c, KEY_5 },
2086 { 0x06, KEY_6 },
2087 { 0x07, KEY_7 },
2088 { 0x08, KEY_8 },
2089 { 0x1d, KEY_9 },
2090 { 0x0a, KEY_0 },
2091
2092 { 0x09, KEY_LIST }, /* -/-- */
2093 { 0x0b, KEY_LAST }, /* recall */
2094
2095 { 0x14, KEY_HOME }, /* win start menu */
2096 { 0x15, KEY_EXIT }, /* exit */
2097 { 0x16, KEY_CHANNELUP }, /* UP */
2098 { 0x12, KEY_CHANNELDOWN }, /* DOWN */
2099 { 0x0c, KEY_VOLUMEUP }, /* RIGHT */
2100 { 0x17, KEY_VOLUMEDOWN }, /* LEFT */
2101
2102 { 0x18, KEY_ENTER }, /* OK */
2103
2104 { 0x0e, KEY_ESC },
2105 { 0x13, KEY_CYCLEWINDOWS }, /* desktop */
2106 { 0x11, KEY_TAB },
2107 { 0x19, KEY_SWITCHVIDEOMODE }, /* switch */
2108
2109 { 0x1a, KEY_MENU },
2110 { 0x1b, KEY_ZOOM }, /* fullscreen */
2111 { 0x44, KEY_TIME }, /* time shift */
2112 { 0x40, KEY_MODE }, /* source */
2113
2114 { 0x5a, KEY_RECORD },
2115 { 0x42, KEY_PLAY }, /* play/pause */
2116 { 0x45, KEY_STOP },
2117 { 0x43, KEY_CAMERA }, /* camera icon */
2118
2119 { 0x48, KEY_REWIND },
2120 { 0x4a, KEY_FASTFORWARD },
2121 { 0x49, KEY_PREVIOUS },
2122 { 0x4b, KEY_NEXT },
2123
2124 { 0x4c, KEY_FAVORITES }, /* tv wall */
2125 { 0x4d, KEY_SOUND }, /* DVD sound */
2126 { 0x4e, KEY_LANGUAGE }, /* DVD lang */
2127 { 0x4f, KEY_TEXT }, /* DVD text */
2128
2129 { 0x50, KEY_SLEEP }, /* shutdown */
2130 { 0x51, KEY_MODE }, /* stereo > main */
2131 { 0x52, KEY_SELECT }, /* stereo > sap */
2132 { 0x53, KEY_PROG1 }, /* teletext */
2133
2134
2135 { 0x59, KEY_RED }, /* AP1 */
2136 { 0x41, KEY_GREEN }, /* AP2 */
2137 { 0x47, KEY_YELLOW }, /* AP3 */
2138 { 0x57, KEY_BLUE }, /* AP4 */
2139};
2140
2141struct ir_scancode_table ir_codes_encore_enltv_table = {
2142 .scan = ir_codes_encore_enltv,
2143 .size = ARRAY_SIZE(ir_codes_encore_enltv),
2144};
2145EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_table);
2146
2147/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton
2148 Mauro Carvalho Chehab <mchehab@infradead.org> */
2149static struct ir_scancode ir_codes_encore_enltv2[] = {
2150 { 0x4c, KEY_POWER2 },
2151 { 0x4a, KEY_TUNER },
2152 { 0x40, KEY_1 },
2153 { 0x60, KEY_2 },
2154 { 0x50, KEY_3 },
2155 { 0x70, KEY_4 },
2156 { 0x48, KEY_5 },
2157 { 0x68, KEY_6 },
2158 { 0x58, KEY_7 },
2159 { 0x78, KEY_8 },
2160 { 0x44, KEY_9 },
2161 { 0x54, KEY_0 },
2162
2163 { 0x64, KEY_LAST }, /* +100 */
2164 { 0x4e, KEY_AGAIN }, /* Recall */
2165
2166 { 0x6c, KEY_SWITCHVIDEOMODE }, /* Video Source */
2167 { 0x5e, KEY_MENU },
2168 { 0x56, KEY_SCREEN },
2169 { 0x7a, KEY_SETUP },
2170
2171 { 0x46, KEY_MUTE },
2172 { 0x5c, KEY_MODE }, /* Stereo */
2173 { 0x74, KEY_INFO },
2174 { 0x7c, KEY_CLEAR },
2175
2176 { 0x55, KEY_UP },
2177 { 0x49, KEY_DOWN },
2178 { 0x7e, KEY_LEFT },
2179 { 0x59, KEY_RIGHT },
2180 { 0x6a, KEY_ENTER },
2181
2182 { 0x42, KEY_VOLUMEUP },
2183 { 0x62, KEY_VOLUMEDOWN },
2184 { 0x52, KEY_CHANNELUP },
2185 { 0x72, KEY_CHANNELDOWN },
2186
2187 { 0x41, KEY_RECORD },
2188 { 0x51, KEY_CAMERA }, /* Snapshot */
2189 { 0x75, KEY_TIME }, /* Timeshift */
2190 { 0x71, KEY_TV2 }, /* PIP */
2191
2192 { 0x45, KEY_REWIND },
2193 { 0x6f, KEY_PAUSE },
2194 { 0x7d, KEY_FORWARD },
2195 { 0x79, KEY_STOP },
2196};
2197
2198struct ir_scancode_table ir_codes_encore_enltv2_table = {
2199 .scan = ir_codes_encore_enltv2,
2200 .size = ARRAY_SIZE(ir_codes_encore_enltv2),
2201};
2202EXPORT_SYMBOL_GPL(ir_codes_encore_enltv2_table);
2203
2204/* for the Technotrend 1500 bundled remotes (grey and black): */
2205static struct ir_scancode ir_codes_tt_1500[] = {
2206 { 0x01, KEY_POWER },
2207 { 0x02, KEY_SHUFFLE }, /* ? double-arrow key */
2208 { 0x03, KEY_1 },
2209 { 0x04, KEY_2 },
2210 { 0x05, KEY_3 },
2211 { 0x06, KEY_4 },
2212 { 0x07, KEY_5 },
2213 { 0x08, KEY_6 },
2214 { 0x09, KEY_7 },
2215 { 0x0a, KEY_8 },
2216 { 0x0b, KEY_9 },
2217 { 0x0c, KEY_0 },
2218 { 0x0d, KEY_UP },
2219 { 0x0e, KEY_LEFT },
2220 { 0x0f, KEY_OK },
2221 { 0x10, KEY_RIGHT },
2222 { 0x11, KEY_DOWN },
2223 { 0x12, KEY_INFO },
2224 { 0x13, KEY_EXIT },
2225 { 0x14, KEY_RED },
2226 { 0x15, KEY_GREEN },
2227 { 0x16, KEY_YELLOW },
2228 { 0x17, KEY_BLUE },
2229 { 0x18, KEY_MUTE },
2230 { 0x19, KEY_TEXT },
2231 { 0x1a, KEY_MODE }, /* ? TV/Radio */
2232 { 0x21, KEY_OPTION },
2233 { 0x22, KEY_EPG },
2234 { 0x23, KEY_CHANNELUP },
2235 { 0x24, KEY_CHANNELDOWN },
2236 { 0x25, KEY_VOLUMEUP },
2237 { 0x26, KEY_VOLUMEDOWN },
2238 { 0x27, KEY_SETUP },
2239 { 0x3a, KEY_RECORD }, /* these keys are only in the black remote */
2240 { 0x3b, KEY_PLAY },
2241 { 0x3c, KEY_STOP },
2242 { 0x3d, KEY_REWIND },
2243 { 0x3e, KEY_PAUSE },
2244 { 0x3f, KEY_FORWARD },
2245};
2246
2247struct ir_scancode_table ir_codes_tt_1500_table = {
2248 .scan = ir_codes_tt_1500,
2249 .size = ARRAY_SIZE(ir_codes_tt_1500),
2250};
2251EXPORT_SYMBOL_GPL(ir_codes_tt_1500_table);
2252
2253/* DViCO FUSION HDTV MCE remote */
2254static struct ir_scancode ir_codes_fusionhdtv_mce[] = {
2255
2256 { 0x0b, KEY_1 },
2257 { 0x17, KEY_2 },
2258 { 0x1b, KEY_3 },
2259 { 0x07, KEY_4 },
2260 { 0x50, KEY_5 },
2261 { 0x54, KEY_6 },
2262 { 0x48, KEY_7 },
2263 { 0x4c, KEY_8 },
2264 { 0x58, KEY_9 },
2265 { 0x03, KEY_0 },
2266
2267 { 0x5e, KEY_OK },
2268 { 0x51, KEY_UP },
2269 { 0x53, KEY_DOWN },
2270 { 0x5b, KEY_LEFT },
2271 { 0x5f, KEY_RIGHT },
2272
2273 { 0x02, KEY_TV }, /* Labeled DTV on remote */
2274 { 0x0e, KEY_MP3 },
2275 { 0x1a, KEY_DVD },
2276 { 0x1e, KEY_FAVORITES }, /* Labeled CPF on remote */
2277 { 0x16, KEY_SETUP },
2278 { 0x46, KEY_POWER2 }, /* TV On/Off button on remote */
2279 { 0x0a, KEY_EPG }, /* Labeled Guide on remote */
2280
2281 { 0x49, KEY_BACK },
2282 { 0x59, KEY_INFO }, /* Labeled MORE on remote */
2283 { 0x4d, KEY_MENU }, /* Labeled DVDMENU on remote */
2284 { 0x55, KEY_CYCLEWINDOWS }, /* Labeled ALT-TAB on remote */
2285
2286 { 0x0f, KEY_PREVIOUSSONG }, /* Labeled |<< REPLAY on remote */
2287 { 0x12, KEY_NEXTSONG }, /* Labeled >>| SKIP on remote */
2288 { 0x42, KEY_ENTER }, /* Labeled START with a green
2289 MS windows logo on remote */
2290
2291 { 0x15, KEY_VOLUMEUP },
2292 { 0x05, KEY_VOLUMEDOWN },
2293 { 0x11, KEY_CHANNELUP },
2294 { 0x09, KEY_CHANNELDOWN },
2295
2296 { 0x52, KEY_CAMERA },
2297 { 0x5a, KEY_TUNER },
2298 { 0x19, KEY_OPEN },
2299
2300 { 0x13, KEY_MODE }, /* 4:3 16:9 select */
2301 { 0x1f, KEY_ZOOM },
2302
2303 { 0x43, KEY_REWIND },
2304 { 0x47, KEY_PLAYPAUSE },
2305 { 0x4f, KEY_FASTFORWARD },
2306 { 0x57, KEY_MUTE },
2307 { 0x0d, KEY_STOP },
2308 { 0x01, KEY_RECORD },
2309 { 0x4e, KEY_POWER },
2310};
2311
2312struct ir_scancode_table ir_codes_fusionhdtv_mce_table = {
2313 .scan = ir_codes_fusionhdtv_mce,
2314 .size = ARRAY_SIZE(ir_codes_fusionhdtv_mce),
2315};
2316EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce_table);
2317
2318/* Pinnacle PCTV HD 800i mini remote */
2319static struct ir_scancode ir_codes_pinnacle_pctv_hd[] = {
2320
2321 { 0x0f, KEY_1 },
2322 { 0x15, KEY_2 },
2323 { 0x10, KEY_3 },
2324 { 0x18, KEY_4 },
2325 { 0x1b, KEY_5 },
2326 { 0x1e, KEY_6 },
2327 { 0x11, KEY_7 },
2328 { 0x21, KEY_8 },
2329 { 0x12, KEY_9 },
2330 { 0x27, KEY_0 },
2331
2332 { 0x24, KEY_ZOOM },
2333 { 0x2a, KEY_SUBTITLE },
2334
2335 { 0x00, KEY_MUTE },
2336 { 0x01, KEY_ENTER }, /* Pinnacle Logo */
2337 { 0x39, KEY_POWER },
2338
2339 { 0x03, KEY_VOLUMEUP },
2340 { 0x09, KEY_VOLUMEDOWN },
2341 { 0x06, KEY_CHANNELUP },
2342 { 0x0c, KEY_CHANNELDOWN },
2343
2344 { 0x2d, KEY_REWIND },
2345 { 0x30, KEY_PLAYPAUSE },
2346 { 0x33, KEY_FASTFORWARD },
2347 { 0x3c, KEY_STOP },
2348 { 0x36, KEY_RECORD },
2349 { 0x3f, KEY_EPG }, /* Labeled "?" */
2350};
2351
2352struct ir_scancode_table ir_codes_pinnacle_pctv_hd_table = {
2353 .scan = ir_codes_pinnacle_pctv_hd,
2354 .size = ARRAY_SIZE(ir_codes_pinnacle_pctv_hd),
2355};
2356EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd_table);
2357
2358/*
2359 * Igor Kuznetsov <igk72@ya.ru>
2360 * Andrey J. Melnikov <temnota@kmv.ru>
2361 *
2362 * Keytable is used by BeholdTV 60x series, M6 series at
2363 * least, and probably other cards too.
2364 * The "ascii-art picture" below (in comments, first row
2365 * is the keycode in hex, and subsequent row(s) shows
2366 * the button labels (several variants when appropriate)
2367 * helps to descide which keycodes to assign to the buttons.
2368 */
2369static struct ir_scancode ir_codes_behold[] = {
2370
2371 /* 0x1c 0x12 *
2372 * TV/FM POWER *
2373 * */
2374 { 0x1c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */
2375 { 0x12, KEY_POWER },
2376
2377 /* 0x01 0x02 0x03 *
2378 * 1 2 3 *
2379 * *
2380 * 0x04 0x05 0x06 *
2381 * 4 5 6 *
2382 * *
2383 * 0x07 0x08 0x09 *
2384 * 7 8 9 *
2385 * */
2386 { 0x01, KEY_1 },
2387 { 0x02, KEY_2 },
2388 { 0x03, KEY_3 },
2389 { 0x04, KEY_4 },
2390 { 0x05, KEY_5 },
2391 { 0x06, KEY_6 },
2392 { 0x07, KEY_7 },
2393 { 0x08, KEY_8 },
2394 { 0x09, KEY_9 },
2395
2396 /* 0x0a 0x00 0x17 *
2397 * RECALL 0 MODE *
2398 * */
2399 { 0x0a, KEY_AGAIN },
2400 { 0x00, KEY_0 },
2401 { 0x17, KEY_MODE },
2402
2403 /* 0x14 0x10 *
2404 * ASPECT FULLSCREEN *
2405 * */
2406 { 0x14, KEY_SCREEN },
2407 { 0x10, KEY_ZOOM },
2408
2409 /* 0x0b *
2410 * Up *
2411 * *
2412 * 0x18 0x16 0x0c *
2413 * Left Ok Right *
2414 * *
2415 * 0x015 *
2416 * Down *
2417 * */
2418 { 0x0b, KEY_CHANNELUP },
2419 { 0x18, KEY_VOLUMEDOWN },
2420 { 0x16, KEY_OK }, /* XXX KEY_ENTER */
2421 { 0x0c, KEY_VOLUMEUP },
2422 { 0x15, KEY_CHANNELDOWN },
2423
2424 /* 0x11 0x0d *
2425 * MUTE INFO *
2426 * */
2427 { 0x11, KEY_MUTE },
2428 { 0x0d, KEY_INFO },
2429
2430 /* 0x0f 0x1b 0x1a *
2431 * RECORD PLAY/PAUSE STOP *
2432 * *
2433 * 0x0e 0x1f 0x1e *
2434 *TELETEXT AUDIO SOURCE *
2435 * RED YELLOW *
2436 * */
2437 { 0x0f, KEY_RECORD },
2438 { 0x1b, KEY_PLAYPAUSE },
2439 { 0x1a, KEY_STOP },
2440 { 0x0e, KEY_TEXT },
2441 { 0x1f, KEY_RED }, /*XXX KEY_AUDIO */
2442 { 0x1e, KEY_YELLOW }, /*XXX KEY_SOURCE */
2443
2444 /* 0x1d 0x13 0x19 *
2445 * SLEEP PREVIEW DVB *
2446 * GREEN BLUE *
2447 * */
2448 { 0x1d, KEY_SLEEP },
2449 { 0x13, KEY_GREEN },
2450 { 0x19, KEY_BLUE }, /* XXX KEY_SAT */
2451
2452 /* 0x58 0x5c *
2453 * FREEZE SNAPSHOT *
2454 * */
2455 { 0x58, KEY_SLOW },
2456 { 0x5c, KEY_CAMERA },
2457
2458};
2459
2460struct ir_scancode_table ir_codes_behold_table = {
2461 .scan = ir_codes_behold,
2462 .size = ARRAY_SIZE(ir_codes_behold),
2463};
2464EXPORT_SYMBOL_GPL(ir_codes_behold_table);
2465
2466/* Beholder Intl. Ltd. 2008
2467 * Dmitry Belimov d.belimov@google.com
2468 * Keytable is used by BeholdTV Columbus
2469 * The "ascii-art picture" below (in comments, first row
2470 * is the keycode in hex, and subsequent row(s) shows
2471 * the button labels (several variants when appropriate)
2472 * helps to descide which keycodes to assign to the buttons.
2473 */
2474static struct ir_scancode ir_codes_behold_columbus[] = {
2475
2476 /* 0x13 0x11 0x1C 0x12 *
2477 * Mute Source TV/FM Power *
2478 * */
2479
2480 { 0x13, KEY_MUTE },
2481 { 0x11, KEY_PROPS },
2482 { 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */
2483 { 0x12, KEY_POWER },
2484
2485 /* 0x01 0x02 0x03 0x0D *
2486 * 1 2 3 Stereo *
2487 * *
2488 * 0x04 0x05 0x06 0x19 *
2489 * 4 5 6 Snapshot *
2490 * *
2491 * 0x07 0x08 0x09 0x10 *
2492 * 7 8 9 Zoom *
2493 * */
2494 { 0x01, KEY_1 },
2495 { 0x02, KEY_2 },
2496 { 0x03, KEY_3 },
2497 { 0x0D, KEY_SETUP }, /* Setup key */
2498 { 0x04, KEY_4 },
2499 { 0x05, KEY_5 },
2500 { 0x06, KEY_6 },
2501 { 0x19, KEY_CAMERA }, /* Snapshot key */
2502 { 0x07, KEY_7 },
2503 { 0x08, KEY_8 },
2504 { 0x09, KEY_9 },
2505 { 0x10, KEY_ZOOM },
2506
2507 /* 0x0A 0x00 0x0B 0x0C *
2508 * RECALL 0 ChannelUp VolumeUp *
2509 * */
2510 { 0x0A, KEY_AGAIN },
2511 { 0x00, KEY_0 },
2512 { 0x0B, KEY_CHANNELUP },
2513 { 0x0C, KEY_VOLUMEUP },
2514
2515 /* 0x1B 0x1D 0x15 0x18 *
2516 * Timeshift Record ChannelDown VolumeDown *
2517 * */
2518
2519 { 0x1B, KEY_TIME },
2520 { 0x1D, KEY_RECORD },
2521 { 0x15, KEY_CHANNELDOWN },
2522 { 0x18, KEY_VOLUMEDOWN },
2523
2524 /* 0x0E 0x1E 0x0F 0x1A *
2525 * Stop Pause Previouse Next *
2526 * */
2527
2528 { 0x0E, KEY_STOP },
2529 { 0x1E, KEY_PAUSE },
2530 { 0x0F, KEY_PREVIOUS },
2531 { 0x1A, KEY_NEXT },
2532
2533};
2534
2535struct ir_scancode_table ir_codes_behold_columbus_table = {
2536 .scan = ir_codes_behold_columbus,
2537 .size = ARRAY_SIZE(ir_codes_behold_columbus),
2538};
2539EXPORT_SYMBOL_GPL(ir_codes_behold_columbus_table);
2540
2541/*
2542 * Remote control for the Genius TVGO A11MCE
2543 * Adrian Pardini <pardo.bsso@gmail.com>
2544 */
2545static struct ir_scancode ir_codes_genius_tvgo_a11mce[] = {
2546 /* Keys 0 to 9 */
2547 { 0x48, KEY_0 },
2548 { 0x09, KEY_1 },
2549 { 0x1d, KEY_2 },
2550 { 0x1f, KEY_3 },
2551 { 0x19, KEY_4 },
2552 { 0x1b, KEY_5 },
2553 { 0x11, KEY_6 },
2554 { 0x17, KEY_7 },
2555 { 0x12, KEY_8 },
2556 { 0x16, KEY_9 },
2557
2558 { 0x54, KEY_RECORD }, /* recording */
2559 { 0x06, KEY_MUTE }, /* mute */
2560 { 0x10, KEY_POWER },
2561 { 0x40, KEY_LAST }, /* recall */
2562 { 0x4c, KEY_CHANNELUP }, /* channel / program + */
2563 { 0x00, KEY_CHANNELDOWN }, /* channel / program - */
2564 { 0x0d, KEY_VOLUMEUP },
2565 { 0x15, KEY_VOLUMEDOWN },
2566 { 0x4d, KEY_OK }, /* also labeled as Pause */
2567 { 0x1c, KEY_ZOOM }, /* full screen and Stop*/
2568 { 0x02, KEY_MODE }, /* AV Source or Rewind*/
2569 { 0x04, KEY_LIST }, /* -/-- */
2570 /* small arrows above numbers */
2571 { 0x1a, KEY_NEXT }, /* also Fast Forward */
2572 { 0x0e, KEY_PREVIOUS }, /* also Rewind */
2573 /* these are in a rather non standard layout and have
2574 an alternate name written */
2575 { 0x1e, KEY_UP }, /* Video Setting */
2576 { 0x0a, KEY_DOWN }, /* Video Default */
2577 { 0x05, KEY_CAMERA }, /* Snapshot */
2578 { 0x0c, KEY_RIGHT }, /* Hide Panel */
2579 /* Four buttons without label */
2580 { 0x49, KEY_RED },
2581 { 0x0b, KEY_GREEN },
2582 { 0x13, KEY_YELLOW },
2583 { 0x50, KEY_BLUE },
2584};
2585
2586struct ir_scancode_table ir_codes_genius_tvgo_a11mce_table = {
2587 .scan = ir_codes_genius_tvgo_a11mce,
2588 .size = ARRAY_SIZE(ir_codes_genius_tvgo_a11mce),
2589};
2590EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce_table);
2591
2592/*
2593 * Remote control for Powercolor Real Angel 330
2594 * Daniel Fraga <fragabr@gmail.com>
2595 */
2596static struct ir_scancode ir_codes_powercolor_real_angel[] = {
2597 { 0x38, KEY_SWITCHVIDEOMODE }, /* switch inputs */
2598 { 0x0c, KEY_MEDIA }, /* Turn ON/OFF App */
2599 { 0x00, KEY_0 },
2600 { 0x01, KEY_1 },
2601 { 0x02, KEY_2 },
2602 { 0x03, KEY_3 },
2603 { 0x04, KEY_4 },
2604 { 0x05, KEY_5 },
2605 { 0x06, KEY_6 },
2606 { 0x07, KEY_7 },
2607 { 0x08, KEY_8 },
2608 { 0x09, KEY_9 },
2609 { 0x0a, KEY_DIGITS }, /* single, double, tripple digit */
2610 { 0x29, KEY_PREVIOUS }, /* previous channel */
2611 { 0x12, KEY_BRIGHTNESSUP },
2612 { 0x13, KEY_BRIGHTNESSDOWN },
2613 { 0x2b, KEY_MODE }, /* stereo/mono */
2614 { 0x2c, KEY_TEXT }, /* teletext */
2615 { 0x20, KEY_CHANNELUP }, /* channel up */
2616 { 0x21, KEY_CHANNELDOWN }, /* channel down */
2617 { 0x10, KEY_VOLUMEUP }, /* volume up */
2618 { 0x11, KEY_VOLUMEDOWN }, /* volume down */
2619 { 0x0d, KEY_MUTE },
2620 { 0x1f, KEY_RECORD },
2621 { 0x17, KEY_PLAY },
2622 { 0x16, KEY_PAUSE },
2623 { 0x0b, KEY_STOP },
2624 { 0x27, KEY_FASTFORWARD },
2625 { 0x26, KEY_REWIND },
2626 { 0x1e, KEY_SEARCH }, /* autoscan */
2627 { 0x0e, KEY_CAMERA }, /* snapshot */
2628 { 0x2d, KEY_SETUP },
2629 { 0x0f, KEY_SCREEN }, /* full screen */
2630 { 0x14, KEY_RADIO }, /* FM radio */
2631 { 0x25, KEY_POWER }, /* power */
2632};
2633
2634struct ir_scancode_table ir_codes_powercolor_real_angel_table = {
2635 .scan = ir_codes_powercolor_real_angel,
2636 .size = ARRAY_SIZE(ir_codes_powercolor_real_angel),
2637};
2638EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel_table);
2639
2640/* Kworld Plus TV Analog Lite PCI IR
2641 Mauro Carvalho Chehab <mchehab@infradead.org>
2642 */
2643static struct ir_scancode ir_codes_kworld_plus_tv_analog[] = {
2644 { 0x0c, KEY_PROG1 }, /* Kworld key */
2645 { 0x16, KEY_CLOSECD }, /* -> ) */
2646 { 0x1d, KEY_POWER2 },
2647
2648 { 0x00, KEY_1 },
2649 { 0x01, KEY_2 },
2650 { 0x02, KEY_3 }, /* Two keys have the same code: 3 and left */
2651 { 0x03, KEY_4 }, /* Two keys have the same code: 3 and right */
2652 { 0x04, KEY_5 },
2653 { 0x05, KEY_6 },
2654 { 0x06, KEY_7 },
2655 { 0x07, KEY_8 },
2656 { 0x08, KEY_9 },
2657 { 0x0a, KEY_0 },
2658
2659 { 0x09, KEY_AGAIN },
2660 { 0x14, KEY_MUTE },
2661
2662 { 0x20, KEY_UP },
2663 { 0x21, KEY_DOWN },
2664 { 0x0b, KEY_ENTER },
2665
2666 { 0x10, KEY_CHANNELUP },
2667 { 0x11, KEY_CHANNELDOWN },
2668
2669 /* Couldn't map key left/key right since those
2670 conflict with '3' and '4' scancodes
2671 I dunno what the original driver does
2672 */
2673
2674 { 0x13, KEY_VOLUMEUP },
2675 { 0x12, KEY_VOLUMEDOWN },
2676
2677 /* The lower part of the IR
2678 There are several duplicated keycodes there.
2679 Most of them conflict with digits.
2680 Add mappings just to the unused scancodes.
2681 Somehow, the original driver has a way to know,
2682 but this doesn't seem to be on some GPIO.
2683 Also, it is not related to the time between keyup
2684 and keydown.
2685 */
2686 { 0x19, KEY_TIME}, /* Timeshift */
2687 { 0x1a, KEY_STOP},
2688 { 0x1b, KEY_RECORD},
2689
2690 { 0x22, KEY_TEXT},
2691
2692 { 0x15, KEY_AUDIO}, /* ((*)) */
2693 { 0x0f, KEY_ZOOM},
2694 { 0x1c, KEY_CAMERA}, /* snapshot */
2695
2696 { 0x18, KEY_RED}, /* B */
2697 { 0x23, KEY_GREEN}, /* C */
2698};
2699struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table = {
2700 .scan = ir_codes_kworld_plus_tv_analog,
2701 .size = ARRAY_SIZE(ir_codes_kworld_plus_tv_analog),
2702};
2703EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog_table);
2704
2705/* Kaiomy TVnPC U2
2706 Mauro Carvalho Chehab <mchehab@infradead.org>
2707 */
2708static struct ir_scancode ir_codes_kaiomy[] = {
2709 { 0x43, KEY_POWER2},
2710 { 0x01, KEY_LIST},
2711 { 0x0b, KEY_ZOOM},
2712 { 0x03, KEY_POWER},
2713
2714 { 0x04, KEY_1},
2715 { 0x08, KEY_2},
2716 { 0x02, KEY_3},
2717
2718 { 0x0f, KEY_4},
2719 { 0x05, KEY_5},
2720 { 0x06, KEY_6},
2721
2722 { 0x0c, KEY_7},
2723 { 0x0d, KEY_8},
2724 { 0x0a, KEY_9},
2725
2726 { 0x11, KEY_0},
2727
2728 { 0x09, KEY_CHANNELUP},
2729 { 0x07, KEY_CHANNELDOWN},
2730
2731 { 0x0e, KEY_VOLUMEUP},
2732 { 0x13, KEY_VOLUMEDOWN},
2733
2734 { 0x10, KEY_HOME},
2735 { 0x12, KEY_ENTER},
2736
2737 { 0x14, KEY_RECORD},
2738 { 0x15, KEY_STOP},
2739 { 0x16, KEY_PLAY},
2740 { 0x17, KEY_MUTE},
2741
2742 { 0x18, KEY_UP},
2743 { 0x19, KEY_DOWN},
2744 { 0x1a, KEY_LEFT},
2745 { 0x1b, KEY_RIGHT},
2746
2747 { 0x1c, KEY_RED},
2748 { 0x1d, KEY_GREEN},
2749 { 0x1e, KEY_YELLOW},
2750 { 0x1f, KEY_BLUE},
2751};
2752struct ir_scancode_table ir_codes_kaiomy_table = {
2753 .scan = ir_codes_kaiomy,
2754 .size = ARRAY_SIZE(ir_codes_kaiomy),
2755};
2756EXPORT_SYMBOL_GPL(ir_codes_kaiomy_table);
2757
2758static struct ir_scancode ir_codes_avermedia_a16d[] = {
2759 { 0x20, KEY_LIST},
2760 { 0x00, KEY_POWER},
2761 { 0x28, KEY_1},
2762 { 0x18, KEY_2},
2763 { 0x38, KEY_3},
2764 { 0x24, KEY_4},
2765 { 0x14, KEY_5},
2766 { 0x34, KEY_6},
2767 { 0x2c, KEY_7},
2768 { 0x1c, KEY_8},
2769 { 0x3c, KEY_9},
2770 { 0x12, KEY_SUBTITLE},
2771 { 0x22, KEY_0},
2772 { 0x32, KEY_REWIND},
2773 { 0x3a, KEY_SHUFFLE},
2774 { 0x02, KEY_PRINT},
2775 { 0x11, KEY_CHANNELDOWN},
2776 { 0x31, KEY_CHANNELUP},
2777 { 0x0c, KEY_ZOOM},
2778 { 0x1e, KEY_VOLUMEDOWN},
2779 { 0x3e, KEY_VOLUMEUP},
2780 { 0x0a, KEY_MUTE},
2781 { 0x04, KEY_AUDIO},
2782 { 0x26, KEY_RECORD},
2783 { 0x06, KEY_PLAY},
2784 { 0x36, KEY_STOP},
2785 { 0x16, KEY_PAUSE},
2786 { 0x2e, KEY_REWIND},
2787 { 0x0e, KEY_FASTFORWARD},
2788 { 0x30, KEY_TEXT},
2789 { 0x21, KEY_GREEN},
2790 { 0x01, KEY_BLUE},
2791 { 0x08, KEY_EPG},
2792 { 0x2a, KEY_MENU},
2793};
2794struct ir_scancode_table ir_codes_avermedia_a16d_table = {
2795 .scan = ir_codes_avermedia_a16d,
2796 .size = ARRAY_SIZE(ir_codes_avermedia_a16d),
2797};
2798EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d_table);
2799
2800/* Encore ENLTV-FM v5.3
2801 Mauro Carvalho Chehab <mchehab@infradead.org>
2802 */
2803static struct ir_scancode ir_codes_encore_enltv_fm53[] = {
2804 { 0x10, KEY_POWER2},
2805 { 0x06, KEY_MUTE},
2806
2807 { 0x09, KEY_1},
2808 { 0x1d, KEY_2},
2809 { 0x1f, KEY_3},
2810 { 0x19, KEY_4},
2811 { 0x1b, KEY_5},
2812 { 0x11, KEY_6},
2813 { 0x17, KEY_7},
2814 { 0x12, KEY_8},
2815 { 0x16, KEY_9},
2816 { 0x48, KEY_0},
2817
2818 { 0x04, KEY_LIST}, /* -/-- */
2819 { 0x40, KEY_LAST}, /* recall */
2820
2821 { 0x02, KEY_MODE}, /* TV/AV */
2822 { 0x05, KEY_CAMERA}, /* SNAPSHOT */
2823
2824 { 0x4c, KEY_CHANNELUP}, /* UP */
2825 { 0x00, KEY_CHANNELDOWN}, /* DOWN */
2826 { 0x0d, KEY_VOLUMEUP}, /* RIGHT */
2827 { 0x15, KEY_VOLUMEDOWN}, /* LEFT */
2828 { 0x49, KEY_ENTER}, /* OK */
2829
2830 { 0x54, KEY_RECORD},
2831 { 0x4d, KEY_PLAY}, /* pause */
2832
2833 { 0x1e, KEY_MENU}, /* video setting */
2834 { 0x0e, KEY_RIGHT}, /* <- */
2835 { 0x1a, KEY_LEFT}, /* -> */
2836
2837 { 0x0a, KEY_CLEAR}, /* video default */
2838 { 0x0c, KEY_ZOOM}, /* hide pannel */
2839 { 0x47, KEY_SLEEP}, /* shutdown */
2840};
2841struct ir_scancode_table ir_codes_encore_enltv_fm53_table = {
2842 .scan = ir_codes_encore_enltv_fm53,
2843 .size = ARRAY_SIZE(ir_codes_encore_enltv_fm53),
2844};
2845EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_fm53_table);
2846
2847/* Zogis Real Audio 220 - 32 keys IR */
2848static struct ir_scancode ir_codes_real_audio_220_32_keys[] = {
2849 { 0x1c, KEY_RADIO},
2850 { 0x12, KEY_POWER2},
2851
2852 { 0x01, KEY_1},
2853 { 0x02, KEY_2},
2854 { 0x03, KEY_3},
2855 { 0x04, KEY_4},
2856 { 0x05, KEY_5},
2857 { 0x06, KEY_6},
2858 { 0x07, KEY_7},
2859 { 0x08, KEY_8},
2860 { 0x09, KEY_9},
2861 { 0x00, KEY_0},
2862
2863 { 0x0c, KEY_VOLUMEUP},
2864 { 0x18, KEY_VOLUMEDOWN},
2865 { 0x0b, KEY_CHANNELUP},
2866 { 0x15, KEY_CHANNELDOWN},
2867 { 0x16, KEY_ENTER},
2868
2869 { 0x11, KEY_LIST}, /* Source */
2870 { 0x0d, KEY_AUDIO}, /* stereo */
2871
2872 { 0x0f, KEY_PREVIOUS}, /* Prev */
2873 { 0x1b, KEY_TIME}, /* Timeshift */
2874 { 0x1a, KEY_NEXT}, /* Next */
2875
2876 { 0x0e, KEY_STOP},
2877 { 0x1f, KEY_PLAY},
2878 { 0x1e, KEY_PLAYPAUSE}, /* Pause */
2879
2880 { 0x1d, KEY_RECORD},
2881 { 0x13, KEY_MUTE},
2882 { 0x19, KEY_CAMERA}, /* Snapshot */
2883
2884};
2885struct ir_scancode_table ir_codes_real_audio_220_32_keys_table = {
2886 .scan = ir_codes_real_audio_220_32_keys,
2887 .size = ARRAY_SIZE(ir_codes_real_audio_220_32_keys),
2888};
2889EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys_table);
2890
2891/* ATI TV Wonder HD 600 USB
2892 Devin Heitmueller <devin.heitmueller@gmail.com>
2893 */
2894static struct ir_scancode ir_codes_ati_tv_wonder_hd_600[] = {
2895 { 0x00, KEY_RECORD}, /* Row 1 */
2896 { 0x01, KEY_PLAYPAUSE},
2897 { 0x02, KEY_STOP},
2898 { 0x03, KEY_POWER},
2899 { 0x04, KEY_PREVIOUS}, /* Row 2 */
2900 { 0x05, KEY_REWIND},
2901 { 0x06, KEY_FORWARD},
2902 { 0x07, KEY_NEXT},
2903 { 0x08, KEY_EPG}, /* Row 3 */
2904 { 0x09, KEY_HOME},
2905 { 0x0a, KEY_MENU},
2906 { 0x0b, KEY_CHANNELUP},
2907 { 0x0c, KEY_BACK}, /* Row 4 */
2908 { 0x0d, KEY_UP},
2909 { 0x0e, KEY_INFO},
2910 { 0x0f, KEY_CHANNELDOWN},
2911 { 0x10, KEY_LEFT}, /* Row 5 */
2912 { 0x11, KEY_SELECT},
2913 { 0x12, KEY_RIGHT},
2914 { 0x13, KEY_VOLUMEUP},
2915 { 0x14, KEY_LAST}, /* Row 6 */
2916 { 0x15, KEY_DOWN},
2917 { 0x16, KEY_MUTE},
2918 { 0x17, KEY_VOLUMEDOWN},
2919};
2920struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table = {
2921 .scan = ir_codes_ati_tv_wonder_hd_600,
2922 .size = ARRAY_SIZE(ir_codes_ati_tv_wonder_hd_600),
2923};
2924EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600_table);
2925
2926/* DVBWorld remotes
2927 Igor M. Liplianin <liplianin@me.by>
2928 */
2929static struct ir_scancode ir_codes_dm1105_nec[] = {
2930 { 0x0a, KEY_POWER2}, /* power */
2931 { 0x0c, KEY_MUTE}, /* mute */
2932 { 0x11, KEY_1},
2933 { 0x12, KEY_2},
2934 { 0x13, KEY_3},
2935 { 0x14, KEY_4},
2936 { 0x15, KEY_5},
2937 { 0x16, KEY_6},
2938 { 0x17, KEY_7},
2939 { 0x18, KEY_8},
2940 { 0x19, KEY_9},
2941 { 0x10, KEY_0},
2942 { 0x1c, KEY_CHANNELUP}, /* ch+ */
2943 { 0x0f, KEY_CHANNELDOWN}, /* ch- */
2944 { 0x1a, KEY_VOLUMEUP}, /* vol+ */
2945 { 0x0e, KEY_VOLUMEDOWN}, /* vol- */
2946 { 0x04, KEY_RECORD}, /* rec */
2947 { 0x09, KEY_CHANNEL}, /* fav */
2948 { 0x08, KEY_BACKSPACE}, /* rewind */
2949 { 0x07, KEY_FASTFORWARD}, /* fast */
2950 { 0x0b, KEY_PAUSE}, /* pause */
2951 { 0x02, KEY_ESC}, /* cancel */
2952 { 0x03, KEY_TAB}, /* tab */
2953 { 0x00, KEY_UP}, /* up */
2954 { 0x1f, KEY_ENTER}, /* ok */
2955 { 0x01, KEY_DOWN}, /* down */
2956 { 0x05, KEY_RECORD}, /* cap */
2957 { 0x06, KEY_STOP}, /* stop */
2958 { 0x40, KEY_ZOOM}, /* full */
2959 { 0x1e, KEY_TV}, /* tvmode */
2960 { 0x1b, KEY_B}, /* recall */
2961};
2962struct ir_scancode_table ir_codes_dm1105_nec_table = {
2963 .scan = ir_codes_dm1105_nec,
2964 .size = ARRAY_SIZE(ir_codes_dm1105_nec),
2965};
2966EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table);
2967
2968static struct ir_scancode ir_codes_tevii_nec[] = {
2969 { 0x0a, KEY_POWER2},
2970 { 0x0c, KEY_MUTE},
2971 { 0x11, KEY_1},
2972 { 0x12, KEY_2},
2973 { 0x13, KEY_3},
2974 { 0x14, KEY_4},
2975 { 0x15, KEY_5},
2976 { 0x16, KEY_6},
2977 { 0x17, KEY_7},
2978 { 0x18, KEY_8},
2979 { 0x19, KEY_9},
2980 { 0x10, KEY_0},
2981 { 0x1c, KEY_MENU},
2982 { 0x0f, KEY_VOLUMEDOWN},
2983 { 0x1a, KEY_LAST},
2984 { 0x0e, KEY_OPEN},
2985 { 0x04, KEY_RECORD},
2986 { 0x09, KEY_VOLUMEUP},
2987 { 0x08, KEY_CHANNELUP},
2988 { 0x07, KEY_PVR},
2989 { 0x0b, KEY_TIME},
2990 { 0x02, KEY_RIGHT},
2991 { 0x03, KEY_LEFT},
2992 { 0x00, KEY_UP},
2993 { 0x1f, KEY_OK},
2994 { 0x01, KEY_DOWN},
2995 { 0x05, KEY_TUNER},
2996 { 0x06, KEY_CHANNELDOWN},
2997 { 0x40, KEY_PLAYPAUSE},
2998 { 0x1e, KEY_REWIND},
2999 { 0x1b, KEY_FAVORITES},
3000 { 0x1d, KEY_BACK},
3001 { 0x4d, KEY_FASTFORWARD},
3002 { 0x44, KEY_EPG},
3003 { 0x4c, KEY_INFO},
3004 { 0x41, KEY_AB},
3005 { 0x43, KEY_AUDIO},
3006 { 0x45, KEY_SUBTITLE},
3007 { 0x4a, KEY_LIST},
3008 { 0x46, KEY_F1},
3009 { 0x47, KEY_F2},
3010 { 0x5e, KEY_F3},
3011 { 0x5c, KEY_F4},
3012 { 0x52, KEY_F5},
3013 { 0x5a, KEY_F6},
3014 { 0x56, KEY_MODE},
3015 { 0x58, KEY_SWITCHVIDEOMODE},
3016};
3017struct ir_scancode_table ir_codes_tevii_nec_table = {
3018 .scan = ir_codes_tevii_nec,
3019 .size = ARRAY_SIZE(ir_codes_tevii_nec),
3020};
3021EXPORT_SYMBOL_GPL(ir_codes_tevii_nec_table);
3022
3023static struct ir_scancode ir_codes_tbs_nec[] = {
3024 { 0x04, KEY_POWER2}, /*power*/
3025 { 0x14, KEY_MUTE}, /*mute*/
3026 { 0x07, KEY_1},
3027 { 0x06, KEY_2},
3028 { 0x05, KEY_3},
3029 { 0x0b, KEY_4},
3030 { 0x0a, KEY_5},
3031 { 0x09, KEY_6},
3032 { 0x0f, KEY_7},
3033 { 0x0e, KEY_8},
3034 { 0x0d, KEY_9},
3035 { 0x12, KEY_0},
3036 { 0x16, KEY_CHANNELUP}, /*ch+*/
3037 { 0x11, KEY_CHANNELDOWN},/*ch-*/
3038 { 0x13, KEY_VOLUMEUP}, /*vol+*/
3039 { 0x0c, KEY_VOLUMEDOWN},/*vol-*/
3040 { 0x03, KEY_RECORD}, /*rec*/
3041 { 0x18, KEY_PAUSE}, /*pause*/
3042 { 0x19, KEY_OK}, /*ok*/
3043 { 0x1a, KEY_CAMERA}, /* snapshot */
3044 { 0x01, KEY_UP},
3045 { 0x10, KEY_LEFT},
3046 { 0x02, KEY_RIGHT},
3047 { 0x08, KEY_DOWN},
3048 { 0x15, KEY_FAVORITES},
3049 { 0x17, KEY_SUBTITLE},
3050 { 0x1d, KEY_ZOOM},
3051 { 0x1f, KEY_EXIT},
3052 { 0x1e, KEY_MENU},
3053 { 0x1c, KEY_EPG},
3054 { 0x00, KEY_PREVIOUS},
3055 { 0x1b, KEY_MODE},
3056};
3057struct ir_scancode_table ir_codes_tbs_nec_table = {
3058 .scan = ir_codes_tbs_nec,
3059 .size = ARRAY_SIZE(ir_codes_tbs_nec),
3060};
3061EXPORT_SYMBOL_GPL(ir_codes_tbs_nec_table);
3062
3063/* Terratec Cinergy Hybrid T USB XS
3064 Devin Heitmueller <dheitmueller@linuxtv.org>
3065 */
3066static struct ir_scancode ir_codes_terratec_cinergy_xs[] = {
3067 { 0x41, KEY_HOME},
3068 { 0x01, KEY_POWER},
3069 { 0x42, KEY_MENU},
3070 { 0x02, KEY_1},
3071 { 0x03, KEY_2},
3072 { 0x04, KEY_3},
3073 { 0x43, KEY_SUBTITLE},
3074 { 0x05, KEY_4},
3075 { 0x06, KEY_5},
3076 { 0x07, KEY_6},
3077 { 0x44, KEY_TEXT},
3078 { 0x08, KEY_7},
3079 { 0x09, KEY_8},
3080 { 0x0a, KEY_9},
3081 { 0x45, KEY_DELETE},
3082 { 0x0b, KEY_TUNER},
3083 { 0x0c, KEY_0},
3084 { 0x0d, KEY_MODE},
3085 { 0x46, KEY_TV},
3086 { 0x47, KEY_DVD},
3087 { 0x49, KEY_VIDEO},
3088 { 0x4b, KEY_AUX},
3089 { 0x10, KEY_UP},
3090 { 0x11, KEY_LEFT},
3091 { 0x12, KEY_OK},
3092 { 0x13, KEY_RIGHT},
3093 { 0x14, KEY_DOWN},
3094 { 0x0f, KEY_EPG},
3095 { 0x16, KEY_INFO},
3096 { 0x4d, KEY_BACKSPACE},
3097 { 0x1c, KEY_VOLUMEUP},
3098 { 0x4c, KEY_PLAY},
3099 { 0x1b, KEY_CHANNELUP},
3100 { 0x1e, KEY_VOLUMEDOWN},
3101 { 0x1d, KEY_MUTE},
3102 { 0x1f, KEY_CHANNELDOWN},
3103 { 0x17, KEY_RED},
3104 { 0x18, KEY_GREEN},
3105 { 0x19, KEY_YELLOW},
3106 { 0x1a, KEY_BLUE},
3107 { 0x58, KEY_RECORD},
3108 { 0x48, KEY_STOP},
3109 { 0x40, KEY_PAUSE},
3110 { 0x54, KEY_LAST},
3111 { 0x4e, KEY_REWIND},
3112 { 0x4f, KEY_FASTFORWARD},
3113 { 0x5c, KEY_NEXT},
3114};
3115struct ir_scancode_table ir_codes_terratec_cinergy_xs_table = {
3116 .scan = ir_codes_terratec_cinergy_xs,
3117 .size = ARRAY_SIZE(ir_codes_terratec_cinergy_xs),
3118};
3119EXPORT_SYMBOL_GPL(ir_codes_terratec_cinergy_xs_table);
3120
3121/* EVGA inDtube
3122 Devin Heitmueller <devin.heitmueller@gmail.com>
3123 */
3124static struct ir_scancode ir_codes_evga_indtube[] = {
3125 { 0x12, KEY_POWER},
3126 { 0x02, KEY_MODE}, /* TV */
3127 { 0x14, KEY_MUTE},
3128 { 0x1a, KEY_CHANNELUP},
3129 { 0x16, KEY_TV2}, /* PIP */
3130 { 0x1d, KEY_VOLUMEUP},
3131 { 0x05, KEY_CHANNELDOWN},
3132 { 0x0f, KEY_PLAYPAUSE},
3133 { 0x19, KEY_VOLUMEDOWN},
3134 { 0x1c, KEY_REWIND},
3135 { 0x0d, KEY_RECORD},
3136 { 0x18, KEY_FORWARD},
3137 { 0x1e, KEY_PREVIOUS},
3138 { 0x1b, KEY_STOP},
3139 { 0x1f, KEY_NEXT},
3140 { 0x13, KEY_CAMERA},
3141};
3142struct ir_scancode_table ir_codes_evga_indtube_table = {
3143 .scan = ir_codes_evga_indtube,
3144 .size = ARRAY_SIZE(ir_codes_evga_indtube),
3145};
3146EXPORT_SYMBOL_GPL(ir_codes_evga_indtube_table);
3147
3148static struct ir_scancode ir_codes_videomate_s350[] = {
3149 { 0x00, KEY_TV},
3150 { 0x01, KEY_DVD},
3151 { 0x04, KEY_RECORD},
3152 { 0x05, KEY_VIDEO}, /* TV/Video */
3153 { 0x07, KEY_STOP},
3154 { 0x08, KEY_PLAYPAUSE},
3155 { 0x0a, KEY_REWIND},
3156 { 0x0f, KEY_FASTFORWARD},
3157 { 0x10, KEY_CHANNELUP},
3158 { 0x12, KEY_VOLUMEUP},
3159 { 0x13, KEY_CHANNELDOWN},
3160 { 0x14, KEY_MUTE},
3161 { 0x15, KEY_VOLUMEDOWN},
3162 { 0x16, KEY_1},
3163 { 0x17, KEY_2},
3164 { 0x18, KEY_3},
3165 { 0x19, KEY_4},
3166 { 0x1a, KEY_5},
3167 { 0x1b, KEY_6},
3168 { 0x1c, KEY_7},
3169 { 0x1d, KEY_8},
3170 { 0x1e, KEY_9},
3171 { 0x1f, KEY_0},
3172 { 0x21, KEY_SLEEP},
3173 { 0x24, KEY_ZOOM},
3174 { 0x25, KEY_LAST}, /* Recall */
3175 { 0x26, KEY_SUBTITLE}, /* CC */
3176 { 0x27, KEY_LANGUAGE}, /* MTS */
3177 { 0x29, KEY_CHANNEL}, /* SURF */
3178 { 0x2b, KEY_A},
3179 { 0x2c, KEY_B},
3180 { 0x2f, KEY_CAMERA}, /* Snapshot */
3181 { 0x23, KEY_RADIO},
3182 { 0x02, KEY_PREVIOUSSONG},
3183 { 0x06, KEY_NEXTSONG},
3184 { 0x03, KEY_EPG},
3185 { 0x09, KEY_SETUP},
3186 { 0x22, KEY_BACKSPACE},
3187 { 0x0c, KEY_UP},
3188 { 0x0e, KEY_DOWN},
3189 { 0x0b, KEY_LEFT},
3190 { 0x0d, KEY_RIGHT},
3191 { 0x11, KEY_ENTER},
3192 { 0x20, KEY_TEXT},
3193};
3194struct ir_scancode_table ir_codes_videomate_s350_table = {
3195 .scan = ir_codes_videomate_s350,
3196 .size = ARRAY_SIZE(ir_codes_videomate_s350),
3197};
3198EXPORT_SYMBOL_GPL(ir_codes_videomate_s350_table);
3199
3200/* GADMEI UTV330+ RM008Z remote
3201 Shine Liu <shinel@foxmail.com>
3202 */
3203static struct ir_scancode ir_codes_gadmei_rm008z[] = {
3204 { 0x14, KEY_POWER2}, /* POWER OFF */
3205 { 0x0c, KEY_MUTE}, /* MUTE */
3206
3207 { 0x18, KEY_TV}, /* TV */
3208 { 0x0e, KEY_VIDEO}, /* AV */
3209 { 0x0b, KEY_AUDIO}, /* SV */
3210 { 0x0f, KEY_RADIO}, /* FM */
3211
3212 { 0x00, KEY_1},
3213 { 0x01, KEY_2},
3214 { 0x02, KEY_3},
3215 { 0x03, KEY_4},
3216 { 0x04, KEY_5},
3217 { 0x05, KEY_6},
3218 { 0x06, KEY_7},
3219 { 0x07, KEY_8},
3220 { 0x08, KEY_9},
3221 { 0x09, KEY_0},
3222 { 0x0a, KEY_INFO}, /* OSD */
3223 { 0x1c, KEY_BACKSPACE}, /* LAST */
3224
3225 { 0x0d, KEY_PLAY}, /* PLAY */
3226 { 0x1e, KEY_CAMERA}, /* SNAPSHOT */
3227 { 0x1a, KEY_RECORD}, /* RECORD */
3228 { 0x17, KEY_STOP}, /* STOP */
3229
3230 { 0x1f, KEY_UP}, /* UP */
3231 { 0x44, KEY_DOWN}, /* DOWN */
3232 { 0x46, KEY_TAB}, /* BACK */
3233 { 0x4a, KEY_ZOOM}, /* FULLSECREEN */
3234
3235 { 0x10, KEY_VOLUMEUP}, /* VOLUMEUP */
3236 { 0x11, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */
3237 { 0x12, KEY_CHANNELUP}, /* CHANNELUP */
3238 { 0x13, KEY_CHANNELDOWN}, /* CHANNELDOWN */
3239 { 0x15, KEY_ENTER}, /* OK */
3240};
3241struct ir_scancode_table ir_codes_gadmei_rm008z_table = {
3242 .scan = ir_codes_gadmei_rm008z,
3243 .size = ARRAY_SIZE(ir_codes_gadmei_rm008z),
3244};
3245EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
3246
3247/*************************************************************
3248 * COMPLETE SCANCODE TABLES
3249 * Instead of just a partial scancode, the tables bellow
3250 * contains the complete scancode and the receiver protocol
3251 *************************************************************/
3252
3253/*
3254 * Hauppauge:the newer, gray remotes (seems there are multiple
3255 * slightly different versions), shipped with cx88+ivtv cards.
3256 *
3257 * This table contains the complete RC5 code, instead of just the data part
3258 */
3259static struct ir_scancode ir_codes_rc5_hauppauge_new[] = {
3260 /* Keys 0 to 9 */
3261 { 0x1e00, KEY_0 },
3262 { 0x1e01, KEY_1 },
3263 { 0x1e02, KEY_2 },
3264 { 0x1e03, KEY_3 },
3265 { 0x1e04, KEY_4 },
3266 { 0x1e05, KEY_5 },
3267 { 0x1e06, KEY_6 },
3268 { 0x1e07, KEY_7 },
3269 { 0x1e08, KEY_8 },
3270 { 0x1e09, KEY_9 },
3271
3272 { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
3273 { 0x1e0b, KEY_RED }, /* red button */
3274 { 0x1e0c, KEY_RADIO },
3275 { 0x1e0d, KEY_MENU },
3276 { 0x1e0e, KEY_SUBTITLE }, /* also the # key */
3277 { 0x1e0f, KEY_MUTE },
3278 { 0x1e10, KEY_VOLUMEUP },
3279 { 0x1e11, KEY_VOLUMEDOWN },
3280 { 0x1e12, KEY_PREVIOUS }, /* previous channel */
3281 { 0x1e14, KEY_UP },
3282 { 0x1e15, KEY_DOWN },
3283 { 0x1e16, KEY_LEFT },
3284 { 0x1e17, KEY_RIGHT },
3285 { 0x1e18, KEY_VIDEO }, /* Videos */
3286 { 0x1e19, KEY_AUDIO }, /* Music */
3287 /* 0x1e1a: Pictures - presume this means
3288 "Multimedia Home Platform" -
3289 no "PICTURES" key in input.h
3290 */
3291 { 0x1e1a, KEY_MHP },
3292
3293 { 0x1e1b, KEY_EPG }, /* Guide */
3294 { 0x1e1c, KEY_TV },
3295 { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
3296 { 0x1e1f, KEY_EXIT }, /* back/exit */
3297 { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
3298 { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
3299 { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */
3300 { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
3301 { 0x1e25, KEY_ENTER }, /* OK */
3302 { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */
3303 { 0x1e29, KEY_BLUE }, /* blue key */
3304 { 0x1e2e, KEY_GREEN }, /* green button */
3305 { 0x1e30, KEY_PAUSE }, /* pause */
3306 { 0x1e32, KEY_REWIND }, /* backward << */
3307 { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
3308 { 0x1e35, KEY_PLAY },
3309 { 0x1e36, KEY_STOP },
3310 { 0x1e37, KEY_RECORD }, /* recording */
3311 { 0x1e38, KEY_YELLOW }, /* yellow key */
3312 { 0x1e3b, KEY_SELECT }, /* top right button */
3313 { 0x1e3c, KEY_ZOOM }, /* full */
3314 { 0x1e3d, KEY_POWER }, /* system power (green button) */
3315};
3316
3317struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = {
3318 .scan = ir_codes_rc5_hauppauge_new,
3319 .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new),
3320 .ir_type = IR_TYPE_RC5,
3321};
3322EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table);
3323
3324/* Terratec Cinergy Hybrid T USB XS FM
3325 Mauro Carvalho Chehab <mchehab@redhat.com>
3326 */
3327static struct ir_scancode ir_codes_nec_terratec_cinergy_xs[] = {
3328 { 0x1441, KEY_HOME},
3329 { 0x1401, KEY_POWER2},
3330
3331 { 0x1442, KEY_MENU}, /* DVD menu */
3332 { 0x1443, KEY_SUBTITLE},
3333 { 0x1444, KEY_TEXT}, /* Teletext */
3334 { 0x1445, KEY_DELETE},
3335
3336 { 0x1402, KEY_1},
3337 { 0x1403, KEY_2},
3338 { 0x1404, KEY_3},
3339 { 0x1405, KEY_4},
3340 { 0x1406, KEY_5},
3341 { 0x1407, KEY_6},
3342 { 0x1408, KEY_7},
3343 { 0x1409, KEY_8},
3344 { 0x140a, KEY_9},
3345 { 0x140c, KEY_0},
3346
3347 { 0x140b, KEY_TUNER}, /* AV */
3348 { 0x140d, KEY_MODE}, /* A.B */
3349
3350 { 0x1446, KEY_TV},
3351 { 0x1447, KEY_DVD},
3352 { 0x1449, KEY_VIDEO},
3353 { 0x144a, KEY_RADIO}, /* Music */
3354 { 0x144b, KEY_CAMERA}, /* PIC */
3355
3356 { 0x1410, KEY_UP},
3357 { 0x1411, KEY_LEFT},
3358 { 0x1412, KEY_OK},
3359 { 0x1413, KEY_RIGHT},
3360 { 0x1414, KEY_DOWN},
3361
3362 { 0x140f, KEY_EPG},
3363 { 0x1416, KEY_INFO},
3364 { 0x144d, KEY_BACKSPACE},
3365
3366 { 0x141c, KEY_VOLUMEUP},
3367 { 0x141e, KEY_VOLUMEDOWN},
3368
3369 { 0x144c, KEY_PLAY},
3370 { 0x141d, KEY_MUTE},
3371
3372 { 0x141b, KEY_CHANNELUP},
3373 { 0x141f, KEY_CHANNELDOWN},
3374
3375 { 0x1417, KEY_RED},
3376 { 0x1418, KEY_GREEN},
3377 { 0x1419, KEY_YELLOW},
3378 { 0x141a, KEY_BLUE},
3379
3380 { 0x1458, KEY_RECORD},
3381 { 0x1448, KEY_STOP},
3382 { 0x1440, KEY_PAUSE},
3383
3384 { 0x1454, KEY_LAST},
3385 { 0x144e, KEY_REWIND},
3386 { 0x144f, KEY_FASTFORWARD},
3387 { 0x145c, KEY_NEXT},
3388};
3389struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table = {
3390 .scan = ir_codes_nec_terratec_cinergy_xs,
3391 .size = ARRAY_SIZE(ir_codes_nec_terratec_cinergy_xs),
3392 .ir_type = IR_TYPE_NEC,
3393};
3394EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table);
3395
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c
new file mode 100644
index 000000000000..99ed2deceef3
--- /dev/null
+++ b/drivers/media/IR/ir-keytable.c
@@ -0,0 +1,433 @@
1/* ir-register.c - handle IR scancode->keycode tables
2 *
3 * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 */
5
6#include <linux/usb/input.h>
7
8#include <media/ir-common.h>
9
10#define IR_TAB_MIN_SIZE 32
11#define IR_TAB_MAX_SIZE 1024
12
13
14/**
15 * ir_seek_table() - returns the element order on the table
16 * @rc_tab: the ir_scancode_table with the keymap to be used
17 * @scancode: the scancode that we're seeking
18 *
19 * This routine is used by the input routines when a key is pressed at the
20 * IR. The scancode is received and needs to be converted into a keycode.
21 * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
22 * corresponding keycode from the table.
23 */
24static int ir_seek_table(struct ir_scancode_table *rc_tab, u32 scancode)
25{
26 int rc;
27 unsigned long flags;
28 struct ir_scancode *keymap = rc_tab->scan;
29
30 spin_lock_irqsave(&rc_tab->lock, flags);
31
32 /* FIXME: replace it by a binary search */
33
34 for (rc = 0; rc < rc_tab->size; rc++)
35 if (keymap[rc].scancode == scancode)
36 goto exit;
37
38 /* Not found */
39 rc = -EINVAL;
40
41exit:
42 spin_unlock_irqrestore(&rc_tab->lock, flags);
43 return rc;
44}
45
46/**
47 * ir_roundup_tablesize() - gets an optimum value for the table size
48 * @n_elems: minimum number of entries to store keycodes
49 *
50 * This routine is used to choose the keycode table size.
51 *
52 * In order to have some empty space for new keycodes,
53 * and knowing in advance that kmalloc allocates only power of two
54 * segments, it optimizes the allocated space to have some spare space
55 * for those new keycodes by using the maximum number of entries that
56 * will be effectively be allocated by kmalloc.
57 * In order to reduce the quantity of table resizes, it has a minimum
58 * table size of IR_TAB_MIN_SIZE.
59 */
60int ir_roundup_tablesize(int n_elems)
61{
62 size_t size;
63
64 if (n_elems < IR_TAB_MIN_SIZE)
65 n_elems = IR_TAB_MIN_SIZE;
66
67 /*
68 * As kmalloc only allocates sizes of power of two, get as
69 * much entries as possible for the allocated memory segment
70 */
71 size = roundup_pow_of_two(n_elems * sizeof(struct ir_scancode));
72 n_elems = size / sizeof(struct ir_scancode);
73
74 return n_elems;
75}
76
77/**
78 * ir_copy_table() - copies a keytable, discarding the unused entries
79 * @destin: destin table
80 * @origin: origin table
81 *
82 * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED
83 */
84
85int ir_copy_table(struct ir_scancode_table *destin,
86 const struct ir_scancode_table *origin)
87{
88 int i, j = 0;
89
90 for (i = 0; i < origin->size; i++) {
91 if (origin->scan[i].keycode == KEY_UNKNOWN ||
92 origin->scan[i].keycode == KEY_RESERVED)
93 continue;
94
95 memcpy(&destin->scan[j], &origin->scan[i], sizeof(struct ir_scancode));
96 j++;
97 }
98 destin->size = j;
99
100 IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size);
101
102 return 0;
103}
104
105/**
106 * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table
107 * @dev: the struct input_dev device descriptor
108 * @scancode: the desired scancode
109 * @keycode: the keycode to be retorned.
110 *
111 * This routine is used to handle evdev EVIOCGKEY ioctl.
112 * If the key is not found, returns -EINVAL, otherwise, returns 0.
113 */
114static int ir_getkeycode(struct input_dev *dev,
115 int scancode, int *keycode)
116{
117 int elem;
118 struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
119
120 elem = ir_seek_table(rc_tab, scancode);
121 if (elem >= 0) {
122 *keycode = rc_tab->scan[elem].keycode;
123 return 0;
124 }
125
126 /*
127 * Scancode not found and table can't be expanded
128 */
129 if (elem < 0 && rc_tab->size == IR_TAB_MAX_SIZE)
130 return -EINVAL;
131
132 /*
133 * If is there extra space, returns KEY_RESERVED,
134 * otherwise, input core won't let ir_setkeycode to work
135 */
136 *keycode = KEY_RESERVED;
137 return 0;
138}
139
140
141/**
142 * ir_is_resize_needed() - Check if the table needs rezise
143 * @table: keycode table that may need to resize
144 * @n_elems: minimum number of entries to store keycodes
145 *
146 * Considering that kmalloc uses power of two storage areas, this
147 * routine detects if the real alloced size will change. If not, it
148 * just returns without doing nothing. Otherwise, it will extend or
149 * reduce the table size to meet the new needs.
150 *
151 * It returns 0 if no resize is needed, 1 otherwise.
152 */
153static int ir_is_resize_needed(struct ir_scancode_table *table, int n_elems)
154{
155 int cur_size = ir_roundup_tablesize(table->size);
156 int new_size = ir_roundup_tablesize(n_elems);
157
158 if (cur_size == new_size)
159 return 0;
160
161 /* Resize is needed */
162 return 1;
163}
164
165/**
166 * ir_delete_key() - remove a keycode from the table
167 * @rc_tab: keycode table
168 * @elem: element to be removed
169 *
170 */
171static void ir_delete_key(struct ir_scancode_table *rc_tab, int elem)
172{
173 unsigned long flags = 0;
174 int newsize = rc_tab->size - 1;
175 int resize = ir_is_resize_needed(rc_tab, newsize);
176 struct ir_scancode *oldkeymap = rc_tab->scan;
177 struct ir_scancode *newkeymap;
178
179 if (resize) {
180 newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
181 sizeof(*newkeymap), GFP_ATOMIC);
182
183 /* There's no memory for resize. Keep the old table */
184 if (!newkeymap)
185 resize = 0;
186 }
187
188 if (!resize) {
189 newkeymap = oldkeymap;
190
191 /* We'll modify the live table. Lock it */
192 spin_lock_irqsave(&rc_tab->lock, flags);
193 }
194
195 /*
196 * Copy the elements before the one that will be deleted
197 * if (!resize), both oldkeymap and newkeymap points
198 * to the same place, so, there's no need to copy
199 */
200 if (resize && elem > 0)
201 memcpy(newkeymap, oldkeymap,
202 elem * sizeof(*newkeymap));
203
204 /*
205 * Copy the other elements overwriting the element to be removed
206 * This operation applies to both resize and non-resize case
207 */
208 if (elem < newsize)
209 memcpy(&newkeymap[elem], &oldkeymap[elem + 1],
210 (newsize - elem) * sizeof(*newkeymap));
211
212 if (resize) {
213 /*
214 * As the copy happened to a temporary table, only here
215 * it needs to lock while replacing the table pointers
216 * to use the new table
217 */
218 spin_lock_irqsave(&rc_tab->lock, flags);
219 rc_tab->size = newsize;
220 rc_tab->scan = newkeymap;
221 spin_unlock_irqrestore(&rc_tab->lock, flags);
222
223 /* Frees the old keytable */
224 kfree(oldkeymap);
225 } else {
226 rc_tab->size = newsize;
227 spin_unlock_irqrestore(&rc_tab->lock, flags);
228 }
229}
230
231/**
232 * ir_insert_key() - insert a keycode at the table
233 * @rc_tab: keycode table
234 * @scancode: the desired scancode
235 * @keycode: the keycode to be retorned.
236 *
237 */
238static int ir_insert_key(struct ir_scancode_table *rc_tab,
239 int scancode, int keycode)
240{
241 unsigned long flags;
242 int elem = rc_tab->size;
243 int newsize = rc_tab->size + 1;
244 int resize = ir_is_resize_needed(rc_tab, newsize);
245 struct ir_scancode *oldkeymap = rc_tab->scan;
246 struct ir_scancode *newkeymap;
247
248 if (resize) {
249 newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
250 sizeof(*newkeymap), GFP_ATOMIC);
251 if (!newkeymap)
252 return -ENOMEM;
253
254 memcpy(newkeymap, oldkeymap,
255 rc_tab->size * sizeof(*newkeymap));
256 } else
257 newkeymap = oldkeymap;
258
259 /* Stores the new code at the table */
260 IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n",
261 rc_tab->size, scancode, keycode);
262
263 spin_lock_irqsave(&rc_tab->lock, flags);
264 rc_tab->size = newsize;
265 if (resize) {
266 rc_tab->scan = newkeymap;
267 kfree(oldkeymap);
268 }
269 newkeymap[elem].scancode = scancode;
270 newkeymap[elem].keycode = keycode;
271 spin_unlock_irqrestore(&rc_tab->lock, flags);
272
273 return 0;
274}
275
276/**
277 * ir_setkeycode() - set a keycode at the evdev scancode ->keycode table
278 * @dev: the struct input_dev device descriptor
279 * @scancode: the desired scancode
280 * @keycode: the keycode to be retorned.
281 *
282 * This routine is used to handle evdev EVIOCSKEY ioctl.
283 * There's one caveat here: how can we increase the size of the table?
284 * If the key is not found, returns -EINVAL, otherwise, returns 0.
285 */
286static int ir_setkeycode(struct input_dev *dev,
287 int scancode, int keycode)
288{
289 int rc = 0;
290 struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
291 struct ir_scancode *keymap = rc_tab->scan;
292 unsigned long flags;
293
294 /*
295 * Handle keycode table deletions
296 *
297 * If userspace is adding a KEY_UNKNOWN or KEY_RESERVED,
298 * deal as a trial to remove an existing scancode attribution
299 * if table become too big, reduce it to save space
300 */
301 if (keycode == KEY_UNKNOWN || keycode == KEY_RESERVED) {
302 rc = ir_seek_table(rc_tab, scancode);
303 if (rc < 0)
304 return 0;
305
306 IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", rc, scancode);
307 clear_bit(keymap[rc].keycode, dev->keybit);
308 ir_delete_key(rc_tab, rc);
309
310 return 0;
311 }
312
313 /*
314 * Handle keycode replacements
315 *
316 * If the scancode exists, just replace by the new value
317 */
318 rc = ir_seek_table(rc_tab, scancode);
319 if (rc >= 0) {
320 IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n",
321 rc, scancode, keycode);
322
323 clear_bit(keymap[rc].keycode, dev->keybit);
324
325 spin_lock_irqsave(&rc_tab->lock, flags);
326 keymap[rc].keycode = keycode;
327 spin_unlock_irqrestore(&rc_tab->lock, flags);
328
329 set_bit(keycode, dev->keybit);
330
331 return 0;
332 }
333
334 /*
335 * Handle new scancode inserts
336 *
337 * reallocate table if needed and insert a new keycode
338 */
339
340 /* Avoid growing the table indefinitely */
341 if (rc_tab->size + 1 > IR_TAB_MAX_SIZE)
342 return -EINVAL;
343
344 rc = ir_insert_key(rc_tab, scancode, keycode);
345 if (rc < 0)
346 return rc;
347 set_bit(keycode, dev->keybit);
348
349 return 0;
350}
351
352/**
353 * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
354 * @input_dev: the struct input_dev descriptor of the device
355 * @scancode: the scancode that we're seeking
356 *
357 * This routine is used by the input routines when a key is pressed at the
358 * IR. The scancode is received and needs to be converted into a keycode.
359 * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
360 * corresponding keycode from the table.
361 */
362u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
363{
364 struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
365 struct ir_scancode *keymap = rc_tab->scan;
366 int elem;
367
368 elem = ir_seek_table(rc_tab, scancode);
369 if (elem >= 0) {
370 IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
371 dev->name, scancode, keymap[elem].keycode);
372
373 return rc_tab->scan[elem].keycode;
374 }
375
376 printk(KERN_INFO "%s: unknown key for scancode 0x%04x\n",
377 dev->name, scancode);
378
379 /* Reports userspace that an unknown keycode were got */
380 return KEY_RESERVED;
381}
382
383/**
384 * ir_set_keycode_table() - sets the IR keycode table and add the handlers
385 * for keymap table get/set
386 * @input_dev: the struct input_dev descriptor of the device
387 * @rc_tab: the struct ir_scancode_table table of scancode/keymap
388 *
389 * This routine is used to initialize the input infrastructure to work with
390 * an IR.
391 * It should be called before registering the IR device.
392 */
393int ir_set_keycode_table(struct input_dev *input_dev,
394 struct ir_scancode_table *rc_tab)
395{
396 struct ir_scancode *keymap = rc_tab->scan;
397 int i;
398
399 spin_lock_init(&rc_tab->lock);
400
401 if (rc_tab->scan == NULL || !rc_tab->size)
402 return -EINVAL;
403
404 /* set the bits for the keys */
405 IR_dprintk(1, "key map size: %d\n", rc_tab->size);
406 for (i = 0; i < rc_tab->size; i++) {
407 IR_dprintk(1, "#%d: setting bit for keycode 0x%04x\n",
408 i, keymap[i].keycode);
409 set_bit(keymap[i].keycode, input_dev->keybit);
410 }
411
412 input_dev->getkeycode = ir_getkeycode;
413 input_dev->setkeycode = ir_setkeycode;
414 input_set_drvdata(input_dev, rc_tab);
415
416 return 0;
417}
418
419void ir_input_free(struct input_dev *dev)
420{
421 struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
422
423 if (!rc_tab)
424 return;
425
426 IR_dprintk(1, "Freed keycode table\n");
427
428 rc_tab->size = 0;
429 kfree(rc_tab->scan);
430 rc_tab->scan = NULL;
431}
432EXPORT_SYMBOL_GPL(ir_input_free);
433