]> git.pld-linux.org Git - packages/kernel.git/blob - 2.6.8-lirc-0.7.0-pre7.patch
- fixed for PLD
[packages/kernel.git] / 2.6.8-lirc-0.7.0-pre7.patch
1 diff -uNr linux-2.6.8-rc4.orig/drivers/char/Kconfig linux-2.6.8-rc4/drivers/char/Kconfig
2 --- linux-2.6.8-rc4.orig/drivers/char/Kconfig   2004-08-10 09:33:29.000000000 +0200
3 +++ linux-2.6.8-rc4/drivers/char/Kconfig        2004-08-10 10:22:53.524975088 +0200
4 @@ -427,6 +427,7 @@
5  source "drivers/serial/Kconfig"
6  
7  
8 +source "drivers/char/lirc/Kconfig"
9  
10  config UNIX98_PTYS
11         bool "Unix98 PTY support" if EMBEDDED
12 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/Kconfig linux-2.6.8-rc4/drivers/char/lirc/Kconfig
13 --- linux-2.6.8-rc4.orig/drivers/char/lirc/Kconfig      1970-01-01 01:00:00.000000000 +0100
14 +++ linux-2.6.8-rc4/drivers/char/lirc/Kconfig   2004-08-10 10:21:59.728153448 +0200
15 @@ -0,0 +1,204 @@
16 +menu "Linux InfraRed Controller"
17 +
18 +config LIRC_SUPPORT
19 +       tristate "Linux InfraRed Controller"
20 +
21 +       config LIRC_MAX_DEV
22 +               int "Maximum LIRC devices"
23 +               default "2"
24 +               depends on LIRC_SUPPORT
25 +
26 +       config LIRC_IRCTL_DEV_MAJOR
27 +               int "Major device number"
28 +               default "61"
29 +               depends on LIRC_SUPPORT
30 +
31 +       config LIRC_I2C
32 +               tristate "I2C Driver"
33 +               depends on LIRC_SUPPORT && VIDEO_BT848 && I2C && I2C_ALGOBIT
34 +               help
35 +                 Say Y here if you need support for the following cards:
36 +
37 +                 Pixelview IR
38 +                 Hauppauage IR
39 +                 PV951 IR
40 +                 TV-Box IR
41 +                 KNC ONE IR
42 +
43 +                 If these dont make sense to you, then dont use the module.
44 +
45 +       config LIRC_GPIO
46 +               tristate "GPIO Driver"
47 +               depends on LIRC_SUPPORT && VIDEO_BT848
48 +
49 +       config LIRC_BT829
50 +               tristate "BT829 Driver"
51 +               depends on LIRC_SUPPORT
52 +
53 +       config LIRC_IT87
54 +               tristate "IT87 Driver"
55 +               depends on LIRC_SUPPORT
56 +
57 +       config LIRC_ATIUSB
58 +               tristate "ATI USB Driver"
59 +               depends on LIRC_SUPPORT && USB
60 +
61 +       config LIRC_MCEUSB
62 +               tristate "MCE USB Driver"
63 +               depends on LIRC_SUPPORT && USB
64 +
65 +       config LIRC_SASEM
66 +               tristate "USB Driver for Sasem Remote Controller"
67 +               depends on LIRC_SUPPORT && USB
68 +
69 +       config LIRC_PARALLEL
70 +               tristate "Parallel Driver"
71 +               depends on LIRC_SUPPORT && !SMP && PARPORT
72 +
73 +               choice
74 +                       prompt "Parallel Port"
75 +                       depends on LIRC_PARALLEL
76 +                       config LIRC_PARALLEL_LPT1
77 +                               bool "LPT1 (0x378, 7)"
78 +                       config LIRC_PARALLEL_LPT2
79 +                               bool "LPT2 (0x278, 5)"
80 +                       config LIRC_PARALLEL_LPT3
81 +                               bool "COM3 (0x3bc, none)"
82 +                       config LIRC_PARALLEL_OTHER
83 +                               bool "Other (custom values)"
84 +               endchoice
85 +
86 +               config LIRC_PORT_PARALLEL
87 +                       hex "I/O Port"
88 +                               default "0x378" if LIRC_PARALLEL_LPT1
89 +                               default "0x278" if LIRC_PARALLEL_LPT2
90 +                               default "0x3bc" if LIRC_PARALLEL_LPT3
91 +                       depends on LIRC_PARALLEL
92 +
93 +               config LIRC_IRQ_PARALLEL
94 +                       hex "IRQ"
95 +                               default "7" if LIRC_PARALLEL_LPT1
96 +                               default "5" if LIRC_PARALLEL_LPT2
97 +                       depends on LIRC_PARALLEL
98 +
99 +               config LIRC_TIMER
100 +                       int "Timer"
101 +                       default "65535"
102 +                       depends on LIRC_PARALLEL
103 +
104 +       config LIRC_SERIAL
105 +               tristate "Serial Driver"
106 +               depends on LIRC_SUPPORT && SERIAL_8250
107 +
108 +               choice
109 +                       prompt "Serial Receiver Type"
110 +                       depends on LIRC_SERIAL
111 +
112 +                       config LIRC_HOMEBREW
113 +                               bool "Homebrew"
114 +
115 +                       config LIRC_SERIAL_ANIMAX
116 +                               bool "Animax"
117 +
118 +                       config LIRC_SERIAL_IRDEO
119 +                               bool "IRdeo"
120 +
121 +                       config LIRC_SERIAL_IRDEO_REMOTE
122 +                               bool "IRdeo Remote"
123 +
124 +               endchoice
125 +
126 +               config LIRC_SERIAL_TRANSMITTER
127 +                       bool "With transmitter diode"
128 +                       depends on LIRC_SERIAL && !LIRC_SERIAL_ANIMAX
129 +
130 +               config LIRC_SERIAL_SOFTCARRIER
131 +                       bool "With software carrier"
132 +                       depends on LIRC_SERIAL_TRANSMITTER
133 +
134 +               config LIRC_SERIAL_IGOR
135 +                       bool "Igor Ceska's variation"
136 +                       depends on LIRC_SERIAL
137 +
138 +               choice
139 +                       prompt "Serial Port"
140 +                       depends on LIRC_SERIAL
141 +                       config LIRC_SERIAL_COM1
142 +                               bool "COM1 (0x3f8, 4)"
143 +                       config LIRC_SERIAL_COM2
144 +                               bool "COM2 (0x2f8, 3)"
145 +                       config LIRC_SERIAL_COM3
146 +                               bool "COM3 (0x3e8, 4)"
147 +                       config LIRC_SERIAL_COM4
148 +                               bool "COM4 (0x2e8, 3)"
149 +                       config LIRC_SERIAL_OTHER
150 +                               bool "Other (custom values)"
151 +               endchoice
152 +
153 +               config LIRC_PORT_SERIAL
154 +                       hex "I/O Port"
155 +                               default "0x3f8" if LIRC_SERIAL_COM1
156 +                               default "0x2f8" if LIRC_SERIAL_COM2
157 +                               default "0x3e8" if LIRC_SERIAL_COM3
158 +                               default "0x2e8" if LIRC_SERIAL_COM4
159 +                       depends on LIRC_SERIAL
160 +
161 +               config LIRC_IRQ_SERIAL
162 +                       hex "IRQ"
163 +                               default "4" if LIRC_SERIAL_COM1 || LIRC_SERIAL_COM3
164 +                               default "3" if LIRC_SERIAL_COM2 || LIRC_SERIAL_COM4
165 +                       depends on LIRC_SERIAL
166 +
167 +       config LIRC_SIR
168 +               tristate "SIR Driver"
169 +               depends on LIRC_SUPPORT
170 +
171 +               config LIRC_ON_SA1100
172 +                       bool "LIRC driver for StrongARM SA1100 embedded microprocessor"
173 +                       depends on LIRC_SIR
174 +
175 +               choice
176 +                       prompt "SIR Type"
177 +                       depends on LIRC_SIR && !LIRC_ON_SA1100
178 +
179 +                       config LIRC_SIR_IRDA
180 +                               bool "SIR IrDA (built-in IR ports)"
181 +
182 +                       config LIRC_SIR_TEKRAM
183 +                               bool "Tekram Irmate 210 (16x50 UART compatible serial port)"
184 +
185 +                       config LIRC_SIR_ACTISYS_ACT200L
186 +                               bool "Actisys Act200L SIR driver support"
187 +
188 +               endchoice
189 +
190 +               choice
191 +                       prompt "Serial Port"
192 +                       depends on LIRC_SIR
193 +                       config LIRC_SIR_COM1
194 +                               bool "COM1 (0x3f8, 4)"
195 +                       config LIRC_SIR_COM2
196 +                               bool "COM2 (0x2f8, 3)"
197 +                       config LIRC_SIR_COM3
198 +                               bool "COM3 (0x3e8, 4)"
199 +                       config LIRC_SIR_COM4
200 +                               bool "COM4 (0x2e8, 3)"
201 +                       config LIRC_SIR_OTHER
202 +                               bool "Other (custom values)"
203 +               endchoice
204 +
205 +               config LIRC_PORT_SIR
206 +                       hex "I/O Port"
207 +                               default "0x3f8" if LIRC_SIR_COM1
208 +                               default "0x2f8" if LIRC_SIR_COM2
209 +                               default "0x3e8" if LIRC_SIR_COM3
210 +                               default "0x2e8" if LIRC_SIR_COM4
211 +                       depends on LIRC_SIR
212 +
213 +               config LIRC_IRQ_SIR
214 +                       hex "IRQ"
215 +                               default "4" if LIRC_SIR_COM1 || LIRC_SIR_COM3
216 +                               default "3" if LIRC_SIR_COM2 || LIRC_SIR_COM4
217 +                       depends on LIRC_SIR
218 +
219 +endmenu
220 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_atiusb.c linux-2.6.8-rc4/drivers/char/lirc/lirc_atiusb.c
221 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_atiusb.c        1970-01-01 01:00:00.000000000 +0100
222 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_atiusb.c     2004-06-13 16:33:11.000000000 +0200
223 @@ -0,0 +1,681 @@
224 +/* lirc_atiusb - USB remote support for LIRC
225 + * (currently only supports X10 USB remotes)
226 + *
227 + * Copyright (C) 2003-2004 Paul Miller <pmiller9@users.sourceforge.net>
228 + *
229 + * This driver was derived from:
230 + *   Vladimir Dergachev <volodya@minspring.com>'s 2002
231 + *      "USB ATI Remote support" (input device)
232 + *   Adrian Dewhurst <sailor-lk@sailorfrag.net>'s 2002
233 + *      "USB StreamZap remote driver" (LIRC)
234 + *   Artur Lipowski <alipowski@kki.net.pl>'s 2002
235 + *      "lirc_dev" and "lirc_gpio" LIRC modules
236 + *
237 + * $Id$
238 + */
239 +
240 +/*
241 + * This program is free software; you can redistribute it and/or modify
242 + * it under the terms of the GNU General Public License as published by
243 + * the Free Software Foundation; either version 2 of the License, or
244 + * (at your option) any later version.
245 + *
246 + * This program is distributed in the hope that it will be useful,
247 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
248 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
249 + * GNU General Public License for more details.
250 + *
251 + * You should have received a copy of the GNU General Public License
252 + * along with this program; if not, write to the Free Software
253 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
254 + *
255 + */
256 +
257 +#include <linux/version.h>
258 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 4)
259 +#error "*******************************************************"
260 +#error "Sorry, this driver needs kernel version 2.2.4 or higher"
261 +#error "*******************************************************"
262 +#endif
263 +
264 +#include <linux/config.h>
265 +
266 +#include <linux/kernel.h>
267 +#include <linux/errno.h>
268 +#include <linux/init.h>
269 +#include <linux/slab.h>
270 +#include <linux/module.h>
271 +#include <linux/kmod.h>
272 +#include <linux/smp_lock.h>
273 +#include <linux/completion.h>
274 +#include <asm/uaccess.h>
275 +#include <linux/usb.h>
276 +#include <linux/poll.h>
277 +#include <linux/wait.h>
278 +
279 +#include <linux/lirc.h>
280 +#include "kcompat.h"
281 +#include "lirc_dev.h"
282 +
283 +#define DRIVER_VERSION         "0.4"
284 +#define DRIVER_AUTHOR          "Paul Miller <pmiller9@users.sourceforge.net>"
285 +#define DRIVER_DESC            "USB remote driver for LIRC"
286 +#define DRIVER_NAME            "lirc_atiusb"
287 +
288 +#define CODE_LENGTH            5
289 +#define CODE_MIN_LENGTH                4
290 +#define USB_BUFLEN             (CODE_LENGTH*4)
291 +
292 +/* module parameters */
293 +#ifdef CONFIG_USB_DEBUG
294 +       static int debug = 1;
295 +#else
296 +       static int debug = 0;
297 +#endif
298 +#define dprintk                        if (debug) printk
299 +static int mask = 0xFFFF;      // channel acceptance bit mask
300 +static int unique = 0;         // enable channel-specific codes
301 +static int repeat = 10;                // repeat time in 1/100 sec
302 +static unsigned long repeat_jiffies; // repeat timeout
303 +
304 +/* get hi and low bytes of a 16-bits int */
305 +#define HI(a)                  ((unsigned char)((a) >> 8))
306 +#define LO(a)                  ((unsigned char)((a) & 0xff))
307 +
308 +/* lock irctl structure */
309 +#define IRLOCK                 down_interruptible(&ir->lock)
310 +#define IRUNLOCK               up(&ir->lock)
311 +
312 +/* general constants */
313 +#define SUCCESS                        0
314 +#define SEND_FLAG_IN_PROGRESS  1
315 +#define SEND_FLAG_COMPLETE     2
316 +
317 +
318 +/* data structure for each usb remote */
319 +struct irctl {
320 +
321 +       /* usb */
322 +       struct usb_device *usbdev;
323 +       struct urb *urb_in;
324 +       struct urb *urb_out;
325 +       int devnum;
326 +
327 +       /* buffers and dma */
328 +       unsigned char *buf_in;
329 +       unsigned char *buf_out;
330 +       unsigned int len_in;
331 +#ifdef KERNEL_2_5
332 +       dma_addr_t dma_in;
333 +       dma_addr_t dma_out;
334 +#endif
335 +
336 +       /* handle repeats */
337 +       unsigned char old[CODE_LENGTH];
338 +       unsigned long old_jiffies;
339 +
340 +       /* lirc */
341 +       struct lirc_plugin *p;
342 +       int connected;
343 +
344 +       /* handle sending (init strings) */
345 +       int send_flags;
346 +       wait_queue_head_t wait_out;
347 +
348 +       struct semaphore lock;
349 +};
350 +
351 +/* init strings */
352 +static char init1[] = {0x01, 0x00, 0x20, 0x14};
353 +static char init2[] = {0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20};
354 +
355 +/* send packet - used to initialize remote */
356 +static void send_packet(struct irctl *ir, u16 cmd, unsigned char *data)
357 +{
358 +       DECLARE_WAITQUEUE(wait, current);
359 +       int timeout = HZ; /* 1 second */
360 +       unsigned char buf[USB_BUFLEN];
361 +
362 +       dprintk(DRIVER_NAME "[%d]: send called (%#x)\n", ir->devnum, cmd);
363 +
364 +       IRLOCK;
365 +       ir->urb_out->transfer_buffer_length = LO(cmd) + 1;
366 +       ir->urb_out->dev = ir->usbdev;
367 +       ir->send_flags = SEND_FLAG_IN_PROGRESS;
368 +
369 +       memcpy(buf+1, data, LO(cmd));
370 +       buf[0] = HI(cmd);
371 +       memcpy(ir->buf_out, buf, LO(cmd)+1);
372 +
373 +       set_current_state(TASK_INTERRUPTIBLE);
374 +       add_wait_queue(&ir->wait_out, &wait);
375 +
376 +#ifdef KERNEL_2_5
377 +       if (usb_submit_urb(ir->urb_out, SLAB_ATOMIC)) {
378 +#else
379 +       if (usb_submit_urb(ir->urb_out)) {
380 +#endif
381 +               set_current_state(TASK_RUNNING);
382 +               remove_wait_queue(&ir->wait_out, &wait);
383 +               IRUNLOCK;
384 +               return;
385 +       }
386 +       IRUNLOCK;
387 +
388 +       while (timeout && (ir->urb_out->status == -EINPROGRESS)
389 +               && !(ir->send_flags & SEND_FLAG_COMPLETE)) {
390 +               timeout = schedule_timeout(timeout);
391 +               rmb();
392 +       }
393 +
394 +       dprintk(DRIVER_NAME "[%d]: send complete (%#x)\n", ir->devnum, cmd);
395 +
396 +       set_current_state(TASK_RUNNING);
397 +       remove_wait_queue(&ir->wait_out, &wait);
398 +       usb_unlink_urb(ir->urb_out);
399 +}
400 +
401 +static int unregister_from_lirc(struct irctl *ir)
402 +{
403 +       struct lirc_plugin *p = ir->p;
404 +       int devnum;
405 +       int rtn;
406 +
407 +       devnum = ir->devnum;
408 +       dprintk(DRIVER_NAME "[%d]: unregister from lirc called\n", devnum);
409 +
410 +       if ((rtn = lirc_unregister_plugin(p->minor)) > 0) {
411 +               printk(DRIVER_NAME "[%d]: error in lirc_unregister minor: %d\n"
412 +                       "Trying again...\n", devnum, p->minor);
413 +               if (rtn == -EBUSY) {
414 +                       printk(DRIVER_NAME
415 +                               "[%d]: device is opened, will unregister"
416 +                               " on close\n", devnum);
417 +                       return -EAGAIN;
418 +               }
419 +               set_current_state(TASK_INTERRUPTIBLE);
420 +               schedule_timeout(HZ);
421 +
422 +               if ((rtn = lirc_unregister_plugin(p->minor)) > 0) {
423 +                       printk(DRIVER_NAME "[%d]: lirc_unregister failed\n",
424 +                       devnum);
425 +               }
426 +       }
427 +
428 +       if (rtn != SUCCESS) {
429 +               printk(DRIVER_NAME "[%d]: didn't free resources\n", devnum);
430 +               return -EAGAIN;
431 +       }
432 +
433 +       printk(DRIVER_NAME "[%d]: usb remote disconnected\n", devnum);
434 +
435 +       lirc_buffer_free(p->rbuf);
436 +       kfree(p->rbuf);
437 +       kfree(p);
438 +       kfree(ir);
439 +       return SUCCESS;
440 +}
441 +
442 +static int set_use_inc(void *data)
443 +{
444 +       struct irctl *ir = data;
445 +
446 +       if (!ir) {
447 +               printk(DRIVER_NAME "[?]: set_use_inc called with no context\n");
448 +               return -EIO;
449 +       }
450 +       dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum);
451 +
452 +       MOD_INC_USE_COUNT;
453 +
454 +       if (!ir->connected) {
455 +               if (!ir->usbdev)
456 +                       return -ENOENT;
457 +               ir->urb_in->dev = ir->usbdev;
458 +#ifdef KERNEL_2_5
459 +               if (usb_submit_urb(ir->urb_in, SLAB_ATOMIC)) {
460 +#else
461 +               if (usb_submit_urb(ir->urb_in)) {
462 +#endif
463 +                       printk(DRIVER_NAME "[%d]: open result = -EIO error "
464 +                               "submitting urb\n", ir->devnum);
465 +                       MOD_DEC_USE_COUNT;
466 +                       return -EIO;
467 +               }
468 +               ir->connected = 1;
469 +       }
470 +
471 +       return SUCCESS;
472 +}
473 +
474 +static void set_use_dec(void *data)
475 +{
476 +       struct irctl *ir = data;
477 +
478 +       if (!ir) {
479 +               printk(DRIVER_NAME "[?]: set_use_dec called with no context\n");
480 +               return;
481 +       }
482 +       dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum);
483 +
484 +       if (ir->connected) {
485 +               IRLOCK;
486 +               usb_unlink_urb(ir->urb_in);
487 +               ir->connected = 0;
488 +               IRUNLOCK;
489 +       }
490 +       MOD_DEC_USE_COUNT;
491 +}
492 +
493 +static void usb_remote_printdata(struct irctl *ir, char *buf, int len)
494 +{
495 +       char codes[USB_BUFLEN*3 + 1];
496 +       int i;
497 +
498 +       if (len <= 0)
499 +               return;
500 +
501 +       for (i = 0; i < len && i < USB_BUFLEN; i++) {
502 +               snprintf(codes+i*3, 4, "%02x ", buf[i] & 0xFF);
503 +       }
504 +       printk(DRIVER_NAME "[%d]: data received %s (length=%d)\n",
505 +               ir->devnum, codes, len);
506 +}
507 +
508 +#ifdef KERNEL_2_5
509 +static void usb_remote_recv(struct urb *urb, struct pt_regs *regs)
510 +#else
511 +static void usb_remote_recv(struct urb *urb)
512 +#endif
513 +{
514 +       struct irctl *ir;
515 +       int i, len;
516 +       int chan;
517 +
518 +       if (!urb)
519 +               return;
520 +
521 +       if (!(ir = urb->context)) {
522 +               usb_unlink_urb(urb);
523 +               return;
524 +       }
525 +
526 +       len = urb->actual_length;
527 +       if (debug)
528 +               usb_remote_printdata(ir,urb->transfer_buffer,len);
529 +
530 +       switch (urb->status) {
531 +
532 +       /* success */
533 +       case SUCCESS:
534 +               /* some remotes emit both 4 and 5 byte length codes. */
535 +               if (len < CODE_MIN_LENGTH || len > CODE_LENGTH)
536 +                       break;
537 +
538 +               // *** channel not tested with 4/5-byte Dutch remotes ***
539 +               chan = ((ir->buf_in[len-1]>>4) & 0x0F);
540 +               if ( !((1<<chan) & mask) ) {
541 +                       dprintk(DRIVER_NAME "[%d]: ignore channel %d\n",
542 +                               ir->devnum, chan+1);
543 +                       break;
544 +               }
545 +
546 +               dprintk(DRIVER_NAME "[%d]: accept channel %d\n",
547 +                       ir->devnum, chan+1);
548 +
549 +               /* strip channel code */
550 +               if (!unique)
551 +                       ir->buf_in[len-1] &= 0x0F;
552 +
553 +               /* check for repeats */
554 +               if (memcmp(ir->old, ir->buf_in, len) == 0) {
555 +                       if (ir->old_jiffies + repeat_jiffies > jiffies) {
556 +                               break;
557 +                       }
558 +               } else {
559 +                       memcpy(ir->old, ir->buf_in, len);
560 +                       for (i = len; i < CODE_LENGTH; i++) ir->old[i] = 0;
561 +               }
562 +               ir->old_jiffies = jiffies;
563 +
564 +               lirc_buffer_write_1(ir->p->rbuf, ir->old);
565 +               wake_up(&ir->p->rbuf->wait_poll);
566 +               break;
567 +
568 +       /* unlink */
569 +       case -ECONNRESET:
570 +       case -ENOENT:
571 +       case -ESHUTDOWN:
572 +               usb_unlink_urb(urb);
573 +               return;
574 +       }
575 +
576 +       /* resubmit urb */
577 +#ifdef KERNEL_2_5
578 +       usb_submit_urb(urb, SLAB_ATOMIC);
579 +#else
580 +       usb_submit_urb(urb);
581 +#endif
582 +}
583 +
584 +#ifdef KERNEL_2_5
585 +static void usb_remote_send(struct urb *urb, struct pt_regs *regs)
586 +#else
587 +static void usb_remote_send(struct urb *urb)
588 +#endif
589 +{
590 +       struct irctl *ir;
591 +
592 +       if (!urb)
593 +               return;
594 +
595 +       if (!(ir = urb->context)) {
596 +               usb_unlink_urb(urb);
597 +               return;
598 +       }
599 +
600 +       dprintk(DRIVER_NAME "[%d]: usb out called\n", ir->devnum);
601 +
602 +       if (urb->status)
603 +               return;
604 +
605 +       ir->send_flags |= SEND_FLAG_COMPLETE;
606 +       wmb();
607 +       if (waitqueue_active(&ir->wait_out))
608 +               wake_up(&ir->wait_out);
609 +}
610 +
611 +#ifdef KERNEL_2_5
612 +static int usb_remote_probe(struct usb_interface *intf,
613 +                               const struct usb_device_id *id)
614 +{
615 +       struct usb_device *dev = NULL;
616 +       struct usb_host_interface *idesc = NULL;
617 +#else
618 +static void *usb_remote_probe(struct usb_device *dev, unsigned int ifnum,
619 +                               const struct usb_device_id *id)
620 +{
621 +       struct usb_interface *intf;
622 +       struct usb_interface_descriptor *idesc;
623 +#endif
624 +       struct usb_endpoint_descriptor *ep_in, *ep_out;
625 +       struct irctl *ir = NULL;
626 +       struct lirc_plugin *plugin = NULL;
627 +       struct lirc_buffer *rbuf = NULL;
628 +       int devnum, pipe, maxp, len, buf_len, bytes_in_key;
629 +       int minor = 0;
630 +       char buf[63], name[128]="";
631 +       int mem_failure = 0;
632 +
633 +       dprintk(DRIVER_NAME ": usb probe called\n");
634 +
635 +#ifdef KERNEL_2_5
636 +       dev = interface_to_usbdev(intf);
637 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,4)
638 +       idesc = intf->cur_altsetting;
639 +#else
640 +       idesc = &intf->altsetting[intf->act_altsetting];
641 +#endif
642 +       if (idesc->desc.bNumEndpoints != 2)
643 +               return -ENODEV;
644 +       ep_in = &idesc->endpoint[0].desc;
645 +       ep_out = &idesc->endpoint[1].desc;
646 +       if (((ep_in->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)
647 +               || (ep_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
648 +               != USB_ENDPOINT_XFER_INT)
649 +               return -ENODEV;
650 +#else
651 +       intf = &dev->actconfig->interface[ifnum];
652 +       idesc = &intf->altsetting[intf->act_altsetting];
653 +       if (idesc->bNumEndpoints != 2)
654 +               return NULL;
655 +       ep_in = idesc->endpoint + 0;
656 +       ep_out = idesc->endpoint + 1;
657 +       if (((ep_in->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)
658 +               || (ep_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
659 +               != USB_ENDPOINT_XFER_INT)
660 +               return NULL;
661 +#endif
662 +       devnum = dev->devnum;
663 +       pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress);
664 +       maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
665 +
666 +       bytes_in_key = CODE_LENGTH;
667 +       len = (maxp > USB_BUFLEN) ? USB_BUFLEN : maxp;
668 +       buf_len = len - (len % bytes_in_key);
669 +
670 +       dprintk(DRIVER_NAME "[%d]: bytes_in_key=%d len=%d maxp=%d buf_len=%d\n",
671 +               devnum, bytes_in_key, len, maxp, buf_len);
672 +
673 +
674 +       /* allocate kernel memory */
675 +       mem_failure = 0;
676 +       if (!(ir = kmalloc(sizeof(struct irctl), GFP_KERNEL))) {
677 +               mem_failure = 1;
678 +       } else {
679 +               memset(ir, 0, sizeof(struct irctl));
680 +
681 +               if (!(plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL))) {
682 +                       mem_failure = 2;
683 +               } else if (!(rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL))) {
684 +                       mem_failure = 3;
685 +               } else if (lirc_buffer_init(rbuf, bytes_in_key, USB_BUFLEN/bytes_in_key)) {
686 +                       mem_failure = 4;
687 +#ifdef KERNEL_2_5
688 +               } else if (!(ir->buf_in = usb_buffer_alloc(dev, buf_len, SLAB_ATOMIC, &ir->dma_in))) {
689 +                       mem_failure = 5;
690 +               } else if (!(ir->buf_out = usb_buffer_alloc(dev, USB_BUFLEN, SLAB_ATOMIC, &ir->dma_out))) {
691 +                       mem_failure = 6;
692 +               } else if (!(ir->urb_in = usb_alloc_urb(0, GFP_KERNEL))) {
693 +                       mem_failure = 7;
694 +               } else if (!(ir->urb_out = usb_alloc_urb(0, GFP_KERNEL))) {
695 +                       mem_failure = 8;
696 +#else
697 +               } else if (!(ir->buf_in = kmalloc(buf_len, GFP_KERNEL))) {
698 +                       mem_failure = 5;
699 +               } else if (!(ir->buf_out = kmalloc(USB_BUFLEN, GFP_KERNEL))) {
700 +                       mem_failure = 6;
701 +               } else if (!(ir->urb_in = usb_alloc_urb(0))) {
702 +                       mem_failure = 7;
703 +               } else if (!(ir->urb_out = usb_alloc_urb(0))) {
704 +                       mem_failure = 8;
705 +#endif
706 +               } else {
707 +
708 +                       memset(plugin, 0, sizeof(struct lirc_plugin));
709 +
710 +                       strcpy(plugin->name, DRIVER_NAME " ");
711 +                       plugin->minor = -1;
712 +                       plugin->code_length = bytes_in_key*8;
713 +                       plugin->features = LIRC_CAN_REC_LIRCCODE;
714 +                       plugin->data = ir;
715 +                       plugin->rbuf = rbuf;
716 +                       plugin->set_use_inc = &set_use_inc;
717 +                       plugin->set_use_dec = &set_use_dec;
718 +
719 +                       init_MUTEX(&ir->lock);
720 +                       init_waitqueue_head(&ir->wait_out);
721 +
722 +                       if ((minor = lirc_register_plugin(plugin)) < 0) {
723 +                               mem_failure = 9;
724 +                       }
725 +               }
726 +       }
727 +
728 +       /* free allocated memory incase of failure */
729 +       switch (mem_failure) {
730 +       case 9:
731 +               lirc_buffer_free(rbuf);
732 +       case 8:
733 +               usb_free_urb(ir->urb_out);
734 +       case 7:
735 +               usb_free_urb(ir->urb_in);
736 +#ifdef KERNEL_2_5
737 +       case 6:
738 +               usb_buffer_free(dev, USB_BUFLEN, ir->buf_out, ir->dma_out);
739 +       case 5:
740 +               usb_buffer_free(dev, buf_len, ir->buf_in, ir->dma_in);
741 +#else
742 +       case 6:
743 +               kfree(ir->buf_out);
744 +       case 5:
745 +               kfree(ir->buf_in);
746 +#endif
747 +       case 4:
748 +               kfree(rbuf);
749 +       case 3:
750 +               kfree(plugin);
751 +       case 2:
752 +               kfree(ir);
753 +       case 1:
754 +               printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n",
755 +                       devnum, mem_failure);
756 +#ifdef KERNEL_2_5
757 +               return -ENOMEM;
758 +#else
759 +               return NULL;
760 +#endif
761 +       }
762 +
763 +       plugin->minor = minor;
764 +       ir->p = plugin;
765 +       ir->devnum = devnum;
766 +       ir->usbdev = dev;
767 +       ir->len_in = buf_len;
768 +       ir->connected = 0;
769 +
770 +       usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in,
771 +               buf_len, usb_remote_recv, ir, ep_in->bInterval);
772 +       usb_fill_int_urb(ir->urb_out, dev,
773 +               usb_sndintpipe(dev, ep_out->bEndpointAddress), ir->buf_out,
774 +               USB_BUFLEN, usb_remote_send, ir, ep_out->bInterval);
775 +
776 +       if (dev->descriptor.iManufacturer
777 +               && usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0)
778 +               strncpy(name, buf, 128);
779 +       if (dev->descriptor.iProduct
780 +               && usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0)
781 +               snprintf(name, 128, "%s %s", name, buf);
782 +       printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name,
783 +              dev->bus->busnum, devnum);
784 +
785 +       send_packet(ir, 0x8004, init1);
786 +       send_packet(ir, 0x8007, init2);
787 +
788 +#ifdef KERNEL_2_5
789 +       usb_set_intfdata(intf, ir);
790 +       return SUCCESS;
791 +#else
792 +       return ir;
793 +#endif
794 +}
795 +
796 +
797 +#ifdef KERNEL_2_5
798 +static void usb_remote_disconnect(struct usb_interface *intf)
799 +{
800 +       struct usb_device *dev = interface_to_usbdev(intf);
801 +       struct irctl *ir = usb_get_intfdata(intf);
802 +       usb_set_intfdata(intf, NULL);
803 +#else
804 +static void usb_remote_disconnect(struct usb_device *dev, void *ptr)
805 +{
806 +       struct irctl *ir = ptr;
807 +#endif
808 +
809 +       if (!ir || !ir->p)
810 +               return;
811 +
812 +       ir->usbdev = NULL;
813 +       wake_up_all(&ir->wait_out);
814 +
815 +       IRLOCK;
816 +       usb_unlink_urb(ir->urb_in);
817 +       usb_unlink_urb(ir->urb_out);
818 +       usb_free_urb(ir->urb_in);
819 +       usb_free_urb(ir->urb_out);
820 +#ifdef KERNEL_2_5
821 +       usb_buffer_free(dev, ir->len_in, ir->buf_in, ir->dma_in);
822 +       usb_buffer_free(dev, USB_BUFLEN, ir->buf_out, ir->dma_out);
823 +#else
824 +       kfree(ir->buf_in);
825 +       kfree(ir->buf_out);
826 +#endif
827 +       IRUNLOCK;
828 +
829 +       unregister_from_lirc(ir);
830 +}
831 +
832 +static struct usb_device_id usb_remote_id_table [] = {
833 +       { USB_DEVICE(0x0bc7, 0x0002) },         /* X10 USB Firecracker Interface */
834 +       { USB_DEVICE(0x0bc7, 0x0003) },         /* X10 VGA Video Sender */
835 +       { USB_DEVICE(0x0bc7, 0x0004) },         /* ATI Wireless Remote Receiver */
836 +       { USB_DEVICE(0x0bc7, 0x0005) },         /* NVIDIA Wireless Remote Receiver */
837 +       { USB_DEVICE(0x0bc7, 0x0006) },         /* ATI Wireless Remote Receiver */
838 +       { USB_DEVICE(0x0bc7, 0x0007) },         /* X10 USB Wireless Transceiver */
839 +       { USB_DEVICE(0x0bc7, 0x0008) },         /* X10 USB Wireless Transceiver */
840 +       { USB_DEVICE(0x0bc7, 0x0009) },         /* X10 USB Wireless Transceiver */
841 +       { USB_DEVICE(0x0bc7, 0x000A) },         /* X10 USB Wireless Transceiver */
842 +       { USB_DEVICE(0x0bc7, 0x000B) },         /* X10 USB Transceiver */
843 +       { USB_DEVICE(0x0bc7, 0x000C) },         /* X10 USB Transceiver */
844 +       { USB_DEVICE(0x0bc7, 0x000D) },         /* X10 USB Transceiver */
845 +       { USB_DEVICE(0x0bc7, 0x000E) },         /* X10 USB Transceiver */
846 +       { USB_DEVICE(0x0bc7, 0x000F) },         /* X10 USB Transceiver */
847 +
848 +       { }                                     /* Terminating entry */
849 +};
850 +
851 +static struct usb_driver usb_remote_driver = {
852 +       .owner =        THIS_MODULE,
853 +       .name =         DRIVER_NAME,
854 +       .probe =        usb_remote_probe,
855 +       .disconnect =   usb_remote_disconnect,
856 +       .id_table =     usb_remote_id_table
857 +};
858 +
859 +static int __init usb_remote_init(void)
860 +{
861 +       int i;
862 +
863 +       printk("\n" DRIVER_NAME ": " DRIVER_DESC " v" DRIVER_VERSION "\n");
864 +       printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n");
865 +       dprintk(DRIVER_NAME ": debug mode enabled\n");
866 +
867 +       request_module("lirc_dev");
868 +
869 +       repeat_jiffies = repeat*HZ/100;
870 +
871 +       if ((i = usb_register(&usb_remote_driver)) < 0) {
872 +               printk(DRIVER_NAME ": usb register failed, result = %d\n", i);
873 +               return -ENODEV;
874 +       }
875 +
876 +       return SUCCESS;
877 +}
878 +
879 +static void __exit usb_remote_exit(void)
880 +{
881 +       usb_deregister(&usb_remote_driver);
882 +}
883 +
884 +module_init(usb_remote_init);
885 +module_exit(usb_remote_exit);
886 +
887 +MODULE_AUTHOR (DRIVER_AUTHOR);
888 +MODULE_DESCRIPTION (DRIVER_DESC);
889 +MODULE_LICENSE ("GPL");
890 +MODULE_DEVICE_TABLE (usb, usb_remote_id_table);
891 +
892 +MODULE_PARM(debug, "i");
893 +MODULE_PARM_DESC(debug, "enable driver debug mode");
894 +MODULE_PARM(mask, "i");
895 +MODULE_PARM_DESC(mask, "set channel acceptance bit mask");
896 +MODULE_PARM(unique, "i");
897 +MODULE_PARM_DESC(unique, "enable channel-specific codes");
898 +MODULE_PARM(repeat, "i");
899 +MODULE_PARM_DESC(repeat, "repeat timeout (1/100 sec)");
900 +
901 +#ifndef KERNEL_2_5
902 +EXPORT_NO_SYMBOLS;
903 +#endif
904 +
905 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_bt829.c linux-2.6.8-rc4/drivers/char/lirc/lirc_bt829.c
906 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_bt829.c 1970-01-01 01:00:00.000000000 +0100
907 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_bt829.c      2004-04-27 20:45:34.000000000 +0200
908 @@ -0,0 +1,389 @@
909 +/*
910 + * Remote control driver for the TV-card based on bt829
911 + *
912 + *  by Leonid Froenchenko <lfroen@galileo.co.il>
913 + *
914 + *  This program is free software; you can redistribute it and/or modify
915 + *  it under the terms of the GNU General Public License as published by
916 + *  the Free Software Foundation; either version 2 of the License, or
917 + *  (at your option) any later version.
918 + *
919 + *  This program is distributed in the hope that it will be useful,
920 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
921 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
922 + *  GNU General Public License for more details.
923 + *
924 + *  You should have received a copy of the GNU General Public License
925 + *  along with this program; if not, write to the Free Software
926 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
927 +*/
928 +
929 +#include <linux/version.h>
930 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
931 +#error "This driver needs kernel version 2.4.0 or higher"
932 +#endif
933 +
934 +#include <linux/config.h>
935 +#include <linux/kernel.h>
936 +#include <linux/module.h>
937 +#include <linux/threads.h>
938 +#include <linux/sched.h>
939 +#include <linux/ioport.h>
940 +#include <linux/pci.h>
941 +#include <linux/delay.h>
942 +
943 +#include "kcompat.h"
944 +#include "lirc_dev.h"
945 +
946 +
947 +
948 +MODULE_AUTHOR("Froenchenko Leonid");
949 +MODULE_DESCRIPTION("IR remote driver for bt829 based TV cards");
950 +
951 +
952 +int poll_main(void);
953 +int atir_init_start(void);
954 +
955 +void write_index(unsigned char index,unsigned int value);
956 +unsigned int read_index(unsigned char index);
957 +
958 +void do_i2c_start(void);
959 +void do_i2c_stop(void);
960 +
961 +void seems_wr_byte(unsigned char al);
962 +unsigned char seems_rd_byte(void);
963 +
964 +unsigned int read_index(unsigned char al);
965 +void write_index(unsigned char ah,unsigned int edx);
966 +
967 +void cycle_delay(int cycle);
968 +
969 +void do_set_bits(unsigned char bl);
970 +unsigned char do_get_bits(void);
971 +
972 +#define DATA_PCI_OFF 0x7FFC00
973 +#define WAIT_CYCLE   20
974 +
975 +
976 +int atir_minor;
977 +unsigned long pci_addr_phys, pci_addr_lin;
978 +
979 +struct lirc_plugin atir_plugin;
980 +
981 +int do_pci_probe(void)
982 +{
983 +       struct pci_dev *my_dev;
984 +#ifndef KERNEL_2_5
985 +       /* unnecessary with recent kernels */
986 +       if ( !pci_present() ) {
987 +               printk(KERN_ERR "ATIR: no pci in this kernel\n");
988 +       }
989 +#endif
990 +       my_dev = (struct pci_dev *)pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_264VT,NULL);
991 +       if ( my_dev ) {
992 +               printk(KERN_ERR "ATIR: Using device: %s\n",
993 +                      pci_pretty_name(my_dev));
994 +               pci_addr_phys = 0;
995 +               if ( my_dev->resource[0].flags & IORESOURCE_MEM ) {
996 +                       pci_addr_phys = my_dev->resource[0].start;
997 +                       printk(KERN_INFO "ATIR memory at 0x%08X \n",(unsigned int)pci_addr_phys);
998 +               }
999 +               if ( pci_addr_phys == 0 ) {
1000 +                       printk(KERN_ERR "ATIR no memory resource ?\n");
1001 +                       return 0;
1002 +               }
1003 +       } else {
1004 +               printk(KERN_ERR "ATIR: pci_prob failed\n");
1005 +               return 0;
1006 +       }
1007 +       return 1;
1008 +}
1009 +
1010 +
1011 +int atir_add_to_buf (void* data, struct lirc_buffer* buf)
1012 +{
1013 +       unsigned char key;
1014 +       int status;
1015 +       status = poll_main();
1016 +       key = (status >> 8) & 0xFF;
1017 +       if( status & 0xFF )
1018 +       {
1019 +       //    printk(KERN_INFO "ATIR reading key %02X\n",*key);
1020 +               lirc_buffer_write_1( buf, &key );
1021 +               return 0;
1022 +       }
1023 +       return -ENODATA;
1024 +}
1025 +
1026 +int atir_set_use_inc(void* data)
1027 +{
1028 +       MOD_INC_USE_COUNT;
1029 +       printk(KERN_DEBUG "ATIR driver is opened\n");
1030 +       return 0;
1031 +}
1032 +
1033 +void atir_set_use_dec(void* data)
1034 +{
1035 +       MOD_DEC_USE_COUNT;
1036 +       printk(KERN_DEBUG "ATIR driver is closed\n");
1037 +}
1038 +
1039 +int init_module(void)
1040 +{
1041 +       if ( !do_pci_probe() ) {
1042 +               return 1;
1043 +       }
1044 +
1045 +       if ( !atir_init_start() ) {
1046 +               return 1;
1047 +       }
1048 +
1049 +       strcpy(atir_plugin.name,"ATIR");
1050 +       atir_plugin.minor       = -1;
1051 +       atir_plugin.code_length = 8;
1052 +       atir_plugin.sample_rate = 10;
1053 +       atir_plugin.data        = 0;
1054 +       atir_plugin.add_to_buf  = atir_add_to_buf;
1055 +       atir_plugin.set_use_inc = atir_set_use_inc;
1056 +       atir_plugin.set_use_dec = atir_set_use_dec;
1057 +
1058 +       atir_minor = lirc_register_plugin(&atir_plugin);
1059 +       printk(KERN_DEBUG "ATIR driver is registered on minor %d\n",atir_minor);
1060 +
1061 +       return 0;
1062 +}
1063 +
1064 +
1065 +void cleanup_module(void)
1066 +{
1067 +       lirc_unregister_plugin(atir_minor);
1068 +}
1069 +
1070 +
1071 +int atir_init_start(void)
1072 +{
1073 +       pci_addr_lin = (unsigned long)ioremap(pci_addr_phys + DATA_PCI_OFF,0x400);
1074 +       if ( pci_addr_lin == 0 ) {
1075 +               printk(KERN_INFO "atir: pci mem must be mapped\n");
1076 +               return 0;
1077 +       }
1078 +       return 1;
1079 +}
1080 +
1081 +void cycle_delay(int cycle)
1082 +{
1083 +       udelay(WAIT_CYCLE*cycle);
1084 +}
1085 +
1086 +
1087 +int poll_main()
1088 +{
1089 +       unsigned char status_high, status_low;
1090 +       
1091 +       do_i2c_start();
1092 +
1093 +       seems_wr_byte(0xAA);
1094 +       seems_wr_byte(0x01);
1095 +
1096 +       do_i2c_start();
1097 +
1098 +       seems_wr_byte(0xAB);
1099 +
1100 +       status_low = seems_rd_byte();
1101 +       status_high = seems_rd_byte();
1102 +
1103 +       do_i2c_stop();
1104 +
1105 +       return (status_high << 8) | status_low;
1106 +}
1107 +
1108 +void do_i2c_start(void)
1109 +{
1110 +       do_set_bits(3);
1111 +       cycle_delay(4);
1112 +
1113 +       do_set_bits(1);
1114 +       cycle_delay(7);
1115 +
1116 +       do_set_bits(0);
1117 +       cycle_delay(2);
1118 +}
1119 +
1120 +void do_i2c_stop(void)
1121 +{
1122 +       unsigned char bits;
1123 +       bits =  do_get_bits() & 0xFD;
1124 +       do_set_bits(bits);
1125 +       cycle_delay(1);
1126 +
1127 +       bits |= 1;
1128 +       do_set_bits(bits);
1129 +       cycle_delay(2);
1130 +
1131 +       bits |= 2;
1132 +       do_set_bits(bits);
1133 +       bits = 3;
1134 +       do_set_bits(bits);
1135 +       cycle_delay(2);
1136 +}
1137 +
1138 +
1139 +void seems_wr_byte(unsigned char value)
1140 +{
1141 +       int i;
1142 +       unsigned char reg;
1143 +    
1144 +       reg = do_get_bits();
1145 +       for(i = 0;i < 8;i++) {
1146 +               if ( value & 0x80 ) {
1147 +                       reg |= 0x02;
1148 +               } else {
1149 +                       reg &= 0xFD;
1150 +               }
1151 +               do_set_bits(reg);
1152 +               cycle_delay(1);
1153 +
1154 +               reg |= 1;
1155 +               do_set_bits(reg);
1156 +               cycle_delay(1);
1157 +
1158 +               reg &= 0xFE;
1159 +               do_set_bits(reg);
1160 +               cycle_delay(1);
1161 +               value <<= 1;
1162 +       }
1163 +       cycle_delay(2);
1164 +
1165 +       reg |= 2;
1166 +       do_set_bits(reg);
1167 +
1168 +       reg |= 1;
1169 +       do_set_bits(reg);
1170 +
1171 +       cycle_delay(1);
1172 +       do_get_bits();
1173 +
1174 +       reg &= 0xFE;
1175 +       do_set_bits(reg);
1176 +       cycle_delay(3);
1177 +}
1178 +
1179 +unsigned char seems_rd_byte(void)
1180 +{
1181 +       int i;
1182 +       int rd_byte;
1183 +       unsigned char bits_2, bits_1;
1184 +
1185 +       bits_1 = do_get_bits() | 2;
1186 +       do_set_bits(bits_1);
1187 +
1188 +       rd_byte = 0;
1189 +       for(i = 0;i < 8;i++) {
1190 +               bits_1 &= 0xFE;
1191 +               do_set_bits(bits_1);
1192 +               cycle_delay(2);
1193 +
1194 +               bits_1 |= 1;
1195 +               do_set_bits(bits_1);
1196 +               cycle_delay(1);
1197 +
1198 +               if ( (bits_2 = do_get_bits()) & 2 ) {
1199 +                       rd_byte |= 1;
1200 +               }
1201 +               rd_byte <<= 1;
1202 +       }
1203 +
1204 +       bits_1 = 0;
1205 +       if ( bits_2 == 0 ) {
1206 +               bits_1 |= 2;
1207 +       }
1208 +       do_set_bits(bits_1);
1209 +       cycle_delay(2);
1210 +
1211 +       bits_1 |= 1;
1212 +       do_set_bits(bits_1);
1213 +       cycle_delay(3);
1214 +
1215 +       bits_1 &= 0xFE;
1216 +       do_set_bits(bits_1);
1217 +       cycle_delay(2);
1218 +
1219 +       rd_byte >>= 1;
1220 +       rd_byte &= 0xFF;
1221 +       return rd_byte;
1222 +}
1223 +
1224 +void do_set_bits(unsigned char new_bits)
1225 +{
1226 +       int reg_val;
1227 +       reg_val = read_index(0x34);
1228 +       if ( new_bits & 2 ) {
1229 +               reg_val &= 0xFFFFFFDF;
1230 +               reg_val |= 1;
1231 +       } else {
1232 +               reg_val &= 0xFFFFFFFE;
1233 +               reg_val |= 0x20;
1234 +       }
1235 +       reg_val |= 0x10;
1236 +       write_index(0x34,reg_val);
1237 +
1238 +       reg_val = read_index(0x31);
1239 +       if ( new_bits & 1 ) {
1240 +               reg_val |= 0x1000000;
1241 +       } else {
1242 +               reg_val &= 0xFEFFFFFF;
1243 +       }
1244 +       reg_val |= 0x8000000;
1245 +       write_index(0x31,reg_val);
1246 +}
1247 +
1248 +unsigned char do_get_bits(void)
1249 +{
1250 +       unsigned char bits;
1251 +       int reg_val;
1252 +
1253 +       reg_val = read_index(0x34);
1254 +       reg_val |= 0x10;
1255 +       reg_val &= 0xFFFFFFDF;
1256 +       write_index(0x34,reg_val);
1257 +
1258 +       reg_val = read_index(0x34);
1259 +       bits = 0;
1260 +       if ( reg_val & 8 ) {
1261 +               bits |= 2;
1262 +       } else {
1263 +               bits &= 0xFD;
1264 +       }
1265 +       reg_val = read_index(0x31);
1266 +       if ( reg_val & 0x1000000 ) {
1267 +               bits |= 1;      
1268 +       } else {
1269 +               bits &= 0xFE;
1270 +       }
1271 +       return bits;
1272 +}
1273 +
1274 +unsigned int read_index(unsigned char index)
1275 +{
1276 +       unsigned int addr, value;
1277 +       //  addr = pci_addr_lin + DATA_PCI_OFF + ((index & 0xFF) << 2);
1278 +       addr = pci_addr_lin + ((index & 0xFF) << 2);
1279 +       value = readl(addr);
1280 +       return value;
1281 +}
1282 +
1283 +void write_index(unsigned char index,unsigned int reg_val)
1284 +{
1285 +       unsigned int addr;
1286 +       addr = pci_addr_lin + ((index & 0xFF) << 2);
1287 +       writel(reg_val,addr);
1288 +}
1289 +
1290 +
1291 +/*
1292 + * Overrides for Emacs so that we follow Linus's tabbing style.
1293 + * ---------------------------------------------------------------------------
1294 + * Local variables:
1295 + * c-basic-offset: 8
1296 + * End:
1297 + */
1298 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_dev.c linux-2.6.8-rc4/drivers/char/lirc/lirc_dev.c
1299 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_dev.c   1970-01-01 01:00:00.000000000 +0100
1300 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_dev.c        2004-04-08 23:17:46.000000000 +0200
1301 @@ -0,0 +1,795 @@
1302 +/*
1303 + * LIRC base driver
1304 + * 
1305 + * (L) by Artur Lipowski <alipowski@interia.pl>
1306 + *
1307 + *  This program is free software; you can redistribute it and/or modify
1308 + *  it under the terms of the GNU General Public License as published by
1309 + *  the Free Software Foundation; either version 2 of the License, or
1310 + *  (at your option) any later version.
1311 + *
1312 + *  This program is distributed in the hope that it will be useful,
1313 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
1314 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1315 + *  GNU General Public License for more details.
1316 + *
1317 + *  You should have received a copy of the GNU General Public License
1318 + *  along with this program; if not, write to the Free Software
1319 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1320 + *
1321 + * $Id$
1322 + *
1323 + */
1324 +
1325 +#ifdef HAVE_CONFIG_H
1326 +# include <config.h>
1327 +#endif
1328
1329 +#include <linux/version.h>
1330 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1331 +#define LIRC_HAVE_DEVFS
1332 +#endif
1333 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
1334 +#warning "**********************************************************"
1335 +#warning "************ disabling devfs for 2.6 kernels *************"
1336 +#warning "**********************************************************"
1337 +#undef LIRC_HAVE_DEVFS
1338 +#endif
1339 +
1340 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
1341 +#error "**********************************************************"
1342 +#error " Sorry, this driver needs kernel version 2.2.18 or higher "
1343 +#error "**********************************************************"
1344 +#endif
1345 +
1346 +#include <linux/config.h>
1347 +#include <linux/module.h>
1348 +#include <linux/kernel.h>
1349 +#include <linux/sched.h>
1350 +#include <linux/errno.h>
1351 +#include <linux/ioctl.h>
1352 +#include <linux/fs.h>
1353 +#include <linux/poll.h>
1354 +#ifdef LIRC_HAVE_DEVFS
1355 +#include <linux/devfs_fs_kernel.h>
1356 +#endif
1357 +#include <linux/smp_lock.h>
1358 +#include <asm/uaccess.h>
1359 +#include <asm/semaphore.h>
1360 +#include <asm/errno.h>
1361 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
1362 +#include <linux/wrapper.h>
1363 +#endif
1364 +#define __KERNEL_SYSCALLS__
1365 +#include <linux/unistd.h>
1366 +
1367 +#include "kcompat.h"
1368 +#include <linux/lirc.h>
1369 +
1370 +#include "lirc_dev.h"
1371 +
1372 +static int debug = 0;
1373 +
1374 +MODULE_PARM(debug,"i");
1375 +
1376 +#define IRCTL_DEV_NAME    "BaseRemoteCtl"
1377 +#define SUCCESS           0
1378 +#define NOPLUG            -1
1379 +#define dprintk           if (debug) printk
1380 +
1381 +#define LOGHEAD           "lirc_dev (%s[%d]): "
1382 +
1383 +struct irctl
1384 +{
1385 +       struct lirc_plugin p;
1386 +       int open;
1387 +
1388 +       struct lirc_buffer *buf;
1389 +
1390 +       int tpid;
1391 +       struct semaphore *t_notify;
1392 +       struct semaphore *t_notify2;
1393 +       int shutdown;
1394 +       long jiffies_to_wait;
1395 +
1396 +#ifdef LIRC_HAVE_DEVFS
1397 +       devfs_handle_t devfs_handle;
1398 +#endif
1399 +};
1400 +
1401 +DECLARE_MUTEX(plugin_lock);
1402 +
1403 +static struct irctl irctls[MAX_IRCTL_DEVICES];
1404 +static struct file_operations fops;
1405 +
1406 +
1407 +/*  helper function
1408 + *  initializes the irctl structure
1409 + */
1410 +static inline void init_irctl(struct irctl *ir)
1411 +{
1412 +       memset(&ir->p, 0, sizeof(struct lirc_plugin));
1413 +       ir->p.minor = NOPLUG;
1414 +
1415 +       ir->tpid = -1;
1416 +       ir->t_notify = NULL;
1417 +       ir->t_notify2 = NULL;
1418 +       ir->shutdown = 0;
1419 +       ir->jiffies_to_wait = 0;
1420 +
1421 +       ir->open = 0;
1422 +}
1423 +
1424 +
1425 +/*  helper function
1426 + *  reads key codes from plugin and puts them into buffer
1427 + *  buffer free space is checked and locking performed
1428 + *  returns 0 on success
1429 + */
1430 +
1431 +inline static int add_to_buf(struct irctl *ir)
1432 +{
1433 +       if (lirc_buffer_full(ir->buf)) {
1434 +               dprintk(LOGHEAD "buffer overflow\n",
1435 +                       ir->p.name, ir->p.minor);
1436 +               return -EOVERFLOW;
1437 +       }
1438 +
1439 +       if(ir->p.add_to_buf) {
1440 +               int res = -ENODATA;
1441 +               int got_data = 0;
1442 +               
1443 +               /* service the device as long as it is returning
1444 +                * data and we have space
1445 +                */
1446 +               while( !lirc_buffer_full(ir->buf) )
1447 +               {
1448 +                       res = ir->p.add_to_buf( ir->p.data, ir->buf );
1449 +                       if( res == SUCCESS )
1450 +                               got_data++;
1451 +                       else
1452 +                               break;
1453 +               }
1454 +               
1455 +               if( res == -ENODEV )
1456 +               {
1457 +                       ir->shutdown = 1;
1458 +               }
1459 +               return (got_data ? SUCCESS : res);
1460 +       }
1461 +       
1462 +       return SUCCESS;
1463 +}
1464 +
1465 +/* main function of the polling thread
1466 + */
1467 +static int lirc_thread(void *irctl)
1468 +{
1469 +       struct irctl *ir = irctl;
1470 +       
1471 +       /* This thread doesn't need any user-level access,
1472 +        * so get rid of all our resources
1473 +        */
1474 +       daemonize("lirc_dev");
1475 +       
1476 +       if (ir->t_notify != NULL) {
1477 +               up(ir->t_notify);
1478 +       }
1479 +       
1480 +       dprintk(LOGHEAD "poll thread started\n", ir->p.name, ir->p.minor);
1481 +       
1482 +       do {
1483 +               if (ir->open) {
1484 +                       if (ir->jiffies_to_wait) {
1485 +                               current->state = TASK_INTERRUPTIBLE;
1486 +                               schedule_timeout(ir->jiffies_to_wait);
1487 +                       } else {
1488 +                               interruptible_sleep_on(ir->p.get_queue(ir->p.data));
1489 +                       }
1490 +                       if (ir->shutdown) {
1491 +                               break;
1492 +                       }
1493 +                       if (!add_to_buf(ir)) {
1494 +                               wake_up_interruptible(&ir->buf->wait_poll);
1495 +                       }
1496 +               } else {
1497 +                       /* if device not opened so we can sleep half a second */
1498 +                       current->state = TASK_INTERRUPTIBLE;
1499 +                       schedule_timeout(HZ/2);
1500 +               }
1501 +       } while (!ir->shutdown);
1502 +       
1503 +       if (ir->t_notify2 != NULL) {
1504 +               down(ir->t_notify2);
1505 +       }
1506 +
1507 +       ir->tpid = -1;
1508 +       if (ir->t_notify != NULL) {
1509 +               up(ir->t_notify);
1510 +       }
1511 +       
1512 +       dprintk(LOGHEAD "poll thread ended\n", ir->p.name, ir->p.minor);
1513 +       
1514 +       return 0;
1515 +}
1516 +
1517 +/*
1518 + *
1519 + */
1520 +int lirc_register_plugin(struct lirc_plugin *p)
1521 +{
1522 +       struct irctl *ir;
1523 +       int minor;
1524 +       int bytes_in_key;
1525 +#ifdef LIRC_HAVE_DEVFS
1526 +       char name[16];
1527 +#endif
1528 +       DECLARE_MUTEX_LOCKED(tn);
1529 +
1530 +       if (!p) {
1531 +               printk("lirc_dev: lirc_register_plugin:"
1532 +                      "plugin pointer must be not NULL!\n");
1533 +               return -EBADRQC;
1534 +       }
1535 +
1536 +       if (MAX_IRCTL_DEVICES <= p->minor) {
1537 +               printk("lirc_dev: lirc_register_plugin:"
1538 +                      "\" minor\" must be between 0 and %d (%d)!\n",
1539 +                      MAX_IRCTL_DEVICES-1, p->minor);
1540 +               return -EBADRQC;
1541 +       }
1542 +
1543 +       if (1 > p->code_length || (BUFLEN*8) < p->code_length) {
1544 +               printk("lirc_dev: lirc_register_plugin:"
1545 +                      "code length in bits for minor (%d) "
1546 +                      "must be less than %d!\n",
1547 +                      p->minor, BUFLEN*8);
1548 +               return -EBADRQC;
1549 +       }
1550 +
1551 +       printk("lirc_dev: lirc_register_plugin:"
1552 +              "sample_rate: %d\n",p->sample_rate);
1553 +       if (p->sample_rate) {
1554 +               if (2 > p->sample_rate || HZ < p->sample_rate) {
1555 +                       printk("lirc_dev: lirc_register_plugin:"
1556 +                              "sample_rate must be between 2 and %d!\n", HZ);
1557 +                       return -EBADRQC;
1558 +               }
1559 +               if (!p->add_to_buf) {
1560 +                       printk("lirc_dev: lirc_register_plugin:"
1561 +                              "add_to_buf cannot be NULL when "
1562 +                              "sample_rate is set\n");
1563 +                       return -EBADRQC;
1564 +               }
1565 +       } else if (!(p->fops && p->fops->read)
1566 +                  && !p->get_queue && !p->rbuf) {
1567 +               printk("lirc_dev: lirc_register_plugin:"
1568 +                      "fops->read, get_queue and rbuf "
1569 +                      "cannot all be NULL!\n");
1570 +               return -EBADRQC;
1571 +       } else if (!p->get_queue && !p->rbuf) {
1572 +               if (!(p->fops && p->fops->read && p->fops->poll) 
1573 +                   || (!p->fops->ioctl && !p->ioctl)) {
1574 +                       printk("lirc_dev: lirc_register_plugin:"
1575 +                              "neither read, poll nor ioctl can be NULL!\n");
1576 +                       return -EBADRQC;
1577 +               }
1578 +       }
1579 +
1580 +       down_interruptible(&plugin_lock);
1581 +
1582 +       minor = p->minor;
1583 +
1584 +       if (0 > minor) {
1585 +               /* find first free slot for plugin */
1586 +               for (minor=0; minor<MAX_IRCTL_DEVICES; minor++)
1587 +                       if (irctls[minor].p.minor == NOPLUG)
1588 +                               break;
1589 +               if (MAX_IRCTL_DEVICES == minor) {
1590 +                       printk("lirc_dev: lirc_register_plugin: "
1591 +                              "no free slots for plugins!\n");
1592 +                       up(&plugin_lock);
1593 +                       return -ENOMEM;
1594 +               }
1595 +       } else if (irctls[minor].p.minor != NOPLUG) {
1596 +               printk("lirc_dev: lirc_register_plugin:"
1597 +                      "minor (%d) just registered!\n", minor);
1598 +               up(&plugin_lock);
1599 +               return -EBUSY;
1600 +       }
1601 +
1602 +       ir = &irctls[minor];
1603 +
1604 +       if (p->sample_rate) {
1605 +               ir->jiffies_to_wait = HZ / p->sample_rate;
1606 +       } else {
1607 +                /* it means - wait for externeal event in task queue */
1608 +               ir->jiffies_to_wait = 0;
1609 +       } 
1610 +
1611 +       /* some safety check 8-) */
1612 +       p->name[sizeof(p->name)-1] = '\0';
1613 +
1614 +       bytes_in_key = p->code_length/8 + (p->code_length%8 ? 1 : 0);
1615 +       
1616 +       if (p->rbuf) {
1617 +               ir->buf = p->rbuf;
1618 +       } else {
1619 +               ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
1620 +               lirc_buffer_init(ir->buf, bytes_in_key, BUFLEN/bytes_in_key);
1621 +       }
1622 +
1623 +       if (p->features==0)
1624 +               p->features = (p->code_length > 8) ?
1625 +                       LIRC_CAN_REC_LIRCCODE : LIRC_CAN_REC_CODE;
1626 +
1627 +       ir->p = *p;
1628 +       ir->p.minor = minor;
1629 +
1630 +#ifdef LIRC_HAVE_DEVFS
1631 +       sprintf (name, DEV_LIRC "/%d", ir->p.minor);
1632 +       ir->devfs_handle = devfs_register(NULL, name, DEVFS_FL_DEFAULT,
1633 +                                         CONFIG_LIRC_IRCTL_DEV_MAJOR, ir->p.minor,
1634 +                                         S_IFCHR | S_IRUSR | S_IWUSR,
1635 +                                         &fops, NULL);
1636 +#endif
1637 +
1638 +       if(p->sample_rate || p->get_queue) {
1639 +               /* try to fire up polling thread */
1640 +               ir->t_notify = &tn;
1641 +               ir->tpid = kernel_thread(lirc_thread, (void*)ir, 0);
1642 +               if (ir->tpid < 0) {
1643 +                       up(&plugin_lock);
1644 +                       printk("lirc_dev: lirc_register_plugin:"
1645 +                              "cannot run poll thread for minor = %d\n",
1646 +                              p->minor);
1647 +                       return -ECHILD;
1648 +               }
1649 +               down(&tn);
1650 +               ir->t_notify = NULL;
1651 +       }
1652 +       up(&plugin_lock);
1653 +
1654 +       MOD_INC_USE_COUNT;
1655 +
1656 +       dprintk("lirc_dev: plugin %s registered at minor number = %d\n",
1657 +               ir->p.name, ir->p.minor);
1658 +
1659 +       return minor;
1660 +}
1661 +
1662 +/*
1663 + *
1664 + */
1665 +int lirc_unregister_plugin(int minor)
1666 +{
1667 +       struct irctl *ir;
1668 +       DECLARE_MUTEX_LOCKED(tn);
1669 +       DECLARE_MUTEX_LOCKED(tn2);
1670 +
1671 +       if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
1672 +               printk("lirc_dev: lirc_unregister_plugin:"
1673 +                      "\" minor\" must be between 0 and %d!\n",
1674 +                      MAX_IRCTL_DEVICES-1);
1675 +               return -EBADRQC;
1676 +       }
1677 +
1678 +       ir = &irctls[minor];
1679 +
1680 +       down_interruptible(&plugin_lock);
1681 +
1682 +       if (ir->p.minor != minor) {
1683 +               printk("lirc_dev: lirc_unregister_plugin:"
1684 +                      "minor (%d) device not registered!", minor);
1685 +               up(&plugin_lock);
1686 +               return -ENOENT;
1687 +       }
1688 +
1689 +       if (ir->open) {
1690 +               printk("lirc_dev: lirc_unregister_plugin:"
1691 +                      "plugin %s[%d] in use!", ir->p.name, ir->p.minor);
1692 +               up(&plugin_lock);
1693 +               return -EBUSY;
1694 +       }
1695 +
1696 +       /* end up polling thread */
1697 +       if (ir->tpid >= 0) {
1698 +               ir->t_notify = &tn;
1699 +               ir->t_notify2 = &tn2;
1700 +               ir->shutdown = 1;
1701 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1702 +               {
1703 +                       struct task_struct *p;
1704 +                       
1705 +                       p = find_task_by_pid(ir->tpid);
1706 +                       wake_up_process(p);
1707 +               }
1708 +#else
1709 +               /* 2.2.x does not export wake_up_process() */
1710 +               wake_up_interruptible(ir->p.get_queue(ir->p.data));
1711 +#endif
1712 +               up(&tn2);
1713 +               down(&tn);
1714 +               ir->t_notify = NULL;
1715 +               ir->t_notify2 = NULL;
1716 +       }
1717 +
1718 +       dprintk("lirc_dev: plugin %s unregistered from minor number = %d\n",
1719 +               ir->p.name, ir->p.minor);
1720 +
1721 +#ifdef LIRC_HAVE_DEVFS
1722 +       devfs_unregister(ir->devfs_handle);
1723 +#endif
1724 +       if (ir->buf != ir->p.rbuf){
1725 +               lirc_buffer_free(ir->buf);
1726 +               kfree(ir->buf);
1727 +       }
1728 +       ir->buf = NULL;
1729 +       init_irctl(ir);
1730 +       up(&plugin_lock);
1731 +
1732 +       MOD_DEC_USE_COUNT;
1733 +
1734 +       return SUCCESS;
1735 +}
1736 +
1737 +/*
1738 + *
1739 + */
1740 +static int irctl_open(struct inode *inode, struct file *file)
1741 +{
1742 +       struct irctl *ir;
1743 +       int retval;
1744 +       
1745 +       if (MINOR(inode->i_rdev) >= MAX_IRCTL_DEVICES) {
1746 +               dprintk("lirc_dev [%d]: open result = -ENODEV\n",
1747 +                       MINOR(inode->i_rdev));
1748 +               return -ENODEV;
1749 +       }
1750 +
1751 +       ir = &irctls[MINOR(inode->i_rdev)];
1752 +
1753 +       dprintk(LOGHEAD "open called\n", ir->p.name, ir->p.minor);
1754 +
1755 +       /* if the plugin has an open function use it instead */
1756 +       if(ir->p.fops && ir->p.fops->open)
1757 +               return ir->p.fops->open(inode, file);
1758 +
1759 +       down_interruptible(&plugin_lock);
1760 +
1761 +       if (ir->p.minor == NOPLUG) {
1762 +               up(&plugin_lock);
1763 +               dprintk(LOGHEAD "open result = -ENODEV\n",
1764 +                       ir->p.name, ir->p.minor);
1765 +               return -ENODEV;
1766 +       }
1767 +
1768 +       if (ir->open) {
1769 +               up(&plugin_lock);
1770 +               dprintk(LOGHEAD "open result = -EBUSY\n",
1771 +                       ir->p.name, ir->p.minor);
1772 +               return -EBUSY;
1773 +       }
1774 +
1775 +       /* there is no need for locking here because ir->open is 0 
1776 +         * and lirc_thread isn't using buffer
1777 +        * plugins which use irq's should allocate them on set_use_inc,
1778 +        * so there should be no problem with those either.
1779 +         */
1780 +       ir->buf->head = ir->buf->tail;
1781 +       ir->buf->fill = 0;
1782 +
1783 +       ++ir->open;
1784 +       retval = ir->p.set_use_inc(ir->p.data);
1785 +
1786 +       up(&plugin_lock);
1787 +
1788 +       if (retval != SUCCESS) {
1789 +               --ir->open;
1790 +               return retval;
1791 +       }
1792 +
1793 +       dprintk(LOGHEAD "open result = %d\n", ir->p.name, ir->p.minor, SUCCESS);
1794 +
1795 +       return SUCCESS;
1796 +}
1797 +
1798 +/*
1799 + *
1800 + */
1801 +static int irctl_close(struct inode *inode, struct file *file)
1802 +{
1803 +       struct irctl *ir = &irctls[MINOR(inode->i_rdev)];
1804 +
1805 +       dprintk(LOGHEAD "close called\n", ir->p.name, ir->p.minor);
1806
1807 +       /* if the plugin has a close function use it instead */
1808 +       if(ir->p.fops && ir->p.fops->release)
1809 +               return ir->p.fops->release(inode, file);
1810 +
1811 +       down_interruptible(&plugin_lock);
1812 +
1813 +       --ir->open;
1814 +       ir->p.set_use_dec(ir->p.data);
1815 +
1816 +       up(&plugin_lock);
1817 +
1818 +       return SUCCESS;
1819 +}
1820 +
1821 +/*
1822 + *
1823 + */
1824 +static unsigned int irctl_poll(struct file *file, poll_table *wait)
1825 +{
1826 +       struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)];
1827 +
1828 +       dprintk(LOGHEAD "poll called\n", ir->p.name, ir->p.minor);
1829 +
1830 +       /* if the plugin has a poll function use it instead */
1831 +       if(ir->p.fops && ir->p.fops->poll)
1832 +               return ir->p.fops->poll(file, wait);
1833 +
1834 +       poll_wait(file, &ir->buf->wait_poll, wait);
1835 +
1836 +       dprintk(LOGHEAD "poll result = %s\n",
1837 +               ir->p.name, ir->p.minor, 
1838 +               lirc_buffer_empty(ir->buf) ? "0" : "POLLIN|POLLRDNORM");
1839 +
1840 +       return lirc_buffer_empty(ir->buf) ? 0 : (POLLIN|POLLRDNORM);
1841 +}
1842 +
1843 +/*
1844 + *
1845 + */
1846 +static int irctl_ioctl(struct inode *inode, struct file *file,
1847 +                       unsigned int cmd, unsigned long arg)
1848 +{
1849 +       unsigned long mode;
1850 +       int result;
1851 +       struct irctl *ir = &irctls[MINOR(inode->i_rdev)];
1852 +
1853 +       dprintk(LOGHEAD "ioctl called (%u)\n",
1854 +               ir->p.name, ir->p.minor, cmd);
1855 +
1856 +       /* if the plugin has a ioctl function use it instead */
1857 +       if(ir->p.fops && ir->p.fops->ioctl)
1858 +               return ir->p.fops->ioctl(inode, file, cmd, arg);
1859 +
1860 +       if (ir->p.minor == NOPLUG) {
1861 +               dprintk(LOGHEAD "ioctl result = -ENODEV\n",
1862 +                       ir->p.name, ir->p.minor);
1863 +               return -ENODEV;
1864 +       }
1865 +
1866 +       /* Give the plugin a chance to handle the ioctl */
1867 +       if(ir->p.ioctl){
1868 +               result = ir->p.ioctl(inode, file, cmd, arg);
1869 +               if (result != -ENOIOCTLCMD)
1870 +                       return result;
1871 +       }
1872 +       /* The plugin can't handle cmd */
1873 +       result = SUCCESS;
1874 +
1875 +       switch(cmd)
1876 +       {
1877 +       case LIRC_GET_FEATURES:
1878 +               result = put_user(ir->p.features, (unsigned long*)arg);
1879 +               break;
1880 +       case LIRC_GET_REC_MODE:
1881 +               if(!(ir->p.features&LIRC_CAN_REC_MASK))
1882 +                       return(-ENOSYS);
1883 +               
1884 +               result = put_user(LIRC_REC2MODE
1885 +                                 (ir->p.features&LIRC_CAN_REC_MASK),
1886 +                                 (unsigned long*)arg);
1887 +               break;
1888 +       case LIRC_SET_REC_MODE:
1889 +               if(!(ir->p.features&LIRC_CAN_REC_MASK))
1890 +                       return(-ENOSYS);
1891 +
1892 +               result = get_user(mode, (unsigned long*)arg);
1893 +               if(!result && !(LIRC_MODE2REC(mode) & ir->p.features)) {
1894 +                       result = -EINVAL;
1895 +               }
1896 +               /* FIXME: We should actually set the mode somehow 
1897 +                * but for now, lirc_serial doesn't support mode changin
1898 +                * eighter */
1899 +               break;
1900 +       case LIRC_GET_LENGTH:
1901 +               result = put_user((unsigned long)ir->p.code_length, 
1902 +                                 (unsigned long *)arg);
1903 +               break;
1904 +       default:
1905 +               result = -ENOIOCTLCMD;
1906 +       }
1907 +
1908 +       dprintk(LOGHEAD "ioctl result = %d\n",
1909 +               ir->p.name, ir->p.minor, result);
1910 +
1911 +       return result;
1912 +}
1913 +
1914 +/*
1915 + *
1916 + */
1917 +static ssize_t irctl_read(struct file *file,
1918 +                         char *buffer,   
1919 +                         size_t length, 
1920 +                         loff_t *ppos)     
1921 +{
1922 +       struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)];
1923 +       unsigned char buf[ir->buf->chunk_size];
1924 +       int ret=0, written=0;
1925 +       DECLARE_WAITQUEUE(wait, current);
1926 +
1927 +       dprintk(LOGHEAD "read called\n", ir->p.name, ir->p.minor);
1928 +
1929 +       /* if the plugin has a specific read function use it instead */
1930 +       if(ir->p.fops && ir->p.fops->read)
1931 +               return ir->p.fops->read(file, buffer, length, ppos);
1932 +
1933 +       if (length % ir->buf->chunk_size) {
1934 +               dprintk(LOGHEAD "read result = -EINVAL\n",
1935 +                       ir->p.name, ir->p.minor);
1936 +               return -EINVAL;
1937 +       }
1938 +
1939 +       /* we add ourselves to the task queue before buffer check 
1940 +         * to avoid losing scan code (in case when queue is awaken somewhere 
1941 +        * beetwen while condition checking and scheduling)
1942 +        */
1943 +       add_wait_queue(&ir->buf->wait_poll, &wait);
1944 +       current->state = TASK_INTERRUPTIBLE;
1945 +
1946 +       /* while we did't provide 'length' bytes, device is opened in blocking
1947 +        * mode and 'copy_to_user' is happy, wait for data.
1948 +        */
1949 +       while (written < length && ret == 0) { 
1950 +               if (lirc_buffer_empty(ir->buf)) {
1951 +                       /* According to the read(2) man page, 'written' can be
1952 +                        * returned as less than 'length', instead of blocking
1953 +                        * again, returning -EWOULDBLOCK, or returning
1954 +                        * -ERESTARTSYS */
1955 +                       if (written) break;
1956 +                       if (file->f_flags & O_NONBLOCK) {
1957 +                               dprintk(LOGHEAD "read result = -EWOULDBLOCK\n", 
1958 +                                               ir->p.name, ir->p.minor);
1959 +                               remove_wait_queue(&ir->buf->wait_poll, &wait);
1960 +                               current->state = TASK_RUNNING;
1961 +                               return -EWOULDBLOCK;
1962 +                       }
1963 +                       if (signal_pending(current)) {
1964 +                               dprintk(LOGHEAD "read result = -ERESTARTSYS\n", 
1965 +                                               ir->p.name, ir->p.minor);
1966 +                               remove_wait_queue(&ir->buf->wait_poll, &wait);
1967 +                               current->state = TASK_RUNNING;
1968 +                               return -ERESTARTSYS;
1969 +                       }
1970 +                       schedule();
1971 +                       current->state = TASK_INTERRUPTIBLE;
1972 +               } else {
1973 +                       lirc_buffer_read_1(ir->buf, buf);
1974 +                       ret = copy_to_user((void *)buffer+written, buf,
1975 +                                          ir->buf->chunk_size);
1976 +                       written += ir->buf->chunk_size;
1977 +               }
1978 +       }
1979 +
1980 +       remove_wait_queue(&ir->buf->wait_poll, &wait);
1981 +       current->state = TASK_RUNNING;
1982 +
1983 +       dprintk(LOGHEAD "read result = %s (%d)\n",
1984 +               ir->p.name, ir->p.minor, ret ? "-EFAULT" : "OK", ret);
1985 +
1986 +       return ret ? -EFAULT : written;
1987 +}
1988 +
1989 +static ssize_t irctl_write(struct file *file, const char *buffer,
1990 +                          size_t length, loff_t * ppos)
1991 +{
1992 +       struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)];
1993 +
1994 +       dprintk(LOGHEAD "read called\n", ir->p.name, ir->p.minor);
1995 +
1996 +       /* if the plugin has a specific read function use it instead */
1997 +       if(ir->p.fops && ir->p.fops->write)
1998 +               return ir->p.fops->write(file, buffer, length, ppos);
1999 +
2000 +       return -EINVAL;
2001 +}
2002 +
2003 +
2004 +static struct file_operations fops = {
2005 +       read:    irctl_read, 
2006 +       write:   irctl_write,
2007 +       poll:    irctl_poll,
2008 +       ioctl:   irctl_ioctl,
2009 +       open:    irctl_open,
2010 +       release: irctl_close
2011 +};
2012 +
2013 +
2014 +
2015 +EXPORT_SYMBOL(lirc_register_plugin);
2016 +EXPORT_SYMBOL(lirc_unregister_plugin);
2017 +
2018 +/*
2019 + *
2020 + */
2021 +int lirc_dev_init(void)
2022 +{      
2023 +       int i;
2024 +
2025 +       for (i=0; i < MAX_IRCTL_DEVICES; ++i) {
2026 +               init_irctl(&irctls[i]); 
2027 +       }
2028 +
2029 +#ifndef LIRC_HAVE_DEVFS
2030 +       i = register_chrdev(CONFIG_LIRC_IRCTL_DEV_MAJOR,
2031 +#else
2032 +       i = devfs_register_chrdev(CONFIG_LIRC_IRCTL_DEV_MAJOR,
2033 +#endif
2034 +                                  IRCTL_DEV_NAME,
2035 +                                  &fops);
2036 +       
2037 +       if (i < 0) {
2038 +               printk ("lirc_dev: device registration failed with %d\n", i);
2039 +               return i;
2040 +       }
2041 +       
2042 +       printk("lirc_dev: IR Remote Control driver registered, at major %d \n", 
2043 +              CONFIG_LIRC_IRCTL_DEV_MAJOR);
2044 +
2045 +       return SUCCESS;
2046 +}
2047 +
2048 +/* ---------------------------------------------------------------------- */
2049 +
2050 +/* For now dont try to use it as a static version !  */
2051 +
2052 +#ifdef MODULE
2053 +
2054 +MODULE_DESCRIPTION("LIRC base driver module");
2055 +MODULE_AUTHOR("Artur Lipowski");
2056 +#ifdef MODULE_LICENSE
2057 +MODULE_LICENSE("GPL");
2058 +#endif
2059 +
2060 +/*
2061 + *
2062 + */
2063 +int init_module(void)
2064 +{
2065 +       return lirc_dev_init();
2066 +}
2067 +
2068 +/*
2069 + *
2070 + */
2071 +void cleanup_module(void)
2072 +{
2073 +       int ret;
2074 +       
2075 +#ifndef LIRC_HAVE_DEVFS
2076 +       ret = unregister_chrdev(CONFIG_LIRC_IRCTL_DEV_MAJOR, IRCTL_DEV_NAME);
2077 +#else
2078 +       ret = devfs_unregister_chrdev(CONFIG_LIRC_IRCTL_DEV_MAJOR, IRCTL_DEV_NAME);
2079 +#endif
2080
2081 +       if (0 > ret){
2082 +               printk("lirc_dev: error in module_unregister_chrdev: %d\n",
2083 +                      ret);
2084 +       } else {
2085 +               dprintk("lirc_dev: module successfully unloaded\n");
2086 +       }
2087 +}
2088 +#endif
2089 +
2090 +/*
2091 + * Overrides for Emacs so that we follow Linus's tabbing style.
2092 + * ---------------------------------------------------------------------------
2093 + * Local variables:
2094 + * c-basic-offset: 8
2095 + * End:
2096 + */
2097 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_dev.h linux-2.6.8-rc4/drivers/char/lirc/lirc_dev.h
2098 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_dev.h   1970-01-01 01:00:00.000000000 +0100
2099 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_dev.h        2004-04-09 17:33:40.000000000 +0200
2100 @@ -0,0 +1,238 @@
2101 +/*
2102 + * LIRC base driver
2103 + * 
2104 + * (L) by Artur Lipowski <alipowski@interia.pl>
2105 + *        This code is licensed under GNU GPL
2106 + *
2107 + * $Id$
2108 + *
2109 + */
2110 +
2111 +#ifndef _LINUX_LIRC_DEV_H
2112 +#define _LINUX_LIRC_DEV_H
2113 +
2114 +#define MAX_IRCTL_DEVICES 2
2115 +#define BUFLEN            16
2116 +
2117 +//#define LIRC_BUFF_POWER_OF_2
2118 +#ifdef LIRC_BUFF_POWER_OF_2
2119 +#define mod(n, div) ((n) & ((div) -1))
2120 +#else
2121 +#define mod(n, div) ((n) % (div))
2122 +#endif
2123 +#include <linux/slab.h>
2124 +#include <linux/fs.h>
2125 +struct lirc_buffer
2126 +{
2127 +        wait_queue_head_t wait_poll;
2128 +       spinlock_t lock;
2129 +
2130 +       unsigned char *data;
2131 +       unsigned int chunk_size;
2132 +       unsigned int size; /* in chunks */
2133 +       unsigned int fill; /* in chunks */
2134 +       int head, tail;    /* in chunks */
2135 +       /* Using chunks instead of bytes pretends to simplify boundary checking 
2136 +        * And should allow for some performance fine tunning later */
2137 +};
2138 +static inline int lirc_buffer_init(struct lirc_buffer *buf,
2139 +                                   unsigned int chunk_size,
2140 +                                   unsigned int size)
2141 +{
2142 +       /* Adjusting size to the next power of 2 would allow for
2143 +        * inconditional LIRC_BUFF_POWER_OF_2 optimization */
2144 +       init_waitqueue_head(&buf->wait_poll);
2145 +       spin_lock_init(&buf->lock);
2146 +       buf->head = buf->tail = buf->fill = 0;
2147 +       buf->chunk_size = chunk_size;
2148 +       buf->size = size;
2149 +       buf->data = kmalloc(size*chunk_size, GFP_KERNEL);
2150 +       if (buf->data == NULL)
2151 +               return -1;
2152 +       memset(buf->data, 0, size*chunk_size);
2153 +       return 0;
2154 +}
2155 +static inline void lirc_buffer_free(struct lirc_buffer *buf)
2156 +{
2157 +       kfree(buf->data);
2158 +       buf->data = NULL;
2159 +       buf->head = buf->tail = buf->fill = 0;
2160 +       buf->chunk_size = 0;
2161 +       buf->size = 0;
2162 +}
2163 +static inline int  lirc_buffer_full(struct lirc_buffer *buf)
2164 +{
2165 +       return (buf->fill >= buf->size);
2166 +}
2167 +static inline int  lirc_buffer_empty(struct lirc_buffer *buf)
2168 +{
2169 +       return !(buf->fill);
2170 +}
2171 +static inline int  lirc_buffer_available(struct lirc_buffer *buf)
2172 +{
2173 +    return (buf->size - buf->fill);
2174 +}
2175 +extern inline void lirc_buffer_lock(struct lirc_buffer *buf, unsigned long *flags)
2176 +{
2177 +       spin_lock_irqsave(&buf->lock, *flags);
2178 +}
2179 +extern inline void lirc_buffer_unlock(struct lirc_buffer *buf, unsigned long *flags)
2180 +{
2181 +       spin_unlock_irqrestore(&buf->lock, *flags);
2182 +}
2183 +static inline void _lirc_buffer_remove_1(struct lirc_buffer *buf)
2184 +{
2185 +       buf->head = mod(buf->head+1, buf->size);
2186 +       buf->fill -= 1;
2187 +}
2188 +static inline void lirc_buffer_remove_1(struct lirc_buffer *buf)
2189 +{
2190 +       unsigned long flags;
2191 +       lirc_buffer_lock(buf, &flags);
2192 +       _lirc_buffer_remove_1(buf);
2193 +       lirc_buffer_unlock(buf, &flags);
2194 +}
2195 +static inline void _lirc_buffer_read_1(struct lirc_buffer *buf,
2196 +                                    unsigned char *dest)
2197 +{
2198 +       memcpy(dest, &buf->data[buf->head*buf->chunk_size], buf->chunk_size);
2199 +       buf->head = mod(buf->head+1, buf->size);
2200 +       buf->fill -= 1;
2201 +}
2202 +static inline void lirc_buffer_read_1(struct lirc_buffer *buf,
2203 +                                     unsigned char *dest)
2204 +{
2205 +       unsigned long flags;
2206 +       lirc_buffer_lock(buf, &flags);
2207 +       _lirc_buffer_read_1(buf, dest);
2208 +       lirc_buffer_unlock(buf, &flags);
2209 +}
2210 +static inline void _lirc_buffer_write_1(struct lirc_buffer *buf,
2211 +                                     unsigned char *orig)
2212 +{
2213 +       memcpy(&buf->data[buf->tail*buf->chunk_size], orig, buf->chunk_size);
2214 +       buf->tail = mod(buf->tail+1, buf->size);
2215 +       buf->fill++;
2216 +}
2217 +static inline void lirc_buffer_write_1(struct lirc_buffer *buf,
2218 +                                      unsigned char *orig)
2219 +{
2220 +       unsigned long flags;
2221 +       lirc_buffer_lock(buf, &flags);
2222 +       _lirc_buffer_write_1(buf, orig);
2223 +       lirc_buffer_unlock(buf, &flags);
2224 +}
2225 +static inline void _lirc_buffer_write_n(struct lirc_buffer *buf,
2226 +                                       unsigned char* orig, int count)
2227 +{
2228 +       memcpy(&buf->data[buf->tail*buf->chunk_size], orig,
2229 +              count*buf->chunk_size);
2230 +       buf->tail = mod(buf->tail+count, buf->size);
2231 +       buf->fill += count;
2232 +}
2233 +static inline void lirc_buffer_write_n(struct lirc_buffer *buf,
2234 +                                      unsigned char* orig, int count)
2235 +{
2236 +       unsigned long flags;
2237 +       int space1;
2238 +       lirc_buffer_lock(buf,&flags);
2239 +       if( buf->head > buf->tail ) space1 = buf->head - buf->tail;
2240 +       else space1 = buf->size - buf->tail;
2241 +       
2242 +       if( count > space1 )
2243 +       {
2244 +               _lirc_buffer_write_n(buf, orig, space1);
2245 +               _lirc_buffer_write_n(buf, orig+(space1*buf->chunk_size),
2246 +                                    count-space1);
2247 +       }
2248 +       else
2249 +       {
2250 +               _lirc_buffer_write_n(buf, orig, count);
2251 +       }
2252 +       lirc_buffer_unlock(buf, &flags);
2253 +}
2254 +
2255 +struct lirc_plugin
2256 +{
2257 +       char name[40];
2258 +       int minor;
2259 +       int code_length;
2260 +       int sample_rate;
2261 +       unsigned long features;
2262 +       void* data;
2263 +       int (*add_to_buf) (void* data, struct lirc_buffer* buf);
2264 +       wait_queue_head_t* (*get_queue) (void* data);
2265 +       struct lirc_buffer *rbuf;
2266 +       int (*set_use_inc) (void* data);
2267 +       void (*set_use_dec) (void* data);
2268 +       int (*ioctl) (struct inode *,struct file *,unsigned int,
2269 +                     unsigned long);
2270 +       struct file_operations *fops;
2271 +};
2272 +/* name:
2273 + * this string will be used for logs
2274 + *
2275 + * minor:
2276 + * indicates minor device (/dev/lirc) number for registered plugin
2277 + * if caller fills it with negative value, then the first free minor 
2278 + * number will be used (if available)
2279 + *
2280 + * code_length:
2281 + * length of the remote control key code expressed in bits
2282 + *
2283 + * sample_rate:
2284 + * sample_rate equal to 0 means that no polling will be performed and
2285 + * add_to_buf will be triggered by external events (through task queue
2286 + * returned by get_queue)
2287 + *
2288 + * data:
2289 + * it may point to any plugin data and this pointer will be passed to
2290 + * all callback functions
2291 + *
2292 + * add_to_buf:
2293 + * add_to_buf will be called after specified period of the time or
2294 + * triggered by the external event, this behavior depends on value of
2295 + * the sample_rate this function will be called in user context. This
2296 + * routine should return 0 if data was added to the buffer and
2297 + * -ENODATA if none was available. This should add some number of bits
2298 + * evenly divisible by code_length to the buffer
2299 + *
2300 + * get_queue:
2301 + * this callback should return a pointer to the task queue which will
2302 + * be used for external event waiting
2303 + *
2304 + * rbuf:
2305 + * if not NULL, it will be used as a read buffer, you will have to
2306 + * write to the buffer by other means, like irq's (see also
2307 + * lirc_serial.c).
2308 + *
2309 + * set_use_inc:
2310 + * set_use_inc will be called after device is opened
2311 + *
2312 + * set_use_dec:
2313 + * set_use_dec will be called after device is closed
2314 + *
2315 + * ioctl:
2316 + * Some ioctl's can be directly handled by lirc_dev but will be
2317 + * forwared here if not NULL and only handled if it returns
2318 + * -ENOIOCTLCMD (see also lirc_serial.c).
2319 + *
2320 + * fops:
2321 + * file_operations for drivers which don't fit the current plugin model.
2322 + */
2323 +
2324 +
2325 +/* following functions can be called ONLY from user context
2326 + *
2327 + * returns negative value on error or minor number 
2328 + * of the registered device if success
2329 + * contens of the structure pointed by p is copied
2330 + */
2331 +extern int lirc_register_plugin(struct lirc_plugin *p);
2332 +
2333 +/* returns negative value on error or 0 if success
2334 +*/
2335 +extern int lirc_unregister_plugin(int minor);
2336 +
2337 +
2338 +#endif
2339 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_gpio.c linux-2.6.8-rc4/drivers/char/lirc/lirc_gpio.c
2340 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_gpio.c  1970-01-01 01:00:00.000000000 +0100
2341 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_gpio.c       2004-04-27 08:08:24.000000000 +0200
2342 @@ -0,0 +1,572 @@
2343 +/*
2344 + * Remote control driver for the TV-card
2345 + * key codes are obtained from GPIO port
2346 + * 
2347 + * (L) by Artur Lipowski <alipowski@interia.pl>
2348 + *     patch for the AverMedia by Santiago Garcia Mantinan <manty@i.am>
2349 + *                            and Christoph Bartelmus <lirc@bartelmus.de>
2350 + *     patch for the BestBuy by Miguel Angel Alvarez <maacruz@navegalia.com>
2351 + *     patch for the Winfast TV2000 by Juan Toledo
2352 + *     <toledo@users.sourceforge.net>
2353 + *     patch for the I-O Data GV-BCTV5/PCI by Jens C. Rasmussen
2354 + *     <jens.rasmussen@ieee.org>
2355 + *
2356 + *  This program is free software; you can redistribute it and/or modify
2357 + *  it under the terms of the GNU General Public License as published by
2358 + *  the Free Software Foundation; either version 2 of the License, or
2359 + *  (at your option) any later version.
2360 + *
2361 + *  This program is distributed in the hope that it will be useful,
2362 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
2363 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2364 + *  GNU General Public License for more details.
2365 + *
2366 + *  You should have received a copy of the GNU General Public License
2367 + *  along with this program; if not, write to the Free Software
2368 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
2369 + *
2370 + * $Id$
2371 + *
2372 + */
2373 +
2374 +#include <linux/version.h>
2375 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 4)
2376 +#error "*******************************************************"
2377 +#error "Sorry, this driver needs kernel version 2.2.4 or higher"
2378 +#error "*******************************************************"
2379 +#endif
2380 +
2381 +#include <linux/module.h>
2382 +#include <linux/kmod.h>
2383 +#include <linux/sched.h>
2384 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
2385 +#include <linux/wrapper.h>
2386 +#endif
2387 +#include <linux/errno.h>
2388 +
2389 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
2390 +#include "../drivers/char/bttv.h"
2391 +#include "../drivers/char/bttvp.h"
2392 +#else
2393 +#include "../drivers/media/video/bttv.h"
2394 +#include "../drivers/media/video/bttvp.h"
2395 +#endif
2396 +
2397 +#if BTTV_VERSION_CODE < KERNEL_VERSION(0,7,45)
2398 +#error "*******************************************************"
2399 +#error " Sorry, this driver needs bttv version 0.7.45 or       "
2400 +#error " higher. If you are using the bttv package, copy it to "
2401 +#error " the kernel                                            "
2402 +#error "*******************************************************"
2403 +#endif
2404 +
2405 +#include "kcompat.h"
2406 +#include "lirc_dev.h"
2407 +
2408 +static int debug = 0;
2409 +static int card = 0;
2410 +static int minor = -1;
2411 +static int bttv_id = BTTV_UNKNOWN;
2412 +static unsigned long gpio_mask = 0;
2413 +static unsigned long gpio_enable = 0;
2414 +static unsigned long gpio_lock_mask = 0;
2415 +static unsigned long gpio_xor_mask = 0;
2416 +static unsigned int soft_gap = 0;
2417 +static unsigned char sample_rate = 10;
2418 +
2419 +MODULE_PARM(debug,"i");
2420 +MODULE_PARM(card,"i");
2421 +MODULE_PARM(minor,"i");
2422 +MODULE_PARM(gpio_mask,"l");
2423 +MODULE_PARM(gpio_lock_mask,"l");
2424 +MODULE_PARM(gpio_xor_mask,"l");
2425 +MODULE_PARM(soft_gap,"i");
2426 +MODULE_PARM(sample_rate,"b");
2427 +MODULE_PARM(bttv_id,"i");
2428 +
2429 +#undef dprintk
2430 +#define dprintk  if (debug) printk
2431 +
2432 +struct rcv_info {
2433 +       int bttv_id;
2434 +       int card_id;
2435 +       unsigned long gpio_mask;
2436 +       unsigned long gpio_enable;
2437 +       unsigned long gpio_lock_mask;
2438 +       unsigned long gpio_xor_mask;
2439 +       unsigned int soft_gap;
2440 +       unsigned char sample_rate;
2441 +       unsigned char code_length;
2442 +};
2443 +
2444 +static struct rcv_info rcv_infos[] = {
2445 +       {BTTV_UNKNOWN,                0,          0,          0,         0,          0,   0,  1,  0},
2446 +       {BTTV_PXELVWPLTVPAK,          0, 0x00003e00,          0, 0x0010000,          0,   0, 15, 32},
2447 +       {BTTV_PXELVWPLTVPRO,          0, 0x00001f00,          0, 0x0008000,          0, 500, 12, 32},
2448 +       {BTTV_PV_BT878P_9B,           0, 0x00001f00,          0, 0x0008000,          0, 500, 12, 32},
2449 +       {BTTV_PV_BT878P_PLUS,         0, 0x00001f00,          0, 0x0008000,          0, 500, 12, 32},
2450 +       {BTTV_AVERMEDIA,              0, 0x00f88000,          0, 0x0010000, 0x00010000,   0, 10, 32},
2451 +       {BTTV_AVPHONE98,     0x00011461, 0x003b8000, 0x00004000, 0x0800000, 0x00800000,   0, 10,  0}, /*mapped to Capture98*/
2452 +       {BTTV_AVERMEDIA98,   0x00021461, 0x003b8000, 0x00004000, 0x0800000, 0x00800000,   0, 10,  0}, /*mapped to Capture98*/
2453 +       {BTTV_AVPHONE98,     0x00031461, 0x00f88000,          0, 0x0010000, 0x00010000,   0, 10, 32}, /*mapped to Phone98*/
2454 +       /* is this one correct? */
2455 +       {BTTV_AVERMEDIA98,   0x00041461, 0x00f88000,          0, 0x0010000, 0x00010000,   0, 10, 32}, /*mapped to Phone98*/
2456 +       /* work-around for VDOMATE */
2457 +       {BTTV_AVERMEDIA98,   0x03001461, 0x00f88000,          0, 0x0010000, 0x00010000,   0, 10, 32}, /*mapped to Phone98*/
2458 +       /* reported by Danijel Korzinek, AVerTV GOw/FM */
2459 +       {BTTV_AVERMEDIA98,   0x00000000, 0x00f88000,          0, 0x0010000, 0x00010000,   0, 10, 32}, /*mapped to Phone98*/
2460 +       {BTTV_CHRONOS_VS2,            0, 0x000000f8,          0, 0x0000100,          0,   0, 20,  0},
2461 +       /* CPH031 and CPH033 cards (?) */
2462 +       /* MIRO was just a work-around */
2463 +       {BTTV_MIRO,                   0, 0x00001f00,          0, 0x0004000,          0,   0, 10, 32},
2464 +       {BTTV_DYNALINK,               0, 0x00001f00,          0, 0x0004000,          0,   0, 10, 32},
2465 +       {BTTV_WINVIEW_601,            0, 0x00001f00,          0, 0x0004000,          0,   0,  0, 32},
2466 +#ifdef BTTV_KWORLD
2467 +       {BTTV_KWORLD,                 0, 0x00007f00,          0, 0x0004000,          0,   0, 12, 32},
2468 +#endif
2469 +       /* just a guess */
2470 +       {BTTV_MAGICTVIEW061,          0, 0x0028e000,          0, 0x0020000,          0,   0, 20, 32},
2471 +       {BTTV_MAGICTVIEW063,          0, 0x0028e000,          0, 0x0020000,          0,   0, 20, 32},
2472 +       {BTTV_PHOEBE_TVMAS,           0, 0x0028e000,          0, 0x0020000,          0,   0, 20, 32},
2473 +#ifdef BTTV_BESTBUY_EASYTV2
2474 +        {BTTV_BESTBUY_EASYTV,         0, 0x00007F00,          0, 0x0004000,          0,   0, 10,  8},
2475 +        {BTTV_BESTBUY_EASYTV2,        0, 0x00007F00,          0, 0x0008000,          0,   0, 10,  8},
2476 +#endif
2477 +       /* lock_mask probably also 0x100, or maybe it is 0x0 for all others !?! */
2478 +       {BTTV_FLYVIDEO,               0, 0x000000f8,          0,         0,          0,   0,  0, 42},
2479 +       {BTTV_FLYVIDEO_98,            0, 0x000000f8,          0, 0x0000100,          0,   0,  0, 42},
2480 +       {BTTV_TYPHOON_TVIEW,          0, 0x000000f8,          0, 0x0000100,          0,   0,  0, 42},
2481 +#ifdef BTTV_FLYVIDEO_98FM
2482 +       /* smorar@alfonzo.smuts.uct.ac.za */
2483 +       {BTTV_FLYVIDEO_98FM,          0, 0x000000f8,          0, 0x0000100,          0,   0,  0, 42},
2484 +#endif
2485 +       /* The Leadtek WinFast TV 2000 XP card (id 0x6606107d) uses an
2486 +        * extra gpio bit compared to the original TV 2000 card (id
2487 +        * 0x217d6606); as the bttv-0.7.100 driver does not
2488 +        * distinguish between the two cards, we enable the extra bit
2489 +        * based on the card id: */
2490 +       {BTTV_WINFAST2000,   0x6606107d, 0x000008f8,          0, 0x0000100,          0,   0,  0, 32},
2491 +       /* default: */
2492 +       {BTTV_WINFAST2000,            0, 0x000000f8,          0, 0x0000100,          0,   0,  0, 32},
2493 +#ifdef BTTV_GVBCTV5PCI
2494 +       {BTTV_GVBCTV5PCI,             0, 0x00f0b000,          0,         0,          0,   0, 20,  8},
2495 +#endif
2496 +};
2497 +
2498 +static unsigned char code_length = 0;
2499 +static unsigned char code_bytes = 1;
2500 +
2501 +#define MAX_BYTES 8
2502 +
2503 +#define SUCCESS 0
2504 +#define LOGHEAD "lirc_gpio (%d): "
2505 +
2506 +/* how many bits GPIO value can be shifted right before processing
2507 + * it is computed from the value of gpio_mask_parameter
2508 + */
2509 +static unsigned char gpio_pre_shift = 0;
2510 +
2511 +
2512 +static inline int reverse(int data, int bits)
2513 +{
2514 +       int i;
2515 +       int c;
2516 +       
2517 +       for (c=0,i=0; i<bits; i++) {
2518 +               c |= (((data & (1<<i)) ? 1:0)) << (bits-1-i);
2519 +       }
2520 +
2521 +       return c;
2522 +}
2523 +
2524 +static int build_key(unsigned long gpio_val, unsigned char codes[MAX_BYTES])
2525 +{
2526 +       unsigned long mask = gpio_mask;
2527 +       unsigned char shift = 0;
2528 +
2529 +       dprintk(LOGHEAD "gpio_val is %lx\n",card,(unsigned long) gpio_val);
2530 +       
2531 +       gpio_val ^= gpio_xor_mask;
2532 +       
2533 +       if (gpio_lock_mask && (gpio_val & gpio_lock_mask)) {
2534 +               return -EBUSY;
2535 +       }
2536 +       
2537 +       switch (bttv_id)
2538 +       {
2539 +       case BTTV_AVERMEDIA98:
2540 +               if (bttv_write_gpio(card, gpio_enable, gpio_enable)) {
2541 +                       dprintk(LOGHEAD "cannot write to GPIO\n", card);
2542 +                       return -EIO;
2543 +               }
2544 +               if (bttv_read_gpio(card, &gpio_val)) {
2545 +                       dprintk(LOGHEAD "cannot read GPIO\n", card);
2546 +                       return -EIO;
2547 +               }
2548 +               if (bttv_write_gpio(card, gpio_enable, 0)) {
2549 +                       dprintk(LOGHEAD "cannot write to GPIO\n", card);
2550 +                       return -EIO;
2551 +               }
2552 +               break;
2553 +       default:
2554 +               break;
2555 +       }
2556 +       
2557 +       /* extract bits from "raw" GPIO value using gpio_mask */
2558 +       codes[0] = 0;
2559 +       gpio_val >>= gpio_pre_shift;
2560 +       while (mask) {
2561 +               if (mask & 1u) {
2562 +                       codes[0] |= (gpio_val & 1u) << shift++;
2563 +               }
2564 +               mask >>= 1;
2565 +               gpio_val >>= 1;
2566 +       }
2567 +       
2568 +       dprintk(LOGHEAD "code is %lx\n",card,(unsigned long) codes[0]);
2569 +       switch (bttv_id)
2570 +       {
2571 +       case BTTV_AVERMEDIA:
2572 +               codes[2] = (codes[0]<<2)&0xff;
2573 +               codes[3] = (~codes[2])&0xff;
2574 +               codes[0] = 0x02;
2575 +               codes[1] = 0xFD;
2576 +               break;
2577 +       case BTTV_AVPHONE98:
2578 +               codes[2] = ((codes[0]&(~0x1))<<2)&0xff;
2579 +               codes[3] = (~codes[2])&0xff;
2580 +               if (codes[0]&0x1) {
2581 +                       codes[0] = 0xc0;
2582 +                       codes[1] = 0x3f;
2583 +               } else {
2584 +                       codes[0] = 0x40;
2585 +                       codes[1] = 0xbf;
2586 +               }
2587 +               break;
2588 +       case BTTV_AVERMEDIA98:
2589 +               break;
2590 +       case BTTV_FLYVIDEO:
2591 +       case BTTV_FLYVIDEO_98:
2592 +       case BTTV_TYPHOON_TVIEW:
2593 +#ifdef BTTV_FLYVIDEO_98FM
2594 +       case BTTV_FLYVIDEO_98FM:
2595 +#endif
2596 +               codes[4]=codes[0]<<3;
2597 +               codes[5]=((~codes[4])&0xff);
2598 +               
2599 +               codes[0]=0x00;
2600 +               codes[1]=0x1A;
2601 +               codes[2]=0x1F;
2602 +               codes[3]=0x2F;
2603 +               break;
2604 +        case BTTV_MAGICTVIEW061:
2605 +        case BTTV_MAGICTVIEW063:
2606 +       case BTTV_PHOEBE_TVMAS:
2607 +               codes[0] = (codes[0]&0x01)
2608 +                       |((codes[0]&0x02)<<1)
2609 +                       |((codes[0]&0x04)<<2)
2610 +                       |((codes[0]&0x08)>>2)
2611 +                       |((codes[0]&0x10)>>1);
2612 +               /* FALLTHROUGH */
2613 +       case BTTV_MIRO:
2614 +       case BTTV_DYNALINK:
2615 +       case BTTV_PXELVWPLTVPAK:
2616 +       case BTTV_PXELVWPLTVPRO:
2617 +       case BTTV_PV_BT878P_9B:
2618 +       case BTTV_PV_BT878P_PLUS:
2619 +#ifdef BTTV_KWORLD
2620 +       case BTTV_KWORLD:
2621 +#endif
2622 +               codes[2] = reverse(codes[0],8);
2623 +               codes[3] = (~codes[2])&0xff;
2624 +               codes[0] = 0x61;
2625 +               codes[1] = 0xD6;
2626 +               break;
2627 +#if 0
2628 +               /* derived from e-tech config file */
2629 +               /* 26 + 16 bits */
2630 +               /* won't apply it until it's confirmed with a fly98 */
2631 +       case BTTV_FLYVIDEO_98:
2632 +       case BTTV_FLYVIDEO_98FM:
2633 +               codes[4]=codes[0]<<3;
2634 +               codes[5]=(~codes[4])&0xff;
2635 +               
2636 +               codes[0]=0x00;
2637 +               codes[1]=0x1A;
2638 +               codes[2]=0x1F;
2639 +               codes[3]=0x2F;
2640 +               break;
2641 +#endif
2642 +       case BTTV_WINFAST2000:
2643 +               /* shift extra bit */
2644 +               codes[0] = (codes[0]&0x1f) | ((codes[0]&0x20) << 1);
2645 +       case BTTV_WINVIEW_601:
2646 +               codes[2] = reverse(codes[0],8);
2647 +               codes[3] = (~codes[2])&0xff;
2648 +               codes[0] = 0xC0;
2649 +               codes[1] = 0x3F;
2650 +               break;
2651 +       default:
2652 +               break;
2653 +       }
2654 +
2655 +       return SUCCESS;
2656 +}
2657 +
2658 +/* add_to_buf - copy a code to the buffer */
2659 +static int add_to_buf(void* data, struct lirc_buffer* buf)
2660 +{
2661 +       static unsigned long next_time = 0;
2662 +       static unsigned char prev_codes[MAX_BYTES];
2663 +       unsigned long code = 0;
2664 +       unsigned char cur_codes[MAX_BYTES];
2665 +    
2666 +       if (bttv_read_gpio(card, &code)) {
2667 +               dprintk(LOGHEAD "cannot read GPIO\n", card);
2668 +               return -EIO;
2669 +       }
2670 +       
2671 +       if (build_key(code, cur_codes)) {
2672 +               return -EFAULT;
2673 +       }
2674 +       
2675 +       if (soft_gap) {
2676 +               if (!memcmp(prev_codes, cur_codes, code_bytes) &&
2677 +                       jiffies < next_time) {
2678 +                       return -EAGAIN;
2679 +               }
2680 +               next_time = jiffies + soft_gap;
2681 +       }
2682 +       memcpy( prev_codes, cur_codes, code_bytes );
2683 +               
2684 +       lirc_buffer_write_1( buf, cur_codes );
2685 +               
2686 +       return SUCCESS;
2687 +}
2688 +
2689 +static int set_use_inc(void* data)
2690 +{
2691 +       MOD_INC_USE_COUNT;
2692 +       return 0;
2693 +}
2694 +
2695 +static void set_use_dec(void* data)
2696 +{
2697 +       MOD_DEC_USE_COUNT;
2698 +}
2699 +
2700 +static wait_queue_head_t* get_queue(void* data)
2701 +{
2702 +       return bttv_get_gpio_queue(card);
2703 +}
2704 +
2705 +static struct lirc_plugin plugin = {
2706 +       .name           = "lirc_gpio  ",
2707 +       .add_to_buf     = add_to_buf,
2708 +       .get_queue      = get_queue,
2709 +       .set_use_inc    = set_use_inc,
2710 +       .set_use_dec    = set_use_dec,
2711 +};
2712 +
2713 +/*
2714 + *
2715 + */
2716 +int gpio_remote_init(void)
2717 +{      
2718 +       int ret;
2719 +       unsigned int mask;
2720 +
2721 +       /* "normalize" gpio_mask
2722 +        * this means shift it right until first bit is set
2723 +        */
2724 +       while (!(gpio_mask & 1u)) {
2725 +               gpio_pre_shift++;
2726 +               gpio_mask >>= 1;
2727 +       }
2728 +
2729 +       if (code_length) {
2730 +               plugin.code_length = code_length;
2731 +       } else {
2732 +               /* calculate scan code length in bits if needed */
2733 +               plugin.code_length = 1;
2734 +               mask = gpio_mask >> 1;
2735 +               while (mask) {
2736 +                       if (mask & 1u) {
2737 +                               plugin.code_length++;
2738 +                       }
2739 +                       mask >>= 1;
2740 +               }
2741 +       }
2742 +
2743 +       code_bytes = (plugin.code_length/8) + (plugin.code_length%8 ? 1 : 0);
2744 +       if (MAX_BYTES < code_bytes) {
2745 +               printk (LOGHEAD "scan code too long (%d bytes)\n",
2746 +                       minor, code_bytes);
2747 +               return -EBADRQC;
2748 +       }
2749 +
2750 +       if (gpio_enable) {
2751 +               if(bttv_gpio_enable(card, gpio_enable, gpio_enable)) {
2752 +                       printk(LOGHEAD "gpio_enable failure\n", minor);
2753 +                       return -EIO;
2754 +               }
2755 +       }
2756 +
2757 +
2758 +       /* translate ms to jiffies */
2759 +       soft_gap = (soft_gap*HZ) / 1000;
2760 +
2761 +       plugin.minor = minor;
2762 +       plugin.sample_rate = sample_rate;
2763 +
2764 +       ret = lirc_register_plugin(&plugin);
2765 +       
2766 +       if (0 > ret) {
2767 +               printk (LOGHEAD "device registration failed with %d\n",
2768 +                       minor, ret);
2769 +               return ret;
2770 +       }
2771 +       
2772 +       minor = ret;
2773 +       printk(LOGHEAD "driver registered\n", minor);
2774 +
2775 +       return SUCCESS;
2776 +}
2777 +
2778 +#ifndef KERNEL_2_5
2779 +EXPORT_NO_SYMBOLS;
2780 +#endif
2781 +
2782 +/* Dont try to use it as a static version !  */
2783 +
2784 +#ifdef MODULE
2785 +MODULE_DESCRIPTION("Driver module for remote control (data from bt848 GPIO port)");
2786 +MODULE_AUTHOR("Artur Lipowski");
2787 +#ifdef MODULE_LICENSE
2788 +MODULE_LICENSE("GPL");
2789 +#endif
2790 +
2791 +/*
2792 + *
2793 + */
2794 +int init_module(void)
2795 +{
2796 +       int type,cardid,card_type;
2797 +
2798 +       if (MAX_IRCTL_DEVICES < minor) {
2799 +               printk("lirc_gpio: parameter minor (%d) must be less than %d!\n",
2800 +                      minor, MAX_IRCTL_DEVICES-1);
2801 +               return -EBADRQC;
2802 +       }
2803 +       
2804 +       request_module("bttv");
2805 +
2806 +       /* if gpio_mask not zero then use module parameters 
2807 +        * instead of autodetecting TV card
2808 +        */
2809 +       if (gpio_mask) {
2810 +               if (sample_rate!=0 &&
2811 +                   (2 > sample_rate || HZ < sample_rate)) {
2812 +                       printk(LOGHEAD "parameter sample_rate "
2813 +                              "must be between 2 and %d!\n", minor, HZ);
2814 +                       return -EBADRQC;
2815 +               }
2816 +
2817 +               if (sample_rate!=0 && soft_gap && 
2818 +                   ((2000/sample_rate) > soft_gap || 1000 < soft_gap)) {
2819 +                       printk(LOGHEAD "parameter soft_gap "
2820 +                              "must be between %d and 1000!\n",
2821 +                              minor, 2000/sample_rate);
2822 +                       return -EBADRQC;
2823 +               }
2824 +       } else {
2825 +               if(bttv_get_cardinfo(card,&type,&cardid)==-1) {
2826 +                       printk(LOGHEAD "could not get card type\n", minor);
2827 +                       return -EBADRQC;
2828 +               }
2829 +               printk(LOGHEAD "card type 0x%x, id 0x%x\n",minor,
2830 +                      type,cardid);
2831 +
2832 +               if (type == BTTV_UNKNOWN) {
2833 +                       printk(LOGHEAD "cannot detect TV card nr %d!\n",
2834 +                              minor, card);
2835 +                       return -EBADRQC;
2836 +               }
2837 +               for (card_type = 1;
2838 +                    card_type < sizeof(rcv_infos)/sizeof(struct rcv_info); 
2839 +                    card_type++) {
2840 +                       if (rcv_infos[card_type].bttv_id == type &&
2841 +                           (rcv_infos[card_type].card_id == 0 ||
2842 +                            rcv_infos[card_type].card_id == cardid)) {
2843 +                               bttv_id = rcv_infos[card_type].bttv_id;
2844 +                               gpio_mask = rcv_infos[card_type].gpio_mask;
2845 +                               gpio_enable = rcv_infos[card_type].gpio_enable;
2846 +                               gpio_lock_mask = rcv_infos[card_type].gpio_lock_mask;
2847 +                               gpio_xor_mask = rcv_infos[card_type].gpio_xor_mask;
2848 +                               soft_gap = rcv_infos[card_type].soft_gap;
2849 +                               sample_rate = rcv_infos[card_type].sample_rate;
2850 +                               code_length = rcv_infos[card_type].code_length;
2851 +                               break;
2852 +                       }
2853 +               }
2854 +               if (type==BTTV_AVPHONE98 && cardid==0x00011461) {
2855 +                       bttv_id = BTTV_AVERMEDIA98;
2856 +               }
2857 +               if (type==BTTV_AVERMEDIA98 && cardid==0x00041461) {
2858 +                       bttv_id = BTTV_AVPHONE98;
2859 +               }
2860 +               if (type==BTTV_AVERMEDIA98 && cardid==0x03001461) {
2861 +                       bttv_id = BTTV_AVPHONE98;
2862 +               }
2863 +               if (type==BTTV_AVERMEDIA98 && cardid==0x00000000) {
2864 +                       bttv_id = BTTV_AVPHONE98;
2865 +               }
2866 +               if (card_type == sizeof(rcv_infos)/sizeof(struct rcv_info)) {
2867 +                       printk(LOGHEAD "TV card type 0x%x not supported!\n",
2868 +                              minor, type);
2869 +                       return -EBADRQC;
2870 +               }
2871 +       }
2872 +
2873 +       request_module("lirc_dev");
2874 +
2875 +       return gpio_remote_init();
2876 +}
2877 +
2878 +/*
2879 + *
2880 + */
2881 +void cleanup_module(void)
2882 +{
2883 +       int ret;
2884 +
2885 +       ret = lirc_unregister_plugin(minor);
2886
2887 +       if (0 > ret) {
2888 +               printk(LOGHEAD "error in lirc_unregister_minor: %d\n"
2889 +                      "Trying again...\n",
2890 +                      minor, ret);
2891 +
2892 +               current->state = TASK_INTERRUPTIBLE;
2893 +               schedule_timeout(HZ);
2894 +
2895 +               ret = lirc_unregister_plugin(minor);
2896
2897 +               if (0 > ret) {
2898 +                       printk(LOGHEAD "error in lirc_unregister_minor: %d!!!\n",
2899 +                              minor, ret);
2900 +                       return;
2901 +               }
2902 +       }
2903 +
2904 +       dprintk(LOGHEAD "module successfully unloaded\n", minor);
2905 +}
2906 +#endif
2907 +
2908 +/*
2909 + * Overrides for Emacs so that we follow Linus's tabbing style.
2910 + * ---------------------------------------------------------------------------
2911 + * Local variables:
2912 + * c-basic-offset: 8
2913 + * End:
2914 + */
2915 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_i2c.c linux-2.6.8-rc4/drivers/char/lirc/lirc_i2c.c
2916 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_i2c.c   1970-01-01 01:00:00.000000000 +0100
2917 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_i2c.c        2004-04-09 17:33:41.000000000 +0200
2918 @@ -0,0 +1,545 @@
2919 +/*      $Id$      */
2920 +
2921 +/*
2922 + * i2c IR lirc plugin for Hauppauge and Pixelview cards - new 2.3.x i2c stack
2923 + *
2924 + * Copyright (c) 2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
2925 + * modified for PixelView (BT878P+W/FM) by
2926 + *      Michal Kochanowicz <mkochano@pld.org.pl>
2927 + *      Christoph Bartelmus <lirc@bartelmus.de>
2928 + * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
2929 + *      Ulrich Mueller <ulrich.mueller42@web.de>
2930 + * modified for Asus TV-Box and Creative/VisionTek BreakOut-Box by
2931 + *      Stefan Jahn <stefan@lkcc.org>
2932 + *
2933 + * parts are cut&pasted from the old lirc_haup.c driver
2934 + *
2935 + *  This program is free software; you can redistribute it and/or modify
2936 + *  it under the terms of the GNU General Public License as published by
2937 + *  the Free Software Foundation; either version 2 of the License, or
2938 + *  (at your option) any later version.
2939 + *
2940 + *  This program is distributed in the hope that it will be useful,
2941 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
2942 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2943 + *  GNU General Public License for more details.
2944 + *
2945 + *  You should have received a copy of the GNU General Public License
2946 + *  along with this program; if not, write to the Free Software
2947 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
2948 + *
2949 + */
2950 +
2951 +#include <linux/version.h>
2952 +#if LINUX_VERSION_CODE < 0x020200
2953 +#error "--- Sorry, this driver needs kernel version 2.2.0 or higher. ---"
2954 +#endif
2955 +
2956 +#ifdef HAVE_CONFIG_H
2957 +#include <config.h>
2958 +#endif
2959 +
2960 +#include <linux/module.h>
2961 +#include <linux/kmod.h>
2962 +#include <linux/kernel.h>
2963 +#include <linux/sched.h>
2964 +#include <linux/string.h>
2965 +#include <linux/timer.h>
2966 +#include <linux/delay.h>
2967 +#include <linux/errno.h>
2968 +#include <linux/slab.h>
2969 +#include <linux/i2c.h>
2970 +
2971 +#ifndef I2C_CLIENT_END
2972 +#error "********************************************************"
2973 +#error " Sorry, this driver needs the new I2C stack.            "
2974 +#error " You can get it at http://www2.lm-sensors.nu/~lm78/.    "
2975 +#error "********************************************************"
2976 +#endif
2977 +
2978 +#include <linux/i2c-algo-bit.h>
2979 +
2980 +#include <asm/semaphore.h>
2981 +
2982 +#include "kcompat.h"
2983 +#include "lirc_dev.h"
2984 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
2985 +#include "../drivers/char/bttv.h"
2986 +#else
2987 +#include "../drivers/media/video/bttv.h"
2988 +#endif
2989 +
2990 +struct IR {
2991 +       struct lirc_plugin l;
2992 +       struct i2c_client  c;
2993 +       int nextkey;
2994 +       unsigned char b[3];
2995 +       unsigned char bits;
2996 +       unsigned char flag;
2997 +};
2998 +
2999 +/* ----------------------------------------------------------------------- */
3000 +/* insmod parameters                                                       */
3001 +
3002 +static int debug   = 0;    /* debug output */
3003 +static int minor   = -1;   /* minor number */
3004 +
3005 +MODULE_PARM(debug,"i");
3006 +MODULE_PARM(minor,"i");
3007 +
3008 +#define dprintk if (debug) printk
3009 +
3010 +/* ----------------------------------------------------------------------- */
3011 +
3012 +#define DEVICE_NAME "lirc_i2c"
3013 +
3014 +/* ----------------------------------------------------------------------- */
3015 +
3016 +static inline int reverse(int data, int bits)
3017 +{
3018 +       int i;
3019 +       int c;
3020 +       
3021 +       for (c=0,i=0; i<bits; i++) {
3022 +               c |= (((data & (1<<i)) ? 1:0)) << (bits-1-i);
3023 +       }
3024 +
3025 +       return c;
3026 +}
3027 +
3028 +static int add_to_buf_pcf8574(void* data, struct lirc_buffer* buf)
3029 +{
3030 +       struct IR *ir = data;
3031 +       int rc;
3032 +       unsigned char all, mask;
3033 +       unsigned char key;
3034 +
3035 +       /* compute all valid bits (key code + pressed/release flag) */
3036 +       all = ir->bits | ir->flag;
3037 +
3038 +       /* save IR writable mask bits */
3039 +       mask = i2c_smbus_read_byte(&ir->c) & ~all;
3040 +
3041 +       /* send bit mask */
3042 +       rc = i2c_smbus_write_byte(&ir->c, (0xff & all) | mask);
3043 +
3044 +       /* receive scan code */
3045 +       rc = i2c_smbus_read_byte(&ir->c);
3046 +
3047 +       if (rc == -1) {
3048 +               dprintk(DEVICE_NAME ": %s read error\n", ir->c.name);
3049 +               return -EIO;
3050 +       }
3051 +
3052 +       /* drop duplicate polls */
3053 +       if (ir->b[0] == (rc & all)) {
3054 +               return -ENODATA;
3055 +       }
3056 +       ir->b[0] = rc & all;
3057 +
3058 +       dprintk(DEVICE_NAME ": %s key 0x%02X %s\n",
3059 +               ir->c.name, rc & ir->bits,
3060 +               (rc & ir->flag) ? "released" : "pressed");
3061 +
3062 +       if (rc & ir->flag) {
3063 +               /* ignore released buttons */
3064 +               return -ENODATA;
3065 +       }
3066 +
3067 +       /* set valid key code */
3068 +       key  = rc & ir->bits;
3069 +       lirc_buffer_write_1( buf, &key );
3070 +       return 0;
3071 +}
3072 +
3073 +static int add_to_buf_haup(void* data, struct lirc_buffer* buf)
3074 +{
3075 +       struct IR *ir = data;
3076 +       unsigned char keybuf[3];
3077 +       __u16 code;
3078 +       unsigned char codes[2];
3079 +
3080 +       /* poll IR chip */
3081 +       if (3 == i2c_master_recv(&ir->c,keybuf,3)) {
3082 +               ir->b[0] = keybuf[0];
3083 +               ir->b[1] = keybuf[1];
3084 +               ir->b[2] = keybuf[2];
3085 +               dprintk(KERN_DEBUG DEVICE_NAME ": key (0x%02x/0x%02x)\n",
3086 +                       ir->b[0], ir->b[1]);
3087 +       } else {
3088 +               dprintk(KERN_DEBUG DEVICE_NAME ": read error\n");
3089 +               /* keep last successfull read buffer */
3090 +       }
3091 +
3092 +       /* key pressed ? */
3093 +       if ((ir->b[0] & 0x80) == 0)
3094 +               return -ENODATA;
3095 +       
3096 +       /* look what we have */
3097 +       code = (((__u16)ir->b[0]&0x7f)<<6) | (ir->b[1]>>2);
3098 +       
3099 +       codes[0] = (code >> 8) & 0xff;
3100 +       codes[1] = code & 0xff;
3101 +
3102 +       /* return it */
3103 +       lirc_buffer_write_1( buf, codes );
3104 +       return 0;
3105 +}
3106 +
3107 +static int add_to_buf_pixelview(void* data, struct lirc_buffer* buf)
3108 +{
3109 +       struct IR *ir = data;
3110 +       unsigned char key;
3111 +       
3112 +       /* poll IR chip */
3113 +       if (1 != i2c_master_recv(&ir->c,&key,1)) {
3114 +               dprintk(KERN_DEBUG DEVICE_NAME ": read error\n");
3115 +               return -1;
3116 +       }
3117 +       dprintk(KERN_DEBUG DEVICE_NAME ": key %02x\n", key);
3118 +
3119 +       /* return it */
3120 +       lirc_buffer_write_1( buf, &key );
3121 +       return 0;
3122 +}
3123 +
3124 +static int add_to_buf_pv951(void* data, struct lirc_buffer* buf)
3125 +{
3126 +       struct IR *ir = data;
3127 +       unsigned char key;
3128 +       unsigned char codes[4];
3129 +       
3130 +       /* poll IR chip */
3131 +       if (1 != i2c_master_recv(&ir->c,&key,1)) {
3132 +               dprintk(KERN_DEBUG DEVICE_NAME ": read error\n");
3133 +               return -ENODATA;
3134 +       }
3135 +       /* ignore 0xaa */
3136 +       if (key==0xaa)
3137 +               return -ENODATA;
3138 +       dprintk(KERN_DEBUG DEVICE_NAME ": key %02x\n", key);
3139 +
3140 +       codes[0] = 0x61;
3141 +       codes[1] = 0xD6;
3142 +       codes[2] = reverse(key,8);
3143 +       codes[3] = (~codes[2])&0xff;
3144 +       
3145 +       lirc_buffer_write_1( buf, codes );
3146 +       return 0;
3147 +}
3148 +
3149 +static int add_to_buf_knc1(void *data, struct lirc_buffer* buf)
3150 +{
3151 +       static unsigned char last_key = 0xFF;
3152 +       struct IR *ir = data;
3153 +       unsigned char key;
3154 +       
3155 +       /* poll IR chip */
3156 +       if (1 != i2c_master_recv(&ir->c,&key,1)) {
3157 +               dprintk(KERN_DEBUG DEVICE_NAME ": read error\n");
3158 +               return -ENODATA;
3159 +       }
3160 +       
3161 +       /* it seems that 0xFE indicates that a button is still hold
3162 +          down, while 0xFF indicates that no button is hold
3163 +          down. 0xFE sequences are sometimes interrupted by 0xFF */
3164 +       
3165 +       dprintk(KERN_DEBUG DEVICE_NAME ": key %02x\n", key);
3166 +       
3167 +       if( key == 0xFF )
3168 +               return -ENODATA;
3169 +       
3170 +       if ( key == 0xFE )
3171 +               key = last_key;
3172 +
3173 +       last_key = key;
3174 +       lirc_buffer_write_1( buf, &key );
3175 +
3176 +       return 0;
3177 +}
3178 +
3179 +static int set_use_inc(void* data)
3180 +{
3181 +       struct IR *ir = data;
3182 +
3183 +       /* lock bttv in memory while /dev/lirc is in use  */
3184 +       /* this is completely broken code. lirc_unregister_plugin()
3185 +          must be possible even when the device is open */
3186 +#ifdef KERNEL_2_5
3187 +       i2c_use_client(&ir->c);
3188 +#else
3189 +       if (ir->c.adapter->inc_use) 
3190 +               ir->c.adapter->inc_use(ir->c.adapter);
3191 +#endif
3192 +
3193 +       MOD_INC_USE_COUNT;
3194 +       return 0;
3195 +}
3196 +
3197 +static void set_use_dec(void* data)
3198 +{
3199 +       struct IR *ir = data;
3200 +
3201 +#ifdef KERNEL_2_5
3202 +       i2c_release_client(&ir->c);
3203 +#else
3204 +       if (ir->c.adapter->dec_use) 
3205 +               ir->c.adapter->dec_use(ir->c.adapter);
3206 +#endif
3207 +       MOD_DEC_USE_COUNT;
3208 +}
3209 +
3210 +static struct lirc_plugin lirc_template = {
3211 +       name:        "lirc_i2c",
3212 +       set_use_inc: set_use_inc,
3213 +       set_use_dec: set_use_dec
3214 +};
3215 +
3216 +/* ----------------------------------------------------------------------- */
3217 +
3218 +static int ir_attach(struct i2c_adapter *adap, int addr,
3219 +                     unsigned short flags, int kind);
3220 +static int ir_detach(struct i2c_client *client);
3221 +static int ir_probe(struct i2c_adapter *adap);
3222 +static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg);
3223 +
3224 +static struct i2c_driver driver = {
3225 +        name:           "i2c ir driver",
3226 +        id:             I2C_DRIVERID_EXP3, /* FIXME */
3227 +        flags:          I2C_DF_NOTIFY,
3228 +        attach_adapter: ir_probe,
3229 +        detach_client:  ir_detach,
3230 +        command:        ir_command,
3231 +};
3232 +
3233 +static struct i2c_client client_template = 
3234 +{
3235 +        name:   "unset",
3236 +        driver: &driver
3237 +};
3238 +
3239 +static int ir_attach(struct i2c_adapter *adap, int addr,
3240 +                    unsigned short flags, int kind)
3241 +{
3242 +        struct IR *ir;
3243 +       
3244 +        client_template.adapter = adap;
3245 +        client_template.addr = addr;
3246 +       
3247 +        if (NULL == (ir = kmalloc(sizeof(struct IR),GFP_KERNEL)))
3248 +                return -ENOMEM;
3249 +        memcpy(&ir->l,&lirc_template,sizeof(struct lirc_plugin));
3250 +        memcpy(&ir->c,&client_template,sizeof(struct i2c_client));
3251 +       
3252 +       ir->c.adapter = adap;
3253 +       ir->c.addr    = addr;
3254 +#ifdef KERNEL_2_5
3255 +       i2c_set_clientdata(&ir->c, ir);
3256 +#else
3257 +       ir->c.data    = ir;
3258 +#endif
3259 +       ir->l.data    = ir;
3260 +       ir->l.minor   = minor;
3261 +       ir->l.sample_rate = 10;
3262 +       ir->nextkey   = -1;
3263 +
3264 +       switch(addr)
3265 +       {
3266 +       case 0x64:
3267 +               strcpy(ir->c.name,"Pixelview IR");
3268 +               ir->l.code_length = 8;
3269 +               ir->l.add_to_buf=add_to_buf_pixelview;
3270 +               break;
3271 +       case 0x4b:
3272 +               strcpy(ir->c.name,"PV951 IR");
3273 +               ir->l.code_length = 32;
3274 +               ir->l.add_to_buf=add_to_buf_pv951;
3275 +               break;
3276 +       case 0x18:
3277 +       case 0x1a:
3278 +               strcpy(ir->c.name,"Hauppauge IR");
3279 +               ir->l.code_length = 13;
3280 +               ir->l.add_to_buf=add_to_buf_haup;
3281 +               break;
3282 +       case 0x30:
3283 +               strcpy(ir->c.name,"KNC ONE IR");
3284 +               ir->l.code_length = 8;
3285 +               ir->l.add_to_buf=add_to_buf_knc1;
3286 +               break;
3287 +       case 0x21:
3288 +       case 0x23:
3289 +               strcpy(ir->c.name,"TV-Box IR");
3290 +               ir->l.code_length = 8;
3291 +               ir->l.add_to_buf=add_to_buf_pcf8574;
3292 +               ir->bits = flags & 0xff;
3293 +               ir->flag = (flags >> 8) & 0xff;
3294 +               break;
3295 +               
3296 +       default:
3297 +               /* shouldn't happen */
3298 +               printk("lirc_i2c: Huh? unknown i2c address (0x%02x)?\n",addr);
3299 +               kfree(ir);
3300 +               return -1;
3301 +       }
3302 +       printk("lirc_i2c: chip found @ 0x%02x (%s)\n",addr,ir->c.name);
3303 +       
3304 +       /* register device */
3305 +       i2c_attach_client(&ir->c);
3306 +       ir->l.minor = lirc_register_plugin(&ir->l);
3307 +#ifdef KERNEL_2_5
3308 +       i2c_use_client(&ir->c);
3309 +#else
3310 +       if (ir->c.adapter->inc_use) 
3311 +               ir->c.adapter->inc_use(ir->c.adapter);
3312 +#endif
3313 +       
3314 +       return 0;
3315 +}
3316 +
3317 +static int ir_detach(struct i2c_client *client)
3318 +{
3319 +#ifdef KERNEL_2_5
3320 +       struct IR *ir = i2c_get_clientdata(client);
3321 +#else
3322 +        struct IR *ir = client->data;
3323 +#endif
3324 +       
3325 +       /* unregister device */
3326 +#ifdef KERNEL_2_5
3327 +       i2c_release_client(&ir->c);
3328 +#else
3329 +       if (ir->c.adapter->dec_use) 
3330 +               ir->c.adapter->dec_use(ir->c.adapter);
3331 +#endif
3332 +       lirc_unregister_plugin(ir->l.minor);
3333 +       i2c_detach_client(&ir->c);
3334 +
3335 +       /* free memory */
3336 +       kfree(ir);
3337 +       return 0;
3338 +}
3339 +
3340 +static int ir_probe(struct i2c_adapter *adap) {
3341 +       
3342 +       /* The external IR receiver is at i2c address 0x34 (0x35 for
3343 +          reads).  Future Hauppauge cards will have an internal
3344 +          receiver at 0x30 (0x31 for reads).  In theory, both can be
3345 +          fitted, and Hauppauge suggest an external overrides an
3346 +          internal. 
3347 +          
3348 +          That's why we probe 0x1a (~0x34) first. CB 
3349 +       */
3350 +       
3351 +       static const int probe[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
3352 +       struct i2c_client c; char buf; int i,rc;
3353 +
3354 +       if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) {
3355 +               memset(&c,0,sizeof(c));
3356 +               c.adapter = adap;
3357 +               for (i = 0; -1 != probe[i]; i++) {
3358 +                       c.addr = probe[i];
3359 +                       rc = i2c_master_recv(&c,&buf,1);
3360 +                       dprintk("lirc_i2c: probe 0x%02x @ %s: %s\n",
3361 +                               probe[i], adap->name, 
3362 +                               (1 == rc) ? "yes" : "no");
3363 +                       if (1 == rc)
3364 +                       {
3365 +                               ir_attach(adap,probe[i],0,0);
3366 +                       }
3367 +               }
3368 +       }
3369 +
3370 +       /* Asus TV-Box and Creative/VisionTek BreakOut-Box (PCF8574) */
3371 +       else if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_RIVA)) {
3372 +               /* addresses to probe;
3373 +                  leave 0x24 and 0x25 because SAA7113H possibly uses it 
3374 +                  0x21 and 0x22 possibly used by SAA7108E 
3375 +                  Asus:      0x21 is a correct address (channel 1 of PCF8574)
3376 +                  Creative:  0x23 is a correct address (channel 3 of PCF8574)
3377 +                  VisionTek: 0x23 is a correct address (channel 3 of PCF8574)
3378 +               */
3379 +               static const int pcf_probe[] = { 0x20, 0x21, 0x22, 0x23,
3380 +                                                0x24, 0x25, 0x26, 0x27, -1 };
3381 +               int ret1, ret2, ret3, ret4;
3382 +               unsigned char bits = 0, flag = 0;
3383 +
3384 +               memset(&c,0,sizeof(c));
3385 +               c.adapter = adap;
3386 +               for (i = 0; -1 != pcf_probe[i]; i++) {
3387 +                       c.addr = pcf_probe[i];
3388 +                       ret1 = i2c_smbus_write_byte(&c, 0xff);
3389 +                       ret2 = i2c_smbus_read_byte(&c);
3390 +                       ret3 = i2c_smbus_write_byte(&c, 0x00);
3391 +                       ret4 = i2c_smbus_read_byte(&c);
3392 +
3393 +                       /* ensure that the writable bitmask works correctly */
3394 +                       rc = 0;
3395 +                       if (ret1 != -1 && ret2 != -1 && 
3396 +                           ret3 != -1 && ret4 != -1) {
3397 +                               /* in the Asus TV-Box: bit 1-0 */
3398 +                               if (((ret2 & 0x03) == 0x03) && 
3399 +                                   ((ret4 & 0x03) == 0x00)) {
3400 +                                       bits = (unsigned char) ~0x07;
3401 +                                       flag = 0x04;
3402 +                                       rc = 1;
3403 +                               }
3404 +                               /* in the Creative/VisionTek BreakOut-Box: bit 7-6 */
3405 +                               if (((ret2 & 0xc0) == 0xc0) && 
3406 +                                   ((ret4 & 0xc0) == 0x00)) {
3407 +                                       bits = (unsigned char) ~0xe0;
3408 +                                       flag = 0x20;
3409 +                                       rc = 1;
3410 +                               }
3411 +                       }
3412 +                       dprintk(DEVICE_NAME ": probe 0x%02x @ %s: %s\n",
3413 +                               c.addr, adap->name, rc ? "yes" : "no");
3414 +                       if (rc)
3415 +                               ir_attach(adap,pcf_probe[i],bits|(flag<<8),0);
3416 +               }
3417 +       }
3418 +               
3419 +       return 0;
3420 +}
3421 +
3422 +static int ir_command(struct i2c_client *client,unsigned int cmd, void *arg)
3423 +{
3424 +       /* nothing */
3425 +       return 0;
3426 +}
3427 +
3428 +/* ----------------------------------------------------------------------- */
3429 +#ifdef MODULE
3430 +MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller, Stefan Jahn");
3431 +MODULE_DESCRIPTION("Infrared receiver driver for Hauppauge and Pixelview cards (i2c stack)");
3432 +#ifdef MODULE_LICENSE
3433 +MODULE_LICENSE("GPL");
3434 +#endif
3435 +#endif
3436 +
3437 +
3438 +#ifdef MODULE
3439 +int init_module(void)
3440 +#else
3441 +int lirc_i2c_init(void)
3442 +#endif
3443 +{
3444 +       request_module("bttv");
3445 +       request_module("rivatv");
3446 +       i2c_add_driver(&driver);
3447 +       return 0;
3448 +}
3449 +
3450 +#ifdef MODULE
3451 +void cleanup_module(void)
3452 +{
3453 +       i2c_del_driver(&driver);
3454 +}
3455 +#endif
3456 +
3457 +/*
3458 + * Overrides for Emacs so that we follow Linus's tabbing style.
3459 + * ---------------------------------------------------------------------------
3460 + * Local variables:
3461 + * c-basic-offset: 8
3462 + * End:
3463 + */
3464 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_it87.c linux-2.6.8-rc4/drivers/char/lirc/lirc_it87.c
3465 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_it87.c  1970-01-01 01:00:00.000000000 +0100
3466 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_it87.c       2004-04-27 20:45:31.000000000 +0200
3467 @@ -0,0 +1,970 @@
3468 +/*
3469 + * LIRC driver for ITE IT8712/IT8705 CIR port
3470 + *
3471 + * Copyright (C) 2001 Hans-Günter Lütke Uphues <hg_lu@web.de>
3472 + *
3473 + * This program is free software; you can redistribute it and/or
3474 + * modify it under the terms of the GNU General Public License as
3475 + * published by the Free Software Foundation; either version 2 of the
3476 + * License, or (at your option) any later version.
3477 + *
3478 + * This program is distributed in the hope that it will be useful, but
3479 + * WITHOUT ANY WARRANTY; without even the implied warranty of
3480 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
3481 + * General Public License for more details.
3482 +
3483 + * You should have received a copy of the GNU General Public License
3484 + * along with this program; if not, write to the Free Software
3485 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
3486 + * USA
3487 + *
3488 + * ITE IT8705 and IT8712(not tested) CIR-port support for lirc based
3489 + * via cut and paste from lirc_sir.c (C) 2000 Milan Pikula
3490 + *
3491 + * Attention: Sendmode only tested with debugging logs 
3492 + *
3493 + * 2001/02/27 Christoph Bartelmus <lirc@bartelmus.de> :
3494 + *   reimplemented read function
3495 + */
3496 +
3497 +
3498 +#include <linux/version.h>
3499 +#include <linux/module.h>
3500 +
3501 +#ifdef HAVE_CONFIG_H
3502 +# include <config.h>
3503 +#endif
3504
3505 +#include <linux/config.h>
3506 +
3507 +
3508 +#include <linux/sched.h>
3509 +#include <linux/errno.h>
3510 +#include <linux/signal.h>
3511 +#include <linux/fs.h>
3512 +#include <linux/interrupt.h>
3513 +#include <linux/ioport.h>
3514 +#include <linux/kernel.h>
3515 +#include <linux/major.h>
3516 +#include <linux/serial_reg.h>
3517 +#include <linux/time.h>
3518 +#include <linux/string.h>
3519 +#include <linux/types.h>
3520 +#include <linux/wait.h>
3521 +#include <linux/mm.h>
3522 +#include <linux/delay.h>
3523 +#include <linux/poll.h>
3524 +#include <asm/system.h>
3525 +#include <asm/segment.h>
3526 +#include <asm/io.h>
3527 +#include <asm/irq.h>
3528 +#include <asm/fcntl.h>
3529 +
3530 +#include <linux/timer.h>
3531 +
3532 +#include <linux/lirc.h>
3533 +#include "lirc_dev.h"
3534 +#include "kcompat.h"
3535 +
3536 +#include "lirc_it87.h"
3537 +
3538 +static unsigned long it87_bits_in_byte_out = 0;
3539 +static unsigned long it87_send_counter = 0;
3540 +static unsigned char it87_RXEN_mask = IT87_CIR_RCR_RXEN;
3541 +
3542 +#define RBUF_LEN 1024
3543 +#define WBUF_LEN 1024
3544 +
3545 +#define LIRC_DRIVER_NAME "lirc_it87"
3546 +
3547 +/* timeout for sequences in jiffies (=5/100s) */
3548 +/* must be longer than TIME_CONST */
3549 +#define IT87_TIMEOUT   (HZ*5/100)
3550 +
3551 +static int io = IT87_CIR_DEFAULT_IOBASE;
3552 +static int irq = IT87_CIR_DEFAULT_IRQ;
3553 +static unsigned char it87_freq = 38; /* kHz */
3554 +/* receiver demodulator default: off */
3555 +static unsigned char it87_enable_demodulator = 0;
3556 +
3557 +static spinlock_t timer_lock = SPIN_LOCK_UNLOCKED;
3558 +static struct timer_list timerlist;
3559 +/* time of last signal change detected */
3560 +static struct timeval last_tv = {0, 0};
3561 +/* time of last UART data ready interrupt */
3562 +static struct timeval last_intr_tv = {0, 0};
3563 +static int last_value = 0;
3564 +
3565 +static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue);
3566 +
3567 +static spinlock_t hardware_lock = SPIN_LOCK_UNLOCKED;
3568 +static spinlock_t dev_lock = SPIN_LOCK_UNLOCKED;
3569 +
3570 +static lirc_t rx_buf[RBUF_LEN]; unsigned int rx_tail = 0, rx_head = 0;
3571 +static lirc_t tx_buf[WBUF_LEN];
3572 +
3573 +/* SECTION: Prototypes */
3574 +
3575 +/* Communication with user-space */
3576 +static int lirc_open(struct inode * inode,
3577 +                    struct file * file);
3578 +static int lirc_close(struct inode * inode,
3579 +                     struct file *file);
3580 +static unsigned int lirc_poll(struct file * file,
3581 +                             poll_table * wait);
3582 +static ssize_t lirc_read(struct file * file,
3583 +                        char * buf,
3584 +                        size_t count,
3585 +                        loff_t * ppos);
3586 +static ssize_t lirc_write(struct file * file,
3587 +                         const char * buf,
3588 +                         size_t n,
3589 +                         loff_t * pos);
3590 +static int lirc_ioctl(struct inode *node,
3591 +                     struct file *filep,
3592 +                     unsigned int cmd,
3593 +                     unsigned long arg);
3594 +static void add_read_queue(int flag,
3595 +                          unsigned long val);
3596 +#ifdef MODULE
3597 +static int init_chrdev(void);
3598 +static void drop_chrdev(void);
3599 +#endif
3600 +       /* Hardware */
3601 +static irqreturn_t it87_interrupt(int irq, void * dev_id,
3602 +                                struct pt_regs * regs);
3603 +static void send_space(unsigned long len);
3604 +static void send_pulse(unsigned long len);
3605 +static void init_send(void);
3606 +static void terminate_send(unsigned long len);
3607 +static int init_hardware(void);
3608 +static void drop_hardware(void);
3609 +       /* Initialisation */
3610 +static int init_port(void);
3611 +static void drop_port(void);
3612 +int init_module(void);
3613 +void cleanup_module(void);
3614 +
3615 +
3616 +/* SECTION: Communication with user-space */
3617 +
3618 +static int lirc_open(struct inode * inode,
3619 +                    struct file * file)
3620 +{
3621 +       spin_lock(&dev_lock);
3622 +       if (MOD_IN_USE) {
3623 +               spin_unlock(&dev_lock);
3624 +               return -EBUSY;
3625 +       }
3626 +       MOD_INC_USE_COUNT;
3627 +       spin_unlock(&dev_lock);
3628 +       return 0;
3629 +}
3630 +
3631 +
3632 +static int lirc_close(struct inode * inode,
3633 +                     struct file *file)
3634 +{
3635 +       MOD_DEC_USE_COUNT;
3636 +       return 0;
3637 +}
3638 +
3639 +
3640 +static unsigned int lirc_poll(struct file * file,
3641 +                             poll_table * wait)
3642 +{
3643 +       poll_wait(file, &lirc_read_queue, wait);
3644 +       if (rx_head != rx_tail)
3645 +               return POLLIN | POLLRDNORM;
3646 +       return 0;
3647 +}
3648 +
3649 +
3650 +static ssize_t lirc_read(struct file * file,
3651 +                        char * buf,
3652 +                        size_t count,
3653 +                        loff_t * ppos)
3654 +{
3655 +       int n=0;
3656 +       int retval=0;
3657 +       
3658 +       while(n<count)
3659 +       {
3660 +               if(file->f_flags & O_NONBLOCK &&
3661 +                  rx_head==rx_tail)
3662 +               {
3663 +                       retval = -EAGAIN;
3664 +                       break;
3665 +               }
3666 +               retval=wait_event_interruptible(lirc_read_queue,
3667 +                                               rx_head!=rx_tail);
3668 +               if(retval)
3669 +               {
3670 +                       break;
3671 +               }
3672 +               
3673 +               retval=verify_area(VERIFY_WRITE,(void *) buf+n,
3674 +                                  sizeof(lirc_t));
3675 +               if (retval)
3676 +               {
3677 +                       return retval;
3678 +               }
3679 +               copy_to_user((void *) buf+n,(void *) (rx_buf+rx_head),
3680 +                            sizeof(lirc_t));
3681 +               rx_head=(rx_head+1)&(RBUF_LEN-1);
3682 +               n+=sizeof(lirc_t);
3683 +       }
3684 +       if(n)
3685 +       {
3686 +               return n;
3687 +       }
3688 +       return retval;
3689 +}
3690 +
3691 +
3692 +static ssize_t lirc_write(struct file * file,
3693 +                         const char * buf,
3694 +                         size_t n,
3695 +                         loff_t * pos)
3696 +{
3697 +       int i;
3698 +       int retval;
3699 +
3700 +        if(n%sizeof(lirc_t) || (n/sizeof(lirc_t)) > WBUF_LEN)
3701 +               return(-EINVAL);
3702 +       retval = verify_area(VERIFY_READ, buf, n);
3703 +       if (retval)
3704 +               return retval;
3705 +       copy_from_user(tx_buf, buf, n);
3706 +       i = 0;
3707 +       n/=sizeof(lirc_t);
3708 +       init_send();
3709 +       while (1) {
3710 +               if (i >= n)
3711 +                       break;
3712 +               if (tx_buf[i])
3713 +                       send_pulse(tx_buf[i]);
3714 +               i++;
3715 +               if (i >= n)
3716 +                       break;
3717 +               if (tx_buf[i])
3718 +                       send_space(tx_buf[i]);
3719 +               i++;
3720 +       }
3721 +       terminate_send(tx_buf[i-1]);
3722 +       return n;
3723 +}
3724 +
3725 +
3726 +static int lirc_ioctl(struct inode *node,
3727 +                     struct file *filep,
3728 +                     unsigned int cmd,
3729 +                     unsigned long arg)
3730 +{
3731 +       int retval = 0;
3732 +       unsigned long value = 0;
3733 +       unsigned int ivalue;
3734 +
3735 +       if (cmd == LIRC_GET_FEATURES)
3736 +               value = LIRC_CAN_SEND_PULSE |
3737 +                       LIRC_CAN_SET_SEND_CARRIER |
3738 +                       LIRC_CAN_REC_MODE2;
3739 +       else if (cmd == LIRC_GET_SEND_MODE)
3740 +               value = LIRC_MODE_PULSE;
3741 +       else if (cmd == LIRC_GET_REC_MODE)
3742 +               value = LIRC_MODE_MODE2;
3743 +       
3744 +       switch (cmd) {
3745 +       case LIRC_GET_FEATURES:
3746 +       case LIRC_GET_SEND_MODE:
3747 +       case LIRC_GET_REC_MODE:
3748 +               retval = put_user(value, (unsigned long *) arg);
3749 +               break;
3750 +
3751 +       case LIRC_SET_SEND_MODE:
3752 +       case LIRC_SET_REC_MODE:
3753 +               retval = get_user(value, (unsigned long *) arg);
3754 +               break;
3755 +
3756 +       case LIRC_SET_SEND_CARRIER:
3757 +               retval=get_user(ivalue,(unsigned int *) arg);
3758 +               if(retval) return(retval);
3759 +               ivalue /= 1000;
3760 +               if (ivalue > IT87_CIR_FREQ_MAX ||
3761 +                   ivalue < IT87_CIR_FREQ_MIN) return(-EINVAL);
3762 +
3763 +               it87_freq = ivalue;
3764 +               {
3765 +                       unsigned long hw_flags;
3766 +
3767 +                       spin_lock_irqsave(&hardware_lock, hw_flags);
3768 +                       outb(((inb(io + IT87_CIR_TCR2) & IT87_CIR_TCR2_TXMPW) |
3769 +                             (it87_freq - IT87_CIR_FREQ_MIN) << 3),
3770 +                            io + IT87_CIR_TCR2);
3771 +                       spin_unlock_irqrestore(&hardware_lock, hw_flags);
3772 +#ifdef DEBUG
3773 +                       printk(KERN_DEBUG LIRC_DRIVER_NAME 
3774 +                              " demodulation frequency: %d kHz\n", it87_freq);
3775 +#endif
3776 +               }
3777 +
3778 +               break;
3779 +
3780 +       default:
3781 +               retval = -ENOIOCTLCMD;
3782 +       }
3783 +       
3784 +       if (retval)
3785 +               return retval;
3786 +       
3787 +       if (cmd == LIRC_SET_REC_MODE) {
3788 +               if (value != LIRC_MODE_MODE2)
3789 +                       retval = -ENOSYS;
3790 +       } else if (cmd == LIRC_SET_SEND_MODE) {
3791 +               if (value != LIRC_MODE_PULSE)
3792 +                       retval = -ENOSYS;
3793 +       }
3794 +       return retval;
3795 +}
3796 +
3797 +static void add_read_queue(int flag,
3798 +                          unsigned long val)
3799 +{
3800 +       unsigned int new_rx_tail;
3801 +       lirc_t newval;
3802 +
3803 +#ifdef DEBUG_SIGNAL
3804 +       printk(KERN_DEBUG LIRC_DRIVER_NAME
3805 +              ": add flag %d with val %lu\n",
3806 +              flag,val);
3807 +#endif
3808 +       
3809 +       newval = val & PULSE_MASK;
3810 +
3811 +       /* statistically pulses are ~TIME_CONST/2 too long: we could
3812 +          maybe make this more exactly but this is good enough */
3813 +       if(flag) /* pulse */ {
3814 +               if(newval>TIME_CONST/2) {
3815 +                       newval-=TIME_CONST/2;
3816 +               }
3817 +               else /* should not ever happen */ {
3818 +                       newval=1;
3819 +               }
3820 +               newval|=PULSE_BIT;
3821 +       }
3822 +       else {
3823 +               newval+=TIME_CONST/2;
3824 +       }
3825 +       new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1);
3826 +       if (new_rx_tail == rx_head) {
3827 +#ifdef DEBUG
3828 +               printk(KERN_WARNING LIRC_DRIVER_NAME ": Buffer overrun.\n");
3829 +#endif
3830 +               return;
3831 +       }
3832 +       rx_buf[rx_tail] = newval;
3833 +       rx_tail = new_rx_tail;
3834 +       wake_up_interruptible(&lirc_read_queue);
3835 +}
3836 +
3837 +
3838 +static struct file_operations lirc_fops = {
3839 +       read:    lirc_read,
3840 +       write:   lirc_write,
3841 +       poll:    lirc_poll,
3842 +       ioctl:   lirc_ioctl,
3843 +       open:    lirc_open,
3844 +       release: lirc_close,
3845 +};
3846 +
3847 +static int set_use_inc(void* data)
3848 +{
3849 +#if WE_DONT_USE_LOCAL_OPEN_CLOSE
3850 +       MOD_INC_USE_COUNT;
3851 +#endif
3852 +       return 0;
3853 +}
3854 +
3855 +static void set_use_dec(void* data)
3856 +{
3857 +#if WE_DONT_USE_LOCAL_OPEN_CLOSE
3858 +       MOD_DEC_USE_COUNT;
3859 +#endif
3860 +}
3861 +static struct lirc_plugin plugin = {
3862 +       name:           LIRC_DRIVER_NAME,
3863 +       minor:          -1,
3864 +       code_length:    1,
3865 +       sample_rate:    0,
3866 +       data:           NULL,
3867 +       add_to_buf:     NULL,
3868 +       get_queue:      NULL,
3869 +       set_use_inc:    set_use_inc,
3870 +       set_use_dec:    set_use_dec,
3871 +       fops:           &lirc_fops,
3872 +};
3873 +
3874 +
3875 +#ifdef MODULE
3876 +int init_chrdev(void)
3877 +{
3878 +       plugin.minor = lirc_register_plugin(&plugin);
3879 +       
3880 +       if (plugin.minor < 0) {
3881 +               printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n");
3882 +               return -EIO;
3883 +       }
3884 +       return 0;
3885 +}
3886 +
3887 +
3888 +static void drop_chrdev(void)
3889 +{
3890 +       lirc_unregister_plugin(plugin.minor);
3891 +}
3892 +#endif
3893 +
3894 +
3895 +/* SECTION: Hardware */
3896 +static long delta(struct timeval * tv1,
3897 +                 struct timeval * tv2)
3898 +{
3899 +       unsigned long deltv;
3900 +       
3901 +       deltv = tv2->tv_sec - tv1->tv_sec;
3902 +       if (deltv > 15)
3903 +               deltv = 0xFFFFFF;
3904 +       else
3905 +               deltv = deltv*1000000 +
3906 +                       tv2->tv_usec -
3907 +                       tv1->tv_usec;
3908 +       return deltv;
3909 +}
3910 +
3911 +
3912 +static void it87_timeout(unsigned long data) 
3913 +{
3914 +       /* if last received signal was a pulse, but receiving stopped
3915 +          within the 9 bit frame, we need to finish this pulse and
3916 +          simulate a signal change to from pulse to space. Otherwise
3917 +          upper layers will receive two sequences next time. */
3918 +       
3919 +       unsigned long flags;
3920 +       unsigned long pulse_end;
3921 +       
3922 +       /* avoid interference with interrupt */
3923 +       spin_lock_irqsave(&timer_lock, flags);
3924 +       if (last_value) {
3925 +               /* determine 'virtual' pulse end: */
3926 +               pulse_end = delta(&last_tv, &last_intr_tv);
3927 +#ifdef DEBUG_SIGNAL
3928 +               printk(KERN_DEBUG LIRC_DRIVER_NAME
3929 +                      ": timeout add %d for %lu usec\n",
3930 +                      last_value,
3931 +                      pulse_end);
3932 +#endif
3933 +               add_read_queue(last_value,
3934 +                              pulse_end);
3935 +               last_value = 0;
3936 +               last_tv=last_intr_tv;
3937 +       }
3938 +       spin_unlock_irqrestore(&timer_lock, flags);             
3939 +}
3940 +
3941 +
3942 +static irqreturn_t it87_interrupt(int irq,
3943 +                                void * dev_id,
3944 +                                struct pt_regs * regs)
3945 +{
3946 +       unsigned char data;
3947 +       struct timeval curr_tv;
3948 +       static unsigned long deltv;
3949 +       unsigned long deltintrtv;
3950 +       unsigned long flags, hw_flags;
3951 +       int iir, lsr;
3952 +       int fifo = 0;
3953 +
3954 +       iir = inb(io + IT87_CIR_IIR);
3955 +
3956 +       switch (iir & IT87_CIR_IIR_IID) {
3957 +       case 0x4:
3958 +       case 0x6:
3959 +               lsr = inb(io + IT87_CIR_RSR) & (IT87_CIR_RSR_RXFTO |
3960 +                                                   IT87_CIR_RSR_RXFBC);
3961 +               fifo = lsr & IT87_CIR_RSR_RXFBC;
3962 +#ifdef DEBUG_SIGNAL
3963 +               printk(KERN_DEBUG LIRC_DRIVER_NAME
3964 +                      "iir: 0x%x fifo: 0x%x\n", iir, lsr);
3965 +#endif
3966 +       
3967 +               /* avoid interference with timer */
3968 +               spin_lock_irqsave(&timer_lock, flags);
3969 +               spin_lock_irqsave(&hardware_lock, hw_flags);
3970 +               do {
3971 +                       del_timer(&timerlist);
3972 +                       data = inb(io + IT87_CIR_DR);
3973 +#ifdef DEBUG_SIGNAL
3974 +                       printk(KERN_DEBUG LIRC_DRIVER_NAME
3975 +                              ": data=%.2x\n",
3976 +                              data);
3977 +#endif
3978 +                       do_gettimeofday(&curr_tv);
3979 +                       deltv = delta(&last_tv, &curr_tv);
3980 +                       deltintrtv = delta(&last_intr_tv, &curr_tv);
3981 +#ifdef DEBUG_SIGNAL
3982 +                       printk(KERN_DEBUG LIRC_DRIVER_NAME
3983 +                              ": t %lu , d %d\n",
3984 +                              deltintrtv,
3985 +                              (int)data);
3986 +#endif
3987 +                       /* if nothing came in last 2 cycles,
3988 +                          it was gap */
3989 +                       if (deltintrtv > TIME_CONST * 2) {
3990 +                               if (last_value) {
3991 +#ifdef DEBUG_SIGNAL
3992 +                                       printk(KERN_DEBUG LIRC_DRIVER_NAME ": GAP\n");
3993 +#endif
3994 +                                       /* simulate signal change */
3995 +                                       add_read_queue(last_value,
3996 +                                                      deltv-
3997 +                                                      deltintrtv);
3998 +                                       last_value = 0;
3999 +                                       last_tv.tv_sec = last_intr_tv.tv_sec;
4000 +                                       last_tv.tv_usec = last_intr_tv.tv_usec;
4001 +                                       deltv = deltintrtv;
4002 +                               }
4003 +                       }
4004 +                       data = 1;
4005 +                       if (data ^ last_value) {
4006 +                               /* deltintrtv > 2*TIME_CONST,
4007 +                                  remember ? */
4008 +                               /* the other case is timeout */
4009 +                               add_read_queue(last_value,
4010 +                                              deltv-TIME_CONST);
4011 +                               last_value = data;
4012 +                               last_tv = curr_tv;
4013 +                               if(last_tv.tv_usec>=TIME_CONST) {
4014 +                                       last_tv.tv_usec-=TIME_CONST;
4015 +                               }
4016 +                               else {
4017 +                                       last_tv.tv_sec--;
4018 +                                       last_tv.tv_usec+=1000000-
4019 +                                               TIME_CONST;
4020 +                               }
4021 +                       }
4022 +                       last_intr_tv = curr_tv;
4023 +                       if (data) {
4024 +                               /* start timer for end of sequence detection */
4025 +                               timerlist.expires = jiffies + IT87_TIMEOUT;
4026 +                               add_timer(&timerlist);
4027 +                       }
4028 +                       outb((inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN) |
4029 +                            IT87_CIR_RCR_RXACT,
4030 +                            io + IT87_CIR_RCR);
4031 +                       if (it87_RXEN_mask) {
4032 +                               outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN, 
4033 +                                    io + IT87_CIR_RCR);
4034 +                       }
4035 +                       fifo--;
4036 +               }
4037 +               while (fifo != 0);
4038 +               spin_unlock_irqrestore(&hardware_lock, hw_flags);
4039 +               spin_unlock_irqrestore(&timer_lock, flags);
4040 +               
4041 +               return IRQ_RETVAL(IRQ_HANDLED);
4042 +
4043 +       default:
4044 +               /* not our irq */
4045 +#ifdef DEBUG_SIGNAL
4046 +               printk(KERN_DEBUG LIRC_DRIVER_NAME
4047 +                      "unknown IRQ (shouldn't happen) !!\n");
4048 +#endif
4049 +               return IRQ_RETVAL(IRQ_NONE);
4050 +       }
4051 +}
4052 +
4053 +
4054 +static void send_it87(unsigned long len,
4055 +                     unsigned long stime,
4056 +                     unsigned char send_byte,
4057 +                     unsigned int count_bits)
4058 +{
4059 +        long count = len / stime;
4060 +       long time_left = 0;
4061 +       static unsigned char byte_out = 0;
4062 +
4063 +#ifdef DEBUG_SIGNAL
4064 +       printk(KERN_DEBUG LIRC_DRIVER_NAME
4065 +              "send_it87: len=%ld, sb=%d\n",
4066 +              len,
4067 +              send_byte);
4068 +#endif
4069 +       time_left = (long)len - (long)count * (long)stime;
4070 +       count += ((2 * time_left) / stime);
4071 +       while (count) {
4072 +               long i=0;
4073 +               for (i=0; i<count_bits; i++) {
4074 +                       byte_out = (byte_out << 1) | (send_byte & 1);
4075 +                       it87_bits_in_byte_out++;
4076 +               }
4077 +               if (it87_bits_in_byte_out == 8) {
4078 +#ifdef DEBUG_SIGNAL
4079 +                       printk(KERN_DEBUG LIRC_DRIVER_NAME
4080 +                              "out=0x%x, tsr_txfbc: 0x%x\n",
4081 +                              byte_out,
4082 +                              inb(io + IT87_CIR_TSR) &
4083 +                              IT87_CIR_TSR_TXFBC);
4084 +#endif
4085 +                       while ((inb(io + IT87_CIR_TSR) &
4086 +                               IT87_CIR_TSR_TXFBC) >= IT87_CIR_FIFO_SIZE);
4087 +                       {
4088 +                               unsigned long hw_flags;
4089 +
4090 +                               spin_lock_irqsave(&hardware_lock, hw_flags);
4091 +                               outb(byte_out, io + IT87_CIR_DR);
4092 +                               spin_unlock_irqrestore(&hardware_lock, hw_flags);
4093 +                       }
4094 +                       it87_bits_in_byte_out = 0;
4095 +                       it87_send_counter++;
4096 +                       byte_out = 0;
4097 +               }
4098 +               count--;
4099 +       }
4100 +}
4101 +
4102 +
4103 +/*
4104 +maybe: exchange space and pulse because
4105 +it8705 only modulates 0-bits
4106 +*/
4107 +
4108 +
4109 +static void send_space(unsigned long len)
4110 +{
4111 +       send_it87(len,
4112 +                 TIME_CONST,
4113 +                 IT87_CIR_SPACE,
4114 +                 IT87_CIR_BAUDRATE_DIVISOR);
4115 +}
4116 +
4117 +static void send_pulse(unsigned long len)
4118 +{
4119 +       send_it87(len,
4120 +                 TIME_CONST,
4121 +                 IT87_CIR_PULSE,
4122 +                 IT87_CIR_BAUDRATE_DIVISOR);
4123 +}
4124 +
4125 +
4126 +static void init_send()
4127 +{
4128 +       unsigned long flags;
4129 +
4130 +       spin_lock_irqsave(&hardware_lock, flags);
4131 +       /* RXEN=0: receiver disable */
4132 +       it87_RXEN_mask = 0;
4133 +       outb(inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN,
4134 +            io + IT87_CIR_RCR);
4135 +       spin_unlock_irqrestore(&hardware_lock, flags);
4136 +       it87_bits_in_byte_out = 0;
4137 +       it87_send_counter = 0;
4138 +}
4139 +
4140 +
4141 +static void terminate_send(unsigned long len)
4142 +{
4143 +       unsigned long flags;
4144 +       unsigned long last = 0;
4145 +
4146 +       last = it87_send_counter;
4147 +       /* make sure all necessary data has been sent */
4148 +       while (last == it87_send_counter)
4149 +               send_space(len);
4150 +       /* wait until all data sent */
4151 +       while ((inb(io + IT87_CIR_TSR) & IT87_CIR_TSR_TXFBC) != 0);
4152 +       /* then reenable receiver */
4153 +       spin_lock_irqsave(&hardware_lock, flags);
4154 +       it87_RXEN_mask = IT87_CIR_RCR_RXEN;
4155 +       outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN,
4156 +            io + IT87_CIR_RCR);
4157 +       spin_unlock_irqrestore(&hardware_lock, flags);
4158 +}
4159 +
4160 +
4161 +static int init_hardware(void)
4162 +{
4163 +       unsigned long flags;
4164 +       unsigned char it87_rcr = 0;
4165 +       
4166 +       spin_lock_irqsave(&hardware_lock, flags);
4167 +       /* init cir-port */
4168 +       /* enable r/w-access to Baudrate-Register */
4169 +       outb(IT87_CIR_IER_BR, io + IT87_CIR_IER);
4170 +       outb(IT87_CIR_BAUDRATE_DIVISOR % 0x100, io+IT87_CIR_BDLR);
4171 +       outb(IT87_CIR_BAUDRATE_DIVISOR / 0x100, io+IT87_CIR_BDHR);
4172 +       /* Baudrate Register off, define IRQs: Input only */
4173 +       outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RDAIE, io + IT87_CIR_IER);
4174 +       /* RX: HCFS=0, RXDCR = 001b (35,6..40,3 kHz), RXEN=1 */
4175 +       it87_rcr = (IT87_CIR_RCR_RXEN & it87_RXEN_mask) | 0x1;
4176 +       if (it87_enable_demodulator)
4177 +               it87_rcr |= IT87_CIR_RCR_RXEND;
4178 +       outb(it87_rcr, io + IT87_CIR_RCR);
4179 +       /* TX: 38kHz, 13,3us (pulse-width */
4180 +       outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x06,
4181 +            io + IT87_CIR_TCR2);
4182 +       spin_unlock_irqrestore(&hardware_lock, flags);
4183 +       return 0;
4184 +}
4185 +
4186 +
4187 +static void drop_hardware(void)
4188 +{
4189 +       unsigned long flags;
4190 +       
4191 +       spin_lock_irqsave(&hardware_lock, flags);
4192 +       disable_irq(irq);
4193 +       /* receiver disable */
4194 +       it87_RXEN_mask = 0;
4195 +       outb(0x1, io + IT87_CIR_RCR);
4196 +       /* turn off irqs */
4197 +       outb(0, io + IT87_CIR_IER);
4198 +       /* fifo clear */
4199 +        outb(IT87_CIR_TCR1_FIFOCLR, io+IT87_CIR_TCR1);
4200 +        /* reset */
4201 +        outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER);
4202 +       enable_irq(irq);
4203 +       spin_unlock_irqrestore(&hardware_lock, flags);
4204 +}
4205 +
4206 +
4207 +static unsigned char it87_read(unsigned char port)
4208 +{
4209 +       outb(port, IT87_ADRPORT);
4210 +       return inb(IT87_DATAPORT);
4211 +}
4212 +
4213 +
4214 +static void it87_write(unsigned char port,
4215 +                      unsigned char data)
4216 +{
4217 +       outb(port, IT87_ADRPORT);
4218 +       outb(data, IT87_DATAPORT);
4219 +}
4220 +
4221 +
4222 +/* SECTION: Initialisation */
4223 +
4224 +static int init_port(void)
4225 +{
4226 +       int retval = 0;
4227 +       
4228 +       unsigned char init_bytes[4] = {IT87_INIT};
4229 +       unsigned char it87_chipid = 0;
4230 +       unsigned char ldn = 0;
4231 +       unsigned int  it87_io = 0;
4232 +       unsigned int  it87_irq = 0;
4233 +       
4234 +       /* Enter MB PnP Mode */
4235 +       outb(init_bytes[0], IT87_ADRPORT);
4236 +       outb(init_bytes[1], IT87_ADRPORT);
4237 +       outb(init_bytes[2], IT87_ADRPORT);
4238 +       outb(init_bytes[3], IT87_ADRPORT);
4239 +       
4240 +       /* 8712 or 8705 ? */
4241 +       it87_chipid = it87_read(IT87_CHIP_ID1);
4242 +       if (it87_chipid != 0x87) {
4243 +               retval = -ENXIO;
4244 +               return retval;
4245 +       }
4246 +       it87_chipid = it87_read(IT87_CHIP_ID2);
4247 +       if ((it87_chipid != 0x12) && (it87_chipid != 0x05)) {
4248 +               printk(KERN_INFO LIRC_DRIVER_NAME
4249 +                      ": no IT8705/12 found, exiting..\n");
4250 +               retval = -ENXIO;
4251 +               return retval;
4252 +       }
4253 +       printk(KERN_INFO LIRC_DRIVER_NAME
4254 +              ": found IT87%.2x.\n",
4255 +              it87_chipid);
4256 +
4257 +       /* get I/O-Port and IRQ */
4258 +       if (it87_chipid == 0x12)
4259 +               ldn = IT8712_CIR_LDN;
4260 +       else
4261 +               ldn = IT8705_CIR_LDN;
4262 +       it87_write(IT87_LDN, ldn);
4263 +       
4264 +       it87_io = it87_read(IT87_CIR_BASE_MSB) * 256 +
4265 +               it87_read(IT87_CIR_BASE_LSB);
4266 +       if (it87_io == 0) {
4267 +               if (io == 0)
4268 +                       io = IT87_CIR_DEFAULT_IOBASE;
4269 +               printk(KERN_INFO LIRC_DRIVER_NAME
4270 +                      ": set default io 0x%x\n",
4271 +                      io);
4272 +               it87_write(IT87_CIR_BASE_MSB, io / 0x100);
4273 +               it87_write(IT87_CIR_BASE_LSB, io % 0x100);
4274 +       }
4275 +       else
4276 +               io = it87_io;
4277 +       
4278 +       it87_irq = it87_read(IT87_CIR_IRQ);
4279 +       if (it87_irq == 0) {
4280 +               if (irq == 0)
4281 +                       irq = IT87_CIR_DEFAULT_IRQ;
4282 +               printk(KERN_INFO LIRC_DRIVER_NAME
4283 +                      ": set default irq 0x%x\n",
4284 +                      irq);
4285 +               it87_write(IT87_CIR_IRQ, irq);
4286 +       }
4287 +       else
4288 +               irq = it87_irq;
4289 +       
4290 +       {
4291 +               unsigned long hw_flags;
4292 +
4293 +               spin_lock_irqsave(&hardware_lock, hw_flags);
4294 +               /* reset */
4295 +               outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER);
4296 +               /* fifo clear */
4297 +               outb(IT87_CIR_TCR1_FIFOCLR |
4298 +                    /*      IT87_CIR_TCR1_ILE | */
4299 +                    IT87_CIR_TCR1_TXRLE |
4300 +                    IT87_CIR_TCR1_TXENDF, io+IT87_CIR_TCR1);
4301 +               spin_unlock_irqrestore(&hardware_lock, hw_flags);
4302 +       }
4303 +       
4304 +       /* get I/O port access and IRQ line */
4305 +       retval = check_region(io, 8);
4306 +       if (retval < 0) {
4307 +               printk(KERN_ERR LIRC_DRIVER_NAME
4308 +                      ": i/o port 0x%.4x already in use.\n",
4309 +                      io);
4310 +               /* Leaving MB PnP Mode */
4311 +               it87_write(IT87_CFGCTRL, 0x2);
4312 +               return retval;
4313 +       }
4314 +
4315 +       /* activate CIR-Device */
4316 +       it87_write(IT87_CIR_ACT, 0x1);
4317 +
4318 +       /* Leaving MB PnP Mode */
4319 +       it87_write(IT87_CFGCTRL, 0x2);
4320 +
4321 +       retval = request_irq(irq, it87_interrupt, 0 /*SA_INTERRUPT*/,
4322 +                            LIRC_DRIVER_NAME, NULL);
4323 +       if (retval < 0) {
4324 +               printk(KERN_ERR LIRC_DRIVER_NAME
4325 +                      ": IRQ %d already in use.\n",
4326 +                      irq);
4327 +               return retval;
4328 +       }
4329 +
4330 +       request_region(io, 8, LIRC_DRIVER_NAME);
4331 +       printk(KERN_INFO LIRC_DRIVER_NAME
4332 +              ": I/O port 0x%.4x, IRQ %d.\n",
4333 +              io,
4334 +              irq);
4335 +
4336 +       init_timer(&timerlist);
4337 +       timerlist.function = it87_timeout;
4338 +       timerlist.data = 0xabadcafe;
4339 +       
4340 +       return 0;
4341 +}
4342 +
4343 +
4344 +static void drop_port(void)
4345 +{
4346 +/*
4347 +        unsigned char init_bytes[4] = {IT87_INIT};
4348
4349 +        / * Enter MB PnP Mode * /
4350 +        outb(init_bytes[0], IT87_ADRPORT);
4351 +        outb(init_bytes[1], IT87_ADRPORT);
4352 +        outb(init_bytes[2], IT87_ADRPORT);
4353 +        outb(init_bytes[3], IT87_ADRPORT);
4354 +
4355 +        / * deactivate CIR-Device * /
4356 +        it87_write(IT87_CIR_ACT, 0x0);
4357 +
4358 +        / * Leaving MB PnP Mode * /
4359 +        it87_write(IT87_CFGCTRL, 0x2);
4360 +*/
4361 +
4362 +       del_timer_sync(&timerlist);
4363 +       free_irq(irq, NULL);
4364 +       release_region(io, 8);
4365 +}
4366 +
4367 +
4368 +int init_lirc_it87(void)
4369 +{
4370 +       int retval;
4371 +       
4372 +       init_waitqueue_head(&lirc_read_queue);
4373 +       retval = init_port();
4374 +       if (retval < 0)
4375 +               return retval;
4376 +       init_hardware();
4377 +       printk(KERN_INFO LIRC_DRIVER_NAME
4378 +              ": Installed.\n");
4379 +       return 0;
4380 +}
4381 +
4382 +
4383 +#ifdef MODULE
4384 +
4385 +MODULE_AUTHOR("Hans-Günter Lütke Uphues");
4386 +MODULE_DESCRIPTION("LIRC driver for ITE IT8712/IT8705 CIR port");
4387 +MODULE_PARM(io, "i");
4388 +MODULE_PARM_DESC(io,
4389 +                "I/O base address (default: 0x310)");
4390 +MODULE_PARM(irq, "i");
4391 +MODULE_PARM_DESC(irq,
4392 +                "Interrupt (1,3-12) (default: 7)");
4393 +MODULE_PARM(it87_enable_demodulator, "i");
4394 +MODULE_PARM_DESC(it87_enable_demodulator,
4395 +                "Receiver demodulator enable/disable (1/0), default: 0");
4396 +#ifdef MODULE_LICENSE
4397 +MODULE_LICENSE("GPL");
4398 +#endif
4399 +
4400 +#ifndef KERNEL_2_5
4401 +EXPORT_NO_SYMBOLS;
4402 +#endif
4403 +
4404 +
4405 +int init_module(void)
4406 +{
4407 +       int retval;
4408 +       
4409 +       retval=init_chrdev();
4410 +       if(retval < 0)
4411 +               return retval;
4412 +       retval = init_lirc_it87();
4413 +       if (retval) {
4414 +               drop_chrdev();
4415 +               return retval;
4416 +       }
4417 +       return 0;
4418 +}
4419 +
4420 +
4421 +void cleanup_module(void)
4422 +{
4423 +       drop_hardware();
4424 +       drop_chrdev();
4425 +       drop_port();
4426 +       printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n");
4427 +}
4428 +#endif
4429 +
4430 +
4431 +/*
4432 + * Overrides for Emacs so that we follow Linus's tabbing style.
4433 + * ---------------------------------------------------------------------------
4434 + * Local variables:
4435 + * c-basic-offset: 8
4436 + * End:
4437 + */
4438 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_it87.h linux-2.6.8-rc4/drivers/char/lirc/lirc_it87.h
4439 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_it87.h  1970-01-01 01:00:00.000000000 +0100
4440 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_it87.h       2001-11-15 11:50:19.000000000 +0100
4441 @@ -0,0 +1,116 @@
4442 +/* lirc_it87.h */
4443 +/* SECTION: Definitions */
4444 +
4445 +/********************************* ITE IT87xx ************************/
4446 +
4447 +/* based on the following documentation from ITE:
4448 +   a) IT8712F Preliminary CIR Programming Guide V0.1
4449 +   b) IT8705F Simple LPC I/O Preliminary Specifiction V0.3
4450 +   c) IT8712F EC-LPC I/O Preliminary Specification V0.5
4451 +*/
4452 +
4453 +/* IT8712/05 Ports: */
4454 +#define IT87_ADRPORT      0x2e
4455 +#define IT87_DATAPORT     0x2f
4456 +#define IT87_INIT         0x87, 0x01, 0x55, 0x55
4457 +
4458 +/* alternate Ports: */
4459 +/*
4460 +#define IT87_ADRPORT      0x4e
4461 +#define IT87_DATAPORT     0x4f
4462 +#define IT87_INIT         0x87, 0x01, 0x55, 0xaa
4463 + */
4464 +
4465 +/* IT8712/05 Registers */
4466 +#define IT87_CFGCTRL      0x2
4467 +#define IT87_LDN          0x7
4468 +#define IT87_CHIP_ID1     0x20
4469 +#define IT87_CHIP_ID2     0x21
4470 +#define IT87_CFG_VERSION  0x22
4471 +#define IT87_SWSUSPEND    0x23
4472 +
4473 +#define IT8712_CIR_LDN    0xa
4474 +#define IT8705_CIR_LDN    0x7
4475 +
4476 +/* CIR Configuration Registers: */
4477 +#define IT87_CIR_ACT      0x30
4478 +#define IT87_CIR_BASE_MSB 0x60
4479 +#define IT87_CIR_BASE_LSB 0x61
4480 +#define IT87_CIR_IRQ      0x70
4481 +#define IT87_CIR_CONFIG   0xf0
4482 +
4483 +/* List of IT87_CIR registers: offset to BaseAddr */
4484 +#define IT87_CIR_DR   0
4485 +#define IT87_CIR_IER  1
4486 +#define IT87_CIR_RCR  2
4487 +#define IT87_CIR_TCR1 3
4488 +#define IT87_CIR_TCR2 4
4489 +#define IT87_CIR_TSR  5
4490 +#define IT87_CIR_RSR  6
4491 +#define IT87_CIR_BDLR 5
4492 +#define IT87_CIR_BDHR 6
4493 +#define IT87_CIR_IIR  7
4494 +
4495 +/* Bit Definitionen */
4496 +/* IER: */
4497 +#define IT87_CIR_IER_TM_EN   0x80
4498 +#define IT87_CIR_IER_RESEVED 0x40
4499 +#define IT87_CIR_IER_RESET   0x20
4500 +#define IT87_CIR_IER_BR      0x10
4501 +#define IT87_CIR_IER_IEC     0x8
4502 +#define IT87_CIR_IER_RFOIE   0x4
4503 +#define IT87_CIR_IER_RDAIE   0x2
4504 +#define IT87_CIR_IER_TLDLIE  0x1
4505 +
4506 +/* RCR: */
4507 +#define IT87_CIR_RCR_RDWOS  0x80
4508 +#define IT87_CIR_RCR_HCFS   0x40
4509 +#define IT87_CIR_RCR_RXEN   0x20
4510 +#define IT87_CIR_RCR_RXEND  0x10
4511 +#define IT87_CIR_RCR_RXACT  0x8
4512 +#define IT87_CIR_RCR_RXDCR  0x7
4513 +
4514 +/* TCR1: */
4515 +#define IT87_CIR_TCR1_FIFOCLR 0x80
4516 +#define IT87_CIR_TCR1_ILE     0x40
4517 +#define IT87_CIR_TCR1_FIFOTL  0x30
4518 +#define IT87_CIR_TCR1_TXRLE   0x8
4519 +#define IT87_CIR_TCR1_TXENDF  0x4
4520 +#define IT87_CIR_TCR1_TXMPM   0x3
4521 +
4522 +/* TCR2: */
4523 +#define IT87_CIR_TCR2_CFQ   0xf8
4524 +#define IT87_CIR_TCR2_TXMPW 0x7
4525 +
4526 +/* TSR: */
4527 +#define IT87_CIR_TSR_RESERVED 0xc0
4528 +#define IT87_CIR_TSR_TXFBC    0x3f
4529 +
4530 +/* RSR: */
4531 +#define IT87_CIR_RSR_RXFTO    0x80
4532 +#define IT87_CIR_RSR_RESERVED 0x40
4533 +#define IT87_CIR_RSR_RXFBC    0x3f
4534 +
4535 +/* IIR: */
4536 +#define IT87_CIR_IIR_RESERVED 0xf8
4537 +#define IT87_CIR_IIR_IID      0x6
4538 +#define IT87_CIR_IIR_IIP      0x1
4539 +
4540 +/* TM: */
4541 +#define IT87_CIR_TM_IL_SEL    0x80
4542 +#define IT87_CIR_TM_RESERVED  0x40
4543 +#define IT87_CIR_TM_TM_REG    0x3f
4544 +
4545 +#define IT87_CIR_FIFO_SIZE 32
4546 +
4547 +/* Baudratedivisor for IT87: power of 2: only 1,2,4 or 8) */
4548 +#define IT87_CIR_BAUDRATE_DIVISOR 0x1
4549 +#define IT87_CIR_DEFAULT_IOBASE 0x310
4550 +#define IT87_CIR_DEFAULT_IRQ    0x7
4551 +#define IT87_CIR_SPACE 0x00
4552 +#define IT87_CIR_PULSE 0xff
4553 +#define IT87_CIR_FREQ_MIN 27
4554 +#define IT87_CIR_FREQ_MAX 58
4555 +#define TIME_CONST (IT87_CIR_BAUDRATE_DIVISOR * 8000000ul / 115200ul)
4556 +
4557 +/********************************* ITE IT87xx ************************/
4558 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_mceusb.c linux-2.6.8-rc4/drivers/char/lirc/lirc_mceusb.c
4559 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_mceusb.c        1970-01-01 01:00:00.000000000 +0100
4560 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_mceusb.c     2004-07-25 18:27:33.000000000 +0200
4561 @@ -0,0 +1,1026 @@
4562 +/*
4563 + * USB Microsoft IR Transceiver driver - 0.2
4564 + *
4565 + * Copyright (c) 2003-2004 Dan Conti (dconti@acm.wwu.edu)
4566 + *
4567 + * This driver is based on the USB skeleton driver packaged with the
4568 + * kernel, and the notice from that package has been retained below.
4569 + *
4570 + * The Microsoft IR Transceiver is a neat little IR receiver with two
4571 + * emitters on it designed for Windows Media Center. This driver might
4572 + * work for all media center remotes, but I have only tested it with
4573 + * the philips model. The first revision of this driver only supports
4574 + * the receive function - the transmit function will be much more
4575 + * tricky due to the nature of the hardware. Microsoft chose to build
4576 + * this device inexpensively, therefore making it extra dumb.
4577 + * There is no interrupt endpoint on this device; all usb traffic
4578 + * happens over two bulk endpoints. As a result of this, poll() for
4579 + * this device is an actual hardware poll (instead of a receive queue
4580 + * check) and is rather expensive.
4581 + *
4582 + * All trademarks property of their respective owners. This driver was
4583 + * originally based on the USB skeleton driver, although significant
4584 + * portions of that code have been removed as the driver has evolved.
4585 + *
4586 + * 2003_11_11 - Restructured to minimalize code interpretation in the
4587 + *              driver. The normal use case will be with lirc.
4588 + *
4589 + * 2004_01_01 - Removed all code interpretation. Generate mode2 data
4590 + *              for passing off to lirc. Cleanup
4591 + *
4592 + * 2004_01_04 - Removed devfs handle. Put in a temporary workaround
4593 + *              for a known issue where repeats generate two
4594 + *              sequential spaces (last_was_repeat_gap)
4595 + *
4596 + * 2004_02_17 - Changed top level api to no longer use fops, and
4597 + *              instead use new interface for polling via
4598 + *              lirc_thread. Restructure data read/mode2 generation to
4599 + *              a single pass, reducing number of buffers. Rev to .2
4600 + *
4601 + * 2004_02_27 - Last of fixups to plugin->add_to_buf API. Properly
4602 + *              handle broken fragments from the receiver. Up the
4603 + *              sample rate and remove any pacing from
4604 + *              fetch_more_data. Fixes all known issues.
4605 + * 
4606 + * TODO
4607 + *   - Fix up minor number, registration of major/minor with usb subsystem
4608 + *
4609 + */
4610 +/*
4611 + * USB Skeleton driver - 1.1
4612 + *
4613 + * Copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com)
4614 + *
4615 + *     This program is free software; you can redistribute it and/or
4616 + *     modify it under the terms of the GNU General Public License as
4617 + *     published by the Free Software Foundation, version 2.
4618 + *
4619 + *
4620 + * This driver is to be used as a skeleton driver to be able to create a
4621 + * USB driver quickly.  The design of it is based on the usb-serial and
4622 + * dc2xx drivers.
4623 + *
4624 + * Thanks to Oliver Neukum, David Brownell, and Alan Stern for their help
4625 + * in debugging this driver.
4626 + *
4627 + *
4628 + * History:
4629 + *
4630 + * 2003-05-06 - 1.1 - changes due to usb core changes with usb_register_dev()
4631 + * 2003-02-25 - 1.0 - fix races involving urb->status, unlink_urb(), and
4632 + *                     disconnect.  Fix transfer amount in read().  Use
4633 + *                     macros instead of magic numbers in probe().  Change
4634 + *                     size variables to size_t.  Show how to eliminate
4635 + *                     DMA bounce buffer.
4636 + * 2002_12_12 - 0.9 - compile fixes and got rid of fixed minor array.
4637 + * 2002_09_26 - 0.8 - changes due to USB core conversion to struct device
4638 + *                     driver.
4639 + * 2002_02_12 - 0.7 - zero out dev in probe function for devices that do
4640 + *                     not have both a bulk in and bulk out endpoint.
4641 + *                     Thanks to Holger Waechtler for the fix.
4642 + * 2001_11_05 - 0.6 - fix minor locking problem in skel_disconnect.
4643 + *                     Thanks to Pete Zaitcev for the fix.
4644 + * 2001_09_04 - 0.5 - fix devfs bug in skel_disconnect. Thanks to wim delvaux
4645 + * 2001_08_21 - 0.4 - more small bug fixes.
4646 + * 2001_05_29 - 0.3 - more bug fixes based on review from linux-usb-devel
4647 + * 2001_05_24 - 0.2 - bug fixes based on review from linux-usb-devel people
4648 + * 2001_05_01 - 0.1 - first version
4649 + *
4650 + */
4651 +
4652 +#include <linux/config.h>
4653 +#include <linux/kernel.h>
4654 +#include <linux/errno.h>
4655 +#include <linux/init.h>
4656 +#include <linux/slab.h>
4657 +#include <linux/module.h>
4658 +#include <linux/smp_lock.h>
4659 +#include <linux/usb.h>
4660 +#ifdef KERNEL_2_5
4661 +#include <linux/completion.h>
4662 +#include <asm/uaccess.h>
4663 +#else
4664 +#include <linux/spinlock.h>
4665 +#include <linux/list.h>
4666 +#include <linux/fcntl.h>
4667 +#include <linux/poll.h>
4668 +#include <linux/sched.h>
4669 +#include <linux/signal.h>
4670 +#endif
4671 +
4672 +#ifdef CONFIG_USB_DEBUG
4673 +       static int debug = 1;
4674 +#else
4675 +       static int debug;
4676 +#endif
4677 +
4678 +#include <linux/lirc.h>
4679 +#include "kcompat.h"
4680 +#include "lirc_dev.h"
4681 +
4682 +
4683 +/* Use our own dbg macro */
4684 +#undef dbg
4685 +#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0)
4686 +
4687 +/* Version Information */
4688 +#define DRIVER_VERSION "v0.2"
4689 +#define DRIVER_AUTHOR "Dan Conti, dconti@acm.wwu.edu"
4690 +#define DRIVER_DESC "USB Microsoft IR Transceiver Driver"
4691 +#define DRIVER_NAME "lirc_mceusb"
4692 +
4693 +/* Module paramaters */
4694 +MODULE_PARM(debug, "i");
4695 +MODULE_PARM_DESC(debug, "Debug enabled or not");
4696 +
4697 +/* Define these values to match your device */
4698 +#define USB_MCEUSB_VENDOR_ID   0x045e
4699 +#define USB_MCEUSB_PRODUCT_ID  0x006d
4700 +
4701 +/* table of devices that work with this driver */
4702 +static struct usb_device_id mceusb_table [] = {
4703 +       { USB_DEVICE(USB_MCEUSB_VENDOR_ID, USB_MCEUSB_PRODUCT_ID) },
4704 +       { }                                     /* Terminating entry */
4705 +};
4706 +
4707 +MODULE_DEVICE_TABLE (usb, mceusb_table);
4708 +
4709 +/* we can have up to this number of device plugged in at once */
4710 +#define MAX_DEVICES            16
4711 +
4712 +/* Structure to hold all of our device specific stuff */
4713 +struct usb_skel {
4714 +       struct usb_device *         udev;               /* save off the usb device pointer */
4715 +       struct usb_interface *  interface;              /* the interface for this device */
4716 +       unsigned char   minor;                          /* the starting minor number for this device */
4717 +       unsigned char   num_ports;                      /* the number of ports this device has */
4718 +       char            num_interrupt_in;               /* number of interrupt in endpoints we have */
4719 +       char            num_bulk_in;                    /* number of bulk in endpoints we have */
4720 +       char            num_bulk_out;                   /* number of bulk out endpoints we have */
4721 +
4722 +       unsigned char *    bulk_in_buffer;              /* the buffer to receive data */
4723 +       int                bulk_in_size;                /* the size of the receive buffer */
4724 +       __u8               bulk_in_endpointAddr;        /* the address of the bulk in endpoint */
4725 +
4726 +       unsigned char *    bulk_out_buffer;             /* the buffer to send data */
4727 +       int                    bulk_out_size;           /* the size of the send buffer */
4728 +       struct urb *       write_urb;                   /* the urb used to send data */
4729 +       __u8               bulk_out_endpointAddr;       /* the address of the bulk out endpoint */
4730 +
4731 +       atomic_t                write_busy;             /* true iff write urb is busy */
4732 +       struct completion       write_finished;         /* wait for the write to finish */
4733 +       
4734 +       wait_queue_head_t  wait_q;                      /* for timeouts */
4735 +       int                open_count;                  /* number of times this port has been opened */
4736 +       struct semaphore   sem;                         /* locks this structure */
4737 +       
4738 +       int                     present;                /* if the device is not disconnected */         
4739 +
4740 +       struct lirc_plugin* plugin;
4741 +       
4742 +       lirc_t lircdata[256];                           /* place to store values until lirc processes them */
4743 +       int    lircidx;                                 /* current index */
4744 +       int    lirccnt;                                 /* remaining values */
4745 +       
4746 +       int    usb_valid_bytes_in_bulk_buffer;          /* leftover data from a previous read */
4747 +       int    mce_bytes_left_in_packet;                /* for packets split across multiple reads */
4748 +       
4749 +       /* Value to hold the last received space; 0 if last value
4750 +        * received was a pulse
4751 +        */
4752 +       int    last_space;
4753 +       
4754 +#ifdef KERNEL_2_5
4755 +       dma_addr_t dma_in;
4756 +       dma_addr_t dma_out;
4757 +#endif
4758 +};
4759 +
4760 +#define MCE_TIME_UNIT 50
4761 +
4762 +/* driver api */
4763 +#ifdef KERNEL_2_5
4764 +static int mceusb_probe                (struct usb_interface *interface, const struct usb_device_id *id);
4765 +static void mceusb_disconnect  (struct usb_interface *interface);
4766 +static void mceusb_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
4767 +#else
4768 +static void * mceusb_probe     (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id);
4769 +static void mceusb_disconnect  (struct usb_device *dev, void *ptr);
4770 +static void mceusb_write_bulk_callback (struct urb *urb);
4771 +#endif
4772 +
4773 +/* read data from the usb bus; convert to mode2 */
4774 +static int msir_fetch_more_data( struct usb_skel* dev, int dont_block );
4775 +
4776 +/* helper functions */
4777 +static void msir_cleanup( struct usb_skel* dev );
4778 +static void set_use_dec( void* data );
4779 +static int set_use_inc( void* data );
4780 +    
4781 +/* array of pointers to our devices that are currently connected */
4782 +static struct usb_skel         *minor_table[MAX_DEVICES];
4783 +
4784 +/* lock to protect the minor_table structure */
4785 +static DECLARE_MUTEX (minor_table_mutex);
4786 +static void mceusb_setup( struct usb_device *udev );
4787 +
4788 +/* usb specific object needed to register this driver with the usb subsystem */
4789 +static struct usb_driver mceusb_driver = {
4790 +       .owner =        THIS_MODULE,
4791 +       .name =         DRIVER_NAME,
4792 +       .probe =        mceusb_probe,
4793 +       .disconnect =   mceusb_disconnect,
4794 +       .id_table =     mceusb_table,
4795 +};
4796 +
4797 +
4798 +/**
4799 + *     usb_mceusb_debug_data
4800 + */
4801 +static inline void usb_mceusb_debug_data (const char *function, int size,
4802 +                                         const unsigned char *data)
4803 +{
4804 +       int i;
4805 +
4806 +       if (!debug)
4807 +               return;
4808 +       
4809 +       printk (KERN_DEBUG __FILE__": %s - length = %d, data = ", 
4810 +               function, size);
4811 +       for (i = 0; i < size; ++i) {
4812 +               printk ("%.2x ", data[i]);
4813 +       }
4814 +       printk ("\n");
4815 +}
4816 +
4817 +/**
4818 + *mceusb_delete
4819 + */
4820 +static inline void mceusb_delete (struct usb_skel *dev)
4821 +{
4822 +       dbg("%s",__func__);
4823 +       minor_table[dev->minor] = NULL;
4824 +#ifdef KERNEL_2_5
4825 +       usb_buffer_free(dev->udev, dev->bulk_in_size, dev->bulk_in_buffer, dev->dma_in);
4826 +       usb_buffer_free(dev->udev, dev->bulk_out_size, dev->bulk_out_buffer, dev->dma_out);
4827 +#else
4828 +       if (dev->bulk_in_buffer != NULL)
4829 +               kfree (dev->bulk_in_buffer);
4830 +       if (dev->bulk_out_buffer != NULL)
4831 +               kfree (dev->bulk_out_buffer);
4832 +#endif
4833 +       if (dev->write_urb != NULL)
4834 +               usb_free_urb (dev->write_urb);
4835 +       kfree (dev);
4836 +}
4837 +
4838 +static void mceusb_setup( struct usb_device *udev )
4839 +{
4840 +       char data[8];
4841 +       int res;
4842 +       
4843 +       memset( data, 0, 8 );
4844 +
4845 +       /* Get Status */
4846 +       res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
4847 +                             USB_REQ_GET_STATUS, USB_DIR_IN,
4848 +                             0, 0, data, 2, HZ * 3);
4849 +    
4850 +       /*    res = usb_get_status( udev, 0, 0, data ); */
4851 +       dbg("%s - res = %d status = 0x%x 0x%x",__func__,res,data[0],data[1]);
4852 +    
4853 +       /* This is a strange one. They issue a set address to the device
4854 +        * on the receive control pipe and expect a certain value pair back
4855 +        */
4856 +       memset( data, 0, 8 );
4857 +
4858 +       res = usb_control_msg( udev, usb_rcvctrlpipe(udev, 0),
4859 +                              5, USB_TYPE_VENDOR, 0, 0,
4860 +                              data, 2, HZ * 3 );
4861 +       dbg("%s - res = %d, devnum = %d", __func__, res, udev->devnum);
4862 +       dbg("%s - data[0] = %d, data[1] = %d", __func__, data[0], data[1] );
4863 +
4864 +    
4865 +       /* set feature */
4866 +       res = usb_control_msg( udev, usb_sndctrlpipe(udev, 0),
4867 +                              USB_REQ_SET_FEATURE, USB_TYPE_VENDOR,
4868 +                              0xc04e, 0x0000, NULL, 0, HZ * 3 );
4869 +    
4870 +       dbg("%s - res = %d", __func__, res);
4871 +
4872 +       /* These two are sent by the windows driver, but stall for
4873 +        * me. I dont have an analyzer on the linux side so i can't
4874 +        * see what is actually different and why the device takes
4875 +        * issue with them
4876 +        */
4877 +#if 0
4878 +       /* this is some custom control message they send */
4879 +       res = usb_control_msg( udev, usb_sndctrlpipe(udev, 0),
4880 +                              0x04, USB_TYPE_VENDOR,
4881 +                              0x0808, 0x0000, NULL, 0, HZ * 3 );
4882 +    
4883 +       dbg("%s - res = %d", __func__, res);
4884 +    
4885 +       /* this is another custom control message they send */
4886 +       res = usb_control_msg( udev, usb_sndctrlpipe(udev, 0),
4887 +                              0x02, USB_TYPE_VENDOR,
4888 +                              0x0000, 0x0100, NULL, 0, HZ * 3 );
4889 +    
4890 +       dbg("%s - res = %d", __func__, res);
4891 +#endif
4892 +}
4893 +
4894 +static void msir_cleanup( struct usb_skel* dev )
4895 +{
4896 +       memset( dev->bulk_in_buffer, 0, dev->bulk_in_size );
4897 +
4898 +       dev->usb_valid_bytes_in_bulk_buffer = 0;
4899 +
4900 +       dev->last_space = PULSE_MASK;
4901 +    
4902 +       dev->mce_bytes_left_in_packet = 0;
4903 +       dev->lircidx = 0;
4904 +       dev->lirccnt = 0;
4905 +       memset( dev->lircdata, 0, sizeof(dev->lircdata) );
4906 +}
4907 +
4908 +static int set_use_inc(void* data)
4909 +{
4910 +       MOD_INC_USE_COUNT;
4911 +       return 0;
4912 +}
4913 +
4914 +static void set_use_dec(void* data)
4915 +{
4916 +       /* check for unplug here */
4917 +       struct usb_skel* dev = (struct usb_skel*) data;
4918 +       if( !dev->udev )
4919 +       { 
4920 +               lirc_unregister_plugin( dev->minor );
4921 +               lirc_buffer_free( dev->plugin->rbuf );
4922 +               kfree( dev->plugin->rbuf );
4923 +               kfree( dev->plugin );
4924 +       }
4925 +       
4926 +       MOD_DEC_USE_COUNT;
4927 +}
4928 +
4929 +/*
4930 + * msir_fetch_more_data
4931 + *
4932 + * The goal here is to read in more remote codes from the remote. In
4933 + * the event that the remote isn't sending us anything, the caller
4934 + * will block until a key is pressed (i.e. this performs phys read,
4935 + * filtering, and queueing of data) unless dont_block is set to 1; in
4936 + * this situation, it will perform a few reads and will exit out if it
4937 + * does not see any appropriate data
4938 + *
4939 + * dev->sem should be locked when this function is called - fine grain
4940 + * locking isn't really important here anyways
4941 + *
4942 + * This routine always returns the number of words available
4943 + *
4944 + */
4945 +static int msir_fetch_more_data( struct usb_skel* dev, int dont_block )
4946 +{
4947 +       int retries = 0;
4948 +       int words_to_read = 
4949 +               (sizeof(dev->lircdata)/sizeof(lirc_t)) - dev->lirccnt;
4950 +       int partial, this_read = 0;
4951 +       int bulkidx = 0;
4952 +       int bytes_left_in_packet = 0;
4953 +       signed char* signedp = (signed char*)dev->bulk_in_buffer;
4954 +       
4955 +       if( words_to_read == 0 )
4956 +               return dev->lirccnt;
4957 +
4958 +       /* this forces all existing data to be read by lirc before we
4959 +        * issue another usb command. this is the only form of
4960 +        * throttling we have
4961 +        */
4962 +       if( dev->lirccnt )
4963 +       {
4964 +               return dev->lirccnt;
4965 +       }
4966 +
4967 +       /* reserve room for our leading space */
4968 +       if( dev->last_space )
4969 +               words_to_read--;
4970 +               
4971 +       while( words_to_read )
4972 +       {
4973 +               /* handle signals and USB disconnects */
4974 +               if( signal_pending(current) )
4975 +               {
4976 +                       return dev->lirccnt ? dev->lirccnt : -EINTR;
4977 +               }
4978 +               if( !dev->udev )
4979 +               {
4980 +                       return -ENODEV;
4981 +               }
4982 +
4983 +               bulkidx = 0;
4984 +
4985 +               /*
4986 +                * perform data read (phys or from previous buffer)
4987 +                */
4988 +        
4989 +               /* use leftovers if present, otherwise perform a read */
4990 +               if( dev->usb_valid_bytes_in_bulk_buffer )
4991 +               {
4992 +                       this_read = partial = 
4993 +                               dev->usb_valid_bytes_in_bulk_buffer;
4994 +                       dev->usb_valid_bytes_in_bulk_buffer = 0;
4995 +               }
4996 +               else
4997 +               {
4998 +                       int retval;
4999 +            
5000 +                       this_read = dev->bulk_in_size;
5001 +                       partial = 0;
5002 +                       retval = usb_bulk_msg
5003 +                               (dev->udev,
5004 +                                usb_rcvbulkpipe
5005 +                                (dev->udev, dev->bulk_in_endpointAddr),
5006 +                                (unsigned char*)dev->bulk_in_buffer,
5007 +                                this_read, &partial, HZ*10);
5008 +                       
5009 +                       /* retry a few times on overruns; map all
5010 +                          other errors to -EIO */
5011 +                       if( retval )
5012 +                       {
5013 +                               if( retval == -EOVERFLOW && 
5014 +                                   retries < 5 )
5015 +                               {
5016 +                                       retries++;
5017 +                                       interruptible_sleep_on_timeout
5018 +                                               ( &dev->wait_q, HZ );
5019 +                                       continue;
5020 +                               }
5021 +                               else
5022 +                               {
5023 +                                       return -EIO;
5024 +                               }
5025 +                       }
5026 +            
5027 +                       retries = 0;
5028 +                       if( partial )
5029 +                               this_read = partial;
5030 +
5031 +                       /* skip the header */
5032 +                       bulkidx += 2;
5033 +            
5034 +                       /* check for empty reads (header only) */
5035 +                       if( this_read == 2 )
5036 +                       {
5037 +                               /* assume no data */
5038 +                               if( dont_block )
5039 +                               {
5040 +                                       break;
5041 +                               }
5042 +
5043 +                               /* sleep for a bit before performing
5044 +                                  another read */
5045 +                               interruptible_sleep_on_timeout
5046 +                                       ( &dev->wait_q, 1 );
5047 +                               continue;
5048 +                       }
5049 +               }
5050 +
5051 +               /*
5052 +                * process data
5053 +                */
5054 +        
5055 +               /* at this point this_read is > 0 */
5056 +               while( bulkidx < this_read &&
5057 +                      (words_to_read > (dev->last_space ? 1 : 0)) )
5058 +                       //while( bulkidx < this_read && words_to_read )
5059 +               {
5060 +                       int keycode;
5061 +                       int pulse = 0;
5062 +            
5063 +                       /* read packet length if needed */
5064 +                       if( !bytes_left_in_packet )
5065 +                       {
5066 +                               
5067 +                               /* we assume we are on a packet length
5068 +                                * value. it is possible, in some
5069 +                                * cases, to get a packet that does
5070 +                                * not start with a length, apparently
5071 +                                * due to some sort of fragmenting,
5072 +                                * but occaisonally we do not receive
5073 +                                * the second half of a fragment
5074 +                                */
5075 +                               bytes_left_in_packet = 
5076 +                                       128 + signedp[bulkidx++];
5077 +
5078 +                               /* unfortunately rather than keep all
5079 +                                * the data in the packetized format,
5080 +                                * the transceiver sends a trailing 8
5081 +                                * bytes that aren't part of the
5082 +                                * transmittion from the remote,
5083 +                                * aren't packetized, and dont really
5084 +                                * have any value. we can basically
5085 +                                * tell we have hit them if 1) we have
5086 +                                * a loooong space currently stored
5087 +                                * up, and 2) the bytes_left value for
5088 +                                * this packet is obviously wrong
5089 +                                */
5090 +                               if( bytes_left_in_packet > 4  )
5091 +                               {
5092 +                                       if( dev->mce_bytes_left_in_packet )
5093 +                                       {
5094 +                                               bytes_left_in_packet = dev->mce_bytes_left_in_packet;
5095 +                                               bulkidx--;
5096 +                                       }
5097 +                                       bytes_left_in_packet = 0;
5098 +                                       bulkidx = this_read;
5099 +                               }
5100 +
5101 +                               /* always clear this if we have a
5102 +                                  valid packet */
5103 +                               dev->mce_bytes_left_in_packet = 0;
5104 +                    
5105 +                               /* continue here to verify we haven't
5106 +                                  hit the end of the bulk_in */
5107 +                               continue;
5108 +                               
5109 +                       }
5110 +
5111 +                       /*
5112 +                        * generate mode2
5113 +                        */
5114 +            
5115 +                       keycode = signedp[bulkidx++];
5116 +                       if( keycode < 0 )
5117 +                       {
5118 +                               pulse = 1;
5119 +                               keycode += 128;
5120 +                       }
5121 +                       keycode *= MCE_TIME_UNIT;
5122 +
5123 +                       bytes_left_in_packet--;
5124 +            
5125 +                       if( pulse )
5126 +                       {
5127 +                               if( dev->last_space )
5128 +                               {
5129 +                                       dev->lircdata[dev->lirccnt++] =
5130 +                                               dev->last_space;
5131 +                                       dev->last_space = 0;
5132 +                                       words_to_read--;
5133 +
5134 +                                       /* clear the lirc_t for the pulse */
5135 +                                       dev->lircdata[dev->lirccnt] = 0;
5136 +                               }
5137 +                               dev->lircdata[dev->lirccnt] += keycode;
5138 +                               dev->lircdata[dev->lirccnt] |= PULSE_BIT;
5139 +                       }
5140 +                       else
5141 +                       {
5142 +                               /* on pulse->space transition, add one
5143 +                                  for the existing pulse */
5144 +                               if( dev->lircdata[dev->lirccnt] &&
5145 +                                   !dev->last_space )
5146 +                               {
5147 +                                       dev->lirccnt++;
5148 +                                       words_to_read--;
5149 +                               }
5150 +                
5151 +                               dev->last_space += keycode;
5152 +                       }
5153 +               }
5154 +       }
5155 +       
5156 +       /* save off some info if we are exiting mid-packet, or with
5157 +          leftovers */
5158 +       if( bytes_left_in_packet )
5159 +       {
5160 +               dev->mce_bytes_left_in_packet = bytes_left_in_packet;
5161 +       }
5162 +       if( bulkidx < this_read )
5163 +       {
5164 +               dev->usb_valid_bytes_in_bulk_buffer = (this_read - bulkidx);
5165 +               memcpy( dev->bulk_in_buffer, &(dev->bulk_in_buffer[bulkidx]),
5166 +                       dev->usb_valid_bytes_in_bulk_buffer );
5167 +       }
5168 +       return dev->lirccnt;
5169 +}
5170 +
5171 +/* mceusb_add_to_buf: called by lirc_dev to fetch all available keys
5172 + * this is used as a polling interface for us: since we set
5173 + * plugin->sample_rate we will periodically get the below call to
5174 + * check for new data returns 0 on success, or -ENODATA if nothing is
5175 + * available
5176 + */
5177 +static int mceusb_add_to_buf(void* data, struct lirc_buffer* buf )
5178 +{
5179 +       struct usb_skel* dev = (struct usb_skel*) data;
5180 +
5181 +       down( &dev->sem );
5182 +
5183 +       /* verify device still present */
5184 +       if( dev->udev == NULL )
5185 +       {
5186 +               up( &dev->sem );
5187 +               return -ENODEV;
5188 +       }
5189 +
5190 +       if( !dev->lirccnt )
5191 +       {
5192 +               int res;
5193 +               dev->lircidx = 0;
5194 +        
5195 +               res = msir_fetch_more_data( dev, 1 );
5196 +               
5197 +               if( res == 0 )
5198 +                       res = -ENODATA;
5199 +               if( res < 0 ) {
5200 +                       up( &dev->sem );
5201 +                       return res;
5202 +               }
5203 +       }
5204 +
5205 +       if( dev->lirccnt )
5206 +       {
5207 +               int keys_to_copy;
5208 +
5209 +               /* determine available buffer space and available data */
5210 +               keys_to_copy = lirc_buffer_available( buf );
5211 +               if( keys_to_copy > dev->lirccnt )
5212 +               {
5213 +                       keys_to_copy = dev->lirccnt;
5214 +               }
5215 +        
5216 +               lirc_buffer_write_n( buf, (unsigned char*) &(dev->lircdata[dev->lircidx]), keys_to_copy );
5217 +               dev->lircidx += keys_to_copy;
5218 +               dev->lirccnt -= keys_to_copy;
5219 +        
5220 +               up( &dev->sem );
5221 +               return 0;
5222 +       }
5223 +
5224 +       up( &dev->sem );
5225 +       return -ENODATA;
5226 +}
5227 +
5228 +/**
5229 + *     mceusb_write_bulk_callback
5230 + */
5231 +#ifdef KERNEL_2_5 
5232 +static void mceusb_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
5233 +#else
5234 +static void mceusb_write_bulk_callback (struct urb *urb)
5235 +#endif
5236 +{
5237 +       struct usb_skel *dev = (struct usb_skel *)urb->context;
5238 +
5239 +       dbg("%s - minor %d", __func__, dev->minor);
5240 +
5241 +       if ((urb->status != -ENOENT) && 
5242 +           (urb->status != -ECONNRESET)) {
5243 +               dbg("%s - nonzero write buld status received: %d\n", __func__, urb->status);
5244 +               return;
5245 +       }
5246 +
5247 +       return;
5248 +}
5249 +
5250 +/**
5251 + *     mceusb_probe
5252 + *
5253 + *     Called by the usb core when a new device is connected that it 
5254 + *     thinks this driver might be interested in.
5255 + */
5256 +#ifdef KERNEL_2_5 
5257 +static int mceusb_probe(struct usb_interface *interface, const struct usb_device_id *id)
5258 +{
5259 +       struct usb_device *udev = interface_to_usbdev(interface);
5260 +       struct usb_host_interface *iface_desc;
5261 +#else
5262 +static void * mceusb_probe(struct usb_device *udev, unsigned int ifnum,
5263 +                          const struct usb_device_id *id)
5264 +{
5265 +       struct usb_interface *interface = &udev->actconfig->interface[ifnum];
5266 +       struct usb_interface_descriptor *iface_desc;    
5267 +#endif
5268 +       struct usb_skel *dev = NULL;
5269 +       struct usb_endpoint_descriptor *endpoint;
5270 +       
5271 +       struct lirc_plugin* plugin;
5272 +       struct lirc_buffer* rbuf;
5273 +
5274 +       int minor;
5275 +       size_t buffer_size;
5276 +       int i;
5277 +       int retval = -ENOMEM;
5278 +       
5279 +       /* See if the device offered us matches what we can accept */
5280 +       if ((udev->descriptor.idVendor != USB_MCEUSB_VENDOR_ID) ||
5281 +           (udev->descriptor.idProduct != USB_MCEUSB_PRODUCT_ID)) {
5282 +               dbg("Wrong Vendor/Product IDs");
5283 +#ifdef KERNEL_2_5
5284 +               return -ENODEV;
5285 +#else
5286 +               return NULL;
5287 +#endif
5288 +       }
5289 +
5290 +       /* select a "subminor" number (part of a minor number) */
5291 +       down (&minor_table_mutex);
5292 +       for (minor = 0; minor < MAX_DEVICES; ++minor) {
5293 +               if (minor_table[minor] == NULL)
5294 +                       break;
5295 +       }
5296 +       if (minor >= MAX_DEVICES) {
5297 +               info ("Too many devices plugged in, "
5298 +                     "can not handle this device.");
5299 +               goto error;
5300 +       }
5301 +
5302 +       /* allocate memory for our device state and initialize it */
5303 +       dev = kmalloc (sizeof(struct usb_skel), GFP_KERNEL);
5304 +       if (dev == NULL) {
5305 +               err ("Out of memory");
5306 +#ifdef KERNEL_2_5
5307 +               retval = -ENOMEM;
5308 +#endif
5309 +               goto error;
5310 +       }
5311 +       minor_table[minor] = dev;
5312 +       
5313 +       memset (dev, 0x00, sizeof (*dev));
5314 +       init_MUTEX (&dev->sem);
5315 +       dev->udev = udev;
5316 +       dev->interface = interface;
5317 +       dev->minor = minor;
5318 +
5319 +       /* set up the endpoint information */
5320 +       /* check out the endpoints */
5321 +       /* use only the first bulk-in and bulk-out endpoints */
5322 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,4)
5323 +       iface_desc = interface->cur_altsetting;
5324 +#else
5325 +       iface_desc = &interface->altsetting[0];
5326 +#endif
5327 +
5328 +#ifdef KERNEL_2_5
5329 +       for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
5330 +               endpoint = &iface_desc->endpoint[i].desc;
5331 +#else
5332 +       for (i = 0; i < iface_desc->bNumEndpoints; ++i) {
5333 +               endpoint = &iface_desc->endpoint[i];
5334 +#endif
5335 +               if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) &&
5336 +                   ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
5337 +                    USB_ENDPOINT_XFER_BULK)) {
5338 +                       dbg("we found a bulk in endpoint");
5339 +                       buffer_size = endpoint->wMaxPacketSize;
5340 +                       dev->bulk_in_size = buffer_size;
5341 +                       dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
5342 +#ifdef KERNEL_2_5
5343 +                       dev->bulk_in_buffer = usb_buffer_alloc
5344 +                               (udev, buffer_size, SLAB_ATOMIC, &dev->dma_in);
5345 +#else
5346 +                       dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
5347 +#endif
5348 +                       if (!dev->bulk_in_buffer) {
5349 +                               err("Couldn't allocate bulk_in_buffer");
5350 +                               goto error;
5351 +                       }
5352 +               }
5353 +               
5354 +               if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == 0x00) &&
5355 +                   ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
5356 +                    USB_ENDPOINT_XFER_BULK)) {
5357 +                       dbg("we found a bulk out endpoint");
5358 +#ifdef KERNEL_2_5
5359 +                       dev->write_urb = usb_alloc_urb(0, GFP_KERNEL);
5360 +#else
5361 +                       dev->write_urb = usb_alloc_urb(0);
5362 +#endif
5363 +                       if (!dev->write_urb) {
5364 +                               err("No free urbs available");
5365 +                               goto error;
5366 +                       }
5367 +                       buffer_size = endpoint->wMaxPacketSize;
5368 +                       dev->bulk_out_size = buffer_size;
5369 +                       dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
5370 +#ifdef KERNEL_2_5
5371 +                       dev->bulk_out_buffer = usb_buffer_alloc(udev, buffer_size, SLAB_ATOMIC, &dev->dma_out);
5372 +#else
5373 +                       dev->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
5374 +#endif
5375 +                       if (!dev->bulk_out_buffer) {
5376 +                               err("Couldn't allocate bulk_out_buffer");
5377 +                               goto error;
5378 +                       }
5379 +#ifdef KERNEL_2_5
5380 +                       usb_fill_bulk_urb(dev->write_urb, udev, 
5381 +                                     usb_sndbulkpipe
5382 +                                     (udev, endpoint->bEndpointAddress),
5383 +                                     dev->bulk_out_buffer, buffer_size,
5384 +                                     mceusb_write_bulk_callback, dev);
5385 +#else
5386 +                       FILL_BULK_URB(dev->write_urb, udev,
5387 +                                     usb_sndbulkpipe
5388 +                                     (udev, endpoint->bEndpointAddress),
5389 +                                     dev->bulk_out_buffer, buffer_size,
5390 +                                     mceusb_write_bulk_callback, dev);
5391 +#endif 
5392 +               }
5393 +       }
5394 +
5395 +       if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
5396 +               err("Couldn't find both bulk-in and bulk-out endpoints");
5397 +               goto error;
5398 +       }
5399 +
5400 +       /* init the waitq */
5401 +       init_waitqueue_head( &dev->wait_q );
5402 +
5403 +
5404 +       /* Set up our lirc plugin */
5405 +       if(!(plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL))) {
5406 +               err("out of memory");
5407 +               goto error;
5408 +       }
5409 +       memset( plugin, 0, sizeof(struct lirc_plugin) );
5410 +
5411 +       if(!(rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL))) {
5412 +               err("out of memory");
5413 +               kfree( plugin );
5414 +               goto error;
5415 +       }
5416 +    
5417 +       /* the lirc_atiusb module doesn't memset rbuf here ... ? */
5418 +       if( lirc_buffer_init( rbuf, sizeof(lirc_t), 128)) {
5419 +               err("out of memory");
5420 +               kfree( plugin );
5421 +               kfree( rbuf );
5422 +               goto error;
5423 +       }
5424 +
5425 +       strcpy(plugin->name, DRIVER_NAME " ");
5426 +       plugin->minor       = minor;
5427 +       plugin->code_length = sizeof(lirc_t) * 8;
5428 +       plugin->features    = LIRC_CAN_REC_MODE2; // | LIRC_CAN_SEND_MODE2;
5429 +       plugin->data        = dev;
5430 +       plugin->rbuf        = rbuf;
5431 +       plugin->ioctl       = NULL;
5432 +       plugin->set_use_inc = &set_use_inc;
5433 +       plugin->set_use_dec = &set_use_dec;
5434 +       plugin->sample_rate = 80;   // sample at 100hz (10ms)
5435 +       plugin->add_to_buf  = &mceusb_add_to_buf;
5436 +       //    plugin->fops        = &mceusb_fops;
5437 +       if( lirc_register_plugin(plugin) < 0 )
5438 +       {
5439 +               kfree( plugin );
5440 +               lirc_buffer_free( rbuf );
5441 +               kfree( rbuf );
5442 +               goto error;
5443 +       }
5444 +       dev->plugin = plugin;
5445 +       
5446 +       /* clear off the first few messages. these look like
5447 +        * calibration or test data, i can't really tell
5448 +        * this also flushes in case we have random ir data queued up
5449 +        */
5450 +       {
5451 +               char junk[64];
5452 +               int partial = 0, retval, i;
5453 +               for( i = 0; i < 40; i++ )
5454 +               {
5455 +                       retval = usb_bulk_msg
5456 +                               (udev, usb_rcvbulkpipe
5457 +                                (udev, dev->bulk_in_endpointAddr),
5458 +                                junk, 64,
5459 +                                &partial, HZ*10);
5460 +               }
5461 +       }
5462 +    
5463 +       msir_cleanup( dev );
5464 +       mceusb_setup( udev );
5465 +       
5466 +#ifdef KERNEL_2_5
5467 +       /* we can register the device now, as it is ready */
5468 +       usb_set_intfdata (interface, dev);
5469 +#endif 
5470 +       /* let the user know what node this device is now attached to */
5471 +       //info ("USB Microsoft IR Transceiver device now attached to msir%d", dev->minor);
5472 +       up (&minor_table_mutex);
5473 +#ifdef KERNEL_2_5
5474 +       return 0;
5475 +#else
5476 +       return dev;
5477 +#endif
5478 + error:
5479 +       mceusb_delete (dev);
5480 +       dev = NULL;
5481 +       dbg("%s: retval = %x",__func__,retval);
5482 +       up (&minor_table_mutex);
5483 +#ifdef KERNEL_2_5
5484 +       return retval;
5485 +#else
5486 +       return NULL;
5487 +#endif
5488 +}
5489 +
5490 +/**
5491 + *     mceusb_disconnect
5492 + *
5493 + *     Called by the usb core when the device is removed from the system.
5494 + *
5495 + *     This routine guarantees that the driver will not submit any more urbs
5496 + *     by clearing dev->udev.  It is also supposed to terminate any currently
5497 + *     active urbs.  Unfortunately, usb_bulk_msg(), used in skel_read(), does
5498 + *     not provide any way to do this.  But at least we can cancel an active
5499 + *     write.
5500 + */
5501 +#ifdef KERNEL_2_5 
5502 +static void mceusb_disconnect(struct usb_interface *interface)
5503 +#else
5504 +static void mceusb_disconnect(struct usb_device *udev, void *ptr)
5505 +#endif
5506 +{
5507 +       struct usb_skel *dev;
5508 +       int minor;
5509 +#ifdef KERNEL_2_5
5510 +       dev = usb_get_intfdata (interface);
5511 +       usb_set_intfdata (interface, NULL);
5512 +#else
5513 +       dev = (struct usb_skel *)ptr;
5514 +#endif
5515 +       
5516 +       down (&minor_table_mutex);
5517 +       down (&dev->sem);
5518 +       minor = dev->minor;
5519 +
5520 +       /* unhook lirc things */
5521 +       lirc_unregister_plugin( minor );
5522 +       lirc_buffer_free( dev->plugin->rbuf );
5523 +       kfree( dev->plugin->rbuf );
5524 +       kfree( dev->plugin );
5525 +#ifdef KERNEL_2_5
5526 +       /* terminate an ongoing write */
5527 +       if (atomic_read (&dev->write_busy)) {
5528 +               usb_unlink_urb (dev->write_urb);
5529 +               wait_for_completion (&dev->write_finished);
5530 +       }
5531 +
5532 +       /* prevent device read, write and ioctl */
5533 +       dev->present = 0;
5534 +#endif
5535 +       
5536 +       mceusb_delete (dev);
5537 +       
5538 +       info("Microsoft IR Transceiver #%d now disconnected", minor);
5539 +       up (&dev->sem);
5540 +       up (&minor_table_mutex);
5541 +}
5542 +
5543 +
5544 +
5545 +/**
5546 + *     usb_mceusb_init
5547 + */
5548 +static int __init usb_mceusb_init(void)
5549 +{
5550 +       int result;
5551 +
5552 +       /* register this driver with the USB subsystem */
5553 +       result = usb_register(&mceusb_driver);
5554 +#ifdef KERNEL_2_5      
5555 +       if ( result ) {
5556 +#else
5557 +       if ( result < 0 ) {
5558 +#endif
5559 +               err("usb_register failed for the " DRIVER_NAME " driver. error number %d",result);
5560 +#ifdef KERNEL_2_5
5561 +               return result;
5562 +#else
5563 +               return -1;
5564 +#endif
5565 +       }
5566 +
5567 +       info(DRIVER_DESC " " DRIVER_VERSION);
5568 +       return 0;
5569 +}
5570 +
5571 +
5572 +/**
5573 + *     usb_mceusb_exit
5574 + */
5575 +static void __exit usb_mceusb_exit(void)
5576 +{
5577 +       /* deregister this driver with the USB subsystem */
5578 +       usb_deregister(&mceusb_driver);
5579 +}
5580 +
5581 +
5582 +module_init (usb_mceusb_init);
5583 +module_exit (usb_mceusb_exit);
5584 +
5585 +MODULE_AUTHOR(DRIVER_AUTHOR);
5586 +MODULE_DESCRIPTION(DRIVER_DESC);
5587 +MODULE_LICENSE("GPL");
5588 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_parallel.c linux-2.6.8-rc4/drivers/char/lirc/lirc_parallel.c
5589 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_parallel.c      1970-01-01 01:00:00.000000000 +0100
5590 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_parallel.c   2004-05-16 11:14:39.000000000 +0200
5591 @@ -0,0 +1,762 @@
5592 +/*      $Id$      */
5593 +
5594 +/****************************************************************************
5595 + ** lirc_parallel.c *********************************************************
5596 + ****************************************************************************
5597 + * 
5598 + * lirc_parallel - device driver for infra-red signal receiving and
5599 + *                 transmitting unit built by the author
5600 + * 
5601 + * Copyright (C) 1998 Christoph Bartelmus <lirc@bartelmus.de>
5602 + *
5603 + *  This program is free software; you can redistribute it and/or modify
5604 + *  it under the terms of the GNU General Public License as published by
5605 + *  the Free Software Foundation; either version 2 of the License, or
5606 + *  (at your option) any later version.
5607 + *
5608 + *  This program is distributed in the hope that it will be useful,
5609 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
5610 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5611 + *  GNU General Public License for more details.
5612 + *
5613 + *  You should have received a copy of the GNU General Public License
5614 + *  along with this program; if not, write to the Free Software
5615 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
5616 + *
5617 + */ 
5618 +
5619 +/***********************************************************************
5620 + *************************       Includes        ***********************
5621 + ***********************************************************************/
5622 +
5623 +#ifdef HAVE_CONFIG_H
5624 +# include <config.h>
5625 +#endif
5626 +
5627 +#include <linux/version.h>
5628 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
5629 +#error "**********************************************************"
5630 +#error " Sorry, this driver needs kernel version 2.2.18 or higher "
5631 +#error "**********************************************************"
5632 +#endif
5633 +
5634 +#include <linux/config.h>
5635 +
5636 +#ifdef CONFIG_SMP
5637 +#error "--- Sorry, this driver is not SMP safe. ---"
5638 +#endif
5639 +
5640 +#include <linux/module.h>
5641 +#include <linux/sched.h>
5642 +#include <linux/errno.h>
5643 +#include <linux/signal.h>
5644 +#include <linux/config.h>
5645 +#include <linux/fs.h>
5646 +#include <linux/kernel.h>
5647 +#include <linux/ioport.h>
5648 +#include <linux/time.h>
5649 +#include <linux/mm.h>
5650 +#include <linux/delay.h>
5651 +
5652 +#include <asm/io.h>
5653 +#include <asm/signal.h>
5654 +#include <asm/irq.h>
5655 +
5656 +#include <asm/uaccess.h>
5657 +#include <linux/poll.h>
5658 +#include <linux/parport.h>
5659 +
5660 +#include <linux/lirc.h>
5661 +#include "kcompat.h"
5662 +#include "lirc_dev.h"
5663 +
5664 +#include "lirc_parallel.h"
5665 +
5666 +#define LIRC_DRIVER_NAME "lirc_parallel"
5667 +
5668 +/***********************************************************************
5669 + *************************   Globale Variablen   ***********************
5670 + ***********************************************************************/
5671 +
5672 +unsigned int irq = CONFIG_LIRC_IRQ_PARALLEL;
5673 +unsigned int io = CONFIG_LIRC_PORT_PARALLEL;
5674 +#ifdef CONFIG_LIRC_TIMER
5675 +unsigned int timer = 0;
5676 +unsigned int default_timer = CONFIG_LIRC_TIMER;
5677 +#endif
5678 +
5679 +#define WBUF_SIZE (256)
5680 +#define RBUF_SIZE (256) /* this must be a power of 2 larger than 1 */
5681 +
5682 +static lirc_t wbuf[WBUF_SIZE];
5683 +static lirc_t rbuf[RBUF_SIZE];
5684 +
5685 +DECLARE_WAIT_QUEUE_HEAD(lirc_wait);
5686 +
5687 +unsigned int rptr=0,wptr=0;
5688 +unsigned int lost_irqs=0;
5689 +int is_open=0;
5690 +
5691 +struct parport *pport;
5692 +struct pardevice *ppdevice;
5693 +int is_claimed=0;
5694 +
5695 +/***********************************************************************
5696 + *************************   Interne Funktionen  ***********************
5697 + ***********************************************************************/
5698 +
5699 +unsigned int __inline__ in(int offset)
5700 +{
5701 +       switch(offset)
5702 +       {
5703 +       case LIRC_LP_BASE:
5704 +               return(parport_read_data(pport));
5705 +       case LIRC_LP_STATUS:
5706 +               return(parport_read_status(pport));
5707 +       case LIRC_LP_CONTROL:
5708 +               return(parport_read_control(pport));
5709 +       }
5710 +       return(0); /* make compiler happy */
5711 +}
5712 +
5713 +void __inline__ out(int offset, int value)
5714 +{
5715 +       switch(offset)
5716 +       {
5717 +       case LIRC_LP_BASE:
5718 +               parport_write_data(pport,value);
5719 +               break;
5720 +       case LIRC_LP_CONTROL:
5721 +               parport_write_control(pport,value);
5722 +               break;
5723 +       case LIRC_LP_STATUS:
5724 +               printk(KERN_INFO "%s: attempt to write to status register\n",
5725 +                      LIRC_DRIVER_NAME);
5726 +               break;
5727 +       }
5728 +}
5729 +
5730 +unsigned int __inline__ lirc_get_timer(void)
5731 +{
5732 +       return(in(LIRC_PORT_TIMER)&LIRC_PORT_TIMER_BIT);
5733 +}
5734 +
5735 +unsigned int __inline__  lirc_get_signal(void)
5736 +{
5737 +       return(in(LIRC_PORT_SIGNAL)&LIRC_PORT_SIGNAL_BIT);
5738 +}
5739 +
5740 +void __inline__ lirc_on(void)
5741 +{
5742 +       out(LIRC_PORT_DATA,LIRC_PORT_DATA_BIT);
5743 +}
5744 +
5745 +void __inline__ lirc_off(void)
5746 +{
5747 +       out(LIRC_PORT_DATA,0);
5748 +}
5749 +
5750 +unsigned int init_lirc_timer(void)
5751 +{
5752 +       struct timeval tv,now;
5753 +       unsigned int level,newlevel,timeelapsed,newtimer;
5754 +       int count=0;
5755 +       
5756 +       do_gettimeofday(&tv);
5757 +       tv.tv_sec++;                     /* wait max. 1 sec. */
5758 +       level=lirc_get_timer();
5759 +       do
5760 +       {
5761 +               newlevel=lirc_get_timer();
5762 +               if(level==0 && newlevel!=0) count++;
5763 +               level=newlevel;
5764 +               do_gettimeofday(&now);
5765 +       }
5766 +       while(count<1000 && (now.tv_sec<tv.tv_sec 
5767 +                            || (now.tv_sec==tv.tv_sec 
5768 +                                && now.tv_usec<tv.tv_usec)));
5769 +
5770 +       timeelapsed=((now.tv_sec+1-tv.tv_sec)*1000000
5771 +                    +(now.tv_usec-tv.tv_usec));
5772 +       if(count>=1000 && timeelapsed>0)
5773 +       {
5774 +               if(default_timer==0)                    /* autodetect timer */
5775 +               {
5776 +                       newtimer=(1000000*count)/timeelapsed;
5777 +                       printk(KERN_INFO "%s: %u Hz timer detected\n",
5778 +                              LIRC_DRIVER_NAME,newtimer);
5779 +                       return(newtimer);
5780 +               }
5781 +               else
5782 +               {
5783 +                       newtimer=(1000000*count)/timeelapsed;
5784 +                       if(abs(newtimer-default_timer)>
5785 +                          default_timer/10) /* bad timer */
5786 +                       {
5787 +                               printk(KERN_NOTICE "%s: bad timer: %u Hz\n",
5788 +                                      LIRC_DRIVER_NAME,newtimer);
5789 +                               printk(KERN_NOTICE "%s: using default timer: "
5790 +                                      "%u Hz\n",
5791 +                                      LIRC_DRIVER_NAME,default_timer);
5792 +                               return(default_timer);
5793 +                       }
5794 +                       else
5795 +                       {
5796 +                               printk(KERN_INFO "%s: %u Hz timer detected\n",
5797 +                                      LIRC_DRIVER_NAME,newtimer);
5798 +                               return(newtimer); /* use detected value */
5799 +                       }
5800 +               }
5801 +       }
5802 +       else
5803 +       {
5804 +               printk(KERN_NOTICE "%s: no timer detected\n",LIRC_DRIVER_NAME);
5805 +               return(0);
5806 +       }
5807 +}
5808 +
5809 +int lirc_claim(void)
5810 +{
5811 +       if(parport_claim(ppdevice)!=0)
5812 +       {
5813 +               printk(KERN_WARNING "%s: could not claim port\n",
5814 +                      LIRC_DRIVER_NAME);
5815 +               printk(KERN_WARNING "%s: waiting for port becoming available"
5816 +                      "\n",LIRC_DRIVER_NAME);
5817 +               if(parport_claim_or_block(ppdevice)<0)
5818 +               {
5819 +                       printk(KERN_NOTICE "%s: could not claim port, giving"
5820 +                              " up\n",LIRC_DRIVER_NAME);
5821 +                       return(0);
5822 +               }
5823 +       }
5824 +       out(LIRC_LP_CONTROL,LP_PSELECP|LP_PINITP);
5825 +       is_claimed=1;
5826 +       return(1);
5827 +}
5828 +
5829 +/***********************************************************************
5830 + *************************   interrupt handler  ************************
5831 + ***********************************************************************/
5832 +
5833 +static inline void rbuf_write(lirc_t signal)
5834 +{
5835 +       unsigned int nwptr;
5836 +
5837 +       nwptr=(wptr+1) & (RBUF_SIZE-1);
5838 +       if(nwptr==rptr) /* no new signals will be accepted */
5839 +       {
5840 +               lost_irqs++;
5841 +               printk(KERN_NOTICE "%s: buffer overrun\n",LIRC_DRIVER_NAME);
5842 +               return;
5843 +       }       
5844 +       rbuf[wptr]=signal;
5845 +       wptr=nwptr;
5846 +}
5847 +
5848 +void irq_handler(int i,void *blah,struct pt_regs * regs)
5849 +{
5850 +       struct timeval tv;
5851 +       static struct timeval lasttv;
5852 +       static int init=0;
5853 +       long signal;
5854 +       lirc_t data;
5855 +       unsigned int level,newlevel;
5856 +       unsigned int timeout;
5857 +
5858 +       if(!MOD_IN_USE)
5859 +               return;
5860 +
5861 +       if(!is_claimed)
5862 +       {
5863 +               return;
5864 +       }
5865 +
5866 +       /* disable interrupt */
5867 +       /*
5868 +         disable_irq(irq);
5869 +         out(LIRC_PORT_IRQ,in(LIRC_PORT_IRQ)&(~LP_PINTEN));
5870 +       */
5871 +       if(in(1)&LP_PSELECD)
5872 +       {
5873 +               return;
5874 +       }
5875 +
5876 +#ifdef LIRC_TIMER
5877 +       if(init)
5878 +       {
5879 +               do_gettimeofday(&tv);
5880 +               
5881 +               signal=tv.tv_sec-lasttv.tv_sec;
5882 +               if(signal>15)
5883 +               {
5884 +                       data=PULSE_MASK;  /* really long time */
5885 +               }
5886 +               else
5887 +               {
5888 +                       data=(lirc_t) (signal*1000000+
5889 +                                      tv.tv_usec-lasttv.tv_usec+
5890 +                                      LIRC_SFH506_DELAY);
5891 +               };
5892 +
5893 +               rbuf_write(data); /* space */
5894 +       }
5895 +       else
5896 +       {
5897 +               if(timer==0) /* wake up; we'll lose this signal 
5898 +                               but it will be garbage if the device 
5899 +                               is turned on anyway
5900 +                             */
5901 +               {
5902 +                       timer=init_lirc_timer();
5903 +                       /* enable_irq(irq); */
5904 +                       return;
5905 +               }
5906 +               init=1;
5907 +       }
5908 +
5909 +       timeout=timer/10;           /* timeout after 1/10 sec. */
5910 +       signal=1;
5911 +       level=lirc_get_timer();
5912 +       do{
5913 +               newlevel=lirc_get_timer();
5914 +               if(level==0 && newlevel!=0) signal++;
5915 +               level=newlevel;
5916 +
5917 +               /* giving up */
5918 +               if(signal>timeout || (in(1)&LP_PSELECD))
5919 +               {
5920 +                       signal=0;
5921 +                       printk(KERN_NOTICE "%s: timeout\n",LIRC_DRIVER_NAME);
5922 +                       break;
5923 +               }
5924 +       }
5925 +       while(lirc_get_signal());
5926 +       if(signal!=0)
5927 +       {
5928 +               /* ajust value to usecs */
5929 +               signal=(long) (((unsigned long long) signal)*1000000)/timer;
5930 +
5931 +               if(signal>LIRC_SFH506_DELAY)
5932 +               {
5933 +                       data=signal-LIRC_SFH506_DELAY;
5934 +               }
5935 +               else
5936 +               {
5937 +                       data=1;
5938 +               }
5939 +               rbuf_write(PULSE_BIT|data); /* pulse */
5940 +       }
5941 +       do_gettimeofday(&lasttv);
5942 +#else
5943 +       /* add your code here */
5944 +#endif
5945 +       
5946 +       wake_up_interruptible(&lirc_wait);
5947 +
5948 +       /* enable interrupt */
5949 +       /*
5950 +         enable_irq(irq);
5951 +         out(LIRC_PORT_IRQ,in(LIRC_PORT_IRQ)|LP_PINTEN);
5952 +       */
5953 +}
5954 +
5955 +/***********************************************************************
5956 + **************************   file_operations   ************************
5957 + ***********************************************************************/
5958 +
5959 +static loff_t lirc_lseek(struct file *filep,loff_t offset,int orig)
5960 +{
5961 +       return(-ESPIPE);
5962 +}
5963 +
5964 +static ssize_t lirc_read(struct file *filep,char *buf,size_t n,loff_t *ppos)
5965 +{
5966 +       int result;
5967 +       int count=0;
5968 +       DECLARE_WAITQUEUE(wait, current);
5969 +       
5970 +       if(n%sizeof(lirc_t)) return(-EINVAL);
5971 +       
5972 +       result=verify_area(VERIFY_WRITE,buf,n);
5973 +       if(result) return(result);
5974 +       
5975 +       add_wait_queue(&lirc_wait,&wait);
5976 +       current->state=TASK_INTERRUPTIBLE;
5977 +       while(count<n)
5978 +       {
5979 +               if(rptr!=wptr)
5980 +               {
5981 +                       copy_to_user(buf+count,(char *) &rbuf[rptr],
5982 +                                    sizeof(lirc_t));
5983 +                       rptr=(rptr+1)&(RBUF_SIZE-1);
5984 +                       count+=sizeof(lirc_t);
5985 +               }
5986 +               else
5987 +               {
5988 +                       if(filep->f_flags & O_NONBLOCK)
5989 +                       {
5990 +                               result=-EAGAIN;
5991 +                               break;
5992 +                       }
5993 +                       if (signal_pending(current))
5994 +                       {
5995 +                               result=-ERESTARTSYS;
5996 +                               break;
5997 +                       }
5998 +                       schedule();
5999 +                       current->state=TASK_INTERRUPTIBLE;
6000 +               }
6001 +       }
6002 +       remove_wait_queue(&lirc_wait,&wait);
6003 +       current->state=TASK_RUNNING;
6004 +       return(count ? count:result);
6005 +}
6006 +
6007 +static ssize_t lirc_write(struct file *filep,const char *buf,size_t n,
6008 +                         loff_t *ppos)
6009 +{
6010 +       int result,count;
6011 +       unsigned int i;
6012 +       unsigned int level,newlevel;
6013 +       unsigned long flags;
6014 +       lirc_t counttimer;
6015 +       
6016 +       if(!is_claimed)
6017 +       {
6018 +               return(-EBUSY);
6019 +       }
6020 +       if(n%sizeof(lirc_t)) return(-EINVAL);
6021 +       result=verify_area(VERIFY_READ,buf,n);
6022 +       if(result) return(result);
6023 +       
6024 +       count=n/sizeof(lirc_t);
6025 +       
6026 +       if(count>WBUF_SIZE || count%2==0) return(-EINVAL);
6027 +       
6028 +       copy_from_user(wbuf,buf,n);
6029 +       
6030 +#ifdef LIRC_TIMER
6031 +       if(timer==0) /* try again if device is ready */
6032 +       {
6033 +               timer=init_lirc_timer();
6034 +               if(timer==0) return(-EIO);
6035 +       }
6036 +
6037 +       /* ajust values from usecs */
6038 +       for(i=0;i<count;i++)
6039 +       {
6040 +               wbuf[i]=(lirc_t) (((double) wbuf[i])*timer/1000000);
6041 +       }
6042 +       
6043 +       local_irq_save(flags);
6044 +       i=0;
6045 +       while(i<count)
6046 +       {
6047 +               level=lirc_get_timer();
6048 +               counttimer=0;
6049 +               lirc_on();
6050 +               do
6051 +               {
6052 +                       newlevel=lirc_get_timer();
6053 +                       if(level==0 && newlevel!=0) counttimer++;
6054 +                       level=newlevel;
6055 +                       if(in(1)&LP_PSELECD)
6056 +                       {
6057 +                               lirc_off();
6058 +                               local_irq_restore(flags);
6059 +                               return(-EIO);
6060 +                       }
6061 +               }
6062 +               while(counttimer<wbuf[i]);i++;
6063 +               
6064 +               lirc_off();
6065 +               if(i==count) break;
6066 +               counttimer=0;
6067 +               do
6068 +               {
6069 +                       newlevel=lirc_get_timer();
6070 +                       if(level==0 && newlevel!=0) counttimer++;
6071 +                       level=newlevel;
6072 +                       if(in(1)&LP_PSELECD)
6073 +                       {
6074 +                               local_irq_restore(flags);
6075 +                               return(-EIO);
6076 +                       }
6077 +               }
6078 +               while(counttimer<wbuf[i]);i++;
6079 +       }
6080 +       local_irq_restore(flags);
6081 +#else
6082 +       /* 
6083 +          place code that handles write
6084 +          without extarnal timer here
6085 +       */
6086 +#endif
6087 +       return(n);
6088 +}
6089 +
6090 +static unsigned int lirc_poll(struct file *file, poll_table * wait)
6091 +{
6092 +       poll_wait(file, &lirc_wait,wait);
6093 +       if (rptr!=wptr)
6094 +               return(POLLIN|POLLRDNORM);
6095 +       return(0);
6096 +}
6097 +
6098 +static int lirc_ioctl(struct inode *node,struct file *filep,unsigned int cmd,
6099 +                     unsigned long arg)
6100 +{
6101 +        int result;
6102 +       unsigned long features=LIRC_CAN_SEND_PULSE|LIRC_CAN_REC_MODE2,mode;
6103 +       
6104 +       switch(cmd)
6105 +       {
6106 +       case LIRC_GET_FEATURES:
6107 +               result=put_user(features,(unsigned long *) arg);
6108 +               if(result) return(result); 
6109 +               break;
6110 +       case LIRC_GET_SEND_MODE:
6111 +               result=put_user(LIRC_MODE_PULSE,(unsigned long *) arg);
6112 +               if(result) return(result); 
6113 +               break;
6114 +       case LIRC_GET_REC_MODE:
6115 +               result=put_user(LIRC_MODE_MODE2,(unsigned long *) arg);
6116 +               if(result) return(result); 
6117 +               break;
6118 +       case LIRC_SET_SEND_MODE:
6119 +               result=get_user(mode,(unsigned long *) arg);
6120 +               if(result) return(result);
6121 +               if(mode!=LIRC_MODE_PULSE) return(-EINVAL);
6122 +               break;
6123 +       case LIRC_SET_REC_MODE:
6124 +               result=get_user(mode,(unsigned long *) arg);
6125 +               if(result) return(result);
6126 +               if(mode!=LIRC_MODE_MODE2) return(-ENOSYS);
6127 +               break;
6128 +       default:
6129 +               return(-ENOIOCTLCMD);
6130 +       }
6131 +       return(0);
6132 +}
6133 +
6134 +static int lirc_open(struct inode* node,struct file* filep)
6135 +{
6136 +       if(MOD_IN_USE)
6137 +       {
6138 +               return(-EBUSY);
6139 +       }
6140 +       if(!lirc_claim())
6141 +       {
6142 +               return(-EBUSY);
6143 +       }
6144 +       pport->ops->enable_irq(pport);
6145 +
6146 +       /* init read ptr */
6147 +       rptr=wptr=0;
6148 +       lost_irqs=0;
6149 +
6150 +       MOD_INC_USE_COUNT;
6151 +       is_open=1;
6152 +       return(0);
6153 +}
6154 +
6155 +static int lirc_close(struct inode* node,struct file* filep)
6156 +{
6157 +       if(is_claimed)
6158 +       {
6159 +               is_claimed=0;
6160 +               parport_release(ppdevice);
6161 +       }
6162 +       is_open=0;
6163 +       MOD_DEC_USE_COUNT;
6164 +       return(0);
6165 +}
6166 +
6167 +static struct file_operations lirc_fops = 
6168 +{
6169 +       llseek:  lirc_lseek,
6170 +       read:    lirc_read,
6171 +       write:   lirc_write,
6172 +       poll:    lirc_poll,
6173 +       ioctl:   lirc_ioctl,
6174 +       open:    lirc_open,
6175 +       release: lirc_close
6176 +};
6177 +
6178 +static int set_use_inc(void* data)
6179 +{
6180 +#if WE_DONT_USE_LOCAL_OPEN_CLOSE
6181 +       MOD_INC_USE_COUNT;
6182 +#endif
6183 +       return 0;
6184 +}
6185 +
6186 +static void set_use_dec(void* data)
6187 +{
6188 +#if WE_DONT_USE_LOCAL_OPEN_CLOSE
6189 +       MOD_DEC_USE_COUNT;
6190 +#endif
6191 +}
6192 +
6193 +static struct lirc_plugin plugin = {
6194 +       name:           LIRC_DRIVER_NAME,
6195 +       minor:          -1,
6196 +       code_length:    1,
6197 +       sample_rate:    0,
6198 +       data:           NULL,
6199 +       add_to_buf:     NULL,
6200 +       get_queue:      NULL,
6201 +       set_use_inc:    set_use_inc,
6202 +       set_use_dec:    set_use_dec,
6203 +       fops:           &lirc_fops,
6204 +};
6205 +
6206 +#ifdef MODULE
6207 +
6208 +MODULE_AUTHOR("Christoph Bartelmus");
6209 +MODULE_DESCRIPTION("Infrared receiver driver for parallel ports.");
6210 +#ifdef MODULE_LICENSE
6211 +MODULE_LICENSE("GPL");
6212 +#endif
6213 +
6214 +MODULE_PARM(io, "i");
6215 +MODULE_PARM_DESC(io, "I/O address base (0x3bc, 0x378 or 0x278)");
6216 +
6217 +MODULE_PARM(irq, "i");
6218 +MODULE_PARM_DESC(irq, "Interrupt (7 or 5)");
6219 +
6220 +#ifndef KERNEL_2_5
6221 +EXPORT_NO_SYMBOLS;
6222 +#endif
6223 +
6224 +int pf(void *handle);
6225 +void kf(void *handle);
6226 +
6227 +static struct timer_list poll_timer;
6228 +static void poll_state(unsigned long ignored);
6229 +
6230 +static void poll_state(unsigned long ignored)
6231 +{
6232 +       printk(KERN_NOTICE "%s: time\n",
6233 +              LIRC_DRIVER_NAME);
6234 +       del_timer(&poll_timer);
6235 +       if(is_claimed)
6236 +               return;
6237 +       kf(NULL);
6238 +       if(!is_claimed)
6239 +       {
6240 +               printk(KERN_NOTICE "%s: could not claim port, giving up\n",
6241 +                      LIRC_DRIVER_NAME);
6242 +               init_timer(&poll_timer);
6243 +               poll_timer.expires=jiffies+HZ;
6244 +               poll_timer.data=(unsigned long) current;
6245 +               poll_timer.function=poll_state;
6246 +               add_timer(&poll_timer);
6247 +       }
6248 +}
6249 +
6250 +int pf(void *handle)
6251 +{
6252 +       pport->ops->disable_irq(pport);
6253 +       is_claimed=0;
6254 +       return(0);
6255 +}
6256 +
6257 +
6258 +void kf(void *handle)
6259 +{
6260 +       if(!is_open)
6261 +               return;
6262 +       if(!lirc_claim())
6263 +               return;
6264 +       pport->ops->enable_irq(pport);
6265 +       /* this is a bit annoying when you actually print...*/
6266 +       /*
6267 +       printk(KERN_INFO "%s: reclaimed port\n",LIRC_DRIVER_NAME);
6268 +       */
6269 +}
6270 +
6271 +/***********************************************************************
6272 + ******************   init_module()/cleanup_module()  ******************
6273 + ***********************************************************************/
6274 +
6275 +int init_module(void)
6276 +{
6277 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 3)
6278 +       pport=parport_find_base(io);
6279 +#else
6280 +       pport=parport_enumerate();
6281 +       while(pport!=NULL)
6282 +       {
6283 +               if(pport->base==io)
6284 +               {
6285 +                       break;
6286 +               }
6287 +               pport=pport->next;
6288 +       }
6289 +#endif
6290 +       if(pport==NULL)
6291 +       {
6292 +               printk(KERN_NOTICE "%s: no port at %x found\n",
6293 +                      LIRC_DRIVER_NAME,io);
6294 +               return(-ENXIO);
6295 +       }
6296 +       ppdevice=parport_register_device(pport,LIRC_DRIVER_NAME,
6297 +                                        pf,kf,irq_handler,0,NULL);
6298 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 3)
6299 +       parport_put_port(pport);
6300 +#endif
6301 +       if(ppdevice==NULL)
6302 +       {
6303 +               printk(KERN_NOTICE "%s: parport_register_device() failed\n",
6304 +                      LIRC_DRIVER_NAME);
6305 +               return(-ENXIO);
6306 +       }
6307 +       if(parport_claim(ppdevice)!=0)
6308 +               goto skip_init;
6309 +       is_claimed=1;
6310 +       out(LIRC_LP_CONTROL,LP_PSELECP|LP_PINITP);
6311 +
6312 +#ifdef LIRC_TIMER
6313 +#       ifdef DEBUG
6314 +       out(LIRC_PORT_DATA,LIRC_PORT_DATA_BIT);
6315 +#       endif
6316 +       
6317 +       timer=init_lirc_timer();
6318 +
6319 +#       if 0   /* continue even if device is offline */
6320 +       if(timer==0) 
6321 +       {
6322 +               is_claimed=0;
6323 +               parport_release(pport);
6324 +               parport_unregister_device(ppdevice);
6325 +               return(-EIO);
6326 +       }
6327 +       
6328 +#       endif
6329 +#       ifdef DEBUG
6330 +       out(LIRC_PORT_DATA,0);
6331 +#       endif
6332 +#endif 
6333 +
6334 +       is_claimed=0;
6335 +       parport_release(ppdevice);
6336 + skip_init:
6337 +       if ((plugin.minor = lirc_register_plugin(&plugin)) < 0)
6338 +       {
6339 +               printk(KERN_NOTICE "%s: register_chrdev() failed\n",LIRC_DRIVER_NAME);
6340 +               parport_unregister_device(ppdevice);
6341 +               return(-EIO);
6342 +       }
6343 +       printk(KERN_INFO "%s: installed using port 0x%04x irq %d\n",LIRC_DRIVER_NAME,io,irq);
6344 +       return(0);
6345 +}
6346 +  
6347 +void cleanup_module(void)
6348 +{
6349 +       if(MOD_IN_USE) return;
6350 +       parport_unregister_device(ppdevice);
6351 +       lirc_unregister_plugin(plugin.minor);
6352 +}
6353 +#endif
6354 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_parallel.h linux-2.6.8-rc4/drivers/char/lirc/lirc_parallel.h
6355 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_parallel.h      1970-01-01 01:00:00.000000000 +0100
6356 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_parallel.h   2001-06-23 18:59:16.000000000 +0200
6357 @@ -0,0 +1,24 @@
6358 +/*      $Id$      */
6359 +
6360 +#ifndef _LIRC_PARALLEL_H
6361 +#define _LIRC_PARALLEL_H
6362 +
6363 +#include <linux/lp.h>
6364 +
6365 +#define LIRC_PORT_LEN 3
6366 +
6367 +#define LIRC_LP_BASE    0
6368 +#define LIRC_LP_STATUS  1
6369 +#define LIRC_LP_CONTROL 2
6370 +
6371 +#define LIRC_PORT_DATA           LIRC_LP_BASE    /* base */
6372 +#define LIRC_PORT_DATA_BIT               0x01    /* 1st bit */
6373 +#define LIRC_PORT_TIMER        LIRC_LP_STATUS    /* status port */
6374 +#define LIRC_PORT_TIMER_BIT          LP_PBUSY    /* busy signal */
6375 +#define LIRC_PORT_SIGNAL       LIRC_LP_STATUS    /* status port */
6376 +#define LIRC_PORT_SIGNAL_BIT          LP_PACK    /* ack signal */
6377 +#define LIRC_PORT_IRQ         LIRC_LP_CONTROL    /* control port */
6378 +
6379 +#define LIRC_SFH506_DELAY 0             /* delay t_phl in usecs */
6380 +
6381 +#endif
6382 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_sasem.c linux-2.6.8-rc4/drivers/char/lirc/lirc_sasem.c
6383 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_sasem.c 1970-01-01 01:00:00.000000000 +0100
6384 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_sasem.c      2004-06-19 08:29:09.000000000 +0200
6385 @@ -0,0 +1,453 @@
6386 +/* lirc_sasem.c - USB remote support for LIRC
6387 + * Version 0.1  [beta status]
6388 + *
6389 + * Copyright (C) 2004 Oliver Stabel <oliver.stabel@gmx.de>
6390 + *
6391 + * This driver was derived from:
6392 + *   Paul Miller <pmiller9@users.sourceforge.net>'s 2003-2004
6393 + *      "lirc_atiusb - USB remote support for LIRC"
6394 + *   Culver Consulting Services <henry@culcon.com>'s 2003
6395 + *      "Sasem OnAir VFD/IR USB driver"
6396 + *
6397 + *
6398 + * 2004/06/13  -       1st version
6399 + *
6400 + * TODO
6401 + *     - keypresses seem to be rather sluggish sometimes; check
6402 + *       intervall and timing
6403 + *     - simulate USBLCD device to work with LCDProc
6404 + *     - include fs operations
6405 + *     - analyse LCD command set
6406 + *     - check USB Minor allocation
6407 + *     - param to enable/disable LIRC communication (??)
6408 + *
6409 + */
6410 +
6411 +/*
6412 + *  This program is free software; you can redistribute it and/or modify
6413 + *  it under the terms of the GNU General Public License as published by
6414 + *  the Free Software Foundation; either version 2 of the License, or
6415 + *  (at your option) any later version.
6416 + *
6417 + *  This program is distributed in the hope that it will be useful,
6418 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
6419 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6420 + *  GNU General Public License for more details.
6421 + *
6422 + *  You should have received a copy of the GNU General Public License
6423 + *  along with this program; if not, write to the Free Software
6424 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
6425 + */
6426 +
6427 +#include <linux/module.h>
6428 +#include <linux/kmod.h>
6429 +#include <linux/kernel.h>
6430 +#include <linux/usb.h>
6431 +#include <linux/init.h>
6432 +#include <linux/slab.h>
6433 +#include <linux/sched.h>
6434 +#include <asm/uaccess.h>
6435 +#include <asm/atomic.h>
6436 +#include <linux/poll.h>
6437 +#include "lirc_sasem.h"
6438 +
6439 +#include <linux/lirc.h>
6440 +#include "lirc_dev.h"
6441 +
6442 +MODULE_AUTHOR( DRIVER_AUTHOR );
6443 +MODULE_DESCRIPTION( DRIVER_DESC );
6444 +MODULE_LICENSE("GPL");
6445 +
6446 +static int debug = 0;
6447 +
6448 +MODULE_PARM(debug, "i");
6449 +MODULE_PARM_DESC(debug, "enable debug = 1, disable = 0 (default)");
6450 +
6451 +static t_usb_device_id s_sasemID [] = {
6452 +       { USB_DEVICE(0x11ba, 0x0101) },
6453 +       { }
6454 +};
6455 +MODULE_DEVICE_TABLE (usb, s_sasemID);
6456 +
6457 +static t_usb_driver s_SasemDriver =
6458 +{
6459 +       owner:                  THIS_MODULE,
6460 +       name:                   "Sasem",
6461 +       probe:                  s_sasemProbe,
6462 +       disconnect:             s_sasemDisconnect,
6463 +       minor:                  SASEM_MINOR,
6464 +       id_table:               s_sasemID,
6465 +};
6466 +
6467 +static int __init s_sasemInit (void)
6468 +{
6469 +       printk(BANNER);
6470 +
6471 +       if (usb_register(&s_SasemDriver)) {
6472 +               printk("USB registration failed");
6473 +               return -ENOSYS;
6474 +       }
6475 +
6476 +       return 0;
6477 +}
6478 +
6479 +static void __exit s_sasemExit (void)
6480 +{
6481 +       usb_deregister (&s_SasemDriver);
6482 +}
6483 +
6484 +module_init (s_sasemInit);
6485 +module_exit (s_sasemExit);
6486 +
6487 +static void * s_sasemProbe(t_usb_device *p_dev, unsigned p_iInterfaceNum,
6488 +                          const t_usb_device_id *p_id)
6489 +{
6490 +       t_sasemDevice *l_sasemDevice = NULL;
6491 +       t_usb_endpoint_descriptor *l_endpoint;
6492 +       t_usb_interface_descriptor *l_currentInterfaceDescriptor;
6493 +       int l_iPipe;
6494 +       int l_iDevnum;
6495 +       t_lirc_plugin *l_lircPlugin = NULL;
6496 +       t_lirc_buffer *l_lircBuffer = NULL;
6497 +       int l_iLircMinor = -1;
6498 +       int l_iMemFailure;
6499 +       char l_cBuf[63], l_cName[128]="";
6500 +
6501 +       if (debug) printk("onair probe\n");
6502 +       
6503 +       l_currentInterfaceDescriptor = p_dev->actconfig->interface->
6504 +               altsetting;
6505 +       l_endpoint = l_currentInterfaceDescriptor->endpoint;
6506 +       
6507 +       if (!(l_endpoint->bEndpointAddress & 0x80) ||
6508 +               ((l_endpoint->bmAttributes & 3) != 0x03)) {
6509 +               printk("OnAir config endpoint error");
6510 +               return NULL;
6511 +       }
6512 +
6513 +       l_iDevnum = p_dev->devnum;
6514 +
6515 +       l_iMemFailure = 0;
6516 +       if (!(l_sasemDevice = kmalloc(sizeof(t_sasemDevice), GFP_KERNEL))) {
6517 +               printk("kmalloc(sizeof(t_sasemDevice), GFP_KERNEL)) failed");
6518 +               l_iMemFailure = 1;
6519 +       }
6520 +       else {
6521 +               memset(l_sasemDevice, 0, sizeof(t_sasemDevice));
6522 +               if (!(l_lircPlugin = kmalloc(sizeof(t_lirc_plugin), GFP_KERNEL))) {
6523 +                       printk("kmalloc(sizeof(t_lirc_plugin), GFP_KERNEL)) failed");
6524 +                       l_iMemFailure = 2;
6525 +               }
6526 +               else if (!(l_lircBuffer = kmalloc(sizeof(t_lirc_buffer), GFP_KERNEL))) {
6527 +                       printk("kmalloc(sizeof(t_lirc_buffer), GFP_KERNEL)) failed");
6528 +                       l_iMemFailure = 3;
6529 +               }
6530 +               else if (lirc_buffer_init(l_lircBuffer, MAX_INTERRUPT_DATA, 4)) {
6531 +                       printk("lirc_buffer_init failed");
6532 +                       l_iMemFailure = 4;
6533 +               }
6534 +               else if (!(l_sasemDevice->m_urbIn = usb_alloc_urb(0))) {
6535 +                       printk("usb_alloc_urb(0) failed");
6536 +                       l_iMemFailure = 5;
6537 +               } else {
6538 +
6539 +                       memset(l_lircPlugin, 0, sizeof(t_lirc_plugin));
6540 +                       strcpy(l_lircPlugin->name, DRIVER_NAME " ");
6541 +                       l_lircPlugin->minor = -1;
6542 +                       l_lircPlugin->code_length = MAX_INTERRUPT_DATA*8;
6543 +                       l_lircPlugin->features = LIRC_CAN_REC_LIRCCODE;
6544 +                       l_lircPlugin->data = l_sasemDevice;
6545 +                       
6546 +                       l_lircPlugin->rbuf = l_lircBuffer;
6547 +                       l_lircPlugin->set_use_inc = &s_lirc_set_use_inc;
6548 +                       l_lircPlugin->set_use_dec = &s_lirc_set_use_dec;
6549 +
6550 +                       if ((l_iLircMinor = lirc_register_plugin(l_lircPlugin)) < 0) {
6551 +                               printk("lirc_register_plugin(l_lircPlugin)) failed");
6552 +                               l_iMemFailure = 9;
6553 +                       }
6554 +               }
6555 +       }
6556 +       switch (l_iMemFailure) {
6557 +       case 9:
6558 +               usb_free_urb(l_sasemDevice->m_urbIn);
6559 +       case 5:
6560 +       case 4:
6561 +               kfree(l_lircBuffer);
6562 +       case 3:
6563 +               kfree(l_lircPlugin);
6564 +       case 2:
6565 +               kfree(l_sasemDevice);
6566 +       case 1:
6567 +               return NULL;
6568 +       }
6569 +       
6570 +       l_lircPlugin->minor = l_iLircMinor;     
6571 +       
6572 +       init_MUTEX(&l_sasemDevice->m_semLock);
6573 +       down_interruptible(&l_sasemDevice->m_semLock);
6574 +       l_sasemDevice->m_descriptorIn = l_endpoint;
6575 +       l_sasemDevice->m_device = p_dev;
6576 +       l_sasemDevice->m_lircPlugin = l_lircPlugin;
6577 +       up(&l_sasemDevice->m_semLock);
6578 +
6579 +       l_iPipe = usb_rcvintpipe(l_sasemDevice->m_device,
6580 +                                l_sasemDevice->m_descriptorIn->
6581 +                                bEndpointAddress);
6582 +       
6583 +       usb_fill_int_urb(l_sasemDevice->m_urbIn, l_sasemDevice->m_device,
6584 +                        l_iPipe, l_sasemDevice->m_cBufferIn,
6585 +                        sizeof(l_sasemDevice->m_cBufferIn),
6586 +                        s_sasemCallbackIn, l_sasemDevice, 
6587 +                        l_sasemDevice->m_descriptorIn->bInterval);
6588 +
6589 +       if (p_dev->descriptor.iManufacturer &&
6590 +           usb_string(p_dev, p_dev->descriptor.iManufacturer, l_cBuf, 63) > 0)
6591 +       {
6592 +               strncpy(l_cName, l_cBuf, 128);
6593 +       }
6594 +       if (p_dev->descriptor.iProduct &&
6595 +           usb_string(p_dev, p_dev->descriptor.iProduct, l_cBuf, 63) > 0)
6596 +       {
6597 +               snprintf(l_cName, 128, "%s %s", l_cName, l_cBuf);
6598 +       }
6599 +       printk(DRIVER_NAME "[%d]: %s on usb%d\n", l_iDevnum, l_cName,
6600 +              p_dev->bus->busnum);
6601 +
6602 +       return l_sasemDevice;
6603 +}
6604 +
6605 +
6606 +static void s_sasemDisconnect(t_usb_device *p_dev, void *p_ptr) {
6607 +       t_sasemDevice *l_sasemDevice = p_ptr;
6608 +       if (debug) printk("s_sasemDisconnect\n");
6609 +
6610 +       down_interruptible(&l_sasemDevice->m_semLock);
6611 +       usb_unlink_urb(l_sasemDevice->m_urbIn);
6612 +       usb_free_urb(l_sasemDevice->m_urbIn);
6613 +       s_unregister_from_lirc(l_sasemDevice);
6614 +       up(&l_sasemDevice->m_semLock);
6615 +       kfree (l_sasemDevice);
6616 +}
6617 +
6618 +static void s_sasemCallbackIn(t_urb *p_urb)
6619 +{
6620 +       t_sasemDevice *l_sasemDevice;
6621 +       int l_iDevnum;
6622 +       int l_iLen;
6623 +       char l_cBuf[MAX_INTERRUPT_DATA];
6624 +       int i;
6625 +
6626 +       if (debug) printk("s_sasemCallbackIn\n");
6627 +       
6628 +       if (!p_urb)
6629 +       {
6630 +               return;
6631 +       }
6632 +
6633 +       if (!(l_sasemDevice = p_urb->context)) {
6634 +               usb_unlink_urb(p_urb);
6635 +               return;
6636 +       }
6637 +
6638 +       l_iDevnum = l_sasemDevice->m_iDevnum;
6639 +       if (debug) {
6640 +               printk(DRIVER_NAME "[%d]: data received (length %d)\n",
6641 +                      l_iDevnum, p_urb->actual_length);
6642 +               printk(DRIVER_NAME 
6643 +                      " intr_callback called %x %x %x %x %x %x %x %x\n", 
6644 +                      l_sasemDevice->m_cBufferIn[0],
6645 +                      l_sasemDevice->m_cBufferIn[1],
6646 +                      l_sasemDevice->m_cBufferIn[2],
6647 +                      l_sasemDevice->m_cBufferIn[3],
6648 +                      l_sasemDevice->m_cBufferIn[4],
6649 +                      l_sasemDevice->m_cBufferIn[5],
6650 +                      l_sasemDevice->m_cBufferIn[6],
6651 +                      l_sasemDevice->m_cBufferIn[7]);
6652 +       }
6653 +
6654 +       switch (p_urb->status) {
6655 +
6656 +       /* success */
6657 +       case 0:
6658 +               l_iLen = p_urb->actual_length;
6659 +               if (l_iLen > MAX_INTERRUPT_DATA) return;
6660 +
6661 +               memcpy(l_cBuf,p_urb->transfer_buffer,l_iLen);
6662 +
6663 +               // is this needed? The OnAir device should always
6664 +               // return 8 bytes
6665 +               for (i = l_iLen; i < MAX_INTERRUPT_DATA; i++) l_cBuf[i] = 0;
6666 +
6667 +               // the OnAir device seems not to be able to signal a
6668 +               // pressed button by repeating its code. Keeping a
6669 +               // button pressed first sends the real code (e.g. 0C
6670 +               // 80 7F 41 BE 00 00 00) and then keeps sending 08 00
6671 +               // 00 00 00 00 00 00 as long as the button is pressed
6672 +               // (notice that in the real key code 80 = !7F and 41 =
6673 +               // !BE is this important? maybe for validation?) maybe
6674 +               // 08 00 00 00 00 00 00 00 is the number of presses?
6675 +               // who knows ...
6676 +               // so lets do the following: if a code != the 08 code
6677 +               // arrives, store it to repeat it if necessary for
6678 +               // LIRC. If an 08 code follows afterwards, send the
6679 +               // old code again to the buffer do this as long as the
6680 +               // 08 code is being sent
6681 +               // example:
6682 +               // Code from Remote          Lirc Buffer
6683 +               //  0C 80 7F 41 BE 00 00 00   0C 80 7F 41 BE 00 00 00
6684 +               //  08 00 00 00 00 00 00 00   0C 80 7F 41 BE 00 00 00
6685 +               //  08 00 00 00 00 00 00 00   0C 80 7F 41 BE 00 00 00
6686 +               //  08 00 00 00 00 00 00 00   0C 80 7F 41 BE 00 00 00
6687 +               //  08 00 00 00 00 00 00 00   0C 80 7F 41 BE 00 00 00
6688 +               //  0C 80 7F 40 BF 00 00 00   0C 80 7F 40 BF 00 00 00
6689 +               //  08 00 00 00 00 00 00 00   0C 80 7F 40 BF 00 00 00
6690 +               //  08 00 00 00 00 00 00 00   0C 80 7F 40 BF 00 00 00
6691 +               //  0C 80 7F 41 BE 00 00 00   0C 80 7F 41 BE 00 00 00
6692 +               
6693 +               if (memcmp(l_cBuf, sc_cSasemCode, MAX_INTERRUPT_DATA) == 0) {
6694 +                       // the repeat code is being sent, so we copy
6695 +                       // the old code to LIRC
6696 +                       if (l_sasemDevice->m_iCodeSaved != 0) {
6697 +                               memcpy(l_cBuf, &l_sasemDevice->m_cLastCode,
6698 +                                      MAX_INTERRUPT_DATA);
6699 +                       }
6700 +                       // there was no old code so what to do?
6701 +                       else {
6702 +                               // TODO
6703 +                       }
6704 +               }
6705 +               else
6706 +               {
6707 +                       // save the current valid code for repeats
6708 +                       memcpy(&l_sasemDevice->m_cLastCode, l_cBuf,
6709 +                              MAX_INTERRUPT_DATA);
6710 +                       // set flag to signal a valid code was save;
6711 +                       // just for safety reasons
6712 +                       l_sasemDevice->m_iCodeSaved = 1;
6713 +               }
6714 +               
6715 +               /* copy 1 code to lirc_buffer */
6716 +               lirc_buffer_write_1(l_sasemDevice->m_lircPlugin->rbuf,
6717 +                                   l_cBuf);
6718 +               wake_up(&l_sasemDevice->m_lircPlugin->rbuf->wait_poll);
6719 +               break;
6720 +
6721 +       /* unlink */
6722 +       case -ECONNRESET:
6723 +       case -ENOENT:
6724 +       case -ESHUTDOWN:
6725 +               usb_unlink_urb(p_urb);
6726 +               return;
6727 +       }
6728 +
6729 +       /* resubmit urb */
6730 +       usb_submit_urb(p_urb);
6731 +}
6732 +
6733 +static int s_unregister_from_lirc(t_sasemDevice *p_sasemDevice) {
6734 +       t_lirc_plugin *l_lircPlugin = p_sasemDevice->m_lircPlugin;
6735 +       int l_iDevnum;
6736 +       int l_iReturn;
6737 +
6738 +       l_iDevnum = p_sasemDevice->m_iDevnum;
6739 +       if (debug) printk(DRIVER_NAME "[%d]: unregister from lirc called\n",
6740 +                         l_iDevnum);
6741 +       
6742 +       if ((l_iReturn = lirc_unregister_plugin(l_lircPlugin->minor)) > 0) {
6743 +               printk(DRIVER_NAME "[%d]: error in lirc_unregister minor: %d\n"
6744 +                      "Trying again...\n", l_iDevnum, l_lircPlugin->minor);
6745 +               if (l_iReturn == -EBUSY) {
6746 +                       printk(DRIVER_NAME "[%d]: device is opened, "
6747 +                              "will unregister on close\n", l_iDevnum);
6748 +                       return -EAGAIN;
6749 +               }
6750 +               set_current_state(TASK_INTERRUPTIBLE);
6751 +               schedule_timeout(HZ);
6752 +
6753 +               if ((l_iReturn = lirc_unregister_plugin(l_lircPlugin->minor)) > 0) {
6754 +                       printk(DRIVER_NAME "[%d]: lirc_unregister failed\n",
6755 +                              l_iDevnum);
6756 +               }
6757 +       }
6758 +       
6759 +       if (l_iReturn != 0) {
6760 +               printk(DRIVER_NAME "[%d]: didn't free resources\n",
6761 +                      l_iDevnum);
6762 +               return -EAGAIN;
6763 +       }
6764 +       
6765 +       printk(DRIVER_NAME "[%d]: usb remote disconnected\n", l_iDevnum);
6766 +       
6767 +       lirc_buffer_free(l_lircPlugin->rbuf);
6768 +       kfree(l_lircPlugin->rbuf);
6769 +       kfree(l_lircPlugin);
6770 +       return 0;
6771 +}
6772 +
6773 +static int s_lirc_set_use_inc(void *p_data)
6774 +{
6775 +       t_sasemDevice *l_sasemDevice = p_data;
6776 +       int l_iDevnum;
6777 +
6778 +       if (!l_sasemDevice) {
6779 +               printk(DRIVER_NAME "[?]: s_lirc_set_use_inc called with no context\n");
6780 +               return -EIO;
6781 +       }
6782 +       
6783 +       l_iDevnum = l_sasemDevice->m_iDevnum;
6784 +       if (debug) printk(DRIVER_NAME "[%d]: s_lirc_set_use_inc\n", 
6785 +                         l_iDevnum);
6786 +
6787 +       if (!l_sasemDevice->m_iConnected) {
6788 +               
6789 +               /*
6790 +                       this is the trigger from LIRC to start
6791 +                       transfering data so the URB is being submitted
6792 +               */
6793 +
6794 +               if (!l_sasemDevice->m_device)
6795 +                       return -ENOENT;
6796 +               
6797 +               /* set USB device in URB */
6798 +               l_sasemDevice->m_urbIn->dev = l_sasemDevice->m_device;
6799 +               
6800 +               /* start communication by submitting URB */
6801 +               if (usb_submit_urb(l_sasemDevice->m_urbIn)) {
6802 +                       printk(DRIVER_NAME "[%d]: open result = -EIO error "
6803 +                               "submitting urb\n", l_iDevnum);
6804 +                       return -EIO;
6805 +               }
6806 +               
6807 +               /* indicate that URB has been submitted */
6808 +               l_sasemDevice->m_iConnected = 1;
6809 +       }
6810 +
6811 +       return 0;
6812 +}
6813 +
6814 +static void s_lirc_set_use_dec(void *p_data) {
6815 +       t_sasemDevice *l_sasemDevice = p_data;
6816 +       int l_iDevnum;
6817 +
6818 +       if (!l_sasemDevice) {
6819 +               printk(DRIVER_NAME "[?]: s_lirc_set_use_dec called with no context\n");
6820 +               return;
6821 +       }
6822 +
6823 +       l_iDevnum = l_sasemDevice->m_iDevnum;
6824 +       if (debug) printk(DRIVER_NAME "[%d]: s_lirc_set_use_dec\n", 
6825 +                         l_iDevnum);
6826 +
6827 +       if (l_sasemDevice->m_iConnected) {
6828 +
6829 +               /*
6830 +                       URB has been submitted before so it can be unlinked
6831 +               */
6832 +
6833 +               down_interruptible(&l_sasemDevice->m_semLock);
6834 +               usb_unlink_urb(l_sasemDevice->m_urbIn);
6835 +               l_sasemDevice->m_iConnected = 0;
6836 +               up(&l_sasemDevice->m_semLock);
6837 +       }
6838 +}
6839 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_sasem.h linux-2.6.8-rc4/drivers/char/lirc/lirc_sasem.h
6840 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_sasem.h 1970-01-01 01:00:00.000000000 +0100
6841 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_sasem.h      2004-06-19 08:34:35.000000000 +0200
6842 @@ -0,0 +1,70 @@
6843 +/*
6844 + * Version Information
6845 + */
6846 +#define DRIVER_VERSION                 "v0.1"
6847 +#define DATE                   "June 2004"
6848 +#define DRIVER_AUTHOR          "Oliver Stabel <oliver.stabel@gmx.de>"
6849 +#define DRIVER_DESC            "USB Driver for Sasem Remote Controller V1.1"
6850 +#define DRIVER_SHORTDESC       "Sasem"
6851 +#define DRIVER_NAME            "lirc_sasem"
6852 +
6853 +#define BANNER \
6854 +  KERN_INFO DRIVER_SHORTDESC " " DRIVER_VERSION " (" DATE ")\n" \
6855 +  KERN_INFO "   by " DRIVER_AUTHOR "\n"
6856 +
6857 +static const char longbanner[] = {
6858 +       DRIVER_DESC ", " DRIVER_VERSION " (" DATE "), by " DRIVER_AUTHOR
6859 +};
6860 +
6861 +#define MAX_INTERRUPT_DATA 8
6862 +#define SASEM_MINOR 144
6863 +
6864 +static const char sc_cSasemCode[MAX_INTERRUPT_DATA] =
6865 +       { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
6866 +
6867 +typedef struct usb_driver t_usb_driver, *tp_usb_driver;
6868 +typedef struct usb_device t_usb_device, *tp_usb_device;
6869 +typedef struct usb_interface t_usb_interface, *tp_usb_interface;
6870 +typedef struct usb_device_id t_usb_device_id, *tp_usb_device_id;
6871 +typedef struct usb_host_interface t_usb_host_interface,
6872 +       *tp_usb_host_interface;
6873 +typedef struct usb_interface_descriptor t_usb_interface_descriptor,
6874 +       *tp_usb_interface_descriptor;
6875 +typedef struct usb_endpoint_descriptor t_usb_endpoint_descriptor,
6876 +       *tp_usb_endpoint_descriptor;
6877 +typedef struct urb t_urb, *tp_urb;
6878 +
6879 +typedef struct semaphore t_semaphore, *tp_semaphore;
6880 +
6881 +typedef struct lirc_plugin t_lirc_plugin, *tp_lirc_plugin;
6882 +typedef struct lirc_buffer t_lirc_buffer;
6883 +
6884 +struct sasemDevice {
6885 +       t_usb_device *m_device;
6886 +       t_usb_endpoint_descriptor *m_descriptorIn;
6887 +       t_usb_endpoint_descriptor *m_descriptorOut;
6888 +       t_urb *m_urbIn;
6889 +       t_urb *m_urbOut;
6890 +       unsigned int m_iInterfaceNum;
6891 +       int     m_iDevnum;
6892 +       unsigned char m_cBufferIn[MAX_INTERRUPT_DATA];
6893 +       t_semaphore m_semLock;
6894 +
6895 +       char m_cLastCode[MAX_INTERRUPT_DATA];
6896 +       int m_iCodeSaved;
6897 +       
6898 +       /* lirc */
6899 +       t_lirc_plugin *m_lircPlugin;
6900 +       int m_iConnected;
6901 +};
6902 +
6903 +typedef struct sasemDevice t_sasemDevice, *tp_sasemDevice;
6904 +
6905 +static void* s_sasemProbe(t_usb_device *p_dev, unsigned p_iInterfaceNum,
6906 +                         const t_usb_device_id *p_id);
6907 +static void s_sasemDisconnect(t_usb_device *p_dev, void *p_ptr);
6908 +static void s_sasemCallbackIn(t_urb *p_urb);
6909 +
6910 +static int s_unregister_from_lirc(t_sasemDevice *p_sasemDevice);
6911 +static int s_lirc_set_use_inc(void *p_data);
6912 +static void s_lirc_set_use_dec(void *p_data);
6913 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_serial.c linux-2.6.8-rc4/drivers/char/lirc/lirc_serial.c
6914 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_serial.c        1970-01-01 01:00:00.000000000 +0100
6915 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_serial.c     2004-04-24 21:59:07.000000000 +0200
6916 @@ -0,0 +1,1100 @@
6917 +/*      $Id$      */
6918 +
6919 +/****************************************************************************
6920 + ** lirc_serial.c ***********************************************************
6921 + ****************************************************************************
6922 + *
6923 + * lirc_serial - Device driver that records pulse- and pause-lengths
6924 + *               (space-lengths) between DDCD event on a serial port.
6925 + *
6926 + * Copyright (C) 1996,97 Ralph Metzler <rjkm@thp.uni-koeln.de>
6927 + * Copyright (C) 1998 Trent Piepho <xyzzy@u.washington.edu>
6928 + * Copyright (C) 1998 Ben Pfaff <blp@gnu.org>
6929 + * Copyright (C) 1999 Christoph Bartelmus <lirc@bartelmus.de>
6930 + *
6931 + *  This program is free software; you can redistribute it and/or modify
6932 + *  it under the terms of the GNU General Public License as published by
6933 + *  the Free Software Foundation; either version 2 of the License, or
6934 + *  (at your option) any later version.
6935 + *
6936 + *  This program is distributed in the hope that it will be useful,
6937 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
6938 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6939 + *  GNU General Public License for more details.
6940 + *
6941 + *  You should have received a copy of the GNU General Public License
6942 + *  along with this program; if not, write to the Free Software
6943 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
6944 + *
6945 + */
6946 +
6947 +/* Steve's changes to improve transmission fidelity:
6948 +     - for systems with the rdtsc instruction and the clock counter, a 
6949 +       send_pule that times the pulses directly using the counter.
6950 +       This means that the LIRC_SERIAL_TRANSMITTER_LATENCY fudge is
6951 +       not needed. Measurement shows very stable waveform, even where
6952 +       PCI activity slows the access to the UART, which trips up other
6953 +       versions.
6954 +     - For other system, non-integer-microsecond pulse/space lengths,
6955 +       done using fixed point binary. So, much more accurate carrier
6956 +       frequency.
6957 +     - fine tuned transmitter latency, taking advantage of fractional
6958 +       microseconds in previous change
6959 +     - Fixed bug in the way transmitter latency was accounted for by
6960 +       tuning the pulse lengths down - the send_pulse routine ignored
6961 +       this overhead as it timed the overall pulse length - so the
6962 +       pulse frequency was right but overall pulse length was too
6963 +       long. Fixed by accounting for latency on each pulse/space
6964 +       iteration.
6965 +
6966 +   Steve Davies <steve@daviesfam.org>  July 2001
6967 +*/
6968 +
6969 +#ifdef HAVE_CONFIG_H
6970 +# include <config.h>
6971 +#endif
6972
6973 +#include <linux/version.h>
6974 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
6975 +#error "**********************************************************"
6976 +#error " Sorry, this driver needs kernel version 2.2.18 or higher "
6977 +#error "**********************************************************"
6978 +#endif
6979 +
6980 +#include <linux/config.h>
6981 +
6982 +#ifndef CONFIG_SERIAL_MODULE
6983 +#warning "******************************************"
6984 +#warning " Your serial port driver is compiled into "
6985 +#warning " the kernel. You will have to release the "
6986 +#warning " port you want to use for LIRC with:      "
6987 +#warning "    setserial /dev/ttySx uart none        "
6988 +#warning "******************************************"
6989 +#endif
6990 +
6991 +#include <linux/module.h>
6992 +#include <linux/errno.h>
6993 +#include <linux/signal.h>
6994 +#include <linux/sched.h>
6995 +#include <linux/fs.h>
6996 +#include <linux/interrupt.h>
6997 +#include <linux/ioport.h>
6998 +#include <linux/kernel.h>
6999 +#include <linux/major.h>
7000 +#include <linux/serial_reg.h>
7001 +#include <linux/time.h>
7002 +#include <linux/string.h>
7003 +#include <linux/types.h>
7004 +#include <linux/wait.h>
7005 +#include <linux/mm.h>
7006 +#include <linux/delay.h>
7007 +#include <linux/poll.h>
7008 +
7009 +#include <asm/system.h>
7010 +#include <asm/segment.h>
7011 +#include <asm/io.h>
7012 +#include <asm/irq.h>
7013 +#include <asm/fcntl.h>
7014 +
7015 +#include <linux/lirc.h>
7016 +#include "kcompat.h"
7017 +#include "lirc_dev.h"
7018 +
7019 +#if defined(LIRC_SERIAL_SOFTCARRIER) && !defined(LIRC_SERIAL_TRANSMITTER)
7020 +#warning "Software carrier only affects transmitting"
7021 +#endif
7022 +
7023 +#if defined(rdtsc)
7024 +
7025 +#define USE_RDTSC
7026 +#warning "Note: using rdtsc instruction"
7027 +#endif
7028 +
7029 +#ifdef LIRC_SERIAL_ANIMAX
7030 +#ifdef LIRC_SERIAL_TRANSMITTER
7031 +#warning "******************************************"
7032 +#warning " This receiver does not have a            "
7033 +#warning " transmitter diode                        "
7034 +#warning "******************************************"
7035 +#endif
7036 +#endif
7037 +
7038 +struct lirc_serial
7039 +{
7040 +       int type;
7041 +       int signal_pin;
7042 +       int signal_pin_change;
7043 +       int on;
7044 +       int off;
7045 +       long (*send_pulse)(unsigned long length);
7046 +       void (*send_space)(long length);
7047 +       int features;
7048 +};
7049 +
7050 +#define LIRC_HOMEBREW        0
7051 +#define LIRC_IRDEO           1
7052 +#define LIRC_IRDEO_REMOTE    2
7053 +#define LIRC_ANIMAX          3
7054 +#define LIRC_IGOR            4
7055 +
7056 +#ifdef LIRC_SERIAL_IRDEO
7057 +int type=LIRC_IRDEO;
7058 +#elif defined(LIRC_SERIAL_IRDEO_REMOTE)
7059 +int type=LIRC_IRDEO_REMOTE;
7060 +#elif defined(LIRC_SERIAL_ANIMAX)
7061 +int type=LIRC_ANIMAX;
7062 +#elif defined(LIRC_SERIAL_IGOR)
7063 +int type=LIRC_IGOR;
7064 +#else
7065 +int type=LIRC_HOMEBREW;
7066 +#endif
7067 +
7068 +#ifdef LIRC_SERIAL_SOFTCARRIER
7069 +int softcarrier=1;
7070 +#else
7071 +int softcarrier=0;
7072 +#endif
7073 +
7074 +/* forward declarations */
7075 +long send_pulse_irdeo(unsigned long length);
7076 +long send_pulse_homebrew(unsigned long length);
7077 +void send_space_irdeo(long length);
7078 +void send_space_homebrew(long length);
7079 +
7080 +struct lirc_serial hardware[]=
7081 +{
7082 +       /* home-brew receiver/transmitter */
7083 +       {
7084 +               LIRC_HOMEBREW,
7085 +               UART_MSR_DCD,
7086 +               UART_MSR_DDCD,
7087 +               UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR,
7088 +               UART_MCR_RTS|UART_MCR_OUT2,
7089 +               send_pulse_homebrew,
7090 +               send_space_homebrew,
7091 +               (
7092 +#ifdef LIRC_SERIAL_TRANSMITTER
7093 +                LIRC_CAN_SET_SEND_DUTY_CYCLE|
7094 +                LIRC_CAN_SET_SEND_CARRIER|
7095 +                LIRC_CAN_SEND_PULSE|
7096 +#endif
7097 +                LIRC_CAN_REC_MODE2)
7098 +       },
7099 +       
7100 +       /* IRdeo classic */
7101 +       {
7102 +               LIRC_IRDEO,
7103 +               UART_MSR_DSR,
7104 +               UART_MSR_DDSR,
7105 +               UART_MCR_OUT2,
7106 +               UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2,
7107 +               send_pulse_irdeo,
7108 +               send_space_irdeo,
7109 +               (LIRC_CAN_SET_SEND_DUTY_CYCLE|
7110 +                LIRC_CAN_SEND_PULSE|
7111 +                LIRC_CAN_REC_MODE2)
7112 +       },
7113 +       
7114 +       /* IRdeo remote */
7115 +       {
7116 +               LIRC_IRDEO_REMOTE,
7117 +               UART_MSR_DSR,
7118 +               UART_MSR_DDSR,
7119 +               UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2,
7120 +               UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2,
7121 +               send_pulse_irdeo,
7122 +               send_space_irdeo,
7123 +               (LIRC_CAN_SET_SEND_DUTY_CYCLE|
7124 +                LIRC_CAN_SEND_PULSE|
7125 +                LIRC_CAN_REC_MODE2)
7126 +       },
7127 +       
7128 +       /* AnimaX */
7129 +       {
7130 +               LIRC_ANIMAX,
7131 +               UART_MSR_DCD,
7132 +               UART_MSR_DDCD,
7133 +               0,
7134 +               UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2,
7135 +               NULL,
7136 +               NULL,
7137 +               LIRC_CAN_REC_MODE2
7138 +       },
7139 +       
7140 +       /* home-brew receiver/transmitter (Igor Cesko's variation) */
7141 +       {
7142 +               LIRC_HOMEBREW,
7143 +               UART_MSR_DSR,
7144 +               UART_MSR_DDSR,
7145 +               UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR,
7146 +               UART_MCR_RTS|UART_MCR_OUT2,
7147 +               send_pulse_homebrew,
7148 +               send_space_homebrew,
7149 +               (
7150 +#ifdef LIRC_SERIAL_TRANSMITTER
7151 +                LIRC_CAN_SET_SEND_DUTY_CYCLE|
7152 +                LIRC_CAN_SET_SEND_CARRIER|
7153 +                LIRC_CAN_SEND_PULSE|
7154 +#endif
7155 +                LIRC_CAN_REC_MODE2)
7156 +       }
7157 +       
7158 +};
7159 +
7160 +#define LIRC_DRIVER_NAME "lirc_serial"
7161 +
7162 +#define RS_ISR_PASS_LIMIT 256
7163 +
7164 +/* A long pulse code from a remote might take upto 300 bytes.  The
7165 +   daemon should read the bytes as soon as they are generated, so take
7166 +   the number of keys you think you can push before the daemon runs
7167 +   and multiply by 300.  The driver will warn you if you overrun this
7168 +   buffer.  If you have a slow computer or non-busmastering IDE disks,
7169 +   maybe you will need to increase this.  */
7170 +
7171 +/* This MUST be a power of two!  It has to be larger than 1 as well. */
7172 +
7173 +#define RBUF_LEN 256
7174 +#define WBUF_LEN 256
7175 +
7176 +static int sense = -1;   /* -1 = auto, 0 = active high, 1 = active low */
7177 +
7178 +static spinlock_t lirc_lock = SPIN_LOCK_UNLOCKED;
7179 +
7180 +static int io = CONFIG_LIRC_PORT_SERIAL;
7181 +static int irq = CONFIG_LIRC_IRQ_SERIAL;
7182 +
7183 +static struct timeval lasttv = {0, 0};
7184 +
7185 +static struct lirc_buffer rbuf;
7186 +
7187 +static lirc_t wbuf[WBUF_LEN];
7188 +
7189 +unsigned int freq = 38000;
7190 +unsigned int duty_cycle = 50;
7191 +
7192 +/* Initialized in init_timing_params() */
7193 +unsigned long period = 0;
7194 +unsigned long pulse_width = 0;
7195 +unsigned long space_width = 0;
7196 +
7197 +#if defined(__i386__)
7198 +/*
7199 +  From:
7200 +  Linux I/O port programming mini-HOWTO
7201 +  Author: Riku Saikkonen <Riku.Saikkonen@hut.fi>
7202 +  v, 28 December 1997
7203 +  
7204 +  [...]
7205 +  Actually, a port I/O instruction on most ports in the 0-0x3ff range
7206 +  takes almost exactly 1 microsecond, so if you're, for example, using
7207 +  the parallel port directly, just do additional inb()s from that port
7208 +  to delay.
7209 +  [...]
7210 +*/
7211 +/* transmitter latency 1.5625us 0x1.90 - this figure arrived at from
7212 + * comment above plus trimming to match actual measured frequency.
7213 + * This will be sensitive to cpu speed, though hopefully most of the 1.5us
7214 + * is spent in the uart access.  Still - for reference test machine was a
7215 + * 1.13GHz Athlon system - Steve
7216 + */
7217 +
7218 +/* changed from 400 to 450 as this works better on slower machines;
7219 +   faster machines will use the rdtsc code anyway */
7220 +
7221 +#define LIRC_SERIAL_TRANSMITTER_LATENCY 450
7222 +
7223 +#else
7224 +
7225 +/* does anybody have information on other platforms ? */
7226 +/* 256 = 1<<8 */
7227 +#define LIRC_SERIAL_TRANSMITTER_LATENCY 256
7228 +
7229 +#endif  /* __i386__ */
7230 +
7231 +static inline unsigned int sinp(int offset)
7232 +{
7233 +       return inb(io + offset);
7234 +}
7235 +
7236 +static inline void soutp(int offset, int value)
7237 +{
7238 +       outb(value, io + offset);
7239 +}
7240 +
7241 +static inline void on(void)
7242 +{
7243 +       soutp(UART_MCR,hardware[type].on);
7244 +}
7245 +  
7246 +static inline void off(void)
7247 +{
7248 +       soutp(UART_MCR,hardware[type].off);
7249 +}
7250 +
7251 +#ifndef MAX_UDELAY_MS
7252 +#define MAX_UDELAY_US 5000
7253 +#else
7254 +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000)
7255 +#endif
7256 +
7257 +static inline void safe_udelay(unsigned long usecs)
7258 +{
7259 +       while(usecs>MAX_UDELAY_US)
7260 +       {
7261 +               udelay(MAX_UDELAY_US);
7262 +               usecs-=MAX_UDELAY_US;
7263 +       }
7264 +       udelay(usecs);
7265 +}
7266 +
7267 +#ifdef USE_RDTSC
7268 +/* This is an overflow/precision juggle, complicated in that we can't
7269 +   do long long divide in the kernel */
7270 +
7271 +/* When we use the rdtsc instruction to measure clocks, we keep the
7272 + * pulse and space widths as clock cycles.  As this is CPU speed
7273 + * dependent, the widths must be calculated in init_port and ioctl
7274 + * time
7275 + */
7276 +
7277 +/* So send_pulse can quickly convert microseconds to clocks */
7278 +unsigned long conv_us_to_clocks = 0;
7279 +
7280 +static inline int init_timing_params(unsigned int new_duty_cycle,
7281 +               unsigned int new_freq)
7282 +{
7283 +       unsigned long long loops_per_sec,work;
7284 +       
7285 +       duty_cycle=new_duty_cycle;
7286 +       freq=new_freq;
7287 +
7288 +       loops_per_sec=current_cpu_data.loops_per_jiffy;
7289 +       loops_per_sec*=HZ;
7290 +       
7291 +       /* How many clocks in a microsecond?, avoiding long long divide */
7292 +       work=loops_per_sec;
7293 +       work*=4295;  /* 4295 = 2^32 / 1e6 */
7294 +       conv_us_to_clocks=(work>>32);
7295 +       
7296 +       /* Carrier period in clocks, approach good up to 32GHz clock,
7297 +           gets carrier frequency within 8Hz */
7298 +       period=loops_per_sec>>3;
7299 +       period/=(freq>>3);
7300 +
7301 +       /* Derive pulse and space from the period */
7302 +
7303 +       pulse_width = period*duty_cycle/100;
7304 +       space_width = period - pulse_width;
7305 +#ifdef DEBUG
7306 +       printk(KERN_INFO LIRC_DRIVER_NAME
7307 +              ": in init_timing_params, freq=%d, duty_cycle=%d, "
7308 +              "clk/jiffy=%ld, pulse=%ld, space=%ld, conv_us_to_clocks=%ld\n",
7309 +              freq, duty_cycle, current_cpu_data.loops_per_jiffy,
7310 +              pulse_width, space_width, conv_us_to_clocks);
7311 +#endif
7312 +       return 0;
7313 +}
7314 +#else /* ! USE_RDTSC */
7315 +static inline int init_timing_params(unsigned int new_duty_cycle,
7316 +               unsigned int new_freq)
7317 +{
7318 +/* period, pulse/space width are kept with 8 binary places -
7319 + * IE multiplied by 256. */
7320 +       if(256*1000000L/new_freq*new_duty_cycle/100<=
7321 +          LIRC_SERIAL_TRANSMITTER_LATENCY) return(-EINVAL);
7322 +       if(256*1000000L/new_freq*(100-new_duty_cycle)/100<=
7323 +          LIRC_SERIAL_TRANSMITTER_LATENCY) return(-EINVAL);
7324 +       duty_cycle=new_duty_cycle;
7325 +       freq=new_freq;
7326 +       period=256*1000000L/freq;
7327 +       pulse_width=period*duty_cycle/100;
7328 +       space_width=period-pulse_width;
7329 +#ifdef DEBUG
7330 +       printk(KERN_WARNING LIRC_DRIVER_NAME
7331 +              ": in init_timing_params, freq=%d pulse=%ld, "
7332 +              "space=%ld\n", freq, pulse_width, space_width);
7333 +#endif
7334 +       return 0;
7335 +}
7336 +#endif /* USE_RDTSC */
7337 +
7338 +
7339 +/* return value: space length delta */
7340 +
7341 +long send_pulse_irdeo(unsigned long length)
7342 +{
7343 +       long rawbits;
7344 +       int i;
7345 +       unsigned char output;
7346 +       unsigned char chunk,shifted;
7347 +       
7348 +       /* how many bits have to be sent ? */
7349 +       rawbits=length*1152/10000;
7350 +       if(duty_cycle>50) chunk=3;
7351 +       else chunk=1;
7352 +       for(i=0,output=0x7f;rawbits>0;rawbits-=3)
7353 +       {
7354 +               shifted=chunk<<(i*3);
7355 +               shifted>>=1;
7356 +               output&=(~shifted);
7357 +               i++;
7358 +               if(i==3)
7359 +               {
7360 +                       soutp(UART_TX,output);
7361 +                       while(!(sinp(UART_LSR) & UART_LSR_THRE));
7362 +                       output=0x7f;
7363 +                       i=0;
7364 +               }
7365 +       }
7366 +       if(i!=0)
7367 +       {
7368 +               soutp(UART_TX,output);
7369 +               while(!(sinp(UART_LSR) & UART_LSR_TEMT));
7370 +       }
7371 +
7372 +       if(i==0)
7373 +       {
7374 +               return((-rawbits)*10000/1152);
7375 +       }
7376 +       else
7377 +       {
7378 +               return((3-i)*3*10000/1152+(-rawbits)*10000/1152);
7379 +       }
7380 +}
7381 +
7382 +#ifdef USE_RDTSC
7383 +/* Version that uses Pentium rdtsc instruction to measure clocks */
7384 +
7385 +/* This version does sub-microsecond timing using rdtsc instruction,
7386 + * and does away with the fudged LIRC_SERIAL_TRANSMITTER_LATENCY
7387 + * Implicitly i586 architecture...  - Steve
7388 + */
7389 +
7390 +static inline long send_pulse_homebrew_softcarrier(unsigned long length)
7391 +{
7392 +       int flag;
7393 +       unsigned long target, start, now;
7394 +
7395 +       /* Get going quick as we can */
7396 +       rdtscl(start);on();
7397 +       /* Convert length from microseconds to clocks */
7398 +       length*=conv_us_to_clocks;
7399 +       /* And loop till time is up - flipping at right intervals */
7400 +       now=start;
7401 +       target=pulse_width;
7402 +       flag=1;
7403 +       while((now-start)<length)
7404 +       {
7405 +               /* Delay till flip time */
7406 +               do
7407 +               {
7408 +                       rdtscl(now);
7409 +               }
7410 +               while ((now-start)<target);
7411 +               /* flip */
7412 +               if(flag)
7413 +               {
7414 +                       rdtscl(now);off();
7415 +                       target+=space_width;
7416 +               }
7417 +               else
7418 +               {
7419 +                       rdtscl(now);on();
7420 +                       target+=pulse_width;
7421 +               }
7422 +               flag=!flag;
7423 +       }
7424 +       rdtscl(now);
7425 +       return(((now-start)-length)/conv_us_to_clocks);
7426 +}
7427 +#else /* ! USE_RDTSC */
7428 +/* Version using udelay() */
7429 +
7430 +/* here we use fixed point arithmetic, with 8
7431 +   fractional bits.  that gets us within 0.1% or so of the right average
7432 +   frequency, albeit with some jitter in pulse length - Steve */
7433 +
7434 +/* To match 8 fractional bits used for pulse/space length */
7435 +
7436 +static inline long send_pulse_homebrew_softcarrier(unsigned long length)
7437 +{
7438 +       int flag;
7439 +       unsigned long actual, target, d;
7440 +       length<<=8;
7441 +
7442 +       actual=target=0; flag=0;
7443 +       while(actual<length)
7444 +       {
7445 +               if(flag)
7446 +               {
7447 +                       off();
7448 +                       target+=space_width;
7449 +               }
7450 +               else
7451 +               {
7452 +                       on();
7453 +                       target+=pulse_width;
7454 +               }
7455 +               d=(target-actual-LIRC_SERIAL_TRANSMITTER_LATENCY+128)>>8;
7456 +               /* Note - we've checked in ioctl that the pulse/space
7457 +                  widths are big enough so that d is > 0 */
7458 +               udelay(d);
7459 +               actual+=(d<<8)+LIRC_SERIAL_TRANSMITTER_LATENCY;
7460 +               flag=!flag;
7461 +       }
7462 +       return((actual-length)>>8);
7463 +}
7464 +#endif /* USE_RDTSC */
7465 +
7466 +long send_pulse_homebrew(unsigned long length)
7467 +{
7468 +       if(length<=0) return 0;
7469 +       if(softcarrier)
7470 +       {
7471 +               return send_pulse_homebrew_softcarrier(length);
7472 +       }
7473 +       else
7474 +       {
7475 +               on();
7476 +               safe_udelay(length);
7477 +               return(0);
7478 +       }
7479 +}
7480 +
7481 +void send_space_irdeo(long length)
7482 +{
7483 +       if(length<=0) return;
7484 +       safe_udelay(length);
7485 +}
7486 +
7487 +void send_space_homebrew(long length)
7488 +{
7489 +        off();
7490 +       if(length<=0) return;
7491 +       safe_udelay(length);
7492 +}
7493 +
7494 +static void inline rbwrite(lirc_t l)
7495 +{
7496 +       if(lirc_buffer_full(&rbuf))    /* no new signals will be accepted */
7497 +       {
7498 +#               ifdef DEBUG
7499 +               printk(KERN_WARNING  LIRC_DRIVER_NAME  ": Buffer overrun\n");
7500 +#               endif
7501 +               return;
7502 +       }
7503 +       _lirc_buffer_write_1(&rbuf, (void *)&l);
7504 +}
7505 +
7506 +static void inline frbwrite(lirc_t l)
7507 +{
7508 +       /* simple noise filter */
7509 +       static lirc_t pulse=0L,space=0L;
7510 +       static unsigned int ptr=0;
7511 +       
7512 +       if(ptr>0 && (l&PULSE_BIT))
7513 +       {
7514 +               pulse+=l&PULSE_MASK;
7515 +               if(pulse>250)
7516 +               {
7517 +                       rbwrite(space);
7518 +                       rbwrite(pulse|PULSE_BIT);
7519 +                       ptr=0;
7520 +                       pulse=0;
7521 +               }
7522 +               return;
7523 +       }
7524 +       if(!(l&PULSE_BIT))
7525 +       {
7526 +               if(ptr==0)
7527 +               {
7528 +                       if(l>20000)
7529 +                       {
7530 +                               space=l;
7531 +                               ptr++;
7532 +                               return;
7533 +                       }
7534 +               }
7535 +               else
7536 +               {
7537 +                       if(l>20000)
7538 +                       {
7539 +                               space+=pulse;
7540 +                               if(space>PULSE_MASK) space=PULSE_MASK;
7541 +                               space+=l;
7542 +                               if(space>PULSE_MASK) space=PULSE_MASK;
7543 +                               pulse=0;
7544 +                               return;
7545 +                       }
7546 +                       rbwrite(space);
7547 +                       rbwrite(pulse|PULSE_BIT);
7548 +                       ptr=0;
7549 +                       pulse=0;
7550 +               }
7551 +       }
7552 +       rbwrite(l);
7553 +}
7554 +
7555 +irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs)
7556 +{
7557 +       struct timeval tv;
7558 +       int status,counter,dcd;
7559 +       long deltv;
7560 +       lirc_t data;
7561 +       
7562 +       counter=0;
7563 +       do{
7564 +               counter++;
7565 +               status=sinp(UART_MSR);
7566 +               if(counter>RS_ISR_PASS_LIMIT)
7567 +               {
7568 +                       printk(KERN_WARNING LIRC_DRIVER_NAME ": AIEEEE: "
7569 +                              "We're caught!\n");
7570 +                       break;
7571 +               }
7572 +               if((status&hardware[type].signal_pin_change) && sense!=-1)
7573 +               {
7574 +                       /* get current time */
7575 +                       do_gettimeofday(&tv);
7576 +                       
7577 +                       /* New mode, written by Trent Piepho 
7578 +                          <xyzzy@u.washington.edu>. */
7579 +                       
7580 +                       /* The old format was not very portable.
7581 +                          We now use the type lirc_t to pass pulses
7582 +                          and spaces to user space.
7583 +                          
7584 +                          If PULSE_BIT is set a pulse has been
7585 +                          received, otherwise a space has been
7586 +                          received.  The driver needs to know if your
7587 +                          receiver is active high or active low, or
7588 +                          the space/pulse sense could be
7589 +                          inverted. The bits denoted by PULSE_MASK are
7590 +                          the length in microseconds. Lengths greater
7591 +                          than or equal to 16 seconds are clamped to
7592 +                          PULSE_MASK.  All other bits are unused.
7593 +                          This is a much simpler interface for user
7594 +                          programs, as well as eliminating "out of
7595 +                          phase" errors with space/pulse
7596 +                          autodetection. */
7597 +
7598 +                       /* calculate time since last interrupt in
7599 +                          microseconds */
7600 +                       dcd=(status & hardware[type].signal_pin) ? 1:0;
7601 +                       
7602 +                       deltv=tv.tv_sec-lasttv.tv_sec;
7603 +                       if(deltv>15) 
7604 +                       {
7605 +#ifdef DEBUG
7606 +                               printk(KERN_WARNING LIRC_DRIVER_NAME
7607 +                                      ": AIEEEE: %d %d %lx %lx %lx %lx\n",
7608 +                                      dcd,sense,
7609 +                                      tv.tv_sec,lasttv.tv_sec,
7610 +                                      tv.tv_usec,lasttv.tv_usec);
7611 +#endif
7612 +                               data=PULSE_MASK; /* really long time */
7613 +                               if(!(dcd^sense)) /* sanity check */
7614 +                               {
7615 +                                       /* detecting pulse while this
7616 +                                          MUST be a space! */
7617 +                                       sense=sense ? 0:1;
7618 +                               }
7619 +                       }
7620 +                       else
7621 +                       {
7622 +                               data=(lirc_t) (deltv*1000000+
7623 +                                              tv.tv_usec-
7624 +                                              lasttv.tv_usec);
7625 +                       };
7626 +                       if(tv.tv_sec<lasttv.tv_sec ||
7627 +                          (tv.tv_sec==lasttv.tv_sec &&
7628 +                           tv.tv_usec<lasttv.tv_usec))
7629 +                       {
7630 +                               printk(KERN_WARNING LIRC_DRIVER_NAME
7631 +                                      ": AIEEEE: your clock just jumped "
7632 +                                      "backwards\n");
7633 +                               printk(KERN_WARNING LIRC_DRIVER_NAME
7634 +                                      ": %d %d %lx %lx %lx %lx\n",
7635 +                                      dcd,sense,
7636 +                                      tv.tv_sec,lasttv.tv_sec,
7637 +                                      tv.tv_usec,lasttv.tv_usec);
7638 +                               data=PULSE_MASK;
7639 +                       }
7640 +                       frbwrite(dcd^sense ? data : (data|PULSE_BIT));
7641 +                       lasttv=tv;
7642 +                       wake_up_interruptible(&rbuf.wait_poll);
7643 +               }
7644 +       } while(!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */
7645 +       return IRQ_RETVAL(IRQ_HANDLED);
7646 +}
7647 +
7648 +static DECLARE_WAIT_QUEUE_HEAD(power_supply_queue);
7649 +
7650 +static int init_port(void)
7651 +{
7652 +       unsigned long flags;
7653 +
7654 +        /* Check io region*/
7655 +       
7656 +        if((check_region(io,8))==-EBUSY)
7657 +       {
7658 +               printk(KERN_ERR  LIRC_DRIVER_NAME  
7659 +                      ": port %04x already in use\n", io);
7660 +               printk(KERN_WARNING LIRC_DRIVER_NAME  
7661 +                      ": use 'setserial /dev/ttySX uart none'\n");
7662 +               printk(KERN_WARNING LIRC_DRIVER_NAME  
7663 +                      ": or compile the serial port driver as module and\n");
7664 +               printk(KERN_WARNING LIRC_DRIVER_NAME  
7665 +                      ": make sure this module is loaded first\n");
7666 +               return(-EBUSY);
7667 +       }
7668 +       
7669 +       /* Reserve io region. */
7670 +       request_region(io, 8, LIRC_DRIVER_NAME);
7671 +       
7672 +       local_irq_save(flags);
7673 +       
7674 +       /* Set DLAB 0. */
7675 +       soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
7676 +       
7677 +       /* First of all, disable all interrupts */
7678 +       soutp(UART_IER, sinp(UART_IER)&
7679 +             (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI)));
7680 +       
7681 +       /* Clear registers. */
7682 +       sinp(UART_LSR);
7683 +       sinp(UART_RX);
7684 +       sinp(UART_IIR);
7685 +       sinp(UART_MSR);
7686 +       
7687 +       /* Set line for power source */
7688 +       soutp(UART_MCR, hardware[type].off);
7689 +       
7690 +       /* Clear registers again to be sure. */
7691 +       sinp(UART_LSR);
7692 +       sinp(UART_RX);
7693 +       sinp(UART_IIR);
7694 +       sinp(UART_MSR);
7695 +
7696 +       switch(hardware[type].type)
7697 +       {
7698 +       case LIRC_IRDEO:
7699 +       case LIRC_IRDEO_REMOTE:
7700 +               /* setup port to 7N1 @ 115200 Baud */
7701 +               /* 7N1+start = 9 bits at 115200 ~ 3 bits at 38kHz */
7702 +               
7703 +               /* Set DLAB 1. */
7704 +               soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB);
7705 +               /* Set divisor to 1 => 115200 Baud */
7706 +               soutp(UART_DLM,0);
7707 +               soutp(UART_DLL,1);
7708 +               /* Set DLAB 0 +  7N1 */
7709 +               soutp(UART_LCR,UART_LCR_WLEN7);
7710 +               /* THR interrupt already disabled at this point */
7711 +               break;
7712 +       default:
7713 +               break;
7714 +       }
7715 +       
7716 +       local_irq_restore(flags);
7717 +       
7718 +       /* Initialize pulse/space widths */
7719 +       init_timing_params(duty_cycle, freq);
7720 +
7721 +       /* If pin is high, then this must be an active low receiver. */
7722 +       if(sense==-1)
7723 +       {
7724 +               /* wait 1 sec for the power supply */
7725 +               
7726 +               sleep_on_timeout(&power_supply_queue,HZ);
7727 +               
7728 +               sense=(sinp(UART_MSR) & hardware[type].signal_pin) ? 1:0;
7729 +               printk(KERN_INFO  LIRC_DRIVER_NAME  ": auto-detected active "
7730 +                      "%s receiver\n",sense ? "low":"high");
7731 +       }
7732 +       else
7733 +       {
7734 +               printk(KERN_INFO  LIRC_DRIVER_NAME  ": Manually using active "
7735 +                      "%s receiver\n",sense ? "low":"high");
7736 +       };
7737 +       
7738 +       return 0;
7739 +}
7740 +
7741 +static int set_use_inc(void* data)
7742 +{
7743 +       int result;
7744 +       unsigned long flags;
7745 +       
7746 +       spin_lock(&lirc_lock);
7747 +       if(MOD_IN_USE)
7748 +       {
7749 +               spin_unlock(&lirc_lock);
7750 +               return -EBUSY;
7751 +       }
7752 +       
7753 +       /* Init read buffer. */
7754 +       if (lirc_buffer_init(&rbuf, sizeof(lirc_t), RBUF_LEN) < 0)
7755 +               return -ENOMEM;
7756 +       
7757 +       /* initialize timestamp */
7758 +       do_gettimeofday(&lasttv);
7759 +       
7760 +       result=request_irq(irq,irq_handler,SA_INTERRUPT,LIRC_DRIVER_NAME,NULL);
7761 +       switch(result)
7762 +       {
7763 +       case -EBUSY:
7764 +               printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq);
7765 +               spin_unlock(&lirc_lock);
7766 +                lirc_buffer_free(&rbuf);
7767 +               return -EBUSY;
7768 +       case -EINVAL:
7769 +               printk(KERN_ERR LIRC_DRIVER_NAME
7770 +                      ": Bad irq number or handler\n");
7771 +               spin_unlock(&lirc_lock);
7772 +                lirc_buffer_free(&rbuf);
7773 +               return -EINVAL;
7774 +       default:
7775 +#               ifdef DEBUG
7776 +               printk(KERN_INFO LIRC_DRIVER_NAME
7777 +                      ": Interrupt %d, port %04x obtained\n", irq, io);
7778 +#               endif
7779 +               break;
7780 +       };
7781 +
7782 +       local_irq_save(flags);
7783 +       
7784 +       /* Set DLAB 0. */
7785 +       soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
7786 +       
7787 +       soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI);
7788 +       
7789 +       local_irq_restore(flags);
7790 +       
7791 +       MOD_INC_USE_COUNT;
7792 +       spin_unlock(&lirc_lock);
7793 +       return 0;
7794 +}
7795 +
7796 +static void set_use_dec(void* data)
7797 +{      unsigned long flags;
7798 +       
7799 +       local_irq_save(flags);
7800 +       
7801 +       /* Set DLAB 0. */
7802 +       soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
7803 +       
7804 +       /* First of all, disable all interrupts */
7805 +       soutp(UART_IER, sinp(UART_IER)&
7806 +             (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI)));
7807 +       local_irq_restore(flags);
7808 +       
7809 +       free_irq(irq, NULL);
7810 +#       ifdef DEBUG
7811 +       printk(KERN_INFO  LIRC_DRIVER_NAME  ": freed IRQ %d\n", irq);
7812 +#       endif
7813 +       lirc_buffer_free(&rbuf);
7814 +       
7815 +       MOD_DEC_USE_COUNT;
7816 +}
7817 +
7818 +static ssize_t lirc_write(struct file *file, const char *buf,
7819 +                        size_t n, loff_t * ppos)
7820 +{
7821 +       int retval,i,count;
7822 +       unsigned long flags;
7823 +       long delta=0;
7824 +       
7825 +       if(!(hardware[type].features&LIRC_CAN_SEND_PULSE))
7826 +       {
7827 +               return(-EBADF);
7828 +       }
7829 +       
7830 +       if(n%sizeof(lirc_t)) return(-EINVAL);
7831 +       retval=verify_area(VERIFY_READ,buf,n);
7832 +       if(retval) return(retval);
7833 +       count=n/sizeof(lirc_t);
7834 +       if(count>WBUF_LEN || count%2==0) return(-EINVAL);
7835 +       copy_from_user(wbuf,buf,n);
7836 +       local_irq_save(flags);
7837 +       if(hardware[type].type==LIRC_IRDEO)
7838 +       {
7839 +               /* DTR, RTS down */
7840 +               on();
7841 +       }
7842 +       for(i=0;i<count;i++)
7843 +       {
7844 +               if(i%2) hardware[type].send_space(wbuf[i]-delta);
7845 +               else delta=hardware[type].send_pulse(wbuf[i]);
7846 +       }
7847 +       off();
7848 +       local_irq_restore(flags);
7849 +       return(n);
7850 +}
7851 +
7852 +static int lirc_ioctl(struct inode *node,struct file *filep,unsigned int cmd,
7853 +                     unsigned long arg)
7854 +{
7855 +        int result;
7856 +       unsigned long value;
7857 +       unsigned int ivalue;
7858 +       
7859 +       switch(cmd)
7860 +       {
7861 +       case LIRC_GET_SEND_MODE:
7862 +               if(!(hardware[type].features&LIRC_CAN_SEND_MASK))
7863 +               {
7864 +                       return(-ENOIOCTLCMD);
7865 +               }
7866 +               
7867 +               result=put_user(LIRC_SEND2MODE
7868 +                               (hardware[type].features&LIRC_CAN_SEND_MASK),
7869 +                               (unsigned long *) arg);
7870 +               if(result) return(result); 
7871 +               break;
7872 +               
7873 +       case LIRC_SET_SEND_MODE:
7874 +               if(!(hardware[type].features&LIRC_CAN_SEND_MASK))
7875 +               {
7876 +                       return(-ENOIOCTLCMD);
7877 +               }
7878 +               
7879 +               result=get_user(value,(unsigned long *) arg);
7880 +               if(result) return(result);
7881 +               /* only LIRC_MODE_PULSE supported */
7882 +               if(value!=LIRC_MODE_PULSE) return(-ENOSYS);
7883 +               break;
7884 +               
7885 +       case LIRC_GET_LENGTH:
7886 +               return(-ENOSYS);
7887 +               break;
7888 +               
7889 +       case LIRC_SET_SEND_DUTY_CYCLE:
7890 +#               ifdef DEBUG
7891 +               printk(KERN_WARNING LIRC_DRIVER_NAME ": SET_SEND_DUTY_CYCLE\n");
7892 +#               endif
7893 +               if(!(hardware[type].features&LIRC_CAN_SET_SEND_DUTY_CYCLE))
7894 +               {
7895 +                       return(-ENOIOCTLCMD);
7896 +               }
7897 +               
7898 +               result=get_user(ivalue,(unsigned int *) arg);
7899 +               if(result) return(result);
7900 +               if(ivalue<=0 || ivalue>100) return(-EINVAL);
7901 +               return init_timing_params(ivalue, freq);
7902 +               break;
7903 +               
7904 +       case LIRC_SET_SEND_CARRIER:
7905 +#               ifdef DEBUG
7906 +               printk(KERN_WARNING LIRC_DRIVER_NAME ": SET_SEND_CARRIER\n");
7907 +#               endif
7908 +               if(!(hardware[type].features&LIRC_CAN_SET_SEND_CARRIER))
7909 +               {
7910 +                       return(-ENOIOCTLCMD);
7911 +               }
7912 +               
7913 +               result=get_user(ivalue,(unsigned int *) arg);
7914 +               if(result) return(result);
7915 +               if(ivalue>500000 || ivalue<20000) return(-EINVAL);
7916 +               return init_timing_params(duty_cycle, ivalue);
7917 +               break;
7918 +               
7919 +       default:
7920 +               return(-ENOIOCTLCMD);
7921 +       }
7922 +       return(0);
7923 +}
7924 +
7925 +static struct file_operations lirc_fops =
7926 +{
7927 +       write:   lirc_write,
7928 +};
7929 +
7930 +static struct lirc_plugin plugin = {
7931 +       name:           LIRC_DRIVER_NAME,
7932 +       minor:          -1,
7933 +       code_length:    1,
7934 +       sample_rate:    0,
7935 +       data:           NULL,
7936 +       add_to_buf:     NULL,
7937 +       get_queue:      NULL,
7938 +       rbuf:           &rbuf,
7939 +       set_use_inc:    set_use_inc,
7940 +       set_use_dec:    set_use_dec,
7941 +       ioctl:          lirc_ioctl,
7942 +       fops:           &lirc_fops,
7943 +};
7944 +
7945 +#ifdef MODULE
7946 +
7947 +MODULE_AUTHOR("Ralph Metzler, Trent Piepho, Ben Pfaff, Christoph Bartelmus");
7948 +MODULE_DESCRIPTION("Infra-red receiver driver for serial ports.");
7949 +#ifdef MODULE_LICENSE
7950 +MODULE_LICENSE("GPL");
7951 +#endif
7952 +
7953 +MODULE_PARM(type, "i");
7954 +MODULE_PARM_DESC(type, "Hardware type (0 = home-brew, 1 = IRdeo,"
7955 +                " 2 = IRdeo Remote, 3 = AnimaX, 4 = IgorPlug");
7956 +
7957 +MODULE_PARM(io, "i");
7958 +MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)");
7959 +
7960 +MODULE_PARM(irq, "i");
7961 +MODULE_PARM_DESC(irq, "Interrupt (4 or 3)");
7962 +
7963 +MODULE_PARM(sense, "i");
7964 +MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit"
7965 +                " (0 = active high, 1 = active low )");
7966 +
7967 +MODULE_PARM(softcarrier, "i");
7968 +MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on)");
7969 +
7970 +
7971 +#ifndef KERNEL_2_5
7972 +EXPORT_NO_SYMBOLS;
7973 +#endif
7974 +
7975 +int init_module(void)
7976 +{
7977 +       int result;
7978 +       
7979 +       switch(type)
7980 +       {
7981 +       case LIRC_HOMEBREW:
7982 +       case LIRC_IRDEO:
7983 +       case LIRC_IRDEO_REMOTE:
7984 +       case LIRC_ANIMAX:
7985 +       case LIRC_IGOR:
7986 +               break;
7987 +       default:
7988 +               return(-EINVAL);
7989 +       }
7990 +       if(!softcarrier && hardware[type].type==LIRC_HOMEBREW)
7991 +       {
7992 +               hardware[type].features&=~(LIRC_CAN_SET_SEND_DUTY_CYCLE|
7993 +                                          LIRC_CAN_SET_SEND_CARRIER);
7994 +       }
7995 +       if ((result = init_port()) < 0)
7996 +               return result;
7997 +       plugin.features = hardware[type].features;
7998 +       if ((plugin.minor = lirc_register_plugin(&plugin)) < 0) {
7999 +               printk(KERN_ERR  LIRC_DRIVER_NAME  
8000 +                      ": register_chrdev failed!\n");
8001 +               release_region(io, 8);
8002 +               return -EIO;
8003 +       }
8004 +       return 0;
8005 +}
8006 +
8007 +void cleanup_module(void)
8008 +{
8009 +       release_region(io, 8);
8010 +       lirc_unregister_plugin(plugin.minor);
8011 +#       ifdef DEBUG
8012 +       printk(KERN_INFO  LIRC_DRIVER_NAME  ": cleaned up module\n");
8013 +#       endif
8014 +}
8015 +
8016 +#endif
8017 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_sir.c linux-2.6.8-rc4/drivers/char/lirc/lirc_sir.c
8018 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_sir.c   1970-01-01 01:00:00.000000000 +0100
8019 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_sir.c        2004-04-27 20:28:16.000000000 +0200
8020 @@ -0,0 +1,1321 @@
8021 +/*
8022 + * LIRC SIR driver, (C) 2000 Milan Pikula <www@fornax.sk>
8023 + *
8024 + * lirc_sir - Device driver for use with SIR (serial infra red)
8025 + * mode of IrDA on many notebooks.
8026 + *
8027 + *  This program is free software; you can redistribute it and/or modify
8028 + *  it under the terms of the GNU General Public License as published by
8029 + *  the Free Software Foundation; either version 2 of the License, or
8030 + *  (at your option) any later version.
8031 + *
8032 + *  This program is distributed in the hope that it will be useful,
8033 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
8034 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8035 + *  GNU General Public License for more details.
8036 + *
8037 + *  You should have received a copy of the GNU General Public License
8038 + *  along with this program; if not, write to the Free Software
8039 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
8040 + *
8041 + *
8042 + * 2000/09/16 Frank Przybylski <mail@frankprzybylski.de> :
8043 + *  added timeout and relaxed pulse detection, removed gap bug
8044 + *
8045 + * 2000/12/15 Christoph Bartelmus <lirc@bartelmus.de> : 
8046 + *   added support for Tekram Irmate 210 (sending does not work yet,
8047 + *   kind of disappointing that nobody was able to implement that
8048 + *   before),
8049 + *   major clean-up
8050 + *
8051 + * 2001/02/27 Christoph Bartelmus <lirc@bartelmus.de> : 
8052 + *   added support for StrongARM SA1100 embedded microprocessor
8053 + *   parts cut'n'pasted from sa1100_ir.c (C) 2000 Russell King
8054 + */
8055 +
8056 +
8057 +#include <linux/version.h>
8058 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
8059 +#error "**********************************************************"
8060 +#error " Sorry, this driver needs kernel version 2.2.18 or higher "
8061 +#error "**********************************************************"
8062 +#endif
8063 +#include <linux/module.h>
8064 +
8065 +#ifdef HAVE_CONFIG_H
8066 +# include <config.h>
8067 +#endif
8068
8069 +#include <linux/config.h>
8070 +
8071 +#if !defined(LIRC_ON_SA1100) && !defined(CONFIG_SERIAL_MODULE)
8072 +#warning "******************************************"
8073 +#warning " Your serial port driver is compiled into "
8074 +#warning " the kernel. You will have to release the "
8075 +#warning " port you want to use for LIRC with:      "
8076 +#warning "    setserial /dev/ttySx uart none        "
8077 +#warning "******************************************"
8078 +#endif
8079 +
8080 +#include <linux/sched.h>
8081 +#include <linux/errno.h>
8082 +#include <linux/signal.h>
8083 +#include <linux/fs.h>
8084 +#include <linux/interrupt.h>
8085 +#include <linux/ioport.h>
8086 +#include <linux/kernel.h>
8087 +#include <linux/major.h>
8088 +#include <linux/serial_reg.h>
8089 +#include <linux/time.h>
8090 +#include <linux/string.h>
8091 +#include <linux/types.h>
8092 +#include <linux/wait.h>
8093 +#include <linux/mm.h>
8094 +#include <linux/delay.h>
8095 +#include <linux/poll.h>
8096 +#include <asm/system.h>
8097 +#include <asm/segment.h>
8098 +#include <asm/io.h>
8099 +#include <asm/irq.h>
8100 +#include <asm/fcntl.h>
8101 +#ifdef LIRC_ON_SA1100
8102 +#include <asm/hardware.h>
8103 +#ifdef CONFIG_SA1100_COLLIE
8104 +#include <asm/arch/tc35143.h>
8105 +#include <asm/ucb1200.h>
8106 +#endif
8107 +#endif
8108 +
8109 +#include <linux/timer.h>
8110 +
8111 +#include <linux/lirc.h>
8112 +#include "lirc_dev.h"
8113 +#include "kcompat.h"
8114 +
8115 +/* SECTION: Definitions */
8116 +
8117 +/**************************** Tekram dongle ***************************/
8118 +#ifdef LIRC_SIR_TEKRAM
8119 +/* stolen from kernel source */
8120 +/* definitions for Tekram dongle */
8121 +#define TEKRAM_115200 0x00
8122 +#define TEKRAM_57600  0x01
8123 +#define TEKRAM_38400  0x02
8124 +#define TEKRAM_19200  0x03
8125 +#define TEKRAM_9600   0x04
8126 +#define TEKRAM_2400   0x08
8127 +
8128 +#define TEKRAM_PW 0x10 /* Pulse select bit */
8129 +
8130 +/* 10bit * 1s/115200bit in milli seconds = 87ms*/
8131 +#define TIME_CONST (10000000ul/115200ul)
8132 +
8133 +#endif
8134 +
8135 +#ifdef LIRC_SIR_ACTISYS_ACT200L
8136 +static void init_act200(void);
8137 +#endif
8138 +
8139 +/******************************* SA1100 ********************************/
8140 +#ifdef LIRC_ON_SA1100
8141 +struct sa1100_ser2_registers
8142 +{
8143 +       /* HSSP control register */
8144 +       unsigned char hscr0;
8145 +       /* UART registers */
8146 +       unsigned char utcr0;
8147 +       unsigned char utcr1;
8148 +       unsigned char utcr2;
8149 +       unsigned char utcr3;
8150 +       unsigned char utcr4;
8151 +       unsigned char utdr;
8152 +       unsigned char utsr0;
8153 +       unsigned char utsr1;
8154 +} sr;
8155 +
8156 +static int irq=IRQ_Ser2ICP;
8157 +
8158 +#define LIRC_ON_SA1100_TRANSMITTER_LATENCY 0
8159 +
8160 +/* pulse/space ratio of 50/50 */
8161 +unsigned long pulse_width = (13-LIRC_ON_SA1100_TRANSMITTER_LATENCY);
8162 +/* 1000000/freq-pulse_width */
8163 +unsigned long space_width = (13-LIRC_ON_SA1100_TRANSMITTER_LATENCY);
8164 +unsigned int freq = 38000;      /* modulation frequency */
8165 +unsigned int duty_cycle = 50;   /* duty cycle of 50% */
8166 +
8167 +#endif
8168 +
8169 +#define RBUF_LEN 1024
8170 +#define WBUF_LEN 1024
8171 +
8172 +#define LIRC_DRIVER_NAME "lirc_sir"
8173 +
8174 +#ifndef LIRC_SIR_TEKRAM
8175 +#define PULSE '['
8176 +
8177 +/* 9bit * 1s/115200bit in milli seconds = 78.125ms*/
8178 +#define TIME_CONST (9000000ul/115200ul)
8179 +#endif
8180 +
8181 +
8182 +/* timeout for sequences in jiffies (=5/100s) */
8183 +/* must be longer than TIME_CONST */
8184 +#define SIR_TIMEOUT    (HZ*5/100)
8185 +
8186 +#ifndef LIRC_ON_SA1100
8187 +static int io = CONFIG_LIRC_PORT_SIR;
8188 +static int irq = CONFIG_LIRC_IRQ_SIR;
8189 +static int threshold = 3;
8190 +#endif
8191 +
8192 +static spinlock_t timer_lock = SPIN_LOCK_UNLOCKED;
8193 +static struct timer_list timerlist;
8194 +/* time of last signal change detected */
8195 +static struct timeval last_tv = {0, 0};
8196 +/* time of last UART data ready interrupt */
8197 +static struct timeval last_intr_tv = {0, 0};
8198 +static int last_value = 0;
8199 +
8200 +static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue);
8201 +
8202 +static spinlock_t hardware_lock = SPIN_LOCK_UNLOCKED;
8203 +static spinlock_t dev_lock = SPIN_LOCK_UNLOCKED;
8204 +
8205 +static lirc_t rx_buf[RBUF_LEN]; unsigned int rx_tail = 0, rx_head = 0;
8206 +#ifndef LIRC_SIR_TEKRAM
8207 +static lirc_t tx_buf[WBUF_LEN];
8208 +#endif
8209 +
8210 +/* SECTION: Prototypes */
8211 +
8212 +/* Communication with user-space */
8213 +static int lirc_open(struct inode * inode, struct file * file);
8214 +static int lirc_close(struct inode * inode, struct file *file);
8215 +static unsigned int lirc_poll(struct file * file, poll_table * wait);
8216 +static ssize_t lirc_read(struct file * file, char * buf, size_t count,
8217 +               loff_t * ppos);
8218 +static ssize_t lirc_write(struct file * file, const char * buf, size_t n, loff_t * pos);
8219 +static int lirc_ioctl(struct inode *node,struct file *filep,unsigned int cmd,
8220 +               unsigned long arg);
8221 +static void add_read_queue(int flag, unsigned long val);
8222 +#ifdef MODULE
8223 +static int init_chrdev(void);
8224 +static void drop_chrdev(void);
8225 +#endif
8226 +       /* Hardware */
8227 +static irqreturn_t sir_interrupt(int irq, void * dev_id,
8228 +                                struct pt_regs * regs);
8229 +#ifndef LIRC_SIR_TEKRAM
8230 +static void send_space(unsigned long len);
8231 +static void send_pulse(unsigned long len);
8232 +#endif
8233 +static int init_hardware(void);
8234 +static void drop_hardware(void);
8235 +       /* Initialisation */
8236 +static int init_port(void);
8237 +static void drop_port(void);
8238 +int init_module(void);
8239 +void cleanup_module(void);
8240 +
8241 +#ifdef LIRC_ON_SA1100
8242 +void inline on(void)
8243 +{
8244 +       PPSR|=PPC_TXD2;
8245 +}
8246 +  
8247 +void inline off(void)
8248 +{
8249 +       PPSR&=~PPC_TXD2;
8250 +}
8251 +#else
8252 +static inline unsigned int sinp(int offset)
8253 +{
8254 +       return inb(io + offset);
8255 +}
8256 +
8257 +static inline void soutp(int offset, int value)
8258 +{
8259 +       outb(value, io + offset);
8260 +}
8261 +#endif
8262 +
8263 +#ifndef MAX_UDELAY_MS
8264 +#define MAX_UDELAY_US 5000
8265 +#else
8266 +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000)
8267 +#endif
8268 +
8269 +static inline void safe_udelay(unsigned long usecs)
8270 +{
8271 +       while(usecs>MAX_UDELAY_US)
8272 +       {
8273 +               udelay(MAX_UDELAY_US);
8274 +               usecs-=MAX_UDELAY_US;
8275 +       }
8276 +       udelay(usecs);
8277 +}
8278 +
8279 +/* SECTION: Communication with user-space */
8280 +
8281 +static int lirc_open(struct inode * inode, struct file * file)
8282 +{
8283 +       spin_lock(&dev_lock);
8284 +       if (MOD_IN_USE) {
8285 +               spin_unlock(&dev_lock);
8286 +               return -EBUSY;
8287 +       }
8288 +       MOD_INC_USE_COUNT;
8289 +       spin_unlock(&dev_lock);
8290 +       return 0;
8291 +}
8292 +
8293 +static int lirc_close(struct inode * inode, struct file *file)
8294 +{
8295 +       MOD_DEC_USE_COUNT;
8296 +       return 0;
8297 +}
8298 +
8299 +static unsigned int lirc_poll(struct file * file, poll_table * wait)
8300 +{
8301 +       poll_wait(file, &lirc_read_queue, wait);
8302 +       if (rx_head != rx_tail)
8303 +               return POLLIN | POLLRDNORM;
8304 +       return 0;
8305 +}
8306 +
8307 +static ssize_t lirc_read(struct file * file, char * buf, size_t count,
8308 +               loff_t * ppos)
8309 +{
8310 +       int n=0;
8311 +       int retval = 0;
8312 +       DECLARE_WAITQUEUE(wait,current);
8313 +       
8314 +       if(n%sizeof(lirc_t)) return(-EINVAL);
8315 +       
8316 +       add_wait_queue(&lirc_read_queue,&wait);
8317 +       current->state=TASK_INTERRUPTIBLE;
8318 +       while(n<count)
8319 +       {
8320 +               if(rx_head!=rx_tail)
8321 +               {
8322 +                       retval=verify_area(VERIFY_WRITE,
8323 +                                          (void *) buf+n,sizeof(lirc_t));
8324 +                       if (retval)
8325 +                       {
8326 +                               return retval;
8327 +                       }
8328 +                       copy_to_user((void *) buf+n,(void *) (rx_buf+rx_head),
8329 +                                    sizeof(lirc_t));
8330 +                       rx_head=(rx_head+1)&(RBUF_LEN-1);
8331 +                       n+=sizeof(lirc_t);
8332 +               }
8333 +               else
8334 +               {
8335 +                       if(file->f_flags & O_NONBLOCK)
8336 +                       {
8337 +                               retval=-EAGAIN;
8338 +                               break;
8339 +                       }
8340 +                       if(signal_pending(current))
8341 +                       {
8342 +                               retval=-ERESTARTSYS;
8343 +                               break;
8344 +                       }
8345 +                       schedule();
8346 +                       current->state=TASK_INTERRUPTIBLE;
8347 +               }
8348 +       }
8349 +       remove_wait_queue(&lirc_read_queue,&wait);
8350 +       current->state=TASK_RUNNING;
8351 +       return (n ? n : retval);
8352 +}
8353 +static ssize_t lirc_write(struct file * file, const char * buf, size_t n, loff_t * pos)
8354 +{
8355 +       unsigned long flags;
8356 +#ifdef LIRC_SIR_TEKRAM
8357 +       return(-EBADF);
8358 +#else
8359 +       int i;
8360 +       int retval;
8361 +
8362 +        if(n%sizeof(lirc_t) || (n/sizeof(lirc_t)) > WBUF_LEN)
8363 +               return(-EINVAL);
8364 +       retval = verify_area(VERIFY_READ, buf, n);
8365 +       if (retval)
8366 +               return retval;
8367 +       copy_from_user(tx_buf, buf, n);
8368 +       i = 0;
8369 +       n/=sizeof(lirc_t);
8370 +#ifdef LIRC_ON_SA1100
8371 +       /* disable receiver */
8372 +       Ser2UTCR3=0;
8373 +#endif
8374 +       local_irq_save(flags);
8375 +       while (1) {
8376 +               if (i >= n)
8377 +                       break;
8378 +               if (tx_buf[i])
8379 +                       send_pulse(tx_buf[i]);
8380 +               i++;
8381 +               if (i >= n)
8382 +                       break;
8383 +               if (tx_buf[i])
8384 +                       send_space(tx_buf[i]);
8385 +               i++;
8386 +       }
8387 +       local_irq_restore(flags);
8388 +#ifdef LIRC_ON_SA1100
8389 +       off();
8390 +       udelay(1000); /* wait 1ms for IR diode to recover */
8391 +       Ser2UTCR3=0;
8392 +       /* clear status register to prevent unwanted interrupts */
8393 +       Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB);
8394 +       /* enable receiver */
8395 +       Ser2UTCR3=UTCR3_RXE|UTCR3_RIE;
8396 +#endif
8397 +       return n;
8398 +#endif
8399 +}
8400 +
8401 +static int lirc_ioctl(struct inode *node,struct file *filep,unsigned int cmd,
8402 +               unsigned long arg)
8403 +{
8404 +       int retval = 0;
8405 +       unsigned long value = 0;
8406 +#ifdef LIRC_ON_SA1100
8407 +       unsigned int ivalue;
8408 +#endif
8409 +
8410 +#ifdef LIRC_SIR_TEKRAM
8411 +       if (cmd == LIRC_GET_FEATURES)
8412 +               value = LIRC_CAN_REC_MODE2;
8413 +       else if (cmd == LIRC_GET_SEND_MODE)
8414 +               value = 0;
8415 +       else if (cmd == LIRC_GET_REC_MODE)
8416 +               value = LIRC_MODE_MODE2;
8417 +#elif defined(LIRC_ON_SA1100)
8418 +       if (cmd == LIRC_GET_FEATURES)
8419 +               value = LIRC_CAN_SEND_PULSE |
8420 +                       LIRC_CAN_SET_SEND_DUTY_CYCLE |
8421 +                       LIRC_CAN_SET_SEND_CARRIER |
8422 +                       LIRC_CAN_REC_MODE2;
8423 +       else if (cmd == LIRC_GET_SEND_MODE)
8424 +               value = LIRC_MODE_PULSE;
8425 +       else if (cmd == LIRC_GET_REC_MODE)
8426 +               value = LIRC_MODE_MODE2;
8427 +#else
8428 +       if (cmd == LIRC_GET_FEATURES)
8429 +               value = LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2;
8430 +       else if (cmd == LIRC_GET_SEND_MODE)
8431 +               value = LIRC_MODE_PULSE;
8432 +       else if (cmd == LIRC_GET_REC_MODE)
8433 +               value = LIRC_MODE_MODE2;
8434 +#endif
8435 +
8436 +       switch (cmd) {
8437 +       case LIRC_GET_FEATURES:
8438 +       case LIRC_GET_SEND_MODE:
8439 +       case LIRC_GET_REC_MODE:
8440 +               retval = put_user(value, (unsigned long *) arg);
8441 +               break;
8442 +
8443 +       case LIRC_SET_SEND_MODE:
8444 +       case LIRC_SET_REC_MODE:
8445 +               retval = get_user(value, (unsigned long *) arg);
8446 +               break;
8447 +#ifdef LIRC_ON_SA1100
8448 +       case LIRC_SET_SEND_DUTY_CYCLE:
8449 +               retval=get_user(ivalue,(unsigned int *) arg);
8450 +               if(retval) return(retval);
8451 +               if(ivalue<=0 || ivalue>100) return(-EINVAL);
8452 +               /* (ivalue/100)*(1000000/freq) */
8453 +               duty_cycle=ivalue;
8454 +               pulse_width=(unsigned long) duty_cycle*10000/freq;
8455 +               space_width=(unsigned long) 1000000L/freq-pulse_width;
8456 +               if(pulse_width>=LIRC_ON_SA1100_TRANSMITTER_LATENCY)
8457 +                       pulse_width-=LIRC_ON_SA1100_TRANSMITTER_LATENCY;
8458 +               if(space_width>=LIRC_ON_SA1100_TRANSMITTER_LATENCY)
8459 +                       space_width-=LIRC_ON_SA1100_TRANSMITTER_LATENCY;
8460 +               break;
8461 +       case LIRC_SET_SEND_CARRIER:
8462 +               retval=get_user(ivalue,(unsigned int *) arg);
8463 +               if(retval) return(retval);
8464 +               if(ivalue>500000 || ivalue<20000) return(-EINVAL);
8465 +               freq=ivalue;
8466 +               pulse_width=(unsigned long) duty_cycle*10000/freq;
8467 +               space_width=(unsigned long) 1000000L/freq-pulse_width;
8468 +               if(pulse_width>=LIRC_ON_SA1100_TRANSMITTER_LATENCY)
8469 +                       pulse_width-=LIRC_ON_SA1100_TRANSMITTER_LATENCY;
8470 +               if(space_width>=LIRC_ON_SA1100_TRANSMITTER_LATENCY)
8471 +                       space_width-=LIRC_ON_SA1100_TRANSMITTER_LATENCY;
8472 +               break;
8473 +#endif
8474 +       default:
8475 +               retval = -ENOIOCTLCMD;
8476 +
8477 +       }
8478 +       
8479 +       if (retval)
8480 +               return retval;
8481 +       
8482 +#ifdef LIRC_SIR_TEKRAM
8483 +       if (cmd == LIRC_SET_REC_MODE) {
8484 +               if (value != LIRC_MODE_MODE2)
8485 +                       retval = -ENOSYS;
8486 +       } else if (cmd == LIRC_SET_SEND_MODE) {
8487 +               retval = -ENOSYS;
8488 +       }
8489 +#else
8490 +       if (cmd == LIRC_SET_REC_MODE) {
8491 +               if (value != LIRC_MODE_MODE2)
8492 +                       retval = -ENOSYS;
8493 +       } else if (cmd == LIRC_SET_SEND_MODE) {
8494 +               if (value != LIRC_MODE_PULSE)
8495 +                       retval = -ENOSYS;
8496 +       }
8497 +#endif
8498 +       return retval;
8499 +}
8500 +
8501 +static void add_read_queue(int flag, unsigned long val)
8502 +{
8503 +       unsigned int new_rx_tail;
8504 +       lirc_t newval;
8505 +
8506 +#ifdef DEBUG_SIGNAL
8507 +       printk(KERN_DEBUG LIRC_DRIVER_NAME
8508 +               ": add flag %d with val %lu\n",
8509 +               flag,val);
8510 +#endif
8511 +
8512 +       newval = val & PULSE_MASK;
8513 +
8514 +       /* statistically pulses are ~TIME_CONST/2 too long: we could
8515 +          maybe make this more exactly but this is good enough */
8516 +       if(flag) /* pulse */
8517 +       {
8518 +               if(newval>TIME_CONST/2)
8519 +               {
8520 +                       newval-=TIME_CONST/2;
8521 +               }
8522 +               else /* should not ever happen */
8523 +               {
8524 +                       newval=1;
8525 +               }
8526 +               newval|=PULSE_BIT;
8527 +       }
8528 +       else
8529 +       {
8530 +               newval+=TIME_CONST/2;
8531 +       }
8532 +       new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1);
8533 +       if (new_rx_tail == rx_head) {
8534 +#               ifdef DEBUG
8535 +               printk(KERN_WARNING LIRC_DRIVER_NAME ": Buffer overrun.\n");
8536 +#               endif
8537 +               return;
8538 +       }
8539 +       rx_buf[rx_tail] = newval;
8540 +       rx_tail = new_rx_tail;
8541 +       wake_up_interruptible(&lirc_read_queue);
8542 +}
8543 +
8544 +static struct file_operations lirc_fops =
8545 +{
8546 +       read:    lirc_read,
8547 +       write:   lirc_write,
8548 +       poll:    lirc_poll,
8549 +       ioctl:   lirc_ioctl,
8550 +       open:    lirc_open,
8551 +       release: lirc_close,
8552 +};
8553 +
8554 +static int set_use_inc(void* data)
8555 +{
8556 +#if WE_DONT_USE_LOCAL_OPEN_CLOSE
8557 +       MOD_INC_USE_COUNT;
8558 +#endif
8559 +       return 0;
8560 +}
8561 +
8562 +static void set_use_dec(void* data)
8563 +{
8564 +#if WE_DONT_USE_LOCAL_OPEN_CLOSE
8565 +       MOD_DEC_USE_COUNT;
8566 +#endif
8567 +}
8568 +static struct lirc_plugin plugin = {
8569 +       name:           LIRC_DRIVER_NAME,
8570 +       minor:          -1,
8571 +       code_length:    1,
8572 +       sample_rate:    0,
8573 +       data:           NULL,
8574 +       add_to_buf:     NULL,
8575 +       get_queue:      NULL,
8576 +       set_use_inc:    set_use_inc,
8577 +       set_use_dec:    set_use_dec,
8578 +       fops:           &lirc_fops,
8579 +};
8580 +
8581 +
8582 +#ifdef MODULE
8583 +int init_chrdev(void)
8584 +{
8585 +       plugin.minor = lirc_register_plugin(&plugin);
8586 +       if (plugin.minor < 0) {
8587 +               printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n");
8588 +               return -EIO;
8589 +       }
8590 +       return 0;
8591 +}
8592 +
8593 +static void drop_chrdev(void)
8594 +{
8595 +       lirc_unregister_plugin(plugin.minor);
8596 +}
8597 +#endif
8598 +
8599 +/* SECTION: Hardware */
8600 +static long delta(struct timeval * tv1, struct timeval * tv2)
8601 +{
8602 +       unsigned long deltv;
8603 +       
8604 +       deltv = tv2->tv_sec - tv1->tv_sec;
8605 +       if (deltv > 15)
8606 +               deltv = 0xFFFFFF;
8607 +       else
8608 +               deltv = deltv*1000000 +
8609 +                       tv2->tv_usec -
8610 +                       tv1->tv_usec;
8611 +       return deltv;
8612 +}
8613 +
8614 +static void sir_timeout(unsigned long data) 
8615 +{
8616 +       /* if last received signal was a pulse, but receiving stopped
8617 +          within the 9 bit frame, we need to finish this pulse and
8618 +          simulate a signal change to from pulse to space. Otherwise
8619 +          upper layers will receive two sequences next time. */
8620 +       
8621 +       unsigned long flags;
8622 +       unsigned long pulse_end;
8623 +       
8624 +       /* avoid interference with interrupt */
8625 +       spin_lock_irqsave(&timer_lock, flags);
8626 +       if (last_value)
8627 +       {
8628 +#ifndef LIRC_ON_SA1100
8629 +               /* clear unread bits in UART and restart */
8630 +               outb(UART_FCR_CLEAR_RCVR, io + UART_FCR);
8631 +#endif
8632 +               /* determine 'virtual' pulse end: */
8633 +               pulse_end = delta(&last_tv, &last_intr_tv);
8634 +#ifdef DEBUG_SIGNAL
8635 +               printk(KERN_DEBUG LIRC_DRIVER_NAME
8636 +                       ": timeout add %d for %lu usec\n",last_value,pulse_end);
8637 +#endif
8638 +               add_read_queue(last_value,pulse_end);
8639 +               last_value = 0;
8640 +               last_tv=last_intr_tv;
8641 +       }
8642 +       spin_unlock_irqrestore(&timer_lock, flags);             
8643 +}
8644 +
8645 +static irqreturn_t sir_interrupt(int irq, void * dev_id,
8646 +                                struct pt_regs * regs)
8647 +{
8648 +       unsigned char data;
8649 +       struct timeval curr_tv;
8650 +       static unsigned long deltv;
8651 +#ifdef LIRC_ON_SA1100
8652 +       int status;
8653 +       static int n=0;
8654 +       
8655 +       //printk("interrupt\n");
8656 +       status = Ser2UTSR0;
8657 +       /*
8658 +        * Deal with any receive errors first.  The bytes in error may be
8659 +        * the only bytes in the receive FIFO, so we do this first.
8660 +        */
8661 +       while (status & UTSR0_EIF)
8662 +       {
8663 +               int bstat;
8664 +               
8665 +#ifdef DEBUG
8666 +               printk("EIF\n");
8667 +               bstat = Ser2UTSR1;
8668 +               
8669 +               if (bstat & UTSR1_FRE)
8670 +                       printk("frame error\n");
8671 +               if (bstat & UTSR1_ROR)
8672 +                       printk("receive fifo overrun\n");
8673 +               if(bstat&UTSR1_PRE)
8674 +                       printk("parity error\n");
8675 +#endif
8676 +               
8677 +               bstat = Ser2UTDR;
8678 +               n++;
8679 +               status = Ser2UTSR0;
8680 +       }
8681 +
8682 +       if (status & (UTSR0_RFS | UTSR0_RID))
8683 +       {
8684 +               do_gettimeofday(&curr_tv);
8685 +               deltv = delta(&last_tv, &curr_tv);
8686 +               do
8687 +               {
8688 +#ifdef DEBUG_SIGNAL
8689 +                       printk(KERN_DEBUG LIRC_DRIVER_NAME": t %lu , d %d\n",
8690 +                              deltintrtv,(int)data);
8691 +#endif
8692 +                       data=Ser2UTDR;
8693 +                       //printk("data: %d\n",data);
8694 +                       n++;
8695 +               }
8696 +               while(status&UTSR0_RID && /* do not empty fifo in
8697 +                                             order to get UTSR0_RID in
8698 +                                             any case */
8699 +                     Ser2UTSR1 & UTSR1_RNE); /* data ready */
8700 +               
8701 +               if(status&UTSR0_RID)
8702 +               {
8703 +                       //printk("add\n");
8704 +                       add_read_queue(0,deltv-n*TIME_CONST); /*space*/
8705 +                       add_read_queue(1,n*TIME_CONST); /*pulse*/
8706 +                       n=0;
8707 +                       last_tv=curr_tv;
8708 +               }
8709 +       }
8710 +
8711 +       if (status & UTSR0_TFS) {
8712 +
8713 +               printk("transmit fifo not full, shouldn't ever happen\n");
8714 +       }
8715 +
8716 +       /*
8717 +        * We must clear certain bits.
8718 +        */
8719 +       status &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB);
8720 +       if (status)
8721 +               Ser2UTSR0 = status;
8722 +#else
8723 +       unsigned long deltintrtv;
8724 +       unsigned long flags;
8725 +       int iir, lsr;
8726 +
8727 +       while ((iir = inb(io + UART_IIR) & UART_IIR_ID)) {
8728 +               switch (iir&UART_IIR_ID) { /* FIXME toto treba preriedit */
8729 +               case UART_IIR_MSI:
8730 +                       (void) inb(io + UART_MSR);
8731 +                       break;
8732 +               case UART_IIR_RLSI:
8733 +                       (void) inb(io + UART_LSR);
8734 +                       break;
8735 +               case UART_IIR_THRI:
8736 +#if 0
8737 +                       if (lsr & UART_LSR_THRE) /* FIFO is empty */
8738 +                               outb(data, io + UART_TX)
8739 +#endif
8740 +                       break;
8741 +               case UART_IIR_RDI:
8742 +                       /* avoid interference with timer */
8743 +                       spin_lock_irqsave(&timer_lock, flags);
8744 +                       do
8745 +                       {
8746 +                               del_timer(&timerlist);
8747 +                               data = inb(io + UART_RX);
8748 +                               do_gettimeofday(&curr_tv);
8749 +                               deltv = delta(&last_tv, &curr_tv);
8750 +                               deltintrtv = delta(&last_intr_tv, &curr_tv);
8751 +#ifdef DEBUG_SIGNAL
8752 +                               printk(KERN_DEBUG LIRC_DRIVER_NAME": t %lu , d %d\n",deltintrtv,(int)data);
8753 +#endif
8754 +                               /* if nothing came in last X cycles,
8755 +                                  it was gap */
8756 +                               if (deltintrtv > TIME_CONST * threshold) {
8757 +                                       if (last_value) {
8758 +#ifdef DEBUG_SIGNAL
8759 +                                               printk(KERN_DEBUG LIRC_DRIVER_NAME ": GAP\n");
8760 +#endif
8761 +                                               /* simulate signal change */
8762 +                                               add_read_queue(last_value,
8763 +                                                              deltv-
8764 +                                                              deltintrtv);
8765 +                                               last_value = 0;
8766 +                                               last_tv.tv_sec = last_intr_tv.tv_sec;
8767 +                                               last_tv.tv_usec = last_intr_tv.tv_usec;
8768 +                                               deltv = deltintrtv;
8769 +                                       }
8770 +                               }
8771 +                               data = 1;
8772 +                               if (data ^ last_value) {
8773 +                                       /* deltintrtv > 2*TIME_CONST,
8774 +                                           remember ? */
8775 +                                       /* the other case is timeout */
8776 +                                       add_read_queue(last_value,
8777 +                                                      deltv-TIME_CONST);
8778 +                                       last_value = data;
8779 +                                       last_tv = curr_tv;
8780 +                                       if(last_tv.tv_usec>=TIME_CONST)
8781 +                                       {
8782 +                                               last_tv.tv_usec-=TIME_CONST;
8783 +                                       }
8784 +                                       else
8785 +                                       {
8786 +                                               last_tv.tv_sec--;
8787 +                                               last_tv.tv_usec+=1000000-
8788 +                                                       TIME_CONST;
8789 +                                       }
8790 +                               }
8791 +                               last_intr_tv = curr_tv;
8792 +                               if (data)
8793 +                               {
8794 +                                       /* start timer for end of sequence detection */
8795 +                                       timerlist.expires = jiffies + SIR_TIMEOUT;
8796 +                                       add_timer(&timerlist);
8797 +                               }
8798 +                       }
8799 +                       while ((lsr = inb(io + UART_LSR))
8800 +                               & UART_LSR_DR); /* data ready */
8801 +                       spin_unlock_irqrestore(&timer_lock, flags);
8802 +                       break;
8803 +               default:
8804 +                       break;
8805 +               }
8806 +       }
8807 +#endif
8808 +       return IRQ_RETVAL(IRQ_HANDLED);
8809 +}
8810 +
8811 +#ifdef LIRC_ON_SA1100
8812 +void send_pulse(unsigned long length)
8813 +{
8814 +       unsigned long k,delay;
8815 +       int flag;
8816 +
8817 +       if(length==0) return;
8818 +       /* this won't give us the carrier frequency we really want
8819 +          due to integer arithmetic, but we can accept this inaccuracy */
8820 +
8821 +       for(k=flag=0;k<length;k+=delay,flag=!flag)
8822 +       {
8823 +               if(flag)
8824 +               {
8825 +                       off();
8826 +                       delay=space_width;
8827 +               }
8828 +               else
8829 +               {
8830 +                       on();
8831 +                       delay=pulse_width;
8832 +               }
8833 +               safe_udelay(delay);
8834 +       }
8835 +       off();
8836 +}
8837 +
8838 +void send_space(unsigned long length)
8839 +{
8840 +       if(length==0) return;
8841 +       off();
8842 +       safe_udelay(length);
8843 +}
8844 +#elif defined(LIRC_SIR_TEKRAM)
8845 +#else
8846 +static void send_space(unsigned long len)
8847 +{
8848 +       safe_udelay(len);
8849 +}
8850 +
8851 +static void send_pulse(unsigned long len)
8852 +{
8853 +       long bytes_out = len / TIME_CONST;
8854 +       long time_left;
8855 +
8856 +       if (!bytes_out)
8857 +               bytes_out++;
8858 +       time_left = (long)len - (long)bytes_out * (long)TIME_CONST;
8859 +       while (--bytes_out) {
8860 +               outb(PULSE, io + UART_TX);
8861 +               /* FIXME treba seriozne cakanie z drivers/char/serial.c */
8862 +               while (!(inb(io + UART_LSR) & UART_LSR_THRE));
8863 +       }
8864 +#if 0
8865 +       if (time_left > 0)
8866 +               safe_udelay(time_left);
8867 +#endif
8868 +}
8869 +#endif
8870 +
8871 +#ifdef CONFIG_SA1100_COLLIE
8872 +static inline int sa1100_irda_set_power_collie(int state)
8873 +{
8874 +       if (state) {
8875 +               /*
8876 +                *  0 - off
8877 +                *  1 - short range, lowest power
8878 +                *  2 - medium range, medium power
8879 +                *  3 - maximum range, high power
8880 +                */
8881 +               ucb1200_set_io_direction(TC35143_GPIO_IR_ON,
8882 +                                        TC35143_IODIR_OUTPUT);
8883 +               ucb1200_set_io(TC35143_GPIO_IR_ON, TC35143_IODAT_LOW);
8884 +               udelay(100);
8885 +       }
8886 +       else {
8887 +               /* OFF */
8888 +               ucb1200_set_io_direction(TC35143_GPIO_IR_ON,
8889 +                                        TC35143_IODIR_OUTPUT);
8890 +               ucb1200_set_io(TC35143_GPIO_IR_ON, TC35143_IODAT_HIGH);
8891 +       }
8892 +       return 0;
8893 +}
8894 +#endif
8895 +
8896 +static int init_hardware(void)
8897 +{
8898 +       unsigned long flags;
8899 +       
8900 +       spin_lock_irqsave(&hardware_lock, flags);
8901 +       /* reset UART */
8902 +#ifdef LIRC_ON_SA1100
8903 +#ifdef CONFIG_SA1100_BITSY
8904 +       if (machine_is_bitsy()) {
8905 +               printk("Power on IR module\n");
8906 +               set_bitsy_egpio(EGPIO_BITSY_IR_ON);
8907 +       }
8908 +#endif
8909 +#ifdef CONFIG_SA1100_COLLIE
8910 +       sa1100_irda_set_power_collie(3);        /* power on */
8911 +#endif
8912 +       sr.hscr0=Ser2HSCR0;
8913 +
8914 +       sr.utcr0=Ser2UTCR0;
8915 +       sr.utcr1=Ser2UTCR1;
8916 +       sr.utcr2=Ser2UTCR2;
8917 +       sr.utcr3=Ser2UTCR3;
8918 +       sr.utcr4=Ser2UTCR4;
8919 +
8920 +       sr.utdr=Ser2UTDR;
8921 +       sr.utsr0=Ser2UTSR0;
8922 +       sr.utsr1=Ser2UTSR1;
8923 +
8924 +       /* configure GPIO */
8925 +       /* output */
8926 +       PPDR|=PPC_TXD2;
8927 +       PSDR|=PPC_TXD2;
8928 +       /* set output to 0 */
8929 +       off();
8930 +       
8931 +       /*
8932 +        * Enable HP-SIR modulation, and ensure that the port is disabled.
8933 +        */
8934 +       Ser2UTCR3=0;
8935 +       Ser2HSCR0=sr.hscr0 & (~HSCR0_HSSP);
8936 +       
8937 +       /* clear status register to prevent unwanted interrupts */
8938 +       Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB);
8939 +       
8940 +       /* 7N1 */
8941 +       Ser2UTCR0=UTCR0_1StpBit|UTCR0_7BitData;
8942 +       /* 115200 */
8943 +       Ser2UTCR1=0;
8944 +       Ser2UTCR2=1;
8945 +       /* use HPSIR, 1.6 usec pulses */
8946 +       Ser2UTCR4=UTCR4_HPSIR|UTCR4_Z1_6us;
8947 +       
8948 +       /* enable receiver, receive fifo interrupt */
8949 +       Ser2UTCR3=UTCR3_RXE|UTCR3_RIE;
8950 +       
8951 +       /* clear status register to prevent unwanted interrupts */
8952 +       Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB);
8953 +       
8954 +#elif defined(LIRC_SIR_TEKRAM)
8955 +       /* disable FIFO */ 
8956 +       soutp(UART_FCR,
8957 +             UART_FCR_CLEAR_RCVR|
8958 +             UART_FCR_CLEAR_XMIT|
8959 +             UART_FCR_TRIGGER_1);
8960 +       
8961 +       /* Set DLAB 0. */
8962 +       soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
8963 +       
8964 +       /* First of all, disable all interrupts */
8965 +       soutp(UART_IER, sinp(UART_IER)&
8966 +             (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI)));
8967 +       
8968 +       /* Set DLAB 1. */
8969 +       soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB);
8970 +       
8971 +       /* Set divisor to 12 => 9600 Baud */
8972 +       soutp(UART_DLM,0);
8973 +       soutp(UART_DLL,12);
8974 +       
8975 +       /* Set DLAB 0. */
8976 +       soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
8977 +       
8978 +       /* power supply */
8979 +       soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2);
8980 +       safe_udelay(50*1000);
8981 +       
8982 +       /* -DTR low -> reset PIC */
8983 +       soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2);
8984 +       udelay(1*1000);
8985 +       
8986 +       soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2);
8987 +       udelay(100);
8988 +
8989 +
8990 +        /* -RTS low -> send control byte */
8991 +       soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2);
8992 +       udelay(7);
8993 +       soutp(UART_TX, TEKRAM_115200|TEKRAM_PW);
8994 +       
8995 +       /* one byte takes ~1042 usec to transmit at 9600,8N1 */
8996 +       udelay(1500);
8997 +       
8998 +       /* back to normal operation */
8999 +       soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2);
9000 +       udelay(50);
9001 +
9002 +       udelay(1500);
9003 +       
9004 +       /* read previous control byte */
9005 +       printk(KERN_INFO LIRC_DRIVER_NAME
9006 +              ": 0x%02x\n",sinp(UART_RX));
9007 +       
9008 +       /* Set DLAB 1. */
9009 +       soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB);
9010 +       
9011 +       /* Set divisor to 1 => 115200 Baud */
9012 +       soutp(UART_DLM,0);
9013 +       soutp(UART_DLL,1);
9014 +
9015 +       /* Set DLAB 0, 8 Bit */
9016 +       soutp(UART_LCR, UART_LCR_WLEN8);
9017 +       /* enable interrupts */
9018 +       soutp(UART_IER, sinp(UART_IER)|UART_IER_RDI);
9019 +#else
9020 +       outb(0, io + UART_MCR);
9021 +       outb(0, io + UART_IER);
9022 +       /* init UART */
9023 +               /* set DLAB, speed = 115200 */
9024 +       outb(UART_LCR_DLAB | UART_LCR_WLEN7, io + UART_LCR);
9025 +       outb(1, io + UART_DLL); outb(0, io + UART_DLM);
9026 +               /* 7N1+start = 9 bits at 115200 ~ 3 bits at 44000 */
9027 +       outb(UART_LCR_WLEN7, io + UART_LCR);
9028 +               /* FIFO operation */
9029 +       outb(UART_FCR_ENABLE_FIFO, io + UART_FCR);
9030 +               /* interrupts */
9031 +       // outb(UART_IER_RLSI|UART_IER_RDI|UART_IER_THRI, io + UART_IER);
9032 +       outb(UART_IER_RDI, io + UART_IER);      
9033 +       /* turn on UART */
9034 +       outb(UART_MCR_DTR|UART_MCR_RTS|UART_MCR_OUT2, io + UART_MCR);
9035 +#ifdef LIRC_SIR_ACTISYS_ACT200L
9036 +       init_act200();
9037 +#endif
9038 +#endif
9039 +       spin_unlock_irqrestore(&hardware_lock, flags);
9040 +       return 0;
9041 +}
9042 +
9043 +static void drop_hardware(void)
9044 +{
9045 +       unsigned long flags;
9046 +
9047 +       spin_lock_irqsave(&hardware_lock, flags);
9048 +
9049 +#ifdef LIRC_ON_SA1100
9050 +       Ser2UTCR3=0;
9051 +       
9052 +       Ser2UTCR0=sr.utcr0;
9053 +       Ser2UTCR1=sr.utcr1;
9054 +       Ser2UTCR2=sr.utcr2;
9055 +       Ser2UTCR4=sr.utcr4;
9056 +       Ser2UTCR3=sr.utcr3;
9057 +       
9058 +       Ser2HSCR0=sr.hscr0;
9059 +#ifdef CONFIG_SA1100_BITSY
9060 +       if (machine_is_bitsy()) {
9061 +               clr_bitsy_egpio(EGPIO_BITSY_IR_ON);
9062 +       }
9063 +#endif
9064 +#ifdef CONFIG_SA1100_COLLIE
9065 +       sa1100_irda_set_power_collie(0);        /* power off */
9066 +#endif
9067 +#else
9068 +       /* turn off interrupts */
9069 +       outb(0, io + UART_IER); 
9070 +#endif
9071 +       spin_unlock_irqrestore(&hardware_lock, flags);
9072 +}
9073 +
9074 +/* SECTION: Initialisation */
9075 +
9076 +static int init_port(void)
9077 +{
9078 +       int retval;
9079 +       
9080 +#ifndef LIRC_ON_SA1100
9081 +       /* get I/O port access and IRQ line */
9082 +       retval = check_region(io, 8);
9083 +       if (retval < 0) {
9084 +               printk(KERN_ERR LIRC_DRIVER_NAME
9085 +                       ": i/o port 0x%.4x already in use.\n",
9086 +                       io);
9087 +               return retval;
9088 +       }
9089 +#endif
9090 +       retval = request_irq(irq, sir_interrupt, SA_INTERRUPT,
9091 +                            LIRC_DRIVER_NAME, NULL);
9092 +       if (retval < 0) {
9093 +               printk(KERN_ERR LIRC_DRIVER_NAME
9094 +                       ": IRQ %d already in use.\n",
9095 +                       irq);
9096 +               return retval;
9097 +       }
9098 +#ifndef LIRC_ON_SA1100
9099 +       request_region(io, 8, LIRC_DRIVER_NAME);
9100 +       printk(KERN_INFO LIRC_DRIVER_NAME
9101 +               ": I/O port 0x%.4x, IRQ %d.\n",
9102 +               io, irq);
9103 +#endif
9104 +
9105 +       init_timer(&timerlist);
9106 +       timerlist.function = sir_timeout;
9107 +       timerlist.data = 0xabadcafe;
9108 +
9109 +       return 0;
9110 +}
9111 +
9112 +static void drop_port(void)
9113 +{
9114 +       disable_irq(irq);
9115 +       free_irq(irq, NULL);
9116 +       del_timer_sync(&timerlist);
9117 +#ifndef LIRC_ON_SA1100
9118 +       release_region(io, 8);
9119 +#endif
9120 +}
9121 +
9122 +#ifdef LIRC_SIR_ACTISYS_ACT200L
9123 +/******************************************************/
9124 +/* Crystal/Cirrus CS8130 IR transceiver, used in Actisys Act200L dongle */
9125 +/* some code borrowed from Linux IRDA driver */
9126 +
9127 +/* Regsiter 0: Control register #1 */
9128 +#define ACT200L_REG0    0x00
9129 +#define ACT200L_TXEN    0x01 /* Enable transmitter */
9130 +#define ACT200L_RXEN    0x02 /* Enable receiver */
9131 +#define ACT200L_ECHO    0x08 /* Echo control chars */
9132 +
9133 +/* Register 1: Control register #2 */
9134 +#define ACT200L_REG1    0x10
9135 +#define ACT200L_LODB    0x01 /* Load new baud rate count value */
9136 +#define ACT200L_WIDE    0x04 /* Expand the maximum allowable pulse */
9137 +
9138 +/* Register 3: Transmit mode register #2 */
9139 +#define ACT200L_REG3    0x30
9140 +#define ACT200L_B0      0x01 /* DataBits, 0=6, 1=7, 2=8, 3=9(8P)  */
9141 +#define ACT200L_B1      0x02 /* DataBits, 0=6, 1=7, 2=8, 3=9(8P)  */
9142 +#define ACT200L_CHSY    0x04 /* StartBit Synced 0=bittime, 1=startbit */
9143 +
9144 +/* Register 4: Output Power register */
9145 +#define ACT200L_REG4    0x40
9146 +#define ACT200L_OP0     0x01 /* Enable LED1C output */
9147 +#define ACT200L_OP1     0x02 /* Enable LED2C output */
9148 +#define ACT200L_BLKR    0x04
9149 +
9150 +/* Register 5: Receive Mode register */
9151 +#define ACT200L_REG5    0x50
9152 +#define ACT200L_RWIDL   0x01 /* fixed 1.6us pulse mode */
9153 +    /*.. other various IRDA bit modes, and TV remote modes..*/
9154 +
9155 +/* Register 6: Receive Sensitivity register #1 */
9156 +#define ACT200L_REG6    0x60
9157 +#define ACT200L_RS0     0x01 /* receive threshold bit 0 */
9158 +#define ACT200L_RS1     0x02 /* receive threshold bit 1 */
9159 +
9160 +/* Register 7: Receive Sensitivity register #2 */
9161 +#define ACT200L_REG7    0x70
9162 +#define ACT200L_ENPOS   0x04 /* Ignore the falling edge */
9163 +
9164 +/* Register 8,9: Baud Rate Dvider register #1,#2 */
9165 +#define ACT200L_REG8    0x80
9166 +#define ACT200L_REG9    0x90
9167 +
9168 +#define ACT200L_2400    0x5f
9169 +#define ACT200L_9600    0x17
9170 +#define ACT200L_19200   0x0b
9171 +#define ACT200L_38400   0x05
9172 +#define ACT200L_57600   0x03
9173 +#define ACT200L_115200  0x01
9174 +
9175 +/* Register 13: Control register #3 */
9176 +#define ACT200L_REG13   0xd0
9177 +#define ACT200L_SHDW    0x01 /* Enable access to shadow registers */
9178 +
9179 +/* Register 15: Status register */
9180 +#define ACT200L_REG15   0xf0
9181 +
9182 +/* Register 21: Control register #4 */
9183 +#define ACT200L_REG21   0x50
9184 +#define ACT200L_EXCK    0x02 /* Disable clock output driver */
9185 +#define ACT200L_OSCL    0x04 /* oscillator in low power, medium accuracy mode */
9186 +
9187 +static void init_act200(void)
9188 +{
9189 +  int i;
9190 +       __u8 control[] = {
9191 +               ACT200L_REG15,
9192 +               ACT200L_REG13 | ACT200L_SHDW,
9193 +               ACT200L_REG21 | ACT200L_EXCK | ACT200L_OSCL,
9194 +               ACT200L_REG13,
9195 +               ACT200L_REG7  | ACT200L_ENPOS,
9196 +               ACT200L_REG6  | ACT200L_RS0  | ACT200L_RS1,
9197 +               ACT200L_REG5  | ACT200L_RWIDL,
9198 +               ACT200L_REG4  | ACT200L_OP0  | ACT200L_OP1 | ACT200L_BLKR,
9199 +               ACT200L_REG3  | ACT200L_B0,
9200 +               ACT200L_REG0  | ACT200L_TXEN | ACT200L_RXEN,
9201 +               ACT200L_REG8 |  (ACT200L_115200       & 0x0f),
9202 +               ACT200L_REG9 | ((ACT200L_115200 >> 4) & 0x0f),
9203 +               ACT200L_REG1 | ACT200L_LODB | ACT200L_WIDE
9204 +       };
9205 +
9206 +       /* Set DLAB 1. */
9207 +       soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN8);
9208 +       
9209 +       /* Set divisor to 12 => 9600 Baud */
9210 +       soutp(UART_DLM,0);
9211 +       soutp(UART_DLL,12);
9212 +       
9213 +       /* Set DLAB 0. */
9214 +       soutp(UART_LCR, UART_LCR_WLEN8);
9215 +       /* Set divisor to 12 => 9600 Baud */
9216 +
9217 +       /* power supply */
9218 +       soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2);
9219 +       for (i=0; i<50; i++) {
9220 +               safe_udelay(1000);
9221 +       }
9222 +
9223 +               /* Reset the dongle : set RTS low for 25 ms */
9224 +       soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2);
9225 +       for (i=0; i<25; i++) {
9226 +               udelay(1000);
9227 +       }
9228 +
9229 +       soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2);
9230 +       udelay(100);
9231 +
9232 +       /* Clear DTR and set RTS to enter command mode */
9233 +       soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2);
9234 +       udelay(7);
9235 +
9236 +/* send out the control register settings for 115K 7N1 SIR operation */
9237 +       for (i=0; i<sizeof(control); i++) {
9238 +               soutp(UART_TX, control[i]);
9239 +               /* one byte takes ~1042 usec to transmit at 9600,8N1 */
9240 +               udelay(1500);
9241 +       }
9242 +
9243 +       /* back to normal operation */
9244 +       soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2);
9245 +       udelay(50);
9246 +
9247 +       udelay(1500);
9248 +       soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB);
9249 +
9250 +       /* Set DLAB 1. */
9251 +       soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN7);
9252 +
9253 +       /* Set divisor to 1 => 115200 Baud */
9254 +       soutp(UART_DLM,0);
9255 +       soutp(UART_DLL,1);
9256 +
9257 +       /* Set DLAB 0. */
9258 +       soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
9259 +
9260 +       /* Set DLAB 0, 7 Bit */
9261 +       soutp(UART_LCR, UART_LCR_WLEN7);
9262 +
9263 +       /* enable interrupts */
9264 +       soutp(UART_IER, sinp(UART_IER)|UART_IER_RDI);
9265 +}
9266 +#endif
9267 +
9268 +int init_lirc_sir(void)
9269 +{
9270 +       int retval;
9271 +
9272 +       init_waitqueue_head(&lirc_read_queue);
9273 +       retval = init_port();
9274 +       if (retval < 0)
9275 +               return retval;
9276 +       init_hardware();
9277 +       enable_irq(irq);
9278 +       printk(KERN_INFO LIRC_DRIVER_NAME
9279 +               ": Installed.\n");
9280 +       return 0;
9281 +}
9282 +
9283 +#ifdef MODULE
9284 +
9285 +#ifdef LIRC_SIR_TEKRAM
9286 +MODULE_AUTHOR("Christoph Bartelmus");
9287 +MODULE_DESCRIPTION("Infrared receiver driver for Tekram Irmate 210");
9288 +#elif defined(LIRC_ON_SA1100)
9289 +MODULE_AUTHOR("Christoph Bartelmus");
9290 +MODULE_DESCRIPTION("LIRC driver for StrongARM SA1100 embedded microprocessor");
9291 +#elif defined(LIRC_SIR_ACTISYS_ACT200L)
9292 +MODULE_AUTHOR("Karl Bongers");
9293 +MODULE_DESCRIPTION("LIRC driver for Actisys Act200L");
9294 +#else
9295 +MODULE_AUTHOR("Milan Pikula");
9296 +MODULE_DESCRIPTION("Infrared receiver driver for SIR type serial ports");
9297 +#endif
9298 +
9299 +#ifdef LIRC_ON_SA1100
9300 +MODULE_PARM(irq, "i");
9301 +MODULE_PARM_DESC(irq, "Interrupt (16)");
9302 +#else
9303 +MODULE_PARM(io, "i");
9304 +MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)");
9305 +MODULE_PARM(irq, "i");
9306 +MODULE_PARM_DESC(irq, "Interrupt (4 or 3)");
9307 +MODULE_PARM(threshold, "i");
9308 +MODULE_PARM_DESC(threshold, "space detection threshold (3)");
9309 +#endif
9310 +
9311 +#ifdef MODULE_LICENSE
9312 +MODULE_LICENSE("GPL");
9313 +#endif
9314 +
9315 +#ifndef KERNEL_2_5
9316 +EXPORT_NO_SYMBOLS;
9317 +#endif
9318 +
9319 +int init_module(void)
9320 +{
9321 +       int retval;
9322 +       
9323 +       retval=init_chrdev();
9324 +       if(retval < 0)
9325 +               return retval;
9326 +       retval = init_lirc_sir();
9327 +       if (retval) {
9328 +               drop_chrdev();
9329 +               return retval;
9330 +       }
9331 +       return 0;
9332 +}
9333 +
9334 +void cleanup_module(void)
9335 +{
9336 +       drop_hardware();
9337 +       drop_chrdev();
9338 +       drop_port();
9339 +       printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n");
9340 +}
9341 +#endif
9342 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/Makefile linux-2.6.8-rc4/drivers/char/lirc/Makefile
9343 --- linux-2.6.8-rc4.orig/drivers/char/lirc/Makefile     1970-01-01 01:00:00.000000000 +0100
9344 +++ linux-2.6.8-rc4/drivers/char/lirc/Makefile  2004-08-10 10:22:06.189171224 +0200
9345 @@ -0,0 +1,11 @@
9346 +obj-$(CONFIG_LIRC_SUPPORT) += lirc_dev.o
9347 +obj-$(CONFIG_LIRC_GPIO) += lirc_gpio.o
9348 +obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
9349 +obj-$(CONFIG_LIRC_IT87) += lirc_it87.o
9350 +obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
9351 +obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
9352 +obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
9353 +obj-$(CONFIG_LIRC_SIR) += lirc_sir.o
9354 +obj-$(CONFIG_LIRC_ATIUSB) += lirc_atiusb.o
9355 +obj-$(CONFIG_LIRC_MCEUSB) += lirc_mceusb.o
9356 +obj-$(CONFIG_LIRC_I2C) += lirc_i2c.o
9357 diff -uNr linux-2.6.8-rc4.orig/drivers/char/Makefile linux-2.6.8-rc4/drivers/char/Makefile
9358 --- linux-2.6.8-rc4.orig/drivers/char/Makefile  2004-08-10 09:33:45.000000000 +0200
9359 +++ linux-2.6.8-rc4/drivers/char/Makefile       2004-08-10 10:23:05.725120384 +0200
9360 @@ -7,7 +7,7 @@
9361  #
9362  FONTMAPFILE = cp437.uni
9363  
9364 -obj-y   += mem.o random.o tty_io.o n_tty.o tty_ioctl.o
9365 +obj-y   += mem.o random.o tty_io.o n_tty.o tty_ioctl.o lirc/
9366  
9367  obj-$(CONFIG_VT)               += vt_ioctl.o vc_screen.o consolemap.o \
9368                                    consolemap_deftbl.o selection.o keyboard.o
9369 diff -uNr linux-2.6.8-rc4.orig/include/linux/lirc.h linux-2.6.8-rc4/include/linux/lirc.h
9370 --- linux-2.6.8-rc4.orig/include/linux/lirc.h   1970-01-01 01:00:00.000000000 +0100
9371 +++ linux-2.6.8-rc4/include/linux/lirc.h        2003-01-26 13:57:59.000000000 +0100
9372 @@ -0,0 +1,100 @@
9373 +/*      $Id$      */
9374 +
9375 +#ifndef _LINUX_LIRC_H
9376 +#define _LINUX_LIRC_H
9377 +
9378 +#if defined (__linux__)
9379 +#include <asm/types.h>
9380 +#include <linux/ioctl.h>
9381 +#else
9382 +#include <sys/types.h>
9383 +typedef u_int32_t __u32;
9384 +#endif
9385 +
9386 +#define PULSE_BIT  0x01000000
9387 +#define PULSE_MASK 0x00FFFFFF
9388 +
9389 +typedef int lirc_t;
9390 +
9391 +/*
9392 + * lirc compatible hardware features
9393 + */
9394 +
9395 +
9396 +#define LIRC_MODE2SEND(x) (x)
9397 +#define LIRC_SEND2MODE(x) (x)
9398 +#define LIRC_MODE2REC(x) ((x) << 16)
9399 +#define LIRC_REC2MODE(x) ((x) >> 16)
9400 +
9401 +#define LIRC_MODE_RAW                  0x00000001
9402 +#define LIRC_MODE_PULSE                0x00000002
9403 +#define LIRC_MODE_MODE2                0x00000004
9404 +#define LIRC_MODE_CODE                 0x00000008
9405 +#define LIRC_MODE_LIRCCODE             0x00000010
9406 +#define LIRC_MODE_STRING               0x00000020
9407 +
9408 +
9409 +#define LIRC_CAN_SEND_RAW              LIRC_MODE2SEND(LIRC_MODE_RAW)
9410 +#define LIRC_CAN_SEND_PULSE            LIRC_MODE2SEND(LIRC_MODE_PULSE)
9411 +#define LIRC_CAN_SEND_MODE2            LIRC_MODE2SEND(LIRC_MODE_MODE2)
9412 +#define LIRC_CAN_SEND_CODE             LIRC_MODE2SEND(LIRC_MODE_CODE)
9413 +#define LIRC_CAN_SEND_LIRCCODE         LIRC_MODE2SEND(LIRC_MODE_LIRCCODE)
9414 +#define LIRC_CAN_SEND_STRING           LIRC_MODE2SEND(LIRC_MODE_STRING)
9415 +
9416 +#define LIRC_CAN_SEND_MASK             0x0000003f
9417 +
9418 +#define LIRC_CAN_SET_SEND_CARRIER      0x00000100
9419 +#define LIRC_CAN_SET_SEND_DUTY_CYCLE   0x00000200
9420 +
9421 +#define LIRC_CAN_REC_RAW               LIRC_MODE2REC(LIRC_MODE_RAW)
9422 +#define LIRC_CAN_REC_PULSE             LIRC_MODE2REC(LIRC_MODE_PULSE)
9423 +#define LIRC_CAN_REC_MODE2             LIRC_MODE2REC(LIRC_MODE_MODE2)
9424 +#define LIRC_CAN_REC_CODE              LIRC_MODE2REC(LIRC_MODE_CODE)
9425 +#define LIRC_CAN_REC_LIRCCODE          LIRC_MODE2REC(LIRC_MODE_LIRCCODE)
9426 +#define LIRC_CAN_REC_STRING            LIRC_MODE2REC(LIRC_MODE_STRING)
9427 +
9428 +#define LIRC_CAN_REC_MASK              LIRC_MODE2REC(LIRC_CAN_SEND_MASK)
9429 +
9430 +#define LIRC_CAN_SET_REC_CARRIER       (LIRC_CAN_SET_SEND_CARRIER << 16)
9431 +#define LIRC_CAN_SET_REC_DUTY_CYCLE    (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16)
9432 +
9433 +#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000
9434 +#define LIRC_CAN_SET_REC_CARRIER_RANGE    0x80000000
9435 +
9436 +
9437 +#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK)
9438 +#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK)
9439 +
9440 +/*
9441 + * IOCTL commands for lirc driver
9442 + */
9443 +
9444 +#define LIRC_GET_FEATURES              _IOR('i', 0x00000000, __u32)
9445 +
9446 +#define LIRC_GET_SEND_MODE             _IOR('i', 0x00000001, __u32)
9447 +#define LIRC_GET_REC_MODE              _IOR('i', 0x00000002, __u32)
9448 +#define LIRC_GET_SEND_CARRIER          _IOR('i', 0x00000003, __u32)
9449 +#define LIRC_GET_REC_CARRIER           _IOR('i', 0x00000004, __u32)
9450 +#define LIRC_GET_SEND_DUTY_CYCLE       _IOR('i', 0x00000005, __u32)
9451 +#define LIRC_GET_REC_DUTY_CYCLE        _IOR('i', 0x00000006, __u32)
9452 +
9453 +/* code length in bits, currently only for LIRC_MODE_LIRCCODE */
9454 +#define LIRC_GET_LENGTH                _IOR('i', 0x0000000f, __u32)
9455 +
9456 +#define LIRC_SET_SEND_MODE             _IOW('i', 0x00000011, __u32)
9457 +#define LIRC_SET_REC_MODE              _IOW('i', 0x00000012, __u32)
9458 +/* Note: these can reset the according pulse_width */
9459 +#define LIRC_SET_SEND_CARRIER          _IOW('i', 0x00000013, __u32)
9460 +#define LIRC_SET_REC_CARRIER           _IOW('i', 0x00000014, __u32)
9461 +#define LIRC_SET_SEND_DUTY_CYCLE       _IOW('i', 0x00000015, __u32)
9462 +#define LIRC_SET_REC_DUTY_CYCLE        _IOW('i', 0x00000016, __u32)
9463 +
9464 +/* to set a range use
9465 +   LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the
9466 +   lower bound first and later
9467 +   LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound */
9468 +
9469 +#define LIRC_SET_REC_DUTY_CYCLE_RANGE  _IOW('i', 0x0000001e, __u32)
9470 +#define LIRC_SET_REC_CARRIER_RANGE     _IOW('i', 0x0000001f, __u32)
9471 +
9472 +#endif
9473 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/kcompat.h linux-2.6.8-rc4/drivers/char/lirc/kcompat.h
9474 --- linux-2.6.8-rc4.orig/drivers/char/lirc/kcompat.h    1970-01-01 01:00:00.000000000 +0100
9475 +++ linux-2.6.8-rc4/drivers/char/lirc/kcompat.h 2004-04-27 20:52:33.000000000 +0200
9476 @@ -0,0 +1,74 @@
9477 +/*      $Id$      */
9478 +
9479 +#include <linux/version.h>
9480 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
9481 +#include <linux/timer.h>
9482 +#include <linux/interrupt.h>
9483 +static inline void del_timer_sync(struct timer_list * timerlist)
9484 +{
9485 +       start_bh_atomic();
9486 +       del_timer(timerlist);
9487 +       end_bh_atomic();
9488 +}
9489 +#endif
9490 +
9491 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
9492 +#undef daemonize
9493 +#define daemonize(name) do {                                           \
9494 +                                                                       \
9495 +       lock_kernel();                                                 \
9496 +                                                                      \
9497 +       exit_mm(current);                                              \
9498 +       exit_files(current);                                           \
9499 +       exit_fs(current);                                              \
9500 +       current->session = 1;                                          \
9501 +       current->pgrp = 1;                                             \
9502 +       current->euid = 0;                                             \
9503 +       current->tty = NULL;                                           \
9504 +       sigfillset(&current->blocked);                                 \
9505 +                                                                      \
9506 +       strcpy(current->comm, name);                                   \
9507 +                                                                      \
9508 +       unlock_kernel();                                               \
9509 +                                                                       \
9510 +} while (0)
9511 +
9512 +#endif
9513 +
9514 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
9515 +#define KERNEL_2_5
9516 +
9517 +#undef MOD_INC_USE_COUNT
9518 +#define MOD_INC_USE_COUNT try_module_get(THIS_MODULE)
9519 +#undef MOD_DEC_USE_COUNT
9520 +#define MOD_DEC_USE_COUNT module_put(THIS_MODULE)
9521 +
9522 +#endif
9523 +
9524 +#ifndef IRQ_RETVAL
9525 +typedef void irqreturn_t;
9526 +#define IRQ_NONE
9527 +#define IRQ_HANDLED
9528 +#define IRQ_RETVAL(x)
9529 +#endif
9530 +
9531 +#ifndef MOD_IN_USE
9532 +#ifdef CONFIG_MODULE_UNLOAD
9533 +#define MOD_IN_USE module_refcount(THIS_MODULE)
9534 +#else
9535 +#error "LIRC modules currently require"
9536 +#error "  'Loadable module support  --->  Module unloading'"
9537 +#error "to be enabled in the kernel"
9538 +#endif
9539 +#endif
9540 +
9541 +#if !defined(local_irq_save)
9542 +#define local_irq_save(flags) do{ save_flags(flags);cli(); } while(0)
9543 +#endif
9544 +#if !defined(local_irq_restore)
9545 +#define local_irq_restore(flags) do{ restore_flags(flags); } while(0)
9546 +#endif
9547 +
9548 +#if !defined(pci_pretty_name)
9549 +#define pci_pretty_name(dev) ((dev)->name)
9550 +#endif
This page took 0.846494 seconds and 3 git commands to generate.