diff options
Diffstat (limited to 'drivers/media/IR/ir-rc5-decoder.c')
-rw-r--r-- | drivers/media/IR/ir-rc5-decoder.c | 104 |
1 files changed, 13 insertions, 91 deletions
diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/IR/ir-rc5-decoder.c index bdfa404a6537..df4770d978ad 100644 --- a/drivers/media/IR/ir-rc5-decoder.c +++ b/drivers/media/IR/ir-rc5-decoder.c | |||
@@ -30,10 +30,6 @@ | |||
30 | #define RC5_BIT_END (1 * RC5_UNIT) | 30 | #define RC5_BIT_END (1 * RC5_UNIT) |
31 | #define RC5X_SPACE (4 * RC5_UNIT) | 31 | #define RC5X_SPACE (4 * RC5_UNIT) |
32 | 32 | ||
33 | /* Used to register rc5_decoder clients */ | ||
34 | static LIST_HEAD(decoder_list); | ||
35 | static DEFINE_SPINLOCK(decoder_lock); | ||
36 | |||
37 | enum rc5_state { | 33 | enum rc5_state { |
38 | STATE_INACTIVE, | 34 | STATE_INACTIVE, |
39 | STATE_BIT_START, | 35 | STATE_BIT_START, |
@@ -42,39 +38,6 @@ enum rc5_state { | |||
42 | STATE_FINISHED, | 38 | STATE_FINISHED, |
43 | }; | 39 | }; |
44 | 40 | ||
45 | struct decoder_data { | ||
46 | struct list_head list; | ||
47 | struct ir_input_dev *ir_dev; | ||
48 | |||
49 | /* State machine control */ | ||
50 | enum rc5_state state; | ||
51 | u32 rc5_bits; | ||
52 | struct ir_raw_event prev_ev; | ||
53 | unsigned count; | ||
54 | unsigned wanted_bits; | ||
55 | }; | ||
56 | |||
57 | |||
58 | /** | ||
59 | * get_decoder_data() - gets decoder data | ||
60 | * @input_dev: input device | ||
61 | * | ||
62 | * Returns the struct decoder_data that corresponds to a device | ||
63 | */ | ||
64 | |||
65 | static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev) | ||
66 | { | ||
67 | struct decoder_data *data = NULL; | ||
68 | |||
69 | spin_lock(&decoder_lock); | ||
70 | list_for_each_entry(data, &decoder_list, list) { | ||
71 | if (data->ir_dev == ir_dev) | ||
72 | break; | ||
73 | } | ||
74 | spin_unlock(&decoder_lock); | ||
75 | return data; | ||
76 | } | ||
77 | |||
78 | /** | 41 | /** |
79 | * ir_rc5_decode() - Decode one RC-5 pulse or space | 42 | * ir_rc5_decode() - Decode one RC-5 pulse or space |
80 | * @input_dev: the struct input_dev descriptor of the device | 43 | * @input_dev: the struct input_dev descriptor of the device |
@@ -84,15 +47,11 @@ static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev) | |||
84 | */ | 47 | */ |
85 | static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev) | 48 | static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev) |
86 | { | 49 | { |
87 | struct decoder_data *data; | ||
88 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 50 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
51 | struct rc5_dec *data = &ir_dev->raw->rc5; | ||
89 | u8 toggle; | 52 | u8 toggle; |
90 | u32 scancode; | 53 | u32 scancode; |
91 | 54 | ||
92 | data = get_decoder_data(ir_dev); | ||
93 | if (!data) | ||
94 | return -EINVAL; | ||
95 | |||
96 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5)) | 55 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5)) |
97 | return 0; | 56 | return 0; |
98 | 57 | ||
@@ -128,16 +87,15 @@ again: | |||
128 | if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2)) | 87 | if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2)) |
129 | break; | 88 | break; |
130 | 89 | ||
131 | data->rc5_bits <<= 1; | 90 | data->bits <<= 1; |
132 | if (!ev.pulse) | 91 | if (!ev.pulse) |
133 | data->rc5_bits |= 1; | 92 | data->bits |= 1; |
134 | data->count++; | 93 | data->count++; |
135 | data->prev_ev = ev; | ||
136 | data->state = STATE_BIT_END; | 94 | data->state = STATE_BIT_END; |
137 | return 0; | 95 | return 0; |
138 | 96 | ||
139 | case STATE_BIT_END: | 97 | case STATE_BIT_END: |
140 | if (!is_transition(&ev, &data->prev_ev)) | 98 | if (!is_transition(&ev, &ir_dev->raw->prev_ev)) |
141 | break; | 99 | break; |
142 | 100 | ||
143 | if (data->count == data->wanted_bits) | 101 | if (data->count == data->wanted_bits) |
@@ -169,11 +127,11 @@ again: | |||
169 | if (data->wanted_bits == RC5X_NBITS) { | 127 | if (data->wanted_bits == RC5X_NBITS) { |
170 | /* RC5X */ | 128 | /* RC5X */ |
171 | u8 xdata, command, system; | 129 | u8 xdata, command, system; |
172 | xdata = (data->rc5_bits & 0x0003F) >> 0; | 130 | xdata = (data->bits & 0x0003F) >> 0; |
173 | command = (data->rc5_bits & 0x00FC0) >> 6; | 131 | command = (data->bits & 0x00FC0) >> 6; |
174 | system = (data->rc5_bits & 0x1F000) >> 12; | 132 | system = (data->bits & 0x1F000) >> 12; |
175 | toggle = (data->rc5_bits & 0x20000) ? 1 : 0; | 133 | toggle = (data->bits & 0x20000) ? 1 : 0; |
176 | command += (data->rc5_bits & 0x01000) ? 0 : 0x40; | 134 | command += (data->bits & 0x01000) ? 0 : 0x40; |
177 | scancode = system << 16 | command << 8 | xdata; | 135 | scancode = system << 16 | command << 8 | xdata; |
178 | 136 | ||
179 | IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n", | 137 | IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n", |
@@ -182,10 +140,10 @@ again: | |||
182 | } else { | 140 | } else { |
183 | /* RC5 */ | 141 | /* RC5 */ |
184 | u8 command, system; | 142 | u8 command, system; |
185 | command = (data->rc5_bits & 0x0003F) >> 0; | 143 | command = (data->bits & 0x0003F) >> 0; |
186 | system = (data->rc5_bits & 0x007C0) >> 6; | 144 | system = (data->bits & 0x007C0) >> 6; |
187 | toggle = (data->rc5_bits & 0x00800) ? 1 : 0; | 145 | toggle = (data->bits & 0x00800) ? 1 : 0; |
188 | command += (data->rc5_bits & 0x01000) ? 0 : 0x40; | 146 | command += (data->bits & 0x01000) ? 0 : 0x40; |
189 | scancode = system << 8 | command; | 147 | scancode = system << 8 | command; |
190 | 148 | ||
191 | IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n", | 149 | IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n", |
@@ -204,45 +162,9 @@ out: | |||
204 | return -EINVAL; | 162 | return -EINVAL; |
205 | } | 163 | } |
206 | 164 | ||
207 | static int ir_rc5_register(struct input_dev *input_dev) | ||
208 | { | ||
209 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | ||
210 | struct decoder_data *data; | ||
211 | |||
212 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
213 | if (!data) | ||
214 | return -ENOMEM; | ||
215 | |||
216 | data->ir_dev = ir_dev; | ||
217 | |||
218 | spin_lock(&decoder_lock); | ||
219 | list_add_tail(&data->list, &decoder_list); | ||
220 | spin_unlock(&decoder_lock); | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static int ir_rc5_unregister(struct input_dev *input_dev) | ||
226 | { | ||
227 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | ||
228 | static struct decoder_data *data; | ||
229 | |||
230 | data = get_decoder_data(ir_dev); | ||
231 | if (!data) | ||
232 | return 0; | ||
233 | |||
234 | spin_lock(&decoder_lock); | ||
235 | list_del(&data->list); | ||
236 | spin_unlock(&decoder_lock); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static struct ir_raw_handler rc5_handler = { | 165 | static struct ir_raw_handler rc5_handler = { |
242 | .protocols = IR_TYPE_RC5, | 166 | .protocols = IR_TYPE_RC5, |
243 | .decode = ir_rc5_decode, | 167 | .decode = ir_rc5_decode, |
244 | .raw_register = ir_rc5_register, | ||
245 | .raw_unregister = ir_rc5_unregister, | ||
246 | }; | 168 | }; |
247 | 169 | ||
248 | static int __init ir_rc5_decode_init(void) | 170 | static int __init ir_rc5_decode_init(void) |