diff options
author | David Härdeman <david@hardeman.nu> | 2010-06-13 16:29:31 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-02 13:54:27 -0400 |
commit | 667c9ebe97f7e5f1e48e7eb321644c6fb1668de5 (patch) | |
tree | 11dae4e3d480960fe697964776222b16ee0ecce8 /drivers/media/IR/ir-raw-event.c | |
parent | 0dc50942d6f23989ffb3024aa2271941ec44aea8 (diff) |
V4L/DVB: ir-core: centralize sysfs raw decoder enabling/disabling
With the current logic, each raw decoder needs to add a copy of the exact
same sysfs code. This is both unnecessary and also means that (re)loading
an IR driver after raw decoder modules have been loaded won't work as
expected.
This patch moves that logic into ir-raw-event and adds a single sysfs
file per device.
Reading that file returns something like:
"rc5 [rc6] nec jvc [sony]"
(with enabled protocols in [] brackets)
Writing either "+protocol" or "-protocol" to that file will
enable or disable the according protocol decoder.
An additional benefit is that the disabling of a decoder will be
remembered across module removal/insertion so a previously
disabled decoder won't suddenly be activated again. The default
setting is to enable all decoders.
This is also necessary for the next patch which moves even more decoder
state into the central raw decoding structs.
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-raw-event.c')
-rw-r--r-- | drivers/media/IR/ir-raw-event.c | 112 |
1 files changed, 65 insertions, 47 deletions
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c index d3bd3f98e008..fb3336c37191 100644 --- a/drivers/media/IR/ir-raw-event.c +++ b/drivers/media/IR/ir-raw-event.c | |||
@@ -21,8 +21,9 @@ | |||
21 | #define MAX_IR_EVENT_SIZE 512 | 21 | #define MAX_IR_EVENT_SIZE 512 |
22 | 22 | ||
23 | /* Used to handle IR raw handler extensions */ | 23 | /* Used to handle IR raw handler extensions */ |
24 | static LIST_HEAD(ir_raw_handler_list); | ||
25 | static DEFINE_SPINLOCK(ir_raw_handler_lock); | 24 | static DEFINE_SPINLOCK(ir_raw_handler_lock); |
25 | static LIST_HEAD(ir_raw_handler_list); | ||
26 | static u64 available_protocols; | ||
26 | 27 | ||
27 | /** | 28 | /** |
28 | * RUN_DECODER() - runs an operation on all IR decoders | 29 | * RUN_DECODER() - runs an operation on all IR decoders |
@@ -64,52 +65,6 @@ static void ir_raw_event_work(struct work_struct *work) | |||
64 | RUN_DECODER(decode, raw->input_dev, ev); | 65 | RUN_DECODER(decode, raw->input_dev, ev); |
65 | } | 66 | } |
66 | 67 | ||
67 | int ir_raw_event_register(struct input_dev *input_dev) | ||
68 | { | ||
69 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | ||
70 | int rc; | ||
71 | |||
72 | ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL); | ||
73 | if (!ir->raw) | ||
74 | return -ENOMEM; | ||
75 | |||
76 | ir->raw->input_dev = input_dev; | ||
77 | INIT_WORK(&ir->raw->rx_work, ir_raw_event_work); | ||
78 | |||
79 | rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE, | ||
80 | GFP_KERNEL); | ||
81 | if (rc < 0) { | ||
82 | kfree(ir->raw); | ||
83 | ir->raw = NULL; | ||
84 | return rc; | ||
85 | } | ||
86 | |||
87 | rc = RUN_DECODER(raw_register, input_dev); | ||
88 | if (rc < 0) { | ||
89 | kfifo_free(&ir->raw->kfifo); | ||
90 | kfree(ir->raw); | ||
91 | ir->raw = NULL; | ||
92 | return rc; | ||
93 | } | ||
94 | |||
95 | return rc; | ||
96 | } | ||
97 | |||
98 | void ir_raw_event_unregister(struct input_dev *input_dev) | ||
99 | { | ||
100 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | ||
101 | |||
102 | if (!ir->raw) | ||
103 | return; | ||
104 | |||
105 | cancel_work_sync(&ir->raw->rx_work); | ||
106 | RUN_DECODER(raw_unregister, input_dev); | ||
107 | |||
108 | kfifo_free(&ir->raw->kfifo); | ||
109 | kfree(ir->raw); | ||
110 | ir->raw = NULL; | ||
111 | } | ||
112 | |||
113 | /** | 68 | /** |
114 | * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders | 69 | * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders |
115 | * @input_dev: the struct input_dev device descriptor | 70 | * @input_dev: the struct input_dev device descriptor |
@@ -203,6 +158,66 @@ void ir_raw_event_handle(struct input_dev *input_dev) | |||
203 | } | 158 | } |
204 | EXPORT_SYMBOL_GPL(ir_raw_event_handle); | 159 | EXPORT_SYMBOL_GPL(ir_raw_event_handle); |
205 | 160 | ||
161 | /* used internally by the sysfs interface */ | ||
162 | u64 | ||
163 | ir_raw_get_allowed_protocols() | ||
164 | { | ||
165 | u64 protocols; | ||
166 | spin_lock(&ir_raw_handler_lock); | ||
167 | protocols = available_protocols; | ||
168 | spin_unlock(&ir_raw_handler_lock); | ||
169 | return protocols; | ||
170 | } | ||
171 | |||
172 | /* | ||
173 | * Used to (un)register raw event clients | ||
174 | */ | ||
175 | int ir_raw_event_register(struct input_dev *input_dev) | ||
176 | { | ||
177 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | ||
178 | int rc; | ||
179 | |||
180 | ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL); | ||
181 | if (!ir->raw) | ||
182 | return -ENOMEM; | ||
183 | |||
184 | ir->raw->input_dev = input_dev; | ||
185 | INIT_WORK(&ir->raw->rx_work, ir_raw_event_work); | ||
186 | ir->raw->enabled_protocols = ~0; | ||
187 | rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE, | ||
188 | GFP_KERNEL); | ||
189 | if (rc < 0) { | ||
190 | kfree(ir->raw); | ||
191 | ir->raw = NULL; | ||
192 | return rc; | ||
193 | } | ||
194 | |||
195 | rc = RUN_DECODER(raw_register, input_dev); | ||
196 | if (rc < 0) { | ||
197 | kfifo_free(&ir->raw->kfifo); | ||
198 | kfree(ir->raw); | ||
199 | ir->raw = NULL; | ||
200 | return rc; | ||
201 | } | ||
202 | |||
203 | return rc; | ||
204 | } | ||
205 | |||
206 | void ir_raw_event_unregister(struct input_dev *input_dev) | ||
207 | { | ||
208 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | ||
209 | |||
210 | if (!ir->raw) | ||
211 | return; | ||
212 | |||
213 | cancel_work_sync(&ir->raw->rx_work); | ||
214 | RUN_DECODER(raw_unregister, input_dev); | ||
215 | |||
216 | kfifo_free(&ir->raw->kfifo); | ||
217 | kfree(ir->raw); | ||
218 | ir->raw = NULL; | ||
219 | } | ||
220 | |||
206 | /* | 221 | /* |
207 | * Extension interface - used to register the IR decoders | 222 | * Extension interface - used to register the IR decoders |
208 | */ | 223 | */ |
@@ -211,7 +226,9 @@ int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) | |||
211 | { | 226 | { |
212 | spin_lock(&ir_raw_handler_lock); | 227 | spin_lock(&ir_raw_handler_lock); |
213 | list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); | 228 | list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); |
229 | available_protocols |= ir_raw_handler->protocols; | ||
214 | spin_unlock(&ir_raw_handler_lock); | 230 | spin_unlock(&ir_raw_handler_lock); |
231 | |||
215 | return 0; | 232 | return 0; |
216 | } | 233 | } |
217 | EXPORT_SYMBOL(ir_raw_handler_register); | 234 | EXPORT_SYMBOL(ir_raw_handler_register); |
@@ -220,6 +237,7 @@ void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) | |||
220 | { | 237 | { |
221 | spin_lock(&ir_raw_handler_lock); | 238 | spin_lock(&ir_raw_handler_lock); |
222 | list_del(&ir_raw_handler->list); | 239 | list_del(&ir_raw_handler->list); |
240 | available_protocols &= ~ir_raw_handler->protocols; | ||
223 | spin_unlock(&ir_raw_handler_lock); | 241 | spin_unlock(&ir_raw_handler_lock); |
224 | } | 242 | } |
225 | EXPORT_SYMBOL(ir_raw_handler_unregister); | 243 | EXPORT_SYMBOL(ir_raw_handler_unregister); |