1 /* ir-raw-event.c - handle IR Pulse/Space event
 
   3  * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
 
   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.
 
   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.
 
  15 #include <linux/workqueue.h>
 
  16 #include <linux/spinlock.h>
 
  17 #include <linux/sched.h>
 
  18 #include "ir-core-priv.h"
 
  20 /* Define the max number of pulse/space transitions to buffer */
 
  21 #define MAX_IR_EVENT_SIZE      512
 
  23 /* Used to handle IR raw handler extensions */
 
  24 static LIST_HEAD(ir_raw_handler_list);
 
  25 static DEFINE_SPINLOCK(ir_raw_handler_lock);
 
  28  * RUN_DECODER()        - runs an operation on all IR decoders
 
  29  * @ops:        IR raw handler operation to be called
 
  30  * @arg:        arguments to be passed to the callback
 
  32  * Calls ir_raw_handler::ops for all registered IR handlers. It prevents
 
  33  * new decode addition/removal while running, by locking ir_raw_handler_lock
 
  34  * mutex. If an error occurs, it stops the ops. Otherwise, it returns a sum
 
  35  * of the return codes.
 
  37 #define RUN_DECODER(ops, ...) ({                                            \
 
  38         struct ir_raw_handler           *_ir_raw_handler;                   \
 
  39         int _sumrc = 0, _rc;                                                \
 
  40         spin_lock(&ir_raw_handler_lock);                                    \
 
  41         list_for_each_entry(_ir_raw_handler, &ir_raw_handler_list, list) {  \
 
  42                 if (_ir_raw_handler->ops) {                                 \
 
  43                         _rc = _ir_raw_handler->ops(__VA_ARGS__);            \
 
  49         spin_unlock(&ir_raw_handler_lock);                                  \
 
  54 /* Used to load the decoders */
 
  55 static struct work_struct wq_load;
 
  58 static void ir_raw_event_work(struct work_struct *work)
 
  60         struct ir_raw_event ev;
 
  61         struct ir_raw_event_ctrl *raw =
 
  62                 container_of(work, struct ir_raw_event_ctrl, rx_work);
 
  64         while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev))
 
  65                 RUN_DECODER(decode, raw->input_dev, ev);
 
  68 int ir_raw_event_register(struct input_dev *input_dev)
 
  70         struct ir_input_dev *ir = input_get_drvdata(input_dev);
 
  73         ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
 
  77         ir->raw->input_dev = input_dev;
 
  78         INIT_WORK(&ir->raw->rx_work, ir_raw_event_work);
 
  80         rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
 
  88         rc = RUN_DECODER(raw_register, input_dev);
 
  90                 kfifo_free(&ir->raw->kfifo);
 
  99 void ir_raw_event_unregister(struct input_dev *input_dev)
 
 101         struct ir_input_dev *ir = input_get_drvdata(input_dev);
 
 106         cancel_work_sync(&ir->raw->rx_work);
 
 107         RUN_DECODER(raw_unregister, input_dev);
 
 109         kfifo_free(&ir->raw->kfifo);
 
 115  * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders
 
 116  * @input_dev:  the struct input_dev device descriptor
 
 117  * @ev:         the struct ir_raw_event descriptor of the pulse/space
 
 119  * This routine (which may be called from an interrupt context) stores a
 
 120  * pulse/space duration for the raw ir decoding state machines. Pulses are
 
 121  * signalled as positive values and spaces as negative values. A zero value
 
 122  * will reset the decoding state machines.
 
 124 int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev)
 
 126         struct ir_input_dev *ir = input_get_drvdata(input_dev);
 
 131         if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
 
 136 EXPORT_SYMBOL_GPL(ir_raw_event_store);
 
 139  * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space
 
 140  * @input_dev:  the struct input_dev device descriptor
 
 141  * @type:       the type of the event that has occurred
 
 143  * This routine (which may be called from an interrupt context) is used to
 
 144  * store the beginning of an ir pulse or space (or the start/end of ir
 
 145  * reception) for the raw ir decoding state machines. This is used by
 
 146  * hardware which does not provide durations directly but only interrupts
 
 147  * (or similar events) on state change.
 
 149 int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type)
 
 151         struct ir_input_dev     *ir = input_get_drvdata(input_dev);
 
 154         struct ir_raw_event     ev;
 
 161         delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
 
 163         /* Check for a long duration since last event or if we're
 
 164          * being called for the first time, note that delta can't
 
 165          * possibly be negative.
 
 168         if (delta > IR_MAX_DURATION || !ir->raw->last_type)
 
 169                 type |= IR_START_EVENT;
 
 173         if (type & IR_START_EVENT)
 
 174                 ir_raw_event_reset(input_dev);
 
 175         else if (ir->raw->last_type & IR_SPACE) {
 
 177                 rc = ir_raw_event_store(input_dev, &ev);
 
 178         } else if (ir->raw->last_type & IR_PULSE) {
 
 180                 rc = ir_raw_event_store(input_dev, &ev);
 
 184         ir->raw->last_event = now;
 
 185         ir->raw->last_type = type;
 
 188 EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
 
 191  * ir_raw_event_handle() - schedules the decoding of stored ir data
 
 192  * @input_dev:  the struct input_dev device descriptor
 
 194  * This routine will signal the workqueue to start decoding stored ir data.
 
 196 void ir_raw_event_handle(struct input_dev *input_dev)
 
 198         struct ir_input_dev *ir = input_get_drvdata(input_dev);
 
 203         schedule_work(&ir->raw->rx_work);
 
 205 EXPORT_SYMBOL_GPL(ir_raw_event_handle);
 
 208  * Extension interface - used to register the IR decoders
 
 211 int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
 
 213         spin_lock(&ir_raw_handler_lock);
 
 214         list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
 
 215         spin_unlock(&ir_raw_handler_lock);
 
 218 EXPORT_SYMBOL(ir_raw_handler_register);
 
 220 void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
 
 222         spin_lock(&ir_raw_handler_lock);
 
 223         list_del(&ir_raw_handler->list);
 
 224         spin_unlock(&ir_raw_handler_lock);
 
 226 EXPORT_SYMBOL(ir_raw_handler_unregister);
 
 229 static void init_decoders(struct work_struct *work)
 
 231         /* Load the decoder modules */
 
 239         /* If needed, we may later add some init code. In this case,
 
 240            it is needed to change the CONFIG_MODULE test at ir-core.h
 
 245 void ir_raw_init(void)
 
 248         INIT_WORK(&wq_load, init_decoders);
 
 249         schedule_work(&wq_load);