0042-lirc-added-support-for-RaspberryPi-GPIO.patch 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  1. From 656c19b0ad2dd41ae053d766ee4bda9a09cf34e6 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
  5. lirc_rpi: Use read_current_timer to determine transmitter delay. Thanks to jjmz and others
  6. See: https://github.com/raspberrypi/linux/issues/525
  7. lirc: Remove restriction on gpio pins that can be used with lirc
  8. Compute Module, for example could use different pins
  9. lirc_rpi: Add parameter to specify input pin pull
  10. Depending on the connected IR circuitry it might be desirable to change the
  11. gpios internal pull from it pull-down default behaviour. Add a module
  12. parameter to allow the user to set it explicitly.
  13. Signed-off-by: Julian Scheel <julian@jusst.de>
  14. lirc-rpi: Use the higher-level irq control functions
  15. This module used to access the irq_chip methods of the
  16. gpio controller directly, rather than going through the
  17. standard enable_irq/irq_set_irq_type functions. This
  18. caused problems on pinctrl-bcm2835 which only implements
  19. the irq_enable/disable methods and not irq_unmask/mask.
  20. lirc-rpi: Correct the interrupt usage
  21. 1) Correct the use of enable_irq (i.e. don't call it so often)
  22. 2) Correct the shutdown sequence.
  23. 3) Avoid a bcm2708_gpio driver quirk by setting the irq flags earlier
  24. lirc-rpi: use getnstimeofday instead of read_current_timer
  25. read_current_timer isn't guaranteed to return values in
  26. microseconds, and indeed it doesn't on a Pi2.
  27. Issue: linux#827
  28. lirc-rpi: Add device tree support, and a suitable overlay
  29. The overlay supports DT parameters that match the old module
  30. parameters, except that gpio_in_pull should be set using the
  31. strings "up", "down" or "off".
  32. lirc-rpi: Also support pinctrl-bcm2835 in non-DT mode
  33. ---
  34. drivers/staging/media/lirc/Kconfig | 6 +
  35. drivers/staging/media/lirc/Makefile | 1 +
  36. drivers/staging/media/lirc/lirc_rpi.c | 730 ++++++++++++++++++++++++++++++++++
  37. include/linux/platform_data/bcm2708.h | 23 ++
  38. 4 files changed, 760 insertions(+)
  39. create mode 100644 drivers/staging/media/lirc/lirc_rpi.c
  40. create mode 100644 include/linux/platform_data/bcm2708.h
  41. --- a/drivers/staging/media/lirc/Kconfig
  42. +++ b/drivers/staging/media/lirc/Kconfig
  43. @@ -32,6 +32,12 @@ config LIRC_PARALLEL
  44. help
  45. Driver for Homebrew Parallel Port Receivers
  46. +config LIRC_RPI
  47. + tristate "Homebrew GPIO Port Receiver/Transmitter for the RaspberryPi"
  48. + depends on LIRC
  49. + help
  50. + Driver for Homebrew GPIO Port Receiver/Transmitter for the RaspberryPi
  51. +
  52. config LIRC_SASEM
  53. tristate "Sasem USB IR Remote"
  54. depends on LIRC && USB
  55. --- a/drivers/staging/media/lirc/Makefile
  56. +++ b/drivers/staging/media/lirc/Makefile
  57. @@ -6,6 +6,7 @@
  58. obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
  59. obj-$(CONFIG_LIRC_IMON) += lirc_imon.o
  60. obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
  61. +obj-$(CONFIG_LIRC_RPI) += lirc_rpi.o
  62. obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
  63. obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
  64. obj-$(CONFIG_LIRC_SIR) += lirc_sir.o
  65. --- /dev/null
  66. +++ b/drivers/staging/media/lirc/lirc_rpi.c
  67. @@ -0,0 +1,730 @@
  68. +/*
  69. + * lirc_rpi.c
  70. + *
  71. + * lirc_rpi - Device driver that records pulse- and pause-lengths
  72. + * (space-lengths) (just like the lirc_serial driver does)
  73. + * between GPIO interrupt events on the Raspberry Pi.
  74. + * Lots of code has been taken from the lirc_serial module,
  75. + * so I would like say thanks to the authors.
  76. + *
  77. + * Copyright (C) 2012 Aron Robert Szabo <aron@reon.hu>,
  78. + * Michael Bishop <cleverca22@gmail.com>
  79. + * This program is free software; you can redistribute it and/or modify
  80. + * it under the terms of the GNU General Public License as published by
  81. + * the Free Software Foundation; either version 2 of the License, or
  82. + * (at your option) any later version.
  83. + *
  84. + * This program is distributed in the hope that it will be useful,
  85. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  86. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  87. + * GNU General Public License for more details.
  88. + *
  89. + * You should have received a copy of the GNU General Public License
  90. + * along with this program; if not, write to the Free Software
  91. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  92. + */
  93. +
  94. +#include <linux/module.h>
  95. +#include <linux/errno.h>
  96. +#include <linux/interrupt.h>
  97. +#include <linux/sched.h>
  98. +#include <linux/kernel.h>
  99. +#include <linux/time.h>
  100. +#include <linux/timex.h>
  101. +#include <linux/timekeeping.h>
  102. +#include <linux/string.h>
  103. +#include <linux/delay.h>
  104. +#include <linux/platform_device.h>
  105. +#include <linux/irq.h>
  106. +#include <linux/spinlock.h>
  107. +#include <media/lirc.h>
  108. +#include <media/lirc_dev.h>
  109. +#include <linux/gpio.h>
  110. +#include <linux/of_platform.h>
  111. +#include <linux/platform_data/bcm2708.h>
  112. +
  113. +#define LIRC_DRIVER_NAME "lirc_rpi"
  114. +#define RBUF_LEN 256
  115. +#define LIRC_TRANSMITTER_LATENCY 50
  116. +
  117. +#ifndef MAX_UDELAY_MS
  118. +#define MAX_UDELAY_US 5000
  119. +#else
  120. +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000)
  121. +#endif
  122. +
  123. +#define dprintk(fmt, args...) \
  124. + do { \
  125. + if (debug) \
  126. + printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \
  127. + fmt, ## args); \
  128. + } while (0)
  129. +
  130. +/* module parameters */
  131. +
  132. +/* set the default GPIO input pin */
  133. +static int gpio_in_pin = 18;
  134. +/* set the default pull behaviour for input pin */
  135. +static int gpio_in_pull = BCM2708_PULL_DOWN;
  136. +/* set the default GPIO output pin */
  137. +static int gpio_out_pin = 17;
  138. +/* enable debugging messages */
  139. +static bool debug;
  140. +/* -1 = auto, 0 = active high, 1 = active low */
  141. +static int sense = -1;
  142. +/* use softcarrier by default */
  143. +static bool softcarrier = 1;
  144. +/* 0 = do not invert output, 1 = invert output */
  145. +static bool invert = 0;
  146. +
  147. +struct gpio_chip *gpiochip;
  148. +static int irq_num;
  149. +
  150. +/* forward declarations */
  151. +static long send_pulse(unsigned long length);
  152. +static void send_space(long length);
  153. +static void lirc_rpi_exit(void);
  154. +
  155. +static struct platform_device *lirc_rpi_dev;
  156. +static struct timeval lasttv = { 0, 0 };
  157. +static struct lirc_buffer rbuf;
  158. +static spinlock_t lock;
  159. +
  160. +/* initialized/set in init_timing_params() */
  161. +static unsigned int freq = 38000;
  162. +static unsigned int duty_cycle = 50;
  163. +static unsigned long period;
  164. +static unsigned long pulse_width;
  165. +static unsigned long space_width;
  166. +
  167. +static void safe_udelay(unsigned long usecs)
  168. +{
  169. + while (usecs > MAX_UDELAY_US) {
  170. + udelay(MAX_UDELAY_US);
  171. + usecs -= MAX_UDELAY_US;
  172. + }
  173. + udelay(usecs);
  174. +}
  175. +
  176. +static unsigned long read_current_us(void)
  177. +{
  178. + struct timespec now;
  179. + getnstimeofday(&now);
  180. + return (now.tv_sec * 1000000) + (now.tv_nsec/1000);
  181. +}
  182. +
  183. +static int init_timing_params(unsigned int new_duty_cycle,
  184. + unsigned int new_freq)
  185. +{
  186. + if (1000 * 1000000L / new_freq * new_duty_cycle / 100 <=
  187. + LIRC_TRANSMITTER_LATENCY)
  188. + return -EINVAL;
  189. + if (1000 * 1000000L / new_freq * (100 - new_duty_cycle) / 100 <=
  190. + LIRC_TRANSMITTER_LATENCY)
  191. + return -EINVAL;
  192. + duty_cycle = new_duty_cycle;
  193. + freq = new_freq;
  194. + period = 1000 * 1000000L / freq;
  195. + pulse_width = period * duty_cycle / 100;
  196. + space_width = period - pulse_width;
  197. + dprintk("in init_timing_params, freq=%d pulse=%ld, "
  198. + "space=%ld\n", freq, pulse_width, space_width);
  199. + return 0;
  200. +}
  201. +
  202. +static long send_pulse_softcarrier(unsigned long length)
  203. +{
  204. + int flag;
  205. + unsigned long actual, target;
  206. + unsigned long actual_us, initial_us, target_us;
  207. +
  208. + length *= 1000;
  209. +
  210. + actual = 0; target = 0; flag = 0;
  211. + actual_us = read_current_us();
  212. +
  213. + while (actual < length) {
  214. + if (flag) {
  215. + gpiochip->set(gpiochip, gpio_out_pin, invert);
  216. + target += space_width;
  217. + } else {
  218. + gpiochip->set(gpiochip, gpio_out_pin, !invert);
  219. + target += pulse_width;
  220. + }
  221. + initial_us = actual_us;
  222. + target_us = actual_us + (target - actual) / 1000;
  223. + /*
  224. + * Note - we've checked in ioctl that the pulse/space
  225. + * widths are big enough so that d is > 0
  226. + */
  227. + if ((int)(target_us - actual_us) > 0)
  228. + udelay(target_us - actual_us);
  229. + actual_us = read_current_us();
  230. + actual += (actual_us - initial_us) * 1000;
  231. + flag = !flag;
  232. + }
  233. + return (actual-length) / 1000;
  234. +}
  235. +
  236. +static long send_pulse(unsigned long length)
  237. +{
  238. + if (length <= 0)
  239. + return 0;
  240. +
  241. + if (softcarrier) {
  242. + return send_pulse_softcarrier(length);
  243. + } else {
  244. + gpiochip->set(gpiochip, gpio_out_pin, !invert);
  245. + safe_udelay(length);
  246. + return 0;
  247. + }
  248. +}
  249. +
  250. +static void send_space(long length)
  251. +{
  252. + gpiochip->set(gpiochip, gpio_out_pin, invert);
  253. + if (length <= 0)
  254. + return;
  255. + safe_udelay(length);
  256. +}
  257. +
  258. +static void rbwrite(int l)
  259. +{
  260. + if (lirc_buffer_full(&rbuf)) {
  261. + /* no new signals will be accepted */
  262. + dprintk("Buffer overrun\n");
  263. + return;
  264. + }
  265. + lirc_buffer_write(&rbuf, (void *)&l);
  266. +}
  267. +
  268. +static void frbwrite(int l)
  269. +{
  270. + /* simple noise filter */
  271. + static int pulse, space;
  272. + static unsigned int ptr;
  273. +
  274. + if (ptr > 0 && (l & PULSE_BIT)) {
  275. + pulse += l & PULSE_MASK;
  276. + if (pulse > 250) {
  277. + rbwrite(space);
  278. + rbwrite(pulse | PULSE_BIT);
  279. + ptr = 0;
  280. + pulse = 0;
  281. + }
  282. + return;
  283. + }
  284. + if (!(l & PULSE_BIT)) {
  285. + if (ptr == 0) {
  286. + if (l > 20000) {
  287. + space = l;
  288. + ptr++;
  289. + return;
  290. + }
  291. + } else {
  292. + if (l > 20000) {
  293. + space += pulse;
  294. + if (space > PULSE_MASK)
  295. + space = PULSE_MASK;
  296. + space += l;
  297. + if (space > PULSE_MASK)
  298. + space = PULSE_MASK;
  299. + pulse = 0;
  300. + return;
  301. + }
  302. + rbwrite(space);
  303. + rbwrite(pulse | PULSE_BIT);
  304. + ptr = 0;
  305. + pulse = 0;
  306. + }
  307. + }
  308. + rbwrite(l);
  309. +}
  310. +
  311. +static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs)
  312. +{
  313. + struct timeval tv;
  314. + long deltv;
  315. + int data;
  316. + int signal;
  317. +
  318. + /* use the GPIO signal level */
  319. + signal = gpiochip->get(gpiochip, gpio_in_pin);
  320. +
  321. + if (sense != -1) {
  322. + /* get current time */
  323. + do_gettimeofday(&tv);
  324. +
  325. + /* calc time since last interrupt in microseconds */
  326. + deltv = tv.tv_sec-lasttv.tv_sec;
  327. + if (tv.tv_sec < lasttv.tv_sec ||
  328. + (tv.tv_sec == lasttv.tv_sec &&
  329. + tv.tv_usec < lasttv.tv_usec)) {
  330. + printk(KERN_WARNING LIRC_DRIVER_NAME
  331. + ": AIEEEE: your clock just jumped backwards\n");
  332. + printk(KERN_WARNING LIRC_DRIVER_NAME
  333. + ": %d %d %lx %lx %lx %lx\n", signal, sense,
  334. + tv.tv_sec, lasttv.tv_sec,
  335. + tv.tv_usec, lasttv.tv_usec);
  336. + data = PULSE_MASK;
  337. + } else if (deltv > 15) {
  338. + data = PULSE_MASK; /* really long time */
  339. + if (!(signal^sense)) {
  340. + /* sanity check */
  341. + printk(KERN_WARNING LIRC_DRIVER_NAME
  342. + ": AIEEEE: %d %d %lx %lx %lx %lx\n",
  343. + signal, sense, tv.tv_sec, lasttv.tv_sec,
  344. + tv.tv_usec, lasttv.tv_usec);
  345. + /*
  346. + * detecting pulse while this
  347. + * MUST be a space!
  348. + */
  349. + sense = sense ? 0 : 1;
  350. + }
  351. + } else {
  352. + data = (int) (deltv*1000000 +
  353. + (tv.tv_usec - lasttv.tv_usec));
  354. + }
  355. + frbwrite(signal^sense ? data : (data|PULSE_BIT));
  356. + lasttv = tv;
  357. + wake_up_interruptible(&rbuf.wait_poll);
  358. + }
  359. +
  360. + return IRQ_HANDLED;
  361. +}
  362. +
  363. +static int is_right_chip(struct gpio_chip *chip, void *data)
  364. +{
  365. + dprintk("is_right_chip %s %d\n", chip->label, strcmp(data, chip->label));
  366. +
  367. + if (strcmp(data, chip->label) == 0)
  368. + return 1;
  369. + return 0;
  370. +}
  371. +
  372. +static inline int read_bool_property(const struct device_node *np,
  373. + const char *propname,
  374. + bool *out_value)
  375. +{
  376. + u32 value = 0;
  377. + int err = of_property_read_u32(np, propname, &value);
  378. + if (err == 0)
  379. + *out_value = (value != 0);
  380. + return err;
  381. +}
  382. +
  383. +static void read_pin_settings(struct device_node *node)
  384. +{
  385. + u32 pin;
  386. + int index;
  387. +
  388. + for (index = 0;
  389. + of_property_read_u32_index(
  390. + node,
  391. + "brcm,pins",
  392. + index,
  393. + &pin) == 0;
  394. + index++) {
  395. + u32 function;
  396. + int err;
  397. + err = of_property_read_u32_index(
  398. + node,
  399. + "brcm,function",
  400. + index,
  401. + &function);
  402. + if (err == 0) {
  403. + if (function == 1) /* Output */
  404. + gpio_out_pin = pin;
  405. + else if (function == 0) /* Input */
  406. + gpio_in_pin = pin;
  407. + }
  408. + }
  409. +}
  410. +
  411. +static int init_port(void)
  412. +{
  413. + int i, nlow, nhigh;
  414. + struct device_node *node;
  415. +
  416. + node = lirc_rpi_dev->dev.of_node;
  417. +
  418. + gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip);
  419. +
  420. + /*
  421. + * Because of the lack of a setpull function, only support
  422. + * pinctrl-bcm2835 if using device tree.
  423. + */
  424. + if (!gpiochip && node)
  425. + gpiochip = gpiochip_find("pinctrl-bcm2835", is_right_chip);
  426. +
  427. + if (!gpiochip) {
  428. + pr_err(LIRC_DRIVER_NAME ": gpio chip not found!\n");
  429. + return -ENODEV;
  430. + }
  431. +
  432. + if (node) {
  433. + struct device_node *pins_node;
  434. +
  435. + pins_node = of_parse_phandle(node, "pinctrl-0", 0);
  436. + if (!pins_node) {
  437. + printk(KERN_ERR LIRC_DRIVER_NAME
  438. + ": pinctrl settings not found!\n");
  439. + return -EINVAL;
  440. + }
  441. +
  442. + read_pin_settings(pins_node);
  443. +
  444. + of_property_read_u32(node, "rpi,sense", &sense);
  445. +
  446. + read_bool_property(node, "rpi,softcarrier", &softcarrier);
  447. +
  448. + read_bool_property(node, "rpi,invert", &invert);
  449. +
  450. + read_bool_property(node, "rpi,debug", &debug);
  451. +
  452. + } else {
  453. + return -EINVAL;
  454. + }
  455. +
  456. + gpiochip->set(gpiochip, gpio_out_pin, invert);
  457. +
  458. + irq_num = gpiochip->to_irq(gpiochip, gpio_in_pin);
  459. + dprintk("to_irq %d\n", irq_num);
  460. +
  461. + /* if pin is high, then this must be an active low receiver. */
  462. + if (sense == -1) {
  463. + /* wait 1/2 sec for the power supply */
  464. + msleep(500);
  465. +
  466. + /*
  467. + * probe 9 times every 0.04s, collect "votes" for
  468. + * active high/low
  469. + */
  470. + nlow = 0;
  471. + nhigh = 0;
  472. + for (i = 0; i < 9; i++) {
  473. + if (gpiochip->get(gpiochip, gpio_in_pin))
  474. + nlow++;
  475. + else
  476. + nhigh++;
  477. + msleep(40);
  478. + }
  479. + sense = (nlow >= nhigh ? 1 : 0);
  480. + printk(KERN_INFO LIRC_DRIVER_NAME
  481. + ": auto-detected active %s receiver on GPIO pin %d\n",
  482. + sense ? "low" : "high", gpio_in_pin);
  483. + } else {
  484. + printk(KERN_INFO LIRC_DRIVER_NAME
  485. + ": manually using active %s receiver on GPIO pin %d\n",
  486. + sense ? "low" : "high", gpio_in_pin);
  487. + }
  488. +
  489. + return 0;
  490. +}
  491. +
  492. +// called when the character device is opened
  493. +static int set_use_inc(void *data)
  494. +{
  495. + int result;
  496. +
  497. + /* initialize timestamp */
  498. + do_gettimeofday(&lasttv);
  499. +
  500. + result = request_irq(irq_num,
  501. + (irq_handler_t) irq_handler,
  502. + IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING,
  503. + LIRC_DRIVER_NAME, (void*) 0);
  504. +
  505. + switch (result) {
  506. + case -EBUSY:
  507. + printk(KERN_ERR LIRC_DRIVER_NAME
  508. + ": IRQ %d is busy\n",
  509. + irq_num);
  510. + return -EBUSY;
  511. + case -EINVAL:
  512. + printk(KERN_ERR LIRC_DRIVER_NAME
  513. + ": Bad irq number or handler\n");
  514. + return -EINVAL;
  515. + default:
  516. + dprintk("Interrupt %d obtained\n",
  517. + irq_num);
  518. + break;
  519. + };
  520. +
  521. + /* initialize pulse/space widths */
  522. + init_timing_params(duty_cycle, freq);
  523. +
  524. + return 0;
  525. +}
  526. +
  527. +static void set_use_dec(void *data)
  528. +{
  529. + /* GPIO Pin Falling/Rising Edge Detect Disable */
  530. + irq_set_irq_type(irq_num, 0);
  531. + disable_irq(irq_num);
  532. +
  533. + free_irq(irq_num, (void *) 0);
  534. +
  535. + dprintk(KERN_INFO LIRC_DRIVER_NAME
  536. + ": freed IRQ %d\n", irq_num);
  537. +}
  538. +
  539. +static ssize_t lirc_write(struct file *file, const char *buf,
  540. + size_t n, loff_t *ppos)
  541. +{
  542. + int i, count;
  543. + unsigned long flags;
  544. + long delta = 0;
  545. + int *wbuf;
  546. +
  547. + count = n / sizeof(int);
  548. + if (n % sizeof(int) || count % 2 == 0)
  549. + return -EINVAL;
  550. + wbuf = memdup_user(buf, n);
  551. + if (IS_ERR(wbuf))
  552. + return PTR_ERR(wbuf);
  553. + spin_lock_irqsave(&lock, flags);
  554. +
  555. + for (i = 0; i < count; i++) {
  556. + if (i%2)
  557. + send_space(wbuf[i] - delta);
  558. + else
  559. + delta = send_pulse(wbuf[i]);
  560. + }
  561. + gpiochip->set(gpiochip, gpio_out_pin, invert);
  562. +
  563. + spin_unlock_irqrestore(&lock, flags);
  564. + kfree(wbuf);
  565. + return n;
  566. +}
  567. +
  568. +static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
  569. +{
  570. + int result;
  571. + __u32 value;
  572. +
  573. + switch (cmd) {
  574. + case LIRC_GET_SEND_MODE:
  575. + return -ENOIOCTLCMD;
  576. + break;
  577. +
  578. + case LIRC_SET_SEND_MODE:
  579. + result = get_user(value, (__u32 *) arg);
  580. + if (result)
  581. + return result;
  582. + /* only LIRC_MODE_PULSE supported */
  583. + if (value != LIRC_MODE_PULSE)
  584. + return -ENOSYS;
  585. + break;
  586. +
  587. + case LIRC_GET_LENGTH:
  588. + return -ENOSYS;
  589. + break;
  590. +
  591. + case LIRC_SET_SEND_DUTY_CYCLE:
  592. + dprintk("SET_SEND_DUTY_CYCLE\n");
  593. + result = get_user(value, (__u32 *) arg);
  594. + if (result)
  595. + return result;
  596. + if (value <= 0 || value > 100)
  597. + return -EINVAL;
  598. + return init_timing_params(value, freq);
  599. + break;
  600. +
  601. + case LIRC_SET_SEND_CARRIER:
  602. + dprintk("SET_SEND_CARRIER\n");
  603. + result = get_user(value, (__u32 *) arg);
  604. + if (result)
  605. + return result;
  606. + if (value > 500000 || value < 20000)
  607. + return -EINVAL;
  608. + return init_timing_params(duty_cycle, value);
  609. + break;
  610. +
  611. + default:
  612. + return lirc_dev_fop_ioctl(filep, cmd, arg);
  613. + }
  614. + return 0;
  615. +}
  616. +
  617. +static const struct file_operations lirc_fops = {
  618. + .owner = THIS_MODULE,
  619. + .write = lirc_write,
  620. + .unlocked_ioctl = lirc_ioctl,
  621. + .read = lirc_dev_fop_read,
  622. + .poll = lirc_dev_fop_poll,
  623. + .open = lirc_dev_fop_open,
  624. + .release = lirc_dev_fop_close,
  625. + .llseek = no_llseek,
  626. +};
  627. +
  628. +static struct lirc_driver driver = {
  629. + .name = LIRC_DRIVER_NAME,
  630. + .minor = -1,
  631. + .code_length = 1,
  632. + .sample_rate = 0,
  633. + .data = NULL,
  634. + .add_to_buf = NULL,
  635. + .rbuf = &rbuf,
  636. + .set_use_inc = set_use_inc,
  637. + .set_use_dec = set_use_dec,
  638. + .fops = &lirc_fops,
  639. + .dev = NULL,
  640. + .owner = THIS_MODULE,
  641. +};
  642. +
  643. +static const struct of_device_id lirc_rpi_of_match[] = {
  644. + { .compatible = "rpi,lirc-rpi", },
  645. + {},
  646. +};
  647. +MODULE_DEVICE_TABLE(of, lirc_rpi_of_match);
  648. +
  649. +static struct platform_driver lirc_rpi_driver = {
  650. + .driver = {
  651. + .name = LIRC_DRIVER_NAME,
  652. + .owner = THIS_MODULE,
  653. + .of_match_table = of_match_ptr(lirc_rpi_of_match),
  654. + },
  655. +};
  656. +
  657. +static int __init lirc_rpi_init(void)
  658. +{
  659. + struct device_node *node;
  660. + int result;
  661. +
  662. + /* Init read buffer. */
  663. + result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN);
  664. + if (result < 0)
  665. + return -ENOMEM;
  666. +
  667. + result = platform_driver_register(&lirc_rpi_driver);
  668. + if (result) {
  669. + printk(KERN_ERR LIRC_DRIVER_NAME
  670. + ": lirc register returned %d\n", result);
  671. + goto exit_buffer_free;
  672. + }
  673. +
  674. + node = of_find_compatible_node(NULL, NULL,
  675. + lirc_rpi_of_match[0].compatible);
  676. +
  677. + if (node) {
  678. + /* DT-enabled */
  679. + lirc_rpi_dev = of_find_device_by_node(node);
  680. + WARN_ON(lirc_rpi_dev->dev.of_node != node);
  681. + of_node_put(node);
  682. + }
  683. + else {
  684. + lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
  685. + if (!lirc_rpi_dev) {
  686. + result = -ENOMEM;
  687. + goto exit_driver_unregister;
  688. + }
  689. +
  690. + result = platform_device_add(lirc_rpi_dev);
  691. + if (result)
  692. + goto exit_device_put;
  693. + }
  694. +
  695. + return 0;
  696. +
  697. + exit_device_put:
  698. + platform_device_put(lirc_rpi_dev);
  699. +
  700. + exit_driver_unregister:
  701. + platform_driver_unregister(&lirc_rpi_driver);
  702. +
  703. + exit_buffer_free:
  704. + lirc_buffer_free(&rbuf);
  705. +
  706. + return result;
  707. +}
  708. +
  709. +static void lirc_rpi_exit(void)
  710. +{
  711. + if (!lirc_rpi_dev->dev.of_node)
  712. + platform_device_unregister(lirc_rpi_dev);
  713. + platform_driver_unregister(&lirc_rpi_driver);
  714. + lirc_buffer_free(&rbuf);
  715. +}
  716. +
  717. +static int __init lirc_rpi_init_module(void)
  718. +{
  719. + int result;
  720. +
  721. + result = lirc_rpi_init();
  722. + if (result)
  723. + return result;
  724. +
  725. + result = init_port();
  726. + if (result < 0)
  727. + goto exit_rpi;
  728. +
  729. + driver.features = LIRC_CAN_SET_SEND_DUTY_CYCLE |
  730. + LIRC_CAN_SET_SEND_CARRIER |
  731. + LIRC_CAN_SEND_PULSE |
  732. + LIRC_CAN_REC_MODE2;
  733. +
  734. + driver.dev = &lirc_rpi_dev->dev;
  735. + driver.minor = lirc_register_driver(&driver);
  736. +
  737. + if (driver.minor < 0) {
  738. + printk(KERN_ERR LIRC_DRIVER_NAME
  739. + ": device registration failed with %d\n", result);
  740. + result = -EIO;
  741. + goto exit_rpi;
  742. + }
  743. +
  744. + printk(KERN_INFO LIRC_DRIVER_NAME ": driver registered!\n");
  745. +
  746. + return 0;
  747. +
  748. + exit_rpi:
  749. + lirc_rpi_exit();
  750. +
  751. + return result;
  752. +}
  753. +
  754. +static void __exit lirc_rpi_exit_module(void)
  755. +{
  756. + lirc_unregister_driver(driver.minor);
  757. +
  758. + gpio_free(gpio_out_pin);
  759. + gpio_free(gpio_in_pin);
  760. +
  761. + lirc_rpi_exit();
  762. +
  763. + printk(KERN_INFO LIRC_DRIVER_NAME ": cleaned up module\n");
  764. +}
  765. +
  766. +module_init(lirc_rpi_init_module);
  767. +module_exit(lirc_rpi_exit_module);
  768. +
  769. +MODULE_DESCRIPTION("Infra-red receiver and blaster driver for Raspberry Pi GPIO.");
  770. +MODULE_AUTHOR("Aron Robert Szabo <aron@reon.hu>");
  771. +MODULE_AUTHOR("Michael Bishop <cleverca22@gmail.com>");
  772. +MODULE_LICENSE("GPL");
  773. +
  774. +module_param(gpio_out_pin, int, S_IRUGO);
  775. +MODULE_PARM_DESC(gpio_out_pin, "GPIO output/transmitter pin number of the BCM"
  776. + " processor. (default 17");
  777. +
  778. +module_param(gpio_in_pin, int, S_IRUGO);
  779. +MODULE_PARM_DESC(gpio_in_pin, "GPIO input pin number of the BCM processor."
  780. + " (default 18");
  781. +
  782. +module_param(gpio_in_pull, int, S_IRUGO);
  783. +MODULE_PARM_DESC(gpio_in_pull, "GPIO input pin pull configuration."
  784. + " (0 = off, 1 = up, 2 = down, default down)");
  785. +
  786. +module_param(sense, int, S_IRUGO);
  787. +MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit"
  788. + " (0 = active high, 1 = active low )");
  789. +
  790. +module_param(softcarrier, bool, S_IRUGO);
  791. +MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)");
  792. +
  793. +module_param(invert, bool, S_IRUGO);
  794. +MODULE_PARM_DESC(invert, "Invert output (0 = off, 1 = on, default off");
  795. +
  796. +module_param(debug, bool, S_IRUGO | S_IWUSR);
  797. +MODULE_PARM_DESC(debug, "Enable debugging messages");
  798. --- /dev/null
  799. +++ b/include/linux/platform_data/bcm2708.h
  800. @@ -0,0 +1,23 @@
  801. +/*
  802. + * include/linux/platform_data/bcm2708.h
  803. + *
  804. + * This program is free software; you can redistribute it and/or modify
  805. + * it under the terms of the GNU General Public License version 2 as
  806. + * published by the Free Software Foundation.
  807. + *
  808. + * (C) 2014 Julian Scheel <julian@jusst.de>
  809. + *
  810. + */
  811. +#ifndef __BCM2708_H_
  812. +#define __BCM2708_H_
  813. +
  814. +typedef enum {
  815. + BCM2708_PULL_OFF,
  816. + BCM2708_PULL_UP,
  817. + BCM2708_PULL_DOWN
  818. +} bcm2708_gpio_pull_t;
  819. +
  820. +extern int bcm2708_gpio_setpull(struct gpio_chip *gc, unsigned offset,
  821. + bcm2708_gpio_pull_t value);
  822. +
  823. +#endif