diff options
author | James Hogan <james.hogan@imgtec.com> | 2014-02-28 18:28:56 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-03-11 14:46:57 -0400 |
commit | 635abb7054f204e036bc6afe41b1f50825294867 (patch) | |
tree | 4e9a6d4a35e09f88154bfe342a3264c18477cd5f | |
parent | 54b2912040d15725004a598cf600f501ab6405f4 (diff) |
[media] rc: img-ir: add NEC decoder module
Add an img-ir module for decoding the NEC and extended NEC infrared
protocols.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r-- | drivers/media/rc/img-ir/Kconfig | 7 | ||||
-rw-r--r-- | drivers/media/rc/img-ir/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/rc/img-ir/img-ir-hw.c | 5 | ||||
-rw-r--r-- | drivers/media/rc/img-ir/img-ir-nec.c | 148 |
4 files changed, 161 insertions, 0 deletions
diff --git a/drivers/media/rc/img-ir/Kconfig b/drivers/media/rc/img-ir/Kconfig index 60eaba6a0843..28498a294daa 100644 --- a/drivers/media/rc/img-ir/Kconfig +++ b/drivers/media/rc/img-ir/Kconfig | |||
@@ -24,3 +24,10 @@ config IR_IMG_HW | |||
24 | signals in hardware. This is more reliable, consumes less processing | 24 | signals in hardware. This is more reliable, consumes less processing |
25 | power since only a single interrupt is received for each scancode, | 25 | power since only a single interrupt is received for each scancode, |
26 | and allows an IR scancode to be used as a wake event. | 26 | and allows an IR scancode to be used as a wake event. |
27 | |||
28 | config IR_IMG_NEC | ||
29 | bool "NEC protocol support" | ||
30 | depends on IR_IMG_HW | ||
31 | help | ||
32 | Say Y here to enable support for the NEC, extended NEC, and 32-bit | ||
33 | NEC protocols in the ImgTec infrared decoder block. | ||
diff --git a/drivers/media/rc/img-ir/Makefile b/drivers/media/rc/img-ir/Makefile index 4ef86edec873..c4091973b35d 100644 --- a/drivers/media/rc/img-ir/Makefile +++ b/drivers/media/rc/img-ir/Makefile | |||
@@ -1,6 +1,7 @@ | |||
1 | img-ir-y := img-ir-core.o | 1 | img-ir-y := img-ir-core.o |
2 | img-ir-$(CONFIG_IR_IMG_RAW) += img-ir-raw.o | 2 | img-ir-$(CONFIG_IR_IMG_RAW) += img-ir-raw.o |
3 | img-ir-$(CONFIG_IR_IMG_HW) += img-ir-hw.o | 3 | img-ir-$(CONFIG_IR_IMG_HW) += img-ir-hw.o |
4 | img-ir-$(CONFIG_IR_IMG_NEC) += img-ir-nec.o | ||
4 | img-ir-objs := $(img-ir-y) | 5 | img-ir-objs := $(img-ir-y) |
5 | 6 | ||
6 | obj-$(CONFIG_IR_IMG) += img-ir.o | 7 | obj-$(CONFIG_IR_IMG) += img-ir.o |
diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c index 21c8bbca8821..139f2c70e382 100644 --- a/drivers/media/rc/img-ir/img-ir-hw.c +++ b/drivers/media/rc/img-ir/img-ir-hw.c | |||
@@ -20,8 +20,13 @@ | |||
20 | /* Decoders lock (only modified to preprocess them) */ | 20 | /* Decoders lock (only modified to preprocess them) */ |
21 | static DEFINE_SPINLOCK(img_ir_decoders_lock); | 21 | static DEFINE_SPINLOCK(img_ir_decoders_lock); |
22 | 22 | ||
23 | extern struct img_ir_decoder img_ir_nec; | ||
24 | |||
23 | static bool img_ir_decoders_preprocessed; | 25 | static bool img_ir_decoders_preprocessed; |
24 | static struct img_ir_decoder *img_ir_decoders[] = { | 26 | static struct img_ir_decoder *img_ir_decoders[] = { |
27 | #ifdef CONFIG_IR_IMG_NEC | ||
28 | &img_ir_nec, | ||
29 | #endif | ||
25 | NULL | 30 | NULL |
26 | }; | 31 | }; |
27 | 32 | ||
diff --git a/drivers/media/rc/img-ir/img-ir-nec.c b/drivers/media/rc/img-ir/img-ir-nec.c new file mode 100644 index 000000000000..e7a731bc3a9b --- /dev/null +++ b/drivers/media/rc/img-ir/img-ir-nec.c | |||
@@ -0,0 +1,148 @@ | |||
1 | /* | ||
2 | * ImgTec IR Decoder setup for NEC protocol. | ||
3 | * | ||
4 | * Copyright 2010-2014 Imagination Technologies Ltd. | ||
5 | */ | ||
6 | |||
7 | #include "img-ir-hw.h" | ||
8 | |||
9 | /* Convert NEC data to a scancode */ | ||
10 | static int img_ir_nec_scancode(int len, u64 raw, int *scancode, u64 protocols) | ||
11 | { | ||
12 | unsigned int addr, addr_inv, data, data_inv; | ||
13 | /* a repeat code has no data */ | ||
14 | if (!len) | ||
15 | return IMG_IR_REPEATCODE; | ||
16 | if (len != 32) | ||
17 | return -EINVAL; | ||
18 | /* raw encoding: ddDDaaAA */ | ||
19 | addr = (raw >> 0) & 0xff; | ||
20 | addr_inv = (raw >> 8) & 0xff; | ||
21 | data = (raw >> 16) & 0xff; | ||
22 | data_inv = (raw >> 24) & 0xff; | ||
23 | if ((data_inv ^ data) != 0xff) { | ||
24 | /* 32-bit NEC (used by Apple and TiVo remotes) */ | ||
25 | /* scan encoding: aaAAddDD */ | ||
26 | *scancode = addr_inv << 24 | | ||
27 | addr << 16 | | ||
28 | data_inv << 8 | | ||
29 | data; | ||
30 | } else if ((addr_inv ^ addr) != 0xff) { | ||
31 | /* Extended NEC */ | ||
32 | /* scan encoding: AAaaDD */ | ||
33 | *scancode = addr << 16 | | ||
34 | addr_inv << 8 | | ||
35 | data; | ||
36 | } else { | ||
37 | /* Normal NEC */ | ||
38 | /* scan encoding: AADD */ | ||
39 | *scancode = addr << 8 | | ||
40 | data; | ||
41 | } | ||
42 | return IMG_IR_SCANCODE; | ||
43 | } | ||
44 | |||
45 | /* Convert NEC scancode to NEC data filter */ | ||
46 | static int img_ir_nec_filter(const struct rc_scancode_filter *in, | ||
47 | struct img_ir_filter *out, u64 protocols) | ||
48 | { | ||
49 | unsigned int addr, addr_inv, data, data_inv; | ||
50 | unsigned int addr_m, addr_inv_m, data_m, data_inv_m; | ||
51 | |||
52 | data = in->data & 0xff; | ||
53 | data_m = in->mask & 0xff; | ||
54 | |||
55 | if ((in->data | in->mask) & 0xff000000) { | ||
56 | /* 32-bit NEC (used by Apple and TiVo remotes) */ | ||
57 | /* scan encoding: aaAAddDD */ | ||
58 | addr_inv = (in->data >> 24) & 0xff; | ||
59 | addr_inv_m = (in->mask >> 24) & 0xff; | ||
60 | addr = (in->data >> 16) & 0xff; | ||
61 | addr_m = (in->mask >> 16) & 0xff; | ||
62 | data_inv = (in->data >> 8) & 0xff; | ||
63 | data_inv_m = (in->mask >> 8) & 0xff; | ||
64 | } else if ((in->data | in->mask) & 0x00ff0000) { | ||
65 | /* Extended NEC */ | ||
66 | /* scan encoding AAaaDD */ | ||
67 | addr = (in->data >> 16) & 0xff; | ||
68 | addr_m = (in->mask >> 16) & 0xff; | ||
69 | addr_inv = (in->data >> 8) & 0xff; | ||
70 | addr_inv_m = (in->mask >> 8) & 0xff; | ||
71 | data_inv = data ^ 0xff; | ||
72 | data_inv_m = data_m; | ||
73 | } else { | ||
74 | /* Normal NEC */ | ||
75 | /* scan encoding: AADD */ | ||
76 | addr = (in->data >> 8) & 0xff; | ||
77 | addr_m = (in->mask >> 8) & 0xff; | ||
78 | addr_inv = addr ^ 0xff; | ||
79 | addr_inv_m = addr_m; | ||
80 | data_inv = data ^ 0xff; | ||
81 | data_inv_m = data_m; | ||
82 | } | ||
83 | |||
84 | /* raw encoding: ddDDaaAA */ | ||
85 | out->data = data_inv << 24 | | ||
86 | data << 16 | | ||
87 | addr_inv << 8 | | ||
88 | addr; | ||
89 | out->mask = data_inv_m << 24 | | ||
90 | data_m << 16 | | ||
91 | addr_inv_m << 8 | | ||
92 | addr_m; | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * NEC decoder | ||
98 | * See also http://www.sbprojects.com/knowledge/ir/nec.php | ||
99 | * http://wiki.altium.com/display/ADOH/NEC+Infrared+Transmission+Protocol | ||
100 | */ | ||
101 | struct img_ir_decoder img_ir_nec = { | ||
102 | .type = RC_BIT_NEC, | ||
103 | .control = { | ||
104 | .decoden = 1, | ||
105 | .code_type = IMG_IR_CODETYPE_PULSEDIST, | ||
106 | }, | ||
107 | /* main timings */ | ||
108 | .unit = 562500, /* 562.5 us */ | ||
109 | .timings = { | ||
110 | /* leader symbol */ | ||
111 | .ldr = { | ||
112 | .pulse = { 16 /* 9ms */ }, | ||
113 | .space = { 8 /* 4.5ms */ }, | ||
114 | }, | ||
115 | /* 0 symbol */ | ||
116 | .s00 = { | ||
117 | .pulse = { 1 /* 562.5 us */ }, | ||
118 | .space = { 1 /* 562.5 us */ }, | ||
119 | }, | ||
120 | /* 1 symbol */ | ||
121 | .s01 = { | ||
122 | .pulse = { 1 /* 562.5 us */ }, | ||
123 | .space = { 3 /* 1687.5 us */ }, | ||
124 | }, | ||
125 | /* free time */ | ||
126 | .ft = { | ||
127 | .minlen = 32, | ||
128 | .maxlen = 32, | ||
129 | .ft_min = 10, /* 5.625 ms */ | ||
130 | }, | ||
131 | }, | ||
132 | /* repeat codes */ | ||
133 | .repeat = 108, /* 108 ms */ | ||
134 | .rtimings = { | ||
135 | /* leader symbol */ | ||
136 | .ldr = { | ||
137 | .space = { 4 /* 2.25 ms */ }, | ||
138 | }, | ||
139 | /* free time */ | ||
140 | .ft = { | ||
141 | .minlen = 0, /* repeat code has no data */ | ||
142 | .maxlen = 0, | ||
143 | }, | ||
144 | }, | ||
145 | /* scancode logic */ | ||
146 | .scancode = img_ir_nec_scancode, | ||
147 | .filter = img_ir_nec_filter, | ||
148 | }; | ||