diff options
Diffstat (limited to 'drivers/media/rc/rc-raw.c')
-rw-r--r-- | drivers/media/rc/rc-raw.c | 191 |
1 files changed, 90 insertions, 101 deletions
diff --git a/drivers/media/rc/rc-raw.c b/drivers/media/rc/rc-raw.c index d6c556e3f0d8..ab9b1e4071c0 100644 --- a/drivers/media/rc/rc-raw.c +++ b/drivers/media/rc/rc-raw.c @@ -64,7 +64,7 @@ static int ir_raw_event_thread(void *data) mutex_lock(&ir_raw_handler_lock); list_for_each_entry(handler, &ir_raw_handler_list, list) - handler->decode(raw->input_dev, ev); + handler->decode(raw->dev, ev); raw->prev_ev = ev; mutex_unlock(&ir_raw_handler_lock); } @@ -74,7 +74,7 @@ static int ir_raw_event_thread(void *data) /** * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders - * @input_dev: the struct input_dev device descriptor + * @dev: the struct rc_dev device descriptor * @ev: the struct ir_raw_event descriptor of the pulse/space * * This routine (which may be called from an interrupt context) stores a @@ -82,17 +82,15 @@ static int ir_raw_event_thread(void *data) * signalled as positive values and spaces as negative values. A zero value * will reset the decoding state machines. */ -int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev) +int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); - - if (!ir->raw) + if (!dev->raw) return -EINVAL; IR_dprintk(2, "sample: (%05dus %s)\n", - TO_US(ev->duration), TO_STR(ev->pulse)); + TO_US(ev->duration), TO_STR(ev->pulse)); - if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) + if (kfifo_in(&dev->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) return -ENOMEM; return 0; @@ -101,7 +99,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store); /** * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space - * @input_dev: the struct input_dev device descriptor + * @dev: the struct rc_dev device descriptor * @type: the type of the event that has occurred * * This routine (which may be called from an interrupt context) is used to @@ -110,50 +108,49 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store); * hardware which does not provide durations directly but only interrupts * (or similar events) on state change. */ -int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type) +int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); ktime_t now; s64 delta; /* ns */ struct ir_raw_event ev; int rc = 0; - if (!ir->raw) + if (!dev->raw) return -EINVAL; now = ktime_get(); - delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event)); + delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); /* Check for a long duration since last event or if we're * being called for the first time, note that delta can't * possibly be negative. */ ev.duration = 0; - if (delta > IR_MAX_DURATION || !ir->raw->last_type) + if (delta > IR_MAX_DURATION || !dev->raw->last_type) type |= IR_START_EVENT; else ev.duration = delta; if (type & IR_START_EVENT) - ir_raw_event_reset(input_dev); - else if (ir->raw->last_type & IR_SPACE) { + ir_raw_event_reset(dev); + else if (dev->raw->last_type & IR_SPACE) { ev.pulse = false; - rc = ir_raw_event_store(input_dev, &ev); - } else if (ir->raw->last_type & IR_PULSE) { + rc = ir_raw_event_store(dev, &ev); + } else if (dev->raw->last_type & IR_PULSE) { ev.pulse = true; - rc = ir_raw_event_store(input_dev, &ev); + rc = ir_raw_event_store(dev, &ev); } else return 0; - ir->raw->last_event = now; - ir->raw->last_type = type; + dev->raw->last_event = now; + dev->raw->last_type = type; return rc; } EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); /** * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing - * @input_dev: the struct input_dev device descriptor + * @dev: the struct rc_dev device descriptor * @type: the type of the event that has occurred * * This routine (which may be called from an interrupt context) works @@ -161,84 +158,76 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); * This routine is intended for devices with limited internal buffer * It automerges samples of same type, and handles timeouts */ -int ir_raw_event_store_with_filter(struct input_dev *input_dev, - struct ir_raw_event *ev) +int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); - struct ir_raw_event_ctrl *raw = ir->raw; - - if (!raw || !ir->props) + if (!dev->raw) return -EINVAL; /* Ignore spaces in idle mode */ - if (ir->idle && !ev->pulse) + if (dev->idle && !ev->pulse) return 0; - else if (ir->idle) - ir_raw_event_set_idle(input_dev, false); - - if (!raw->this_ev.duration) { - raw->this_ev = *ev; - } else if (ev->pulse == raw->this_ev.pulse) { - raw->this_ev.duration += ev->duration; - } else { - ir_raw_event_store(input_dev, &raw->this_ev); - raw->this_ev = *ev; + else if (dev->idle) + ir_raw_event_set_idle(dev, false); + + if (!dev->raw->this_ev.duration) + dev->raw->this_ev = *ev; + else if (ev->pulse == dev->raw->this_ev.pulse) + dev->raw->this_ev.duration += ev->duration; + else { + ir_raw_event_store(dev, &dev->raw->this_ev); + dev->raw->this_ev = *ev; } /* Enter idle mode if nessesary */ - if (!ev->pulse && ir->props->timeout && - raw->this_ev.duration >= ir->props->timeout) { - ir_raw_event_set_idle(input_dev, true); - } + if (!ev->pulse && dev->timeout && + dev->raw->this_ev.duration >= dev->timeout) + ir_raw_event_set_idle(dev, true); + return 0; } EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); /** - * ir_raw_event_set_idle() - hint the ir core if device is receiving - * IR data or not - * @input_dev: the struct input_dev device descriptor - * @idle: the hint value + * ir_raw_event_set_idle() - provide hint to rc-core when the device is idle or not + * @dev: the struct rc_dev device descriptor + * @idle: whether the device is idle or not */ -void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle) +void ir_raw_event_set_idle(struct rc_dev *dev, bool idle) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); - struct ir_raw_event_ctrl *raw = ir->raw; - - if (!ir->props || !ir->raw) + if (!dev->raw) return; IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); if (idle) { - raw->this_ev.timeout = true; - ir_raw_event_store(input_dev, &raw->this_ev); - init_ir_raw_event(&raw->this_ev); + dev->raw->this_ev.timeout = true; + ir_raw_event_store(dev, &dev->raw->this_ev); + init_ir_raw_event(&dev->raw->this_ev); } - if (ir->props->s_idle) - ir->props->s_idle(ir->props->priv, idle); - ir->idle = idle; + if (dev->s_idle) + dev->s_idle(dev, idle); + + dev->idle = idle; } EXPORT_SYMBOL_GPL(ir_raw_event_set_idle); /** * ir_raw_event_handle() - schedules the decoding of stored ir data - * @input_dev: the struct input_dev device descriptor + * @dev: the struct rc_dev device descriptor * - * This routine will signal the workqueue to start decoding stored ir data. + * This routine will tell rc-core to start decoding stored ir data. */ -void ir_raw_event_handle(struct input_dev *input_dev) +void ir_raw_event_handle(struct rc_dev *dev) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); unsigned long flags; - if (!ir->raw) + if (!dev->raw) return; - spin_lock_irqsave(&ir->raw->lock, flags); - wake_up_process(ir->raw->thread); - spin_unlock_irqrestore(&ir->raw->lock, flags); + spin_lock_irqsave(&dev->raw->lock, flags); + wake_up_process(dev->raw->thread); + spin_unlock_irqrestore(&dev->raw->lock, flags); } EXPORT_SYMBOL_GPL(ir_raw_event_handle); @@ -256,69 +245,69 @@ ir_raw_get_allowed_protocols() /* * Used to (un)register raw event clients */ -int ir_raw_event_register(struct input_dev *input_dev) +int ir_raw_event_register(struct rc_dev *dev) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); int rc; struct ir_raw_handler *handler; - ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL); - if (!ir->raw) - return -ENOMEM; + if (!dev) + return -EINVAL; - ir->raw->input_dev = input_dev; + dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL); + if (!dev->raw) + return -ENOMEM; - ir->raw->enabled_protocols = ~0; - rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE, + dev->raw->dev = dev; + dev->raw->enabled_protocols = ~0; + rc = kfifo_alloc(&dev->raw->kfifo, + sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE, GFP_KERNEL); - if (rc < 0) { - kfree(ir->raw); - ir->raw = NULL; - return rc; - } + if (rc < 0) + goto out; - spin_lock_init(&ir->raw->lock); - ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw, - "rc%u", (unsigned int)ir->devno); + spin_lock_init(&dev->raw->lock); + dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, + "rc%ld", dev->devno); - if (IS_ERR(ir->raw->thread)) { - int ret = PTR_ERR(ir->raw->thread); - - kfree(ir->raw); - ir->raw = NULL; - return ret; + if (IS_ERR(dev->raw->thread)) { + rc = PTR_ERR(dev->raw->thread); + goto out; } mutex_lock(&ir_raw_handler_lock); - list_add_tail(&ir->raw->list, &ir_raw_client_list); + list_add_tail(&dev->raw->list, &ir_raw_client_list); list_for_each_entry(handler, &ir_raw_handler_list, list) if (handler->raw_register) - handler->raw_register(ir->raw->input_dev); + handler->raw_register(dev); mutex_unlock(&ir_raw_handler_lock); return 0; + +out: + kfree(dev->raw); + dev->raw = NULL; + return rc; } -void ir_raw_event_unregister(struct input_dev *input_dev) +void ir_raw_event_unregister(struct rc_dev *dev) { - struct ir_input_dev *ir = input_get_drvdata(input_dev); struct ir_raw_handler *handler; - if (!ir->raw) + if (!dev || !dev->raw) return; - kthread_stop(ir->raw->thread); + kthread_stop(dev->raw->thread); mutex_lock(&ir_raw_handler_lock); - list_del(&ir->raw->list); + list_del(&dev->raw->list); list_for_each_entry(handler, &ir_raw_handler_list, list) if (handler->raw_unregister) - handler->raw_unregister(ir->raw->input_dev); + handler->raw_unregister(dev); mutex_unlock(&ir_raw_handler_lock); - kfifo_free(&ir->raw->kfifo); - kfree(ir->raw); - ir->raw = NULL; + kfifo_free(&dev->raw->kfifo); + kfree(dev->raw); + dev->raw = NULL; } /* @@ -333,7 +322,7 @@ int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); if (ir_raw_handler->raw_register) list_for_each_entry(raw, &ir_raw_client_list, list) - ir_raw_handler->raw_register(raw->input_dev); + ir_raw_handler->raw_register(raw->dev); available_protocols |= ir_raw_handler->protocols; mutex_unlock(&ir_raw_handler_lock); @@ -349,7 +338,7 @@ void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) list_del(&ir_raw_handler->list); if (ir_raw_handler->raw_unregister) list_for_each_entry(raw, &ir_raw_client_list, list) - ir_raw_handler->raw_unregister(raw->input_dev); + ir_raw_handler->raw_unregister(raw->dev); available_protocols &= ~ir_raw_handler->protocols; mutex_unlock(&ir_raw_handler_lock); } |