aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2010-04-08 12:10:00 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-19 11:57:03 -0400
commit724e2495502a98aaa3f93c404472a991da8ff857 (patch)
treedfdc90b4408fa95f7757b1c6e5b36c2789da0df2
parentd22e546ea18ee66c255af906f2714d3ee82d4b42 (diff)
V4L/DVB: Teach drivers/media/IR/ir-raw-event.c to use durations
drivers/media/IR/ir-raw-event.c is currently written with the assumption that all "raw" hardware will generate events only on state change (i.e. when a pulse or space starts). However, some hardware (like mceusb, probably the most popular IR receiver out there) only generates duration data (and that data is buffered so using any kind of timing on the data is futile). Furthermore, using signed int's to represent pulse/space durations is a well-known approach when writing ir decoders. With this patch: - s64 int's are used to represent pulse/space durations in ns - a workqueue is used to decode the ir protocols outside of interrupt context - #defines are added to make decoders clearer - decoder reset is implemented by passing a zero duration to the kfifo queue and decoders are updated accordingly Signed-off-by: David Härdeman <david@hardeman.nu> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-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 */