aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2014-02-28 18:28:56 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-03-11 14:46:57 -0400
commit635abb7054f204e036bc6afe41b1f50825294867 (patch)
tree4e9a6d4a35e09f88154bfe342a3264c18477cd5f
parent54b2912040d15725004a598cf600f501ab6405f4 (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/Kconfig7
-rw-r--r--drivers/media/rc/img-ir/Makefile1
-rw-r--r--drivers/media/rc/img-ir/img-ir-hw.c5
-rw-r--r--drivers/media/rc/img-ir/img-ir-nec.c148
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
28config 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 @@
1img-ir-y := img-ir-core.o 1img-ir-y := img-ir-core.o
2img-ir-$(CONFIG_IR_IMG_RAW) += img-ir-raw.o 2img-ir-$(CONFIG_IR_IMG_RAW) += img-ir-raw.o
3img-ir-$(CONFIG_IR_IMG_HW) += img-ir-hw.o 3img-ir-$(CONFIG_IR_IMG_HW) += img-ir-hw.o
4img-ir-$(CONFIG_IR_IMG_NEC) += img-ir-nec.o
4img-ir-objs := $(img-ir-y) 5img-ir-objs := $(img-ir-y)
5 6
6obj-$(CONFIG_IR_IMG) += img-ir.o 7obj-$(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) */
21static DEFINE_SPINLOCK(img_ir_decoders_lock); 21static DEFINE_SPINLOCK(img_ir_decoders_lock);
22 22
23extern struct img_ir_decoder img_ir_nec;
24
23static bool img_ir_decoders_preprocessed; 25static bool img_ir_decoders_preprocessed;
24static struct img_ir_decoder *img_ir_decoders[] = { 26static 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 */
10static 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 */
46static 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 */
101struct 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};