1 diff -uNr linux-2.6.8-rc4.orig/drivers/char/Kconfig linux-2.6.8-rc4/drivers/char/Kconfig
2 --- linux-2.6.8-rc4.orig/drivers/char/Kconfig 2004-08-10 09:33:29.000000000 +0200
3 +++ linux-2.6.8-rc4/drivers/char/Kconfig 2004-08-10 10:22:53.524975088 +0200
5 source "drivers/serial/Kconfig"
8 +source "drivers/char/lirc/Kconfig"
11 bool "Unix98 PTY support" if EMBEDDED
12 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/Kconfig linux-2.6.8-rc4/drivers/char/lirc/Kconfig
13 --- linux-2.6.8-rc4.orig/drivers/char/lirc/Kconfig 1970-01-01 01:00:00.000000000 +0100
14 +++ linux-2.6.8-rc4/drivers/char/lirc/Kconfig 2004-08-10 10:21:59.728153448 +0200
16 +menu "Linux InfraRed Controller"
19 + tristate "Linux InfraRed Controller"
22 + int "Maximum LIRC devices"
24 + depends on LIRC_SUPPORT
26 + config LIRC_IRCTL_DEV_MAJOR
27 + int "Major device number"
29 + depends on LIRC_SUPPORT
32 + tristate "I2C Driver"
33 + depends on LIRC_SUPPORT && VIDEO_BT848 && I2C && I2C_ALGOBIT
35 + Say Y here if you need support for the following cards:
43 + If these dont make sense to you, then dont use the module.
46 + tristate "GPIO Driver"
47 + depends on LIRC_SUPPORT && VIDEO_BT848
50 + tristate "BT829 Driver"
51 + depends on LIRC_SUPPORT
54 + tristate "IT87 Driver"
55 + depends on LIRC_SUPPORT
58 + tristate "ATI USB Driver"
59 + depends on LIRC_SUPPORT && USB
62 + tristate "MCE USB Driver"
63 + depends on LIRC_SUPPORT && USB
66 + tristate "USB Driver for Sasem Remote Controller"
67 + depends on LIRC_SUPPORT && USB
69 + config LIRC_PARALLEL
70 + tristate "Parallel Driver"
71 + depends on LIRC_SUPPORT && !SMP && PARPORT
74 + prompt "Parallel Port"
75 + depends on LIRC_PARALLEL
76 + config LIRC_PARALLEL_LPT1
77 + bool "LPT1 (0x378, 7)"
78 + config LIRC_PARALLEL_LPT2
79 + bool "LPT2 (0x278, 5)"
80 + config LIRC_PARALLEL_LPT3
81 + bool "COM3 (0x3bc, none)"
82 + config LIRC_PARALLEL_OTHER
83 + bool "Other (custom values)"
86 + config LIRC_PORT_PARALLEL
88 + default "0x378" if LIRC_PARALLEL_LPT1
89 + default "0x278" if LIRC_PARALLEL_LPT2
90 + default "0x3bc" if LIRC_PARALLEL_LPT3
91 + depends on LIRC_PARALLEL
93 + config LIRC_IRQ_PARALLEL
95 + default "7" if LIRC_PARALLEL_LPT1
96 + default "5" if LIRC_PARALLEL_LPT2
97 + depends on LIRC_PARALLEL
102 + depends on LIRC_PARALLEL
105 + tristate "Serial Driver"
106 + depends on LIRC_SUPPORT && SERIAL_8250
109 + prompt "Serial Receiver Type"
110 + depends on LIRC_SERIAL
112 + config LIRC_HOMEBREW
115 + config LIRC_SERIAL_ANIMAX
118 + config LIRC_SERIAL_IRDEO
121 + config LIRC_SERIAL_IRDEO_REMOTE
122 + bool "IRdeo Remote"
126 + config LIRC_SERIAL_TRANSMITTER
127 + bool "With transmitter diode"
128 + depends on LIRC_SERIAL && !LIRC_SERIAL_ANIMAX
130 + config LIRC_SERIAL_SOFTCARRIER
131 + bool "With software carrier"
132 + depends on LIRC_SERIAL_TRANSMITTER
134 + config LIRC_SERIAL_IGOR
135 + bool "Igor Ceska's variation"
136 + depends on LIRC_SERIAL
139 + prompt "Serial Port"
140 + depends on LIRC_SERIAL
141 + config LIRC_SERIAL_COM1
142 + bool "COM1 (0x3f8, 4)"
143 + config LIRC_SERIAL_COM2
144 + bool "COM2 (0x2f8, 3)"
145 + config LIRC_SERIAL_COM3
146 + bool "COM3 (0x3e8, 4)"
147 + config LIRC_SERIAL_COM4
148 + bool "COM4 (0x2e8, 3)"
149 + config LIRC_SERIAL_OTHER
150 + bool "Other (custom values)"
153 + config LIRC_PORT_SERIAL
155 + default "0x3f8" if LIRC_SERIAL_COM1
156 + default "0x2f8" if LIRC_SERIAL_COM2
157 + default "0x3e8" if LIRC_SERIAL_COM3
158 + default "0x2e8" if LIRC_SERIAL_COM4
159 + depends on LIRC_SERIAL
161 + config LIRC_IRQ_SERIAL
163 + default "4" if LIRC_SERIAL_COM1 || LIRC_SERIAL_COM3
164 + default "3" if LIRC_SERIAL_COM2 || LIRC_SERIAL_COM4
165 + depends on LIRC_SERIAL
168 + tristate "SIR Driver"
169 + depends on LIRC_SUPPORT
171 + config LIRC_ON_SA1100
172 + bool "LIRC driver for StrongARM SA1100 embedded microprocessor"
173 + depends on LIRC_SIR
177 + depends on LIRC_SIR && !LIRC_ON_SA1100
179 + config LIRC_SIR_IRDA
180 + bool "SIR IrDA (built-in IR ports)"
182 + config LIRC_SIR_TEKRAM
183 + bool "Tekram Irmate 210 (16x50 UART compatible serial port)"
185 + config LIRC_SIR_ACTISYS_ACT200L
186 + bool "Actisys Act200L SIR driver support"
191 + prompt "Serial Port"
192 + depends on LIRC_SIR
193 + config LIRC_SIR_COM1
194 + bool "COM1 (0x3f8, 4)"
195 + config LIRC_SIR_COM2
196 + bool "COM2 (0x2f8, 3)"
197 + config LIRC_SIR_COM3
198 + bool "COM3 (0x3e8, 4)"
199 + config LIRC_SIR_COM4
200 + bool "COM4 (0x2e8, 3)"
201 + config LIRC_SIR_OTHER
202 + bool "Other (custom values)"
205 + config LIRC_PORT_SIR
207 + default "0x3f8" if LIRC_SIR_COM1
208 + default "0x2f8" if LIRC_SIR_COM2
209 + default "0x3e8" if LIRC_SIR_COM3
210 + default "0x2e8" if LIRC_SIR_COM4
211 + depends on LIRC_SIR
213 + config LIRC_IRQ_SIR
215 + default "4" if LIRC_SIR_COM1 || LIRC_SIR_COM3
216 + default "3" if LIRC_SIR_COM2 || LIRC_SIR_COM4
217 + depends on LIRC_SIR
220 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_atiusb.c linux-2.6.8-rc4/drivers/char/lirc/lirc_atiusb.c
221 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_atiusb.c 1970-01-01 01:00:00.000000000 +0100
222 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_atiusb.c 2004-06-13 16:33:11.000000000 +0200
224 +/* lirc_atiusb - USB remote support for LIRC
225 + * (currently only supports X10 USB remotes)
227 + * Copyright (C) 2003-2004 Paul Miller <pmiller9@users.sourceforge.net>
229 + * This driver was derived from:
230 + * Vladimir Dergachev <volodya@minspring.com>'s 2002
231 + * "USB ATI Remote support" (input device)
232 + * Adrian Dewhurst <sailor-lk@sailorfrag.net>'s 2002
233 + * "USB StreamZap remote driver" (LIRC)
234 + * Artur Lipowski <alipowski@kki.net.pl>'s 2002
235 + * "lirc_dev" and "lirc_gpio" LIRC modules
241 + * This program is free software; you can redistribute it and/or modify
242 + * it under the terms of the GNU General Public License as published by
243 + * the Free Software Foundation; either version 2 of the License, or
244 + * (at your option) any later version.
246 + * This program is distributed in the hope that it will be useful,
247 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
248 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
249 + * GNU General Public License for more details.
251 + * You should have received a copy of the GNU General Public License
252 + * along with this program; if not, write to the Free Software
253 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
257 +#include <linux/version.h>
258 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 4)
259 +#error "*******************************************************"
260 +#error "Sorry, this driver needs kernel version 2.2.4 or higher"
261 +#error "*******************************************************"
264 +#include <linux/config.h>
266 +#include <linux/kernel.h>
267 +#include <linux/errno.h>
268 +#include <linux/init.h>
269 +#include <linux/slab.h>
270 +#include <linux/module.h>
271 +#include <linux/kmod.h>
272 +#include <linux/smp_lock.h>
273 +#include <linux/completion.h>
274 +#include <asm/uaccess.h>
275 +#include <linux/usb.h>
276 +#include <linux/poll.h>
277 +#include <linux/wait.h>
279 +#include <linux/lirc.h>
280 +#include "kcompat.h"
281 +#include "lirc_dev.h"
283 +#define DRIVER_VERSION "0.4"
284 +#define DRIVER_AUTHOR "Paul Miller <pmiller9@users.sourceforge.net>"
285 +#define DRIVER_DESC "USB remote driver for LIRC"
286 +#define DRIVER_NAME "lirc_atiusb"
288 +#define CODE_LENGTH 5
289 +#define CODE_MIN_LENGTH 4
290 +#define USB_BUFLEN (CODE_LENGTH*4)
292 +/* module parameters */
293 +#ifdef CONFIG_USB_DEBUG
294 + static int debug = 1;
296 + static int debug = 0;
298 +#define dprintk if (debug) printk
299 +static int mask = 0xFFFF; // channel acceptance bit mask
300 +static int unique = 0; // enable channel-specific codes
301 +static int repeat = 10; // repeat time in 1/100 sec
302 +static unsigned long repeat_jiffies; // repeat timeout
304 +/* get hi and low bytes of a 16-bits int */
305 +#define HI(a) ((unsigned char)((a) >> 8))
306 +#define LO(a) ((unsigned char)((a) & 0xff))
308 +/* lock irctl structure */
309 +#define IRLOCK down_interruptible(&ir->lock)
310 +#define IRUNLOCK up(&ir->lock)
312 +/* general constants */
314 +#define SEND_FLAG_IN_PROGRESS 1
315 +#define SEND_FLAG_COMPLETE 2
318 +/* data structure for each usb remote */
322 + struct usb_device *usbdev;
323 + struct urb *urb_in;
324 + struct urb *urb_out;
327 + /* buffers and dma */
328 + unsigned char *buf_in;
329 + unsigned char *buf_out;
330 + unsigned int len_in;
333 + dma_addr_t dma_out;
336 + /* handle repeats */
337 + unsigned char old[CODE_LENGTH];
338 + unsigned long old_jiffies;
341 + struct lirc_plugin *p;
344 + /* handle sending (init strings) */
346 + wait_queue_head_t wait_out;
348 + struct semaphore lock;
352 +static char init1[] = {0x01, 0x00, 0x20, 0x14};
353 +static char init2[] = {0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20};
355 +/* send packet - used to initialize remote */
356 +static void send_packet(struct irctl *ir, u16 cmd, unsigned char *data)
358 + DECLARE_WAITQUEUE(wait, current);
359 + int timeout = HZ; /* 1 second */
360 + unsigned char buf[USB_BUFLEN];
362 + dprintk(DRIVER_NAME "[%d]: send called (%#x)\n", ir->devnum, cmd);
365 + ir->urb_out->transfer_buffer_length = LO(cmd) + 1;
366 + ir->urb_out->dev = ir->usbdev;
367 + ir->send_flags = SEND_FLAG_IN_PROGRESS;
369 + memcpy(buf+1, data, LO(cmd));
371 + memcpy(ir->buf_out, buf, LO(cmd)+1);
373 + set_current_state(TASK_INTERRUPTIBLE);
374 + add_wait_queue(&ir->wait_out, &wait);
377 + if (usb_submit_urb(ir->urb_out, SLAB_ATOMIC)) {
379 + if (usb_submit_urb(ir->urb_out)) {
381 + set_current_state(TASK_RUNNING);
382 + remove_wait_queue(&ir->wait_out, &wait);
388 + while (timeout && (ir->urb_out->status == -EINPROGRESS)
389 + && !(ir->send_flags & SEND_FLAG_COMPLETE)) {
390 + timeout = schedule_timeout(timeout);
394 + dprintk(DRIVER_NAME "[%d]: send complete (%#x)\n", ir->devnum, cmd);
396 + set_current_state(TASK_RUNNING);
397 + remove_wait_queue(&ir->wait_out, &wait);
398 + usb_unlink_urb(ir->urb_out);
401 +static int unregister_from_lirc(struct irctl *ir)
403 + struct lirc_plugin *p = ir->p;
407 + devnum = ir->devnum;
408 + dprintk(DRIVER_NAME "[%d]: unregister from lirc called\n", devnum);
410 + if ((rtn = lirc_unregister_plugin(p->minor)) > 0) {
411 + printk(DRIVER_NAME "[%d]: error in lirc_unregister minor: %d\n"
412 + "Trying again...\n", devnum, p->minor);
413 + if (rtn == -EBUSY) {
415 + "[%d]: device is opened, will unregister"
416 + " on close\n", devnum);
419 + set_current_state(TASK_INTERRUPTIBLE);
420 + schedule_timeout(HZ);
422 + if ((rtn = lirc_unregister_plugin(p->minor)) > 0) {
423 + printk(DRIVER_NAME "[%d]: lirc_unregister failed\n",
428 + if (rtn != SUCCESS) {
429 + printk(DRIVER_NAME "[%d]: didn't free resources\n", devnum);
433 + printk(DRIVER_NAME "[%d]: usb remote disconnected\n", devnum);
435 + lirc_buffer_free(p->rbuf);
442 +static int set_use_inc(void *data)
444 + struct irctl *ir = data;
447 + printk(DRIVER_NAME "[?]: set_use_inc called with no context\n");
450 + dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum);
454 + if (!ir->connected) {
457 + ir->urb_in->dev = ir->usbdev;
459 + if (usb_submit_urb(ir->urb_in, SLAB_ATOMIC)) {
461 + if (usb_submit_urb(ir->urb_in)) {
463 + printk(DRIVER_NAME "[%d]: open result = -EIO error "
464 + "submitting urb\n", ir->devnum);
474 +static void set_use_dec(void *data)
476 + struct irctl *ir = data;
479 + printk(DRIVER_NAME "[?]: set_use_dec called with no context\n");
482 + dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum);
484 + if (ir->connected) {
486 + usb_unlink_urb(ir->urb_in);
493 +static void usb_remote_printdata(struct irctl *ir, char *buf, int len)
495 + char codes[USB_BUFLEN*3 + 1];
501 + for (i = 0; i < len && i < USB_BUFLEN; i++) {
502 + snprintf(codes+i*3, 4, "%02x ", buf[i] & 0xFF);
504 + printk(DRIVER_NAME "[%d]: data received %s (length=%d)\n",
505 + ir->devnum, codes, len);
509 +static void usb_remote_recv(struct urb *urb, struct pt_regs *regs)
511 +static void usb_remote_recv(struct urb *urb)
521 + if (!(ir = urb->context)) {
522 + usb_unlink_urb(urb);
526 + len = urb->actual_length;
528 + usb_remote_printdata(ir,urb->transfer_buffer,len);
530 + switch (urb->status) {
534 + /* some remotes emit both 4 and 5 byte length codes. */
535 + if (len < CODE_MIN_LENGTH || len > CODE_LENGTH)
538 + // *** channel not tested with 4/5-byte Dutch remotes ***
539 + chan = ((ir->buf_in[len-1]>>4) & 0x0F);
540 + if ( !((1<<chan) & mask) ) {
541 + dprintk(DRIVER_NAME "[%d]: ignore channel %d\n",
542 + ir->devnum, chan+1);
546 + dprintk(DRIVER_NAME "[%d]: accept channel %d\n",
547 + ir->devnum, chan+1);
549 + /* strip channel code */
551 + ir->buf_in[len-1] &= 0x0F;
553 + /* check for repeats */
554 + if (memcmp(ir->old, ir->buf_in, len) == 0) {
555 + if (ir->old_jiffies + repeat_jiffies > jiffies) {
559 + memcpy(ir->old, ir->buf_in, len);
560 + for (i = len; i < CODE_LENGTH; i++) ir->old[i] = 0;
562 + ir->old_jiffies = jiffies;
564 + lirc_buffer_write_1(ir->p->rbuf, ir->old);
565 + wake_up(&ir->p->rbuf->wait_poll);
572 + usb_unlink_urb(urb);
578 + usb_submit_urb(urb, SLAB_ATOMIC);
580 + usb_submit_urb(urb);
585 +static void usb_remote_send(struct urb *urb, struct pt_regs *regs)
587 +static void usb_remote_send(struct urb *urb)
595 + if (!(ir = urb->context)) {
596 + usb_unlink_urb(urb);
600 + dprintk(DRIVER_NAME "[%d]: usb out called\n", ir->devnum);
605 + ir->send_flags |= SEND_FLAG_COMPLETE;
607 + if (waitqueue_active(&ir->wait_out))
608 + wake_up(&ir->wait_out);
612 +static int usb_remote_probe(struct usb_interface *intf,
613 + const struct usb_device_id *id)
615 + struct usb_device *dev = NULL;
616 + struct usb_host_interface *idesc = NULL;
618 +static void *usb_remote_probe(struct usb_device *dev, unsigned int ifnum,
619 + const struct usb_device_id *id)
621 + struct usb_interface *intf;
622 + struct usb_interface_descriptor *idesc;
624 + struct usb_endpoint_descriptor *ep_in, *ep_out;
625 + struct irctl *ir = NULL;
626 + struct lirc_plugin *plugin = NULL;
627 + struct lirc_buffer *rbuf = NULL;
628 + int devnum, pipe, maxp, len, buf_len, bytes_in_key;
630 + char buf[63], name[128]="";
631 + int mem_failure = 0;
633 + dprintk(DRIVER_NAME ": usb probe called\n");
636 + dev = interface_to_usbdev(intf);
637 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,4)
638 + idesc = intf->cur_altsetting;
640 + idesc = &intf->altsetting[intf->act_altsetting];
642 + if (idesc->desc.bNumEndpoints != 2)
644 + ep_in = &idesc->endpoint[0].desc;
645 + ep_out = &idesc->endpoint[1].desc;
646 + if (((ep_in->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)
647 + || (ep_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
648 + != USB_ENDPOINT_XFER_INT)
651 + intf = &dev->actconfig->interface[ifnum];
652 + idesc = &intf->altsetting[intf->act_altsetting];
653 + if (idesc->bNumEndpoints != 2)
655 + ep_in = idesc->endpoint + 0;
656 + ep_out = idesc->endpoint + 1;
657 + if (((ep_in->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)
658 + || (ep_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
659 + != USB_ENDPOINT_XFER_INT)
662 + devnum = dev->devnum;
663 + pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress);
664 + maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
666 + bytes_in_key = CODE_LENGTH;
667 + len = (maxp > USB_BUFLEN) ? USB_BUFLEN : maxp;
668 + buf_len = len - (len % bytes_in_key);
670 + dprintk(DRIVER_NAME "[%d]: bytes_in_key=%d len=%d maxp=%d buf_len=%d\n",
671 + devnum, bytes_in_key, len, maxp, buf_len);
674 + /* allocate kernel memory */
676 + if (!(ir = kmalloc(sizeof(struct irctl), GFP_KERNEL))) {
679 + memset(ir, 0, sizeof(struct irctl));
681 + if (!(plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL))) {
683 + } else if (!(rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL))) {
685 + } else if (lirc_buffer_init(rbuf, bytes_in_key, USB_BUFLEN/bytes_in_key)) {
688 + } else if (!(ir->buf_in = usb_buffer_alloc(dev, buf_len, SLAB_ATOMIC, &ir->dma_in))) {
690 + } else if (!(ir->buf_out = usb_buffer_alloc(dev, USB_BUFLEN, SLAB_ATOMIC, &ir->dma_out))) {
692 + } else if (!(ir->urb_in = usb_alloc_urb(0, GFP_KERNEL))) {
694 + } else if (!(ir->urb_out = usb_alloc_urb(0, GFP_KERNEL))) {
697 + } else if (!(ir->buf_in = kmalloc(buf_len, GFP_KERNEL))) {
699 + } else if (!(ir->buf_out = kmalloc(USB_BUFLEN, GFP_KERNEL))) {
701 + } else if (!(ir->urb_in = usb_alloc_urb(0))) {
703 + } else if (!(ir->urb_out = usb_alloc_urb(0))) {
708 + memset(plugin, 0, sizeof(struct lirc_plugin));
710 + strcpy(plugin->name, DRIVER_NAME " ");
711 + plugin->minor = -1;
712 + plugin->code_length = bytes_in_key*8;
713 + plugin->features = LIRC_CAN_REC_LIRCCODE;
715 + plugin->rbuf = rbuf;
716 + plugin->set_use_inc = &set_use_inc;
717 + plugin->set_use_dec = &set_use_dec;
719 + init_MUTEX(&ir->lock);
720 + init_waitqueue_head(&ir->wait_out);
722 + if ((minor = lirc_register_plugin(plugin)) < 0) {
728 + /* free allocated memory incase of failure */
729 + switch (mem_failure) {
731 + lirc_buffer_free(rbuf);
733 + usb_free_urb(ir->urb_out);
735 + usb_free_urb(ir->urb_in);
738 + usb_buffer_free(dev, USB_BUFLEN, ir->buf_out, ir->dma_out);
740 + usb_buffer_free(dev, buf_len, ir->buf_in, ir->dma_in);
743 + kfree(ir->buf_out);
754 + printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n",
755 + devnum, mem_failure);
763 + plugin->minor = minor;
765 + ir->devnum = devnum;
767 + ir->len_in = buf_len;
770 + usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in,
771 + buf_len, usb_remote_recv, ir, ep_in->bInterval);
772 + usb_fill_int_urb(ir->urb_out, dev,
773 + usb_sndintpipe(dev, ep_out->bEndpointAddress), ir->buf_out,
774 + USB_BUFLEN, usb_remote_send, ir, ep_out->bInterval);
776 + if (dev->descriptor.iManufacturer
777 + && usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0)
778 + strncpy(name, buf, 128);
779 + if (dev->descriptor.iProduct
780 + && usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0)
781 + snprintf(name, 128, "%s %s", name, buf);
782 + printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name,
783 + dev->bus->busnum, devnum);
785 + send_packet(ir, 0x8004, init1);
786 + send_packet(ir, 0x8007, init2);
789 + usb_set_intfdata(intf, ir);
798 +static void usb_remote_disconnect(struct usb_interface *intf)
800 + struct usb_device *dev = interface_to_usbdev(intf);
801 + struct irctl *ir = usb_get_intfdata(intf);
802 + usb_set_intfdata(intf, NULL);
804 +static void usb_remote_disconnect(struct usb_device *dev, void *ptr)
806 + struct irctl *ir = ptr;
813 + wake_up_all(&ir->wait_out);
816 + usb_unlink_urb(ir->urb_in);
817 + usb_unlink_urb(ir->urb_out);
818 + usb_free_urb(ir->urb_in);
819 + usb_free_urb(ir->urb_out);
821 + usb_buffer_free(dev, ir->len_in, ir->buf_in, ir->dma_in);
822 + usb_buffer_free(dev, USB_BUFLEN, ir->buf_out, ir->dma_out);
825 + kfree(ir->buf_out);
829 + unregister_from_lirc(ir);
832 +static struct usb_device_id usb_remote_id_table [] = {
833 + { USB_DEVICE(0x0bc7, 0x0002) }, /* X10 USB Firecracker Interface */
834 + { USB_DEVICE(0x0bc7, 0x0003) }, /* X10 VGA Video Sender */
835 + { USB_DEVICE(0x0bc7, 0x0004) }, /* ATI Wireless Remote Receiver */
836 + { USB_DEVICE(0x0bc7, 0x0005) }, /* NVIDIA Wireless Remote Receiver */
837 + { USB_DEVICE(0x0bc7, 0x0006) }, /* ATI Wireless Remote Receiver */
838 + { USB_DEVICE(0x0bc7, 0x0007) }, /* X10 USB Wireless Transceiver */
839 + { USB_DEVICE(0x0bc7, 0x0008) }, /* X10 USB Wireless Transceiver */
840 + { USB_DEVICE(0x0bc7, 0x0009) }, /* X10 USB Wireless Transceiver */
841 + { USB_DEVICE(0x0bc7, 0x000A) }, /* X10 USB Wireless Transceiver */
842 + { USB_DEVICE(0x0bc7, 0x000B) }, /* X10 USB Transceiver */
843 + { USB_DEVICE(0x0bc7, 0x000C) }, /* X10 USB Transceiver */
844 + { USB_DEVICE(0x0bc7, 0x000D) }, /* X10 USB Transceiver */
845 + { USB_DEVICE(0x0bc7, 0x000E) }, /* X10 USB Transceiver */
846 + { USB_DEVICE(0x0bc7, 0x000F) }, /* X10 USB Transceiver */
848 + { } /* Terminating entry */
851 +static struct usb_driver usb_remote_driver = {
852 + .owner = THIS_MODULE,
853 + .name = DRIVER_NAME,
854 + .probe = usb_remote_probe,
855 + .disconnect = usb_remote_disconnect,
856 + .id_table = usb_remote_id_table
859 +static int __init usb_remote_init(void)
863 + printk("\n" DRIVER_NAME ": " DRIVER_DESC " v" DRIVER_VERSION "\n");
864 + printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n");
865 + dprintk(DRIVER_NAME ": debug mode enabled\n");
867 + request_module("lirc_dev");
869 + repeat_jiffies = repeat*HZ/100;
871 + if ((i = usb_register(&usb_remote_driver)) < 0) {
872 + printk(DRIVER_NAME ": usb register failed, result = %d\n", i);
879 +static void __exit usb_remote_exit(void)
881 + usb_deregister(&usb_remote_driver);
884 +module_init(usb_remote_init);
885 +module_exit(usb_remote_exit);
887 +MODULE_AUTHOR (DRIVER_AUTHOR);
888 +MODULE_DESCRIPTION (DRIVER_DESC);
889 +MODULE_LICENSE ("GPL");
890 +MODULE_DEVICE_TABLE (usb, usb_remote_id_table);
892 +MODULE_PARM(debug, "i");
893 +MODULE_PARM_DESC(debug, "enable driver debug mode");
894 +MODULE_PARM(mask, "i");
895 +MODULE_PARM_DESC(mask, "set channel acceptance bit mask");
896 +MODULE_PARM(unique, "i");
897 +MODULE_PARM_DESC(unique, "enable channel-specific codes");
898 +MODULE_PARM(repeat, "i");
899 +MODULE_PARM_DESC(repeat, "repeat timeout (1/100 sec)");
905 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_bt829.c linux-2.6.8-rc4/drivers/char/lirc/lirc_bt829.c
906 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_bt829.c 1970-01-01 01:00:00.000000000 +0100
907 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_bt829.c 2004-04-27 20:45:34.000000000 +0200
910 + * Remote control driver for the TV-card based on bt829
912 + * by Leonid Froenchenko <lfroen@galileo.co.il>
914 + * This program is free software; you can redistribute it and/or modify
915 + * it under the terms of the GNU General Public License as published by
916 + * the Free Software Foundation; either version 2 of the License, or
917 + * (at your option) any later version.
919 + * This program is distributed in the hope that it will be useful,
920 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
921 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
922 + * GNU General Public License for more details.
924 + * You should have received a copy of the GNU General Public License
925 + * along with this program; if not, write to the Free Software
926 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
929 +#include <linux/version.h>
930 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
931 +#error "This driver needs kernel version 2.4.0 or higher"
934 +#include <linux/config.h>
935 +#include <linux/kernel.h>
936 +#include <linux/module.h>
937 +#include <linux/threads.h>
938 +#include <linux/sched.h>
939 +#include <linux/ioport.h>
940 +#include <linux/pci.h>
941 +#include <linux/delay.h>
943 +#include "kcompat.h"
944 +#include "lirc_dev.h"
948 +MODULE_AUTHOR("Froenchenko Leonid");
949 +MODULE_DESCRIPTION("IR remote driver for bt829 based TV cards");
952 +int poll_main(void);
953 +int atir_init_start(void);
955 +void write_index(unsigned char index,unsigned int value);
956 +unsigned int read_index(unsigned char index);
958 +void do_i2c_start(void);
959 +void do_i2c_stop(void);
961 +void seems_wr_byte(unsigned char al);
962 +unsigned char seems_rd_byte(void);
964 +unsigned int read_index(unsigned char al);
965 +void write_index(unsigned char ah,unsigned int edx);
967 +void cycle_delay(int cycle);
969 +void do_set_bits(unsigned char bl);
970 +unsigned char do_get_bits(void);
972 +#define DATA_PCI_OFF 0x7FFC00
973 +#define WAIT_CYCLE 20
977 +unsigned long pci_addr_phys, pci_addr_lin;
979 +struct lirc_plugin atir_plugin;
981 +int do_pci_probe(void)
983 + struct pci_dev *my_dev;
985 + /* unnecessary with recent kernels */
986 + if ( !pci_present() ) {
987 + printk(KERN_ERR "ATIR: no pci in this kernel\n");
990 + my_dev = (struct pci_dev *)pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_264VT,NULL);
992 + printk(KERN_ERR "ATIR: Using device: %s\n",
993 + pci_pretty_name(my_dev));
995 + if ( my_dev->resource[0].flags & IORESOURCE_MEM ) {
996 + pci_addr_phys = my_dev->resource[0].start;
997 + printk(KERN_INFO "ATIR memory at 0x%08X \n",(unsigned int)pci_addr_phys);
999 + if ( pci_addr_phys == 0 ) {
1000 + printk(KERN_ERR "ATIR no memory resource ?\n");
1004 + printk(KERN_ERR "ATIR: pci_prob failed\n");
1011 +int atir_add_to_buf (void* data, struct lirc_buffer* buf)
1013 + unsigned char key;
1015 + status = poll_main();
1016 + key = (status >> 8) & 0xFF;
1017 + if( status & 0xFF )
1019 + // printk(KERN_INFO "ATIR reading key %02X\n",*key);
1020 + lirc_buffer_write_1( buf, &key );
1026 +int atir_set_use_inc(void* data)
1028 + MOD_INC_USE_COUNT;
1029 + printk(KERN_DEBUG "ATIR driver is opened\n");
1033 +void atir_set_use_dec(void* data)
1035 + MOD_DEC_USE_COUNT;
1036 + printk(KERN_DEBUG "ATIR driver is closed\n");
1039 +int init_module(void)
1041 + if ( !do_pci_probe() ) {
1045 + if ( !atir_init_start() ) {
1049 + strcpy(atir_plugin.name,"ATIR");
1050 + atir_plugin.minor = -1;
1051 + atir_plugin.code_length = 8;
1052 + atir_plugin.sample_rate = 10;
1053 + atir_plugin.data = 0;
1054 + atir_plugin.add_to_buf = atir_add_to_buf;
1055 + atir_plugin.set_use_inc = atir_set_use_inc;
1056 + atir_plugin.set_use_dec = atir_set_use_dec;
1058 + atir_minor = lirc_register_plugin(&atir_plugin);
1059 + printk(KERN_DEBUG "ATIR driver is registered on minor %d\n",atir_minor);
1065 +void cleanup_module(void)
1067 + lirc_unregister_plugin(atir_minor);
1071 +int atir_init_start(void)
1073 + pci_addr_lin = (unsigned long)ioremap(pci_addr_phys + DATA_PCI_OFF,0x400);
1074 + if ( pci_addr_lin == 0 ) {
1075 + printk(KERN_INFO "atir: pci mem must be mapped\n");
1081 +void cycle_delay(int cycle)
1083 + udelay(WAIT_CYCLE*cycle);
1089 + unsigned char status_high, status_low;
1093 + seems_wr_byte(0xAA);
1094 + seems_wr_byte(0x01);
1098 + seems_wr_byte(0xAB);
1100 + status_low = seems_rd_byte();
1101 + status_high = seems_rd_byte();
1105 + return (status_high << 8) | status_low;
1108 +void do_i2c_start(void)
1120 +void do_i2c_stop(void)
1122 + unsigned char bits;
1123 + bits = do_get_bits() & 0xFD;
1124 + do_set_bits(bits);
1128 + do_set_bits(bits);
1132 + do_set_bits(bits);
1134 + do_set_bits(bits);
1139 +void seems_wr_byte(unsigned char value)
1142 + unsigned char reg;
1144 + reg = do_get_bits();
1145 + for(i = 0;i < 8;i++) {
1146 + if ( value & 0x80 ) {
1179 +unsigned char seems_rd_byte(void)
1183 + unsigned char bits_2, bits_1;
1185 + bits_1 = do_get_bits() | 2;
1186 + do_set_bits(bits_1);
1189 + for(i = 0;i < 8;i++) {
1191 + do_set_bits(bits_1);
1195 + do_set_bits(bits_1);
1198 + if ( (bits_2 = do_get_bits()) & 2 ) {
1205 + if ( bits_2 == 0 ) {
1208 + do_set_bits(bits_1);
1212 + do_set_bits(bits_1);
1216 + do_set_bits(bits_1);
1224 +void do_set_bits(unsigned char new_bits)
1227 + reg_val = read_index(0x34);
1228 + if ( new_bits & 2 ) {
1229 + reg_val &= 0xFFFFFFDF;
1232 + reg_val &= 0xFFFFFFFE;
1236 + write_index(0x34,reg_val);
1238 + reg_val = read_index(0x31);
1239 + if ( new_bits & 1 ) {
1240 + reg_val |= 0x1000000;
1242 + reg_val &= 0xFEFFFFFF;
1244 + reg_val |= 0x8000000;
1245 + write_index(0x31,reg_val);
1248 +unsigned char do_get_bits(void)
1250 + unsigned char bits;
1253 + reg_val = read_index(0x34);
1255 + reg_val &= 0xFFFFFFDF;
1256 + write_index(0x34,reg_val);
1258 + reg_val = read_index(0x34);
1260 + if ( reg_val & 8 ) {
1265 + reg_val = read_index(0x31);
1266 + if ( reg_val & 0x1000000 ) {
1274 +unsigned int read_index(unsigned char index)
1276 + unsigned int addr, value;
1277 + // addr = pci_addr_lin + DATA_PCI_OFF + ((index & 0xFF) << 2);
1278 + addr = pci_addr_lin + ((index & 0xFF) << 2);
1279 + value = readl(addr);
1283 +void write_index(unsigned char index,unsigned int reg_val)
1285 + unsigned int addr;
1286 + addr = pci_addr_lin + ((index & 0xFF) << 2);
1287 + writel(reg_val,addr);
1292 + * Overrides for Emacs so that we follow Linus's tabbing style.
1293 + * ---------------------------------------------------------------------------
1294 + * Local variables:
1295 + * c-basic-offset: 8
1298 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_dev.c linux-2.6.8-rc4/drivers/char/lirc/lirc_dev.c
1299 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_dev.c 1970-01-01 01:00:00.000000000 +0100
1300 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_dev.c 2004-04-08 23:17:46.000000000 +0200
1303 + * LIRC base driver
1305 + * (L) by Artur Lipowski <alipowski@interia.pl>
1307 + * This program is free software; you can redistribute it and/or modify
1308 + * it under the terms of the GNU General Public License as published by
1309 + * the Free Software Foundation; either version 2 of the License, or
1310 + * (at your option) any later version.
1312 + * This program is distributed in the hope that it will be useful,
1313 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1314 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1315 + * GNU General Public License for more details.
1317 + * You should have received a copy of the GNU General Public License
1318 + * along with this program; if not, write to the Free Software
1319 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1325 +#ifdef HAVE_CONFIG_H
1326 +# include <config.h>
1329 +#include <linux/version.h>
1330 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1331 +#define LIRC_HAVE_DEVFS
1333 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
1334 +#warning "**********************************************************"
1335 +#warning "************ disabling devfs for 2.6 kernels *************"
1336 +#warning "**********************************************************"
1337 +#undef LIRC_HAVE_DEVFS
1340 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
1341 +#error "**********************************************************"
1342 +#error " Sorry, this driver needs kernel version 2.2.18 or higher "
1343 +#error "**********************************************************"
1346 +#include <linux/config.h>
1347 +#include <linux/module.h>
1348 +#include <linux/kernel.h>
1349 +#include <linux/sched.h>
1350 +#include <linux/errno.h>
1351 +#include <linux/ioctl.h>
1352 +#include <linux/fs.h>
1353 +#include <linux/poll.h>
1354 +#ifdef LIRC_HAVE_DEVFS
1355 +#include <linux/devfs_fs_kernel.h>
1357 +#include <linux/smp_lock.h>
1358 +#include <asm/uaccess.h>
1359 +#include <asm/semaphore.h>
1360 +#include <asm/errno.h>
1361 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
1362 +#include <linux/wrapper.h>
1364 +#define __KERNEL_SYSCALLS__
1365 +#include <linux/unistd.h>
1367 +#include "kcompat.h"
1368 +#include <linux/lirc.h>
1370 +#include "lirc_dev.h"
1372 +static int debug = 0;
1374 +MODULE_PARM(debug,"i");
1376 +#define IRCTL_DEV_NAME "BaseRemoteCtl"
1379 +#define dprintk if (debug) printk
1381 +#define LOGHEAD "lirc_dev (%s[%d]): "
1385 + struct lirc_plugin p;
1388 + struct lirc_buffer *buf;
1391 + struct semaphore *t_notify;
1392 + struct semaphore *t_notify2;
1394 + long jiffies_to_wait;
1396 +#ifdef LIRC_HAVE_DEVFS
1397 + devfs_handle_t devfs_handle;
1401 +DECLARE_MUTEX(plugin_lock);
1403 +static struct irctl irctls[MAX_IRCTL_DEVICES];
1404 +static struct file_operations fops;
1408 + * initializes the irctl structure
1410 +static inline void init_irctl(struct irctl *ir)
1412 + memset(&ir->p, 0, sizeof(struct lirc_plugin));
1413 + ir->p.minor = NOPLUG;
1416 + ir->t_notify = NULL;
1417 + ir->t_notify2 = NULL;
1419 + ir->jiffies_to_wait = 0;
1426 + * reads key codes from plugin and puts them into buffer
1427 + * buffer free space is checked and locking performed
1428 + * returns 0 on success
1431 +inline static int add_to_buf(struct irctl *ir)
1433 + if (lirc_buffer_full(ir->buf)) {
1434 + dprintk(LOGHEAD "buffer overflow\n",
1435 + ir->p.name, ir->p.minor);
1436 + return -EOVERFLOW;
1439 + if(ir->p.add_to_buf) {
1440 + int res = -ENODATA;
1443 + /* service the device as long as it is returning
1444 + * data and we have space
1446 + while( !lirc_buffer_full(ir->buf) )
1448 + res = ir->p.add_to_buf( ir->p.data, ir->buf );
1449 + if( res == SUCCESS )
1455 + if( res == -ENODEV )
1459 + return (got_data ? SUCCESS : res);
1465 +/* main function of the polling thread
1467 +static int lirc_thread(void *irctl)
1469 + struct irctl *ir = irctl;
1471 + /* This thread doesn't need any user-level access,
1472 + * so get rid of all our resources
1474 + daemonize("lirc_dev");
1476 + if (ir->t_notify != NULL) {
1480 + dprintk(LOGHEAD "poll thread started\n", ir->p.name, ir->p.minor);
1484 + if (ir->jiffies_to_wait) {
1485 + current->state = TASK_INTERRUPTIBLE;
1486 + schedule_timeout(ir->jiffies_to_wait);
1488 + interruptible_sleep_on(ir->p.get_queue(ir->p.data));
1490 + if (ir->shutdown) {
1493 + if (!add_to_buf(ir)) {
1494 + wake_up_interruptible(&ir->buf->wait_poll);
1497 + /* if device not opened so we can sleep half a second */
1498 + current->state = TASK_INTERRUPTIBLE;
1499 + schedule_timeout(HZ/2);
1501 + } while (!ir->shutdown);
1503 + if (ir->t_notify2 != NULL) {
1504 + down(ir->t_notify2);
1508 + if (ir->t_notify != NULL) {
1512 + dprintk(LOGHEAD "poll thread ended\n", ir->p.name, ir->p.minor);
1520 +int lirc_register_plugin(struct lirc_plugin *p)
1525 +#ifdef LIRC_HAVE_DEVFS
1528 + DECLARE_MUTEX_LOCKED(tn);
1531 + printk("lirc_dev: lirc_register_plugin:"
1532 + "plugin pointer must be not NULL!\n");
1536 + if (MAX_IRCTL_DEVICES <= p->minor) {
1537 + printk("lirc_dev: lirc_register_plugin:"
1538 + "\" minor\" must be between 0 and %d (%d)!\n",
1539 + MAX_IRCTL_DEVICES-1, p->minor);
1543 + if (1 > p->code_length || (BUFLEN*8) < p->code_length) {
1544 + printk("lirc_dev: lirc_register_plugin:"
1545 + "code length in bits for minor (%d) "
1546 + "must be less than %d!\n",
1547 + p->minor, BUFLEN*8);
1551 + printk("lirc_dev: lirc_register_plugin:"
1552 + "sample_rate: %d\n",p->sample_rate);
1553 + if (p->sample_rate) {
1554 + if (2 > p->sample_rate || HZ < p->sample_rate) {
1555 + printk("lirc_dev: lirc_register_plugin:"
1556 + "sample_rate must be between 2 and %d!\n", HZ);
1559 + if (!p->add_to_buf) {
1560 + printk("lirc_dev: lirc_register_plugin:"
1561 + "add_to_buf cannot be NULL when "
1562 + "sample_rate is set\n");
1565 + } else if (!(p->fops && p->fops->read)
1566 + && !p->get_queue && !p->rbuf) {
1567 + printk("lirc_dev: lirc_register_plugin:"
1568 + "fops->read, get_queue and rbuf "
1569 + "cannot all be NULL!\n");
1571 + } else if (!p->get_queue && !p->rbuf) {
1572 + if (!(p->fops && p->fops->read && p->fops->poll)
1573 + || (!p->fops->ioctl && !p->ioctl)) {
1574 + printk("lirc_dev: lirc_register_plugin:"
1575 + "neither read, poll nor ioctl can be NULL!\n");
1580 + down_interruptible(&plugin_lock);
1585 + /* find first free slot for plugin */
1586 + for (minor=0; minor<MAX_IRCTL_DEVICES; minor++)
1587 + if (irctls[minor].p.minor == NOPLUG)
1589 + if (MAX_IRCTL_DEVICES == minor) {
1590 + printk("lirc_dev: lirc_register_plugin: "
1591 + "no free slots for plugins!\n");
1595 + } else if (irctls[minor].p.minor != NOPLUG) {
1596 + printk("lirc_dev: lirc_register_plugin:"
1597 + "minor (%d) just registered!\n", minor);
1602 + ir = &irctls[minor];
1604 + if (p->sample_rate) {
1605 + ir->jiffies_to_wait = HZ / p->sample_rate;
1607 + /* it means - wait for externeal event in task queue */
1608 + ir->jiffies_to_wait = 0;
1611 + /* some safety check 8-) */
1612 + p->name[sizeof(p->name)-1] = '\0';
1614 + bytes_in_key = p->code_length/8 + (p->code_length%8 ? 1 : 0);
1617 + ir->buf = p->rbuf;
1619 + ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
1620 + lirc_buffer_init(ir->buf, bytes_in_key, BUFLEN/bytes_in_key);
1623 + if (p->features==0)
1624 + p->features = (p->code_length > 8) ?
1625 + LIRC_CAN_REC_LIRCCODE : LIRC_CAN_REC_CODE;
1628 + ir->p.minor = minor;
1630 +#ifdef LIRC_HAVE_DEVFS
1631 + sprintf (name, DEV_LIRC "/%d", ir->p.minor);
1632 + ir->devfs_handle = devfs_register(NULL, name, DEVFS_FL_DEFAULT,
1633 + CONFIG_LIRC_IRCTL_DEV_MAJOR, ir->p.minor,
1634 + S_IFCHR | S_IRUSR | S_IWUSR,
1638 + if(p->sample_rate || p->get_queue) {
1639 + /* try to fire up polling thread */
1640 + ir->t_notify = &tn;
1641 + ir->tpid = kernel_thread(lirc_thread, (void*)ir, 0);
1642 + if (ir->tpid < 0) {
1644 + printk("lirc_dev: lirc_register_plugin:"
1645 + "cannot run poll thread for minor = %d\n",
1650 + ir->t_notify = NULL;
1654 + MOD_INC_USE_COUNT;
1656 + dprintk("lirc_dev: plugin %s registered at minor number = %d\n",
1657 + ir->p.name, ir->p.minor);
1665 +int lirc_unregister_plugin(int minor)
1668 + DECLARE_MUTEX_LOCKED(tn);
1669 + DECLARE_MUTEX_LOCKED(tn2);
1671 + if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
1672 + printk("lirc_dev: lirc_unregister_plugin:"
1673 + "\" minor\" must be between 0 and %d!\n",
1674 + MAX_IRCTL_DEVICES-1);
1678 + ir = &irctls[minor];
1680 + down_interruptible(&plugin_lock);
1682 + if (ir->p.minor != minor) {
1683 + printk("lirc_dev: lirc_unregister_plugin:"
1684 + "minor (%d) device not registered!", minor);
1690 + printk("lirc_dev: lirc_unregister_plugin:"
1691 + "plugin %s[%d] in use!", ir->p.name, ir->p.minor);
1696 + /* end up polling thread */
1697 + if (ir->tpid >= 0) {
1698 + ir->t_notify = &tn;
1699 + ir->t_notify2 = &tn2;
1701 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1703 + struct task_struct *p;
1705 + p = find_task_by_pid(ir->tpid);
1706 + wake_up_process(p);
1709 + /* 2.2.x does not export wake_up_process() */
1710 + wake_up_interruptible(ir->p.get_queue(ir->p.data));
1714 + ir->t_notify = NULL;
1715 + ir->t_notify2 = NULL;
1718 + dprintk("lirc_dev: plugin %s unregistered from minor number = %d\n",
1719 + ir->p.name, ir->p.minor);
1721 +#ifdef LIRC_HAVE_DEVFS
1722 + devfs_unregister(ir->devfs_handle);
1724 + if (ir->buf != ir->p.rbuf){
1725 + lirc_buffer_free(ir->buf);
1732 + MOD_DEC_USE_COUNT;
1740 +static int irctl_open(struct inode *inode, struct file *file)
1745 + if (MINOR(inode->i_rdev) >= MAX_IRCTL_DEVICES) {
1746 + dprintk("lirc_dev [%d]: open result = -ENODEV\n",
1747 + MINOR(inode->i_rdev));
1751 + ir = &irctls[MINOR(inode->i_rdev)];
1753 + dprintk(LOGHEAD "open called\n", ir->p.name, ir->p.minor);
1755 + /* if the plugin has an open function use it instead */
1756 + if(ir->p.fops && ir->p.fops->open)
1757 + return ir->p.fops->open(inode, file);
1759 + down_interruptible(&plugin_lock);
1761 + if (ir->p.minor == NOPLUG) {
1763 + dprintk(LOGHEAD "open result = -ENODEV\n",
1764 + ir->p.name, ir->p.minor);
1770 + dprintk(LOGHEAD "open result = -EBUSY\n",
1771 + ir->p.name, ir->p.minor);
1775 + /* there is no need for locking here because ir->open is 0
1776 + * and lirc_thread isn't using buffer
1777 + * plugins which use irq's should allocate them on set_use_inc,
1778 + * so there should be no problem with those either.
1780 + ir->buf->head = ir->buf->tail;
1781 + ir->buf->fill = 0;
1784 + retval = ir->p.set_use_inc(ir->p.data);
1788 + if (retval != SUCCESS) {
1793 + dprintk(LOGHEAD "open result = %d\n", ir->p.name, ir->p.minor, SUCCESS);
1801 +static int irctl_close(struct inode *inode, struct file *file)
1803 + struct irctl *ir = &irctls[MINOR(inode->i_rdev)];
1805 + dprintk(LOGHEAD "close called\n", ir->p.name, ir->p.minor);
1807 + /* if the plugin has a close function use it instead */
1808 + if(ir->p.fops && ir->p.fops->release)
1809 + return ir->p.fops->release(inode, file);
1811 + down_interruptible(&plugin_lock);
1814 + ir->p.set_use_dec(ir->p.data);
1824 +static unsigned int irctl_poll(struct file *file, poll_table *wait)
1826 + struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)];
1828 + dprintk(LOGHEAD "poll called\n", ir->p.name, ir->p.minor);
1830 + /* if the plugin has a poll function use it instead */
1831 + if(ir->p.fops && ir->p.fops->poll)
1832 + return ir->p.fops->poll(file, wait);
1834 + poll_wait(file, &ir->buf->wait_poll, wait);
1836 + dprintk(LOGHEAD "poll result = %s\n",
1837 + ir->p.name, ir->p.minor,
1838 + lirc_buffer_empty(ir->buf) ? "0" : "POLLIN|POLLRDNORM");
1840 + return lirc_buffer_empty(ir->buf) ? 0 : (POLLIN|POLLRDNORM);
1846 +static int irctl_ioctl(struct inode *inode, struct file *file,
1847 + unsigned int cmd, unsigned long arg)
1849 + unsigned long mode;
1851 + struct irctl *ir = &irctls[MINOR(inode->i_rdev)];
1853 + dprintk(LOGHEAD "ioctl called (%u)\n",
1854 + ir->p.name, ir->p.minor, cmd);
1856 + /* if the plugin has a ioctl function use it instead */
1857 + if(ir->p.fops && ir->p.fops->ioctl)
1858 + return ir->p.fops->ioctl(inode, file, cmd, arg);
1860 + if (ir->p.minor == NOPLUG) {
1861 + dprintk(LOGHEAD "ioctl result = -ENODEV\n",
1862 + ir->p.name, ir->p.minor);
1866 + /* Give the plugin a chance to handle the ioctl */
1868 + result = ir->p.ioctl(inode, file, cmd, arg);
1869 + if (result != -ENOIOCTLCMD)
1872 + /* The plugin can't handle cmd */
1877 + case LIRC_GET_FEATURES:
1878 + result = put_user(ir->p.features, (unsigned long*)arg);
1880 + case LIRC_GET_REC_MODE:
1881 + if(!(ir->p.features&LIRC_CAN_REC_MASK))
1884 + result = put_user(LIRC_REC2MODE
1885 + (ir->p.features&LIRC_CAN_REC_MASK),
1886 + (unsigned long*)arg);
1888 + case LIRC_SET_REC_MODE:
1889 + if(!(ir->p.features&LIRC_CAN_REC_MASK))
1892 + result = get_user(mode, (unsigned long*)arg);
1893 + if(!result && !(LIRC_MODE2REC(mode) & ir->p.features)) {
1896 + /* FIXME: We should actually set the mode somehow
1897 + * but for now, lirc_serial doesn't support mode changin
1900 + case LIRC_GET_LENGTH:
1901 + result = put_user((unsigned long)ir->p.code_length,
1902 + (unsigned long *)arg);
1905 + result = -ENOIOCTLCMD;
1908 + dprintk(LOGHEAD "ioctl result = %d\n",
1909 + ir->p.name, ir->p.minor, result);
1917 +static ssize_t irctl_read(struct file *file,
1922 + struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)];
1923 + unsigned char buf[ir->buf->chunk_size];
1924 + int ret=0, written=0;
1925 + DECLARE_WAITQUEUE(wait, current);
1927 + dprintk(LOGHEAD "read called\n", ir->p.name, ir->p.minor);
1929 + /* if the plugin has a specific read function use it instead */
1930 + if(ir->p.fops && ir->p.fops->read)
1931 + return ir->p.fops->read(file, buffer, length, ppos);
1933 + if (length % ir->buf->chunk_size) {
1934 + dprintk(LOGHEAD "read result = -EINVAL\n",
1935 + ir->p.name, ir->p.minor);
1939 + /* we add ourselves to the task queue before buffer check
1940 + * to avoid losing scan code (in case when queue is awaken somewhere
1941 + * beetwen while condition checking and scheduling)
1943 + add_wait_queue(&ir->buf->wait_poll, &wait);
1944 + current->state = TASK_INTERRUPTIBLE;
1946 + /* while we did't provide 'length' bytes, device is opened in blocking
1947 + * mode and 'copy_to_user' is happy, wait for data.
1949 + while (written < length && ret == 0) {
1950 + if (lirc_buffer_empty(ir->buf)) {
1951 + /* According to the read(2) man page, 'written' can be
1952 + * returned as less than 'length', instead of blocking
1953 + * again, returning -EWOULDBLOCK, or returning
1955 + if (written) break;
1956 + if (file->f_flags & O_NONBLOCK) {
1957 + dprintk(LOGHEAD "read result = -EWOULDBLOCK\n",
1958 + ir->p.name, ir->p.minor);
1959 + remove_wait_queue(&ir->buf->wait_poll, &wait);
1960 + current->state = TASK_RUNNING;
1961 + return -EWOULDBLOCK;
1963 + if (signal_pending(current)) {
1964 + dprintk(LOGHEAD "read result = -ERESTARTSYS\n",
1965 + ir->p.name, ir->p.minor);
1966 + remove_wait_queue(&ir->buf->wait_poll, &wait);
1967 + current->state = TASK_RUNNING;
1968 + return -ERESTARTSYS;
1971 + current->state = TASK_INTERRUPTIBLE;
1973 + lirc_buffer_read_1(ir->buf, buf);
1974 + ret = copy_to_user((void *)buffer+written, buf,
1975 + ir->buf->chunk_size);
1976 + written += ir->buf->chunk_size;
1980 + remove_wait_queue(&ir->buf->wait_poll, &wait);
1981 + current->state = TASK_RUNNING;
1983 + dprintk(LOGHEAD "read result = %s (%d)\n",
1984 + ir->p.name, ir->p.minor, ret ? "-EFAULT" : "OK", ret);
1986 + return ret ? -EFAULT : written;
1989 +static ssize_t irctl_write(struct file *file, const char *buffer,
1990 + size_t length, loff_t * ppos)
1992 + struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)];
1994 + dprintk(LOGHEAD "read called\n", ir->p.name, ir->p.minor);
1996 + /* if the plugin has a specific read function use it instead */
1997 + if(ir->p.fops && ir->p.fops->write)
1998 + return ir->p.fops->write(file, buffer, length, ppos);
2004 +static struct file_operations fops = {
2006 + write: irctl_write,
2008 + ioctl: irctl_ioctl,
2010 + release: irctl_close
2015 +EXPORT_SYMBOL(lirc_register_plugin);
2016 +EXPORT_SYMBOL(lirc_unregister_plugin);
2021 +int lirc_dev_init(void)
2025 + for (i=0; i < MAX_IRCTL_DEVICES; ++i) {
2026 + init_irctl(&irctls[i]);
2029 +#ifndef LIRC_HAVE_DEVFS
2030 + i = register_chrdev(CONFIG_LIRC_IRCTL_DEV_MAJOR,
2032 + i = devfs_register_chrdev(CONFIG_LIRC_IRCTL_DEV_MAJOR,
2038 + printk ("lirc_dev: device registration failed with %d\n", i);
2042 + printk("lirc_dev: IR Remote Control driver registered, at major %d \n",
2043 + CONFIG_LIRC_IRCTL_DEV_MAJOR);
2048 +/* ---------------------------------------------------------------------- */
2050 +/* For now dont try to use it as a static version ! */
2054 +MODULE_DESCRIPTION("LIRC base driver module");
2055 +MODULE_AUTHOR("Artur Lipowski");
2056 +#ifdef MODULE_LICENSE
2057 +MODULE_LICENSE("GPL");
2063 +int init_module(void)
2065 + return lirc_dev_init();
2071 +void cleanup_module(void)
2075 +#ifndef LIRC_HAVE_DEVFS
2076 + ret = unregister_chrdev(CONFIG_LIRC_IRCTL_DEV_MAJOR, IRCTL_DEV_NAME);
2078 + ret = devfs_unregister_chrdev(CONFIG_LIRC_IRCTL_DEV_MAJOR, IRCTL_DEV_NAME);
2082 + printk("lirc_dev: error in module_unregister_chrdev: %d\n",
2085 + dprintk("lirc_dev: module successfully unloaded\n");
2091 + * Overrides for Emacs so that we follow Linus's tabbing style.
2092 + * ---------------------------------------------------------------------------
2093 + * Local variables:
2094 + * c-basic-offset: 8
2097 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_dev.h linux-2.6.8-rc4/drivers/char/lirc/lirc_dev.h
2098 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_dev.h 1970-01-01 01:00:00.000000000 +0100
2099 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_dev.h 2004-04-09 17:33:40.000000000 +0200
2102 + * LIRC base driver
2104 + * (L) by Artur Lipowski <alipowski@interia.pl>
2105 + * This code is licensed under GNU GPL
2111 +#ifndef _LINUX_LIRC_DEV_H
2112 +#define _LINUX_LIRC_DEV_H
2114 +#define MAX_IRCTL_DEVICES 2
2117 +//#define LIRC_BUFF_POWER_OF_2
2118 +#ifdef LIRC_BUFF_POWER_OF_2
2119 +#define mod(n, div) ((n) & ((div) -1))
2121 +#define mod(n, div) ((n) % (div))
2123 +#include <linux/slab.h>
2124 +#include <linux/fs.h>
2127 + wait_queue_head_t wait_poll;
2130 + unsigned char *data;
2131 + unsigned int chunk_size;
2132 + unsigned int size; /* in chunks */
2133 + unsigned int fill; /* in chunks */
2134 + int head, tail; /* in chunks */
2135 + /* Using chunks instead of bytes pretends to simplify boundary checking
2136 + * And should allow for some performance fine tunning later */
2138 +static inline int lirc_buffer_init(struct lirc_buffer *buf,
2139 + unsigned int chunk_size,
2140 + unsigned int size)
2142 + /* Adjusting size to the next power of 2 would allow for
2143 + * inconditional LIRC_BUFF_POWER_OF_2 optimization */
2144 + init_waitqueue_head(&buf->wait_poll);
2145 + spin_lock_init(&buf->lock);
2146 + buf->head = buf->tail = buf->fill = 0;
2147 + buf->chunk_size = chunk_size;
2149 + buf->data = kmalloc(size*chunk_size, GFP_KERNEL);
2150 + if (buf->data == NULL)
2152 + memset(buf->data, 0, size*chunk_size);
2155 +static inline void lirc_buffer_free(struct lirc_buffer *buf)
2159 + buf->head = buf->tail = buf->fill = 0;
2160 + buf->chunk_size = 0;
2163 +static inline int lirc_buffer_full(struct lirc_buffer *buf)
2165 + return (buf->fill >= buf->size);
2167 +static inline int lirc_buffer_empty(struct lirc_buffer *buf)
2169 + return !(buf->fill);
2171 +static inline int lirc_buffer_available(struct lirc_buffer *buf)
2173 + return (buf->size - buf->fill);
2175 +extern inline void lirc_buffer_lock(struct lirc_buffer *buf, unsigned long *flags)
2177 + spin_lock_irqsave(&buf->lock, *flags);
2179 +extern inline void lirc_buffer_unlock(struct lirc_buffer *buf, unsigned long *flags)
2181 + spin_unlock_irqrestore(&buf->lock, *flags);
2183 +static inline void _lirc_buffer_remove_1(struct lirc_buffer *buf)
2185 + buf->head = mod(buf->head+1, buf->size);
2188 +static inline void lirc_buffer_remove_1(struct lirc_buffer *buf)
2190 + unsigned long flags;
2191 + lirc_buffer_lock(buf, &flags);
2192 + _lirc_buffer_remove_1(buf);
2193 + lirc_buffer_unlock(buf, &flags);
2195 +static inline void _lirc_buffer_read_1(struct lirc_buffer *buf,
2196 + unsigned char *dest)
2198 + memcpy(dest, &buf->data[buf->head*buf->chunk_size], buf->chunk_size);
2199 + buf->head = mod(buf->head+1, buf->size);
2202 +static inline void lirc_buffer_read_1(struct lirc_buffer *buf,
2203 + unsigned char *dest)
2205 + unsigned long flags;
2206 + lirc_buffer_lock(buf, &flags);
2207 + _lirc_buffer_read_1(buf, dest);
2208 + lirc_buffer_unlock(buf, &flags);
2210 +static inline void _lirc_buffer_write_1(struct lirc_buffer *buf,
2211 + unsigned char *orig)
2213 + memcpy(&buf->data[buf->tail*buf->chunk_size], orig, buf->chunk_size);
2214 + buf->tail = mod(buf->tail+1, buf->size);
2217 +static inline void lirc_buffer_write_1(struct lirc_buffer *buf,
2218 + unsigned char *orig)
2220 + unsigned long flags;
2221 + lirc_buffer_lock(buf, &flags);
2222 + _lirc_buffer_write_1(buf, orig);
2223 + lirc_buffer_unlock(buf, &flags);
2225 +static inline void _lirc_buffer_write_n(struct lirc_buffer *buf,
2226 + unsigned char* orig, int count)
2228 + memcpy(&buf->data[buf->tail*buf->chunk_size], orig,
2229 + count*buf->chunk_size);
2230 + buf->tail = mod(buf->tail+count, buf->size);
2231 + buf->fill += count;
2233 +static inline void lirc_buffer_write_n(struct lirc_buffer *buf,
2234 + unsigned char* orig, int count)
2236 + unsigned long flags;
2238 + lirc_buffer_lock(buf,&flags);
2239 + if( buf->head > buf->tail ) space1 = buf->head - buf->tail;
2240 + else space1 = buf->size - buf->tail;
2242 + if( count > space1 )
2244 + _lirc_buffer_write_n(buf, orig, space1);
2245 + _lirc_buffer_write_n(buf, orig+(space1*buf->chunk_size),
2250 + _lirc_buffer_write_n(buf, orig, count);
2252 + lirc_buffer_unlock(buf, &flags);
2261 + unsigned long features;
2263 + int (*add_to_buf) (void* data, struct lirc_buffer* buf);
2264 + wait_queue_head_t* (*get_queue) (void* data);
2265 + struct lirc_buffer *rbuf;
2266 + int (*set_use_inc) (void* data);
2267 + void (*set_use_dec) (void* data);
2268 + int (*ioctl) (struct inode *,struct file *,unsigned int,
2270 + struct file_operations *fops;
2273 + * this string will be used for logs
2276 + * indicates minor device (/dev/lirc) number for registered plugin
2277 + * if caller fills it with negative value, then the first free minor
2278 + * number will be used (if available)
2281 + * length of the remote control key code expressed in bits
2284 + * sample_rate equal to 0 means that no polling will be performed and
2285 + * add_to_buf will be triggered by external events (through task queue
2286 + * returned by get_queue)
2289 + * it may point to any plugin data and this pointer will be passed to
2290 + * all callback functions
2293 + * add_to_buf will be called after specified period of the time or
2294 + * triggered by the external event, this behavior depends on value of
2295 + * the sample_rate this function will be called in user context. This
2296 + * routine should return 0 if data was added to the buffer and
2297 + * -ENODATA if none was available. This should add some number of bits
2298 + * evenly divisible by code_length to the buffer
2301 + * this callback should return a pointer to the task queue which will
2302 + * be used for external event waiting
2305 + * if not NULL, it will be used as a read buffer, you will have to
2306 + * write to the buffer by other means, like irq's (see also
2310 + * set_use_inc will be called after device is opened
2313 + * set_use_dec will be called after device is closed
2316 + * Some ioctl's can be directly handled by lirc_dev but will be
2317 + * forwared here if not NULL and only handled if it returns
2318 + * -ENOIOCTLCMD (see also lirc_serial.c).
2321 + * file_operations for drivers which don't fit the current plugin model.
2325 +/* following functions can be called ONLY from user context
2327 + * returns negative value on error or minor number
2328 + * of the registered device if success
2329 + * contens of the structure pointed by p is copied
2331 +extern int lirc_register_plugin(struct lirc_plugin *p);
2333 +/* returns negative value on error or 0 if success
2335 +extern int lirc_unregister_plugin(int minor);
2339 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_gpio.c linux-2.6.8-rc4/drivers/char/lirc/lirc_gpio.c
2340 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_gpio.c 1970-01-01 01:00:00.000000000 +0100
2341 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_gpio.c 2004-04-27 08:08:24.000000000 +0200
2344 + * Remote control driver for the TV-card
2345 + * key codes are obtained from GPIO port
2347 + * (L) by Artur Lipowski <alipowski@interia.pl>
2348 + * patch for the AverMedia by Santiago Garcia Mantinan <manty@i.am>
2349 + * and Christoph Bartelmus <lirc@bartelmus.de>
2350 + * patch for the BestBuy by Miguel Angel Alvarez <maacruz@navegalia.com>
2351 + * patch for the Winfast TV2000 by Juan Toledo
2352 + * <toledo@users.sourceforge.net>
2353 + * patch for the I-O Data GV-BCTV5/PCI by Jens C. Rasmussen
2354 + * <jens.rasmussen@ieee.org>
2356 + * This program is free software; you can redistribute it and/or modify
2357 + * it under the terms of the GNU General Public License as published by
2358 + * the Free Software Foundation; either version 2 of the License, or
2359 + * (at your option) any later version.
2361 + * This program is distributed in the hope that it will be useful,
2362 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2363 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2364 + * GNU General Public License for more details.
2366 + * You should have received a copy of the GNU General Public License
2367 + * along with this program; if not, write to the Free Software
2368 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2374 +#include <linux/version.h>
2375 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 4)
2376 +#error "*******************************************************"
2377 +#error "Sorry, this driver needs kernel version 2.2.4 or higher"
2378 +#error "*******************************************************"
2381 +#include <linux/module.h>
2382 +#include <linux/kmod.h>
2383 +#include <linux/sched.h>
2384 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
2385 +#include <linux/wrapper.h>
2387 +#include <linux/errno.h>
2389 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
2390 +#include "../drivers/char/bttv.h"
2391 +#include "../drivers/char/bttvp.h"
2393 +#include "../drivers/media/video/bttv.h"
2394 +#include "../drivers/media/video/bttvp.h"
2397 +#if BTTV_VERSION_CODE < KERNEL_VERSION(0,7,45)
2398 +#error "*******************************************************"
2399 +#error " Sorry, this driver needs bttv version 0.7.45 or "
2400 +#error " higher. If you are using the bttv package, copy it to "
2401 +#error " the kernel "
2402 +#error "*******************************************************"
2405 +#include "kcompat.h"
2406 +#include "lirc_dev.h"
2408 +static int debug = 0;
2409 +static int card = 0;
2410 +static int minor = -1;
2411 +static int bttv_id = BTTV_UNKNOWN;
2412 +static unsigned long gpio_mask = 0;
2413 +static unsigned long gpio_enable = 0;
2414 +static unsigned long gpio_lock_mask = 0;
2415 +static unsigned long gpio_xor_mask = 0;
2416 +static unsigned int soft_gap = 0;
2417 +static unsigned char sample_rate = 10;
2419 +MODULE_PARM(debug,"i");
2420 +MODULE_PARM(card,"i");
2421 +MODULE_PARM(minor,"i");
2422 +MODULE_PARM(gpio_mask,"l");
2423 +MODULE_PARM(gpio_lock_mask,"l");
2424 +MODULE_PARM(gpio_xor_mask,"l");
2425 +MODULE_PARM(soft_gap,"i");
2426 +MODULE_PARM(sample_rate,"b");
2427 +MODULE_PARM(bttv_id,"i");
2430 +#define dprintk if (debug) printk
2435 + unsigned long gpio_mask;
2436 + unsigned long gpio_enable;
2437 + unsigned long gpio_lock_mask;
2438 + unsigned long gpio_xor_mask;
2439 + unsigned int soft_gap;
2440 + unsigned char sample_rate;
2441 + unsigned char code_length;
2444 +static struct rcv_info rcv_infos[] = {
2445 + {BTTV_UNKNOWN, 0, 0, 0, 0, 0, 0, 1, 0},
2446 + {BTTV_PXELVWPLTVPAK, 0, 0x00003e00, 0, 0x0010000, 0, 0, 15, 32},
2447 + {BTTV_PXELVWPLTVPRO, 0, 0x00001f00, 0, 0x0008000, 0, 500, 12, 32},
2448 + {BTTV_PV_BT878P_9B, 0, 0x00001f00, 0, 0x0008000, 0, 500, 12, 32},
2449 + {BTTV_PV_BT878P_PLUS, 0, 0x00001f00, 0, 0x0008000, 0, 500, 12, 32},
2450 + {BTTV_AVERMEDIA, 0, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32},
2451 + {BTTV_AVPHONE98, 0x00011461, 0x003b8000, 0x00004000, 0x0800000, 0x00800000, 0, 10, 0}, /*mapped to Capture98*/
2452 + {BTTV_AVERMEDIA98, 0x00021461, 0x003b8000, 0x00004000, 0x0800000, 0x00800000, 0, 10, 0}, /*mapped to Capture98*/
2453 + {BTTV_AVPHONE98, 0x00031461, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, /*mapped to Phone98*/
2454 + /* is this one correct? */
2455 + {BTTV_AVERMEDIA98, 0x00041461, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, /*mapped to Phone98*/
2456 + /* work-around for VDOMATE */
2457 + {BTTV_AVERMEDIA98, 0x03001461, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, /*mapped to Phone98*/
2458 + /* reported by Danijel Korzinek, AVerTV GOw/FM */
2459 + {BTTV_AVERMEDIA98, 0x00000000, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, /*mapped to Phone98*/
2460 + {BTTV_CHRONOS_VS2, 0, 0x000000f8, 0, 0x0000100, 0, 0, 20, 0},
2461 + /* CPH031 and CPH033 cards (?) */
2462 + /* MIRO was just a work-around */
2463 + {BTTV_MIRO, 0, 0x00001f00, 0, 0x0004000, 0, 0, 10, 32},
2464 + {BTTV_DYNALINK, 0, 0x00001f00, 0, 0x0004000, 0, 0, 10, 32},
2465 + {BTTV_WINVIEW_601, 0, 0x00001f00, 0, 0x0004000, 0, 0, 0, 32},
2467 + {BTTV_KWORLD, 0, 0x00007f00, 0, 0x0004000, 0, 0, 12, 32},
2469 + /* just a guess */
2470 + {BTTV_MAGICTVIEW061, 0, 0x0028e000, 0, 0x0020000, 0, 0, 20, 32},
2471 + {BTTV_MAGICTVIEW063, 0, 0x0028e000, 0, 0x0020000, 0, 0, 20, 32},
2472 + {BTTV_PHOEBE_TVMAS, 0, 0x0028e000, 0, 0x0020000, 0, 0, 20, 32},
2473 +#ifdef BTTV_BESTBUY_EASYTV2
2474 + {BTTV_BESTBUY_EASYTV, 0, 0x00007F00, 0, 0x0004000, 0, 0, 10, 8},
2475 + {BTTV_BESTBUY_EASYTV2, 0, 0x00007F00, 0, 0x0008000, 0, 0, 10, 8},
2477 + /* lock_mask probably also 0x100, or maybe it is 0x0 for all others !?! */
2478 + {BTTV_FLYVIDEO, 0, 0x000000f8, 0, 0, 0, 0, 0, 42},
2479 + {BTTV_FLYVIDEO_98, 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 42},
2480 + {BTTV_TYPHOON_TVIEW, 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 42},
2481 +#ifdef BTTV_FLYVIDEO_98FM
2482 + /* smorar@alfonzo.smuts.uct.ac.za */
2483 + {BTTV_FLYVIDEO_98FM, 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 42},
2485 + /* The Leadtek WinFast TV 2000 XP card (id 0x6606107d) uses an
2486 + * extra gpio bit compared to the original TV 2000 card (id
2487 + * 0x217d6606); as the bttv-0.7.100 driver does not
2488 + * distinguish between the two cards, we enable the extra bit
2489 + * based on the card id: */
2490 + {BTTV_WINFAST2000, 0x6606107d, 0x000008f8, 0, 0x0000100, 0, 0, 0, 32},
2492 + {BTTV_WINFAST2000, 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 32},
2493 +#ifdef BTTV_GVBCTV5PCI
2494 + {BTTV_GVBCTV5PCI, 0, 0x00f0b000, 0, 0, 0, 0, 20, 8},
2498 +static unsigned char code_length = 0;
2499 +static unsigned char code_bytes = 1;
2501 +#define MAX_BYTES 8
2504 +#define LOGHEAD "lirc_gpio (%d): "
2506 +/* how many bits GPIO value can be shifted right before processing
2507 + * it is computed from the value of gpio_mask_parameter
2509 +static unsigned char gpio_pre_shift = 0;
2512 +static inline int reverse(int data, int bits)
2517 + for (c=0,i=0; i<bits; i++) {
2518 + c |= (((data & (1<<i)) ? 1:0)) << (bits-1-i);
2524 +static int build_key(unsigned long gpio_val, unsigned char codes[MAX_BYTES])
2526 + unsigned long mask = gpio_mask;
2527 + unsigned char shift = 0;
2529 + dprintk(LOGHEAD "gpio_val is %lx\n",card,(unsigned long) gpio_val);
2531 + gpio_val ^= gpio_xor_mask;
2533 + if (gpio_lock_mask && (gpio_val & gpio_lock_mask)) {
2539 + case BTTV_AVERMEDIA98:
2540 + if (bttv_write_gpio(card, gpio_enable, gpio_enable)) {
2541 + dprintk(LOGHEAD "cannot write to GPIO\n", card);
2544 + if (bttv_read_gpio(card, &gpio_val)) {
2545 + dprintk(LOGHEAD "cannot read GPIO\n", card);
2548 + if (bttv_write_gpio(card, gpio_enable, 0)) {
2549 + dprintk(LOGHEAD "cannot write to GPIO\n", card);
2557 + /* extract bits from "raw" GPIO value using gpio_mask */
2559 + gpio_val >>= gpio_pre_shift;
2562 + codes[0] |= (gpio_val & 1u) << shift++;
2568 + dprintk(LOGHEAD "code is %lx\n",card,(unsigned long) codes[0]);
2571 + case BTTV_AVERMEDIA:
2572 + codes[2] = (codes[0]<<2)&0xff;
2573 + codes[3] = (~codes[2])&0xff;
2577 + case BTTV_AVPHONE98:
2578 + codes[2] = ((codes[0]&(~0x1))<<2)&0xff;
2579 + codes[3] = (~codes[2])&0xff;
2580 + if (codes[0]&0x1) {
2588 + case BTTV_AVERMEDIA98:
2590 + case BTTV_FLYVIDEO:
2591 + case BTTV_FLYVIDEO_98:
2592 + case BTTV_TYPHOON_TVIEW:
2593 +#ifdef BTTV_FLYVIDEO_98FM
2594 + case BTTV_FLYVIDEO_98FM:
2596 + codes[4]=codes[0]<<3;
2597 + codes[5]=((~codes[4])&0xff);
2604 + case BTTV_MAGICTVIEW061:
2605 + case BTTV_MAGICTVIEW063:
2606 + case BTTV_PHOEBE_TVMAS:
2607 + codes[0] = (codes[0]&0x01)
2608 + |((codes[0]&0x02)<<1)
2609 + |((codes[0]&0x04)<<2)
2610 + |((codes[0]&0x08)>>2)
2611 + |((codes[0]&0x10)>>1);
2614 + case BTTV_DYNALINK:
2615 + case BTTV_PXELVWPLTVPAK:
2616 + case BTTV_PXELVWPLTVPRO:
2617 + case BTTV_PV_BT878P_9B:
2618 + case BTTV_PV_BT878P_PLUS:
2622 + codes[2] = reverse(codes[0],8);
2623 + codes[3] = (~codes[2])&0xff;
2628 + /* derived from e-tech config file */
2629 + /* 26 + 16 bits */
2630 + /* won't apply it until it's confirmed with a fly98 */
2631 + case BTTV_FLYVIDEO_98:
2632 + case BTTV_FLYVIDEO_98FM:
2633 + codes[4]=codes[0]<<3;
2634 + codes[5]=(~codes[4])&0xff;
2642 + case BTTV_WINFAST2000:
2643 + /* shift extra bit */
2644 + codes[0] = (codes[0]&0x1f) | ((codes[0]&0x20) << 1);
2645 + case BTTV_WINVIEW_601:
2646 + codes[2] = reverse(codes[0],8);
2647 + codes[3] = (~codes[2])&0xff;
2658 +/* add_to_buf - copy a code to the buffer */
2659 +static int add_to_buf(void* data, struct lirc_buffer* buf)
2661 + static unsigned long next_time = 0;
2662 + static unsigned char prev_codes[MAX_BYTES];
2663 + unsigned long code = 0;
2664 + unsigned char cur_codes[MAX_BYTES];
2666 + if (bttv_read_gpio(card, &code)) {
2667 + dprintk(LOGHEAD "cannot read GPIO\n", card);
2671 + if (build_key(code, cur_codes)) {
2676 + if (!memcmp(prev_codes, cur_codes, code_bytes) &&
2677 + jiffies < next_time) {
2680 + next_time = jiffies + soft_gap;
2682 + memcpy( prev_codes, cur_codes, code_bytes );
2684 + lirc_buffer_write_1( buf, cur_codes );
2689 +static int set_use_inc(void* data)
2691 + MOD_INC_USE_COUNT;
2695 +static void set_use_dec(void* data)
2697 + MOD_DEC_USE_COUNT;
2700 +static wait_queue_head_t* get_queue(void* data)
2702 + return bttv_get_gpio_queue(card);
2705 +static struct lirc_plugin plugin = {
2706 + .name = "lirc_gpio ",
2707 + .add_to_buf = add_to_buf,
2708 + .get_queue = get_queue,
2709 + .set_use_inc = set_use_inc,
2710 + .set_use_dec = set_use_dec,
2716 +int gpio_remote_init(void)
2719 + unsigned int mask;
2721 + /* "normalize" gpio_mask
2722 + * this means shift it right until first bit is set
2724 + while (!(gpio_mask & 1u)) {
2729 + if (code_length) {
2730 + plugin.code_length = code_length;
2732 + /* calculate scan code length in bits if needed */
2733 + plugin.code_length = 1;
2734 + mask = gpio_mask >> 1;
2737 + plugin.code_length++;
2743 + code_bytes = (plugin.code_length/8) + (plugin.code_length%8 ? 1 : 0);
2744 + if (MAX_BYTES < code_bytes) {
2745 + printk (LOGHEAD "scan code too long (%d bytes)\n",
2746 + minor, code_bytes);
2750 + if (gpio_enable) {
2751 + if(bttv_gpio_enable(card, gpio_enable, gpio_enable)) {
2752 + printk(LOGHEAD "gpio_enable failure\n", minor);
2758 + /* translate ms to jiffies */
2759 + soft_gap = (soft_gap*HZ) / 1000;
2761 + plugin.minor = minor;
2762 + plugin.sample_rate = sample_rate;
2764 + ret = lirc_register_plugin(&plugin);
2767 + printk (LOGHEAD "device registration failed with %d\n",
2773 + printk(LOGHEAD "driver registered\n", minor);
2782 +/* Dont try to use it as a static version ! */
2785 +MODULE_DESCRIPTION("Driver module for remote control (data from bt848 GPIO port)");
2786 +MODULE_AUTHOR("Artur Lipowski");
2787 +#ifdef MODULE_LICENSE
2788 +MODULE_LICENSE("GPL");
2794 +int init_module(void)
2796 + int type,cardid,card_type;
2798 + if (MAX_IRCTL_DEVICES < minor) {
2799 + printk("lirc_gpio: parameter minor (%d) must be less than %d!\n",
2800 + minor, MAX_IRCTL_DEVICES-1);
2804 + request_module("bttv");
2806 + /* if gpio_mask not zero then use module parameters
2807 + * instead of autodetecting TV card
2810 + if (sample_rate!=0 &&
2811 + (2 > sample_rate || HZ < sample_rate)) {
2812 + printk(LOGHEAD "parameter sample_rate "
2813 + "must be between 2 and %d!\n", minor, HZ);
2817 + if (sample_rate!=0 && soft_gap &&
2818 + ((2000/sample_rate) > soft_gap || 1000 < soft_gap)) {
2819 + printk(LOGHEAD "parameter soft_gap "
2820 + "must be between %d and 1000!\n",
2821 + minor, 2000/sample_rate);
2825 + if(bttv_get_cardinfo(card,&type,&cardid)==-1) {
2826 + printk(LOGHEAD "could not get card type\n", minor);
2829 + printk(LOGHEAD "card type 0x%x, id 0x%x\n",minor,
2832 + if (type == BTTV_UNKNOWN) {
2833 + printk(LOGHEAD "cannot detect TV card nr %d!\n",
2837 + for (card_type = 1;
2838 + card_type < sizeof(rcv_infos)/sizeof(struct rcv_info);
2840 + if (rcv_infos[card_type].bttv_id == type &&
2841 + (rcv_infos[card_type].card_id == 0 ||
2842 + rcv_infos[card_type].card_id == cardid)) {
2843 + bttv_id = rcv_infos[card_type].bttv_id;
2844 + gpio_mask = rcv_infos[card_type].gpio_mask;
2845 + gpio_enable = rcv_infos[card_type].gpio_enable;
2846 + gpio_lock_mask = rcv_infos[card_type].gpio_lock_mask;
2847 + gpio_xor_mask = rcv_infos[card_type].gpio_xor_mask;
2848 + soft_gap = rcv_infos[card_type].soft_gap;
2849 + sample_rate = rcv_infos[card_type].sample_rate;
2850 + code_length = rcv_infos[card_type].code_length;
2854 + if (type==BTTV_AVPHONE98 && cardid==0x00011461) {
2855 + bttv_id = BTTV_AVERMEDIA98;
2857 + if (type==BTTV_AVERMEDIA98 && cardid==0x00041461) {
2858 + bttv_id = BTTV_AVPHONE98;
2860 + if (type==BTTV_AVERMEDIA98 && cardid==0x03001461) {
2861 + bttv_id = BTTV_AVPHONE98;
2863 + if (type==BTTV_AVERMEDIA98 && cardid==0x00000000) {
2864 + bttv_id = BTTV_AVPHONE98;
2866 + if (card_type == sizeof(rcv_infos)/sizeof(struct rcv_info)) {
2867 + printk(LOGHEAD "TV card type 0x%x not supported!\n",
2873 + request_module("lirc_dev");
2875 + return gpio_remote_init();
2881 +void cleanup_module(void)
2885 + ret = lirc_unregister_plugin(minor);
2888 + printk(LOGHEAD "error in lirc_unregister_minor: %d\n"
2889 + "Trying again...\n",
2892 + current->state = TASK_INTERRUPTIBLE;
2893 + schedule_timeout(HZ);
2895 + ret = lirc_unregister_plugin(minor);
2898 + printk(LOGHEAD "error in lirc_unregister_minor: %d!!!\n",
2904 + dprintk(LOGHEAD "module successfully unloaded\n", minor);
2909 + * Overrides for Emacs so that we follow Linus's tabbing style.
2910 + * ---------------------------------------------------------------------------
2911 + * Local variables:
2912 + * c-basic-offset: 8
2915 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_i2c.c linux-2.6.8-rc4/drivers/char/lirc/lirc_i2c.c
2916 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_i2c.c 1970-01-01 01:00:00.000000000 +0100
2917 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_i2c.c 2004-04-09 17:33:41.000000000 +0200
2922 + * i2c IR lirc plugin for Hauppauge and Pixelview cards - new 2.3.x i2c stack
2924 + * Copyright (c) 2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
2925 + * modified for PixelView (BT878P+W/FM) by
2926 + * Michal Kochanowicz <mkochano@pld.org.pl>
2927 + * Christoph Bartelmus <lirc@bartelmus.de>
2928 + * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
2929 + * Ulrich Mueller <ulrich.mueller42@web.de>
2930 + * modified for Asus TV-Box and Creative/VisionTek BreakOut-Box by
2931 + * Stefan Jahn <stefan@lkcc.org>
2933 + * parts are cut&pasted from the old lirc_haup.c driver
2935 + * This program is free software; you can redistribute it and/or modify
2936 + * it under the terms of the GNU General Public License as published by
2937 + * the Free Software Foundation; either version 2 of the License, or
2938 + * (at your option) any later version.
2940 + * This program is distributed in the hope that it will be useful,
2941 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2942 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2943 + * GNU General Public License for more details.
2945 + * You should have received a copy of the GNU General Public License
2946 + * along with this program; if not, write to the Free Software
2947 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2951 +#include <linux/version.h>
2952 +#if LINUX_VERSION_CODE < 0x020200
2953 +#error "--- Sorry, this driver needs kernel version 2.2.0 or higher. ---"
2956 +#ifdef HAVE_CONFIG_H
2957 +#include <config.h>
2960 +#include <linux/module.h>
2961 +#include <linux/kmod.h>
2962 +#include <linux/kernel.h>
2963 +#include <linux/sched.h>
2964 +#include <linux/string.h>
2965 +#include <linux/timer.h>
2966 +#include <linux/delay.h>
2967 +#include <linux/errno.h>
2968 +#include <linux/slab.h>
2969 +#include <linux/i2c.h>
2971 +#ifndef I2C_CLIENT_END
2972 +#error "********************************************************"
2973 +#error " Sorry, this driver needs the new I2C stack. "
2974 +#error " You can get it at http://www2.lm-sensors.nu/~lm78/. "
2975 +#error "********************************************************"
2978 +#include <linux/i2c-algo-bit.h>
2980 +#include <asm/semaphore.h>
2982 +#include "kcompat.h"
2983 +#include "lirc_dev.h"
2984 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
2985 +#include "../drivers/char/bttv.h"
2987 +#include "../drivers/media/video/bttv.h"
2991 + struct lirc_plugin l;
2992 + struct i2c_client c;
2994 + unsigned char b[3];
2995 + unsigned char bits;
2996 + unsigned char flag;
2999 +/* ----------------------------------------------------------------------- */
3000 +/* insmod parameters */
3002 +static int debug = 0; /* debug output */
3003 +static int minor = -1; /* minor number */
3005 +MODULE_PARM(debug,"i");
3006 +MODULE_PARM(minor,"i");
3008 +#define dprintk if (debug) printk
3010 +/* ----------------------------------------------------------------------- */
3012 +#define DEVICE_NAME "lirc_i2c"
3014 +/* ----------------------------------------------------------------------- */
3016 +static inline int reverse(int data, int bits)
3021 + for (c=0,i=0; i<bits; i++) {
3022 + c |= (((data & (1<<i)) ? 1:0)) << (bits-1-i);
3028 +static int add_to_buf_pcf8574(void* data, struct lirc_buffer* buf)
3030 + struct IR *ir = data;
3032 + unsigned char all, mask;
3033 + unsigned char key;
3035 + /* compute all valid bits (key code + pressed/release flag) */
3036 + all = ir->bits | ir->flag;
3038 + /* save IR writable mask bits */
3039 + mask = i2c_smbus_read_byte(&ir->c) & ~all;
3041 + /* send bit mask */
3042 + rc = i2c_smbus_write_byte(&ir->c, (0xff & all) | mask);
3044 + /* receive scan code */
3045 + rc = i2c_smbus_read_byte(&ir->c);
3048 + dprintk(DEVICE_NAME ": %s read error\n", ir->c.name);
3052 + /* drop duplicate polls */
3053 + if (ir->b[0] == (rc & all)) {
3056 + ir->b[0] = rc & all;
3058 + dprintk(DEVICE_NAME ": %s key 0x%02X %s\n",
3059 + ir->c.name, rc & ir->bits,
3060 + (rc & ir->flag) ? "released" : "pressed");
3062 + if (rc & ir->flag) {
3063 + /* ignore released buttons */
3067 + /* set valid key code */
3068 + key = rc & ir->bits;
3069 + lirc_buffer_write_1( buf, &key );
3073 +static int add_to_buf_haup(void* data, struct lirc_buffer* buf)
3075 + struct IR *ir = data;
3076 + unsigned char keybuf[3];
3078 + unsigned char codes[2];
3080 + /* poll IR chip */
3081 + if (3 == i2c_master_recv(&ir->c,keybuf,3)) {
3082 + ir->b[0] = keybuf[0];
3083 + ir->b[1] = keybuf[1];
3084 + ir->b[2] = keybuf[2];
3085 + dprintk(KERN_DEBUG DEVICE_NAME ": key (0x%02x/0x%02x)\n",
3086 + ir->b[0], ir->b[1]);
3088 + dprintk(KERN_DEBUG DEVICE_NAME ": read error\n");
3089 + /* keep last successfull read buffer */
3092 + /* key pressed ? */
3093 + if ((ir->b[0] & 0x80) == 0)
3096 + /* look what we have */
3097 + code = (((__u16)ir->b[0]&0x7f)<<6) | (ir->b[1]>>2);
3099 + codes[0] = (code >> 8) & 0xff;
3100 + codes[1] = code & 0xff;
3103 + lirc_buffer_write_1( buf, codes );
3107 +static int add_to_buf_pixelview(void* data, struct lirc_buffer* buf)
3109 + struct IR *ir = data;
3110 + unsigned char key;
3112 + /* poll IR chip */
3113 + if (1 != i2c_master_recv(&ir->c,&key,1)) {
3114 + dprintk(KERN_DEBUG DEVICE_NAME ": read error\n");
3117 + dprintk(KERN_DEBUG DEVICE_NAME ": key %02x\n", key);
3120 + lirc_buffer_write_1( buf, &key );
3124 +static int add_to_buf_pv951(void* data, struct lirc_buffer* buf)
3126 + struct IR *ir = data;
3127 + unsigned char key;
3128 + unsigned char codes[4];
3130 + /* poll IR chip */
3131 + if (1 != i2c_master_recv(&ir->c,&key,1)) {
3132 + dprintk(KERN_DEBUG DEVICE_NAME ": read error\n");
3138 + dprintk(KERN_DEBUG DEVICE_NAME ": key %02x\n", key);
3142 + codes[2] = reverse(key,8);
3143 + codes[3] = (~codes[2])&0xff;
3145 + lirc_buffer_write_1( buf, codes );
3149 +static int add_to_buf_knc1(void *data, struct lirc_buffer* buf)
3151 + static unsigned char last_key = 0xFF;
3152 + struct IR *ir = data;
3153 + unsigned char key;
3155 + /* poll IR chip */
3156 + if (1 != i2c_master_recv(&ir->c,&key,1)) {
3157 + dprintk(KERN_DEBUG DEVICE_NAME ": read error\n");
3161 + /* it seems that 0xFE indicates that a button is still hold
3162 + down, while 0xFF indicates that no button is hold
3163 + down. 0xFE sequences are sometimes interrupted by 0xFF */
3165 + dprintk(KERN_DEBUG DEVICE_NAME ": key %02x\n", key);
3170 + if ( key == 0xFE )
3174 + lirc_buffer_write_1( buf, &key );
3179 +static int set_use_inc(void* data)
3181 + struct IR *ir = data;
3183 + /* lock bttv in memory while /dev/lirc is in use */
3184 + /* this is completely broken code. lirc_unregister_plugin()
3185 + must be possible even when the device is open */
3187 + i2c_use_client(&ir->c);
3189 + if (ir->c.adapter->inc_use)
3190 + ir->c.adapter->inc_use(ir->c.adapter);
3193 + MOD_INC_USE_COUNT;
3197 +static void set_use_dec(void* data)
3199 + struct IR *ir = data;
3202 + i2c_release_client(&ir->c);
3204 + if (ir->c.adapter->dec_use)
3205 + ir->c.adapter->dec_use(ir->c.adapter);
3207 + MOD_DEC_USE_COUNT;
3210 +static struct lirc_plugin lirc_template = {
3212 + set_use_inc: set_use_inc,
3213 + set_use_dec: set_use_dec
3216 +/* ----------------------------------------------------------------------- */
3218 +static int ir_attach(struct i2c_adapter *adap, int addr,
3219 + unsigned short flags, int kind);
3220 +static int ir_detach(struct i2c_client *client);
3221 +static int ir_probe(struct i2c_adapter *adap);
3222 +static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg);
3224 +static struct i2c_driver driver = {
3225 + name: "i2c ir driver",
3226 + id: I2C_DRIVERID_EXP3, /* FIXME */
3227 + flags: I2C_DF_NOTIFY,
3228 + attach_adapter: ir_probe,
3229 + detach_client: ir_detach,
3230 + command: ir_command,
3233 +static struct i2c_client client_template =
3239 +static int ir_attach(struct i2c_adapter *adap, int addr,
3240 + unsigned short flags, int kind)
3244 + client_template.adapter = adap;
3245 + client_template.addr = addr;
3247 + if (NULL == (ir = kmalloc(sizeof(struct IR),GFP_KERNEL)))
3249 + memcpy(&ir->l,&lirc_template,sizeof(struct lirc_plugin));
3250 + memcpy(&ir->c,&client_template,sizeof(struct i2c_client));
3252 + ir->c.adapter = adap;
3253 + ir->c.addr = addr;
3255 + i2c_set_clientdata(&ir->c, ir);
3260 + ir->l.minor = minor;
3261 + ir->l.sample_rate = 10;
3267 + strcpy(ir->c.name,"Pixelview IR");
3268 + ir->l.code_length = 8;
3269 + ir->l.add_to_buf=add_to_buf_pixelview;
3272 + strcpy(ir->c.name,"PV951 IR");
3273 + ir->l.code_length = 32;
3274 + ir->l.add_to_buf=add_to_buf_pv951;
3278 + strcpy(ir->c.name,"Hauppauge IR");
3279 + ir->l.code_length = 13;
3280 + ir->l.add_to_buf=add_to_buf_haup;
3283 + strcpy(ir->c.name,"KNC ONE IR");
3284 + ir->l.code_length = 8;
3285 + ir->l.add_to_buf=add_to_buf_knc1;
3289 + strcpy(ir->c.name,"TV-Box IR");
3290 + ir->l.code_length = 8;
3291 + ir->l.add_to_buf=add_to_buf_pcf8574;
3292 + ir->bits = flags & 0xff;
3293 + ir->flag = (flags >> 8) & 0xff;
3297 + /* shouldn't happen */
3298 + printk("lirc_i2c: Huh? unknown i2c address (0x%02x)?\n",addr);
3302 + printk("lirc_i2c: chip found @ 0x%02x (%s)\n",addr,ir->c.name);
3304 + /* register device */
3305 + i2c_attach_client(&ir->c);
3306 + ir->l.minor = lirc_register_plugin(&ir->l);
3308 + i2c_use_client(&ir->c);
3310 + if (ir->c.adapter->inc_use)
3311 + ir->c.adapter->inc_use(ir->c.adapter);
3317 +static int ir_detach(struct i2c_client *client)
3320 + struct IR *ir = i2c_get_clientdata(client);
3322 + struct IR *ir = client->data;
3325 + /* unregister device */
3327 + i2c_release_client(&ir->c);
3329 + if (ir->c.adapter->dec_use)
3330 + ir->c.adapter->dec_use(ir->c.adapter);
3332 + lirc_unregister_plugin(ir->l.minor);
3333 + i2c_detach_client(&ir->c);
3340 +static int ir_probe(struct i2c_adapter *adap) {
3342 + /* The external IR receiver is at i2c address 0x34 (0x35 for
3343 + reads). Future Hauppauge cards will have an internal
3344 + receiver at 0x30 (0x31 for reads). In theory, both can be
3345 + fitted, and Hauppauge suggest an external overrides an
3348 + That's why we probe 0x1a (~0x34) first. CB
3351 + static const int probe[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
3352 + struct i2c_client c; char buf; int i,rc;
3354 + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) {
3355 + memset(&c,0,sizeof(c));
3357 + for (i = 0; -1 != probe[i]; i++) {
3358 + c.addr = probe[i];
3359 + rc = i2c_master_recv(&c,&buf,1);
3360 + dprintk("lirc_i2c: probe 0x%02x @ %s: %s\n",
3361 + probe[i], adap->name,
3362 + (1 == rc) ? "yes" : "no");
3365 + ir_attach(adap,probe[i],0,0);
3370 + /* Asus TV-Box and Creative/VisionTek BreakOut-Box (PCF8574) */
3371 + else if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_RIVA)) {
3372 + /* addresses to probe;
3373 + leave 0x24 and 0x25 because SAA7113H possibly uses it
3374 + 0x21 and 0x22 possibly used by SAA7108E
3375 + Asus: 0x21 is a correct address (channel 1 of PCF8574)
3376 + Creative: 0x23 is a correct address (channel 3 of PCF8574)
3377 + VisionTek: 0x23 is a correct address (channel 3 of PCF8574)
3379 + static const int pcf_probe[] = { 0x20, 0x21, 0x22, 0x23,
3380 + 0x24, 0x25, 0x26, 0x27, -1 };
3381 + int ret1, ret2, ret3, ret4;
3382 + unsigned char bits = 0, flag = 0;
3384 + memset(&c,0,sizeof(c));
3386 + for (i = 0; -1 != pcf_probe[i]; i++) {
3387 + c.addr = pcf_probe[i];
3388 + ret1 = i2c_smbus_write_byte(&c, 0xff);
3389 + ret2 = i2c_smbus_read_byte(&c);
3390 + ret3 = i2c_smbus_write_byte(&c, 0x00);
3391 + ret4 = i2c_smbus_read_byte(&c);
3393 + /* ensure that the writable bitmask works correctly */
3395 + if (ret1 != -1 && ret2 != -1 &&
3396 + ret3 != -1 && ret4 != -1) {
3397 + /* in the Asus TV-Box: bit 1-0 */
3398 + if (((ret2 & 0x03) == 0x03) &&
3399 + ((ret4 & 0x03) == 0x00)) {
3400 + bits = (unsigned char) ~0x07;
3404 + /* in the Creative/VisionTek BreakOut-Box: bit 7-6 */
3405 + if (((ret2 & 0xc0) == 0xc0) &&
3406 + ((ret4 & 0xc0) == 0x00)) {
3407 + bits = (unsigned char) ~0xe0;
3412 + dprintk(DEVICE_NAME ": probe 0x%02x @ %s: %s\n",
3413 + c.addr, adap->name, rc ? "yes" : "no");
3415 + ir_attach(adap,pcf_probe[i],bits|(flag<<8),0);
3422 +static int ir_command(struct i2c_client *client,unsigned int cmd, void *arg)
3428 +/* ----------------------------------------------------------------------- */
3430 +MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller, Stefan Jahn");
3431 +MODULE_DESCRIPTION("Infrared receiver driver for Hauppauge and Pixelview cards (i2c stack)");
3432 +#ifdef MODULE_LICENSE
3433 +MODULE_LICENSE("GPL");
3439 +int init_module(void)
3441 +int lirc_i2c_init(void)
3444 + request_module("bttv");
3445 + request_module("rivatv");
3446 + i2c_add_driver(&driver);
3451 +void cleanup_module(void)
3453 + i2c_del_driver(&driver);
3458 + * Overrides for Emacs so that we follow Linus's tabbing style.
3459 + * ---------------------------------------------------------------------------
3460 + * Local variables:
3461 + * c-basic-offset: 8
3464 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_it87.c linux-2.6.8-rc4/drivers/char/lirc/lirc_it87.c
3465 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_it87.c 1970-01-01 01:00:00.000000000 +0100
3466 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_it87.c 2004-04-27 20:45:31.000000000 +0200
3469 + * LIRC driver for ITE IT8712/IT8705 CIR port
3471 + * Copyright (C) 2001 Hans-Günter Lütke Uphues <hg_lu@web.de>
3473 + * This program is free software; you can redistribute it and/or
3474 + * modify it under the terms of the GNU General Public License as
3475 + * published by the Free Software Foundation; either version 2 of the
3476 + * License, or (at your option) any later version.
3478 + * This program is distributed in the hope that it will be useful, but
3479 + * WITHOUT ANY WARRANTY; without even the implied warranty of
3480 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3481 + * General Public License for more details.
3483 + * You should have received a copy of the GNU General Public License
3484 + * along with this program; if not, write to the Free Software
3485 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
3488 + * ITE IT8705 and IT8712(not tested) CIR-port support for lirc based
3489 + * via cut and paste from lirc_sir.c (C) 2000 Milan Pikula
3491 + * Attention: Sendmode only tested with debugging logs
3493 + * 2001/02/27 Christoph Bartelmus <lirc@bartelmus.de> :
3494 + * reimplemented read function
3498 +#include <linux/version.h>
3499 +#include <linux/module.h>
3501 +#ifdef HAVE_CONFIG_H
3502 +# include <config.h>
3505 +#include <linux/config.h>
3508 +#include <linux/sched.h>
3509 +#include <linux/errno.h>
3510 +#include <linux/signal.h>
3511 +#include <linux/fs.h>
3512 +#include <linux/interrupt.h>
3513 +#include <linux/ioport.h>
3514 +#include <linux/kernel.h>
3515 +#include <linux/major.h>
3516 +#include <linux/serial_reg.h>
3517 +#include <linux/time.h>
3518 +#include <linux/string.h>
3519 +#include <linux/types.h>
3520 +#include <linux/wait.h>
3521 +#include <linux/mm.h>
3522 +#include <linux/delay.h>
3523 +#include <linux/poll.h>
3524 +#include <asm/system.h>
3525 +#include <asm/segment.h>
3526 +#include <asm/io.h>
3527 +#include <asm/irq.h>
3528 +#include <asm/fcntl.h>
3530 +#include <linux/timer.h>
3532 +#include <linux/lirc.h>
3533 +#include "lirc_dev.h"
3534 +#include "kcompat.h"
3536 +#include "lirc_it87.h"
3538 +static unsigned long it87_bits_in_byte_out = 0;
3539 +static unsigned long it87_send_counter = 0;
3540 +static unsigned char it87_RXEN_mask = IT87_CIR_RCR_RXEN;
3542 +#define RBUF_LEN 1024
3543 +#define WBUF_LEN 1024
3545 +#define LIRC_DRIVER_NAME "lirc_it87"
3547 +/* timeout for sequences in jiffies (=5/100s) */
3548 +/* must be longer than TIME_CONST */
3549 +#define IT87_TIMEOUT (HZ*5/100)
3551 +static int io = IT87_CIR_DEFAULT_IOBASE;
3552 +static int irq = IT87_CIR_DEFAULT_IRQ;
3553 +static unsigned char it87_freq = 38; /* kHz */
3554 +/* receiver demodulator default: off */
3555 +static unsigned char it87_enable_demodulator = 0;
3557 +static spinlock_t timer_lock = SPIN_LOCK_UNLOCKED;
3558 +static struct timer_list timerlist;
3559 +/* time of last signal change detected */
3560 +static struct timeval last_tv = {0, 0};
3561 +/* time of last UART data ready interrupt */
3562 +static struct timeval last_intr_tv = {0, 0};
3563 +static int last_value = 0;
3565 +static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue);
3567 +static spinlock_t hardware_lock = SPIN_LOCK_UNLOCKED;
3568 +static spinlock_t dev_lock = SPIN_LOCK_UNLOCKED;
3570 +static lirc_t rx_buf[RBUF_LEN]; unsigned int rx_tail = 0, rx_head = 0;
3571 +static lirc_t tx_buf[WBUF_LEN];
3573 +/* SECTION: Prototypes */
3575 +/* Communication with user-space */
3576 +static int lirc_open(struct inode * inode,
3577 + struct file * file);
3578 +static int lirc_close(struct inode * inode,
3579 + struct file *file);
3580 +static unsigned int lirc_poll(struct file * file,
3581 + poll_table * wait);
3582 +static ssize_t lirc_read(struct file * file,
3586 +static ssize_t lirc_write(struct file * file,
3590 +static int lirc_ioctl(struct inode *node,
3591 + struct file *filep,
3593 + unsigned long arg);
3594 +static void add_read_queue(int flag,
3595 + unsigned long val);
3597 +static int init_chrdev(void);
3598 +static void drop_chrdev(void);
3601 +static irqreturn_t it87_interrupt(int irq, void * dev_id,
3602 + struct pt_regs * regs);
3603 +static void send_space(unsigned long len);
3604 +static void send_pulse(unsigned long len);
3605 +static void init_send(void);
3606 +static void terminate_send(unsigned long len);
3607 +static int init_hardware(void);
3608 +static void drop_hardware(void);
3609 + /* Initialisation */
3610 +static int init_port(void);
3611 +static void drop_port(void);
3612 +int init_module(void);
3613 +void cleanup_module(void);
3616 +/* SECTION: Communication with user-space */
3618 +static int lirc_open(struct inode * inode,
3619 + struct file * file)
3621 + spin_lock(&dev_lock);
3623 + spin_unlock(&dev_lock);
3626 + MOD_INC_USE_COUNT;
3627 + spin_unlock(&dev_lock);
3632 +static int lirc_close(struct inode * inode,
3633 + struct file *file)
3635 + MOD_DEC_USE_COUNT;
3640 +static unsigned int lirc_poll(struct file * file,
3641 + poll_table * wait)
3643 + poll_wait(file, &lirc_read_queue, wait);
3644 + if (rx_head != rx_tail)
3645 + return POLLIN | POLLRDNORM;
3650 +static ssize_t lirc_read(struct file * file,
3660 + if(file->f_flags & O_NONBLOCK &&
3666 + retval=wait_event_interruptible(lirc_read_queue,
3667 + rx_head!=rx_tail);
3673 + retval=verify_area(VERIFY_WRITE,(void *) buf+n,
3679 + copy_to_user((void *) buf+n,(void *) (rx_buf+rx_head),
3681 + rx_head=(rx_head+1)&(RBUF_LEN-1);
3682 + n+=sizeof(lirc_t);
3692 +static ssize_t lirc_write(struct file * file,
3700 + if(n%sizeof(lirc_t) || (n/sizeof(lirc_t)) > WBUF_LEN)
3702 + retval = verify_area(VERIFY_READ, buf, n);
3705 + copy_from_user(tx_buf, buf, n);
3707 + n/=sizeof(lirc_t);
3713 + send_pulse(tx_buf[i]);
3718 + send_space(tx_buf[i]);
3721 + terminate_send(tx_buf[i-1]);
3726 +static int lirc_ioctl(struct inode *node,
3727 + struct file *filep,
3729 + unsigned long arg)
3732 + unsigned long value = 0;
3733 + unsigned int ivalue;
3735 + if (cmd == LIRC_GET_FEATURES)
3736 + value = LIRC_CAN_SEND_PULSE |
3737 + LIRC_CAN_SET_SEND_CARRIER |
3738 + LIRC_CAN_REC_MODE2;
3739 + else if (cmd == LIRC_GET_SEND_MODE)
3740 + value = LIRC_MODE_PULSE;
3741 + else if (cmd == LIRC_GET_REC_MODE)
3742 + value = LIRC_MODE_MODE2;
3745 + case LIRC_GET_FEATURES:
3746 + case LIRC_GET_SEND_MODE:
3747 + case LIRC_GET_REC_MODE:
3748 + retval = put_user(value, (unsigned long *) arg);
3751 + case LIRC_SET_SEND_MODE:
3752 + case LIRC_SET_REC_MODE:
3753 + retval = get_user(value, (unsigned long *) arg);
3756 + case LIRC_SET_SEND_CARRIER:
3757 + retval=get_user(ivalue,(unsigned int *) arg);
3758 + if(retval) return(retval);
3760 + if (ivalue > IT87_CIR_FREQ_MAX ||
3761 + ivalue < IT87_CIR_FREQ_MIN) return(-EINVAL);
3763 + it87_freq = ivalue;
3765 + unsigned long hw_flags;
3767 + spin_lock_irqsave(&hardware_lock, hw_flags);
3768 + outb(((inb(io + IT87_CIR_TCR2) & IT87_CIR_TCR2_TXMPW) |
3769 + (it87_freq - IT87_CIR_FREQ_MIN) << 3),
3770 + io + IT87_CIR_TCR2);
3771 + spin_unlock_irqrestore(&hardware_lock, hw_flags);
3773 + printk(KERN_DEBUG LIRC_DRIVER_NAME
3774 + " demodulation frequency: %d kHz\n", it87_freq);
3781 + retval = -ENOIOCTLCMD;
3787 + if (cmd == LIRC_SET_REC_MODE) {
3788 + if (value != LIRC_MODE_MODE2)
3790 + } else if (cmd == LIRC_SET_SEND_MODE) {
3791 + if (value != LIRC_MODE_PULSE)
3797 +static void add_read_queue(int flag,
3798 + unsigned long val)
3800 + unsigned int new_rx_tail;
3803 +#ifdef DEBUG_SIGNAL
3804 + printk(KERN_DEBUG LIRC_DRIVER_NAME
3805 + ": add flag %d with val %lu\n",
3809 + newval = val & PULSE_MASK;
3811 + /* statistically pulses are ~TIME_CONST/2 too long: we could
3812 + maybe make this more exactly but this is good enough */
3813 + if(flag) /* pulse */ {
3814 + if(newval>TIME_CONST/2) {
3815 + newval-=TIME_CONST/2;
3817 + else /* should not ever happen */ {
3820 + newval|=PULSE_BIT;
3823 + newval+=TIME_CONST/2;
3825 + new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1);
3826 + if (new_rx_tail == rx_head) {
3828 + printk(KERN_WARNING LIRC_DRIVER_NAME ": Buffer overrun.\n");
3832 + rx_buf[rx_tail] = newval;
3833 + rx_tail = new_rx_tail;
3834 + wake_up_interruptible(&lirc_read_queue);
3838 +static struct file_operations lirc_fops = {
3840 + write: lirc_write,
3842 + ioctl: lirc_ioctl,
3844 + release: lirc_close,
3847 +static int set_use_inc(void* data)
3849 +#if WE_DONT_USE_LOCAL_OPEN_CLOSE
3850 + MOD_INC_USE_COUNT;
3855 +static void set_use_dec(void* data)
3857 +#if WE_DONT_USE_LOCAL_OPEN_CLOSE
3858 + MOD_DEC_USE_COUNT;
3861 +static struct lirc_plugin plugin = {
3862 + name: LIRC_DRIVER_NAME,
3869 + set_use_inc: set_use_inc,
3870 + set_use_dec: set_use_dec,
3876 +int init_chrdev(void)
3878 + plugin.minor = lirc_register_plugin(&plugin);
3880 + if (plugin.minor < 0) {
3881 + printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n");
3888 +static void drop_chrdev(void)
3890 + lirc_unregister_plugin(plugin.minor);
3895 +/* SECTION: Hardware */
3896 +static long delta(struct timeval * tv1,
3897 + struct timeval * tv2)
3899 + unsigned long deltv;
3901 + deltv = tv2->tv_sec - tv1->tv_sec;
3905 + deltv = deltv*1000000 +
3912 +static void it87_timeout(unsigned long data)
3914 + /* if last received signal was a pulse, but receiving stopped
3915 + within the 9 bit frame, we need to finish this pulse and
3916 + simulate a signal change to from pulse to space. Otherwise
3917 + upper layers will receive two sequences next time. */
3919 + unsigned long flags;
3920 + unsigned long pulse_end;
3922 + /* avoid interference with interrupt */
3923 + spin_lock_irqsave(&timer_lock, flags);
3925 + /* determine 'virtual' pulse end: */
3926 + pulse_end = delta(&last_tv, &last_intr_tv);
3927 +#ifdef DEBUG_SIGNAL
3928 + printk(KERN_DEBUG LIRC_DRIVER_NAME
3929 + ": timeout add %d for %lu usec\n",
3933 + add_read_queue(last_value,
3936 + last_tv=last_intr_tv;
3938 + spin_unlock_irqrestore(&timer_lock, flags);
3942 +static irqreturn_t it87_interrupt(int irq,
3944 + struct pt_regs * regs)
3946 + unsigned char data;
3947 + struct timeval curr_tv;
3948 + static unsigned long deltv;
3949 + unsigned long deltintrtv;
3950 + unsigned long flags, hw_flags;
3954 + iir = inb(io + IT87_CIR_IIR);
3956 + switch (iir & IT87_CIR_IIR_IID) {
3959 + lsr = inb(io + IT87_CIR_RSR) & (IT87_CIR_RSR_RXFTO |
3960 + IT87_CIR_RSR_RXFBC);
3961 + fifo = lsr & IT87_CIR_RSR_RXFBC;
3962 +#ifdef DEBUG_SIGNAL
3963 + printk(KERN_DEBUG LIRC_DRIVER_NAME
3964 + "iir: 0x%x fifo: 0x%x\n", iir, lsr);
3967 + /* avoid interference with timer */
3968 + spin_lock_irqsave(&timer_lock, flags);
3969 + spin_lock_irqsave(&hardware_lock, hw_flags);
3971 + del_timer(&timerlist);
3972 + data = inb(io + IT87_CIR_DR);
3973 +#ifdef DEBUG_SIGNAL
3974 + printk(KERN_DEBUG LIRC_DRIVER_NAME
3978 + do_gettimeofday(&curr_tv);
3979 + deltv = delta(&last_tv, &curr_tv);
3980 + deltintrtv = delta(&last_intr_tv, &curr_tv);
3981 +#ifdef DEBUG_SIGNAL
3982 + printk(KERN_DEBUG LIRC_DRIVER_NAME
3983 + ": t %lu , d %d\n",
3987 + /* if nothing came in last 2 cycles,
3989 + if (deltintrtv > TIME_CONST * 2) {
3991 +#ifdef DEBUG_SIGNAL
3992 + printk(KERN_DEBUG LIRC_DRIVER_NAME ": GAP\n");
3994 + /* simulate signal change */
3995 + add_read_queue(last_value,
3999 + last_tv.tv_sec = last_intr_tv.tv_sec;
4000 + last_tv.tv_usec = last_intr_tv.tv_usec;
4001 + deltv = deltintrtv;
4005 + if (data ^ last_value) {
4006 + /* deltintrtv > 2*TIME_CONST,
4008 + /* the other case is timeout */
4009 + add_read_queue(last_value,
4010 + deltv-TIME_CONST);
4011 + last_value = data;
4012 + last_tv = curr_tv;
4013 + if(last_tv.tv_usec>=TIME_CONST) {
4014 + last_tv.tv_usec-=TIME_CONST;
4018 + last_tv.tv_usec+=1000000-
4022 + last_intr_tv = curr_tv;
4024 + /* start timer for end of sequence detection */
4025 + timerlist.expires = jiffies + IT87_TIMEOUT;
4026 + add_timer(&timerlist);
4028 + outb((inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN) |
4029 + IT87_CIR_RCR_RXACT,
4030 + io + IT87_CIR_RCR);
4031 + if (it87_RXEN_mask) {
4032 + outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN,
4033 + io + IT87_CIR_RCR);
4037 + while (fifo != 0);
4038 + spin_unlock_irqrestore(&hardware_lock, hw_flags);
4039 + spin_unlock_irqrestore(&timer_lock, flags);
4041 + return IRQ_RETVAL(IRQ_HANDLED);
4045 +#ifdef DEBUG_SIGNAL
4046 + printk(KERN_DEBUG LIRC_DRIVER_NAME
4047 + "unknown IRQ (shouldn't happen) !!\n");
4049 + return IRQ_RETVAL(IRQ_NONE);
4054 +static void send_it87(unsigned long len,
4055 + unsigned long stime,
4056 + unsigned char send_byte,
4057 + unsigned int count_bits)
4059 + long count = len / stime;
4060 + long time_left = 0;
4061 + static unsigned char byte_out = 0;
4063 +#ifdef DEBUG_SIGNAL
4064 + printk(KERN_DEBUG LIRC_DRIVER_NAME
4065 + "send_it87: len=%ld, sb=%d\n",
4069 + time_left = (long)len - (long)count * (long)stime;
4070 + count += ((2 * time_left) / stime);
4073 + for (i=0; i<count_bits; i++) {
4074 + byte_out = (byte_out << 1) | (send_byte & 1);
4075 + it87_bits_in_byte_out++;
4077 + if (it87_bits_in_byte_out == 8) {
4078 +#ifdef DEBUG_SIGNAL
4079 + printk(KERN_DEBUG LIRC_DRIVER_NAME
4080 + "out=0x%x, tsr_txfbc: 0x%x\n",
4082 + inb(io + IT87_CIR_TSR) &
4083 + IT87_CIR_TSR_TXFBC);
4085 + while ((inb(io + IT87_CIR_TSR) &
4086 + IT87_CIR_TSR_TXFBC) >= IT87_CIR_FIFO_SIZE);
4088 + unsigned long hw_flags;
4090 + spin_lock_irqsave(&hardware_lock, hw_flags);
4091 + outb(byte_out, io + IT87_CIR_DR);
4092 + spin_unlock_irqrestore(&hardware_lock, hw_flags);
4094 + it87_bits_in_byte_out = 0;
4095 + it87_send_counter++;
4104 +maybe: exchange space and pulse because
4105 +it8705 only modulates 0-bits
4109 +static void send_space(unsigned long len)
4114 + IT87_CIR_BAUDRATE_DIVISOR);
4117 +static void send_pulse(unsigned long len)
4122 + IT87_CIR_BAUDRATE_DIVISOR);
4126 +static void init_send()
4128 + unsigned long flags;
4130 + spin_lock_irqsave(&hardware_lock, flags);
4131 + /* RXEN=0: receiver disable */
4132 + it87_RXEN_mask = 0;
4133 + outb(inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN,
4134 + io + IT87_CIR_RCR);
4135 + spin_unlock_irqrestore(&hardware_lock, flags);
4136 + it87_bits_in_byte_out = 0;
4137 + it87_send_counter = 0;
4141 +static void terminate_send(unsigned long len)
4143 + unsigned long flags;
4144 + unsigned long last = 0;
4146 + last = it87_send_counter;
4147 + /* make sure all necessary data has been sent */
4148 + while (last == it87_send_counter)
4150 + /* wait until all data sent */
4151 + while ((inb(io + IT87_CIR_TSR) & IT87_CIR_TSR_TXFBC) != 0);
4152 + /* then reenable receiver */
4153 + spin_lock_irqsave(&hardware_lock, flags);
4154 + it87_RXEN_mask = IT87_CIR_RCR_RXEN;
4155 + outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN,
4156 + io + IT87_CIR_RCR);
4157 + spin_unlock_irqrestore(&hardware_lock, flags);
4161 +static int init_hardware(void)
4163 + unsigned long flags;
4164 + unsigned char it87_rcr = 0;
4166 + spin_lock_irqsave(&hardware_lock, flags);
4167 + /* init cir-port */
4168 + /* enable r/w-access to Baudrate-Register */
4169 + outb(IT87_CIR_IER_BR, io + IT87_CIR_IER);
4170 + outb(IT87_CIR_BAUDRATE_DIVISOR % 0x100, io+IT87_CIR_BDLR);
4171 + outb(IT87_CIR_BAUDRATE_DIVISOR / 0x100, io+IT87_CIR_BDHR);
4172 + /* Baudrate Register off, define IRQs: Input only */
4173 + outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RDAIE, io + IT87_CIR_IER);
4174 + /* RX: HCFS=0, RXDCR = 001b (35,6..40,3 kHz), RXEN=1 */
4175 + it87_rcr = (IT87_CIR_RCR_RXEN & it87_RXEN_mask) | 0x1;
4176 + if (it87_enable_demodulator)
4177 + it87_rcr |= IT87_CIR_RCR_RXEND;
4178 + outb(it87_rcr, io + IT87_CIR_RCR);
4179 + /* TX: 38kHz, 13,3us (pulse-width */
4180 + outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x06,
4181 + io + IT87_CIR_TCR2);
4182 + spin_unlock_irqrestore(&hardware_lock, flags);
4187 +static void drop_hardware(void)
4189 + unsigned long flags;
4191 + spin_lock_irqsave(&hardware_lock, flags);
4193 + /* receiver disable */
4194 + it87_RXEN_mask = 0;
4195 + outb(0x1, io + IT87_CIR_RCR);
4196 + /* turn off irqs */
4197 + outb(0, io + IT87_CIR_IER);
4199 + outb(IT87_CIR_TCR1_FIFOCLR, io+IT87_CIR_TCR1);
4201 + outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER);
4203 + spin_unlock_irqrestore(&hardware_lock, flags);
4207 +static unsigned char it87_read(unsigned char port)
4209 + outb(port, IT87_ADRPORT);
4210 + return inb(IT87_DATAPORT);
4214 +static void it87_write(unsigned char port,
4215 + unsigned char data)
4217 + outb(port, IT87_ADRPORT);
4218 + outb(data, IT87_DATAPORT);
4222 +/* SECTION: Initialisation */
4224 +static int init_port(void)
4228 + unsigned char init_bytes[4] = {IT87_INIT};
4229 + unsigned char it87_chipid = 0;
4230 + unsigned char ldn = 0;
4231 + unsigned int it87_io = 0;
4232 + unsigned int it87_irq = 0;
4234 + /* Enter MB PnP Mode */
4235 + outb(init_bytes[0], IT87_ADRPORT);
4236 + outb(init_bytes[1], IT87_ADRPORT);
4237 + outb(init_bytes[2], IT87_ADRPORT);
4238 + outb(init_bytes[3], IT87_ADRPORT);
4240 + /* 8712 or 8705 ? */
4241 + it87_chipid = it87_read(IT87_CHIP_ID1);
4242 + if (it87_chipid != 0x87) {
4246 + it87_chipid = it87_read(IT87_CHIP_ID2);
4247 + if ((it87_chipid != 0x12) && (it87_chipid != 0x05)) {
4248 + printk(KERN_INFO LIRC_DRIVER_NAME
4249 + ": no IT8705/12 found, exiting..\n");
4253 + printk(KERN_INFO LIRC_DRIVER_NAME
4254 + ": found IT87%.2x.\n",
4257 + /* get I/O-Port and IRQ */
4258 + if (it87_chipid == 0x12)
4259 + ldn = IT8712_CIR_LDN;
4261 + ldn = IT8705_CIR_LDN;
4262 + it87_write(IT87_LDN, ldn);
4264 + it87_io = it87_read(IT87_CIR_BASE_MSB) * 256 +
4265 + it87_read(IT87_CIR_BASE_LSB);
4266 + if (it87_io == 0) {
4268 + io = IT87_CIR_DEFAULT_IOBASE;
4269 + printk(KERN_INFO LIRC_DRIVER_NAME
4270 + ": set default io 0x%x\n",
4272 + it87_write(IT87_CIR_BASE_MSB, io / 0x100);
4273 + it87_write(IT87_CIR_BASE_LSB, io % 0x100);
4278 + it87_irq = it87_read(IT87_CIR_IRQ);
4279 + if (it87_irq == 0) {
4281 + irq = IT87_CIR_DEFAULT_IRQ;
4282 + printk(KERN_INFO LIRC_DRIVER_NAME
4283 + ": set default irq 0x%x\n",
4285 + it87_write(IT87_CIR_IRQ, irq);
4291 + unsigned long hw_flags;
4293 + spin_lock_irqsave(&hardware_lock, hw_flags);
4295 + outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER);
4297 + outb(IT87_CIR_TCR1_FIFOCLR |
4298 + /* IT87_CIR_TCR1_ILE | */
4299 + IT87_CIR_TCR1_TXRLE |
4300 + IT87_CIR_TCR1_TXENDF, io+IT87_CIR_TCR1);
4301 + spin_unlock_irqrestore(&hardware_lock, hw_flags);
4304 + /* get I/O port access and IRQ line */
4305 + retval = check_region(io, 8);
4307 + printk(KERN_ERR LIRC_DRIVER_NAME
4308 + ": i/o port 0x%.4x already in use.\n",
4310 + /* Leaving MB PnP Mode */
4311 + it87_write(IT87_CFGCTRL, 0x2);
4315 + /* activate CIR-Device */
4316 + it87_write(IT87_CIR_ACT, 0x1);
4318 + /* Leaving MB PnP Mode */
4319 + it87_write(IT87_CFGCTRL, 0x2);
4321 + retval = request_irq(irq, it87_interrupt, 0 /*SA_INTERRUPT*/,
4322 + LIRC_DRIVER_NAME, NULL);
4324 + printk(KERN_ERR LIRC_DRIVER_NAME
4325 + ": IRQ %d already in use.\n",
4330 + request_region(io, 8, LIRC_DRIVER_NAME);
4331 + printk(KERN_INFO LIRC_DRIVER_NAME
4332 + ": I/O port 0x%.4x, IRQ %d.\n",
4336 + init_timer(&timerlist);
4337 + timerlist.function = it87_timeout;
4338 + timerlist.data = 0xabadcafe;
4344 +static void drop_port(void)
4347 + unsigned char init_bytes[4] = {IT87_INIT};
4349 + / * Enter MB PnP Mode * /
4350 + outb(init_bytes[0], IT87_ADRPORT);
4351 + outb(init_bytes[1], IT87_ADRPORT);
4352 + outb(init_bytes[2], IT87_ADRPORT);
4353 + outb(init_bytes[3], IT87_ADRPORT);
4355 + / * deactivate CIR-Device * /
4356 + it87_write(IT87_CIR_ACT, 0x0);
4358 + / * Leaving MB PnP Mode * /
4359 + it87_write(IT87_CFGCTRL, 0x2);
4362 + del_timer_sync(&timerlist);
4363 + free_irq(irq, NULL);
4364 + release_region(io, 8);
4368 +int init_lirc_it87(void)
4372 + init_waitqueue_head(&lirc_read_queue);
4373 + retval = init_port();
4377 + printk(KERN_INFO LIRC_DRIVER_NAME
4378 + ": Installed.\n");
4385 +MODULE_AUTHOR("Hans-Günter Lütke Uphues");
4386 +MODULE_DESCRIPTION("LIRC driver for ITE IT8712/IT8705 CIR port");
4387 +MODULE_PARM(io, "i");
4388 +MODULE_PARM_DESC(io,
4389 + "I/O base address (default: 0x310)");
4390 +MODULE_PARM(irq, "i");
4391 +MODULE_PARM_DESC(irq,
4392 + "Interrupt (1,3-12) (default: 7)");
4393 +MODULE_PARM(it87_enable_demodulator, "i");
4394 +MODULE_PARM_DESC(it87_enable_demodulator,
4395 + "Receiver demodulator enable/disable (1/0), default: 0");
4396 +#ifdef MODULE_LICENSE
4397 +MODULE_LICENSE("GPL");
4405 +int init_module(void)
4409 + retval=init_chrdev();
4412 + retval = init_lirc_it87();
4421 +void cleanup_module(void)
4426 + printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n");
4432 + * Overrides for Emacs so that we follow Linus's tabbing style.
4433 + * ---------------------------------------------------------------------------
4434 + * Local variables:
4435 + * c-basic-offset: 8
4438 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_it87.h linux-2.6.8-rc4/drivers/char/lirc/lirc_it87.h
4439 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_it87.h 1970-01-01 01:00:00.000000000 +0100
4440 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_it87.h 2001-11-15 11:50:19.000000000 +0100
4443 +/* SECTION: Definitions */
4445 +/********************************* ITE IT87xx ************************/
4447 +/* based on the following documentation from ITE:
4448 + a) IT8712F Preliminary CIR Programming Guide V0.1
4449 + b) IT8705F Simple LPC I/O Preliminary Specifiction V0.3
4450 + c) IT8712F EC-LPC I/O Preliminary Specification V0.5
4453 +/* IT8712/05 Ports: */
4454 +#define IT87_ADRPORT 0x2e
4455 +#define IT87_DATAPORT 0x2f
4456 +#define IT87_INIT 0x87, 0x01, 0x55, 0x55
4458 +/* alternate Ports: */
4460 +#define IT87_ADRPORT 0x4e
4461 +#define IT87_DATAPORT 0x4f
4462 +#define IT87_INIT 0x87, 0x01, 0x55, 0xaa
4465 +/* IT8712/05 Registers */
4466 +#define IT87_CFGCTRL 0x2
4467 +#define IT87_LDN 0x7
4468 +#define IT87_CHIP_ID1 0x20
4469 +#define IT87_CHIP_ID2 0x21
4470 +#define IT87_CFG_VERSION 0x22
4471 +#define IT87_SWSUSPEND 0x23
4473 +#define IT8712_CIR_LDN 0xa
4474 +#define IT8705_CIR_LDN 0x7
4476 +/* CIR Configuration Registers: */
4477 +#define IT87_CIR_ACT 0x30
4478 +#define IT87_CIR_BASE_MSB 0x60
4479 +#define IT87_CIR_BASE_LSB 0x61
4480 +#define IT87_CIR_IRQ 0x70
4481 +#define IT87_CIR_CONFIG 0xf0
4483 +/* List of IT87_CIR registers: offset to BaseAddr */
4484 +#define IT87_CIR_DR 0
4485 +#define IT87_CIR_IER 1
4486 +#define IT87_CIR_RCR 2
4487 +#define IT87_CIR_TCR1 3
4488 +#define IT87_CIR_TCR2 4
4489 +#define IT87_CIR_TSR 5
4490 +#define IT87_CIR_RSR 6
4491 +#define IT87_CIR_BDLR 5
4492 +#define IT87_CIR_BDHR 6
4493 +#define IT87_CIR_IIR 7
4495 +/* Bit Definitionen */
4497 +#define IT87_CIR_IER_TM_EN 0x80
4498 +#define IT87_CIR_IER_RESEVED 0x40
4499 +#define IT87_CIR_IER_RESET 0x20
4500 +#define IT87_CIR_IER_BR 0x10
4501 +#define IT87_CIR_IER_IEC 0x8
4502 +#define IT87_CIR_IER_RFOIE 0x4
4503 +#define IT87_CIR_IER_RDAIE 0x2
4504 +#define IT87_CIR_IER_TLDLIE 0x1
4507 +#define IT87_CIR_RCR_RDWOS 0x80
4508 +#define IT87_CIR_RCR_HCFS 0x40
4509 +#define IT87_CIR_RCR_RXEN 0x20
4510 +#define IT87_CIR_RCR_RXEND 0x10
4511 +#define IT87_CIR_RCR_RXACT 0x8
4512 +#define IT87_CIR_RCR_RXDCR 0x7
4515 +#define IT87_CIR_TCR1_FIFOCLR 0x80
4516 +#define IT87_CIR_TCR1_ILE 0x40
4517 +#define IT87_CIR_TCR1_FIFOTL 0x30
4518 +#define IT87_CIR_TCR1_TXRLE 0x8
4519 +#define IT87_CIR_TCR1_TXENDF 0x4
4520 +#define IT87_CIR_TCR1_TXMPM 0x3
4523 +#define IT87_CIR_TCR2_CFQ 0xf8
4524 +#define IT87_CIR_TCR2_TXMPW 0x7
4527 +#define IT87_CIR_TSR_RESERVED 0xc0
4528 +#define IT87_CIR_TSR_TXFBC 0x3f
4531 +#define IT87_CIR_RSR_RXFTO 0x80
4532 +#define IT87_CIR_RSR_RESERVED 0x40
4533 +#define IT87_CIR_RSR_RXFBC 0x3f
4536 +#define IT87_CIR_IIR_RESERVED 0xf8
4537 +#define IT87_CIR_IIR_IID 0x6
4538 +#define IT87_CIR_IIR_IIP 0x1
4541 +#define IT87_CIR_TM_IL_SEL 0x80
4542 +#define IT87_CIR_TM_RESERVED 0x40
4543 +#define IT87_CIR_TM_TM_REG 0x3f
4545 +#define IT87_CIR_FIFO_SIZE 32
4547 +/* Baudratedivisor for IT87: power of 2: only 1,2,4 or 8) */
4548 +#define IT87_CIR_BAUDRATE_DIVISOR 0x1
4549 +#define IT87_CIR_DEFAULT_IOBASE 0x310
4550 +#define IT87_CIR_DEFAULT_IRQ 0x7
4551 +#define IT87_CIR_SPACE 0x00
4552 +#define IT87_CIR_PULSE 0xff
4553 +#define IT87_CIR_FREQ_MIN 27
4554 +#define IT87_CIR_FREQ_MAX 58
4555 +#define TIME_CONST (IT87_CIR_BAUDRATE_DIVISOR * 8000000ul / 115200ul)
4557 +/********************************* ITE IT87xx ************************/
4558 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_mceusb.c linux-2.6.8-rc4/drivers/char/lirc/lirc_mceusb.c
4559 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_mceusb.c 1970-01-01 01:00:00.000000000 +0100
4560 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_mceusb.c 2004-07-25 18:27:33.000000000 +0200
4563 + * USB Microsoft IR Transceiver driver - 0.2
4565 + * Copyright (c) 2003-2004 Dan Conti (dconti@acm.wwu.edu)
4567 + * This driver is based on the USB skeleton driver packaged with the
4568 + * kernel, and the notice from that package has been retained below.
4570 + * The Microsoft IR Transceiver is a neat little IR receiver with two
4571 + * emitters on it designed for Windows Media Center. This driver might
4572 + * work for all media center remotes, but I have only tested it with
4573 + * the philips model. The first revision of this driver only supports
4574 + * the receive function - the transmit function will be much more
4575 + * tricky due to the nature of the hardware. Microsoft chose to build
4576 + * this device inexpensively, therefore making it extra dumb.
4577 + * There is no interrupt endpoint on this device; all usb traffic
4578 + * happens over two bulk endpoints. As a result of this, poll() for
4579 + * this device is an actual hardware poll (instead of a receive queue
4580 + * check) and is rather expensive.
4582 + * All trademarks property of their respective owners. This driver was
4583 + * originally based on the USB skeleton driver, although significant
4584 + * portions of that code have been removed as the driver has evolved.
4586 + * 2003_11_11 - Restructured to minimalize code interpretation in the
4587 + * driver. The normal use case will be with lirc.
4589 + * 2004_01_01 - Removed all code interpretation. Generate mode2 data
4590 + * for passing off to lirc. Cleanup
4592 + * 2004_01_04 - Removed devfs handle. Put in a temporary workaround
4593 + * for a known issue where repeats generate two
4594 + * sequential spaces (last_was_repeat_gap)
4596 + * 2004_02_17 - Changed top level api to no longer use fops, and
4597 + * instead use new interface for polling via
4598 + * lirc_thread. Restructure data read/mode2 generation to
4599 + * a single pass, reducing number of buffers. Rev to .2
4601 + * 2004_02_27 - Last of fixups to plugin->add_to_buf API. Properly
4602 + * handle broken fragments from the receiver. Up the
4603 + * sample rate and remove any pacing from
4604 + * fetch_more_data. Fixes all known issues.
4607 + * - Fix up minor number, registration of major/minor with usb subsystem
4611 + * USB Skeleton driver - 1.1
4613 + * Copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com)
4615 + * This program is free software; you can redistribute it and/or
4616 + * modify it under the terms of the GNU General Public License as
4617 + * published by the Free Software Foundation, version 2.
4620 + * This driver is to be used as a skeleton driver to be able to create a
4621 + * USB driver quickly. The design of it is based on the usb-serial and
4624 + * Thanks to Oliver Neukum, David Brownell, and Alan Stern for their help
4625 + * in debugging this driver.
4630 + * 2003-05-06 - 1.1 - changes due to usb core changes with usb_register_dev()
4631 + * 2003-02-25 - 1.0 - fix races involving urb->status, unlink_urb(), and
4632 + * disconnect. Fix transfer amount in read(). Use
4633 + * macros instead of magic numbers in probe(). Change
4634 + * size variables to size_t. Show how to eliminate
4635 + * DMA bounce buffer.
4636 + * 2002_12_12 - 0.9 - compile fixes and got rid of fixed minor array.
4637 + * 2002_09_26 - 0.8 - changes due to USB core conversion to struct device
4639 + * 2002_02_12 - 0.7 - zero out dev in probe function for devices that do
4640 + * not have both a bulk in and bulk out endpoint.
4641 + * Thanks to Holger Waechtler for the fix.
4642 + * 2001_11_05 - 0.6 - fix minor locking problem in skel_disconnect.
4643 + * Thanks to Pete Zaitcev for the fix.
4644 + * 2001_09_04 - 0.5 - fix devfs bug in skel_disconnect. Thanks to wim delvaux
4645 + * 2001_08_21 - 0.4 - more small bug fixes.
4646 + * 2001_05_29 - 0.3 - more bug fixes based on review from linux-usb-devel
4647 + * 2001_05_24 - 0.2 - bug fixes based on review from linux-usb-devel people
4648 + * 2001_05_01 - 0.1 - first version
4652 +#include <linux/config.h>
4653 +#include <linux/kernel.h>
4654 +#include <linux/errno.h>
4655 +#include <linux/init.h>
4656 +#include <linux/slab.h>
4657 +#include <linux/module.h>
4658 +#include <linux/smp_lock.h>
4659 +#include <linux/usb.h>
4661 +#include <linux/completion.h>
4662 +#include <asm/uaccess.h>
4664 +#include <linux/spinlock.h>
4665 +#include <linux/list.h>
4666 +#include <linux/fcntl.h>
4667 +#include <linux/poll.h>
4668 +#include <linux/sched.h>
4669 +#include <linux/signal.h>
4672 +#ifdef CONFIG_USB_DEBUG
4673 + static int debug = 1;
4678 +#include <linux/lirc.h>
4679 +#include "kcompat.h"
4680 +#include "lirc_dev.h"
4683 +/* Use our own dbg macro */
4685 +#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0)
4687 +/* Version Information */
4688 +#define DRIVER_VERSION "v0.2"
4689 +#define DRIVER_AUTHOR "Dan Conti, dconti@acm.wwu.edu"
4690 +#define DRIVER_DESC "USB Microsoft IR Transceiver Driver"
4691 +#define DRIVER_NAME "lirc_mceusb"
4693 +/* Module paramaters */
4694 +MODULE_PARM(debug, "i");
4695 +MODULE_PARM_DESC(debug, "Debug enabled or not");
4697 +/* Define these values to match your device */
4698 +#define USB_MCEUSB_VENDOR_ID 0x045e
4699 +#define USB_MCEUSB_PRODUCT_ID 0x006d
4701 +/* table of devices that work with this driver */
4702 +static struct usb_device_id mceusb_table [] = {
4703 + { USB_DEVICE(USB_MCEUSB_VENDOR_ID, USB_MCEUSB_PRODUCT_ID) },
4704 + { } /* Terminating entry */
4707 +MODULE_DEVICE_TABLE (usb, mceusb_table);
4709 +/* we can have up to this number of device plugged in at once */
4710 +#define MAX_DEVICES 16
4712 +/* Structure to hold all of our device specific stuff */
4714 + struct usb_device * udev; /* save off the usb device pointer */
4715 + struct usb_interface * interface; /* the interface for this device */
4716 + unsigned char minor; /* the starting minor number for this device */
4717 + unsigned char num_ports; /* the number of ports this device has */
4718 + char num_interrupt_in; /* number of interrupt in endpoints we have */
4719 + char num_bulk_in; /* number of bulk in endpoints we have */
4720 + char num_bulk_out; /* number of bulk out endpoints we have */
4722 + unsigned char * bulk_in_buffer; /* the buffer to receive data */
4723 + int bulk_in_size; /* the size of the receive buffer */
4724 + __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
4726 + unsigned char * bulk_out_buffer; /* the buffer to send data */
4727 + int bulk_out_size; /* the size of the send buffer */
4728 + struct urb * write_urb; /* the urb used to send data */
4729 + __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
4731 + atomic_t write_busy; /* true iff write urb is busy */
4732 + struct completion write_finished; /* wait for the write to finish */
4734 + wait_queue_head_t wait_q; /* for timeouts */
4735 + int open_count; /* number of times this port has been opened */
4736 + struct semaphore sem; /* locks this structure */
4738 + int present; /* if the device is not disconnected */
4740 + struct lirc_plugin* plugin;
4742 + lirc_t lircdata[256]; /* place to store values until lirc processes them */
4743 + int lircidx; /* current index */
4744 + int lirccnt; /* remaining values */
4746 + int usb_valid_bytes_in_bulk_buffer; /* leftover data from a previous read */
4747 + int mce_bytes_left_in_packet; /* for packets split across multiple reads */
4749 + /* Value to hold the last received space; 0 if last value
4750 + * received was a pulse
4755 + dma_addr_t dma_in;
4756 + dma_addr_t dma_out;
4760 +#define MCE_TIME_UNIT 50
4764 +static int mceusb_probe (struct usb_interface *interface, const struct usb_device_id *id);
4765 +static void mceusb_disconnect (struct usb_interface *interface);
4766 +static void mceusb_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
4768 +static void * mceusb_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id);
4769 +static void mceusb_disconnect (struct usb_device *dev, void *ptr);
4770 +static void mceusb_write_bulk_callback (struct urb *urb);
4773 +/* read data from the usb bus; convert to mode2 */
4774 +static int msir_fetch_more_data( struct usb_skel* dev, int dont_block );
4776 +/* helper functions */
4777 +static void msir_cleanup( struct usb_skel* dev );
4778 +static void set_use_dec( void* data );
4779 +static int set_use_inc( void* data );
4781 +/* array of pointers to our devices that are currently connected */
4782 +static struct usb_skel *minor_table[MAX_DEVICES];
4784 +/* lock to protect the minor_table structure */
4785 +static DECLARE_MUTEX (minor_table_mutex);
4786 +static void mceusb_setup( struct usb_device *udev );
4788 +/* usb specific object needed to register this driver with the usb subsystem */
4789 +static struct usb_driver mceusb_driver = {
4790 + .owner = THIS_MODULE,
4791 + .name = DRIVER_NAME,
4792 + .probe = mceusb_probe,
4793 + .disconnect = mceusb_disconnect,
4794 + .id_table = mceusb_table,
4799 + * usb_mceusb_debug_data
4801 +static inline void usb_mceusb_debug_data (const char *function, int size,
4802 + const unsigned char *data)
4809 + printk (KERN_DEBUG __FILE__": %s - length = %d, data = ",
4811 + for (i = 0; i < size; ++i) {
4812 + printk ("%.2x ", data[i]);
4820 +static inline void mceusb_delete (struct usb_skel *dev)
4822 + dbg("%s",__func__);
4823 + minor_table[dev->minor] = NULL;
4825 + usb_buffer_free(dev->udev, dev->bulk_in_size, dev->bulk_in_buffer, dev->dma_in);
4826 + usb_buffer_free(dev->udev, dev->bulk_out_size, dev->bulk_out_buffer, dev->dma_out);
4828 + if (dev->bulk_in_buffer != NULL)
4829 + kfree (dev->bulk_in_buffer);
4830 + if (dev->bulk_out_buffer != NULL)
4831 + kfree (dev->bulk_out_buffer);
4833 + if (dev->write_urb != NULL)
4834 + usb_free_urb (dev->write_urb);
4838 +static void mceusb_setup( struct usb_device *udev )
4843 + memset( data, 0, 8 );
4846 + res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
4847 + USB_REQ_GET_STATUS, USB_DIR_IN,
4848 + 0, 0, data, 2, HZ * 3);
4850 + /* res = usb_get_status( udev, 0, 0, data ); */
4851 + dbg("%s - res = %d status = 0x%x 0x%x",__func__,res,data[0],data[1]);
4853 + /* This is a strange one. They issue a set address to the device
4854 + * on the receive control pipe and expect a certain value pair back
4856 + memset( data, 0, 8 );
4858 + res = usb_control_msg( udev, usb_rcvctrlpipe(udev, 0),
4859 + 5, USB_TYPE_VENDOR, 0, 0,
4860 + data, 2, HZ * 3 );
4861 + dbg("%s - res = %d, devnum = %d", __func__, res, udev->devnum);
4862 + dbg("%s - data[0] = %d, data[1] = %d", __func__, data[0], data[1] );
4866 + res = usb_control_msg( udev, usb_sndctrlpipe(udev, 0),
4867 + USB_REQ_SET_FEATURE, USB_TYPE_VENDOR,
4868 + 0xc04e, 0x0000, NULL, 0, HZ * 3 );
4870 + dbg("%s - res = %d", __func__, res);
4872 + /* These two are sent by the windows driver, but stall for
4873 + * me. I dont have an analyzer on the linux side so i can't
4874 + * see what is actually different and why the device takes
4878 + /* this is some custom control message they send */
4879 + res = usb_control_msg( udev, usb_sndctrlpipe(udev, 0),
4880 + 0x04, USB_TYPE_VENDOR,
4881 + 0x0808, 0x0000, NULL, 0, HZ * 3 );
4883 + dbg("%s - res = %d", __func__, res);
4885 + /* this is another custom control message they send */
4886 + res = usb_control_msg( udev, usb_sndctrlpipe(udev, 0),
4887 + 0x02, USB_TYPE_VENDOR,
4888 + 0x0000, 0x0100, NULL, 0, HZ * 3 );
4890 + dbg("%s - res = %d", __func__, res);
4894 +static void msir_cleanup( struct usb_skel* dev )
4896 + memset( dev->bulk_in_buffer, 0, dev->bulk_in_size );
4898 + dev->usb_valid_bytes_in_bulk_buffer = 0;
4900 + dev->last_space = PULSE_MASK;
4902 + dev->mce_bytes_left_in_packet = 0;
4905 + memset( dev->lircdata, 0, sizeof(dev->lircdata) );
4908 +static int set_use_inc(void* data)
4910 + MOD_INC_USE_COUNT;
4914 +static void set_use_dec(void* data)
4916 + /* check for unplug here */
4917 + struct usb_skel* dev = (struct usb_skel*) data;
4920 + lirc_unregister_plugin( dev->minor );
4921 + lirc_buffer_free( dev->plugin->rbuf );
4922 + kfree( dev->plugin->rbuf );
4923 + kfree( dev->plugin );
4926 + MOD_DEC_USE_COUNT;
4930 + * msir_fetch_more_data
4932 + * The goal here is to read in more remote codes from the remote. In
4933 + * the event that the remote isn't sending us anything, the caller
4934 + * will block until a key is pressed (i.e. this performs phys read,
4935 + * filtering, and queueing of data) unless dont_block is set to 1; in
4936 + * this situation, it will perform a few reads and will exit out if it
4937 + * does not see any appropriate data
4939 + * dev->sem should be locked when this function is called - fine grain
4940 + * locking isn't really important here anyways
4942 + * This routine always returns the number of words available
4945 +static int msir_fetch_more_data( struct usb_skel* dev, int dont_block )
4948 + int words_to_read =
4949 + (sizeof(dev->lircdata)/sizeof(lirc_t)) - dev->lirccnt;
4950 + int partial, this_read = 0;
4952 + int bytes_left_in_packet = 0;
4953 + signed char* signedp = (signed char*)dev->bulk_in_buffer;
4955 + if( words_to_read == 0 )
4956 + return dev->lirccnt;
4958 + /* this forces all existing data to be read by lirc before we
4959 + * issue another usb command. this is the only form of
4960 + * throttling we have
4962 + if( dev->lirccnt )
4964 + return dev->lirccnt;
4967 + /* reserve room for our leading space */
4968 + if( dev->last_space )
4971 + while( words_to_read )
4973 + /* handle signals and USB disconnects */
4974 + if( signal_pending(current) )
4976 + return dev->lirccnt ? dev->lirccnt : -EINTR;
4986 + * perform data read (phys or from previous buffer)
4989 + /* use leftovers if present, otherwise perform a read */
4990 + if( dev->usb_valid_bytes_in_bulk_buffer )
4992 + this_read = partial =
4993 + dev->usb_valid_bytes_in_bulk_buffer;
4994 + dev->usb_valid_bytes_in_bulk_buffer = 0;
5000 + this_read = dev->bulk_in_size;
5002 + retval = usb_bulk_msg
5005 + (dev->udev, dev->bulk_in_endpointAddr),
5006 + (unsigned char*)dev->bulk_in_buffer,
5007 + this_read, &partial, HZ*10);
5009 + /* retry a few times on overruns; map all
5010 + other errors to -EIO */
5013 + if( retval == -EOVERFLOW &&
5017 + interruptible_sleep_on_timeout
5018 + ( &dev->wait_q, HZ );
5029 + this_read = partial;
5031 + /* skip the header */
5034 + /* check for empty reads (header only) */
5035 + if( this_read == 2 )
5037 + /* assume no data */
5043 + /* sleep for a bit before performing
5045 + interruptible_sleep_on_timeout
5046 + ( &dev->wait_q, 1 );
5055 + /* at this point this_read is > 0 */
5056 + while( bulkidx < this_read &&
5057 + (words_to_read > (dev->last_space ? 1 : 0)) )
5058 + //while( bulkidx < this_read && words_to_read )
5063 + /* read packet length if needed */
5064 + if( !bytes_left_in_packet )
5067 + /* we assume we are on a packet length
5068 + * value. it is possible, in some
5069 + * cases, to get a packet that does
5070 + * not start with a length, apparently
5071 + * due to some sort of fragmenting,
5072 + * but occaisonally we do not receive
5073 + * the second half of a fragment
5075 + bytes_left_in_packet =
5076 + 128 + signedp[bulkidx++];
5078 + /* unfortunately rather than keep all
5079 + * the data in the packetized format,
5080 + * the transceiver sends a trailing 8
5081 + * bytes that aren't part of the
5082 + * transmittion from the remote,
5083 + * aren't packetized, and dont really
5084 + * have any value. we can basically
5085 + * tell we have hit them if 1) we have
5086 + * a loooong space currently stored
5087 + * up, and 2) the bytes_left value for
5088 + * this packet is obviously wrong
5090 + if( bytes_left_in_packet > 4 )
5092 + if( dev->mce_bytes_left_in_packet )
5094 + bytes_left_in_packet = dev->mce_bytes_left_in_packet;
5097 + bytes_left_in_packet = 0;
5098 + bulkidx = this_read;
5101 + /* always clear this if we have a
5103 + dev->mce_bytes_left_in_packet = 0;
5105 + /* continue here to verify we haven't
5106 + hit the end of the bulk_in */
5115 + keycode = signedp[bulkidx++];
5121 + keycode *= MCE_TIME_UNIT;
5123 + bytes_left_in_packet--;
5127 + if( dev->last_space )
5129 + dev->lircdata[dev->lirccnt++] =
5131 + dev->last_space = 0;
5134 + /* clear the lirc_t for the pulse */
5135 + dev->lircdata[dev->lirccnt] = 0;
5137 + dev->lircdata[dev->lirccnt] += keycode;
5138 + dev->lircdata[dev->lirccnt] |= PULSE_BIT;
5142 + /* on pulse->space transition, add one
5143 + for the existing pulse */
5144 + if( dev->lircdata[dev->lirccnt] &&
5145 + !dev->last_space )
5151 + dev->last_space += keycode;
5156 + /* save off some info if we are exiting mid-packet, or with
5158 + if( bytes_left_in_packet )
5160 + dev->mce_bytes_left_in_packet = bytes_left_in_packet;
5162 + if( bulkidx < this_read )
5164 + dev->usb_valid_bytes_in_bulk_buffer = (this_read - bulkidx);
5165 + memcpy( dev->bulk_in_buffer, &(dev->bulk_in_buffer[bulkidx]),
5166 + dev->usb_valid_bytes_in_bulk_buffer );
5168 + return dev->lirccnt;
5171 +/* mceusb_add_to_buf: called by lirc_dev to fetch all available keys
5172 + * this is used as a polling interface for us: since we set
5173 + * plugin->sample_rate we will periodically get the below call to
5174 + * check for new data returns 0 on success, or -ENODATA if nothing is
5177 +static int mceusb_add_to_buf(void* data, struct lirc_buffer* buf )
5179 + struct usb_skel* dev = (struct usb_skel*) data;
5181 + down( &dev->sem );
5183 + /* verify device still present */
5184 + if( dev->udev == NULL )
5190 + if( !dev->lirccnt )
5195 + res = msir_fetch_more_data( dev, 1 );
5205 + if( dev->lirccnt )
5209 + /* determine available buffer space and available data */
5210 + keys_to_copy = lirc_buffer_available( buf );
5211 + if( keys_to_copy > dev->lirccnt )
5213 + keys_to_copy = dev->lirccnt;
5216 + lirc_buffer_write_n( buf, (unsigned char*) &(dev->lircdata[dev->lircidx]), keys_to_copy );
5217 + dev->lircidx += keys_to_copy;
5218 + dev->lirccnt -= keys_to_copy;
5229 + * mceusb_write_bulk_callback
5232 +static void mceusb_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
5234 +static void mceusb_write_bulk_callback (struct urb *urb)
5237 + struct usb_skel *dev = (struct usb_skel *)urb->context;
5239 + dbg("%s - minor %d", __func__, dev->minor);
5241 + if ((urb->status != -ENOENT) &&
5242 + (urb->status != -ECONNRESET)) {
5243 + dbg("%s - nonzero write buld status received: %d\n", __func__, urb->status);
5253 + * Called by the usb core when a new device is connected that it
5254 + * thinks this driver might be interested in.
5257 +static int mceusb_probe(struct usb_interface *interface, const struct usb_device_id *id)
5259 + struct usb_device *udev = interface_to_usbdev(interface);
5260 + struct usb_host_interface *iface_desc;
5262 +static void * mceusb_probe(struct usb_device *udev, unsigned int ifnum,
5263 + const struct usb_device_id *id)
5265 + struct usb_interface *interface = &udev->actconfig->interface[ifnum];
5266 + struct usb_interface_descriptor *iface_desc;
5268 + struct usb_skel *dev = NULL;
5269 + struct usb_endpoint_descriptor *endpoint;
5271 + struct lirc_plugin* plugin;
5272 + struct lirc_buffer* rbuf;
5275 + size_t buffer_size;
5277 + int retval = -ENOMEM;
5279 + /* See if the device offered us matches what we can accept */
5280 + if ((udev->descriptor.idVendor != USB_MCEUSB_VENDOR_ID) ||
5281 + (udev->descriptor.idProduct != USB_MCEUSB_PRODUCT_ID)) {
5282 + dbg("Wrong Vendor/Product IDs");
5290 + /* select a "subminor" number (part of a minor number) */
5291 + down (&minor_table_mutex);
5292 + for (minor = 0; minor < MAX_DEVICES; ++minor) {
5293 + if (minor_table[minor] == NULL)
5296 + if (minor >= MAX_DEVICES) {
5297 + info ("Too many devices plugged in, "
5298 + "can not handle this device.");
5302 + /* allocate memory for our device state and initialize it */
5303 + dev = kmalloc (sizeof(struct usb_skel), GFP_KERNEL);
5304 + if (dev == NULL) {
5305 + err ("Out of memory");
5311 + minor_table[minor] = dev;
5313 + memset (dev, 0x00, sizeof (*dev));
5314 + init_MUTEX (&dev->sem);
5316 + dev->interface = interface;
5317 + dev->minor = minor;
5319 + /* set up the endpoint information */
5320 + /* check out the endpoints */
5321 + /* use only the first bulk-in and bulk-out endpoints */
5322 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,4)
5323 + iface_desc = interface->cur_altsetting;
5325 + iface_desc = &interface->altsetting[0];
5329 + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
5330 + endpoint = &iface_desc->endpoint[i].desc;
5332 + for (i = 0; i < iface_desc->bNumEndpoints; ++i) {
5333 + endpoint = &iface_desc->endpoint[i];
5335 + if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) &&
5336 + ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
5337 + USB_ENDPOINT_XFER_BULK)) {
5338 + dbg("we found a bulk in endpoint");
5339 + buffer_size = endpoint->wMaxPacketSize;
5340 + dev->bulk_in_size = buffer_size;
5341 + dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
5343 + dev->bulk_in_buffer = usb_buffer_alloc
5344 + (udev, buffer_size, SLAB_ATOMIC, &dev->dma_in);
5346 + dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
5348 + if (!dev->bulk_in_buffer) {
5349 + err("Couldn't allocate bulk_in_buffer");
5354 + if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == 0x00) &&
5355 + ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
5356 + USB_ENDPOINT_XFER_BULK)) {
5357 + dbg("we found a bulk out endpoint");
5359 + dev->write_urb = usb_alloc_urb(0, GFP_KERNEL);
5361 + dev->write_urb = usb_alloc_urb(0);
5363 + if (!dev->write_urb) {
5364 + err("No free urbs available");
5367 + buffer_size = endpoint->wMaxPacketSize;
5368 + dev->bulk_out_size = buffer_size;
5369 + dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
5371 + dev->bulk_out_buffer = usb_buffer_alloc(udev, buffer_size, SLAB_ATOMIC, &dev->dma_out);
5373 + dev->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
5375 + if (!dev->bulk_out_buffer) {
5376 + err("Couldn't allocate bulk_out_buffer");
5380 + usb_fill_bulk_urb(dev->write_urb, udev,
5382 + (udev, endpoint->bEndpointAddress),
5383 + dev->bulk_out_buffer, buffer_size,
5384 + mceusb_write_bulk_callback, dev);
5386 + FILL_BULK_URB(dev->write_urb, udev,
5388 + (udev, endpoint->bEndpointAddress),
5389 + dev->bulk_out_buffer, buffer_size,
5390 + mceusb_write_bulk_callback, dev);
5395 + if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
5396 + err("Couldn't find both bulk-in and bulk-out endpoints");
5400 + /* init the waitq */
5401 + init_waitqueue_head( &dev->wait_q );
5404 + /* Set up our lirc plugin */
5405 + if(!(plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL))) {
5406 + err("out of memory");
5409 + memset( plugin, 0, sizeof(struct lirc_plugin) );
5411 + if(!(rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL))) {
5412 + err("out of memory");
5417 + /* the lirc_atiusb module doesn't memset rbuf here ... ? */
5418 + if( lirc_buffer_init( rbuf, sizeof(lirc_t), 128)) {
5419 + err("out of memory");
5425 + strcpy(plugin->name, DRIVER_NAME " ");
5426 + plugin->minor = minor;
5427 + plugin->code_length = sizeof(lirc_t) * 8;
5428 + plugin->features = LIRC_CAN_REC_MODE2; // | LIRC_CAN_SEND_MODE2;
5429 + plugin->data = dev;
5430 + plugin->rbuf = rbuf;
5431 + plugin->ioctl = NULL;
5432 + plugin->set_use_inc = &set_use_inc;
5433 + plugin->set_use_dec = &set_use_dec;
5434 + plugin->sample_rate = 80; // sample at 100hz (10ms)
5435 + plugin->add_to_buf = &mceusb_add_to_buf;
5436 + // plugin->fops = &mceusb_fops;
5437 + if( lirc_register_plugin(plugin) < 0 )
5440 + lirc_buffer_free( rbuf );
5444 + dev->plugin = plugin;
5446 + /* clear off the first few messages. these look like
5447 + * calibration or test data, i can't really tell
5448 + * this also flushes in case we have random ir data queued up
5452 + int partial = 0, retval, i;
5453 + for( i = 0; i < 40; i++ )
5455 + retval = usb_bulk_msg
5456 + (udev, usb_rcvbulkpipe
5457 + (udev, dev->bulk_in_endpointAddr),
5463 + msir_cleanup( dev );
5464 + mceusb_setup( udev );
5467 + /* we can register the device now, as it is ready */
5468 + usb_set_intfdata (interface, dev);
5470 + /* let the user know what node this device is now attached to */
5471 + //info ("USB Microsoft IR Transceiver device now attached to msir%d", dev->minor);
5472 + up (&minor_table_mutex);
5479 + mceusb_delete (dev);
5481 + dbg("%s: retval = %x",__func__,retval);
5482 + up (&minor_table_mutex);
5491 + * mceusb_disconnect
5493 + * Called by the usb core when the device is removed from the system.
5495 + * This routine guarantees that the driver will not submit any more urbs
5496 + * by clearing dev->udev. It is also supposed to terminate any currently
5497 + * active urbs. Unfortunately, usb_bulk_msg(), used in skel_read(), does
5498 + * not provide any way to do this. But at least we can cancel an active
5502 +static void mceusb_disconnect(struct usb_interface *interface)
5504 +static void mceusb_disconnect(struct usb_device *udev, void *ptr)
5507 + struct usb_skel *dev;
5510 + dev = usb_get_intfdata (interface);
5511 + usb_set_intfdata (interface, NULL);
5513 + dev = (struct usb_skel *)ptr;
5516 + down (&minor_table_mutex);
5518 + minor = dev->minor;
5520 + /* unhook lirc things */
5521 + lirc_unregister_plugin( minor );
5522 + lirc_buffer_free( dev->plugin->rbuf );
5523 + kfree( dev->plugin->rbuf );
5524 + kfree( dev->plugin );
5526 + /* terminate an ongoing write */
5527 + if (atomic_read (&dev->write_busy)) {
5528 + usb_unlink_urb (dev->write_urb);
5529 + wait_for_completion (&dev->write_finished);
5532 + /* prevent device read, write and ioctl */
5536 + mceusb_delete (dev);
5538 + info("Microsoft IR Transceiver #%d now disconnected", minor);
5540 + up (&minor_table_mutex);
5548 +static int __init usb_mceusb_init(void)
5552 + /* register this driver with the USB subsystem */
5553 + result = usb_register(&mceusb_driver);
5557 + if ( result < 0 ) {
5559 + err("usb_register failed for the " DRIVER_NAME " driver. error number %d",result);
5567 + info(DRIVER_DESC " " DRIVER_VERSION);
5575 +static void __exit usb_mceusb_exit(void)
5577 + /* deregister this driver with the USB subsystem */
5578 + usb_deregister(&mceusb_driver);
5582 +module_init (usb_mceusb_init);
5583 +module_exit (usb_mceusb_exit);
5585 +MODULE_AUTHOR(DRIVER_AUTHOR);
5586 +MODULE_DESCRIPTION(DRIVER_DESC);
5587 +MODULE_LICENSE("GPL");
5588 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_parallel.c linux-2.6.8-rc4/drivers/char/lirc/lirc_parallel.c
5589 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_parallel.c 1970-01-01 01:00:00.000000000 +0100
5590 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_parallel.c 2004-05-16 11:14:39.000000000 +0200
5594 +/****************************************************************************
5595 + ** lirc_parallel.c *********************************************************
5596 + ****************************************************************************
5598 + * lirc_parallel - device driver for infra-red signal receiving and
5599 + * transmitting unit built by the author
5601 + * Copyright (C) 1998 Christoph Bartelmus <lirc@bartelmus.de>
5603 + * This program is free software; you can redistribute it and/or modify
5604 + * it under the terms of the GNU General Public License as published by
5605 + * the Free Software Foundation; either version 2 of the License, or
5606 + * (at your option) any later version.
5608 + * This program is distributed in the hope that it will be useful,
5609 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5610 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5611 + * GNU General Public License for more details.
5613 + * You should have received a copy of the GNU General Public License
5614 + * along with this program; if not, write to the Free Software
5615 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5619 +/***********************************************************************
5620 + ************************* Includes ***********************
5621 + ***********************************************************************/
5623 +#ifdef HAVE_CONFIG_H
5624 +# include <config.h>
5627 +#include <linux/version.h>
5628 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
5629 +#error "**********************************************************"
5630 +#error " Sorry, this driver needs kernel version 2.2.18 or higher "
5631 +#error "**********************************************************"
5634 +#include <linux/config.h>
5637 +#error "--- Sorry, this driver is not SMP safe. ---"
5640 +#include <linux/module.h>
5641 +#include <linux/sched.h>
5642 +#include <linux/errno.h>
5643 +#include <linux/signal.h>
5644 +#include <linux/config.h>
5645 +#include <linux/fs.h>
5646 +#include <linux/kernel.h>
5647 +#include <linux/ioport.h>
5648 +#include <linux/time.h>
5649 +#include <linux/mm.h>
5650 +#include <linux/delay.h>
5652 +#include <asm/io.h>
5653 +#include <asm/signal.h>
5654 +#include <asm/irq.h>
5656 +#include <asm/uaccess.h>
5657 +#include <linux/poll.h>
5658 +#include <linux/parport.h>
5660 +#include <linux/lirc.h>
5661 +#include "kcompat.h"
5662 +#include "lirc_dev.h"
5664 +#include "lirc_parallel.h"
5666 +#define LIRC_DRIVER_NAME "lirc_parallel"
5668 +/***********************************************************************
5669 + ************************* Globale Variablen ***********************
5670 + ***********************************************************************/
5672 +unsigned int irq = CONFIG_LIRC_IRQ_PARALLEL;
5673 +unsigned int io = CONFIG_LIRC_PORT_PARALLEL;
5674 +#ifdef CONFIG_LIRC_TIMER
5675 +unsigned int timer = 0;
5676 +unsigned int default_timer = CONFIG_LIRC_TIMER;
5679 +#define WBUF_SIZE (256)
5680 +#define RBUF_SIZE (256) /* this must be a power of 2 larger than 1 */
5682 +static lirc_t wbuf[WBUF_SIZE];
5683 +static lirc_t rbuf[RBUF_SIZE];
5685 +DECLARE_WAIT_QUEUE_HEAD(lirc_wait);
5687 +unsigned int rptr=0,wptr=0;
5688 +unsigned int lost_irqs=0;
5691 +struct parport *pport;
5692 +struct pardevice *ppdevice;
5695 +/***********************************************************************
5696 + ************************* Interne Funktionen ***********************
5697 + ***********************************************************************/
5699 +unsigned int __inline__ in(int offset)
5703 + case LIRC_LP_BASE:
5704 + return(parport_read_data(pport));
5705 + case LIRC_LP_STATUS:
5706 + return(parport_read_status(pport));
5707 + case LIRC_LP_CONTROL:
5708 + return(parport_read_control(pport));
5710 + return(0); /* make compiler happy */
5713 +void __inline__ out(int offset, int value)
5717 + case LIRC_LP_BASE:
5718 + parport_write_data(pport,value);
5720 + case LIRC_LP_CONTROL:
5721 + parport_write_control(pport,value);
5723 + case LIRC_LP_STATUS:
5724 + printk(KERN_INFO "%s: attempt to write to status register\n",
5725 + LIRC_DRIVER_NAME);
5730 +unsigned int __inline__ lirc_get_timer(void)
5732 + return(in(LIRC_PORT_TIMER)&LIRC_PORT_TIMER_BIT);
5735 +unsigned int __inline__ lirc_get_signal(void)
5737 + return(in(LIRC_PORT_SIGNAL)&LIRC_PORT_SIGNAL_BIT);
5740 +void __inline__ lirc_on(void)
5742 + out(LIRC_PORT_DATA,LIRC_PORT_DATA_BIT);
5745 +void __inline__ lirc_off(void)
5747 + out(LIRC_PORT_DATA,0);
5750 +unsigned int init_lirc_timer(void)
5752 + struct timeval tv,now;
5753 + unsigned int level,newlevel,timeelapsed,newtimer;
5756 + do_gettimeofday(&tv);
5757 + tv.tv_sec++; /* wait max. 1 sec. */
5758 + level=lirc_get_timer();
5761 + newlevel=lirc_get_timer();
5762 + if(level==0 && newlevel!=0) count++;
5764 + do_gettimeofday(&now);
5766 + while(count<1000 && (now.tv_sec<tv.tv_sec
5767 + || (now.tv_sec==tv.tv_sec
5768 + && now.tv_usec<tv.tv_usec)));
5770 + timeelapsed=((now.tv_sec+1-tv.tv_sec)*1000000
5771 + +(now.tv_usec-tv.tv_usec));
5772 + if(count>=1000 && timeelapsed>0)
5774 + if(default_timer==0) /* autodetect timer */
5776 + newtimer=(1000000*count)/timeelapsed;
5777 + printk(KERN_INFO "%s: %u Hz timer detected\n",
5778 + LIRC_DRIVER_NAME,newtimer);
5783 + newtimer=(1000000*count)/timeelapsed;
5784 + if(abs(newtimer-default_timer)>
5785 + default_timer/10) /* bad timer */
5787 + printk(KERN_NOTICE "%s: bad timer: %u Hz\n",
5788 + LIRC_DRIVER_NAME,newtimer);
5789 + printk(KERN_NOTICE "%s: using default timer: "
5791 + LIRC_DRIVER_NAME,default_timer);
5792 + return(default_timer);
5796 + printk(KERN_INFO "%s: %u Hz timer detected\n",
5797 + LIRC_DRIVER_NAME,newtimer);
5798 + return(newtimer); /* use detected value */
5804 + printk(KERN_NOTICE "%s: no timer detected\n",LIRC_DRIVER_NAME);
5809 +int lirc_claim(void)
5811 + if(parport_claim(ppdevice)!=0)
5813 + printk(KERN_WARNING "%s: could not claim port\n",
5814 + LIRC_DRIVER_NAME);
5815 + printk(KERN_WARNING "%s: waiting for port becoming available"
5816 + "\n",LIRC_DRIVER_NAME);
5817 + if(parport_claim_or_block(ppdevice)<0)
5819 + printk(KERN_NOTICE "%s: could not claim port, giving"
5820 + " up\n",LIRC_DRIVER_NAME);
5824 + out(LIRC_LP_CONTROL,LP_PSELECP|LP_PINITP);
5829 +/***********************************************************************
5830 + ************************* interrupt handler ************************
5831 + ***********************************************************************/
5833 +static inline void rbuf_write(lirc_t signal)
5835 + unsigned int nwptr;
5837 + nwptr=(wptr+1) & (RBUF_SIZE-1);
5838 + if(nwptr==rptr) /* no new signals will be accepted */
5841 + printk(KERN_NOTICE "%s: buffer overrun\n",LIRC_DRIVER_NAME);
5844 + rbuf[wptr]=signal;
5848 +void irq_handler(int i,void *blah,struct pt_regs * regs)
5850 + struct timeval tv;
5851 + static struct timeval lasttv;
5852 + static int init=0;
5855 + unsigned int level,newlevel;
5856 + unsigned int timeout;
5866 + /* disable interrupt */
5869 + out(LIRC_PORT_IRQ,in(LIRC_PORT_IRQ)&(~LP_PINTEN));
5871 + if(in(1)&LP_PSELECD)
5879 + do_gettimeofday(&tv);
5881 + signal=tv.tv_sec-lasttv.tv_sec;
5884 + data=PULSE_MASK; /* really long time */
5888 + data=(lirc_t) (signal*1000000+
5889 + tv.tv_usec-lasttv.tv_usec+
5890 + LIRC_SFH506_DELAY);
5893 + rbuf_write(data); /* space */
5897 + if(timer==0) /* wake up; we'll lose this signal
5898 + but it will be garbage if the device
5899 + is turned on anyway
5902 + timer=init_lirc_timer();
5903 + /* enable_irq(irq); */
5909 + timeout=timer/10; /* timeout after 1/10 sec. */
5911 + level=lirc_get_timer();
5913 + newlevel=lirc_get_timer();
5914 + if(level==0 && newlevel!=0) signal++;
5918 + if(signal>timeout || (in(1)&LP_PSELECD))
5921 + printk(KERN_NOTICE "%s: timeout\n",LIRC_DRIVER_NAME);
5925 + while(lirc_get_signal());
5928 + /* ajust value to usecs */
5929 + signal=(long) (((unsigned long long) signal)*1000000)/timer;
5931 + if(signal>LIRC_SFH506_DELAY)
5933 + data=signal-LIRC_SFH506_DELAY;
5939 + rbuf_write(PULSE_BIT|data); /* pulse */
5941 + do_gettimeofday(&lasttv);
5943 + /* add your code here */
5946 + wake_up_interruptible(&lirc_wait);
5948 + /* enable interrupt */
5951 + out(LIRC_PORT_IRQ,in(LIRC_PORT_IRQ)|LP_PINTEN);
5955 +/***********************************************************************
5956 + ************************** file_operations ************************
5957 + ***********************************************************************/
5959 +static loff_t lirc_lseek(struct file *filep,loff_t offset,int orig)
5964 +static ssize_t lirc_read(struct file *filep,char *buf,size_t n,loff_t *ppos)
5968 + DECLARE_WAITQUEUE(wait, current);
5970 + if(n%sizeof(lirc_t)) return(-EINVAL);
5972 + result=verify_area(VERIFY_WRITE,buf,n);
5973 + if(result) return(result);
5975 + add_wait_queue(&lirc_wait,&wait);
5976 + current->state=TASK_INTERRUPTIBLE;
5981 + copy_to_user(buf+count,(char *) &rbuf[rptr],
5983 + rptr=(rptr+1)&(RBUF_SIZE-1);
5984 + count+=sizeof(lirc_t);
5988 + if(filep->f_flags & O_NONBLOCK)
5993 + if (signal_pending(current))
5995 + result=-ERESTARTSYS;
5999 + current->state=TASK_INTERRUPTIBLE;
6002 + remove_wait_queue(&lirc_wait,&wait);
6003 + current->state=TASK_RUNNING;
6004 + return(count ? count:result);
6007 +static ssize_t lirc_write(struct file *filep,const char *buf,size_t n,
6012 + unsigned int level,newlevel;
6013 + unsigned long flags;
6014 + lirc_t counttimer;
6020 + if(n%sizeof(lirc_t)) return(-EINVAL);
6021 + result=verify_area(VERIFY_READ,buf,n);
6022 + if(result) return(result);
6024 + count=n/sizeof(lirc_t);
6026 + if(count>WBUF_SIZE || count%2==0) return(-EINVAL);
6028 + copy_from_user(wbuf,buf,n);
6031 + if(timer==0) /* try again if device is ready */
6033 + timer=init_lirc_timer();
6034 + if(timer==0) return(-EIO);
6037 + /* ajust values from usecs */
6038 + for(i=0;i<count;i++)
6040 + wbuf[i]=(lirc_t) (((double) wbuf[i])*timer/1000000);
6043 + local_irq_save(flags);
6047 + level=lirc_get_timer();
6052 + newlevel=lirc_get_timer();
6053 + if(level==0 && newlevel!=0) counttimer++;
6055 + if(in(1)&LP_PSELECD)
6058 + local_irq_restore(flags);
6062 + while(counttimer<wbuf[i]);i++;
6065 + if(i==count) break;
6069 + newlevel=lirc_get_timer();
6070 + if(level==0 && newlevel!=0) counttimer++;
6072 + if(in(1)&LP_PSELECD)
6074 + local_irq_restore(flags);
6078 + while(counttimer<wbuf[i]);i++;
6080 + local_irq_restore(flags);
6083 + place code that handles write
6084 + without extarnal timer here
6090 +static unsigned int lirc_poll(struct file *file, poll_table * wait)
6092 + poll_wait(file, &lirc_wait,wait);
6094 + return(POLLIN|POLLRDNORM);
6098 +static int lirc_ioctl(struct inode *node,struct file *filep,unsigned int cmd,
6099 + unsigned long arg)
6102 + unsigned long features=LIRC_CAN_SEND_PULSE|LIRC_CAN_REC_MODE2,mode;
6106 + case LIRC_GET_FEATURES:
6107 + result=put_user(features,(unsigned long *) arg);
6108 + if(result) return(result);
6110 + case LIRC_GET_SEND_MODE:
6111 + result=put_user(LIRC_MODE_PULSE,(unsigned long *) arg);
6112 + if(result) return(result);
6114 + case LIRC_GET_REC_MODE:
6115 + result=put_user(LIRC_MODE_MODE2,(unsigned long *) arg);
6116 + if(result) return(result);
6118 + case LIRC_SET_SEND_MODE:
6119 + result=get_user(mode,(unsigned long *) arg);
6120 + if(result) return(result);
6121 + if(mode!=LIRC_MODE_PULSE) return(-EINVAL);
6123 + case LIRC_SET_REC_MODE:
6124 + result=get_user(mode,(unsigned long *) arg);
6125 + if(result) return(result);
6126 + if(mode!=LIRC_MODE_MODE2) return(-ENOSYS);
6129 + return(-ENOIOCTLCMD);
6134 +static int lirc_open(struct inode* node,struct file* filep)
6144 + pport->ops->enable_irq(pport);
6146 + /* init read ptr */
6150 + MOD_INC_USE_COUNT;
6155 +static int lirc_close(struct inode* node,struct file* filep)
6160 + parport_release(ppdevice);
6163 + MOD_DEC_USE_COUNT;
6167 +static struct file_operations lirc_fops =
6169 + llseek: lirc_lseek,
6171 + write: lirc_write,
6173 + ioctl: lirc_ioctl,
6175 + release: lirc_close
6178 +static int set_use_inc(void* data)
6180 +#if WE_DONT_USE_LOCAL_OPEN_CLOSE
6181 + MOD_INC_USE_COUNT;
6186 +static void set_use_dec(void* data)
6188 +#if WE_DONT_USE_LOCAL_OPEN_CLOSE
6189 + MOD_DEC_USE_COUNT;
6193 +static struct lirc_plugin plugin = {
6194 + name: LIRC_DRIVER_NAME,
6201 + set_use_inc: set_use_inc,
6202 + set_use_dec: set_use_dec,
6208 +MODULE_AUTHOR("Christoph Bartelmus");
6209 +MODULE_DESCRIPTION("Infrared receiver driver for parallel ports.");
6210 +#ifdef MODULE_LICENSE
6211 +MODULE_LICENSE("GPL");
6214 +MODULE_PARM(io, "i");
6215 +MODULE_PARM_DESC(io, "I/O address base (0x3bc, 0x378 or 0x278)");
6217 +MODULE_PARM(irq, "i");
6218 +MODULE_PARM_DESC(irq, "Interrupt (7 or 5)");
6224 +int pf(void *handle);
6225 +void kf(void *handle);
6227 +static struct timer_list poll_timer;
6228 +static void poll_state(unsigned long ignored);
6230 +static void poll_state(unsigned long ignored)
6232 + printk(KERN_NOTICE "%s: time\n",
6233 + LIRC_DRIVER_NAME);
6234 + del_timer(&poll_timer);
6240 + printk(KERN_NOTICE "%s: could not claim port, giving up\n",
6241 + LIRC_DRIVER_NAME);
6242 + init_timer(&poll_timer);
6243 + poll_timer.expires=jiffies+HZ;
6244 + poll_timer.data=(unsigned long) current;
6245 + poll_timer.function=poll_state;
6246 + add_timer(&poll_timer);
6250 +int pf(void *handle)
6252 + pport->ops->disable_irq(pport);
6258 +void kf(void *handle)
6264 + pport->ops->enable_irq(pport);
6265 + /* this is a bit annoying when you actually print...*/
6267 + printk(KERN_INFO "%s: reclaimed port\n",LIRC_DRIVER_NAME);
6271 +/***********************************************************************
6272 + ****************** init_module()/cleanup_module() ******************
6273 + ***********************************************************************/
6275 +int init_module(void)
6277 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 3)
6278 + pport=parport_find_base(io);
6280 + pport=parport_enumerate();
6281 + while(pport!=NULL)
6283 + if(pport->base==io)
6287 + pport=pport->next;
6292 + printk(KERN_NOTICE "%s: no port at %x found\n",
6293 + LIRC_DRIVER_NAME,io);
6296 + ppdevice=parport_register_device(pport,LIRC_DRIVER_NAME,
6297 + pf,kf,irq_handler,0,NULL);
6298 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 3)
6299 + parport_put_port(pport);
6301 + if(ppdevice==NULL)
6303 + printk(KERN_NOTICE "%s: parport_register_device() failed\n",
6304 + LIRC_DRIVER_NAME);
6307 + if(parport_claim(ppdevice)!=0)
6310 + out(LIRC_LP_CONTROL,LP_PSELECP|LP_PINITP);
6314 + out(LIRC_PORT_DATA,LIRC_PORT_DATA_BIT);
6317 + timer=init_lirc_timer();
6319 +# if 0 /* continue even if device is offline */
6323 + parport_release(pport);
6324 + parport_unregister_device(ppdevice);
6330 + out(LIRC_PORT_DATA,0);
6335 + parport_release(ppdevice);
6337 + if ((plugin.minor = lirc_register_plugin(&plugin)) < 0)
6339 + printk(KERN_NOTICE "%s: register_chrdev() failed\n",LIRC_DRIVER_NAME);
6340 + parport_unregister_device(ppdevice);
6343 + printk(KERN_INFO "%s: installed using port 0x%04x irq %d\n",LIRC_DRIVER_NAME,io,irq);
6347 +void cleanup_module(void)
6349 + if(MOD_IN_USE) return;
6350 + parport_unregister_device(ppdevice);
6351 + lirc_unregister_plugin(plugin.minor);
6354 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_parallel.h linux-2.6.8-rc4/drivers/char/lirc/lirc_parallel.h
6355 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_parallel.h 1970-01-01 01:00:00.000000000 +0100
6356 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_parallel.h 2001-06-23 18:59:16.000000000 +0200
6360 +#ifndef _LIRC_PARALLEL_H
6361 +#define _LIRC_PARALLEL_H
6363 +#include <linux/lp.h>
6365 +#define LIRC_PORT_LEN 3
6367 +#define LIRC_LP_BASE 0
6368 +#define LIRC_LP_STATUS 1
6369 +#define LIRC_LP_CONTROL 2
6371 +#define LIRC_PORT_DATA LIRC_LP_BASE /* base */
6372 +#define LIRC_PORT_DATA_BIT 0x01 /* 1st bit */
6373 +#define LIRC_PORT_TIMER LIRC_LP_STATUS /* status port */
6374 +#define LIRC_PORT_TIMER_BIT LP_PBUSY /* busy signal */
6375 +#define LIRC_PORT_SIGNAL LIRC_LP_STATUS /* status port */
6376 +#define LIRC_PORT_SIGNAL_BIT LP_PACK /* ack signal */
6377 +#define LIRC_PORT_IRQ LIRC_LP_CONTROL /* control port */
6379 +#define LIRC_SFH506_DELAY 0 /* delay t_phl in usecs */
6382 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_sasem.c linux-2.6.8-rc4/drivers/char/lirc/lirc_sasem.c
6383 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_sasem.c 1970-01-01 01:00:00.000000000 +0100
6384 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_sasem.c 2004-06-19 08:29:09.000000000 +0200
6386 +/* lirc_sasem.c - USB remote support for LIRC
6387 + * Version 0.1 [beta status]
6389 + * Copyright (C) 2004 Oliver Stabel <oliver.stabel@gmx.de>
6391 + * This driver was derived from:
6392 + * Paul Miller <pmiller9@users.sourceforge.net>'s 2003-2004
6393 + * "lirc_atiusb - USB remote support for LIRC"
6394 + * Culver Consulting Services <henry@culcon.com>'s 2003
6395 + * "Sasem OnAir VFD/IR USB driver"
6398 + * 2004/06/13 - 1st version
6401 + * - keypresses seem to be rather sluggish sometimes; check
6402 + * intervall and timing
6403 + * - simulate USBLCD device to work with LCDProc
6404 + * - include fs operations
6405 + * - analyse LCD command set
6406 + * - check USB Minor allocation
6407 + * - param to enable/disable LIRC communication (??)
6412 + * This program is free software; you can redistribute it and/or modify
6413 + * it under the terms of the GNU General Public License as published by
6414 + * the Free Software Foundation; either version 2 of the License, or
6415 + * (at your option) any later version.
6417 + * This program is distributed in the hope that it will be useful,
6418 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6419 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6420 + * GNU General Public License for more details.
6422 + * You should have received a copy of the GNU General Public License
6423 + * along with this program; if not, write to the Free Software
6424 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6427 +#include <linux/module.h>
6428 +#include <linux/kmod.h>
6429 +#include <linux/kernel.h>
6430 +#include <linux/usb.h>
6431 +#include <linux/init.h>
6432 +#include <linux/slab.h>
6433 +#include <linux/sched.h>
6434 +#include <asm/uaccess.h>
6435 +#include <asm/atomic.h>
6436 +#include <linux/poll.h>
6437 +#include "lirc_sasem.h"
6439 +#include <linux/lirc.h>
6440 +#include "lirc_dev.h"
6442 +MODULE_AUTHOR( DRIVER_AUTHOR );
6443 +MODULE_DESCRIPTION( DRIVER_DESC );
6444 +MODULE_LICENSE("GPL");
6446 +static int debug = 0;
6448 +MODULE_PARM(debug, "i");
6449 +MODULE_PARM_DESC(debug, "enable debug = 1, disable = 0 (default)");
6451 +static t_usb_device_id s_sasemID [] = {
6452 + { USB_DEVICE(0x11ba, 0x0101) },
6455 +MODULE_DEVICE_TABLE (usb, s_sasemID);
6457 +static t_usb_driver s_SasemDriver =
6459 + owner: THIS_MODULE,
6461 + probe: s_sasemProbe,
6462 + disconnect: s_sasemDisconnect,
6463 + minor: SASEM_MINOR,
6464 + id_table: s_sasemID,
6467 +static int __init s_sasemInit (void)
6471 + if (usb_register(&s_SasemDriver)) {
6472 + printk("USB registration failed");
6479 +static void __exit s_sasemExit (void)
6481 + usb_deregister (&s_SasemDriver);
6484 +module_init (s_sasemInit);
6485 +module_exit (s_sasemExit);
6487 +static void * s_sasemProbe(t_usb_device *p_dev, unsigned p_iInterfaceNum,
6488 + const t_usb_device_id *p_id)
6490 + t_sasemDevice *l_sasemDevice = NULL;
6491 + t_usb_endpoint_descriptor *l_endpoint;
6492 + t_usb_interface_descriptor *l_currentInterfaceDescriptor;
6495 + t_lirc_plugin *l_lircPlugin = NULL;
6496 + t_lirc_buffer *l_lircBuffer = NULL;
6497 + int l_iLircMinor = -1;
6498 + int l_iMemFailure;
6499 + char l_cBuf[63], l_cName[128]="";
6501 + if (debug) printk("onair probe\n");
6503 + l_currentInterfaceDescriptor = p_dev->actconfig->interface->
6505 + l_endpoint = l_currentInterfaceDescriptor->endpoint;
6507 + if (!(l_endpoint->bEndpointAddress & 0x80) ||
6508 + ((l_endpoint->bmAttributes & 3) != 0x03)) {
6509 + printk("OnAir config endpoint error");
6513 + l_iDevnum = p_dev->devnum;
6515 + l_iMemFailure = 0;
6516 + if (!(l_sasemDevice = kmalloc(sizeof(t_sasemDevice), GFP_KERNEL))) {
6517 + printk("kmalloc(sizeof(t_sasemDevice), GFP_KERNEL)) failed");
6518 + l_iMemFailure = 1;
6521 + memset(l_sasemDevice, 0, sizeof(t_sasemDevice));
6522 + if (!(l_lircPlugin = kmalloc(sizeof(t_lirc_plugin), GFP_KERNEL))) {
6523 + printk("kmalloc(sizeof(t_lirc_plugin), GFP_KERNEL)) failed");
6524 + l_iMemFailure = 2;
6526 + else if (!(l_lircBuffer = kmalloc(sizeof(t_lirc_buffer), GFP_KERNEL))) {
6527 + printk("kmalloc(sizeof(t_lirc_buffer), GFP_KERNEL)) failed");
6528 + l_iMemFailure = 3;
6530 + else if (lirc_buffer_init(l_lircBuffer, MAX_INTERRUPT_DATA, 4)) {
6531 + printk("lirc_buffer_init failed");
6532 + l_iMemFailure = 4;
6534 + else if (!(l_sasemDevice->m_urbIn = usb_alloc_urb(0))) {
6535 + printk("usb_alloc_urb(0) failed");
6536 + l_iMemFailure = 5;
6539 + memset(l_lircPlugin, 0, sizeof(t_lirc_plugin));
6540 + strcpy(l_lircPlugin->name, DRIVER_NAME " ");
6541 + l_lircPlugin->minor = -1;
6542 + l_lircPlugin->code_length = MAX_INTERRUPT_DATA*8;
6543 + l_lircPlugin->features = LIRC_CAN_REC_LIRCCODE;
6544 + l_lircPlugin->data = l_sasemDevice;
6546 + l_lircPlugin->rbuf = l_lircBuffer;
6547 + l_lircPlugin->set_use_inc = &s_lirc_set_use_inc;
6548 + l_lircPlugin->set_use_dec = &s_lirc_set_use_dec;
6550 + if ((l_iLircMinor = lirc_register_plugin(l_lircPlugin)) < 0) {
6551 + printk("lirc_register_plugin(l_lircPlugin)) failed");
6552 + l_iMemFailure = 9;
6556 + switch (l_iMemFailure) {
6558 + usb_free_urb(l_sasemDevice->m_urbIn);
6561 + kfree(l_lircBuffer);
6563 + kfree(l_lircPlugin);
6565 + kfree(l_sasemDevice);
6570 + l_lircPlugin->minor = l_iLircMinor;
6572 + init_MUTEX(&l_sasemDevice->m_semLock);
6573 + down_interruptible(&l_sasemDevice->m_semLock);
6574 + l_sasemDevice->m_descriptorIn = l_endpoint;
6575 + l_sasemDevice->m_device = p_dev;
6576 + l_sasemDevice->m_lircPlugin = l_lircPlugin;
6577 + up(&l_sasemDevice->m_semLock);
6579 + l_iPipe = usb_rcvintpipe(l_sasemDevice->m_device,
6580 + l_sasemDevice->m_descriptorIn->
6581 + bEndpointAddress);
6583 + usb_fill_int_urb(l_sasemDevice->m_urbIn, l_sasemDevice->m_device,
6584 + l_iPipe, l_sasemDevice->m_cBufferIn,
6585 + sizeof(l_sasemDevice->m_cBufferIn),
6586 + s_sasemCallbackIn, l_sasemDevice,
6587 + l_sasemDevice->m_descriptorIn->bInterval);
6589 + if (p_dev->descriptor.iManufacturer &&
6590 + usb_string(p_dev, p_dev->descriptor.iManufacturer, l_cBuf, 63) > 0)
6592 + strncpy(l_cName, l_cBuf, 128);
6594 + if (p_dev->descriptor.iProduct &&
6595 + usb_string(p_dev, p_dev->descriptor.iProduct, l_cBuf, 63) > 0)
6597 + snprintf(l_cName, 128, "%s %s", l_cName, l_cBuf);
6599 + printk(DRIVER_NAME "[%d]: %s on usb%d\n", l_iDevnum, l_cName,
6600 + p_dev->bus->busnum);
6602 + return l_sasemDevice;
6606 +static void s_sasemDisconnect(t_usb_device *p_dev, void *p_ptr) {
6607 + t_sasemDevice *l_sasemDevice = p_ptr;
6608 + if (debug) printk("s_sasemDisconnect\n");
6610 + down_interruptible(&l_sasemDevice->m_semLock);
6611 + usb_unlink_urb(l_sasemDevice->m_urbIn);
6612 + usb_free_urb(l_sasemDevice->m_urbIn);
6613 + s_unregister_from_lirc(l_sasemDevice);
6614 + up(&l_sasemDevice->m_semLock);
6615 + kfree (l_sasemDevice);
6618 +static void s_sasemCallbackIn(t_urb *p_urb)
6620 + t_sasemDevice *l_sasemDevice;
6623 + char l_cBuf[MAX_INTERRUPT_DATA];
6626 + if (debug) printk("s_sasemCallbackIn\n");
6633 + if (!(l_sasemDevice = p_urb->context)) {
6634 + usb_unlink_urb(p_urb);
6638 + l_iDevnum = l_sasemDevice->m_iDevnum;
6640 + printk(DRIVER_NAME "[%d]: data received (length %d)\n",
6641 + l_iDevnum, p_urb->actual_length);
6642 + printk(DRIVER_NAME
6643 + " intr_callback called %x %x %x %x %x %x %x %x\n",
6644 + l_sasemDevice->m_cBufferIn[0],
6645 + l_sasemDevice->m_cBufferIn[1],
6646 + l_sasemDevice->m_cBufferIn[2],
6647 + l_sasemDevice->m_cBufferIn[3],
6648 + l_sasemDevice->m_cBufferIn[4],
6649 + l_sasemDevice->m_cBufferIn[5],
6650 + l_sasemDevice->m_cBufferIn[6],
6651 + l_sasemDevice->m_cBufferIn[7]);
6654 + switch (p_urb->status) {
6658 + l_iLen = p_urb->actual_length;
6659 + if (l_iLen > MAX_INTERRUPT_DATA) return;
6661 + memcpy(l_cBuf,p_urb->transfer_buffer,l_iLen);
6663 + // is this needed? The OnAir device should always
6665 + for (i = l_iLen; i < MAX_INTERRUPT_DATA; i++) l_cBuf[i] = 0;
6667 + // the OnAir device seems not to be able to signal a
6668 + // pressed button by repeating its code. Keeping a
6669 + // button pressed first sends the real code (e.g. 0C
6670 + // 80 7F 41 BE 00 00 00) and then keeps sending 08 00
6671 + // 00 00 00 00 00 00 as long as the button is pressed
6672 + // (notice that in the real key code 80 = !7F and 41 =
6673 + // !BE is this important? maybe for validation?) maybe
6674 + // 08 00 00 00 00 00 00 00 is the number of presses?
6676 + // so lets do the following: if a code != the 08 code
6677 + // arrives, store it to repeat it if necessary for
6678 + // LIRC. If an 08 code follows afterwards, send the
6679 + // old code again to the buffer do this as long as the
6680 + // 08 code is being sent
6682 + // Code from Remote Lirc Buffer
6683 + // 0C 80 7F 41 BE 00 00 00 0C 80 7F 41 BE 00 00 00
6684 + // 08 00 00 00 00 00 00 00 0C 80 7F 41 BE 00 00 00
6685 + // 08 00 00 00 00 00 00 00 0C 80 7F 41 BE 00 00 00
6686 + // 08 00 00 00 00 00 00 00 0C 80 7F 41 BE 00 00 00
6687 + // 08 00 00 00 00 00 00 00 0C 80 7F 41 BE 00 00 00
6688 + // 0C 80 7F 40 BF 00 00 00 0C 80 7F 40 BF 00 00 00
6689 + // 08 00 00 00 00 00 00 00 0C 80 7F 40 BF 00 00 00
6690 + // 08 00 00 00 00 00 00 00 0C 80 7F 40 BF 00 00 00
6691 + // 0C 80 7F 41 BE 00 00 00 0C 80 7F 41 BE 00 00 00
6693 + if (memcmp(l_cBuf, sc_cSasemCode, MAX_INTERRUPT_DATA) == 0) {
6694 + // the repeat code is being sent, so we copy
6695 + // the old code to LIRC
6696 + if (l_sasemDevice->m_iCodeSaved != 0) {
6697 + memcpy(l_cBuf, &l_sasemDevice->m_cLastCode,
6698 + MAX_INTERRUPT_DATA);
6700 + // there was no old code so what to do?
6707 + // save the current valid code for repeats
6708 + memcpy(&l_sasemDevice->m_cLastCode, l_cBuf,
6709 + MAX_INTERRUPT_DATA);
6710 + // set flag to signal a valid code was save;
6711 + // just for safety reasons
6712 + l_sasemDevice->m_iCodeSaved = 1;
6715 + /* copy 1 code to lirc_buffer */
6716 + lirc_buffer_write_1(l_sasemDevice->m_lircPlugin->rbuf,
6718 + wake_up(&l_sasemDevice->m_lircPlugin->rbuf->wait_poll);
6725 + usb_unlink_urb(p_urb);
6729 + /* resubmit urb */
6730 + usb_submit_urb(p_urb);
6733 +static int s_unregister_from_lirc(t_sasemDevice *p_sasemDevice) {
6734 + t_lirc_plugin *l_lircPlugin = p_sasemDevice->m_lircPlugin;
6738 + l_iDevnum = p_sasemDevice->m_iDevnum;
6739 + if (debug) printk(DRIVER_NAME "[%d]: unregister from lirc called\n",
6742 + if ((l_iReturn = lirc_unregister_plugin(l_lircPlugin->minor)) > 0) {
6743 + printk(DRIVER_NAME "[%d]: error in lirc_unregister minor: %d\n"
6744 + "Trying again...\n", l_iDevnum, l_lircPlugin->minor);
6745 + if (l_iReturn == -EBUSY) {
6746 + printk(DRIVER_NAME "[%d]: device is opened, "
6747 + "will unregister on close\n", l_iDevnum);
6750 + set_current_state(TASK_INTERRUPTIBLE);
6751 + schedule_timeout(HZ);
6753 + if ((l_iReturn = lirc_unregister_plugin(l_lircPlugin->minor)) > 0) {
6754 + printk(DRIVER_NAME "[%d]: lirc_unregister failed\n",
6759 + if (l_iReturn != 0) {
6760 + printk(DRIVER_NAME "[%d]: didn't free resources\n",
6765 + printk(DRIVER_NAME "[%d]: usb remote disconnected\n", l_iDevnum);
6767 + lirc_buffer_free(l_lircPlugin->rbuf);
6768 + kfree(l_lircPlugin->rbuf);
6769 + kfree(l_lircPlugin);
6773 +static int s_lirc_set_use_inc(void *p_data)
6775 + t_sasemDevice *l_sasemDevice = p_data;
6778 + if (!l_sasemDevice) {
6779 + printk(DRIVER_NAME "[?]: s_lirc_set_use_inc called with no context\n");
6783 + l_iDevnum = l_sasemDevice->m_iDevnum;
6784 + if (debug) printk(DRIVER_NAME "[%d]: s_lirc_set_use_inc\n",
6787 + if (!l_sasemDevice->m_iConnected) {
6790 + this is the trigger from LIRC to start
6791 + transfering data so the URB is being submitted
6794 + if (!l_sasemDevice->m_device)
6797 + /* set USB device in URB */
6798 + l_sasemDevice->m_urbIn->dev = l_sasemDevice->m_device;
6800 + /* start communication by submitting URB */
6801 + if (usb_submit_urb(l_sasemDevice->m_urbIn)) {
6802 + printk(DRIVER_NAME "[%d]: open result = -EIO error "
6803 + "submitting urb\n", l_iDevnum);
6807 + /* indicate that URB has been submitted */
6808 + l_sasemDevice->m_iConnected = 1;
6814 +static void s_lirc_set_use_dec(void *p_data) {
6815 + t_sasemDevice *l_sasemDevice = p_data;
6818 + if (!l_sasemDevice) {
6819 + printk(DRIVER_NAME "[?]: s_lirc_set_use_dec called with no context\n");
6823 + l_iDevnum = l_sasemDevice->m_iDevnum;
6824 + if (debug) printk(DRIVER_NAME "[%d]: s_lirc_set_use_dec\n",
6827 + if (l_sasemDevice->m_iConnected) {
6830 + URB has been submitted before so it can be unlinked
6833 + down_interruptible(&l_sasemDevice->m_semLock);
6834 + usb_unlink_urb(l_sasemDevice->m_urbIn);
6835 + l_sasemDevice->m_iConnected = 0;
6836 + up(&l_sasemDevice->m_semLock);
6839 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_sasem.h linux-2.6.8-rc4/drivers/char/lirc/lirc_sasem.h
6840 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_sasem.h 1970-01-01 01:00:00.000000000 +0100
6841 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_sasem.h 2004-06-19 08:34:35.000000000 +0200
6844 + * Version Information
6846 +#define DRIVER_VERSION "v0.1"
6847 +#define DATE "June 2004"
6848 +#define DRIVER_AUTHOR "Oliver Stabel <oliver.stabel@gmx.de>"
6849 +#define DRIVER_DESC "USB Driver for Sasem Remote Controller V1.1"
6850 +#define DRIVER_SHORTDESC "Sasem"
6851 +#define DRIVER_NAME "lirc_sasem"
6854 + KERN_INFO DRIVER_SHORTDESC " " DRIVER_VERSION " (" DATE ")\n" \
6855 + KERN_INFO " by " DRIVER_AUTHOR "\n"
6857 +static const char longbanner[] = {
6858 + DRIVER_DESC ", " DRIVER_VERSION " (" DATE "), by " DRIVER_AUTHOR
6861 +#define MAX_INTERRUPT_DATA 8
6862 +#define SASEM_MINOR 144
6864 +static const char sc_cSasemCode[MAX_INTERRUPT_DATA] =
6865 + { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
6867 +typedef struct usb_driver t_usb_driver, *tp_usb_driver;
6868 +typedef struct usb_device t_usb_device, *tp_usb_device;
6869 +typedef struct usb_interface t_usb_interface, *tp_usb_interface;
6870 +typedef struct usb_device_id t_usb_device_id, *tp_usb_device_id;
6871 +typedef struct usb_host_interface t_usb_host_interface,
6872 + *tp_usb_host_interface;
6873 +typedef struct usb_interface_descriptor t_usb_interface_descriptor,
6874 + *tp_usb_interface_descriptor;
6875 +typedef struct usb_endpoint_descriptor t_usb_endpoint_descriptor,
6876 + *tp_usb_endpoint_descriptor;
6877 +typedef struct urb t_urb, *tp_urb;
6879 +typedef struct semaphore t_semaphore, *tp_semaphore;
6881 +typedef struct lirc_plugin t_lirc_plugin, *tp_lirc_plugin;
6882 +typedef struct lirc_buffer t_lirc_buffer;
6884 +struct sasemDevice {
6885 + t_usb_device *m_device;
6886 + t_usb_endpoint_descriptor *m_descriptorIn;
6887 + t_usb_endpoint_descriptor *m_descriptorOut;
6890 + unsigned int m_iInterfaceNum;
6892 + unsigned char m_cBufferIn[MAX_INTERRUPT_DATA];
6893 + t_semaphore m_semLock;
6895 + char m_cLastCode[MAX_INTERRUPT_DATA];
6899 + t_lirc_plugin *m_lircPlugin;
6903 +typedef struct sasemDevice t_sasemDevice, *tp_sasemDevice;
6905 +static void* s_sasemProbe(t_usb_device *p_dev, unsigned p_iInterfaceNum,
6906 + const t_usb_device_id *p_id);
6907 +static void s_sasemDisconnect(t_usb_device *p_dev, void *p_ptr);
6908 +static void s_sasemCallbackIn(t_urb *p_urb);
6910 +static int s_unregister_from_lirc(t_sasemDevice *p_sasemDevice);
6911 +static int s_lirc_set_use_inc(void *p_data);
6912 +static void s_lirc_set_use_dec(void *p_data);
6913 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_serial.c linux-2.6.8-rc4/drivers/char/lirc/lirc_serial.c
6914 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_serial.c 1970-01-01 01:00:00.000000000 +0100
6915 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_serial.c 2004-04-24 21:59:07.000000000 +0200
6919 +/****************************************************************************
6920 + ** lirc_serial.c ***********************************************************
6921 + ****************************************************************************
6923 + * lirc_serial - Device driver that records pulse- and pause-lengths
6924 + * (space-lengths) between DDCD event on a serial port.
6926 + * Copyright (C) 1996,97 Ralph Metzler <rjkm@thp.uni-koeln.de>
6927 + * Copyright (C) 1998 Trent Piepho <xyzzy@u.washington.edu>
6928 + * Copyright (C) 1998 Ben Pfaff <blp@gnu.org>
6929 + * Copyright (C) 1999 Christoph Bartelmus <lirc@bartelmus.de>
6931 + * This program is free software; you can redistribute it and/or modify
6932 + * it under the terms of the GNU General Public License as published by
6933 + * the Free Software Foundation; either version 2 of the License, or
6934 + * (at your option) any later version.
6936 + * This program is distributed in the hope that it will be useful,
6937 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6938 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6939 + * GNU General Public License for more details.
6941 + * You should have received a copy of the GNU General Public License
6942 + * along with this program; if not, write to the Free Software
6943 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6947 +/* Steve's changes to improve transmission fidelity:
6948 + - for systems with the rdtsc instruction and the clock counter, a
6949 + send_pule that times the pulses directly using the counter.
6950 + This means that the LIRC_SERIAL_TRANSMITTER_LATENCY fudge is
6951 + not needed. Measurement shows very stable waveform, even where
6952 + PCI activity slows the access to the UART, which trips up other
6954 + - For other system, non-integer-microsecond pulse/space lengths,
6955 + done using fixed point binary. So, much more accurate carrier
6957 + - fine tuned transmitter latency, taking advantage of fractional
6958 + microseconds in previous change
6959 + - Fixed bug in the way transmitter latency was accounted for by
6960 + tuning the pulse lengths down - the send_pulse routine ignored
6961 + this overhead as it timed the overall pulse length - so the
6962 + pulse frequency was right but overall pulse length was too
6963 + long. Fixed by accounting for latency on each pulse/space
6966 + Steve Davies <steve@daviesfam.org> July 2001
6969 +#ifdef HAVE_CONFIG_H
6970 +# include <config.h>
6973 +#include <linux/version.h>
6974 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
6975 +#error "**********************************************************"
6976 +#error " Sorry, this driver needs kernel version 2.2.18 or higher "
6977 +#error "**********************************************************"
6980 +#include <linux/config.h>
6982 +#ifndef CONFIG_SERIAL_MODULE
6983 +#warning "******************************************"
6984 +#warning " Your serial port driver is compiled into "
6985 +#warning " the kernel. You will have to release the "
6986 +#warning " port you want to use for LIRC with: "
6987 +#warning " setserial /dev/ttySx uart none "
6988 +#warning "******************************************"
6991 +#include <linux/module.h>
6992 +#include <linux/errno.h>
6993 +#include <linux/signal.h>
6994 +#include <linux/sched.h>
6995 +#include <linux/fs.h>
6996 +#include <linux/interrupt.h>
6997 +#include <linux/ioport.h>
6998 +#include <linux/kernel.h>
6999 +#include <linux/major.h>
7000 +#include <linux/serial_reg.h>
7001 +#include <linux/time.h>
7002 +#include <linux/string.h>
7003 +#include <linux/types.h>
7004 +#include <linux/wait.h>
7005 +#include <linux/mm.h>
7006 +#include <linux/delay.h>
7007 +#include <linux/poll.h>
7009 +#include <asm/system.h>
7010 +#include <asm/segment.h>
7011 +#include <asm/io.h>
7012 +#include <asm/irq.h>
7013 +#include <asm/fcntl.h>
7015 +#include <linux/lirc.h>
7016 +#include "kcompat.h"
7017 +#include "lirc_dev.h"
7019 +#if defined(LIRC_SERIAL_SOFTCARRIER) && !defined(LIRC_SERIAL_TRANSMITTER)
7020 +#warning "Software carrier only affects transmitting"
7026 +#warning "Note: using rdtsc instruction"
7029 +#ifdef LIRC_SERIAL_ANIMAX
7030 +#ifdef LIRC_SERIAL_TRANSMITTER
7031 +#warning "******************************************"
7032 +#warning " This receiver does not have a "
7033 +#warning " transmitter diode "
7034 +#warning "******************************************"
7042 + int signal_pin_change;
7045 + long (*send_pulse)(unsigned long length);
7046 + void (*send_space)(long length);
7050 +#define LIRC_HOMEBREW 0
7051 +#define LIRC_IRDEO 1
7052 +#define LIRC_IRDEO_REMOTE 2
7053 +#define LIRC_ANIMAX 3
7054 +#define LIRC_IGOR 4
7056 +#ifdef LIRC_SERIAL_IRDEO
7057 +int type=LIRC_IRDEO;
7058 +#elif defined(LIRC_SERIAL_IRDEO_REMOTE)
7059 +int type=LIRC_IRDEO_REMOTE;
7060 +#elif defined(LIRC_SERIAL_ANIMAX)
7061 +int type=LIRC_ANIMAX;
7062 +#elif defined(LIRC_SERIAL_IGOR)
7063 +int type=LIRC_IGOR;
7065 +int type=LIRC_HOMEBREW;
7068 +#ifdef LIRC_SERIAL_SOFTCARRIER
7074 +/* forward declarations */
7075 +long send_pulse_irdeo(unsigned long length);
7076 +long send_pulse_homebrew(unsigned long length);
7077 +void send_space_irdeo(long length);
7078 +void send_space_homebrew(long length);
7080 +struct lirc_serial hardware[]=
7082 + /* home-brew receiver/transmitter */
7087 + UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR,
7088 + UART_MCR_RTS|UART_MCR_OUT2,
7089 + send_pulse_homebrew,
7090 + send_space_homebrew,
7092 +#ifdef LIRC_SERIAL_TRANSMITTER
7093 + LIRC_CAN_SET_SEND_DUTY_CYCLE|
7094 + LIRC_CAN_SET_SEND_CARRIER|
7095 + LIRC_CAN_SEND_PULSE|
7097 + LIRC_CAN_REC_MODE2)
7100 + /* IRdeo classic */
7106 + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2,
7109 + (LIRC_CAN_SET_SEND_DUTY_CYCLE|
7110 + LIRC_CAN_SEND_PULSE|
7111 + LIRC_CAN_REC_MODE2)
7114 + /* IRdeo remote */
7116 + LIRC_IRDEO_REMOTE,
7119 + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2,
7120 + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2,
7123 + (LIRC_CAN_SET_SEND_DUTY_CYCLE|
7124 + LIRC_CAN_SEND_PULSE|
7125 + LIRC_CAN_REC_MODE2)
7134 + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2,
7137 + LIRC_CAN_REC_MODE2
7140 + /* home-brew receiver/transmitter (Igor Cesko's variation) */
7145 + UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR,
7146 + UART_MCR_RTS|UART_MCR_OUT2,
7147 + send_pulse_homebrew,
7148 + send_space_homebrew,
7150 +#ifdef LIRC_SERIAL_TRANSMITTER
7151 + LIRC_CAN_SET_SEND_DUTY_CYCLE|
7152 + LIRC_CAN_SET_SEND_CARRIER|
7153 + LIRC_CAN_SEND_PULSE|
7155 + LIRC_CAN_REC_MODE2)
7160 +#define LIRC_DRIVER_NAME "lirc_serial"
7162 +#define RS_ISR_PASS_LIMIT 256
7164 +/* A long pulse code from a remote might take upto 300 bytes. The
7165 + daemon should read the bytes as soon as they are generated, so take
7166 + the number of keys you think you can push before the daemon runs
7167 + and multiply by 300. The driver will warn you if you overrun this
7168 + buffer. If you have a slow computer or non-busmastering IDE disks,
7169 + maybe you will need to increase this. */
7171 +/* This MUST be a power of two! It has to be larger than 1 as well. */
7173 +#define RBUF_LEN 256
7174 +#define WBUF_LEN 256
7176 +static int sense = -1; /* -1 = auto, 0 = active high, 1 = active low */
7178 +static spinlock_t lirc_lock = SPIN_LOCK_UNLOCKED;
7180 +static int io = CONFIG_LIRC_PORT_SERIAL;
7181 +static int irq = CONFIG_LIRC_IRQ_SERIAL;
7183 +static struct timeval lasttv = {0, 0};
7185 +static struct lirc_buffer rbuf;
7187 +static lirc_t wbuf[WBUF_LEN];
7189 +unsigned int freq = 38000;
7190 +unsigned int duty_cycle = 50;
7192 +/* Initialized in init_timing_params() */
7193 +unsigned long period = 0;
7194 +unsigned long pulse_width = 0;
7195 +unsigned long space_width = 0;
7197 +#if defined(__i386__)
7200 + Linux I/O port programming mini-HOWTO
7201 + Author: Riku Saikkonen <Riku.Saikkonen@hut.fi>
7202 + v, 28 December 1997
7205 + Actually, a port I/O instruction on most ports in the 0-0x3ff range
7206 + takes almost exactly 1 microsecond, so if you're, for example, using
7207 + the parallel port directly, just do additional inb()s from that port
7211 +/* transmitter latency 1.5625us 0x1.90 - this figure arrived at from
7212 + * comment above plus trimming to match actual measured frequency.
7213 + * This will be sensitive to cpu speed, though hopefully most of the 1.5us
7214 + * is spent in the uart access. Still - for reference test machine was a
7215 + * 1.13GHz Athlon system - Steve
7218 +/* changed from 400 to 450 as this works better on slower machines;
7219 + faster machines will use the rdtsc code anyway */
7221 +#define LIRC_SERIAL_TRANSMITTER_LATENCY 450
7225 +/* does anybody have information on other platforms ? */
7227 +#define LIRC_SERIAL_TRANSMITTER_LATENCY 256
7229 +#endif /* __i386__ */
7231 +static inline unsigned int sinp(int offset)
7233 + return inb(io + offset);
7236 +static inline void soutp(int offset, int value)
7238 + outb(value, io + offset);
7241 +static inline void on(void)
7243 + soutp(UART_MCR,hardware[type].on);
7246 +static inline void off(void)
7248 + soutp(UART_MCR,hardware[type].off);
7251 +#ifndef MAX_UDELAY_MS
7252 +#define MAX_UDELAY_US 5000
7254 +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000)
7257 +static inline void safe_udelay(unsigned long usecs)
7259 + while(usecs>MAX_UDELAY_US)
7261 + udelay(MAX_UDELAY_US);
7262 + usecs-=MAX_UDELAY_US;
7268 +/* This is an overflow/precision juggle, complicated in that we can't
7269 + do long long divide in the kernel */
7271 +/* When we use the rdtsc instruction to measure clocks, we keep the
7272 + * pulse and space widths as clock cycles. As this is CPU speed
7273 + * dependent, the widths must be calculated in init_port and ioctl
7277 +/* So send_pulse can quickly convert microseconds to clocks */
7278 +unsigned long conv_us_to_clocks = 0;
7280 +static inline int init_timing_params(unsigned int new_duty_cycle,
7281 + unsigned int new_freq)
7283 + unsigned long long loops_per_sec,work;
7285 + duty_cycle=new_duty_cycle;
7288 + loops_per_sec=current_cpu_data.loops_per_jiffy;
7289 + loops_per_sec*=HZ;
7291 + /* How many clocks in a microsecond?, avoiding long long divide */
7292 + work=loops_per_sec;
7293 + work*=4295; /* 4295 = 2^32 / 1e6 */
7294 + conv_us_to_clocks=(work>>32);
7296 + /* Carrier period in clocks, approach good up to 32GHz clock,
7297 + gets carrier frequency within 8Hz */
7298 + period=loops_per_sec>>3;
7299 + period/=(freq>>3);
7301 + /* Derive pulse and space from the period */
7303 + pulse_width = period*duty_cycle/100;
7304 + space_width = period - pulse_width;
7306 + printk(KERN_INFO LIRC_DRIVER_NAME
7307 + ": in init_timing_params, freq=%d, duty_cycle=%d, "
7308 + "clk/jiffy=%ld, pulse=%ld, space=%ld, conv_us_to_clocks=%ld\n",
7309 + freq, duty_cycle, current_cpu_data.loops_per_jiffy,
7310 + pulse_width, space_width, conv_us_to_clocks);
7314 +#else /* ! USE_RDTSC */
7315 +static inline int init_timing_params(unsigned int new_duty_cycle,
7316 + unsigned int new_freq)
7318 +/* period, pulse/space width are kept with 8 binary places -
7319 + * IE multiplied by 256. */
7320 + if(256*1000000L/new_freq*new_duty_cycle/100<=
7321 + LIRC_SERIAL_TRANSMITTER_LATENCY) return(-EINVAL);
7322 + if(256*1000000L/new_freq*(100-new_duty_cycle)/100<=
7323 + LIRC_SERIAL_TRANSMITTER_LATENCY) return(-EINVAL);
7324 + duty_cycle=new_duty_cycle;
7326 + period=256*1000000L/freq;
7327 + pulse_width=period*duty_cycle/100;
7328 + space_width=period-pulse_width;
7330 + printk(KERN_WARNING LIRC_DRIVER_NAME
7331 + ": in init_timing_params, freq=%d pulse=%ld, "
7332 + "space=%ld\n", freq, pulse_width, space_width);
7336 +#endif /* USE_RDTSC */
7339 +/* return value: space length delta */
7341 +long send_pulse_irdeo(unsigned long length)
7345 + unsigned char output;
7346 + unsigned char chunk,shifted;
7348 + /* how many bits have to be sent ? */
7349 + rawbits=length*1152/10000;
7350 + if(duty_cycle>50) chunk=3;
7352 + for(i=0,output=0x7f;rawbits>0;rawbits-=3)
7354 + shifted=chunk<<(i*3);
7356 + output&=(~shifted);
7360 + soutp(UART_TX,output);
7361 + while(!(sinp(UART_LSR) & UART_LSR_THRE));
7368 + soutp(UART_TX,output);
7369 + while(!(sinp(UART_LSR) & UART_LSR_TEMT));
7374 + return((-rawbits)*10000/1152);
7378 + return((3-i)*3*10000/1152+(-rawbits)*10000/1152);
7383 +/* Version that uses Pentium rdtsc instruction to measure clocks */
7385 +/* This version does sub-microsecond timing using rdtsc instruction,
7386 + * and does away with the fudged LIRC_SERIAL_TRANSMITTER_LATENCY
7387 + * Implicitly i586 architecture... - Steve
7390 +static inline long send_pulse_homebrew_softcarrier(unsigned long length)
7393 + unsigned long target, start, now;
7395 + /* Get going quick as we can */
7396 + rdtscl(start);on();
7397 + /* Convert length from microseconds to clocks */
7398 + length*=conv_us_to_clocks;
7399 + /* And loop till time is up - flipping at right intervals */
7401 + target=pulse_width;
7403 + while((now-start)<length)
7405 + /* Delay till flip time */
7410 + while ((now-start)<target);
7414 + rdtscl(now);off();
7415 + target+=space_width;
7420 + target+=pulse_width;
7425 + return(((now-start)-length)/conv_us_to_clocks);
7427 +#else /* ! USE_RDTSC */
7428 +/* Version using udelay() */
7430 +/* here we use fixed point arithmetic, with 8
7431 + fractional bits. that gets us within 0.1% or so of the right average
7432 + frequency, albeit with some jitter in pulse length - Steve */
7434 +/* To match 8 fractional bits used for pulse/space length */
7436 +static inline long send_pulse_homebrew_softcarrier(unsigned long length)
7439 + unsigned long actual, target, d;
7442 + actual=target=0; flag=0;
7443 + while(actual<length)
7448 + target+=space_width;
7453 + target+=pulse_width;
7455 + d=(target-actual-LIRC_SERIAL_TRANSMITTER_LATENCY+128)>>8;
7456 + /* Note - we've checked in ioctl that the pulse/space
7457 + widths are big enough so that d is > 0 */
7459 + actual+=(d<<8)+LIRC_SERIAL_TRANSMITTER_LATENCY;
7462 + return((actual-length)>>8);
7464 +#endif /* USE_RDTSC */
7466 +long send_pulse_homebrew(unsigned long length)
7468 + if(length<=0) return 0;
7471 + return send_pulse_homebrew_softcarrier(length);
7476 + safe_udelay(length);
7481 +void send_space_irdeo(long length)
7483 + if(length<=0) return;
7484 + safe_udelay(length);
7487 +void send_space_homebrew(long length)
7490 + if(length<=0) return;
7491 + safe_udelay(length);
7494 +static void inline rbwrite(lirc_t l)
7496 + if(lirc_buffer_full(&rbuf)) /* no new signals will be accepted */
7499 + printk(KERN_WARNING LIRC_DRIVER_NAME ": Buffer overrun\n");
7503 + _lirc_buffer_write_1(&rbuf, (void *)&l);
7506 +static void inline frbwrite(lirc_t l)
7508 + /* simple noise filter */
7509 + static lirc_t pulse=0L,space=0L;
7510 + static unsigned int ptr=0;
7512 + if(ptr>0 && (l&PULSE_BIT))
7514 + pulse+=l&PULSE_MASK;
7518 + rbwrite(pulse|PULSE_BIT);
7524 + if(!(l&PULSE_BIT))
7540 + if(space>PULSE_MASK) space=PULSE_MASK;
7542 + if(space>PULSE_MASK) space=PULSE_MASK;
7547 + rbwrite(pulse|PULSE_BIT);
7555 +irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs)
7557 + struct timeval tv;
7558 + int status,counter,dcd;
7565 + status=sinp(UART_MSR);
7566 + if(counter>RS_ISR_PASS_LIMIT)
7568 + printk(KERN_WARNING LIRC_DRIVER_NAME ": AIEEEE: "
7569 + "We're caught!\n");
7572 + if((status&hardware[type].signal_pin_change) && sense!=-1)
7574 + /* get current time */
7575 + do_gettimeofday(&tv);
7577 + /* New mode, written by Trent Piepho
7578 + <xyzzy@u.washington.edu>. */
7580 + /* The old format was not very portable.
7581 + We now use the type lirc_t to pass pulses
7582 + and spaces to user space.
7584 + If PULSE_BIT is set a pulse has been
7585 + received, otherwise a space has been
7586 + received. The driver needs to know if your
7587 + receiver is active high or active low, or
7588 + the space/pulse sense could be
7589 + inverted. The bits denoted by PULSE_MASK are
7590 + the length in microseconds. Lengths greater
7591 + than or equal to 16 seconds are clamped to
7592 + PULSE_MASK. All other bits are unused.
7593 + This is a much simpler interface for user
7594 + programs, as well as eliminating "out of
7595 + phase" errors with space/pulse
7598 + /* calculate time since last interrupt in
7600 + dcd=(status & hardware[type].signal_pin) ? 1:0;
7602 + deltv=tv.tv_sec-lasttv.tv_sec;
7606 + printk(KERN_WARNING LIRC_DRIVER_NAME
7607 + ": AIEEEE: %d %d %lx %lx %lx %lx\n",
7609 + tv.tv_sec,lasttv.tv_sec,
7610 + tv.tv_usec,lasttv.tv_usec);
7612 + data=PULSE_MASK; /* really long time */
7613 + if(!(dcd^sense)) /* sanity check */
7615 + /* detecting pulse while this
7616 + MUST be a space! */
7617 + sense=sense ? 0:1;
7622 + data=(lirc_t) (deltv*1000000+
7626 + if(tv.tv_sec<lasttv.tv_sec ||
7627 + (tv.tv_sec==lasttv.tv_sec &&
7628 + tv.tv_usec<lasttv.tv_usec))
7630 + printk(KERN_WARNING LIRC_DRIVER_NAME
7631 + ": AIEEEE: your clock just jumped "
7633 + printk(KERN_WARNING LIRC_DRIVER_NAME
7634 + ": %d %d %lx %lx %lx %lx\n",
7636 + tv.tv_sec,lasttv.tv_sec,
7637 + tv.tv_usec,lasttv.tv_usec);
7640 + frbwrite(dcd^sense ? data : (data|PULSE_BIT));
7642 + wake_up_interruptible(&rbuf.wait_poll);
7644 + } while(!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */
7645 + return IRQ_RETVAL(IRQ_HANDLED);
7648 +static DECLARE_WAIT_QUEUE_HEAD(power_supply_queue);
7650 +static int init_port(void)
7652 + unsigned long flags;
7654 + /* Check io region*/
7656 + if((check_region(io,8))==-EBUSY)
7658 + printk(KERN_ERR LIRC_DRIVER_NAME
7659 + ": port %04x already in use\n", io);
7660 + printk(KERN_WARNING LIRC_DRIVER_NAME
7661 + ": use 'setserial /dev/ttySX uart none'\n");
7662 + printk(KERN_WARNING LIRC_DRIVER_NAME
7663 + ": or compile the serial port driver as module and\n");
7664 + printk(KERN_WARNING LIRC_DRIVER_NAME
7665 + ": make sure this module is loaded first\n");
7669 + /* Reserve io region. */
7670 + request_region(io, 8, LIRC_DRIVER_NAME);
7672 + local_irq_save(flags);
7675 + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
7677 + /* First of all, disable all interrupts */
7678 + soutp(UART_IER, sinp(UART_IER)&
7679 + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI)));
7681 + /* Clear registers. */
7687 + /* Set line for power source */
7688 + soutp(UART_MCR, hardware[type].off);
7690 + /* Clear registers again to be sure. */
7696 + switch(hardware[type].type)
7699 + case LIRC_IRDEO_REMOTE:
7700 + /* setup port to 7N1 @ 115200 Baud */
7701 + /* 7N1+start = 9 bits at 115200 ~ 3 bits at 38kHz */
7704 + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB);
7705 + /* Set divisor to 1 => 115200 Baud */
7706 + soutp(UART_DLM,0);
7707 + soutp(UART_DLL,1);
7708 + /* Set DLAB 0 + 7N1 */
7709 + soutp(UART_LCR,UART_LCR_WLEN7);
7710 + /* THR interrupt already disabled at this point */
7716 + local_irq_restore(flags);
7718 + /* Initialize pulse/space widths */
7719 + init_timing_params(duty_cycle, freq);
7721 + /* If pin is high, then this must be an active low receiver. */
7724 + /* wait 1 sec for the power supply */
7726 + sleep_on_timeout(&power_supply_queue,HZ);
7728 + sense=(sinp(UART_MSR) & hardware[type].signal_pin) ? 1:0;
7729 + printk(KERN_INFO LIRC_DRIVER_NAME ": auto-detected active "
7730 + "%s receiver\n",sense ? "low":"high");
7734 + printk(KERN_INFO LIRC_DRIVER_NAME ": Manually using active "
7735 + "%s receiver\n",sense ? "low":"high");
7741 +static int set_use_inc(void* data)
7744 + unsigned long flags;
7746 + spin_lock(&lirc_lock);
7749 + spin_unlock(&lirc_lock);
7753 + /* Init read buffer. */
7754 + if (lirc_buffer_init(&rbuf, sizeof(lirc_t), RBUF_LEN) < 0)
7757 + /* initialize timestamp */
7758 + do_gettimeofday(&lasttv);
7760 + result=request_irq(irq,irq_handler,SA_INTERRUPT,LIRC_DRIVER_NAME,NULL);
7764 + printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq);
7765 + spin_unlock(&lirc_lock);
7766 + lirc_buffer_free(&rbuf);
7769 + printk(KERN_ERR LIRC_DRIVER_NAME
7770 + ": Bad irq number or handler\n");
7771 + spin_unlock(&lirc_lock);
7772 + lirc_buffer_free(&rbuf);
7776 + printk(KERN_INFO LIRC_DRIVER_NAME
7777 + ": Interrupt %d, port %04x obtained\n", irq, io);
7782 + local_irq_save(flags);
7785 + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
7787 + soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI);
7789 + local_irq_restore(flags);
7791 + MOD_INC_USE_COUNT;
7792 + spin_unlock(&lirc_lock);
7796 +static void set_use_dec(void* data)
7797 +{ unsigned long flags;
7799 + local_irq_save(flags);
7802 + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
7804 + /* First of all, disable all interrupts */
7805 + soutp(UART_IER, sinp(UART_IER)&
7806 + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI)));
7807 + local_irq_restore(flags);
7809 + free_irq(irq, NULL);
7811 + printk(KERN_INFO LIRC_DRIVER_NAME ": freed IRQ %d\n", irq);
7813 + lirc_buffer_free(&rbuf);
7815 + MOD_DEC_USE_COUNT;
7818 +static ssize_t lirc_write(struct file *file, const char *buf,
7819 + size_t n, loff_t * ppos)
7821 + int retval,i,count;
7822 + unsigned long flags;
7825 + if(!(hardware[type].features&LIRC_CAN_SEND_PULSE))
7830 + if(n%sizeof(lirc_t)) return(-EINVAL);
7831 + retval=verify_area(VERIFY_READ,buf,n);
7832 + if(retval) return(retval);
7833 + count=n/sizeof(lirc_t);
7834 + if(count>WBUF_LEN || count%2==0) return(-EINVAL);
7835 + copy_from_user(wbuf,buf,n);
7836 + local_irq_save(flags);
7837 + if(hardware[type].type==LIRC_IRDEO)
7839 + /* DTR, RTS down */
7842 + for(i=0;i<count;i++)
7844 + if(i%2) hardware[type].send_space(wbuf[i]-delta);
7845 + else delta=hardware[type].send_pulse(wbuf[i]);
7848 + local_irq_restore(flags);
7852 +static int lirc_ioctl(struct inode *node,struct file *filep,unsigned int cmd,
7853 + unsigned long arg)
7856 + unsigned long value;
7857 + unsigned int ivalue;
7861 + case LIRC_GET_SEND_MODE:
7862 + if(!(hardware[type].features&LIRC_CAN_SEND_MASK))
7864 + return(-ENOIOCTLCMD);
7867 + result=put_user(LIRC_SEND2MODE
7868 + (hardware[type].features&LIRC_CAN_SEND_MASK),
7869 + (unsigned long *) arg);
7870 + if(result) return(result);
7873 + case LIRC_SET_SEND_MODE:
7874 + if(!(hardware[type].features&LIRC_CAN_SEND_MASK))
7876 + return(-ENOIOCTLCMD);
7879 + result=get_user(value,(unsigned long *) arg);
7880 + if(result) return(result);
7881 + /* only LIRC_MODE_PULSE supported */
7882 + if(value!=LIRC_MODE_PULSE) return(-ENOSYS);
7885 + case LIRC_GET_LENGTH:
7889 + case LIRC_SET_SEND_DUTY_CYCLE:
7891 + printk(KERN_WARNING LIRC_DRIVER_NAME ": SET_SEND_DUTY_CYCLE\n");
7893 + if(!(hardware[type].features&LIRC_CAN_SET_SEND_DUTY_CYCLE))
7895 + return(-ENOIOCTLCMD);
7898 + result=get_user(ivalue,(unsigned int *) arg);
7899 + if(result) return(result);
7900 + if(ivalue<=0 || ivalue>100) return(-EINVAL);
7901 + return init_timing_params(ivalue, freq);
7904 + case LIRC_SET_SEND_CARRIER:
7906 + printk(KERN_WARNING LIRC_DRIVER_NAME ": SET_SEND_CARRIER\n");
7908 + if(!(hardware[type].features&LIRC_CAN_SET_SEND_CARRIER))
7910 + return(-ENOIOCTLCMD);
7913 + result=get_user(ivalue,(unsigned int *) arg);
7914 + if(result) return(result);
7915 + if(ivalue>500000 || ivalue<20000) return(-EINVAL);
7916 + return init_timing_params(duty_cycle, ivalue);
7920 + return(-ENOIOCTLCMD);
7925 +static struct file_operations lirc_fops =
7927 + write: lirc_write,
7930 +static struct lirc_plugin plugin = {
7931 + name: LIRC_DRIVER_NAME,
7939 + set_use_inc: set_use_inc,
7940 + set_use_dec: set_use_dec,
7941 + ioctl: lirc_ioctl,
7947 +MODULE_AUTHOR("Ralph Metzler, Trent Piepho, Ben Pfaff, Christoph Bartelmus");
7948 +MODULE_DESCRIPTION("Infra-red receiver driver for serial ports.");
7949 +#ifdef MODULE_LICENSE
7950 +MODULE_LICENSE("GPL");
7953 +MODULE_PARM(type, "i");
7954 +MODULE_PARM_DESC(type, "Hardware type (0 = home-brew, 1 = IRdeo,"
7955 + " 2 = IRdeo Remote, 3 = AnimaX, 4 = IgorPlug");
7957 +MODULE_PARM(io, "i");
7958 +MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)");
7960 +MODULE_PARM(irq, "i");
7961 +MODULE_PARM_DESC(irq, "Interrupt (4 or 3)");
7963 +MODULE_PARM(sense, "i");
7964 +MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit"
7965 + " (0 = active high, 1 = active low )");
7967 +MODULE_PARM(softcarrier, "i");
7968 +MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on)");
7975 +int init_module(void)
7981 + case LIRC_HOMEBREW:
7983 + case LIRC_IRDEO_REMOTE:
7990 + if(!softcarrier && hardware[type].type==LIRC_HOMEBREW)
7992 + hardware[type].features&=~(LIRC_CAN_SET_SEND_DUTY_CYCLE|
7993 + LIRC_CAN_SET_SEND_CARRIER);
7995 + if ((result = init_port()) < 0)
7997 + plugin.features = hardware[type].features;
7998 + if ((plugin.minor = lirc_register_plugin(&plugin)) < 0) {
7999 + printk(KERN_ERR LIRC_DRIVER_NAME
8000 + ": register_chrdev failed!\n");
8001 + release_region(io, 8);
8007 +void cleanup_module(void)
8009 + release_region(io, 8);
8010 + lirc_unregister_plugin(plugin.minor);
8012 + printk(KERN_INFO LIRC_DRIVER_NAME ": cleaned up module\n");
8017 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_sir.c linux-2.6.8-rc4/drivers/char/lirc/lirc_sir.c
8018 --- linux-2.6.8-rc4.orig/drivers/char/lirc/lirc_sir.c 1970-01-01 01:00:00.000000000 +0100
8019 +++ linux-2.6.8-rc4/drivers/char/lirc/lirc_sir.c 2004-04-27 20:28:16.000000000 +0200
8022 + * LIRC SIR driver, (C) 2000 Milan Pikula <www@fornax.sk>
8024 + * lirc_sir - Device driver for use with SIR (serial infra red)
8025 + * mode of IrDA on many notebooks.
8027 + * This program is free software; you can redistribute it and/or modify
8028 + * it under the terms of the GNU General Public License as published by
8029 + * the Free Software Foundation; either version 2 of the License, or
8030 + * (at your option) any later version.
8032 + * This program is distributed in the hope that it will be useful,
8033 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8034 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8035 + * GNU General Public License for more details.
8037 + * You should have received a copy of the GNU General Public License
8038 + * along with this program; if not, write to the Free Software
8039 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
8042 + * 2000/09/16 Frank Przybylski <mail@frankprzybylski.de> :
8043 + * added timeout and relaxed pulse detection, removed gap bug
8045 + * 2000/12/15 Christoph Bartelmus <lirc@bartelmus.de> :
8046 + * added support for Tekram Irmate 210 (sending does not work yet,
8047 + * kind of disappointing that nobody was able to implement that
8051 + * 2001/02/27 Christoph Bartelmus <lirc@bartelmus.de> :
8052 + * added support for StrongARM SA1100 embedded microprocessor
8053 + * parts cut'n'pasted from sa1100_ir.c (C) 2000 Russell King
8057 +#include <linux/version.h>
8058 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)
8059 +#error "**********************************************************"
8060 +#error " Sorry, this driver needs kernel version 2.2.18 or higher "
8061 +#error "**********************************************************"
8063 +#include <linux/module.h>
8065 +#ifdef HAVE_CONFIG_H
8066 +# include <config.h>
8069 +#include <linux/config.h>
8071 +#if !defined(LIRC_ON_SA1100) && !defined(CONFIG_SERIAL_MODULE)
8072 +#warning "******************************************"
8073 +#warning " Your serial port driver is compiled into "
8074 +#warning " the kernel. You will have to release the "
8075 +#warning " port you want to use for LIRC with: "
8076 +#warning " setserial /dev/ttySx uart none "
8077 +#warning "******************************************"
8080 +#include <linux/sched.h>
8081 +#include <linux/errno.h>
8082 +#include <linux/signal.h>
8083 +#include <linux/fs.h>
8084 +#include <linux/interrupt.h>
8085 +#include <linux/ioport.h>
8086 +#include <linux/kernel.h>
8087 +#include <linux/major.h>
8088 +#include <linux/serial_reg.h>
8089 +#include <linux/time.h>
8090 +#include <linux/string.h>
8091 +#include <linux/types.h>
8092 +#include <linux/wait.h>
8093 +#include <linux/mm.h>
8094 +#include <linux/delay.h>
8095 +#include <linux/poll.h>
8096 +#include <asm/system.h>
8097 +#include <asm/segment.h>
8098 +#include <asm/io.h>
8099 +#include <asm/irq.h>
8100 +#include <asm/fcntl.h>
8101 +#ifdef LIRC_ON_SA1100
8102 +#include <asm/hardware.h>
8103 +#ifdef CONFIG_SA1100_COLLIE
8104 +#include <asm/arch/tc35143.h>
8105 +#include <asm/ucb1200.h>
8109 +#include <linux/timer.h>
8111 +#include <linux/lirc.h>
8112 +#include "lirc_dev.h"
8113 +#include "kcompat.h"
8115 +/* SECTION: Definitions */
8117 +/**************************** Tekram dongle ***************************/
8118 +#ifdef LIRC_SIR_TEKRAM
8119 +/* stolen from kernel source */
8120 +/* definitions for Tekram dongle */
8121 +#define TEKRAM_115200 0x00
8122 +#define TEKRAM_57600 0x01
8123 +#define TEKRAM_38400 0x02
8124 +#define TEKRAM_19200 0x03
8125 +#define TEKRAM_9600 0x04
8126 +#define TEKRAM_2400 0x08
8128 +#define TEKRAM_PW 0x10 /* Pulse select bit */
8130 +/* 10bit * 1s/115200bit in milli seconds = 87ms*/
8131 +#define TIME_CONST (10000000ul/115200ul)
8135 +#ifdef LIRC_SIR_ACTISYS_ACT200L
8136 +static void init_act200(void);
8139 +/******************************* SA1100 ********************************/
8140 +#ifdef LIRC_ON_SA1100
8141 +struct sa1100_ser2_registers
8143 + /* HSSP control register */
8144 + unsigned char hscr0;
8145 + /* UART registers */
8146 + unsigned char utcr0;
8147 + unsigned char utcr1;
8148 + unsigned char utcr2;
8149 + unsigned char utcr3;
8150 + unsigned char utcr4;
8151 + unsigned char utdr;
8152 + unsigned char utsr0;
8153 + unsigned char utsr1;
8156 +static int irq=IRQ_Ser2ICP;
8158 +#define LIRC_ON_SA1100_TRANSMITTER_LATENCY 0
8160 +/* pulse/space ratio of 50/50 */
8161 +unsigned long pulse_width = (13-LIRC_ON_SA1100_TRANSMITTER_LATENCY);
8162 +/* 1000000/freq-pulse_width */
8163 +unsigned long space_width = (13-LIRC_ON_SA1100_TRANSMITTER_LATENCY);
8164 +unsigned int freq = 38000; /* modulation frequency */
8165 +unsigned int duty_cycle = 50; /* duty cycle of 50% */
8169 +#define RBUF_LEN 1024
8170 +#define WBUF_LEN 1024
8172 +#define LIRC_DRIVER_NAME "lirc_sir"
8174 +#ifndef LIRC_SIR_TEKRAM
8177 +/* 9bit * 1s/115200bit in milli seconds = 78.125ms*/
8178 +#define TIME_CONST (9000000ul/115200ul)
8182 +/* timeout for sequences in jiffies (=5/100s) */
8183 +/* must be longer than TIME_CONST */
8184 +#define SIR_TIMEOUT (HZ*5/100)
8186 +#ifndef LIRC_ON_SA1100
8187 +static int io = CONFIG_LIRC_PORT_SIR;
8188 +static int irq = CONFIG_LIRC_IRQ_SIR;
8189 +static int threshold = 3;
8192 +static spinlock_t timer_lock = SPIN_LOCK_UNLOCKED;
8193 +static struct timer_list timerlist;
8194 +/* time of last signal change detected */
8195 +static struct timeval last_tv = {0, 0};
8196 +/* time of last UART data ready interrupt */
8197 +static struct timeval last_intr_tv = {0, 0};
8198 +static int last_value = 0;
8200 +static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue);
8202 +static spinlock_t hardware_lock = SPIN_LOCK_UNLOCKED;
8203 +static spinlock_t dev_lock = SPIN_LOCK_UNLOCKED;
8205 +static lirc_t rx_buf[RBUF_LEN]; unsigned int rx_tail = 0, rx_head = 0;
8206 +#ifndef LIRC_SIR_TEKRAM
8207 +static lirc_t tx_buf[WBUF_LEN];
8210 +/* SECTION: Prototypes */
8212 +/* Communication with user-space */
8213 +static int lirc_open(struct inode * inode, struct file * file);
8214 +static int lirc_close(struct inode * inode, struct file *file);
8215 +static unsigned int lirc_poll(struct file * file, poll_table * wait);
8216 +static ssize_t lirc_read(struct file * file, char * buf, size_t count,
8218 +static ssize_t lirc_write(struct file * file, const char * buf, size_t n, loff_t * pos);
8219 +static int lirc_ioctl(struct inode *node,struct file *filep,unsigned int cmd,
8220 + unsigned long arg);
8221 +static void add_read_queue(int flag, unsigned long val);
8223 +static int init_chrdev(void);
8224 +static void drop_chrdev(void);
8227 +static irqreturn_t sir_interrupt(int irq, void * dev_id,
8228 + struct pt_regs * regs);
8229 +#ifndef LIRC_SIR_TEKRAM
8230 +static void send_space(unsigned long len);
8231 +static void send_pulse(unsigned long len);
8233 +static int init_hardware(void);
8234 +static void drop_hardware(void);
8235 + /* Initialisation */
8236 +static int init_port(void);
8237 +static void drop_port(void);
8238 +int init_module(void);
8239 +void cleanup_module(void);
8241 +#ifdef LIRC_ON_SA1100
8242 +void inline on(void)
8247 +void inline off(void)
8252 +static inline unsigned int sinp(int offset)
8254 + return inb(io + offset);
8257 +static inline void soutp(int offset, int value)
8259 + outb(value, io + offset);
8263 +#ifndef MAX_UDELAY_MS
8264 +#define MAX_UDELAY_US 5000
8266 +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000)
8269 +static inline void safe_udelay(unsigned long usecs)
8271 + while(usecs>MAX_UDELAY_US)
8273 + udelay(MAX_UDELAY_US);
8274 + usecs-=MAX_UDELAY_US;
8279 +/* SECTION: Communication with user-space */
8281 +static int lirc_open(struct inode * inode, struct file * file)
8283 + spin_lock(&dev_lock);
8285 + spin_unlock(&dev_lock);
8288 + MOD_INC_USE_COUNT;
8289 + spin_unlock(&dev_lock);
8293 +static int lirc_close(struct inode * inode, struct file *file)
8295 + MOD_DEC_USE_COUNT;
8299 +static unsigned int lirc_poll(struct file * file, poll_table * wait)
8301 + poll_wait(file, &lirc_read_queue, wait);
8302 + if (rx_head != rx_tail)
8303 + return POLLIN | POLLRDNORM;
8307 +static ssize_t lirc_read(struct file * file, char * buf, size_t count,
8312 + DECLARE_WAITQUEUE(wait,current);
8314 + if(n%sizeof(lirc_t)) return(-EINVAL);
8316 + add_wait_queue(&lirc_read_queue,&wait);
8317 + current->state=TASK_INTERRUPTIBLE;
8320 + if(rx_head!=rx_tail)
8322 + retval=verify_area(VERIFY_WRITE,
8323 + (void *) buf+n,sizeof(lirc_t));
8328 + copy_to_user((void *) buf+n,(void *) (rx_buf+rx_head),
8330 + rx_head=(rx_head+1)&(RBUF_LEN-1);
8331 + n+=sizeof(lirc_t);
8335 + if(file->f_flags & O_NONBLOCK)
8340 + if(signal_pending(current))
8342 + retval=-ERESTARTSYS;
8346 + current->state=TASK_INTERRUPTIBLE;
8349 + remove_wait_queue(&lirc_read_queue,&wait);
8350 + current->state=TASK_RUNNING;
8351 + return (n ? n : retval);
8353 +static ssize_t lirc_write(struct file * file, const char * buf, size_t n, loff_t * pos)
8355 + unsigned long flags;
8356 +#ifdef LIRC_SIR_TEKRAM
8362 + if(n%sizeof(lirc_t) || (n/sizeof(lirc_t)) > WBUF_LEN)
8364 + retval = verify_area(VERIFY_READ, buf, n);
8367 + copy_from_user(tx_buf, buf, n);
8369 + n/=sizeof(lirc_t);
8370 +#ifdef LIRC_ON_SA1100
8371 + /* disable receiver */
8374 + local_irq_save(flags);
8379 + send_pulse(tx_buf[i]);
8384 + send_space(tx_buf[i]);
8387 + local_irq_restore(flags);
8388 +#ifdef LIRC_ON_SA1100
8390 + udelay(1000); /* wait 1ms for IR diode to recover */
8392 + /* clear status register to prevent unwanted interrupts */
8393 + Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB);
8394 + /* enable receiver */
8395 + Ser2UTCR3=UTCR3_RXE|UTCR3_RIE;
8401 +static int lirc_ioctl(struct inode *node,struct file *filep,unsigned int cmd,
8402 + unsigned long arg)
8405 + unsigned long value = 0;
8406 +#ifdef LIRC_ON_SA1100
8407 + unsigned int ivalue;
8410 +#ifdef LIRC_SIR_TEKRAM
8411 + if (cmd == LIRC_GET_FEATURES)
8412 + value = LIRC_CAN_REC_MODE2;
8413 + else if (cmd == LIRC_GET_SEND_MODE)
8415 + else if (cmd == LIRC_GET_REC_MODE)
8416 + value = LIRC_MODE_MODE2;
8417 +#elif defined(LIRC_ON_SA1100)
8418 + if (cmd == LIRC_GET_FEATURES)
8419 + value = LIRC_CAN_SEND_PULSE |
8420 + LIRC_CAN_SET_SEND_DUTY_CYCLE |
8421 + LIRC_CAN_SET_SEND_CARRIER |
8422 + LIRC_CAN_REC_MODE2;
8423 + else if (cmd == LIRC_GET_SEND_MODE)
8424 + value = LIRC_MODE_PULSE;
8425 + else if (cmd == LIRC_GET_REC_MODE)
8426 + value = LIRC_MODE_MODE2;
8428 + if (cmd == LIRC_GET_FEATURES)
8429 + value = LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2;
8430 + else if (cmd == LIRC_GET_SEND_MODE)
8431 + value = LIRC_MODE_PULSE;
8432 + else if (cmd == LIRC_GET_REC_MODE)
8433 + value = LIRC_MODE_MODE2;
8437 + case LIRC_GET_FEATURES:
8438 + case LIRC_GET_SEND_MODE:
8439 + case LIRC_GET_REC_MODE:
8440 + retval = put_user(value, (unsigned long *) arg);
8443 + case LIRC_SET_SEND_MODE:
8444 + case LIRC_SET_REC_MODE:
8445 + retval = get_user(value, (unsigned long *) arg);
8447 +#ifdef LIRC_ON_SA1100
8448 + case LIRC_SET_SEND_DUTY_CYCLE:
8449 + retval=get_user(ivalue,(unsigned int *) arg);
8450 + if(retval) return(retval);
8451 + if(ivalue<=0 || ivalue>100) return(-EINVAL);
8452 + /* (ivalue/100)*(1000000/freq) */
8453 + duty_cycle=ivalue;
8454 + pulse_width=(unsigned long) duty_cycle*10000/freq;
8455 + space_width=(unsigned long) 1000000L/freq-pulse_width;
8456 + if(pulse_width>=LIRC_ON_SA1100_TRANSMITTER_LATENCY)
8457 + pulse_width-=LIRC_ON_SA1100_TRANSMITTER_LATENCY;
8458 + if(space_width>=LIRC_ON_SA1100_TRANSMITTER_LATENCY)
8459 + space_width-=LIRC_ON_SA1100_TRANSMITTER_LATENCY;
8461 + case LIRC_SET_SEND_CARRIER:
8462 + retval=get_user(ivalue,(unsigned int *) arg);
8463 + if(retval) return(retval);
8464 + if(ivalue>500000 || ivalue<20000) return(-EINVAL);
8466 + pulse_width=(unsigned long) duty_cycle*10000/freq;
8467 + space_width=(unsigned long) 1000000L/freq-pulse_width;
8468 + if(pulse_width>=LIRC_ON_SA1100_TRANSMITTER_LATENCY)
8469 + pulse_width-=LIRC_ON_SA1100_TRANSMITTER_LATENCY;
8470 + if(space_width>=LIRC_ON_SA1100_TRANSMITTER_LATENCY)
8471 + space_width-=LIRC_ON_SA1100_TRANSMITTER_LATENCY;
8475 + retval = -ENOIOCTLCMD;
8482 +#ifdef LIRC_SIR_TEKRAM
8483 + if (cmd == LIRC_SET_REC_MODE) {
8484 + if (value != LIRC_MODE_MODE2)
8486 + } else if (cmd == LIRC_SET_SEND_MODE) {
8490 + if (cmd == LIRC_SET_REC_MODE) {
8491 + if (value != LIRC_MODE_MODE2)
8493 + } else if (cmd == LIRC_SET_SEND_MODE) {
8494 + if (value != LIRC_MODE_PULSE)
8501 +static void add_read_queue(int flag, unsigned long val)
8503 + unsigned int new_rx_tail;
8506 +#ifdef DEBUG_SIGNAL
8507 + printk(KERN_DEBUG LIRC_DRIVER_NAME
8508 + ": add flag %d with val %lu\n",
8512 + newval = val & PULSE_MASK;
8514 + /* statistically pulses are ~TIME_CONST/2 too long: we could
8515 + maybe make this more exactly but this is good enough */
8516 + if(flag) /* pulse */
8518 + if(newval>TIME_CONST/2)
8520 + newval-=TIME_CONST/2;
8522 + else /* should not ever happen */
8526 + newval|=PULSE_BIT;
8530 + newval+=TIME_CONST/2;
8532 + new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1);
8533 + if (new_rx_tail == rx_head) {
8535 + printk(KERN_WARNING LIRC_DRIVER_NAME ": Buffer overrun.\n");
8539 + rx_buf[rx_tail] = newval;
8540 + rx_tail = new_rx_tail;
8541 + wake_up_interruptible(&lirc_read_queue);
8544 +static struct file_operations lirc_fops =
8547 + write: lirc_write,
8549 + ioctl: lirc_ioctl,
8551 + release: lirc_close,
8554 +static int set_use_inc(void* data)
8556 +#if WE_DONT_USE_LOCAL_OPEN_CLOSE
8557 + MOD_INC_USE_COUNT;
8562 +static void set_use_dec(void* data)
8564 +#if WE_DONT_USE_LOCAL_OPEN_CLOSE
8565 + MOD_DEC_USE_COUNT;
8568 +static struct lirc_plugin plugin = {
8569 + name: LIRC_DRIVER_NAME,
8576 + set_use_inc: set_use_inc,
8577 + set_use_dec: set_use_dec,
8583 +int init_chrdev(void)
8585 + plugin.minor = lirc_register_plugin(&plugin);
8586 + if (plugin.minor < 0) {
8587 + printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n");
8593 +static void drop_chrdev(void)
8595 + lirc_unregister_plugin(plugin.minor);
8599 +/* SECTION: Hardware */
8600 +static long delta(struct timeval * tv1, struct timeval * tv2)
8602 + unsigned long deltv;
8604 + deltv = tv2->tv_sec - tv1->tv_sec;
8608 + deltv = deltv*1000000 +
8614 +static void sir_timeout(unsigned long data)
8616 + /* if last received signal was a pulse, but receiving stopped
8617 + within the 9 bit frame, we need to finish this pulse and
8618 + simulate a signal change to from pulse to space. Otherwise
8619 + upper layers will receive two sequences next time. */
8621 + unsigned long flags;
8622 + unsigned long pulse_end;
8624 + /* avoid interference with interrupt */
8625 + spin_lock_irqsave(&timer_lock, flags);
8628 +#ifndef LIRC_ON_SA1100
8629 + /* clear unread bits in UART and restart */
8630 + outb(UART_FCR_CLEAR_RCVR, io + UART_FCR);
8632 + /* determine 'virtual' pulse end: */
8633 + pulse_end = delta(&last_tv, &last_intr_tv);
8634 +#ifdef DEBUG_SIGNAL
8635 + printk(KERN_DEBUG LIRC_DRIVER_NAME
8636 + ": timeout add %d for %lu usec\n",last_value,pulse_end);
8638 + add_read_queue(last_value,pulse_end);
8640 + last_tv=last_intr_tv;
8642 + spin_unlock_irqrestore(&timer_lock, flags);
8645 +static irqreturn_t sir_interrupt(int irq, void * dev_id,
8646 + struct pt_regs * regs)
8648 + unsigned char data;
8649 + struct timeval curr_tv;
8650 + static unsigned long deltv;
8651 +#ifdef LIRC_ON_SA1100
8655 + //printk("interrupt\n");
8656 + status = Ser2UTSR0;
8658 + * Deal with any receive errors first. The bytes in error may be
8659 + * the only bytes in the receive FIFO, so we do this first.
8661 + while (status & UTSR0_EIF)
8667 + bstat = Ser2UTSR1;
8669 + if (bstat & UTSR1_FRE)
8670 + printk("frame error\n");
8671 + if (bstat & UTSR1_ROR)
8672 + printk("receive fifo overrun\n");
8673 + if(bstat&UTSR1_PRE)
8674 + printk("parity error\n");
8679 + status = Ser2UTSR0;
8682 + if (status & (UTSR0_RFS | UTSR0_RID))
8684 + do_gettimeofday(&curr_tv);
8685 + deltv = delta(&last_tv, &curr_tv);
8688 +#ifdef DEBUG_SIGNAL
8689 + printk(KERN_DEBUG LIRC_DRIVER_NAME": t %lu , d %d\n",
8690 + deltintrtv,(int)data);
8693 + //printk("data: %d\n",data);
8696 + while(status&UTSR0_RID && /* do not empty fifo in
8697 + order to get UTSR0_RID in
8699 + Ser2UTSR1 & UTSR1_RNE); /* data ready */
8701 + if(status&UTSR0_RID)
8703 + //printk("add\n");
8704 + add_read_queue(0,deltv-n*TIME_CONST); /*space*/
8705 + add_read_queue(1,n*TIME_CONST); /*pulse*/
8711 + if (status & UTSR0_TFS) {
8713 + printk("transmit fifo not full, shouldn't ever happen\n");
8717 + * We must clear certain bits.
8719 + status &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB);
8721 + Ser2UTSR0 = status;
8723 + unsigned long deltintrtv;
8724 + unsigned long flags;
8727 + while ((iir = inb(io + UART_IIR) & UART_IIR_ID)) {
8728 + switch (iir&UART_IIR_ID) { /* FIXME toto treba preriedit */
8729 + case UART_IIR_MSI:
8730 + (void) inb(io + UART_MSR);
8732 + case UART_IIR_RLSI:
8733 + (void) inb(io + UART_LSR);
8735 + case UART_IIR_THRI:
8737 + if (lsr & UART_LSR_THRE) /* FIFO is empty */
8738 + outb(data, io + UART_TX)
8741 + case UART_IIR_RDI:
8742 + /* avoid interference with timer */
8743 + spin_lock_irqsave(&timer_lock, flags);
8746 + del_timer(&timerlist);
8747 + data = inb(io + UART_RX);
8748 + do_gettimeofday(&curr_tv);
8749 + deltv = delta(&last_tv, &curr_tv);
8750 + deltintrtv = delta(&last_intr_tv, &curr_tv);
8751 +#ifdef DEBUG_SIGNAL
8752 + printk(KERN_DEBUG LIRC_DRIVER_NAME": t %lu , d %d\n",deltintrtv,(int)data);
8754 + /* if nothing came in last X cycles,
8756 + if (deltintrtv > TIME_CONST * threshold) {
8758 +#ifdef DEBUG_SIGNAL
8759 + printk(KERN_DEBUG LIRC_DRIVER_NAME ": GAP\n");
8761 + /* simulate signal change */
8762 + add_read_queue(last_value,
8766 + last_tv.tv_sec = last_intr_tv.tv_sec;
8767 + last_tv.tv_usec = last_intr_tv.tv_usec;
8768 + deltv = deltintrtv;
8772 + if (data ^ last_value) {
8773 + /* deltintrtv > 2*TIME_CONST,
8775 + /* the other case is timeout */
8776 + add_read_queue(last_value,
8777 + deltv-TIME_CONST);
8778 + last_value = data;
8779 + last_tv = curr_tv;
8780 + if(last_tv.tv_usec>=TIME_CONST)
8782 + last_tv.tv_usec-=TIME_CONST;
8787 + last_tv.tv_usec+=1000000-
8791 + last_intr_tv = curr_tv;
8794 + /* start timer for end of sequence detection */
8795 + timerlist.expires = jiffies + SIR_TIMEOUT;
8796 + add_timer(&timerlist);
8799 + while ((lsr = inb(io + UART_LSR))
8800 + & UART_LSR_DR); /* data ready */
8801 + spin_unlock_irqrestore(&timer_lock, flags);
8808 + return IRQ_RETVAL(IRQ_HANDLED);
8811 +#ifdef LIRC_ON_SA1100
8812 +void send_pulse(unsigned long length)
8814 + unsigned long k,delay;
8817 + if(length==0) return;
8818 + /* this won't give us the carrier frequency we really want
8819 + due to integer arithmetic, but we can accept this inaccuracy */
8821 + for(k=flag=0;k<length;k+=delay,flag=!flag)
8826 + delay=space_width;
8831 + delay=pulse_width;
8833 + safe_udelay(delay);
8838 +void send_space(unsigned long length)
8840 + if(length==0) return;
8842 + safe_udelay(length);
8844 +#elif defined(LIRC_SIR_TEKRAM)
8846 +static void send_space(unsigned long len)
8851 +static void send_pulse(unsigned long len)
8853 + long bytes_out = len / TIME_CONST;
8858 + time_left = (long)len - (long)bytes_out * (long)TIME_CONST;
8859 + while (--bytes_out) {
8860 + outb(PULSE, io + UART_TX);
8861 + /* FIXME treba seriozne cakanie z drivers/char/serial.c */
8862 + while (!(inb(io + UART_LSR) & UART_LSR_THRE));
8865 + if (time_left > 0)
8866 + safe_udelay(time_left);
8871 +#ifdef CONFIG_SA1100_COLLIE
8872 +static inline int sa1100_irda_set_power_collie(int state)
8877 + * 1 - short range, lowest power
8878 + * 2 - medium range, medium power
8879 + * 3 - maximum range, high power
8881 + ucb1200_set_io_direction(TC35143_GPIO_IR_ON,
8882 + TC35143_IODIR_OUTPUT);
8883 + ucb1200_set_io(TC35143_GPIO_IR_ON, TC35143_IODAT_LOW);
8888 + ucb1200_set_io_direction(TC35143_GPIO_IR_ON,
8889 + TC35143_IODIR_OUTPUT);
8890 + ucb1200_set_io(TC35143_GPIO_IR_ON, TC35143_IODAT_HIGH);
8896 +static int init_hardware(void)
8898 + unsigned long flags;
8900 + spin_lock_irqsave(&hardware_lock, flags);
8902 +#ifdef LIRC_ON_SA1100
8903 +#ifdef CONFIG_SA1100_BITSY
8904 + if (machine_is_bitsy()) {
8905 + printk("Power on IR module\n");
8906 + set_bitsy_egpio(EGPIO_BITSY_IR_ON);
8909 +#ifdef CONFIG_SA1100_COLLIE
8910 + sa1100_irda_set_power_collie(3); /* power on */
8912 + sr.hscr0=Ser2HSCR0;
8914 + sr.utcr0=Ser2UTCR0;
8915 + sr.utcr1=Ser2UTCR1;
8916 + sr.utcr2=Ser2UTCR2;
8917 + sr.utcr3=Ser2UTCR3;
8918 + sr.utcr4=Ser2UTCR4;
8921 + sr.utsr0=Ser2UTSR0;
8922 + sr.utsr1=Ser2UTSR1;
8924 + /* configure GPIO */
8928 + /* set output to 0 */
8932 + * Enable HP-SIR modulation, and ensure that the port is disabled.
8935 + Ser2HSCR0=sr.hscr0 & (~HSCR0_HSSP);
8937 + /* clear status register to prevent unwanted interrupts */
8938 + Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB);
8941 + Ser2UTCR0=UTCR0_1StpBit|UTCR0_7BitData;
8945 + /* use HPSIR, 1.6 usec pulses */
8946 + Ser2UTCR4=UTCR4_HPSIR|UTCR4_Z1_6us;
8948 + /* enable receiver, receive fifo interrupt */
8949 + Ser2UTCR3=UTCR3_RXE|UTCR3_RIE;
8951 + /* clear status register to prevent unwanted interrupts */
8952 + Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB);
8954 +#elif defined(LIRC_SIR_TEKRAM)
8955 + /* disable FIFO */
8957 + UART_FCR_CLEAR_RCVR|
8958 + UART_FCR_CLEAR_XMIT|
8959 + UART_FCR_TRIGGER_1);
8962 + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
8964 + /* First of all, disable all interrupts */
8965 + soutp(UART_IER, sinp(UART_IER)&
8966 + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI)));
8969 + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB);
8971 + /* Set divisor to 12 => 9600 Baud */
8972 + soutp(UART_DLM,0);
8973 + soutp(UART_DLL,12);
8976 + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
8978 + /* power supply */
8979 + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2);
8980 + safe_udelay(50*1000);
8982 + /* -DTR low -> reset PIC */
8983 + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2);
8986 + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2);
8990 + /* -RTS low -> send control byte */
8991 + soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2);
8993 + soutp(UART_TX, TEKRAM_115200|TEKRAM_PW);
8995 + /* one byte takes ~1042 usec to transmit at 9600,8N1 */
8998 + /* back to normal operation */
8999 + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2);
9004 + /* read previous control byte */
9005 + printk(KERN_INFO LIRC_DRIVER_NAME
9006 + ": 0x%02x\n",sinp(UART_RX));
9009 + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB);
9011 + /* Set divisor to 1 => 115200 Baud */
9012 + soutp(UART_DLM,0);
9013 + soutp(UART_DLL,1);
9015 + /* Set DLAB 0, 8 Bit */
9016 + soutp(UART_LCR, UART_LCR_WLEN8);
9017 + /* enable interrupts */
9018 + soutp(UART_IER, sinp(UART_IER)|UART_IER_RDI);
9020 + outb(0, io + UART_MCR);
9021 + outb(0, io + UART_IER);
9023 + /* set DLAB, speed = 115200 */
9024 + outb(UART_LCR_DLAB | UART_LCR_WLEN7, io + UART_LCR);
9025 + outb(1, io + UART_DLL); outb(0, io + UART_DLM);
9026 + /* 7N1+start = 9 bits at 115200 ~ 3 bits at 44000 */
9027 + outb(UART_LCR_WLEN7, io + UART_LCR);
9028 + /* FIFO operation */
9029 + outb(UART_FCR_ENABLE_FIFO, io + UART_FCR);
9031 + // outb(UART_IER_RLSI|UART_IER_RDI|UART_IER_THRI, io + UART_IER);
9032 + outb(UART_IER_RDI, io + UART_IER);
9033 + /* turn on UART */
9034 + outb(UART_MCR_DTR|UART_MCR_RTS|UART_MCR_OUT2, io + UART_MCR);
9035 +#ifdef LIRC_SIR_ACTISYS_ACT200L
9039 + spin_unlock_irqrestore(&hardware_lock, flags);
9043 +static void drop_hardware(void)
9045 + unsigned long flags;
9047 + spin_lock_irqsave(&hardware_lock, flags);
9049 +#ifdef LIRC_ON_SA1100
9052 + Ser2UTCR0=sr.utcr0;
9053 + Ser2UTCR1=sr.utcr1;
9054 + Ser2UTCR2=sr.utcr2;
9055 + Ser2UTCR4=sr.utcr4;
9056 + Ser2UTCR3=sr.utcr3;
9058 + Ser2HSCR0=sr.hscr0;
9059 +#ifdef CONFIG_SA1100_BITSY
9060 + if (machine_is_bitsy()) {
9061 + clr_bitsy_egpio(EGPIO_BITSY_IR_ON);
9064 +#ifdef CONFIG_SA1100_COLLIE
9065 + sa1100_irda_set_power_collie(0); /* power off */
9068 + /* turn off interrupts */
9069 + outb(0, io + UART_IER);
9071 + spin_unlock_irqrestore(&hardware_lock, flags);
9074 +/* SECTION: Initialisation */
9076 +static int init_port(void)
9080 +#ifndef LIRC_ON_SA1100
9081 + /* get I/O port access and IRQ line */
9082 + retval = check_region(io, 8);
9084 + printk(KERN_ERR LIRC_DRIVER_NAME
9085 + ": i/o port 0x%.4x already in use.\n",
9090 + retval = request_irq(irq, sir_interrupt, SA_INTERRUPT,
9091 + LIRC_DRIVER_NAME, NULL);
9093 + printk(KERN_ERR LIRC_DRIVER_NAME
9094 + ": IRQ %d already in use.\n",
9098 +#ifndef LIRC_ON_SA1100
9099 + request_region(io, 8, LIRC_DRIVER_NAME);
9100 + printk(KERN_INFO LIRC_DRIVER_NAME
9101 + ": I/O port 0x%.4x, IRQ %d.\n",
9105 + init_timer(&timerlist);
9106 + timerlist.function = sir_timeout;
9107 + timerlist.data = 0xabadcafe;
9112 +static void drop_port(void)
9115 + free_irq(irq, NULL);
9116 + del_timer_sync(&timerlist);
9117 +#ifndef LIRC_ON_SA1100
9118 + release_region(io, 8);
9122 +#ifdef LIRC_SIR_ACTISYS_ACT200L
9123 +/******************************************************/
9124 +/* Crystal/Cirrus CS8130 IR transceiver, used in Actisys Act200L dongle */
9125 +/* some code borrowed from Linux IRDA driver */
9127 +/* Regsiter 0: Control register #1 */
9128 +#define ACT200L_REG0 0x00
9129 +#define ACT200L_TXEN 0x01 /* Enable transmitter */
9130 +#define ACT200L_RXEN 0x02 /* Enable receiver */
9131 +#define ACT200L_ECHO 0x08 /* Echo control chars */
9133 +/* Register 1: Control register #2 */
9134 +#define ACT200L_REG1 0x10
9135 +#define ACT200L_LODB 0x01 /* Load new baud rate count value */
9136 +#define ACT200L_WIDE 0x04 /* Expand the maximum allowable pulse */
9138 +/* Register 3: Transmit mode register #2 */
9139 +#define ACT200L_REG3 0x30
9140 +#define ACT200L_B0 0x01 /* DataBits, 0=6, 1=7, 2=8, 3=9(8P) */
9141 +#define ACT200L_B1 0x02 /* DataBits, 0=6, 1=7, 2=8, 3=9(8P) */
9142 +#define ACT200L_CHSY 0x04 /* StartBit Synced 0=bittime, 1=startbit */
9144 +/* Register 4: Output Power register */
9145 +#define ACT200L_REG4 0x40
9146 +#define ACT200L_OP0 0x01 /* Enable LED1C output */
9147 +#define ACT200L_OP1 0x02 /* Enable LED2C output */
9148 +#define ACT200L_BLKR 0x04
9150 +/* Register 5: Receive Mode register */
9151 +#define ACT200L_REG5 0x50
9152 +#define ACT200L_RWIDL 0x01 /* fixed 1.6us pulse mode */
9153 + /*.. other various IRDA bit modes, and TV remote modes..*/
9155 +/* Register 6: Receive Sensitivity register #1 */
9156 +#define ACT200L_REG6 0x60
9157 +#define ACT200L_RS0 0x01 /* receive threshold bit 0 */
9158 +#define ACT200L_RS1 0x02 /* receive threshold bit 1 */
9160 +/* Register 7: Receive Sensitivity register #2 */
9161 +#define ACT200L_REG7 0x70
9162 +#define ACT200L_ENPOS 0x04 /* Ignore the falling edge */
9164 +/* Register 8,9: Baud Rate Dvider register #1,#2 */
9165 +#define ACT200L_REG8 0x80
9166 +#define ACT200L_REG9 0x90
9168 +#define ACT200L_2400 0x5f
9169 +#define ACT200L_9600 0x17
9170 +#define ACT200L_19200 0x0b
9171 +#define ACT200L_38400 0x05
9172 +#define ACT200L_57600 0x03
9173 +#define ACT200L_115200 0x01
9175 +/* Register 13: Control register #3 */
9176 +#define ACT200L_REG13 0xd0
9177 +#define ACT200L_SHDW 0x01 /* Enable access to shadow registers */
9179 +/* Register 15: Status register */
9180 +#define ACT200L_REG15 0xf0
9182 +/* Register 21: Control register #4 */
9183 +#define ACT200L_REG21 0x50
9184 +#define ACT200L_EXCK 0x02 /* Disable clock output driver */
9185 +#define ACT200L_OSCL 0x04 /* oscillator in low power, medium accuracy mode */
9187 +static void init_act200(void)
9190 + __u8 control[] = {
9192 + ACT200L_REG13 | ACT200L_SHDW,
9193 + ACT200L_REG21 | ACT200L_EXCK | ACT200L_OSCL,
9195 + ACT200L_REG7 | ACT200L_ENPOS,
9196 + ACT200L_REG6 | ACT200L_RS0 | ACT200L_RS1,
9197 + ACT200L_REG5 | ACT200L_RWIDL,
9198 + ACT200L_REG4 | ACT200L_OP0 | ACT200L_OP1 | ACT200L_BLKR,
9199 + ACT200L_REG3 | ACT200L_B0,
9200 + ACT200L_REG0 | ACT200L_TXEN | ACT200L_RXEN,
9201 + ACT200L_REG8 | (ACT200L_115200 & 0x0f),
9202 + ACT200L_REG9 | ((ACT200L_115200 >> 4) & 0x0f),
9203 + ACT200L_REG1 | ACT200L_LODB | ACT200L_WIDE
9207 + soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN8);
9209 + /* Set divisor to 12 => 9600 Baud */
9210 + soutp(UART_DLM,0);
9211 + soutp(UART_DLL,12);
9214 + soutp(UART_LCR, UART_LCR_WLEN8);
9215 + /* Set divisor to 12 => 9600 Baud */
9217 + /* power supply */
9218 + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2);
9219 + for (i=0; i<50; i++) {
9220 + safe_udelay(1000);
9223 + /* Reset the dongle : set RTS low for 25 ms */
9224 + soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2);
9225 + for (i=0; i<25; i++) {
9229 + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2);
9232 + /* Clear DTR and set RTS to enter command mode */
9233 + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2);
9236 +/* send out the control register settings for 115K 7N1 SIR operation */
9237 + for (i=0; i<sizeof(control); i++) {
9238 + soutp(UART_TX, control[i]);
9239 + /* one byte takes ~1042 usec to transmit at 9600,8N1 */
9243 + /* back to normal operation */
9244 + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2);
9248 + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB);
9251 + soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN7);
9253 + /* Set divisor to 1 => 115200 Baud */
9254 + soutp(UART_DLM,0);
9255 + soutp(UART_DLL,1);
9258 + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB));
9260 + /* Set DLAB 0, 7 Bit */
9261 + soutp(UART_LCR, UART_LCR_WLEN7);
9263 + /* enable interrupts */
9264 + soutp(UART_IER, sinp(UART_IER)|UART_IER_RDI);
9268 +int init_lirc_sir(void)
9272 + init_waitqueue_head(&lirc_read_queue);
9273 + retval = init_port();
9278 + printk(KERN_INFO LIRC_DRIVER_NAME
9279 + ": Installed.\n");
9285 +#ifdef LIRC_SIR_TEKRAM
9286 +MODULE_AUTHOR("Christoph Bartelmus");
9287 +MODULE_DESCRIPTION("Infrared receiver driver for Tekram Irmate 210");
9288 +#elif defined(LIRC_ON_SA1100)
9289 +MODULE_AUTHOR("Christoph Bartelmus");
9290 +MODULE_DESCRIPTION("LIRC driver for StrongARM SA1100 embedded microprocessor");
9291 +#elif defined(LIRC_SIR_ACTISYS_ACT200L)
9292 +MODULE_AUTHOR("Karl Bongers");
9293 +MODULE_DESCRIPTION("LIRC driver for Actisys Act200L");
9295 +MODULE_AUTHOR("Milan Pikula");
9296 +MODULE_DESCRIPTION("Infrared receiver driver for SIR type serial ports");
9299 +#ifdef LIRC_ON_SA1100
9300 +MODULE_PARM(irq, "i");
9301 +MODULE_PARM_DESC(irq, "Interrupt (16)");
9303 +MODULE_PARM(io, "i");
9304 +MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)");
9305 +MODULE_PARM(irq, "i");
9306 +MODULE_PARM_DESC(irq, "Interrupt (4 or 3)");
9307 +MODULE_PARM(threshold, "i");
9308 +MODULE_PARM_DESC(threshold, "space detection threshold (3)");
9311 +#ifdef MODULE_LICENSE
9312 +MODULE_LICENSE("GPL");
9319 +int init_module(void)
9323 + retval=init_chrdev();
9326 + retval = init_lirc_sir();
9334 +void cleanup_module(void)
9339 + printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n");
9342 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/Makefile linux-2.6.8-rc4/drivers/char/lirc/Makefile
9343 --- linux-2.6.8-rc4.orig/drivers/char/lirc/Makefile 1970-01-01 01:00:00.000000000 +0100
9344 +++ linux-2.6.8-rc4/drivers/char/lirc/Makefile 2004-08-10 10:22:06.189171224 +0200
9346 +obj-$(CONFIG_LIRC_SUPPORT) += lirc_dev.o
9347 +obj-$(CONFIG_LIRC_GPIO) += lirc_gpio.o
9348 +obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
9349 +obj-$(CONFIG_LIRC_IT87) += lirc_it87.o
9350 +obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
9351 +obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
9352 +obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
9353 +obj-$(CONFIG_LIRC_SIR) += lirc_sir.o
9354 +obj-$(CONFIG_LIRC_ATIUSB) += lirc_atiusb.o
9355 +obj-$(CONFIG_LIRC_MCEUSB) += lirc_mceusb.o
9356 +obj-$(CONFIG_LIRC_I2C) += lirc_i2c.o
9357 diff -uNr linux-2.6.8-rc4.orig/drivers/char/Makefile linux-2.6.8-rc4/drivers/char/Makefile
9358 --- linux-2.6.8-rc4.orig/drivers/char/Makefile 2004-08-10 09:33:45.000000000 +0200
9359 +++ linux-2.6.8-rc4/drivers/char/Makefile 2004-08-10 10:23:05.725120384 +0200
9362 FONTMAPFILE = cp437.uni
9364 -obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o
9365 +obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o lirc/
9367 obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o consolemap.o \
9368 consolemap_deftbl.o selection.o keyboard.o
9369 diff -uNr linux-2.6.8-rc4.orig/include/linux/lirc.h linux-2.6.8-rc4/include/linux/lirc.h
9370 --- linux-2.6.8-rc4.orig/include/linux/lirc.h 1970-01-01 01:00:00.000000000 +0100
9371 +++ linux-2.6.8-rc4/include/linux/lirc.h 2003-01-26 13:57:59.000000000 +0100
9375 +#ifndef _LINUX_LIRC_H
9376 +#define _LINUX_LIRC_H
9378 +#if defined (__linux__)
9379 +#include <asm/types.h>
9380 +#include <linux/ioctl.h>
9382 +#include <sys/types.h>
9383 +typedef u_int32_t __u32;
9386 +#define PULSE_BIT 0x01000000
9387 +#define PULSE_MASK 0x00FFFFFF
9389 +typedef int lirc_t;
9392 + * lirc compatible hardware features
9396 +#define LIRC_MODE2SEND(x) (x)
9397 +#define LIRC_SEND2MODE(x) (x)
9398 +#define LIRC_MODE2REC(x) ((x) << 16)
9399 +#define LIRC_REC2MODE(x) ((x) >> 16)
9401 +#define LIRC_MODE_RAW 0x00000001
9402 +#define LIRC_MODE_PULSE 0x00000002
9403 +#define LIRC_MODE_MODE2 0x00000004
9404 +#define LIRC_MODE_CODE 0x00000008
9405 +#define LIRC_MODE_LIRCCODE 0x00000010
9406 +#define LIRC_MODE_STRING 0x00000020
9409 +#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW)
9410 +#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE)
9411 +#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2)
9412 +#define LIRC_CAN_SEND_CODE LIRC_MODE2SEND(LIRC_MODE_CODE)
9413 +#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE)
9414 +#define LIRC_CAN_SEND_STRING LIRC_MODE2SEND(LIRC_MODE_STRING)
9416 +#define LIRC_CAN_SEND_MASK 0x0000003f
9418 +#define LIRC_CAN_SET_SEND_CARRIER 0x00000100
9419 +#define LIRC_CAN_SET_SEND_DUTY_CYCLE 0x00000200
9421 +#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW)
9422 +#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE)
9423 +#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2)
9424 +#define LIRC_CAN_REC_CODE LIRC_MODE2REC(LIRC_MODE_CODE)
9425 +#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE)
9426 +#define LIRC_CAN_REC_STRING LIRC_MODE2REC(LIRC_MODE_STRING)
9428 +#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK)
9430 +#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16)
9431 +#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16)
9433 +#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000
9434 +#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000
9437 +#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK)
9438 +#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK)
9441 + * IOCTL commands for lirc driver
9444 +#define LIRC_GET_FEATURES _IOR('i', 0x00000000, __u32)
9446 +#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, __u32)
9447 +#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, __u32)
9448 +#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, __u32)
9449 +#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, __u32)
9450 +#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, __u32)
9451 +#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, __u32)
9453 +/* code length in bits, currently only for LIRC_MODE_LIRCCODE */
9454 +#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, __u32)
9456 +#define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, __u32)
9457 +#define LIRC_SET_REC_MODE _IOW('i', 0x00000012, __u32)
9458 +/* Note: these can reset the according pulse_width */
9459 +#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, __u32)
9460 +#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, __u32)
9461 +#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, __u32)
9462 +#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, __u32)
9464 +/* to set a range use
9465 + LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the
9466 + lower bound first and later
9467 + LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound */
9469 +#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, __u32)
9470 +#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, __u32)
9473 diff -uNr linux-2.6.8-rc4.orig/drivers/char/lirc/kcompat.h linux-2.6.8-rc4/drivers/char/lirc/kcompat.h
9474 --- linux-2.6.8-rc4.orig/drivers/char/lirc/kcompat.h 1970-01-01 01:00:00.000000000 +0100
9475 +++ linux-2.6.8-rc4/drivers/char/lirc/kcompat.h 2004-04-27 20:52:33.000000000 +0200
9479 +#include <linux/version.h>
9480 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
9481 +#include <linux/timer.h>
9482 +#include <linux/interrupt.h>
9483 +static inline void del_timer_sync(struct timer_list * timerlist)
9485 + start_bh_atomic();
9486 + del_timer(timerlist);
9491 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
9493 +#define daemonize(name) do { \
9497 + exit_mm(current); \
9498 + exit_files(current); \
9499 + exit_fs(current); \
9500 + current->session = 1; \
9501 + current->pgrp = 1; \
9502 + current->euid = 0; \
9503 + current->tty = NULL; \
9504 + sigfillset(¤t->blocked); \
9506 + strcpy(current->comm, name); \
9508 + unlock_kernel(); \
9514 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
9517 +#undef MOD_INC_USE_COUNT
9518 +#define MOD_INC_USE_COUNT try_module_get(THIS_MODULE)
9519 +#undef MOD_DEC_USE_COUNT
9520 +#define MOD_DEC_USE_COUNT module_put(THIS_MODULE)
9525 +typedef void irqreturn_t;
9527 +#define IRQ_HANDLED
9528 +#define IRQ_RETVAL(x)
9532 +#ifdef CONFIG_MODULE_UNLOAD
9533 +#define MOD_IN_USE module_refcount(THIS_MODULE)
9535 +#error "LIRC modules currently require"
9536 +#error " 'Loadable module support ---> Module unloading'"
9537 +#error "to be enabled in the kernel"
9541 +#if !defined(local_irq_save)
9542 +#define local_irq_save(flags) do{ save_flags(flags);cli(); } while(0)
9544 +#if !defined(local_irq_restore)
9545 +#define local_irq_restore(flags) do{ restore_flags(flags); } while(0)
9548 +#if !defined(pci_pretty_name)
9549 +#define pci_pretty_name(dev) ((dev)->name)