ramips: add support for PandoraBox PBR-M1
[15.05/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;