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