Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lirc_parallel.c
Go to the documentation of this file.
1 /*
2  * lirc_parallel.c
3  *
4  * lirc_parallel - device driver for infra-red signal receiving and
5  * transmitting unit built by the author
6  *
7  * Copyright (C) 1998 Christoph Bartelmus <[email protected]>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  *
23  */
24 
25 /*** Includes ***/
26 
27 #include <linux/module.h>
28 #include <linux/sched.h>
29 #include <linux/errno.h>
30 #include <linux/signal.h>
31 #include <linux/fs.h>
32 #include <linux/kernel.h>
33 #include <linux/ioport.h>
34 #include <linux/time.h>
35 #include <linux/mm.h>
36 #include <linux/delay.h>
37 
38 #include <linux/io.h>
39 #include <linux/irq.h>
40 #include <linux/uaccess.h>
41 #include <asm/div64.h>
42 
43 #include <linux/poll.h>
44 #include <linux/parport.h>
45 #include <linux/platform_device.h>
46 
47 #include <media/lirc.h>
48 #include <media/lirc_dev.h>
49 
50 #include "lirc_parallel.h"
51 
52 #define LIRC_DRIVER_NAME "lirc_parallel"
53 
54 #ifndef LIRC_IRQ
55 #define LIRC_IRQ 7
56 #endif
57 #ifndef LIRC_PORT
58 #define LIRC_PORT 0x378
59 #endif
60 #ifndef LIRC_TIMER
61 #define LIRC_TIMER 65536
62 #endif
63 
64 /*** Global Variables ***/
65 
66 static bool debug;
67 static bool check_pselecd;
68 
69 unsigned int irq = LIRC_IRQ;
70 unsigned int io = LIRC_PORT;
71 #ifdef LIRC_TIMER
72 unsigned int timer;
73 unsigned int default_timer = LIRC_TIMER;
74 #endif
75 
76 #define RBUF_SIZE (256) /* this must be a power of 2 larger than 1 */
77 
78 static int rbuf[RBUF_SIZE];
79 
80 DECLARE_WAIT_QUEUE_HEAD(lirc_wait);
81 
82 unsigned int rptr;
83 unsigned int wptr;
84 unsigned int lost_irqs;
85 int is_open;
86 
87 struct parport *pport;
90 
91 unsigned int tx_mask = 1;
92 
93 /*** Internal Functions ***/
94 
95 static unsigned int in(int offset)
96 {
97  switch (offset) {
98  case LIRC_LP_BASE:
99  return parport_read_data(pport);
100  case LIRC_LP_STATUS:
101  return parport_read_status(pport);
102  case LIRC_LP_CONTROL:
103  return parport_read_control(pport);
104  }
105  return 0; /* make compiler happy */
106 }
107 
108 static void out(int offset, int value)
109 {
110  switch (offset) {
111  case LIRC_LP_BASE:
112  parport_write_data(pport, value);
113  break;
114  case LIRC_LP_CONTROL:
115  parport_write_control(pport, value);
116  break;
117  case LIRC_LP_STATUS:
118  printk(KERN_INFO "%s: attempt to write to status register\n",
120  break;
121  }
122 }
123 
124 static unsigned int lirc_get_timer(void)
125 {
127 }
128 
129 static unsigned int lirc_get_signal(void)
130 {
132 }
133 
134 static void lirc_on(void)
135 {
137 }
138 
139 static void lirc_off(void)
140 {
141  out(LIRC_PORT_DATA, 0);
142 }
143 
144 static unsigned int init_lirc_timer(void)
145 {
146  struct timeval tv, now;
147  unsigned int level, newlevel, timeelapsed, newtimer;
148  int count = 0;
149 
150  do_gettimeofday(&tv);
151  tv.tv_sec++; /* wait max. 1 sec. */
152  level = lirc_get_timer();
153  do {
154  newlevel = lirc_get_timer();
155  if (level == 0 && newlevel != 0)
156  count++;
157  level = newlevel;
158  do_gettimeofday(&now);
159  } while (count < 1000 && (now.tv_sec < tv.tv_sec
160  || (now.tv_sec == tv.tv_sec
161  && now.tv_usec < tv.tv_usec)));
162 
163  timeelapsed = ((now.tv_sec + 1 - tv.tv_sec)*1000000
164  + (now.tv_usec - tv.tv_usec));
165  if (count >= 1000 && timeelapsed > 0) {
166  if (default_timer == 0) {
167  /* autodetect timer */
168  newtimer = (1000000*count)/timeelapsed;
169  printk(KERN_INFO "%s: %u Hz timer detected\n",
170  LIRC_DRIVER_NAME, newtimer);
171  return newtimer;
172  } else {
173  newtimer = (1000000*count)/timeelapsed;
174  if (abs(newtimer - default_timer) > default_timer/10) {
175  /* bad timer */
176  printk(KERN_NOTICE "%s: bad timer: %u Hz\n",
177  LIRC_DRIVER_NAME, newtimer);
178  printk(KERN_NOTICE "%s: using default timer: "
179  "%u Hz\n",
181  return default_timer;
182  } else {
183  printk(KERN_INFO "%s: %u Hz timer detected\n",
184  LIRC_DRIVER_NAME, newtimer);
185  return newtimer; /* use detected value */
186  }
187  }
188  } else {
189  printk(KERN_NOTICE "%s: no timer detected\n", LIRC_DRIVER_NAME);
190  return 0;
191  }
192 }
193 
194 static int lirc_claim(void)
195 {
196  if (parport_claim(ppdevice) != 0) {
197  printk(KERN_WARNING "%s: could not claim port\n",
199  printk(KERN_WARNING "%s: waiting for port becoming available"
200  "\n", LIRC_DRIVER_NAME);
201  if (parport_claim_or_block(ppdevice) < 0) {
202  printk(KERN_NOTICE "%s: could not claim port, giving"
203  " up\n", LIRC_DRIVER_NAME);
204  return 0;
205  }
206  }
208  is_claimed = 1;
209  return 1;
210 }
211 
212 /*** interrupt handler ***/
213 
214 static void rbuf_write(int signal)
215 {
216  unsigned int nwptr;
217 
218  nwptr = (wptr + 1) & (RBUF_SIZE - 1);
219  if (nwptr == rptr) {
220  /* no new signals will be accepted */
221  lost_irqs++;
222  printk(KERN_NOTICE "%s: buffer overrun\n", LIRC_DRIVER_NAME);
223  return;
224  }
225  rbuf[wptr] = signal;
226  wptr = nwptr;
227 }
228 
229 static void irq_handler(void *blah)
230 {
231  struct timeval tv;
232  static struct timeval lasttv;
233  static int init;
234  long signal;
235  int data;
236  unsigned int level, newlevel;
237  unsigned int timeout;
238 
239  if (!is_open)
240  return;
241 
242  if (!is_claimed)
243  return;
244 
245 #if 0
246  /* disable interrupt */
247  disable_irq(irq);
249 #endif
250  if (check_pselecd && (in(1) & LP_PSELECD))
251  return;
252 
253 #ifdef LIRC_TIMER
254  if (init) {
255  do_gettimeofday(&tv);
256 
257  signal = tv.tv_sec - lasttv.tv_sec;
258  if (signal > 15)
259  /* really long time */
260  data = PULSE_MASK;
261  else
262  data = (int) (signal*1000000 +
263  tv.tv_usec - lasttv.tv_usec +
265 
266  rbuf_write(data); /* space */
267  } else {
268  if (timer == 0) {
269  /*
270  * wake up; we'll lose this signal, but it will be
271  * garbage if the device is turned on anyway
272  */
273  timer = init_lirc_timer();
274  /* enable_irq(irq); */
275  return;
276  }
277  init = 1;
278  }
279 
280  timeout = timer/10; /* timeout after 1/10 sec. */
281  signal = 1;
282  level = lirc_get_timer();
283  do {
284  newlevel = lirc_get_timer();
285  if (level == 0 && newlevel != 0)
286  signal++;
287  level = newlevel;
288 
289  /* giving up */
290  if (signal > timeout
291  || (check_pselecd && (in(1) & LP_PSELECD))) {
292  signal = 0;
293  printk(KERN_NOTICE "%s: timeout\n", LIRC_DRIVER_NAME);
294  break;
295  }
296  } while (lirc_get_signal());
297 
298  if (signal != 0) {
299  /* adjust value to usecs */
300  __u64 helper;
301 
302  helper = ((__u64) signal)*1000000;
303  do_div(helper, timer);
304  signal = (long) helper;
305 
306  if (signal > LIRC_SFH506_DELAY)
307  data = signal - LIRC_SFH506_DELAY;
308  else
309  data = 1;
310  rbuf_write(PULSE_BIT|data); /* pulse */
311  }
312  do_gettimeofday(&lasttv);
313 #else
314  /* add your code here */
315 #endif
316 
317  wake_up_interruptible(&lirc_wait);
318 
319  /* enable interrupt */
320  /*
321  enable_irq(irq);
322  out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ)|LP_PINTEN);
323  */
324 }
325 
326 /*** file operations ***/
327 
328 static loff_t lirc_lseek(struct file *filep, loff_t offset, int orig)
329 {
330  return -ESPIPE;
331 }
332 
333 static ssize_t lirc_read(struct file *filep, char *buf, size_t n, loff_t *ppos)
334 {
335  int result = 0;
336  int count = 0;
338 
339  if (n % sizeof(int))
340  return -EINVAL;
341 
342  add_wait_queue(&lirc_wait, &wait);
344  while (count < n) {
345  if (rptr != wptr) {
346  if (copy_to_user(buf+count, (char *) &rbuf[rptr],
347  sizeof(int))) {
348  result = -EFAULT;
349  break;
350  }
351  rptr = (rptr + 1) & (RBUF_SIZE - 1);
352  count += sizeof(int);
353  } else {
354  if (filep->f_flags & O_NONBLOCK) {
355  result = -EAGAIN;
356  break;
357  }
358  if (signal_pending(current)) {
359  result = -ERESTARTSYS;
360  break;
361  }
362  schedule();
364  }
365  }
366  remove_wait_queue(&lirc_wait, &wait);
368  return count ? count : result;
369 }
370 
371 static ssize_t lirc_write(struct file *filep, const char *buf, size_t n,
372  loff_t *ppos)
373 {
374  int count;
375  unsigned int i;
376  unsigned int level, newlevel;
377  unsigned long flags;
378  int counttimer;
379  int *wbuf;
380  ssize_t ret;
381 
382  if (!is_claimed)
383  return -EBUSY;
384 
385  count = n / sizeof(int);
386 
387  if (n % sizeof(int) || count % 2 == 0)
388  return -EINVAL;
389 
390  wbuf = memdup_user(buf, n);
391  if (IS_ERR(wbuf))
392  return PTR_ERR(wbuf);
393 
394 #ifdef LIRC_TIMER
395  if (timer == 0) {
396  /* try again if device is ready */
397  timer = init_lirc_timer();
398  if (timer == 0) {
399  ret = -EIO;
400  goto out;
401  }
402  }
403 
404  /* adjust values from usecs */
405  for (i = 0; i < count; i++) {
406  __u64 helper;
407 
408  helper = ((__u64) wbuf[i])*timer;
409  do_div(helper, 1000000);
410  wbuf[i] = (int) helper;
411  }
412 
413  local_irq_save(flags);
414  i = 0;
415  while (i < count) {
416  level = lirc_get_timer();
417  counttimer = 0;
418  lirc_on();
419  do {
420  newlevel = lirc_get_timer();
421  if (level == 0 && newlevel != 0)
422  counttimer++;
423  level = newlevel;
424  if (check_pselecd && (in(1) & LP_PSELECD)) {
425  lirc_off();
426  local_irq_restore(flags);
427  ret = -EIO;
428  goto out;
429  }
430  } while (counttimer < wbuf[i]);
431  i++;
432 
433  lirc_off();
434  if (i == count)
435  break;
436  counttimer = 0;
437  do {
438  newlevel = lirc_get_timer();
439  if (level == 0 && newlevel != 0)
440  counttimer++;
441  level = newlevel;
442  if (check_pselecd && (in(1) & LP_PSELECD)) {
443  local_irq_restore(flags);
444  ret = -EIO;
445  goto out;
446  }
447  } while (counttimer < wbuf[i]);
448  i++;
449  }
450  local_irq_restore(flags);
451 #else
452  /* place code that handles write without external timer here */
453 #endif
454  ret = n;
455 out:
456  kfree(wbuf);
457 
458  return ret;
459 }
460 
461 static unsigned int lirc_poll(struct file *file, poll_table *wait)
462 {
463  poll_wait(file, &lirc_wait, wait);
464  if (rptr != wptr)
465  return POLLIN | POLLRDNORM;
466  return 0;
467 }
468 
469 static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
470 {
471  int result;
474  __u32 mode;
475  __u32 value;
476 
477  switch (cmd) {
478  case LIRC_GET_FEATURES:
479  result = put_user(features, (__u32 *) arg);
480  if (result)
481  return result;
482  break;
483  case LIRC_GET_SEND_MODE:
484  result = put_user(LIRC_MODE_PULSE, (__u32 *) arg);
485  if (result)
486  return result;
487  break;
488  case LIRC_GET_REC_MODE:
489  result = put_user(LIRC_MODE_MODE2, (__u32 *) arg);
490  if (result)
491  return result;
492  break;
493  case LIRC_SET_SEND_MODE:
494  result = get_user(mode, (__u32 *) arg);
495  if (result)
496  return result;
497  if (mode != LIRC_MODE_PULSE)
498  return -EINVAL;
499  break;
500  case LIRC_SET_REC_MODE:
501  result = get_user(mode, (__u32 *) arg);
502  if (result)
503  return result;
504  if (mode != LIRC_MODE_MODE2)
505  return -ENOSYS;
506  break;
508  result = get_user(value, (__u32 *) arg);
509  if (result)
510  return result;
511  if ((value & LIRC_PARALLEL_TRANSMITTER_MASK) != value)
513  tx_mask = value;
514  break;
515  default:
516  return -ENOIOCTLCMD;
517  }
518  return 0;
519 }
520 
521 static int lirc_open(struct inode *node, struct file *filep)
522 {
523  if (is_open || !lirc_claim())
524  return -EBUSY;
525 
526  parport_enable_irq(pport);
527 
528  /* init read ptr */
529  rptr = 0;
530  wptr = 0;
531  lost_irqs = 0;
532 
533  is_open = 1;
534  return 0;
535 }
536 
537 static int lirc_close(struct inode *node, struct file *filep)
538 {
539  if (is_claimed) {
540  is_claimed = 0;
541  parport_release(ppdevice);
542  }
543  is_open = 0;
544  return 0;
545 }
546 
547 static const struct file_operations lirc_fops = {
548  .owner = THIS_MODULE,
549  .llseek = lirc_lseek,
550  .read = lirc_read,
551  .write = lirc_write,
552  .poll = lirc_poll,
553  .unlocked_ioctl = lirc_ioctl,
554 #ifdef CONFIG_COMPAT
555  .compat_ioctl = lirc_ioctl,
556 #endif
557  .open = lirc_open,
558  .release = lirc_close
559 };
560 
561 static int set_use_inc(void *data)
562 {
563  return 0;
564 }
565 
566 static void set_use_dec(void *data)
567 {
568 }
569 
570 static struct lirc_driver driver = {
571  .name = LIRC_DRIVER_NAME,
572  .minor = -1,
573  .code_length = 1,
574  .sample_rate = 0,
575  .data = NULL,
576  .add_to_buf = NULL,
577  .set_use_inc = set_use_inc,
578  .set_use_dec = set_use_dec,
579  .fops = &lirc_fops,
580  .dev = NULL,
581  .owner = THIS_MODULE,
582 };
583 
584 static struct platform_device *lirc_parallel_dev;
585 
586 static int __devinit lirc_parallel_probe(struct platform_device *dev)
587 {
588  return 0;
589 }
590 
591 static int __devexit lirc_parallel_remove(struct platform_device *dev)
592 {
593  return 0;
594 }
595 
596 static int lirc_parallel_suspend(struct platform_device *dev,
598 {
599  return 0;
600 }
601 
602 static int lirc_parallel_resume(struct platform_device *dev)
603 {
604  return 0;
605 }
606 
607 static struct platform_driver lirc_parallel_driver = {
608  .probe = lirc_parallel_probe,
609  .remove = __devexit_p(lirc_parallel_remove),
610  .suspend = lirc_parallel_suspend,
611  .resume = lirc_parallel_resume,
612  .driver = {
613  .name = LIRC_DRIVER_NAME,
614  .owner = THIS_MODULE,
615  },
616 };
617 
618 static int pf(void *handle)
619 {
620  parport_disable_irq(pport);
621  is_claimed = 0;
622  return 0;
623 }
624 
625 static void kf(void *handle)
626 {
627  if (!is_open)
628  return;
629  if (!lirc_claim())
630  return;
631  parport_enable_irq(pport);
632  lirc_off();
633  /* this is a bit annoying when you actually print...*/
634  /*
635  printk(KERN_INFO "%s: reclaimed port\n", LIRC_DRIVER_NAME);
636  */
637 }
638 
639 /*** module initialization and cleanup ***/
640 
641 static int __init lirc_parallel_init(void)
642 {
643  int result;
644 
645  result = platform_driver_register(&lirc_parallel_driver);
646  if (result) {
647  printk(KERN_NOTICE "platform_driver_register"
648  " returned %d\n", result);
649  return result;
650  }
651 
652  lirc_parallel_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
653  if (!lirc_parallel_dev) {
654  result = -ENOMEM;
655  goto exit_driver_unregister;
656  }
657 
658  result = platform_device_add(lirc_parallel_dev);
659  if (result)
660  goto exit_device_put;
661 
662  pport = parport_find_base(io);
663  if (pport == NULL) {
664  printk(KERN_NOTICE "%s: no port at %x found\n",
666  result = -ENXIO;
667  goto exit_device_put;
668  }
669  ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME,
670  pf, kf, irq_handler, 0, NULL);
671  parport_put_port(pport);
672  if (ppdevice == NULL) {
673  printk(KERN_NOTICE "%s: parport_register_device() failed\n",
675  result = -ENXIO;
676  goto exit_device_put;
677  }
678  if (parport_claim(ppdevice) != 0)
679  goto skip_init;
680  is_claimed = 1;
682 
683 #ifdef LIRC_TIMER
684  if (debug)
686 
687  timer = init_lirc_timer();
688 
689 #if 0 /* continue even if device is offline */
690  if (timer == 0) {
691  is_claimed = 0;
692  parport_release(pport);
693  parport_unregister_device(ppdevice);
694  result = -EIO;
695  goto exit_device_put;
696  }
697 
698 #endif
699  if (debug)
700  out(LIRC_PORT_DATA, 0);
701 #endif
702 
703  is_claimed = 0;
704  parport_release(ppdevice);
705  skip_init:
706  driver.dev = &lirc_parallel_dev->dev;
707  driver.minor = lirc_register_driver(&driver);
708  if (driver.minor < 0) {
709  printk(KERN_NOTICE "%s: register_chrdev() failed\n",
711  parport_unregister_device(ppdevice);
712  result = -EIO;
713  goto exit_device_put;
714  }
715  printk(KERN_INFO "%s: installed using port 0x%04x irq %d\n",
716  LIRC_DRIVER_NAME, io, irq);
717  return 0;
718 
719 exit_device_put:
720  platform_device_put(lirc_parallel_dev);
721 exit_driver_unregister:
722  platform_driver_unregister(&lirc_parallel_driver);
723  return result;
724 }
725 
726 static void __exit lirc_parallel_exit(void)
727 {
728  parport_unregister_device(ppdevice);
730 
731  platform_device_unregister(lirc_parallel_dev);
732  platform_driver_unregister(&lirc_parallel_driver);
733 }
734 
735 module_init(lirc_parallel_init);
736 module_exit(lirc_parallel_exit);
737 
738 MODULE_DESCRIPTION("Infrared receiver driver for parallel ports.");
739 MODULE_AUTHOR("Christoph Bartelmus");
740 MODULE_LICENSE("GPL");
741 
742 module_param(io, int, S_IRUGO);
743 MODULE_PARM_DESC(io, "I/O address base (0x3bc, 0x378 or 0x278)");
744 
745 module_param(irq, int, S_IRUGO);
746 MODULE_PARM_DESC(irq, "Interrupt (7 or 5)");
747 
749 MODULE_PARM_DESC(tx_maxk, "Transmitter mask (default: 0x01)");
750 
752 MODULE_PARM_DESC(debug, "Enable debugging messages");
753 
754 module_param(check_pselecd, bool, S_IRUGO | S_IWUSR);
755 MODULE_PARM_DESC(check_pselecd, "Check for printer (default: 0)");