ca23a3a9a78bc79317fe6e68859afdb3a57fe265
[openwrt.git] / target / linux / brcm2708 / patches-3.10 / 008-lirc_rpi_driver.patch
1 diff -urN linux-3.10/drivers/staging/media/lirc/Kconfig linux-rpi-3.10.y/drivers/staging/media/lirc/Kconfig
2 --- linux-3.10/drivers/staging/media/lirc/Kconfig       2013-06-30 23:13:29.000000000 +0100
3 +++ linux-rpi-3.10.y/drivers/staging/media/lirc/Kconfig 2013-07-06 15:25:50.000000000 +0100
4 @@ -38,6 +38,12 @@
5         help
6           Driver for Homebrew Parallel Port Receivers
7  
8 +config LIRC_RPI
9 +       tristate "Homebrew GPIO Port Receiver/Transmitter for the RaspberryPi"
10 +       depends on LIRC
11 +       help
12 +         Driver for Homebrew GPIO Port Receiver/Transmitter for the RaspberryPi
13 +
14  config LIRC_SASEM
15         tristate "Sasem USB IR Remote"
16         depends on LIRC && USB
17 diff -urN linux-3.10/drivers/staging/media/lirc/lirc_rpi.c linux-rpi-3.10.y/drivers/staging/media/lirc/lirc_rpi.c
18 --- linux-3.10/drivers/staging/media/lirc/lirc_rpi.c    1970-01-01 01:00:00.000000000 +0100
19 +++ linux-rpi-3.10.y/drivers/staging/media/lirc/lirc_rpi.c      2013-07-06 15:25:50.000000000 +0100
20 @@ -0,0 +1,692 @@
21 +/*
22 + * lirc_rpi.c
23 + *
24 + * lirc_rpi - Device driver that records pulse- and pause-lengths
25 + *           (space-lengths) (just like the lirc_serial driver does)
26 + *           between GPIO interrupt events on the Raspberry Pi.
27 + *           Lots of code has been taken from the lirc_serial module,
28 + *           so I would like say thanks to the authors.
29 + *
30 + * Copyright (C) 2012 Aron Robert Szabo <aron@reon.hu>,
31 + *                   Michael Bishop <cleverca22@gmail.com>
32 + *  This program is free software; you can redistribute it and/or modify
33 + *  it under the terms of the GNU General Public License as published by
34 + *  the Free Software Foundation; either version 2 of the License, or
35 + *  (at your option) any later version.
36 + *
37 + *  This program is distributed in the hope that it will be useful,
38 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
39 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40 + *  GNU General Public License for more details.
41 + *
42 + *  You should have received a copy of the GNU General Public License
43 + *  along with this program; if not, write to the Free Software
44 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
45 + */
46 +
47 +#include <linux/module.h>
48 +#include <linux/errno.h>
49 +#include <linux/interrupt.h>
50 +#include <linux/sched.h>
51 +#include <linux/kernel.h>
52 +#include <linux/time.h>
53 +#include <linux/string.h>
54 +#include <linux/delay.h>
55 +#include <linux/platform_device.h>
56 +#include <linux/irq.h>
57 +#include <linux/spinlock.h>
58 +#include <media/lirc.h>
59 +#include <media/lirc_dev.h>
60 +#include <linux/gpio.h>
61 +
62 +#define LIRC_DRIVER_NAME "lirc_rpi"
63 +#define RBUF_LEN 256
64 +#define LIRC_TRANSMITTER_LATENCY 256
65 +
66 +#ifndef MAX_UDELAY_MS
67 +#define MAX_UDELAY_US 5000
68 +#else
69 +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000)
70 +#endif
71 +
72 +#define dprintk(fmt, args...)                                  \
73 +       do {                                                    \
74 +               if (debug)                                      \
75 +                       printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \
76 +                              fmt, ## args);                   \
77 +       } while (0)
78 +
79 +/* module parameters */
80 +
81 +/* set the default GPIO input pin */
82 +static int gpio_in_pin = 18;
83 +/* set the default GPIO output pin */
84 +static int gpio_out_pin = 17;
85 +/* enable debugging messages */
86 +static int debug;
87 +/* -1 = auto, 0 = active high, 1 = active low */
88 +static int sense = -1;
89 +/* use softcarrier by default */
90 +static int softcarrier = 1;
91 +/* 0 = do not invert output, 1 = invert output */
92 +static int invert = 0;
93 +
94 +struct gpio_chip *gpiochip;
95 +struct irq_chip *irqchip;
96 +struct irq_data *irqdata;
97 +
98 +/* forward declarations */
99 +static long send_pulse(unsigned long length);
100 +static void send_space(long length);
101 +static void lirc_rpi_exit(void);
102 +
103 +int valid_gpio_pins[] = { 0, 1, 4, 8, 7, 9, 10, 11, 14, 15, 17, 18, 21, 22, 23,
104 +       24, 25 };
105 +
106 +static struct platform_device *lirc_rpi_dev;
107 +static struct timeval lasttv = { 0, 0 };
108 +static struct lirc_buffer rbuf;
109 +static spinlock_t lock;
110 +
111 +/* initialized/set in init_timing_params() */
112 +static unsigned int freq = 38000;
113 +static unsigned int duty_cycle = 50;
114 +static unsigned long period;
115 +static unsigned long pulse_width;
116 +static unsigned long space_width;
117 +
118 +static void safe_udelay(unsigned long usecs)
119 +{
120 +       while (usecs > MAX_UDELAY_US) {
121 +               udelay(MAX_UDELAY_US);
122 +               usecs -= MAX_UDELAY_US;
123 +       }
124 +       udelay(usecs);
125 +}
126 +
127 +static int init_timing_params(unsigned int new_duty_cycle,
128 +       unsigned int new_freq)
129 +{
130 +       /*
131 +        * period, pulse/space width are kept with 8 binary places -
132 +        * IE multiplied by 256.
133 +        */
134 +       if (256 * 1000000L / new_freq * new_duty_cycle / 100 <=
135 +           LIRC_TRANSMITTER_LATENCY)
136 +               return -EINVAL;
137 +       if (256 * 1000000L / new_freq * (100 - new_duty_cycle) / 100 <=
138 +           LIRC_TRANSMITTER_LATENCY)
139 +               return -EINVAL;
140 +       duty_cycle = new_duty_cycle;
141 +       freq = new_freq;
142 +       period = 256 * 1000000L / freq;
143 +       pulse_width = period * duty_cycle / 100;
144 +       space_width = period - pulse_width;
145 +       dprintk("in init_timing_params, freq=%d pulse=%ld, "
146 +               "space=%ld\n", freq, pulse_width, space_width);
147 +       return 0;
148 +}
149 +
150 +static long send_pulse_softcarrier(unsigned long length)
151 +{
152 +       int flag;
153 +       unsigned long actual, target, d;
154 +
155 +       length <<= 8;
156 +
157 +       actual = 0; target = 0; flag = 0;
158 +       while (actual < length) {
159 +               if (flag) {
160 +                       gpiochip->set(gpiochip, gpio_out_pin, invert);
161 +                       target += space_width;
162 +               } else {
163 +                       gpiochip->set(gpiochip, gpio_out_pin, !invert);
164 +                       target += pulse_width;
165 +               }
166 +               d = (target - actual -
167 +                    LIRC_TRANSMITTER_LATENCY + 128) >> 8;
168 +               /*
169 +                * Note - we've checked in ioctl that the pulse/space
170 +                * widths are big enough so that d is > 0
171 +                */
172 +               udelay(d);
173 +               actual += (d << 8) + LIRC_TRANSMITTER_LATENCY;
174 +               flag = !flag;
175 +       }
176 +       return (actual-length) >> 8;
177 +}
178 +
179 +static long send_pulse(unsigned long length)
180 +{
181 +       if (length <= 0)
182 +               return 0;
183 +
184 +       if (softcarrier) {
185 +               return send_pulse_softcarrier(length);
186 +       } else {
187 +               gpiochip->set(gpiochip, gpio_out_pin, !invert);
188 +               safe_udelay(length);
189 +               return 0;
190 +       }
191 +}
192 +
193 +static void send_space(long length)
194 +{
195 +       gpiochip->set(gpiochip, gpio_out_pin, invert);
196 +       if (length <= 0)
197 +               return;
198 +       safe_udelay(length);
199 +}
200 +
201 +static void rbwrite(int l)
202 +{
203 +       if (lirc_buffer_full(&rbuf)) {
204 +               /* no new signals will be accepted */
205 +               dprintk("Buffer overrun\n");
206 +               return;
207 +       }
208 +       lirc_buffer_write(&rbuf, (void *)&l);
209 +}
210 +
211 +static void frbwrite(int l)
212 +{
213 +       /* simple noise filter */
214 +       static int pulse, space;
215 +       static unsigned int ptr;
216 +
217 +       if (ptr > 0 && (l & PULSE_BIT)) {
218 +               pulse += l & PULSE_MASK;
219 +               if (pulse > 250) {
220 +                       rbwrite(space);
221 +                       rbwrite(pulse | PULSE_BIT);
222 +                       ptr = 0;
223 +                       pulse = 0;
224 +               }
225 +               return;
226 +       }
227 +       if (!(l & PULSE_BIT)) {
228 +               if (ptr == 0) {
229 +                       if (l > 20000) {
230 +                               space = l;
231 +                               ptr++;
232 +                               return;
233 +                       }
234 +               } else {
235 +                       if (l > 20000) {
236 +                               space += pulse;
237 +                               if (space > PULSE_MASK)
238 +                                       space = PULSE_MASK;
239 +                               space += l;
240 +                               if (space > PULSE_MASK)
241 +                                       space = PULSE_MASK;
242 +                               pulse = 0;
243 +                               return;
244 +                       }
245 +                       rbwrite(space);
246 +                       rbwrite(pulse | PULSE_BIT);
247 +                       ptr = 0;
248 +                       pulse = 0;
249 +               }
250 +       }
251 +       rbwrite(l);
252 +}
253 +
254 +static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs)
255 +{
256 +       struct timeval tv;
257 +       long deltv;
258 +       int data;
259 +       int signal;
260 +
261 +       /* use the GPIO signal level */
262 +       signal = gpiochip->get(gpiochip, gpio_in_pin);
263 +
264 +       /* unmask the irq */
265 +       irqchip->irq_unmask(irqdata);
266 +
267 +       if (sense != -1) {
268 +               /* get current time */
269 +               do_gettimeofday(&tv);
270 +
271 +               /* calc time since last interrupt in microseconds */
272 +               deltv = tv.tv_sec-lasttv.tv_sec;
273 +               if (tv.tv_sec < lasttv.tv_sec ||
274 +                   (tv.tv_sec == lasttv.tv_sec &&
275 +                    tv.tv_usec < lasttv.tv_usec)) {
276 +                       printk(KERN_WARNING LIRC_DRIVER_NAME
277 +                              ": AIEEEE: your clock just jumped backwards\n");
278 +                       printk(KERN_WARNING LIRC_DRIVER_NAME
279 +                              ": %d %d %lx %lx %lx %lx\n", signal, sense,
280 +                              tv.tv_sec, lasttv.tv_sec,
281 +                              tv.tv_usec, lasttv.tv_usec);
282 +                       data = PULSE_MASK;
283 +               } else if (deltv > 15) {
284 +                       data = PULSE_MASK; /* really long time */
285 +                       if (!(signal^sense)) {
286 +                               /* sanity check */
287 +                               printk(KERN_WARNING LIRC_DRIVER_NAME
288 +                                      ": AIEEEE: %d %d %lx %lx %lx %lx\n",
289 +                                      signal, sense, tv.tv_sec, lasttv.tv_sec,
290 +                                      tv.tv_usec, lasttv.tv_usec);
291 +                               /*
292 +                                * detecting pulse while this
293 +                                * MUST be a space!
294 +                                */
295 +                               sense = sense ? 0 : 1;
296 +                       }
297 +               } else {
298 +                       data = (int) (deltv*1000000 +
299 +                                     (tv.tv_usec - lasttv.tv_usec));
300 +               }
301 +               frbwrite(signal^sense ? data : (data|PULSE_BIT));
302 +               lasttv = tv;
303 +               wake_up_interruptible(&rbuf.wait_poll);
304 +       }
305 +
306 +       return IRQ_HANDLED;
307 +}
308 +
309 +static int is_right_chip(struct gpio_chip *chip, void *data)
310 +{
311 +       dprintk("is_right_chip %s %d\n", chip->label, strcmp(data, chip->label));
312 +
313 +       if (strcmp(data, chip->label) == 0)
314 +               return 1;
315 +       return 0;
316 +}
317 +
318 +static int init_port(void)
319 +{
320 +       int i, nlow, nhigh, ret, irq;
321 +
322 +       gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip);
323 +
324 +       if (!gpiochip)
325 +               return -ENODEV;
326 +
327 +       if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) {
328 +               printk(KERN_ALERT LIRC_DRIVER_NAME
329 +                      ": cant claim gpio pin %d\n", gpio_out_pin);
330 +               ret = -ENODEV;
331 +               goto exit_init_port;
332 +       }
333 +
334 +       if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) {
335 +               printk(KERN_ALERT LIRC_DRIVER_NAME
336 +                      ": cant claim gpio pin %d\n", gpio_in_pin);
337 +               ret = -ENODEV;
338 +               goto exit_gpio_free_out_pin;
339 +       }
340 +
341 +       gpiochip->direction_input(gpiochip, gpio_in_pin);
342 +       gpiochip->direction_output(gpiochip, gpio_out_pin, 1);
343 +       gpiochip->set(gpiochip, gpio_out_pin, invert);
344 +
345 +       irq = gpiochip->to_irq(gpiochip, gpio_in_pin);
346 +       dprintk("to_irq %d\n", irq);
347 +       irqdata = irq_get_irq_data(irq);
348 +
349 +       if (irqdata && irqdata->chip) {
350 +               irqchip = irqdata->chip;
351 +       } else {
352 +               ret = -ENODEV;
353 +               goto exit_gpio_free_in_pin;
354 +       }
355 +
356 +       /* if pin is high, then this must be an active low receiver. */
357 +       if (sense == -1) {
358 +               /* wait 1/2 sec for the power supply */
359 +               msleep(500);
360 +
361 +               /*
362 +                * probe 9 times every 0.04s, collect "votes" for
363 +                * active high/low
364 +                */
365 +               nlow = 0;
366 +               nhigh = 0;
367 +               for (i = 0; i < 9; i++) {
368 +                       if (gpiochip->get(gpiochip, gpio_in_pin))
369 +                               nlow++;
370 +                       else
371 +                               nhigh++;
372 +                       msleep(40);
373 +               }
374 +               sense = (nlow >= nhigh ? 1 : 0);
375 +               printk(KERN_INFO LIRC_DRIVER_NAME
376 +                      ": auto-detected active %s receiver on GPIO pin %d\n",
377 +                      sense ? "low" : "high", gpio_in_pin);
378 +       } else {
379 +               printk(KERN_INFO LIRC_DRIVER_NAME
380 +                      ": manually using active %s receiver on GPIO pin %d\n",
381 +                      sense ? "low" : "high", gpio_in_pin);
382 +       }
383 +
384 +       return 0;
385 +
386 +       exit_gpio_free_in_pin:
387 +       gpio_free(gpio_in_pin);
388 +
389 +       exit_gpio_free_out_pin:
390 +       gpio_free(gpio_out_pin);
391 +
392 +       exit_init_port:
393 +       return ret;
394 +}
395 +
396 +// called when the character device is opened
397 +static int set_use_inc(void *data)
398 +{
399 +       int result;
400 +       unsigned long flags;
401 +
402 +       /* initialize timestamp */
403 +       do_gettimeofday(&lasttv);
404 +
405 +       result = request_irq(gpiochip->to_irq(gpiochip, gpio_in_pin),
406 +                            (irq_handler_t) irq_handler, 0,
407 +                            LIRC_DRIVER_NAME, (void*) 0);
408 +
409 +       switch (result) {
410 +       case -EBUSY:
411 +               printk(KERN_ERR LIRC_DRIVER_NAME
412 +                      ": IRQ %d is busy\n",
413 +                      gpiochip->to_irq(gpiochip, gpio_in_pin));
414 +               return -EBUSY;
415 +       case -EINVAL:
416 +               printk(KERN_ERR LIRC_DRIVER_NAME
417 +                      ": Bad irq number or handler\n");
418 +               return -EINVAL;
419 +       default:
420 +               dprintk("Interrupt %d obtained\n",
421 +                       gpiochip->to_irq(gpiochip, gpio_in_pin));
422 +               break;
423 +       };
424 +
425 +       /* initialize pulse/space widths */
426 +       init_timing_params(duty_cycle, freq);
427 +
428 +       spin_lock_irqsave(&lock, flags);
429 +
430 +       /* GPIO Pin Falling/Rising Edge Detect Enable */
431 +       irqchip->irq_set_type(irqdata,
432 +                             IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING);
433 +
434 +       /* unmask the irq */
435 +       irqchip->irq_unmask(irqdata);
436 +
437 +       spin_unlock_irqrestore(&lock, flags);
438 +
439 +       return 0;
440 +}
441 +
442 +static void set_use_dec(void *data)
443 +{
444 +       unsigned long flags;
445 +
446 +       spin_lock_irqsave(&lock, flags);
447 +
448 +       /* GPIO Pin Falling/Rising Edge Detect Disable */
449 +       irqchip->irq_set_type(irqdata, 0);
450 +       irqchip->irq_mask(irqdata);
451 +
452 +       spin_unlock_irqrestore(&lock, flags);
453 +
454 +       free_irq(gpiochip->to_irq(gpiochip, gpio_in_pin), (void *) 0);
455 +
456 +       dprintk(KERN_INFO LIRC_DRIVER_NAME
457 +               ": freed IRQ %d\n", gpiochip->to_irq(gpiochip, gpio_in_pin));
458 +}
459 +
460 +static ssize_t lirc_write(struct file *file, const char *buf,
461 +       size_t n, loff_t *ppos)
462 +{
463 +       int i, count;
464 +       unsigned long flags;
465 +       long delta = 0;
466 +       int *wbuf;
467 +
468 +       count = n / sizeof(int);
469 +       if (n % sizeof(int) || count % 2 == 0)
470 +               return -EINVAL;
471 +       wbuf = memdup_user(buf, n);
472 +       if (IS_ERR(wbuf))
473 +               return PTR_ERR(wbuf);
474 +       spin_lock_irqsave(&lock, flags);
475 +
476 +       for (i = 0; i < count; i++) {
477 +               if (i%2)
478 +                       send_space(wbuf[i] - delta);
479 +               else
480 +                       delta = send_pulse(wbuf[i]);
481 +       }
482 +       gpiochip->set(gpiochip, gpio_out_pin, invert);
483 +
484 +       spin_unlock_irqrestore(&lock, flags);
485 +       kfree(wbuf);
486 +       return n;
487 +}
488 +
489 +static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
490 +{
491 +       int result;
492 +       __u32 value;
493 +
494 +       switch (cmd) {
495 +       case LIRC_GET_SEND_MODE:
496 +               return -ENOIOCTLCMD;
497 +               break;
498 +
499 +       case LIRC_SET_SEND_MODE:
500 +               result = get_user(value, (__u32 *) arg);
501 +               if (result)
502 +                       return result;
503 +               /* only LIRC_MODE_PULSE supported */
504 +               if (value != LIRC_MODE_PULSE)
505 +                       return -ENOSYS;
506 +               break;
507 +
508 +       case LIRC_GET_LENGTH:
509 +               return -ENOSYS;
510 +               break;
511 +
512 +       case LIRC_SET_SEND_DUTY_CYCLE:
513 +               dprintk("SET_SEND_DUTY_CYCLE\n");
514 +               result = get_user(value, (__u32 *) arg);
515 +               if (result)
516 +                       return result;
517 +               if (value <= 0 || value > 100)
518 +                       return -EINVAL;
519 +               return init_timing_params(value, freq);
520 +               break;
521 +
522 +       case LIRC_SET_SEND_CARRIER:
523 +               dprintk("SET_SEND_CARRIER\n");
524 +               result = get_user(value, (__u32 *) arg);
525 +               if (result)
526 +                       return result;
527 +               if (value > 500000 || value < 20000)
528 +                       return -EINVAL;
529 +               return init_timing_params(duty_cycle, value);
530 +               break;
531 +
532 +       default:
533 +               return lirc_dev_fop_ioctl(filep, cmd, arg);
534 +       }
535 +       return 0;
536 +}
537 +
538 +static const struct file_operations lirc_fops = {
539 +       .owner          = THIS_MODULE,
540 +       .write          = lirc_write,
541 +       .unlocked_ioctl = lirc_ioctl,
542 +       .read           = lirc_dev_fop_read,
543 +       .poll           = lirc_dev_fop_poll,
544 +       .open           = lirc_dev_fop_open,
545 +       .release        = lirc_dev_fop_close,
546 +       .llseek         = no_llseek,
547 +};
548 +
549 +static struct lirc_driver driver = {
550 +       .name           = LIRC_DRIVER_NAME,
551 +       .minor          = -1,
552 +       .code_length    = 1,
553 +       .sample_rate    = 0,
554 +       .data           = NULL,
555 +       .add_to_buf     = NULL,
556 +       .rbuf           = &rbuf,
557 +       .set_use_inc    = set_use_inc,
558 +       .set_use_dec    = set_use_dec,
559 +       .fops           = &lirc_fops,
560 +       .dev            = NULL,
561 +       .owner          = THIS_MODULE,
562 +};
563 +
564 +static struct platform_driver lirc_rpi_driver = {
565 +       .driver = {
566 +               .name   = LIRC_DRIVER_NAME,
567 +               .owner  = THIS_MODULE,
568 +       },
569 +};
570 +
571 +static int __init lirc_rpi_init(void)
572 +{
573 +       int result;
574 +
575 +       /* Init read buffer. */
576 +       result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN);
577 +       if (result < 0)
578 +               return -ENOMEM;
579 +
580 +       result = platform_driver_register(&lirc_rpi_driver);
581 +       if (result) {
582 +               printk(KERN_ERR LIRC_DRIVER_NAME
583 +                      ": lirc register returned %d\n", result);
584 +               goto exit_buffer_free;
585 +       }
586 +
587 +       lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
588 +       if (!lirc_rpi_dev) {
589 +               result = -ENOMEM;
590 +               goto exit_driver_unregister;
591 +       }
592 +
593 +       result = platform_device_add(lirc_rpi_dev);
594 +       if (result)
595 +               goto exit_device_put;
596 +
597 +       return 0;
598 +
599 +       exit_device_put:
600 +       platform_device_put(lirc_rpi_dev);
601 +
602 +       exit_driver_unregister:
603 +       platform_driver_unregister(&lirc_rpi_driver);
604 +
605 +       exit_buffer_free:
606 +       lirc_buffer_free(&rbuf);
607 +
608 +       return result;
609 +}
610 +
611 +static void lirc_rpi_exit(void)
612 +{
613 +       gpio_free(gpio_out_pin);
614 +       gpio_free(gpio_in_pin);
615 +       platform_device_unregister(lirc_rpi_dev);
616 +       platform_driver_unregister(&lirc_rpi_driver);
617 +       lirc_buffer_free(&rbuf);
618 +}
619 +
620 +static int __init lirc_rpi_init_module(void)
621 +{
622 +       int result, i;
623 +
624 +       result = lirc_rpi_init();
625 +       if (result)
626 +               return result;
627 +
628 +       /* check if the module received valid gpio pin numbers */
629 +       result = 0;
630 +       if (gpio_in_pin != gpio_out_pin) {
631 +               for(i = 0; (i < ARRAY_SIZE(valid_gpio_pins)) && (result != 2); i++) {
632 +                       if (gpio_in_pin == valid_gpio_pins[i] ||
633 +                          gpio_out_pin == valid_gpio_pins[i]) {
634 +                               result++;
635 +                       }
636 +               }
637 +       }
638 +
639 +       if (result != 2) {
640 +               result = -EINVAL;
641 +               printk(KERN_ERR LIRC_DRIVER_NAME
642 +                      ": invalid GPIO pin(s) specified!\n");
643 +               goto exit_rpi;
644 +       }
645 +
646 +       driver.features = LIRC_CAN_SET_SEND_DUTY_CYCLE |
647 +                         LIRC_CAN_SET_SEND_CARRIER |
648 +                         LIRC_CAN_SEND_PULSE |
649 +                         LIRC_CAN_REC_MODE2;
650 +
651 +       driver.dev = &lirc_rpi_dev->dev;
652 +       driver.minor = lirc_register_driver(&driver);
653 +
654 +       if (driver.minor < 0) {
655 +               printk(KERN_ERR LIRC_DRIVER_NAME
656 +                      ": device registration failed with %d\n", result);
657 +               result = -EIO;
658 +               goto exit_rpi;
659 +       }
660 +
661 +       printk(KERN_INFO LIRC_DRIVER_NAME ": driver registered!\n");
662 +
663 +       result = init_port();
664 +       if (result < 0)
665 +               goto exit_rpi;
666 +
667 +       return 0;
668 +
669 +       exit_rpi:
670 +       lirc_rpi_exit();
671 +
672 +       return result;
673 +}
674 +
675 +static void __exit lirc_rpi_exit_module(void)
676 +{
677 +       lirc_rpi_exit();
678 +
679 +       lirc_unregister_driver(driver.minor);
680 +       printk(KERN_INFO LIRC_DRIVER_NAME ": cleaned up module\n");
681 +}
682 +
683 +module_init(lirc_rpi_init_module);
684 +module_exit(lirc_rpi_exit_module);
685 +
686 +MODULE_DESCRIPTION("Infra-red receiver and blaster driver for Raspberry Pi GPIO.");
687 +MODULE_AUTHOR("Aron Robert Szabo <aron@reon.hu>");
688 +MODULE_AUTHOR("Michael Bishop <cleverca22@gmail.com>");
689 +MODULE_LICENSE("GPL");
690 +
691 +module_param(gpio_out_pin, int, S_IRUGO);
692 +MODULE_PARM_DESC(gpio_out_pin, "GPIO output/transmitter pin number of the BCM"
693 +                " processor. Valid pin numbers are: 0, 1, 4, 8, 7, 9, 10, 11,"
694 +                " 14, 15, 17, 18, 21, 22, 23, 24, 25, default 17");
695 +
696 +module_param(gpio_in_pin, int, S_IRUGO);
697 +MODULE_PARM_DESC(gpio_in_pin, "GPIO input pin number of the BCM processor."
698 +                " Valid pin numbers are: 0, 1, 4, 8, 7, 9, 10, 11, 14, 15,"
699 +                " 17, 18, 21, 22, 23, 24, 25, default 18");
700 +
701 +module_param(sense, bool, S_IRUGO);
702 +MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit"
703 +                " (0 = active high, 1 = active low )");
704 +
705 +module_param(softcarrier, bool, S_IRUGO);
706 +MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)");
707 +
708 +module_param(invert, bool, S_IRUGO);
709 +MODULE_PARM_DESC(invert, "Invert output (0 = off, 1 = on, default off");
710 +
711 +module_param(debug, bool, S_IRUGO | S_IWUSR);
712 +MODULE_PARM_DESC(debug, "Enable debugging messages");
713 diff -urN linux-3.10/drivers/staging/media/lirc/Makefile linux-rpi-3.10.y/drivers/staging/media/lirc/Makefile
714 --- linux-3.10/drivers/staging/media/lirc/Makefile      2013-06-30 23:13:29.000000000 +0100
715 +++ linux-rpi-3.10.y/drivers/staging/media/lirc/Makefile        2013-07-06 15:25:50.000000000 +0100
716 @@ -7,6 +7,7 @@
717  obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o
718  obj-$(CONFIG_LIRC_IMON)                += lirc_imon.o
719  obj-$(CONFIG_LIRC_PARALLEL)    += lirc_parallel.o
720 +obj-$(CONFIG_LIRC_RPI)         += lirc_rpi.o
721  obj-$(CONFIG_LIRC_SASEM)       += lirc_sasem.o
722  obj-$(CONFIG_LIRC_SERIAL)      += lirc_serial.o
723  obj-$(CONFIG_LIRC_SIR)         += lirc_sir.o