aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common/ir-common.c
diff options
context:
space:
mode:
authorRicardo Cerqueira <v4l@cerqueira.org>2006-01-23 06:42:06 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-01-23 06:42:06 -0500
commit4c0f631e14b849782259519c749414b1f1ddbfa8 (patch)
tree7976453534a7785899a71bc6cd574e5c7ebc3a95 /drivers/media/common/ir-common.c
parentbf47e4e43e4dcf88fef61b1b4139ce2da20e1f73 (diff)
V4L/DVB (3393): Move all IR keymaps to ir-common module
- All the keymaps have the same structure, and can be shared between different chips, so it makes no sense having them scattered between the input files. This aggregates them all at ir-common module. - Added new Hauppauge remote (Hauppauge grey), contributed by J.O. Aho <trizt@iname.com> (with some small changes) Changed KEY_KPx (keypad numerals) references to KEY_x, to avoid problems when NumLock is off (suggested by Peter Missel <peter.missel@onlinehome.de>) - Some cleanups at IR code Signed-off-by: Ricardo Cerqueira <v4l@cerqueira.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/common/ir-common.c')
-rw-r--r--drivers/media/common/ir-common.c519
1 files changed, 0 insertions, 519 deletions
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
deleted file mode 100644
index 97fa3fc571c4..000000000000
--- a/drivers/media/common/ir-common.c
+++ /dev/null
@@ -1,519 +0,0 @@
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/moduleparam.h>
25#include <linux/string.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
37static int debug = 0; /* debug level (0,1,2) */
38module_param(debug, int, 0644);
39
40#define dprintk(level, fmt, arg...) if (debug >= level) \
41 printk(KERN_DEBUG fmt , ## arg)
42
43/* -------------------------------------------------------------------------- */
44
45/* generic RC5 keytable */
46/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
47/* used by old (black) Hauppauge remotes */
48IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = {
49 /* Keys 0 to 9 */
50 [ 0x00 ] = KEY_KP0,
51 [ 0x01 ] = KEY_KP1,
52 [ 0x02 ] = KEY_KP2,
53 [ 0x03 ] = KEY_KP3,
54 [ 0x04 ] = KEY_KP4,
55 [ 0x05 ] = KEY_KP5,
56 [ 0x06 ] = KEY_KP6,
57 [ 0x07 ] = KEY_KP7,
58 [ 0x08 ] = KEY_KP8,
59 [ 0x09 ] = KEY_KP9,
60
61 [ 0x0b ] = KEY_CHANNEL, /* channel / program (japan: 11) */
62 [ 0x0c ] = KEY_POWER, /* standby */
63 [ 0x0d ] = KEY_MUTE, /* mute / demute */
64 [ 0x0f ] = KEY_TV, /* display */
65 [ 0x10 ] = KEY_VOLUMEUP,
66 [ 0x11 ] = KEY_VOLUMEDOWN,
67 [ 0x12 ] = KEY_BRIGHTNESSUP,
68 [ 0x13 ] = KEY_BRIGHTNESSDOWN,
69 [ 0x1e ] = KEY_SEARCH, /* search + */
70 [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */
71 [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */
72 [ 0x22 ] = KEY_CHANNEL, /* alt / channel */
73 [ 0x23 ] = KEY_LANGUAGE, /* 1st / 2nd language */
74 [ 0x26 ] = KEY_SLEEP, /* sleeptimer */
75 [ 0x2e ] = KEY_MENU, /* 2nd controls (USA: menu) */
76 [ 0x30 ] = KEY_PAUSE,
77 [ 0x32 ] = KEY_REWIND,
78 [ 0x33 ] = KEY_GOTO,
79 [ 0x35 ] = KEY_PLAY,
80 [ 0x36 ] = KEY_STOP,
81 [ 0x37 ] = KEY_RECORD, /* recording */
82 [ 0x3c ] = KEY_TEXT, /* teletext submode (Japan: 12) */
83 [ 0x3d ] = KEY_SUSPEND, /* system standby */
84
85};
86EXPORT_SYMBOL_GPL(ir_codes_rc5_tv);
87
88/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
89IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
90 /* Keys 0 to 9 */
91 [ 18 ] = KEY_KP0,
92 [ 5 ] = KEY_KP1,
93 [ 6 ] = KEY_KP2,
94 [ 7 ] = KEY_KP3,
95 [ 9 ] = KEY_KP4,
96 [ 10 ] = KEY_KP5,
97 [ 11 ] = KEY_KP6,
98 [ 13 ] = KEY_KP7,
99 [ 14 ] = KEY_KP8,
100 [ 15 ] = KEY_KP9,
101
102 [ 0 ] = KEY_POWER,
103 [ 2 ] = KEY_TUNER, /* TV/FM */
104 [ 30 ] = KEY_VIDEO,
105 [ 4 ] = KEY_VOLUMEUP,
106 [ 8 ] = KEY_VOLUMEDOWN,
107 [ 12 ] = KEY_CHANNELUP,
108 [ 16 ] = KEY_CHANNELDOWN,
109 [ 3 ] = KEY_ZOOM, /* fullscreen */
110 [ 31 ] = KEY_SUBTITLE, /* closed caption/teletext */
111 [ 32 ] = KEY_SLEEP,
112 [ 20 ] = KEY_MUTE,
113 [ 43 ] = KEY_RED,
114 [ 44 ] = KEY_GREEN,
115 [ 45 ] = KEY_YELLOW,
116 [ 46 ] = KEY_BLUE,
117 [ 24 ] = KEY_KPPLUS, /* fine tune + */
118 [ 25 ] = KEY_KPMINUS, /* fine tune - */
119 [ 33 ] = KEY_KPDOT,
120 [ 19 ] = KEY_KPENTER,
121 [ 34 ] = KEY_BACK,
122 [ 35 ] = KEY_PLAYPAUSE,
123 [ 36 ] = KEY_NEXT,
124 [ 38 ] = KEY_STOP,
125 [ 39 ] = KEY_RECORD
126};
127EXPORT_SYMBOL_GPL(ir_codes_winfast);
128
129IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
130 [ 0x59 ] = KEY_MUTE,
131 [ 0x4a ] = KEY_POWER,
132
133 [ 0x18 ] = KEY_TEXT,
134 [ 0x26 ] = KEY_TV,
135 [ 0x3d ] = KEY_PRINT,
136
137 [ 0x48 ] = KEY_RED,
138 [ 0x04 ] = KEY_GREEN,
139 [ 0x11 ] = KEY_YELLOW,
140 [ 0x00 ] = KEY_BLUE,
141
142 [ 0x2d ] = KEY_VOLUMEUP,
143 [ 0x1e ] = KEY_VOLUMEDOWN,
144
145 [ 0x49 ] = KEY_MENU,
146
147 [ 0x16 ] = KEY_CHANNELUP,
148 [ 0x17 ] = KEY_CHANNELDOWN,
149
150 [ 0x20 ] = KEY_UP,
151 [ 0x21 ] = KEY_DOWN,
152 [ 0x22 ] = KEY_LEFT,
153 [ 0x23 ] = KEY_RIGHT,
154 [ 0x0d ] = KEY_SELECT,
155
156
157
158 [ 0x08 ] = KEY_BACK,
159 [ 0x07 ] = KEY_REFRESH,
160
161 [ 0x2f ] = KEY_ZOOM,
162 [ 0x29 ] = KEY_RECORD,
163
164 [ 0x4b ] = KEY_PAUSE,
165 [ 0x4d ] = KEY_REWIND,
166 [ 0x2e ] = KEY_PLAY,
167 [ 0x4e ] = KEY_FORWARD,
168 [ 0x53 ] = KEY_PREVIOUS,
169 [ 0x4c ] = KEY_STOP,
170 [ 0x54 ] = KEY_NEXT,
171
172 [ 0x69 ] = KEY_KP0,
173 [ 0x6a ] = KEY_KP1,
174 [ 0x6b ] = KEY_KP2,
175 [ 0x6c ] = KEY_KP3,
176 [ 0x6d ] = KEY_KP4,
177 [ 0x6e ] = KEY_KP5,
178 [ 0x6f ] = KEY_KP6,
179 [ 0x70 ] = KEY_KP7,
180 [ 0x71 ] = KEY_KP8,
181 [ 0x72 ] = KEY_KP9,
182
183 [ 0x74 ] = KEY_CHANNEL,
184 [ 0x0a ] = KEY_BACKSPACE,
185};
186
187EXPORT_SYMBOL_GPL(ir_codes_pinnacle);
188
189/* empty keytable, can be used as placeholder for not-yet created keytables */
190IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = {
191 [ 42 ] = KEY_COFFEE,
192};
193EXPORT_SYMBOL_GPL(ir_codes_empty);
194
195/* Hauppauge: the newer, gray remotes (seems there are multiple
196 * slightly different versions), shipped with cx88+ivtv cards.
197 * almost rc5 coding, but some non-standard keys */
198IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
199 /* Keys 0 to 9 */
200 [ 0x00 ] = KEY_KP0,
201 [ 0x01 ] = KEY_KP1,
202 [ 0x02 ] = KEY_KP2,
203 [ 0x03 ] = KEY_KP3,
204 [ 0x04 ] = KEY_KP4,
205 [ 0x05 ] = KEY_KP5,
206 [ 0x06 ] = KEY_KP6,
207 [ 0x07 ] = KEY_KP7,
208 [ 0x08 ] = KEY_KP8,
209 [ 0x09 ] = KEY_KP9,
210
211 [ 0x0a ] = KEY_TEXT, /* keypad asterisk as well */
212 [ 0x0b ] = KEY_RED, /* red button */
213 [ 0x0c ] = KEY_RADIO,
214 [ 0x0d ] = KEY_MENU,
215 [ 0x0e ] = KEY_SUBTITLE, /* also the # key */
216 [ 0x0f ] = KEY_MUTE,
217 [ 0x10 ] = KEY_VOLUMEUP,
218 [ 0x11 ] = KEY_VOLUMEDOWN,
219 [ 0x12 ] = KEY_PREVIOUS, /* previous channel */
220 [ 0x14 ] = KEY_UP,
221 [ 0x15 ] = KEY_DOWN,
222 [ 0x16 ] = KEY_LEFT,
223 [ 0x17 ] = KEY_RIGHT,
224 [ 0x18 ] = KEY_VIDEO, /* Videos */
225 [ 0x19 ] = KEY_AUDIO, /* Music */
226 /* 0x1a: Pictures - presume this means
227 "Multimedia Home Platform" -
228 no "PICTURES" key in input.h
229 */
230 [ 0x1a ] = KEY_MHP,
231
232 [ 0x1b ] = KEY_EPG, /* Guide */
233 [ 0x1c ] = KEY_TV,
234 [ 0x1e ] = KEY_NEXTSONG, /* skip >| */
235 [ 0x1f ] = KEY_EXIT, /* back/exit */
236 [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */
237 [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */
238 [ 0x22 ] = KEY_CHANNEL, /* source (old black remote) */
239 [ 0x24 ] = KEY_PREVIOUSSONG, /* replay |< */
240 [ 0x25 ] = KEY_ENTER, /* OK */
241 [ 0x26 ] = KEY_SLEEP, /* minimize (old black remote) */
242 [ 0x29 ] = KEY_BLUE, /* blue key */
243 [ 0x2e ] = KEY_GREEN, /* green button */
244 [ 0x30 ] = KEY_PAUSE, /* pause */
245 [ 0x32 ] = KEY_REWIND, /* backward << */
246 [ 0x34 ] = KEY_FASTFORWARD, /* forward >> */
247 [ 0x35 ] = KEY_PLAY,
248 [ 0x36 ] = KEY_STOP,
249 [ 0x37 ] = KEY_RECORD, /* recording */
250 [ 0x38 ] = KEY_YELLOW, /* yellow key */
251 [ 0x3b ] = KEY_SELECT, /* top right button */
252 [ 0x3c ] = KEY_ZOOM, /* full */
253 [ 0x3d ] = KEY_POWER, /* system power (green button) */
254};
255EXPORT_SYMBOL(ir_codes_hauppauge_new);
256
257IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
258 [ 2 ] = KEY_KP0,
259 [ 1 ] = KEY_KP1,
260 [ 11 ] = KEY_KP2,
261 [ 27 ] = KEY_KP3,
262 [ 5 ] = KEY_KP4,
263 [ 9 ] = KEY_KP5,
264 [ 21 ] = KEY_KP6,
265 [ 6 ] = KEY_KP7,
266 [ 10 ] = KEY_KP8,
267 [ 18 ] = KEY_KP9,
268
269 [ 3 ] = KEY_TUNER, /* TV/FM */
270 [ 7 ] = KEY_SEARCH, /* scan */
271 [ 28 ] = KEY_ZOOM, /* full screen */
272 [ 30 ] = KEY_POWER,
273 [ 23 ] = KEY_VOLUMEDOWN,
274 [ 31 ] = KEY_VOLUMEUP,
275 [ 20 ] = KEY_CHANNELDOWN,
276 [ 22 ] = KEY_CHANNELUP,
277 [ 24 ] = KEY_MUTE,
278
279 [ 0 ] = KEY_LIST, /* source */
280 [ 19 ] = KEY_INFO, /* loop */
281 [ 16 ] = KEY_LAST, /* +100 */
282 [ 13 ] = KEY_CLEAR, /* reset */
283 [ 12 ] = BTN_RIGHT, /* fun++ */
284 [ 4 ] = BTN_LEFT, /* fun-- */
285 [ 14 ] = KEY_GOTO, /* function */
286 [ 15 ] = KEY_STOP, /* freeze */
287};
288EXPORT_SYMBOL(ir_codes_pixelview);
289
290/* -------------------------------------------------------------------------- */
291
292static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
293{
294 if (KEY_RESERVED == ir->keycode) {
295 printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n",
296 dev->name,ir->ir_key,ir->ir_raw,ir->keypressed);
297 return;
298 }
299 dprintk(1,"%s: key event code=%d down=%d\n",
300 dev->name,ir->keycode,ir->keypressed);
301 input_report_key(dev,ir->keycode,ir->keypressed);
302 input_sync(dev);
303}
304
305/* -------------------------------------------------------------------------- */
306
307void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
308 int ir_type, IR_KEYTAB_TYPE *ir_codes)
309{
310 int i;
311
312 ir->ir_type = ir_type;
313 if (ir_codes)
314 memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes));
315
316
317 dev->keycode = ir->ir_codes;
318 dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
319 dev->keycodemax = IR_KEYTAB_SIZE;
320 for (i = 0; i < IR_KEYTAB_SIZE; i++)
321 set_bit(ir->ir_codes[i], dev->keybit);
322 clear_bit(0, dev->keybit);
323
324 set_bit(EV_KEY, dev->evbit);
325 if (repeat)
326 set_bit(EV_REP, dev->evbit);
327}
328
329void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
330{
331 if (ir->keypressed) {
332 ir->keypressed = 0;
333 ir_input_key_event(dev,ir);
334 }
335}
336
337void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
338 u32 ir_key, u32 ir_raw)
339{
340 u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key);
341
342 if (ir->keypressed && ir->keycode != keycode) {
343 ir->keypressed = 0;
344 ir_input_key_event(dev,ir);
345 }
346 if (!ir->keypressed) {
347 ir->ir_key = ir_key;
348 ir->ir_raw = ir_raw;
349 ir->keycode = keycode;
350 ir->keypressed = 1;
351 ir_input_key_event(dev,ir);
352 }
353}
354
355/* -------------------------------------------------------------------------- */
356
357u32 ir_extract_bits(u32 data, u32 mask)
358{
359 int mbit, vbit;
360 u32 value;
361
362 value = 0;
363 vbit = 0;
364 for (mbit = 0; mbit < 32; mbit++) {
365 if (!(mask & ((u32)1 << mbit)))
366 continue;
367 if (data & ((u32)1 << mbit))
368 value |= (1 << vbit);
369 vbit++;
370 }
371 return value;
372}
373
374static int inline getbit(u32 *samples, int bit)
375{
376 return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0;
377}
378
379/* sump raw samples for visual debugging ;) */
380int ir_dump_samples(u32 *samples, int count)
381{
382 int i, bit, start;
383
384 printk(KERN_DEBUG "ir samples: ");
385 start = 0;
386 for (i = 0; i < count * 32; i++) {
387 bit = getbit(samples,i);
388 if (bit)
389 start = 1;
390 if (0 == start)
391 continue;
392 printk("%s", bit ? "#" : "_");
393 }
394 printk("\n");
395 return 0;
396}
397
398/* decode raw samples, pulse distance coding used by NEC remotes */
399int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
400{
401 int i,last,bit,len;
402 u32 curBit;
403 u32 value;
404
405 /* find start burst */
406 for (i = len = 0; i < count * 32; i++) {
407 bit = getbit(samples,i);
408 if (bit) {
409 len++;
410 } else {
411 if (len >= 29)
412 break;
413 len = 0;
414 }
415 }
416
417 /* start burst to short */
418 if (len < 29)
419 return 0xffffffff;
420
421 /* find start silence */
422 for (len = 0; i < count * 32; i++) {
423 bit = getbit(samples,i);
424 if (bit) {
425 break;
426 } else {
427 len++;
428 }
429 }
430
431 /* silence to short */
432 if (len < 7)
433 return 0xffffffff;
434
435 /* go decoding */
436 len = 0;
437 last = 1;
438 value = 0; curBit = 1;
439 for (; i < count * 32; i++) {
440 bit = getbit(samples,i);
441 if (last) {
442 if(bit) {
443 continue;
444 } else {
445 len = 1;
446 }
447 } else {
448 if (bit) {
449 if (len > (low + high) /2)
450 value |= curBit;
451 curBit <<= 1;
452 if (curBit == 1)
453 break;
454 } else {
455 len++;
456 }
457 }
458 last = bit;
459 }
460
461 return value;
462}
463
464/* decode raw samples, biphase coding, used by rc5 for example */
465int ir_decode_biphase(u32 *samples, int count, int low, int high)
466{
467 int i,last,bit,len,flips;
468 u32 value;
469
470 /* find start bit (1) */
471 for (i = 0; i < 32; i++) {
472 bit = getbit(samples,i);
473 if (bit)
474 break;
475 }
476
477 /* go decoding */
478 len = 0;
479 flips = 0;
480 value = 1;
481 for (; i < count * 32; i++) {
482 if (len > high)
483 break;
484 if (flips > 1)
485 break;
486 last = bit;
487 bit = getbit(samples,i);
488 if (last == bit) {
489 len++;
490 continue;
491 }
492 if (len < low) {
493 len++;
494 flips++;
495 continue;
496 }
497 value <<= 1;
498 value |= bit;
499 flips = 0;
500 len = 1;
501 }
502 return value;
503}
504
505EXPORT_SYMBOL_GPL(ir_input_init);
506EXPORT_SYMBOL_GPL(ir_input_nokey);
507EXPORT_SYMBOL_GPL(ir_input_keydown);
508
509EXPORT_SYMBOL_GPL(ir_extract_bits);
510EXPORT_SYMBOL_GPL(ir_dump_samples);
511EXPORT_SYMBOL_GPL(ir_decode_biphase);
512EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
513
514/*
515 * Local variables:
516 * c-basic-offset: 8
517 * End:
518 */
519