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