sir_ir.c 10 KB

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