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