sir_ir.c 10 KB

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