aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR/ir-raw-event.c
diff options
context:
space:
mode:
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);