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