Blob Blame History Raw
This patch rolls up the following v4l-dvb upstream commits:

commit 9b44ed200f1584f029da82e60e1f284d1d8de3da
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Sat Jul 31 11:59:26 2010 -0300

    V4L/DVB: IR: Port ene driver to new IR subsystem and enable it

    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit 46192437f6d17c49f37bef73c97a14f2ed278db0
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Sat Jul 31 11:59:25 2010 -0300

    V4L/DVB: STAGING: remove lirc_ene0100 driver
    
    Add latest unported version of this driver to media/IR.
    Next patch will port it to ir core.
    
    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit abf84383ecadc8ada1963f9976e887c6f0b1bad9
Author: Joe Perches <joe@perches.com>
Date:   Mon Jul 12 17:50:03 2010 -0300

    V4L/DVB: drivers/media: Remove unnecessary casts of private_data

    Signed-off-by: Joe Perches <joe@perches.com>
    Acked-by: Jarod Wilson <jarod@redhat.com>
    Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit 26699e3cf2ce4938112ddf60e084feaf4ce435b5
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Sat Jul 31 11:59:20 2010 -0300

    V4L/DVB: IR: NECX: support repeat
        
    This adds support for repeat detecting for NECX variant
    Tested with uneversal remote

    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit 7f01033b288bb86d4f9d2885966d2c255f3659c1
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Sat Jul 31 11:59:19 2010 -0300

    V4L/DVB: IR: nec decoder: fix repeat

    Repeat space is 4 units, not 8.
    Current code would never trigger a repeat.

    However that isn't true for NECX, so repeat there
    must be handled differently.

    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Reviewed-by: Andy Walls <awalls@md.metrocast.net>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit 54f7413aa4ce44d18c7f9744e37ff64c4668daa6
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Sat Jul 31 11:59:18 2010 -0300

    V4L/DVB: IR: JVC: make repeat work

    Currently, jvc decoder will attempt misdetect next press as a repeat
    of last keypress, therefore second keypress isn't detected.

    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit 951c6835be77d1baf619f7960c2beb22eea36947
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Sat Jul 31 11:59:24 2010 -0300

    V4L/DVB: IR: report unknown scancodes the in-kernel decoders found

    This way it is possible to use evtest to create keymap for unknown remote.

    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit 3879b56940f84f3b90fb77ad5860083930be4bac
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Sat Jul 31 11:59:23 2010 -0300

    V4L/DVB: IR: extend interfaces to support more device settings

    LIRC: add new IOCTL that enables learning mode (wide band receiver)
    Still missing features: carrier report & timeout reports.
    Will need to pack these into ir_raw_event

    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit 2f5fb55510cf309cd749f1af85e26274f9e360ab
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Sat Jul 31 11:59:22 2010 -0300

    V4L/DVB: IR: add helper function for hardware with small o/b buffer
    
    Some ir input devices have small buffer, and interrupt the host
    each time it is full (or half full)
    
    Add a helper that automaticly handles timeouts, and also
    automaticly merges samples of same time (space-space)
    Such samples might be placed by hardware because size of
    sample in the buffer is small (a byte for example).
    
    Also remove constness from ir_dev_props, because it now contains timeout
    settings that driver might want to change
    
    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Acked-by: Jarod Wilson <jarod@redhat.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit 0f3f74ce40f25e80e3733e5d5293251568b03d83
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Sat Jul 31 11:59:21 2010 -0300

    V4L/DVB: IR: Allow not to compile keymaps in
    
    Currently, ir device registration fails if keymap requested by driver is not found.
    Fix that by always compiling in the empty keymap, and using it as a failback.
    
    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Acked-by: Jarod Wilson <jarod@redhat.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit daad37e3a9e0b9366da8eecb3e64bd47ac831938
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Sat Jul 31 11:59:17 2010 -0300

    V4L/DVB: IR: replace workqueue with kthread
    
    It is perfectly possible to have ir_raw_event_work
    running concurently on two cpus, thus we must protect
    it from that situation.
    
    This stems from the fact that if hardware sends short packets of samples
    we might end up queueing the work item more times that nessesary.
    
    Such job isn't well suited for a workqueue, so use a kernel thread.
    
    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit 7c4be7bab7bb06974d649835cac66b5df984047f
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Sat Jul 31 11:59:16 2010 -0300

    V4L/DVB: IR: replace spinlock with mutex
    
    Some handlers (lirc for example) allocates memory on initialization,
    doing so in atomic context is cumbersome.
    Fixes warning about sleeping function in atomic context.
    
    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit 211ed16e58b2fdf0335e47546b252398b47e7790
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Sat Jul 31 11:59:15 2010 -0300

    V4L/DVB: IR: minor fixes
    
    * lirc: Don't propagate reset event to userspace
    * lirc: Remove strange logic from lirc that would make first sample always be pulse
    * Make TO_US macro actualy print what it should.
    
    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit d8ffb6454250115ca0636d8481030466c1e3fdec
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Sat Jul 31 11:59:14 2010 -0300

    V4L/DVB: IR: Kconfig fixes
    
    Move IR drives below separate menu.
    This allows to disable them.
    Also correct a typo.
    
    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit 5af935cc96a291f90799bf6a2587d87329a91699
Author: Mauro Carvalho Chehab <mchehab@redhat.com>
Date:   Sun Aug 1 08:02:35 2010 -0300

    V4L/DVB: dib0700: break keytable into NEC and RC-5 variants
    
    Instead of having one big keytable with 2 protocols inside, break it
    into two separate tables, being one for NEC and another for RC-5 variants,
    and properly identify what variant should be used at the boards entries.
    
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

commit 50b9d21ae2ac1b85be46f1ee5aa1b5e588622361
Author: Jarod Wilson <jarod@redhat.com>
Date:   Fri Aug 27 18:21:14 2010 -0300

    V4L/DVB: mceusb: add two new ASUS device IDs
    
    Reported in lirc sf.net tracker and on lirc mailing list
    
    Signed-off-by: Jarod Wilson <jarod@redhat.com>
    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>


diff -Naurp linux-2.6.35/drivers/media/IR/ene_ir.c linux-2.6.35.new/drivers/media/IR/ene_ir.c
--- linux-2.6.35/drivers/media/IR/ene_ir.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.35.new/drivers/media/IR/ene_ir.c	2010-09-09 23:21:49.000000000 -0400
@@ -0,0 +1,1023 @@
+/*
+ * driver for ENE KB3926 B/C/D CIR (pnp id: ENE0XXX)
+ *
+ * Copyright (C) 2010 Maxim Levitsky <maximlevitsky@gmail.com>
+ *
+ * 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
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pnp.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <media/ir-core.h>
+#include <media/ir-common.h>
+#include "ene_ir.h"
+
+
+static int sample_period = -1;
+static int enable_idle = 1;
+static int input = 1;
+static int debug;
+static int txsim;
+
+static int ene_irq_status(struct ene_device *dev);
+
+/* read a hardware register */
+static u8 ene_hw_read_reg(struct ene_device *dev, u16 reg)
+{
+	u8 retval;
+	outb(reg >> 8, dev->hw_io + ENE_ADDR_HI);
+	outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO);
+	retval = inb(dev->hw_io + ENE_IO);
+
+	ene_dbg_verbose("reg %04x == %02x", reg, retval);
+	return retval;
+}
+
+/* write a hardware register */
+static void ene_hw_write_reg(struct ene_device *dev, u16 reg, u8 value)
+{
+	outb(reg >> 8, dev->hw_io + ENE_ADDR_HI);
+	outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO);
+	outb(value, dev->hw_io + ENE_IO);
+
+	ene_dbg_verbose("reg %04x <- %02x", reg, value);
+}
+
+/* change specific bits in hardware register */
+static void ene_hw_write_reg_mask(struct ene_device *dev,
+				  u16 reg, u8 value, u8 mask)
+{
+	u8 regvalue;
+
+	outb(reg >> 8, dev->hw_io + ENE_ADDR_HI);
+	outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO);
+
+	regvalue = inb(dev->hw_io + ENE_IO) & ~mask;
+	regvalue |= (value & mask);
+	outb(regvalue, dev->hw_io + ENE_IO);
+
+	ene_dbg_verbose("reg %04x <- %02x (mask=%02x)", reg, value, mask);
+}
+
+/* detect hardware features */
+static int ene_hw_detect(struct ene_device *dev)
+{
+	u8 chip_major, chip_minor;
+	u8 hw_revision, old_ver;
+	u8 tmp;
+	u8 fw_capabilities;
+	int pll_freq;
+
+	tmp = ene_hw_read_reg(dev, ENE_HW_UNK);
+	ene_hw_write_reg(dev, ENE_HW_UNK, tmp & ~ENE_HW_UNK_CLR);
+
+	chip_major = ene_hw_read_reg(dev, ENE_HW_VER_MAJOR);
+	chip_minor = ene_hw_read_reg(dev, ENE_HW_VER_MINOR);
+
+	ene_hw_write_reg(dev, ENE_HW_UNK, tmp);
+	hw_revision = ene_hw_read_reg(dev, ENE_HW_VERSION);
+	old_ver = ene_hw_read_reg(dev, ENE_HW_VER_OLD);
+
+	pll_freq = (ene_hw_read_reg(dev, ENE_PLLFRH) << 4) +
+		(ene_hw_read_reg(dev, ENE_PLLFRL) >> 4);
+
+	if (pll_freq != 1000)
+		dev->rx_period_adjust = 4;
+	else
+		dev->rx_period_adjust = 2;
+
+
+	ene_printk(KERN_NOTICE, "PLL freq = %d\n", pll_freq);
+
+	if (hw_revision == 0xFF) {
+
+		ene_printk(KERN_WARNING, "device seems to be disabled\n");
+		ene_printk(KERN_WARNING,
+			"send a mail to lirc-list@lists.sourceforge.net\n");
+		ene_printk(KERN_WARNING, "please attach output of acpidump\n");
+		return -ENODEV;
+	}
+
+	if (chip_major == 0x33) {
+		ene_printk(KERN_WARNING, "chips 0x33xx aren't supported\n");
+		return -ENODEV;
+	}
+
+	if (chip_major == 0x39 && chip_minor == 0x26 && hw_revision == 0xC0) {
+		dev->hw_revision = ENE_HW_C;
+	} else if (old_ver == 0x24 && hw_revision == 0xC0) {
+		dev->hw_revision = ENE_HW_B;
+		ene_printk(KERN_NOTICE, "KB3926B detected\n");
+	} else {
+		dev->hw_revision = ENE_HW_D;
+		ene_printk(KERN_WARNING,
+			"unknown ENE chip detected, assuming KB3926D\n");
+		ene_printk(KERN_WARNING,
+			"driver support might be not complete");
+
+	}
+
+	ene_printk(KERN_DEBUG,
+		"chip is 0x%02x%02x - kbver = 0x%02x, rev = 0x%02x\n",
+			chip_major, chip_minor, old_ver, hw_revision);
+
+	/* detect features hardware supports */
+	if (dev->hw_revision < ENE_HW_C)
+		return 0;
+
+	fw_capabilities = ene_hw_read_reg(dev, ENE_FW2);
+	ene_dbg("Firmware capabilities: %02x", fw_capabilities);
+
+	dev->hw_gpio40_learning = fw_capabilities & ENE_FW2_GP40_AS_LEARN;
+	dev->hw_learning_and_tx_capable = fw_capabilities & ENE_FW2_LEARNING;
+
+	dev->hw_fan_as_normal_input = dev->hw_learning_and_tx_capable &&
+	    (fw_capabilities & ENE_FW2_FAN_AS_NRML_IN);
+
+	ene_printk(KERN_NOTICE, "hardware features:\n");
+	ene_printk(KERN_NOTICE,
+		"learning and transmit %s, gpio40_learn %s, fan_in %s\n",
+	       dev->hw_learning_and_tx_capable ? "on" : "off",
+	       dev->hw_gpio40_learning ? "on" : "off",
+	       dev->hw_fan_as_normal_input ? "on" : "off");
+
+	if (dev->hw_learning_and_tx_capable) {
+		ene_printk(KERN_WARNING,
+		"Device supports transmitting, but that support is\n");
+		ene_printk(KERN_WARNING,
+		"lightly tested. Please test it and mail\n");
+		ene_printk(KERN_WARNING,
+		"lirc-list@lists.sourceforge.net\n");
+	}
+	return 0;
+}
+
+/* this enables/disables IR input via gpio40*/
+static void ene_enable_gpio40_receive(struct ene_device *dev, int enable)
+{
+	ene_hw_write_reg_mask(dev, ENE_CIR_CONF2, enable ?
+			      0 : ENE_CIR_CONF2_GPIO40DIS,
+			      ENE_CIR_CONF2_GPIO40DIS);
+}
+
+/* this enables/disables IR via standard input */
+static void ene_enable_normal_receive(struct ene_device *dev, int enable)
+{
+	ene_hw_write_reg(dev, ENE_CIR_CONF1, enable ? ENE_CIR_CONF1_RX_ON : 0);
+}
+
+/* this enables/disables IR input via unused fan tachtometer input */
+static void ene_enable_fan_receive(struct ene_device *dev, int enable)
+{
+	if (!enable)
+		ene_hw_write_reg(dev, ENE_FAN_AS_IN1, 0);
+	else {
+		ene_hw_write_reg(dev, ENE_FAN_AS_IN1, ENE_FAN_AS_IN1_EN);
+		ene_hw_write_reg(dev, ENE_FAN_AS_IN2, ENE_FAN_AS_IN2_EN);
+	}
+	dev->rx_fan_input_inuse = enable;
+}
+
+
+/* Sense current received carrier */
+static int ene_rx_sense_carrier(struct ene_device *dev)
+{
+	int period = ene_hw_read_reg(dev, ENE_RX_CARRIER);
+	int carrier;
+	ene_dbg("RX: hardware carrier period = %02x", period);
+
+	if (!(period & ENE_RX_CARRIER_VALID))
+		return 0;
+
+	period &= ~ENE_RX_CARRIER_VALID;
+
+	if (!period)
+		return 0;
+
+	carrier = 2000000 / period;
+	ene_dbg("RX: sensed carrier = %d Hz", carrier);
+	return carrier;
+}
+
+/* determine which input to use*/
+static void ene_rx_set_inputs(struct ene_device *dev)
+{
+	int learning_mode = dev->learning_enabled;
+
+	ene_dbg("RX: setup receiver, learning mode = %d", learning_mode);
+
+	ene_enable_normal_receive(dev, 1);
+
+	/* old hardware doesn't support learning mode for sure */
+	if (dev->hw_revision <= ENE_HW_B)
+		return;
+
+	/* receiver not learning capable, still set gpio40 correctly */
+	if (!dev->hw_learning_and_tx_capable) {
+		ene_enable_gpio40_receive(dev, !dev->hw_gpio40_learning);
+		return;
+	}
+
+	/* enable learning mode */
+	if (learning_mode) {
+		ene_enable_gpio40_receive(dev, dev->hw_gpio40_learning);
+
+		/* fan input is not used for learning */
+		if (dev->hw_fan_as_normal_input)
+			ene_enable_fan_receive(dev, 0);
+
+	/* disable learning mode */
+	} else {
+		if (dev->hw_fan_as_normal_input) {
+			ene_enable_fan_receive(dev, 1);
+			ene_enable_normal_receive(dev, 0);
+		} else
+			ene_enable_gpio40_receive(dev,
+					!dev->hw_gpio40_learning);
+	}
+
+	/* set few additional settings for this mode */
+	ene_hw_write_reg_mask(dev, ENE_CIR_CONF1, learning_mode ?
+			      ENE_CIR_CONF1_LEARN1 : 0, ENE_CIR_CONF1_LEARN1);
+
+	ene_hw_write_reg_mask(dev, ENE_CIR_CONF2, learning_mode ?
+			      ENE_CIR_CONF2_LEARN2 : 0, ENE_CIR_CONF2_LEARN2);
+
+	if (dev->rx_fan_input_inuse) {
+		dev->props->rx_resolution = ENE_SAMPLE_PERIOD_FAN * 1000;
+
+		dev->props->timeout =
+			ENE_FAN_VALUE_MASK * ENE_SAMPLE_PERIOD_FAN * 1000;
+	} else {
+		dev->props->rx_resolution = sample_period * 1000;
+		dev->props->timeout = ENE_MAXGAP * 1000;
+	}
+}
+
+/* Enable the device for receive */
+static void ene_rx_enable(struct ene_device *dev)
+{
+	u8 reg_value;
+
+	if (dev->hw_revision < ENE_HW_C) {
+		ene_hw_write_reg(dev, ENEB_IRQ, dev->irq << 1);
+		ene_hw_write_reg(dev, ENEB_IRQ_UNK1, 0x01);
+	} else {
+		reg_value = ene_hw_read_reg(dev, ENEC_IRQ) & 0xF0;
+		reg_value |= ENEC_IRQ_UNK_EN;
+		reg_value &= ~ENEC_IRQ_STATUS;
+		reg_value |= (dev->irq & ENEC_IRQ_MASK);
+		ene_hw_write_reg(dev, ENEC_IRQ, reg_value);
+		ene_hw_write_reg(dev, ENE_TX_UNK1, 0x63);
+	}
+
+	ene_hw_write_reg(dev, ENE_CIR_CONF2, 0x00);
+	ene_rx_set_inputs(dev);
+
+	/* set sampling period */
+	ene_hw_write_reg(dev, ENE_CIR_SAMPLE_PERIOD, sample_period);
+
+	/* ack any pending irqs - just in case */
+	ene_irq_status(dev);
+
+	/* enable firmware bits */
+	ene_hw_write_reg_mask(dev, ENE_FW1,
+			      ENE_FW1_ENABLE | ENE_FW1_IRQ,
+			      ENE_FW1_ENABLE | ENE_FW1_IRQ);
+
+	/* enter idle mode */
+	ir_raw_event_set_idle(dev->idev, 1);
+	ir_raw_event_reset(dev->idev);
+
+}
+
+/* Disable the device receiver */
+static void ene_rx_disable(struct ene_device *dev)
+{
+	/* disable inputs */
+	ene_enable_normal_receive(dev, 0);
+
+	if (dev->hw_fan_as_normal_input)
+		ene_enable_fan_receive(dev, 0);
+
+	/* disable hardware IRQ and firmware flag */
+	ene_hw_write_reg_mask(dev, ENE_FW1, 0, ENE_FW1_ENABLE | ENE_FW1_IRQ);
+
+	ir_raw_event_set_idle(dev->idev, 1);
+	ir_raw_event_reset(dev->idev);
+}
+
+
+/* prepare transmission */
+static void ene_tx_prepare(struct ene_device *dev)
+{
+	u8 conf1;
+
+	conf1 = ene_hw_read_reg(dev, ENE_CIR_CONF1);
+	dev->saved_conf1 = conf1;
+
+	if (dev->hw_revision == ENE_HW_C)
+		conf1 &= ~ENE_CIR_CONF1_TX_CLEAR;
+
+	/* Enable TX engine */
+	conf1 |= ENE_CIR_CONF1_TX_ON;
+
+	/* Set carrier */
+	if (dev->tx_period) {
+
+		/* NOTE: duty cycle handling is just a guess, it might
+			not be aviable. Default values were tested */
+		int tx_period_in500ns = dev->tx_period * 2;
+
+		int tx_pulse_width_in_500ns =
+			tx_period_in500ns / (100 / dev->tx_duty_cycle);
+
+		if (!tx_pulse_width_in_500ns)
+			tx_pulse_width_in_500ns = 1;
+
+		ene_dbg("TX: pulse distance = %d * 500 ns", tx_period_in500ns);
+		ene_dbg("TX: pulse width = %d * 500 ns",
+						tx_pulse_width_in_500ns);
+
+		ene_hw_write_reg(dev, ENE_TX_PERIOD, ENE_TX_PERIOD_UNKBIT |
+					tx_period_in500ns);
+
+		ene_hw_write_reg(dev, ENE_TX_PERIOD_PULSE,
+					tx_pulse_width_in_500ns);
+
+		conf1 |= ENE_CIR_CONF1_TX_CARR;
+	} else
+		conf1 &= ~ENE_CIR_CONF1_TX_CARR;
+
+	ene_hw_write_reg(dev, ENE_CIR_CONF1, conf1);
+
+}
+
+/* end transmission */
+static void ene_tx_complete(struct ene_device *dev)
+{
+	ene_hw_write_reg(dev, ENE_CIR_CONF1, dev->saved_conf1);
+	dev->tx_buffer = NULL;
+}
+
+/* set transmit mask */
+static void ene_tx_hw_set_transmiter_mask(struct ene_device *dev)
+{
+	u8 txport1 = ene_hw_read_reg(dev, ENE_TX_PORT1) & ~ENE_TX_PORT1_EN;
+	u8 txport2 = ene_hw_read_reg(dev, ENE_TX_PORT2) & ~ENE_TX_PORT2_EN;
+
+	if (dev->transmitter_mask & 0x01)
+		txport1 |= ENE_TX_PORT1_EN;
+
+	if (dev->transmitter_mask & 0x02)
+		txport2 |= ENE_TX_PORT2_EN;
+
+	ene_hw_write_reg(dev, ENE_TX_PORT1, txport1);
+	ene_hw_write_reg(dev, ENE_TX_PORT2, txport2);
+}
+
+/* TX one sample - must be called with dev->hw_lock*/
+static void ene_tx_sample(struct ene_device *dev)
+{
+	u8 raw_tx;
+	u32 sample;
+
+	if (!dev->tx_buffer) {
+		ene_dbg("TX: attempt to transmit NULL buffer");
+		return;
+	}
+
+	/* Grab next TX sample */
+	if (!dev->tx_sample) {
+again:
+		if (dev->tx_pos == dev->tx_len + 1) {
+			if (!dev->tx_done) {
+				ene_dbg("TX: no more data to send");
+				dev->tx_done = 1;
+				goto exit;
+			} else {
+				ene_dbg("TX: last sample sent by hardware");
+				ene_tx_complete(dev);
+				complete(&dev->tx_complete);
+				return;
+			}
+		}
+
+		sample = dev->tx_buffer[dev->tx_pos++];
+		dev->tx_sample_pulse = !dev->tx_sample_pulse;
+
+		ene_dbg("TX: sample %8d (%s)", sample, dev->tx_sample_pulse ?
+							"pulse" : "space");
+
+		dev->tx_sample = DIV_ROUND_CLOSEST(sample, ENE_TX_SMPL_PERIOD);
+
+		/* guard against too short samples */
+		if (!dev->tx_sample)
+			goto again;
+	}
+
+	raw_tx = min(dev->tx_sample , (unsigned int)ENE_TX_SMLP_MASK);
+	dev->tx_sample -= raw_tx;
+
+	if (dev->tx_sample_pulse)
+		raw_tx |= ENE_TX_PULSE_MASK;
+
+	ene_hw_write_reg(dev, ENE_TX_INPUT1 + dev->tx_reg, raw_tx);
+	dev->tx_reg = !dev->tx_reg;
+exit:
+	/* simulate TX done interrupt */
+	if (txsim)
+		mod_timer(&dev->tx_sim_timer, jiffies + HZ / 500);
+}
+
+/* timer to simulate tx done interrupt */
+static void ene_tx_irqsim(unsigned long data)
+{
+	struct ene_device *dev = (struct ene_device *)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->hw_lock, flags);
+	ene_tx_sample(dev);
+	spin_unlock_irqrestore(&dev->hw_lock, flags);
+}
+
+
+/* read irq status and ack it */
+static int ene_irq_status(struct ene_device *dev)
+{
+	u8 irq_status;
+	u8 fw_flags1, fw_flags2;
+	int cur_rx_pointer;
+	int retval = 0;
+
+	fw_flags2 = ene_hw_read_reg(dev, ENE_FW2);
+	cur_rx_pointer = !!(fw_flags2 & ENE_FW2_BUF_HIGH);
+
+	if (dev->hw_revision < ENE_HW_C) {
+		irq_status = ene_hw_read_reg(dev, ENEB_IRQ_STATUS);
+
+		if (!(irq_status & ENEB_IRQ_STATUS_IR))
+			return 0;
+
+		ene_hw_write_reg(dev, ENEB_IRQ_STATUS,
+				 irq_status & ~ENEB_IRQ_STATUS_IR);
+		dev->rx_pointer = cur_rx_pointer;
+		return ENE_IRQ_RX;
+	}
+
+	irq_status = ene_hw_read_reg(dev, ENEC_IRQ);
+
+	if (!(irq_status & ENEC_IRQ_STATUS))
+		return 0;
+
+	/* original driver does that twice - a workaround ? */
+	ene_hw_write_reg(dev, ENEC_IRQ, irq_status & ~ENEC_IRQ_STATUS);
+	ene_hw_write_reg(dev, ENEC_IRQ, irq_status & ~ENEC_IRQ_STATUS);
+
+	/* clear unknown flag in F8F9 */
+	if (fw_flags2 & ENE_FW2_IRQ_CLR)
+		ene_hw_write_reg(dev, ENE_FW2, fw_flags2 & ~ENE_FW2_IRQ_CLR);
+
+	/* check if this is a TX interrupt */
+	fw_flags1 = ene_hw_read_reg(dev, ENE_FW1);
+	if (fw_flags1 & ENE_FW1_TXIRQ) {
+		ene_hw_write_reg(dev, ENE_FW1, fw_flags1 & ~ENE_FW1_TXIRQ);
+		retval |= ENE_IRQ_TX;
+	}
+
+	/* Check if this is RX interrupt */
+	if (dev->rx_pointer != cur_rx_pointer) {
+		retval |= ENE_IRQ_RX;
+		dev->rx_pointer = cur_rx_pointer;
+
+	} else if (!(retval & ENE_IRQ_TX)) {
+		ene_dbg("RX: interrupt without change in RX pointer(%d)",
+			dev->rx_pointer);
+		retval |= ENE_IRQ_RX;
+	}
+
+	if ((retval & ENE_IRQ_RX) && (retval & ENE_IRQ_TX))
+		ene_dbg("both RX and TX interrupt at same time");
+
+	return retval;
+}
+
+/* interrupt handler */
+static irqreturn_t ene_isr(int irq, void *data)
+{
+	u16 hw_value;
+	int i, hw_sample;
+	int pulse;
+	int irq_status;
+	unsigned long flags;
+	int carrier = 0;
+	irqreturn_t retval = IRQ_NONE;
+	struct ene_device *dev = (struct ene_device *)data;
+	struct ir_raw_event ev;
+
+
+	spin_lock_irqsave(&dev->hw_lock, flags);
+	irq_status = ene_irq_status(dev);
+
+	if (!irq_status)
+		goto unlock;
+
+	retval = IRQ_HANDLED;
+
+	if (irq_status & ENE_IRQ_TX) {
+
+		if (!dev->hw_learning_and_tx_capable) {
+			ene_dbg("TX interrupt on unsupported device!");
+			goto unlock;
+		}
+		ene_tx_sample(dev);
+	}
+
+	if (!(irq_status & ENE_IRQ_RX))
+		goto unlock;
+
+
+	if (dev->carrier_detect_enabled || debug)
+		carrier = ene_rx_sense_carrier(dev);
+#if 0
+	/* TODO */
+	if (dev->carrier_detect_enabled && carrier)
+		ir_raw_event_report_frequency(dev->idev, carrier);
+#endif
+
+	for (i = 0; i < ENE_SAMPLES_SIZE; i++) {
+		hw_value = ene_hw_read_reg(dev,
+				ENE_SAMPLE_BUFFER + dev->rx_pointer * 4 + i);
+
+		if (dev->rx_fan_input_inuse) {
+			/* read high part of the sample */
+			hw_value |= ene_hw_read_reg(dev,
+			    ENE_SAMPLE_BUFFER_FAN +
+					dev->rx_pointer * 4 + i) << 8;
+			pulse = hw_value & ENE_FAN_SMPL_PULS_MSK;
+
+			/* clear space bit, and other unused bits */
+			hw_value &= ENE_FAN_VALUE_MASK;
+			hw_sample = hw_value * ENE_SAMPLE_PERIOD_FAN;
+
+		} else {
+			pulse = !(hw_value & ENE_SAMPLE_SPC_MASK);
+			hw_value &= ENE_SAMPLE_VALUE_MASK;
+			hw_sample = hw_value * sample_period;
+
+			if (dev->rx_period_adjust) {
+				hw_sample *= (100 - dev->rx_period_adjust);
+				hw_sample /= 100;
+			}
+		}
+		/* no more data */
+		if (!(hw_value))
+			break;
+
+		ene_dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space");
+
+
+		ev.duration = hw_sample * 1000;
+		ev.pulse = pulse;
+		ir_raw_event_store_with_filter(dev->idev, &ev);
+	}
+
+	ir_raw_event_handle(dev->idev);
+unlock:
+	spin_unlock_irqrestore(&dev->hw_lock, flags);
+	return retval;
+}
+
+/* Initialize default settings */
+static void ene_setup_settings(struct ene_device *dev)
+{
+	dev->tx_period = 32;
+	dev->tx_duty_cycle = 25; /*%*/
+	dev->transmitter_mask = 3;
+
+	/* Force learning mode if (input == 2), otherwise
+		let user set it with LIRC_SET_REC_CARRIER */
+	dev->learning_enabled =
+		(input == 2 && dev->hw_learning_and_tx_capable);
+
+	dev->rx_pointer = -1;
+
+}
+
+/* outside interface: called on first open*/
+static int ene_open(void *data)
+{
+	struct ene_device *dev = (struct ene_device *)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->hw_lock, flags);
+	dev->in_use = 1;
+	ene_setup_settings(dev);
+	ene_rx_enable(dev);
+	spin_unlock_irqrestore(&dev->hw_lock, flags);
+	return 0;
+}
+
+/* outside interface: called on device close*/
+static void ene_close(void *data)
+{
+	struct ene_device *dev = (struct ene_device *)data;
+	unsigned long flags;
+	spin_lock_irqsave(&dev->hw_lock, flags);
+
+	ene_rx_disable(dev);
+	dev->in_use = 0;
+	spin_unlock_irqrestore(&dev->hw_lock, flags);
+}
+
+/* outside interface: set transmitter mask */
+static int ene_set_tx_mask(void *data, u32 tx_mask)
+{
+	struct ene_device *dev = (struct ene_device *)data;
+	unsigned long flags;
+	ene_dbg("TX: attempt to set transmitter mask %02x", tx_mask);
+
+	/* invalid txmask */
+	if (!tx_mask || tx_mask & ~0x3) {
+		ene_dbg("TX: invalid mask");
+		/* return count of transmitters */
+		return 2;
+	}
+
+	spin_lock_irqsave(&dev->hw_lock, flags);
+	dev->transmitter_mask = tx_mask;
+	spin_unlock_irqrestore(&dev->hw_lock, flags);
+	return 0;
+}
+
+/* outside interface : set tx carrier */
+static int ene_set_tx_carrier(void *data, u32 carrier)
+{
+	struct ene_device *dev = (struct ene_device *)data;
+	unsigned long flags;
+	u32 period = 1000000 / carrier; /* (1 / freq) (* # usec in 1 sec) */
+
+	ene_dbg("TX: attempt to set tx carrier to %d kHz", carrier);
+
+	if (period && (period > ENE_TX_PERIOD_MAX ||
+			period < ENE_TX_PERIOD_MIN)) {
+
+		ene_dbg("TX: out of range %d-%d carrier, "
+			"falling back to 32 kHz",
+			1000 / ENE_TX_PERIOD_MIN,
+			1000 / ENE_TX_PERIOD_MAX);
+
+		period = 32; /* this is just a coincidence!!! */
+	}
+	ene_dbg("TX: set carrier to %d kHz", carrier);
+
+	spin_lock_irqsave(&dev->hw_lock, flags);
+	dev->tx_period = period;
+	spin_unlock_irqrestore(&dev->hw_lock, flags);
+	return 0;
+}
+
+
+/* outside interface: enable learning mode */
+static int ene_set_learning_mode(void *data, int enable)
+{
+	struct ene_device *dev = (struct ene_device *)data;
+	unsigned long flags;
+	if (enable == dev->learning_enabled)
+		return 0;
+
+	spin_lock_irqsave(&dev->hw_lock, flags);
+	dev->learning_enabled = enable;
+	ene_rx_set_inputs(dev);
+	spin_unlock_irqrestore(&dev->hw_lock, flags);
+	return 0;
+}
+
+/* outside interface: set rec carrier */
+static int ene_set_rec_carrier(void *data, u32 min, u32 max)
+{
+	struct ene_device *dev = (struct ene_device *)data;
+	ene_set_learning_mode(dev,
+		max > ENE_NORMAL_RX_HI || min < ENE_NORMAL_RX_LOW);
+	return 0;
+}
+
+/* outside interface: enable or disable idle mode */
+static void ene_rx_set_idle(void *data, int idle)
+{
+	struct ene_device *dev = (struct ene_device *)data;
+	ene_dbg("%sabling idle mode", idle ? "en" : "dis");
+
+	ene_hw_write_reg_mask(dev, ENE_CIR_SAMPLE_PERIOD,
+		(enable_idle && idle) ? 0 : ENE_CIR_SAMPLE_OVERFLOW,
+			ENE_CIR_SAMPLE_OVERFLOW);
+}
+
+
+/* outside interface: transmit */
+static int ene_transmit(void *data, int *buf, u32 n)
+{
+	struct ene_device *dev = (struct ene_device *)data;
+	unsigned long flags;
+
+	dev->tx_buffer = buf;
+	dev->tx_len = n / sizeof(int);
+	dev->tx_pos = 0;
+	dev->tx_reg = 0;
+	dev->tx_done = 0;
+	dev->tx_sample = 0;
+	dev->tx_sample_pulse = 0;
+
+	ene_dbg("TX: %d samples", dev->tx_len);
+
+	spin_lock_irqsave(&dev->hw_lock, flags);
+
+	ene_tx_hw_set_transmiter_mask(dev);
+	ene_tx_prepare(dev);
+
+	/* Transmit first two samples */
+	ene_tx_sample(dev);
+	ene_tx_sample(dev);
+
+	spin_unlock_irqrestore(&dev->hw_lock, flags);
+
+	if (wait_for_completion_timeout(&dev->tx_complete, 2 * HZ) == 0) {
+		ene_dbg("TX: timeout");
+		spin_lock_irqsave(&dev->hw_lock, flags);
+		ene_tx_complete(dev);
+		spin_unlock_irqrestore(&dev->hw_lock, flags);
+	} else
+		ene_dbg("TX: done");
+	return n;
+}
+
+
+/* probe entry */
+static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
+{
+	int error = -ENOMEM;
+	struct ir_dev_props *ir_props;
+	struct input_dev *input_dev;
+	struct ene_device *dev;
+
+	/* allocate memory */
+	input_dev = input_allocate_device();
+	ir_props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
+	dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
+
+	if (!input_dev || !ir_props || !dev)
+		goto error;
+
+	/* validate resources */
+	error = -ENODEV;
+
+	if (!pnp_port_valid(pnp_dev, 0) ||
+	    pnp_port_len(pnp_dev, 0) < ENE_MAX_IO)
+		goto error;
+
+	if (!pnp_irq_valid(pnp_dev, 0))
+		goto error;
+
+	dev->hw_io = pnp_port_start(pnp_dev, 0);
+	dev->irq = pnp_irq(pnp_dev, 0);
+	spin_lock_init(&dev->hw_lock);
+
+	/* claim the resources */
+	error = -EBUSY;
+	if (!request_region(dev->hw_io, ENE_MAX_IO, ENE_DRIVER_NAME))
+		goto error;
+
+	if (request_irq(dev->irq, ene_isr,
+			IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev))
+		goto error;
+
+	pnp_set_drvdata(pnp_dev, dev);
+	dev->pnp_dev = pnp_dev;
+
+	/* detect hardware version and features */
+	error = ene_hw_detect(dev);
+	if (error)
+		goto error;
+
+	ene_setup_settings(dev);
+
+	if (!dev->hw_learning_and_tx_capable && txsim) {
+		dev->hw_learning_and_tx_capable = 1;
+		setup_timer(&dev->tx_sim_timer, ene_tx_irqsim,
+						(long unsigned int)dev);
+		ene_printk(KERN_WARNING,
+			"Simulation of TX activated\n");
+	}
+
+	ir_props->driver_type = RC_DRIVER_IR_RAW;
+	ir_props->allowed_protos = IR_TYPE_ALL;
+	ir_props->priv = dev;
+	ir_props->open = ene_open;
+	ir_props->close = ene_close;
+	ir_props->min_timeout = ENE_MINGAP * 1000;
+	ir_props->max_timeout = ENE_MAXGAP * 1000;
+	ir_props->timeout = ENE_MAXGAP * 1000;
+
+	if (dev->hw_revision == ENE_HW_B)
+		ir_props->s_idle = ene_rx_set_idle;
+
+
+	dev->props = ir_props;
+	dev->idev = input_dev;
+
+	/* don't allow too short/long sample periods */
+	if (sample_period < 5 || sample_period > 0x7F)
+		sample_period = -1;
+
+	/* choose default sample period */
+	if (sample_period == -1) {
+
+		sample_period = 50;
+
+		/* on revB, hardware idle mode eats first sample
+		  if we set too low sample period */
+		if (dev->hw_revision == ENE_HW_B && enable_idle)
+			sample_period = 75;
+	}
+
+	ir_props->rx_resolution = sample_period * 1000;
+
+	if (dev->hw_learning_and_tx_capable) {
+
+		ir_props->s_learning_mode = ene_set_learning_mode;
+
+		if (input == 0)
+			ir_props->s_rx_carrier_range = ene_set_rec_carrier;
+
+		init_completion(&dev->tx_complete);
+		ir_props->tx_ir = ene_transmit;
+		ir_props->s_tx_mask = ene_set_tx_mask;
+		ir_props->s_tx_carrier = ene_set_tx_carrier;
+		ir_props->tx_resolution = ENE_TX_SMPL_PERIOD * 1000;
+		/* ir_props->s_carrier_report = ene_set_carrier_report; */
+	}
+
+
+	device_set_wakeup_capable(&pnp_dev->dev, 1);
+	device_set_wakeup_enable(&pnp_dev->dev, 1);
+
+	if (dev->hw_learning_and_tx_capable)
+		input_dev->name = "ENE eHome Infrared Remote Transceiver";
+	else
+		input_dev->name = "ENE eHome Infrared Remote Receiver";
+
+
+	error = -ENODEV;
+	if (ir_input_register(input_dev, RC_MAP_RC6_MCE, ir_props,
+							ENE_DRIVER_NAME))
+		goto error;
+
+
+	ene_printk(KERN_NOTICE, "driver has been succesfully loaded\n");
+	return 0;
+error:
+	if (dev->irq)
+		free_irq(dev->irq, dev);
+	if (dev->hw_io)
+		release_region(dev->hw_io, ENE_MAX_IO);
+
+	input_free_device(input_dev);
+	kfree(ir_props);
+	kfree(dev);
+	return error;
+}
+
+/* main unload function */
+static void ene_remove(struct pnp_dev *pnp_dev)
+{
+	struct ene_device *dev = pnp_get_drvdata(pnp_dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->hw_lock, flags);
+	ene_rx_disable(dev);
+	spin_unlock_irqrestore(&dev->hw_lock, flags);
+
+	free_irq(dev->irq, dev);
+	release_region(dev->hw_io, ENE_MAX_IO);
+	ir_input_unregister(dev->idev);
+	kfree(dev->props);
+	kfree(dev);
+}
+
+/* enable wake on IR (wakes on specific button on original remote) */
+static void ene_enable_wake(struct ene_device *dev, int enable)
+{
+	enable = enable && device_may_wakeup(&dev->pnp_dev->dev);
+
+	ene_dbg("wake on IR %s", enable ? "enabled" : "disabled");
+
+	ene_hw_write_reg_mask(dev, ENE_FW1, enable ?
+		ENE_FW1_WAKE : 0, ENE_FW1_WAKE);
+}
+
+#ifdef CONFIG_PM
+static int ene_suspend(struct pnp_dev *pnp_dev, pm_message_t state)
+{
+	struct ene_device *dev = pnp_get_drvdata(pnp_dev);
+	ene_enable_wake(dev, 1);
+	return 0;
+}
+
+static int ene_resume(struct pnp_dev *pnp_dev)
+{
+	struct ene_device *dev = pnp_get_drvdata(pnp_dev);
+	if (dev->in_use)
+		ene_rx_enable(dev);
+
+	ene_enable_wake(dev, 0);
+	return 0;
+}
+#endif
+
+static void ene_shutdown(struct pnp_dev *pnp_dev)
+{
+	struct ene_device *dev = pnp_get_drvdata(pnp_dev);
+	ene_enable_wake(dev, 1);
+}
+
+static const struct pnp_device_id ene_ids[] = {
+	{.id = "ENE0100",},
+	{.id = "ENE0200",},
+	{.id = "ENE0201",},
+	{.id = "ENE0202",},
+	{},
+};
+
+static struct pnp_driver ene_driver = {
+	.name = ENE_DRIVER_NAME,
+	.id_table = ene_ids,
+	.flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
+
+	.probe = ene_probe,
+	.remove = __devexit_p(ene_remove),
+#ifdef CONFIG_PM
+	.suspend = ene_suspend,
+	.resume = ene_resume,
+#endif
+	.shutdown = ene_shutdown,
+};
+
+static int __init ene_init(void)
+{
+	return pnp_register_driver(&ene_driver);
+}
+
+static void ene_exit(void)
+{
+	pnp_unregister_driver(&ene_driver);
+}
+
+module_param(sample_period, int, S_IRUGO);
+MODULE_PARM_DESC(sample_period, "Hardware sample period (50 us default)");
+
+module_param(enable_idle, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(enable_idle,
+	"Enables turning off signal sampling after long inactivity time; "
+	"if disabled might help detecting input signal (default: enabled)"
+	" (KB3926B only)");
+
+module_param(input, bool, S_IRUGO);
+MODULE_PARM_DESC(input, "select which input to use "
+	"0 - auto, 1 - standard, 2 - wideband(KB3926C+)");
+
+module_param(debug, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Enable debug (debug=2 verbose debug output)");
+
+module_param(txsim, bool, S_IRUGO);
+MODULE_PARM_DESC(txsim,
+	"Simulate TX features on unsupported hardware (dangerous)");
+
+MODULE_DEVICE_TABLE(pnp, ene_ids);
+MODULE_DESCRIPTION
+	("Infrared input driver for KB3926B/KB3926C/KB3926D "
+	"(aka ENE0100/ENE0200/ENE0201) CIR port");
+
+MODULE_AUTHOR("Maxim Levitsky");
+MODULE_LICENSE("GPL");
+
+module_init(ene_init);
+module_exit(ene_exit);
diff -Naurp linux-2.6.35/drivers/media/IR/ene_ir.h linux-2.6.35.new/drivers/media/IR/ene_ir.h
--- linux-2.6.35/drivers/media/IR/ene_ir.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.35.new/drivers/media/IR/ene_ir.h	2010-09-09 23:21:49.000000000 -0400
@@ -0,0 +1,235 @@
+/*
+ * driver for ENE KB3926 B/C/D CIR (also known as ENE0XXX)
+ *
+ * Copyright (C) 2010 Maxim Levitsky <maximlevitsky@gmail.com>
+ *
+ * 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
+ */
+#include <linux/spinlock.h>
+
+
+/* hardware address */
+#define ENE_STATUS		0	/* hardware status - unused */
+#define ENE_ADDR_HI		1	/* hi byte of register address */
+#define ENE_ADDR_LO		2	/* low byte of register address */
+#define ENE_IO			3	/* read/write window */
+#define ENE_MAX_IO		4
+
+/* 8 bytes of samples, divided in 2 halfs*/
+#define ENE_SAMPLE_BUFFER	0xF8F0	/* regular sample buffer */
+#define ENE_SAMPLE_SPC_MASK	0x80	/* sample is space */
+#define ENE_SAMPLE_VALUE_MASK	0x7F
+#define ENE_SAMPLE_OVERFLOW	0x7F
+#define ENE_SAMPLES_SIZE	4
+
+/* fan input sample buffer */
+#define ENE_SAMPLE_BUFFER_FAN	0xF8FB	/* this buffer holds high byte of */
+					/* each sample of normal buffer */
+#define ENE_FAN_SMPL_PULS_MSK	0x8000	/* this bit of combined sample */
+					/* if set, says that sample is pulse */
+#define ENE_FAN_VALUE_MASK	0x0FFF  /* mask for valid bits of the value */
+
+/* first firmware register */
+#define ENE_FW1			0xF8F8
+#define	ENE_FW1_ENABLE		0x01	/* enable fw processing */
+#define ENE_FW1_TXIRQ		0x02	/* TX interrupt pending */
+#define ENE_FW1_WAKE		0x40	/* enable wake from S3 */
+#define ENE_FW1_IRQ		0x80	/* enable interrupt */
+
+/* second firmware register */
+#define ENE_FW2			0xF8F9
+#define ENE_FW2_BUF_HIGH	0x01	/* which half of the buffer to read */
+#define ENE_FW2_IRQ_CLR		0x04	/* clear this on IRQ */
+#define ENE_FW2_GP40_AS_LEARN	0x08	/* normal input is used as */
+					/* learning input */
+#define ENE_FW2_FAN_AS_NRML_IN	0x40	/* fan is used as normal input */
+#define ENE_FW2_LEARNING	0x80	/* hardware supports learning and TX */
+
+/* transmitter ports */
+#define ENE_TX_PORT2		0xFC01	/* this enables one or both */
+#define ENE_TX_PORT2_EN		0x20	/* TX ports */
+#define ENE_TX_PORT1		0xFC08
+#define ENE_TX_PORT1_EN		0x02
+
+/* IRQ registers block (for revision B) */
+#define ENEB_IRQ		0xFD09	/* IRQ number */
+#define ENEB_IRQ_UNK1		0xFD17	/* unknown setting = 1 */
+#define ENEB_IRQ_STATUS		0xFD80	/* irq status */
+#define ENEB_IRQ_STATUS_IR	0x20	/* IR irq */
+
+/* fan as input settings - only if learning capable */
+#define ENE_FAN_AS_IN1		0xFE30  /* fan init reg 1 */
+#define ENE_FAN_AS_IN1_EN	0xCD
+#define ENE_FAN_AS_IN2		0xFE31  /* fan init reg 2 */
+#define ENE_FAN_AS_IN2_EN	0x03
+#define ENE_SAMPLE_PERIOD_FAN   61	/* fan input has fixed sample period */
+
+/* IRQ registers block (for revision C,D) */
+#define ENEC_IRQ		0xFE9B	/* new irq settings register */
+#define ENEC_IRQ_MASK		0x0F	/* irq number mask */
+#define ENEC_IRQ_UNK_EN		0x10	/* always enabled */
+#define ENEC_IRQ_STATUS		0x20	/* irq status and ACK */
+
+/* CIR block settings */
+#define ENE_CIR_CONF1		0xFEC0
+#define ENE_CIR_CONF1_TX_CLEAR	0x01	/* clear that on revC */
+					/* while transmitting */
+#define ENE_CIR_CONF1_RX_ON	0x07	/* normal receiver enabled */
+#define ENE_CIR_CONF1_LEARN1	0x08	/* enabled on learning mode */
+#define ENE_CIR_CONF1_TX_ON	0x30	/* enabled on transmit */
+#define ENE_CIR_CONF1_TX_CARR	0x80	/* send TX carrier or not */
+
+#define ENE_CIR_CONF2		0xFEC1	/* unknown setting = 0 */
+#define ENE_CIR_CONF2_LEARN2	0x10	/* set on enable learning */
+#define ENE_CIR_CONF2_GPIO40DIS	0x20	/* disable input via gpio40 */
+
+#define ENE_CIR_SAMPLE_PERIOD	0xFEC8	/* sample period in us */
+#define ENE_CIR_SAMPLE_OVERFLOW	0x80	/* interrupt on overflows if set */
+
+
+/* Two byte tx buffer */
+#define ENE_TX_INPUT1		0xFEC9
+#define ENE_TX_INPUT2		0xFECA
+#define ENE_TX_PULSE_MASK	0x80	/* Transmitted sample is pulse */
+#define ENE_TX_SMLP_MASK	0x7F
+#define ENE_TX_SMPL_PERIOD	50	/* transmit sample period - fixed */
+
+
+/* Unknown TX setting - TX sample period ??? */
+#define ENE_TX_UNK1		0xFECB	/* set to 0x63 */
+
+/* Current received carrier period */
+#define ENE_RX_CARRIER		0xFECC	/* RX period (500 ns) */
+#define ENE_RX_CARRIER_VALID	0x80	/* Register content valid */
+
+
+/* TX period (1/carrier) */
+#define ENE_TX_PERIOD		0xFECE	/* TX period (500 ns) */
+#define ENE_TX_PERIOD_UNKBIT	0x80	/* This bit set on transmit*/
+#define ENE_TX_PERIOD_PULSE	0xFECF	/* TX pulse period (500 ns)*/
+
+/* Hardware versions */
+#define ENE_HW_VERSION		0xFF00	/* hardware revision */
+#define ENE_PLLFRH		0xFF16
+#define ENE_PLLFRL		0xFF17
+
+#define ENE_HW_UNK		0xFF1D
+#define ENE_HW_UNK_CLR		0x04
+#define ENE_HW_VER_MAJOR	0xFF1E	/* chip version */
+#define ENE_HW_VER_MINOR	0xFF1F
+#define ENE_HW_VER_OLD		0xFD00
+
+/* Normal/Learning carrier ranges - only valid if we have learning input*/
+/* TODO: test */
+#define ENE_NORMAL_RX_LOW	34
+#define ENE_NORMAL_RX_HI	38
+
+/* Tx carrier range */
+/* Hardware might be able to do more, but this range is enough for
+   all purposes */
+#define ENE_TX_PERIOD_MAX	32	/* corresponds to 29.4 kHz */
+#define ENE_TX_PERIOD_MIN	16	/* corrsponds to 62.5 kHz */
+
+
+
+/* Minimal and maximal gaps */
+
+/* Normal case:
+	Minimal gap is 0x7F * sample period
+	Maximum gap depends on hardware.
+	For KB3926B, it is unlimited, for newer models its around
+	250000, after which HW stops sending samples, and that is
+	not possible to change */
+
+/* Fan case:
+	Both minimal and maximal gaps are same, and equal to 0xFFF * 0x61
+	And there is nothing to change this setting
+*/
+
+#define ENE_MAXGAP		250000
+#define ENE_MINGAP		(127 * sample_period)
+
+/******************************************************************************/
+
+#define ENE_DRIVER_NAME		"ene_ir"
+
+#define ENE_IRQ_RX		1
+#define ENE_IRQ_TX		2
+
+#define  ENE_HW_B		1	/* 3926B */
+#define  ENE_HW_C		2	/* 3926C */
+#define  ENE_HW_D		3	/* 3926D */
+
+#define ene_printk(level, text, ...) \
+	printk(level ENE_DRIVER_NAME ": " text, ## __VA_ARGS__)
+
+#define ene_dbg(text, ...) \
+	if (debug) \
+		printk(KERN_DEBUG \
+			ENE_DRIVER_NAME ": " text "\n" , ## __VA_ARGS__)
+
+#define ene_dbg_verbose(text, ...) \
+	if (debug > 1) \
+		printk(KERN_DEBUG \
+			ENE_DRIVER_NAME ": " text "\n" , ## __VA_ARGS__)
+
+
+struct ene_device {
+	struct pnp_dev *pnp_dev;
+	struct input_dev *idev;
+	struct ir_dev_props *props;
+	int in_use;
+
+	/* hw IO settings */
+	unsigned long hw_io;
+	int irq;
+	spinlock_t hw_lock;
+
+	/* HW features */
+	int hw_revision;			/* hardware revision */
+	bool hw_learning_and_tx_capable;	/* learning capable */
+	bool hw_gpio40_learning;		/* gpio40 is learning */
+	bool hw_fan_as_normal_input;		/* fan input is used as */
+						/* regular input */
+	/* HW state*/
+	int rx_pointer;				/* hw pointer to rx buffer */
+	bool rx_fan_input_inuse;		/* is fan input in use for rx*/
+	int tx_reg;				/* current reg used for TX */
+	u8  saved_conf1;			/* saved FEC0 reg */
+
+	/* TX sample handling */
+	unsigned int tx_sample;			/* current sample for TX */
+	bool tx_sample_pulse;			/* current sample is pulse */
+
+	/* TX buffer */
+	int *tx_buffer;				/* input samples buffer*/
+	int tx_pos;				/* position in that bufer */
+	int tx_len;				/* current len of tx buffer */
+	int tx_done;				/* done transmitting */
+						/* one more sample pending*/
+	struct completion tx_complete;		/* TX completion */
+	struct timer_list tx_sim_timer;
+
+	/* TX settings */
+	int tx_period;
+	int tx_duty_cycle;
+	int transmitter_mask;
+
+	/* RX settings */
+	bool learning_enabled;			/* learning input enabled */
+	bool carrier_detect_enabled;		/* carrier detect enabled */
+	int rx_period_adjust;
+};
diff -Naurp linux-2.6.35/drivers/media/IR/imon.c linux-2.6.35.new/drivers/media/IR/imon.c
--- linux-2.6.35/drivers/media/IR/imon.c	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/imon.c	2010-09-09 23:21:42.000000000 -0400
@@ -406,7 +406,7 @@ static int display_close(struct inode *i
 	struct imon_context *ictx = NULL;
 	int retval = 0;
 
-	ictx = (struct imon_context *)file->private_data;
+	ictx = file->private_data;
 
 	if (!ictx) {
 		err("%s: no context for device", __func__);
@@ -811,7 +811,7 @@ static ssize_t vfd_write(struct file *fi
 	const unsigned char vfd_packet6[] = {
 		0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
 
-	ictx = (struct imon_context *)file->private_data;
+	ictx = file->private_data;
 	if (!ictx) {
 		err("%s: no context for device", __func__);
 		return -ENODEV;
@@ -895,7 +895,7 @@ static ssize_t lcd_write(struct file *fi
 	int retval = 0;
 	struct imon_context *ictx;
 
-	ictx = (struct imon_context *)file->private_data;
+	ictx = file->private_data;
 	if (!ictx) {
 		err("%s: no context for device", __func__);
 		return -ENODEV;
diff -Naurp linux-2.6.35/drivers/media/IR/ir-core-priv.h linux-2.6.35.new/drivers/media/IR/ir-core-priv.h
--- linux-2.6.35/drivers/media/IR/ir-core-priv.h	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/ir-core-priv.h	2010-09-09 23:21:49.000000000 -0400
@@ -32,7 +32,7 @@ struct ir_raw_handler {
 
 struct ir_raw_event_ctrl {
 	struct list_head		list;		/* to keep track of raw clients */
-	struct work_struct		rx_work;	/* for the rx decoding workqueue */
+	struct task_struct		*thread;
 	struct kfifo			kfifo;		/* fifo for the pulse/space durations */
 	ktime_t				last_event;	/* when last event occurred */
 	enum raw_event_type		last_type;	/* last event type */
@@ -41,10 +41,13 @@ struct ir_raw_event_ctrl {
 
 	/* raw decoder state follows */
 	struct ir_raw_event prev_ev;
+	struct ir_raw_event this_ev;
 	struct nec_dec {
 		int state;
 		unsigned count;
 		u32 bits;
+		bool is_nec_x;
+		bool necx_repeat;
 	} nec;
 	struct rc5_dec {
 		int state;
@@ -82,7 +85,7 @@ struct ir_raw_event_ctrl {
 	struct lirc_codec {
 		struct ir_input_dev *ir_dev;
 		struct lirc_driver *drv;
-		int lircdata;
+		int carrier_low;
 	} lirc;
 };
 
@@ -110,10 +113,9 @@ static inline void decrease_duration(str
 		ev->duration -= duration;
 }
 
-#define TO_US(duration)			(((duration) + 500) / 1000)
+#define TO_US(duration)			DIV_ROUND_CLOSEST((duration), 1000)
 #define TO_STR(is_pulse)		((is_pulse) ? "pulse" : "space")
 #define IS_RESET(ev)			(ev.duration == 0)
-
 /*
  * Routines from ir-sysfs.c - Meant to be called only internally inside
  * ir-core
@@ -132,7 +134,8 @@ int ir_raw_handler_register(struct ir_ra
 void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
 void ir_raw_init(void);
 
-
+int ir_rcmap_init(void);
+void ir_rcmap_cleanup(void);
 /*
  * Decoder initialization code
  *
diff -Naurp linux-2.6.35/drivers/media/IR/ir-jvc-decoder.c linux-2.6.35.new/drivers/media/IR/ir-jvc-decoder.c
--- linux-2.6.35/drivers/media/IR/ir-jvc-decoder.c	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/ir-jvc-decoder.c	2010-09-09 23:21:49.000000000 -0400
@@ -32,6 +32,7 @@ enum jvc_state {
 	STATE_BIT_SPACE,
 	STATE_TRAILER_PULSE,
 	STATE_TRAILER_SPACE,
+	STATE_CHECK_REPEAT,
 };
 
 /**
@@ -60,6 +61,7 @@ static int ir_jvc_decode(struct input_de
 	IR_dprintk(2, "JVC decode started at state %d (%uus %s)\n",
 		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 
+again:
 	switch (data->state) {
 
 	case STATE_INACTIVE:
@@ -149,8 +151,18 @@ static int ir_jvc_decode(struct input_de
 		}
 
 		data->count = 0;
-		data->state = STATE_BIT_PULSE;
+		data->state = STATE_CHECK_REPEAT;
 		return 0;
+
+	case STATE_CHECK_REPEAT:
+		if (!ev.pulse)
+			break;
+
+		if (eq_margin(ev.duration, JVC_HEADER_PULSE, JVC_UNIT / 2))
+			data->state = STATE_INACTIVE;
+  else
+			data->state = STATE_BIT_PULSE;
+		goto again;
 	}
 
 out:
diff -Naurp linux-2.6.35/drivers/media/IR/ir-keytable.c linux-2.6.35.new/drivers/media/IR/ir-keytable.c
--- linux-2.6.35/drivers/media/IR/ir-keytable.c	2010-08-01 18:11:14.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/ir-keytable.c	2010-09-09 23:21:49.000000000 -0400
@@ -339,6 +339,8 @@ void ir_repeat(struct input_dev *dev)
 
 	spin_lock_irqsave(&ir->keylock, flags);
 
+	input_event(dev, EV_MSC, MSC_SCAN, ir->last_scancode);
+
 	if (!ir->keypressed)
 		goto out;
 
@@ -370,6 +372,8 @@ void ir_keydown(struct input_dev *dev, i
 
 	spin_lock_irqsave(&ir->keylock, flags);
 
+	input_event(dev, EV_MSC, MSC_SCAN, scancode);
+
 	/* Repeat event? */
 	if (ir->keypressed &&
 	    ir->last_scancode == scancode &&
@@ -383,9 +387,11 @@ void ir_keydown(struct input_dev *dev, i
 	ir->last_toggle = toggle;
 	ir->last_keycode = keycode;
 
+
 	if (keycode == KEY_RESERVED)
 		goto out;
 
+
 	/* Register a keypress */
 	ir->keypressed = true;
 	IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n",
@@ -428,7 +434,7 @@ static void ir_close(struct input_dev *i
  */
 int __ir_input_register(struct input_dev *input_dev,
 		      const struct ir_scancode_table *rc_tab,
-		      const struct ir_dev_props *props,
+		      struct ir_dev_props *props,
 		      const char *driver_name)
 {
 	struct ir_input_dev *ir_dev;
@@ -480,6 +486,8 @@ int __ir_input_register(struct input_dev
 
 	set_bit(EV_KEY, input_dev->evbit);
 	set_bit(EV_REP, input_dev->evbit);
+	set_bit(EV_MSC, input_dev->evbit);
+	set_bit(MSC_SCAN, input_dev->mscbit);
 
 	if (ir_setkeytable(input_dev, &ir_dev->rc_tab, rc_tab)) {
 		rc = -ENOMEM;
@@ -497,8 +505,10 @@ int __ir_input_register(struct input_dev
 				goto out_event;
 		}
 
-	IR_dprintk(1, "Registered input device on %s for %s remote.\n",
-		   driver_name, rc_tab->name);
+	IR_dprintk(1, "Registered input device on %s for %s remote%s.\n",
+		   driver_name, rc_tab->name,
+		   (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ?
+			" in raw mode" : "");
 
 	return 0;
 
diff -Naurp linux-2.6.35/drivers/media/IR/ir-lirc-codec.c linux-2.6.35.new/drivers/media/IR/ir-lirc-codec.c
--- linux-2.6.35/drivers/media/IR/ir-lirc-codec.c	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/ir-lirc-codec.c	2010-09-09 23:21:49.000000000 -0400
@@ -32,6 +32,7 @@
 static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
 {
 	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+	int sample;
 
 	if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC))
 		return 0;
@@ -39,18 +40,20 @@ static int ir_lirc_decode(struct input_d
 	if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf)
 		return -EINVAL;
 
+	if (IS_RESET(ev))
+		return 0;
+
 	IR_dprintk(2, "LIRC data transfer started (%uus %s)\n",
 		   TO_US(ev.duration), TO_STR(ev.pulse));
 
-	ir_dev->raw->lirc.lircdata += ev.duration / 1000;
+	sample = ev.duration / 1000;
 	if (ev.pulse)
-		ir_dev->raw->lirc.lircdata |= PULSE_BIT;
+		sample |= PULSE_BIT;
 
 	lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
-			  (unsigned char *) &ir_dev->raw->lirc.lircdata);
+			  (unsigned char *) &sample);
 	wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
 
-	ir_dev->raw->lirc.lircdata = 0;
 
 	return 0;
 }
@@ -74,14 +77,9 @@ static ssize_t ir_lirc_transmit_ir(struc
 	if (count > LIRCBUF_SIZE || count % 2 == 0)
 		return -EINVAL;
 
-	txbuf = kzalloc(sizeof(int) * LIRCBUF_SIZE, GFP_KERNEL);
-	if (!txbuf)
-		return -ENOMEM;
-
-	if (copy_from_user(txbuf, buf, n)) {
-		ret = -EFAULT;
-		goto out;
-	}
+	txbuf = memdup_user(buf, n);
+	if (IS_ERR(txbuf))
+		return PTR_ERR(txbuf);
 
 	ir_dev = lirc->ir_dev;
 	if (!ir_dev) {
@@ -97,13 +95,14 @@ out:
 	return ret;
 }
 
-static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
+			unsigned long __user arg)
 {
 	struct lirc_codec *lirc;
 	struct ir_input_dev *ir_dev;
 	int ret = 0;
 	void *drv_data;
-	unsigned long val;
+	unsigned long val = 0;
 
 	lirc = lirc_get_pdata(filep);
 	if (!lirc)
@@ -115,47 +114,106 @@ static long ir_lirc_ioctl(struct file *f
 
 	drv_data = ir_dev->props->priv;
 
-	switch (cmd) {
-	case LIRC_SET_TRANSMITTER_MASK:
+	if (_IOC_DIR(cmd) & _IOC_WRITE) {
 		ret = get_user(val, (unsigned long *)arg);
 		if (ret)
 			return ret;
+	}
+
+	switch (cmd) {
+
+	/* legacy support */
+	case LIRC_GET_SEND_MODE:
+		val = LIRC_CAN_SEND_PULSE & LIRC_CAN_SEND_MASK;
+		break;
 
-		if (ir_dev->props && ir_dev->props->s_tx_mask)
+	case LIRC_SET_SEND_MODE:
+		if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
+			return -EINVAL;
+		break;
+
+	/* TX settings */
+	case LIRC_SET_TRANSMITTER_MASK:
+		if (ir_dev->props->s_tx_mask)
 			ret = ir_dev->props->s_tx_mask(drv_data, (u32)val);
 		else
 			return -EINVAL;
 		break;
 
 	case LIRC_SET_SEND_CARRIER:
-		ret = get_user(val, (unsigned long *)arg);
-		if (ret)
-			return ret;
-
-		if (ir_dev->props && ir_dev->props->s_tx_carrier)
+		if (ir_dev->props->s_tx_carrier)
 			ir_dev->props->s_tx_carrier(drv_data, (u32)val);
 		else
 			return -EINVAL;
 		break;
 
-	case LIRC_GET_SEND_MODE:
-		val = LIRC_CAN_SEND_PULSE & LIRC_CAN_SEND_MASK;
-		ret = put_user(val, (unsigned long *)arg);
+	case LIRC_SET_SEND_DUTY_CYCLE:
+		if (!ir_dev->props->s_tx_duty_cycle)
+			return -ENOSYS;
+
+		if (val <= 0 || val >= 100)
+			return -EINVAL;
+
+		ir_dev->props->s_tx_duty_cycle(ir_dev->props->priv, val);
 		break;
 
-	case LIRC_SET_SEND_MODE:
-		ret = get_user(val, (unsigned long *)arg);
-		if (ret)
-			return ret;
+	/* RX settings */
+	case LIRC_SET_REC_CARRIER:
+		if (ir_dev->props->s_rx_carrier_range)
+			ret = ir_dev->props->s_rx_carrier_range(
+				ir_dev->props->priv,
+				ir_dev->raw->lirc.carrier_low, val);
+		else
+			return -ENOSYS;
 
-		if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
+		if (!ret)
+			ir_dev->raw->lirc.carrier_low = 0;
+		break;
+
+	case LIRC_SET_REC_CARRIER_RANGE:
+		if (val >= 0)
+			ir_dev->raw->lirc.carrier_low = val;
+		break;
+
+
+	case LIRC_GET_REC_RESOLUTION:
+		val = ir_dev->props->rx_resolution;
+		break;
+
+	case LIRC_SET_WIDEBAND_RECEIVER:
+		if (ir_dev->props->s_learning_mode)
+			return ir_dev->props->s_learning_mode(
+				ir_dev->props->priv, !!val);
+		else
+			return -ENOSYS;
+
+	/* Generic timeout support */
+	case LIRC_GET_MIN_TIMEOUT:
+		if (!ir_dev->props->max_timeout)
+			return -ENOSYS;
+		val = ir_dev->props->min_timeout / 1000;
+		break;
+
+	case LIRC_GET_MAX_TIMEOUT:
+		if (!ir_dev->props->max_timeout)
+			return -ENOSYS;
+		val = ir_dev->props->max_timeout / 1000;
+		break;
+
+	case LIRC_SET_REC_TIMEOUT:
+		if (val < ir_dev->props->min_timeout ||
+		    val > ir_dev->props->max_timeout)
 			return -EINVAL;
+		ir_dev->props->timeout = val * 1000;
 		break;
 
 	default:
 		return lirc_dev_fop_ioctl(filep, cmd, arg);
 	}
 
+	if (_IOC_DIR(cmd) & _IOC_READ)
+		ret = put_user(val, (unsigned long *)arg);
+
 	return ret;
 }
 
@@ -192,7 +250,7 @@ static int ir_lirc_register(struct input
 		return rc;
 
 	rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
-	if (!drv)
+	if (!rbuf)
 		goto rbuf_alloc_failed;
 
 	rc = lirc_buffer_init(rbuf, sizeof(int), LIRCBUF_SIZE);
@@ -201,13 +259,28 @@ static int ir_lirc_register(struct input
 
 	features = LIRC_CAN_REC_MODE2;
 	if (ir_dev->props->tx_ir) {
+
 		features |= LIRC_CAN_SEND_PULSE;
 		if (ir_dev->props->s_tx_mask)
 			features |= LIRC_CAN_SET_TRANSMITTER_MASK;
 		if (ir_dev->props->s_tx_carrier)
 			features |= LIRC_CAN_SET_SEND_CARRIER;
+
+		if (ir_dev->props->s_tx_duty_cycle)
+			features |= LIRC_CAN_SET_REC_DUTY_CYCLE;
 	}
 
+	if (ir_dev->props->s_rx_carrier_range)
+		features |= LIRC_CAN_SET_REC_CARRIER |
+			LIRC_CAN_SET_REC_CARRIER_RANGE;
+
+	if (ir_dev->props->s_learning_mode)
+		features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
+
+	if (ir_dev->props->max_timeout)
+		features |= LIRC_CAN_SET_REC_TIMEOUT;
+
+
 	snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)",
 		 ir_dev->driver_name);
 	drv->minor = -1;
@@ -229,8 +302,6 @@ static int ir_lirc_register(struct input
 
 	ir_dev->raw->lirc.drv = drv;
 	ir_dev->raw->lirc.ir_dev = ir_dev;
-	ir_dev->raw->lirc.lircdata = PULSE_MASK;
-
 	return 0;
 
 lirc_register_failed:
diff -Naurp linux-2.6.35/drivers/media/IR/ir-nec-decoder.c linux-2.6.35.new/drivers/media/IR/ir-nec-decoder.c
--- linux-2.6.35/drivers/media/IR/ir-nec-decoder.c	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/ir-nec-decoder.c	2010-09-09 23:21:49.000000000 -0400
@@ -20,12 +20,13 @@
 #define NEC_HEADER_PULSE	(16 * NEC_UNIT)
 #define NECX_HEADER_PULSE	(8  * NEC_UNIT) /* Less common NEC variant */
 #define NEC_HEADER_SPACE	(8  * NEC_UNIT)
-#define NEC_REPEAT_SPACE	(8  * NEC_UNIT)
+#define NEC_REPEAT_SPACE	(4  * NEC_UNIT)
 #define NEC_BIT_PULSE		(1  * NEC_UNIT)
 #define NEC_BIT_0_SPACE		(1  * NEC_UNIT)
 #define NEC_BIT_1_SPACE		(3  * NEC_UNIT)
 #define	NEC_TRAILER_PULSE	(1  * NEC_UNIT)
 #define	NEC_TRAILER_SPACE	(10 * NEC_UNIT) /* even longer in reality */
+#define NECX_REPEAT_BITS	1
 
 enum nec_state {
 	STATE_INACTIVE,
@@ -67,8 +68,12 @@ static int ir_nec_decode(struct input_de
 		if (!ev.pulse)
 			break;
 
-		if (!eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2) &&
-		    !eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2))
+		if (eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2)) {
+			data->is_nec_x = false;
+			data->necx_repeat = false;
+		} else if (eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2))
+			data->is_nec_x = true;
+		else
 			break;
 
 		data->count = 0;
@@ -105,6 +110,17 @@ static int ir_nec_decode(struct input_de
 		if (ev.pulse)
 			break;
 
+		if (data->necx_repeat && data->count == NECX_REPEAT_BITS &&
+			geq_margin(ev.duration,
+			NEC_TRAILER_SPACE, NEC_UNIT / 2)) {
+				IR_dprintk(1, "Repeat last key\n");
+				ir_repeat(input_dev);
+				data->state = STATE_INACTIVE;
+				return 0;
+
+		} else if (data->count > NECX_REPEAT_BITS)
+			data->necx_repeat = false;
+
 		data->bits <<= 1;
 		if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
 			data->bits |= 1;
@@ -159,6 +175,9 @@ static int ir_nec_decode(struct input_de
 			IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
 		}
 
+		if (data->is_nec_x)
+			data->necx_repeat = true;
+
 		ir_keydown(input_dev, scancode, 0);
 		data->state = STATE_INACTIVE;
 		return 0;
diff -Naurp linux-2.6.35/drivers/media/IR/ir-raw-event.c linux-2.6.35.new/drivers/media/IR/ir-raw-event.c
--- linux-2.6.35/drivers/media/IR/ir-raw-event.c	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/ir-raw-event.c	2010-09-09 23:21:49.000000000 -0400
@@ -12,9 +12,10 @@
  *  GNU General Public License for more details.
  */
 
-#include <linux/workqueue.h>
-#include <linux/spinlock.h>
+#include <linux/kthread.h>
+#include <linux/mutex.h>
 #include <linux/sched.h>
+#include <linux/freezer.h>
 #include "ir-core-priv.h"
 
 /* Define the max number of pulse/space transitions to buffer */
@@ -24,7 +25,7 @@
 static LIST_HEAD(ir_raw_client_list);
 
 /* Used to handle IR raw handler extensions */
-static DEFINE_SPINLOCK(ir_raw_handler_lock);
+static DEFINE_MUTEX(ir_raw_handler_lock);
 static LIST_HEAD(ir_raw_handler_list);
 static u64 available_protocols;
 
@@ -33,20 +34,30 @@ static u64 available_protocols;
 static struct work_struct wq_load;
 #endif
 
-static void ir_raw_event_work(struct work_struct *work)
+static int ir_raw_event_thread(void *data)
 {
 	struct ir_raw_event ev;
 	struct ir_raw_handler *handler;
-	struct ir_raw_event_ctrl *raw =
-		container_of(work, struct ir_raw_event_ctrl, rx_work);
+	struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data;
 
-	while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) {
-		spin_lock(&ir_raw_handler_lock);
-		list_for_each_entry(handler, &ir_raw_handler_list, list)
-			handler->decode(raw->input_dev, ev);
-		spin_unlock(&ir_raw_handler_lock);
-		raw->prev_ev = ev;
+	while (!kthread_should_stop()) {
+		try_to_freeze();
+
+		mutex_lock(&ir_raw_handler_lock);
+
+		while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) {
+			list_for_each_entry(handler, &ir_raw_handler_list, list)
+				handler->decode(raw->input_dev, ev);
+			raw->prev_ev = ev;
+		}
+
+		mutex_unlock(&ir_raw_handler_lock);
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule();
 	}
+
+	return 0;
 }
 
 /**
@@ -66,6 +77,9 @@ int ir_raw_event_store(struct input_dev 
 	if (!ir->raw)
 		return -EINVAL;
 
+	IR_dprintk(2, "sample: (05%dus %s)\n",
+		TO_US(ev->duration), TO_STR(ev->pulse));
+
 	if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
 		return -ENOMEM;
 
@@ -126,6 +140,90 @@ int ir_raw_event_store_edge(struct input
 EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
 
 /**
+ * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing
+ * @input_dev:	the struct input_dev device descriptor
+ * @type:	the type of the event that has occurred
+ *
+ * This routine (which may be called from an interrupt context) works
+ * in similiar manner to ir_raw_event_store_edge.
+ * This routine is intended for devices with limited internal buffer
+ * It automerges samples of same type, and handles timeouts
+ */
+int ir_raw_event_store_with_filter(struct input_dev *input_dev,
+						struct ir_raw_event *ev)
+{
+	struct ir_input_dev *ir = input_get_drvdata(input_dev);
+	struct ir_raw_event_ctrl *raw = ir->raw;
+
+	if (!raw || !ir->props)
+		return -EINVAL;
+
+	/* Ignore spaces in idle mode */
+	if (ir->idle && !ev->pulse)
+		return 0;
+	else if (ir->idle)
+		ir_raw_event_set_idle(input_dev, 0);
+
+	if (!raw->this_ev.duration) {
+		raw->this_ev = *ev;
+	} else if (ev->pulse == raw->this_ev.pulse) {
+		raw->this_ev.duration += ev->duration;
+	} else {
+		ir_raw_event_store(input_dev, &raw->this_ev);
+		raw->this_ev = *ev;
+	}
+
+	/* Enter idle mode if nessesary */
+	if (!ev->pulse && ir->props->timeout &&
+		raw->this_ev.duration >= ir->props->timeout)
+		ir_raw_event_set_idle(input_dev, 1);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
+
+void ir_raw_event_set_idle(struct input_dev *input_dev, int idle)
+{
+	struct ir_input_dev *ir = input_get_drvdata(input_dev);
+	struct ir_raw_event_ctrl *raw = ir->raw;
+	ktime_t now;
+	u64 delta;
+
+	if (!ir->props)
+		return;
+
+	if (!ir->raw)
+		goto out;
+
+	if (idle) {
+		IR_dprintk(2, "enter idle mode\n");
+		raw->last_event = ktime_get();
+	} else {
+		IR_dprintk(2, "exit idle mode\n");
+
+		now = ktime_get();
+		delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
+
+		WARN_ON(raw->this_ev.pulse);
+
+		raw->this_ev.duration =
+			min(raw->this_ev.duration + delta,
+						(u64)IR_MAX_DURATION);
+
+		ir_raw_event_store(input_dev, &raw->this_ev);
+
+		if (raw->this_ev.duration == IR_MAX_DURATION)
+			ir_raw_event_reset(input_dev);
+
+		raw->this_ev.duration = 0;
+	}
+out:
+	if (ir->props->s_idle)
+		ir->props->s_idle(ir->props->priv, idle);
+	ir->idle = idle;
+}
+EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
+
+/**
  * ir_raw_event_handle() - schedules the decoding of stored ir data
  * @input_dev:	the struct input_dev device descriptor
  *
@@ -138,7 +236,7 @@ void ir_raw_event_handle(struct input_de
 	if (!ir->raw)
 		return;
 
-	schedule_work(&ir->raw->rx_work);
+	wake_up_process(ir->raw->thread);
 }
 EXPORT_SYMBOL_GPL(ir_raw_event_handle);
 
@@ -147,9 +245,9 @@ u64
 ir_raw_get_allowed_protocols()
 {
 	u64 protocols;
-	spin_lock(&ir_raw_handler_lock);
+	mutex_lock(&ir_raw_handler_lock);
 	protocols = available_protocols;
-	spin_unlock(&ir_raw_handler_lock);
+	mutex_unlock(&ir_raw_handler_lock);
 	return protocols;
 }
 
@@ -167,7 +265,7 @@ int ir_raw_event_register(struct input_d
 		return -ENOMEM;
 
 	ir->raw->input_dev = input_dev;
-	INIT_WORK(&ir->raw->rx_work, ir_raw_event_work);
+
 	ir->raw->enabled_protocols = ~0;
 	rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
 			 GFP_KERNEL);
@@ -177,12 +275,23 @@ int ir_raw_event_register(struct input_d
 		return rc;
 	}
 
-	spin_lock(&ir_raw_handler_lock);
+	ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw,
+			"rc%u",  (unsigned int)ir->devno);
+
+	if (IS_ERR(ir->raw->thread)) {
+		int ret = PTR_ERR(ir->raw->thread);
+
+		kfree(ir->raw);
+		ir->raw = NULL;
+		return ret;
+	}
+
+	mutex_lock(&ir_raw_handler_lock);
 	list_add_tail(&ir->raw->list, &ir_raw_client_list);
 	list_for_each_entry(handler, &ir_raw_handler_list, list)
 		if (handler->raw_register)
 			handler->raw_register(ir->raw->input_dev);
-	spin_unlock(&ir_raw_handler_lock);
+	mutex_unlock(&ir_raw_handler_lock);
 
 	return 0;
 }
@@ -195,14 +304,14 @@ void ir_raw_event_unregister(struct inpu
 	if (!ir->raw)
 		return;
 
-	cancel_work_sync(&ir->raw->rx_work);
+	kthread_stop(ir->raw->thread);
 
-	spin_lock(&ir_raw_handler_lock);
+	mutex_lock(&ir_raw_handler_lock);
 	list_del(&ir->raw->list);
 	list_for_each_entry(handler, &ir_raw_handler_list, list)
 		if (handler->raw_unregister)
 			handler->raw_unregister(ir->raw->input_dev);
-	spin_unlock(&ir_raw_handler_lock);
+	mutex_unlock(&ir_raw_handler_lock);
 
 	kfifo_free(&ir->raw->kfifo);
 	kfree(ir->raw);
@@ -217,13 +326,13 @@ int ir_raw_handler_register(struct ir_ra
 {
 	struct ir_raw_event_ctrl *raw;
 
-	spin_lock(&ir_raw_handler_lock);
+	mutex_lock(&ir_raw_handler_lock);
 	list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
 	if (ir_raw_handler->raw_register)
 		list_for_each_entry(raw, &ir_raw_client_list, list)
 			ir_raw_handler->raw_register(raw->input_dev);
 	available_protocols |= ir_raw_handler->protocols;
-	spin_unlock(&ir_raw_handler_lock);
+	mutex_unlock(&ir_raw_handler_lock);
 
 	return 0;
 }
@@ -233,13 +342,13 @@ void ir_raw_handler_unregister(struct ir
 {
 	struct ir_raw_event_ctrl *raw;
 
-	spin_lock(&ir_raw_handler_lock);
+	mutex_lock(&ir_raw_handler_lock);
 	list_del(&ir_raw_handler->list);
 	if (ir_raw_handler->raw_unregister)
 		list_for_each_entry(raw, &ir_raw_client_list, list)
 			ir_raw_handler->raw_unregister(raw->input_dev);
 	available_protocols &= ~ir_raw_handler->protocols;
-	spin_unlock(&ir_raw_handler_lock);
+	mutex_unlock(&ir_raw_handler_lock);
 }
 EXPORT_SYMBOL(ir_raw_handler_unregister);
 
diff -Naurp linux-2.6.35/drivers/media/IR/ir-sysfs.c linux-2.6.35.new/drivers/media/IR/ir-sysfs.c
--- linux-2.6.35/drivers/media/IR/ir-sysfs.c	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/ir-sysfs.c	2010-09-09 23:21:49.000000000 -0400
@@ -33,6 +33,22 @@ static struct class ir_input_class = {
 	.devnode	= ir_devnode,
 };
 
+static struct {
+	u64	type;
+	char	*name;
+} proto_names[] = {
+	{ IR_TYPE_UNKNOWN,	"unknown"	},
+	{ IR_TYPE_RC5,		"rc-5"		},
+	{ IR_TYPE_NEC,		"nec"		},
+	{ IR_TYPE_RC6,		"rc-6"		},
+	{ IR_TYPE_JVC,		"jvc"		},
+	{ IR_TYPE_SONY,		"sony"		},
+	{ IR_TYPE_RC5_SZ,	"rc-5-sz"	},
+	{ IR_TYPE_LIRC,		"lirc"		},
+};
+
+#define PROTO_NONE	"none"
+
 /**
  * show_protocols() - shows the current IR protocol(s)
  * @d:		the device descriptor
@@ -50,6 +66,7 @@ static ssize_t show_protocols(struct dev
 	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
 	u64 allowed, enabled;
 	char *tmp = buf;
+	int i;
 
 	if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
 		enabled = ir_dev->rc_tab.ir_type;
@@ -63,45 +80,12 @@ static ssize_t show_protocols(struct dev
 		   (long long)allowed,
 		   (long long)enabled);
 
-	if (allowed & enabled & IR_TYPE_UNKNOWN)
-		tmp += sprintf(tmp, "[unknown] ");
-	else if (allowed & IR_TYPE_UNKNOWN)
-		tmp += sprintf(tmp, "unknown ");
-
-	if (allowed & enabled & IR_TYPE_RC5)
-		tmp += sprintf(tmp, "[rc5] ");
-	else if (allowed & IR_TYPE_RC5)
-		tmp += sprintf(tmp, "rc5 ");
-
-	if (allowed & enabled & IR_TYPE_NEC)
-		tmp += sprintf(tmp, "[nec] ");
-	else if (allowed & IR_TYPE_NEC)
-		tmp += sprintf(tmp, "nec ");
-
-	if (allowed & enabled & IR_TYPE_RC6)
-		tmp += sprintf(tmp, "[rc6] ");
-	else if (allowed & IR_TYPE_RC6)
-		tmp += sprintf(tmp, "rc6 ");
-
-	if (allowed & enabled & IR_TYPE_JVC)
-		tmp += sprintf(tmp, "[jvc] ");
-	else if (allowed & IR_TYPE_JVC)
-		tmp += sprintf(tmp, "jvc ");
-
-	if (allowed & enabled & IR_TYPE_SONY)
-		tmp += sprintf(tmp, "[sony] ");
-	else if (allowed & IR_TYPE_SONY)
-		tmp += sprintf(tmp, "sony ");
-
-	if (allowed & enabled & IR_TYPE_RC5_SZ)
-		tmp += sprintf(tmp, "[rc5sz] ");
-	else if (allowed & IR_TYPE_RC5_SZ)
-		tmp += sprintf(tmp, "rc5sz ");
-
-	if (allowed & enabled & IR_TYPE_LIRC)
-		tmp += sprintf(tmp, "[lirc] ");
-	else if (allowed & IR_TYPE_LIRC)
-		tmp += sprintf(tmp, "lirc ");
+	for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
+		if (allowed & enabled & proto_names[i].type)
+			tmp += sprintf(tmp, "[%s] ", proto_names[i].name);
+		else if (allowed & proto_names[i].type)
+			tmp += sprintf(tmp, "%s ", proto_names[i].name);
+	}
 
 	if (tmp != buf)
 		tmp--;
@@ -121,6 +105,7 @@ static ssize_t show_protocols(struct dev
  * Writing "+proto" will add a protocol to the list of enabled protocols.
  * Writing "-proto" will remove a protocol from the list of enabled protocols.
  * Writing "proto" will enable only "proto".
+ * Writing "none" will disable all protocols.
  * Returns -EINVAL if an invalid protocol combination or unknown protocol name
  * is used, otherwise @len.
  */
@@ -134,71 +119,63 @@ static ssize_t store_protocols(struct de
 	const char *tmp;
 	u64 type;
 	u64 mask;
-	int rc;
+	int rc, i, count = 0;
 	unsigned long flags;
 
-	tmp = skip_spaces(data);
+	if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
+		type = ir_dev->rc_tab.ir_type;
+	else
+		type = ir_dev->raw->enabled_protocols;
 
-	if (*tmp == '+') {
-		enable = true;
-		disable = false;
-		tmp++;
-	} else if (*tmp == '-') {
-		enable = false;
-		disable = true;
-		tmp++;
-	} else {
-		enable = false;
-		disable = false;
-	}
+	while ((tmp = strsep((char **) &data, " \n")) != NULL) {
+		if (!*tmp)
+			break;
+
+		if (*tmp == '+') {
+			enable = true;
+			disable = false;
+			tmp++;
+		} else if (*tmp == '-') {
+			enable = false;
+			disable = true;
+			tmp++;
+		} else {
+			enable = false;
+			disable = false;
+		}
 
-	if (!strncasecmp(tmp, "unknown", 7)) {
-		tmp += 7;
-		mask = IR_TYPE_UNKNOWN;
-	} else if (!strncasecmp(tmp, "rc5", 3)) {
-		tmp += 3;
-		mask = IR_TYPE_RC5;
-	} else if (!strncasecmp(tmp, "nec", 3)) {
-		tmp += 3;
-		mask = IR_TYPE_NEC;
-	} else if (!strncasecmp(tmp, "rc6", 3)) {
-		tmp += 3;
-		mask = IR_TYPE_RC6;
-	} else if (!strncasecmp(tmp, "jvc", 3)) {
-		tmp += 3;
-		mask = IR_TYPE_JVC;
-	} else if (!strncasecmp(tmp, "sony", 4)) {
-		tmp += 4;
-		mask = IR_TYPE_SONY;
-	} else if (!strncasecmp(tmp, "rc5sz", 5)) {
-		tmp += 5;
-		mask = IR_TYPE_RC5_SZ;
-	} else if (!strncasecmp(tmp, "lirc", 4)) {
-		tmp += 4;
-		mask = IR_TYPE_LIRC;
-	} else {
-		IR_dprintk(1, "Unknown protocol\n");
-		return -EINVAL;
+		if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) {
+			tmp += sizeof(PROTO_NONE);
+			mask = 0;
+			count++;
+		} else {
+			for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
+				if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) {
+					tmp += strlen(proto_names[i].name);
+					mask = proto_names[i].type;
+					break;
+				}
+			}
+			if (i == ARRAY_SIZE(proto_names)) {
+				IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
+				return -EINVAL;
+			}
+			count++;
+		}
+
+		if (enable)
+			type |= mask;
+		else if (disable)
+			type &= ~mask;
+		else
+			type = mask;
 	}
 
-	tmp = skip_spaces(tmp);
-	if (*tmp != '\0') {
-		IR_dprintk(1, "Invalid trailing characters\n");
+	if (!count) {
+		IR_dprintk(1, "Protocol not specified\n");
 		return -EINVAL;
 	}
 
-	if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
-		type = ir_dev->rc_tab.ir_type;
-	else
-		type = ir_dev->raw->enabled_protocols;
-
-	if (enable)
-		type |= mask;
-	else if (disable)
-		type &= ~mask;
-	else
-		type = mask;
-
 	if (ir_dev->props && ir_dev->props->change_protocol) {
 		rc = ir_dev->props->change_protocol(ir_dev->props->priv,
 						    type);
@@ -217,7 +194,6 @@ static ssize_t store_protocols(struct de
 		ir_dev->raw->enabled_protocols = type;
 	}
 
-
 	IR_dprintk(1, "Current protocol(s): 0x%llx\n",
 		   (long long)type);
 
@@ -286,6 +262,7 @@ int ir_register_class(struct input_dev *
 		return devno;
 
 	ir_dev->dev.type = &rc_dev_type;
+
 	ir_dev->dev.class = &ir_input_class;
 	ir_dev->dev.parent = input_dev->dev.parent;
 	dev_set_name(&ir_dev->dev, "rc%d", devno);
@@ -349,6 +326,7 @@ static int __init ir_core_init(void)
 
 	/* Initialize/load the decoders/keymap code that will be used */
 	ir_raw_init();
+	ir_rcmap_init();
 
 	return 0;
 }
@@ -356,6 +334,7 @@ static int __init ir_core_init(void)
 static void __exit ir_core_exit(void)
 {
 	class_unregister(&ir_input_class);
+	ir_rcmap_cleanup();
 }
 
 module_init(ir_core_init);
diff -Naurp linux-2.6.35/drivers/media/IR/Kconfig linux-2.6.35.new/drivers/media/IR/Kconfig
--- linux-2.6.35/drivers/media/IR/Kconfig	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/Kconfig	2010-09-09 23:21:49.000000000 -0400
@@ -1,13 +1,22 @@
-config IR_CORE
-	tristate
+menuconfig IR_CORE
+	tristate "Infrared remote controller adapters"
 	depends on INPUT
 	default INPUT
+	---help---
+	  Enable support for Remote Controllers on Linux. This is
+	  needed in order to support several video capture adapters.
+
+	  Enable this option if you have a video capture board even
+	  if you don't need IR, as otherwise, you may not be able to
+	  compile the driver for your adapter.
 
 config VIDEO_IR
 	tristate
 	depends on IR_CORE
 	default IR_CORE
 
+if IR_CORE
+
 config LIRC
 	tristate
 	default y
@@ -16,7 +25,7 @@ config LIRC
 	   Enable this option to build the Linux Infrared Remote
 	   Control (LIRC) core device interface driver. The LIRC
 	   interface passes raw IR to and from userspace, where the
-	   LIRC daemon handles protocol decoding for IR reception ann
+	   LIRC daemon handles protocol decoding for IR reception and
 	   encoding for IR transmitting (aka "blasting").
 
 source "drivers/media/IR/keymaps/Kconfig"
@@ -44,6 +53,7 @@ config IR_RC5_DECODER
 config IR_RC6_DECODER
 	tristate "Enable IR raw decoder for the RC6 protocol"
 	depends on IR_CORE
+	select BITREVERSE
 	default y
 
 	---help---
@@ -77,7 +87,9 @@ config IR_RC5_SZ_DECODER
 
 	---help---
 	   Enable this option if you have IR with RC-5 (streamzap) protocol,
-	   and if the IR is decoded in software.
+	   and if the IR is decoded in software. (The Streamzap PC Remote
+	   uses an IR protocol that is almost standard RC-5, but not quite,
+	   as it uses an additional bit).
 
 config IR_LIRC_CODEC
 	tristate "Enable IR to LIRC bridge"
@@ -113,6 +125,20 @@ config IR_MCEUSB
 	   To compile this driver as a module, choose M here: the
 	   module will be called mceusb.
 
+config IR_ENE
+	tristate "ENE eHome Receiver/Transciever (pnp id: ENE0100/ENE02xxx)"
+	depends on PNP
+	depends on IR_CORE
+	---help---
+	   Say Y here to enable support for integrated infrared receiver
+	   /transciever made by ENE.
+
+	   You can see if you have it by looking at lspnp output.
+	   Output should include ENE0100 ENE0200 or something similiar.
+
+	   To compile this driver as a module, choose M here: the
+	   module will be called ene_ir.
+
 config IR_STREAMZAP
 	tristate "Streamzap PC Remote IR Receiver"
 	depends on USB_ARCH_HAS_HCD
@@ -124,3 +150,5 @@ config IR_STREAMZAP
 
 	   To compile this driver as a module, choose M here: the
 	   module will be called streamzap.
+
+endif #IR_CORE
diff -Naurp linux-2.6.35/drivers/media/IR/keymaps/Makefile linux-2.6.35.new/drivers/media/IR/keymaps/Makefile
--- linux-2.6.35/drivers/media/IR/keymaps/Makefile	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/keymaps/Makefile	2010-09-09 23:21:42.000000000 -0400
@@ -14,10 +14,11 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t
 			rc-budget-ci-old.o \
 			rc-cinergy-1400.o \
 			rc-cinergy.o \
+			rc-dib0700-nec.o \
+			rc-dib0700-rc5.o \
 			rc-dm1105-nec.o \
 			rc-dntv-live-dvb-t.o \
 			rc-dntv-live-dvbt-pro.o \
-			rc-empty.o \
 			rc-em-terratec.o \
 			rc-encore-enltv2.o \
 			rc-encore-enltv.o \
diff -Naurp linux-2.6.35/drivers/media/IR/keymaps/rc-dib0700-nec.c linux-2.6.35.new/drivers/media/IR/keymaps/rc-dib0700-nec.c
--- linux-2.6.35/drivers/media/IR/keymaps/rc-dib0700-nec.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.35.new/drivers/media/IR/keymaps/rc-dib0700-nec.c	2010-09-09 23:21:42.000000000 -0400
@@ -0,0 +1,124 @@
+/* rc-dvb0700-big.c - Keytable for devices in dvb0700
+ *
+ * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * TODO: This table is a real mess, as it merges RC codes from several
+ * devices into a big table. It also has both RC-5 and NEC codes inside.
+ * It should be broken into small tables, and the protocols should properly
+ * be indentificated.
+ *
+ * The table were imported from dib0700_devices.c.
+ *
+ * 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.
+ */
+
+#include <media/rc-map.h>
+
+static struct ir_scancode dib0700_nec_table[] = {
+	/* Key codes for the Pixelview SBTVD remote */
+	{ 0x8613, KEY_MUTE },
+	{ 0x8612, KEY_POWER },
+	{ 0x8601, KEY_1 },
+	{ 0x8602, KEY_2 },
+	{ 0x8603, KEY_3 },
+	{ 0x8604, KEY_4 },
+	{ 0x8605, KEY_5 },
+	{ 0x8606, KEY_6 },
+	{ 0x8607, KEY_7 },
+	{ 0x8608, KEY_8 },
+	{ 0x8609, KEY_9 },
+	{ 0x8600, KEY_0 },
+	{ 0x860d, KEY_CHANNELUP },
+	{ 0x8619, KEY_CHANNELDOWN },
+	{ 0x8610, KEY_VOLUMEUP },
+	{ 0x860c, KEY_VOLUMEDOWN },
+
+	{ 0x860a, KEY_CAMERA },
+	{ 0x860b, KEY_ZOOM },
+	{ 0x861b, KEY_BACKSPACE },
+	{ 0x8615, KEY_ENTER },
+
+	{ 0x861d, KEY_UP },
+	{ 0x861e, KEY_DOWN },
+	{ 0x860e, KEY_LEFT },
+	{ 0x860f, KEY_RIGHT },
+
+	{ 0x8618, KEY_RECORD },
+	{ 0x861a, KEY_STOP },
+
+	/* Key codes for the EvolutePC TVWay+ remote */
+	{ 0x7a00, KEY_MENU },
+	{ 0x7a01, KEY_RECORD },
+	{ 0x7a02, KEY_PLAY },
+	{ 0x7a03, KEY_STOP },
+	{ 0x7a10, KEY_CHANNELUP },
+	{ 0x7a11, KEY_CHANNELDOWN },
+	{ 0x7a12, KEY_VOLUMEUP },
+	{ 0x7a13, KEY_VOLUMEDOWN },
+	{ 0x7a40, KEY_POWER },
+	{ 0x7a41, KEY_MUTE },
+
+	/* Key codes for the Elgato EyeTV Diversity silver remote */
+	{ 0x4501, KEY_POWER },
+	{ 0x4502, KEY_MUTE },
+	{ 0x4503, KEY_1 },
+	{ 0x4504, KEY_2 },
+	{ 0x4505, KEY_3 },
+	{ 0x4506, KEY_4 },
+	{ 0x4507, KEY_5 },
+	{ 0x4508, KEY_6 },
+	{ 0x4509, KEY_7 },
+	{ 0x450a, KEY_8 },
+	{ 0x450b, KEY_9 },
+	{ 0x450c, KEY_LAST },
+	{ 0x450d, KEY_0 },
+	{ 0x450e, KEY_ENTER },
+	{ 0x450f, KEY_RED },
+	{ 0x4510, KEY_CHANNELUP },
+	{ 0x4511, KEY_GREEN },
+	{ 0x4512, KEY_VOLUMEDOWN },
+	{ 0x4513, KEY_OK },
+	{ 0x4514, KEY_VOLUMEUP },
+	{ 0x4515, KEY_YELLOW },
+	{ 0x4516, KEY_CHANNELDOWN },
+	{ 0x4517, KEY_BLUE },
+	{ 0x4518, KEY_LEFT }, /* Skip backwards */
+	{ 0x4519, KEY_PLAYPAUSE },
+	{ 0x451a, KEY_RIGHT }, /* Skip forward */
+	{ 0x451b, KEY_REWIND },
+	{ 0x451c, KEY_L }, /* Live */
+	{ 0x451d, KEY_FASTFORWARD },
+	{ 0x451e, KEY_STOP }, /* 'Reveal' for Teletext */
+	{ 0x451f, KEY_MENU }, /* KEY_TEXT for Teletext */
+	{ 0x4540, KEY_RECORD }, /* Font 'Size' for Teletext */
+	{ 0x4541, KEY_SCREEN }, /*  Full screen toggle, 'Hold' for Teletext */
+	{ 0x4542, KEY_SELECT }, /* Select video input, 'Select' for Teletext */
+};
+
+static struct rc_keymap dib0700_nec_map = {
+	.map = {
+		.scan    = dib0700_nec_table,
+		.size    = ARRAY_SIZE(dib0700_nec_table),
+		.ir_type = IR_TYPE_NEC,
+		.name    = RC_MAP_DIB0700_NEC_TABLE,
+	}
+};
+
+static int __init init_rc_map(void)
+{
+	return ir_register_map(&dib0700_nec_map);
+}
+
+static void __exit exit_rc_map(void)
+{
+	ir_unregister_map(&dib0700_nec_map);
+}
+
+module_init(init_rc_map)
+module_exit(exit_rc_map)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff -Naurp linux-2.6.35/drivers/media/IR/keymaps/rc-dib0700-rc5.c linux-2.6.35.new/drivers/media/IR/keymaps/rc-dib0700-rc5.c
--- linux-2.6.35/drivers/media/IR/keymaps/rc-dib0700-rc5.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.35.new/drivers/media/IR/keymaps/rc-dib0700-rc5.c	2010-09-09 23:21:42.000000000 -0400
@@ -0,0 +1,235 @@
+/* rc-dvb0700-big.c - Keytable for devices in dvb0700
+ *
+ * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * TODO: This table is a real mess, as it merges RC codes from several
+ * devices into a big table. It also has both RC-5 and NEC codes inside.
+ * It should be broken into small tables, and the protocols should properly
+ * be indentificated.
+ *
+ * The table were imported from dib0700_devices.c.
+ *
+ * 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.
+ */
+
+#include <media/rc-map.h>
+
+static struct ir_scancode dib0700_rc5_table[] = {
+	/* Key codes for the tiny Pinnacle remote*/
+	{ 0x0700, KEY_MUTE },
+	{ 0x0701, KEY_MENU }, /* Pinnacle logo */
+	{ 0x0739, KEY_POWER },
+	{ 0x0703, KEY_VOLUMEUP },
+	{ 0x0709, KEY_VOLUMEDOWN },
+	{ 0x0706, KEY_CHANNELUP },
+	{ 0x070c, KEY_CHANNELDOWN },
+	{ 0x070f, KEY_1 },
+	{ 0x0715, KEY_2 },
+	{ 0x0710, KEY_3 },
+	{ 0x0718, KEY_4 },
+	{ 0x071b, KEY_5 },
+	{ 0x071e, KEY_6 },
+	{ 0x0711, KEY_7 },
+	{ 0x0721, KEY_8 },
+	{ 0x0712, KEY_9 },
+	{ 0x0727, KEY_0 },
+	{ 0x0724, KEY_SCREEN }, /* 'Square' key */
+	{ 0x072a, KEY_TEXT },   /* 'T' key */
+	{ 0x072d, KEY_REWIND },
+	{ 0x0730, KEY_PLAY },
+	{ 0x0733, KEY_FASTFORWARD },
+	{ 0x0736, KEY_RECORD },
+	{ 0x073c, KEY_STOP },
+	{ 0x073f, KEY_CANCEL }, /* '?' key */
+
+	/* Key codes for the Terratec Cinergy DT XS Diversity, similar to cinergyT2.c */
+	{ 0xeb01, KEY_POWER },
+	{ 0xeb02, KEY_1 },
+	{ 0xeb03, KEY_2 },
+	{ 0xeb04, KEY_3 },
+	{ 0xeb05, KEY_4 },
+	{ 0xeb06, KEY_5 },
+	{ 0xeb07, KEY_6 },
+	{ 0xeb08, KEY_7 },
+	{ 0xeb09, KEY_8 },
+	{ 0xeb0a, KEY_9 },
+	{ 0xeb0b, KEY_VIDEO },
+	{ 0xeb0c, KEY_0 },
+	{ 0xeb0d, KEY_REFRESH },
+	{ 0xeb0f, KEY_EPG },
+	{ 0xeb10, KEY_UP },
+	{ 0xeb11, KEY_LEFT },
+	{ 0xeb12, KEY_OK },
+	{ 0xeb13, KEY_RIGHT },
+	{ 0xeb14, KEY_DOWN },
+	{ 0xeb16, KEY_INFO },
+	{ 0xeb17, KEY_RED },
+	{ 0xeb18, KEY_GREEN },
+	{ 0xeb19, KEY_YELLOW },
+	{ 0xeb1a, KEY_BLUE },
+	{ 0xeb1b, KEY_CHANNELUP },
+	{ 0xeb1c, KEY_VOLUMEUP },
+	{ 0xeb1d, KEY_MUTE },
+	{ 0xeb1e, KEY_VOLUMEDOWN },
+	{ 0xeb1f, KEY_CHANNELDOWN },
+	{ 0xeb40, KEY_PAUSE },
+	{ 0xeb41, KEY_HOME },
+	{ 0xeb42, KEY_MENU }, /* DVD Menu */
+	{ 0xeb43, KEY_SUBTITLE },
+	{ 0xeb44, KEY_TEXT }, /* Teletext */
+	{ 0xeb45, KEY_DELETE },
+	{ 0xeb46, KEY_TV },
+	{ 0xeb47, KEY_DVD },
+	{ 0xeb48, KEY_STOP },
+	{ 0xeb49, KEY_VIDEO },
+	{ 0xeb4a, KEY_AUDIO }, /* Music */
+	{ 0xeb4b, KEY_SCREEN }, /* Pic */
+	{ 0xeb4c, KEY_PLAY },
+	{ 0xeb4d, KEY_BACK },
+	{ 0xeb4e, KEY_REWIND },
+	{ 0xeb4f, KEY_FASTFORWARD },
+	{ 0xeb54, KEY_PREVIOUS },
+	{ 0xeb58, KEY_RECORD },
+	{ 0xeb5c, KEY_NEXT },
+
+	/* Key codes for the Haupauge WinTV Nova-TD, copied from nova-t-usb2.c (Nova-T USB2) */
+	{ 0x1e00, KEY_0 },
+	{ 0x1e01, KEY_1 },
+	{ 0x1e02, KEY_2 },
+	{ 0x1e03, KEY_3 },
+	{ 0x1e04, KEY_4 },
+	{ 0x1e05, KEY_5 },
+	{ 0x1e06, KEY_6 },
+	{ 0x1e07, KEY_7 },
+	{ 0x1e08, KEY_8 },
+	{ 0x1e09, KEY_9 },
+	{ 0x1e0a, KEY_KPASTERISK },
+	{ 0x1e0b, KEY_RED },
+	{ 0x1e0c, KEY_RADIO },
+	{ 0x1e0d, KEY_MENU },
+	{ 0x1e0e, KEY_GRAVE }, /* # */
+	{ 0x1e0f, KEY_MUTE },
+	{ 0x1e10, KEY_VOLUMEUP },
+	{ 0x1e11, KEY_VOLUMEDOWN },
+	{ 0x1e12, KEY_CHANNEL },
+	{ 0x1e14, KEY_UP },
+	{ 0x1e15, KEY_DOWN },
+	{ 0x1e16, KEY_LEFT },
+	{ 0x1e17, KEY_RIGHT },
+	{ 0x1e18, KEY_VIDEO },
+	{ 0x1e19, KEY_AUDIO },
+	{ 0x1e1a, KEY_MEDIA },
+	{ 0x1e1b, KEY_EPG },
+	{ 0x1e1c, KEY_TV },
+	{ 0x1e1e, KEY_NEXT },
+	{ 0x1e1f, KEY_BACK },
+	{ 0x1e20, KEY_CHANNELUP },
+	{ 0x1e21, KEY_CHANNELDOWN },
+	{ 0x1e24, KEY_LAST }, /* Skip backwards */
+	{ 0x1e25, KEY_OK },
+	{ 0x1e29, KEY_BLUE},
+	{ 0x1e2e, KEY_GREEN },
+	{ 0x1e30, KEY_PAUSE },
+	{ 0x1e32, KEY_REWIND },
+	{ 0x1e34, KEY_FASTFORWARD },
+	{ 0x1e35, KEY_PLAY },
+	{ 0x1e36, KEY_STOP },
+	{ 0x1e37, KEY_RECORD },
+	{ 0x1e38, KEY_YELLOW },
+	{ 0x1e3b, KEY_GOTO },
+	{ 0x1e3d, KEY_POWER },
+
+	/* Key codes for the Leadtek Winfast DTV Dongle */
+	{ 0x0042, KEY_POWER },
+	{ 0x077c, KEY_TUNER },
+	{ 0x0f4e, KEY_PRINT }, /* PREVIEW */
+	{ 0x0840, KEY_SCREEN }, /* full screen toggle*/
+	{ 0x0f71, KEY_DOT }, /* frequency */
+	{ 0x0743, KEY_0 },
+	{ 0x0c41, KEY_1 },
+	{ 0x0443, KEY_2 },
+	{ 0x0b7f, KEY_3 },
+	{ 0x0e41, KEY_4 },
+	{ 0x0643, KEY_5 },
+	{ 0x097f, KEY_6 },
+	{ 0x0d7e, KEY_7 },
+	{ 0x057c, KEY_8 },
+	{ 0x0a40, KEY_9 },
+	{ 0x0e4e, KEY_CLEAR },
+	{ 0x047c, KEY_CHANNEL }, /* show channel number */
+	{ 0x0f41, KEY_LAST }, /* recall */
+	{ 0x0342, KEY_MUTE },
+	{ 0x064c, KEY_RESERVED }, /* PIP button*/
+	{ 0x0172, KEY_SHUFFLE }, /* SNAPSHOT */
+	{ 0x0c4e, KEY_PLAYPAUSE }, /* TIMESHIFT */
+	{ 0x0b70, KEY_RECORD },
+	{ 0x037d, KEY_VOLUMEUP },
+	{ 0x017d, KEY_VOLUMEDOWN },
+	{ 0x0242, KEY_CHANNELUP },
+	{ 0x007d, KEY_CHANNELDOWN },
+
+	/* Key codes for Nova-TD "credit card" remote control. */
+	{ 0x1d00, KEY_0 },
+	{ 0x1d01, KEY_1 },
+	{ 0x1d02, KEY_2 },
+	{ 0x1d03, KEY_3 },
+	{ 0x1d04, KEY_4 },
+	{ 0x1d05, KEY_5 },
+	{ 0x1d06, KEY_6 },
+	{ 0x1d07, KEY_7 },
+	{ 0x1d08, KEY_8 },
+	{ 0x1d09, KEY_9 },
+	{ 0x1d0a, KEY_TEXT },
+	{ 0x1d0d, KEY_MENU },
+	{ 0x1d0f, KEY_MUTE },
+	{ 0x1d10, KEY_VOLUMEUP },
+	{ 0x1d11, KEY_VOLUMEDOWN },
+	{ 0x1d12, KEY_CHANNEL },
+	{ 0x1d14, KEY_UP },
+	{ 0x1d15, KEY_DOWN },
+	{ 0x1d16, KEY_LEFT },
+	{ 0x1d17, KEY_RIGHT },
+	{ 0x1d1c, KEY_TV },
+	{ 0x1d1e, KEY_NEXT },
+	{ 0x1d1f, KEY_BACK },
+	{ 0x1d20, KEY_CHANNELUP },
+	{ 0x1d21, KEY_CHANNELDOWN },
+	{ 0x1d24, KEY_LAST },
+	{ 0x1d25, KEY_OK },
+	{ 0x1d30, KEY_PAUSE },
+	{ 0x1d32, KEY_REWIND },
+	{ 0x1d34, KEY_FASTFORWARD },
+	{ 0x1d35, KEY_PLAY },
+	{ 0x1d36, KEY_STOP },
+	{ 0x1d37, KEY_RECORD },
+	{ 0x1d3b, KEY_GOTO },
+	{ 0x1d3d, KEY_POWER },
+};
+
+static struct rc_keymap dib0700_rc5_map = {
+	.map = {
+		.scan    = dib0700_rc5_table,
+		.size    = ARRAY_SIZE(dib0700_rc5_table),
+		.ir_type = IR_TYPE_RC5,
+		.name    = RC_MAP_DIB0700_RC5_TABLE,
+	}
+};
+
+static int __init init_rc_map(void)
+{
+	return ir_register_map(&dib0700_rc5_map);
+}
+
+static void __exit exit_rc_map(void)
+{
+	ir_unregister_map(&dib0700_rc5_map);
+}
+
+module_init(init_rc_map)
+module_exit(exit_rc_map)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff -Naurp linux-2.6.35/drivers/media/IR/keymaps/rc-rc6-mce.c linux-2.6.35.new/drivers/media/IR/keymaps/rc-rc6-mce.c
--- linux-2.6.35/drivers/media/IR/keymaps/rc-rc6-mce.c	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/keymaps/rc-rc6-mce.c	2010-09-09 23:21:49.000000000 -0400
@@ -74,6 +74,8 @@ static struct ir_scancode rc6_mce[] = {
 	{ 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
 	{ 0x800f044d, KEY_TITLE },
 
+       { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
+
 	{ 0x800f040c, KEY_POWER },
 	{ 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
 
diff -Naurp linux-2.6.35/drivers/media/IR/keymaps/rc-streamzap.c linux-2.6.35.new/drivers/media/IR/keymaps/rc-streamzap.c
--- linux-2.6.35/drivers/media/IR/keymaps/rc-streamzap.c	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/keymaps/rc-streamzap.c	2010-09-09 23:21:42.000000000 -0400
@@ -60,7 +60,7 @@ static struct rc_keymap streamzap_map = 
 	.map = {
 		.scan    = streamzap,
 		.size    = ARRAY_SIZE(streamzap),
-		.ir_type = IR_TYPE_RC5,
+		.ir_type = IR_TYPE_RC5_SZ,
 		.name    = RC_MAP_STREAMZAP,
 	}
 };
diff -Naurp linux-2.6.35/drivers/media/IR/Makefile linux-2.6.35.new/drivers/media/IR/Makefile
--- linux-2.6.35/drivers/media/IR/Makefile	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/Makefile	2010-09-09 23:21:42.000000000 -0400
@@ -17,4 +17,5 @@ obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-c
 # stand-alone IR receivers/transmitters
 obj-$(CONFIG_IR_IMON) += imon.o
 obj-$(CONFIG_IR_MCEUSB) += mceusb.o
+obj-$(CONFIG_IR_ENE) += ene_ir.o
 obj-$(CONFIG_IR_STREAMZAP) += streamzap.o
diff -Naurp linux-2.6.35/drivers/media/IR/mceusb.c linux-2.6.35.new/drivers/media/IR/mceusb.c
--- linux-2.6.35/drivers/media/IR/mceusb.c	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/mceusb.c	2010-09-09 23:21:49.000000000 -0400
@@ -120,6 +120,10 @@ static struct usb_device_id mceusb_dev_t
 	{ USB_DEVICE(VENDOR_PHILIPS, 0x0613) },
 	/* Philips eHome Infrared Transceiver */
 	{ USB_DEVICE(VENDOR_PHILIPS, 0x0815) },
+	/* Philips/Spinel plus IR transceiver for ASUS */
+	{ USB_DEVICE(VENDOR_PHILIPS, 0x206c) },
+	/* Philips/Spinel plus IR transceiver for ASUS */
+	{ USB_DEVICE(VENDOR_PHILIPS, 0x2088) },
 	/* Realtek MCE IR Receiver */
 	{ USB_DEVICE(VENDOR_REALTEK, 0x0161) },
 	/* SMK/Toshiba G83C0004D410 */
@@ -427,7 +431,7 @@ static void mceusb_dev_printdata(struct 
 	}
 }
 
-static void usb_async_callback(struct urb *urb, struct pt_regs *regs)
+static void mce_async_callback(struct urb *urb, struct pt_regs *regs)
 {
 	struct mceusb_dev *ir;
 	int len;
@@ -476,7 +480,7 @@ static void mce_request_packet(struct mc
 		/* outbound data */
 		usb_fill_int_urb(async_urb, ir->usbdev,
 			usb_sndintpipe(ir->usbdev, ep->bEndpointAddress),
-			async_buf, size, (usb_complete_t) usb_async_callback,
+			async_buf, size, (usb_complete_t)mce_async_callback,
 			ir, ep->bInterval);
 		memcpy(async_buf, data, size);
 
@@ -919,7 +923,6 @@ static int __devinit mceusb_dev_probe(st
 	struct usb_endpoint_descriptor *ep = NULL;
 	struct usb_endpoint_descriptor *ep_in = NULL;
 	struct usb_endpoint_descriptor *ep_out = NULL;
-	struct usb_host_config *config;
 	struct mceusb_dev *ir = NULL;
 	int pipe, maxp, i;
 	char buf[63], name[128] = "";
@@ -929,7 +932,6 @@ static int __devinit mceusb_dev_probe(st
 
 	dev_dbg(&intf->dev, ": %s called\n", __func__);
 
-	config = dev->actconfig;
 	idesc  = intf->cur_altsetting;
 
 	is_gen3 = usb_match_id(intf, gen3_list) ? 1 : 0;
diff -Naurp linux-2.6.35/drivers/media/IR/rc-map.c linux-2.6.35.new/drivers/media/IR/rc-map.c
--- linux-2.6.35/drivers/media/IR/rc-map.c	2010-08-01 18:11:14.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/rc-map.c	2010-09-09 23:21:49.000000000 -0400
@@ -82,3 +82,26 @@ void ir_unregister_map(struct rc_keymap 
 }
 EXPORT_SYMBOL_GPL(ir_unregister_map);
 
+
+static struct ir_scancode empty[] = {
+	{ 0x2a, KEY_COFFEE },
+};
+
+static struct rc_keymap empty_map = {
+	.map = {
+		.scan    = empty,
+		.size    = ARRAY_SIZE(empty),
+		.ir_type = IR_TYPE_UNKNOWN,	/* Legacy IR type */
+		.name    = RC_MAP_EMPTY,
+	}
+};
+
+int ir_rcmap_init(void)
+{
+	return ir_register_map(&empty_map);
+}
+
+void ir_rcmap_cleanup(void)
+{
+	ir_unregister_map(&empty_map);
+}
diff -Naurp linux-2.6.35/drivers/media/IR/streamzap.c linux-2.6.35.new/drivers/media/IR/streamzap.c
--- linux-2.6.35/drivers/media/IR/streamzap.c	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/media/IR/streamzap.c	2010-09-09 23:21:42.000000000 -0400
@@ -71,9 +71,9 @@ MODULE_DEVICE_TABLE(usb, streamzap_table
 
 /* from ir-rc5-sz-decoder.c */
 #ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE
-#define load_rc5_sz_decode()   request_module("ir-rc5-sz-decoder")
+#define load_rc5_sz_decode()    request_module("ir-rc5-sz-decoder")
 #else
-#define load_rc5_sz_decode()   0
+#define load_rc5_sz_decode()    0
 #endif
 
 enum StreamzapDecoderState {
@@ -244,9 +244,9 @@ static void streamzap_callback(struct ur
 		break;
 	}
 
-	dev_info(sz->dev, "%s: received urb, len %d\n", __func__, len);
+	dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
 	for (i = 0; i < len; i++) {
-		dev_info(sz->dev, "sz idx %d: %x\n",
+		dev_dbg(sz->dev, "sz idx %d: %x\n",
 			i, (unsigned char)sz->buf_in[i]);
 		switch (sz->decoder_state) {
 		case PulseSpace:
diff -Naurp linux-2.6.35/drivers/staging/lirc/Kconfig linux-2.6.35.new/drivers/staging/lirc/Kconfig
--- linux-2.6.35/drivers/staging/lirc/Kconfig	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/staging/lirc/Kconfig	2010-09-09 23:21:42.000000000 -0400
@@ -18,14 +18,6 @@ config LIRC_BT829
 	help
 	  Driver for the IR interface on BT829-based hardware
 
-config LIRC_ENE0100
-	tristate "ENE KB3924/ENE0100 CIR Port Reciever"
-	depends on LIRC_STAGING && PNP
-	help
-	  This is a driver for CIR port handled by ENE KB3924 embedded
-	  controller found on some notebooks.
-	  It appears on PNP list as ENE0100.
-
 config LIRC_I2C
 	tristate "I2C Based IR Receivers"
 	depends on LIRC_STAGING && I2C
diff -Naurp linux-2.6.35/drivers/staging/lirc/lirc_ene0100.c linux-2.6.35.new/drivers/staging/lirc/lirc_ene0100.c
--- linux-2.6.35/drivers/staging/lirc/lirc_ene0100.c	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/staging/lirc/lirc_ene0100.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,646 +0,0 @@
-/*
- * driver for ENE KB3926 B/C/D CIR (also known as ENE0100)
- *
- * Copyright (C) 2009 Maxim Levitsky <maximlevitsky@gmail.com>
- *
- * 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
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pnp.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include "lirc_ene0100.h"
-
-static int sample_period = 75;
-static int enable_idle = 1;
-static int enable_learning;
-
-static void ene_set_idle(struct ene_device *dev, int idle);
-static void ene_set_inputs(struct ene_device *dev, int enable);
-
-/* read a hardware register */
-static u8 ene_hw_read_reg(struct ene_device *dev, u16 reg)
-{
-	outb(reg >> 8, dev->hw_io + ENE_ADDR_HI);
-	outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO);
-	return inb(dev->hw_io + ENE_IO);
-}
-
-/* write a hardware register */
-static void ene_hw_write_reg(struct ene_device *dev, u16 reg, u8 value)
-{
-	outb(reg >> 8, dev->hw_io + ENE_ADDR_HI);
-	outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO);
-	outb(value, dev->hw_io + ENE_IO);
-}
-
-/* change specific bits in hardware register */
-static void ene_hw_write_reg_mask(struct ene_device *dev,
-				  u16 reg, u8 value, u8 mask)
-{
-	u8 regvalue;
-
-	outb(reg >> 8, dev->hw_io + ENE_ADDR_HI);
-	outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO);
-
-	regvalue = inb(dev->hw_io + ENE_IO) & ~mask;
-	regvalue |= (value & mask);
-	outb(regvalue, dev->hw_io + ENE_IO);
-}
-
-/* read irq status and ack it */
-static int ene_hw_irq_status(struct ene_device *dev, int *buffer_pointer)
-{
-	u8 irq_status;
-	u8 fw_flags1, fw_flags2;
-
-	fw_flags2 = ene_hw_read_reg(dev, ENE_FW2);
-
-	if (buffer_pointer)
-		*buffer_pointer = 4 * (fw_flags2 & ENE_FW2_BUF_HIGH);
-
-	if (dev->hw_revision < ENE_HW_C) {
-		irq_status = ene_hw_read_reg(dev, ENEB_IRQ_STATUS);
-
-		if (!(irq_status & ENEB_IRQ_STATUS_IR))
-			return 0;
-		ene_hw_write_reg(dev, ENEB_IRQ_STATUS,
-				 irq_status & ~ENEB_IRQ_STATUS_IR);
-
-		/* rev B support only recieving */
-		return ENE_IRQ_RX;
-	}
-
-	irq_status = ene_hw_read_reg(dev, ENEC_IRQ);
-
-	if (!(irq_status & ENEC_IRQ_STATUS))
-		return 0;
-
-	/* original driver does that twice - a workaround ? */
-	ene_hw_write_reg(dev, ENEC_IRQ, irq_status & ~ENEC_IRQ_STATUS);
-	ene_hw_write_reg(dev, ENEC_IRQ, irq_status & ~ENEC_IRQ_STATUS);
-
-	/* clear unknown flag in F8F9 */
-	if (fw_flags2 & ENE_FW2_IRQ_CLR)
-		ene_hw_write_reg(dev, ENE_FW2, fw_flags2 & ~ENE_FW2_IRQ_CLR);
-
-	/* check if this is a TX interrupt */
-	fw_flags1 = ene_hw_read_reg(dev, ENE_FW1);
-
-	if (fw_flags1 & ENE_FW1_TXIRQ) {
-		ene_hw_write_reg(dev, ENE_FW1, fw_flags1 & ~ENE_FW1_TXIRQ);
-		return ENE_IRQ_TX;
-	} else
-		return ENE_IRQ_RX;
-}
-
-static int ene_hw_detect(struct ene_device *dev)
-{
-	u8 chip_major, chip_minor;
-	u8 hw_revision, old_ver;
-	u8 tmp;
-	u8 fw_capabilities;
-
-	tmp = ene_hw_read_reg(dev, ENE_HW_UNK);
-	ene_hw_write_reg(dev, ENE_HW_UNK, tmp & ~ENE_HW_UNK_CLR);
-
-	chip_major = ene_hw_read_reg(dev, ENE_HW_VER_MAJOR);
-	chip_minor = ene_hw_read_reg(dev, ENE_HW_VER_MINOR);
-
-	ene_hw_write_reg(dev, ENE_HW_UNK, tmp);
-	hw_revision = ene_hw_read_reg(dev, ENE_HW_VERSION);
-	old_ver = ene_hw_read_reg(dev, ENE_HW_VER_OLD);
-
-	if (hw_revision == 0xFF) {
-
-		ene_printk(KERN_WARNING, "device seems to be disabled\n");
-		ene_printk(KERN_WARNING,
-			"send a mail to lirc-list@lists.sourceforge.net\n");
-		ene_printk(KERN_WARNING, "please attach output of acpidump\n");
-
-		return -ENODEV;
-	}
-
-	if (chip_major == 0x33) {
-		ene_printk(KERN_WARNING, "chips 0x33xx aren't supported yet\n");
-		return -ENODEV;
-	}
-
-	if (chip_major == 0x39 && chip_minor == 0x26 && hw_revision == 0xC0) {
-		dev->hw_revision = ENE_HW_C;
-		ene_printk(KERN_WARNING,
-		       "KB3926C detected, driver support is not complete!\n");
-
-	} else if (old_ver == 0x24 && hw_revision == 0xC0) {
-		dev->hw_revision = ENE_HW_B;
-		ene_printk(KERN_NOTICE, "KB3926B detected\n");
-	} else {
-		dev->hw_revision = ENE_HW_D;
-		ene_printk(KERN_WARNING,
-			"unknown ENE chip detected, assuming KB3926D\n");
-		ene_printk(KERN_WARNING, "driver support incomplete");
-
-	}
-
-	ene_printk(KERN_DEBUG, "chip is 0x%02x%02x - 0x%02x, 0x%02x\n",
-		chip_major, chip_minor, old_ver, hw_revision);
-
-
-	/* detect features hardware supports */
-
-	if (dev->hw_revision < ENE_HW_C)
-		return 0;
-
-	fw_capabilities = ene_hw_read_reg(dev, ENE_FW2);
-
-	dev->hw_gpio40_learning = fw_capabilities & ENE_FW2_GP40_AS_LEARN;
-	dev->hw_learning_and_tx_capable = fw_capabilities & ENE_FW2_LEARNING;
-
-	dev->hw_fan_as_normal_input = dev->hw_learning_and_tx_capable &&
-	    fw_capabilities & ENE_FW2_FAN_AS_NRML_IN;
-
-	ene_printk(KERN_NOTICE, "hardware features:\n");
-	ene_printk(KERN_NOTICE,
-		"learning and tx %s, gpio40_learn %s, fan_in %s\n",
-	       dev->hw_learning_and_tx_capable ? "on" : "off",
-	       dev->hw_gpio40_learning ? "on" : "off",
-	       dev->hw_fan_as_normal_input ? "on" : "off");
-
-	if (!dev->hw_learning_and_tx_capable && enable_learning)
-		enable_learning = 0;
-
-	if (dev->hw_learning_and_tx_capable) {
-		ene_printk(KERN_WARNING,
-		"Device supports transmitting, but the driver doesn't\n");
-		ene_printk(KERN_WARNING,
-		"due to lack of hardware to test against.\n");
-		ene_printk(KERN_WARNING,
-		"Send a mail to: lirc-list@lists.sourceforge.net\n");
-	}
-	return 0;
-}
-
-/* hardware initialization */
-static int ene_hw_init(void *data)
-{
-	u8 reg_value;
-	struct ene_device *dev = (struct ene_device *)data;
-	dev->in_use = 1;
-
-	if (dev->hw_revision < ENE_HW_C) {
-		ene_hw_write_reg(dev, ENEB_IRQ, dev->irq << 1);
-		ene_hw_write_reg(dev, ENEB_IRQ_UNK1, 0x01);
-	} else {
-		reg_value = ene_hw_read_reg(dev, ENEC_IRQ) & 0xF0;
-		reg_value |= ENEC_IRQ_UNK_EN;
-		reg_value &= ~ENEC_IRQ_STATUS;
-		reg_value |= (dev->irq & ENEC_IRQ_MASK);
-		ene_hw_write_reg(dev, ENEC_IRQ, reg_value);
-		ene_hw_write_reg(dev, ENE_TX_UNK1, 0x63);
-	}
-
-	ene_hw_write_reg(dev, ENE_CIR_CONF2, 0x00);
-	ene_set_inputs(dev, enable_learning);
-
-	/* set sampling period */
-	ene_hw_write_reg(dev, ENE_CIR_SAMPLE_PERIOD, sample_period);
-
-	/* ack any pending irqs - just in case */
-	ene_hw_irq_status(dev, NULL);
-
-	/* enter idle mode */
-	ene_set_idle(dev, 1);
-
-	/* enable firmware bits */
-	ene_hw_write_reg_mask(dev, ENE_FW1,
-			      ENE_FW1_ENABLE | ENE_FW1_IRQ,
-			      ENE_FW1_ENABLE | ENE_FW1_IRQ);
-	/* clear stats */
-	dev->sample = 0;
-	return 0;
-}
-
-/* this enables gpio40 signal, used if connected to wide band input*/
-static void ene_enable_gpio40(struct ene_device *dev, int enable)
-{
-	ene_hw_write_reg_mask(dev, ENE_CIR_CONF1, enable ?
-			      0 : ENE_CIR_CONF2_GPIO40DIS,
-			      ENE_CIR_CONF2_GPIO40DIS);
-}
-
-/* this enables the classic sampler */
-static void ene_enable_normal_recieve(struct ene_device *dev, int enable)
-{
-	ene_hw_write_reg(dev, ENE_CIR_CONF1, enable ? ENE_CIR_CONF1_ADC_ON : 0);
-}
-
-/* this enables recieve via fan input */
-static void ene_enable_fan_recieve(struct ene_device *dev, int enable)
-{
-	if (!enable)
-		ene_hw_write_reg(dev, ENE_FAN_AS_IN1, 0);
-	else {
-		ene_hw_write_reg(dev, ENE_FAN_AS_IN1, ENE_FAN_AS_IN1_EN);
-		ene_hw_write_reg(dev, ENE_FAN_AS_IN2, ENE_FAN_AS_IN2_EN);
-	}
-	dev->fan_input_inuse = enable;
-}
-
-/* determine which input to use*/
-static void ene_set_inputs(struct ene_device *dev, int learning_enable)
-{
-	ene_enable_normal_recieve(dev, 1);
-
-	/* old hardware doesn't support learning mode for sure */
-	if (dev->hw_revision <= ENE_HW_B)
-		return;
-
-	/* reciever not learning capable, still set gpio40 correctly */
-	if (!dev->hw_learning_and_tx_capable) {
-		ene_enable_gpio40(dev, !dev->hw_gpio40_learning);
-		return;
-	}
-
-	/* enable learning mode */
-	if (learning_enable) {
-		ene_enable_gpio40(dev, dev->hw_gpio40_learning);
-
-		/* fan input is not used for learning */
-		if (dev->hw_fan_as_normal_input)
-			ene_enable_fan_recieve(dev, 0);
-
-	/* disable learning mode */
-	} else {
-		if (dev->hw_fan_as_normal_input) {
-			ene_enable_fan_recieve(dev, 1);
-			ene_enable_normal_recieve(dev, 0);
-		} else
-			ene_enable_gpio40(dev, !dev->hw_gpio40_learning);
-	}
-
-	/* set few additional settings for this mode */
-	ene_hw_write_reg_mask(dev, ENE_CIR_CONF1, learning_enable ?
-			      ENE_CIR_CONF1_LEARN1 : 0, ENE_CIR_CONF1_LEARN1);
-
-	ene_hw_write_reg_mask(dev, ENE_CIR_CONF2, learning_enable ?
-			      ENE_CIR_CONF2_LEARN2 : 0, ENE_CIR_CONF2_LEARN2);
-}
-
-/* deinitialization */
-static void ene_hw_deinit(void *data)
-{
-	struct ene_device *dev = (struct ene_device *)data;
-
-	/* disable samplers */
-	ene_enable_normal_recieve(dev, 0);
-
-	if (dev->hw_fan_as_normal_input)
-		ene_enable_fan_recieve(dev, 0);
-
-	/* disable hardware IRQ and firmware flag */
-	ene_hw_write_reg_mask(dev, ENE_FW1, 0, ENE_FW1_ENABLE | ENE_FW1_IRQ);
-
-	ene_set_idle(dev, 1);
-	dev->in_use = 0;
-}
-
-/*  sends current sample to userspace */
-static void send_sample(struct ene_device *dev)
-{
-	int value = abs(dev->sample) & PULSE_MASK;
-
-	if (dev->sample > 0)
-		value |= PULSE_BIT;
-
-	if (!lirc_buffer_full(dev->lirc_driver->rbuf)) {
-		lirc_buffer_write(dev->lirc_driver->rbuf, (void *)&value);
-		wake_up(&dev->lirc_driver->rbuf->wait_poll);
-	}
-	dev->sample = 0;
-}
-
-/*  this updates current sample */
-static void update_sample(struct ene_device *dev, int sample)
-{
-	if (!dev->sample)
-		dev->sample = sample;
-	else if (same_sign(dev->sample, sample))
-		dev->sample += sample;
-	else {
-		send_sample(dev);
-		dev->sample = sample;
-	}
-}
-
-/* enable or disable idle mode */
-static void ene_set_idle(struct ene_device *dev, int idle)
-{
-	struct timeval now;
-	int disable = idle && enable_idle && (dev->hw_revision < ENE_HW_C);
-
-	ene_hw_write_reg_mask(dev, ENE_CIR_SAMPLE_PERIOD,
-			      disable ? 0 : ENE_CIR_SAMPLE_OVERFLOW,
-			      ENE_CIR_SAMPLE_OVERFLOW);
-	dev->idle = idle;
-
-	/* remember when we have entered the idle mode */
-	if (idle) {
-		do_gettimeofday(&dev->gap_start);
-		return;
-	}
-
-	/* send the gap between keypresses now */
-	do_gettimeofday(&now);
-
-	if (now.tv_sec - dev->gap_start.tv_sec > 16)
-		dev->sample = space(PULSE_MASK);
-	else
-		dev->sample = dev->sample +
-		    space(1000000ull * (now.tv_sec - dev->gap_start.tv_sec))
-		    + space(now.tv_usec - dev->gap_start.tv_usec);
-
-	if (abs(dev->sample) > PULSE_MASK)
-		dev->sample = space(PULSE_MASK);
-	send_sample(dev);
-}
-
-/* interrupt handler */
-static irqreturn_t ene_hw_irq(int irq, void *data)
-{
-	u16 hw_value;
-	int i, hw_sample;
-	int space;
-	int buffer_pointer;
-	int irq_status;
-
-	struct ene_device *dev = (struct ene_device *)data;
-	irq_status = ene_hw_irq_status(dev, &buffer_pointer);
-
-	if (!irq_status)
-		return IRQ_NONE;
-
-	/* TODO: only RX for now */
-	if (irq_status == ENE_IRQ_TX)
-		return IRQ_HANDLED;
-
-	for (i = 0; i < ENE_SAMPLES_SIZE; i++) {
-
-		hw_value = ene_hw_read_reg(dev,
-				ENE_SAMPLE_BUFFER + buffer_pointer + i);
-
-		if (dev->fan_input_inuse) {
-			/* read high part of the sample */
-			hw_value |= ene_hw_read_reg(dev,
-			    ENE_SAMPLE_BUFFER_FAN + buffer_pointer + i) << 8;
-
-			/* test for _space_ bit */
-			space = !(hw_value & ENE_FAN_SMPL_PULS_MSK);
-
-			/* clear space bit, and other unused bits */
-			hw_value &= ENE_FAN_VALUE_MASK;
-			hw_sample = hw_value * ENE_SAMPLE_PERIOD_FAN;
-
-		} else {
-			space = hw_value & ENE_SAMPLE_SPC_MASK;
-			hw_value &= ENE_SAMPLE_VALUE_MASK;
-			hw_sample = hw_value * sample_period;
-		}
-
-		/* no more data */
-		if (!(hw_value))
-			break;
-
-		if (space)
-			hw_sample *= -1;
-
-		/* overflow sample recieved, handle it */
-
-		if (!dev->fan_input_inuse && hw_value == ENE_SAMPLE_OVERFLOW) {
-
-			if (dev->idle)
-				continue;
-
-			if (dev->sample > 0 || abs(dev->sample) <= ENE_MAXGAP)
-				update_sample(dev, hw_sample);
-			else
-				ene_set_idle(dev, 1);
-
-			continue;
-		}
-
-		/* normal first sample recieved */
-		if (!dev->fan_input_inuse && dev->idle) {
-			ene_set_idle(dev, 0);
-
-			/* discard first recieved value, its random
-			   since its the time signal was off before
-			   first pulse if idle mode is enabled, HW
-			   does that for us */
-
-			if (!enable_idle)
-				continue;
-		}
-		update_sample(dev, hw_sample);
-		send_sample(dev);
-	}
-	return IRQ_HANDLED;
-}
-
-static int ene_probe(struct pnp_dev *pnp_dev,
-		     const struct pnp_device_id *dev_id)
-{
-	struct ene_device *dev;
-	struct lirc_driver *lirc_driver;
-	int error = -ENOMEM;
-
-	dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
-
-	if (!dev)
-		goto err1;
-
-	dev->pnp_dev = pnp_dev;
-	pnp_set_drvdata(pnp_dev, dev);
-
-
-	/* prepare lirc interface */
-	error = -ENOMEM;
-	lirc_driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
-
-	if (!lirc_driver)
-		goto err2;
-
-	dev->lirc_driver = lirc_driver;
-
-	strcpy(lirc_driver->name, ENE_DRIVER_NAME);
-	lirc_driver->minor = -1;
-	lirc_driver->code_length = sizeof(int) * 8;
-	lirc_driver->features = LIRC_CAN_REC_MODE2;
-	lirc_driver->data = dev;
-	lirc_driver->set_use_inc = ene_hw_init;
-	lirc_driver->set_use_dec = ene_hw_deinit;
-	lirc_driver->dev = &pnp_dev->dev;
-	lirc_driver->owner = THIS_MODULE;
-
-	lirc_driver->rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
-
-	if (!lirc_driver->rbuf)
-		goto err3;
-
-	if (lirc_buffer_init(lirc_driver->rbuf, sizeof(int), sizeof(int) * 256))
-		goto err4;
-
-	error = -ENODEV;
-	if (lirc_register_driver(lirc_driver))
-		goto err5;
-
-	/* validate resources */
-	if (!pnp_port_valid(pnp_dev, 0) ||
-	    pnp_port_len(pnp_dev, 0) < ENE_MAX_IO)
-		goto err6;
-
-	if (!pnp_irq_valid(pnp_dev, 0))
-		goto err6;
-
-	dev->hw_io = pnp_port_start(pnp_dev, 0);
-	dev->irq = pnp_irq(pnp_dev, 0);
-
-	/* claim the resources */
-	error = -EBUSY;
-	if (!request_region(dev->hw_io, ENE_MAX_IO, ENE_DRIVER_NAME))
-		goto err6;
-
-	if (request_irq(dev->irq, ene_hw_irq,
-			IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev))
-		goto err7;
-
-	/* detect hardware version and features */
-	error = ene_hw_detect(dev);
-	if (error)
-		goto err8;
-
-	ene_printk(KERN_NOTICE, "driver has been succesfully loaded\n");
-	return 0;
-
-err8:
-	free_irq(dev->irq, dev);
-err7:
-	release_region(dev->hw_io, ENE_MAX_IO);
-err6:
-	lirc_unregister_driver(lirc_driver->minor);
-err5:
-	lirc_buffer_free(lirc_driver->rbuf);
-err4:
-	kfree(lirc_driver->rbuf);
-err3:
-	kfree(lirc_driver);
-err2:
-	kfree(dev);
-err1:
-	return error;
-}
-
-static void ene_remove(struct pnp_dev *pnp_dev)
-{
-	struct ene_device *dev = pnp_get_drvdata(pnp_dev);
-	ene_hw_deinit(dev);
-	free_irq(dev->irq, dev);
-	release_region(dev->hw_io, ENE_MAX_IO);
-	lirc_unregister_driver(dev->lirc_driver->minor);
-	lirc_buffer_free(dev->lirc_driver->rbuf);
-	kfree(dev->lirc_driver);
-	kfree(dev);
-}
-
-#ifdef CONFIG_PM
-
-/* TODO: make 'wake on IR' configurable and add .shutdown */
-/* currently impossible due to lack of kernel support */
-
-static int ene_suspend(struct pnp_dev *pnp_dev, pm_message_t state)
-{
-	struct ene_device *dev = pnp_get_drvdata(pnp_dev);
-	ene_hw_write_reg_mask(dev, ENE_FW1, ENE_FW1_WAKE, ENE_FW1_WAKE);
-	return 0;
-}
-
-static int ene_resume(struct pnp_dev *pnp_dev)
-{
-	struct ene_device *dev = pnp_get_drvdata(pnp_dev);
-	if (dev->in_use)
-		ene_hw_init(dev);
-
-	ene_hw_write_reg_mask(dev, ENE_FW1, 0, ENE_FW1_WAKE);
-	return 0;
-}
-
-#endif
-
-static const struct pnp_device_id ene_ids[] = {
-	{.id = "ENE0100",},
-	{},
-};
-
-static struct pnp_driver ene_driver = {
-	.name = ENE_DRIVER_NAME,
-	.id_table = ene_ids,
-	.flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
-
-	.probe = ene_probe,
-	.remove = __devexit_p(ene_remove),
-
-#ifdef CONFIG_PM
-	.suspend = ene_suspend,
-	.resume = ene_resume,
-#endif
-};
-
-static int __init ene_init(void)
-{
-	if (sample_period < 5) {
-		ene_printk(KERN_ERR, "sample period must be at\n");
-		ene_printk(KERN_ERR, "least 5 us, (at least 30 recommended)\n");
-		return -EINVAL;
-	}
-	return pnp_register_driver(&ene_driver);
-}
-
-static void ene_exit(void)
-{
-	pnp_unregister_driver(&ene_driver);
-}
-
-module_param(sample_period, int, S_IRUGO);
-MODULE_PARM_DESC(sample_period, "Hardware sample period (75 us default)");
-
-module_param(enable_idle, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(enable_idle,
-	"Enables turning off signal sampling after long inactivity time; "
-	"if disabled might help detecting input signal (default: enabled)");
-
-module_param(enable_learning, bool, S_IRUGO);
-MODULE_PARM_DESC(enable_learning, "Use wide band (learning) reciever");
-
-MODULE_DEVICE_TABLE(pnp, ene_ids);
-MODULE_DESCRIPTION
-    ("LIRC driver for KB3926B/KB3926C/KB3926D (aka ENE0100) CIR port");
-MODULE_AUTHOR("Maxim Levitsky");
-MODULE_LICENSE("GPL");
-
-module_init(ene_init);
-module_exit(ene_exit);
diff -Naurp linux-2.6.35/drivers/staging/lirc/lirc_ene0100.h linux-2.6.35.new/drivers/staging/lirc/lirc_ene0100.h
--- linux-2.6.35/drivers/staging/lirc/lirc_ene0100.h	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/staging/lirc/lirc_ene0100.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,169 +0,0 @@
-/*
- * driver for ENE KB3926 B/C/D CIR (also known as ENE0100)
- *
- * Copyright (C) 2009 Maxim Levitsky <maximlevitsky@gmail.com>
- *
- * 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
- */
-
-#include <media/lirc.h>
-#include <media/lirc_dev.h>
-
-/* hardware address */
-#define ENE_STATUS		0	 /* hardware status - unused */
-#define ENE_ADDR_HI		1	 /* hi byte of register address */
-#define ENE_ADDR_LO		2	 /* low byte of register address */
-#define ENE_IO			3	 /* read/write window */
-#define ENE_MAX_IO		4
-
-/* 8 bytes of samples, divided in 2 halfs*/
-#define ENE_SAMPLE_BUFFER	0xF8F0	 /* regular sample buffer */
-#define ENE_SAMPLE_SPC_MASK	(1 << 7) /* sample is space */
-#define ENE_SAMPLE_VALUE_MASK	0x7F
-#define ENE_SAMPLE_OVERFLOW	0x7F
-#define ENE_SAMPLES_SIZE	4
-
-/* fan input sample buffer */
-#define ENE_SAMPLE_BUFFER_FAN	0xF8FB	 /* this buffer holds high byte of */
-					 /* each sample of normal buffer */
-
-#define ENE_FAN_SMPL_PULS_MSK	0x8000	 /* this bit of combined sample */
-					 /* if set, says that sample is pulse */
-#define ENE_FAN_VALUE_MASK	0x0FFF   /* mask for valid bits of the value */
-
-/* first firmware register */
-#define ENE_FW1			0xF8F8
-#define	ENE_FW1_ENABLE		(1 << 0) /* enable fw processing */
-#define ENE_FW1_TXIRQ		(1 << 1) /* TX interrupt pending */
-#define ENE_FW1_WAKE		(1 << 6) /* enable wake from S3 */
-#define ENE_FW1_IRQ		(1 << 7) /* enable interrupt */
-
-/* second firmware register */
-#define ENE_FW2			0xF8F9
-#define ENE_FW2_BUF_HIGH	(1 << 0) /* which half of the buffer to read */
-#define ENE_FW2_IRQ_CLR		(1 << 2) /* clear this on IRQ */
-#define ENE_FW2_GP40_AS_LEARN	(1 << 4) /* normal input is used as */
-					 /* learning input */
-#define ENE_FW2_FAN_AS_NRML_IN	(1 << 6) /* fan is used as normal input */
-#define ENE_FW2_LEARNING	(1 << 7) /* hardware supports learning and TX */
-
-/* fan as input settings - only if learning capable */
-#define ENE_FAN_AS_IN1		0xFE30   /* fan init reg 1 */
-#define ENE_FAN_AS_IN1_EN	0xCD
-#define ENE_FAN_AS_IN2		0xFE31   /* fan init reg 2 */
-#define ENE_FAN_AS_IN2_EN	0x03
-#define ENE_SAMPLE_PERIOD_FAN   61	 /* fan input has fixed sample period */
-
-/* IRQ registers block (for revision B) */
-#define ENEB_IRQ		0xFD09	 /* IRQ number */
-#define ENEB_IRQ_UNK1		0xFD17	 /* unknown setting = 1 */
-#define ENEB_IRQ_STATUS		0xFD80	 /* irq status */
-#define ENEB_IRQ_STATUS_IR	(1 << 5) /* IR irq */
-
-/* IRQ registers block (for revision C,D) */
-#define ENEC_IRQ		0xFE9B	 /* new irq settings register */
-#define ENEC_IRQ_MASK		0x0F	 /* irq number mask */
-#define ENEC_IRQ_UNK_EN		(1 << 4) /* always enabled */
-#define ENEC_IRQ_STATUS		(1 << 5) /* irq status and ACK */
-
-/* CIR block settings */
-#define ENE_CIR_CONF1		0xFEC0
-#define ENE_CIR_CONF1_ADC_ON	0x7	 /* reciever on gpio40 enabled */
-#define ENE_CIR_CONF1_LEARN1	(1 << 3) /* enabled on learning mode */
-#define ENE_CIR_CONF1_TX_ON	0x30	 /* enabled on transmit */
-#define ENE_CIR_CONF1_TX_CARR	(1 << 7) /* send TX carrier or not */
-
-#define ENE_CIR_CONF2		0xFEC1	 /* unknown setting = 0 */
-#define ENE_CIR_CONF2_LEARN2	(1 << 4) /* set on enable learning */
-#define ENE_CIR_CONF2_GPIO40DIS	(1 << 5) /* disable normal input via gpio40 */
-
-#define ENE_CIR_SAMPLE_PERIOD	0xFEC8	 /* sample period in us */
-#define ENE_CIR_SAMPLE_OVERFLOW	(1 << 7) /* interrupt on overflows if set */
-
-
-/* transmitter - not implemented yet */
-/* KB3926C and higher */
-/* transmission is very similiar to recieving, a byte is written to */
-/* ENE_TX_INPUT, in same manner as it is read from sample buffer */
-/* sample period is fixed*/
-
-
-/* transmitter ports */
-#define ENE_TX_PORT1		0xFC01	 /* this enables one or both */
-#define ENE_TX_PORT1_EN		(1 << 5) /* TX ports */
-#define ENE_TX_PORT2		0xFC08
-#define ENE_TX_PORT2_EN		(1 << 1)
-
-#define ENE_TX_INPUT		0xFEC9	 /* next byte to transmit */
-#define ENE_TX_SPC_MASK		(1 << 7) /* Transmitted sample is space */
-#define ENE_TX_UNK1		0xFECB	 /* set to 0x63 */
-#define ENE_TX_SMPL_PERIOD	50	 /* transmit sample period */
-
-
-#define ENE_TX_CARRIER		0xFECE	 /* TX carrier * 2 (khz) */
-#define ENE_TX_CARRIER_UNKBIT	0x80	 /* This bit set on transmit */
-#define ENE_TX_CARRIER_LOW	0xFECF	 /* TX carrier / 2 */
-
-/* Hardware versions */
-#define ENE_HW_VERSION		0xFF00	 /* hardware revision */
-#define ENE_HW_UNK		0xFF1D
-#define ENE_HW_UNK_CLR		(1 << 2)
-#define ENE_HW_VER_MAJOR	0xFF1E	 /* chip version */
-#define ENE_HW_VER_MINOR	0xFF1F
-#define ENE_HW_VER_OLD		0xFD00
-
-#define same_sign(a, b) ((((a) > 0) && (b) > 0) || ((a) < 0 && (b) < 0))
-
-#define ENE_DRIVER_NAME		"enecir"
-#define ENE_MAXGAP		250000	 /* this is amount of time we wait
-					 before turning the sampler, chosen
-					 arbitry */
-
-#define space(len)	       (-(len))	 /* add a space */
-
-/* software defines */
-#define ENE_IRQ_RX		1
-#define ENE_IRQ_TX		2
-
-#define  ENE_HW_B		1	/* 3926B */
-#define  ENE_HW_C		2	/* 3926C */
-#define  ENE_HW_D		3	/* 3926D */
-
-#define ene_printk(level, text, ...) \
-	printk(level ENE_DRIVER_NAME ": " text, ## __VA_ARGS__)
-
-struct ene_device {
-	struct pnp_dev *pnp_dev;
-	struct lirc_driver *lirc_driver;
-
-	/* hw settings */
-	unsigned long hw_io;
-	int irq;
-
-	int hw_revision;			/* hardware revision */
-	int hw_learning_and_tx_capable;		/* learning capable */
-	int hw_gpio40_learning;			/* gpio40 is learning */
-	int hw_fan_as_normal_input;	/* fan input is used as regular input */
-
-	/* device data */
-	int idle;
-	int fan_input_inuse;
-
-	int sample;
-	int in_use;
-
-	struct timeval gap_start;
-};
diff -Naurp linux-2.6.35/drivers/staging/lirc/Makefile linux-2.6.35.new/drivers/staging/lirc/Makefile
--- linux-2.6.35/drivers/staging/lirc/Makefile	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/drivers/staging/lirc/Makefile	2010-09-09 23:21:42.000000000 -0400
@@ -4,7 +4,6 @@
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_LIRC_BT829)	+= lirc_bt829.o
-obj-$(CONFIG_LIRC_ENE0100)	+= lirc_ene0100.o
 obj-$(CONFIG_LIRC_I2C)		+= lirc_i2c.o
 obj-$(CONFIG_LIRC_IGORPLUGUSB)	+= lirc_igorplugusb.o
 obj-$(CONFIG_LIRC_IMON)		+= lirc_imon.o
diff -Naurp linux-2.6.35/include/media/ir-core.h linux-2.6.35.new/include/media/ir-core.h
--- linux-2.6.35/include/media/ir-core.h	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/include/media/ir-core.h	2010-09-09 23:21:49.000000000 -0400
@@ -41,6 +41,11 @@ enum rc_driver_type {
  *	anything with it. Yet, as the same keycode table can be used with other
  *	devices, a mask is provided to allow its usage. Drivers should generally
  *	leave this field in blank
+ * @timeout: optional time after which device stops sending data
+ * @min_timeout: minimum timeout supported by device
+ * @max_timeout: maximum timeout supported by device
+ * @rx_resolution : resolution (in ns) of input sampler
+ * @tx_resolution: resolution (in ns) of output sampler
  * @priv: driver-specific data, to be used on the callbacks
  * @change_protocol: allow changing the protocol used on hardware decoders
  * @open: callback to allow drivers to enable polling/irq when IR input device
@@ -49,19 +54,36 @@ enum rc_driver_type {
  *	is opened.
  * @s_tx_mask: set transmitter mask (for devices with multiple tx outputs)
  * @s_tx_carrier: set transmit carrier frequency
+ * @s_tx_duty_cycle: set transmit duty cycle (0% - 100%)
+ * @s_rx_carrier: inform driver about carrier it is expected to handle
  * @tx_ir: transmit IR
+ * @s_idle: optional: enable/disable hardware idle mode, upon which,
+	device doesn't interrupt host until it sees IR pulses
+ * @s_learning_mode: enable wide band receiver used for learning
  */
 struct ir_dev_props {
 	enum rc_driver_type	driver_type;
 	unsigned long		allowed_protos;
 	u32			scanmask;
+
+	u32			timeout;
+	u32			min_timeout;
+	u32			max_timeout;
+
+	u32			rx_resolution;
+	u32			tx_resolution;
+
 	void			*priv;
 	int			(*change_protocol)(void *priv, u64 ir_type);
 	int			(*open)(void *priv);
 	void			(*close)(void *priv);
 	int			(*s_tx_mask)(void *priv, u32 mask);
 	int			(*s_tx_carrier)(void *priv, u32 carrier);
+	int			(*s_tx_duty_cycle)(void *priv, u32 duty_cycle);
+	int			(*s_rx_carrier_range)(void *priv, u32 min, u32 max);
 	int			(*tx_ir)(void *priv, int *txbuf, u32 n);
+	void			(*s_idle)(void *priv, int enable);
+	int			(*s_learning_mode)(void *priv, int enable);
 };
 
 struct ir_input_dev {
@@ -69,9 +91,10 @@ struct ir_input_dev {
 	char				*driver_name;	/* Name of the driver module */
 	struct ir_scancode_table	rc_tab;		/* scan/key table */
 	unsigned long			devno;		/* device number */
-	const struct ir_dev_props	*props;		/* Device properties */
+	struct ir_dev_props		*props;		/* Device properties */
 	struct ir_raw_event_ctrl	*raw;		/* for raw pulse/space events */
 	struct input_dev		*input_dev;	/* the input device associated with this device */
+	bool				idle;
 
 	/* key info - needed by IR keycode handlers */
 	spinlock_t			keylock;	/* protects the below members */
@@ -95,12 +118,12 @@ enum raw_event_type {
 /* From ir-keytable.c */
 int __ir_input_register(struct input_dev *dev,
 		      const struct ir_scancode_table *ir_codes,
-		      const struct ir_dev_props *props,
+		      struct ir_dev_props *props,
 		      const char *driver_name);
 
 static inline int ir_input_register(struct input_dev *dev,
 		      const char *map_name,
-		      const struct ir_dev_props *props,
+		      struct ir_dev_props *props,
 		      const char *driver_name) {
 	struct ir_scancode_table *ir_codes;
 	struct ir_input_dev *ir_dev;
@@ -110,8 +133,12 @@ static inline int ir_input_register(stru
 		return -EINVAL;
 
 	ir_codes = get_rc_map(map_name);
-	if (!ir_codes)
-		return -EINVAL;
+	if (!ir_codes) {
+		ir_codes = get_rc_map(RC_MAP_EMPTY);
+
+		if (!ir_codes)
+			return -EINVAL;
+	}
 
 	rc = __ir_input_register(dev, ir_codes, props, driver_name);
 	if (rc < 0)
@@ -144,6 +171,10 @@ struct ir_raw_event {
 void ir_raw_event_handle(struct input_dev *input_dev);
 int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev);
 int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type);
+int ir_raw_event_store_with_filter(struct input_dev *input_dev,
+				struct ir_raw_event *ev);
+void ir_raw_event_set_idle(struct input_dev *input_dev, int idle);
+
 static inline void ir_raw_event_reset(struct input_dev *input_dev)
 {
 	struct ir_raw_event ev = { .pulse = false, .duration = 0 };
diff -Naurp linux-2.6.35/include/media/lirc.h linux-2.6.35.new/include/media/lirc.h
--- linux-2.6.35/include/media/lirc.h	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/include/media/lirc.h	2010-09-09 23:21:42.000000000 -0400
@@ -77,6 +77,7 @@
 #define LIRC_CAN_SET_REC_FILTER           0x08000000
 
 #define LIRC_CAN_MEASURE_CARRIER          0x02000000
+#define LIRC_CAN_USE_WIDEBAND_RECEIVER    0x04000000
 
 #define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK)
 #define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK)
@@ -145,7 +146,7 @@
  * if enabled from the next key press on the driver will send
  * LIRC_MODE2_FREQUENCY packets
  */
-#define LIRC_SET_MEASURE_CARRIER_MODE  _IOW('i', 0x0000001d, __u32)
+#define LIRC_SET_MEASURE_CARRIER_MODE	_IOW('i', 0x0000001d, __u32)
 
 /*
  * to set a range use
@@ -162,4 +163,6 @@
 #define LIRC_SETUP_START               _IO('i', 0x00000021)
 #define LIRC_SETUP_END                 _IO('i', 0x00000022)
 
+#define LIRC_SET_WIDEBAND_RECEIVER     _IOW('i', 0x00000023, __u32)
+
 #endif
diff -Naurp linux-2.6.35/include/media/rc-map.h linux-2.6.35.new/include/media/rc-map.h
--- linux-2.6.35/include/media/rc-map.h	2010-09-09 23:19:00.000000000 -0400
+++ linux-2.6.35.new/include/media/rc-map.h	2010-09-09 23:21:42.000000000 -0400
@@ -70,6 +70,8 @@ void rc_map_init(void);
 #define RC_MAP_BUDGET_CI_OLD             "rc-budget-ci-old"
 #define RC_MAP_CINERGY_1400              "rc-cinergy-1400"
 #define RC_MAP_CINERGY                   "rc-cinergy"
+#define RC_MAP_DIB0700_NEC_TABLE         "rc-dib0700-nec"
+#define RC_MAP_DIB0700_RC5_TABLE         "rc-dib0700-rc5"
 #define RC_MAP_DM1105_NEC                "rc-dm1105-nec"
 #define RC_MAP_DNTV_LIVE_DVBT_PRO        "rc-dntv-live-dvbt-pro"
 #define RC_MAP_DNTV_LIVE_DVB_T           "rc-dntv-live-dvb-t"
@@ -125,6 +127,7 @@ void rc_map_init(void);
 #define RC_MAP_VIDEOMATE_TV_PVR          "rc-videomate-tv-pvr"
 #define RC_MAP_WINFAST                   "rc-winfast"
 #define RC_MAP_WINFAST_USBII_DELUXE      "rc-winfast-usbii-deluxe"
+
 /*
  * Please, do not just append newer Remote Controller names at the end.
  * The names should be ordered in alphabetical order