/[linux-patches]/genpatches-2.6/historical/2.6.3/405_lirc_infrared-2.6.2-02092004.patch
Gentoo

Contents of /genpatches-2.6/historical/2.6.3/405_lirc_infrared-2.6.2-02092004.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations) (download) (as text)
Sat Jun 11 23:16:54 2005 UTC (15 years, 2 months ago) by dsd
File MIME type: text/x-diff
File size: 237221 byte(s)
Import historical releases
1 dsd 2 diff -NPaur linux-2.6.2/Documentation/lirc/lirc_it87 linux-2.6.2-lirc/Documentation/lirc/lirc_it87
2     --- linux-2.6.2/Documentation/lirc/lirc_it87 1970-01-01 01:00:00.000000000 +0100
3     +++ linux-2.6.2-lirc/Documentation/lirc/lirc_it87 2004-02-09 20:03:11.565862952 +0100
4     @@ -0,0 +1,54 @@
5     +This is the README using the ITE IT8705 and IT8712 CIR port for LIRC.
6     +
7     +The IT8705 for example can be found on the ECS K7S5A.
8     +
9     +The driver supports receiving (MODE2) and sending (PULSE). It seems
10     +sending 'LIRC_CAN_SEND_PULSE' isn't optimal for this type of hardware.
11     +But because I don't know how to implement 'LIRC_CAN_SEND_CODE', I did
12     +it this way.
13     +
14     +Attention:
15     +Because of missing hardware, the following hasn't been tested:
16     +a) receiving with demodulator enabled,
17     +b) sending (debugging output looks good) and
18     +c) using IT8712
19     +
20     +Any help and/or additions etc. is welcome.
21     +
22     +lirc_it87 knows about the following module-parameters:
23     +MODULE_DESCRIPTION("LIRC driver for ITE IT8712/IT8705 CIR port");
24     +MODULE_PARM(io, "i");
25     +MODULE_PARM_DESC(io, "I/O base address (default: 0x310)");
26     +MODULE_PARM(irq, "i");
27     +MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 7)");
28     +MODULE_PARM(it87_enable_demodulator, "i");
29     +MODULE_PARM_DESC(it87_enable_demodulator, "Receiver demodulator
30     + enable/disable (1/0), default: 0");
31     +
32     +
33     +Usage:
34     +
35     +a) io and irq:
36     +
37     +If the driver finds the IT8705/12-CIR port initialized, io and irq of
38     +the preinitialized hardware is used by the driver. If both values are
39     +read 0x0 from the hardware, the default or given value is used.
40     +Note: I experienced using irq=3. The driver initialized without any
41     +problems, but no irqs are recognized by the system. I had to switch
42     +back to default, irq 7.
43     +
44     +b) it87_enable_demodulator:
45     +
46     +The demodulator for the receiver can be switched off (default within
47     +the driver). If you need the demodulator simple enable it by the
48     +following way: it87_enable_demodulator=1.
49     +
50     +Hans-Günter Lütke Uphues
51     +
52     +
53     +TODO
54     +
55     +This is my todo-list for lirc_it87:
56     +
57     +1. enabling/using shared IRQ
58     +2. init/drop IRQ-usage in lirc_open/lirc_close
59     diff -NPaur linux-2.6.2/drivers/char/Kconfig linux-2.6.2-lirc/drivers/char/Kconfig
60     --- linux-2.6.2/drivers/char/Kconfig 2004-02-09 20:00:26.551948880 +0100
61     +++ linux-2.6.2-lirc/drivers/char/Kconfig 2004-02-09 20:03:11.600857632 +0100
62     @@ -589,6 +589,8 @@
63     depends on PC9800_OLDLP
64    
65    
66     +source "drivers/char/lirc/Kconfig"
67     +
68     menu "Mice"
69    
70     config BUSMOUSE
71     diff -NPaur linux-2.6.2/drivers/char/Makefile linux-2.6.2-lirc/drivers/char/Makefile
72     --- linux-2.6.2/drivers/char/Makefile 2004-02-09 20:00:26.563947056 +0100
73     +++ linux-2.6.2-lirc/drivers/char/Makefile 2004-02-09 20:03:15.015338552 +0100
74     @@ -7,7 +7,7 @@
75     #
76     FONTMAPFILE = cp437.uni
77    
78     -obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o pty.o misc.o
79     +obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o pty.o misc.o lirc/
80    
81     obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o consolemap.o \
82     consolemap_deftbl.o selection.o keyboard.o
83     diff -NPaur linux-2.6.2/drivers/char/lirc/Kconfig linux-2.6.2-lirc/drivers/char/lirc/Kconfig
84     --- linux-2.6.2/drivers/char/lirc/Kconfig 1970-01-01 01:00:00.000000000 +0100
85     +++ linux-2.6.2-lirc/drivers/char/lirc/Kconfig 2004-02-09 20:03:15.017338248 +0100
86     @@ -0,0 +1,208 @@
87     +# LIRC http://lirc.sf.net/
88     +# Kernel patch by Flameeyes <dgp85@users.sf.net>
89     +# Check for new patch at http://flameeyes.web.ctonet.it
90     +#
91     +# Thanks to Koos Vriezen <koos.vriezen@xs4all.nl> for the Homebrew support.
92     +# Thanks to Jeff Clark <jeff@tmtrading.com> for support when I wasn't able
93     +# to update it and for his patch (found at http://www.clarkmania.com/~jclark/
94     +# Thanks to Bernhard Rosenkraenzer <bero@arklinux.org> for SMP patch.
95     +# Thanks to Vince <fuzzy77@free.fr> for the temporary lirc_atiusb driver.
96     +# Thanks to Paul Miller <pmiller9@users.sourceforge.net> for the new working
97     +# lirc_atiusb driver.
98     +
99     +menu "Linux InfraRed Controller"
100     +
101     +config LIRC_SUPPORT
102     + tristate "Linux InfraRed Controller"
103     +
104     + config LIRC_MAX_DEV
105     + int "Maximum LIRC devices"
106     + default "2"
107     + depends on LIRC_SUPPORT
108     +
109     + config LIRC_I2C
110     + tristate "I2C Driver"
111     + depends on LIRC_SUPPORT && VIDEO_BT848 && I2C && I2C_ALGOBIT
112     + help
113     + Say Y here if you need support for the following cards:
114     +
115     + Pixelview IR
116     + Hauppauage IR
117     + PV951 IR
118     + TV-Box IR
119     + KNC ONE IR
120     +
121     + If these dont make sense to you, then dont use the module.
122     +
123     + config LIRC_GPIO
124     + tristate "GPIO Driver"
125     + depends on LIRC_SUPPORT && VIDEO_BT848
126     +
127     + config LIRC_BT829
128     + tristate "BT829 Driver"
129     + depends on LIRC_SUPPORT
130     +
131     + config LIRC_IT87
132     + tristate "IT87 Driver"
133     + depends on LIRC_SUPPORT
134     +
135     + config LIRC_ATIUSB
136     + tristate "ATI USB Driver"
137     + depends on LIRC_SUPPORT && USB
138     +
139     + config LIRC_MCEUSB
140     + tristate "MCE USB Driver"
141     + depends on LIRC_SUPPORT && USB
142     +
143     + config LIRC_PARALLEL
144     + tristate "Parallel Driver"
145     + depends on LIRC_SUPPORT && !SMP && PARPORT
146     +
147     + choice
148     + prompt "Parallel Port"
149     + depends on LIRC_PARALLEL
150     + config LIRC_PARALLEL_LPT1
151     + bool "LPT1 (0x378, 7)"
152     + config LIRC_PARALLEL_LPT2
153     + bool "LPT2 (0x278, 5)"
154     + config LIRC_PARALLEL_LPT3
155     + bool "COM3 (0x3bc, none)"
156     + config LIRC_PARALLEL_OTHER
157     + bool "Other (custom values)"
158     + endchoice
159     +
160     + config LIRC_PORT_PARALLEL
161     + hex "I/O Port"
162     + default "0x378" if LIRC_PARALLEL_LPT1
163     + default "0x278" if LIRC_PARALLEL_LPT2
164     + default "0x3bc" if LIRC_PARALLEL_LPT3
165     + depends on LIRC_PARALLEL
166     +
167     + config LIRC_IRQ_PARALLEL
168     + hex "IRQ"
169     + default "7" if LIRC_PARALLEL_LPT1
170     + default "5" if LIRC_PARALLEL_LPT2
171     + depends on LIRC_PARALLEL
172     +
173     + config LIRC_TIMER
174     + int "Timer"
175     + default "65535"
176     + depends on LIRC_PARALLEL
177     +
178     + config LIRC_SERIAL
179     + tristate "Serial Driver"
180     + depends on LIRC_SUPPORT && SERIAL_8250
181     +
182     + choice
183     + prompt "Serial Receiver Type"
184     + depends on LIRC_SERIAL
185     +
186     + config LIRC_HOMEBREW
187     + bool "Homebrew"
188     +
189     + config LIRC_SERIAL_ANIMAX
190     + bool "Animax"
191     +
192     + config LIRC_SERIAL_IRDEO
193     + bool "IRdeo"
194     +
195     + config LIRC_SERIAL_IRDEO_REMOTE
196     + bool "IRdeo Remote"
197     +
198     + endchoice
199     +
200     + config LIRC_SERIAL_TRANSMITTER
201     + bool "With transmitter diode"
202     + depends on LIRC_SERIAL && !LIRC_SERIAL_ANIMAX
203     +
204     + config LIRC_SERIAL_SOFTCARRIER
205     + bool "With software carrier"
206     + depends on LIRC_SERIAL_TRANSMITTER
207     +
208     + config LIRC_SERIAL_IGOR
209     + bool "Igor Ceska's variation"
210     + depends on LIRC_SERIAL
211     +
212     + choice
213     + prompt "Serial Port"
214     + depends on LIRC_SERIAL
215     + config LIRC_SERIAL_COM1
216     + bool "COM1 (0x3f8, 4)"
217     + config LIRC_SERIAL_COM2
218     + bool "COM2 (0x2f8, 3)"
219     + config LIRC_SERIAL_COM3
220     + bool "COM3 (0x3e8, 4)"
221     + config LIRC_SERIAL_COM4
222     + bool "COM4 (0x2e8, 3)"
223     + config LIRC_SERIAL_OTHER
224     + bool "Other (custom values)"
225     + endchoice
226     +
227     + config LIRC_PORT_SERIAL
228     + hex "I/O Port"
229     + default "0x3f8" if LIRC_SERIAL_COM1
230     + default "0x2f8" if LIRC_SERIAL_COM2
231     + default "0x3e8" if LIRC_SERIAL_COM3
232     + default "0x2e8" if LIRC_SERIAL_COM4
233     + depends on LIRC_SERIAL
234     +
235     + config LIRC_IRQ_SERIAL
236     + hex "IRQ"
237     + default "4" if LIRC_SERIAL_COM1 || LIRC_SERIAL_COM3
238     + default "3" if LIRC_SERIAL_COM2 || LIRC_SERIAL_COM4
239     + depends on LIRC_SERIAL
240     +
241     + config LIRC_SIR
242     + tristate "SIR Driver"
243     + depends on LIRC_SUPPORT
244     +
245     + config LIRC_ON_SA1100
246     + bool "LIRC driver for StrongARM SA1100 embedded microprocessor"
247     + depends on LIRC_SIR
248     +
249     + choice
250     + prompt "SIR Type"
251     + depends on LIRC_SIR && !LIRC_ON_SA1100
252     +
253     + config LIRC_SIR_IRDA
254     + bool "SIR IrDA (built-in IR ports)"
255     +
256     + config LIRC_SIR_TEKRAM
257     + bool "Tekram Irmate 210 (16x50 UART compatible serial port)"
258     +
259     + config LIRC_SIR_ACTISYS_ACT200L
260     + bool "Actisys Act200L SIR driver support"
261     +
262     + endchoice
263     +
264     + choice
265     + prompt "Serial Port"
266     + depends on LIRC_SIR
267     + config LIRC_SIR_COM1
268     + bool "COM1 (0x3f8, 4)"
269     + config LIRC_SIR_COM2
270     + bool "COM2 (0x2f8, 3)"
271     + config LIRC_SIR_COM3
272     + bool "COM3 (0x3e8, 4)"
273     + config LIRC_SIR_COM4
274     + bool "COM4 (0x2e8, 3)"
275     + config LIRC_SIR_OTHER
276     + bool "Other (custom values)"
277     + endchoice
278     +
279     + config LIRC_PORT_SIR
280     + hex "I/O Port"
281     + default "0x3f8" if LIRC_SIR_COM1
282     + default "0x2f8" if LIRC_SIR_COM2
283     + default "0x3e8" if LIRC_SIR_COM3
284     + default "0x2e8" if LIRC_SIR_COM4
285     + depends on LIRC_SIR
286     +
287     + config LIRC_IRQ_SIR
288     + hex "IRQ"
289     + default "4" if LIRC_SIR_COM1 || LIRC_SIR_COM3
290     + default "3" if LIRC_SIR_COM2 || LIRC_SIR_COM4
291     + depends on LIRC_SIR
292     +
293     +endmenu
294     +
295     diff -NPaur linux-2.6.2/drivers/char/lirc/Makefile linux-2.6.2-lirc/drivers/char/lirc/Makefile
296     --- linux-2.6.2/drivers/char/lirc/Makefile 1970-01-01 01:00:00.000000000 +0100
297     +++ linux-2.6.2-lirc/drivers/char/lirc/Makefile 2004-02-09 20:03:15.019337944 +0100
298     @@ -0,0 +1,14 @@
299     +#
300     +# Makefile for the lirc drivers
301     +#
302     +
303     +obj-$(CONFIG_LIRC_SUPPORT) += lirc_dev.o
304     +obj-$(CONFIG_LIRC_GPIO) += lirc_gpio.o
305     +obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
306     +obj-$(CONFIG_LIRC_IT87) += lirc_it87.o
307     +obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
308     +obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
309     +obj-$(CONFIG_LIRC_SIR) += lirc_sir.o
310     +obj-$(CONFIG_LIRC_ATIUSB) += lirc_atiusb.o
311     +obj-$(CONFIG_LIRC_MCEUSB) += lirc_mceusb.o
312     +obj-$(CONFIG_LIRC_I2C) += lirc_i2c.o
313     diff -NPaur linux-2.6.2/drivers/char/lirc/lirc_atiusb.c linux-2.6.2-lirc/drivers/char/lirc/lirc_atiusb.c
314     --- linux-2.6.2/drivers/char/lirc/lirc_atiusb.c 1970-01-01 01:00:00.000000000 +0100
315     +++ linux-2.6.2-lirc/drivers/char/lirc/lirc_atiusb.c 2004-02-09 20:03:15.022337488 +0100
316     @@ -0,0 +1,629 @@
317     +/* lirc_atiusb - USB remote support for LIRC
318     + * (currently only supports X10 USB remotes)
319     + * Version 0.3 [beta status]
320     + *
321     + * Copyright (C) 2003-2004 Paul Miller <pmiller9@users.sourceforge.net>
322     + *
323     + * This driver was derived from:
324     + * Vladimir Dergachev <volodya@minspring.com>'s 2002
325     + * "USB ATI Remote support" (input device)
326     + * Adrian Dewhurst <sailor-lk@sailorfrag.net>'s 2002
327     + * "USB StreamZap remote driver" (LIRC)
328     + * Artur Lipowski <alipowski@kki.net.pl>'s 2002
329     + * "lirc_dev" and "lirc_gpio" LIRC modules
330     + *
331     + * $Id: 405_lirc_infrared-2.6.2-02092004.patch,v 1.1 2004/02/24 22:27:37 brad_mssw Exp $
332     + */
333     +
334     +/*
335     + * This program is free software; you can redistribute it and/or modify
336     + * it under the terms of the GNU General Public License as published by
337     + * the Free Software Foundation; either version 2 of the License, or
338     + * (at your option) any later version.
339     + *
340     + * This program is distributed in the hope that it will be useful,
341     + * but WITHOUT ANY WARRANTY; without even the implied warranty of
342     + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
343     + * GNU General Public License for more details.
344     + *
345     + * You should have received a copy of the GNU General Public License
346     + * along with this program; if not, write to the Free Software
347     + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
348     + *
349     + */
350     +
351     +#include <linux/version.h>
352     +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 4)
353     +#error "*******************************************************"
354     +#error "Sorry, this driver needs kernel version 2.2.4 or higher"
355     +#error "*******************************************************"
356     +#endif
357     +
358     +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
359     +#define KERNEL26 1
360     +#else
361     +#define KERNEL26 0
362     +#endif
363     +
364     +#include <linux/config.h>
365     +
366     +#include <linux/kernel.h>
367     +#include <linux/errno.h>
368     +#include <linux/init.h>
369     +#include <linux/slab.h>
370     +#include <linux/module.h>
371     +#include <linux/kmod.h>
372     +#include <linux/smp_lock.h>
373     +#include <linux/completion.h>
374     +#include <asm/uaccess.h>
375     +#include <linux/usb.h>
376     +#include <linux/poll.h>
377     +#include <linux/wait.h>
378     +
379     +#if KERNEL26
380     +#include <linux/lirc.h>
381     +#include "lirc_dev.h"
382     +#else
383     +#include "drivers/lirc.h"
384     +#include "drivers/lirc_dev/lirc_dev.h"
385     +#endif
386     +
387     +#define DRIVER_VERSION "0.3"
388     +#define DRIVER_AUTHOR "Paul Miller <pmiller9@users.sourceforge.net>"
389     +#define DRIVER_DESC "USB remote driver for LIRC"
390     +#define DRIVER_NAME "lirc_atiusb"
391     +
392     +#define CODE_LENGTH 5
393     +#define CODE_MIN_LENGTH 4
394     +#define USB_BUFLEN (CODE_LENGTH*4)
395     +
396     +#ifdef CONFIG_USB_DEBUG
397     + static int debug = 1;
398     +#else
399     + static int debug = 0;
400     +#endif
401     +#define dprintk if (debug) printk
402     +
403     +/* get hi and low bytes of a 16-bits int */
404     +#define HI(a) ((unsigned char)((a) >> 8))
405     +#define LO(a) ((unsigned char)((a) & 0xff))
406     +
407     +/* lock irctl structure */
408     +#define IRLOCK down_interruptible(&ir->lock)
409     +#define IRUNLOCK up(&ir->lock)
410     +
411     +/* general constants */
412     +#define SUCCESS 0
413     +#define SEND_FLAG_IN_PROGRESS 1
414     +#define SEND_FLAG_COMPLETE 2
415     +
416     +
417     +/* data structure for each usb remote */
418     +struct irctl {
419     +
420     + /* usb */
421     + struct usb_device *usbdev;
422     + struct urb *urb_in;
423     + struct urb *urb_out;
424     + int devnum;
425     +
426     + /* buffers and dma */
427     + unsigned char *buf_in;
428     + unsigned char *buf_out;
429     + unsigned int len_in;
430     +#if KERNEL26
431     + dma_addr_t dma_in;
432     + dma_addr_t dma_out;
433     +#endif
434     +
435     + /* lirc */
436     + struct lirc_plugin *p;
437     + int connected;
438     +
439     + /* handle sending (init strings) */
440     + int send_flags;
441     + wait_queue_head_t wait_out;
442     +
443     + struct semaphore lock;
444     +};
445     +
446     +/* init strings */
447     +static char init1[] = {0x01, 0x00, 0x20, 0x14};
448     +static char init2[] = {0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20};
449     +
450     +/* send packet - used to initialize remote */
451     +static void send_packet(struct irctl *ir, u16 cmd, unsigned char *data)
452     +{
453     + DECLARE_WAITQUEUE(wait, current);
454     + int timeout = HZ; /* 1 second */
455     + unsigned char buf[USB_BUFLEN];
456     +
457     + dprintk(DRIVER_NAME "[%d]: send called (%#x)\n", ir->devnum, cmd);
458     +
459     + IRLOCK;
460     + ir->urb_out->transfer_buffer_length = LO(cmd) + 1;
461     + ir->urb_out->dev = ir->usbdev;
462     + ir->send_flags = SEND_FLAG_IN_PROGRESS;
463     +
464     + memcpy(buf+1, data, LO(cmd));
465     + buf[0] = HI(cmd);
466     + memcpy(ir->buf_out, buf, LO(cmd)+1);
467     +
468     + set_current_state(TASK_INTERRUPTIBLE);
469     + add_wait_queue(&ir->wait_out, &wait);
470     +
471     +#if KERNEL26
472     + if (usb_submit_urb(ir->urb_out, SLAB_ATOMIC)) {
473     +#else
474     + if (usb_submit_urb(ir->urb_out)) {
475     +#endif
476     + set_current_state(TASK_RUNNING);
477     + remove_wait_queue(&ir->wait_out, &wait);
478     + IRUNLOCK;
479     + return;
480     + }
481     + IRUNLOCK;
482     +
483     + while (timeout && (ir->urb_out->status == -EINPROGRESS)
484     + && !(ir->send_flags & SEND_FLAG_COMPLETE)) {
485     + timeout = schedule_timeout(timeout);
486     + rmb();
487     + }
488     +
489     + dprintk(DRIVER_NAME "[%d]: send complete (%#x)\n", ir->devnum, cmd);
490     +
491     + set_current_state(TASK_RUNNING);
492     + remove_wait_queue(&ir->wait_out, &wait);
493     + usb_unlink_urb(ir->urb_out);
494     +}
495     +
496     +static int unregister_from_lirc(struct irctl *ir)
497     +{
498     + struct lirc_plugin *p = ir->p;
499     + int devnum;
500     + int rtn;
501     +
502     + devnum = ir->devnum;
503     + dprintk(DRIVER_NAME "[%d]: unregister from lirc called\n", devnum);
504     +
505     + if ((rtn = lirc_unregister_plugin(p->minor)) > 0) {
506     + printk(DRIVER_NAME "[%d]: error in lirc_unregister minor: %d\n"
507     + "Trying again...\n", devnum, p->minor);
508     + if (rtn == -EBUSY) {
509     + printk(DRIVER_NAME
510     + "[%d]: device is opened, will unregister"
511     + " on close\n", devnum);
512     + return -EAGAIN;
513     + }
514     + set_current_state(TASK_INTERRUPTIBLE);
515     + schedule_timeout(HZ);
516     +
517     + if ((rtn = lirc_unregister_plugin(p->minor)) > 0) {
518     + printk(DRIVER_NAME "[%d]: lirc_unregister failed\n",
519     + devnum);
520     + }
521     + }
522     +
523     + if (rtn != SUCCESS) {
524     + printk(DRIVER_NAME "[%d]: didn't free resources\n", devnum);
525     + return -EAGAIN;
526     + }
527     +
528     + printk(DRIVER_NAME "[%d]: usb remote disconnected\n", devnum);
529     +
530     + lirc_buffer_free(p->rbuf);
531     + kfree(p->rbuf);
532     + kfree(p);
533     + kfree(ir);
534     + return SUCCESS;
535     +}
536     +
537     +static int set_use_inc(void *data)
538     +{
539     + struct irctl *ir = data;
540     +
541     + if (!ir) {
542     + printk(DRIVER_NAME "[?]: set_use_inc called with no context\n");
543     + return -EIO;
544     + }
545     + dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum);
546     +
547     + if (!ir->connected) {
548     + if (!ir->usbdev)
549     + return -ENOENT;
550     + ir->urb_in->dev = ir->usbdev;
551     +#if KERNEL26
552     + if (usb_submit_urb(ir->urb_in, SLAB_ATOMIC)) {
553     +#else
554     + if (usb_submit_urb(ir->urb_in)) {
555     +#endif
556     + printk(DRIVER_NAME "[%d]: open result = -EIO error "
557     + "submitting urb\n", ir->devnum);
558     + return -EIO;
559     + }
560     + ir->connected = 1;
561     + }
562     +
563     + return SUCCESS;
564     +}
565     +
566     +static void set_use_dec(void *data)
567     +{
568     + struct irctl *ir = data;
569     +
570     + if (!ir) {
571     + printk(DRIVER_NAME "[?]: set_use_dec called with no context\n");
572     + return;
573     + }
574     + dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum);
575     +
576     + if (ir->connected) {
577     + IRLOCK;
578     + usb_unlink_urb(ir->urb_in);
579     + ir->connected = 0;
580     + IRUNLOCK;
581     + }
582     +}
583     +
584     +
585     +#if KERNEL26
586     +static void usb_remote_recv(struct urb *urb, struct pt_regs *regs)
587     +#else
588     +static void usb_remote_recv(struct urb *urb)
589     +#endif
590     +{
591     + struct irctl *ir;
592     + char buf[CODE_LENGTH];
593     + int i, len;
594     +
595     + if (!urb)
596     + return;
597     +
598     + if (!(ir = urb->context)) {
599     + usb_unlink_urb(urb);
600     + return;
601     + }
602     +
603     + dprintk(DRIVER_NAME "[%d]: data received (length %d)\n",
604     + ir->devnum, urb->actual_length);
605     +
606     + switch (urb->status) {
607     +
608     + /* success */
609     + case SUCCESS:
610     + /* some remotes emit both 4 and 5 byte length codes. */
611     + len = urb->actual_length;
612     + if (len < CODE_MIN_LENGTH || len > CODE_LENGTH) return;
613     +
614     + memcpy(buf,urb->transfer_buffer,len);
615     + for (i = len; i < CODE_LENGTH; i++) buf[i] = 0;
616     +
617     + lirc_buffer_write_1(ir->p->rbuf, buf);
618     + wake_up(&ir->p->rbuf->wait_poll);
619     + break;
620     +
621     + /* unlink */
622     + case -ECONNRESET:
623     + case -ENOENT:
624     + case -ESHUTDOWN:
625     + usb_unlink_urb(urb);
626     + return;
627     + }
628     +
629     + /* resubmit urb */
630     +#if KERNEL26
631     + usb_submit_urb(urb, SLAB_ATOMIC);
632     +#else
633     + usb_submit_urb(urb);
634     +#endif
635     +}
636     +
637     +#if KERNEL26
638     +static void usb_remote_send(struct urb *urb, struct pt_regs *regs)
639     +#else
640     +static void usb_remote_send(struct urb *urb)
641     +#endif
642     +{
643     + struct irctl *ir;
644     +
645     + if (!urb)
646     + return;
647     +
648     + if (!(ir = urb->context)) {
649     + usb_unlink_urb(urb);
650     + return;
651     + }
652     +
653     + dprintk(DRIVER_NAME "[%d]: usb out called\n", ir->devnum);
654     +
655     + if (urb->status)
656     + return;
657     +
658     + ir->send_flags |= SEND_FLAG_COMPLETE;
659     + wmb();
660     + if (waitqueue_active(&ir->wait_out))
661     + wake_up(&ir->wait_out);
662     +}
663     +
664     +#if KERNEL26
665     +static int usb_remote_probe(struct usb_interface *intf,
666     + const struct usb_device_id *id)
667     +{
668     + struct usb_device *dev = NULL;
669     + struct usb_host_interface *idesc = NULL;
670     +#else
671     +static void *usb_remote_probe(struct usb_device *dev, unsigned int ifnum,
672     + const struct usb_device_id *id)
673     +{
674     + struct usb_interface *intf;
675     + struct usb_interface_descriptor *idesc;
676     +#endif
677     + struct usb_endpoint_descriptor *ep_in, *ep_out;
678     + struct irctl *ir = NULL;
679     + struct lirc_plugin *plugin = NULL;
680     + struct lirc_buffer *rbuf = NULL;
681     + int devnum, pipe, maxp, len, buf_len, bytes_in_key;
682     + int minor = 0;
683     + char buf[63], name[128]="";
684     + int mem_failure = 0;
685     +
686     + dprintk(DRIVER_NAME ": usb probe called\n");
687     +
688     +#if KERNEL26
689     + dev = interface_to_usbdev(intf);
690     + idesc = &intf->altsetting[intf->act_altsetting];
691     + if (idesc->desc.bNumEndpoints != 2)
692     + return -ENODEV;
693     + ep_in = &idesc->endpoint[0].desc;
694     + ep_out = &idesc->endpoint[1].desc;
695     + if (((ep_in->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)
696     + || (ep_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
697     + != USB_ENDPOINT_XFER_INT)
698     + return -ENODEV;
699     +#else
700     + intf = &dev->actconfig->interface[ifnum];
701     + idesc = &intf->altsetting[intf->act_altsetting];
702     + if (idesc->bNumEndpoints != 2)
703     + return NULL;
704     + ep_in = idesc->endpoint + 0;
705     + ep_out = idesc->endpoint + 1;
706     + if (((ep_in->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)
707     + || (ep_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
708     + != USB_ENDPOINT_XFER_INT)
709     + return NULL;
710     +#endif
711     + devnum = dev->devnum;
712     + pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress);
713     + maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
714     +
715     + bytes_in_key = CODE_LENGTH;
716     + len = (maxp > USB_BUFLEN) ? USB_BUFLEN : maxp;
717     + buf_len = len - (len % bytes_in_key);
718     +
719     + dprintk(DRIVER_NAME "[%d]: bytes_in_key=%d len=%d maxp=%d buf_len=%d\n",
720     + devnum, bytes_in_key, len, maxp, buf_len);
721     +
722     +
723     + /* allocate kernel memory */
724     + mem_failure = 0;
725     + if (!(ir = kmalloc(sizeof(struct irctl), GFP_KERNEL))) {
726     + mem_failure = 1;
727     + } else {
728     + memset(ir, 0, sizeof(struct irctl));
729     +
730     + if (!(plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL))) {
731     + mem_failure = 2;
732     + } else if (!(rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL))) {
733     + mem_failure = 3;
734     + } else if (lirc_buffer_init(rbuf, bytes_in_key, USB_BUFLEN/bytes_in_key)) {
735     + mem_failure = 4;
736     +#if KERNEL26
737     + } else if (!(ir->buf_in = usb_buffer_alloc(dev, buf_len, SLAB_ATOMIC, &ir->dma_in))) {
738     + mem_failure = 5;
739     + } else if (!(ir->buf_out = usb_buffer_alloc(dev, USB_BUFLEN, SLAB_ATOMIC, &ir->dma_out))) {
740     + mem_failure = 6;
741     + } else if (!(ir->urb_in = usb_alloc_urb(0, GFP_KERNEL))) {
742     + mem_failure = 7;
743     + } else if (!(ir->urb_out = usb_alloc_urb(0, GFP_KERNEL))) {
744     + mem_failure = 8;
745     +#else
746     + } else if (!(ir->buf_in = kmalloc(buf_len, GFP_KERNEL))) {
747     + mem_failure = 5;
748     + } else if (!(ir->buf_out = kmalloc(USB_BUFLEN, GFP_KERNEL))) {
749     + mem_failure = 6;
750     + } else if (!(ir->urb_in = usb_alloc_urb(0))) {
751     + mem_failure = 7;
752     + } else if (!(ir->urb_out = usb_alloc_urb(0))) {
753     + mem_failure = 8;
754     +#endif
755     + } else {
756     +
757     + memset(plugin, 0, sizeof(struct lirc_plugin));
758     +
759     + strcpy(plugin->name, DRIVER_NAME " ");
760     + plugin->minor = -1;
761     + plugin->code_length = bytes_in_key*8;
762     + plugin->features = LIRC_CAN_REC_LIRCCODE;
763     + plugin->data = ir;
764     + plugin->rbuf = rbuf;
765     + plugin->set_use_inc = &set_use_inc;
766     + plugin->set_use_dec = &set_use_dec;
767     +
768     + init_MUTEX(&ir->lock);
769     + init_waitqueue_head(&ir->wait_out);
770     +
771     + if ((minor = lirc_register_plugin(plugin)) < 0) {
772     + mem_failure = 9;
773     + }
774     + }
775     + }
776     +
777     + /* free allocated memory incase of failure */
778     + switch (mem_failure) {
779     + case 9:
780     + lirc_buffer_free(rbuf);
781     + case 8:
782     + usb_free_urb(ir->urb_out);
783     + case 7:
784     + usb_free_urb(ir->urb_in);
785     +#if KERNEL26
786     + case 6:
787     + usb_buffer_free(dev, USB_BUFLEN, ir->buf_out, ir->dma_out);
788     + case 5:
789     + usb_buffer_free(dev, buf_len, ir->buf_in, ir->dma_in);
790     +#else
791     + case 6:
792     + kfree(ir->buf_out);
793     + case 5:
794     + kfree(ir->buf_in);
795     +#endif
796     + case 4:
797     + kfree(rbuf);
798     + case 3:
799     + kfree(plugin);
800     + case 2:
801     + kfree(ir);
802     + case 1:
803     + printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n",
804     + devnum, mem_failure);
805     +#if KERNEL26
806     + return -ENOMEM;
807     +#else
808     + return NULL;
809     +#endif
810     + }
811     +
812     + plugin->minor = minor;
813     + ir->p = plugin;
814     + ir->devnum = devnum;
815     + ir->usbdev = dev;
816     + ir->len_in = buf_len;
817     + ir->connected = 0;
818     +
819     + usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in,
820     + buf_len, usb_remote_recv, ir, ep_in->bInterval);
821     + usb_fill_int_urb(ir->urb_out, dev,
822     + usb_sndintpipe(dev, ep_out->bEndpointAddress), ir->buf_out,
823     + USB_BUFLEN, usb_remote_send, ir, ep_out->bInterval);
824     +
825     + if (dev->descriptor.iManufacturer
826     + && usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0)
827     + strncpy(name, buf, 128);
828     + if (dev->descriptor.iProduct
829     + && usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0)
830     + snprintf(name, 128, "%s %s", name, buf);
831     + printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name,
832     + dev->bus->busnum, devnum);
833     +
834     + send_packet(ir, 0x8004, init1);
835     + send_packet(ir, 0x8007, init2);
836     +
837     +#if KERNEL26
838     + usb_set_intfdata(intf, ir);
839     + return SUCCESS;
840     +#else
841     + return ir;
842     +#endif
843     +}
844     +
845     +
846     +#if KERNEL26
847     +static void usb_remote_disconnect(struct usb_interface *intf)
848     +{
849     + struct usb_device *dev = interface_to_usbdev(intf);
850     + struct irctl *ir = usb_get_intfdata(intf);
851     + usb_set_intfdata(intf, NULL);
852     +#else
853     +static void usb_remote_disconnect(struct usb_device *dev, void *ptr)
854     +{
855     + struct irctl *ir = ptr;
856     +#endif
857     +
858     + if (!ir || !ir->p)
859     + return;
860     +
861     + ir->usbdev = NULL;
862     + wake_up_all(&ir->wait_out);
863     +
864     + IRLOCK;
865     + usb_unlink_urb(ir->urb_in);
866     + usb_unlink_urb(ir->urb_out);
867     + usb_free_urb(ir->urb_in);
868     + usb_free_urb(ir->urb_out);
869     +#if KERNEL26
870     + usb_buffer_free(dev, ir->len_in, ir->buf_in, ir->dma_in);
871     + usb_buffer_free(dev, USB_BUFLEN, ir->buf_out, ir->dma_out);
872     +#else
873     + kfree(ir->buf_in);
874     + kfree(ir->buf_out);
875     +#endif
876     + IRUNLOCK;
877     +
878     + unregister_from_lirc(ir);
879     +}
880     +
881     +static struct usb_device_id usb_remote_id_table [] = {
882     + { USB_DEVICE(0x0bc7, 0x0002) }, /* X10 USB Firecracker Interface */
883     + { USB_DEVICE(0x0bc7, 0x0003) }, /* X10 VGA Video Sender */
884     + { USB_DEVICE(0x0bc7, 0x0004) }, /* ATI Wireless Remote Receiver */
885     + { USB_DEVICE(0x0bc7, 0x0005) }, /* NVIDIA Wireless Remote Receiver */
886     + { USB_DEVICE(0x0bc7, 0x0006) }, /* ATI Wireless Remote Receiver */
887     + { USB_DEVICE(0x0bc7, 0x0007) }, /* X10 USB Wireless Transceiver */
888     + { USB_DEVICE(0x0bc7, 0x0008) }, /* X10 USB Wireless Transceiver */
889     + { USB_DEVICE(0x0bc7, 0x0009) }, /* X10 USB Wireless Transceiver */
890     + { USB_DEVICE(0x0bc7, 0x000A) }, /* X10 USB Wireless Transceiver */
891     + { USB_DEVICE(0x0bc7, 0x000B) }, /* X10 USB Transceiver */
892     + { USB_DEVICE(0x0bc7, 0x000C) }, /* X10 USB Transceiver */
893     + { USB_DEVICE(0x0bc7, 0x000D) }, /* X10 USB Transceiver */
894     + { USB_DEVICE(0x0bc7, 0x000E) }, /* X10 USB Transceiver */
895     + { USB_DEVICE(0x0bc7, 0x000F) }, /* X10 USB Transceiver */
896     +
897     + { } /* Terminating entry */
898     +};
899     +
900     +static struct usb_driver usb_remote_driver = {
901     + .owner = THIS_MODULE,
902     + .name = DRIVER_NAME,
903     + .probe = usb_remote_probe,
904     + .disconnect = usb_remote_disconnect,
905     + .id_table = usb_remote_id_table
906     +};
907     +
908     +static int __init usb_remote_init(void)
909     +{
910     + int i;
911     +
912     + printk("\n" DRIVER_NAME ": " DRIVER_DESC " v" DRIVER_VERSION "\n");
913     + printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n");
914     + dprintk(DRIVER_NAME ": debug mode enabled\n");
915     +
916     + request_module("lirc_dev");
917     +
918     + if ((i = usb_register(&usb_remote_driver)) < 0) {
919     + printk(DRIVER_NAME ": usb register failed, result = %d\n", i);
920     + return -ENODEV;
921     + }
922     +
923     + return SUCCESS;
924     +}
925     +
926     +static void __exit usb_remote_exit(void)
927     +{
928     + usb_deregister(&usb_remote_driver);
929     +}
930     +
931     +module_init(usb_remote_init);
932     +module_exit(usb_remote_exit);
933     +
934     +MODULE_AUTHOR (DRIVER_AUTHOR);
935     +MODULE_DESCRIPTION (DRIVER_DESC);
936     +MODULE_LICENSE ("GPL");
937     +MODULE_DEVICE_TABLE (usb, usb_remote_id_table);
938     +
939     +MODULE_PARM(debug, "i");
940     +MODULE_PARM_DESC(debug, "enable driver debug mode");
941     +
942     +#if !KERNEL26
943     +EXPORT_NO_SYMBOLS;
944     +#endif
945     +
946     diff -NPaur linux-2.6.2/drivers/char/lirc/lirc_bt829.c linux-2.6.2-lirc/drivers/char/lirc/lirc_bt829.c
947     --- linux-2.6.2/drivers/char/lirc/lirc_bt829.c 1970-01-01 01:00:00.000000000 +0100
948     +++ linux-2.6.2-lirc/drivers/char/lirc/lirc_bt829.c 2004-02-09 20:03:15.045333992 +0100
949     @@ -0,0 +1,364 @@
950     +/*
951     + * Remote control driver for the TV-card based on bt829
952     + *
953     + * by Leonid Froenchenko <lfroen@galileo.co.il>
954     + *
955     + * This program is free software; you can redistribute it and/or modify
956     + * it under the terms of the GNU General Public License as published by
957     + * the Free Software Foundation; either version 2 of the License, or
958     + * (at your option) any later version.
959     + *
960     + * This program is distributed in the hope that it will be useful,
961     + * but WITHOUT ANY WARRANTY; without even the implied warranty of
962     + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
963     + * GNU General Public License for more details.
964     + *
965     + * You should have received a copy of the GNU General Public License
966     + * along with this program; if not, write to the Free Software
967     + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
968     +*/
969     +
970     +#include <linux/version.h>
971     +#include <linux/config.h>
972     +#include <linux/kernel.h>
973     +#include <linux/module.h>
974     +#include <linux/threads.h>
975     +#include <linux/sched.h>
976     +#include <linux/ioport.h>
977     +#include <linux/pci.h>
978     +#include <linux/delay.h>
979     +#include <linux/init.h>
980     +
981     +#include "lirc_dev.h"
982     +
983     +int poll_main(void);
984     +int atir_init_start(void);
985     +
986     +void write_index(unsigned char index,unsigned int value);
987     +unsigned int read_index(unsigned char index);
988     +
989     +void do_i2c_start(void);
990     +void do_i2c_stop(void);
991     +
992     +void seems_wr_byte(unsigned char al);
993     +unsigned char seems_rd_byte(void);
994     +
995     +unsigned int read_index(unsigned char al);
996     +void write_index(unsigned char ah,unsigned int edx);
997     +
998     +void cycle_delay(int cycle);
999     +
1000     +void do_set_bits(unsigned char bl);
1001     +unsigned char do_get_bits(void);
1002     +
1003     +#define DATA_PCI_OFF 0x7FFC00
1004     +#define WAIT_CYCLE 20
1005     +
1006     +
1007     +int atir_minor;
1008     +unsigned long pci_addr_phys, pci_addr_lin;
1009     +
1010     +struct lirc_plugin atir_plugin;
1011     +
1012     +int do_pci_probe(void)
1013     +{
1014     + struct pci_dev *my_dev;
1015     + my_dev = (struct pci_dev *)pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_264VT,NULL);
1016     + if ( my_dev ) {
1017     + printk(KERN_ERR "ATIR: Using device: %s\n",my_dev->slot_name);
1018     + pci_addr_phys = 0;
1019     + if ( my_dev->resource[0].flags & IORESOURCE_MEM ) {
1020     + pci_addr_phys = my_dev->resource[0].start;
1021     + printk(KERN_INFO "ATIR memory at 0x%08X \n",(unsigned int)pci_addr_phys);
1022     + }
1023     + if ( pci_addr_phys == 0 ) {
1024     + printk(KERN_ERR "ATIR no memory resource ?\n");
1025     + return 0;
1026     + }
1027     + } else {
1028     + printk(KERN_ERR "ATIR: pci_prob failed\n");
1029     + return 0;
1030     + }
1031     + return 1;
1032     +}
1033     +
1034     +
1035     +int atir_get_key (void* data, unsigned char* key, int key_no)
1036     +{
1037     + int status;
1038     + status = poll_main();
1039     + *key = (status >> 8) & 0xFF;
1040     + // if ( status & 0xFF ) {
1041     + // printk(KERN_INFO "ATIR reading key %02X\n",*key);
1042     + // }
1043     + return (status & 0xFF) ? 0 : -1;
1044     +}
1045     +
1046     +int atir_set_use_inc(void* data)
1047     +{
1048     + printk(KERN_DEBUG "ATIR driver is opened\n");
1049     + return 0;
1050     +}
1051     +
1052     +void atir_set_use_dec(void* data)
1053     +{
1054     + printk(KERN_DEBUG "ATIR driver is closed\n");
1055     +}
1056     +
1057     +static int __init lirc_bt829_init(void)
1058     +{
1059     + if ( !do_pci_probe() ) {
1060     + return 1;
1061     + }
1062     +
1063     + if ( !atir_init_start() ) {
1064     + return 1;
1065     + }
1066     +
1067     + strcpy(atir_plugin.name,"ATIR");
1068     + atir_plugin.minor = -1;
1069     + atir_plugin.code_length = 8;
1070     + atir_plugin.sample_rate = 10;
1071     + atir_plugin.data = 0;
1072     + atir_plugin.get_key = atir_get_key;
1073     + atir_plugin.set_use_inc = atir_set_use_inc;
1074     + atir_plugin.set_use_dec = atir_set_use_dec;
1075     +
1076     + atir_minor = lirc_register_plugin(&atir_plugin);
1077     + printk(KERN_DEBUG "ATIR driver is registered on minor %d\n",atir_minor);
1078     +
1079     + return 0;
1080     +}
1081     +
1082     +
1083     +static void __exit lirc_bt829_exit(void)
1084     +{
1085     + lirc_unregister_plugin(atir_minor);
1086     +}
1087     +
1088     +
1089     +int atir_init_start(void)
1090     +{
1091     + pci_addr_lin = (unsigned long)ioremap(pci_addr_phys + DATA_PCI_OFF,0x400);
1092     + if ( pci_addr_lin == 0 ) {
1093     + printk(KERN_INFO "atir: pci mem must be mapped\n");
1094     + return 0;
1095     + }
1096     + return 1;
1097     +}
1098     +
1099     +void cycle_delay(int cycle)
1100     +{
1101     + udelay(WAIT_CYCLE*cycle);
1102     +}
1103     +
1104     +
1105     +int poll_main()
1106     +{
1107     + unsigned char status_high, status_low;
1108     +
1109     + do_i2c_start();
1110     +
1111     + seems_wr_byte(0xAA);
1112     + seems_wr_byte(0x01);
1113     +
1114     + do_i2c_start();
1115     +
1116     + seems_wr_byte(0xAB);
1117     +
1118     + status_low = seems_rd_byte();
1119     + status_high = seems_rd_byte();
1120     +
1121     + do_i2c_stop();
1122     +
1123     + return (status_high << 8) | status_low;
1124     +}
1125     +
1126     +void do_i2c_start(void)
1127     +{
1128     + do_set_bits(3);
1129     + cycle_delay(4);
1130     +
1131     + do_set_bits(1);
1132     + cycle_delay(7);
1133     +
1134     + do_set_bits(0);
1135     + cycle_delay(2);
1136     +}
1137     +
1138     +void do_i2c_stop(void)
1139     +{
1140     + unsigned char bits;
1141     + bits = do_get_bits() & 0xFD;
1142     + do_set_bits(bits);
1143     + cycle_delay(1);
1144     +
1145     + bits |= 1;
1146     + do_set_bits(bits);
1147     + cycle_delay(2);
1148     +
1149     + bits |= 2;
1150     + do_set_bits(bits);
1151     + bits = 3;
1152     + do_set_bits(bits);
1153     + cycle_delay(2);
1154     +}
1155     +
1156     +
1157     +void seems_wr_byte(unsigned char value)
1158     +{
1159     + int i;
1160     + unsigned char reg;
1161     +
1162     + reg = do_get_bits();
1163     + for(i = 0;i < 8;i++) {
1164     + if ( value & 0x80 ) {
1165     + reg |= 0x02;
1166     + } else {
1167     + reg &= 0xFD;
1168     + }
1169     + do_set_bits(reg);
1170     + cycle_delay(1);
1171     +
1172     + reg |= 1;
1173     + do_set_bits(reg);
1174     + cycle_delay(1);
1175     +
1176     + reg &= 0xFE;
1177     + do_set_bits(reg);
1178     + cycle_delay(1);
1179     + value <<= 1;
1180     + }
1181     + cycle_delay(2);
1182     +
1183     + reg |= 2;
1184     + do_set_bits(reg);
1185     +
1186     + reg |= 1;
1187     + do_set_bits(reg);
1188     +
1189     + cycle_delay(1);
1190     + do_get_bits();
1191     +
1192     + reg &= 0xFE;
1193     + do_set_bits(reg);
1194     + cycle_delay(3);
1195     +}
1196     +
1197     +unsigned char seems_rd_byte(void)
1198     +{
1199     + int i;
1200     + int rd_byte;
1201     + unsigned char bits_2, bits_1;
1202     +
1203     + bits_1 = do_get_bits() | 2;
1204     + do_set_bits(bits_1);
1205     +
1206     + rd_byte = 0;
1207     + for(i = 0;i < 8;i++) {
1208     + bits_1 &= 0xFE;
1209     + do_set_bits(bits_1);
1210     + cycle_delay(2);
1211     +
1212     + bits_1 |= 1;
1213     + do_set_bits(bits_1);
1214     + cycle_delay(1);
1215     +
1216     + if ( (bits_2 = do_get_bits()) & 2 ) {
1217     + rd_byte |= 1;
1218     + }
1219     + rd_byte <<= 1;
1220     + }
1221     +
1222     + bits_1 = 0;
1223     + if ( bits_2 == 0 ) {
1224     + bits_1 |= 2;
1225     + }
1226     + do_set_bits(bits_1);
1227     + cycle_delay(2);
1228     +
1229     + bits_1 |= 1;
1230     + do_set_bits(bits_1);
1231     + cycle_delay(3);
1232     +
1233     + bits_1 &= 0xFE;
1234     + do_set_bits(bits_1);
1235     + cycle_delay(2);
1236     +
1237     + rd_byte >>= 1;
1238     + rd_byte &= 0xFF;
1239     + return rd_byte;
1240     +}
1241     +
1242     +void do_set_bits(unsigned char new_bits)
1243     +{
1244     + int reg_val;
1245     + reg_val = read_index(0x34);
1246     + if ( new_bits & 2 ) {
1247     + reg_val &= 0xFFFFFFDF;
1248     + reg_val |= 1;
1249     + } else {
1250     + reg_val &= 0xFFFFFFFE;
1251     + reg_val |= 0x20;
1252     + }
1253     + reg_val |= 0x10;
1254     + write_index(0x34,reg_val);
1255     +
1256     + reg_val = read_index(0x31);
1257     + if ( new_bits & 1 ) {
1258     + reg_val |= 0x1000000;
1259     + } else {
1260     + reg_val &= 0xFEFFFFFF;
1261     + }
1262     + reg_val |= 0x8000000;
1263     + write_index(0x31,reg_val);
1264     +}
1265     +
1266     +unsigned char do_get_bits(void)
1267     +{
1268     + unsigned char bits;
1269     + int reg_val;
1270     +
1271     + reg_val = read_index(0x34);
1272     + reg_val |= 0x10;
1273     + reg_val &= 0xFFFFFFDF;
1274     + write_index(0x34,reg_val);
1275     +
1276     + reg_val = read_index(0x34);
1277     + bits = 0;
1278     + if ( reg_val & 8 ) {
1279     + bits |= 2;
1280     + } else {
1281     + bits &= 0xFD;
1282     + }
1283     + reg_val = read_index(0x31);
1284     + if ( reg_val & 0x1000000 ) {
1285     + bits |= 1;
1286     + } else {
1287     + bits &= 0xFE;
1288     + }
1289     + return bits;
1290     +}
1291     +
1292     +unsigned int read_index(unsigned char index)
1293     +{
1294     + unsigned int addr, value;
1295     + // addr = pci_addr_lin + DATA_PCI_OFF + ((index & 0xFF) << 2);
1296     + addr = pci_addr_lin + ((index & 0xFF) << 2);
1297     + value = readl(addr);
1298     + return value;
1299     +}
1300     +
1301     +void write_index(unsigned char index,unsigned int reg_val)
1302     +{
1303     + unsigned int addr;
1304     + addr = pci_addr_lin + ((index & 0xFF) << 2);
1305     + writel(reg_val,addr);
1306     +}
1307     +
1308     +MODULE_AUTHOR("Froenchenko Leonid");
1309     +MODULE_DESCRIPTION("IR remote driver for bt829 based TV cards");
1310     +MODULE_LICENSE("GPL");
1311     +
1312     +module_init(lirc_bt829_init);
1313     +module_exit(lirc_bt829_exit);
1314     diff -NPaur linux-2.6.2/drivers/char/lirc/lirc_dev.c linux-2.6.2-lirc/drivers/char/lirc/lirc_dev.c
1315     --- linux-2.6.2/drivers/char/lirc/lirc_dev.c 1970-01-01 01:00:00.000000000 +0100
1316     +++ linux-2.6.2-lirc/drivers/char/lirc/lirc_dev.c 2004-02-09 20:03:15.048333536 +0100
1317     @@ -0,0 +1,713 @@
1318     +/*
1319     + * LIRC base driver
1320     + *
1321     + * (L) by Artur Lipowski <alipowski@interia.pl>
1322     + *
1323     + * This program is free software; you can redistribute it and/or modify
1324     + * it under the terms of the GNU General Public License as published by
1325     + * the Free Software Foundation; either version 2 of the License, or
1326     + * (at your option) any later version.
1327     + *
1328     + * This program is distributed in the hope that it will be useful,
1329     + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1330     + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1331     + * GNU General Public License for more details.
1332     + *
1333     + * You should have received a copy of the GNU General Public License
1334     + * along with this program; if not, write to the Free Software
1335     + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1336     + *
1337     + * $Id: 405_lirc_infrared-2.6.2-02092004.patch,v 1.1 2004/02/24 22:27:37 brad_mssw Exp $
1338     + *
1339     + */
1340     +
1341     +#include <linux/version.h>
1342     +
1343     +#include <linux/config.h>
1344     +#include <linux/module.h>
1345     +#include <linux/kernel.h>
1346     +#include <linux/sched.h>
1347     +#include <linux/ioctl.h>
1348     +#include <linux/fs.h>
1349     +#include <linux/poll.h>
1350     +#include <linux/smp_lock.h>
1351     +#include <asm/uaccess.h>
1352     +#include <asm/semaphore.h>
1353     +#include <asm/errno.h>
1354     +#define __KERNEL_SYSCALLS__
1355     +#include <linux/unistd.h>
1356     +#include <linux/init.h>
1357     +#include <linux/devfs_fs_kernel.h>
1358     +
1359     +#include <linux/lirc.h>
1360     +
1361     +#include "lirc_dev.h"
1362     +
1363     +static int debug = 0;
1364     +
1365     +MODULE_PARM(debug,"i");
1366     +
1367     +#define IRCTL_DEV_NAME "BaseRemoteCtl"
1368     +#define SUCCESS 0
1369     +#define NOPLUG -1
1370     +#define dprintk if (debug) printk
1371     +
1372     +#define LOGHEAD "lirc_dev (%s[%d]): "
1373     +
1374     +struct irctl
1375     +{
1376     + struct lirc_plugin p;
1377     + int open;
1378     +
1379     + struct lirc_buffer *buf;
1380     +
1381     + int t_pid;
1382     +
1383     + struct semaphore *t_notify;
1384     + struct semaphore *t_notify2;
1385     + int shutdown;
1386     + long jiffies_to_wait;
1387     +};
1388     +
1389     +DECLARE_MUTEX(plugin_lock);
1390     +
1391     +static struct irctl irctls[CONFIG_LIRC_MAX_DEV];
1392     +static struct file_operations fops;
1393     +
1394     +
1395     +/* helper function
1396     + * initializes the irctl structure
1397     + */
1398     +static inline void init_irctl(struct irctl *ir)
1399     +{
1400     + memset(&ir->p, 0, sizeof(struct lirc_plugin));
1401     + ir->p.minor = NOPLUG;
1402     +
1403     + ir->t_pid = -1;
1404     + ir->t_notify = NULL;
1405     + ir->t_notify2 = NULL;
1406     + ir->shutdown = 0;
1407     +
1408     + ir->jiffies_to_wait = 0;
1409     +
1410     + ir->open = 0;
1411     +}
1412     +
1413     +
1414     +/* helper function
1415     + * reads key codes from plugin and puts them into buffer
1416     + * buffer free space is checked and locking performed
1417     + * returns 0 on success
1418     + */
1419     +
1420     +inline static int add_to_buf(struct irctl *ir)
1421     +{
1422     + unsigned char buf[BUFLEN];
1423     + unsigned int i;
1424     +
1425     + if (lirc_buffer_full(ir->buf)) {
1426     + dprintk(LOGHEAD "buffer overflow\n",
1427     + ir->p.name, ir->p.minor);
1428     + return -EOVERFLOW;
1429     + }
1430     +
1431     + for (i=0; i < ir->buf->chunk_size; i++) {
1432     + if (ir->p.get_key(ir->p.data, &buf[i], i)) {
1433     + return -ENODATA;
1434     + }
1435     + dprintk(LOGHEAD "remote code (0x%x) now in buffer\n",
1436     + ir->p.name, ir->p.minor, buf[i]);
1437     + }
1438     +
1439     + /* here is the only point at which we add key codes to the buffer */
1440     + lirc_buffer_write_1(ir->buf, buf);
1441     +
1442     + return SUCCESS;
1443     +}
1444     +
1445     +/* main function of the polling thread
1446     + */
1447     +static int lirc_thread(void *irctl)
1448     +{
1449     + struct irctl *ir = irctl;
1450     +
1451     + daemonize("lirc_dev");
1452     +
1453     + if (ir->t_notify != NULL) {
1454     + up(ir->t_notify);
1455     + }
1456     +
1457     + dprintk(LOGHEAD "poll thread started\n", ir->p.name, ir->p.minor);
1458     +
1459     + do {
1460     + if (ir->open) {
1461     + if (ir->jiffies_to_wait) {
1462     + current->state = TASK_INTERRUPTIBLE;
1463     + schedule_timeout(ir->jiffies_to_wait);
1464     + } else {
1465     + interruptible_sleep_on(ir->p.get_queue(ir->p.data));
1466     + }
1467     + if (ir->shutdown) {
1468     + break;
1469     + }
1470     + if (!add_to_buf(ir)) {
1471     + wake_up_interruptible(&ir->buf->wait_poll);
1472     + }
1473     + } else {
1474     + /* if device not opened so we can sleep half a second */
1475     + current->state = TASK_INTERRUPTIBLE;
1476     + schedule_timeout(HZ/2);
1477     + }
1478     + } while (!ir->shutdown);
1479     +
1480     + dprintk(LOGHEAD "poll thread ended\n", ir->p.name, ir->p.minor);
1481     +
1482     + if (ir->t_notify2 != NULL) {
1483     + down(ir->t_notify2);
1484     + }
1485     +
1486     + ir->t_pid = -1;
1487     +
1488     + if (ir->t_notify != NULL) {
1489     + up(ir->t_notify);
1490     + }
1491     +
1492     + return 0;
1493     +}
1494     +
1495     +/*
1496     + *
1497     + */
1498     +int lirc_register_plugin(struct lirc_plugin *p)
1499     +{
1500     + struct irctl *ir;
1501     + int minor;
1502     + int bytes_in_key;
1503     + DECLARE_MUTEX_LOCKED(tn);
1504     +
1505     + if (!p) {
1506     + printk("lirc_dev: lirc_register_plugin:"
1507     + "plugin pointer must be not NULL!\n");
1508     + return -EBADRQC;
1509     + }
1510     +
1511     + if (CONFIG_LIRC_MAX_DEV <= p->minor) {
1512     + printk("lirc_dev: lirc_register_plugin:"
1513     + "\" minor\" must be beetween 0 and %d (%d)!\n",
1514     + CONFIG_LIRC_MAX_DEV-1, p->minor);
1515     + return -EBADRQC;
1516     + }
1517     +
1518     + if (1 > p->code_length || (BUFLEN*8) < p->code_length) {
1519     + printk("lirc_dev: lirc_register_plugin:"
1520     + "code length in bits for minor (%d) "
1521     + "must be less than %d!\n",
1522     + p->minor, BUFLEN*8);
1523     + return -EBADRQC;
1524     + }
1525     +
1526     + printk("lirc_dev: lirc_register_plugin:"
1527     + "sample_rate: %d\n",p->sample_rate);
1528     + if (p->sample_rate) {
1529     + if (2 > p->sample_rate || 50 < p->sample_rate) {
1530     + printk("lirc_dev: lirc_register_plugin:"
1531     + "sample_rate must be beetween 2 and 50!\n");
1532     + return -EBADRQC;
1533     + }
1534     + } else if (!(p->fops && p->fops->read)
1535     + && !p->get_queue && !p->rbuf) {
1536     + printk("lirc_dev: lirc_register_plugin:"
1537     + "fops->read, get_queue and rbuf cannot all be NULL!\n");
1538     + return -EBADRQC;
1539     + } else if (!p->get_queue && !p->rbuf) {
1540     + if (!(p->fops && p->fops->read && p->fops->poll)
1541     + || (!p->fops->ioctl && !p->ioctl)) {
1542     + printk("lirc_dev: lirc_register_plugin:"
1543     + "neither read, poll nor ioctl can be NULL!\n");
1544     + return -EBADRQC;
1545     + }
1546     + }
1547     +
1548     + down_interruptible(&plugin_lock);
1549     +
1550     + minor = p->minor;
1551     +
1552     + if (0 > minor) {
1553     + /* find first free slot for plugin */
1554     + for (minor=0; minor<CONFIG_LIRC_MAX_DEV; minor++)
1555     + if (irctls[minor].p.minor == NOPLUG)
1556     + break;
1557     + if (CONFIG_LIRC_MAX_DEV == minor) {
1558     + printk("lirc_dev: lirc_register_plugin: "
1559     + "no free slots for plugins!\n");
1560     + up(&plugin_lock);
1561     + return -ENOMEM;
1562     + }
1563     + } else if (irctls[minor].p.minor != NOPLUG) {
1564     + printk("lirc_dev: lirc_register_plugin:"
1565     + "minor (%d) just registerd!\n", minor);
1566     + up(&plugin_lock);
1567     + return -EBUSY;
1568     + }
1569     +
1570     + ir = &irctls[minor];
1571     +
1572     + if (p->sample_rate) {
1573     + ir->jiffies_to_wait = HZ / p->sample_rate;
1574     + } else {
1575     + /* it means - wait for externeal event in task queue */
1576     + ir->jiffies_to_wait = 0;
1577     + }
1578     +
1579     + /* some safety check 8-) */
1580     + p->name[sizeof(p->name)-1] = '\0';
1581     +
1582     + bytes_in_key = p->code_length/8 + (p->code_length%8 ? 1 : 0);
1583     +
1584     + if (p->rbuf) {
1585     + ir->buf = p->rbuf;
1586     + } else {
1587     + ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
1588     + lirc_buffer_init(ir->buf, bytes_in_key, BUFLEN/bytes_in_key);
1589     + }
1590     +
1591     + if (p->features==0)
1592     + p->features = (p->code_length > 8) ?
1593     + LIRC_CAN_REC_LIRCCODE : LIRC_CAN_REC_CODE;
1594     +
1595     + ir->p = *p;
1596     + ir->p.minor = minor;
1597     +
1598     +#ifdef CONFIG_DEVFS_FS
1599     + devfs_mk_cdev(MKDEV(IRCTL_DEV_MAJOR, ir->p.minor), S_IFCHR | S_IRUSR | S_IWUSR, "lirc/lirc%d", ir->p.minor);
1600     +#endif
1601     +
1602     + if(p->sample_rate || p->get_queue) {
1603     + /* try to fire up polling thread */
1604     + ir->t_notify = &tn;
1605     + ir->t_pid = kernel_thread(lirc_thread, (void*)ir, 0);
1606     + if (ir->t_pid < 0) {
1607     + up(&plugin_lock);
1608     + printk("lirc_dev: lirc_register_plugin:"
1609     + "cannot run poll thread for minor = %d\n",
1610     + p->minor);
1611     + return -ECHILD;
1612     + }
1613     + down(&tn);
1614     + ir->t_notify = NULL;
1615     + }
1616     + up(&plugin_lock);
1617     +
1618     + try_module_get(THIS_MODULE);
1619     +
1620     + dprintk("lirc_dev: plugin %s registered at minor number = %d\n",
1621     + ir->p.name, ir->p.minor);
1622     +
1623     + return minor;
1624     +}
1625     +
1626     +/*
1627     + *
1628     + */
1629     +int lirc_unregister_plugin(int minor)
1630     +{
1631     + struct irctl *ir;
1632     + DECLARE_MUTEX_LOCKED(tn);
1633     + DECLARE_MUTEX_LOCKED(tn2);
1634     +
1635     + if (minor < 0 || minor >= CONFIG_LIRC_MAX_DEV) {
1636     + printk("lirc_dev: lirc_unregister_plugin:"
1637     + "\" minor\" must be beetween 0 and %d!\n",
1638     + CONFIG_LIRC_MAX_DEV-1);
1639     + return -EBADRQC;
1640     + }
1641     +
1642     + ir = &irctls[minor];
1643     +
1644     + down_interruptible(&plugin_lock);
1645     +
1646     + if (ir->p.minor != minor) {
1647     + printk("lirc_dev: lirc_unregister_plugin:"
1648     + "minor (%d) device not registered!", minor);
1649     + up(&plugin_lock);
1650     + return -ENOENT;
1651     + }
1652     +
1653     + if (ir->open) {
1654     + printk("lirc_dev: lirc_unregister_plugin:"
1655     + "plugin %s[%d] in use!", ir->p.name, ir->p.minor);
1656     + up(&plugin_lock);
1657     + return -EBUSY;
1658     + }
1659     +
1660     + /* end up polling thread */
1661     + if (ir->t_pid >= 0) {
1662     + ir->t_notify = &tn;
1663     + ir->t_notify2 = &tn2;
1664     + ir->shutdown = 1;
1665     + {
1666     + struct task_struct *p;
1667     +
1668     + p = find_task_by_pid(ir->t_pid);
1669     + wake_up_process(p);
1670     + }
1671     + up(&tn2);
1672     + down(&tn);
1673     + ir->t_notify = NULL;
1674     + ir->t_notify2 = NULL;
1675     + }
1676     +
1677     + dprintk("lirc_dev: plugin %s unregistered from minor number = %d\n",
1678     + ir->p.name, ir->p.minor);
1679     +
1680     +#ifdef CONFIG_DEVFS_FS
1681     + devfs_remove("lirc/lirc%d", ir->p.minor);
1682     +#endif
1683     +
1684     + if (ir->buf != ir->p.rbuf){
1685     + lirc_buffer_free(ir->buf);
1686     + kfree(ir->buf);
1687     + }
1688     + ir->buf = NULL;
1689     + init_irctl(ir);
1690     + up(&plugin_lock);
1691     +
1692     + module_put(THIS_MODULE);
1693     +
1694     + return SUCCESS;
1695     +}
1696     +
1697     +/*
1698     + *
1699     + */
1700     +static int irctl_open(struct inode *inode, struct file *file)
1701     +{
1702     + struct irctl *ir;
1703     + int retval;
1704     +
1705     + if (MINOR(inode->i_rdev) >= CONFIG_LIRC_MAX_DEV) {
1706     + dprintk("lirc_dev [%d]: open result = -ENODEV\n",
1707     + MINOR(inode->i_rdev));
1708     + return -ENODEV;
1709     + }
1710     +
1711     + ir = &irctls[MINOR(inode->i_rdev)];
1712     +
1713     + dprintk(LOGHEAD "open called\n", ir->p.name, ir->p.minor);
1714     +
1715     + /* if the plugin has an open function use it instead */
1716     + if(ir->p.fops && ir->p.fops->open)
1717     + return ir->p.fops->open(inode, file);
1718     +
1719     + down_interruptible(&plugin_lock);
1720     +
1721     + if (ir->p.minor == NOPLUG) {
1722     + up(&plugin_lock);
1723     + dprintk(LOGHEAD "open result = -ENODEV\n",
1724     + ir->p.name, ir->p.minor);
1725     + return -ENODEV;
1726     + }
1727     +
1728     + if (ir->open) {
1729     + up(&plugin_lock);
1730     + dprintk(LOGHEAD "open result = -EBUSY\n",
1731     + ir->p.name, ir->p.minor);
1732     + return -EBUSY;
1733     + }
1734     +
1735     + /* there is no need for locking here because ir->open is 0
1736     + * and lirc_thread isn't using buffer
1737     + * plugins which use irq's should allocate them on set_use_inc,
1738     + * so there should be no problem with those either.
1739     + */
1740     + ir->buf->head = ir->buf->tail;
1741     + ir->buf->fill = 0;
1742     +
1743     + ++ir->open;
1744     + retval = ir->p.set_use_inc(ir->p.data);
1745     +
1746     + up(&plugin_lock);
1747     +
1748     + if (retval != SUCCESS) {
1749     + --ir->open;
1750     + return retval;
1751     + }
1752     +
1753     + dprintk(LOGHEAD "open result = %d\n", ir->p.name, ir->p.minor, SUCCESS);
1754     +
1755     + return SUCCESS;
1756     +}
1757     +
1758     +/*
1759     + *
1760     + */
1761     +static int irctl_close(struct inode *inode, struct file *file)
1762     +{
1763     + struct irctl *ir = &irctls[MINOR(inode->i_rdev)];
1764     +
1765     + dprintk(LOGHEAD "close called\n", ir->p.name, ir->p.minor);
1766     +
1767     + /* if the plugin has a close function use it instead */
1768     + if(ir->p.fops && ir->p.fops->release)
1769     + return ir->p.fops->release(inode, file);
1770     +
1771     + down_interruptible(&plugin_lock);
1772     +
1773     + --ir->open;
1774     + ir->p.set_use_dec(ir->p.data);
1775     +
1776     + up(&plugin_lock);
1777     +
1778     + return SUCCESS;
1779     +}
1780     +
1781     +/*
1782     + *
1783     + */
1784     +static unsigned int irctl_poll(struct file *file, poll_table *wait)
1785     +{
1786     + struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)];
1787     +
1788     + dprintk(LOGHEAD "poll called\n", ir->p.name, ir->p.minor);
1789     +
1790     + /* if the plugin has a poll function use it instead */
1791     + if(ir->p.fops && ir->p.fops->poll)
1792     + return ir->p.fops->poll(file, wait);
1793     +
1794     + poll_wait(file, &ir->buf->wait_poll, wait);
1795     +
1796     + dprintk(LOGHEAD "poll result = %s\n",
1797     + ir->p.name, ir->p.minor,
1798     + lirc_buffer_empty(ir->buf) ? "0" : "POLLIN|POLLRDNORM");
1799     +
1800     + return lirc_buffer_empty(ir->buf) ? 0 : (POLLIN|POLLRDNORM);
1801     +}
1802     +
1803     +/*
1804     + *
1805     + */
1806     +static int irctl_ioctl(struct inode *inode, struct file *file,
1807     + unsigned int cmd, unsigned long arg)
1808     +{
1809     + unsigned long mode;
1810     + int result;
1811     + struct irctl *ir = &irctls[MINOR(inode->i_rdev)];
1812     +
1813     + dprintk(LOGHEAD "ioctl called (%u)\n",
1814     + ir->p.name, ir->p.minor, cmd);
1815     +
1816     + /* if the plugin has a ioctl function use it instead */
1817     + if(ir->p.fops && ir->p.fops->ioctl)
1818     + return ir->p.fops->ioctl(inode, file, cmd, arg);
1819     +
1820     + if (ir->p.minor == NOPLUG) {
1821     + dprintk(LOGHEAD "ioctl result = -ENODEV\n",
1822     + ir->p.name, ir->p.minor);
1823     + return -ENODEV;
1824     + }
1825     +
1826     + /* Give the plugin a chance to handle the ioctl */
1827     + if(ir->p.ioctl){
1828     + result = ir->p.ioctl(inode, file, cmd, arg);
1829     + if (result != -ENOIOCTLCMD)
1830     + return result;
1831     + }
1832     + /* The plugin can't handle cmd */
1833     + result = SUCCESS;
1834     +
1835     + switch(cmd)
1836     + {
1837     + case LIRC_GET_FEATURES:
1838     + result = put_user(ir->p.features, (unsigned long*)arg);
1839     + break;
1840     + case LIRC_GET_REC_MODE:
1841     + if(!(ir->p.features&LIRC_CAN_REC_MASK))
1842     + return(-ENOSYS);
1843     +
1844     + result = put_user(LIRC_REC2MODE
1845     + (ir->p.features&LIRC_CAN_REC_MASK),
1846     + (unsigned long*)arg);
1847     + break;
1848     + case LIRC_SET_REC_MODE:
1849     + if(!(ir->p.features&LIRC_CAN_REC_MASK))
1850     + return(-ENOSYS);
1851     +
1852     + result = get_user(mode, (unsigned long*)arg);
1853     + if(!result && !(LIRC_MODE2REC(mode) & ir->p.features)) {
1854     + result = -EINVAL;
1855     + }
1856     + /* FIXME: We should actually set the mode somehow
1857     + * but for now, lirc_serial doesn't support mode changin
1858     + * eighter */
1859     + break;
1860     + case LIRC_GET_LENGTH:
1861     + result = put_user((unsigned long)ir->p.code_length,
1862     + (unsigned long *)arg);
1863     + break;
1864     + default:
1865     + result = -ENOIOCTLCMD;
1866     + }
1867     +
1868     + dprintk(LOGHEAD "ioctl result = %d\n",
1869     + ir->p.name, ir->p.minor, result);
1870     +
1871     + return result;
1872     +}
1873     +
1874     +/*
1875     + *
1876     + */
1877     +static ssize_t irctl_read(struct file *file,
1878     + char *buffer,
1879     + size_t length,
1880     + loff_t *ppos)
1881     +{
1882     + struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)];
1883     + unsigned char buf[ir->buf->chunk_size];
1884     + int ret=0, written=0;
1885     + DECLARE_WAITQUEUE(wait, current);
1886     +
1887     + dprintk(LOGHEAD "read called\n", ir->p.name, ir->p.minor);
1888     +
1889     + /* if the plugin has a specific read function use it instead */
1890     + if(ir->p.fops && ir->p.fops->read)
1891     + return ir->p.fops->read(file, buffer, length, ppos);
1892     +
1893     + if (length % ir->buf->chunk_size) {
1894     + dprintk(LOGHEAD "read result = -EINVAL\n",
1895     + ir->p.name, ir->p.minor);
1896     + return -EINVAL;
1897     + }
1898     +
1899     + /* we add ourselves to the task queue before buffer check
1900     + * to avoid losing scan code (in case when queue is awaken somewhere
1901     + * beetwen while condition checking and scheduling)
1902     + */
1903     + add_wait_queue(&ir->buf->wait_poll, &wait);
1904     + current->state = TASK_INTERRUPTIBLE;
1905     +
1906     + /* while we did't provide 'length' bytes, device is opened in blocking
1907     + * mode and 'copy_to_user' is happy, wait for data.
1908     + */
1909     + while (written < length && ret == 0) {
1910     + if (lirc_buffer_empty(ir->buf)) {
1911     + /* According to the read(2) man page, 'written' can be
1912     + * returned as less than 'length', instead of blocking
1913     + * again, returning -EWOULDBLOCK, or returning
1914     + * -ERESTARTSYS */
1915     + if (written) break;
1916     + if (file->f_flags & O_NONBLOCK) {
1917     + dprintk(LOGHEAD "read result = -EWOULDBLOCK\n",
1918     + ir->p.name, ir->p.minor);
1919     + remove_wait_queue(&ir->buf->wait_poll, &wait);
1920     + current->state = TASK_RUNNING;
1921     + return -EWOULDBLOCK;
1922     + }
1923     + if (signal_pending(current)) {
1924     + dprintk(LOGHEAD "read result = -ERESTARTSYS\n",
1925     + ir->p.name, ir->p.minor);
1926     + remove_wait_queue(&ir->buf->wait_poll, &wait);
1927     + current->state = TASK_RUNNING;
1928     + return -ERESTARTSYS;
1929     + }
1930     + schedule();
1931     + current->state = TASK_INTERRUPTIBLE;
1932     + } else {
1933     + lirc_buffer_read_1(ir->buf, buf);
1934     + ret = copy_to_user((void *)buffer+written, buf,
1935     + ir->buf->chunk_size);
1936     + written += ir->buf->chunk_size;
1937     + }
1938     + }
1939     +
1940     + remove_wait_queue(&ir->buf->wait_poll, &wait);
1941     + current->state = TASK_RUNNING;
1942     +
1943     + dprintk(LOGHEAD "read result = %s (%d)\n",
1944     + ir->p.name, ir->p.minor, ret ? "-EFAULT" : "OK", ret);
1945     +
1946     + return ret ? -EFAULT : written;
1947     +}
1948     +
1949     +static ssize_t irctl_write(struct file *file, const char *buffer,
1950     + size_t length, loff_t * ppos)
1951     +{
1952     + struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)];
1953     +
1954     + dprintk(LOGHEAD "write called\n", ir->p.name, ir->p.minor);
1955     +
1956     + /* if the plugin has a specific read function use it instead */
1957     + if(ir->p.fops && ir->p.fops->write)
1958     + return ir->p.fops->write(file, buffer, length, ppos);
1959     +
1960     + return -EINVAL;
1961     +}
1962     +
1963     +
1964     +static struct file_operations fops = {
1965     + read: irctl_read,
1966     + write: irctl_write,
1967     + poll: irctl_poll,
1968     + ioctl: irctl_ioctl,
1969     + open: irctl_open,
1970     + release: irctl_close
1971     +};
1972     +
1973     +static int __init lirc_dev_init(void)
1974     +{
1975     + int i;
1976     +
1977     + for (i=0; i < CONFIG_LIRC_MAX_DEV; ++i) {
1978     + init_irctl(&irctls[i]);
1979     + }
1980     +
1981     + i = register_chrdev(IRCTL_DEV_MAJOR,
1982     + IRCTL_DEV_NAME,
1983     + &fops);
1984     +
1985     + if (i < 0) {
1986     + printk ("lirc_dev: device registration failed with %d\n", i);
1987     + return i;
1988     + }
1989     +
1990     + printk("lirc_dev: IR Remote Control driver registered, at major %d \n",
1991     + IRCTL_DEV_MAJOR);
1992     +
1993     + return SUCCESS;
1994     +}
1995     +
1996     +static void __exit lirc_dev_exit(void)
1997     +{
1998     + int ret;
1999     +
2000     + ret = unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME);
2001     +
2002     + if (0 > ret){
2003     + printk("lirc_dev: error in module_unregister_chrdev: %d\n",
2004     + ret);
2005     + } else {
2006     + dprintk("lirc_dev: module successfully unloaded\n");
2007     + }
2008     +}
2009     +
2010     +/* ---------------------------------------------------------------------- */
2011     +
2012     +/* For now dont try to use it as a static version ! */
2013     +
2014     +MODULE_DESCRIPTION("LIRC base driver module");
2015     +MODULE_AUTHOR("Artur Lipowski");
2016     +MODULE_LICENSE("GPL");
2017     +
2018     +EXPORT_SYMBOL(lirc_register_plugin);
2019     +EXPORT_SYMBOL(lirc_unregister_plugin);
2020     +
2021     +module_init(lirc_dev_init);
2022     +module_exit(lirc_dev_exit);
2023     +
2024     +/*
2025     + * Overrides for Emacs so that we follow Linus's tabbing style.
2026     + * ---------------------------------------------------------------------------
2027     + * Local variables:
2028     + * c-basic-offset: 8
2029     + * End:
2030     + */
2031     diff -NPaur linux-2.6.2/drivers/char/lirc/lirc_dev.h linux-2.6.2-lirc/drivers/char/lirc/lirc_dev.h
2032     --- linux-2.6.2/drivers/char/lirc/lirc_dev.h 1970-01-01 01:00:00.000000000 +0100
2033     +++ linux-2.6.2-lirc/drivers/char/lirc/lirc_dev.h 2004-02-09 20:03:15.050333232 +0100
2034     @@ -0,0 +1,206 @@
2035     +/*
2036     + * LIRC base driver
2037     + *
2038     + * (L) by Artur Lipowski <alipowski@interia.pl>
2039     + * This code is licensed under GNU GPL
2040     + *
2041     + * $Id: 405_lirc_infrared-2.6.2-02092004.patch,v 1.1 2004/02/24 22:27:37 brad_mssw Exp $
2042     + *
2043     + */
2044     +
2045     +#ifndef _LINUX_LIRC_DEV_H
2046     +#define _LINUX_LIRC_DEV_H
2047     +
2048     +#define BUFLEN 16
2049     +
2050     +//#define LIRC_BUFF_POWER_OF_2
2051     +#ifdef LIRC_BUFF_POWER_OF_2
2052     +#define mod(n, div) ((n) & ((div) -1))
2053     +#else
2054     +#define mod(n, div) ((n) % (div))
2055     +#endif
2056     +#include <linux/slab.h>
2057     +#include <linux/fs.h>
2058     +struct lirc_buffer
2059     +{
2060     + wait_queue_head_t wait_poll;
2061     + spinlock_t lock;
2062     +
2063     + unsigned char *data;
2064     + unsigned int chunk_size;
2065     + unsigned int size; /* in chunks */
2066     + unsigned int fill; /* in chunks */
2067     + int head, tail; /* in chunks */
2068     + /* Using chunks instead of bytes pretends to simplify boundary checking
2069     + * And should allow for some performance fine tunning later */
2070     +};
2071     +static inline int lirc_buffer_init(struct lirc_buffer *buf,
2072     + unsigned int chunk_size,
2073     + unsigned int size)
2074     +{
2075     + /* Adjusting size to the next power of 2 would allow for
2076     + * inconditional LIRC_BUFF_POWER_OF_2 optimization */
2077     + init_waitqueue_head(&buf->wait_poll);
2078     + spin_lock_init(&buf->lock);
2079     + buf->head = buf->tail = buf->fill = 0;
2080     + buf->chunk_size = chunk_size;
2081     + buf->size = size;
2082     + buf->data = kmalloc(size*chunk_size, GFP_KERNEL);
2083     + if (buf->data == NULL)
2084     + return -1;
2085     + memset(buf->data, 0, size*chunk_size);
2086     + return 0;
2087     +}
2088     +static inline void lirc_buffer_free(struct lirc_buffer *buf)
2089     +{
2090     + kfree(buf->data);
2091     + buf->data = NULL;
2092     + buf->head = buf->tail = buf->fill = 0;
2093     + buf->chunk_size = 0;
2094     + buf->size = 0;
2095     +}
2096     +static inline int lirc_buffer_full(struct lirc_buffer *buf)
2097     +{
2098     + return (buf->fill >= buf->size);
2099     +}
2100     +static inline int lirc_buffer_empty(struct lirc_buffer *buf)
2101     +{
2102     + return !(buf->fill);
2103     +}
2104     +extern inline void lirc_buffer_lock(struct lirc_buffer *buf, unsigned long *flags)
2105     +{
2106     + spin_lock_irqsave(&buf->lock, *flags);
2107     +}
2108     +extern inline void lirc_buffer_unlock(struct lirc_buffer *buf, unsigned long *flags)
2109     +{
2110     + spin_unlock_irqrestore(&buf->lock, *flags);
2111     +}
2112     +static inline void _lirc_buffer_remove_1(struct lirc_buffer *buf)
2113     +{
2114     + buf->head = mod(buf->head+1, buf->size);
2115     + buf->fill -= 1;
2116     +}
2117     +static inline void lirc_buffer_remove_1(struct lirc_buffer *buf)
2118     +{
2119     + unsigned long flags;
2120     + lirc_buffer_lock(buf, &flags);
2121     + _lirc_buffer_remove_1(buf);
2122     + lirc_buffer_unlock(buf, &flags);
2123     +}
2124     +static inline void _lirc_buffer_read_1(struct lirc_buffer *buf,
2125     + unsigned char *dest)
2126     +{
2127     + memcpy(dest, &buf->data[buf->head*buf->chunk_size], buf->chunk_size);
2128     + buf->head = mod(buf->head+1, buf->size);
2129     + buf->fill -= 1;
2130     +}
2131     +static inline void lirc_buffer_read_1(struct lirc_buffer *buf,
2132     + unsigned char *dest)
2133     +{
2134     + unsigned long flags;
2135     + lirc_buffer_lock(buf, &flags);
2136     + _lirc_buffer_read_1(buf, dest);
2137     + lirc_buffer_unlock(buf, &flags);
2138     +}
2139     +static inline void _lirc_buffer_write_1(struct lirc_buffer *buf,
2140     + unsigned char *orig)
2141     +{
2142     + memcpy(&buf->data[buf->tail*buf->chunk_size], orig, buf->chunk_size);
2143     + buf->tail = mod(buf->tail+1, buf->size);
2144     + buf->fill++;
2145     +}
2146     +static inline void lirc_buffer_write_1(struct lirc_buffer *buf,
2147     + unsigned char *orig)
2148     +{
2149     + unsigned long flags;
2150     + lirc_buffer_lock(buf, &flags);
2151     + _lirc_buffer_write_1(buf, orig);
2152     + lirc_buffer_unlock(buf, &flags);
2153     +}
2154     +
2155     +struct lirc_plugin
2156     +{
2157     + char name[40];
2158     + int minor;
2159     + int code_length;
2160     + int sample_rate;
2161     + unsigned long features;
2162     + void* data;
2163     + int (*get_key) (void* data, unsigned char* key, int key_no);
2164     + wait_queue_head_t* (*get_queue) (void* data);
2165     + struct lirc_buffer *rbuf;
2166     + int (*set_use_inc) (void* data);
2167     + void (*set_use_dec) (void* data);
2168     + int (*ioctl) (struct inode *,struct file *,unsigned int, unsigned long);
2169     + struct file_operations *fops;
2170     +};
2171     +/* name:
2172     + * this string will be used for logs
2173     + *
2174     + * minor:
2175     + * indicates minor device (/dev/lircd) number for registered plugin
2176     + * if caller fills it with negative value, then the first free minor
2177     + * number will be used (if available)
2178     + *
2179     + * code_length:
2180     + * length ofthe remote control key code expressed in bits
2181     + * if code_length > 8 then many bytes are returned through the device read
2182     + * in such situation get_key should return key code values starting
2183     + * from most significant byte (device read will preseve this order)
2184     + * in addition if code_length > 8 then get_key will be called
2185     + * several (ceil(code_length/8)) times in one pool pass (or after task queue
2186     + * awake) key_no parameter denotes number of the requested byte (0 means first
2187     + * byte)
2188     + *
2189     + * sample_rate:
2190     + * sample_rate equal to 0 means that no pooling will be performed and get_key
2191     + * will be triggered by external events (through task queue returned by
2192     + * get_queue)
2193     + *
2194     + * data:
2195     + * it may point to any plugin data and this pointer will be passed to all
2196     + * callback functions
2197     + *
2198     + * get_key:
2199     + * get_key will be called after specified period of the time or triggered by the
2200     + * external event, this behavior depends on value of the sample_rate
2201     + * this function will be called in user context
2202     + *
2203     + * get_queue:
2204     + * this callback should return a pointer to the task queue which will be used
2205     + * for external event waiting
2206     + *
2207     + * rbuf:
2208     + * if not NULL, it will be used as a read buffer, you will have to write to
2209     + * the buffer by other means, like irq's (see also lirc_serial.c).
2210     + *
2211     + * set_use_inc:
2212     + * set_use_inc will be called after device is opened
2213     + *
2214     + * set_use_dec:
2215     + * set_use_dec will be called after device is closed
2216     + *
2217     + * ioctl:
2218     + * Some ioctl's can be directly handled by lirc_dev but will be forwared here
2219     + * if not NULL and only handled if it returns -ENOIOCTLCMD (see also
2220     + * lirc_serial.c).
2221     + *
2222     + * fops:
2223     + * file_operations for drivers which don't fit the current plugin model.
2224     + */
2225     +
2226     +
2227     +/* following functions can be called ONLY from user context
2228     + *
2229     + * returns negative value on error or minor number
2230     + * of the registered device if success
2231     + * contens of the structure pointed by p is copied
2232     + */
2233     +extern int lirc_register_plugin(struct lirc_plugin *p);
2234     +
2235     +/* returns negative value on error or 0 if success
2236     +*/
2237     +extern int lirc_unregister_plugin(int minor);
2238     +
2239     +
2240     +#endif
2241     diff -NPaur linux-2.6.2/drivers/char/lirc/lirc_gpio.c linux-2.6.2-lirc/drivers/char/lirc/lirc_gpio.c
2242     --- linux-2.6.2/drivers/char/lirc/lirc_gpio.c 1970-01-01 01:00:00.000000000 +0100
2243     +++ linux-2.6.2-lirc/drivers/char/lirc/lirc_gpio.c 2004-02-09 20:03:15.053332776 +0100
2244     @@ -0,0 +1,550 @@
2245     +/*
2246     + * Remote control driver for the TV-card
2247     + * key codes are obtained from GPIO port
2248     + *
2249     + * (L) by Artur Lipowski <alipowski@interia.pl>
2250     + * patch for the AverMedia by Santiago Garcia Mantinan <manty@i.am>
2251     + * and Christoph Bartelmus <lirc@bartelmus.de>
2252     + * patch for the BestBuy by Miguel Angel Alvarez <maacruz@navegalia.com>
2253     + * patch for the Winfast TV2000 by Juan Toledo
2254     + * <toledo@users.sourceforge.net>
2255     + * patch for the I-O Data GV-BCTV5/PCI by Jens C. Rasmussen
2256     + * <jens.rasmussen@ieee.org>
2257     + *
2258     + * This program is free software; you can redistribute it and/or modify
2259     + * it under the terms of the GNU General Public License as published by
2260     + * the Free Software Foundation; either version 2 of the License, or
2261     + * (at your option) any later version.
2262     + *
2263     + * This program is distributed in the hope that it will be useful,
2264     + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2265     + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2266     + * GNU General Public License for more details.
2267     + *
2268     + * You should have received a copy of the GNU General Public License
2269     + * along with this program; if not, write to the Free Software
2270     + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2271     + *
2272     + * $Id: 405_lirc_infrared-2.6.2-02092004.patch,v 1.1 2004/02/24 22:27:37 brad_mssw Exp $
2273     + *
2274     + */
2275     +
2276     +#include <linux/version.h>
2277     +
2278     +#include <linux/module.h>
2279     +#include <linux/kmod.h>
2280     +#include <linux/sched.h>
2281     +#include <linux/errno.h>
2282     +#include <linux/init.h>
2283     +#include <linux/moduleparam.h>
2284     +
2285     +#include "../../media/video/bttv.h"
2286     +#include "../../media/video/bttvp.h"
2287     +
2288     +#include "lirc_dev.h"
2289     +
2290     +static int debug = 0;
2291     +static int card = 0;
2292     +static int minor = -1;
2293     +static int bttv_id = BTTV_UNKNOWN;
2294     +static unsigned long gpio_mask = 0;
2295     +static unsigned long gpio_enable = 0;
2296     +static unsigned long gpio_lock_mask = 0;
2297     +static unsigned long gpio_xor_mask = 0;
2298     +static unsigned int soft_gap = 0;
2299     +static unsigned char sample_rate = 10;
2300     +
2301     +MODULE_PARM(debug,"i");
2302     +MODULE_PARM(card,"i");
2303     +MODULE_PARM(minor,"i");
2304     +MODULE_PARM(gpio_mask,"l");
2305     +MODULE_PARM(gpio_lock_mask,"l");
2306     +MODULE_PARM(gpio_xor_mask,"l");
2307     +MODULE_PARM(soft_gap,"i");
2308     +MODULE_PARM(sample_rate,"b");
2309     +MODULE_PARM(bttv_id,"i");
2310     +
2311     +#undef dprintk
2312     +#define dprintk if (debug) printk
2313     +
2314     +struct rcv_info {
2315     + int bttv_id;
2316     + int card_id;
2317     + unsigned long gpio_mask;
2318     + unsigned long gpio_enable;
2319     + unsigned long gpio_lock_mask;
2320     + unsigned long gpio_xor_mask;
2321     + unsigned int soft_gap;
2322     + unsigned char sample_rate;
2323     + unsigned char code_length;
2324     +};
2325     +
2326     +static struct rcv_info rcv_infos[] = {
2327     + {BTTV_UNKNOWN, 0, 0, 0, 0, 0, 0, 1, 0},
2328     + {BTTV_PXELVWPLTVPAK, 0, 0x00003e00, 0, 0x0010000, 0, 0, 15, 32},
2329     + {BTTV_PXELVWPLTVPRO, 0, 0x00001f00, 0, 0x0008000, 0, 500, 12, 32},
2330     + {BTTV_PV_BT878P_9B, 0, 0x00001f00, 0, 0x0008000, 0, 500, 12, 32},
2331     + {BTTV_PV_BT878P_PLUS, 0, 0x00001f00, 0, 0x0008000, 0, 500, 12, 32},
2332     + {BTTV_AVERMEDIA, 0, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32},
2333     + {BTTV_AVPHONE98, 0x00011461, 0x003b8000, 0x00004000, 0x0800000, 0x00800000, 0, 10, 0}, /*mapped to Capture98*/
2334     + {BTTV_AVERMEDIA98, 0x00021461, 0x003b8000, 0x00004000, 0x0800000, 0x00800000, 0, 10, 0}, /*mapped to Capture98*/
2335     + {BTTV_AVPHONE98, 0x00031461, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, /*mapped to Phone98*/
2336     + /* is this one correct? */
2337     + {BTTV_AVERMEDIA98, 0x00041461, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, /*mapped to Phone98*/
2338     + /* work-around for VDOMATE */
2339     + {BTTV_AVERMEDIA98, 0x03001461, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, /*mapped to Phone98*/
2340     + /* reported by Danijel Korzinek, AVerTV GOw/FM */
2341     + {BTTV_AVERMEDIA98, 0x00000000, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, /*mapped to Phone98*/
2342     + {BTTV_CHRONOS_VS2, 0, 0x000000f8, 0, 0x0000100, 0, 0, 20, 0},
2343     + /* CPH031 and CPH033 cards (?) */
2344     + /* MIRO was just a work-around */
2345     + {BTTV_MIRO, 0, 0x00001f00, 0, 0x0004000, 0, 0, 10, 32},
2346     + {BTTV_DYNALINK, 0, 0x00001f00, 0, 0x0004000, 0, 0, 10, 32},
2347     + {BTTV_WINVIEW_601, 0, 0x00001f00, 0, 0x0004000, 0, 0, 0, 32},
2348     +#ifdef BTTV_KWORLD
2349     + {BTTV_KWORLD, 0, 0x00007f00, 0, 0x0004000, 0, 0, 12, 32},
2350     +#endif
2351     + /* just a guess */
2352     + {BTTV_MAGICTVIEW061, 0, 0x0028e000, 0, 0x0020000, 0, 0, 20, 32},
2353     + {BTTV_MAGICTVIEW063, 0, 0x0028e000, 0, 0x0020000, 0, 0, 20, 32},
2354     + {BTTV_PHOEBE_TVMAS, 0, 0x0028e000, 0, 0x0020000, 0, 0, 20, 32},
2355     +#ifdef BTTV_BESTBUY_EASYTV2
2356     + {BTTV_BESTBUY_EASYTV, 0, 0x00007F00, 0, 0x0004000, 0, 0, 10, 8},
2357     + {BTTV_BESTBUY_EASYTV2, 0, 0x00007F00, 0, 0x0008000, 0, 0, 10, 8},
2358     +#endif
2359     + /* lock_mask probably also 0x100, or maybe it is 0x0 for all others !?! */
2360     + {BTTV_FLYVIDEO, 0, 0x000000f8, 0, 0, 0, 0, 0, 42},
2361     + {BTTV_FLYVIDEO_98, 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 42},
2362     + {BTTV_TYPHOON_TVIEW, 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 42},
2363     +#ifdef BTTV_FLYVIDEO_98FM
2364     + /* smorar@alfonzo.smuts.uct.ac.za */
2365     + {BTTV_FLYVIDEO_98FM, 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 42},
2366     +#endif
2367     + /* The Leadtek WinFast TV 2000 XP card (id 0x6606107d) uses an
2368     + * extra gpio bit compared to the original TV 2000 card (id
2369     + * 0x217d6606); as the bttv-0.7.100 driver does not
2370     + * distinguish between the two cards, we enable the extra bit
2371     + * based on the card id: */
2372     + {BTTV_WINFAST2000, 0x6606107d, 0x000008f8, 0, 0x0000100, 0, 0, 0, 32},
2373     + /* default: */
2374     + {BTTV_WINFAST2000, 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 32},
2375     +#ifdef BTTV_GVBCTV5PCI
2376     + {BTTV_GVBCTV5PCI, 0, 0x00f0b000, 0, 0, 0, 0, 20, 8},
2377     +#endif
2378     +};
2379     +
2380     +static unsigned char code_length = 0;
2381     +static unsigned char code_bytes = 1;
2382     +
2383     +#define MAX_BYTES 8
2384     +
2385     +#define SUCCESS 0
2386     +#define LOGHEAD "lirc_gpio (%d): "
2387     +
2388     +/* how many bits GPIO value can be shifted right before processing
2389     + * it is computed from the value of gpio_mask_parameter
2390     + */
2391     +static unsigned char gpio_pre_shift = 0;
2392     +
2393     +
2394     +static inline int reverse(int data, int bits)
2395     +{
2396     + int i;
2397     + int c;
2398     +
2399     + for (c=0,i=0; i<bits; i++) {
2400     + c |= (((data & (1<<i)) ? 1:0)) << (bits-1-i);
2401     + }
2402     +
2403     + return c;
2404     +}
2405     +
2406     +static int build_key(unsigned long gpio_val, unsigned char codes[MAX_BYTES])
2407     +{
2408     + unsigned long mask = gpio_mask;
2409     + unsigned char shift = 0;
2410     +
2411     + dprintk(LOGHEAD "gpio_val is %lx\n",card,(unsigned long) gpio_val);
2412     +
2413     + gpio_val ^= gpio_xor_mask;
2414     +
2415     + if (gpio_lock_mask && (gpio_val & gpio_lock_mask)) {
2416     + return -EBUSY;
2417     + }
2418     +
2419     + switch (bttv_id)
2420     + {
2421     + case BTTV_AVERMEDIA98:
2422     + if (bttv_write_gpio(card, gpio_enable, gpio_enable)) {
2423     + dprintk(LOGHEAD "cannot write to GPIO\n", card);
2424     + return -EIO;
2425     + }
2426     + if (bttv_read_gpio(card, &gpio_val)) {
2427     + dprintk(LOGHEAD "cannot read GPIO\n", card);
2428     + return -EIO;
2429     + }
2430     + if (bttv_write_gpio(card, gpio_enable, 0)) {
2431     + dprintk(LOGHEAD "cannot write to GPIO\n", card);
2432     + return -EIO;
2433     + }
2434     + break;
2435     + default:
2436     + break;
2437     + }
2438     +
2439     + /* extract bits from "raw" GPIO value using gpio_mask */
2440     + codes[0] = 0;
2441     + gpio_val >>= gpio_pre_shift;
2442     + while (mask) {
2443     + if (mask & 1u) {
2444     + codes[0] |= (gpio_val & 1u) << shift++;
2445     + }
2446     + mask >>= 1;
2447     + gpio_val >>= 1;
2448     + }
2449     +
2450     + dprintk(LOGHEAD "code is %lx\n",card,(unsigned long) codes[0]);
2451     + switch (bttv_id)
2452     + {
2453     + case BTTV_AVERMEDIA:
2454     + codes[2] = (codes[0]<<2)&0xff;
2455     + codes[3] = (~codes[2])&0xff;
2456     + codes[0] = 0x02;
2457     + codes[1] = 0xFD;
2458     + break;
2459     + case BTTV_AVPHONE98:
2460     + codes[2] = ((codes[0]&(~0x1))<<2)&0xff;
2461     + codes[3] = (~codes[2])&0xff;
2462     + if (codes[0]&0x1) {
2463     + codes[0] = 0xc0;
2464     + codes[1] = 0x3f;
2465     + } else {
2466     + codes[0] = 0x40;
2467     + codes[1] = 0xbf;
2468     + }
2469     + break;
2470     + case BTTV_AVERMEDIA98:
2471     + break;
2472     + case BTTV_FLYVIDEO:
2473     + case BTTV_FLYVIDEO_98:
2474     + case BTTV_TYPHOON_TVIEW:
2475     +#ifdef BTTV_FLYVIDEO_98FM
2476     + case BTTV_FLYVIDEO_98FM:
2477     +#endif
2478     + codes[4]=codes[0]<<3;
2479     + codes[5]=((~codes[4])&0xff);
2480     +
2481     + codes[0]=0x00;
2482     + codes[1]=0x1A;
2483     + codes[2]=0x1F;
2484     + codes[3]=0x2F;
2485     + break;
2486     + case BTTV_MAGICTVIEW061:
2487     + case BTTV_MAGICTVIEW063:
2488     + case BTTV_PHOEBE_TVMAS:
2489     + codes[0] = (codes[0]&0x01)
2490     + |((codes[0]&0x02)<<1)
2491     + |((codes[0]&0x04)<<2)
2492     + |((codes[0]&0x08)>>2)
2493     + |((codes[0]&0x10)>>1);
2494     + /* FALLTHROUGH */
2495     + case BTTV_MIRO:
2496     + case BTTV_DYNALINK:
2497     + case BTTV_PXELVWPLTVPAK:
2498     + case BTTV_PXELVWPLTVPRO:
2499     + case BTTV_PV_BT878P_9B:
2500     + case BTTV_PV_BT878P_PLUS:
2501     +#ifdef BTTV_KWORLD
2502     + case BTTV_KWORLD:
2503     +#endif
2504     + codes[2] = reverse(codes[0],8);
2505     + codes[3] = (~codes[2])&0xff;
2506     + codes[0] = 0x61;
2507     + codes[1] = 0xD6;
2508     + break;
2509     +#if 0
2510     + /* derived from e-tech config file */
2511     + /* 26 + 16 bits */
2512     + /* won't apply it until it's confirmed with a fly98 */
2513     + case BTTV_FLYVIDEO_98:
2514     + case BTTV_FLYVIDEO_98FM:
2515     + codes[4]=codes[0]<<3;
2516     + codes[5]=(~codes[4])&0xff;
2517     +
2518     + codes[0]=0x00;
2519     + codes[1]=0x1A;
2520     + codes[2]=0x1F;
2521     + codes[3]=0x2F;
2522     + break;
2523     +#endif
2524     + case BTTV_WINFAST2000:
2525     + /* shift extra bit */
2526     + codes[0] = (codes[0]&0x1f) | ((codes[0]&0x20) << 1);
2527     + case BTTV_WINVIEW_601:
2528     + codes[2] = reverse(codes[0],8);
2529     + codes[3] = (~codes[2])&0xff;
2530     + codes[0] = 0xC0;
2531     + codes[1] = 0x3F;
2532     + break;
2533     + default:
2534     + break;
2535     + }
2536     +
2537     + return SUCCESS;
2538     +}
2539     +
2540     +static int get_key(void* data, unsigned char *key, int key_no)
2541     +{
2542     + static unsigned long next_time = 0;
2543     + static unsigned char codes[MAX_BYTES];
2544     + unsigned long code = 0;
2545     + unsigned char cur_codes[MAX_BYTES];
2546     +
2547     + if (key_no > 0) {
2548     + if (code_bytes < 2 || key_no >= code_bytes) {
2549     + dprintk(LOGHEAD "something wrong in get_key\n", card);
2550     + return -EBADRQC;
2551     + }
2552     + *key = codes[key_no];
2553     + return SUCCESS;
2554     + }
2555     +
2556     + if (bttv_read_gpio(card, &code)) {
2557     + dprintk(LOGHEAD "cannot read GPIO\n", card);
2558     + return -EIO;
2559     + }
2560     +
2561     + if (build_key(code, cur_codes)) {
2562     + return -EFAULT;
2563     + }
2564     +
2565     + if (soft_gap) {
2566     + if (!memcmp(codes, cur_codes, code_bytes) &&
2567     + jiffies < next_time) {
2568     + return -EAGAIN;
2569     + }
2570     + next_time = jiffies + soft_gap;
2571     + }
2572     +
2573     + memcpy(codes, cur_codes, code_bytes);
2574     +
2575     + *key = codes[0];
2576     +
2577     + return SUCCESS;
2578     +}
2579     +
2580     +static int set_use_inc(void* data)
2581     +{
2582     + try_module_get(THIS_MODULE);
2583     + return 0;
2584     +}
2585     +
2586     +static void set_use_dec(void* data)
2587     +{
2588     + module_put(THIS_MODULE);
2589     +}
2590     +
2591     +static wait_queue_head_t* get_queue(void* data)
2592     +{
2593     + return bttv_get_gpio_queue(card);
2594     +}
2595     +
2596     +static struct lirc_plugin plugin = {
2597     + .name = "lirc_gpio ",
2598     + .get_key = get_key,
2599     + .get_queue = get_queue,
2600     + .set_use_inc = set_use_inc,
2601     + .set_use_dec = set_use_dec,
2602     +};
2603     +
2604     +/*
2605     + *
2606     + */
2607     +int gpio_remote_init(void)
2608     +{
2609     + int ret;
2610     + unsigned int mask;
2611     +
2612     + /* "normalize" gpio_mask
2613     + * this means shift it right until first bit is set
2614     + */
2615     + while (!(gpio_mask & 1u)) {
2616     + gpio_pre_shift++;
2617     + gpio_mask >>= 1;
2618     + }
2619     +
2620     + if (code_length) {
2621     + plugin.code_length = code_length;
2622     + } else {
2623     + /* calculate scan code length in bits if needed */
2624     + plugin.code_length = 1;
2625     + mask = gpio_mask >> 1;
2626     + while (mask) {
2627     + if (mask & 1u) {
2628     + plugin.code_length++;
2629     + }
2630     + mask >>= 1;
2631     + }
2632     + }
2633     +
2634     + code_bytes = (plugin.code_length/8) + (plugin.code_length%8 ? 1 : 0);
2635     + if (MAX_BYTES < code_bytes) {
2636     + printk (LOGHEAD "scan code too long (%d bytes)\n",
2637     + minor, code_bytes);
2638     + return -EBADRQC;
2639     + }
2640     +
2641     + if (gpio_enable) {
2642     + if(bttv_gpio_enable(card, gpio_enable, gpio_enable)) {
2643     + printk(LOGHEAD "gpio_enable failure\n", minor);
2644     + return -EIO;
2645     + }
2646     + }
2647     +
2648     +
2649     + /* translate ms to jiffies */
2650     + soft_gap = (soft_gap*HZ) / 1000;
2651     +
2652     + plugin.minor = minor;
2653     + plugin.sample_rate = sample_rate;
2654     +
2655     + ret = lirc_register_plugin(&plugin);
2656     +
2657     + if (0 > ret) {
2658     + printk (LOGHEAD "device registration failed with %d\n",
2659     + minor, ret);
2660     + return ret;
2661     + }
2662     +
2663     + minor = ret;
2664     + printk(LOGHEAD "driver registered\n", minor);
2665     +
2666     + return SUCCESS;
2667     +}
2668     +
2669     +static int __init lirc_gpio_init(void)
2670     +{
2671     + int type,cardid,card_type;
2672     +
2673     + if (CONFIG_LIRC_MAX_DEV < minor) {
2674     + printk("lirc_gpio: parameter minor (%d) must be less than %d!\n",
2675     + minor, CONFIG_LIRC_MAX_DEV-1);
2676     + return -EBADRQC;
2677     + }
2678     +
2679     + request_module("bttv");
2680     +
2681     + /* if gpio_mask not zero then use module parameters
2682     + * instead of autodetecting TV card
2683     + */
2684     + if (gpio_mask) {
2685     + if (sample_rate!=0 && (2 > sample_rate || 50 < sample_rate)) {
2686     + printk(LOGHEAD "parameter sample_rate "
2687     + "must be beetween 2 and 50!\n", minor);
2688     + return -EBADRQC;
2689     + }
2690     +
2691     + if (sample_rate!=0 && soft_gap &&
2692     + ((2000/sample_rate) > soft_gap || 1000 < soft_gap)) {
2693     + printk(LOGHEAD "parameter soft_gap "
2694     + "must be beetween %d and 1000!\n",
2695     + minor, 2000/sample_rate);
2696     + return -EBADRQC;
2697     + }
2698     + } else {
2699     + if(bttv_get_cardinfo(card,&type,&cardid)==-1) {
2700     + printk(LOGHEAD "could not get card type\n", minor);
2701     + }
2702     + printk(LOGHEAD "card type 0x%x, id 0x%x\n",minor,
2703     + type,cardid);
2704     +
2705     + if (type == BTTV_UNKNOWN) {
2706     + printk(LOGHEAD "cannot detect TV card nr %d!\n",
2707     + minor, card);
2708     + return -EBADRQC;
2709     + }
2710     + for (card_type = 1;
2711     + card_type < sizeof(rcv_infos)/sizeof(struct rcv_info);
2712     + card_type++) {
2713     + if (rcv_infos[card_type].bttv_id == type &&
2714     + (rcv_infos[card_type].card_id == 0 ||
2715     + rcv_infos[card_type].card_id == cardid)) {
2716     + bttv_id = rcv_infos[card_type].bttv_id;
2717     + gpio_mask = rcv_infos[card_type].gpio_mask;
2718     + gpio_enable = rcv_infos[card_type].gpio_enable;
2719     + gpio_lock_mask = rcv_infos[card_type].gpio_lock_mask;
2720     + gpio_xor_mask = rcv_infos[card_type].gpio_xor_mask;
2721     + soft_gap = rcv_infos[card_type].soft_gap;
2722     + sample_rate = rcv_infos[card_type].sample_rate;
2723     + code_length = rcv_infos[card_type].code_length;
2724     + break;
2725     + }
2726     + }
2727     + if (type==BTTV_AVPHONE98 && cardid==0x00011461) {
2728     + bttv_id = BTTV_AVERMEDIA98;
2729     + }
2730     + if (type==BTTV_AVERMEDIA98 && cardid==0x00041461) {
2731     + bttv_id = BTTV_AVPHONE98;
2732     + }
2733     + if (type==BTTV_AVERMEDIA98 && cardid==0x03001461) {
2734     + bttv_id = BTTV_AVPHONE98;
2735     + }
2736     + if (type==BTTV_AVERMEDIA98 && cardid==0x00000000) {
2737     + bttv_id = BTTV_AVPHONE98;
2738     + }
2739     + if (card_type == sizeof(rcv_infos)/sizeof(struct rcv_info)) {
2740     + printk(LOGHEAD "TV card type 0x%x not supported!\n",
2741     + minor, type);
2742     + return -EBADRQC;
2743     + }
2744     + }
2745     +
2746     + request_module("lirc_dev");
2747     +
2748     + return gpio_remote_init();
2749     +}
2750     +
2751     +void __exit lirc_gpio_exit(void)
2752     +{
2753     + int ret;
2754     +
2755     + ret = lirc_unregister_plugin(minor);
2756     +
2757     + if (0 > ret) {
2758     + printk(LOGHEAD "error in lirc_unregister_minor: %d\n"
2759     + "Trying again...\n",
2760     + minor, ret);
2761     +
2762     + current->state = TASK_INTERRUPTIBLE;
2763     + schedule_timeout(HZ);
2764     +
2765     + ret = lirc_unregister_plugin(minor);
2766     +
2767     + if (0 > ret) {
2768     + printk(LOGHEAD "error in lirc_unregister_minor: %d!!!\n",
2769     + minor, ret);
2770     + return;
2771     + }
2772     + }
2773     +
2774     + dprintk(LOGHEAD "module successfully unloaded\n", minor);
2775     +}
2776     +
2777     +MODULE_DESCRIPTION("Driver module for remote control (data from bt848 GPIO port)");
2778     +MODULE_AUTHOR("Artur Lipowski");
2779     +MODULE_LICENSE("GPL");
2780     +
2781     +#ifdef MODULE
2782     + module_init(lirc_gpio_init);
2783     +#else
2784     + late_initcall(lirc_gpio_init);
2785     +#endif
2786     +module_exit(lirc_gpio_exit);
2787     +
2788     +/*
2789     + * Overrides for Emacs so that we follow Linus's tabbing style.
2790     + * ---------------------------------------------------------------------------
2791     + * Local variables:
2792     + * c-basic-offset: 8
2793     + * End:
2794     + */
2795     diff -NPaur linux-2.6.2/drivers/char/lirc/lirc_i2c.c linux-2.6.2-lirc/drivers/char/lirc/lirc_i2c.c
2796     --- linux-2.6.2/drivers/char/lirc/lirc_i2c.c 1970-01-01 01:00:00.000000000 +0100
2797     +++ linux-2.6.2-lirc/drivers/char/lirc/lirc_i2c.c 2004-02-09 20:03:15.067330648 +0100
2798     @@ -0,0 +1,444 @@
2799     +/* $Id: 405_lirc_infrared-2.6.2-02092004.patch,v 1.1 2004/02/24 22:27:37 brad_mssw Exp $ */
2800     +
2801     +/*
2802     + * i2c IR lirc plugin for Hauppauge and Pixelview cards - new 2.8.x i2c stack
2803     + *
2804     + * Copyright (c) 2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
2805     + * modified for PixelView (BT878P+W/FM) by
2806     + * Michal Kochanowicz <mkochano@pld.org.pl>
2807     + * Christoph Bartelmus <lirc@bartelmus.de>
2808     + * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
2809     + * Ulrich Mueller <ulrich.mueller42@web.de>
2810     + * modified for Asus TV-Box and Creative/VisionTek BreakOut-Box by
2811     + * Stefan Jahn <stefan@lkcc.org>
2812     + * modified for Linux 2.6 by
2813     + * Jeffrey Clark <jeff@clarkmania.com>
2814     + *
2815     + * parts are cut&pasted from the old lirc_haup.c driver
2816     + *
2817     + * This program is free software; you can redistribute it and/or modify
2818     + * it under the terms of the GNU General Public License as published by
2819     + * the Free Software Foundation; either version 2 of the License, or
2820     + * (at your option) any later version.
2821     + *
2822     + * This program is distributed in the hope that it will be useful,
2823     + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2824     + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2825     + * GNU General Public License for more details.
2826     + *
2827     + * You should have received a copy of the GNU General Public License
2828     + * along with this program; if not, write to the Free Software
2829     + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2830     + *
2831     + */
2832     +
2833     +#include <linux/module.h>
2834     +#include <linux/kmod.h>
2835     +#include <linux/kernel.h>
2836     +#include <linux/sched.h>
2837     +#include <linux/string.h>
2838     +#include <linux/timer.h>
2839     +#include <linux/delay.h>
2840     +#include <linux/errno.h>
2841     +#include <linux/slab.h>
2842     +#include <linux/init.h>
2843     +#include <linux/moduleparam.h>
2844     +
2845     +#include <linux/i2c.h>
2846     +#include <linux/i2c-algo-bit.h>
2847     +#include <asm/semaphore.h>
2848     +
2849     +#include "../../media/video/bttv.h"
2850     +
2851     +#include "lirc_dev.h"
2852     +
2853     +static unsigned short normal_i2c[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, 0x21, 0x23, I2C_CLIENT_END };
2854     +static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
2855     +static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
2856     +static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
2857     +static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
2858     +static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
2859     +static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
2860     +
2861     +static struct i2c_client_address_data addr_data = {
2862     + .normal_i2c = normal_i2c,
2863     + .normal_i2c_range = normal_i2c_range,
2864     + .probe = probe,
2865     + .probe_range = probe_range,
2866     + .ignore = ignore,
2867     + .ignore_range = ignore_range,
2868     + .force = force
2869     +};
2870     +
2871     +struct i2c_ir {
2872     + struct lirc_plugin lirc;
2873     + struct i2c_client client;
2874     + int nextkey;
2875     + unsigned char b[3];
2876     + unsigned char bits;
2877     + unsigned char flag;
2878     +};
2879     +
2880     +/* ----------------------------------------------------------------------- */
2881     +/* insmod parameters */
2882     +
2883     +static int debug = 0; /* debug output */
2884     +static int minor = -1; /* minor number */
2885     +
2886     +MODULE_PARM(debug,"i");
2887     +MODULE_PARM(minor,"i");
2888     +
2889     +MODULE_DESCRIPTION("Infrared receiver driver for Hauppauge and Pixelview cards (i2c stack)");
2890     +MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller, Stefan Jahn, Jeffrey Clark");
2891     +MODULE_LICENSE("GPL");
2892     +
2893     +#define dprintk if (debug) printk
2894     +
2895     +/* ----------------------------------------------------------------------- */
2896     +
2897     +#define DRIVER_NAME "lirc_i2c"
2898     +
2899     +/* ----------------------------------------------------------------------- */
2900     +
2901     +static inline int reverse(int data, int bits)
2902     +{
2903     + int i;
2904     + int c;
2905     +
2906     + for (c=0,i=0; i<bits; i++) {
2907     + c |= (((data & (1<<i)) ? 1:0)) << (bits-1-i);
2908     + }
2909     +
2910     + return c;
2911     +}
2912     +
2913     +static int get_key_pcf8574(void* data, unsigned char* key, int key_no)
2914     +{
2915     + struct i2c_ir *ir = data;
2916     + int rc;
2917     + unsigned char all, mask;
2918     +
2919     + /* compute all valid bits (key code + pressed/release flag) */
2920     + all = ir->bits | ir->flag;
2921     +
2922     + /* save IR writable mask bits */
2923     + mask = i2c_smbus_read_byte(&ir->client) & ~all;
2924     +
2925     + /* send bit mask */
2926     + rc = i2c_smbus_write_byte(&ir->client, (0xff & all) | mask);
2927     +
2928     + /* receive scan code */
2929     + rc = i2c_smbus_read_byte(&ir->client);
2930     +
2931     + if (rc == -1) {
2932     + dprintk(DRIVER_NAME ": %s read error\n", ir->client.name);
2933     + return -1;
2934     + }
2935     +
2936     + /* drop duplicate polls */
2937     + if (ir->b[0] == (rc & all)) {
2938     + return -1;
2939     + }
2940     + ir->b[0] = rc & all;
2941     +
2942     + dprintk(DRIVER_NAME ": %s key 0x%02X %s\n",
2943     + ir->client.name, rc & ir->bits,
2944     + (rc & ir->flag) ? "released" : "pressed");
2945     +
2946     + if (rc & ir->flag) {
2947     + /* ignore released buttons */
2948     + return -1;
2949     + }
2950     +
2951     + /* return valid key code */
2952     + *key = rc & ir->bits;
2953     + return 0;
2954     +}
2955     +
2956     +static int get_key_haup(void* data, unsigned char* key, int key_no)
2957     +{
2958     + struct i2c_ir *ir = data;
2959     + unsigned char buf[3];
2960     + __u16 code;
2961     +
2962     + if (ir->nextkey != -1) {
2963     + /* pass second byte */
2964     + *key = ir->nextkey;
2965     + ir->nextkey = -1;
2966     + return 0;
2967     + }
2968     +
2969     + /* poll IR chip */
2970     + if (3 == i2c_master_recv(&ir->client,buf,3)) {
2971     + ir->b[0] = buf[0];
2972     + ir->b[1] = buf[1];
2973     + ir->b[2] = buf[2];
2974     + } else {
2975     + dprintk(DRIVER_NAME ": read error\n");
2976     + /* keep last successfull read buffer */
2977     + }
2978     +
2979     + /* key pressed ? */
2980     + if ((ir->b[0] & 0x80) == 0)
2981     + return -1;
2982     +
2983     + dprintk(DRIVER_NAME ": key (0x%02x/0x%02x)\n",
2984     + ir->b[0], ir->b[1]);
2985     +
2986     + /* look what we have */
2987     + code = (((__u16)ir->b[0]&0x7f)<<6) | (ir->b[1]>>2);
2988     +
2989     + /* return it */
2990     + *key = (code >> 8) & 0xff;
2991     + ir->nextkey = code & 0xff;
2992     + return 0;
2993     +}
2994     +
2995     +static int get_key_pixelview(void* data, unsigned char* key, int key_no)
2996     +{
2997     + struct i2c_ir *ir = data;
2998     + unsigned char b;
2999     +
3000     + /* poll IR chip */
3001     + if (1 != i2c_master_recv(&ir->client,&b,1)) {
3002     + dprintk(DRIVER_NAME ": read error\n");
3003     + return -1;
3004     + }
3005     + dprintk(DRIVER_NAME ": key %02x\n", b);
3006     + *key = b;
3007     + return 0;
3008     +}
3009     +
3010     +static int get_key_pv951(void* data, unsigned char* key, int key_no)
3011     +{
3012     + struct i2c_ir *ir = data;
3013     + unsigned char b;
3014     + static unsigned char codes[4];
3015     +
3016     + if(key_no>0)
3017     + {
3018     + if(key_no>=4) {
3019     + dprintk(DRIVER_NAME
3020     + ": something wrong in get_key_pv951\n");
3021     + return -EBADRQC;
3022     + }
3023     + *key = codes[key_no];
3024     + return 0;
3025     + }
3026     +
3027     + /* poll IR chip */
3028     + if (1 != i2c_master_recv(&ir->client,&b,1)) {
3029     + dprintk(DRIVER_NAME ": read error\n");
3030     + return -1;
3031     + }
3032     + /* ignore 0xaa */
3033     + if (b==0xaa)
3034     + return -1;
3035     + dprintk(DRIVER_NAME ": key %02x\n", b);
3036     +
3037     + codes[2] = reverse(b,8);
3038     + codes[3] = (~codes[2])&0xff;
3039     + codes[0] = 0x61;
3040     + codes[1] = 0xD6;
3041     +
3042     + *key=codes[0];
3043     + return 0;
3044     +}
3045     +
3046     +static int get_key_knc1(void *data, unsigned char *key, int key_no)
3047     +{
3048     + struct i2c_ir *ir = data;
3049     + unsigned char b;
3050     + static unsigned char last_button = 0xFF;
3051     +
3052     + /* poll IR chip */
3053     + if (1 != i2c_master_recv(&ir->client,&b,1)) {
3054     + dprintk(DRIVER_NAME ": read error\n");
3055     + return -1;
3056     + }
3057     +
3058     + /* it seems that 0xFE indicates that a button is still hold
3059     + down, while 0xFF indicates that no button is hold
3060     + down. 0xFE sequences are sometimes interrupted by 0xFF */
3061     +
3062     + if( b == 0xFF )
3063     + return -1;
3064     +
3065     + dprintk(DRIVER_NAME ": key %02x\n", b);
3066     +
3067     + if ( b == 0xFE )
3068     + b = last_button;
3069     +
3070     + *key = b;
3071     + last_button = b;
3072     + return 0;
3073     +}
3074     +
3075     +static int set_use_inc(void* data)
3076     +{
3077     + try_module_get(THIS_MODULE);
3078     + return 0;
3079     +}
3080     +
3081     +static void set_use_dec(void* data)
3082     +{
3083     + module_put(THIS_MODULE);
3084     +}
3085     +
3086     +static struct lirc_plugin lirc_template = {
3087     + .name = "lirc_i2c",
3088     + .set_use_inc = set_use_inc,
3089     + .set_use_dec = set_use_dec
3090     +};
3091     +
3092     +/* ----------------------------------------------------------------------- */
3093     +
3094     +static int lirc_i2c_attach(struct i2c_adapter *adap, int addr, int kind);
3095     +static int lirc_i2c_detach(struct i2c_client *client);
3096     +static int lirc_i2c_probe(struct i2c_adapter *adap);
3097     +
3098     +static struct i2c_driver driver = {
3099     + .owner = THIS_MODULE,
3100     + .name = DRIVER_NAME,
3101     + .id = I2C_DRIVERID_EXP3, /* FIXME */
3102     + .flags = I2C_DF_NOTIFY,
3103     + .attach_adapter = lirc_i2c_probe,
3104     + .detach_client = lirc_i2c_detach,
3105     +};
3106     +
3107     +static struct i2c_client client_template =
3108     +{
3109     + I2C_DEVNAME("(unset)"),
3110     + .flags = I2C_CLIENT_ALLOW_USE,
3111     + .driver = &driver
3112     +};
3113     +
3114     +static int lirc_i2c_attach(struct i2c_adapter *adap, int addr, int kind)
3115     +{
3116     + struct i2c_ir *ir;
3117     + int ret;
3118     +
3119     + client_template.adapter = adap;
3120     + client_template.addr = addr;
3121     +
3122     + if (NULL == (ir = kmalloc(sizeof(struct i2c_ir),GFP_KERNEL)))
3123     + return -ENOMEM;
3124     + memset(ir,0,sizeof(struct i2c_ir));
3125     + memcpy(&ir->client,&client_template,sizeof(struct i2c_client));
3126     + memcpy(&ir->lirc,&lirc_template,sizeof(struct lirc_plugin));
3127     +
3128     + ir->lirc.data = ir;
3129     + ir->lirc.minor = minor;
3130     + ir->nextkey = -1;
3131     +
3132     + i2c_set_clientdata(&ir->client,ir);
3133     +
3134     + switch(addr)
3135     + {
3136     + case 0x64:
3137     + strncpy(ir->client.name, "Pixelview IR", I2C_NAME_SIZE);
3138     + ir->lirc.code_length = 8;
3139     + ir->lirc.sample_rate = 10;
3140     + ir->lirc.get_key = get_key_pixelview;
3141     + break;
3142     + case 0x4b:
3143     + strncpy(ir->client.name,"PV951 IR", I2C_NAME_SIZE);
3144     + ir->lirc.code_length = 32;
3145     + ir->lirc.sample_rate = 10;
3146     + ir->lirc.get_key = get_key_pv951;
3147     + break;
3148     + case 0x18:
3149     + case 0x1a:
3150     + strncpy(ir->client.name,"Hauppauge IR", I2C_NAME_SIZE);
3151     + ir->lirc.code_length = 13;
3152     + ir->lirc.sample_rate = 6;
3153     + ir->lirc.get_key = get_key_haup;
3154     + break;
3155     + case 0x30:
3156     + strncpy(ir->client.name,"KNC ONE IR", I2C_NAME_SIZE);
3157     + ir->lirc.code_length = 8;
3158     + ir->lirc.sample_rate = 10;
3159     + ir->lirc.get_key = get_key_knc1;
3160     + break;
3161     + case 0x21:
3162     + case 0x23:
3163     + strncpy(ir->client.name,"TV-Box IR", I2C_NAME_SIZE);
3164     + ir->lirc.code_length = 8;
3165     + ir->lirc.sample_rate = 10;
3166     + ir->lirc.get_key = get_key_pcf8574;
3167     + ir->bits = ir->client.flags & 0xff;
3168     + ir->flag = (ir->client.flags >> 8) & 0xff;
3169     + break;
3170     +
3171     + default:
3172     + /* shouldn't happen */
3173     + dprintk(DRIVER_NAME ": unknown i2c address (0x%02x)?\n",addr);
3174     + kfree(ir);
3175     + return -1;
3176     + }
3177     + dprintk(DRIVER_NAME ": chip found @ 0x%02x (%s)\n",addr,
3178     + ir->client.name);
3179     +
3180     + /* register device */
3181     + i2c_attach_client(&ir->client);
3182     +
3183     + if((ret = lirc_register_plugin(&ir->lirc))) {
3184     + dprintk(DRIVER_NAME ": device registration failed with %d\n",
3185     + ret);
3186     + kfree(ir);
3187     + return -1;
3188     + }
3189     +
3190     + ir->lirc.minor = ret;
3191     + dprintk(DRIVER_NAME ": driver registered\n");
3192     +
3193     + return 0;
3194     +}
3195     +
3196     +static int lirc_i2c_detach(struct i2c_client *client)
3197     +{
3198     + struct i2c_ir *ir = i2c_get_clientdata(client);
3199     + int err;
3200     +
3201     + /* unregister device */
3202     + if ((err = lirc_unregister_plugin(ir->lirc.minor))) {
3203     + dprintk(DRIVER_NAME ": lirc unregister failed\n");
3204     + return err;
3205     + } else {
3206     + dprintk(DRIVER_NAME ": lirc unregister successful\n");
3207     + }
3208     +
3209     + if ((err = i2c_detach_client(&ir->client))) {
3210     + dprintk(DRIVER_NAME ": i2c detach failed\n");
3211     + return err;
3212     + } else {
3213     + dprintk(DRIVER_NAME ": i2c detach successful\n");
3214     + }
3215     +
3216     + /* free memory */
3217     + kfree(ir);
3218     + return 0;
3219     +}
3220     +
3221     +static int lirc_i2c_probe(struct i2c_adapter *adap) {
3222     + dprintk(DRIVER_NAME ": starting probe for adapter %s (0x%x)\n",
3223     + adap->name, adap->id);
3224     + return i2c_probe(adap, &addr_data, lirc_i2c_attach);
3225     +}
3226     +
3227     +static int __init lirc_i2c_init(void)
3228     +{
3229     + dprintk(DRIVER_NAME ": init\n");
3230     + request_module("bttv");
3231     + request_module("lirc_dev");
3232     + return i2c_add_driver(&driver);
3233     +}
3234     +
3235     +static void __exit lirc_i2c_exit(void)
3236     +{
3237     + dprintk(DRIVER_NAME ": exit\n");
3238     + i2c_del_driver(&driver);
3239     +}
3240     +
3241     +module_init(lirc_i2c_init);
3242     +module_exit(lirc_i2c_exit);
3243     diff -NPaur linux-2.6.2/drivers/char/lirc/lirc_it87.c linux-2.6.2-lirc/drivers/char/lirc/lirc_it87.c
3244     --- linux-2.6.2/drivers/char/lirc/lirc_it87.c 1970-01-01 01:00:00.000000000 +0100
3245     +++ linux-2.6.2-lirc/drivers/char/lirc/lirc_it87.c 2004-02-09 20:03:15.072329888 +0100
3246     @@ -0,0 +1,953 @@
3247     +/*
3248     + * LIRC driver for ITE IT8712/IT8705 CIR port
3249     + *
3250     + * Copyright (C) 2001 Hans-Günter Lütke Uphues <hg_lu@web.de>
3251     + *
3252     + * This program is free software; you can redistribute it and/or
3253     + * modify it under the terms of the GNU General Public License as
3254     + * published by the Free Software Foundation; either version 2 of the
3255     + * License, or (at your option) any later version.
3256     + *
3257     + * This program is distributed in the hope that it will be useful, but
3258     + * WITHOUT ANY WARRANTY; without even the implied warranty of
3259     + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3260     + * General Public License for more details.
3261     +
3262     + * You should have received a copy of the GNU General Public License
3263     + * along with this program; if not, write to the Free Software
3264     + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
3265     + * USA
3266     + *
3267     + * ITE IT8705 and IT8712(not tested) CIR-port support for lirc based
3268     + * via cut and paste from lirc_sir.c (C) 2000 Milan Pikula
3269     + *
3270     + * Attention: Sendmode only tested with debugging logs
3271     + *
3272     + * 2001/02/27 Christoph Bartelmus <lirc@bartelmus.de> :
3273     + * reimplemented read function
3274     + */
3275     +
3276     +
3277     +#include <linux/version.h>
3278     +#include <linux/module.h>
3279     +
3280     +#include <linux/config.h>
3281     +
3282     +
3283     +#include <linux/sched.h>
3284     +#include <linux/errno.h>
3285     +#include <linux/signal.h>
3286     +#include <linux/fs.h>
3287     +#include <linux/interrupt.h>
3288     +#include <linux/ioport.h>
3289     +#include <linux/kernel.h>
3290     +#include <linux/major.h>
3291     +#include <linux/serial_reg.h>
3292     +#include <linux/time.h>
3293     +#include <linux/string.h>
3294     +#include <linux/types.h>
3295     +#include <linux/wait.h>
3296     +#include <linux/mm.h>
3297     +#include <linux/delay.h>
3298     +#include <linux/poll.h>
3299     +#include <asm/system.h>
3300     +#include <asm/segment.h>
3301     +#include <asm/io.h>
3302     +#include <asm/irq.h>
3303     +#include <asm/fcntl.h>
3304     +
3305     +#include <linux/timer.h>
3306     +
3307     +#include <linux/lirc.h>
3308     +#include "lirc_dev.h"
3309     +
3310     +#include "lirc_it87.h"
3311     +
3312     +static unsigned long it87_bits_in_byte_out = 0;
3313     +static unsigned long it87_send_counter = 0;
3314     +static unsigned char it87_RXEN_mask = IT87_CIR_RCR_RXEN;
3315     +
3316     +#define RBUF_LEN 1024
3317     +#define WBUF_LEN 1024
3318     +
3319     +#define LIRC_DRIVER_NAME "lirc_it87"
3320     +
3321     +/* timeout for sequences in jiffies (=5/100s) */
3322     +/* must be longer than TIME_CONST */
3323     +#define IT87_TIMEOUT (HZ*5/100)
3324     +
3325     +static int io = IT87_CIR_DEFAULT_IOBASE;
3326     +static int irq = IT87_CIR_DEFAULT_IRQ;
3327     +static unsigned char it87_freq = 38; /* kHz */
3328     +/* receiver demodulator default: off */
3329     +static unsigned char it87_enable_demodulator = 0;
3330     +
3331     +static spinlock_t timer_lock = SPIN_LOCK_UNLOCKED;
3332     +static struct timer_list timerlist;
3333     +/* time of last signal change detected */
3334     +static struct timeval last_tv = {0, 0};
3335     +/* time of last UART data ready interrupt */
3336     +static struct timeval last_intr_tv = {0, 0};
3337     +static int last_value = 0;
3338     +
3339     +static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue);
3340     +
3341     +static spinlock_t hardware_lock = SPIN_LOCK_UNLOCKED;
3342     +static spinlock_t dev_lock = SPIN_LOCK_UNLOCKED;
3343     +
3344     +static lirc_t rx_buf[RBUF_LEN]; unsigned int rx_tail = 0, rx_head = 0;
3345     +static lirc_t tx_buf[WBUF_LEN];
3346     +
3347     +/* SECTION: Prototypes */
3348     +
3349     +/* Communication with user-space */
3350     +static int lirc_open(struct inode * inode,
3351     + struct file * file);
3352     +static int lirc_close(struct inode * inode,
3353     + struct file *file);
3354     +static unsigned int lirc_poll(struct file * file,
3355     + poll_table * wait);
3356     +static ssize_t lirc_read(struct file * file,
3357     + char * buf,
3358     + size_t count,
3359     + loff_t * ppos);
3360     +static ssize_t lirc_write(struct file * file,
3361     + const char * buf,
3362     + size_t n,
3363     + loff_t * pos);
3364     +static int lirc_ioctl(struct inode *node,
3365     + struct file *filep,
3366     + unsigned int cmd,
3367     + unsigned long arg);
3368     +static void add_read_queue(int flag,
3369     + unsigned long val);
3370     +static int init_chrdev(void);
3371     +static void drop_chrdev(void);
3372     + /* Hardware */
3373     +static void it87_interrupt(int irq,
3374     + void * dev_id,
3375     + struct pt_regs * regs);
3376     +static void send_space(unsigned long len);
3377     +static void send_pulse(unsigned long len);
3378     +static void init_send(void);
3379     +static void terminate_send(unsigned long len);
3380     +static int init_hardware(void);
3381     +static void drop_hardware(void);
3382     + /* Initialisation */
3383     +static int init_port(void);
3384     +static void drop_port(void);
3385     +int init_module(void);
3386     +void cleanup_module(void);
3387     +
3388     +
3389     +/* SECTION: Communication with user-space */
3390     +
3391     +static int lirc_open(struct inode * inode,
3392     + struct file * file)
3393     +{
3394     + spin_lock(&dev_lock);
3395     + if (module_refcount(THIS_MODULE)) {
3396     + spin_unlock(&dev_lock);
3397     + return -EBUSY;
3398     + }
3399     + try_module_get(THIS_MODULE);
3400     + spin_unlock(&dev_lock);
3401     + return 0;
3402     +}
3403     +
3404     +
3405     +static int lirc_close(struct inode * inode,
3406     + struct file *file)
3407     +{
3408     + module_put(THIS_MODULE);
3409     + return 0;
3410     +}
3411     +
3412     +
3413     +static unsigned int lirc_poll(struct file * file,
3414     + poll_table * wait)
3415     +{
3416     + poll_wait(file, &lirc_read_queue, wait);
3417     + if (rx_head != rx_tail)
3418     + return POLLIN | POLLRDNORM;
3419     + return 0;
3420     +}
3421     +
3422     +
3423     +static ssize_t lirc_read(struct file * file,
3424     + char * buf,
3425     + size_t count,
3426     + loff_t * ppos)
3427     +{
3428     + int n=0;
3429     + int retval=0;
3430     +
3431     + while(n<count)
3432     + {
3433     + if(file->f_flags & O_NONBLOCK &&
3434     + rx_head==rx_tail)
3435     + {
3436     + retval = -EAGAIN;
3437     + break;
3438     + }
3439     + retval=wait_event_interruptible(lirc_read_queue,
3440     + rx_head!=rx_tail);
3441     + if(retval)
3442     + {
3443     + break;
3444     + }
3445     +
3446     + retval=verify_area(VERIFY_WRITE,(void *) buf+n,
3447     + sizeof(lirc_t));
3448     + if (retval)
3449     + {
3450     + return retval;
3451     + }
3452     + copy_to_user((void *) buf+n,(void *) (rx_buf+rx_head),
3453     + sizeof(lirc_t));
3454     + rx_head=(rx_head+1)&(RBUF_LEN-1);
3455     + n+=sizeof(lirc_t);
3456     + }
3457     + if(n)
3458     + {
3459     + return n;
3460     + }
3461     + return retval;
3462     +}
3463     +
3464     +
3465     +static ssize_t lirc_write(struct file * file,
3466     + const char * buf,
3467     + size_t n,
3468     + loff_t * pos)
3469     +{
3470     + int i;
3471     + int retval;
3472     +
3473     + if(n%sizeof(lirc_t) || (n/sizeof(lirc_t)) > WBUF_LEN)
3474     + return(-EINVAL);
3475     + retval = verify_area(VERIFY_READ, buf, n);
3476     + if (retval)
3477     + return retval;
3478     + copy_from_user(tx_buf, buf, n);
3479     + i = 0;
3480     + n/=sizeof(lirc_t);
3481     + init_send();
3482     + while (1) {
3483     + if (i >= n)
3484     + break;
3485     + if (tx_buf[i])
3486     + send_pulse(tx_buf[i]);
3487     + i++;
3488     + if (i >= n)
3489     + break;
3490     + if (tx_buf[i])
3491     + send_space(tx_buf[i]);
3492     + i++;
3493     + }
3494     + terminate_send(tx_buf[i-1]);
3495     + return n;
3496     +}
3497     +
3498     +
3499     +static int lirc_ioctl(struct inode *node,
3500     + struct file *filep,
3501     + unsigned int cmd,
3502     + unsigned long arg)
3503     +{
3504     + int retval = 0;
3505     + unsigned long value = 0;
3506     + unsigned int ivalue;
3507     +
3508     + if (cmd == LIRC_GET_FEATURES)
3509     + value = LIRC_CAN_SEND_PULSE |
3510     + LIRC_CAN_SET_SEND_CARRIER |
3511     + LIRC_CAN_REC_MODE2;
3512     + else if (cmd == LIRC_GET_SEND_MODE)
3513     + value = LIRC_MODE_PULSE;
3514     + else if (cmd == LIRC_GET_REC_MODE)
3515     + value = LIRC_MODE_MODE2;
3516     +
3517     + switch (cmd) {
3518     + case LIRC_GET_FEATURES:
3519     + case LIRC_GET_SEND_MODE:
3520     + case LIRC_GET_REC_MODE:
3521     + retval = put_user(value, (unsigned long *) arg);
3522     + break;
3523     +
3524     + case LIRC_SET_SEND_MODE:
3525     + case LIRC_SET_REC_MODE:
3526     + retval = get_user(value, (unsigned long *) arg);
3527     + break;
3528     +
3529     + case LIRC_SET_SEND_CARRIER:
3530     + retval=get_user(ivalue,(unsigned int *) arg);
3531     + if(retval) return(retval);
3532     + ivalue /= 1000;
3533     + if (ivalue > IT87_CIR_FREQ_MAX ||
3534     + ivalue < IT87_CIR_FREQ_MIN) return(-EINVAL);
3535     +
3536     + it87_freq = ivalue;
3537     + {
3538     + unsigned long hw_flags;
3539     +
3540     + spin_lock_irqsave(&hardware_lock, hw_flags);
3541     + outb(((inb(io + IT87_CIR_TCR2) & IT87_CIR_TCR2_TXMPW) |
3542     + (it87_freq - IT87_CIR_FREQ_MIN) << 3),
3543     + io + IT87_CIR_TCR2);
3544     + spin_unlock_irqrestore(&hardware_lock, hw_flags);
3545     +#ifdef DEBUG
3546     + printk(KERN_DEBUG LIRC_DRIVER_NAME
3547     + " demodulation frequency: %d kHz\n", it87_freq);
3548     +#endif
3549     + }
3550     +
3551     + break;
3552     +
3553     + default:
3554     + retval = -ENOIOCTLCMD;
3555     + }
3556     +
3557     + if (retval)
3558     + return retval;
3559     +
3560     + if (cmd == LIRC_SET_REC_MODE) {
3561     + if (value != LIRC_MODE_MODE2)
3562     + retval = -ENOSYS;
3563     + } else if (cmd == LIRC_SET_SEND_MODE) {
3564     + if (value != LIRC_MODE_PULSE)
3565     + retval = -ENOSYS;
3566     + }
3567     + return retval;
3568     +}
3569     +
3570     +static void add_read_queue(int flag,
3571     + unsigned long val)
3572     +{
3573     + unsigned int new_rx_tail;
3574     + lirc_t newval;
3575     +
3576     +#ifdef DEBUG_SIGNAL
3577     + printk(KERN_DEBUG LIRC_DRIVER_NAME
3578     + ": add flag %d with val %lu\n",
3579     + flag,val);
3580     +#endif
3581     +
3582     + newval = val & PULSE_MASK;
3583     +
3584     + /* statistically pulses are ~TIME_CONST/2 too long: we could
3585     + maybe make this more exactly but this is good enough */
3586     + if(flag) /* pulse */ {
3587     + if(newval>TIME_CONST/2) {
3588     + newval-=TIME_CONST/2;
3589     + }
3590     + else /* should not ever happen */ {
3591     + newval=1;
3592     + }
3593     + newval|=PULSE_BIT;
3594     + }
3595     + else {
3596     + newval+=TIME_CONST/2;
3597     + }
3598     + new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1);
3599     + if (new_rx_tail == rx_head) {
3600     +#ifdef DEBUG
3601     + printk(KERN_WARNING LIRC_DRIVER_NAME ": Buffer overrun.\n");
3602     +#endif
3603     + return;
3604     + }
3605     + rx_buf[rx_tail] = newval;
3606     + rx_tail = new_rx_tail;
3607     + wake_up_interruptible(&lirc_read_queue);
3608     +}
3609     +
3610     +
3611     +static struct file_operations lirc_fops = {
3612     + read: lirc_read,
3613     + write: lirc_write,
3614     + poll: lirc_poll,
3615     + ioctl: lirc_ioctl,
3616     + open: lirc_open,
3617     + release: lirc_close,
3618     +};
3619     +
3620     +static int set_use_inc(void* data)
3621     +{
3622     +#if WE_DONT_USE_LOCAL_OPEN_CLOSE
3623     + try_module_get(THIS_MODULE);
3624     +#endif
3625     + return 0;
3626     +}
3627     +
3628     +static void set_use_dec(void* data)
3629     +{
3630     +#if WE_DONT_USE_LOCAL_OPEN_CLOSE
3631     + module_put(THIS_MODULE);
3632     +#endif
3633     +}
3634     +static struct lirc_plugin plugin = {
3635     + name: LIRC_DRIVER_NAME,
3636     + minor: -1,
3637     + code_length: 1,
3638     + sample_rate: 0,
3639     + data: NULL,
3640     + get_key: NULL,
3641     + get_queue: NULL,
3642     + set_use_inc: set_use_inc,
3643     + set_use_dec: set_use_dec,
3644     + fops: &lirc_fops,
3645     +};
3646     +
3647     +
3648     +int init_chrdev(void)
3649     +{
3650     + plugin.minor = lirc_register_plugin(&plugin);
3651     +
3652     + if (plugin.minor < 0) {
3653     + printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n");
3654     + return -EIO;
3655     + }
3656     + return 0;
3657     +}
3658     +
3659     +
3660     +static void drop_chrdev(void)
3661     +{
3662     + lirc_unregister_plugin(plugin.minor);
3663     +}
3664     +
3665     +/* SECTION: Hardware */
3666     +static long delta(struct timeval * tv1,
3667     + struct timeval * tv2)
3668     +{
3669     + unsigned long deltv;
3670     +
3671     + deltv = tv2->tv_sec - tv1->tv_sec;
3672     + if (deltv > 15)
3673     + deltv = 0xFFFFFF;
3674     + else
3675     + deltv = deltv*1000000 +
3676     + tv2->tv_usec -
3677     + tv1->tv_usec;
3678     + return deltv;
3679     +}
3680     +
3681     +
3682     +static void it87_timeout(unsigned long data)
3683     +{
3684     + /* if last received signal was a pulse, but receiving stopped
3685     + within the 9 bit frame, we need to finish this pulse and
3686     + simulate a signal change to from pulse to space. Otherwise
3687     + upper layers will receive two sequences next time. */
3688     +
3689     + unsigned long flags;
3690     + unsigned long pulse_end;
3691     +
3692     + /* avoid interference with interrupt */
3693     + spin_lock_irqsave(&timer_lock, flags);
3694     + if (last_value) {
3695     + /* determine 'virtual' pulse end: */
3696     + pulse_end = delta(&last_tv, &last_intr_tv);
3697     +#ifdef DEBUG_SIGNAL
3698     + printk(KERN_DEBUG LIRC_DRIVER_NAME
3699     + ": timeout add %d for %lu usec\n",
3700     + last_value,
3701     + pulse_end);
3702     +#endif
3703     + add_read_queue(last_value,
3704     + pulse_end);
3705     + last_value = 0;
3706     + last_tv=last_intr_tv;
3707     + }
3708     + spin_unlock_irqrestore(&timer_lock, flags);
3709     +}
3710     +
3711     +
3712     +static void it87_interrupt(int irq,
3713     + void * dev_id,
3714     + struct pt_regs * regs)
3715     +{
3716     + unsigned char data;
3717     + struct timeval curr_tv;
3718     + static unsigned long deltv;
3719     + unsigned long deltintrtv;
3720     + unsigned long flags, hw_flags;
3721     + int iir, lsr;
3722     + int fifo = 0;
3723     +
3724     + iir = inb(io + IT87_CIR_IIR);
3725     +
3726     + switch (iir & IT87_CIR_IIR_IID) {
3727     + case 0x4:
3728     + case 0x6:
3729     + lsr = inb(io + IT87_CIR_RSR) & (IT87_CIR_RSR_RXFTO |
3730     + IT87_CIR_RSR_RXFBC);
3731     + fifo = lsr & IT87_CIR_RSR_RXFBC;
3732     +#ifdef DEBUG_SIGNAL
3733     + printk(KERN_DEBUG LIRC_DRIVER_NAME
3734     + "iir: 0x%x fifo: 0x%x\n", iir, lsr);
3735     +#endif
3736     +
3737     + /* avoid interference with timer */
3738     + spin_lock_irqsave(&timer_lock, flags);
3739     + spin_lock_irqsave(&hardware_lock, hw_flags);
3740     + do {
3741     + del_timer(&timerlist);
3742     + data = inb(io + IT87_CIR_DR);
3743