lkml.org 
[lkml]   [2008]   [Sep]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 17/18] lirc driver for homebrew parallel port receivers
    Date
    Signed-off-by: Jarod Wilson <jarod@redhat.com>
    Signed-off-by: Janne Grunau <j@jannau.net>
    CC: Christoph Bartelmus <lirc@bartelmus.de>
    ---
    drivers/input/lirc/Kconfig | 7 +
    drivers/input/lirc/Makefile | 1 +
    drivers/input/lirc/lirc_parallel.c | 728 ++++++++++++++++++++++++++++++++++++
    drivers/input/lirc/lirc_parallel.h | 26 ++
    4 files changed, 762 insertions(+), 0 deletions(-)
    create mode 100644 drivers/input/lirc/lirc_parallel.c
    create mode 100644 drivers/input/lirc/lirc_parallel.h
    diff --git a/drivers/input/lirc/Kconfig b/drivers/input/lirc/Kconfig
    index 2af6278..fb8ba38 100644
    --- a/drivers/input/lirc/Kconfig
    +++ b/drivers/input/lirc/Kconfig
    @@ -89,6 +89,13 @@ config LIRC_MCEUSB2
    help
    Driver for the Microsoft Media Center Ed. Receiver, v2

    +config LIRC_PARALLEL
    + tristate "Homebrew Parallel Port Receiver"
    + default n
    + depends on LIRC_DEV && !SMP
    + help
    + Driver for Homebrew Parallel Port Receivers
    +
    config LIRC_SASEM
    tristate "Sasem USB IR Remote"
    default n
    diff --git a/drivers/input/lirc/Makefile b/drivers/input/lirc/Makefile
    index c5f71fa..3a1469c 100644
    --- a/drivers/input/lirc/Makefile
    +++ b/drivers/input/lirc/Makefile
    @@ -16,6 +16,7 @@ obj-$(CONFIG_LIRC_IT87) += lirc_it87.o
    obj-$(CONFIG_LIRC_ITE8709) += lirc_ite8709.o
    obj-$(CONFIG_LIRC_MCEUSB) += lirc_mceusb.o
    obj-$(CONFIG_LIRC_MCEUSB2) += lirc_mceusb2.o
    +obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
    obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
    obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
    obj-$(CONFIG_LIRC_SIR) += lirc_sir.o
    diff --git a/drivers/input/lirc/lirc_parallel.c b/drivers/input/lirc/lirc_parallel.c
    new file mode 100644
    index 0000000..912cad2
    --- /dev/null
    +++ b/drivers/input/lirc/lirc_parallel.c
    @@ -0,0 +1,728 @@
    +/****************************************************************************
    + ** lirc_parallel.c *********************************************************
    + ****************************************************************************
    + *
    + * lirc_parallel - device driver for infra-red signal receiving and
    + * transmitting unit built by the author
    + *
    + * Copyright (C) 1998 Christoph Bartelmus <lirc@bartelmus.de>
    + *
    + * This program is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License as published by
    + * the Free Software Foundation; either version 2 of the License, or
    + * (at your option) any later version.
    + *
    + * This program is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    + * GNU General Public License for more details.
    + *
    + * You should have received a copy of the GNU General Public License
    + * along with this program; if not, write to the Free Software
    + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    + *
    + */
    +
    +/***********************************************************************
    + ************************* Includes ***********************
    + ***********************************************************************/
    +
    +#include <linux/version.h>
    +
    +#include <linux/autoconf.h>
    +
    +#ifdef CONFIG_SMP
    +#error "--- Sorry, this driver is not SMP safe. ---"
    +#endif
    +
    +#include <linux/module.h>
    +#include <linux/sched.h>
    +#include <linux/errno.h>
    +#include <linux/signal.h>
    +#include <linux/autoconf.h>
    +#include <linux/fs.h>
    +#include <linux/kernel.h>
    +#include <linux/ioport.h>
    +#include <linux/time.h>
    +#include <linux/mm.h>
    +#include <linux/delay.h>
    +
    +#include <linux/io.h>
    +#include <linux/signal.h>
    +#include <linux/irq.h>
    +#include <linux/uaccess.h>
    +#include <asm/div64.h>
    +
    +#include <linux/poll.h>
    +#include <linux/parport.h>
    +
    +#include "lirc.h"
    +#include "lirc_dev.h"
    +
    +#include "lirc_parallel.h"
    +
    +#define LIRC_DRIVER_NAME "lirc_parallel"
    +
    +#ifndef LIRC_IRQ
    +#define LIRC_IRQ 7
    +#endif
    +#ifndef LIRC_PORT
    +#define LIRC_PORT 0x378
    +#endif
    +#ifndef LIRC_TIMER
    +#define LIRC_TIMER 65536
    +#endif
    +
    +/***********************************************************************
    + ************************* Globale Variablen ***********************
    + ***********************************************************************/
    +
    +static int debug;
    +static int check_pselecd;
    +
    +unsigned int irq = LIRC_IRQ;
    +unsigned int io = LIRC_PORT;
    +#ifdef LIRC_TIMER
    +unsigned int timer;
    +unsigned int default_timer = LIRC_TIMER;
    +#endif
    +
    +#define WBUF_SIZE (256)
    +#define RBUF_SIZE (256) /* this must be a power of 2 larger than 1 */
    +
    +static int wbuf[WBUF_SIZE];
    +static int rbuf[RBUF_SIZE];
    +
    +DECLARE_WAIT_QUEUE_HEAD(lirc_wait);
    +
    +unsigned int rptr;
    +unsigned int wptr;
    +unsigned int lost_irqs;
    +int is_open;
    +
    +struct parport *pport;
    +struct pardevice *ppdevice;
    +int is_claimed;
    +
    +unsigned int tx_mask = 1;
    +
    +/***********************************************************************
    + ************************* Interne Funktionen ***********************
    + ***********************************************************************/
    +
    +static inline unsigned int in(int offset)
    +{
    + switch (offset) {
    + case LIRC_LP_BASE:
    + return parport_read_data(pport);
    + case LIRC_LP_STATUS:
    + return parport_read_status(pport);
    + case LIRC_LP_CONTROL:
    + return parport_read_control(pport);
    + }
    + return 0; /* make compiler happy */
    +}
    +
    +static inline void out(int offset, int value)
    +{
    + switch (offset) {
    + case LIRC_LP_BASE:
    + parport_write_data(pport, value);
    + break;
    + case LIRC_LP_CONTROL:
    + parport_write_control(pport, value);
    + break;
    + case LIRC_LP_STATUS:
    + printk(KERN_INFO "%s: attempt to write to status register\n",
    + LIRC_DRIVER_NAME);
    + break;
    + }
    +}
    +
    +static inline unsigned int lirc_get_timer(void)
    +{
    + return in(LIRC_PORT_TIMER) & LIRC_PORT_TIMER_BIT;
    +}
    +
    +static inline unsigned int lirc_get_signal(void)
    +{
    + return in(LIRC_PORT_SIGNAL) & LIRC_PORT_SIGNAL_BIT;
    +}
    +
    +static inline void lirc_on(void)
    +{
    + out(LIRC_PORT_DATA, tx_mask);
    +}
    +
    +static inline void lirc_off(void)
    +{
    + out(LIRC_PORT_DATA, 0);
    +}
    +
    +static unsigned int init_lirc_timer(void)
    +{
    + struct timeval tv, now;
    + unsigned int level, newlevel, timeelapsed, newtimer;
    + int count = 0;
    +
    + do_gettimeofday(&tv);
    + tv.tv_sec++; /* wait max. 1 sec. */
    + level = lirc_get_timer();
    + do {
    + newlevel = lirc_get_timer();
    + if (level == 0 && newlevel != 0)
    + count++;
    + level = newlevel;
    + do_gettimeofday(&now);
    + } while (count < 1000 && (now.tv_sec < tv.tv_sec
    + || (now.tv_sec == tv.tv_sec
    + && now.tv_usec < tv.tv_usec)));
    +
    + timeelapsed = ((now.tv_sec + 1 - tv.tv_sec)*1000000
    + + (now.tv_usec - tv.tv_usec));
    + if (count >= 1000 && timeelapsed > 0) {
    + if (default_timer == 0) {
    + /* autodetect timer */
    + newtimer = (1000000*count)/timeelapsed;
    + printk(KERN_INFO "%s: %u Hz timer detected\n",
    + LIRC_DRIVER_NAME, newtimer);
    + return newtimer;
    + } else {
    + newtimer = (1000000*count)/timeelapsed;
    + if (abs(newtimer - default_timer) > default_timer/10) {
    + /* bad timer */
    + printk(KERN_NOTICE "%s: bad timer: %u Hz\n",
    + LIRC_DRIVER_NAME, newtimer);
    + printk(KERN_NOTICE "%s: using default timer: "
    + "%u Hz\n",
    + LIRC_DRIVER_NAME, default_timer);
    + return default_timer;
    + } else {
    + printk(KERN_INFO "%s: %u Hz timer detected\n",
    + LIRC_DRIVER_NAME, newtimer);
    + return newtimer; /* use detected value */
    + }
    + }
    + } else {
    + printk(KERN_NOTICE "%s: no timer detected\n", LIRC_DRIVER_NAME);
    + return 0;
    + }
    +}
    +
    +static int lirc_claim(void)
    +{
    + if (parport_claim(ppdevice) != 0) {
    + printk(KERN_WARNING "%s: could not claim port\n",
    + LIRC_DRIVER_NAME);
    + printk(KERN_WARNING "%s: waiting for port becoming available"
    + "\n", LIRC_DRIVER_NAME);
    + if (parport_claim_or_block(ppdevice) < 0) {
    + printk(KERN_NOTICE "%s: could not claim port, giving"
    + " up\n", LIRC_DRIVER_NAME);
    + return 0;
    + }
    + }
    + out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP);
    + is_claimed = 1;
    + return 1;
    +}
    +
    +/***********************************************************************
    + ************************* interrupt handler ************************
    + ***********************************************************************/
    +
    +static inline void rbuf_write(int signal)
    +{
    + unsigned int nwptr;
    +
    + nwptr = (wptr + 1) & (RBUF_SIZE - 1);
    + if (nwptr == rptr) {
    + /* no new signals will be accepted */
    + lost_irqs++;
    + printk(KERN_NOTICE "%s: buffer overrun\n", LIRC_DRIVER_NAME);
    + return;
    + }
    + rbuf[wptr] = signal;
    + wptr = nwptr;
    +}
    +
    +static void irq_handler(void *blah)
    +{
    + struct timeval tv;
    + static struct timeval lasttv;
    + static int init;
    + long signal;
    + int data;
    + unsigned int level, newlevel;
    + unsigned int timeout;
    +
    + if (!module_refcount(THIS_MODULE))
    + return;
    +
    + if (!is_claimed)
    + return;
    +
    + /* disable interrupt */
    + /*
    + disable_irq(irq);
    + out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ) & (~LP_PINTEN));
    + */
    + if (check_pselecd && (in(1) & LP_PSELECD))
    + return;
    +
    +#ifdef LIRC_TIMER
    + if (init) {
    + do_gettimeofday(&tv);
    +
    + signal = tv.tv_sec - lasttv.tv_sec;
    + if (signal > 15)
    + /* really long time */
    + data = PULSE_MASK;
    + else
    + data = (int) (signal*1000000 +
    + tv.tv_usec - lasttv.tv_usec +
    + LIRC_SFH506_DELAY);
    +
    + rbuf_write(data); /* space */
    + } else {
    + if (timer == 0) {
    + /* wake up; we'll lose this signal
    + * but it will be garbage if the device
    + * is turned on anyway */
    + timer = init_lirc_timer();
    + /* enable_irq(irq); */
    + return;
    + }
    + init = 1;
    + }
    +
    + timeout = timer/10; /* timeout after 1/10 sec. */
    + signal = 1;
    + level = lirc_get_timer();
    + do {
    + newlevel = lirc_get_timer();
    + if (level == 0 && newlevel != 0)
    + signal++;
    + level = newlevel;
    +
    + /* giving up */
    + if (signal > timeout
    + || (check_pselecd && (in(1) & LP_PSELECD))) {
    + signal = 0;
    + printk(KERN_NOTICE "%s: timeout\n", LIRC_DRIVER_NAME);
    + break;
    + }
    + } while (lirc_get_signal());
    +
    + if (signal != 0) {
    + /* ajust value to usecs */
    + unsigned long long helper;
    +
    + helper = ((unsigned long long) signal)*1000000;
    + do_div(helper, timer);
    + signal = (long) helper;
    +
    + if (signal > LIRC_SFH506_DELAY)
    + data = signal - LIRC_SFH506_DELAY;
    + else
    + data = 1;
    + rbuf_write(PULSE_BIT|data); /* pulse */
    + }
    + do_gettimeofday(&lasttv);
    +#else
    + /* add your code here */
    +#endif
    +
    + wake_up_interruptible(&lirc_wait);
    +
    + /* enable interrupt */
    + /*
    + enable_irq(irq);
    + out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ)|LP_PINTEN);
    + */
    +}
    +
    +/***********************************************************************
    + ************************** file_operations ************************
    + ***********************************************************************/
    +
    +static loff_t lirc_lseek(struct file *filep, loff_t offset, int orig)
    +{
    + return -ESPIPE;
    +}
    +
    +static ssize_t lirc_read(struct file *filep, char *buf, size_t n, loff_t *ppos)
    +{
    + int result = 0;
    + int count = 0;
    + DECLARE_WAITQUEUE(wait, current);
    +
    + if (n % sizeof(int))
    + return -EINVAL;
    +
    + add_wait_queue(&lirc_wait, &wait);
    + set_current_state(TASK_INTERRUPTIBLE);
    + while (count < n) {
    + if (rptr != wptr) {
    + if (copy_to_user(buf+count, (char *) &rbuf[rptr],
    + sizeof(int))) {
    + result = -EFAULT;
    + break;
    + }
    + rptr = (rptr + 1) & (RBUF_SIZE - 1);
    + count += sizeof(int);
    + } else {
    + if (filep->f_flags & O_NONBLOCK) {
    + result = -EAGAIN;
    + break;
    + }
    + if (signal_pending(current)) {
    + result = -ERESTARTSYS;
    + break;
    + }
    + schedule();
    + set_current_state(TASK_INTERRUPTIBLE);
    + }
    + }
    + remove_wait_queue(&lirc_wait, &wait);
    + set_current_state(TASK_RUNNING);
    + return count ? count : result;
    +}
    +
    +static ssize_t lirc_write(struct file *filep, const char *buf, size_t n,
    + loff_t *ppos)
    +{
    + int count;
    + unsigned int i;
    + unsigned int level, newlevel;
    + unsigned long flags;
    + int counttimer;
    +
    + if (!is_claimed)
    + return -EBUSY;
    +
    + if (n % sizeof(int))
    + return -EINVAL;
    +
    + count = n / sizeof(int);
    +
    + if (count > WBUF_SIZE || count % 2 == 0)
    + return -EINVAL;
    +
    + if (copy_from_user(wbuf, buf, n))
    + return -EFAULT;
    +
    +#ifdef LIRC_TIMER
    + if (timer == 0) {
    + /* try again if device is ready */
    + timer = init_lirc_timer();
    + if (timer == 0)
    + return -EIO;
    + }
    +
    + /* ajust values from usecs */
    + for (i = 0; i < count; i++) {
    + unsigned long long helper;
    +
    + helper = ((unsigned long long) wbuf[i])*timer;
    + do_div(helper, 1000000);
    + wbuf[i] = (int) helper;
    + }
    +
    + local_irq_save(flags);
    + i = 0;
    + while (i < count) {
    + level = lirc_get_timer();
    + counttimer = 0;
    + lirc_on();
    + do {
    + newlevel = lirc_get_timer();
    + if (level == 0 && newlevel != 0)
    + counttimer++;
    + level = newlevel;
    + if (check_pselecd && (in(1) & LP_PSELECD)) {
    + lirc_off();
    + local_irq_restore(flags);
    + return -EIO;
    + }
    + } while (counttimer < wbuf[i]);
    + i++;
    +
    + lirc_off();
    + if (i == count)
    + break;
    + counttimer = 0;
    + do {
    + newlevel = lirc_get_timer();
    + if (level == 0 && newlevel != 0)
    + counttimer++;
    + level = newlevel;
    + if (check_pselecd && (in(1) & LP_PSELECD)) {
    + local_irq_restore(flags);
    + return -EIO;
    + }
    + } while (counttimer < wbuf[i]);
    + i++;
    + }
    + local_irq_restore(flags);
    +#else
    + /* place code that handles write
    + * without external timer here */
    +#endif
    + return n;
    +}
    +
    +static unsigned int lirc_poll(struct file *file, poll_table *wait)
    +{
    + poll_wait(file, &lirc_wait, wait);
    + if (rptr != wptr)
    + return POLLIN | POLLRDNORM;
    + return 0;
    +}
    +
    +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd,
    + unsigned long arg)
    +{
    + int result;
    + unsigned long features = LIRC_CAN_SET_TRANSMITTER_MASK |
    + LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2;
    + unsigned long mode;
    + unsigned int ivalue;
    +
    + switch (cmd) {
    + case LIRC_GET_FEATURES:
    + result = put_user(features, (unsigned long *) arg);
    + if (result)
    + return result;
    + break;
    + case LIRC_GET_SEND_MODE:
    + result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg);
    + if (result)
    + return result;
    + break;
    + case LIRC_GET_REC_MODE:
    + result = put_user(LIRC_MODE_MODE2, (unsigned long *) arg);
    + if (result)
    + return result;
    + break;
    + case LIRC_SET_SEND_MODE:
    + result = get_user(mode, (unsigned long *) arg);
    + if (result)
    + return result;
    + if (mode != LIRC_MODE_PULSE)
    + return -EINVAL;
    + break;
    + case LIRC_SET_REC_MODE:
    + result = get_user(mode, (unsigned long *) arg);
    + if (result)
    + return result;
    + if (mode != LIRC_MODE_MODE2)
    + return -ENOSYS;
    + break;
    + case LIRC_SET_TRANSMITTER_MASK:
    + result = get_user(ivalue, (unsigned int *) arg);
    + if (result)
    + return result;
    + if ((ivalue & LIRC_PARALLEL_TRANSMITTER_MASK) != ivalue)
    + return LIRC_PARALLEL_MAX_TRANSMITTERS;
    + tx_mask = ivalue;
    + break;
    + default:
    + return -ENOIOCTLCMD;
    + }
    + return 0;
    +}
    +
    +static int lirc_open(struct inode *node, struct file *filep)
    +{
    + if (module_refcount(THIS_MODULE) || !lirc_claim())
    + return -EBUSY;
    +
    + parport_enable_irq(pport);
    +
    + /* init read ptr */
    + rptr = 0;
    + wptr = 0;
    + lost_irqs = 0;
    +
    + is_open = 1;
    + return 0;
    +}
    +
    +static int lirc_close(struct inode *node, struct file *filep)
    +{
    + if (is_claimed) {
    + is_claimed = 0;
    + parport_release(ppdevice);
    + }
    + is_open = 0;
    + return 0;
    +}
    +
    +static struct file_operations lirc_fops = {
    + .llseek = lirc_lseek,
    + .read = lirc_read,
    + .write = lirc_write,
    + .poll = lirc_poll,
    + .ioctl = lirc_ioctl,
    + .open = lirc_open,
    + .release = lirc_close
    +};
    +
    +static int set_use_inc(void *data)
    +{
    + return 0;
    +}
    +
    +static void set_use_dec(void *data)
    +{
    +}
    +
    +static struct lirc_plugin plugin = {
    + .name = LIRC_DRIVER_NAME,
    + .minor = -1,
    + .code_length = 1,
    + .sample_rate = 0,
    + .data = NULL,
    + .add_to_buf = NULL,
    + .get_queue = NULL,
    + .set_use_inc = set_use_inc,
    + .set_use_dec = set_use_dec,
    + .fops = &lirc_fops,
    + .dev = NULL,
    + .owner = THIS_MODULE,
    +};
    +
    +#ifdef MODULE
    +
    +static int pf(void *handle);
    +static void kf(void *handle);
    +
    +static struct timer_list poll_timer;
    +static void poll_state(unsigned long ignored);
    +
    +static void poll_state(unsigned long ignored)
    +{
    + printk(KERN_NOTICE "%s: time\n",
    + LIRC_DRIVER_NAME);
    + del_timer(&poll_timer);
    + if (is_claimed)
    + return;
    + kf(NULL);
    + if (!is_claimed) {
    + printk(KERN_NOTICE "%s: could not claim port, giving up\n",
    + LIRC_DRIVER_NAME);
    + init_timer(&poll_timer);
    + poll_timer.expires = jiffies + HZ;
    + poll_timer.data = (unsigned long)current;
    + poll_timer.function = poll_state;
    + add_timer(&poll_timer);
    + }
    +}
    +
    +static int pf(void *handle)
    +{
    + parport_disable_irq(pport);
    + is_claimed = 0;
    + return 0;
    +}
    +
    +static void kf(void *handle)
    +{
    + if (!is_open)
    + return;
    + if (!lirc_claim())
    + return;
    + parport_enable_irq(pport);
    + lirc_off();
    + /* this is a bit annoying when you actually print...*/
    + /*
    + printk(KERN_INFO "%s: reclaimed port\n", LIRC_DRIVER_NAME);
    + */
    +}
    +
    +/***********************************************************************
    + ****************** init_module()/cleanup_module() ******************
    + ***********************************************************************/
    +
    +int init_module(void)
    +{
    + pport = parport_find_base(io);
    + if (pport == NULL) {
    + printk(KERN_NOTICE "%s: no port at %x found\n",
    + LIRC_DRIVER_NAME, io);
    + return -ENXIO;
    + }
    + ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME,
    + pf, kf, irq_handler, 0, NULL);
    + parport_put_port(pport);
    + if (ppdevice == NULL) {
    + printk(KERN_NOTICE "%s: parport_register_device() failed\n",
    + LIRC_DRIVER_NAME);
    + return -ENXIO;
    + }
    + if (parport_claim(ppdevice) != 0)
    + goto skip_init;
    + is_claimed = 1;
    + out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP);
    +
    +#ifdef LIRC_TIMER
    + if (debug)
    + out(LIRC_PORT_DATA, tx_mask);
    +
    + timer = init_lirc_timer();
    +
    +#if 0 /* continue even if device is offline */
    + if (timer == 0) {
    + is_claimed = 0;
    + parport_release(pport);
    + parport_unregister_device(ppdevice);
    + return -EIO;
    + }
    +
    +#endif
    + if (debug)
    + out(LIRC_PORT_DATA, 0);
    +#endif
    +
    + is_claimed = 0;
    + parport_release(ppdevice);
    + skip_init:
    + plugin.minor = lirc_register_plugin(&plugin);
    + if (plugin.minor < 0) {
    + printk(KERN_NOTICE "%s: register_chrdev() failed\n",
    + LIRC_DRIVER_NAME);
    + parport_unregister_device(ppdevice);
    + return -EIO;
    + }
    + printk(KERN_INFO "%s: installed using port 0x%04x irq %d\n",
    + LIRC_DRIVER_NAME, io, irq);
    + return 0;
    +}
    +
    +void cleanup_module(void)
    +{
    + parport_unregister_device(ppdevice);
    + lirc_unregister_plugin(plugin.minor);
    +}
    +
    +MODULE_DESCRIPTION("Infrared receiver driver for parallel ports.");
    +MODULE_AUTHOR("Christoph Bartelmus");
    +MODULE_LICENSE("GPL");
    +
    +module_param(io, int, 0444);
    +MODULE_PARM_DESC(io, "I/O address base (0x3bc, 0x378 or 0x278)");
    +
    +module_param(irq, int, 0444);
    +MODULE_PARM_DESC(irq, "Interrupt (7 or 5)");
    +
    +module_param(tx_mask, int, 0444);
    +MODULE_PARM_DESC(tx_maxk, "Transmitter mask (default: 0x01)");
    +
    +module_param(debug, bool, 0644);
    +MODULE_PARM_DESC(debug, "Enable debugging messages");
    +
    +module_param(check_pselecd, bool, 0644);
    +MODULE_PARM_DESC(debug, "Check for printer (default: 0)");
    +
    +#endif /* MODULE */
    diff --git a/drivers/input/lirc/lirc_parallel.h b/drivers/input/lirc/lirc_parallel.h
    new file mode 100644
    index 0000000..4bed6af
    --- /dev/null
    +++ b/drivers/input/lirc/lirc_parallel.h
    @@ -0,0 +1,26 @@
    +/* lirc_parallel.h */
    +
    +#ifndef _LIRC_PARALLEL_H
    +#define _LIRC_PARALLEL_H
    +
    +#include <linux/lp.h>
    +
    +#define LIRC_PORT_LEN 3
    +
    +#define LIRC_LP_BASE 0
    +#define LIRC_LP_STATUS 1
    +#define LIRC_LP_CONTROL 2
    +
    +#define LIRC_PORT_DATA LIRC_LP_BASE /* base */
    +#define LIRC_PORT_TIMER LIRC_LP_STATUS /* status port */
    +#define LIRC_PORT_TIMER_BIT LP_PBUSY /* busy signal */
    +#define LIRC_PORT_SIGNAL LIRC_LP_STATUS /* status port */
    +#define LIRC_PORT_SIGNAL_BIT LP_PACK /* ack signal */
    +#define LIRC_PORT_IRQ LIRC_LP_CONTROL /* control port */
    +
    +#define LIRC_SFH506_DELAY 0 /* delay t_phl in usecs */
    +
    +#define LIRC_PARALLEL_MAX_TRANSMITTERS 8
    +#define LIRC_PARALLEL_TRANSMITTER_MASK ((1<<LIRC_PARALLEL_MAX_TRANSMITTERS) - 1)
    +
    +#endif
    --
    1.6.0.1


    \
     
     \ /
      Last update: 2008-09-09 06:13    [from the cache]
    ©2003-2011 Jasper Spaans