diff options
Diffstat (limited to 'drivers/media/IR/ir-rc6-decoder.c')
-rw-r--r-- | drivers/media/IR/ir-rc6-decoder.c | 92 |
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 */ | ||
40 | static LIST_HEAD(decoder_list); | ||
41 | static DEFINE_SPINLOCK(decoder_lock); | ||
42 | |||
43 | enum rc6_mode { | 39 | enum 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 | ||
61 | struct decoder_data { | 57 | static 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 | */ | ||
82 | static 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 | |||
95 | static 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 | */ |
115 | static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev) | 78 | static 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 | ||
303 | static 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 | |||
321 | static 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 | |||
337 | static struct ir_raw_handler rc6_handler = { | 257 | static 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 | ||
344 | static int __init ir_rc6_decode_init(void) | 262 | static int __init ir_rc6_decode_init(void) |