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