[kernel/f14/master] ir-core rebase to current upstream

Jarod Wilson jwilson at fedoraproject.org
Fri Sep 10 15:58:13 UTC 2010


commit 17a76a95c4958dbe264bbd1b2cdb84be681fbef8
Author: Jarod Wilson <jarod at redhat.com>
Date:   Fri Sep 10 11:57:42 2010 -0400

    ir-core rebase to current upstream
    
    Signed-off-by: Jarod Wilson <jarod at redhat.com>

 config-generic                           |    3 +
 kernel.spec                              |    6 +-
 linux-2.6-v4l-dvb-ir-core-update-2.patch | 3989 ++++++++++++++++++++++++++++++
 3 files changed, 3997 insertions(+), 1 deletions(-)
---
diff --git a/config-generic b/config-generic
index d7269a5..cf8619a 100644
--- a/config-generic
+++ b/config-generic
@@ -2582,6 +2582,7 @@ CONFIG_VIDEO_PVRUSB2_SYSFS=y
 # CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
 
 CONFIG_RC_MAP=m
+CONFIG_IR_CORE=m
 CONFIG_IR_NEC_DECODER=m
 CONFIG_IR_RC5_DECODER=m
 CONFIG_IR_RC6_DECODER=m
@@ -2589,9 +2590,11 @@ CONFIG_IR_JVC_DECODER=m
 CONFIG_IR_SONY_DECODER=m
 CONFIG_IR_RC5_SZ_DECODER=m
 CONFIG_IR_LIRC_CODEC=m
+CONFIG_IR_ENE=m
 CONFIG_IR_IMON=m
 CONFIG_IR_MCEUSB=m
 CONFIG_IR_STREAMZAP=m
+CONFIG_IR_WINBOND_CIR=m
 
 CONFIG_V4L_MEM2MEM_DRIVERS=y
 # CONFIG_VIDEO_MEM2MEM_TESTDEV is not set
diff --git a/kernel.spec b/kernel.spec
index c7f8bdd..e4fc678 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -691,6 +691,7 @@ Patch2914: linux-2.6-v4l-dvb-ir-core-streamzap.patch
 Patch2915: lirc-staging-2.6.36.patch
 #Patch2916: lirc-staging-2.6.36-fixes.patch
 Patch2917: hdpvr-ir-enable.patch
+Patch2918: linux-2.6-v4l-dvb-ir-core-update-2.patch
 
 Patch3000: linux-2.6-via-velocity-dma-fix.patch
 
@@ -1310,6 +1311,7 @@ ApplyPatch lirc-staging-2.6.36.patch
 #ApplyOptionalPatch lirc-staging-2.6.36-fixes.patch
 # enable IR receiver on Hauppauge HD PVR (v4l-dvb merge pending)
 ApplyPatch hdpvr-ir-enable.patch
+ApplyPatch linux-2.6-v4l-dvb-ir-core-update-2.patch
 
 # Fix DMA bug on via-velocity
 ApplyPatch linux-2.6-via-velocity-dma-fix.patch
@@ -1341,7 +1343,6 @@ ApplyPatch dell-wmi-add-support-for-eject-key-studio-1555.patch
 
 # bz #575873
 ApplyPatch flexcop-fix-xlate_proc_name-warning.patch
-
 # END OF PATCH APPLICATIONS
 
 %endif
@@ -1928,6 +1929,9 @@ fi
 # and build.
 
 %changelog
+* Fri Sep 10 2010 Jarod Wilson <jarod at redhat.com> 2.6.35.4-26
+- ir-core rebase to current upstream
+
 * Fri Sep 10 2010 Bastien Nocera <bnocera at redhat.com> - 2.6.35.4-25
 - Update AppleIR patch to work, and support the enter key on
   newer remotes
diff --git a/linux-2.6-v4l-dvb-ir-core-update-2.patch b/linux-2.6-v4l-dvb-ir-core-update-2.patch
new file mode 100644
index 0000000..449b496
--- /dev/null
+++ b/linux-2.6-v4l-dvb-ir-core-update-2.patch
@@ -0,0 +1,3989 @@
+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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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/rc-map.c.orig linux-2.6.35.new/drivers/media/IR/rc-map.c.orig
+--- linux-2.6.35/drivers/media/IR/rc-map.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.new/drivers/media/IR/rc-map.c.orig	2010-09-09 23:21:42.000000000 -0400
+@@ -0,0 +1,84 @@
++/* ir-raw-event.c - handle IR Pulse/Space event
++ *
++ * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab at redhat.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 version 2 of the License.
++ *
++ *  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.
++ */
++
++#include <media/ir-core.h>
++#include <linux/spinlock.h>
++#include <linux/delay.h>
++
++/* Used to handle IR raw handler extensions */
++static LIST_HEAD(rc_map_list);
++static DEFINE_SPINLOCK(rc_map_lock);
++
++static struct rc_keymap *seek_rc_map(const char *name)
++{
++	struct rc_keymap *map = NULL;
++
++	spin_lock(&rc_map_lock);
++	list_for_each_entry(map, &rc_map_list, list) {
++		if (!strcmp(name, map->map.name)) {
++			spin_unlock(&rc_map_lock);
++			return map;
++		}
++	}
++	spin_unlock(&rc_map_lock);
++
++	return NULL;
++}
++
++struct ir_scancode_table *get_rc_map(const char *name)
++{
++
++	struct rc_keymap *map;
++
++	map = seek_rc_map(name);
++#ifdef MODULE
++	if (!map) {
++		int rc = request_module(name);
++		if (rc < 0) {
++			printk(KERN_ERR "Couldn't load IR keymap %s\n", name);
++			return NULL;
++		}
++		msleep(20);	/* Give some time for IR to register */
++
++		map = seek_rc_map(name);
++	}
++#endif
++	if (!map) {
++		printk(KERN_ERR "IR keymap %s not found\n", name);
++		return NULL;
++	}
++
++	printk(KERN_INFO "Registered IR keymap %s\n", map->map.name);
++
++	return &map->map;
++}
++EXPORT_SYMBOL_GPL(get_rc_map);
++
++int ir_register_map(struct rc_keymap *map)
++{
++	spin_lock(&rc_map_lock);
++	list_add_tail(&map->list, &rc_map_list);
++	spin_unlock(&rc_map_lock);
++	return 0;
++}
++EXPORT_SYMBOL_GPL(ir_register_map);
++
++void ir_unregister_map(struct rc_keymap *map)
++{
++	spin_lock(&rc_map_lock);
++	list_del(&map->list);
++	spin_unlock(&rc_map_lock);
++}
++EXPORT_SYMBOL_GPL(ir_unregister_map);
++
+diff -Naurp linux-2.6.35/drivers/media/IR/rc-map.c.rej linux-2.6.35.new/drivers/media/IR/rc-map.c.rej
+--- linux-2.6.35/drivers/media/IR/rc-map.c.rej	1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.35.new/drivers/media/IR/rc-map.c.rej	2010-09-09 23:21:42.000000000 -0400
+@@ -0,0 +1,13 @@
++--- drivers/media/IR/rc-map.c
+++++ drivers/media/IR/rc-map.c
++@@ -100,8 +100,10 @@
++ {
++ 	return ir_register_map(&empty_map);
++ }
+++EXPORT_SYMBOL_GPL(ir_rcmap_init);
++ 
++ void ir_rcmap_cleanup(void)
++ {
++ 	ir_unregister_map(&empty_map);
++ }
+++EXPORT_SYMBOL_GPL(ir_rcmap_cleanup);
+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 at 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 at 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 at 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 at 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


More information about the scm-commits mailing list