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