]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/staging/media/lirc/lirc_parallel.c
Merge remote-tracking branch 'kselftest/next'
[karo-tx-linux.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 #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
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
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
125 static unsigned int lirc_get_timer(void)
126 {
127         return in(LIRC_PORT_TIMER) & LIRC_PORT_TIMER_BIT;
128 }
129
130 static unsigned int lirc_get_signal(void)
131 {
132         return in(LIRC_PORT_SIGNAL) & LIRC_PORT_SIGNAL_BIT;
133 }
134
135 static void lirc_on(void)
136 {
137         out(LIRC_PORT_DATA, tx_mask);
138 }
139
140 static void lirc_off(void)
141 {
142         out(LIRC_PORT_DATA, 0);
143 }
144
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
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
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
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
320 static loff_t lirc_lseek(struct file *filep, loff_t offset, int orig)
321 {
322         return -ESPIPE;
323 }
324
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
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
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
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
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 #ifdef CONFIG_COMPAT
549         .compat_ioctl   = lirc_ioctl,
550 #endif
551         .open           = lirc_open,
552         .release        = lirc_close
553 };
554
555 static int set_use_inc(void *data)
556 {
557         return 0;
558 }
559
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
580 static int lirc_parallel_probe(struct platform_device *dev)
581 {
582         return 0;
583 }
584
585 static int lirc_parallel_remove(struct platform_device *dev)
586 {
587         return 0;
588 }
589
590 static int lirc_parallel_suspend(struct platform_device *dev,
591                                         pm_message_t state)
592 {
593         return 0;
594 }
595
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
611 static int pf(void *handle)
612 {
613         parport_disable_irq(pport);
614         is_claimed = 0;
615         return 0;
616 }
617
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
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
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)");