1 From 277c109833c1d78543bec0723ab42f4c79937df9 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] 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 lirc: Remove restriction on gpio pins that can be used with lirc
11 Compute Module, for example could use different pins
13 lirc_rpi: Add parameter to specify input pin pull
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.
19 Signed-off-by: Julian Scheel <julian@jusst.de>
21 lirc-rpi: Use the higher-level irq control functions
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.
29 lirc-rpi: Correct the interrupt usage
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
35 lirc-rpi: use getnstimeofday instead of read_current_timer
37 read_current_timer isn't guaranteed to return values in
38 microseconds, and indeed it doesn't on a Pi2.
42 lirc-rpi: Add device tree support, and a suitable overlay
44 The overlay supports DT parameters that match the old module
45 parameters, except that gpio_in_pull should be set using the
46 strings "up", "down" or "off".
48 lirc-rpi: Also support pinctrl-bcm2835 in non-DT mode
50 fix auto-sense in lirc_rpi driver
52 On a Raspberry Pi 2, the lirc_rpi driver might receive spurious
53 interrupts and change it's low-active / high-active setting.
54 When this happens, the IR remote control stops working.
56 This patch disables this auto-detection if the 'sense' parameter
57 was set in the device tree, making the driver robust to such
60 drivers/staging/media/lirc/Kconfig | 6 +
61 drivers/staging/media/lirc/Makefile | 1 +
62 drivers/staging/media/lirc/lirc_rpi.c | 734 ++++++++++++++++++++++++++++++++++
63 include/linux/platform_data/bcm2708.h | 23 ++
64 4 files changed, 764 insertions(+)
65 create mode 100644 drivers/staging/media/lirc/lirc_rpi.c
66 create mode 100644 include/linux/platform_data/bcm2708.h
68 --- a/drivers/staging/media/lirc/Kconfig
69 +++ b/drivers/staging/media/lirc/Kconfig
70 @@ -32,6 +32,12 @@ config LIRC_PARALLEL
72 Driver for Homebrew Parallel Port Receivers
75 + tristate "Homebrew GPIO Port Receiver/Transmitter for the RaspberryPi"
78 + Driver for Homebrew GPIO Port Receiver/Transmitter for the RaspberryPi
81 tristate "Sasem USB IR Remote"
82 depends on LIRC && USB
83 --- a/drivers/staging/media/lirc/Makefile
84 +++ b/drivers/staging/media/lirc/Makefile
86 obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
87 obj-$(CONFIG_LIRC_IMON) += lirc_imon.o
88 obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
89 +obj-$(CONFIG_LIRC_RPI) += lirc_rpi.o
90 obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
91 obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
92 obj-$(CONFIG_LIRC_SIR) += lirc_sir.o
94 +++ b/drivers/staging/media/lirc/lirc_rpi.c
99 + * lirc_rpi - Device driver that records pulse- and pause-lengths
100 + * (space-lengths) (just like the lirc_serial driver does)
101 + * between GPIO interrupt events on the Raspberry Pi.
102 + * Lots of code has been taken from the lirc_serial module,
103 + * so I would like say thanks to the authors.
105 + * Copyright (C) 2012 Aron Robert Szabo <aron@reon.hu>,
106 + * Michael Bishop <cleverca22@gmail.com>
107 + * This program is free software; you can redistribute it and/or modify
108 + * it under the terms of the GNU General Public License as published by
109 + * the Free Software Foundation; either version 2 of the License, or
110 + * (at your option) any later version.
112 + * This program is distributed in the hope that it will be useful,
113 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
114 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
115 + * GNU General Public License for more details.
117 + * You should have received a copy of the GNU General Public License
118 + * along with this program; if not, write to the Free Software
119 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
122 +#include <linux/module.h>
123 +#include <linux/errno.h>
124 +#include <linux/interrupt.h>
125 +#include <linux/sched.h>
126 +#include <linux/kernel.h>
127 +#include <linux/time.h>
128 +#include <linux/timex.h>
129 +#include <linux/timekeeping.h>
130 +#include <linux/string.h>
131 +#include <linux/delay.h>
132 +#include <linux/platform_device.h>
133 +#include <linux/irq.h>
134 +#include <linux/spinlock.h>
135 +#include <media/lirc.h>
136 +#include <media/lirc_dev.h>
137 +#include <linux/gpio.h>
138 +#include <linux/of_platform.h>
139 +#include <linux/platform_data/bcm2708.h>
141 +#define LIRC_DRIVER_NAME "lirc_rpi"
142 +#define RBUF_LEN 256
143 +#define LIRC_TRANSMITTER_LATENCY 50
145 +#ifndef MAX_UDELAY_MS
146 +#define MAX_UDELAY_US 5000
148 +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000)
151 +#define dprintk(fmt, args...) \
154 + printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \
158 +/* module parameters */
160 +/* set the default GPIO input pin */
161 +static int gpio_in_pin = 18;
162 +/* set the default pull behaviour for input pin */
163 +static int gpio_in_pull = BCM2708_PULL_DOWN;
164 +/* set the default GPIO output pin */
165 +static int gpio_out_pin = 17;
166 +/* enable debugging messages */
168 +/* -1 = auto, 0 = active high, 1 = active low */
169 +static int sense = -1;
170 +/* use softcarrier by default */
171 +static bool softcarrier = 1;
172 +/* 0 = do not invert output, 1 = invert output */
173 +static bool invert = 0;
175 +struct gpio_chip *gpiochip;
177 +static int auto_sense = 1;
179 +/* forward declarations */
180 +static long send_pulse(unsigned long length);
181 +static void send_space(long length);
182 +static void lirc_rpi_exit(void);
184 +static struct platform_device *lirc_rpi_dev;
185 +static struct timeval lasttv = { 0, 0 };
186 +static struct lirc_buffer rbuf;
187 +static spinlock_t lock;
189 +/* initialized/set in init_timing_params() */
190 +static unsigned int freq = 38000;
191 +static unsigned int duty_cycle = 50;
192 +static unsigned long period;
193 +static unsigned long pulse_width;
194 +static unsigned long space_width;
196 +static void safe_udelay(unsigned long usecs)
198 + while (usecs > MAX_UDELAY_US) {
199 + udelay(MAX_UDELAY_US);
200 + usecs -= MAX_UDELAY_US;
205 +static unsigned long read_current_us(void)
207 + struct timespec now;
208 + getnstimeofday(&now);
209 + return (now.tv_sec * 1000000) + (now.tv_nsec/1000);
212 +static int init_timing_params(unsigned int new_duty_cycle,
213 + unsigned int new_freq)
215 + if (1000 * 1000000L / new_freq * new_duty_cycle / 100 <=
216 + LIRC_TRANSMITTER_LATENCY)
218 + if (1000 * 1000000L / new_freq * (100 - new_duty_cycle) / 100 <=
219 + LIRC_TRANSMITTER_LATENCY)
221 + duty_cycle = new_duty_cycle;
223 + period = 1000 * 1000000L / freq;
224 + pulse_width = period * duty_cycle / 100;
225 + space_width = period - pulse_width;
226 + dprintk("in init_timing_params, freq=%d pulse=%ld, "
227 + "space=%ld\n", freq, pulse_width, space_width);
231 +static long send_pulse_softcarrier(unsigned long length)
234 + unsigned long actual, target;
235 + unsigned long actual_us, initial_us, target_us;
239 + actual = 0; target = 0; flag = 0;
240 + actual_us = read_current_us();
242 + while (actual < length) {
244 + gpiochip->set(gpiochip, gpio_out_pin, invert);
245 + target += space_width;
247 + gpiochip->set(gpiochip, gpio_out_pin, !invert);
248 + target += pulse_width;
250 + initial_us = actual_us;
251 + target_us = actual_us + (target - actual) / 1000;
253 + * Note - we've checked in ioctl that the pulse/space
254 + * widths are big enough so that d is > 0
256 + if ((int)(target_us - actual_us) > 0)
257 + udelay(target_us - actual_us);
258 + actual_us = read_current_us();
259 + actual += (actual_us - initial_us) * 1000;
262 + return (actual-length) / 1000;
265 +static long send_pulse(unsigned long length)
271 + return send_pulse_softcarrier(length);
273 + gpiochip->set(gpiochip, gpio_out_pin, !invert);
274 + safe_udelay(length);
279 +static void send_space(long length)
281 + gpiochip->set(gpiochip, gpio_out_pin, invert);
284 + safe_udelay(length);
287 +static void rbwrite(int l)
289 + if (lirc_buffer_full(&rbuf)) {
290 + /* no new signals will be accepted */
291 + dprintk("Buffer overrun\n");
294 + lirc_buffer_write(&rbuf, (void *)&l);
297 +static void frbwrite(int l)
299 + /* simple noise filter */
300 + static int pulse, space;
301 + static unsigned int ptr;
303 + if (ptr > 0 && (l & PULSE_BIT)) {
304 + pulse += l & PULSE_MASK;
307 + rbwrite(pulse | PULSE_BIT);
313 + if (!(l & PULSE_BIT)) {
323 + if (space > PULSE_MASK)
324 + space = PULSE_MASK;
326 + if (space > PULSE_MASK)
327 + space = PULSE_MASK;
332 + rbwrite(pulse | PULSE_BIT);
340 +static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs)
347 + /* use the GPIO signal level */
348 + signal = gpiochip->get(gpiochip, gpio_in_pin);
351 + /* get current time */
352 + do_gettimeofday(&tv);
354 + /* calc time since last interrupt in microseconds */
355 + deltv = tv.tv_sec-lasttv.tv_sec;
356 + if (tv.tv_sec < lasttv.tv_sec ||
357 + (tv.tv_sec == lasttv.tv_sec &&
358 + tv.tv_usec < lasttv.tv_usec)) {
359 + printk(KERN_WARNING LIRC_DRIVER_NAME
360 + ": AIEEEE: your clock just jumped backwards\n");
361 + printk(KERN_WARNING LIRC_DRIVER_NAME
362 + ": %d %d %lx %lx %lx %lx\n", signal, sense,
363 + tv.tv_sec, lasttv.tv_sec,
364 + tv.tv_usec, lasttv.tv_usec);
366 + } else if (deltv > 15) {
367 + data = PULSE_MASK; /* really long time */
368 + if (!(signal^sense)) {
370 + printk(KERN_DEBUG LIRC_DRIVER_NAME
371 + ": AIEEEE: %d %d %lx %lx %lx %lx\n",
372 + signal, sense, tv.tv_sec, lasttv.tv_sec,
373 + tv.tv_usec, lasttv.tv_usec);
375 + * detecting pulse while this
379 + sense = sense ? 0 : 1;
383 + data = (int) (deltv*1000000 +
384 + (tv.tv_usec - lasttv.tv_usec));
386 + frbwrite(signal^sense ? data : (data|PULSE_BIT));
388 + wake_up_interruptible(&rbuf.wait_poll);
391 + return IRQ_HANDLED;
394 +static int is_right_chip(struct gpio_chip *chip, void *data)
396 + dprintk("is_right_chip %s %d\n", chip->label, strcmp(data, chip->label));
398 + if (strcmp(data, chip->label) == 0)
403 +static inline int read_bool_property(const struct device_node *np,
404 + const char *propname,
408 + int err = of_property_read_u32(np, propname, &value);
410 + *out_value = (value != 0);
414 +static void read_pin_settings(struct device_node *node)
420 + of_property_read_u32_index(
428 + err = of_property_read_u32_index(
434 + if (function == 1) /* Output */
435 + gpio_out_pin = pin;
436 + else if (function == 0) /* Input */
442 +static int init_port(void)
444 + int i, nlow, nhigh;
445 + struct device_node *node;
447 + node = lirc_rpi_dev->dev.of_node;
449 + gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip);
452 + * Because of the lack of a setpull function, only support
453 + * pinctrl-bcm2835 if using device tree.
455 + if (!gpiochip && node)
456 + gpiochip = gpiochip_find("pinctrl-bcm2835", is_right_chip);
459 + pr_err(LIRC_DRIVER_NAME ": gpio chip not found!\n");
464 + struct device_node *pins_node;
466 + pins_node = of_parse_phandle(node, "pinctrl-0", 0);
468 + printk(KERN_ERR LIRC_DRIVER_NAME
469 + ": pinctrl settings not found!\n");
473 + read_pin_settings(pins_node);
475 + of_property_read_u32(node, "rpi,sense", &sense);
477 + read_bool_property(node, "rpi,softcarrier", &softcarrier);
479 + read_bool_property(node, "rpi,invert", &invert);
481 + read_bool_property(node, "rpi,debug", &debug);
487 + gpiochip->set(gpiochip, gpio_out_pin, invert);
489 + irq_num = gpiochip->to_irq(gpiochip, gpio_in_pin);
490 + dprintk("to_irq %d\n", irq_num);
492 + /* if pin is high, then this must be an active low receiver. */
494 + /* wait 1/2 sec for the power supply */
498 + * probe 9 times every 0.04s, collect "votes" for
503 + for (i = 0; i < 9; i++) {
504 + if (gpiochip->get(gpiochip, gpio_in_pin))
510 + sense = (nlow >= nhigh ? 1 : 0);
511 + printk(KERN_INFO LIRC_DRIVER_NAME
512 + ": auto-detected active %s receiver on GPIO pin %d\n",
513 + sense ? "low" : "high", gpio_in_pin);
515 + printk(KERN_INFO LIRC_DRIVER_NAME
516 + ": manually using active %s receiver on GPIO pin %d\n",
517 + sense ? "low" : "high", gpio_in_pin);
524 +// called when the character device is opened
525 +static int set_use_inc(void *data)
529 + /* initialize timestamp */
530 + do_gettimeofday(&lasttv);
532 + result = request_irq(irq_num,
533 + (irq_handler_t) irq_handler,
534 + IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING,
535 + LIRC_DRIVER_NAME, (void*) 0);
539 + printk(KERN_ERR LIRC_DRIVER_NAME
540 + ": IRQ %d is busy\n",
544 + printk(KERN_ERR LIRC_DRIVER_NAME
545 + ": Bad irq number or handler\n");
548 + dprintk("Interrupt %d obtained\n",
553 + /* initialize pulse/space widths */
554 + init_timing_params(duty_cycle, freq);
559 +static void set_use_dec(void *data)
561 + /* GPIO Pin Falling/Rising Edge Detect Disable */
562 + irq_set_irq_type(irq_num, 0);
563 + disable_irq(irq_num);
565 + free_irq(irq_num, (void *) 0);
567 + dprintk(KERN_INFO LIRC_DRIVER_NAME
568 + ": freed IRQ %d\n", irq_num);
571 +static ssize_t lirc_write(struct file *file, const char *buf,
572 + size_t n, loff_t *ppos)
575 + unsigned long flags;
579 + count = n / sizeof(int);
580 + if (n % sizeof(int) || count % 2 == 0)
582 + wbuf = memdup_user(buf, n);
584 + return PTR_ERR(wbuf);
585 + spin_lock_irqsave(&lock, flags);
587 + for (i = 0; i < count; i++) {
589 + send_space(wbuf[i] - delta);
591 + delta = send_pulse(wbuf[i]);
593 + gpiochip->set(gpiochip, gpio_out_pin, invert);
595 + spin_unlock_irqrestore(&lock, flags);
600 +static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
606 + case LIRC_GET_SEND_MODE:
607 + return -ENOIOCTLCMD;
610 + case LIRC_SET_SEND_MODE:
611 + result = get_user(value, (__u32 *) arg);
614 + /* only LIRC_MODE_PULSE supported */
615 + if (value != LIRC_MODE_PULSE)
619 + case LIRC_GET_LENGTH:
623 + case LIRC_SET_SEND_DUTY_CYCLE:
624 + dprintk("SET_SEND_DUTY_CYCLE\n");
625 + result = get_user(value, (__u32 *) arg);
628 + if (value <= 0 || value > 100)
630 + return init_timing_params(value, freq);
633 + case LIRC_SET_SEND_CARRIER:
634 + dprintk("SET_SEND_CARRIER\n");
635 + result = get_user(value, (__u32 *) arg);
638 + if (value > 500000 || value < 20000)
640 + return init_timing_params(duty_cycle, value);
644 + return lirc_dev_fop_ioctl(filep, cmd, arg);
649 +static const struct file_operations lirc_fops = {
650 + .owner = THIS_MODULE,
651 + .write = lirc_write,
652 + .unlocked_ioctl = lirc_ioctl,
653 + .read = lirc_dev_fop_read,
654 + .poll = lirc_dev_fop_poll,
655 + .open = lirc_dev_fop_open,
656 + .release = lirc_dev_fop_close,
657 + .llseek = no_llseek,
660 +static struct lirc_driver driver = {
661 + .name = LIRC_DRIVER_NAME,
666 + .add_to_buf = NULL,
668 + .set_use_inc = set_use_inc,
669 + .set_use_dec = set_use_dec,
670 + .fops = &lirc_fops,
672 + .owner = THIS_MODULE,
675 +static const struct of_device_id lirc_rpi_of_match[] = {
676 + { .compatible = "rpi,lirc-rpi", },
679 +MODULE_DEVICE_TABLE(of, lirc_rpi_of_match);
681 +static struct platform_driver lirc_rpi_driver = {
683 + .name = LIRC_DRIVER_NAME,
684 + .owner = THIS_MODULE,
685 + .of_match_table = of_match_ptr(lirc_rpi_of_match),
689 +static int __init lirc_rpi_init(void)
691 + struct device_node *node;
694 + /* Init read buffer. */
695 + result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN);
699 + result = platform_driver_register(&lirc_rpi_driver);
701 + printk(KERN_ERR LIRC_DRIVER_NAME
702 + ": lirc register returned %d\n", result);
703 + goto exit_buffer_free;
706 + node = of_find_compatible_node(NULL, NULL,
707 + lirc_rpi_of_match[0].compatible);
711 + lirc_rpi_dev = of_find_device_by_node(node);
712 + WARN_ON(lirc_rpi_dev->dev.of_node != node);
716 + lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
717 + if (!lirc_rpi_dev) {
719 + goto exit_driver_unregister;
722 + result = platform_device_add(lirc_rpi_dev);
724 + goto exit_device_put;
730 + platform_device_put(lirc_rpi_dev);
732 + exit_driver_unregister:
733 + platform_driver_unregister(&lirc_rpi_driver);
736 + lirc_buffer_free(&rbuf);
741 +static void lirc_rpi_exit(void)
743 + if (!lirc_rpi_dev->dev.of_node)
744 + platform_device_unregister(lirc_rpi_dev);
745 + platform_driver_unregister(&lirc_rpi_driver);
746 + lirc_buffer_free(&rbuf);
749 +static int __init lirc_rpi_init_module(void)
753 + result = lirc_rpi_init();
757 + result = init_port();
761 + driver.features = LIRC_CAN_SET_SEND_DUTY_CYCLE |
762 + LIRC_CAN_SET_SEND_CARRIER |
763 + LIRC_CAN_SEND_PULSE |
764 + LIRC_CAN_REC_MODE2;
766 + driver.dev = &lirc_rpi_dev->dev;
767 + driver.minor = lirc_register_driver(&driver);
769 + if (driver.minor < 0) {
770 + printk(KERN_ERR LIRC_DRIVER_NAME
771 + ": device registration failed with %d\n", result);
776 + printk(KERN_INFO LIRC_DRIVER_NAME ": driver registered!\n");
786 +static void __exit lirc_rpi_exit_module(void)
788 + lirc_unregister_driver(driver.minor);
790 + gpio_free(gpio_out_pin);
791 + gpio_free(gpio_in_pin);
795 + printk(KERN_INFO LIRC_DRIVER_NAME ": cleaned up module\n");
798 +module_init(lirc_rpi_init_module);
799 +module_exit(lirc_rpi_exit_module);
801 +MODULE_DESCRIPTION("Infra-red receiver and blaster driver for Raspberry Pi GPIO.");
802 +MODULE_AUTHOR("Aron Robert Szabo <aron@reon.hu>");
803 +MODULE_AUTHOR("Michael Bishop <cleverca22@gmail.com>");
804 +MODULE_LICENSE("GPL");
806 +module_param(gpio_out_pin, int, S_IRUGO);
807 +MODULE_PARM_DESC(gpio_out_pin, "GPIO output/transmitter pin number of the BCM"
808 + " processor. (default 17");
810 +module_param(gpio_in_pin, int, S_IRUGO);
811 +MODULE_PARM_DESC(gpio_in_pin, "GPIO input pin number of the BCM processor."
814 +module_param(gpio_in_pull, int, S_IRUGO);
815 +MODULE_PARM_DESC(gpio_in_pull, "GPIO input pin pull configuration."
816 + " (0 = off, 1 = up, 2 = down, default down)");
818 +module_param(sense, int, S_IRUGO);
819 +MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit"
820 + " (0 = active high, 1 = active low )");
822 +module_param(softcarrier, bool, S_IRUGO);
823 +MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)");
825 +module_param(invert, bool, S_IRUGO);
826 +MODULE_PARM_DESC(invert, "Invert output (0 = off, 1 = on, default off");
828 +module_param(debug, bool, S_IRUGO | S_IWUSR);
829 +MODULE_PARM_DESC(debug, "Enable debugging messages");
831 +++ b/include/linux/platform_data/bcm2708.h
834 + * include/linux/platform_data/bcm2708.h
836 + * This program is free software; you can redistribute it and/or modify
837 + * it under the terms of the GNU General Public License version 2 as
838 + * published by the Free Software Foundation.
840 + * (C) 2014 Julian Scheel <julian@jusst.de>
843 +#ifndef __BCM2708_H_
844 +#define __BCM2708_H_
850 +} bcm2708_gpio_pull_t;
852 +extern int bcm2708_gpio_setpull(struct gpio_chip *gc, unsigned offset,
853 + bcm2708_gpio_pull_t value);