aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR/ir-rc6-decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/IR/ir-rc6-decoder.c')
-rw-r--r--drivers/media/IR/ir-rc6-decoder.c92
1 files changed, 5 insertions, 87 deletions
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c
index 2ebd4ea69538..f1624b8279bc 100644
--- a/drivers/media/IR/ir-rc6-decoder.c
+++ b/drivers/media/IR/ir-rc6-decoder.c
@@ -36,10 +36,6 @@
36#define RC6_STARTBIT_MASK 0x08 /* for the header bits */ 36#define RC6_STARTBIT_MASK 0x08 /* for the header bits */
37#define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */ 37#define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */
38 38
39/* Used to register rc6_decoder clients */
40static LIST_HEAD(decoder_list);
41static DEFINE_SPINLOCK(decoder_lock);
42
43enum rc6_mode { 39enum rc6_mode {
44 RC6_MODE_0, 40 RC6_MODE_0,
45 RC6_MODE_6A, 41 RC6_MODE_6A,
@@ -58,41 +54,8 @@ enum rc6_state {
58 STATE_FINISHED, 54 STATE_FINISHED,
59}; 55};
60 56
61struct decoder_data { 57static enum rc6_mode rc6_mode(struct rc6_dec *data)
62 struct list_head list;
63 struct ir_input_dev *ir_dev;
64
65 /* State machine control */
66 enum rc6_state state;
67 u8 header;
68 u32 body;
69 struct ir_raw_event prev_ev;
70 bool toggle;
71 unsigned count;
72 unsigned wanted_bits;
73};
74
75
76/**
77 * get_decoder_data() - gets decoder data
78 * @input_dev: input device
79 *
80 * Returns the struct decoder_data that corresponds to a device
81 */
82static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
83{ 58{
84 struct decoder_data *data = NULL;
85
86 spin_lock(&decoder_lock);
87 list_for_each_entry(data, &decoder_list, list) {
88 if (data->ir_dev == ir_dev)
89 break;
90 }
91 spin_unlock(&decoder_lock);
92 return data;
93}
94
95static enum rc6_mode rc6_mode(struct decoder_data *data) {
96 switch (data->header & RC6_MODE_MASK) { 59 switch (data->header & RC6_MODE_MASK) {
97 case 0: 60 case 0:
98 return RC6_MODE_0; 61 return RC6_MODE_0;
@@ -114,15 +77,11 @@ static enum rc6_mode rc6_mode(struct decoder_data *data) {
114 */ 77 */
115static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev) 78static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
116{ 79{
117 struct decoder_data *data;
118 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); 80 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
81 struct rc6_dec *data = &ir_dev->raw->rc6;
119 u32 scancode; 82 u32 scancode;
120 u8 toggle; 83 u8 toggle;
121 84
122 data = get_decoder_data(ir_dev);
123 if (!data)
124 return -EINVAL;
125
126 if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6)) 85 if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
127 return 0; 86 return 0;
128 87
@@ -175,12 +134,11 @@ again:
175 if (ev.pulse) 134 if (ev.pulse)
176 data->header |= 1; 135 data->header |= 1;
177 data->count++; 136 data->count++;
178 data->prev_ev = ev;
179 data->state = STATE_HEADER_BIT_END; 137 data->state = STATE_HEADER_BIT_END;
180 return 0; 138 return 0;
181 139
182 case STATE_HEADER_BIT_END: 140 case STATE_HEADER_BIT_END:
183 if (!is_transition(&ev, &data->prev_ev)) 141 if (!is_transition(&ev, &ir_dev->raw->prev_ev))
184 break; 142 break;
185 143
186 if (data->count == RC6_HEADER_NBITS) 144 if (data->count == RC6_HEADER_NBITS)
@@ -196,12 +154,11 @@ again:
196 break; 154 break;
197 155
198 data->toggle = ev.pulse; 156 data->toggle = ev.pulse;
199 data->prev_ev = ev;
200 data->state = STATE_TOGGLE_END; 157 data->state = STATE_TOGGLE_END;
201 return 0; 158 return 0;
202 159
203 case STATE_TOGGLE_END: 160 case STATE_TOGGLE_END:
204 if (!is_transition(&ev, &data->prev_ev) || 161 if (!is_transition(&ev, &ir_dev->raw->prev_ev) ||
205 !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2)) 162 !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
206 break; 163 break;
207 164
@@ -211,7 +168,6 @@ again:
211 } 168 }
212 169
213 data->state = STATE_BODY_BIT_START; 170 data->state = STATE_BODY_BIT_START;
214 data->prev_ev = ev;
215 decrease_duration(&ev, RC6_TOGGLE_END); 171 decrease_duration(&ev, RC6_TOGGLE_END);
216 data->count = 0; 172 data->count = 0;
217 173
@@ -243,13 +199,11 @@ again:
243 if (ev.pulse) 199 if (ev.pulse)
244 data->body |= 1; 200 data->body |= 1;
245 data->count++; 201 data->count++;
246 data->prev_ev = ev;
247
248 data->state = STATE_BODY_BIT_END; 202 data->state = STATE_BODY_BIT_END;
249 return 0; 203 return 0;
250 204
251 case STATE_BODY_BIT_END: 205 case STATE_BODY_BIT_END:
252 if (!is_transition(&ev, &data->prev_ev)) 206 if (!is_transition(&ev, &ir_dev->raw->prev_ev))
253 break; 207 break;
254 208
255 if (data->count == data->wanted_bits) 209 if (data->count == data->wanted_bits)
@@ -300,45 +254,9 @@ out:
300 return -EINVAL; 254 return -EINVAL;
301} 255}
302 256
303static int ir_rc6_register(struct input_dev *input_dev)
304{
305 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
306 struct decoder_data *data;
307
308 data = kzalloc(sizeof(*data), GFP_KERNEL);
309 if (!data)
310 return -ENOMEM;
311
312 data->ir_dev = ir_dev;
313
314 spin_lock(&decoder_lock);
315 list_add_tail(&data->list, &decoder_list);
316 spin_unlock(&decoder_lock);
317
318 return 0;
319}
320
321static int ir_rc6_unregister(struct input_dev *input_dev)
322{
323 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
324 static struct decoder_data *data;
325
326 data = get_decoder_data(ir_dev);
327 if (!data)
328 return 0;
329
330 spin_lock(&decoder_lock);
331 list_del(&data->list);
332 spin_unlock(&decoder_lock);
333
334 return 0;
335}
336
337static struct ir_raw_handler rc6_handler = { 257static struct ir_raw_handler rc6_handler = {
338 .protocols = IR_TYPE_RC6, 258 .protocols = IR_TYPE_RC6,
339 .decode = ir_rc6_decode, 259 .decode = ir_rc6_decode,
340 .raw_register = ir_rc6_register,
341 .raw_unregister = ir_rc6_unregister,
342}; 260};
343 261
344static int __init ir_rc6_decode_init(void) 262static int __init ir_rc6_decode_init(void)