sir_ir.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*
  2. * IR SIR driver, (C) 2000 Milan Pikula <www@fornax.sk>
  3. *
  4. * sir_ir - Device driver for use with SIR (serial infra red)
  5. * mode of IrDA on many notebooks.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. */
  12. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  13. #include <linux/module.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/kernel.h>
  16. #include <linux/serial_reg.h>
  17. #include <linux/ktime.h>
  18. #include <linux/delay.h>
  19. #include <linux/platform_device.h>
  20. #include <media/rc-core.h>
  21. /* SECTION: Definitions */
  22. #define PULSE '['
  23. /* 9bit * 1s/115200bit in milli seconds = 78.125ms*/
  24. #define TIME_CONST (9000000ul / 115200ul)
  25. /* timeout for sequences in jiffies (=5/100s), must be longer than TIME_CONST */
  26. #define SIR_TIMEOUT (HZ * 5 / 100)
  27. /* onboard sir ports are typically com3 */
  28. static int io = 0x3e8;
  29. static int irq = 4;
  30. static int threshold = 3;
  31. static DEFINE_SPINLOCK(timer_lock);
  32. static struct timer_list timerlist;
  33. /* time of last signal change detected */
  34. static ktime_t last;
  35. /* time of last UART data ready interrupt */
  36. static ktime_t last_intr_time;
  37. static int last_value;
  38. static struct rc_dev *rcdev;
  39. static struct platform_device *sir_ir_dev;
  40. static DEFINE_SPINLOCK(hardware_lock);
  41. /* SECTION: Prototypes */
  42. /* Communication with user-space */
  43. static void add_read_queue(int flag, unsigned long val);
  44. static int init_chrdev(void);
  45. /* Hardware */
  46. static irqreturn_t sir_interrupt(int irq, void *dev_id);
  47. static void send_space(unsigned long len);
  48. static void send_pulse(unsigned long len);
  49. static int init_hardware(void);
  50. static void drop_hardware(void);
  51. /* Initialisation */
  52. static int init_port(void);
  53. static void drop_port(void);
  54. static inline unsigned int sinp(int offset)
  55. {
  56. return inb(io + offset);
  57. }
  58. static inline void soutp(int offset, int value)
  59. {
  60. outb(value, io + offset);
  61. }
  62. /* SECTION: Communication with user-space */
  63. static int sir_tx_ir(struct rc_dev *dev, unsigned int *tx_buf,
  64. unsigned int count)
  65. {
  66. unsigned long flags;
  67. int i;
  68. local_irq_save(flags);
  69. for (i = 0; i < count;) {
  70. if (tx_buf[i])
  71. send_pulse(tx_buf[i]);
  72. i++;
  73. if (i >= count)
  74. break;
  75. if (tx_buf[i])
  76. send_space(tx_buf[i]);
  77. i++;
  78. }
  79. local_irq_restore(flags);
  80. return count;
  81. }
  82. static void add_read_queue(int flag, unsigned long val)
  83. {
  84. DEFINE_IR_RAW_EVENT(ev);
  85. pr_debug("add flag %d with val %lu\n", flag, val);
  86. /*
  87. * statistically, pulses are ~TIME_CONST/2 too long. we could
  88. * maybe make this more exact, but this is good enough
  89. */
  90. if (flag) {
  91. /* pulse */
  92. if (val > TIME_CONST / 2)
  93. val -= TIME_CONST / 2;
  94. else /* should not ever happen */
  95. val = 1;
  96. ev.pulse = true;
  97. } else {
  98. val += TIME_CONST / 2;
  99. }
  100. ev.duration = US_TO_NS(val);
  101. ir_raw_event_store_with_filter(rcdev, &ev);
  102. }
  103. static int init_chrdev(void)
  104. {
  105. rcdev = devm_rc_allocate_device(&sir_ir_dev->dev, RC_DRIVER_IR_RAW);
  106. if (!rcdev)
  107. return -ENOMEM;
  108. rcdev->input_name = "SIR IrDA port";
  109. rcdev->input_phys = KBUILD_MODNAME "/input0";
  110. rcdev->input_id.bustype = BUS_HOST;
  111. rcdev->input_id.vendor = 0x0001;
  112. rcdev->input_id.product = 0x0001;
  113. rcdev->input_id.version = 0x0100;
  114. rcdev->tx_ir = sir_tx_ir;
  115. rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
  116. rcdev->driver_name = KBUILD_MODNAME;
  117. rcdev->map_name = RC_MAP_RC6_MCE;
  118. rcdev->timeout = IR_DEFAULT_TIMEOUT;
  119. rcdev->dev.parent = &sir_ir_dev->dev;
  120. return devm_rc_register_device(&sir_ir_dev->dev, rcdev);
  121. }
  122. /* SECTION: Hardware */
  123. static void sir_timeout(unsigned long data)
  124. {
  125. /*
  126. * if last received signal was a pulse, but receiving stopped
  127. * within the 9 bit frame, we need to finish this pulse and
  128. * simulate a signal change to from pulse to space. Otherwise
  129. * upper layers will receive two sequences next time.
  130. */
  131. unsigned long flags;
  132. unsigned long pulse_end;
  133. /* avoid interference with interrupt */
  134. spin_lock_irqsave(&timer_lock, flags);
  135. if (last_value) {
  136. /* clear unread bits in UART and restart */
  137. outb(UART_FCR_CLEAR_RCVR, io + UART_FCR);
  138. /* determine 'virtual' pulse end: */
  139. pulse_end = min_t(unsigned long,
  140. ktime_us_delta(last, last_intr_time),
  141. IR_MAX_DURATION);
  142. dev_dbg(&sir_ir_dev->dev, "timeout add %d for %lu usec\n",
  143. last_value, pulse_end);
  144. add_read_queue(last_value, pulse_end);
  145. last_value = 0;
  146. last = last_intr_time;
  147. }
  148. spin_unlock_irqrestore(&timer_lock, flags);
  149. ir_raw_event_handle(rcdev);
  150. }
  151. static irqreturn_t sir_interrupt(int irq, void *dev_id)
  152. {
  153. unsigned char data;
  154. ktime_t curr_time;
  155. static unsigned long delt;
  156. unsigned long deltintr;
  157. unsigned long flags;
  158. int iir, lsr;
  159. while ((iir = inb(io + UART_IIR) & UART_IIR_ID)) {
  160. switch (iir & UART_IIR_ID) { /* FIXME toto treba preriedit */
  161. case UART_IIR_MSI:
  162. (void)inb(io + UART_MSR);
  163. break;
  164. case UART_IIR_RLSI:
  165. case UART_IIR_THRI:
  166. (void)inb(io + UART_LSR);
  167. break;
  168. case UART_IIR_RDI:
  169. /* avoid interference with timer */
  170. spin_lock_irqsave(&timer_lock, flags);
  171. do {
  172. del_timer(&timerlist);
  173. data = inb(io + UART_RX);
  174. curr_time = ktime_get();
  175. delt = min_t(unsigned long,
  176. ktime_us_delta(last, curr_time),
  177. IR_MAX_DURATION);
  178. deltintr = min_t(unsigned long,
  179. ktime_us_delta(last_intr_time,
  180. curr_time),
  181. IR_MAX_DURATION);
  182. dev_dbg(&sir_ir_dev->dev, "t %lu, d %d\n",
  183. deltintr, (int)data);
  184. /*
  185. * if nothing came in last X cycles,
  186. * it was gap
  187. */
  188. if (deltintr > TIME_CONST * threshold) {
  189. if (last_value) {
  190. dev_dbg(&sir_ir_dev->dev, "GAP\n");
  191. /* simulate signal change */
  192. add_read_queue(last_value,
  193. delt -
  194. deltintr);
  195. last_value = 0;
  196. last = last_intr_time;
  197. delt = deltintr;
  198. }
  199. }
  200. data = 1;
  201. if (data ^ last_value) {
  202. /*
  203. * deltintr > 2*TIME_CONST, remember?
  204. * the other case is timeout
  205. */
  206. add_read_queue(last_value,
  207. delt - TIME_CONST);
  208. last_value = data;
  209. last = curr_time;
  210. last = ktime_sub_us(last,
  211. TIME_CONST);
  212. }
  213. last_intr_time = curr_time;
  214. if (data) {
  215. /*
  216. * start timer for end of
  217. * sequence detection
  218. */
  219. timerlist.expires = jiffies +
  220. SIR_TIMEOUT;
  221. add_timer(&timerlist);
  222. }
  223. lsr = inb(io + UART_LSR);
  224. } while (lsr & UART_LSR_DR); /* data ready */
  225. spin_unlock_irqrestore(&timer_lock, flags);
  226. break;
  227. default:
  228. break;
  229. }
  230. }
  231. ir_raw_event_handle(rcdev);
  232. return IRQ_RETVAL(IRQ_HANDLED);
  233. }
  234. static void send_space(unsigned long len)
  235. {
  236. usleep_range(len, len + 25);
  237. }
  238. static void send_pulse(unsigned long len)
  239. {
  240. long bytes_out = len / TIME_CONST;
  241. if (bytes_out == 0)
  242. bytes_out++;
  243. while (bytes_out--) {
  244. outb(PULSE, io + UART_TX);
  245. /* FIXME treba seriozne cakanie z char/serial.c */
  246. while (!(inb(io + UART_LSR) & UART_LSR_THRE))
  247. ;
  248. }
  249. }
  250. static int init_hardware(void)
  251. {
  252. unsigned long flags;
  253. spin_lock_irqsave(&hardware_lock, flags);
  254. /* reset UART */
  255. outb(0, io + UART_MCR);
  256. outb(0, io + UART_IER);
  257. /* init UART */
  258. /* set DLAB, speed = 115200 */
  259. outb(UART_LCR_DLAB | UART_LCR_WLEN7, io + UART_LCR);
  260. outb(1, io + UART_DLL); outb(0, io + UART_DLM);
  261. /* 7N1+start = 9 bits at 115200 ~ 3 bits at 44000 */
  262. outb(UART_LCR_WLEN7, io + UART_LCR);
  263. /* FIFO operation */
  264. outb(UART_FCR_ENABLE_FIFO, io + UART_FCR);
  265. /* interrupts */
  266. /* outb(UART_IER_RLSI|UART_IER_RDI|UART_IER_THRI, io + UART_IER); */
  267. outb(UART_IER_RDI, io + UART_IER);
  268. /* turn on UART */
  269. outb(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2, io + UART_MCR);
  270. spin_unlock_irqrestore(&hardware_lock, flags);
  271. return 0;
  272. }
  273. static void drop_hardware(void)
  274. {
  275. unsigned long flags;
  276. spin_lock_irqsave(&hardware_lock, flags);
  277. /* turn off interrupts */
  278. outb(0, io + UART_IER);
  279. spin_unlock_irqrestore(&hardware_lock, flags);
  280. }
  281. /* SECTION: Initialisation */
  282. static int init_port(void)
  283. {
  284. int retval;
  285. setup_timer(&timerlist, sir_timeout, 0);
  286. /* get I/O port access and IRQ line */
  287. if (!request_region(io, 8, KBUILD_MODNAME)) {
  288. pr_err("i/o port 0x%.4x already in use.\n", io);
  289. return -EBUSY;
  290. }
  291. retval = request_irq(irq, sir_interrupt, 0,
  292. KBUILD_MODNAME, NULL);
  293. if (retval < 0) {
  294. release_region(io, 8);
  295. pr_err("IRQ %d already in use.\n", irq);
  296. return retval;
  297. }
  298. pr_info("I/O port 0x%.4x, IRQ %d.\n", io, irq);
  299. return 0;
  300. }
  301. static void drop_port(void)
  302. {
  303. free_irq(irq, NULL);
  304. del_timer_sync(&timerlist);
  305. release_region(io, 8);
  306. }
  307. static int init_sir_ir(void)
  308. {
  309. int retval;
  310. retval = init_port();
  311. if (retval < 0)
  312. return retval;
  313. init_hardware();
  314. return 0;
  315. }
  316. static int sir_ir_probe(struct platform_device *dev)
  317. {
  318. int retval;
  319. retval = init_chrdev();
  320. if (retval < 0)
  321. return retval;
  322. return init_sir_ir();
  323. }
  324. static int sir_ir_remove(struct platform_device *dev)
  325. {
  326. return 0;
  327. }
  328. static struct platform_driver sir_ir_driver = {
  329. .probe = sir_ir_probe,
  330. .remove = sir_ir_remove,
  331. .driver = {
  332. .name = "sir_ir",
  333. },
  334. };
  335. static int __init sir_ir_init(void)
  336. {
  337. int retval;
  338. retval = platform_driver_register(&sir_ir_driver);
  339. if (retval)
  340. return retval;
  341. sir_ir_dev = platform_device_alloc("sir_ir", 0);
  342. if (!sir_ir_dev) {
  343. retval = -ENOMEM;
  344. goto pdev_alloc_fail;
  345. }
  346. retval = platform_device_add(sir_ir_dev);
  347. if (retval)
  348. goto pdev_add_fail;
  349. return 0;
  350. pdev_add_fail:
  351. platform_device_put(sir_ir_dev);
  352. pdev_alloc_fail:
  353. platform_driver_unregister(&sir_ir_driver);
  354. return retval;
  355. }
  356. static void __exit sir_ir_exit(void)
  357. {
  358. drop_hardware();
  359. drop_port();
  360. platform_device_unregister(sir_ir_dev);
  361. platform_driver_unregister(&sir_ir_driver);
  362. }
  363. module_init(sir_ir_init);
  364. module_exit(sir_ir_exit);
  365. MODULE_DESCRIPTION("Infrared receiver driver for SIR type serial ports");
  366. MODULE_AUTHOR("Milan Pikula");
  367. MODULE_LICENSE("GPL");
  368. module_param(io, int, 0444);
  369. MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)");
  370. module_param(irq, int, 0444);
  371. MODULE_PARM_DESC(irq, "Interrupt (4 or 3)");
  372. module_param(threshold, int, 0444);
  373. MODULE_PARM_DESC(threshold, "space detection threshold (3)");