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