diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-03-24 19:47:53 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-17 23:52:59 -0400 |
commit | 995187bed30c0545e8da88372e9807da0a85911e (patch) | |
tree | e3e28eff10f8f01f1bfd7ff865a29076bf6700dc /drivers | |
parent | 9f1547829a6f39fe6b2da22653dff40502f3d568 (diff) |
V4L/DVB: ir-core: dynamically load the compiled IR protocols
Instead of hardcoding the protocols into ir-core, add a register interface
for the IR protocol decoders, and convert ir-nec-decoder into a client of
ir-core.
With this approach, it is possible to dynamically load the needed IR protocols,
and to add a RAW IR interface module, registered as one IR raw protocol decoder.
This patch opens a way to register a lirc_dev interface to work as an userspace
IR protocol decoder.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/IR/Kconfig | 9 | ||||
-rw-r--r-- | drivers/media/IR/Makefile | 3 | ||||
-rw-r--r-- | drivers/media/IR/ir-nec-decoder.c | 35 | ||||
-rw-r--r-- | drivers/media/IR/ir-raw-event.c | 57 | ||||
-rw-r--r-- | drivers/media/IR/ir-sysfs.c | 7 |
5 files changed, 101 insertions, 10 deletions
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig index 4dde7d180a32..de410d46ae26 100644 --- a/drivers/media/IR/Kconfig +++ b/drivers/media/IR/Kconfig | |||
@@ -7,3 +7,12 @@ config VIDEO_IR | |||
7 | tristate | 7 | tristate |
8 | depends on IR_CORE | 8 | depends on IR_CORE |
9 | default IR_CORE | 9 | default IR_CORE |
10 | |||
11 | config IR_NEC_DECODER | ||
12 | tristate "Enable IR raw decoder for NEC protocol" | ||
13 | depends on IR_CORE | ||
14 | default y | ||
15 | |||
16 | ---help--- | ||
17 | Enable this option if you have IR with NEC protocol, and | ||
18 | if the IR is decoded in software | ||
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile index 18794c7b0ea6..6140b2712c8a 100644 --- a/drivers/media/IR/Makefile +++ b/drivers/media/IR/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | ir-common-objs := ir-functions.o ir-keymaps.o | 1 | ir-common-objs := ir-functions.o ir-keymaps.o |
2 | ir-core-objs := ir-keytable.o ir-sysfs.o ir-raw-event.o ir-nec-decoder.o | 2 | ir-core-objs := ir-keytable.o ir-sysfs.o ir-raw-event.o |
3 | 3 | ||
4 | obj-$(CONFIG_IR_CORE) += ir-core.o | 4 | obj-$(CONFIG_IR_CORE) += ir-core.o |
5 | obj-$(CONFIG_VIDEO_IR) += ir-common.o | 5 | obj-$(CONFIG_VIDEO_IR) += ir-common.o |
6 | obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o | ||
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c index 104482a6991e..c9a986dd57fd 100644 --- a/drivers/media/IR/ir-nec-decoder.c +++ b/drivers/media/IR/ir-nec-decoder.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* ir-raw-event.c - handle IR Pulse/Space event | 1 | /* ir-nec-decoder.c - handle NEC IR Pulse/Space protocol |
2 | * | 2 | * |
3 | * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> | 3 | * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> |
4 | * | 4 | * |
@@ -147,7 +147,7 @@ static int __ir_nec_decode(struct input_dev *input_dev, | |||
147 | if (++count == 32) | 147 | if (++count == 32) |
148 | break; | 148 | break; |
149 | } | 149 | } |
150 | *pos++; | 150 | (*pos)++; |
151 | 151 | ||
152 | /* | 152 | /* |
153 | * Fixme: may need to accept Extended NEC protocol? | 153 | * Fixme: may need to accept Extended NEC protocol? |
@@ -181,9 +181,9 @@ err: | |||
181 | * This function returns the number of decoded pulses or -EINVAL if no | 181 | * This function returns the number of decoded pulses or -EINVAL if no |
182 | * pulse got decoded | 182 | * pulse got decoded |
183 | */ | 183 | */ |
184 | int ir_nec_decode(struct input_dev *input_dev, | 184 | static int ir_nec_decode(struct input_dev *input_dev, |
185 | struct ir_raw_event *evs, | 185 | struct ir_raw_event *evs, |
186 | int len) | 186 | int len) |
187 | { | 187 | { |
188 | int pos = 0; | 188 | int pos = 0; |
189 | int rc = 0; | 189 | int rc = 0; |
@@ -198,4 +198,27 @@ int ir_nec_decode(struct input_dev *input_dev, | |||
198 | return rc; | 198 | return rc; |
199 | } | 199 | } |
200 | 200 | ||
201 | EXPORT_SYMBOL_GPL(ir_nec_decode); | 201 | static struct ir_raw_handler nec_handler = { |
202 | .decode = ir_nec_decode, | ||
203 | }; | ||
204 | |||
205 | static int __init ir_nec_decode_init(void) | ||
206 | { | ||
207 | ir_raw_handler_register(&nec_handler); | ||
208 | |||
209 | printk(KERN_INFO "IR NEC protocol handler initialized\n"); | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | static void __exit ir_nec_decode_exit(void) | ||
214 | { | ||
215 | ir_raw_handler_unregister(&nec_handler); | ||
216 | } | ||
217 | |||
218 | module_init(ir_nec_decode_init); | ||
219 | module_exit(ir_nec_decode_exit); | ||
220 | |||
221 | MODULE_LICENSE("GPL"); | ||
222 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | ||
223 | MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); | ||
224 | MODULE_DESCRIPTION("NEC IR protocol decoder"); | ||
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c index 0ae55433cef9..3eae128400ea 100644 --- a/drivers/media/IR/ir-raw-event.c +++ b/drivers/media/IR/ir-raw-event.c | |||
@@ -13,10 +13,18 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <media/ir-core.h> | 15 | #include <media/ir-core.h> |
16 | #include <linux/workqueue.h> | ||
16 | 17 | ||
17 | /* Define the max number of bit transitions per IR keycode */ | 18 | /* Define the max number of bit transitions per IR keycode */ |
18 | #define MAX_IR_EVENT_SIZE 256 | 19 | #define MAX_IR_EVENT_SIZE 256 |
19 | 20 | ||
21 | /* Used to handle IR raw handler extensions */ | ||
22 | static LIST_HEAD(ir_raw_handler_list); | ||
23 | static DEFINE_MUTEX(ir_raw_handler_lock); | ||
24 | |||
25 | /* Used to load the decoders */ | ||
26 | static struct work_struct wq_load; | ||
27 | |||
20 | static void ir_keyup_timer(unsigned long data) | 28 | static void ir_keyup_timer(unsigned long data) |
21 | { | 29 | { |
22 | struct input_dev *input_dev = (struct input_dev *)data; | 30 | struct input_dev *input_dev = (struct input_dev *)data; |
@@ -101,6 +109,7 @@ int ir_raw_event_handle(struct input_dev *input_dev) | |||
101 | int rc; | 109 | int rc; |
102 | struct ir_raw_event *evs; | 110 | struct ir_raw_event *evs; |
103 | int len, i; | 111 | int len, i; |
112 | struct ir_raw_handler *ir_raw_handler; | ||
104 | 113 | ||
105 | /* | 114 | /* |
106 | * Store the events into a temporary buffer. This allows calling more than | 115 | * Store the events into a temporary buffer. This allows calling more than |
@@ -122,10 +131,56 @@ int ir_raw_event_handle(struct input_dev *input_dev) | |||
122 | evs[i].type, (evs[i].delta.tv_nsec + 500) / 1000); | 131 | evs[i].type, (evs[i].delta.tv_nsec + 500) / 1000); |
123 | } | 132 | } |
124 | 133 | ||
125 | rc = ir_nec_decode(input_dev, evs, len); | 134 | /* |
135 | * Call all ir decoders. This allows decoding the same event with | ||
136 | * more than one protocol handler. | ||
137 | * FIXME: better handle the returned code: does it make sense to use | ||
138 | * other decoders, if the first one already handled the IR? | ||
139 | */ | ||
140 | list_for_each_entry(ir_raw_handler, &ir_raw_handler_list, list) { | ||
141 | rc = ir_raw_handler->decode(input_dev, evs, len); | ||
142 | } | ||
126 | 143 | ||
127 | kfree(evs); | 144 | kfree(evs); |
128 | 145 | ||
129 | return rc; | 146 | return rc; |
130 | } | 147 | } |
131 | EXPORT_SYMBOL_GPL(ir_raw_event_handle); | 148 | EXPORT_SYMBOL_GPL(ir_raw_event_handle); |
149 | |||
150 | /* | ||
151 | * Extension interface - used to register the IR decoders | ||
152 | */ | ||
153 | |||
154 | int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) | ||
155 | { | ||
156 | mutex_lock(&ir_raw_handler_lock); | ||
157 | list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); | ||
158 | mutex_unlock(&ir_raw_handler_lock); | ||
159 | return 0; | ||
160 | } | ||
161 | EXPORT_SYMBOL(ir_raw_handler_register); | ||
162 | |||
163 | void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) | ||
164 | { | ||
165 | mutex_lock(&ir_raw_handler_lock); | ||
166 | list_del(&ir_raw_handler->list); | ||
167 | mutex_unlock(&ir_raw_handler_lock); | ||
168 | } | ||
169 | EXPORT_SYMBOL(ir_raw_handler_unregister); | ||
170 | |||
171 | static void init_decoders(struct work_struct *work) | ||
172 | { | ||
173 | /* Load the decoder modules */ | ||
174 | |||
175 | load_nec_decode(); | ||
176 | |||
177 | /* If needed, we may later add some init code. In this case, | ||
178 | it is needed to change the CONFIG_MODULE test at ir-core.h | ||
179 | */ | ||
180 | } | ||
181 | |||
182 | void ir_raw_init(void) | ||
183 | { | ||
184 | INIT_WORK(&wq_load, init_decoders); | ||
185 | schedule_work(&wq_load); | ||
186 | } \ No newline at end of file | ||
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c index 253e66999f18..2279d5594b05 100644 --- a/drivers/media/IR/ir-sysfs.c +++ b/drivers/media/IR/ir-sysfs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* ir-register.c - handle IR scancode->keycode tables | 1 | /* ir-register.c - handle IR scancode->keycode tables |
2 | * | 2 | * |
3 | * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com> | 3 | * Copyright (C) 2009-2010 by Mauro Carvalho Chehab <mchehab@redhat.com> |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
@@ -28,7 +28,7 @@ static char *ir_devnode(struct device *dev, mode_t *mode) | |||
28 | return kasprintf(GFP_KERNEL, "irrcv/%s", dev_name(dev)); | 28 | return kasprintf(GFP_KERNEL, "irrcv/%s", dev_name(dev)); |
29 | } | 29 | } |
30 | 30 | ||
31 | struct class ir_input_class = { | 31 | static struct class ir_input_class = { |
32 | .name = "irrcv", | 32 | .name = "irrcv", |
33 | .devnode = ir_devnode, | 33 | .devnode = ir_devnode, |
34 | }; | 34 | }; |
@@ -251,6 +251,9 @@ static int __init ir_core_init(void) | |||
251 | return rc; | 251 | return rc; |
252 | } | 252 | } |
253 | 253 | ||
254 | /* Initialize/load the decoders that will be used */ | ||
255 | ir_raw_init(); | ||
256 | |||
254 | return 0; | 257 | return 0; |
255 | } | 258 | } |
256 | 259 | ||