aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR/ir-raw-event.c
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2010-06-13 16:29:31 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-02 13:54:27 -0400
commit667c9ebe97f7e5f1e48e7eb321644c6fb1668de5 (patch)
tree11dae4e3d480960fe697964776222b16ee0ecce8 /drivers/media/IR/ir-raw-event.c
parent0dc50942d6f23989ffb3024aa2271941ec44aea8 (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.c112
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 */
24static LIST_HEAD(ir_raw_handler_list);
25static DEFINE_SPINLOCK(ir_raw_handler_lock); 24static DEFINE_SPINLOCK(ir_raw_handler_lock);
25static LIST_HEAD(ir_raw_handler_list);
26static 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
67int 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
98void 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}
204EXPORT_SYMBOL_GPL(ir_raw_event_handle); 159EXPORT_SYMBOL_GPL(ir_raw_event_handle);
205 160
161/* used internally by the sysfs interface */
162u64
163ir_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 */
175int 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
206void 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}
217EXPORT_SYMBOL(ir_raw_handler_register); 234EXPORT_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}
225EXPORT_SYMBOL(ir_raw_handler_unregister); 243EXPORT_SYMBOL(ir_raw_handler_unregister);