tty/serial: atmel_serial: whitespace and braces modifications
[zen-stable.git] / drivers / staging / lirc / lirc_parallel.c
blob792aac0a8e7b94f353afd76bb0f831dbad1fab28
1 /*
2 * lirc_parallel.c
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 /*** Includes ***/
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>
38 #include <linux/io.h>
39 #include <linux/irq.h>
40 #include <linux/uaccess.h>
41 #include <asm/div64.h>
43 #include <linux/poll.h>
44 #include <linux/parport.h>
45 #include <linux/platform_device.h>
47 #include <media/lirc.h>
48 #include <media/lirc_dev.h>
50 #include "lirc_parallel.h"
52 #define LIRC_DRIVER_NAME "lirc_parallel"
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
64 /*** Global Variables ***/
66 static int debug;
67 static int check_pselecd;
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
76 #define RBUF_SIZE (256) /* this must be a power of 2 larger than 1 */
78 static int rbuf[RBUF_SIZE];
80 DECLARE_WAIT_QUEUE_HEAD(lirc_wait);
82 unsigned int rptr;
83 unsigned int wptr;
84 unsigned int lost_irqs;
85 int is_open;
87 struct parport *pport;
88 struct pardevice *ppdevice;
89 int is_claimed;
91 unsigned int tx_mask = 1;
93 /*** Internal Functions ***/
95 static unsigned int in(int offset)
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);
105 return 0; /* make compiler happy */
108 static void out(int offset, int value)
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",
119 LIRC_DRIVER_NAME);
120 break;
124 static unsigned int lirc_get_timer(void)
126 return in(LIRC_PORT_TIMER) & LIRC_PORT_TIMER_BIT;
129 static unsigned int lirc_get_signal(void)
131 return in(LIRC_PORT_SIGNAL) & LIRC_PORT_SIGNAL_BIT;
134 static void lirc_on(void)
136 out(LIRC_PORT_DATA, tx_mask);
139 static void lirc_off(void)
141 out(LIRC_PORT_DATA, 0);
144 static unsigned int init_lirc_timer(void)
146 struct timeval tv, now;
147 unsigned int level, newlevel, timeelapsed, newtimer;
148 int count = 0;
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)));
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",
180 LIRC_DRIVER_NAME, default_timer);
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 */
188 } else {
189 printk(KERN_NOTICE "%s: no timer detected\n", LIRC_DRIVER_NAME);
190 return 0;
194 static int lirc_claim(void)
196 if (parport_claim(ppdevice) != 0) {
197 printk(KERN_WARNING "%s: could not claim port\n",
198 LIRC_DRIVER_NAME);
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;
207 out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP);
208 is_claimed = 1;
209 return 1;
212 /*** interrupt handler ***/
214 static void rbuf_write(int signal)
216 unsigned int nwptr;
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;
225 rbuf[wptr] = signal;
226 wptr = nwptr;
229 static void irq_handler(void *blah)
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;
239 if (!is_open)
240 return;
242 if (!is_claimed)
243 return;
245 #if 0
246 /* disable interrupt */
247 disable_irq(irq);
248 out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ) & (~LP_PINTEN));
249 #endif
250 if (check_pselecd && (in(1) & LP_PSELECD))
251 return;
253 #ifdef LIRC_TIMER
254 if (init) {
255 do_gettimeofday(&tv);
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 +
264 LIRC_SFH506_DELAY);
266 rbuf_write(data); /* space */
267 } else {
268 if (timer == 0) {
270 * wake up; we'll lose this signal, but it will be
271 * garbage if the device is turned on anyway
273 timer = init_lirc_timer();
274 /* enable_irq(irq); */
275 return;
277 init = 1;
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;
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;
296 } while (lirc_get_signal());
298 if (signal != 0) {
299 /* adjust value to usecs */
300 __u64 helper;
302 helper = ((__u64) signal)*1000000;
303 do_div(helper, timer);
304 signal = (long) helper;
306 if (signal > LIRC_SFH506_DELAY)
307 data = signal - LIRC_SFH506_DELAY;
308 else
309 data = 1;
310 rbuf_write(PULSE_BIT|data); /* pulse */
312 do_gettimeofday(&lasttv);
313 #else
314 /* add your code here */
315 #endif
317 wake_up_interruptible(&lirc_wait);
319 /* enable interrupt */
321 enable_irq(irq);
322 out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ)|LP_PINTEN);
326 /*** file operations ***/
328 static loff_t lirc_lseek(struct file *filep, loff_t offset, int orig)
330 return -ESPIPE;
333 static ssize_t lirc_read(struct file *filep, char *buf, size_t n, loff_t *ppos)
335 int result = 0;
336 int count = 0;
337 DECLARE_WAITQUEUE(wait, current);
339 if (n % sizeof(int))
340 return -EINVAL;
342 add_wait_queue(&lirc_wait, &wait);
343 set_current_state(TASK_INTERRUPTIBLE);
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;
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;
358 if (signal_pending(current)) {
359 result = -ERESTARTSYS;
360 break;
362 schedule();
363 set_current_state(TASK_INTERRUPTIBLE);
366 remove_wait_queue(&lirc_wait, &wait);
367 set_current_state(TASK_RUNNING);
368 return count ? count : result;
371 static ssize_t lirc_write(struct file *filep, const char *buf, size_t n,
372 loff_t *ppos)
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;
382 if (!is_claimed)
383 return -EBUSY;
385 count = n / sizeof(int);
387 if (n % sizeof(int) || count % 2 == 0)
388 return -EINVAL;
390 wbuf = memdup_user(buf, n);
391 if (IS_ERR(wbuf))
392 return PTR_ERR(wbuf);
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;
404 /* adjust values from usecs */
405 for (i = 0; i < count; i++) {
406 __u64 helper;
408 helper = ((__u64) wbuf[i])*timer;
409 do_div(helper, 1000000);
410 wbuf[i] = (int) helper;
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;
430 } while (counttimer < wbuf[i]);
431 i++;
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;
447 } while (counttimer < wbuf[i]);
448 i++;
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);
458 return ret;
461 static unsigned int lirc_poll(struct file *file, poll_table *wait)
463 poll_wait(file, &lirc_wait, wait);
464 if (rptr != wptr)
465 return POLLIN | POLLRDNORM;
466 return 0;
469 static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
471 int result;
472 __u32 features = LIRC_CAN_SET_TRANSMITTER_MASK |
473 LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2;
474 __u32 mode;
475 __u32 value;
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;
507 case LIRC_SET_TRANSMITTER_MASK:
508 result = get_user(value, (__u32 *) arg);
509 if (result)
510 return result;
511 if ((value & LIRC_PARALLEL_TRANSMITTER_MASK) != value)
512 return LIRC_PARALLEL_MAX_TRANSMITTERS;
513 tx_mask = value;
514 break;
515 default:
516 return -ENOIOCTLCMD;
518 return 0;
521 static int lirc_open(struct inode *node, struct file *filep)
523 if (is_open || !lirc_claim())
524 return -EBUSY;
526 parport_enable_irq(pport);
528 /* init read ptr */
529 rptr = 0;
530 wptr = 0;
531 lost_irqs = 0;
533 is_open = 1;
534 return 0;
537 static int lirc_close(struct inode *node, struct file *filep)
539 if (is_claimed) {
540 is_claimed = 0;
541 parport_release(ppdevice);
543 is_open = 0;
544 return 0;
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
561 static int set_use_inc(void *data)
563 return 0;
566 static void set_use_dec(void *data)
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,
584 static struct platform_device *lirc_parallel_dev;
586 static int __devinit lirc_parallel_probe(struct platform_device *dev)
588 return 0;
591 static int __devexit lirc_parallel_remove(struct platform_device *dev)
593 return 0;
596 static int lirc_parallel_suspend(struct platform_device *dev,
597 pm_message_t state)
599 return 0;
602 static int lirc_parallel_resume(struct platform_device *dev)
604 return 0;
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,
618 static int pf(void *handle)
620 parport_disable_irq(pport);
621 is_claimed = 0;
622 return 0;
625 static void kf(void *handle)
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...*/
635 printk(KERN_INFO "%s: reclaimed port\n", LIRC_DRIVER_NAME);
639 /*** module initialization and cleanup ***/
641 static int __init lirc_parallel_init(void)
643 int result;
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;
652 lirc_parallel_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
653 if (!lirc_parallel_dev) {
654 result = -ENOMEM;
655 goto exit_driver_unregister;
658 result = platform_device_add(lirc_parallel_dev);
659 if (result)
660 goto exit_device_put;
662 pport = parport_find_base(io);
663 if (pport == NULL) {
664 printk(KERN_NOTICE "%s: no port at %x found\n",
665 LIRC_DRIVER_NAME, io);
666 result = -ENXIO;
667 goto exit_device_put;
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",
674 LIRC_DRIVER_NAME);
675 result = -ENXIO;
676 goto exit_device_put;
678 if (parport_claim(ppdevice) != 0)
679 goto skip_init;
680 is_claimed = 1;
681 out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP);
683 #ifdef LIRC_TIMER
684 if (debug)
685 out(LIRC_PORT_DATA, tx_mask);
687 timer = init_lirc_timer();
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;
698 #endif
699 if (debug)
700 out(LIRC_PORT_DATA, 0);
701 #endif
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",
710 LIRC_DRIVER_NAME);
711 parport_unregister_device(ppdevice);
712 result = -EIO;
713 goto exit_device_put;
715 printk(KERN_INFO "%s: installed using port 0x%04x irq %d\n",
716 LIRC_DRIVER_NAME, io, irq);
717 return 0;
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;
726 static void __exit lirc_parallel_exit(void)
728 parport_unregister_device(ppdevice);
729 lirc_unregister_driver(driver.minor);
731 platform_device_unregister(lirc_parallel_dev);
732 platform_driver_unregister(&lirc_parallel_driver);
735 module_init(lirc_parallel_init);
736 module_exit(lirc_parallel_exit);
738 MODULE_DESCRIPTION("Infrared receiver driver for parallel ports.");
739 MODULE_AUTHOR("Christoph Bartelmus");
740 MODULE_LICENSE("GPL");
742 module_param(io, int, S_IRUGO);
743 MODULE_PARM_DESC(io, "I/O address base (0x3bc, 0x378 or 0x278)");
745 module_param(irq, int, S_IRUGO);
746 MODULE_PARM_DESC(irq, "Interrupt (7 or 5)");
748 module_param(tx_mask, int, S_IRUGO);
749 MODULE_PARM_DESC(tx_maxk, "Transmitter mask (default: 0x01)");
751 module_param(debug, bool, S_IRUGO | S_IWUSR);
752 MODULE_PARM_DESC(debug, "Enable debugging messages");
754 module_param(check_pselecd, bool, S_IRUGO | S_IWUSR);
755 MODULE_PARM_DESC(debug, "Check for printer (default: 0)");