1/* ir-lirc-codec.c - rc-core to classic lirc interface bridge 2 * 3 * Copyright (C) 2010 by Jarod Wilson <jarod@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/sched.h> 16#include <linux/wait.h> 17#include <linux/module.h> 18#include <media/lirc.h> 19#include <media/lirc_dev.h> 20#include <media/rc-core.h> 21#include "rc-core-priv.h" 22 23#define LIRCBUF_SIZE 256 24 25/** 26 * ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the 27 * lircd userspace daemon for decoding. 28 * @input_dev: the struct rc_dev descriptor of the device 29 * @duration: the struct ir_raw_event descriptor of the pulse/space 30 * 31 * This function returns -EINVAL if the lirc interfaces aren't wired up. 32 */ 33static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev) 34{ 35 struct lirc_codec *lirc = &dev->raw->lirc; 36 int sample; 37 38 if (!(dev->enabled_protocols & RC_BIT_LIRC)) 39 return 0; 40 41 if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf) 42 return -EINVAL; 43 44 /* Packet start */ 45 if (ev.reset) { 46 /* Userspace expects a long space event before the start of 47 * the signal to use as a sync. This may be done with repeat 48 * packets and normal samples. But if a reset has been sent 49 * then we assume that a long time has passed, so we send a 50 * space with the maximum time value. */ 51 sample = LIRC_SPACE(LIRC_VALUE_MASK); 52 IR_dprintk(2, "delivering reset sync space to lirc_dev\n"); 53 54 /* Carrier reports */ 55 } else if (ev.carrier_report) { 56 sample = LIRC_FREQUENCY(ev.carrier); 57 IR_dprintk(2, "carrier report (freq: %d)\n", sample); 58 59 /* Packet end */ 60 } else if (ev.timeout) { 61 62 if (lirc->gap) 63 return 0; 64 65 lirc->gap_start = ktime_get(); 66 lirc->gap = true; 67 lirc->gap_duration = ev.duration; 68 69 if (!lirc->send_timeout_reports) 70 return 0; 71 72 sample = LIRC_TIMEOUT(ev.duration / 1000); 73 IR_dprintk(2, "timeout report (duration: %d)\n", sample); 74 75 /* Normal sample */ 76 } else { 77 78 if (lirc->gap) { 79 int gap_sample; 80 81 lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(), 82 lirc->gap_start)); 83 84 /* Convert to ms and cap by LIRC_VALUE_MASK */ 85 do_div(lirc->gap_duration, 1000); 86 lirc->gap_duration = min(lirc->gap_duration, 87 (u64)LIRC_VALUE_MASK); 88 89 gap_sample = LIRC_SPACE(lirc->gap_duration); 90 lirc_buffer_write(dev->raw->lirc.drv->rbuf, 91 (unsigned char *) &gap_sample); 92 lirc->gap = false; 93 } 94 95 sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) : 96 LIRC_SPACE(ev.duration / 1000); 97 IR_dprintk(2, "delivering %uus %s to lirc_dev\n", 98 TO_US(ev.duration), TO_STR(ev.pulse)); 99 } 100 101 lirc_buffer_write(dev->raw->lirc.drv->rbuf, 102 (unsigned char *) &sample); 103 wake_up(&dev->raw->lirc.drv->rbuf->wait_poll); 104 105 return 0; 106} 107 108static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, 109 size_t n, loff_t *ppos) 110{ 111 struct lirc_codec *lirc; 112 struct rc_dev *dev; 113 unsigned int *txbuf; /* buffer with values to transmit */ 114 ssize_t ret = -EINVAL; 115 size_t count; 116 ktime_t start; 117 s64 towait; 118 unsigned int duration = 0; /* signal duration in us */ 119 int i; 120 121 start = ktime_get(); 122 123 lirc = lirc_get_pdata(file); 124 if (!lirc) 125 return -EFAULT; 126 127 if (n < sizeof(unsigned) || n % sizeof(unsigned)) 128 return -EINVAL; 129 130 count = n / sizeof(unsigned); 131 if (count > LIRCBUF_SIZE || count % 2 == 0) 132 return -EINVAL; 133 134 txbuf = memdup_user(buf, n); 135 if (IS_ERR(txbuf)) 136 return PTR_ERR(txbuf); 137 138 dev = lirc->dev; 139 if (!dev) { 140 ret = -EFAULT; 141 goto out; 142 } 143 144 if (!dev->tx_ir) { 145 ret = -ENOSYS; 146 goto out; 147 } 148 149 for (i = 0; i < count; i++) { 150 if (txbuf[i] > IR_MAX_DURATION / 1000 - duration || !txbuf[i]) { 151 ret = -EINVAL; 152 goto out; 153 } 154 155 duration += txbuf[i]; 156 } 157 158 ret = dev->tx_ir(dev, txbuf, count); 159 if (ret < 0) 160 goto out; 161 162 for (duration = i = 0; i < ret; i++) 163 duration += txbuf[i]; 164 165 ret *= sizeof(unsigned int); 166 167 /* 168 * The lircd gap calculation expects the write function to 169 * wait for the actual IR signal to be transmitted before 170 * returning. 171 */ 172 towait = ktime_us_delta(ktime_add_us(start, duration), ktime_get()); 173 if (towait > 0) { 174 set_current_state(TASK_INTERRUPTIBLE); 175 schedule_timeout(usecs_to_jiffies(towait)); 176 } 177 178out: 179 kfree(txbuf); 180 return ret; 181} 182 183static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, 184 unsigned long arg) 185{ 186 struct lirc_codec *lirc; 187 struct rc_dev *dev; 188 u32 __user *argp = (u32 __user *)(arg); 189 int ret = 0; 190 __u32 val = 0, tmp; 191 192 lirc = lirc_get_pdata(filep); 193 if (!lirc) 194 return -EFAULT; 195 196 dev = lirc->dev; 197 if (!dev) 198 return -EFAULT; 199 200 if (_IOC_DIR(cmd) & _IOC_WRITE) { 201 ret = get_user(val, argp); 202 if (ret) 203 return ret; 204 } 205 206 switch (cmd) { 207 208 /* legacy support */ 209 case LIRC_GET_SEND_MODE: 210 val = LIRC_CAN_SEND_PULSE & LIRC_CAN_SEND_MASK; 211 break; 212 213 case LIRC_SET_SEND_MODE: 214 if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK)) 215 return -EINVAL; 216 return 0; 217 218 /* TX settings */ 219 case LIRC_SET_TRANSMITTER_MASK: 220 if (!dev->s_tx_mask) 221 return -ENOSYS; 222 223 return dev->s_tx_mask(dev, val); 224 225 case LIRC_SET_SEND_CARRIER: 226 if (!dev->s_tx_carrier) 227 return -ENOSYS; 228 229 return dev->s_tx_carrier(dev, val); 230 231 case LIRC_SET_SEND_DUTY_CYCLE: 232 if (!dev->s_tx_duty_cycle) 233 return -ENOSYS; 234 235 if (val <= 0 || val >= 100) 236 return -EINVAL; 237 238 return dev->s_tx_duty_cycle(dev, val); 239 240 /* RX settings */ 241 case LIRC_SET_REC_CARRIER: 242 if (!dev->s_rx_carrier_range) 243 return -ENOSYS; 244 245 if (val <= 0) 246 return -EINVAL; 247 248 return dev->s_rx_carrier_range(dev, 249 dev->raw->lirc.carrier_low, 250 val); 251 252 case LIRC_SET_REC_CARRIER_RANGE: 253 if (val <= 0) 254 return -EINVAL; 255 256 dev->raw->lirc.carrier_low = val; 257 return 0; 258 259 case LIRC_GET_REC_RESOLUTION: 260 val = dev->rx_resolution; 261 break; 262 263 case LIRC_SET_WIDEBAND_RECEIVER: 264 if (!dev->s_learning_mode) 265 return -ENOSYS; 266 267 return dev->s_learning_mode(dev, !!val); 268 269 case LIRC_SET_MEASURE_CARRIER_MODE: 270 if (!dev->s_carrier_report) 271 return -ENOSYS; 272 273 return dev->s_carrier_report(dev, !!val); 274 275 /* Generic timeout support */ 276 case LIRC_GET_MIN_TIMEOUT: 277 if (!dev->max_timeout) 278 return -ENOSYS; 279 val = dev->min_timeout / 1000; 280 break; 281 282 case LIRC_GET_MAX_TIMEOUT: 283 if (!dev->max_timeout) 284 return -ENOSYS; 285 val = dev->max_timeout / 1000; 286 break; 287 288 case LIRC_SET_REC_TIMEOUT: 289 if (!dev->max_timeout) 290 return -ENOSYS; 291 292 tmp = val * 1000; 293 294 if (tmp < dev->min_timeout || 295 tmp > dev->max_timeout) 296 return -EINVAL; 297 298 dev->timeout = tmp; 299 break; 300 301 case LIRC_SET_REC_TIMEOUT_REPORTS: 302 lirc->send_timeout_reports = !!val; 303 break; 304 305 default: 306 return lirc_dev_fop_ioctl(filep, cmd, arg); 307 } 308 309 if (_IOC_DIR(cmd) & _IOC_READ) 310 ret = put_user(val, argp); 311 312 return ret; 313} 314 315static int ir_lirc_open(void *data) 316{ 317 return 0; 318} 319 320static void ir_lirc_close(void *data) 321{ 322 return; 323} 324 325static const struct file_operations lirc_fops = { 326 .owner = THIS_MODULE, 327 .write = ir_lirc_transmit_ir, 328 .unlocked_ioctl = ir_lirc_ioctl, 329#ifdef CONFIG_COMPAT 330 .compat_ioctl = ir_lirc_ioctl, 331#endif 332 .read = lirc_dev_fop_read, 333 .poll = lirc_dev_fop_poll, 334 .open = lirc_dev_fop_open, 335 .release = lirc_dev_fop_close, 336 .llseek = no_llseek, 337}; 338 339static int ir_lirc_register(struct rc_dev *dev) 340{ 341 struct lirc_driver *drv; 342 struct lirc_buffer *rbuf; 343 int rc = -ENOMEM; 344 unsigned long features; 345 346 drv = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); 347 if (!drv) 348 return rc; 349 350 rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL); 351 if (!rbuf) 352 goto rbuf_alloc_failed; 353 354 rc = lirc_buffer_init(rbuf, sizeof(int), LIRCBUF_SIZE); 355 if (rc) 356 goto rbuf_init_failed; 357 358 features = LIRC_CAN_REC_MODE2; 359 if (dev->tx_ir) { 360 features |= LIRC_CAN_SEND_PULSE; 361 if (dev->s_tx_mask) 362 features |= LIRC_CAN_SET_TRANSMITTER_MASK; 363 if (dev->s_tx_carrier) 364 features |= LIRC_CAN_SET_SEND_CARRIER; 365 if (dev->s_tx_duty_cycle) 366 features |= LIRC_CAN_SET_SEND_DUTY_CYCLE; 367 } 368 369 if (dev->s_rx_carrier_range) 370 features |= LIRC_CAN_SET_REC_CARRIER | 371 LIRC_CAN_SET_REC_CARRIER_RANGE; 372 373 if (dev->s_learning_mode) 374 features |= LIRC_CAN_USE_WIDEBAND_RECEIVER; 375 376 if (dev->s_carrier_report) 377 features |= LIRC_CAN_MEASURE_CARRIER; 378 379 if (dev->max_timeout) 380 features |= LIRC_CAN_SET_REC_TIMEOUT; 381 382 snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)", 383 dev->driver_name); 384 drv->minor = -1; 385 drv->features = features; 386 drv->data = &dev->raw->lirc; 387 drv->rbuf = rbuf; 388 drv->set_use_inc = &ir_lirc_open; 389 drv->set_use_dec = &ir_lirc_close; 390 drv->code_length = sizeof(struct ir_raw_event) * 8; 391 drv->fops = &lirc_fops; 392 drv->dev = &dev->dev; 393 drv->rdev = dev; 394 drv->owner = THIS_MODULE; 395 396 drv->minor = lirc_register_driver(drv); 397 if (drv->minor < 0) { 398 rc = -ENODEV; 399 goto lirc_register_failed; 400 } 401 402 dev->raw->lirc.drv = drv; 403 dev->raw->lirc.dev = dev; 404 return 0; 405 406lirc_register_failed: 407rbuf_init_failed: 408 kfree(rbuf); 409rbuf_alloc_failed: 410 kfree(drv); 411 412 return rc; 413} 414 415static int ir_lirc_unregister(struct rc_dev *dev) 416{ 417 struct lirc_codec *lirc = &dev->raw->lirc; 418 419 lirc_unregister_driver(lirc->drv->minor); 420 lirc_buffer_free(lirc->drv->rbuf); 421 kfree(lirc->drv); 422 423 return 0; 424} 425 426static struct ir_raw_handler lirc_handler = { 427 .protocols = RC_BIT_LIRC, 428 .decode = ir_lirc_decode, 429 .raw_register = ir_lirc_register, 430 .raw_unregister = ir_lirc_unregister, 431}; 432 433static int __init ir_lirc_codec_init(void) 434{ 435 ir_raw_handler_register(&lirc_handler); 436 437 printk(KERN_INFO "IR LIRC bridge handler initialized\n"); 438 return 0; 439} 440 441static void __exit ir_lirc_codec_exit(void) 442{ 443 ir_raw_handler_unregister(&lirc_handler); 444} 445 446module_init(ir_lirc_codec_init); 447module_exit(ir_lirc_codec_exit); 448 449MODULE_LICENSE("GPL"); 450MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); 451MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); 452MODULE_DESCRIPTION("LIRC IR handler bridge"); 453