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