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