diff options
author | David Härdeman <david@hardeman.nu> | 2010-06-13 16:29:36 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-02 13:55:15 -0400 |
commit | c216369e61fae586cd48c0913cca2a37fbfeb912 (patch) | |
tree | c4dfc55e6b4673a2e5698bd1f8aa8ae3919f57f7 /drivers/media/IR/ir-nec-decoder.c | |
parent | de8592bd539b2bb8da2b55b1007562eb1abd1fe6 (diff) |
V4L/DVB: ir-core: move decoding state to ir_raw_event_ctrl
This patch moves the state from each raw decoder into the
ir_raw_event_ctrl struct.
This allows the removal of code like this:
spin_lock(&decoder_lock);
list_for_each_entry(data, &decoder_list, list) {
if (data->ir_dev == ir_dev)
break;
}
spin_unlock(&decoder_lock);
return data;
which is currently run for each decoder on each event in order
to get the client-specific decoding state data.
In addition, ir decoding modules and ir driver module load
order is now independent. Centralizing the data also allows
for a nice code reduction of about 30% per raw decoder as
client lists and client registration callbacks are no longer
necessary (but still kept around for the benefit of the lirc
decoder).
Out-of-tree modules can still use a similar trick to what
the raw decoders did before this patch until they are merged.
Signed-off-by: David Härdeman <david@hardeman.nu>
Acked-by: Jarod Wilson <jarod@redhat.com>
Tested-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/IR/ir-nec-decoder.c')
-rw-r--r-- | drivers/media/IR/ir-nec-decoder.c | 90 |
1 files changed, 8 insertions, 82 deletions
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c index db62c652dfc5..52e0f378ae3d 100644 --- a/drivers/media/IR/ir-nec-decoder.c +++ b/drivers/media/IR/ir-nec-decoder.c | |||
@@ -27,10 +27,6 @@ | |||
27 | #define NEC_TRAILER_PULSE (1 * NEC_UNIT) | 27 | #define NEC_TRAILER_PULSE (1 * NEC_UNIT) |
28 | #define NEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */ | 28 | #define NEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */ |
29 | 29 | ||
30 | /* Used to register nec_decoder clients */ | ||
31 | static LIST_HEAD(decoder_list); | ||
32 | static DEFINE_SPINLOCK(decoder_lock); | ||
33 | |||
34 | enum nec_state { | 30 | enum nec_state { |
35 | STATE_INACTIVE, | 31 | STATE_INACTIVE, |
36 | STATE_HEADER_SPACE, | 32 | STATE_HEADER_SPACE, |
@@ -40,36 +36,6 @@ enum nec_state { | |||
40 | STATE_TRAILER_SPACE, | 36 | STATE_TRAILER_SPACE, |
41 | }; | 37 | }; |
42 | 38 | ||
43 | struct decoder_data { | ||
44 | struct list_head list; | ||
45 | struct ir_input_dev *ir_dev; | ||
46 | |||
47 | /* State machine control */ | ||
48 | enum nec_state state; | ||
49 | u32 nec_bits; | ||
50 | unsigned count; | ||
51 | }; | ||
52 | |||
53 | |||
54 | /** | ||
55 | * get_decoder_data() - gets decoder data | ||
56 | * @input_dev: input device | ||
57 | * | ||
58 | * Returns the struct decoder_data that corresponds to a device | ||
59 | */ | ||
60 | static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev) | ||
61 | { | ||
62 | struct decoder_data *data = NULL; | ||
63 | |||
64 | spin_lock(&decoder_lock); | ||
65 | list_for_each_entry(data, &decoder_list, list) { | ||
66 | if (data->ir_dev == ir_dev) | ||
67 | break; | ||
68 | } | ||
69 | spin_unlock(&decoder_lock); | ||
70 | return data; | ||
71 | } | ||
72 | |||
73 | /** | 39 | /** |
74 | * ir_nec_decode() - Decode one NEC pulse or space | 40 | * ir_nec_decode() - Decode one NEC pulse or space |
75 | * @input_dev: the struct input_dev descriptor of the device | 41 | * @input_dev: the struct input_dev descriptor of the device |
@@ -79,15 +45,11 @@ static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev) | |||
79 | */ | 45 | */ |
80 | static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) | 46 | static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) |
81 | { | 47 | { |
82 | struct decoder_data *data; | ||
83 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 48 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
49 | struct nec_dec *data = &ir_dev->raw->nec; | ||
84 | u32 scancode; | 50 | u32 scancode; |
85 | u8 address, not_address, command, not_command; | 51 | u8 address, not_address, command, not_command; |
86 | 52 | ||
87 | data = get_decoder_data(ir_dev); | ||
88 | if (!data) | ||
89 | return -EINVAL; | ||
90 | |||
91 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC)) | 53 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC)) |
92 | return 0; | 54 | return 0; |
93 | 55 | ||
@@ -143,9 +105,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
143 | if (ev.pulse) | 105 | if (ev.pulse) |
144 | break; | 106 | break; |
145 | 107 | ||
146 | data->nec_bits <<= 1; | 108 | data->bits <<= 1; |
147 | if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2)) | 109 | if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2)) |
148 | data->nec_bits |= 1; | 110 | data->bits |= 1; |
149 | else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2)) | 111 | else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2)) |
150 | break; | 112 | break; |
151 | data->count++; | 113 | data->count++; |
@@ -174,14 +136,14 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
174 | if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2)) | 136 | if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2)) |
175 | break; | 137 | break; |
176 | 138 | ||
177 | address = bitrev8((data->nec_bits >> 24) & 0xff); | 139 | address = bitrev8((data->bits >> 24) & 0xff); |
178 | not_address = bitrev8((data->nec_bits >> 16) & 0xff); | 140 | not_address = bitrev8((data->bits >> 16) & 0xff); |
179 | command = bitrev8((data->nec_bits >> 8) & 0xff); | 141 | command = bitrev8((data->bits >> 8) & 0xff); |
180 | not_command = bitrev8((data->nec_bits >> 0) & 0xff); | 142 | not_command = bitrev8((data->bits >> 0) & 0xff); |
181 | 143 | ||
182 | if ((command ^ not_command) != 0xff) { | 144 | if ((command ^ not_command) != 0xff) { |
183 | IR_dprintk(1, "NEC checksum error: received 0x%08x\n", | 145 | IR_dprintk(1, "NEC checksum error: received 0x%08x\n", |
184 | data->nec_bits); | 146 | data->bits); |
185 | break; | 147 | break; |
186 | } | 148 | } |
187 | 149 | ||
@@ -208,45 +170,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
208 | return -EINVAL; | 170 | return -EINVAL; |
209 | } | 171 | } |
210 | 172 | ||
211 | static int ir_nec_register(struct input_dev *input_dev) | ||
212 | { | ||
213 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | ||
214 | struct decoder_data *data; | ||
215 | |||
216 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
217 | if (!data) | ||
218 | return -ENOMEM; | ||
219 | |||
220 | data->ir_dev = ir_dev; | ||
221 | |||
222 | spin_lock(&decoder_lock); | ||
223 | list_add_tail(&data->list, &decoder_list); | ||
224 | spin_unlock(&decoder_lock); | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static int ir_nec_unregister(struct input_dev *input_dev) | ||
230 | { | ||
231 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | ||
232 | static struct decoder_data *data; | ||
233 | |||
234 | data = get_decoder_data(ir_dev); | ||
235 | if (!data) | ||
236 | return 0; | ||
237 | |||
238 | spin_lock(&decoder_lock); | ||
239 | list_del(&data->list); | ||
240 | spin_unlock(&decoder_lock); | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static struct ir_raw_handler nec_handler = { | 173 | static struct ir_raw_handler nec_handler = { |
246 | .protocols = IR_TYPE_NEC, | 174 | .protocols = IR_TYPE_NEC, |
247 | .decode = ir_nec_decode, | 175 | .decode = ir_nec_decode, |
248 | .raw_register = ir_nec_register, | ||
249 | .raw_unregister = ir_nec_unregister, | ||
250 | }; | 176 | }; |
251 | 177 | ||
252 | static int __init ir_nec_decode_init(void) | 178 | static int __init ir_nec_decode_init(void) |