0068-lirc-rpi-Add-device-tree-support-and-a-suitable-over.patch 7.3 KB

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