Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.0-rc6 370 lines 9.5 kB view raw
1/* ir-raw.c - handle IR pulse/space events 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 "rc-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 int retval; 43 44 while (!kthread_should_stop()) { 45 46 spin_lock_irq(&raw->lock); 47 retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev)); 48 49 if (!retval) { 50 set_current_state(TASK_INTERRUPTIBLE); 51 52 if (kthread_should_stop()) 53 set_current_state(TASK_RUNNING); 54 55 spin_unlock_irq(&raw->lock); 56 schedule(); 57 continue; 58 } 59 60 spin_unlock_irq(&raw->lock); 61 62 63 BUG_ON(retval != sizeof(ev)); 64 65 mutex_lock(&ir_raw_handler_lock); 66 list_for_each_entry(handler, &ir_raw_handler_list, list) 67 handler->decode(raw->dev, ev); 68 raw->prev_ev = ev; 69 mutex_unlock(&ir_raw_handler_lock); 70 } 71 72 return 0; 73} 74 75/** 76 * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders 77 * @dev: the struct rc_dev device descriptor 78 * @ev: the struct ir_raw_event descriptor of the pulse/space 79 * 80 * This routine (which may be called from an interrupt context) stores a 81 * pulse/space duration for the raw ir decoding state machines. Pulses are 82 * signalled as positive values and spaces as negative values. A zero value 83 * will reset the decoding state machines. 84 */ 85int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev) 86{ 87 if (!dev->raw) 88 return -EINVAL; 89 90 IR_dprintk(2, "sample: (%05dus %s)\n", 91 TO_US(ev->duration), TO_STR(ev->pulse)); 92 93 if (kfifo_in(&dev->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) 94 return -ENOMEM; 95 96 return 0; 97} 98EXPORT_SYMBOL_GPL(ir_raw_event_store); 99 100/** 101 * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space 102 * @dev: the struct rc_dev device descriptor 103 * @type: the type of the event that has occurred 104 * 105 * This routine (which may be called from an interrupt context) is used to 106 * store the beginning of an ir pulse or space (or the start/end of ir 107 * reception) for the raw ir decoding state machines. This is used by 108 * hardware which does not provide durations directly but only interrupts 109 * (or similar events) on state change. 110 */ 111int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) 112{ 113 ktime_t now; 114 s64 delta; /* ns */ 115 DEFINE_IR_RAW_EVENT(ev); 116 int rc = 0; 117 118 if (!dev->raw) 119 return -EINVAL; 120 121 now = ktime_get(); 122 delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); 123 124 /* Check for a long duration since last event or if we're 125 * being called for the first time, note that delta can't 126 * possibly be negative. 127 */ 128 if (delta > IR_MAX_DURATION || !dev->raw->last_type) 129 type |= IR_START_EVENT; 130 else 131 ev.duration = delta; 132 133 if (type & IR_START_EVENT) 134 ir_raw_event_reset(dev); 135 else if (dev->raw->last_type & IR_SPACE) { 136 ev.pulse = false; 137 rc = ir_raw_event_store(dev, &ev); 138 } else if (dev->raw->last_type & IR_PULSE) { 139 ev.pulse = true; 140 rc = ir_raw_event_store(dev, &ev); 141 } else 142 return 0; 143 144 dev->raw->last_event = now; 145 dev->raw->last_type = type; 146 return rc; 147} 148EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); 149 150/** 151 * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing 152 * @dev: the struct rc_dev device descriptor 153 * @type: the type of the event that has occurred 154 * 155 * This routine (which may be called from an interrupt context) works 156 * in similar manner to ir_raw_event_store_edge. 157 * This routine is intended for devices with limited internal buffer 158 * It automerges samples of same type, and handles timeouts 159 */ 160int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev) 161{ 162 if (!dev->raw) 163 return -EINVAL; 164 165 /* Ignore spaces in idle mode */ 166 if (dev->idle && !ev->pulse) 167 return 0; 168 else if (dev->idle) 169 ir_raw_event_set_idle(dev, false); 170 171 if (!dev->raw->this_ev.duration) 172 dev->raw->this_ev = *ev; 173 else if (ev->pulse == dev->raw->this_ev.pulse) 174 dev->raw->this_ev.duration += ev->duration; 175 else { 176 ir_raw_event_store(dev, &dev->raw->this_ev); 177 dev->raw->this_ev = *ev; 178 } 179 180 /* Enter idle mode if nessesary */ 181 if (!ev->pulse && dev->timeout && 182 dev->raw->this_ev.duration >= dev->timeout) 183 ir_raw_event_set_idle(dev, true); 184 185 return 0; 186} 187EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); 188 189/** 190 * ir_raw_event_set_idle() - provide hint to rc-core when the device is idle or not 191 * @dev: the struct rc_dev device descriptor 192 * @idle: whether the device is idle or not 193 */ 194void ir_raw_event_set_idle(struct rc_dev *dev, bool idle) 195{ 196 if (!dev->raw) 197 return; 198 199 IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); 200 201 if (idle) { 202 dev->raw->this_ev.timeout = true; 203 ir_raw_event_store(dev, &dev->raw->this_ev); 204 init_ir_raw_event(&dev->raw->this_ev); 205 } 206 207 if (dev->s_idle) 208 dev->s_idle(dev, idle); 209 210 dev->idle = idle; 211} 212EXPORT_SYMBOL_GPL(ir_raw_event_set_idle); 213 214/** 215 * ir_raw_event_handle() - schedules the decoding of stored ir data 216 * @dev: the struct rc_dev device descriptor 217 * 218 * This routine will tell rc-core to start decoding stored ir data. 219 */ 220void ir_raw_event_handle(struct rc_dev *dev) 221{ 222 unsigned long flags; 223 224 if (!dev->raw) 225 return; 226 227 spin_lock_irqsave(&dev->raw->lock, flags); 228 wake_up_process(dev->raw->thread); 229 spin_unlock_irqrestore(&dev->raw->lock, flags); 230} 231EXPORT_SYMBOL_GPL(ir_raw_event_handle); 232 233/* used internally by the sysfs interface */ 234u64 235ir_raw_get_allowed_protocols(void) 236{ 237 u64 protocols; 238 mutex_lock(&ir_raw_handler_lock); 239 protocols = available_protocols; 240 mutex_unlock(&ir_raw_handler_lock); 241 return protocols; 242} 243 244/* 245 * Used to (un)register raw event clients 246 */ 247int ir_raw_event_register(struct rc_dev *dev) 248{ 249 int rc; 250 struct ir_raw_handler *handler; 251 252 if (!dev) 253 return -EINVAL; 254 255 dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL); 256 if (!dev->raw) 257 return -ENOMEM; 258 259 dev->raw->dev = dev; 260 dev->raw->enabled_protocols = ~0; 261 rc = kfifo_alloc(&dev->raw->kfifo, 262 sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE, 263 GFP_KERNEL); 264 if (rc < 0) 265 goto out; 266 267 spin_lock_init(&dev->raw->lock); 268 dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw, 269 "rc%ld", dev->devno); 270 271 if (IS_ERR(dev->raw->thread)) { 272 rc = PTR_ERR(dev->raw->thread); 273 goto out; 274 } 275 276 mutex_lock(&ir_raw_handler_lock); 277 list_add_tail(&dev->raw->list, &ir_raw_client_list); 278 list_for_each_entry(handler, &ir_raw_handler_list, list) 279 if (handler->raw_register) 280 handler->raw_register(dev); 281 mutex_unlock(&ir_raw_handler_lock); 282 283 return 0; 284 285out: 286 kfree(dev->raw); 287 dev->raw = NULL; 288 return rc; 289} 290 291void ir_raw_event_unregister(struct rc_dev *dev) 292{ 293 struct ir_raw_handler *handler; 294 295 if (!dev || !dev->raw) 296 return; 297 298 kthread_stop(dev->raw->thread); 299 300 mutex_lock(&ir_raw_handler_lock); 301 list_del(&dev->raw->list); 302 list_for_each_entry(handler, &ir_raw_handler_list, list) 303 if (handler->raw_unregister) 304 handler->raw_unregister(dev); 305 mutex_unlock(&ir_raw_handler_lock); 306 307 kfifo_free(&dev->raw->kfifo); 308 kfree(dev->raw); 309 dev->raw = NULL; 310} 311 312/* 313 * Extension interface - used to register the IR decoders 314 */ 315 316int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) 317{ 318 struct ir_raw_event_ctrl *raw; 319 320 mutex_lock(&ir_raw_handler_lock); 321 list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); 322 if (ir_raw_handler->raw_register) 323 list_for_each_entry(raw, &ir_raw_client_list, list) 324 ir_raw_handler->raw_register(raw->dev); 325 available_protocols |= ir_raw_handler->protocols; 326 mutex_unlock(&ir_raw_handler_lock); 327 328 return 0; 329} 330EXPORT_SYMBOL(ir_raw_handler_register); 331 332void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) 333{ 334 struct ir_raw_event_ctrl *raw; 335 336 mutex_lock(&ir_raw_handler_lock); 337 list_del(&ir_raw_handler->list); 338 if (ir_raw_handler->raw_unregister) 339 list_for_each_entry(raw, &ir_raw_client_list, list) 340 ir_raw_handler->raw_unregister(raw->dev); 341 available_protocols &= ~ir_raw_handler->protocols; 342 mutex_unlock(&ir_raw_handler_lock); 343} 344EXPORT_SYMBOL(ir_raw_handler_unregister); 345 346#ifdef MODULE 347static void init_decoders(struct work_struct *work) 348{ 349 /* Load the decoder modules */ 350 351 load_nec_decode(); 352 load_rc5_decode(); 353 load_rc6_decode(); 354 load_jvc_decode(); 355 load_sony_decode(); 356 load_lirc_codec(); 357 358 /* If needed, we may later add some init code. In this case, 359 it is needed to change the CONFIG_MODULE test at rc-core.h 360 */ 361} 362#endif 363 364void ir_raw_init(void) 365{ 366#ifdef MODULE 367 INIT_WORK(&wq_load, init_decoders); 368 schedule_work(&wq_load); 369#endif 370}