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
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
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
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
21 Driver for Homebrew Parallel Port Receivers
24 + tristate "Homebrew GPIO Port Receiver/Transmitter for the RaspberryPi"
27 + Driver for Homebrew GPIO Port Receiver/Transmitter for the RaspberryPi
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
46 index 0000000..57ffacf
48 +++ b/drivers/staging/media/lirc/lirc_rpi.c
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.
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.
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.
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
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>
92 +#define LIRC_DRIVER_NAME "lirc_rpi"
94 +#define LIRC_TRANSMITTER_LATENCY 50
96 +#ifndef MAX_UDELAY_MS
97 +#define MAX_UDELAY_US 5000
99 +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000)
102 +#define dprintk(fmt, args...) \
105 + printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \
109 +/* module parameters */
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 */
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;
124 +struct gpio_chip *gpiochip;
125 +struct irq_chip *irqchip;
126 +struct irq_data *irqdata;
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);
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 };
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;
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;
148 +static void safe_udelay(unsigned long usecs)
150 + while (usecs > MAX_UDELAY_US) {
151 + udelay(MAX_UDELAY_US);
152 + usecs -= MAX_UDELAY_US;
157 +static int init_timing_params(unsigned int new_duty_cycle,
158 + unsigned int new_freq)
160 + if (1000 * 1000000L / new_freq * new_duty_cycle / 100 <=
161 + LIRC_TRANSMITTER_LATENCY)
163 + if (1000 * 1000000L / new_freq * (100 - new_duty_cycle) / 100 <=
164 + LIRC_TRANSMITTER_LATENCY)
166 + duty_cycle = new_duty_cycle;
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);
176 +static long send_pulse_softcarrier(unsigned long length)
179 + unsigned long actual, target;
180 + unsigned long actual_us, initial_us, target_us;
184 + actual = 0; target = 0; flag = 0;
185 + read_current_timer(&actual_us);
187 + while (actual < length) {
189 + gpiochip->set(gpiochip, gpio_out_pin, invert);
190 + target += space_width;
192 + gpiochip->set(gpiochip, gpio_out_pin, !invert);
193 + target += pulse_width;
195 + initial_us = actual_us;
196 + target_us = actual_us + (target - actual) / 1000;
198 + * Note - we've checked in ioctl that the pulse/space
199 + * widths are big enough so that d is > 0
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;
207 + return (actual-length) / 1000;
210 +static long send_pulse(unsigned long length)
216 + return send_pulse_softcarrier(length);
218 + gpiochip->set(gpiochip, gpio_out_pin, !invert);
219 + safe_udelay(length);
224 +static void send_space(long length)
226 + gpiochip->set(gpiochip, gpio_out_pin, invert);
229 + safe_udelay(length);
232 +static void rbwrite(int l)
234 + if (lirc_buffer_full(&rbuf)) {
235 + /* no new signals will be accepted */
236 + dprintk("Buffer overrun\n");
239 + lirc_buffer_write(&rbuf, (void *)&l);
242 +static void frbwrite(int l)
244 + /* simple noise filter */
245 + static int pulse, space;
246 + static unsigned int ptr;
248 + if (ptr > 0 && (l & PULSE_BIT)) {
249 + pulse += l & PULSE_MASK;
252 + rbwrite(pulse | PULSE_BIT);
258 + if (!(l & PULSE_BIT)) {
268 + if (space > PULSE_MASK)
269 + space = PULSE_MASK;
271 + if (space > PULSE_MASK)
272 + space = PULSE_MASK;
277 + rbwrite(pulse | PULSE_BIT);
285 +static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs)
292 + /* use the GPIO signal level */
293 + signal = gpiochip->get(gpiochip, gpio_in_pin);
295 + /* unmask the irq */
296 + irqchip->irq_unmask(irqdata);
299 + /* get current time */
300 + do_gettimeofday(&tv);
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);
314 + } else if (deltv > 15) {
315 + data = PULSE_MASK; /* really long time */
316 + if (!(signal^sense)) {
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);
323 + * detecting pulse while this
326 + sense = sense ? 0 : 1;
329 + data = (int) (deltv*1000000 +
330 + (tv.tv_usec - lasttv.tv_usec));
332 + frbwrite(signal^sense ? data : (data|PULSE_BIT));
334 + wake_up_interruptible(&rbuf.wait_poll);
337 + return IRQ_HANDLED;
340 +static int is_right_chip(struct gpio_chip *chip, void *data)
342 + dprintk("is_right_chip %s %d\n", chip->label, strcmp(data, chip->label));
344 + if (strcmp(data, chip->label) == 0)
349 +static int init_port(void)
351 + int i, nlow, nhigh, ret, irq;
353 + gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip);
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);
362 + goto exit_init_port;
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);
369 + goto exit_gpio_free_out_pin;
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);
376 + irq = gpiochip->to_irq(gpiochip, gpio_in_pin);
377 + dprintk("to_irq %d\n", irq);
378 + irqdata = irq_get_irq_data(irq);
380 + if (irqdata && irqdata->chip) {
381 + irqchip = irqdata->chip;
384 + goto exit_gpio_free_in_pin;
387 + /* if pin is high, then this must be an active low receiver. */
389 + /* wait 1/2 sec for the power supply */
393 + * probe 9 times every 0.04s, collect "votes" for
398 + for (i = 0; i < 9; i++) {
399 + if (gpiochip->get(gpiochip, gpio_in_pin))
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);
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);
417 + exit_gpio_free_in_pin:
418 + gpio_free(gpio_in_pin);
420 + exit_gpio_free_out_pin:
421 + gpio_free(gpio_out_pin);
427 +// called when the character device is opened
428 +static int set_use_inc(void *data)
431 + unsigned long flags;
433 + /* initialize timestamp */
434 + do_gettimeofday(&lasttv);
436 + result = request_irq(gpiochip->to_irq(gpiochip, gpio_in_pin),
437 + (irq_handler_t) irq_handler, 0,
438 + LIRC_DRIVER_NAME, (void*) 0);
442 + printk(KERN_ERR LIRC_DRIVER_NAME
443 + ": IRQ %d is busy\n",
444 + gpiochip->to_irq(gpiochip, gpio_in_pin));
447 + printk(KERN_ERR LIRC_DRIVER_NAME
448 + ": Bad irq number or handler\n");
451 + dprintk("Interrupt %d obtained\n",
452 + gpiochip->to_irq(gpiochip, gpio_in_pin));
456 + /* initialize pulse/space widths */
457 + init_timing_params(duty_cycle, freq);
459 + spin_lock_irqsave(&lock, flags);
461 + /* GPIO Pin Falling/Rising Edge Detect Enable */
462 + irqchip->irq_set_type(irqdata,
463 + IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING);
465 + /* unmask the irq */
466 + irqchip->irq_unmask(irqdata);
468 + spin_unlock_irqrestore(&lock, flags);
473 +static void set_use_dec(void *data)
475 + unsigned long flags;
477 + spin_lock_irqsave(&lock, flags);
479 + /* GPIO Pin Falling/Rising Edge Detect Disable */
480 + irqchip->irq_set_type(irqdata, 0);
481 + irqchip->irq_mask(irqdata);
483 + spin_unlock_irqrestore(&lock, flags);
485 + free_irq(gpiochip->to_irq(gpiochip, gpio_in_pin), (void *) 0);
487 + dprintk(KERN_INFO LIRC_DRIVER_NAME
488 + ": freed IRQ %d\n", gpiochip->to_irq(gpiochip, gpio_in_pin));
491 +static ssize_t lirc_write(struct file *file, const char *buf,
492 + size_t n, loff_t *ppos)
495 + unsigned long flags;
499 + count = n / sizeof(int);
500 + if (n % sizeof(int) || count % 2 == 0)
502 + wbuf = memdup_user(buf, n);
504 + return PTR_ERR(wbuf);
505 + spin_lock_irqsave(&lock, flags);
507 + for (i = 0; i < count; i++) {
509 + send_space(wbuf[i] - delta);
511 + delta = send_pulse(wbuf[i]);
513 + gpiochip->set(gpiochip, gpio_out_pin, invert);
515 + spin_unlock_irqrestore(&lock, flags);
520 +static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
526 + case LIRC_GET_SEND_MODE:
527 + return -ENOIOCTLCMD;
530 + case LIRC_SET_SEND_MODE:
531 + result = get_user(value, (__u32 *) arg);
534 + /* only LIRC_MODE_PULSE supported */
535 + if (value != LIRC_MODE_PULSE)
539 + case LIRC_GET_LENGTH:
543 + case LIRC_SET_SEND_DUTY_CYCLE:
544 + dprintk("SET_SEND_DUTY_CYCLE\n");
545 + result = get_user(value, (__u32 *) arg);
548 + if (value <= 0 || value > 100)
550 + return init_timing_params(value, freq);
553 + case LIRC_SET_SEND_CARRIER:
554 + dprintk("SET_SEND_CARRIER\n");
555 + result = get_user(value, (__u32 *) arg);
558 + if (value > 500000 || value < 20000)
560 + return init_timing_params(duty_cycle, value);
564 + return lirc_dev_fop_ioctl(filep, cmd, arg);
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,
580 +static struct lirc_driver driver = {
581 + .name = LIRC_DRIVER_NAME,
586 + .add_to_buf = NULL,
588 + .set_use_inc = set_use_inc,
589 + .set_use_dec = set_use_dec,
590 + .fops = &lirc_fops,
592 + .owner = THIS_MODULE,
595 +static struct platform_driver lirc_rpi_driver = {
597 + .name = LIRC_DRIVER_NAME,
598 + .owner = THIS_MODULE,
602 +static int __init lirc_rpi_init(void)
606 + /* Init read buffer. */
607 + result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN);
611 + result = platform_driver_register(&lirc_rpi_driver);
613 + printk(KERN_ERR LIRC_DRIVER_NAME
614 + ": lirc register returned %d\n", result);
615 + goto exit_buffer_free;
618 + lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
619 + if (!lirc_rpi_dev) {
621 + goto exit_driver_unregister;
624 + result = platform_device_add(lirc_rpi_dev);
626 + goto exit_device_put;
631 + platform_device_put(lirc_rpi_dev);
633 + exit_driver_unregister:
634 + platform_driver_unregister(&lirc_rpi_driver);
637 + lirc_buffer_free(&rbuf);
642 +static void lirc_rpi_exit(void)
644 + platform_device_unregister(lirc_rpi_dev);
645 + platform_driver_unregister(&lirc_rpi_driver);
646 + lirc_buffer_free(&rbuf);
649 +static int __init lirc_rpi_init_module(void)
653 + result = lirc_rpi_init();
657 + /* check if the module received valid gpio pin numbers */
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]) {
670 + printk(KERN_ERR LIRC_DRIVER_NAME
671 + ": invalid GPIO pin(s) specified!\n");
675 + result = init_port();
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;
684 + driver.dev = &lirc_rpi_dev->dev;
685 + driver.minor = lirc_register_driver(&driver);
687 + if (driver.minor < 0) {
688 + printk(KERN_ERR LIRC_DRIVER_NAME
689 + ": device registration failed with %d\n", result);
694 + printk(KERN_INFO LIRC_DRIVER_NAME ": driver registered!\n");
704 +static void __exit lirc_rpi_exit_module(void)
706 + gpio_free(gpio_out_pin);
707 + gpio_free(gpio_in_pin);
711 + lirc_unregister_driver(driver.minor);
712 + printk(KERN_INFO LIRC_DRIVER_NAME ": cleaned up module\n");
715 +module_init(lirc_rpi_init_module);
716 +module_exit(lirc_rpi_exit_module);
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");
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");
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");
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 )");
737 +module_param(softcarrier, bool, S_IRUGO);
738 +MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)");
740 +module_param(invert, bool, S_IRUGO);
741 +MODULE_PARM_DESC(invert, "Invert output (0 = off, 1 = on, default off");
743 +module_param(debug, bool, S_IRUGO | S_IWUSR);
744 +MODULE_PARM_DESC(debug, "Enable debugging messages");