4 * lirc_parallel - device driver for infra-red signal receiving and
5 * transmitting unit built by the author
7 * Copyright (C) 1998 Christoph Bartelmus <lirc@bartelmus.de>
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.
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.
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
25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
29 #include <linux/module.h>
30 #include <linux/sched.h>
31 #include <linux/errno.h>
32 #include <linux/signal.h>
34 #include <linux/kernel.h>
35 #include <linux/ioport.h>
36 #include <linux/time.h>
38 #include <linux/delay.h>
41 #include <linux/irq.h>
42 #include <linux/uaccess.h>
43 #include <asm/div64.h>
45 #include <linux/poll.h>
46 #include <linux/parport.h>
47 #include <linux/platform_device.h>
49 #include <media/lirc.h>
50 #include <media/lirc_dev.h>
52 #include "lirc_parallel.h"
54 #define LIRC_DRIVER_NAME "lirc_parallel"
60 #define LIRC_PORT 0x378
63 #define LIRC_TIMER 65536
66 /*** Global Variables ***/
69 static bool check_pselecd;
71 static unsigned int irq = LIRC_IRQ;
72 static unsigned int io = LIRC_PORT;
74 static unsigned int timer;
75 static unsigned int default_timer = LIRC_TIMER;
78 #define RBUF_SIZE (256) /* this must be a power of 2 larger than 1 */
80 static int rbuf[RBUF_SIZE];
82 static DECLARE_WAIT_QUEUE_HEAD(lirc_wait);
84 static unsigned int rptr;
85 static unsigned int wptr;
86 static unsigned int lost_irqs;
89 static struct parport *pport;
90 static struct pardevice *ppdevice;
91 static int is_claimed;
93 static unsigned int tx_mask = 1;
95 /*** Internal Functions ***/
97 static unsigned int in(int offset)
101 return parport_read_data(pport);
103 return parport_read_status(pport);
104 case LIRC_LP_CONTROL:
105 return parport_read_control(pport);
107 return 0; /* make compiler happy */
110 static void out(int offset, int value)
114 parport_write_data(pport, value);
116 case LIRC_LP_CONTROL:
117 parport_write_control(pport, value);
120 pr_info("attempt to write to status register\n");
125 static unsigned int lirc_get_timer(void)
127 return in(LIRC_PORT_TIMER) & LIRC_PORT_TIMER_BIT;
130 static unsigned int lirc_get_signal(void)
132 return in(LIRC_PORT_SIGNAL) & LIRC_PORT_SIGNAL_BIT;
135 static void lirc_on(void)
137 out(LIRC_PORT_DATA, tx_mask);
140 static void lirc_off(void)
142 out(LIRC_PORT_DATA, 0);
145 static unsigned int init_lirc_timer(void)
147 struct timeval tv, now;
148 unsigned int level, newlevel, timeelapsed, newtimer;
151 do_gettimeofday(&tv);
152 tv.tv_sec++; /* wait max. 1 sec. */
153 level = lirc_get_timer();
155 newlevel = lirc_get_timer();
156 if (level == 0 && newlevel != 0)
159 do_gettimeofday(&now);
160 } while (count < 1000 && (now.tv_sec < tv.tv_sec
161 || (now.tv_sec == tv.tv_sec
162 && now.tv_usec < tv.tv_usec)));
164 timeelapsed = (now.tv_sec + 1 - tv.tv_sec)*1000000
165 + (now.tv_usec - tv.tv_usec);
166 if (count >= 1000 && timeelapsed > 0) {
167 if (default_timer == 0) {
168 /* autodetect timer */
169 newtimer = (1000000*count)/timeelapsed;
170 pr_info("%u Hz timer detected\n", newtimer);
173 newtimer = (1000000*count)/timeelapsed;
174 if (abs(newtimer - default_timer) > default_timer/10) {
176 pr_notice("bad timer: %u Hz\n", newtimer);
177 pr_notice("using default timer: %u Hz\n",
179 return default_timer;
181 pr_info("%u Hz timer detected\n", newtimer);
182 return newtimer; /* use detected value */
185 pr_notice("no timer detected\n");
189 static int lirc_claim(void)
191 if (parport_claim(ppdevice) != 0) {
192 pr_warn("could not claim port\n");
193 pr_warn("waiting for port becoming available\n");
194 if (parport_claim_or_block(ppdevice) < 0) {
195 pr_notice("could not claim port, giving up\n");
199 out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP);
204 /*** interrupt handler ***/
206 static void rbuf_write(int signal)
210 nwptr = (wptr + 1) & (RBUF_SIZE - 1);
212 /* no new signals will be accepted */
214 pr_notice("buffer overrun\n");
221 static void lirc_lirc_irq_handler(void *blah)
224 static struct timeval lasttv;
228 unsigned int level, newlevel;
229 unsigned int timeout;
238 /* disable interrupt */
240 out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ) & (~LP_PINTEN));
242 if (check_pselecd && (in(1) & LP_PSELECD))
247 do_gettimeofday(&tv);
249 signal = tv.tv_sec - lasttv.tv_sec;
251 /* really long time */
254 data = (int) (signal*1000000 +
255 tv.tv_usec - lasttv.tv_usec +
258 rbuf_write(data); /* space */
262 * wake up; we'll lose this signal, but it will be
263 * garbage if the device is turned on anyway
265 timer = init_lirc_timer();
266 /* enable_irq(irq); */
272 timeout = timer/10; /* timeout after 1/10 sec. */
274 level = lirc_get_timer();
276 newlevel = lirc_get_timer();
277 if (level == 0 && newlevel != 0)
283 || (check_pselecd && (in(1) & LP_PSELECD))) {
285 pr_notice("timeout\n");
288 } while (lirc_get_signal());
291 /* adjust value to usecs */
294 helper = ((__u64) signal)*1000000;
295 do_div(helper, timer);
296 signal = (long) helper;
298 if (signal > LIRC_SFH506_DELAY)
299 data = signal - LIRC_SFH506_DELAY;
302 rbuf_write(PULSE_BIT|data); /* pulse */
304 do_gettimeofday(&lasttv);
306 /* add your code here */
309 wake_up_interruptible(&lirc_wait);
311 /* enable interrupt */
314 out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ)|LP_PINTEN);
318 /*** file operations ***/
320 static loff_t lirc_lseek(struct file *filep, loff_t offset, int orig)
325 static ssize_t lirc_read(struct file *filep, char __user *buf, size_t n,
330 DECLARE_WAITQUEUE(wait, current);
335 add_wait_queue(&lirc_wait, &wait);
336 set_current_state(TASK_INTERRUPTIBLE);
339 if (copy_to_user(buf+count, &rbuf[rptr],
344 rptr = (rptr + 1) & (RBUF_SIZE - 1);
345 count += sizeof(int);
347 if (filep->f_flags & O_NONBLOCK) {
351 if (signal_pending(current)) {
352 result = -ERESTARTSYS;
356 set_current_state(TASK_INTERRUPTIBLE);
359 remove_wait_queue(&lirc_wait, &wait);
360 set_current_state(TASK_RUNNING);
361 return count ? count : result;
364 static ssize_t lirc_write(struct file *filep, const char __user *buf, size_t n,
369 unsigned int level, newlevel;
378 count = n / sizeof(int);
380 if (n % sizeof(int) || count % 2 == 0)
383 wbuf = memdup_user(buf, n);
385 return PTR_ERR(wbuf);
389 /* try again if device is ready */
390 timer = init_lirc_timer();
397 /* adjust values from usecs */
398 for (i = 0; i < count; i++) {
401 helper = ((__u64) wbuf[i])*timer;
402 do_div(helper, 1000000);
403 wbuf[i] = (int) helper;
406 local_irq_save(flags);
409 level = lirc_get_timer();
413 newlevel = lirc_get_timer();
414 if (level == 0 && newlevel != 0)
417 if (check_pselecd && (in(1) & LP_PSELECD)) {
419 local_irq_restore(flags);
423 } while (counttimer < wbuf[i]);
431 newlevel = lirc_get_timer();
432 if (level == 0 && newlevel != 0)
435 if (check_pselecd && (in(1) & LP_PSELECD)) {
436 local_irq_restore(flags);
440 } while (counttimer < wbuf[i]);
443 local_irq_restore(flags);
445 /* place code that handles write without external timer here */
454 static unsigned int lirc_poll(struct file *file, poll_table *wait)
456 poll_wait(file, &lirc_wait, wait);
458 return POLLIN | POLLRDNORM;
462 static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
465 u32 __user *uptr = (u32 __user *)arg;
466 u32 features = LIRC_CAN_SET_TRANSMITTER_MASK |
467 LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2;
472 case LIRC_GET_FEATURES:
473 result = put_user(features, uptr);
477 case LIRC_GET_SEND_MODE:
478 result = put_user(LIRC_MODE_PULSE, uptr);
482 case LIRC_GET_REC_MODE:
483 result = put_user(LIRC_MODE_MODE2, uptr);
487 case LIRC_SET_SEND_MODE:
488 result = get_user(mode, uptr);
491 if (mode != LIRC_MODE_PULSE)
494 case LIRC_SET_REC_MODE:
495 result = get_user(mode, uptr);
498 if (mode != LIRC_MODE_MODE2)
501 case LIRC_SET_TRANSMITTER_MASK:
502 result = get_user(value, uptr);
505 if ((value & LIRC_PARALLEL_TRANSMITTER_MASK) != value)
506 return LIRC_PARALLEL_MAX_TRANSMITTERS;
515 static int lirc_open(struct inode *node, struct file *filep)
517 if (is_open || !lirc_claim())
520 parport_enable_irq(pport);
531 static int lirc_close(struct inode *node, struct file *filep)
535 parport_release(ppdevice);
541 static const struct file_operations lirc_fops = {
542 .owner = THIS_MODULE,
543 .llseek = lirc_lseek,
547 .unlocked_ioctl = lirc_ioctl,
549 .compat_ioctl = lirc_ioctl,
552 .release = lirc_close
555 static int set_use_inc(void *data)
560 static void set_use_dec(void *data)
564 static struct lirc_driver driver = {
565 .name = LIRC_DRIVER_NAME,
571 .set_use_inc = set_use_inc,
572 .set_use_dec = set_use_dec,
575 .owner = THIS_MODULE,
578 static struct platform_device *lirc_parallel_dev;
580 static int lirc_parallel_probe(struct platform_device *dev)
585 static int lirc_parallel_remove(struct platform_device *dev)
590 static int lirc_parallel_suspend(struct platform_device *dev,
596 static int lirc_parallel_resume(struct platform_device *dev)
601 static struct platform_driver lirc_parallel_driver = {
602 .probe = lirc_parallel_probe,
603 .remove = lirc_parallel_remove,
604 .suspend = lirc_parallel_suspend,
605 .resume = lirc_parallel_resume,
607 .name = LIRC_DRIVER_NAME,
611 static int pf(void *handle)
613 parport_disable_irq(pport);
618 static void kf(void *handle)
624 parport_enable_irq(pport);
626 /* this is a bit annoying when you actually print...*/
628 printk(KERN_INFO "%s: reclaimed port\n", LIRC_DRIVER_NAME);
632 /*** module initialization and cleanup ***/
634 static int __init lirc_parallel_init(void)
638 result = platform_driver_register(&lirc_parallel_driver);
640 pr_notice("platform_driver_register returned %d\n", result);
644 lirc_parallel_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
645 if (!lirc_parallel_dev) {
647 goto exit_driver_unregister;
650 result = platform_device_add(lirc_parallel_dev);
652 goto exit_device_put;
654 pport = parport_find_base(io);
656 pr_notice("no port at %x found\n", io);
658 goto exit_device_put;
660 ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME,
661 pf, kf, lirc_lirc_irq_handler, 0,
663 parport_put_port(pport);
664 if (ppdevice == NULL) {
665 pr_notice("parport_register_device() failed\n");
667 goto exit_device_put;
669 if (parport_claim(ppdevice) != 0)
672 out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP);
676 out(LIRC_PORT_DATA, tx_mask);
678 timer = init_lirc_timer();
680 #if 0 /* continue even if device is offline */
683 parport_release(pport);
684 parport_unregister_device(ppdevice);
686 goto exit_device_put;
691 out(LIRC_PORT_DATA, 0);
695 parport_release(ppdevice);
697 driver.dev = &lirc_parallel_dev->dev;
698 driver.minor = lirc_register_driver(&driver);
699 if (driver.minor < 0) {
700 pr_notice("register_chrdev() failed\n");
701 parport_unregister_device(ppdevice);
703 goto exit_device_put;
705 pr_info("installed using port 0x%04x irq %d\n", io, irq);
709 platform_device_put(lirc_parallel_dev);
710 exit_driver_unregister:
711 platform_driver_unregister(&lirc_parallel_driver);
715 static void __exit lirc_parallel_exit(void)
717 parport_unregister_device(ppdevice);
718 lirc_unregister_driver(driver.minor);
720 platform_device_unregister(lirc_parallel_dev);
721 platform_driver_unregister(&lirc_parallel_driver);
724 module_init(lirc_parallel_init);
725 module_exit(lirc_parallel_exit);
727 MODULE_DESCRIPTION("Infrared receiver driver for parallel ports.");
728 MODULE_AUTHOR("Christoph Bartelmus");
729 MODULE_LICENSE("GPL");
731 module_param(io, int, S_IRUGO);
732 MODULE_PARM_DESC(io, "I/O address base (0x3bc, 0x378 or 0x278)");
734 module_param(irq, int, S_IRUGO);
735 MODULE_PARM_DESC(irq, "Interrupt (7 or 5)");
737 module_param(tx_mask, int, S_IRUGO);
738 MODULE_PARM_DESC(tx_maxk, "Transmitter mask (default: 0x01)");
740 module_param(debug, bool, S_IRUGO | S_IWUSR);
741 MODULE_PARM_DESC(debug, "Enable debugging messages");
743 module_param(check_pselecd, bool, S_IRUGO | S_IWUSR);
744 MODULE_PARM_DESC(check_pselecd, "Check for printer (default: 0)");