]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/lirc/lirc_parallel.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
[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
805a8966
JW
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>
805a8966
JW
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
65static int debug;
66static int check_pselecd;
67
68unsigned int irq = LIRC_IRQ;
69unsigned int io = LIRC_PORT;
70#ifdef LIRC_TIMER
71unsigned int timer;
72unsigned int default_timer = LIRC_TIMER;
73#endif
74
75#define RBUF_SIZE (256) /* this must be a power of 2 larger than 1 */
76
77static int rbuf[RBUF_SIZE];
78
79DECLARE_WAIT_QUEUE_HEAD(lirc_wait);
80
81unsigned int rptr;
82unsigned int wptr;
83unsigned int lost_irqs;
84int is_open;
85
86struct parport *pport;
87struct pardevice *ppdevice;
88int is_claimed;
89
90unsigned int tx_mask = 1;
91
92/*** Internal Functions ***/
93
94static 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
107static 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
123static unsigned int lirc_get_timer(void)
124{
125 return in(LIRC_PORT_TIMER) & LIRC_PORT_TIMER_BIT;
126}
127
128static unsigned int lirc_get_signal(void)
129{
130 return in(LIRC_PORT_SIGNAL) & LIRC_PORT_SIGNAL_BIT;
131}
132
133static void lirc_on(void)
134{
135 out(LIRC_PORT_DATA, tx_mask);
136}
137
138static void lirc_off(void)
139{
140 out(LIRC_PORT_DATA, 0);
141}
142
143static 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
193static 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
213static 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
228static 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
82ce67bf 238 if (!is_open)
805a8966
JW
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 */
a1266818 299 __u64 helper;
805a8966 300
a1266818 301 helper = ((__u64) signal)*1000000;
805a8966
JW
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
327static loff_t lirc_lseek(struct file *filep, loff_t offset, int orig)
328{
329 return -ESPIPE;
330}
331
332static 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
370static 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
380 if (!is_claimed)
381 return -EBUSY;
382
383 count = n / sizeof(int);
384
385 if (n % sizeof(int) || count % 2 == 0)
386 return -EINVAL;
387
388 wbuf = memdup_user(buf, n);
389 if (IS_ERR(wbuf))
390 return PTR_ERR(wbuf);
391
392#ifdef LIRC_TIMER
393 if (timer == 0) {
394 /* try again if device is ready */
395 timer = init_lirc_timer();
396 if (timer == 0)
397 return -EIO;
398 }
399
400 /* adjust values from usecs */
401 for (i = 0; i < count; i++) {
a1266818 402 __u64 helper;
805a8966 403
a1266818 404 helper = ((__u64) wbuf[i])*timer;
805a8966
JW
405 do_div(helper, 1000000);
406 wbuf[i] = (int) helper;
407 }
408
409 local_irq_save(flags);
410 i = 0;
411 while (i < count) {
412 level = lirc_get_timer();
413 counttimer = 0;
414 lirc_on();
415 do {
416 newlevel = lirc_get_timer();
417 if (level == 0 && newlevel != 0)
418 counttimer++;
419 level = newlevel;
420 if (check_pselecd && (in(1) & LP_PSELECD)) {
421 lirc_off();
422 local_irq_restore(flags);
423 return -EIO;
424 }
425 } while (counttimer < wbuf[i]);
426 i++;
427
428 lirc_off();
429 if (i == count)
430 break;
431 counttimer = 0;
432 do {
433 newlevel = lirc_get_timer();
434 if (level == 0 && newlevel != 0)
435 counttimer++;
436 level = newlevel;
437 if (check_pselecd && (in(1) & LP_PSELECD)) {
438 local_irq_restore(flags);
439 return -EIO;
440 }
441 } while (counttimer < wbuf[i]);
442 i++;
443 }
444 local_irq_restore(flags);
445#else
446 /* place code that handles write without external timer here */
447#endif
448 return n;
449}
450
451static unsigned int lirc_poll(struct file *file, poll_table *wait)
452{
453 poll_wait(file, &lirc_wait, wait);
454 if (rptr != wptr)
455 return POLLIN | POLLRDNORM;
456 return 0;
457}
458
459static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
460{
461 int result;
a1266818
JW
462 __u32 features = LIRC_CAN_SET_TRANSMITTER_MASK |
463 LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2;
464 __u32 mode;
465 __u32 value;
805a8966
JW
466
467 switch (cmd) {
468 case LIRC_GET_FEATURES:
a1266818 469 result = put_user(features, (__u32 *) arg);
805a8966
JW
470 if (result)
471 return result;
472 break;
473 case LIRC_GET_SEND_MODE:
a1266818 474 result = put_user(LIRC_MODE_PULSE, (__u32 *) arg);
805a8966
JW
475 if (result)
476 return result;
477 break;
478 case LIRC_GET_REC_MODE:
a1266818 479 result = put_user(LIRC_MODE_MODE2, (__u32 *) arg);
805a8966
JW
480 if (result)
481 return result;
482 break;
483 case LIRC_SET_SEND_MODE:
a1266818 484 result = get_user(mode, (__u32 *) arg);
805a8966
JW
485 if (result)
486 return result;
487 if (mode != LIRC_MODE_PULSE)
488 return -EINVAL;
489 break;
490 case LIRC_SET_REC_MODE:
a1266818 491 result = get_user(mode, (__u32 *) arg);
805a8966
JW
492 if (result)
493 return result;
494 if (mode != LIRC_MODE_MODE2)
495 return -ENOSYS;
496 break;
497 case LIRC_SET_TRANSMITTER_MASK:
a1266818 498 result = get_user(value, (__u32 *) arg);
805a8966
JW
499 if (result)
500 return result;
a1266818 501 if ((value & LIRC_PARALLEL_TRANSMITTER_MASK) != value)
805a8966 502 return LIRC_PARALLEL_MAX_TRANSMITTERS;
a1266818 503 tx_mask = value;
805a8966
JW
504 break;
505 default:
506 return -ENOIOCTLCMD;
507 }
508 return 0;
509}
510
511static int lirc_open(struct inode *node, struct file *filep)
512{
82ce67bf 513 if (is_open || !lirc_claim())
805a8966
JW
514 return -EBUSY;
515
516 parport_enable_irq(pport);
517
518 /* init read ptr */
519 rptr = 0;
520 wptr = 0;
521 lost_irqs = 0;
522
523 is_open = 1;
524 return 0;
525}
526
527static int lirc_close(struct inode *node, struct file *filep)
528{
529 if (is_claimed) {
530 is_claimed = 0;
531 parport_release(ppdevice);
532 }
533 is_open = 0;
534 return 0;
535}
536
0f9313ad 537static const struct file_operations lirc_fops = {
805a8966
JW
538 .owner = THIS_MODULE,
539 .llseek = lirc_lseek,
540 .read = lirc_read,
541 .write = lirc_write,
542 .poll = lirc_poll,
543 .unlocked_ioctl = lirc_ioctl,
8be292cc
JW
544#ifdef CONFIG_COMPAT
545 .compat_ioctl = lirc_ioctl,
546#endif
805a8966
JW
547 .open = lirc_open,
548 .release = lirc_close
549};
550
551static int set_use_inc(void *data)
552{
553 return 0;
554}
555
556static void set_use_dec(void *data)
557{
558}
559
560static struct lirc_driver driver = {
561 .name = LIRC_DRIVER_NAME,
562 .minor = -1,
563 .code_length = 1,
564 .sample_rate = 0,
565 .data = NULL,
566 .add_to_buf = NULL,
567 .set_use_inc = set_use_inc,
568 .set_use_dec = set_use_dec,
569 .fops = &lirc_fops,
570 .dev = NULL,
571 .owner = THIS_MODULE,
572};
573
574static int pf(void *handle);
575static void kf(void *handle);
576
805a8966
JW
577static int pf(void *handle)
578{
579 parport_disable_irq(pport);
580 is_claimed = 0;
581 return 0;
582}
583
584static void kf(void *handle)
585{
586 if (!is_open)
587 return;
588 if (!lirc_claim())
589 return;
590 parport_enable_irq(pport);
591 lirc_off();
592 /* this is a bit annoying when you actually print...*/
593 /*
594 printk(KERN_INFO "%s: reclaimed port\n", LIRC_DRIVER_NAME);
595 */
596}
597
598/*** module initialization and cleanup ***/
599
600static int __init lirc_parallel_init(void)
601{
602 pport = parport_find_base(io);
603 if (pport == NULL) {
604 printk(KERN_NOTICE "%s: no port at %x found\n",
605 LIRC_DRIVER_NAME, io);
606 return -ENXIO;
607 }
608 ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME,
609 pf, kf, irq_handler, 0, NULL);
610 parport_put_port(pport);
611 if (ppdevice == NULL) {
612 printk(KERN_NOTICE "%s: parport_register_device() failed\n",
613 LIRC_DRIVER_NAME);
614 return -ENXIO;
615 }
616 if (parport_claim(ppdevice) != 0)
617 goto skip_init;
618 is_claimed = 1;
619 out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP);
620
621#ifdef LIRC_TIMER
622 if (debug)
623 out(LIRC_PORT_DATA, tx_mask);
624
625 timer = init_lirc_timer();
626
627#if 0 /* continue even if device is offline */
628 if (timer == 0) {
629 is_claimed = 0;
630 parport_release(pport);
631 parport_unregister_device(ppdevice);
632 return -EIO;
633 }
634
635#endif
636 if (debug)
637 out(LIRC_PORT_DATA, 0);
638#endif
639
640 is_claimed = 0;
641 parport_release(ppdevice);
642 skip_init:
643 driver.minor = lirc_register_driver(&driver);
644 if (driver.minor < 0) {
645 printk(KERN_NOTICE "%s: register_chrdev() failed\n",
646 LIRC_DRIVER_NAME);
647 parport_unregister_device(ppdevice);
648 return -EIO;
649 }
650 printk(KERN_INFO "%s: installed using port 0x%04x irq %d\n",
651 LIRC_DRIVER_NAME, io, irq);
652 return 0;
653}
654
655static void __exit lirc_parallel_exit(void)
656{
657 parport_unregister_device(ppdevice);
658 lirc_unregister_driver(driver.minor);
659}
660
661module_init(lirc_parallel_init);
662module_exit(lirc_parallel_exit);
663
664MODULE_DESCRIPTION("Infrared receiver driver for parallel ports.");
665MODULE_AUTHOR("Christoph Bartelmus");
666MODULE_LICENSE("GPL");
667
668module_param(io, int, S_IRUGO);
669MODULE_PARM_DESC(io, "I/O address base (0x3bc, 0x378 or 0x278)");
670
671module_param(irq, int, S_IRUGO);
672MODULE_PARM_DESC(irq, "Interrupt (7 or 5)");
673
674module_param(tx_mask, int, S_IRUGO);
675MODULE_PARM_DESC(tx_maxk, "Transmitter mask (default: 0x01)");
676
677module_param(debug, bool, S_IRUGO | S_IWUSR);
678MODULE_PARM_DESC(debug, "Enable debugging messages");
679
680module_param(check_pselecd, bool, S_IRUGO | S_IWUSR);
681MODULE_PARM_DESC(debug, "Check for printer (default: 0)");