Merge branch 'for-3.8' of git://linux-nfs.org/~bfields/linux
[sfrench/cifs-2.6.git] / drivers / staging / media / 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 #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>
37
38 #include <linux/io.h>
39 #include <linux/irq.h>
40 #include <linux/uaccess.h>
41 #include <asm/div64.h>
42
43 #include <linux/poll.h>
44 #include <linux/parport.h>
45 #include <linux/platform_device.h>
46
47 #include <media/lirc.h>
48 #include <media/lirc_dev.h>
49
50 #include "lirc_parallel.h"
51
52 #define LIRC_DRIVER_NAME "lirc_parallel"
53
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
63
64 /*** Global Variables ***/
65
66 static bool debug;
67 static bool check_pselecd;
68
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
75
76 #define RBUF_SIZE (256) /* this must be a power of 2 larger than 1 */
77
78 static int rbuf[RBUF_SIZE];
79
80 DECLARE_WAIT_QUEUE_HEAD(lirc_wait);
81
82 unsigned int rptr;
83 unsigned int wptr;
84 unsigned int lost_irqs;
85 int is_open;
86
87 struct parport *pport;
88 struct pardevice *ppdevice;
89 int is_claimed;
90
91 unsigned int tx_mask = 1;
92
93 /*** Internal Functions ***/
94
95 static unsigned int in(int offset)
96 {
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);
104         }
105         return 0; /* make compiler happy */
106 }
107
108 static void out(int offset, int value)
109 {
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;
121         }
122 }
123
124 static unsigned int lirc_get_timer(void)
125 {
126         return in(LIRC_PORT_TIMER) & LIRC_PORT_TIMER_BIT;
127 }
128
129 static unsigned int lirc_get_signal(void)
130 {
131         return in(LIRC_PORT_SIGNAL) & LIRC_PORT_SIGNAL_BIT;
132 }
133
134 static void lirc_on(void)
135 {
136         out(LIRC_PORT_DATA, tx_mask);
137 }
138
139 static void lirc_off(void)
140 {
141         out(LIRC_PORT_DATA, 0);
142 }
143
144 static unsigned int init_lirc_timer(void)
145 {
146         struct timeval tv, now;
147         unsigned int level, newlevel, timeelapsed, newtimer;
148         int count = 0;
149
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)));
162
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 */
186                         }
187                 }
188         } else {
189                 printk(KERN_NOTICE "%s: no timer detected\n", LIRC_DRIVER_NAME);
190                 return 0;
191         }
192 }
193
194 static int lirc_claim(void)
195 {
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;
205                 }
206         }
207         out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP);
208         is_claimed = 1;
209         return 1;
210 }
211
212 /*** interrupt handler ***/
213
214 static void rbuf_write(int signal)
215 {
216         unsigned int nwptr;
217
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;
224         }
225         rbuf[wptr] = signal;
226         wptr = nwptr;
227 }
228
229 static void irq_handler(void *blah)
230 {
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;
238
239         if (!is_open)
240                 return;
241
242         if (!is_claimed)
243                 return;
244
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;
252
253 #ifdef LIRC_TIMER
254         if (init) {
255                 do_gettimeofday(&tv);
256
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);
265
266                 rbuf_write(data); /* space */
267         } else {
268                 if (timer == 0) {
269                         /*
270                          * wake up; we'll lose this signal, but it will be
271                          * garbage if the device is turned on anyway
272                          */
273                         timer = init_lirc_timer();
274                         /* enable_irq(irq); */
275                         return;
276                 }
277                 init = 1;
278         }
279
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;
288
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;
295                 }
296         } while (lirc_get_signal());
297
298         if (signal != 0) {
299                 /* adjust value to usecs */
300                 __u64 helper;
301
302                 helper = ((__u64) signal)*1000000;
303                 do_div(helper, timer);
304                 signal = (long) helper;
305
306                 if (signal > LIRC_SFH506_DELAY)
307                         data = signal - LIRC_SFH506_DELAY;
308                 else
309                         data = 1;
310                 rbuf_write(PULSE_BIT|data); /* pulse */
311         }
312         do_gettimeofday(&lasttv);
313 #else
314         /* add your code here */
315 #endif
316
317         wake_up_interruptible(&lirc_wait);
318
319         /* enable interrupt */
320         /*
321           enable_irq(irq);
322           out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ)|LP_PINTEN);
323         */
324 }
325
326 /*** file operations ***/
327
328 static loff_t lirc_lseek(struct file *filep, loff_t offset, int orig)
329 {
330         return -ESPIPE;
331 }
332
333 static ssize_t lirc_read(struct file *filep, char *buf, size_t n, loff_t *ppos)
334 {
335         int result = 0;
336         int count = 0;
337         DECLARE_WAITQUEUE(wait, current);
338
339         if (n % sizeof(int))
340                 return -EINVAL;
341
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;
350                         }
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;
357                         }
358                         if (signal_pending(current)) {
359                                 result = -ERESTARTSYS;
360                                 break;
361                         }
362                         schedule();
363                         set_current_state(TASK_INTERRUPTIBLE);
364                 }
365         }
366         remove_wait_queue(&lirc_wait, &wait);
367         set_current_state(TASK_RUNNING);
368         return count ? count : result;
369 }
370
371 static ssize_t lirc_write(struct file *filep, const char *buf, size_t n,
372                           loff_t *ppos)
373 {
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;
381
382         if (!is_claimed)
383                 return -EBUSY;
384
385         count = n / sizeof(int);
386
387         if (n % sizeof(int) || count % 2 == 0)
388                 return -EINVAL;
389
390         wbuf = memdup_user(buf, n);
391         if (IS_ERR(wbuf))
392                 return PTR_ERR(wbuf);
393
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;
401                 }
402         }
403
404         /* adjust values from usecs */
405         for (i = 0; i < count; i++) {
406                 __u64 helper;
407
408                 helper = ((__u64) 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                                 ret = -EIO;
428                                 goto out;
429                         }
430                 } while (counttimer < wbuf[i]);
431                 i++;
432
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;
446                         }
447                 } while (counttimer < wbuf[i]);
448                 i++;
449         }
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);
457
458         return ret;
459 }
460
461 static unsigned int lirc_poll(struct file *file, poll_table *wait)
462 {
463         poll_wait(file, &lirc_wait, wait);
464         if (rptr != wptr)
465                 return POLLIN | POLLRDNORM;
466         return 0;
467 }
468
469 static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
470 {
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;
476
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;
517         }
518         return 0;
519 }
520
521 static int lirc_open(struct inode *node, struct file *filep)
522 {
523         if (is_open || !lirc_claim())
524                 return -EBUSY;
525
526         parport_enable_irq(pport);
527
528         /* init read ptr */
529         rptr = 0;
530         wptr = 0;
531         lost_irqs = 0;
532
533         is_open = 1;
534         return 0;
535 }
536
537 static int lirc_close(struct inode *node, struct file *filep)
538 {
539         if (is_claimed) {
540                 is_claimed = 0;
541                 parport_release(ppdevice);
542         }
543         is_open = 0;
544         return 0;
545 }
546
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
559 };
560
561 static int set_use_inc(void *data)
562 {
563         return 0;
564 }
565
566 static void set_use_dec(void *data)
567 {
568 }
569
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,
582 };
583
584 static struct platform_device *lirc_parallel_dev;
585
586 static int lirc_parallel_probe(struct platform_device *dev)
587 {
588         return 0;
589 }
590
591 static int lirc_parallel_remove(struct platform_device *dev)
592 {
593         return 0;
594 }
595
596 static int lirc_parallel_suspend(struct platform_device *dev,
597                                         pm_message_t state)
598 {
599         return 0;
600 }
601
602 static int lirc_parallel_resume(struct platform_device *dev)
603 {
604         return 0;
605 }
606
607 static struct platform_driver lirc_parallel_driver = {
608         .probe  = lirc_parallel_probe,
609         .remove = lirc_parallel_remove,
610         .suspend        = lirc_parallel_suspend,
611         .resume = lirc_parallel_resume,
612         .driver = {
613                 .name   = LIRC_DRIVER_NAME,
614                 .owner  = THIS_MODULE,
615         },
616 };
617
618 static int pf(void *handle)
619 {
620         parport_disable_irq(pport);
621         is_claimed = 0;
622         return 0;
623 }
624
625 static void kf(void *handle)
626 {
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...*/
634         /*
635         printk(KERN_INFO "%s: reclaimed port\n", LIRC_DRIVER_NAME);
636         */
637 }
638
639 /*** module initialization and cleanup ***/
640
641 static int __init lirc_parallel_init(void)
642 {
643         int result;
644
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;
650         }
651
652         lirc_parallel_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
653         if (!lirc_parallel_dev) {
654                 result = -ENOMEM;
655                 goto exit_driver_unregister;
656         }
657
658         result = platform_device_add(lirc_parallel_dev);
659         if (result)
660                 goto exit_device_put;
661
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;
668         }
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;
677         }
678         if (parport_claim(ppdevice) != 0)
679                 goto skip_init;
680         is_claimed = 1;
681         out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP);
682
683 #ifdef LIRC_TIMER
684         if (debug)
685                 out(LIRC_PORT_DATA, tx_mask);
686
687         timer = init_lirc_timer();
688
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;
696         }
697
698 #endif
699         if (debug)
700                 out(LIRC_PORT_DATA, 0);
701 #endif
702
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;
714         }
715         printk(KERN_INFO "%s: installed using port 0x%04x irq %d\n",
716                LIRC_DRIVER_NAME, io, irq);
717         return 0;
718
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;
724 }
725
726 static void __exit lirc_parallel_exit(void)
727 {
728         parport_unregister_device(ppdevice);
729         lirc_unregister_driver(driver.minor);
730
731         platform_device_unregister(lirc_parallel_dev);
732         platform_driver_unregister(&lirc_parallel_driver);
733 }
734
735 module_init(lirc_parallel_init);
736 module_exit(lirc_parallel_exit);
737
738 MODULE_DESCRIPTION("Infrared receiver driver for parallel ports.");
739 MODULE_AUTHOR("Christoph Bartelmus");
740 MODULE_LICENSE("GPL");
741
742 module_param(io, int, S_IRUGO);
743 MODULE_PARM_DESC(io, "I/O address base (0x3bc, 0x378 or 0x278)");
744
745 module_param(irq, int, S_IRUGO);
746 MODULE_PARM_DESC(irq, "Interrupt (7 or 5)");
747
748 module_param(tx_mask, int, S_IRUGO);
749 MODULE_PARM_DESC(tx_maxk, "Transmitter mask (default: 0x01)");
750
751 module_param(debug, bool, S_IRUGO | S_IWUSR);
752 MODULE_PARM_DESC(debug, "Enable debugging messages");
753
754 module_param(check_pselecd, bool, S_IRUGO | S_IWUSR);
755 MODULE_PARM_DESC(check_pselecd, "Check for printer (default: 0)");