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
28 #error "--- Sorry, this driver is not SMP safe. ---"
31 #include <linux/module.h>
32 #include <linux/sched.h>
33 #include <linux/errno.h>
34 #include <linux/signal.h>
36 #include <linux/kernel.h>
37 #include <linux/ioport.h>
38 #include <linux/time.h>
40 #include <linux/delay.h>
43 #include <linux/signal.h>
44 #include <linux/irq.h>
45 #include <linux/uaccess.h>
46 #include <asm/div64.h>
48 #include <linux/poll.h>
49 #include <linux/parport.h>
51 #include <media/lirc.h>
52 #include <media/lirc_dev.h>
54 #include "lirc_parallel.h"
56 #define LIRC_DRIVER_NAME "lirc_parallel"
62 #define LIRC_PORT 0x378
65 #define LIRC_TIMER 65536
68 /*** Global Variables ***/
71 static int check_pselecd
;
73 unsigned int irq
= LIRC_IRQ
;
74 unsigned int io
= LIRC_PORT
;
77 unsigned int default_timer
= LIRC_TIMER
;
80 #define RBUF_SIZE (256) /* this must be a power of 2 larger than 1 */
82 static int rbuf
[RBUF_SIZE
];
84 DECLARE_WAIT_QUEUE_HEAD(lirc_wait
);
88 unsigned int lost_irqs
;
91 struct parport
*pport
;
92 struct pardevice
*ppdevice
;
95 unsigned int tx_mask
= 1;
97 /*** Internal Functions ***/
99 static unsigned int in(int offset
)
103 return parport_read_data(pport
);
105 return parport_read_status(pport
);
106 case LIRC_LP_CONTROL
:
107 return parport_read_control(pport
);
109 return 0; /* make compiler happy */
112 static void out(int offset
, int value
)
116 parport_write_data(pport
, value
);
118 case LIRC_LP_CONTROL
:
119 parport_write_control(pport
, value
);
122 printk(KERN_INFO
"%s: attempt to write to status register\n",
128 static unsigned int lirc_get_timer(void)
130 return in(LIRC_PORT_TIMER
) & LIRC_PORT_TIMER_BIT
;
133 static unsigned int lirc_get_signal(void)
135 return in(LIRC_PORT_SIGNAL
) & LIRC_PORT_SIGNAL_BIT
;
138 static void lirc_on(void)
140 out(LIRC_PORT_DATA
, tx_mask
);
143 static void lirc_off(void)
145 out(LIRC_PORT_DATA
, 0);
148 static unsigned int init_lirc_timer(void)
150 struct timeval tv
, now
;
151 unsigned int level
, newlevel
, timeelapsed
, newtimer
;
154 do_gettimeofday(&tv
);
155 tv
.tv_sec
++; /* wait max. 1 sec. */
156 level
= lirc_get_timer();
158 newlevel
= lirc_get_timer();
159 if (level
== 0 && newlevel
!= 0)
162 do_gettimeofday(&now
);
163 } while (count
< 1000 && (now
.tv_sec
< tv
.tv_sec
164 || (now
.tv_sec
== tv
.tv_sec
165 && now
.tv_usec
< tv
.tv_usec
)));
167 timeelapsed
= ((now
.tv_sec
+ 1 - tv
.tv_sec
)*1000000
168 + (now
.tv_usec
- tv
.tv_usec
));
169 if (count
>= 1000 && timeelapsed
> 0) {
170 if (default_timer
== 0) {
171 /* autodetect timer */
172 newtimer
= (1000000*count
)/timeelapsed
;
173 printk(KERN_INFO
"%s: %u Hz timer detected\n",
174 LIRC_DRIVER_NAME
, newtimer
);
177 newtimer
= (1000000*count
)/timeelapsed
;
178 if (abs(newtimer
- default_timer
) > default_timer
/10) {
180 printk(KERN_NOTICE
"%s: bad timer: %u Hz\n",
181 LIRC_DRIVER_NAME
, newtimer
);
182 printk(KERN_NOTICE
"%s: using default timer: "
184 LIRC_DRIVER_NAME
, default_timer
);
185 return default_timer
;
187 printk(KERN_INFO
"%s: %u Hz timer detected\n",
188 LIRC_DRIVER_NAME
, newtimer
);
189 return newtimer
; /* use detected value */
193 printk(KERN_NOTICE
"%s: no timer detected\n", LIRC_DRIVER_NAME
);
198 static int lirc_claim(void)
200 if (parport_claim(ppdevice
) != 0) {
201 printk(KERN_WARNING
"%s: could not claim port\n",
203 printk(KERN_WARNING
"%s: waiting for port becoming available"
204 "\n", LIRC_DRIVER_NAME
);
205 if (parport_claim_or_block(ppdevice
) < 0) {
206 printk(KERN_NOTICE
"%s: could not claim port, giving"
207 " up\n", LIRC_DRIVER_NAME
);
211 out(LIRC_LP_CONTROL
, LP_PSELECP
|LP_PINITP
);
216 /*** interrupt handler ***/
218 static void rbuf_write(int signal
)
222 nwptr
= (wptr
+ 1) & (RBUF_SIZE
- 1);
224 /* no new signals will be accepted */
226 printk(KERN_NOTICE
"%s: buffer overrun\n", LIRC_DRIVER_NAME
);
233 static void irq_handler(void *blah
)
236 static struct timeval lasttv
;
240 unsigned int level
, newlevel
;
241 unsigned int timeout
;
250 /* disable interrupt */
252 out(LIRC_PORT_IRQ
, in(LIRC_PORT_IRQ
) & (~LP_PINTEN
));
254 if (check_pselecd
&& (in(1) & LP_PSELECD
))
259 do_gettimeofday(&tv
);
261 signal
= tv
.tv_sec
- lasttv
.tv_sec
;
263 /* really long time */
266 data
= (int) (signal
*1000000 +
267 tv
.tv_usec
- lasttv
.tv_usec
+
270 rbuf_write(data
); /* space */
274 * wake up; we'll lose this signal, but it will be
275 * garbage if the device is turned on anyway
277 timer
= init_lirc_timer();
278 /* enable_irq(irq); */
284 timeout
= timer
/10; /* timeout after 1/10 sec. */
286 level
= lirc_get_timer();
288 newlevel
= lirc_get_timer();
289 if (level
== 0 && newlevel
!= 0)
295 || (check_pselecd
&& (in(1) & LP_PSELECD
))) {
297 printk(KERN_NOTICE
"%s: timeout\n", LIRC_DRIVER_NAME
);
300 } while (lirc_get_signal());
303 /* ajust value to usecs */
304 unsigned long long helper
;
306 helper
= ((unsigned long long) signal
)*1000000;
307 do_div(helper
, timer
);
308 signal
= (long) helper
;
310 if (signal
> LIRC_SFH506_DELAY
)
311 data
= signal
- LIRC_SFH506_DELAY
;
314 rbuf_write(PULSE_BIT
|data
); /* pulse */
316 do_gettimeofday(&lasttv
);
318 /* add your code here */
321 wake_up_interruptible(&lirc_wait
);
323 /* enable interrupt */
326 out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ)|LP_PINTEN);
330 /*** file operations ***/
332 static loff_t
lirc_lseek(struct file
*filep
, loff_t offset
, int orig
)
337 static ssize_t
lirc_read(struct file
*filep
, char *buf
, size_t n
, loff_t
*ppos
)
341 DECLARE_WAITQUEUE(wait
, current
);
346 add_wait_queue(&lirc_wait
, &wait
);
347 set_current_state(TASK_INTERRUPTIBLE
);
350 if (copy_to_user(buf
+count
, (char *) &rbuf
[rptr
],
355 rptr
= (rptr
+ 1) & (RBUF_SIZE
- 1);
356 count
+= sizeof(int);
358 if (filep
->f_flags
& O_NONBLOCK
) {
362 if (signal_pending(current
)) {
363 result
= -ERESTARTSYS
;
367 set_current_state(TASK_INTERRUPTIBLE
);
370 remove_wait_queue(&lirc_wait
, &wait
);
371 set_current_state(TASK_RUNNING
);
372 return count
? count
: result
;
375 static ssize_t
lirc_write(struct file
*filep
, const char *buf
, size_t n
,
380 unsigned int level
, newlevel
;
388 count
= n
/ sizeof(int);
390 if (n
% sizeof(int) || count
% 2 == 0)
393 wbuf
= memdup_user(buf
, n
);
395 return PTR_ERR(wbuf
);
399 /* try again if device is ready */
400 timer
= init_lirc_timer();
405 /* adjust values from usecs */
406 for (i
= 0; i
< count
; i
++) {
407 unsigned long long helper
;
409 helper
= ((unsigned long long) wbuf
[i
])*timer
;
410 do_div(helper
, 1000000);
411 wbuf
[i
] = (int) helper
;
414 local_irq_save(flags
);
417 level
= lirc_get_timer();
421 newlevel
= lirc_get_timer();
422 if (level
== 0 && newlevel
!= 0)
425 if (check_pselecd
&& (in(1) & LP_PSELECD
)) {
427 local_irq_restore(flags
);
430 } while (counttimer
< wbuf
[i
]);
438 newlevel
= lirc_get_timer();
439 if (level
== 0 && newlevel
!= 0)
442 if (check_pselecd
&& (in(1) & LP_PSELECD
)) {
443 local_irq_restore(flags
);
446 } while (counttimer
< wbuf
[i
]);
449 local_irq_restore(flags
);
451 /* place code that handles write without external timer here */
456 static unsigned int lirc_poll(struct file
*file
, poll_table
*wait
)
458 poll_wait(file
, &lirc_wait
, wait
);
460 return POLLIN
| POLLRDNORM
;
464 static long lirc_ioctl(struct file
*filep
, unsigned int cmd
, unsigned long arg
)
467 unsigned long features
= LIRC_CAN_SET_TRANSMITTER_MASK
|
468 LIRC_CAN_SEND_PULSE
| LIRC_CAN_REC_MODE2
;
473 case LIRC_GET_FEATURES
:
474 result
= put_user(features
, (unsigned long *) arg
);
478 case LIRC_GET_SEND_MODE
:
479 result
= put_user(LIRC_MODE_PULSE
, (unsigned long *) arg
);
483 case LIRC_GET_REC_MODE
:
484 result
= put_user(LIRC_MODE_MODE2
, (unsigned long *) arg
);
488 case LIRC_SET_SEND_MODE
:
489 result
= get_user(mode
, (unsigned long *) arg
);
492 if (mode
!= LIRC_MODE_PULSE
)
495 case LIRC_SET_REC_MODE
:
496 result
= get_user(mode
, (unsigned long *) arg
);
499 if (mode
!= LIRC_MODE_MODE2
)
502 case LIRC_SET_TRANSMITTER_MASK
:
503 result
= get_user(ivalue
, (unsigned int *) arg
);
506 if ((ivalue
& LIRC_PARALLEL_TRANSMITTER_MASK
) != ivalue
)
507 return LIRC_PARALLEL_MAX_TRANSMITTERS
;
516 static int lirc_open(struct inode
*node
, struct file
*filep
)
518 if (is_open
|| !lirc_claim())
521 parport_enable_irq(pport
);
532 static int lirc_close(struct inode
*node
, struct file
*filep
)
536 parport_release(ppdevice
);
542 static const struct file_operations lirc_fops
= {
543 .owner
= THIS_MODULE
,
544 .llseek
= lirc_lseek
,
548 .unlocked_ioctl
= lirc_ioctl
,
550 .release
= lirc_close
553 static int set_use_inc(void *data
)
558 static void set_use_dec(void *data
)
562 static struct lirc_driver driver
= {
563 .name
= LIRC_DRIVER_NAME
,
569 .set_use_inc
= set_use_inc
,
570 .set_use_dec
= set_use_dec
,
573 .owner
= THIS_MODULE
,
576 static int pf(void *handle
);
577 static void kf(void *handle
);
579 static struct timer_list poll_timer
;
580 static void poll_state(unsigned long ignored
);
582 static void poll_state(unsigned long ignored
)
584 printk(KERN_NOTICE
"%s: time\n",
586 del_timer(&poll_timer
);
591 printk(KERN_NOTICE
"%s: could not claim port, giving up\n",
593 init_timer(&poll_timer
);
594 poll_timer
.expires
= jiffies
+ HZ
;
595 poll_timer
.data
= (unsigned long)current
;
596 poll_timer
.function
= poll_state
;
597 add_timer(&poll_timer
);
601 static int pf(void *handle
)
603 parport_disable_irq(pport
);
608 static void kf(void *handle
)
614 parport_enable_irq(pport
);
616 /* this is a bit annoying when you actually print...*/
618 printk(KERN_INFO "%s: reclaimed port\n", LIRC_DRIVER_NAME);
622 /*** module initialization and cleanup ***/
624 static int __init
lirc_parallel_init(void)
626 pport
= parport_find_base(io
);
628 printk(KERN_NOTICE
"%s: no port at %x found\n",
629 LIRC_DRIVER_NAME
, io
);
632 ppdevice
= parport_register_device(pport
, LIRC_DRIVER_NAME
,
633 pf
, kf
, irq_handler
, 0, NULL
);
634 parport_put_port(pport
);
635 if (ppdevice
== NULL
) {
636 printk(KERN_NOTICE
"%s: parport_register_device() failed\n",
640 if (parport_claim(ppdevice
) != 0)
643 out(LIRC_LP_CONTROL
, LP_PSELECP
|LP_PINITP
);
647 out(LIRC_PORT_DATA
, tx_mask
);
649 timer
= init_lirc_timer();
651 #if 0 /* continue even if device is offline */
654 parport_release(pport
);
655 parport_unregister_device(ppdevice
);
661 out(LIRC_PORT_DATA
, 0);
665 parport_release(ppdevice
);
667 driver
.minor
= lirc_register_driver(&driver
);
668 if (driver
.minor
< 0) {
669 printk(KERN_NOTICE
"%s: register_chrdev() failed\n",
671 parport_unregister_device(ppdevice
);
674 printk(KERN_INFO
"%s: installed using port 0x%04x irq %d\n",
675 LIRC_DRIVER_NAME
, io
, irq
);
679 static void __exit
lirc_parallel_exit(void)
681 parport_unregister_device(ppdevice
);
682 lirc_unregister_driver(driver
.minor
);
685 module_init(lirc_parallel_init
);
686 module_exit(lirc_parallel_exit
);
688 MODULE_DESCRIPTION("Infrared receiver driver for parallel ports.");
689 MODULE_AUTHOR("Christoph Bartelmus");
690 MODULE_LICENSE("GPL");
692 module_param(io
, int, S_IRUGO
);
693 MODULE_PARM_DESC(io
, "I/O address base (0x3bc, 0x378 or 0x278)");
695 module_param(irq
, int, S_IRUGO
);
696 MODULE_PARM_DESC(irq
, "Interrupt (7 or 5)");
698 module_param(tx_mask
, int, S_IRUGO
);
699 MODULE_PARM_DESC(tx_maxk
, "Transmitter mask (default: 0x01)");
701 module_param(debug
, bool, S_IRUGO
| S_IWUSR
);
702 MODULE_PARM_DESC(debug
, "Enable debugging messages");
704 module_param(check_pselecd
, bool, S_IRUGO
| S_IWUSR
);
705 MODULE_PARM_DESC(debug
, "Check for printer (default: 0)");