1 From f3c1830096661e270f11f2a33ffb7274f50c90a6 Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.org>
3 Date: Thu, 18 Dec 2014 16:48:32 +0000
4 Subject: [PATCH 068/114] lirc-rpi: Add device tree support, and a suitable
7 The overlay supports DT parameters that match the old module
8 parameters, except that gpio_in_pull should be set using the
9 strings "up", "down" or "off".
11 lirc-rpi: Also support pinctrl-bcm2835 in non-DT mode
13 arch/arm/boot/dts/lirc-rpi-overlay.dts | 57 ++++++++++++
14 drivers/staging/media/lirc/lirc_rpi.c | 154 +++++++++++++++++++++++++++------
15 2 files changed, 183 insertions(+), 28 deletions(-)
16 create mode 100644 arch/arm/boot/dts/lirc-rpi-overlay.dts
19 +++ b/arch/arm/boot/dts/lirc-rpi-overlay.dts
21 +// Definitions for lirc-rpi module
26 + compatible = "brcm,bcm2708";
31 + lirc_rpi: lirc_rpi {
32 + compatible = "rpi,lirc-rpi";
33 + pinctrl-names = "default";
34 + pinctrl-0 = <&lirc_pins>;
37 + // Override autodetection of IR receiver circuit
38 + // (0 = active high, 1 = active low, -1 = no override )
39 + rpi,sense = <0xffffffff>;
42 + // (0 = off, 1 = on)
43 + rpi,softcarrier = <1>;
46 + // (0 = off, 1 = on)
49 + // Enable debugging messages
50 + // (0 = off, 1 = on)
59 + lirc_pins: lirc_pins {
60 + brcm,pins = <17 18>;
61 + brcm,function = <1 0>; // out in
62 + brcm,pull = <0 1>; // off down
68 + gpio_out_pin = <&lirc_pins>,"brcm,pins:0";
69 + gpio_in_pin = <&lirc_pins>,"brcm,pins:4";
70 + gpio_in_pull = <&lirc_pins>,"brcm,pull:4";
72 + sense = <&lirc_rpi>,"rpi,sense:0";
73 + softcarrier = <&lirc_rpi>,"rpi,softcarrier:0";
74 + invert = <&lirc_rpi>,"rpi,invert:0";
75 + debug = <&lirc_rpi>,"rpi,debug:0";
78 --- a/drivers/staging/media/lirc/lirc_rpi.c
79 +++ b/drivers/staging/media/lirc/lirc_rpi.c
81 #include <media/lirc_dev.h>
82 #include <mach/gpio.h>
83 #include <linux/gpio.h>
84 +#include <linux/of_platform.h>
86 #include <linux/platform_data/bcm2708.h>
88 @@ -295,32 +296,117 @@ static int is_right_chip(struct gpio_chi
92 +static inline int read_bool_property(const struct device_node *np,
93 + const char *propname,
97 + int err = of_property_read_u32(np, propname, &value);
99 + *out_value = (value != 0);
103 +static void read_pin_settings(struct device_node *node)
109 + of_property_read_u32_index(
117 + err = of_property_read_u32_index(
123 + if (function == 1) /* Output */
124 + gpio_out_pin = pin;
125 + else if (function == 0) /* Input */
131 static int init_port(void)
133 int i, nlow, nhigh, ret;
134 + struct device_node *node;
136 + node = lirc_rpi_dev->dev.of_node;
138 gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip);
142 + * Because of the lack of a setpull function, only support
143 + * pinctrl-bcm2835 if using device tree.
145 + if (!gpiochip && node)
146 + gpiochip = gpiochip_find("pinctrl-bcm2835", is_right_chip);
149 + pr_err(LIRC_DRIVER_NAME ": gpio chip not found!\n");
154 + struct device_node *pins_node;
156 + pins_node = of_parse_phandle(node, "pinctrl-0", 0);
158 + printk(KERN_ERR LIRC_DRIVER_NAME
159 + ": pinctrl settings not found!\n");
161 + goto exit_init_port;
164 + read_pin_settings(pins_node);
166 + of_property_read_u32(node, "rpi,sense", &sense);
168 + read_bool_property(node, "rpi,softcarrier", &softcarrier);
170 + read_bool_property(node, "rpi,invert", &invert);
172 + read_bool_property(node, "rpi,debug", &debug);
177 + if (gpio_in_pin >= BCM2708_NR_GPIOS ||
178 + gpio_out_pin >= BCM2708_NR_GPIOS) {
180 + printk(KERN_ERR LIRC_DRIVER_NAME
181 + ": invalid GPIO pin(s) specified!\n");
182 + goto exit_init_port;
185 + if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) {
186 + printk(KERN_ALERT LIRC_DRIVER_NAME
187 + ": cant claim gpio pin %d\n", gpio_out_pin);
189 + goto exit_init_port;
192 + if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) {
193 + printk(KERN_ALERT LIRC_DRIVER_NAME
194 + ": cant claim gpio pin %d\n", gpio_in_pin);
196 + goto exit_gpio_free_out_pin;
199 + bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull);
200 + gpiochip->direction_input(gpiochip, gpio_in_pin);
201 + gpiochip->direction_output(gpiochip, gpio_out_pin, 1);
204 - if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) {
205 - printk(KERN_ALERT LIRC_DRIVER_NAME
206 - ": cant claim gpio pin %d\n", gpio_out_pin);
208 - goto exit_init_port;
211 - if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) {
212 - printk(KERN_ALERT LIRC_DRIVER_NAME
213 - ": cant claim gpio pin %d\n", gpio_in_pin);
215 - goto exit_gpio_free_out_pin;
218 - bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull);
219 - gpiochip->direction_input(gpiochip, gpio_in_pin);
220 - gpiochip->direction_output(gpiochip, gpio_out_pin, 1);
221 gpiochip->set(gpiochip, gpio_out_pin, invert);
223 irq_num = gpiochip->to_irq(gpiochip, gpio_in_pin);
224 @@ -514,15 +600,23 @@ static struct lirc_driver driver = {
225 .owner = THIS_MODULE,
228 +static const struct of_device_id lirc_rpi_of_match[] = {
229 + { .compatible = "rpi,lirc-rpi", },
232 +MODULE_DEVICE_TABLE(of, lirc_rpi_of_match);
234 static struct platform_driver lirc_rpi_driver = {
236 .name = LIRC_DRIVER_NAME,
237 .owner = THIS_MODULE,
238 + .of_match_table = of_match_ptr(lirc_rpi_of_match),
242 static int __init lirc_rpi_init(void)
244 + struct device_node *node;
247 /* Init read buffer. */
248 @@ -537,15 +631,26 @@ static int __init lirc_rpi_init(void)
249 goto exit_buffer_free;
252 - lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
253 - if (!lirc_rpi_dev) {
255 - goto exit_driver_unregister;
257 + node = of_find_compatible_node(NULL, NULL,
258 + lirc_rpi_of_match[0].compatible);
260 - result = platform_device_add(lirc_rpi_dev);
262 - goto exit_device_put;
265 + lirc_rpi_dev = of_find_device_by_node(node);
266 + WARN_ON(lirc_rpi_dev->dev.of_node != node);
270 + lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
271 + if (!lirc_rpi_dev) {
273 + goto exit_driver_unregister;
276 + result = platform_device_add(lirc_rpi_dev);
278 + goto exit_device_put;
283 @@ -577,13 +682,6 @@ static int __init lirc_rpi_init_module(v
287 - if (gpio_in_pin >= BCM2708_NR_GPIOS || gpio_out_pin >= BCM2708_NR_GPIOS) {
289 - printk(KERN_ERR LIRC_DRIVER_NAME
290 - ": invalid GPIO pin(s) specified!\n");
294 result = init_port();