diff options
-rw-r--r-- | drivers/media/IR/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/IR/ir-nec-decoder.c | 131 | ||||
-rw-r--r-- | drivers/media/IR/ir-raw-event.c | 117 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-input.c | 85 | ||||
-rw-r--r-- | include/media/ir-common.h | 3 | ||||
-rw-r--r-- | include/media/ir-core.h | 32 |
6 files changed, 365 insertions, 5 deletions
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile index 171890e7a41d..18794c7b0ea6 100644 --- a/drivers/media/IR/Makefile +++ b/drivers/media/IR/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | ir-common-objs := ir-functions.o ir-keymaps.o | 1 | ir-common-objs := ir-functions.o ir-keymaps.o |
2 | ir-core-objs := ir-keytable.o ir-sysfs.o | 2 | ir-core-objs := ir-keytable.o ir-sysfs.o ir-raw-event.o ir-nec-decoder.o |
3 | 3 | ||
4 | obj-$(CONFIG_IR_CORE) += ir-core.o | 4 | obj-$(CONFIG_IR_CORE) += ir-core.o |
5 | obj-$(CONFIG_VIDEO_IR) += ir-common.o | 5 | obj-$(CONFIG_VIDEO_IR) += ir-common.o |
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c new file mode 100644 index 000000000000..16360eb4055b --- /dev/null +++ b/drivers/media/IR/ir-nec-decoder.c | |||
@@ -0,0 +1,131 @@ | |||
1 | /* ir-raw-event.c - handle IR Pulse/Space event | ||
2 | * | ||
3 | * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> | ||
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 version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <media/ir-core.h> | ||
16 | |||
17 | /* Start time: 4.5 ms */ | ||
18 | #define MIN_START_TIME 3900000 | ||
19 | #define MAX_START_TIME 5100000 | ||
20 | |||
21 | /* Pulse time: 560 us */ | ||
22 | #define MIN_PULSE_TIME 460000 | ||
23 | #define MAX_PULSE_TIME 660000 | ||
24 | |||
25 | /* Bit 1 space time: 2.25ms-560 us */ | ||
26 | #define MIN_BIT1_TIME 1490000 | ||
27 | #define MAX_BIT1_TIME 1890000 | ||
28 | |||
29 | /* Bit 0 space time: 1.12ms-560 us */ | ||
30 | #define MIN_BIT0_TIME 360000 | ||
31 | #define MAX_BIT0_TIME 760000 | ||
32 | |||
33 | |||
34 | /** Decode NEC pulsecode. This code can take up to 76.5 ms to run. | ||
35 | Unfortunately, using IRQ to decode pulse didn't work, since it uses | ||
36 | a pulse train of 38KHz. This means one pulse on each 52 us | ||
37 | */ | ||
38 | |||
39 | int ir_nec_decode(struct input_dev *input_dev, | ||
40 | struct ir_raw_event *evs, | ||
41 | int len) | ||
42 | { | ||
43 | int i, count = -1; | ||
44 | int ircode = 0, not_code = 0; | ||
45 | #if 0 | ||
46 | /* Needed only after porting the event code to the decoder */ | ||
47 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | ||
48 | #endif | ||
49 | |||
50 | /* Be sure that the first event is an start one and is a pulse */ | ||
51 | for (i = 0; i < len; i++) { | ||
52 | if (evs[i].type & (IR_START_EVENT | IR_PULSE)) | ||
53 | break; | ||
54 | } | ||
55 | i++; /* First event doesn't contain data */ | ||
56 | |||
57 | if (i >= len) | ||
58 | return 0; | ||
59 | |||
60 | /* First space should have 4.5 ms otherwise is not NEC protocol */ | ||
61 | if ((evs[i].delta.tv_nsec < MIN_START_TIME) | | ||
62 | (evs[i].delta.tv_nsec > MAX_START_TIME) | | ||
63 | (evs[i].type != IR_SPACE)) | ||
64 | goto err; | ||
65 | |||
66 | /* | ||
67 | * FIXME: need to implement the repeat sequence | ||
68 | */ | ||
69 | |||
70 | count = 0; | ||
71 | for (i++; i < len; i++) { | ||
72 | int bit; | ||
73 | |||
74 | if ((evs[i].delta.tv_nsec < MIN_PULSE_TIME) | | ||
75 | (evs[i].delta.tv_nsec > MAX_PULSE_TIME) | | ||
76 | (evs[i].type != IR_PULSE)) | ||
77 | goto err; | ||
78 | |||
79 | if (++i >= len) | ||
80 | goto err; | ||
81 | if (evs[i].type != IR_SPACE) | ||
82 | goto err; | ||
83 | |||
84 | if ((evs[i].delta.tv_nsec > MIN_BIT1_TIME) && | ||
85 | (evs[i].delta.tv_nsec < MAX_BIT1_TIME)) | ||
86 | bit = 1; | ||
87 | else if ((evs[i].delta.tv_nsec > MIN_BIT0_TIME) && | ||
88 | (evs[i].delta.tv_nsec < MAX_BIT0_TIME)) | ||
89 | bit = 0; | ||
90 | else | ||
91 | goto err; | ||
92 | |||
93 | if (bit) { | ||
94 | int shift = count; | ||
95 | /* Address first, then command */ | ||
96 | if (shift < 8) { | ||
97 | shift += 8; | ||
98 | ircode |= 1 << shift; | ||
99 | } else if (shift < 16) { | ||
100 | not_code |= 1 << shift; | ||
101 | } else if (shift < 24) { | ||
102 | shift -= 16; | ||
103 | ircode |= 1 << shift; | ||
104 | } else { | ||
105 | shift -= 24; | ||
106 | not_code |= 1 << shift; | ||
107 | } | ||
108 | } | ||
109 | if (++count == 32) | ||
110 | break; | ||
111 | } | ||
112 | |||
113 | /* | ||
114 | * Fixme: may need to accept Extended NEC protocol? | ||
115 | */ | ||
116 | if ((ircode & ~not_code) != ircode) { | ||
117 | IR_dprintk(1, "NEC checksum error: code 0x%04x, not-code 0x%04x\n", | ||
118 | ircode, not_code); | ||
119 | return -EINVAL; | ||
120 | } | ||
121 | |||
122 | IR_dprintk(1, "NEC scancode 0x%04x\n", ircode); | ||
123 | |||
124 | return ircode; | ||
125 | err: | ||
126 | IR_dprintk(1, "NEC decoded failed at bit %d while decoding %luus time\n", | ||
127 | count, (evs[i].delta.tv_nsec + 500) / 1000); | ||
128 | |||
129 | return -EINVAL; | ||
130 | } | ||
131 | EXPORT_SYMBOL_GPL(ir_nec_decode); | ||
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c new file mode 100644 index 000000000000..9c71ac858923 --- /dev/null +++ b/drivers/media/IR/ir-raw-event.c | |||
@@ -0,0 +1,117 @@ | |||
1 | /* ir-raw-event.c - handle IR Pulse/Space event | ||
2 | * | ||
3 | * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> | ||
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 version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <media/ir-core.h> | ||
16 | |||
17 | /* Define the max number of bit transitions per IR keycode */ | ||
18 | #define MAX_IR_EVENT_SIZE 256 | ||
19 | |||
20 | int ir_raw_event_register(struct input_dev *input_dev) | ||
21 | { | ||
22 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | ||
23 | int rc, size; | ||
24 | |||
25 | ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL); | ||
26 | |||
27 | size = sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE * 2; | ||
28 | size = roundup_pow_of_two(size); | ||
29 | |||
30 | rc = kfifo_alloc(&ir->raw->kfifo, size, GFP_KERNEL); | ||
31 | |||
32 | return rc; | ||
33 | } | ||
34 | EXPORT_SYMBOL_GPL(ir_raw_event_register); | ||
35 | |||
36 | void ir_raw_event_unregister(struct input_dev *input_dev) | ||
37 | { | ||
38 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | ||
39 | |||
40 | if (!ir->raw) | ||
41 | return; | ||
42 | |||
43 | kfifo_free(&ir->raw->kfifo); | ||
44 | kfree(ir->raw); | ||
45 | ir->raw = NULL; | ||
46 | } | ||
47 | EXPORT_SYMBOL_GPL(ir_raw_event_unregister); | ||
48 | |||
49 | int ir_raw_event_store(struct input_dev *input_dev, enum raw_event_type type) | ||
50 | { | ||
51 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | ||
52 | struct timespec ts; | ||
53 | struct ir_raw_event event; | ||
54 | int rc; | ||
55 | |||
56 | if (!ir->raw) | ||
57 | return -EINVAL; | ||
58 | |||
59 | event.type = type; | ||
60 | event.delta.tv_sec = 0; | ||
61 | event.delta.tv_nsec = 0; | ||
62 | |||
63 | ktime_get_ts(&ts); | ||
64 | |||
65 | if (timespec_equal(&ir->raw->last_event, &event.delta)) | ||
66 | event.type |= IR_START_EVENT; | ||
67 | else | ||
68 | event.delta = timespec_sub(ts, ir->raw->last_event); | ||
69 | |||
70 | memcpy(&ir->raw->last_event, &ts, sizeof(ts)); | ||
71 | |||
72 | if (event.delta.tv_sec) { | ||
73 | event.type |= IR_START_EVENT; | ||
74 | event.delta.tv_sec = 0; | ||
75 | event.delta.tv_nsec = 0; | ||
76 | } | ||
77 | |||
78 | kfifo_in(&ir->raw->kfifo, &event, sizeof(event)); | ||
79 | |||
80 | return rc; | ||
81 | } | ||
82 | EXPORT_SYMBOL_GPL(ir_raw_event_store); | ||
83 | |||
84 | int ir_raw_event_handle(struct input_dev *input_dev) | ||
85 | { | ||
86 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | ||
87 | int rc; | ||
88 | struct ir_raw_event *evs; | ||
89 | int len, i; | ||
90 | |||
91 | /* | ||
92 | * Store the events into a temporary buffer. This allows calling more than | ||
93 | * one decoder to deal with the received data | ||
94 | */ | ||
95 | len = kfifo_len(&ir->raw->kfifo) / sizeof(*evs); | ||
96 | if (!len) | ||
97 | return 0; | ||
98 | evs = kmalloc(len * sizeof(*evs), GFP_ATOMIC); | ||
99 | |||
100 | for (i = 0; i < len; i++) { | ||
101 | rc = kfifo_out(&ir->raw->kfifo, &evs[i], sizeof(*evs)); | ||
102 | if (rc != sizeof(*evs)) { | ||
103 | IR_dprintk(1, "overflow error: received %d instead of %zd\n", | ||
104 | rc, sizeof(*evs)); | ||
105 | return -EINVAL; | ||
106 | } | ||
107 | IR_dprintk(2, "event type %d, time before event: %07luus\n", | ||
108 | evs[i].type, (evs[i].delta.tv_nsec + 500) / 1000); | ||
109 | } | ||
110 | |||
111 | rc = ir_nec_decode(input_dev, evs, len); | ||
112 | |||
113 | kfree(evs); | ||
114 | |||
115 | return rc; | ||
116 | } | ||
117 | EXPORT_SYMBOL_GPL(ir_raw_event_handle); | ||
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 7e6f125e4e31..1a7cf9c8c68c 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -68,6 +68,7 @@ MODULE_PARM_DESC(disable_other_ir, "disable full codes of " | |||
68 | /* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */ | 68 | /* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */ |
69 | static int saa7134_rc5_irq(struct saa7134_dev *dev); | 69 | static int saa7134_rc5_irq(struct saa7134_dev *dev); |
70 | static int saa7134_nec_irq(struct saa7134_dev *dev); | 70 | static int saa7134_nec_irq(struct saa7134_dev *dev); |
71 | static int saa7134_raw_decode_irq(struct saa7134_dev *dev); | ||
71 | static void nec_task(unsigned long data); | 72 | static void nec_task(unsigned long data); |
72 | static void saa7134_nec_timer(unsigned long data); | 73 | static void saa7134_nec_timer(unsigned long data); |
73 | 74 | ||
@@ -403,10 +404,12 @@ void saa7134_input_irq(struct saa7134_dev *dev) | |||
403 | 404 | ||
404 | if (ir->nec_gpio) { | 405 | if (ir->nec_gpio) { |
405 | saa7134_nec_irq(dev); | 406 | saa7134_nec_irq(dev); |
406 | } else if (!ir->polling && !ir->rc5_gpio) { | 407 | } else if (!ir->polling && !ir->rc5_gpio && !ir->raw_decode) { |
407 | build_key(dev); | 408 | build_key(dev); |
408 | } else if (ir->rc5_gpio) { | 409 | } else if (ir->rc5_gpio) { |
409 | saa7134_rc5_irq(dev); | 410 | saa7134_rc5_irq(dev); |
411 | } else if (ir->raw_decode) { | ||
412 | saa7134_raw_decode_irq(dev); | ||
410 | } | 413 | } |
411 | } | 414 | } |
412 | 415 | ||
@@ -419,6 +422,23 @@ static void saa7134_input_timer(unsigned long data) | |||
419 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); | 422 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); |
420 | } | 423 | } |
421 | 424 | ||
425 | void ir_raw_decode_timer_end(unsigned long data) | ||
426 | { | ||
427 | struct saa7134_dev *dev = (struct saa7134_dev *)data; | ||
428 | struct card_ir *ir = dev->remote; | ||
429 | int rc; | ||
430 | |||
431 | /* | ||
432 | * FIXME: the IR key handling code should be called by the decoder, | ||
433 | * after implementing the repeat mode | ||
434 | */ | ||
435 | rc = ir_raw_event_handle(dev->remote->dev); | ||
436 | if (rc >= 0) { | ||
437 | ir_input_keydown(ir->dev, &ir->ir, rc); | ||
438 | ir_input_nokey(ir->dev, &ir->ir); | ||
439 | } | ||
440 | } | ||
441 | |||
422 | void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) | 442 | void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) |
423 | { | 443 | { |
424 | if (ir->running) | 444 | if (ir->running) |
@@ -447,6 +467,11 @@ void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) | |||
447 | setup_timer(&ir->timer_keyup, saa7134_nec_timer, | 467 | setup_timer(&ir->timer_keyup, saa7134_nec_timer, |
448 | (unsigned long)dev); | 468 | (unsigned long)dev); |
449 | tasklet_init(&ir->tlet, nec_task, (unsigned long)dev); | 469 | tasklet_init(&ir->tlet, nec_task, (unsigned long)dev); |
470 | } else if (ir->raw_decode) { | ||
471 | /* set timer_end for code completion */ | ||
472 | init_timer(&ir->timer_end); | ||
473 | ir->timer_end.function = ir_raw_decode_timer_end; | ||
474 | ir->timer_end.data = (unsigned long)dev; | ||
450 | } | 475 | } |
451 | } | 476 | } |
452 | 477 | ||
@@ -462,6 +487,9 @@ void saa7134_ir_stop(struct saa7134_dev *dev) | |||
462 | del_timer_sync(&ir->timer_end); | 487 | del_timer_sync(&ir->timer_end); |
463 | else if (ir->nec_gpio) | 488 | else if (ir->nec_gpio) |
464 | tasklet_kill(&ir->tlet); | 489 | tasklet_kill(&ir->tlet); |
490 | else if (ir->raw_decode) | ||
491 | del_timer_sync(&ir->timer_end); | ||
492 | |||
465 | ir->running = 0; | 493 | ir->running = 0; |
466 | } | 494 | } |
467 | 495 | ||
@@ -509,6 +537,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
509 | int polling = 0; | 537 | int polling = 0; |
510 | int rc5_gpio = 0; | 538 | int rc5_gpio = 0; |
511 | int nec_gpio = 0; | 539 | int nec_gpio = 0; |
540 | int raw_decode = 0; | ||
512 | u64 ir_type = IR_TYPE_OTHER; | 541 | u64 ir_type = IR_TYPE_OTHER; |
513 | int err; | 542 | int err; |
514 | 543 | ||
@@ -574,7 +603,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
574 | ir_codes = &ir_codes_avermedia_m135a_rm_jx_table; | 603 | ir_codes = &ir_codes_avermedia_m135a_rm_jx_table; |
575 | mask_keydown = 0x0040000; | 604 | mask_keydown = 0x0040000; |
576 | mask_keycode = 0xffff; | 605 | mask_keycode = 0xffff; |
577 | nec_gpio = 1; | 606 | raw_decode = 1; |
578 | break; | 607 | break; |
579 | case SAA7134_BOARD_AVERMEDIA_777: | 608 | case SAA7134_BOARD_AVERMEDIA_777: |
580 | case SAA7134_BOARD_AVERMEDIA_A16AR: | 609 | case SAA7134_BOARD_AVERMEDIA_A16AR: |
@@ -755,6 +784,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
755 | ir->polling = polling; | 784 | ir->polling = polling; |
756 | ir->rc5_gpio = rc5_gpio; | 785 | ir->rc5_gpio = rc5_gpio; |
757 | ir->nec_gpio = nec_gpio; | 786 | ir->nec_gpio = nec_gpio; |
787 | ir->raw_decode = raw_decode; | ||
758 | 788 | ||
759 | /* init input device */ | 789 | /* init input device */ |
760 | snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", | 790 | snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", |
@@ -762,7 +792,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
762 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", | 792 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", |
763 | pci_name(dev->pci)); | 793 | pci_name(dev->pci)); |
764 | 794 | ||
765 | if (ir_codes->ir_type != IR_TYPE_OTHER) { | 795 | if (ir_codes->ir_type != IR_TYPE_OTHER && !raw_decode) { |
766 | ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; | 796 | ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; |
767 | ir->props.priv = dev; | 797 | ir->props.priv = dev; |
768 | ir->props.change_protocol = saa7134_ir_change_protocol; | 798 | ir->props.change_protocol = saa7134_ir_change_protocol; |
@@ -790,6 +820,11 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
790 | err = ir_input_register(ir->dev, ir_codes, &ir->props, MODULE_NAME); | 820 | err = ir_input_register(ir->dev, ir_codes, &ir->props, MODULE_NAME); |
791 | if (err) | 821 | if (err) |
792 | goto err_out_stop; | 822 | goto err_out_stop; |
823 | if (ir_codes->ir_type != IR_TYPE_OTHER) { | ||
824 | err = ir_raw_event_register(ir->dev); | ||
825 | if (err) | ||
826 | goto err_out_stop; | ||
827 | } | ||
793 | 828 | ||
794 | saa7134_ir_start(dev, ir); | 829 | saa7134_ir_start(dev, ir); |
795 | 830 | ||
@@ -813,6 +848,7 @@ void saa7134_input_fini(struct saa7134_dev *dev) | |||
813 | return; | 848 | return; |
814 | 849 | ||
815 | saa7134_ir_stop(dev); | 850 | saa7134_ir_stop(dev); |
851 | ir_raw_event_unregister(dev->remote->dev); | ||
816 | ir_input_unregister(dev->remote->dev); | 852 | ir_input_unregister(dev->remote->dev); |
817 | kfree(dev->remote); | 853 | kfree(dev->remote); |
818 | dev->remote = NULL; | 854 | dev->remote = NULL; |
@@ -919,6 +955,48 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) | |||
919 | i2c_new_device(&dev->i2c_adap, &info); | 955 | i2c_new_device(&dev->i2c_adap, &info); |
920 | } | 956 | } |
921 | 957 | ||
958 | static int saa7134_raw_decode_irq(struct saa7134_dev *dev) | ||
959 | { | ||
960 | struct card_ir *ir = dev->remote; | ||
961 | unsigned long timeout; | ||
962 | int count, pulse, oldpulse; | ||
963 | |||
964 | /* Disable IR IRQ line */ | ||
965 | saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18); | ||
966 | |||
967 | /* Generate initial event */ | ||
968 | saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
969 | saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
970 | pulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown; | ||
971 | ir_raw_event_store(dev->remote->dev, pulse? IR_PULSE : IR_SPACE); | ||
972 | |||
973 | #if 1 | ||
974 | /* Wait up to 10 ms for event change */ | ||
975 | oldpulse = pulse; | ||
976 | for (count = 0; count < 1000; count++) { | ||
977 | udelay(10); | ||
978 | /* rising SAA7134_GPIO_GPRESCAN reads the status */ | ||
979 | saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
980 | saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
981 | pulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) | ||
982 | & ir->mask_keydown; | ||
983 | if (pulse != oldpulse) | ||
984 | break; | ||
985 | } | ||
986 | |||
987 | /* Store final event */ | ||
988 | ir_raw_event_store(dev->remote->dev, pulse? IR_PULSE : IR_SPACE); | ||
989 | #endif | ||
990 | /* Wait 15 ms before deciding to do something else */ | ||
991 | timeout = jiffies + jiffies_to_msecs(15); | ||
992 | mod_timer(&ir->timer_end, timeout); | ||
993 | |||
994 | /* Enable IR IRQ line */ | ||
995 | saa_setl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18); | ||
996 | |||
997 | return 1; | ||
998 | } | ||
999 | |||
922 | static int saa7134_rc5_irq(struct saa7134_dev *dev) | 1000 | static int saa7134_rc5_irq(struct saa7134_dev *dev) |
923 | { | 1001 | { |
924 | struct card_ir *ir = dev->remote; | 1002 | struct card_ir *ir = dev->remote; |
@@ -961,7 +1039,6 @@ static int saa7134_rc5_irq(struct saa7134_dev *dev) | |||
961 | return 1; | 1039 | return 1; |
962 | } | 1040 | } |
963 | 1041 | ||
964 | |||
965 | /* On NEC protocol, One has 2.25 ms, and zero has 1.125 ms | 1042 | /* On NEC protocol, One has 2.25 ms, and zero has 1.125 ms |
966 | The first pulse (start) has 9 + 4.5 ms | 1043 | The first pulse (start) has 9 + 4.5 ms |
967 | */ | 1044 | */ |
diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 41469b79ad11..87f2ec78deb8 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h | |||
@@ -82,6 +82,9 @@ struct card_ir { | |||
82 | /* NEC decoding */ | 82 | /* NEC decoding */ |
83 | u32 nec_gpio; | 83 | u32 nec_gpio; |
84 | struct tasklet_struct tlet; | 84 | struct tasklet_struct tlet; |
85 | |||
86 | /* IR core raw decoding */ | ||
87 | u32 raw_decode; | ||
85 | }; | 88 | }; |
86 | 89 | ||
87 | /* Routines from ir-functions.c */ | 90 | /* Routines from ir-functions.c */ |
diff --git a/include/media/ir-core.h b/include/media/ir-core.h index 1eae72d518e0..369969d90779 100644 --- a/include/media/ir-core.h +++ b/include/media/ir-core.h | |||
@@ -16,6 +16,8 @@ | |||
16 | 16 | ||
17 | #include <linux/input.h> | 17 | #include <linux/input.h> |
18 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
19 | #include <linux/kfifo.h> | ||
20 | #include <linux/time.h> | ||
19 | 21 | ||
20 | extern int ir_core_debug; | 22 | extern int ir_core_debug; |
21 | #define IR_dprintk(level, fmt, arg...) if (ir_core_debug >= level) \ | 23 | #define IR_dprintk(level, fmt, arg...) if (ir_core_debug >= level) \ |
@@ -27,6 +29,13 @@ extern int ir_core_debug; | |||
27 | #define IR_TYPE_NEC (1 << 2) | 29 | #define IR_TYPE_NEC (1 << 2) |
28 | #define IR_TYPE_OTHER (((u64)1) << 63l) | 30 | #define IR_TYPE_OTHER (((u64)1) << 63l) |
29 | 31 | ||
32 | enum raw_event_type { | ||
33 | IR_SPACE = (1 << 0), | ||
34 | IR_PULSE = (1 << 1), | ||
35 | IR_START_EVENT = (1 << 2), | ||
36 | IR_STOP_EVENT = (1 << 3), | ||
37 | }; | ||
38 | |||
30 | struct ir_scancode { | 39 | struct ir_scancode { |
31 | u16 scancode; | 40 | u16 scancode; |
32 | u32 keycode; | 41 | u32 keycode; |
@@ -46,6 +55,15 @@ struct ir_dev_props { | |||
46 | int (*change_protocol)(void *priv, u64 ir_type); | 55 | int (*change_protocol)(void *priv, u64 ir_type); |
47 | }; | 56 | }; |
48 | 57 | ||
58 | struct ir_raw_event { | ||
59 | struct timespec delta; /* Time spent before event */ | ||
60 | enum raw_event_type type; /* event type */ | ||
61 | }; | ||
62 | |||
63 | struct ir_raw_event_ctrl { | ||
64 | struct kfifo kfifo; /* fifo for the pulse/space events */ | ||
65 | struct timespec last_event; /* when last event occurred */ | ||
66 | }; | ||
49 | 67 | ||
50 | struct ir_input_dev { | 68 | struct ir_input_dev { |
51 | struct device dev; /* device */ | 69 | struct device dev; /* device */ |
@@ -53,7 +71,9 @@ struct ir_input_dev { | |||
53 | struct ir_scancode_table rc_tab; /* scan/key table */ | 71 | struct ir_scancode_table rc_tab; /* scan/key table */ |
54 | unsigned long devno; /* device number */ | 72 | unsigned long devno; /* device number */ |
55 | const struct ir_dev_props *props; /* Device properties */ | 73 | const struct ir_dev_props *props; /* Device properties */ |
74 | struct ir_raw_event_ctrl *raw; /* for raw pulse/space events */ | ||
56 | }; | 75 | }; |
76 | |||
57 | #define to_ir_input_dev(_attr) container_of(_attr, struct ir_input_dev, attr) | 77 | #define to_ir_input_dev(_attr) container_of(_attr, struct ir_input_dev, attr) |
58 | 78 | ||
59 | /* Routines from ir-keytable.c */ | 79 | /* Routines from ir-keytable.c */ |
@@ -72,4 +92,16 @@ void ir_input_unregister(struct input_dev *input_dev); | |||
72 | int ir_register_class(struct input_dev *input_dev); | 92 | int ir_register_class(struct input_dev *input_dev); |
73 | void ir_unregister_class(struct input_dev *input_dev); | 93 | void ir_unregister_class(struct input_dev *input_dev); |
74 | 94 | ||
95 | /* Routines from ir-raw-event.c */ | ||
96 | int ir_raw_event_register(struct input_dev *input_dev); | ||
97 | void ir_raw_event_unregister(struct input_dev *input_dev); | ||
98 | int ir_raw_event_store(struct input_dev *input_dev, enum raw_event_type type); | ||
99 | int ir_raw_event_handle(struct input_dev *input_dev); | ||
100 | |||
101 | /* from ir-nec-decoder.c */ | ||
102 | int ir_nec_decode(struct input_dev *input_dev, | ||
103 | struct ir_raw_event *evs, | ||
104 | int len); | ||
105 | |||
106 | |||
75 | #endif | 107 | #endif |