• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/media/IR/
1/* ir-raw-event.c - handle IR Pulse/Space event
2 *
3 * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 *
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
7 *  the Free Software Foundation version 2 of the License.
8 *
9 *  This program is distributed in the hope that it will be useful,
10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 *  GNU General Public License for more details.
13 */
14
15#include <linux/kthread.h>
16#include <linux/mutex.h>
17#include <linux/sched.h>
18#include <linux/freezer.h>
19#include "ir-core-priv.h"
20
21/* Define the max number of pulse/space transitions to buffer */
22#define MAX_IR_EVENT_SIZE      512
23
24/* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */
25static LIST_HEAD(ir_raw_client_list);
26
27/* Used to handle IR raw handler extensions */
28static DEFINE_MUTEX(ir_raw_handler_lock);
29static LIST_HEAD(ir_raw_handler_list);
30static u64 available_protocols;
31
32#ifdef MODULE
33/* Used to load the decoders */
34static struct work_struct wq_load;
35#endif
36
37static int ir_raw_event_thread(void *data)
38{
39	struct ir_raw_event ev;
40	struct ir_raw_handler *handler;
41	struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data;
42
43	while (!kthread_should_stop()) {
44		try_to_freeze();
45
46		mutex_lock(&ir_raw_handler_lock);
47
48		while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) {
49			list_for_each_entry(handler, &ir_raw_handler_list, list)
50				handler->decode(raw->input_dev, ev);
51			raw->prev_ev = ev;
52		}
53
54		mutex_unlock(&ir_raw_handler_lock);
55
56		set_current_state(TASK_INTERRUPTIBLE);
57		schedule();
58	}
59
60	return 0;
61}
62
63/**
64 * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders
65 * @input_dev:	the struct input_dev device descriptor
66 * @ev:		the struct ir_raw_event descriptor of the pulse/space
67 *
68 * This routine (which may be called from an interrupt context) stores a
69 * pulse/space duration for the raw ir decoding state machines. Pulses are
70 * signalled as positive values and spaces as negative values. A zero value
71 * will reset the decoding state machines.
72 */
73int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev)
74{
75	struct ir_input_dev *ir = input_get_drvdata(input_dev);
76
77	if (!ir->raw)
78		return -EINVAL;
79
80	IR_dprintk(2, "sample: (05%dus %s)\n",
81		TO_US(ev->duration), TO_STR(ev->pulse));
82
83	if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
84		return -ENOMEM;
85
86	return 0;
87}
88EXPORT_SYMBOL_GPL(ir_raw_event_store);
89
90/**
91 * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space
92 * @input_dev:	the struct input_dev device descriptor
93 * @type:	the type of the event that has occurred
94 *
95 * This routine (which may be called from an interrupt context) is used to
96 * store the beginning of an ir pulse or space (or the start/end of ir
97 * reception) for the raw ir decoding state machines. This is used by
98 * hardware which does not provide durations directly but only interrupts
99 * (or similar events) on state change.
100 */
101int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type)
102{
103	struct ir_input_dev	*ir = input_get_drvdata(input_dev);
104	ktime_t			now;
105	s64			delta; /* ns */
106	struct ir_raw_event	ev;
107	int			rc = 0;
108
109	if (!ir->raw)
110		return -EINVAL;
111
112	now = ktime_get();
113	delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
114
115	/* Check for a long duration since last event or if we're
116	 * being called for the first time, note that delta can't
117	 * possibly be negative.
118	 */
119	ev.duration = 0;
120	if (delta > IR_MAX_DURATION || !ir->raw->last_type)
121		type |= IR_START_EVENT;
122	else
123		ev.duration = delta;
124
125	if (type & IR_START_EVENT)
126		ir_raw_event_reset(input_dev);
127	else if (ir->raw->last_type & IR_SPACE) {
128		ev.pulse = false;
129		rc = ir_raw_event_store(input_dev, &ev);
130	} else if (ir->raw->last_type & IR_PULSE) {
131		ev.pulse = true;
132		rc = ir_raw_event_store(input_dev, &ev);
133	} else
134		return 0;
135
136	ir->raw->last_event = now;
137	ir->raw->last_type = type;
138	return rc;
139}
140EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
141
142/**
143 * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing
144 * @input_dev:	the struct input_dev device descriptor
145 * @type:	the type of the event that has occurred
146 *
147 * This routine (which may be called from an interrupt context) works
148 * in similiar manner to ir_raw_event_store_edge.
149 * This routine is intended for devices with limited internal buffer
150 * It automerges samples of same type, and handles timeouts
151 */
152int ir_raw_event_store_with_filter(struct input_dev *input_dev,
153						struct ir_raw_event *ev)
154{
155	struct ir_input_dev *ir = input_get_drvdata(input_dev);
156	struct ir_raw_event_ctrl *raw = ir->raw;
157
158	if (!raw || !ir->props)
159		return -EINVAL;
160
161	/* Ignore spaces in idle mode */
162	if (ir->idle && !ev->pulse)
163		return 0;
164	else if (ir->idle)
165		ir_raw_event_set_idle(input_dev, 0);
166
167	if (!raw->this_ev.duration) {
168		raw->this_ev = *ev;
169	} else if (ev->pulse == raw->this_ev.pulse) {
170		raw->this_ev.duration += ev->duration;
171	} else {
172		ir_raw_event_store(input_dev, &raw->this_ev);
173		raw->this_ev = *ev;
174	}
175
176	/* Enter idle mode if nessesary */
177	if (!ev->pulse && ir->props->timeout &&
178		raw->this_ev.duration >= ir->props->timeout)
179		ir_raw_event_set_idle(input_dev, 1);
180	return 0;
181}
182EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
183
184void ir_raw_event_set_idle(struct input_dev *input_dev, int idle)
185{
186	struct ir_input_dev *ir = input_get_drvdata(input_dev);
187	struct ir_raw_event_ctrl *raw = ir->raw;
188	ktime_t now;
189	u64 delta;
190
191	if (!ir->props)
192		return;
193
194	if (!ir->raw)
195		goto out;
196
197	if (idle) {
198		IR_dprintk(2, "enter idle mode\n");
199		raw->last_event = ktime_get();
200	} else {
201		IR_dprintk(2, "exit idle mode\n");
202
203		now = ktime_get();
204		delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
205
206		WARN_ON(raw->this_ev.pulse);
207
208		raw->this_ev.duration =
209			min(raw->this_ev.duration + delta,
210						(u64)IR_MAX_DURATION);
211
212		ir_raw_event_store(input_dev, &raw->this_ev);
213
214		if (raw->this_ev.duration == IR_MAX_DURATION)
215			ir_raw_event_reset(input_dev);
216
217		raw->this_ev.duration = 0;
218	}
219out:
220	if (ir->props->s_idle)
221		ir->props->s_idle(ir->props->priv, idle);
222	ir->idle = idle;
223}
224EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
225
226/**
227 * ir_raw_event_handle() - schedules the decoding of stored ir data
228 * @input_dev:	the struct input_dev device descriptor
229 *
230 * This routine will signal the workqueue to start decoding stored ir data.
231 */
232void ir_raw_event_handle(struct input_dev *input_dev)
233{
234	struct ir_input_dev *ir = input_get_drvdata(input_dev);
235
236	if (!ir->raw)
237		return;
238
239	wake_up_process(ir->raw->thread);
240}
241EXPORT_SYMBOL_GPL(ir_raw_event_handle);
242
243/* used internally by the sysfs interface */
244u64
245ir_raw_get_allowed_protocols()
246{
247	u64 protocols;
248	mutex_lock(&ir_raw_handler_lock);
249	protocols = available_protocols;
250	mutex_unlock(&ir_raw_handler_lock);
251	return protocols;
252}
253
254/*
255 * Used to (un)register raw event clients
256 */
257int ir_raw_event_register(struct input_dev *input_dev)
258{
259	struct ir_input_dev *ir = input_get_drvdata(input_dev);
260	int rc;
261	struct ir_raw_handler *handler;
262
263	ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
264	if (!ir->raw)
265		return -ENOMEM;
266
267	ir->raw->input_dev = input_dev;
268
269	ir->raw->enabled_protocols = ~0;
270	rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
271			 GFP_KERNEL);
272	if (rc < 0) {
273		kfree(ir->raw);
274		ir->raw = NULL;
275		return rc;
276	}
277
278	ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw,
279			"rc%u",  (unsigned int)ir->devno);
280
281	if (IS_ERR(ir->raw->thread)) {
282		int ret = PTR_ERR(ir->raw->thread);
283
284		kfree(ir->raw);
285		ir->raw = NULL;
286		return ret;
287	}
288
289	mutex_lock(&ir_raw_handler_lock);
290	list_add_tail(&ir->raw->list, &ir_raw_client_list);
291	list_for_each_entry(handler, &ir_raw_handler_list, list)
292		if (handler->raw_register)
293			handler->raw_register(ir->raw->input_dev);
294	mutex_unlock(&ir_raw_handler_lock);
295
296	return 0;
297}
298
299void ir_raw_event_unregister(struct input_dev *input_dev)
300{
301	struct ir_input_dev *ir = input_get_drvdata(input_dev);
302	struct ir_raw_handler *handler;
303
304	if (!ir->raw)
305		return;
306
307	kthread_stop(ir->raw->thread);
308
309	mutex_lock(&ir_raw_handler_lock);
310	list_del(&ir->raw->list);
311	list_for_each_entry(handler, &ir_raw_handler_list, list)
312		if (handler->raw_unregister)
313			handler->raw_unregister(ir->raw->input_dev);
314	mutex_unlock(&ir_raw_handler_lock);
315
316	kfifo_free(&ir->raw->kfifo);
317	kfree(ir->raw);
318	ir->raw = NULL;
319}
320
321/*
322 * Extension interface - used to register the IR decoders
323 */
324
325int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
326{
327	struct ir_raw_event_ctrl *raw;
328
329	mutex_lock(&ir_raw_handler_lock);
330	list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
331	if (ir_raw_handler->raw_register)
332		list_for_each_entry(raw, &ir_raw_client_list, list)
333			ir_raw_handler->raw_register(raw->input_dev);
334	available_protocols |= ir_raw_handler->protocols;
335	mutex_unlock(&ir_raw_handler_lock);
336
337	return 0;
338}
339EXPORT_SYMBOL(ir_raw_handler_register);
340
341void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
342{
343	struct ir_raw_event_ctrl *raw;
344
345	mutex_lock(&ir_raw_handler_lock);
346	list_del(&ir_raw_handler->list);
347	if (ir_raw_handler->raw_unregister)
348		list_for_each_entry(raw, &ir_raw_client_list, list)
349			ir_raw_handler->raw_unregister(raw->input_dev);
350	available_protocols &= ~ir_raw_handler->protocols;
351	mutex_unlock(&ir_raw_handler_lock);
352}
353EXPORT_SYMBOL(ir_raw_handler_unregister);
354
355#ifdef MODULE
356static void init_decoders(struct work_struct *work)
357{
358	/* Load the decoder modules */
359
360	load_nec_decode();
361	load_rc5_decode();
362	load_rc6_decode();
363	load_jvc_decode();
364	load_sony_decode();
365	load_lirc_codec();
366
367	/* If needed, we may later add some init code. In this case,
368	   it is needed to change the CONFIG_MODULE test at ir-core.h
369	 */
370}
371#endif
372
373void ir_raw_init(void)
374{
375#ifdef MODULE
376	INIT_WORK(&wq_load, init_decoders);
377	schedule_work(&wq_load);
378#endif
379}
380