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