aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/IR/ir-nec-decoder.c247
-rw-r--r--drivers/media/IR/ir-raw-event.c143
-rw-r--r--drivers/media/IR/ir-rc5-decoder.c150
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c2
-rw-r--r--include/media/ir-core.h47
5 files changed, 296 insertions, 293 deletions
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
index 18918e52c0c0..02682e617fae 100644
--- a/drivers/media/IR/ir-nec-decoder.c
+++ b/drivers/media/IR/ir-nec-decoder.c
@@ -13,15 +13,16 @@
13 */ 13 */
14 14
15#include <media/ir-core.h> 15#include <media/ir-core.h>
16#include <linux/bitrev.h>
16 17
17#define NEC_NBITS 32 18#define NEC_NBITS 32
18#define NEC_UNIT 559979 /* ns */ 19#define NEC_UNIT 562500 /* ns */
19#define NEC_HEADER_MARK (16 * NEC_UNIT) 20#define NEC_HEADER_PULSE PULSE(16)
20#define NEC_HEADER_SPACE (8 * NEC_UNIT) 21#define NEC_HEADER_SPACE SPACE(8)
21#define NEC_REPEAT_SPACE (4 * NEC_UNIT) 22#define NEC_REPEAT_SPACE SPACE(4)
22#define NEC_MARK (NEC_UNIT) 23#define NEC_BIT_PULSE PULSE(1)
23#define NEC_0_SPACE (NEC_UNIT) 24#define NEC_BIT_0_SPACE SPACE(1)
24#define NEC_1_SPACE (3 * NEC_UNIT) 25#define NEC_BIT_1_SPACE SPACE(3)
25 26
26/* Used to register nec_decoder clients */ 27/* Used to register nec_decoder clients */
27static LIST_HEAD(decoder_list); 28static LIST_HEAD(decoder_list);
@@ -29,21 +30,13 @@ static DEFINE_SPINLOCK(decoder_lock);
29 30
30enum nec_state { 31enum nec_state {
31 STATE_INACTIVE, 32 STATE_INACTIVE,
32 STATE_HEADER_MARK,
33 STATE_HEADER_SPACE, 33 STATE_HEADER_SPACE,
34 STATE_MARK, 34 STATE_BIT_PULSE,
35 STATE_SPACE, 35 STATE_BIT_SPACE,
36 STATE_TRAILER_MARK, 36 STATE_TRAILER_PULSE,
37 STATE_TRAILER_SPACE, 37 STATE_TRAILER_SPACE,
38}; 38};
39 39
40struct nec_code {
41 u8 address;
42 u8 not_address;
43 u8 command;
44 u8 not_command;
45};
46
47struct decoder_data { 40struct decoder_data {
48 struct list_head list; 41 struct list_head list;
49 struct ir_input_dev *ir_dev; 42 struct ir_input_dev *ir_dev;
@@ -51,7 +44,7 @@ struct decoder_data {
51 44
52 /* State machine control */ 45 /* State machine control */
53 enum nec_state state; 46 enum nec_state state;
54 struct nec_code nec_code; 47 u32 nec_bits;
55 unsigned count; 48 unsigned count;
56}; 49};
57 50
@@ -62,7 +55,6 @@ struct decoder_data {
62 * 55 *
63 * Returns the struct decoder_data that corresponds to a device 56 * Returns the struct decoder_data that corresponds to a device
64 */ 57 */
65
66static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev) 58static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
67{ 59{
68 struct decoder_data *data = NULL; 60 struct decoder_data *data = NULL;
@@ -123,20 +115,20 @@ static struct attribute_group decoder_attribute_group = {
123 .attrs = decoder_attributes, 115 .attrs = decoder_attributes,
124}; 116};
125 117
126
127/** 118/**
128 * ir_nec_decode() - Decode one NEC pulse or space 119 * ir_nec_decode() - Decode one NEC pulse or space
129 * @input_dev: the struct input_dev descriptor of the device 120 * @input_dev: the struct input_dev descriptor of the device
130 * @ev: event array with type/duration of pulse/space 121 * @duration: duration in ns of pulse/space
131 * 122 *
132 * This function returns -EINVAL if the pulse violates the state machine 123 * This function returns -EINVAL if the pulse violates the state machine
133 */ 124 */
134static int ir_nec_decode(struct input_dev *input_dev, 125static int ir_nec_decode(struct input_dev *input_dev, s64 duration)
135 struct ir_raw_event *ev)
136{ 126{
137 struct decoder_data *data; 127 struct decoder_data *data;
138 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); 128 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
139 int bit, last_bit; 129 int u;
130 u32 scancode;
131 u8 address, not_address, command, not_command;
140 132
141 data = get_decoder_data(ir_dev); 133 data = get_decoder_data(ir_dev);
142 if (!data) 134 if (!data)
@@ -145,150 +137,107 @@ static int ir_nec_decode(struct input_dev *input_dev,
145 if (!data->enabled) 137 if (!data->enabled)
146 return 0; 138 return 0;
147 139
148 /* Except for the initial event, what matters is the previous bit */ 140 if (IS_RESET(duration)) {
149 bit = (ev->type & IR_PULSE) ? 1 : 0;
150
151 last_bit = !bit;
152
153 /* Discards spurious space last_bits when inactive */
154
155 /* Very long delays are considered as start events */
156 if (ev->delta.tv_nsec > NEC_HEADER_MARK + NEC_HEADER_SPACE - NEC_UNIT / 2)
157 data->state = STATE_INACTIVE; 141 data->state = STATE_INACTIVE;
142 return 0;
143 }
158 144
159 if (ev->type & IR_START_EVENT) 145 u = TO_UNITS(duration, NEC_UNIT);
160 data->state = STATE_INACTIVE; 146 if (DURATION(u) == 0)
147 goto out;
148
149 IR_dprintk(2, "NEC decode started at state %d (%i units, %ius)\n",
150 data->state, u, TO_US(duration));
161 151
162 switch (data->state) { 152 switch (data->state) {
163 case STATE_INACTIVE:
164 if (!bit) /* PULSE marks the start event */
165 return 0;
166 153
167 data->count = 0; 154 case STATE_INACTIVE:
168 data->state = STATE_HEADER_MARK; 155 if (u == NEC_HEADER_PULSE) {
169 memset (&data->nec_code, 0, sizeof(data->nec_code)); 156 data->count = 0;
170 return 0; 157 data->state = STATE_HEADER_SPACE;
171 case STATE_HEADER_MARK: 158 }
172 if (!last_bit)
173 goto err;
174 if (ev->delta.tv_nsec < NEC_HEADER_MARK - 6 * NEC_UNIT)
175 goto err;
176 data->state = STATE_HEADER_SPACE;
177 return 0; 159 return 0;
160
178 case STATE_HEADER_SPACE: 161 case STATE_HEADER_SPACE:
179 if (last_bit) 162 if (u == NEC_HEADER_SPACE) {
180 goto err; 163 data->state = STATE_BIT_PULSE;
181 if (ev->delta.tv_nsec >= NEC_HEADER_SPACE - NEC_UNIT / 2) {
182 data->state = STATE_MARK;
183 return 0; 164 return 0;
184 } 165 } else if (u == NEC_REPEAT_SPACE) {
185
186 if (ev->delta.tv_nsec >= NEC_REPEAT_SPACE - NEC_UNIT / 2) {
187 ir_repeat(input_dev); 166 ir_repeat(input_dev);
188 IR_dprintk(1, "Repeat last key\n"); 167 IR_dprintk(1, "Repeat last key\n");
189 data->state = STATE_TRAILER_MARK; 168 data->state = STATE_TRAILER_PULSE;
190 return 0; 169 return 0;
191 } 170 }
192 goto err; 171 break;
193 case STATE_MARK: 172
194 if (!last_bit) 173 case STATE_BIT_PULSE:
195 goto err; 174 if (u == NEC_BIT_PULSE) {
196 if ((ev->delta.tv_nsec > NEC_MARK + NEC_UNIT / 2) || 175 data->state = STATE_BIT_SPACE;
197 (ev->delta.tv_nsec < NEC_MARK - NEC_UNIT / 2)) 176 return 0;
198 goto err; 177 }
199 data->state = STATE_SPACE; 178 break;
200 return 0; 179
201 case STATE_SPACE: 180 case STATE_BIT_SPACE:
202 if (last_bit) 181 if (u != NEC_BIT_0_SPACE && u != NEC_BIT_1_SPACE)
203 goto err; 182 break;
204 183
205 if ((ev->delta.tv_nsec >= NEC_0_SPACE - NEC_UNIT / 2) && 184 data->nec_bits <<= 1;
206 (ev->delta.tv_nsec < NEC_0_SPACE + NEC_UNIT / 2)) 185 if (u == NEC_BIT_1_SPACE)
207 bit = 0; 186 data->nec_bits |= 1;
208 else if ((ev->delta.tv_nsec >= NEC_1_SPACE - NEC_UNIT / 2) && 187 data->count++;
209 (ev->delta.tv_nsec < NEC_1_SPACE + NEC_UNIT / 2)) 188
210 bit = 1; 189 if (data->count != NEC_NBITS) {
211 else { 190 data->state = STATE_BIT_PULSE;
212 IR_dprintk(1, "Decode failed at %d-th bit (%s) @%luus\n", 191 return 0;
213 data->count, 192 }
214 last_bit ? "pulse" : "space", 193
215 (ev->delta.tv_nsec + 500) / 1000); 194 address = bitrev8((data->nec_bits >> 24) & 0xff);
216 195 not_address = bitrev8((data->nec_bits >> 16) & 0xff);
217 goto err2; 196 command = bitrev8((data->nec_bits >> 8) & 0xff);
197 not_command = bitrev8((data->nec_bits >> 0) & 0xff);
198
199 if ((command ^ not_command) != 0xff) {
200 IR_dprintk(1, "NEC checksum error: received 0x%08x\n",
201 data->nec_bits);
202 break;
218 } 203 }
219 204
220 /* Ok, we've got a valid bit. proccess it */ 205 if ((address ^ not_address) != 0xff) {
221 if (bit) { 206 /* Extended NEC */
222 int shift = data->count; 207 scancode = address << 16 |
223 208 not_address << 8 |
224 /* 209 command;
225 * NEC transmit bytes on this temporal order: 210 IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode);
226 * address | not address | command | not command 211 } else {
227 */ 212 /* normal NEC */
228 if (shift < 8) { 213 scancode = address << 8 | command;
229 data->nec_code.address |= 1 << shift; 214 IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
230 } else if (shift < 16) {
231 data->nec_code.not_address |= 1 << (shift - 8);
232 } else if (shift < 24) {
233 data->nec_code.command |= 1 << (shift - 16);
234 } else {
235 data->nec_code.not_command |= 1 << (shift - 24);
236 }
237 } 215 }
238 if (++data->count == NEC_NBITS) { 216
239 u32 scancode; 217 ir_keydown(input_dev, scancode, 0);
240 /* 218 data->state = STATE_TRAILER_PULSE;
241 * Fixme: may need to accept Extended NEC protocol?
242 */
243 if ((data->nec_code.command ^ data->nec_code.not_command) != 0xff)
244 goto checksum_err;
245
246 if ((data->nec_code.address ^ data->nec_code.not_address) != 0xff) {
247 /* Extended NEC */
248 scancode = data->nec_code.address << 16 |
249 data->nec_code.not_address << 8 |
250 data->nec_code.command;
251 IR_dprintk(1, "NEC scancode 0x%06x\n", scancode);
252 } else {
253 /* normal NEC */
254 scancode = data->nec_code.address << 8 |
255 data->nec_code.command;
256 IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
257 }
258 ir_keydown(input_dev, scancode, 0);
259
260 data->state = STATE_TRAILER_MARK;
261 } else
262 data->state = STATE_MARK;
263 return 0;
264 case STATE_TRAILER_MARK:
265 if (!last_bit)
266 goto err;
267 data->state = STATE_TRAILER_SPACE;
268 return 0; 219 return 0;
220
221 case STATE_TRAILER_PULSE:
222 if (u > 0) {
223 data->state = STATE_TRAILER_SPACE;
224 return 0;
225 }
226 break;
227
269 case STATE_TRAILER_SPACE: 228 case STATE_TRAILER_SPACE:
270 if (last_bit) 229 if (u < 0) {
271 goto err; 230 data->state = STATE_INACTIVE;
272 data->state = STATE_INACTIVE; 231 return 0;
273 return 0; 232 }
274 }
275 233
276err: 234 break;
277 IR_dprintk(1, "NEC decoded failed at state %d (%s) @ %luus\n", 235 }
278 data->state,
279 bit ? "pulse" : "space",
280 (ev->delta.tv_nsec + 500) / 1000);
281err2:
282 data->state = STATE_INACTIVE;
283 return -EINVAL;
284 236
285checksum_err: 237out:
238 IR_dprintk(1, "NEC decode failed at state %d (%i units, %ius)\n",
239 data->state, u, TO_US(duration));
286 data->state = STATE_INACTIVE; 240 data->state = STATE_INACTIVE;
287 IR_dprintk(1, "NEC checksum error: received 0x%02x%02x%02x%02x\n",
288 data->nec_code.address,
289 data->nec_code.not_address,
290 data->nec_code.command,
291 data->nec_code.not_command);
292 return -EINVAL; 241 return -EINVAL;
293} 242}
294 243
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
index bc4ca08adf4a..e144f1522962 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/IR/ir-raw-event.c
@@ -15,9 +15,10 @@
15#include <media/ir-core.h> 15#include <media/ir-core.h>
16#include <linux/workqueue.h> 16#include <linux/workqueue.h>
17#include <linux/spinlock.h> 17#include <linux/spinlock.h>
18#include <linux/sched.h>
18 19
19/* Define the max number of bit transitions per IR keycode */ 20/* Define the max number of pulse/space transitions to buffer */
20#define MAX_IR_EVENT_SIZE 256 21#define MAX_IR_EVENT_SIZE 512
21 22
22/* Used to handle IR raw handler extensions */ 23/* Used to handle IR raw handler extensions */
23static LIST_HEAD(ir_raw_handler_list); 24static LIST_HEAD(ir_raw_handler_list);
@@ -53,19 +54,30 @@ static DEFINE_SPINLOCK(ir_raw_handler_lock);
53/* Used to load the decoders */ 54/* Used to load the decoders */
54static struct work_struct wq_load; 55static struct work_struct wq_load;
55 56
57static void ir_raw_event_work(struct work_struct *work)
58{
59 s64 d;
60 struct ir_raw_event_ctrl *raw =
61 container_of(work, struct ir_raw_event_ctrl, rx_work);
62
63 while (kfifo_out(&raw->kfifo, &d, sizeof(d)) == sizeof(d))
64 RUN_DECODER(decode, raw->input_dev, d);
65}
66
56int ir_raw_event_register(struct input_dev *input_dev) 67int ir_raw_event_register(struct input_dev *input_dev)
57{ 68{
58 struct ir_input_dev *ir = input_get_drvdata(input_dev); 69 struct ir_input_dev *ir = input_get_drvdata(input_dev);
59 int rc, size; 70 int rc;
60 71
61 ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL); 72 ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
62 if (!ir->raw) 73 if (!ir->raw)
63 return -ENOMEM; 74 return -ENOMEM;
64 75
65 size = sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE * 2; 76 ir->raw->input_dev = input_dev;
66 size = roundup_pow_of_two(size); 77 INIT_WORK(&ir->raw->rx_work, ir_raw_event_work);
67 78
68 rc = kfifo_alloc(&ir->raw->kfifo, size, GFP_KERNEL); 79 rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
80 GFP_KERNEL);
69 if (rc < 0) { 81 if (rc < 0) {
70 kfree(ir->raw); 82 kfree(ir->raw);
71 ir->raw = NULL; 83 ir->raw = NULL;
@@ -90,6 +102,7 @@ void ir_raw_event_unregister(struct input_dev *input_dev)
90 if (!ir->raw) 102 if (!ir->raw)
91 return; 103 return;
92 104
105 cancel_work_sync(&ir->raw->rx_work);
93 RUN_DECODER(raw_unregister, input_dev); 106 RUN_DECODER(raw_unregister, input_dev);
94 107
95 kfifo_free(&ir->raw->kfifo); 108 kfifo_free(&ir->raw->kfifo);
@@ -97,74 +110,90 @@ void ir_raw_event_unregister(struct input_dev *input_dev)
97 ir->raw = NULL; 110 ir->raw = NULL;
98} 111}
99 112
100int ir_raw_event_store(struct input_dev *input_dev, enum raw_event_type type) 113/**
114 * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders
115 * @input_dev: the struct input_dev device descriptor
116 * @duration: duration of the pulse or space in ns
117 *
118 * This routine (which may be called from an interrupt context) stores a
119 * pulse/space duration for the raw ir decoding state machines. Pulses are
120 * signalled as positive values and spaces as negative values. A zero value
121 * will reset the decoding state machines.
122 */
123int ir_raw_event_store(struct input_dev *input_dev, s64 duration)
101{ 124{
102 struct ir_input_dev *ir = input_get_drvdata(input_dev); 125 struct ir_input_dev *ir = input_get_drvdata(input_dev);
103 struct timespec ts;
104 struct ir_raw_event event;
105 int rc;
106 126
107 if (!ir->raw) 127 if (!ir->raw)
108 return -EINVAL; 128 return -EINVAL;
109 129
110 event.type = type; 130 if (kfifo_in(&ir->raw->kfifo, &duration, sizeof(duration)) != sizeof(duration))
111 event.delta.tv_sec = 0; 131 return -ENOMEM;
112 event.delta.tv_nsec = 0;
113 132
114 ktime_get_ts(&ts); 133 return 0;
134}
135EXPORT_SYMBOL_GPL(ir_raw_event_store);
115 136
116 if (timespec_equal(&ir->raw->last_event, &event.delta)) 137/**
117 event.type |= IR_START_EVENT; 138 * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space
118 else 139 * @input_dev: the struct input_dev device descriptor
119 event.delta = timespec_sub(ts, ir->raw->last_event); 140 * @type: the type of the event that has occurred
141 *
142 * This routine (which may be called from an interrupt context) is used to
143 * store the beginning of an ir pulse or space (or the start/end of ir
144 * reception) for the raw ir decoding state machines. This is used by
145 * hardware which does not provide durations directly but only interrupts
146 * (or similar events) on state change.
147 */
148int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type)
149{
150 struct ir_input_dev *ir = input_get_drvdata(input_dev);
151 ktime_t now;
152 s64 delta; /* ns */
153 int rc = 0;
120 154
121 memcpy(&ir->raw->last_event, &ts, sizeof(ts)); 155 if (!ir->raw)
156 return -EINVAL;
122 157
123 if (event.delta.tv_sec) { 158 now = ktime_get();
124 event.type |= IR_START_EVENT; 159 delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
125 event.delta.tv_sec = 0;
126 event.delta.tv_nsec = 0;
127 }
128 160
129 kfifo_in(&ir->raw->kfifo, &event, sizeof(event)); 161 /* Check for a long duration since last event or if we're
162 * being called for the first time, note that delta can't
163 * possibly be negative.
164 */
165 if (delta > NSEC_PER_SEC || !ir->raw->last_type)
166 type |= IR_START_EVENT;
167
168 if (type & IR_START_EVENT)
169 ir_raw_event_reset(input_dev);
170 else if (ir->raw->last_type & IR_SPACE)
171 rc = ir_raw_event_store(input_dev, -delta);
172 else if (ir->raw->last_type & IR_PULSE)
173 rc = ir_raw_event_store(input_dev, delta);
174 else
175 return 0;
130 176
177 ir->raw->last_event = now;
178 ir->raw->last_type = type;
131 return rc; 179 return rc;
132} 180}
133EXPORT_SYMBOL_GPL(ir_raw_event_store); 181EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
134 182
135int ir_raw_event_handle(struct input_dev *input_dev) 183/**
184 * ir_raw_event_handle() - schedules the decoding of stored ir data
185 * @input_dev: the struct input_dev device descriptor
186 *
187 * This routine will signal the workqueue to start decoding stored ir data.
188 */
189void ir_raw_event_handle(struct input_dev *input_dev)
136{ 190{
137 struct ir_input_dev *ir = input_get_drvdata(input_dev); 191 struct ir_input_dev *ir = input_get_drvdata(input_dev);
138 int rc;
139 struct ir_raw_event ev;
140 int len, i;
141
142 /*
143 * Store the events into a temporary buffer. This allows calling more than
144 * one decoder to deal with the received data
145 */
146 len = kfifo_len(&ir->raw->kfifo) / sizeof(ev);
147 if (!len)
148 return 0;
149
150 for (i = 0; i < len; i++) {
151 rc = kfifo_out(&ir->raw->kfifo, &ev, sizeof(ev));
152 if (rc != sizeof(ev)) {
153 IR_dprintk(1, "overflow error: received %d instead of %zd\n",
154 rc, sizeof(ev));
155 return -EINVAL;
156 }
157 IR_dprintk(2, "event type %d, time before event: %07luus\n",
158 ev.type, (ev.delta.tv_nsec + 500) / 1000);
159 rc = RUN_DECODER(decode, input_dev, &ev);
160 }
161 192
162 /* 193 if (!ir->raw)
163 * Call all ir decoders. This allows decoding the same event with 194 return;
164 * more than one protocol handler.
165 */
166 195
167 return rc; 196 schedule_work(&ir->raw->rx_work);
168} 197}
169EXPORT_SYMBOL_GPL(ir_raw_event_handle); 198EXPORT_SYMBOL_GPL(ir_raw_event_handle);
170 199
diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/IR/ir-rc5-decoder.c
index 6323066438b5..1d0857b69089 100644
--- a/drivers/media/IR/ir-rc5-decoder.c
+++ b/drivers/media/IR/ir-rc5-decoder.c
@@ -21,11 +21,8 @@
21 21
22#include <media/ir-core.h> 22#include <media/ir-core.h>
23 23
24static unsigned int ir_rc5_remote_gap = 888888;
25
26#define RC5_NBITS 14 24#define RC5_NBITS 14
27#define RC5_BIT (ir_rc5_remote_gap * 2) 25#define RC5_UNIT 888888 /* ns */
28#define RC5_DURATION (ir_rc5_remote_gap * RC5_NBITS)
29 26
30/* Used to register rc5_decoder clients */ 27/* Used to register rc5_decoder clients */
31static LIST_HEAD(decoder_list); 28static LIST_HEAD(decoder_list);
@@ -33,13 +30,9 @@ static DEFINE_SPINLOCK(decoder_lock);
33 30
34enum rc5_state { 31enum rc5_state {
35 STATE_INACTIVE, 32 STATE_INACTIVE,
36 STATE_MARKSPACE, 33 STATE_BIT_START,
37 STATE_TRAILER, 34 STATE_BIT_END,
38}; 35 STATE_FINISHED,
39
40struct rc5_code {
41 u8 address;
42 u8 command;
43}; 36};
44 37
45struct decoder_data { 38struct decoder_data {
@@ -49,8 +42,9 @@ struct decoder_data {
49 42
50 /* State machine control */ 43 /* State machine control */
51 enum rc5_state state; 44 enum rc5_state state;
52 struct rc5_code rc5_code; 45 u32 rc5_bits;
53 unsigned code, elapsed, last_bit, last_code; 46 int last_unit;
47 unsigned count;
54}; 48};
55 49
56 50
@@ -122,18 +116,19 @@ static struct attribute_group decoder_attribute_group = {
122}; 116};
123 117
124/** 118/**
125 * handle_event() - Decode one RC-5 pulse or space 119 * ir_rc5_decode() - Decode one RC-5 pulse or space
126 * @input_dev: the struct input_dev descriptor of the device 120 * @input_dev: the struct input_dev descriptor of the device
127 * @ev: event array with type/duration of pulse/space 121 * @duration: duration of pulse/space in ns
128 * 122 *
129 * This function returns -EINVAL if the pulse violates the state machine 123 * This function returns -EINVAL if the pulse violates the state machine
130 */ 124 */
131static int ir_rc5_decode(struct input_dev *input_dev, 125static int ir_rc5_decode(struct input_dev *input_dev, s64 duration)
132 struct ir_raw_event *ev)
133{ 126{
134 struct decoder_data *data; 127 struct decoder_data *data;
135 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); 128 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
136 int is_pulse, scancode, delta, toggle; 129 u8 command, system, toggle;
130 u32 scancode;
131 int u;
137 132
138 data = get_decoder_data(ir_dev); 133 data = get_decoder_data(ir_dev);
139 if (!data) 134 if (!data)
@@ -142,79 +137,84 @@ static int ir_rc5_decode(struct input_dev *input_dev,
142 if (!data->enabled) 137 if (!data->enabled)
143 return 0; 138 return 0;
144 139
145 delta = DIV_ROUND_CLOSEST(ev->delta.tv_nsec, ir_rc5_remote_gap); 140 if (IS_RESET(duration)) {
146
147 /* The duration time refers to the last bit time */
148 is_pulse = (ev->type & IR_PULSE) ? 1 : 0;
149
150 /* Very long delays are considered as start events */
151 if (delta > RC5_DURATION || (ev->type & IR_START_EVENT))
152 data->state = STATE_INACTIVE; 141 data->state = STATE_INACTIVE;
153
154 switch (data->state) {
155 case STATE_INACTIVE:
156 IR_dprintk(2, "currently inative. Start bit (%s) @%uus\n",
157 is_pulse ? "pulse" : "space",
158 (unsigned)(ev->delta.tv_nsec + 500) / 1000);
159
160 /* Discards the initial start space */
161 if (!is_pulse)
162 goto err;
163 data->code = 1;
164 data->last_bit = 1;
165 data->elapsed = 0;
166 memset(&data->rc5_code, 0, sizeof(data->rc5_code));
167 data->state = STATE_MARKSPACE;
168 return 0; 142 return 0;
169 case STATE_MARKSPACE: 143 }
170 if (delta != 1)
171 data->last_bit = data->last_bit ? 0 : 1;
172 144
173 data->elapsed += delta; 145 u = TO_UNITS(duration, RC5_UNIT);
146 if (DURATION(u) == 0)
147 goto out;
174 148
175 if ((data->elapsed % 2) == 1) 149again:
176 return 0; 150 IR_dprintk(2, "RC5 decode started at state %i (%i units, %ius)\n",
151 data->state, u, TO_US(duration));
177 152
178 data->code <<= 1; 153 if (DURATION(u) == 0 && data->state != STATE_FINISHED)
179 data->code |= data->last_bit; 154 return 0;
180
181 /* Fill the 2 unused bits at the command with 0 */
182 if (data->elapsed / 2 == 6)
183 data->code <<= 2;
184 155
185 if (data->elapsed >= (RC5_NBITS - 1) * 2) { 156 switch (data->state) {
186 scancode = data->code;
187 157
188 /* Check for the start bits */ 158 case STATE_INACTIVE:
189 if ((scancode & 0xc000) != 0xc000) { 159 if (IS_PULSE(u)) {
190 IR_dprintk(1, "Code 0x%04x doesn't have two start bits. It is not RC-5\n", scancode); 160 data->state = STATE_BIT_START;
191 goto err; 161 data->count = 1;
162 DECREASE_DURATION(u, 1);
163 goto again;
164 }
165 break;
166
167 case STATE_BIT_START:
168 if (DURATION(u) == 1) {
169 data->rc5_bits <<= 1;
170 if (IS_SPACE(u))
171 data->rc5_bits |= 1;
172 data->count++;
173 data->last_unit = u;
174
175 /*
176 * If the last bit is zero, a space will merge
177 * with the silence after the command.
178 */
179 if (IS_PULSE(u) && data->count == RC5_NBITS) {
180 data->state = STATE_FINISHED;
181 goto again;
192 } 182 }
193 183
194 toggle = (scancode & 0x2000) ? 1 : 0; 184 data->state = STATE_BIT_END;
185 return 0;
186 }
187 break;
195 188
196 if (scancode == data->last_code) { 189 case STATE_BIT_END:
197 IR_dprintk(1, "RC-5 repeat\n"); 190 if (IS_TRANSITION(u, data->last_unit)) {
198 ir_repeat(input_dev); 191 if (data->count == RC5_NBITS)
199 } else { 192 data->state = STATE_FINISHED;
200 data->last_code = scancode; 193 else
201 scancode &= 0x1fff; 194 data->state = STATE_BIT_START;
202 IR_dprintk(1, "RC-5 scancode 0x%04x\n", scancode);
203 195
204 ir_keydown(input_dev, scancode, 0); 196 DECREASE_DURATION(u, 1);
205 } 197 goto again;
206 data->state = STATE_TRAILER;
207 } 198 }
208 return 0; 199 break;
209 case STATE_TRAILER: 200
201 case STATE_FINISHED:
202 command = (data->rc5_bits & 0x0003F) >> 0;
203 system = (data->rc5_bits & 0x007C0) >> 6;
204 toggle = (data->rc5_bits & 0x00800) ? 1 : 0;
205 command += (data->rc5_bits & 0x01000) ? 0 : 0x40;
206 scancode = system << 8 | command;
207
208 IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n",
209 scancode, toggle);
210 ir_keydown(input_dev, scancode, toggle);
210 data->state = STATE_INACTIVE; 211 data->state = STATE_INACTIVE;
211 return 0; 212 return 0;
212 } 213 }
213 214
214err: 215out:
215 IR_dprintk(1, "RC-5 decoded failed at %s @ %luus\n", 216 IR_dprintk(1, "RC5 decode failed at state %i (%i units, %ius)\n",
216 is_pulse ? "pulse" : "space", 217 data->state, u, TO_US(duration));
217 (ev->delta.tv_nsec + 500) / 1000);
218 data->state = STATE_INACTIVE; 218 data->state = STATE_INACTIVE;
219 return -EINVAL; 219 return -EINVAL;
220} 220}
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 6d5fe596245d..e4681eda01f9 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -1018,7 +1018,7 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
1018 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); 1018 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
1019 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); 1019 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
1020 space = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown; 1020 space = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown;
1021 ir_raw_event_store(dev->remote->dev, space ? IR_SPACE : IR_PULSE); 1021 ir_raw_event_store_edge(dev->remote->dev, space ? IR_SPACE : IR_PULSE);
1022 1022
1023 1023
1024 /* 1024 /*
diff --git a/include/media/ir-core.h b/include/media/ir-core.h
index e9fa94fe2ef5..e9a0cbf67ff6 100644
--- a/include/media/ir-core.h
+++ b/include/media/ir-core.h
@@ -65,14 +65,12 @@ struct ir_dev_props {
65 void (*close)(void *priv); 65 void (*close)(void *priv);
66}; 66};
67 67
68struct ir_raw_event {
69 struct timespec delta; /* Time spent before event */
70 enum raw_event_type type; /* event type */
71};
72
73struct ir_raw_event_ctrl { 68struct ir_raw_event_ctrl {
74 struct kfifo kfifo; /* fifo for the pulse/space events */ 69 struct work_struct rx_work; /* for the rx decoding workqueue */
75 struct timespec last_event; /* when last event occurred */ 70 struct kfifo kfifo; /* fifo for the pulse/space durations */
71 ktime_t last_event; /* when last event occurred */
72 enum raw_event_type last_type; /* last event type */
73 struct input_dev *input_dev; /* pointer to the parent input_dev */
76}; 74};
77 75
78struct ir_input_dev { 76struct ir_input_dev {
@@ -97,8 +95,7 @@ struct ir_input_dev {
97struct ir_raw_handler { 95struct ir_raw_handler {
98 struct list_head list; 96 struct list_head list;
99 97
100 int (*decode)(struct input_dev *input_dev, 98 int (*decode)(struct input_dev *input_dev, s64 duration);
101 struct ir_raw_event *ev);
102 int (*raw_register)(struct input_dev *input_dev); 99 int (*raw_register)(struct input_dev *input_dev);
103 int (*raw_unregister)(struct input_dev *input_dev); 100 int (*raw_unregister)(struct input_dev *input_dev);
104}; 101};
@@ -154,8 +151,14 @@ void ir_unregister_class(struct input_dev *input_dev);
154/* Routines from ir-raw-event.c */ 151/* Routines from ir-raw-event.c */
155int ir_raw_event_register(struct input_dev *input_dev); 152int ir_raw_event_register(struct input_dev *input_dev);
156void ir_raw_event_unregister(struct input_dev *input_dev); 153void ir_raw_event_unregister(struct input_dev *input_dev);
157int ir_raw_event_store(struct input_dev *input_dev, enum raw_event_type type); 154void ir_raw_event_handle(struct input_dev *input_dev);
158int ir_raw_event_handle(struct input_dev *input_dev); 155int ir_raw_event_store(struct input_dev *input_dev, s64 duration);
156int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type);
157static inline void ir_raw_event_reset(struct input_dev *input_dev)
158{
159 ir_raw_event_store(input_dev, 0);
160 ir_raw_event_handle(input_dev);
161}
159int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); 162int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
160void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler); 163void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
161void ir_raw_init(void); 164void ir_raw_init(void);
@@ -174,4 +177,26 @@ void ir_raw_init(void);
174#define load_rc5_decode() 0 177#define load_rc5_decode() 0
175#endif 178#endif
176 179
180/* macros for ir decoders */
181#define PULSE(units) ((units))
182#define SPACE(units) (-(units))
183#define IS_RESET(duration) ((duration) == 0)
184#define IS_PULSE(duration) ((duration) > 0)
185#define IS_SPACE(duration) ((duration) < 0)
186#define DURATION(duration) (abs((duration)))
187#define IS_TRANSITION(x, y) ((x) * (y) < 0)
188#define DECREASE_DURATION(duration, amount) \
189 do { \
190 if (IS_SPACE(duration)) \
191 duration += (amount); \
192 else if (IS_PULSE(duration)) \
193 duration -= (amount); \
194 } while (0)
195
196#define TO_UNITS(duration, unit_len) \
197 ((int)((duration) > 0 ? \
198 DIV_ROUND_CLOSEST(abs((duration)), (unit_len)) :\
199 -DIV_ROUND_CLOSEST(abs((duration)), (unit_len))))
200#define TO_US(duration) ((int)TO_UNITS(duration, 1000))
201
177#endif /* _IR_CORE */ 202#endif /* _IR_CORE */