brcm2708: use BuildDTB in image/Makefile
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-3.18 / 0068-lirc-rpi-Add-device-tree-support-and-a-suitable-over.patch
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
5 overlay
6
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".
10
11 lirc-rpi: Also support pinctrl-bcm2835 in non-DT mode
12 ---
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
17
18 --- /dev/null
19 +++ b/arch/arm/boot/dts/lirc-rpi-overlay.dts
20 @@ -0,0 +1,57 @@
21 +// Definitions for lirc-rpi module
22 +/dts-v1/;
23 +/plugin/;
24 +
25 +/ {
26 + compatible = "brcm,bcm2708";
27 +
28 + fragment@0 {
29 + target-path = "/";
30 + __overlay__ {
31 + lirc_rpi: lirc_rpi {
32 + compatible = "rpi,lirc-rpi";
33 + pinctrl-names = "default";
34 + pinctrl-0 = <&lirc_pins>;
35 + status = "okay";
36 +
37 + // Override autodetection of IR receiver circuit
38 + // (0 = active high, 1 = active low, -1 = no override )
39 + rpi,sense = <0xffffffff>;
40 +
41 + // Software carrier
42 + // (0 = off, 1 = on)
43 + rpi,softcarrier = <1>;
44 +
45 + // Invert output
46 + // (0 = off, 1 = on)
47 + rpi,invert = <0>;
48 +
49 + // Enable debugging messages
50 + // (0 = off, 1 = on)
51 + rpi,debug = <0>;
52 + };
53 + };
54 + };
55 +
56 + fragment@1 {
57 + target = <&gpio>;
58 + __overlay__ {
59 + lirc_pins: lirc_pins {
60 + brcm,pins = <17 18>;
61 + brcm,function = <1 0>; // out in
62 + brcm,pull = <0 1>; // off down
63 + };
64 + };
65 + };
66 +
67 + __overrides__ {
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";
71 +
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";
76 + };
77 +};
78 --- a/drivers/staging/media/lirc/lirc_rpi.c
79 +++ b/drivers/staging/media/lirc/lirc_rpi.c
80 @@ -40,6 +40,7 @@
81 #include <media/lirc_dev.h>
82 #include <mach/gpio.h>
83 #include <linux/gpio.h>
84 +#include <linux/of_platform.h>
85
86 #include <linux/platform_data/bcm2708.h>
87
88 @@ -295,32 +296,117 @@ static int is_right_chip(struct gpio_chi
89 return 0;
90 }
91
92 +static inline int read_bool_property(const struct device_node *np,
93 + const char *propname,
94 + bool *out_value)
95 +{
96 + u32 value = 0;
97 + int err = of_property_read_u32(np, propname, &value);
98 + if (err == 0)
99 + *out_value = (value != 0);
100 + return err;
101 +}
102 +
103 +static void read_pin_settings(struct device_node *node)
104 +{
105 + u32 pin;
106 + int index;
107 +
108 + for (index = 0;
109 + of_property_read_u32_index(
110 + node,
111 + "brcm,pins",
112 + index,
113 + &pin) == 0;
114 + index++) {
115 + u32 function;
116 + int err;
117 + err = of_property_read_u32_index(
118 + node,
119 + "brcm,function",
120 + index,
121 + &function);
122 + if (err == 0) {
123 + if (function == 1) /* Output */
124 + gpio_out_pin = pin;
125 + else if (function == 0) /* Input */
126 + gpio_in_pin = pin;
127 + }
128 + }
129 +}
130 +
131 static int init_port(void)
132 {
133 int i, nlow, nhigh, ret;
134 + struct device_node *node;
135 +
136 + node = lirc_rpi_dev->dev.of_node;
137
138 gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip);
139
140 - if (!gpiochip)
141 + /*
142 + * Because of the lack of a setpull function, only support
143 + * pinctrl-bcm2835 if using device tree.
144 + */
145 + if (!gpiochip && node)
146 + gpiochip = gpiochip_find("pinctrl-bcm2835", is_right_chip);
147 +
148 + if (!gpiochip) {
149 + pr_err(LIRC_DRIVER_NAME ": gpio chip not found!\n");
150 return -ENODEV;
151 + }
152 +
153 + if (node) {
154 + struct device_node *pins_node;
155 +
156 + pins_node = of_parse_phandle(node, "pinctrl-0", 0);
157 + if (!pins_node) {
158 + printk(KERN_ERR LIRC_DRIVER_NAME
159 + ": pinctrl settings not found!\n");
160 + ret = -EINVAL;
161 + goto exit_init_port;
162 + }
163 +
164 + read_pin_settings(pins_node);
165 +
166 + of_property_read_u32(node, "rpi,sense", &sense);
167 +
168 + read_bool_property(node, "rpi,softcarrier", &softcarrier);
169 +
170 + read_bool_property(node, "rpi,invert", &invert);
171 +
172 + read_bool_property(node, "rpi,debug", &debug);
173 +
174 + }
175 + else
176 + {
177 + if (gpio_in_pin >= BCM2708_NR_GPIOS ||
178 + gpio_out_pin >= BCM2708_NR_GPIOS) {
179 + ret = -EINVAL;
180 + printk(KERN_ERR LIRC_DRIVER_NAME
181 + ": invalid GPIO pin(s) specified!\n");
182 + goto exit_init_port;
183 + }
184 +
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);
188 + ret = -ENODEV;
189 + goto exit_init_port;
190 + }
191 +
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);
195 + ret = -ENODEV;
196 + goto exit_gpio_free_out_pin;
197 + }
198 +
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);
202 + }
203
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);
207 - ret = -ENODEV;
208 - goto exit_init_port;
209 - }
210 -
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);
214 - ret = -ENODEV;
215 - goto exit_gpio_free_out_pin;
216 - }
217 -
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);
222
223 irq_num = gpiochip->to_irq(gpiochip, gpio_in_pin);
224 @@ -514,15 +600,23 @@ static struct lirc_driver driver = {
225 .owner = THIS_MODULE,
226 };
227
228 +static const struct of_device_id lirc_rpi_of_match[] = {
229 + { .compatible = "rpi,lirc-rpi", },
230 + {},
231 +};
232 +MODULE_DEVICE_TABLE(of, lirc_rpi_of_match);
233 +
234 static struct platform_driver lirc_rpi_driver = {
235 .driver = {
236 .name = LIRC_DRIVER_NAME,
237 .owner = THIS_MODULE,
238 + .of_match_table = of_match_ptr(lirc_rpi_of_match),
239 },
240 };
241
242 static int __init lirc_rpi_init(void)
243 {
244 + struct device_node *node;
245 int result;
246
247 /* Init read buffer. */
248 @@ -537,15 +631,26 @@ static int __init lirc_rpi_init(void)
249 goto exit_buffer_free;
250 }
251
252 - lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
253 - if (!lirc_rpi_dev) {
254 - result = -ENOMEM;
255 - goto exit_driver_unregister;
256 - }
257 + node = of_find_compatible_node(NULL, NULL,
258 + lirc_rpi_of_match[0].compatible);
259
260 - result = platform_device_add(lirc_rpi_dev);
261 - if (result)
262 - goto exit_device_put;
263 + if (node) {
264 + /* DT-enabled */
265 + lirc_rpi_dev = of_find_device_by_node(node);
266 + WARN_ON(lirc_rpi_dev->dev.of_node != node);
267 + of_node_put(node);
268 + }
269 + else {
270 + lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
271 + if (!lirc_rpi_dev) {
272 + result = -ENOMEM;
273 + goto exit_driver_unregister;
274 + }
275 +
276 + result = platform_device_add(lirc_rpi_dev);
277 + if (result)
278 + goto exit_device_put;
279 + }
280
281 return 0;
282
283 @@ -577,13 +682,6 @@ static int __init lirc_rpi_init_module(v
284 if (result)
285 return result;
286
287 - if (gpio_in_pin >= BCM2708_NR_GPIOS || gpio_out_pin >= BCM2708_NR_GPIOS) {
288 - result = -EINVAL;
289 - printk(KERN_ERR LIRC_DRIVER_NAME
290 - ": invalid GPIO pin(s) specified!\n");
291 - goto exit_rpi;
292 - }
293 -
294 result = init_port();
295 if (result < 0)
296 goto exit_rpi;