Jesse Keating 7a32965
Patch generated from the linuxtv staging/other branch, with a few
Jesse Keating 7a32965
additional pending fixes merged in, and just about everything not
Jesse Keating 7a32965
essential to the ir-core update chopped out.
Jesse Keating 7a32965
Jesse Keating 7a32965
(Patch generated 2010.07.16)
Jesse Keating 7a32965
Jesse Keating 7a32965
Signed-off-by: Jarod Wilson <jarod@redhat.com>
Jesse Keating 7a32965
Jesse Keating 7a32965
---
Jesse Keating 7a32965
 Documentation/DocBook/media-entities.tmpl           |    1 
Jesse Keating 7a32965
 Documentation/DocBook/media.tmpl                    |    8 
Jesse Keating 7a32965
 Documentation/DocBook/v4l/lirc_device_interface.xml |  235 ++++
Jesse Keating 7a32965
 Documentation/DocBook/v4l/remote_controllers.xml    |    2 
Jesse Keating 7a32965
 Documentation/dvb/get_dvb_firmware                  |   19 
Jesse Keating 7a32965
 Documentation/video4linux/CARDLIST.cx23885          |    6 
Jesse Keating 7a32965
 drivers/input/evdev.c                               |   39 
Jesse Keating 7a32965
 drivers/input/input.c                               |  268 ++++
Jesse Keating 7a32965
 drivers/media/IR/Kconfig                            |   34 
Jesse Keating 7a32965
 drivers/media/IR/Makefile                           |    3 
Jesse Keating 7a32965
 drivers/media/IR/imon.c                             |    5 
Jesse Keating 7a32965
 drivers/media/IR/ir-core-priv.h                     |   54 
Jesse Keating 7a32965
 drivers/media/IR/ir-jvc-decoder.c                   |  152 --
Jesse Keating 7a32965
 drivers/media/IR/ir-lirc-codec.c                    |  283 ++++
Jesse Keating 7a32965
 drivers/media/IR/ir-nec-decoder.c                   |  151 --
Jesse Keating 7a32965
 drivers/media/IR/ir-raw-event.c                     |  167 +-
Jesse Keating 7a32965
 drivers/media/IR/ir-rc5-decoder.c                   |  167 --
Jesse Keating 7a32965
 drivers/media/IR/ir-rc6-decoder.c                   |  153 --
Jesse Keating 7a32965
 drivers/media/IR/ir-sony-decoder.c                  |  155 --
Jesse Keating 7a32965
 drivers/media/IR/ir-sysfs.c                         |  261 ++--
Jesse Keating 7a32965
 drivers/media/IR/keymaps/Makefile                   |    2 
Jesse Keating 7a32965
 drivers/media/IR/keymaps/rc-lirc.c                  |   41 
Jesse Keating 7a32965
 drivers/media/IR/keymaps/rc-rc6-mce.c               |  105 +
Jesse Keating 7a32965
 drivers/media/IR/lirc_dev.c                         |  764 +++++++++++++
Jesse Keating 7a32965
 drivers/media/IR/mceusb.c                           | 1143 ++++++++++++++++++++
Jesse Keating 7a32965
 drivers/media/common/tuners/tda18271-fe.c           |    8 
Jesse Keating 7a32965
 drivers/media/dvb/mantis/Kconfig                    |   14 
Jesse Keating 7a32965
 drivers/media/dvb/mantis/mantis_input.c             |    5 
Jesse Keating 7a32965
 drivers/media/video/cx23885/cx23885-cards.c         |   40 
Jesse Keating 7a32965
 drivers/media/video/cx23885/cx23885-core.c          |   11 
Jesse Keating 7a32965
 drivers/media/video/cx23885/cx23885-dvb.c           |    2 
Jesse Keating 7a32965
 drivers/media/video/cx23885/cx23885-input.c         |  317 +----
Jesse Keating 7a32965
 drivers/media/video/cx23885/cx23885-ir.c            |    2 
Jesse Keating 7a32965
 drivers/media/video/cx23885/cx23885.h               |   12 
Jesse Keating 7a32965
 drivers/media/video/cx88/cx88-cards.c               |    9 
Jesse Keating 7a32965
 drivers/media/video/cx88/cx88-i2c.c                 |    6 
Jesse Keating 7a32965
 drivers/media/video/cx88/cx88-input.c               |   46 
Jesse Keating 7a32965
 drivers/media/video/cx88/cx88.h                     |    1 
Jesse Keating 7a32965
 drivers/media/video/em28xx/em28xx-input.c           |   80 -
Jesse Keating 7a32965
 drivers/media/video/em28xx/em28xx-video.c           |    4 
Jesse Keating 7a32965
 drivers/media/video/em28xx/em28xx.h                 |    1 
Jesse Keating 7a32965
 drivers/media/video/hdpvr/hdpvr-core.c              |    5 
Jesse Keating 7a32965
 drivers/media/video/ir-kbd-i2c.c                    |   14 
Jesse Keating 7a32965
 drivers/media/video/pvrusb2/pvrusb2-ioread.c        |    5 
Jesse Keating 7a32965
 include/linux/input.h                               |   39 
Jesse Keating 7a32965
 include/media/ir-core.h                             |    8 
Jesse Keating 7a32965
 include/media/ir-kbd-i2c.h                          |    2 
Jesse Keating 7a32965
 include/media/lirc.h                                |  165 ++
Jesse Keating 7a32965
 include/media/lirc_dev.h                            |  225 +++
Jesse Keating 7a32965
 include/media/rc-map.h                              |    7 
Jesse Keating 7a32965
 50 files changed, 3971 insertions(+), 1275 deletions(-)
Jesse Keating 7a32965
Jesse Keating 7a32965
diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl
Jesse Keating 7a32965
index 5d4d40f..6ae9715 100644
Jesse Keating 7a32965
--- a/Documentation/DocBook/media-entities.tmpl
Jesse Keating 7a32965
+++ b/Documentation/DocBook/media-entities.tmpl
Jesse Keating 7a32965
@@ -218,6 +218,7 @@
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 
Jesse Keating 7a32965
diff --git a/Documentation/DocBook/media.tmpl b/Documentation/DocBook/media.tmpl
Jesse Keating 7a32965
index eea564b..f11048d 100644
Jesse Keating 7a32965
--- a/Documentation/DocBook/media.tmpl
Jesse Keating 7a32965
+++ b/Documentation/DocBook/media.tmpl
Jesse Keating 7a32965
@@ -28,7 +28,7 @@
Jesse Keating 7a32965
 <title>LINUX MEDIA INFRASTRUCTURE API</title>
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 <copyright>
Jesse Keating 7a32965
-	<year>2009</year>
Jesse Keating 7a32965
+	<year>2009-2010</year>
Jesse Keating 7a32965
 	<holder>LinuxTV Developers</holder>
Jesse Keating 7a32965
 </copyright>
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -61,7 +61,7 @@ Foundation. A copy of the license is included in the chapter entitled
Jesse Keating 7a32965
 		in fact it covers several different video standards including
Jesse Keating 7a32965
 		DVB-T, DVB-S, DVB-C and ATSC. The API is currently being updated
Jesse Keating 7a32965
 		to documment support also for DVB-S2, ISDB-T and ISDB-S.</para>
Jesse Keating 7a32965
-	<para>The third part covers other API's used by all media infrastructure devices</para>
Jesse Keating 7a32965
+	<para>The third part covers Remote Controller API</para>
Jesse Keating 7a32965
 	<para>For additional information and for the latest development code,
Jesse Keating 7a32965
 		see: <ulink url="http://linuxtv.org">http://linuxtv.org</ulink>.</para>
Jesse Keating 7a32965
 	<para>For discussing improvements, reporting troubles, sending new drivers, etc, please mail to: <ulink url="http://vger.kernel.org/vger-lists.html#linux-media">Linux Media Mailing List (LMML).</ulink>.</para>
Jesse Keating 7a32965
@@ -86,7 +86,7 @@ Foundation. A copy of the license is included in the chapter entitled
Jesse Keating 7a32965
 </author>
Jesse Keating 7a32965
 </authorgroup>
Jesse Keating 7a32965
 <copyright>
Jesse Keating 7a32965
-	<year>2009</year>
Jesse Keating 7a32965
+	<year>2009-2010</year>
Jesse Keating 7a32965
 	<holder>Mauro Carvalho Chehab</holder>
Jesse Keating 7a32965
 </copyright>
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -101,7 +101,7 @@ Foundation. A copy of the license is included in the chapter entitled
Jesse Keating 7a32965
 </revhistory>
Jesse Keating 7a32965
 </partinfo>
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-<title>Other API's used by media infrastructure drivers</title>
Jesse Keating 7a32965
+<title>Remote Controller API</title>
Jesse Keating 7a32965
 <chapter id="remote_controllers">
Jesse Keating 7a32965
 &sub-remote_controllers;
Jesse Keating 7a32965
 </chapter>
Jesse Keating 7a32965
diff --git a/Documentation/DocBook/v4l/lirc_device_interface.xml b/Documentation/DocBook/v4l/lirc_device_interface.xml
Jesse Keating 7a32965
new file mode 100644
Jesse Keating 7a32965
index 0000000..0413234
Jesse Keating 7a32965
--- /dev/null
Jesse Keating 7a32965
+++ b/Documentation/DocBook/v4l/lirc_device_interface.xml
Jesse Keating 7a32965
@@ -0,0 +1,235 @@
Jesse Keating 7a32965
+<section id="lirc_dev">
Jesse Keating 7a32965
+<title>LIRC Device Interface</title>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+<section id="lirc_dev_intro">
Jesse Keating 7a32965
+<title>Introduction</title>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+<para>The LIRC device interface is a bi-directional interface for
Jesse Keating 7a32965
+transporting raw IR data between userspace and kernelspace. Fundamentally,
Jesse Keating 7a32965
+it is just a chardev (/dev/lircX, for X = 0, 1, 2, ...), with a number
Jesse Keating 7a32965
+of standard struct file_operations defined on it. With respect to
Jesse Keating 7a32965
+transporting raw IR data to and fro, the essential fops are read, write
Jesse Keating 7a32965
+and ioctl.</para>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+<para>Example dmesg output upon a driver registering w/LIRC:</para>
Jesse Keating 7a32965
+  
Jesse Keating 7a32965
+    <para>$ dmesg |grep lirc_dev</para>
Jesse Keating 7a32965
+    <para>lirc_dev: IR Remote Control driver registered, major 248</para>
Jesse Keating 7a32965
+    <para>rc rc0: lirc_dev: driver ir-lirc-codec (mceusb) registered at minor = 0</para>
Jesse Keating 7a32965
+  
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+<para>What you should see for a chardev:</para>
Jesse Keating 7a32965
+  
Jesse Keating 7a32965
+    <para>$ ls -l /dev/lirc*</para>
Jesse Keating 7a32965
+    <para>crw-rw---- 1 root root 248, 0 Jul  2 22:20 /dev/lirc0</para>
Jesse Keating 7a32965
+  
Jesse Keating 7a32965
+</section>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+<section id="lirc_read">
Jesse Keating 7a32965
+<title>LIRC read fop</title>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+<para>The lircd userspace daemon reads raw IR data from the LIRC chardev. The
Jesse Keating 7a32965
+exact format of the data depends on what modes a driver supports, and what
Jesse Keating 7a32965
+mode has been selected. lircd obtains supported modes and sets the active mode
Jesse Keating 7a32965
+via the ioctl interface, detailed at <xref linkend="lirc_ioctl"/>. The generally
Jesse Keating 7a32965
+preferred mode is LIRC_MODE_MODE2, in which packets containing an int value
Jesse Keating 7a32965
+describing an IR signal are read from the chardev.</para>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+<para>See also <ulink url="http://www.lirc.org/html/technical.html">http://www.lirc.org/html/technical.html</ulink> for more info.</para>
Jesse Keating 7a32965
+</section>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+<section id="lirc_write">
Jesse Keating 7a32965
+<title>LIRC write fop</title>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+<para>The data written to the chardev is a pulse/space sequence of integer
Jesse Keating 7a32965
+values. Pulses and spaces are only marked implicitly by their position. The
Jesse Keating 7a32965
+data must start and end with a pulse, therefore, the data must always include
Jesse Keating 7a32965
+an unevent number of samples. The write function must block until the data has
Jesse Keating 7a32965
+been transmitted by the hardware.</para>
Jesse Keating 7a32965
+</section>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+<section id="lirc_ioctl">
Jesse Keating 7a32965
+<title>LIRC ioctl fop</title>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+<para>The LIRC device's ioctl definition is bound by the ioctl function
Jesse Keating 7a32965
+definition of struct file_operations, leaving us with an unsigned int
Jesse Keating 7a32965
+for the ioctl command and an unsigned long for the arg. For the purposes
Jesse Keating 7a32965
+of ioctl portability across 32-bit and 64-bit, these values are capped
Jesse Keating 7a32965
+to their 32-bit sizes.</para>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+<para>The following ioctls can be used to change specific hardware settings.
Jesse Keating 7a32965
+In general each driver should have a default set of settings. The driver
Jesse Keating 7a32965
+implementation is expected to re-apply the default settings when the device
Jesse Keating 7a32965
+is closed by user-space, so that every application opening the device can rely
Jesse Keating 7a32965
+on working with the default settings initially.</para>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+<variablelist>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_GET_FEATURES</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Obviously, get the underlying hardware device's features. If a driver
Jesse Keating 7a32965
+      does not announce support of certain features, calling of the corresponding
Jesse Keating 7a32965
+      ioctls is undefined.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_GET_SEND_MODE</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Get supported transmit mode. Only LIRC_MODE_PULSE is supported by lircd.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_GET_REC_MODE</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Get supported receive modes. Only LIRC_MODE_MODE2 and LIRC_MODE_LIRCCODE
Jesse Keating 7a32965
+      are supported by lircd.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_GET_SEND_CARRIER</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Get carrier frequency (in Hz) currently used for transmit.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_GET_REC_CARRIER</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Get carrier frequency (in Hz) currently used for IR reception.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_{G,S}ET_{SEND,REC}_DUTY_CYCLE</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Get/set the duty cycle (from 0 to 100) of the carrier signal. Currently,
Jesse Keating 7a32965
+      no special meaning is defined for 0 or 100, but this could be used to switch
Jesse Keating 7a32965
+      off carrier generation in the future, so these values should be reserved.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_GET_REC_RESOLUTION</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Some receiver have maximum resolution which is defined by internal
Jesse Keating 7a32965
+      sample rate or data format limitations. E.g. it's common that signals can
Jesse Keating 7a32965
+      only be reported in 50 microsecond steps. This integer value is used by
Jesse Keating 7a32965
+      lircd to automatically adjust the aeps tolerance value in the lircd
Jesse Keating 7a32965
+      config file.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_GET_M{IN,AX}_TIMEOUT</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Some devices have internal timers that can be used to detect when
Jesse Keating 7a32965
+      there's no IR activity for a long time. This can help lircd in detecting
Jesse Keating 7a32965
+      that a IR signal is finished and can speed up the decoding process.
Jesse Keating 7a32965
+      Returns an integer value with the minimum/maximum timeout that can be
Jesse Keating 7a32965
+      set. Some devices have a fixed timeout, in that case both ioctls will
Jesse Keating 7a32965
+      return the same value even though the timeout cannot be changed.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_GET_M{IN,AX}_FILTER_{PULSE,SPACE}</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Some devices are able to filter out spikes in the incoming signal
Jesse Keating 7a32965
+      using given filter rules. These ioctls return the hardware capabilities
Jesse Keating 7a32965
+      that describe the bounds of the possible filters. Filter settings depend
Jesse Keating 7a32965
+      on the IR protocols that are expected. lircd derives the settings from
Jesse Keating 7a32965
+      all protocols definitions found in its config file.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_GET_LENGTH</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Retrieves the code length in bits (only for LIRC_MODE_LIRCCODE).
Jesse Keating 7a32965
+      Reads on the device must be done in blocks matching the bit count.
Jesse Keating 7a32965
+      The bit could should be rounded up so that it matches full bytes.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_SET_{SEND,REC}_MODE</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Set send/receive mode. Largely obsolete for send, as only
Jesse Keating 7a32965
+      LIRC_MODE_PULSE is supported.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_SET_{SEND,REC}_CARRIER</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Set send/receive carrier (in Hz).</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_SET_TRANSMITTER_MASK</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>This enables the given set of transmitters. The first transmitter
Jesse Keating 7a32965
+      is encoded by the least significant bit, etc. When an invalid bit mask
Jesse Keating 7a32965
+      is given, i.e. a bit is set, even though the device does not have so many
Jesse Keating 7a32965
+      transitters, then this ioctl returns the number of available transitters
Jesse Keating 7a32965
+      and does nothing otherwise.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_SET_REC_TIMEOUT</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Sets the integer value for IR inactivity timeout (cf.
Jesse Keating 7a32965
+      LIRC_GET_MIN_TIMEOUT and LIRC_GET_MAX_TIMEOUT). A value of 0 (if
Jesse Keating 7a32965
+      supported by the hardware) disables all hardware timeouts and data should
Jesse Keating 7a32965
+      be reported as soon as possible. If the exact value cannot be set, then
Jesse Keating 7a32965
+      the next possible value _greater_ than the given value should be set.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_SET_REC_TIMEOUT_REPORTS</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Enable (1) or disable (0) timeout reports in LIRC_MODE_MODE2. By
Jesse Keating 7a32965
+      default, timeout reports should be turned off.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_SET_REC_FILTER_{,PULSE,SPACE}</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Pulses/spaces shorter than this are filtered out by hardware. If
Jesse Keating 7a32965
+      filters cannot be set independently for pulse/space, the corresponding
Jesse Keating 7a32965
+      ioctls must return an error and LIRC_SET_REC_FILTER shall be used instead.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_SET_MEASURE_CARRIER_MODE</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Enable (1)/disable (0) measure mode. If enabled, from the next key
Jesse Keating 7a32965
+      press on, the driver will send LIRC_MODE2_FREQUENCY packets. By default
Jesse Keating 7a32965
+      this should be turned off.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_SET_REC_{DUTY_CYCLE,CARRIER}_RANGE</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>To set a range use LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE
Jesse Keating 7a32965
+      with the lower bound first and later LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER
Jesse Keating 7a32965
+      with the upper bound.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_NOTIFY_DECODE</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>This ioctl is called by lircd whenever a successful decoding of an
Jesse Keating 7a32965
+      incoming IR signal could be done. This can be used by supporting hardware
Jesse Keating 7a32965
+      to give visual feedback to the user e.g. by flashing a LED.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+  <varlistentry>
Jesse Keating 7a32965
+    <term>LIRC_SETUP_{START,END}</term>
Jesse Keating 7a32965
+    <listitem>
Jesse Keating 7a32965
+      <para>Setting of several driver parameters can be optimized by encapsulating
Jesse Keating 7a32965
+      the according ioctl calls with LIRC_SETUP_START/LIRC_SETUP_END. When a
Jesse Keating 7a32965
+      driver receives a LIRC_SETUP_START ioctl it can choose to not commit
Jesse Keating 7a32965
+      further setting changes to the hardware until a LIRC_SETUP_END is received.
Jesse Keating 7a32965
+      But this is open to the driver implementation and every driver must also
Jesse Keating 7a32965
+      handle parameter changes which are not encapsulated by LIRC_SETUP_START
Jesse Keating 7a32965
+      and LIRC_SETUP_END. Drivers can also choose to ignore these ioctls.</para>
Jesse Keating 7a32965
+    </listitem>
Jesse Keating 7a32965
+  </varlistentry>
Jesse Keating 7a32965
+</variablelist>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+</section>
Jesse Keating 7a32965
+</section>
Jesse Keating 7a32965
diff --git a/Documentation/DocBook/v4l/remote_controllers.xml b/Documentation/DocBook/v4l/remote_controllers.xml
Jesse Keating 7a32965
index 73f5eab..3c3b667 100644
Jesse Keating 7a32965
--- a/Documentation/DocBook/v4l/remote_controllers.xml
Jesse Keating 7a32965
+++ b/Documentation/DocBook/v4l/remote_controllers.xml
Jesse Keating 7a32965
@@ -173,3 +173,5 @@ keymapping.</para>
Jesse Keating 7a32965
 <para>This program demonstrates how to replace the keymap tables.</para>
Jesse Keating 7a32965
 &sub-keytable-c;
Jesse Keating 7a32965
 </section>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+&sub-lirc_device_interface;
Jesse Keating 7a32965
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
Jesse Keating 7a32965
index 239cbdb..9ea94dc 100644
Jesse Keating 7a32965
--- a/Documentation/dvb/get_dvb_firmware
Jesse Keating 7a32965
+++ b/Documentation/dvb/get_dvb_firmware
Jesse Keating 7a32965
@@ -26,7 +26,7 @@ use IO::Handle;
Jesse Keating 7a32965
 		"dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
Jesse Keating 7a32965
 		"or51211", "or51132_qam", "or51132_vsb", "bluebird",
Jesse Keating 7a32965
 		"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
Jesse Keating 7a32965
-		"af9015", "ngene");
Jesse Keating 7a32965
+		"af9015", "ngene", "az6027");
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 # Check args
Jesse Keating 7a32965
 syntax() if (scalar(@ARGV) != 1);
Jesse Keating 7a32965
@@ -567,6 +567,23 @@ sub ngene {
Jesse Keating 7a32965
     "$file1, $file2";
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+sub az6027{
Jesse Keating 7a32965
+    my $file = "AZ6027_Linux_Driver.tar.gz";
Jesse Keating 7a32965
+    my $url = "http://linux.terratec.de/files/$file";
Jesse Keating 7a32965
+    my $firmware = "dvb-usb-az6027-03.fw";
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+    wgetfile($file, $url);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+    #untar
Jesse Keating 7a32965
+    if( system("tar xzvf $file $firmware")){
Jesse Keating 7a32965
+        die "failed to untar firmware";
Jesse Keating 7a32965
+    }
Jesse Keating 7a32965
+    if( system("rm $file")){
Jesse Keating 7a32965
+        die ("unable to remove unnecessary files");
Jesse Keating 7a32965
+    }
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+    $firmware;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
 # ---------------------------------------------------------------
Jesse Keating 7a32965
 # Utilities
Jesse Keating 7a32965
 
Jesse Keating 7a32965
diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
Jesse Keating 7a32965
index 16ca030..87c4634 100644
Jesse Keating 7a32965
--- a/Documentation/video4linux/CARDLIST.cx23885
Jesse Keating 7a32965
+++ b/Documentation/video4linux/CARDLIST.cx23885
Jesse Keating 7a32965
@@ -17,9 +17,9 @@
Jesse Keating 7a32965
  16 -> DVBWorld DVB-S2 2005                                [0001:2005]
Jesse Keating 7a32965
  17 -> NetUP Dual DVB-S2 CI                                [1b55:2a2c]
Jesse Keating 7a32965
  18 -> Hauppauge WinTV-HVR1270                             [0070:2211]
Jesse Keating 7a32965
- 19 -> Hauppauge WinTV-HVR1275                             [0070:2215]
Jesse Keating 7a32965
- 20 -> Hauppauge WinTV-HVR1255                             [0070:2251]
Jesse Keating 7a32965
- 21 -> Hauppauge WinTV-HVR1210                             [0070:2291,0070:2295]
Jesse Keating 7a32965
+ 19 -> Hauppauge WinTV-HVR1275                             [0070:2215,0070:221d,0070:22f2]
Jesse Keating 7a32965
+ 20 -> Hauppauge WinTV-HVR1255                             [0070:2251,0070:2259,0070:22f1]
Jesse Keating 7a32965
+ 21 -> Hauppauge WinTV-HVR1210                             [0070:2291,0070:2295,0070:2299,0070:229d,0070:22f0,0070:22f3,0070:22f4,0070:22f5]
Jesse Keating 7a32965
  22 -> Mygica X8506 DMB-TH                                 [14f1:8651]
Jesse Keating 7a32965
  23 -> Magic-Pro ProHDTV Extreme 2                         [14f1:8657]
Jesse Keating 7a32965
  24 -> Hauppauge WinTV-HVR1850                             [0070:8541]
Jesse Keating 7a32965
diff --git a/Documentation/video4linux/extract_xc3028.pl b/Documentation/video4linux/extract_xc3028.pl
Jesse Keating 7a32965
old mode 100644
Jesse Keating 7a32965
new mode 100755
Jesse Keating 7a32965
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
Jesse Keating 7a32965
index 2ee6c7a..b8a5673 100644
Jesse Keating 7a32965
--- a/drivers/input/evdev.c
Jesse Keating 7a32965
+++ b/drivers/input/evdev.c
Jesse Keating 7a32965
@@ -515,6 +515,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
Jesse Keating 7a32965
 	struct input_absinfo abs;
Jesse Keating 7a32965
 	struct ff_effect effect;
Jesse Keating 7a32965
 	int __user *ip = (int __user *)p;
Jesse Keating 7a32965
+	struct keycode_table_entry kt, *kt_p = p;
Jesse Keating 7a32965
+	char scancode[16];
Jesse Keating 7a32965
 	unsigned int i, t, u, v;
Jesse Keating 7a32965
 	int error;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -569,6 +571,43 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		return input_set_keycode(dev, t, v);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	case EVIOCGKEYCODEBIG:
Jesse Keating 7a32965
+		if (copy_from_user(&kt, kt_p, sizeof(kt)))
Jesse Keating 7a32965
+			return -EFAULT;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		if (kt.len > sizeof(scancode))
Jesse Keating 7a32965
+			return -EINVAL;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		kt.scancode = scancode;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		error = input_get_keycode_big(dev, &kt;;
Jesse Keating 7a32965
+		if (error)
Jesse Keating 7a32965
+			return error;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		if (copy_to_user(kt_p, &kt, sizeof(kt)))
Jesse Keating 7a32965
+			return -EFAULT;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		/* FIXME: probably need some compat32 code */
Jesse Keating 7a32965
+		if (copy_to_user(kt_p->scancode, kt.scancode, kt.len))
Jesse Keating 7a32965
+			return -EFAULT;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		return 0;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	case EVIOCSKEYCODEBIG:
Jesse Keating 7a32965
+		if (copy_from_user(&kt, kt_p, sizeof(kt)))
Jesse Keating 7a32965
+			return -EFAULT;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		if (kt.len > sizeof(scancode))
Jesse Keating 7a32965
+			return -EINVAL;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		kt.scancode = scancode;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		/* FIXME: probably need some compat32 code */
Jesse Keating 7a32965
+		if (copy_from_user(kt.scancode, kt_p->scancode, kt.len))
Jesse Keating 7a32965
+			return -EFAULT;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		return input_set_keycode_big(dev, &kt;;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	case EVIOCRMFF:
Jesse Keating 7a32965
 		return input_ff_erase(dev, (int)(unsigned long) p, file);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
diff --git a/drivers/input/input.c b/drivers/input/input.c
Jesse Keating 7a32965
index 9c79bd5..43aeb71 100644
Jesse Keating 7a32965
--- a/drivers/input/input.c
Jesse Keating 7a32965
+++ b/drivers/input/input.c
Jesse Keating 7a32965
@@ -568,6 +568,11 @@ static void input_disconnect_device(struct input_dev *dev)
Jesse Keating 7a32965
 	spin_unlock_irq(&dev->event_lock);
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+/*
Jesse Keating 7a32965
+ * Those routines handle the default case where no [gs]etkeycode() is
Jesse Keating 7a32965
+ * defined. In this case, an array indexed by the scancode is used.
Jesse Keating 7a32965
+ */
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 static int input_fetch_keycode(struct input_dev *dev, int scancode)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	switch (dev->keycodesize) {
Jesse Keating 7a32965
@@ -582,27 +587,74 @@ static int input_fetch_keycode(struct input_dev *dev, int scancode)
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static int input_default_getkeycode(struct input_dev *dev,
Jesse Keating 7a32965
-				    unsigned int scancode,
Jesse Keating 7a32965
-				    unsigned int *keycode)
Jesse Keating 7a32965
+/*
Jesse Keating 7a32965
+ * Supports only 8, 16 and 32 bit scancodes. It wouldn't be that
Jesse Keating 7a32965
+ * hard to write some machine-endian logic to support 24 bit scancodes,
Jesse Keating 7a32965
+ * but it seemed overkill. It should also be noticed that, since there
Jesse Keating 7a32965
+ * are, in general, less than 256 scancodes sparsed into the scancode
Jesse Keating 7a32965
+ * space, even with 16 bits, the codespace is sparsed, with leads into
Jesse Keating 7a32965
+ * memory and code ineficiency, when retrieving the entire scancode
Jesse Keating 7a32965
+ * space.
Jesse Keating 7a32965
+ * So, it is highly recommended to implement getkeycodebig/setkeycodebig
Jesse Keating 7a32965
+ * instead of using a normal table approach, when more than 8 bits is
Jesse Keating 7a32965
+ * needed for the scancode.
Jesse Keating 7a32965
+ */
Jesse Keating 7a32965
+static int input_fetch_scancode(struct keycode_table_entry *kt_entry,
Jesse Keating 7a32965
+				u32 *scancode)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
+	switch (kt_entry->len) {
Jesse Keating 7a32965
+	case 1:
Jesse Keating 7a32965
+		*scancode = *((u8 *)kt_entry->scancode);
Jesse Keating 7a32965
+		break;
Jesse Keating 7a32965
+	case 2:
Jesse Keating 7a32965
+		*scancode = *((u16 *)kt_entry->scancode);
Jesse Keating 7a32965
+		break;
Jesse Keating 7a32965
+	case 4:
Jesse Keating 7a32965
+		*scancode = *((u32 *)kt_entry->scancode);
Jesse Keating 7a32965
+		break;
Jesse Keating 7a32965
+	default:
Jesse Keating 7a32965
+		return -EINVAL;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static int input_default_getkeycode_from_index(struct input_dev *dev,
Jesse Keating 7a32965
+				    struct keycode_table_entry *kt_entry)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	u32 scancode = kt_entry->index;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	if (!dev->keycodesize)
Jesse Keating 7a32965
 		return -EINVAL;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (scancode >= dev->keycodemax)
Jesse Keating 7a32965
 		return -EINVAL;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	*keycode = input_fetch_keycode(dev, scancode);
Jesse Keating 7a32965
+	kt_entry->keycode = input_fetch_keycode(dev, scancode);
Jesse Keating 7a32965
+	memcpy(kt_entry->scancode, &scancode, 4);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	return 0;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+static int input_default_getkeycode_from_scancode(struct input_dev *dev,
Jesse Keating 7a32965
+				    struct keycode_table_entry *kt_entry)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	if (input_fetch_scancode(kt_entry, &kt_entry->index))
Jesse Keating 7a32965
+		return -EINVAL;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return input_default_getkeycode_from_index(dev, kt_entry);
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 static int input_default_setkeycode(struct input_dev *dev,
Jesse Keating 7a32965
-				    unsigned int scancode,
Jesse Keating 7a32965
-				    unsigned int keycode)
Jesse Keating 7a32965
+				    struct keycode_table_entry *kt_entry)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
-	int old_keycode;
Jesse Keating 7a32965
+	u32 old_keycode;
Jesse Keating 7a32965
 	int i;
Jesse Keating 7a32965
+	u32 scancode;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (input_fetch_scancode(kt_entry, &scancode))
Jesse Keating 7a32965
+		return -EINVAL;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (scancode >= dev->keycodemax)
Jesse Keating 7a32965
 		return -EINVAL;
Jesse Keating 7a32965
@@ -610,32 +662,33 @@ static int input_default_setkeycode(struct input_dev *dev,
Jesse Keating 7a32965
 	if (!dev->keycodesize)
Jesse Keating 7a32965
 		return -EINVAL;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
Jesse Keating 7a32965
+	if (dev->keycodesize < sizeof(dev->keycode) &&
Jesse Keating 7a32965
+	    (kt_entry->keycode >> (dev->keycodesize * 8)))
Jesse Keating 7a32965
 		return -EINVAL;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	switch (dev->keycodesize) {
Jesse Keating 7a32965
 		case 1: {
Jesse Keating 7a32965
 			u8 *k = (u8 *)dev->keycode;
Jesse Keating 7a32965
 			old_keycode = k[scancode];
Jesse Keating 7a32965
-			k[scancode] = keycode;
Jesse Keating 7a32965
+			k[scancode] = kt_entry->keycode;
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 		}
Jesse Keating 7a32965
 		case 2: {
Jesse Keating 7a32965
 			u16 *k = (u16 *)dev->keycode;
Jesse Keating 7a32965
 			old_keycode = k[scancode];
Jesse Keating 7a32965
-			k[scancode] = keycode;
Jesse Keating 7a32965
+			k[scancode] = kt_entry->keycode;
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 		}
Jesse Keating 7a32965
 		default: {
Jesse Keating 7a32965
 			u32 *k = (u32 *)dev->keycode;
Jesse Keating 7a32965
 			old_keycode = k[scancode];
Jesse Keating 7a32965
-			k[scancode] = keycode;
Jesse Keating 7a32965
+			k[scancode] = kt_entry->keycode;
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 		}
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	__clear_bit(old_keycode, dev->keybit);
Jesse Keating 7a32965
-	__set_bit(keycode, dev->keybit);
Jesse Keating 7a32965
+	__set_bit(kt_entry->keycode, dev->keybit);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	for (i = 0; i < dev->keycodemax; i++) {
Jesse Keating 7a32965
 		if (input_fetch_keycode(dev, i) == old_keycode) {
Jesse Keating 7a32965
@@ -648,6 +701,110 @@ static int input_default_setkeycode(struct input_dev *dev,
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /**
Jesse Keating 7a32965
+ * input_get_keycode_big - retrieve keycode currently mapped to a given scancode
Jesse Keating 7a32965
+ * @dev: input device which keymap is being queried
Jesse Keating 7a32965
+ * @kt_entry: keytable entry
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ * This function should be called by anyone interested in retrieving current
Jesse Keating 7a32965
+ * keymap. Presently evdev handlers use it.
Jesse Keating 7a32965
+ */
Jesse Keating 7a32965
+int input_get_keycode_big(struct input_dev *dev,
Jesse Keating 7a32965
+			  struct keycode_table_entry *kt_entry)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	if (dev->getkeycode) {
Jesse Keating 7a32965
+		u32 scancode = kt_entry->index;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		/*
Jesse Keating 7a32965
+		 * Support for legacy drivers, that don't implement the new
Jesse Keating 7a32965
+		 * ioctls
Jesse Keating 7a32965
+		 */
Jesse Keating 7a32965
+		memcpy(kt_entry->scancode, &scancode, 4);
Jesse Keating 7a32965
+		return dev->getkeycode(dev, scancode,
Jesse Keating 7a32965
+				       &kt_entry->keycode);
Jesse Keating 7a32965
+	} else
Jesse Keating 7a32965
+		return dev->getkeycodebig_from_index(dev, kt_entry);
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+EXPORT_SYMBOL(input_get_keycode_big);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+/**
Jesse Keating 7a32965
+ * input_set_keycode_big - attribute a keycode to a given scancode
Jesse Keating 7a32965
+ * @dev: input device which keymap is being queried
Jesse Keating 7a32965
+ * @kt_entry: keytable entry
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ * This function should be called by anyone needing to update current
Jesse Keating 7a32965
+ * keymap. Presently keyboard and evdev handlers use it.
Jesse Keating 7a32965
+ */
Jesse Keating 7a32965
+int input_set_keycode_big(struct input_dev *dev,
Jesse Keating 7a32965
+			  struct keycode_table_entry *kt_entry)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	unsigned long flags;
Jesse Keating 7a32965
+	int old_keycode;
Jesse Keating 7a32965
+	int retval = -EINVAL;
Jesse Keating 7a32965
+	u32 uninitialized_var(scancode);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (kt_entry->keycode < 0 || kt_entry->keycode > KEY_MAX)
Jesse Keating 7a32965
+		return -EINVAL;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	spin_lock_irqsave(&dev->event_lock, flags);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/*
Jesse Keating 7a32965
+	 * We need to know the old scancode, in order to generate a
Jesse Keating 7a32965
+	 * keyup effect, if the set operation happens successfully
Jesse Keating 7a32965
+	 */
Jesse Keating 7a32965
+	if (dev->getkeycode) {
Jesse Keating 7a32965
+		/*
Jesse Keating 7a32965
+		 * Support for legacy drivers, that don't implement the new
Jesse Keating 7a32965
+		 * ioctls
Jesse Keating 7a32965
+		 */
Jesse Keating 7a32965
+		if (!dev->setkeycode)
Jesse Keating 7a32965
+			goto out;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		retval = input_fetch_scancode(kt_entry, &scancode);
Jesse Keating 7a32965
+		if (retval)
Jesse Keating 7a32965
+			goto out;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		retval = dev->getkeycode(dev, scancode,
Jesse Keating 7a32965
+					 &old_keycode);
Jesse Keating 7a32965
+	} else {
Jesse Keating 7a32965
+		int new_keycode = kt_entry->keycode;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		retval = dev->getkeycodebig_from_scancode(dev, kt_entry);
Jesse Keating 7a32965
+		old_keycode = kt_entry->keycode;
Jesse Keating 7a32965
+		kt_entry->keycode = new_keycode;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (retval)
Jesse Keating 7a32965
+		goto out;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (dev->getkeycode)
Jesse Keating 7a32965
+		retval = dev->setkeycode(dev, scancode,
Jesse Keating 7a32965
+					 kt_entry->keycode);
Jesse Keating 7a32965
+	else
Jesse Keating 7a32965
+		retval = dev->setkeycodebig(dev, kt_entry);
Jesse Keating 7a32965
+	if (retval)
Jesse Keating 7a32965
+		goto out;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/*
Jesse Keating 7a32965
+	 * Simulate keyup event if keycode is not present
Jesse Keating 7a32965
+	 * in the keymap anymore
Jesse Keating 7a32965
+	 */
Jesse Keating 7a32965
+	if (test_bit(EV_KEY, dev->evbit) &&
Jesse Keating 7a32965
+	    !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
Jesse Keating 7a32965
+	    __test_and_clear_bit(old_keycode, dev->key)) {
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		input_pass_event(dev, EV_KEY, old_keycode, 0);
Jesse Keating 7a32965
+		if (dev->sync)
Jesse Keating 7a32965
+			input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+ out:
Jesse Keating 7a32965
+	spin_unlock_irqrestore(&dev->event_lock, flags);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return retval;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+EXPORT_SYMBOL(input_set_keycode_big);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+/**
Jesse Keating 7a32965
  * input_get_keycode - retrieve keycode currently mapped to a given scancode
Jesse Keating 7a32965
  * @dev: input device which keymap is being queried
Jesse Keating 7a32965
  * @scancode: scancode (or its equivalent for device in question) for which
Jesse Keating 7a32965
@@ -661,13 +818,35 @@ int input_get_keycode(struct input_dev *dev,
Jesse Keating 7a32965
 		      unsigned int scancode, unsigned int *keycode)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	unsigned long flags;
Jesse Keating 7a32965
-	int retval;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	spin_lock_irqsave(&dev->event_lock, flags);
Jesse Keating 7a32965
-	retval = dev->getkeycode(dev, scancode, keycode);
Jesse Keating 7a32965
-	spin_unlock_irqrestore(&dev->event_lock, flags);
Jesse Keating 7a32965
+	if (dev->getkeycode) {
Jesse Keating 7a32965
+		/*
Jesse Keating 7a32965
+		 * Use the legacy calls
Jesse Keating 7a32965
+		 */
Jesse Keating 7a32965
+		return dev->getkeycode(dev, scancode, keycode);
Jesse Keating 7a32965
+	} else {
Jesse Keating 7a32965
+		int retval;
Jesse Keating 7a32965
+		struct keycode_table_entry kt_entry;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	return retval;
Jesse Keating 7a32965
+		/*
Jesse Keating 7a32965
+		 * Userspace is using a legacy call with a driver ported
Jesse Keating 7a32965
+		 * to the new way. This is a bad idea with long sparsed
Jesse Keating 7a32965
+		 * tables, since lots of the retrieved values will be in
Jesse Keating 7a32965
+		 * blank. Also, it makes sense only if the table size is
Jesse Keating 7a32965
+		 * lower than 2^32.
Jesse Keating 7a32965
+		 */
Jesse Keating 7a32965
+		memset(&kt_entry, 0, sizeof(kt_entry));
Jesse Keating 7a32965
+		kt_entry.len = 4;
Jesse Keating 7a32965
+		kt_entry.index = scancode;
Jesse Keating 7a32965
+		kt_entry.scancode = (char *)&scancode;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		spin_lock_irqsave(&dev->event_lock, flags);
Jesse Keating 7a32965
+		retval = dev->getkeycodebig_from_index(dev, &kt_entry);
Jesse Keating 7a32965
+		spin_unlock_irqrestore(&dev->event_lock, flags);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		*keycode = kt_entry.keycode;
Jesse Keating 7a32965
+		return retval;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 EXPORT_SYMBOL(input_get_keycode);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -692,13 +871,42 @@ int input_set_keycode(struct input_dev *dev,
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	spin_lock_irqsave(&dev->event_lock, flags);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	retval = dev->getkeycode(dev, scancode, &old_keycode);
Jesse Keating 7a32965
-	if (retval)
Jesse Keating 7a32965
-		goto out;
Jesse Keating 7a32965
+	if (dev->getkeycode) {
Jesse Keating 7a32965
+		/*
Jesse Keating 7a32965
+		 * Use the legacy calls
Jesse Keating 7a32965
+		 */
Jesse Keating 7a32965
+		retval = dev->getkeycode(dev, scancode, &old_keycode);
Jesse Keating 7a32965
+		if (retval)
Jesse Keating 7a32965
+			goto out;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	retval = dev->setkeycode(dev, scancode, keycode);
Jesse Keating 7a32965
-	if (retval)
Jesse Keating 7a32965
-		goto out;
Jesse Keating 7a32965
+		retval = dev->setkeycode(dev, scancode, keycode);
Jesse Keating 7a32965
+		if (retval)
Jesse Keating 7a32965
+			goto out;
Jesse Keating 7a32965
+	} else {
Jesse Keating 7a32965
+		struct keycode_table_entry kt_entry;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		/*
Jesse Keating 7a32965
+		 * Userspace is using a legacy call with a driver ported
Jesse Keating 7a32965
+		 * to the new way. This is a bad idea with long sparsed
Jesse Keating 7a32965
+		 * tables, since lots of the retrieved values will be in
Jesse Keating 7a32965
+		 * blank. Also, it makes sense only if the table size is
Jesse Keating 7a32965
+		 * lower than 2^32.
Jesse Keating 7a32965
+		 */
Jesse Keating 7a32965
+		memset(&kt_entry, 0, sizeof(kt_entry));
Jesse Keating 7a32965
+		kt_entry.len = 4;
Jesse Keating 7a32965
+		kt_entry.scancode = (char *)&scancode;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		retval = dev->getkeycodebig_from_scancode(dev, &kt_entry);
Jesse Keating 7a32965
+		if (retval)
Jesse Keating 7a32965
+			goto out;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		old_keycode = kt_entry.keycode;
Jesse Keating 7a32965
+		kt_entry.keycode = keycode;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		retval = dev->setkeycodebig(dev, &kt_entry);
Jesse Keating 7a32965
+		if (retval)
Jesse Keating 7a32965
+			goto out;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* Make sure KEY_RESERVED did not get enabled. */
Jesse Keating 7a32965
 	__clear_bit(KEY_RESERVED, dev->keybit);
Jesse Keating 7a32965
@@ -1636,11 +1843,17 @@ int input_register_device(struct input_dev *dev)
Jesse Keating 7a32965
 		dev->rep[REP_PERIOD] = 33;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (!dev->getkeycode)
Jesse Keating 7a32965
-		dev->getkeycode = input_default_getkeycode;
Jesse Keating 7a32965
+	if (!dev->getkeycode) {
Jesse Keating 7a32965
+		if (!dev->getkeycodebig_from_index)
Jesse Keating 7a32965
+			dev->getkeycodebig_from_index = input_default_getkeycode_from_index;
Jesse Keating 7a32965
+		if (!dev->getkeycodebig_from_scancode)
Jesse Keating 7a32965
+			dev->getkeycodebig_from_scancode = input_default_getkeycode_from_scancode;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (!dev->setkeycode)
Jesse Keating 7a32965
-		dev->setkeycode = input_default_setkeycode;
Jesse Keating 7a32965
+	if (!dev->setkeycode) {
Jesse Keating 7a32965
+		if (!dev->setkeycodebig)
Jesse Keating 7a32965
+			dev->setkeycodebig = input_default_setkeycode;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	dev_set_name(&dev->dev, "input%ld",
Jesse Keating 7a32965
 		     (unsigned long) atomic_inc_return(&input_no) - 1);
Jesse Keating 7a32965
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig
Jesse Keating 7a32965
index d22a8ec..e557ae0 100644
Jesse Keating 7a32965
--- a/drivers/media/IR/Kconfig
Jesse Keating 7a32965
+++ b/drivers/media/IR/Kconfig
Jesse Keating 7a32965
@@ -8,6 +8,17 @@ config VIDEO_IR
Jesse Keating 7a32965
 	depends on IR_CORE
Jesse Keating 7a32965
 	default IR_CORE
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+config LIRC
Jesse Keating 7a32965
+	tristate
Jesse Keating 7a32965
+	default y
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	---help---
Jesse Keating 7a32965
+	   Enable this option to build the Linux Infrared Remote
Jesse Keating 7a32965
+	   Control (LIRC) core device interface driver. The LIRC
Jesse Keating 7a32965
+	   interface passes raw IR to and from userspace, where the
Jesse Keating 7a32965
+	   LIRC daemon handles protocol decoding for IR reception ann
Jesse Keating 7a32965
+	   encoding for IR transmitting (aka "blasting").
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 source "drivers/media/IR/keymaps/Kconfig"
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 config IR_NEC_DECODER
Jesse Keating 7a32965
@@ -42,6 +53,7 @@ config IR_RC6_DECODER
Jesse Keating 7a32965
 config IR_JVC_DECODER
Jesse Keating 7a32965
 	tristate "Enable IR raw decoder for the JVC protocol"
Jesse Keating 7a32965
 	depends on IR_CORE
Jesse Keating 7a32965
+	select BITREVERSE
Jesse Keating 7a32965
 	default y
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	---help---
Jesse Keating 7a32965
@@ -57,6 +69,16 @@ config IR_SONY_DECODER
Jesse Keating 7a32965
 	   Enable this option if you have an infrared remote control which
Jesse Keating 7a32965
 	   uses the Sony protocol, and you need software decoding support.
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+config IR_LIRC_CODEC
Jesse Keating 7a32965
+	tristate "Enable IR to LIRC bridge"
Jesse Keating 7a32965
+	depends on IR_CORE
Jesse Keating 7a32965
+	depends on LIRC
Jesse Keating 7a32965
+	default y
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	---help---
Jesse Keating 7a32965
+	   Enable this option to pass raw IR to and from userspace via
Jesse Keating 7a32965
+	   the LIRC interface.
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 config IR_IMON
Jesse Keating 7a32965
 	tristate "SoundGraph iMON Receiver and Display"
Jesse Keating 7a32965
 	depends on USB_ARCH_HAS_HCD
Jesse Keating 7a32965
@@ -68,3 +90,15 @@ config IR_IMON
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	   To compile this driver as a module, choose M here: the
Jesse Keating 7a32965
 	   module will be called imon.
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+config IR_MCEUSB
Jesse Keating 7a32965
+	tristate "Windows Media Center Ed. eHome Infrared Transceiver"
Jesse Keating 7a32965
+	depends on USB_ARCH_HAS_HCD
Jesse Keating 7a32965
+	depends on IR_CORE
Jesse Keating 7a32965
+	select USB
Jesse Keating 7a32965
+	---help---
Jesse Keating 7a32965
+	   Say Y here if you want to use a Windows Media Center Edition
Jesse Keating 7a32965
+	   eHome Infrared Transceiver.
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	   To compile this driver as a module, choose M here: the
Jesse Keating 7a32965
+	   module will be called mceusb.
Jesse Keating 7a32965
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile
Jesse Keating 7a32965
index b998fcc..2ae4f3a 100644
Jesse Keating 7a32965
--- a/drivers/media/IR/Makefile
Jesse Keating 7a32965
+++ b/drivers/media/IR/Makefile
Jesse Keating 7a32965
@@ -5,11 +5,14 @@ obj-y += keymaps/
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 obj-$(CONFIG_IR_CORE) += ir-core.o
Jesse Keating 7a32965
 obj-$(CONFIG_VIDEO_IR) += ir-common.o
Jesse Keating 7a32965
+obj-$(CONFIG_LIRC) += lirc_dev.o
Jesse Keating 7a32965
 obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
Jesse Keating 7a32965
 obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
Jesse Keating 7a32965
 obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
Jesse Keating 7a32965
 obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
Jesse Keating 7a32965
 obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
Jesse Keating 7a32965
+obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 # stand-alone IR receivers/transmitters
Jesse Keating 7a32965
 obj-$(CONFIG_IR_IMON) += imon.o
Jesse Keating 7a32965
+obj-$(CONFIG_IR_MCEUSB) += mceusb.o
Jesse Keating 7a32965
diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c
Jesse Keating 7a32965
index 4bbd45f..0195dd5 100644
Jesse Keating 7a32965
--- a/drivers/media/IR/imon.c
Jesse Keating 7a32965
+++ b/drivers/media/IR/imon.c
Jesse Keating 7a32965
@@ -1943,7 +1943,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
Jesse Keating 7a32965
 	return ictx;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 urb_submit_failed:
Jesse Keating 7a32965
-	input_unregister_device(ictx->idev);
Jesse Keating 7a32965
+	ir_input_unregister(ictx->idev);
Jesse Keating 7a32965
 	input_free_device(ictx->idev);
Jesse Keating 7a32965
 idev_setup_failed:
Jesse Keating 7a32965
 find_endpoint_failed:
Jesse Keating 7a32965
@@ -2067,6 +2067,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
Jesse Keating 7a32965
 		detected_display_type = IMON_DISPLAY_TYPE_VFD;
Jesse Keating 7a32965
 		break;
Jesse Keating 7a32965
 	/* iMON LCD, MCE IR */
Jesse Keating 7a32965
+	case 0x9e:
Jesse Keating 7a32965
 	case 0x9f:
Jesse Keating 7a32965
 		dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR");
Jesse Keating 7a32965
 		detected_display_type = IMON_DISPLAY_TYPE_LCD;
Jesse Keating 7a32965
@@ -2306,7 +2307,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
Jesse Keating 7a32965
 	if (ifnum == 0) {
Jesse Keating 7a32965
 		ictx->dev_present_intf0 = false;
Jesse Keating 7a32965
 		usb_kill_urb(ictx->rx_urb_intf0);
Jesse Keating 7a32965
-		input_unregister_device(ictx->idev);
Jesse Keating 7a32965
+		ir_input_unregister(ictx->idev);
Jesse Keating 7a32965
 		if (ictx->display_supported) {
Jesse Keating 7a32965
 			if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
Jesse Keating 7a32965
 				usb_deregister_dev(interface, &imon_lcd_class);
Jesse Keating 7a32965
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
Jesse Keating 7a32965
index 9a5e65a..babd520 100644
Jesse Keating 7a32965
--- a/drivers/media/IR/ir-core-priv.h
Jesse Keating 7a32965
+++ b/drivers/media/IR/ir-core-priv.h
Jesse Keating 7a32965
@@ -22,17 +22,62 @@
Jesse Keating 7a32965
 struct ir_raw_handler {
Jesse Keating 7a32965
 	struct list_head list;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	u64 protocols; /* which are handled by this handler */
Jesse Keating 7a32965
 	int (*decode)(struct input_dev *input_dev, struct ir_raw_event event);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* These two should only be used by the lirc decoder */
Jesse Keating 7a32965
 	int (*raw_register)(struct input_dev *input_dev);
Jesse Keating 7a32965
 	int (*raw_unregister)(struct input_dev *input_dev);
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 struct ir_raw_event_ctrl {
Jesse Keating 7a32965
+	struct list_head		list;		/* to keep track of raw clients */
Jesse Keating 7a32965
 	struct work_struct		rx_work;	/* for the rx decoding workqueue */
Jesse Keating 7a32965
 	struct kfifo			kfifo;		/* fifo for the pulse/space durations */
Jesse Keating 7a32965
 	ktime_t				last_event;	/* when last event occurred */
Jesse Keating 7a32965
 	enum raw_event_type		last_type;	/* last event type */
Jesse Keating 7a32965
 	struct input_dev		*input_dev;	/* pointer to the parent input_dev */
Jesse Keating 7a32965
+	u64				enabled_protocols; /* enabled raw protocol decoders */
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* raw decoder state follows */
Jesse Keating 7a32965
+	struct ir_raw_event prev_ev;
Jesse Keating 7a32965
+	struct nec_dec {
Jesse Keating 7a32965
+		int state;
Jesse Keating 7a32965
+		unsigned count;
Jesse Keating 7a32965
+		u32 bits;
Jesse Keating 7a32965
+	} nec;
Jesse Keating 7a32965
+	struct rc5_dec {
Jesse Keating 7a32965
+		int state;
Jesse Keating 7a32965
+		u32 bits;
Jesse Keating 7a32965
+		unsigned count;
Jesse Keating 7a32965
+		unsigned wanted_bits;
Jesse Keating 7a32965
+	} rc5;
Jesse Keating 7a32965
+	struct rc6_dec {
Jesse Keating 7a32965
+		int state;
Jesse Keating 7a32965
+		u8 header;
Jesse Keating 7a32965
+		u32 body;
Jesse Keating 7a32965
+		bool toggle;
Jesse Keating 7a32965
+		unsigned count;
Jesse Keating 7a32965
+		unsigned wanted_bits;
Jesse Keating 7a32965
+	} rc6;
Jesse Keating 7a32965
+	struct sony_dec {
Jesse Keating 7a32965
+		int state;
Jesse Keating 7a32965
+		u32 bits;
Jesse Keating 7a32965
+		unsigned count;
Jesse Keating 7a32965
+	} sony;
Jesse Keating 7a32965
+	struct jvc_dec {
Jesse Keating 7a32965
+		int state;
Jesse Keating 7a32965
+		u16 bits;
Jesse Keating 7a32965
+		u16 old_bits;
Jesse Keating 7a32965
+		unsigned count;
Jesse Keating 7a32965
+		bool first;
Jesse Keating 7a32965
+		bool toggle;
Jesse Keating 7a32965
+	} jvc;
Jesse Keating 7a32965
+	struct lirc_codec {
Jesse Keating 7a32965
+		struct ir_input_dev *ir_dev;
Jesse Keating 7a32965
+		struct lirc_driver *drv;
Jesse Keating 7a32965
+		int lircdata;
Jesse Keating 7a32965
+	} lirc;
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /* macros for IR decoders */
Jesse Keating 7a32965
@@ -74,6 +119,7 @@ void ir_unregister_class(struct input_dev *input_dev);
Jesse Keating 7a32965
 /*
Jesse Keating 7a32965
  * Routines from ir-raw-event.c to be used internally and by decoders
Jesse Keating 7a32965
  */
Jesse Keating 7a32965
+u64 ir_raw_get_allowed_protocols(void);
Jesse Keating 7a32965
 int ir_raw_event_register(struct input_dev *input_dev);
Jesse Keating 7a32965
 void ir_raw_event_unregister(struct input_dev *input_dev);
Jesse Keating 7a32965
 int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
Jesse Keating 7a32965
@@ -123,4 +169,12 @@ void ir_raw_init(void);
Jesse Keating 7a32965
 #define load_sony_decode()	0
Jesse Keating 7a32965
 #endif
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+/* from ir-lirc-codec.c */
Jesse Keating 7a32965
+#ifdef CONFIG_IR_LIRC_CODEC_MODULE
Jesse Keating 7a32965
+#define load_lirc_codec()	request_module("ir-lirc-codec")
Jesse Keating 7a32965
+#else
Jesse Keating 7a32965
+#define load_lirc_codec()	0
Jesse Keating 7a32965
+#endif
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 #endif /* _IR_RAW_EVENT */
Jesse Keating 7a32965
diff --git a/drivers/media/IR/ir-jvc-decoder.c b/drivers/media/IR/ir-jvc-decoder.c
Jesse Keating 7a32965
index 0b80494..8894d8b 100644
Jesse Keating 7a32965
--- a/drivers/media/IR/ir-jvc-decoder.c
Jesse Keating 7a32965
+++ b/drivers/media/IR/ir-jvc-decoder.c
Jesse Keating 7a32965
@@ -25,10 +25,6 @@
Jesse Keating 7a32965
 #define JVC_TRAILER_PULSE	(1  * JVC_UNIT)
Jesse Keating 7a32965
 #define	JVC_TRAILER_SPACE	(35 * JVC_UNIT)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-/* Used to register jvc_decoder clients */
Jesse Keating 7a32965
-static LIST_HEAD(decoder_list);
Jesse Keating 7a32965
-DEFINE_SPINLOCK(decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 enum jvc_state {
Jesse Keating 7a32965
 	STATE_INACTIVE,
Jesse Keating 7a32965
 	STATE_HEADER_SPACE,
Jesse Keating 7a32965
@@ -38,87 +34,6 @@ enum jvc_state {
Jesse Keating 7a32965
 	STATE_TRAILER_SPACE,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-struct decoder_data {
Jesse Keating 7a32965
-	struct list_head	list;
Jesse Keating 7a32965
-	struct ir_input_dev	*ir_dev;
Jesse Keating 7a32965
-	int			enabled:1;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* State machine control */
Jesse Keating 7a32965
-	enum jvc_state		state;
Jesse Keating 7a32965
-	u16			jvc_bits;
Jesse Keating 7a32965
-	u16			jvc_old_bits;
Jesse Keating 7a32965
-	unsigned		count;
Jesse Keating 7a32965
-	bool			first;
Jesse Keating 7a32965
-	bool			toggle;
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-/**
Jesse Keating 7a32965
- * get_decoder_data()	- gets decoder data
Jesse Keating 7a32965
- * @input_dev:	input device
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * Returns the struct decoder_data that corresponds to a device
Jesse Keating 7a32965
- */
Jesse Keating 7a32965
-static struct decoder_data *get_decoder_data(struct  ir_input_dev *ir_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct decoder_data *data = NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_for_each_entry(data, &decoder_list, list) {
Jesse Keating 7a32965
-		if (data->ir_dev == ir_dev)
Jesse Keating 7a32965
-			break;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-	return data;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static ssize_t store_enabled(struct device *d,
Jesse Keating 7a32965
-			     struct device_attribute *mattr,
Jesse Keating 7a32965
-			     const char *buf,
Jesse Keating 7a32965
-			     size_t len)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	unsigned long value;
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
Jesse Keating 7a32965
-	struct decoder_data *data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (strict_strtoul(buf, 10, &value) || value > 1)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data->enabled = value;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return len;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static ssize_t show_enabled(struct device *d,
Jesse Keating 7a32965
-			     struct device_attribute *mattr, char *buf)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
Jesse Keating 7a32965
-	struct decoder_data *data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (data->enabled)
Jesse Keating 7a32965
-		return sprintf(buf, "1\n");
Jesse Keating 7a32965
-	else
Jesse Keating 7a32965
-	return sprintf(buf, "0\n");
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static struct attribute *decoder_attributes[] = {
Jesse Keating 7a32965
-	&dev_attr_enabled.attr,
Jesse Keating 7a32965
-	NULL
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static struct attribute_group decoder_attribute_group = {
Jesse Keating 7a32965
-	.name	= "jvc_decoder",
Jesse Keating 7a32965
-	.attrs	= decoder_attributes,
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 /**
Jesse Keating 7a32965
  * ir_jvc_decode() - Decode one JVC pulse or space
Jesse Keating 7a32965
  * @input_dev:	the struct input_dev descriptor of the device
Jesse Keating 7a32965
@@ -128,14 +43,10 @@ static struct attribute_group decoder_attribute_group = {
Jesse Keating 7a32965
  */
Jesse Keating 7a32965
 static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
-	struct decoder_data *data;
Jesse Keating 7a32965
 	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
+	struct jvc_dec *data = &ir_dev->raw->jvc;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data->enabled)
Jesse Keating 7a32965
+	if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC))
Jesse Keating 7a32965
 		return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (IS_RESET(ev)) {
Jesse Keating 7a32965
@@ -188,9 +99,9 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
Jesse Keating 7a32965
 		if (ev.pulse)
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-		data->jvc_bits <<= 1;
Jesse Keating 7a32965
+		data->bits <<= 1;
Jesse Keating 7a32965
 		if (eq_margin(ev.duration, JVC_BIT_1_SPACE, JVC_UNIT / 2)) {
Jesse Keating 7a32965
-			data->jvc_bits |= 1;
Jesse Keating 7a32965
+			data->bits |= 1;
Jesse Keating 7a32965
 			decrease_duration(&ev, JVC_BIT_1_SPACE);
Jesse Keating 7a32965
 		} else if (eq_margin(ev.duration, JVC_BIT_0_SPACE, JVC_UNIT / 2))
Jesse Keating 7a32965
 			decrease_duration(&ev, JVC_BIT_0_SPACE);
Jesse Keating 7a32965
@@ -223,13 +134,13 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		if (data->first) {
Jesse Keating 7a32965
 			u32 scancode;
Jesse Keating 7a32965
-			scancode = (bitrev8((data->jvc_bits >> 8) & 0xff) << 8) |
Jesse Keating 7a32965
-				   (bitrev8((data->jvc_bits >> 0) & 0xff) << 0);
Jesse Keating 7a32965
+			scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) |
Jesse Keating 7a32965
+				   (bitrev8((data->bits >> 0) & 0xff) << 0);
Jesse Keating 7a32965
 			IR_dprintk(1, "JVC scancode 0x%04x\n", scancode);
Jesse Keating 7a32965
 			ir_keydown(input_dev, scancode, data->toggle);
Jesse Keating 7a32965
 			data->first = false;
Jesse Keating 7a32965
-			data->jvc_old_bits = data->jvc_bits;
Jesse Keating 7a32965
-		} else if (data->jvc_bits == data->jvc_old_bits) {
Jesse Keating 7a32965
+			data->old_bits = data->bits;
Jesse Keating 7a32965
+		} else if (data->bits == data->old_bits) {
Jesse Keating 7a32965
 			IR_dprintk(1, "JVC repeat\n");
Jesse Keating 7a32965
 			ir_repeat(input_dev);
Jesse Keating 7a32965
 		} else {
Jesse Keating 7a32965
@@ -249,54 +160,9 @@ out:
Jesse Keating 7a32965
 	return -EINVAL;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static int ir_jvc_register(struct input_dev *input_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
-	struct decoder_data *data;
Jesse Keating 7a32965
-	int rc;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-	if (rc < 0)
Jesse Keating 7a32965
-		return rc;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
Jesse Keating 7a32965
-	if (!data) {
Jesse Keating 7a32965
-		sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-		return -ENOMEM;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data->ir_dev = ir_dev;
Jesse Keating 7a32965
-	data->enabled = 1;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_add_tail(&data->list, &decoder_list);
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return 0;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static int ir_jvc_unregister(struct input_dev *input_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
-	static struct decoder_data *data;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return 0;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_del(&data->list);
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return 0;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 static struct ir_raw_handler jvc_handler = {
Jesse Keating 7a32965
+	.protocols	= IR_TYPE_JVC,
Jesse Keating 7a32965
 	.decode		= ir_jvc_decode,
Jesse Keating 7a32965
-	.raw_register	= ir_jvc_register,
Jesse Keating 7a32965
-	.raw_unregister	= ir_jvc_unregister,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 static int __init ir_jvc_decode_init(void)
Jesse Keating 7a32965
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c
Jesse Keating 7a32965
new file mode 100644
Jesse Keating 7a32965
index 0000000..afb1ada
Jesse Keating 7a32965
--- /dev/null
Jesse Keating 7a32965
+++ b/drivers/media/IR/ir-lirc-codec.c
Jesse Keating 7a32965
@@ -0,0 +1,283 @@
Jesse Keating 7a32965
+/* ir-lirc-codec.c - ir-core to classic lirc interface bridge
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ * This program is free software; you can redistribute it and/or modify
Jesse Keating 7a32965
+ *  it under the terms of the GNU General Public License as published by
Jesse Keating 7a32965
+ *  the Free Software Foundation version 2 of the License.
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ *  This program is distributed in the hope that it will be useful,
Jesse Keating 7a32965
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Jesse Keating 7a32965
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Jesse Keating 7a32965
+ *  GNU General Public License for more details.
Jesse Keating 7a32965
+ */
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+#include <linux/sched.h>
Jesse Keating 7a32965
+#include <linux/wait.h>
Jesse Keating 7a32965
+#include <media/lirc.h>
Jesse Keating 7a32965
+#include <media/lirc_dev.h>
Jesse Keating 7a32965
+#include <media/ir-core.h>
Jesse Keating 7a32965
+#include "ir-core-priv.h"
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+#define LIRCBUF_SIZE 256
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+/**
Jesse Keating 7a32965
+ * ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the
Jesse Keating 7a32965
+ *		      lircd userspace daemon for decoding.
Jesse Keating 7a32965
+ * @input_dev:	the struct input_dev descriptor of the device
Jesse Keating 7a32965
+ * @duration:	the struct ir_raw_event descriptor of the pulse/space
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ * This function returns -EINVAL if the lirc interfaces aren't wired up.
Jesse Keating 7a32965
+ */
Jesse Keating 7a32965
+static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC))
Jesse Keating 7a32965
+		return 0;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf)
Jesse Keating 7a32965
+		return -EINVAL;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	IR_dprintk(2, "LIRC data transfer started (%uus %s)\n",
Jesse Keating 7a32965
+		   TO_US(ev.duration), TO_STR(ev.pulse));
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	ir_dev->raw->lirc.lircdata += ev.duration / 1000;
Jesse Keating 7a32965
+	if (ev.pulse)
Jesse Keating 7a32965
+		ir_dev->raw->lirc.lircdata |= PULSE_BIT;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
Jesse Keating 7a32965
+			  (unsigned char *) &ir_dev->raw->lirc.lircdata);
Jesse Keating 7a32965
+	wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	ir_dev->raw->lirc.lircdata = 0;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static ssize_t ir_lirc_transmit_ir(struct file *file, const char *buf,
Jesse Keating 7a32965
+				   size_t n, loff_t *ppos)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct lirc_codec *lirc;
Jesse Keating 7a32965
+	struct ir_input_dev *ir_dev;
Jesse Keating 7a32965
+	int *txbuf; /* buffer with values to transmit */
Jesse Keating 7a32965
+	int ret = 0, count;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	lirc = lirc_get_pdata(file);
Jesse Keating 7a32965
+	if (!lirc)
Jesse Keating 7a32965
+		return -EFAULT;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (n % sizeof(int))
Jesse Keating 7a32965
+		return -EINVAL;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	count = n / sizeof(int);
Jesse Keating 7a32965
+	if (count > LIRCBUF_SIZE || count % 2 == 0)
Jesse Keating 7a32965
+		return -EINVAL;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	txbuf = kzalloc(sizeof(int) * LIRCBUF_SIZE, GFP_KERNEL);
Jesse Keating 7a32965
+	if (!txbuf)
Jesse Keating 7a32965
+		return -ENOMEM;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (copy_from_user(txbuf, buf, n)) {
Jesse Keating 7a32965
+		ret = -EFAULT;
Jesse Keating 7a32965
+		goto out;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	ir_dev = lirc->ir_dev;
Jesse Keating 7a32965
+	if (!ir_dev) {
Jesse Keating 7a32965
+		ret = -EFAULT;
Jesse Keating 7a32965
+		goto out;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (ir_dev->props && ir_dev->props->tx_ir)
Jesse Keating 7a32965
+		ret = ir_dev->props->tx_ir(ir_dev->props->priv, txbuf, (u32)n);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+out:
Jesse Keating 7a32965
+	kfree(txbuf);
Jesse Keating 7a32965
+	return ret;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct lirc_codec *lirc;
Jesse Keating 7a32965
+	struct ir_input_dev *ir_dev;
Jesse Keating 7a32965
+	int ret = 0;
Jesse Keating 7a32965
+	void *drv_data;
Jesse Keating 7a32965
+	unsigned long val;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	lirc = lirc_get_pdata(filep);
Jesse Keating 7a32965
+	if (!lirc)
Jesse Keating 7a32965
+		return -EFAULT;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	ir_dev = lirc->ir_dev;
Jesse Keating 7a32965
+	if (!ir_dev || !ir_dev->props || !ir_dev->props->priv)
Jesse Keating 7a32965
+		return -EFAULT;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	drv_data = ir_dev->props->priv;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	switch (cmd) {
Jesse Keating 7a32965
+	case LIRC_SET_TRANSMITTER_MASK:
Jesse Keating 7a32965
+		ret = get_user(val, (unsigned long *)arg);
Jesse Keating 7a32965
+		if (ret)
Jesse Keating 7a32965
+			return ret;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		if (ir_dev->props && ir_dev->props->s_tx_mask)
Jesse Keating 7a32965
+			ret = ir_dev->props->s_tx_mask(drv_data, (u32)val);
Jesse Keating 7a32965
+		else
Jesse Keating 7a32965
+			return -EINVAL;
Jesse Keating 7a32965
+		break;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	case LIRC_SET_SEND_CARRIER:
Jesse Keating 7a32965
+		ret = get_user(val, (unsigned long *)arg);
Jesse Keating 7a32965
+		if (ret)
Jesse Keating 7a32965
+			return ret;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		if (ir_dev->props && ir_dev->props->s_tx_carrier)
Jesse Keating 7a32965
+			ir_dev->props->s_tx_carrier(drv_data, (u32)val);
Jesse Keating 7a32965
+		else
Jesse Keating 7a32965
+			return -EINVAL;
Jesse Keating 7a32965
+		break;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	case LIRC_GET_SEND_MODE:
Jesse Keating 7a32965
+		val = LIRC_CAN_SEND_PULSE & LIRC_CAN_SEND_MASK;
Jesse Keating 7a32965
+		ret = put_user(val, (unsigned long *)arg);
Jesse Keating 7a32965
+		break;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	case LIRC_SET_SEND_MODE:
Jesse Keating 7a32965
+		ret = get_user(val, (unsigned long *)arg);
Jesse Keating 7a32965
+		if (ret)
Jesse Keating 7a32965
+			return ret;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
Jesse Keating 7a32965
+			return -EINVAL;
Jesse Keating 7a32965
+		break;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	default:
Jesse Keating 7a32965
+		return lirc_dev_fop_ioctl(filep, cmd, arg);
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return ret;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static int ir_lirc_open(void *data)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static void ir_lirc_close(void *data)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	return;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static struct file_operations lirc_fops = {
Jesse Keating 7a32965
+	.owner		= THIS_MODULE,
Jesse Keating 7a32965
+	.write		= ir_lirc_transmit_ir,
Jesse Keating 7a32965
+	.unlocked_ioctl	= ir_lirc_ioctl,
Jesse Keating 7a32965
+	.read		= lirc_dev_fop_read,
Jesse Keating 7a32965
+	.poll		= lirc_dev_fop_poll,
Jesse Keating 7a32965
+	.open		= lirc_dev_fop_open,
Jesse Keating 7a32965
+	.release	= lirc_dev_fop_close,
Jesse Keating 7a32965
+};
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static int ir_lirc_register(struct input_dev *input_dev)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
+	struct lirc_driver *drv;
Jesse Keating 7a32965
+	struct lirc_buffer *rbuf;
Jesse Keating 7a32965
+	int rc = -ENOMEM;
Jesse Keating 7a32965
+	unsigned long features;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	drv = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
Jesse Keating 7a32965
+	if (!drv)
Jesse Keating 7a32965
+		return rc;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
Jesse Keating 7a32965
+	if (!drv)
Jesse Keating 7a32965
+		goto rbuf_alloc_failed;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	rc = lirc_buffer_init(rbuf, sizeof(int), LIRCBUF_SIZE);
Jesse Keating 7a32965
+	if (rc)
Jesse Keating 7a32965
+		goto rbuf_init_failed;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	features = LIRC_CAN_REC_MODE2;
Jesse Keating 7a32965
+	if (ir_dev->props->tx_ir) {
Jesse Keating 7a32965
+		features |= LIRC_CAN_SEND_PULSE;
Jesse Keating 7a32965
+		if (ir_dev->props->s_tx_mask)
Jesse Keating 7a32965
+			features |= LIRC_CAN_SET_TRANSMITTER_MASK;
Jesse Keating 7a32965
+		if (ir_dev->props->s_tx_carrier)
Jesse Keating 7a32965
+			features |= LIRC_CAN_SET_SEND_CARRIER;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)",
Jesse Keating 7a32965
+		 ir_dev->driver_name);
Jesse Keating 7a32965
+	drv->minor = -1;
Jesse Keating 7a32965
+	drv->features = features;
Jesse Keating 7a32965
+	drv->data = &ir_dev->raw->lirc;
Jesse Keating 7a32965
+	drv->rbuf = rbuf;
Jesse Keating 7a32965
+	drv->set_use_inc = &ir_lirc_open;
Jesse Keating 7a32965
+	drv->set_use_dec = &ir_lirc_close;
Jesse Keating 7a32965
+	drv->code_length = sizeof(struct ir_raw_event) * 8;
Jesse Keating 7a32965
+	drv->fops = &lirc_fops;
Jesse Keating 7a32965
+	drv->dev = &ir_dev->dev;
Jesse Keating 7a32965
+	drv->owner = THIS_MODULE;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	drv->minor = lirc_register_driver(drv);
Jesse Keating 7a32965
+	if (drv->minor < 0) {
Jesse Keating 7a32965
+		rc = -ENODEV;
Jesse Keating 7a32965
+		goto lirc_register_failed;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	ir_dev->raw->lirc.drv = drv;
Jesse Keating 7a32965
+	ir_dev->raw->lirc.ir_dev = ir_dev;
Jesse Keating 7a32965
+	ir_dev->raw->lirc.lircdata = PULSE_MASK;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+lirc_register_failed:
Jesse Keating 7a32965
+rbuf_init_failed:
Jesse Keating 7a32965
+	kfree(rbuf);
Jesse Keating 7a32965
+rbuf_alloc_failed:
Jesse Keating 7a32965
+	kfree(drv);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return rc;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static int ir_lirc_unregister(struct input_dev *input_dev)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
+	struct lirc_codec *lirc = &ir_dev->raw->lirc;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	lirc_unregister_driver(lirc->drv->minor);
Jesse Keating 7a32965
+	lirc_buffer_free(lirc->drv->rbuf);
Jesse Keating 7a32965
+	kfree(lirc->drv);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static struct ir_raw_handler lirc_handler = {
Jesse Keating 7a32965
+	.protocols	= IR_TYPE_LIRC,
Jesse Keating 7a32965
+	.decode		= ir_lirc_decode,
Jesse Keating 7a32965
+	.raw_register	= ir_lirc_register,
Jesse Keating 7a32965
+	.raw_unregister	= ir_lirc_unregister,
Jesse Keating 7a32965
+};
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static int __init ir_lirc_codec_init(void)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	ir_raw_handler_register(&lirc_handler);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	printk(KERN_INFO "IR LIRC bridge handler initialized\n");
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static void __exit ir_lirc_codec_exit(void)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	ir_raw_handler_unregister(&lirc_handler);
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+module_init(ir_lirc_codec_init);
Jesse Keating 7a32965
+module_exit(ir_lirc_codec_exit);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+MODULE_LICENSE("GPL");
Jesse Keating 7a32965
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
Jesse Keating 7a32965
+MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
Jesse Keating 7a32965
+MODULE_DESCRIPTION("LIRC IR handler bridge");
Jesse Keating 7a32965
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
Jesse Keating 7a32965
index ba79233..52e0f37 100644
Jesse Keating 7a32965
--- a/drivers/media/IR/ir-nec-decoder.c
Jesse Keating 7a32965
+++ b/drivers/media/IR/ir-nec-decoder.c
Jesse Keating 7a32965
@@ -27,10 +27,6 @@
Jesse Keating 7a32965
 #define	NEC_TRAILER_PULSE	(1  * NEC_UNIT)
Jesse Keating 7a32965
 #define	NEC_TRAILER_SPACE	(10 * NEC_UNIT) /* even longer in reality */
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-/* Used to register nec_decoder clients */
Jesse Keating 7a32965
-static LIST_HEAD(decoder_list);
Jesse Keating 7a32965
-static DEFINE_SPINLOCK(decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 enum nec_state {
Jesse Keating 7a32965
 	STATE_INACTIVE,
Jesse Keating 7a32965
 	STATE_HEADER_SPACE,
Jesse Keating 7a32965
@@ -40,84 +36,6 @@ enum nec_state {
Jesse Keating 7a32965
 	STATE_TRAILER_SPACE,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-struct decoder_data {
Jesse Keating 7a32965
-	struct list_head	list;
Jesse Keating 7a32965
-	struct ir_input_dev	*ir_dev;
Jesse Keating 7a32965
-	int			enabled:1;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* State machine control */
Jesse Keating 7a32965
-	enum nec_state		state;
Jesse Keating 7a32965
-	u32			nec_bits;
Jesse Keating 7a32965
-	unsigned		count;
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-/**
Jesse Keating 7a32965
- * get_decoder_data()	- gets decoder data
Jesse Keating 7a32965
- * @input_dev:	input device
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * Returns the struct decoder_data that corresponds to a device
Jesse Keating 7a32965
- */
Jesse Keating 7a32965
-static struct decoder_data *get_decoder_data(struct  ir_input_dev *ir_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct decoder_data *data = NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_for_each_entry(data, &decoder_list, list) {
Jesse Keating 7a32965
-		if (data->ir_dev == ir_dev)
Jesse Keating 7a32965
-			break;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-	return data;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static ssize_t store_enabled(struct device *d,
Jesse Keating 7a32965
-			     struct device_attribute *mattr,
Jesse Keating 7a32965
-			     const char *buf,
Jesse Keating 7a32965
-			     size_t len)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	unsigned long value;
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
Jesse Keating 7a32965
-	struct decoder_data *data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (strict_strtoul(buf, 10, &value) || value > 1)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data->enabled = value;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return len;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static ssize_t show_enabled(struct device *d,
Jesse Keating 7a32965
-			     struct device_attribute *mattr, char *buf)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
Jesse Keating 7a32965
-	struct decoder_data *data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (data->enabled)
Jesse Keating 7a32965
-		return sprintf(buf, "1\n");
Jesse Keating 7a32965
-	else
Jesse Keating 7a32965
-	return sprintf(buf, "0\n");
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static struct attribute *decoder_attributes[] = {
Jesse Keating 7a32965
-	&dev_attr_enabled.attr,
Jesse Keating 7a32965
-	NULL
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static struct attribute_group decoder_attribute_group = {
Jesse Keating 7a32965
-	.name	= "nec_decoder",
Jesse Keating 7a32965
-	.attrs	= decoder_attributes,
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 /**
Jesse Keating 7a32965
  * ir_nec_decode() - Decode one NEC pulse or space
Jesse Keating 7a32965
  * @input_dev:	the struct input_dev descriptor of the device
Jesse Keating 7a32965
@@ -127,16 +45,12 @@ static struct attribute_group decoder_attribute_group = {
Jesse Keating 7a32965
  */
Jesse Keating 7a32965
 static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
-	struct decoder_data *data;
Jesse Keating 7a32965
 	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
+	struct nec_dec *data = &ir_dev->raw->nec;
Jesse Keating 7a32965
 	u32 scancode;
Jesse Keating 7a32965
 	u8 address, not_address, command, not_command;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data->enabled)
Jesse Keating 7a32965
+	if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC))
Jesse Keating 7a32965
 		return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (IS_RESET(ev)) {
Jesse Keating 7a32965
@@ -191,9 +105,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
Jesse Keating 7a32965
 		if (ev.pulse)
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-		data->nec_bits <<= 1;
Jesse Keating 7a32965
+		data->bits <<= 1;
Jesse Keating 7a32965
 		if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
Jesse Keating 7a32965
-			data->nec_bits |= 1;
Jesse Keating 7a32965
+			data->bits |= 1;
Jesse Keating 7a32965
 		else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 		data->count++;
Jesse Keating 7a32965
@@ -222,14 +136,14 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
Jesse Keating 7a32965
 		if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-		address     = bitrev8((data->nec_bits >> 24) & 0xff);
Jesse Keating 7a32965
-		not_address = bitrev8((data->nec_bits >> 16) & 0xff);
Jesse Keating 7a32965
-		command	    = bitrev8((data->nec_bits >>  8) & 0xff);
Jesse Keating 7a32965
-		not_command = bitrev8((data->nec_bits >>  0) & 0xff);
Jesse Keating 7a32965
+		address     = bitrev8((data->bits >> 24) & 0xff);
Jesse Keating 7a32965
+		not_address = bitrev8((data->bits >> 16) & 0xff);
Jesse Keating 7a32965
+		command	    = bitrev8((data->bits >>  8) & 0xff);
Jesse Keating 7a32965
+		not_command = bitrev8((data->bits >>  0) & 0xff);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		if ((command ^ not_command) != 0xff) {
Jesse Keating 7a32965
 			IR_dprintk(1, "NEC checksum error: received 0x%08x\n",
Jesse Keating 7a32965
-				   data->nec_bits);
Jesse Keating 7a32965
+				   data->bits);
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 		}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -256,54 +170,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
Jesse Keating 7a32965
 	return -EINVAL;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static int ir_nec_register(struct input_dev *input_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
-	struct decoder_data *data;
Jesse Keating 7a32965
-	int rc;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-	if (rc < 0)
Jesse Keating 7a32965
-		return rc;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
Jesse Keating 7a32965
-	if (!data) {
Jesse Keating 7a32965
-		sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-		return -ENOMEM;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data->ir_dev = ir_dev;
Jesse Keating 7a32965
-	data->enabled = 1;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_add_tail(&data->list, &decoder_list);
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return 0;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static int ir_nec_unregister(struct input_dev *input_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
-	static struct decoder_data *data;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return 0;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_del(&data->list);
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return 0;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 static struct ir_raw_handler nec_handler = {
Jesse Keating 7a32965
+	.protocols	= IR_TYPE_NEC,
Jesse Keating 7a32965
 	.decode		= ir_nec_decode,
Jesse Keating 7a32965
-	.raw_register	= ir_nec_register,
Jesse Keating 7a32965
-	.raw_unregister	= ir_nec_unregister,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 static int __init ir_nec_decode_init(void)
Jesse Keating 7a32965
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
Jesse Keating 7a32965
index ea68a3f..6f192ef 100644
Jesse Keating 7a32965
--- a/drivers/media/IR/ir-raw-event.c
Jesse Keating 7a32965
+++ b/drivers/media/IR/ir-raw-event.c
Jesse Keating 7a32965
@@ -20,35 +20,13 @@
Jesse Keating 7a32965
 /* Define the max number of pulse/space transitions to buffer */
Jesse Keating 7a32965
 #define MAX_IR_EVENT_SIZE      512
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+/* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */
Jesse Keating 7a32965
+static LIST_HEAD(ir_raw_client_list);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 /* Used to handle IR raw handler extensions */
Jesse Keating 7a32965
-static LIST_HEAD(ir_raw_handler_list);
Jesse Keating 7a32965
 static DEFINE_SPINLOCK(ir_raw_handler_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-/**
Jesse Keating 7a32965
- * RUN_DECODER()	- runs an operation on all IR decoders
Jesse Keating 7a32965
- * @ops:	IR raw handler operation to be called
Jesse Keating 7a32965
- * @arg:	arguments to be passed to the callback
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * Calls ir_raw_handler::ops for all registered IR handlers. It prevents
Jesse Keating 7a32965
- * new decode addition/removal while running, by locking ir_raw_handler_lock
Jesse Keating 7a32965
- * mutex. If an error occurs, it stops the ops. Otherwise, it returns a sum
Jesse Keating 7a32965
- * of the return codes.
Jesse Keating 7a32965
- */
Jesse Keating 7a32965
-#define RUN_DECODER(ops, ...) ({					    \
Jesse Keating 7a32965
-	struct ir_raw_handler		*_ir_raw_handler;		    \
Jesse Keating 7a32965
-	int _sumrc = 0, _rc;						    \
Jesse Keating 7a32965
-	spin_lock(&ir_raw_handler_lock);				    \
Jesse Keating 7a32965
-	list_for_each_entry(_ir_raw_handler, &ir_raw_handler_list, list) {  \
Jesse Keating 7a32965
-		if (_ir_raw_handler->ops) {				    \
Jesse Keating 7a32965
-			_rc = _ir_raw_handler->ops(__VA_ARGS__);	    \
Jesse Keating 7a32965
-			if (_rc < 0)					    \
Jesse Keating 7a32965
-				break;					    \
Jesse Keating 7a32965
-			_sumrc += _rc;					    \
Jesse Keating 7a32965
-		}							    \
Jesse Keating 7a32965
-	}								    \
Jesse Keating 7a32965
-	spin_unlock(&ir_raw_handler_lock);				    \
Jesse Keating 7a32965
-	_sumrc;								    \
Jesse Keating 7a32965
-})
Jesse Keating 7a32965
+static LIST_HEAD(ir_raw_handler_list);
Jesse Keating 7a32965
+static u64 available_protocols;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 #ifdef MODULE
Jesse Keating 7a32965
 /* Used to load the decoders */
Jesse Keating 7a32965
@@ -58,57 +36,17 @@ static struct work_struct wq_load;
Jesse Keating 7a32965
 static void ir_raw_event_work(struct work_struct *work)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct ir_raw_event ev;
Jesse Keating 7a32965
+	struct ir_raw_handler *handler;
Jesse Keating 7a32965
 	struct ir_raw_event_ctrl *raw =
Jesse Keating 7a32965
 		container_of(work, struct ir_raw_event_ctrl, rx_work);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev))
Jesse Keating 7a32965
-		RUN_DECODER(decode, raw->input_dev, ev);
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-int ir_raw_event_register(struct input_dev *input_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir = input_get_drvdata(input_dev);
Jesse Keating 7a32965
-	int rc;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
Jesse Keating 7a32965
-	if (!ir->raw)
Jesse Keating 7a32965
-		return -ENOMEM;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	ir->raw->input_dev = input_dev;
Jesse Keating 7a32965
-	INIT_WORK(&ir->raw->rx_work, ir_raw_event_work);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
Jesse Keating 7a32965
-			 GFP_KERNEL);
Jesse Keating 7a32965
-	if (rc < 0) {
Jesse Keating 7a32965
-		kfree(ir->raw);
Jesse Keating 7a32965
-		ir->raw = NULL;
Jesse Keating 7a32965
-		return rc;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	rc = RUN_DECODER(raw_register, input_dev);
Jesse Keating 7a32965
-	if (rc < 0) {
Jesse Keating 7a32965
-		kfifo_free(&ir->raw->kfifo);
Jesse Keating 7a32965
-		kfree(ir->raw);
Jesse Keating 7a32965
-		ir->raw = NULL;
Jesse Keating 7a32965
-		return rc;
Jesse Keating 7a32965
+	while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) {
Jesse Keating 7a32965
+		spin_lock(&ir_raw_handler_lock);
Jesse Keating 7a32965
+		list_for_each_entry(handler, &ir_raw_handler_list, list)
Jesse Keating 7a32965
+			handler->decode(raw->input_dev, ev);
Jesse Keating 7a32965
+		spin_unlock(&ir_raw_handler_lock);
Jesse Keating 7a32965
+		raw->prev_ev = ev;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return rc;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-void ir_raw_event_unregister(struct input_dev *input_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir = input_get_drvdata(input_dev);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!ir->raw)
Jesse Keating 7a32965
-		return;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	cancel_work_sync(&ir->raw->rx_work);
Jesse Keating 7a32965
-	RUN_DECODER(raw_unregister, input_dev);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	kfifo_free(&ir->raw->kfifo);
Jesse Keating 7a32965
-	kfree(ir->raw);
Jesse Keating 7a32965
-	ir->raw = NULL;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /**
Jesse Keating 7a32965
@@ -204,23 +142,103 @@ void ir_raw_event_handle(struct input_dev *input_dev)
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 EXPORT_SYMBOL_GPL(ir_raw_event_handle);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+/* used internally by the sysfs interface */
Jesse Keating 7a32965
+u64
Jesse Keating 7a32965
+ir_raw_get_allowed_protocols()
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	u64 protocols;
Jesse Keating 7a32965
+	spin_lock(&ir_raw_handler_lock);
Jesse Keating 7a32965
+	protocols = available_protocols;
Jesse Keating 7a32965
+	spin_unlock(&ir_raw_handler_lock);
Jesse Keating 7a32965
+	return protocols;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+/*
Jesse Keating 7a32965
+ * Used to (un)register raw event clients
Jesse Keating 7a32965
+ */
Jesse Keating 7a32965
+int ir_raw_event_register(struct input_dev *input_dev)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct ir_input_dev *ir = input_get_drvdata(input_dev);
Jesse Keating 7a32965
+	int rc;
Jesse Keating 7a32965
+	struct ir_raw_handler *handler;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
Jesse Keating 7a32965
+	if (!ir->raw)
Jesse Keating 7a32965
+		return -ENOMEM;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	ir->raw->input_dev = input_dev;
Jesse Keating 7a32965
+	INIT_WORK(&ir->raw->rx_work, ir_raw_event_work);
Jesse Keating 7a32965
+	ir->raw->enabled_protocols = ~0;
Jesse Keating 7a32965
+	rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
Jesse Keating 7a32965
+			 GFP_KERNEL);
Jesse Keating 7a32965
+	if (rc < 0) {
Jesse Keating 7a32965
+		kfree(ir->raw);
Jesse Keating 7a32965
+		ir->raw = NULL;
Jesse Keating 7a32965
+		return rc;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	spin_lock(&ir_raw_handler_lock);
Jesse Keating 7a32965
+	list_add_tail(&ir->raw->list, &ir_raw_client_list);
Jesse Keating 7a32965
+	list_for_each_entry(handler, &ir_raw_handler_list, list)
Jesse Keating 7a32965
+		if (handler->raw_register)
Jesse Keating 7a32965
+			handler->raw_register(ir->raw->input_dev);
Jesse Keating 7a32965
+	spin_unlock(&ir_raw_handler_lock);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+void ir_raw_event_unregister(struct input_dev *input_dev)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct ir_input_dev *ir = input_get_drvdata(input_dev);
Jesse Keating 7a32965
+	struct ir_raw_handler *handler;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (!ir->raw)
Jesse Keating 7a32965
+		return;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	cancel_work_sync(&ir->raw->rx_work);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	spin_lock(&ir_raw_handler_lock);
Jesse Keating 7a32965
+	list_del(&ir->raw->list);
Jesse Keating 7a32965
+	list_for_each_entry(handler, &ir_raw_handler_list, list)
Jesse Keating 7a32965
+		if (handler->raw_unregister)
Jesse Keating 7a32965
+			handler->raw_unregister(ir->raw->input_dev);
Jesse Keating 7a32965
+	spin_unlock(&ir_raw_handler_lock);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	kfifo_free(&ir->raw->kfifo);
Jesse Keating 7a32965
+	kfree(ir->raw);
Jesse Keating 7a32965
+	ir->raw = NULL;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 /*
Jesse Keating 7a32965
  * Extension interface - used to register the IR decoders
Jesse Keating 7a32965
  */
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
+	struct ir_raw_event_ctrl *raw;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	spin_lock(&ir_raw_handler_lock);
Jesse Keating 7a32965
 	list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
Jesse Keating 7a32965
+	if (ir_raw_handler->raw_register)
Jesse Keating 7a32965
+		list_for_each_entry(raw, &ir_raw_client_list, list)
Jesse Keating 7a32965
+			ir_raw_handler->raw_register(raw->input_dev);
Jesse Keating 7a32965
+	available_protocols |= ir_raw_handler->protocols;
Jesse Keating 7a32965
 	spin_unlock(&ir_raw_handler_lock);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	return 0;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 EXPORT_SYMBOL(ir_raw_handler_register);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
+	struct ir_raw_event_ctrl *raw;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	spin_lock(&ir_raw_handler_lock);
Jesse Keating 7a32965
 	list_del(&ir_raw_handler->list);
Jesse Keating 7a32965
+	if (ir_raw_handler->raw_unregister)
Jesse Keating 7a32965
+		list_for_each_entry(raw, &ir_raw_client_list, list)
Jesse Keating 7a32965
+			ir_raw_handler->raw_unregister(raw->input_dev);
Jesse Keating 7a32965
+	available_protocols &= ~ir_raw_handler->protocols;
Jesse Keating 7a32965
 	spin_unlock(&ir_raw_handler_lock);
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 EXPORT_SYMBOL(ir_raw_handler_unregister);
Jesse Keating 7a32965
@@ -235,6 +253,7 @@ static void init_decoders(struct work_struct *work)
Jesse Keating 7a32965
 	load_rc6_decode();
Jesse Keating 7a32965
 	load_jvc_decode();
Jesse Keating 7a32965
 	load_sony_decode();
Jesse Keating 7a32965
+	load_lirc_codec();
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* If needed, we may later add some init code. In this case,
Jesse Keating 7a32965
 	   it is needed to change the CONFIG_MODULE test at ir-core.h
Jesse Keating 7a32965
diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/IR/ir-rc5-decoder.c
Jesse Keating 7a32965
index 23cdb1b..df4770d 100644
Jesse Keating 7a32965
--- a/drivers/media/IR/ir-rc5-decoder.c
Jesse Keating 7a32965
+++ b/drivers/media/IR/ir-rc5-decoder.c
Jesse Keating 7a32965
@@ -30,10 +30,6 @@
Jesse Keating 7a32965
 #define RC5_BIT_END		(1 * RC5_UNIT)
Jesse Keating 7a32965
 #define RC5X_SPACE		(4 * RC5_UNIT)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-/* Used to register rc5_decoder clients */
Jesse Keating 7a32965
-static LIST_HEAD(decoder_list);
Jesse Keating 7a32965
-static DEFINE_SPINLOCK(decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 enum rc5_state {
Jesse Keating 7a32965
 	STATE_INACTIVE,
Jesse Keating 7a32965
 	STATE_BIT_START,
Jesse Keating 7a32965
@@ -42,87 +38,6 @@ enum rc5_state {
Jesse Keating 7a32965
 	STATE_FINISHED,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-struct decoder_data {
Jesse Keating 7a32965
-	struct list_head	list;
Jesse Keating 7a32965
-	struct ir_input_dev	*ir_dev;
Jesse Keating 7a32965
-	int			enabled:1;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* State machine control */
Jesse Keating 7a32965
-	enum rc5_state		state;
Jesse Keating 7a32965
-	u32			rc5_bits;
Jesse Keating 7a32965
-	struct ir_raw_event	prev_ev;
Jesse Keating 7a32965
-	unsigned		count;
Jesse Keating 7a32965
-	unsigned		wanted_bits;
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-/**
Jesse Keating 7a32965
- * get_decoder_data()	- gets decoder data
Jesse Keating 7a32965
- * @input_dev:	input device
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * Returns the struct decoder_data that corresponds to a device
Jesse Keating 7a32965
- */
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static struct decoder_data *get_decoder_data(struct  ir_input_dev *ir_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct decoder_data *data = NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_for_each_entry(data, &decoder_list, list) {
Jesse Keating 7a32965
-		if (data->ir_dev == ir_dev)
Jesse Keating 7a32965
-			break;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-	return data;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static ssize_t store_enabled(struct device *d,
Jesse Keating 7a32965
-			     struct device_attribute *mattr,
Jesse Keating 7a32965
-			     const char *buf,
Jesse Keating 7a32965
-			     size_t len)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	unsigned long value;
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
Jesse Keating 7a32965
-	struct decoder_data *data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (strict_strtoul(buf, 10, &value) || value > 1)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data->enabled = value;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return len;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static ssize_t show_enabled(struct device *d,
Jesse Keating 7a32965
-			     struct device_attribute *mattr, char *buf)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
Jesse Keating 7a32965
-	struct decoder_data *data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (data->enabled)
Jesse Keating 7a32965
-		return sprintf(buf, "1\n");
Jesse Keating 7a32965
-	else
Jesse Keating 7a32965
-	return sprintf(buf, "0\n");
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static struct attribute *decoder_attributes[] = {
Jesse Keating 7a32965
-	&dev_attr_enabled.attr,
Jesse Keating 7a32965
-	NULL
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static struct attribute_group decoder_attribute_group = {
Jesse Keating 7a32965
-	.name	= "rc5_decoder",
Jesse Keating 7a32965
-	.attrs	= decoder_attributes,
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 /**
Jesse Keating 7a32965
  * ir_rc5_decode() - Decode one RC-5 pulse or space
Jesse Keating 7a32965
  * @input_dev:	the struct input_dev descriptor of the device
Jesse Keating 7a32965
@@ -132,17 +47,13 @@ static struct attribute_group decoder_attribute_group = {
Jesse Keating 7a32965
  */
Jesse Keating 7a32965
 static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
-	struct decoder_data *data;
Jesse Keating 7a32965
 	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
+	struct rc5_dec *data = &ir_dev->raw->rc5;
Jesse Keating 7a32965
 	u8 toggle;
Jesse Keating 7a32965
 	u32 scancode;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data->enabled)
Jesse Keating 7a32965
-		return 0;
Jesse Keating 7a32965
+        if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5))
Jesse Keating 7a32965
+                return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (IS_RESET(ev)) {
Jesse Keating 7a32965
 		data->state = STATE_INACTIVE;
Jesse Keating 7a32965
@@ -176,16 +87,15 @@ again:
Jesse Keating 7a32965
 		if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-		data->rc5_bits <<= 1;
Jesse Keating 7a32965
+		data->bits <<= 1;
Jesse Keating 7a32965
 		if (!ev.pulse)
Jesse Keating 7a32965
-			data->rc5_bits |= 1;
Jesse Keating 7a32965
+			data->bits |= 1;
Jesse Keating 7a32965
 		data->count++;
Jesse Keating 7a32965
-		data->prev_ev = ev;
Jesse Keating 7a32965
 		data->state = STATE_BIT_END;
Jesse Keating 7a32965
 		return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	case STATE_BIT_END:
Jesse Keating 7a32965
-		if (!is_transition(&ev, &data->prev_ev))
Jesse Keating 7a32965
+		if (!is_transition(&ev, &ir_dev->raw->prev_ev))
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		if (data->count == data->wanted_bits)
Jesse Keating 7a32965
@@ -217,11 +127,11 @@ again:
Jesse Keating 7a32965
 		if (data->wanted_bits == RC5X_NBITS) {
Jesse Keating 7a32965
 			/* RC5X */
Jesse Keating 7a32965
 			u8 xdata, command, system;
Jesse Keating 7a32965
-			xdata    = (data->rc5_bits & 0x0003F) >> 0;
Jesse Keating 7a32965
-			command  = (data->rc5_bits & 0x00FC0) >> 6;
Jesse Keating 7a32965
-			system   = (data->rc5_bits & 0x1F000) >> 12;
Jesse Keating 7a32965
-			toggle   = (data->rc5_bits & 0x20000) ? 1 : 0;
Jesse Keating 7a32965
-			command += (data->rc5_bits & 0x01000) ? 0 : 0x40;
Jesse Keating 7a32965
+			xdata    = (data->bits & 0x0003F) >> 0;
Jesse Keating 7a32965
+			command  = (data->bits & 0x00FC0) >> 6;
Jesse Keating 7a32965
+			system   = (data->bits & 0x1F000) >> 12;
Jesse Keating 7a32965
+			toggle   = (data->bits & 0x20000) ? 1 : 0;
Jesse Keating 7a32965
+			command += (data->bits & 0x01000) ? 0 : 0x40;
Jesse Keating 7a32965
 			scancode = system << 16 | command << 8 | xdata;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 			IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n",
Jesse Keating 7a32965
@@ -230,10 +140,10 @@ again:
Jesse Keating 7a32965
 		} else {
Jesse Keating 7a32965
 			/* RC5 */
Jesse Keating 7a32965
 			u8 command, system;
Jesse Keating 7a32965
-			command  = (data->rc5_bits & 0x0003F) >> 0;
Jesse Keating 7a32965
-			system   = (data->rc5_bits & 0x007C0) >> 6;
Jesse Keating 7a32965
-			toggle   = (data->rc5_bits & 0x00800) ? 1 : 0;
Jesse Keating 7a32965
-			command += (data->rc5_bits & 0x01000) ? 0 : 0x40;
Jesse Keating 7a32965
+			command  = (data->bits & 0x0003F) >> 0;
Jesse Keating 7a32965
+			system   = (data->bits & 0x007C0) >> 6;
Jesse Keating 7a32965
+			toggle   = (data->bits & 0x00800) ? 1 : 0;
Jesse Keating 7a32965
+			command += (data->bits & 0x01000) ? 0 : 0x40;
Jesse Keating 7a32965
 			scancode = system << 8 | command;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 			IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n",
Jesse Keating 7a32965
@@ -252,54 +162,9 @@ out:
Jesse Keating 7a32965
 	return -EINVAL;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static int ir_rc5_register(struct input_dev *input_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
-	struct decoder_data *data;
Jesse Keating 7a32965
-	int rc;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-	if (rc < 0)
Jesse Keating 7a32965
-		return rc;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
Jesse Keating 7a32965
-	if (!data) {
Jesse Keating 7a32965
-		sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-		return -ENOMEM;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data->ir_dev = ir_dev;
Jesse Keating 7a32965
-	data->enabled = 1;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_add_tail(&data->list, &decoder_list);
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return 0;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static int ir_rc5_unregister(struct input_dev *input_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
-	static struct decoder_data *data;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return 0;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_del(&data->list);
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return 0;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 static struct ir_raw_handler rc5_handler = {
Jesse Keating 7a32965
+	.protocols	= IR_TYPE_RC5,
Jesse Keating 7a32965
 	.decode		= ir_rc5_decode,
Jesse Keating 7a32965
-	.raw_register	= ir_rc5_register,
Jesse Keating 7a32965
-	.raw_unregister	= ir_rc5_unregister,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 static int __init ir_rc5_decode_init(void)
Jesse Keating 7a32965
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c
Jesse Keating 7a32965
index 2bf479f..f1624b8 100644
Jesse Keating 7a32965
--- a/drivers/media/IR/ir-rc6-decoder.c
Jesse Keating 7a32965
+++ b/drivers/media/IR/ir-rc6-decoder.c
Jesse Keating 7a32965
@@ -36,10 +36,6 @@
Jesse Keating 7a32965
 #define RC6_STARTBIT_MASK	0x08	/* for the header bits */
Jesse Keating 7a32965
 #define RC6_6A_MCE_TOGGLE_MASK	0x8000	/* for the body bits */
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-/* Used to register rc6_decoder clients */
Jesse Keating 7a32965
-static LIST_HEAD(decoder_list);
Jesse Keating 7a32965
-static DEFINE_SPINLOCK(decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 enum rc6_mode {
Jesse Keating 7a32965
 	RC6_MODE_0,
Jesse Keating 7a32965
 	RC6_MODE_6A,
Jesse Keating 7a32965
@@ -58,89 +54,8 @@ enum rc6_state {
Jesse Keating 7a32965
 	STATE_FINISHED,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-struct decoder_data {
Jesse Keating 7a32965
-	struct list_head	list;
Jesse Keating 7a32965
-	struct ir_input_dev	*ir_dev;
Jesse Keating 7a32965
-	int			enabled:1;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* State machine control */
Jesse Keating 7a32965
-	enum rc6_state		state;
Jesse Keating 7a32965
-	u8			header;
Jesse Keating 7a32965
-	u32			body;
Jesse Keating 7a32965
-	struct ir_raw_event	prev_ev;
Jesse Keating 7a32965
-	bool			toggle;
Jesse Keating 7a32965
-	unsigned		count;
Jesse Keating 7a32965
-	unsigned		wanted_bits;
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-/**
Jesse Keating 7a32965
- * get_decoder_data()	- gets decoder data
Jesse Keating 7a32965
- * @input_dev:	input device
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * Returns the struct decoder_data that corresponds to a device
Jesse Keating 7a32965
- */
Jesse Keating 7a32965
-static struct decoder_data *get_decoder_data(struct  ir_input_dev *ir_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct decoder_data *data = NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_for_each_entry(data, &decoder_list, list) {
Jesse Keating 7a32965
-		if (data->ir_dev == ir_dev)
Jesse Keating 7a32965
-			break;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-	return data;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static ssize_t store_enabled(struct device *d,
Jesse Keating 7a32965
-			     struct device_attribute *mattr,
Jesse Keating 7a32965
-			     const char *buf,
Jesse Keating 7a32965
-			     size_t len)
Jesse Keating 7a32965
+static enum rc6_mode rc6_mode(struct rc6_dec *data)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
-	unsigned long value;
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
Jesse Keating 7a32965
-	struct decoder_data *data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (strict_strtoul(buf, 10, &value) || value > 1)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data->enabled = value;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return len;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static ssize_t show_enabled(struct device *d,
Jesse Keating 7a32965
-			     struct device_attribute *mattr, char *buf)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
Jesse Keating 7a32965
-	struct decoder_data *data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (data->enabled)
Jesse Keating 7a32965
-		return sprintf(buf, "1\n");
Jesse Keating 7a32965
-	else
Jesse Keating 7a32965
-	return sprintf(buf, "0\n");
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static struct attribute *decoder_attributes[] = {
Jesse Keating 7a32965
-	&dev_attr_enabled.attr,
Jesse Keating 7a32965
-	NULL
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static struct attribute_group decoder_attribute_group = {
Jesse Keating 7a32965
-	.name	= "rc6_decoder",
Jesse Keating 7a32965
-	.attrs	= decoder_attributes,
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static enum rc6_mode rc6_mode(struct decoder_data *data) {
Jesse Keating 7a32965
 	switch (data->header & RC6_MODE_MASK) {
Jesse Keating 7a32965
 	case 0:
Jesse Keating 7a32965
 		return RC6_MODE_0;
Jesse Keating 7a32965
@@ -162,16 +77,12 @@ static enum rc6_mode rc6_mode(struct decoder_data *data) {
Jesse Keating 7a32965
  */
Jesse Keating 7a32965
 static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
-	struct decoder_data *data;
Jesse Keating 7a32965
 	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
+	struct rc6_dec *data = &ir_dev->raw->rc6;
Jesse Keating 7a32965
 	u32 scancode;
Jesse Keating 7a32965
 	u8 toggle;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data->enabled)
Jesse Keating 7a32965
+	if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
Jesse Keating 7a32965
 		return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (IS_RESET(ev)) {
Jesse Keating 7a32965
@@ -223,12 +134,11 @@ again:
Jesse Keating 7a32965
 		if (ev.pulse)
Jesse Keating 7a32965
 			data->header |= 1;
Jesse Keating 7a32965
 		data->count++;
Jesse Keating 7a32965
-		data->prev_ev = ev;
Jesse Keating 7a32965
 		data->state = STATE_HEADER_BIT_END;
Jesse Keating 7a32965
 		return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	case STATE_HEADER_BIT_END:
Jesse Keating 7a32965
-		if (!is_transition(&ev, &data->prev_ev))
Jesse Keating 7a32965
+		if (!is_transition(&ev, &ir_dev->raw->prev_ev))
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		if (data->count == RC6_HEADER_NBITS)
Jesse Keating 7a32965
@@ -244,12 +154,11 @@ again:
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		data->toggle = ev.pulse;
Jesse Keating 7a32965
-		data->prev_ev = ev;
Jesse Keating 7a32965
 		data->state = STATE_TOGGLE_END;
Jesse Keating 7a32965
 		return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	case STATE_TOGGLE_END:
Jesse Keating 7a32965
-		if (!is_transition(&ev, &data->prev_ev) ||
Jesse Keating 7a32965
+		if (!is_transition(&ev, &ir_dev->raw->prev_ev) ||
Jesse Keating 7a32965
 		    !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -259,7 +168,6 @@ again:
Jesse Keating 7a32965
 		}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		data->state = STATE_BODY_BIT_START;
Jesse Keating 7a32965
-		data->prev_ev = ev;
Jesse Keating 7a32965
 		decrease_duration(&ev, RC6_TOGGLE_END);
Jesse Keating 7a32965
 		data->count = 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -291,13 +199,11 @@ again:
Jesse Keating 7a32965
 		if (ev.pulse)
Jesse Keating 7a32965
 			data->body |= 1;
Jesse Keating 7a32965
 		data->count++;
Jesse Keating 7a32965
-		data->prev_ev = ev;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 		data->state = STATE_BODY_BIT_END;
Jesse Keating 7a32965
 		return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	case STATE_BODY_BIT_END:
Jesse Keating 7a32965
-		if (!is_transition(&ev, &data->prev_ev))
Jesse Keating 7a32965
+		if (!is_transition(&ev, &ir_dev->raw->prev_ev))
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		if (data->count == data->wanted_bits)
Jesse Keating 7a32965
@@ -348,54 +254,9 @@ out:
Jesse Keating 7a32965
 	return -EINVAL;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static int ir_rc6_register(struct input_dev *input_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
-	struct decoder_data *data;
Jesse Keating 7a32965
-	int rc;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-	if (rc < 0)
Jesse Keating 7a32965
-		return rc;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
Jesse Keating 7a32965
-	if (!data) {
Jesse Keating 7a32965
-		sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-		return -ENOMEM;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data->ir_dev = ir_dev;
Jesse Keating 7a32965
-	data->enabled = 1;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_add_tail(&data->list, &decoder_list);
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return 0;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static int ir_rc6_unregister(struct input_dev *input_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
-	static struct decoder_data *data;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return 0;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_del(&data->list);
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return 0;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 static struct ir_raw_handler rc6_handler = {
Jesse Keating 7a32965
+	.protocols	= IR_TYPE_RC6,
Jesse Keating 7a32965
 	.decode		= ir_rc6_decode,
Jesse Keating 7a32965
-	.raw_register	= ir_rc6_register,
Jesse Keating 7a32965
-	.raw_unregister	= ir_rc6_unregister,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 static int __init ir_rc6_decode_init(void)
Jesse Keating 7a32965
diff --git a/drivers/media/IR/ir-sony-decoder.c b/drivers/media/IR/ir-sony-decoder.c
Jesse Keating 7a32965
index 9f440c5..b9074f0 100644
Jesse Keating 7a32965
--- a/drivers/media/IR/ir-sony-decoder.c
Jesse Keating 7a32965
+++ b/drivers/media/IR/ir-sony-decoder.c
Jesse Keating 7a32965
@@ -23,10 +23,6 @@
Jesse Keating 7a32965
 #define SONY_BIT_SPACE		(1 * SONY_UNIT)
Jesse Keating 7a32965
 #define SONY_TRAILER_SPACE	(10 * SONY_UNIT) /* minimum */
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-/* Used to register sony_decoder clients */
Jesse Keating 7a32965
-static LIST_HEAD(decoder_list);
Jesse Keating 7a32965
-static DEFINE_SPINLOCK(decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 enum sony_state {
Jesse Keating 7a32965
 	STATE_INACTIVE,
Jesse Keating 7a32965
 	STATE_HEADER_SPACE,
Jesse Keating 7a32965
@@ -35,84 +31,6 @@ enum sony_state {
Jesse Keating 7a32965
 	STATE_FINISHED,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-struct decoder_data {
Jesse Keating 7a32965
-	struct list_head	list;
Jesse Keating 7a32965
-	struct ir_input_dev	*ir_dev;
Jesse Keating 7a32965
-	int			enabled:1;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* State machine control */
Jesse Keating 7a32965
-	enum sony_state		state;
Jesse Keating 7a32965
-	u32			sony_bits;
Jesse Keating 7a32965
-	unsigned		count;
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-/**
Jesse Keating 7a32965
- * get_decoder_data()	- gets decoder data
Jesse Keating 7a32965
- * @input_dev:	input device
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * Returns the struct decoder_data that corresponds to a device
Jesse Keating 7a32965
- */
Jesse Keating 7a32965
-static struct decoder_data *get_decoder_data(struct  ir_input_dev *ir_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct decoder_data *data = NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_for_each_entry(data, &decoder_list, list) {
Jesse Keating 7a32965
-		if (data->ir_dev == ir_dev)
Jesse Keating 7a32965
-			break;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-	return data;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static ssize_t store_enabled(struct device *d,
Jesse Keating 7a32965
-			     struct device_attribute *mattr,
Jesse Keating 7a32965
-			     const char *buf,
Jesse Keating 7a32965
-			     size_t len)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	unsigned long value;
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
Jesse Keating 7a32965
-	struct decoder_data *data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (strict_strtoul(buf, 10, &value) || value > 1)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data->enabled = value;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return len;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static ssize_t show_enabled(struct device *d,
Jesse Keating 7a32965
-			     struct device_attribute *mattr, char *buf)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
Jesse Keating 7a32965
-	struct decoder_data *data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (data->enabled)
Jesse Keating 7a32965
-		return sprintf(buf, "1\n");
Jesse Keating 7a32965
-	else
Jesse Keating 7a32965
-	return sprintf(buf, "0\n");
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static struct attribute *decoder_attributes[] = {
Jesse Keating 7a32965
-	&dev_attr_enabled.attr,
Jesse Keating 7a32965
-	NULL
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static struct attribute_group decoder_attribute_group = {
Jesse Keating 7a32965
-	.name	= "sony_decoder",
Jesse Keating 7a32965
-	.attrs	= decoder_attributes,
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 /**
Jesse Keating 7a32965
  * ir_sony_decode() - Decode one Sony pulse or space
Jesse Keating 7a32965
  * @input_dev:	the struct input_dev descriptor of the device
Jesse Keating 7a32965
@@ -122,16 +40,12 @@ static struct attribute_group decoder_attribute_group = {
Jesse Keating 7a32965
  */
Jesse Keating 7a32965
 static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
-	struct decoder_data *data;
Jesse Keating 7a32965
 	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
+	struct sony_dec *data = &ir_dev->raw->sony;
Jesse Keating 7a32965
 	u32 scancode;
Jesse Keating 7a32965
 	u8 device, subdevice, function;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!data->enabled)
Jesse Keating 7a32965
+	if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY))
Jesse Keating 7a32965
 		return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (IS_RESET(ev)) {
Jesse Keating 7a32965
@@ -172,9 +86,9 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
Jesse Keating 7a32965
 		if (!ev.pulse)
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-		data->sony_bits <<= 1;
Jesse Keating 7a32965
+		data->bits <<= 1;
Jesse Keating 7a32965
 		if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2))
Jesse Keating 7a32965
-			data->sony_bits |= 1;
Jesse Keating 7a32965
+			data->bits |= 1;
Jesse Keating 7a32965
 		else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2))
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -208,19 +122,19 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		switch (data->count) {
Jesse Keating 7a32965
 		case 12:
Jesse Keating 7a32965
-			device    = bitrev8((data->sony_bits <<  3) & 0xF8);
Jesse Keating 7a32965
+			device    = bitrev8((data->bits <<  3) & 0xF8);
Jesse Keating 7a32965
 			subdevice = 0;
Jesse Keating 7a32965
-			function  = bitrev8((data->sony_bits >>  4) & 0xFE);
Jesse Keating 7a32965
+			function  = bitrev8((data->bits >>  4) & 0xFE);
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 		case 15:
Jesse Keating 7a32965
-			device    = bitrev8((data->sony_bits >>  0) & 0xFF);
Jesse Keating 7a32965
+			device    = bitrev8((data->bits >>  0) & 0xFF);
Jesse Keating 7a32965
 			subdevice = 0;
Jesse Keating 7a32965
-			function  = bitrev8((data->sony_bits >>  7) & 0xFD);
Jesse Keating 7a32965
+			function  = bitrev8((data->bits >>  7) & 0xFD);
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 		case 20:
Jesse Keating 7a32965
-			device    = bitrev8((data->sony_bits >>  5) & 0xF8);
Jesse Keating 7a32965
-			subdevice = bitrev8((data->sony_bits >>  0) & 0xFF);
Jesse Keating 7a32965
-			function  = bitrev8((data->sony_bits >> 12) & 0xFE);
Jesse Keating 7a32965
+			device    = bitrev8((data->bits >>  5) & 0xF8);
Jesse Keating 7a32965
+			subdevice = bitrev8((data->bits >>  0) & 0xFF);
Jesse Keating 7a32965
+			function  = bitrev8((data->bits >> 12) & 0xFE);
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 		default:
Jesse Keating 7a32965
 			IR_dprintk(1, "Sony invalid bitcount %u\n", data->count);
Jesse Keating 7a32965
@@ -241,54 +155,9 @@ out:
Jesse Keating 7a32965
 	return -EINVAL;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static int ir_sony_register(struct input_dev *input_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
-	struct decoder_data *data;
Jesse Keating 7a32965
-	int rc;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-	if (rc < 0)
Jesse Keating 7a32965
-		return rc;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
Jesse Keating 7a32965
-	if (!data) {
Jesse Keating 7a32965
-		sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-		return -ENOMEM;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data->ir_dev = ir_dev;
Jesse Keating 7a32965
-	data->enabled = 1;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_add_tail(&data->list, &decoder_list);
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return 0;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static int ir_sony_unregister(struct input_dev *input_dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
Jesse Keating 7a32965
-	static struct decoder_data *data;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	data = get_decoder_data(ir_dev);
Jesse Keating 7a32965
-	if (!data)
Jesse Keating 7a32965
-		return 0;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	spin_lock(&decoder_lock);
Jesse Keating 7a32965
-	list_del(&data->list);
Jesse Keating 7a32965
-	spin_unlock(&decoder_lock);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return 0;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 static struct ir_raw_handler sony_handler = {
Jesse Keating 7a32965
+	.protocols	= IR_TYPE_SONY,
Jesse Keating 7a32965
 	.decode		= ir_sony_decode,
Jesse Keating 7a32965
-	.raw_register	= ir_sony_register,
Jesse Keating 7a32965
-	.raw_unregister	= ir_sony_unregister,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 static int __init ir_sony_decode_init(void)
Jesse Keating 7a32965
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
Jesse Keating 7a32965
index 2098dd1..a841e51 100644
Jesse Keating 7a32965
--- a/drivers/media/IR/ir-sysfs.c
Jesse Keating 7a32965
+++ b/drivers/media/IR/ir-sysfs.c
Jesse Keating 7a32965
@@ -34,122 +34,186 @@ static struct class ir_input_class = {
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /**
Jesse Keating 7a32965
- * show_protocol() - shows the current IR protocol
Jesse Keating 7a32965
+ * show_protocols() - shows the current IR protocol(s)
Jesse Keating 7a32965
  * @d:		the device descriptor
Jesse Keating 7a32965
  * @mattr:	the device attribute struct (unused)
Jesse Keating 7a32965
  * @buf:	a pointer to the output buffer
Jesse Keating 7a32965
  *
Jesse Keating 7a32965
- * This routine is a callback routine for input read the IR protocol type.
Jesse Keating 7a32965
- * it is trigged by reading /sys/class/rc/rc?/current_protocol.
Jesse Keating 7a32965
- * It returns the protocol name, as understood by the driver.
Jesse Keating 7a32965
+ * This routine is a callback routine for input read the IR protocol type(s).
Jesse Keating 7a32965
+ * it is trigged by reading /sys/class/rc/rc?/protocols.
Jesse Keating 7a32965
+ * It returns the protocol names of supported protocols.
Jesse Keating 7a32965
+ * Enabled protocols are printed in brackets.
Jesse Keating 7a32965
  */
Jesse Keating 7a32965
-static ssize_t show_protocol(struct device *d,
Jesse Keating 7a32965
-			     struct device_attribute *mattr, char *buf)
Jesse Keating 7a32965
+static ssize_t show_protocols(struct device *d,
Jesse Keating 7a32965
+			      struct device_attribute *mattr, char *buf)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
-	char *s;
Jesse Keating 7a32965
 	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
Jesse Keating 7a32965
-	u64 ir_type = ir_dev->rc_tab.ir_type;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	IR_dprintk(1, "Current protocol is %lld\n", (long long)ir_type);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* FIXME: doesn't support multiple protocols at the same time */
Jesse Keating 7a32965
-	if (ir_type == IR_TYPE_UNKNOWN)
Jesse Keating 7a32965
-		s = "Unknown";
Jesse Keating 7a32965
-	else if (ir_type == IR_TYPE_RC5)
Jesse Keating 7a32965
-		s = "rc-5";
Jesse Keating 7a32965
-	else if (ir_type == IR_TYPE_NEC)
Jesse Keating 7a32965
-		s = "nec";
Jesse Keating 7a32965
-	else if (ir_type == IR_TYPE_RC6)
Jesse Keating 7a32965
-		s = "rc6";
Jesse Keating 7a32965
-	else if (ir_type == IR_TYPE_JVC)
Jesse Keating 7a32965
-		s = "jvc";
Jesse Keating 7a32965
-	else if (ir_type == IR_TYPE_SONY)
Jesse Keating 7a32965
-		s = "sony";
Jesse Keating 7a32965
-	else
Jesse Keating 7a32965
-		s = "other";
Jesse Keating 7a32965
+	u64 allowed, enabled;
Jesse Keating 7a32965
+	char *tmp = buf;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
Jesse Keating 7a32965
+		enabled = ir_dev->rc_tab.ir_type;
Jesse Keating 7a32965
+		allowed = ir_dev->props->allowed_protos;
Jesse Keating 7a32965
+	} else {
Jesse Keating 7a32965
+		enabled = ir_dev->raw->enabled_protocols;
Jesse Keating 7a32965
+		allowed = ir_raw_get_allowed_protocols();
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	return sprintf(buf, "%s\n", s);
Jesse Keating 7a32965
+	IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
Jesse Keating 7a32965
+		   (long long)allowed,
Jesse Keating 7a32965
+		   (long long)enabled);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (allowed & enabled & IR_TYPE_UNKNOWN)
Jesse Keating 7a32965
+		tmp += sprintf(tmp, "[unknown] ");
Jesse Keating 7a32965
+	else if (allowed & IR_TYPE_UNKNOWN)
Jesse Keating 7a32965
+		tmp += sprintf(tmp, "unknown ");
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (allowed & enabled & IR_TYPE_RC5)
Jesse Keating 7a32965
+		tmp += sprintf(tmp, "[rc5] ");
Jesse Keating 7a32965
+	else if (allowed & IR_TYPE_RC5)
Jesse Keating 7a32965
+		tmp += sprintf(tmp, "rc5 ");
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (allowed & enabled & IR_TYPE_NEC)
Jesse Keating 7a32965
+		tmp += sprintf(tmp, "[nec] ");
Jesse Keating 7a32965
+	else if (allowed & IR_TYPE_NEC)
Jesse Keating 7a32965
+		tmp += sprintf(tmp, "nec ");
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (allowed & enabled & IR_TYPE_RC6)
Jesse Keating 7a32965
+		tmp += sprintf(tmp, "[rc6] ");
Jesse Keating 7a32965
+	else if (allowed & IR_TYPE_RC6)
Jesse Keating 7a32965
+		tmp += sprintf(tmp, "rc6 ");
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (allowed & enabled & IR_TYPE_JVC)
Jesse Keating 7a32965
+		tmp += sprintf(tmp, "[jvc] ");
Jesse Keating 7a32965
+	else if (allowed & IR_TYPE_JVC)
Jesse Keating 7a32965
+		tmp += sprintf(tmp, "jvc ");
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (allowed & enabled & IR_TYPE_SONY)
Jesse Keating 7a32965
+		tmp += sprintf(tmp, "[sony] ");
Jesse Keating 7a32965
+	else if (allowed & IR_TYPE_SONY)
Jesse Keating 7a32965
+		tmp += sprintf(tmp, "sony ");
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (allowed & enabled & IR_TYPE_LIRC)
Jesse Keating 7a32965
+		tmp += sprintf(tmp, "[lirc] ");
Jesse Keating 7a32965
+	else if (allowed & IR_TYPE_LIRC)
Jesse Keating 7a32965
+		tmp += sprintf(tmp, "lirc ");
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (tmp != buf)
Jesse Keating 7a32965
+		tmp--;
Jesse Keating 7a32965
+	*tmp = '\n';
Jesse Keating 7a32965
+	return tmp + 1 - buf;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /**
Jesse Keating 7a32965
- * store_protocol() - shows the current IR protocol
Jesse Keating 7a32965
+ * store_protocols() - changes the current IR protocol(s)
Jesse Keating 7a32965
  * @d:		the device descriptor
Jesse Keating 7a32965
  * @mattr:	the device attribute struct (unused)
Jesse Keating 7a32965
  * @buf:	a pointer to the input buffer
Jesse Keating 7a32965
  * @len:	length of the input buffer
Jesse Keating 7a32965
  *
Jesse Keating 7a32965
  * This routine is a callback routine for changing the IR protocol type.
Jesse Keating 7a32965
- * it is trigged by reading /sys/class/rc/rc?/current_protocol.
Jesse Keating 7a32965
- * It changes the IR the protocol name, if the IR type is recognized
Jesse Keating 7a32965
- * by the driver.
Jesse Keating 7a32965
- * If an unknown protocol name is used, returns -EINVAL.
Jesse Keating 7a32965
+ * It is trigged by writing to /sys/class/rc/rc?/protocols.
Jesse Keating 7a32965
+ * Writing "+proto" will add a protocol to the list of enabled protocols.
Jesse Keating 7a32965
+ * Writing "-proto" will remove a protocol from the list of enabled protocols.
Jesse Keating 7a32965
+ * Writing "proto" will enable only "proto".
Jesse Keating 7a32965
+ * Returns -EINVAL if an invalid protocol combination or unknown protocol name
Jesse Keating 7a32965
+ * is used, otherwise @len.
Jesse Keating 7a32965
  */
Jesse Keating 7a32965
-static ssize_t store_protocol(struct device *d,
Jesse Keating 7a32965
-			      struct device_attribute *mattr,
Jesse Keating 7a32965
-			      const char *data,
Jesse Keating 7a32965
-			      size_t len)
Jesse Keating 7a32965
+static ssize_t store_protocols(struct device *d,
Jesse Keating 7a32965
+			       struct device_attribute *mattr,
Jesse Keating 7a32965
+			       const char *data,
Jesse Keating 7a32965
+			       size_t len)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
Jesse Keating 7a32965
-	u64 ir_type = 0;
Jesse Keating 7a32965
-	int rc = -EINVAL;
Jesse Keating 7a32965
+	bool enable, disable;
Jesse Keating 7a32965
+	const char *tmp;
Jesse Keating 7a32965
+	u64 type;
Jesse Keating 7a32965
+	u64 mask;
Jesse Keating 7a32965
+	int rc;
Jesse Keating 7a32965
 	unsigned long flags;
Jesse Keating 7a32965
-	char *buf;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	while ((buf = strsep((char **) &data, " \n")) != NULL) {
Jesse Keating 7a32965
-		if (!strcasecmp(buf, "rc-5") || !strcasecmp(buf, "rc5"))
Jesse Keating 7a32965
-			ir_type |= IR_TYPE_RC5;
Jesse Keating 7a32965
-		if (!strcasecmp(buf, "nec"))
Jesse Keating 7a32965
-			ir_type |= IR_TYPE_NEC;
Jesse Keating 7a32965
-		if (!strcasecmp(buf, "jvc"))
Jesse Keating 7a32965
-			ir_type |= IR_TYPE_JVC;
Jesse Keating 7a32965
-		if (!strcasecmp(buf, "sony"))
Jesse Keating 7a32965
-			ir_type |= IR_TYPE_SONY;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	tmp = skip_spaces(data);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (*tmp == '+') {
Jesse Keating 7a32965
+		enable = true;
Jesse Keating 7a32965
+		disable = false;
Jesse Keating 7a32965
+		tmp++;
Jesse Keating 7a32965
+	} else if (*tmp == '-') {
Jesse Keating 7a32965
+		enable = false;
Jesse Keating 7a32965
+		disable = true;
Jesse Keating 7a32965
+		tmp++;
Jesse Keating 7a32965
+	} else {
Jesse Keating 7a32965
+		enable = false;
Jesse Keating 7a32965
+		disable = false;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (!ir_type) {
Jesse Keating 7a32965
+	if (!strncasecmp(tmp, "unknown", 7)) {
Jesse Keating 7a32965
+		tmp += 7;
Jesse Keating 7a32965
+		mask = IR_TYPE_UNKNOWN;
Jesse Keating 7a32965
+	} else if (!strncasecmp(tmp, "rc5", 3)) {
Jesse Keating 7a32965
+		tmp += 3;
Jesse Keating 7a32965
+		mask = IR_TYPE_RC5;
Jesse Keating 7a32965
+	} else if (!strncasecmp(tmp, "nec", 3)) {
Jesse Keating 7a32965
+		tmp += 3;
Jesse Keating 7a32965
+		mask = IR_TYPE_NEC;
Jesse Keating 7a32965
+	} else if (!strncasecmp(tmp, "rc6", 3)) {
Jesse Keating 7a32965
+		tmp += 3;
Jesse Keating 7a32965
+		mask = IR_TYPE_RC6;
Jesse Keating 7a32965
+	} else if (!strncasecmp(tmp, "jvc", 3)) {
Jesse Keating 7a32965
+		tmp += 3;
Jesse Keating 7a32965
+		mask = IR_TYPE_JVC;
Jesse Keating 7a32965
+	} else if (!strncasecmp(tmp, "sony", 4)) {
Jesse Keating 7a32965
+		tmp += 4;
Jesse Keating 7a32965
+		mask = IR_TYPE_SONY;
Jesse Keating 7a32965
+	} else if (!strncasecmp(tmp, "lirc", 4)) {
Jesse Keating 7a32965
+		tmp += 4;
Jesse Keating 7a32965
+		mask = IR_TYPE_LIRC;
Jesse Keating 7a32965
+	} else {
Jesse Keating 7a32965
 		IR_dprintk(1, "Unknown protocol\n");
Jesse Keating 7a32965
 		return -EINVAL;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (ir_dev->props && ir_dev->props->change_protocol)
Jesse Keating 7a32965
-		rc = ir_dev->props->change_protocol(ir_dev->props->priv,
Jesse Keating 7a32965
-						    ir_type);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (rc < 0) {
Jesse Keating 7a32965
-		IR_dprintk(1, "Error setting protocol to %lld\n",
Jesse Keating 7a32965
-			   (long long)ir_type);
Jesse Keating 7a32965
+	tmp = skip_spaces(tmp);
Jesse Keating 7a32965
+	if (*tmp != '\0') {
Jesse Keating 7a32965
+		IR_dprintk(1, "Invalid trailing characters\n");
Jesse Keating 7a32965
 		return -EINVAL;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
Jesse Keating 7a32965
-	ir_dev->rc_tab.ir_type = ir_type;
Jesse Keating 7a32965
-	spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
Jesse Keating 7a32965
+	if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
Jesse Keating 7a32965
+		type = ir_dev->rc_tab.ir_type;
Jesse Keating 7a32965
+	else
Jesse Keating 7a32965
+		type = ir_dev->raw->enabled_protocols;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	IR_dprintk(1, "Current protocol(s) is(are) %lld\n",
Jesse Keating 7a32965
-		   (long long)ir_type);
Jesse Keating 7a32965
+	if (enable)
Jesse Keating 7a32965
+		type |= mask;
Jesse Keating 7a32965
+	else if (disable)
Jesse Keating 7a32965
+		type &= ~mask;
Jesse Keating 7a32965
+	else
Jesse Keating 7a32965
+		type = mask;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	return len;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
+	if (ir_dev->props && ir_dev->props->change_protocol) {
Jesse Keating 7a32965
+		rc = ir_dev->props->change_protocol(ir_dev->props->priv,
Jesse Keating 7a32965
+						    type);
Jesse Keating 7a32965
+		if (rc < 0) {
Jesse Keating 7a32965
+			IR_dprintk(1, "Error setting protocols to 0x%llx\n",
Jesse Keating 7a32965
+				   (long long)type);
Jesse Keating 7a32965
+			return -EINVAL;
Jesse Keating 7a32965
+		}
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static ssize_t show_supported_protocols(struct device *d,
Jesse Keating 7a32965
-			     struct device_attribute *mattr, char *buf)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	char *orgbuf = buf;
Jesse Keating 7a32965
-	struct ir_input_dev *ir_dev = dev_get_drvdata(d);
Jesse Keating 7a32965
+	if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
Jesse Keating 7a32965
+		spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
Jesse Keating 7a32965
+		ir_dev->rc_tab.ir_type = type;
Jesse Keating 7a32965
+		spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
Jesse Keating 7a32965
+	} else {
Jesse Keating 7a32965
+		ir_dev->raw->enabled_protocols = type;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	/* FIXME: doesn't support multiple protocols at the same time */
Jesse Keating 7a32965
-	if (ir_dev->props->allowed_protos == IR_TYPE_UNKNOWN)
Jesse Keating 7a32965
-		buf += sprintf(buf, "unknown ");
Jesse Keating 7a32965
-	if (ir_dev->props->allowed_protos & IR_TYPE_RC5)
Jesse Keating 7a32965
-		buf += sprintf(buf, "rc-5 ");
Jesse Keating 7a32965
-	if (ir_dev->props->allowed_protos & IR_TYPE_NEC)
Jesse Keating 7a32965
-		buf += sprintf(buf, "nec ");
Jesse Keating 7a32965
-	if (buf == orgbuf)
Jesse Keating 7a32965
-		buf += sprintf(buf, "other ");
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	buf += sprintf(buf - 1, "\n");
Jesse Keating 7a32965
+	IR_dprintk(1, "Current protocol(s): 0x%llx\n",
Jesse Keating 7a32965
+		   (long long)type);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	return buf - orgbuf;
Jesse Keating 7a32965
+	return len;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 #define ADD_HOTPLUG_VAR(fmt, val...)					\
Jesse Keating 7a32965
@@ -159,7 +223,7 @@ static ssize_t show_supported_protocols(struct device *d,
Jesse Keating 7a32965
 			return err;					\
Jesse Keating 7a32965
 	} while (0)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static int ir_dev_uevent(struct device *device, struct kobj_uevent_env *env)
Jesse Keating 7a32965
+static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct ir_input_dev *ir_dev = dev_get_drvdata(device);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -174,34 +238,26 @@ static int ir_dev_uevent(struct device *device, struct kobj_uevent_env *env)
Jesse Keating 7a32965
 /*
Jesse Keating 7a32965
  * Static device attribute struct with the sysfs attributes for IR's
Jesse Keating 7a32965
  */
Jesse Keating 7a32965
-static DEVICE_ATTR(protocol, S_IRUGO | S_IWUSR,
Jesse Keating 7a32965
-		   show_protocol, store_protocol);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static DEVICE_ATTR(supported_protocols, S_IRUGO | S_IWUSR,
Jesse Keating 7a32965
-		   show_supported_protocols, NULL);
Jesse Keating 7a32965
+static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR,
Jesse Keating 7a32965
+		   show_protocols, store_protocols);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static struct attribute *ir_hw_dev_attrs[] = {
Jesse Keating 7a32965
-	&dev_attr_protocol.attr,
Jesse Keating 7a32965
-	&dev_attr_supported_protocols.attr,
Jesse Keating 7a32965
+static struct attribute *rc_dev_attrs[] = {
Jesse Keating 7a32965
+	&dev_attr_protocols.attr,
Jesse Keating 7a32965
 	NULL,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static struct attribute_group ir_hw_dev_attr_grp = {
Jesse Keating 7a32965
-	.attrs	= ir_hw_dev_attrs,
Jesse Keating 7a32965
+static struct attribute_group rc_dev_attr_grp = {
Jesse Keating 7a32965
+	.attrs	= rc_dev_attrs,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static const struct attribute_group *ir_hw_dev_attr_groups[] = {
Jesse Keating 7a32965
-	&ir_hw_dev_attr_grp,
Jesse Keating 7a32965
+static const struct attribute_group *rc_dev_attr_groups[] = {
Jesse Keating 7a32965
+	&rc_dev_attr_grp,
Jesse Keating 7a32965
 	NULL
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 static struct device_type rc_dev_type = {
Jesse Keating 7a32965
-	.groups		= ir_hw_dev_attr_groups,
Jesse Keating 7a32965
-	.uevent		= ir_dev_uevent,
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static struct device_type ir_raw_dev_type = {
Jesse Keating 7a32965
-	.uevent		= ir_dev_uevent,
Jesse Keating 7a32965
+	.groups		= rc_dev_attr_groups,
Jesse Keating 7a32965
+	.uevent		= rc_dev_uevent,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /**
Jesse Keating 7a32965
@@ -221,12 +277,7 @@ int ir_register_class(struct input_dev *input_dev)
Jesse Keating 7a32965
 	if (unlikely(devno < 0))
Jesse Keating 7a32965
 		return devno;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (ir_dev->props) {
Jesse Keating 7a32965
-		if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
Jesse Keating 7a32965
-			ir_dev->dev.type = &rc_dev_type;
Jesse Keating 7a32965
-	} else
Jesse Keating 7a32965
-		ir_dev->dev.type = &ir_raw_dev_type;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
+	ir_dev->dev.type = &rc_dev_type;
Jesse Keating 7a32965
 	ir_dev->dev.class = &ir_input_class;
Jesse Keating 7a32965
 	ir_dev->dev.parent = input_dev->dev.parent;
Jesse Keating 7a32965
 	dev_set_name(&ir_dev->dev, "rc%d", devno);
Jesse Keating 7a32965
diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/IR/keymaps/Makefile
Jesse Keating 7a32965
index aea649f..86d3d1f 100644
Jesse Keating 7a32965
--- a/drivers/media/IR/keymaps/Makefile
Jesse Keating 7a32965
+++ b/drivers/media/IR/keymaps/Makefile
Jesse Keating 7a32965
@@ -37,6 +37,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
Jesse Keating 7a32965
 			rc-kaiomy.o \
Jesse Keating 7a32965
 			rc-kworld-315u.o \
Jesse Keating 7a32965
 			rc-kworld-plus-tv-analog.o \
Jesse Keating 7a32965
+			rc-lirc.o \
Jesse Keating 7a32965
 			rc-manli.o \
Jesse Keating 7a32965
 			rc-msi-tvanywhere.o \
Jesse Keating 7a32965
 			rc-msi-tvanywhere-plus.o \
Jesse Keating 7a32965
@@ -57,6 +58,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
Jesse Keating 7a32965
 			rc-pv951.o \
Jesse Keating 7a32965
 			rc-rc5-hauppauge-new.o \
Jesse Keating 7a32965
 			rc-rc5-tv.o \
Jesse Keating 7a32965
+			rc-rc6-mce.o \
Jesse Keating 7a32965
 			rc-real-audio-220-32-keys.o \
Jesse Keating 7a32965
 			rc-tbs-nec.o \
Jesse Keating 7a32965
 			rc-terratec-cinergy-xs.o \
Jesse Keating 7a32965
diff --git a/drivers/media/IR/keymaps/rc-lirc.c b/drivers/media/IR/keymaps/rc-lirc.c
Jesse Keating 7a32965
new file mode 100644
Jesse Keating 7a32965
index 0000000..43fcf90
Jesse Keating 7a32965
--- /dev/null
Jesse Keating 7a32965
+++ b/drivers/media/IR/keymaps/rc-lirc.c
Jesse Keating 7a32965
@@ -0,0 +1,41 @@
Jesse Keating 7a32965
+/* rc-lirc.c - Empty dummy keytable, for use when its preferred to pass
Jesse Keating 7a32965
+ * all raw IR data to the lirc userspace decoder.
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ * This program is free software; you can redistribute it and/or modify
Jesse Keating 7a32965
+ * it under the terms of the GNU General Public License as published by
Jesse Keating 7a32965
+ * the Free Software Foundation; either version 2 of the License, or
Jesse Keating 7a32965
+ * (at your option) any later version.
Jesse Keating 7a32965
+ */
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+#include <media/ir-core.h>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static struct ir_scancode lirc[] = {
Jesse Keating 7a32965
+	{ },
Jesse Keating 7a32965
+};
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static struct rc_keymap lirc_map = {
Jesse Keating 7a32965
+	.map = {
Jesse Keating 7a32965
+		.scan    = lirc,
Jesse Keating 7a32965
+		.size    = ARRAY_SIZE(lirc),
Jesse Keating 7a32965
+		.ir_type = IR_TYPE_LIRC,
Jesse Keating 7a32965
+		.name    = RC_MAP_LIRC,
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+};
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static int __init init_rc_map_lirc(void)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	return ir_register_map(&lirc_map);
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static void __exit exit_rc_map_lirc(void)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	ir_unregister_map(&lirc_map);
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+module_init(init_rc_map_lirc)
Jesse Keating 7a32965
+module_exit(exit_rc_map_lirc)
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+MODULE_LICENSE("GPL");
Jesse Keating 7a32965
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
Jesse Keating 7a32965
diff --git a/drivers/media/IR/keymaps/rc-rc6-mce.c b/drivers/media/IR/keymaps/rc-rc6-mce.c
Jesse Keating 7a32965
new file mode 100644
Jesse Keating 7a32965
index 0000000..c6726a8
Jesse Keating 7a32965
--- /dev/null
Jesse Keating 7a32965
+++ b/drivers/media/IR/keymaps/rc-rc6-mce.c
Jesse Keating 7a32965
@@ -0,0 +1,105 @@
Jesse Keating 7a32965
+/* rc-rc6-mce.c - Keytable for Windows Media Center RC-6 remotes for use
Jesse Keating 7a32965
+ * with the Media Center Edition eHome Infrared Transceiver.
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ * This program is free software; you can redistribute it and/or modify
Jesse Keating 7a32965
+ * it under the terms of the GNU General Public License as published by
Jesse Keating 7a32965
+ * the Free Software Foundation; either version 2 of the License, or
Jesse Keating 7a32965
+ * (at your option) any later version.
Jesse Keating 7a32965
+ */
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+#include <media/rc-map.h>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static struct ir_scancode rc6_mce[] = {
Jesse Keating 7a32965
+	{ 0x800f0415, KEY_REWIND },
Jesse Keating 7a32965
+	{ 0x800f0414, KEY_FASTFORWARD },
Jesse Keating 7a32965
+	{ 0x800f041b, KEY_PREVIOUS },
Jesse Keating 7a32965
+	{ 0x800f041a, KEY_NEXT },
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	{ 0x800f0416, KEY_PLAY },
Jesse Keating 7a32965
+	{ 0x800f0418, KEY_PAUSE },
Jesse Keating 7a32965
+	{ 0x800f0419, KEY_STOP },
Jesse Keating 7a32965
+	{ 0x800f0417, KEY_RECORD },
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	{ 0x800f041e, KEY_UP },
Jesse Keating 7a32965
+	{ 0x800f041f, KEY_DOWN },
Jesse Keating 7a32965
+	{ 0x800f0420, KEY_LEFT },
Jesse Keating 7a32965
+	{ 0x800f0421, KEY_RIGHT },
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	{ 0x800f040b, KEY_ENTER },
Jesse Keating 7a32965
+	{ 0x800f0422, KEY_OK },
Jesse Keating 7a32965
+	{ 0x800f0423, KEY_EXIT },
Jesse Keating 7a32965
+	{ 0x800f040a, KEY_DELETE },
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	{ 0x800f040e, KEY_MUTE },
Jesse Keating 7a32965
+	{ 0x800f0410, KEY_VOLUMEUP },
Jesse Keating 7a32965
+	{ 0x800f0411, KEY_VOLUMEDOWN },
Jesse Keating 7a32965
+	{ 0x800f0412, KEY_CHANNELUP },
Jesse Keating 7a32965
+	{ 0x800f0413, KEY_CHANNELDOWN },
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	{ 0x800f0401, KEY_NUMERIC_1 },
Jesse Keating 7a32965
+	{ 0x800f0402, KEY_NUMERIC_2 },
Jesse Keating 7a32965
+	{ 0x800f0403, KEY_NUMERIC_3 },
Jesse Keating 7a32965
+	{ 0x800f0404, KEY_NUMERIC_4 },
Jesse Keating 7a32965
+	{ 0x800f0405, KEY_NUMERIC_5 },
Jesse Keating 7a32965
+	{ 0x800f0406, KEY_NUMERIC_6 },
Jesse Keating 7a32965
+	{ 0x800f0407, KEY_NUMERIC_7 },
Jesse Keating 7a32965
+	{ 0x800f0408, KEY_NUMERIC_8 },
Jesse Keating 7a32965
+	{ 0x800f0409, KEY_NUMERIC_9 },
Jesse Keating 7a32965
+	{ 0x800f0400, KEY_NUMERIC_0 },
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	{ 0x800f041d, KEY_NUMERIC_STAR },
Jesse Keating 7a32965
+	{ 0x800f041c, KEY_NUMERIC_POUND },
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	{ 0x800f0446, KEY_TV },
Jesse Keating 7a32965
+	{ 0x800f0447, KEY_AUDIO }, /* My Music */
Jesse Keating 7a32965
+	{ 0x800f0448, KEY_PVR }, /* RecordedTV */
Jesse Keating 7a32965
+	{ 0x800f0449, KEY_CAMERA },
Jesse Keating 7a32965
+	{ 0x800f044a, KEY_VIDEO },
Jesse Keating 7a32965
+	{ 0x800f0424, KEY_DVD },
Jesse Keating 7a32965
+	{ 0x800f0425, KEY_TUNER }, /* LiveTV */
Jesse Keating 7a32965
+	{ 0x800f0450, KEY_RADIO },
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	{ 0x800f044c, KEY_LANGUAGE },
Jesse Keating 7a32965
+	{ 0x800f0427, KEY_ZOOM }, /* Aspect */
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	{ 0x800f045b, KEY_RED },
Jesse Keating 7a32965
+	{ 0x800f045c, KEY_GREEN },
Jesse Keating 7a32965
+	{ 0x800f045d, KEY_YELLOW },
Jesse Keating 7a32965
+	{ 0x800f045e, KEY_BLUE },
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	{ 0x800f040f, KEY_INFO },
Jesse Keating 7a32965
+	{ 0x800f0426, KEY_EPG }, /* Guide */
Jesse Keating 7a32965
+	{ 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
Jesse Keating 7a32965
+	{ 0x800f044d, KEY_TITLE },
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	{ 0x800f040c, KEY_POWER },
Jesse Keating 7a32965
+	{ 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+};
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static struct rc_keymap rc6_mce_map = {
Jesse Keating 7a32965
+	.map = {
Jesse Keating 7a32965
+		.scan    = rc6_mce,
Jesse Keating 7a32965
+		.size    = ARRAY_SIZE(rc6_mce),
Jesse Keating 7a32965
+		.ir_type = IR_TYPE_RC6,
Jesse Keating 7a32965
+		.name    = RC_MAP_RC6_MCE,
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+};
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static int __init init_rc_map_rc6_mce(void)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	return ir_register_map(&rc6_mce_map);
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static void __exit exit_rc_map_rc6_mce(void)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	ir_unregister_map(&rc6_mce_map);
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+module_init(init_rc_map_rc6_mce)
Jesse Keating 7a32965
+module_exit(exit_rc_map_rc6_mce)
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+MODULE_LICENSE("GPL");
Jesse Keating 7a32965
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
Jesse Keating 7a32965
diff --git a/drivers/media/IR/lirc_dev.c b/drivers/media/IR/lirc_dev.c
Jesse Keating 7a32965
new file mode 100644
Jesse Keating 7a32965
index 0000000..899891b
Jesse Keating 7a32965
--- /dev/null
Jesse Keating 7a32965
+++ b/drivers/media/IR/lirc_dev.c
Jesse Keating 7a32965
@@ -0,0 +1,764 @@
Jesse Keating 7a32965
+/*
Jesse Keating 7a32965
+ * LIRC base driver
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ * by Artur Lipowski <alipowski@interia.pl>
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ *  This program is free software; you can redistribute it and/or modify
Jesse Keating 7a32965
+ *  it under the terms of the GNU General Public License as published by
Jesse Keating 7a32965
+ *  the Free Software Foundation; either version 2 of the License, or
Jesse Keating 7a32965
+ *  (at your option) any later version.
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ *  This program is distributed in the hope that it will be useful,
Jesse Keating 7a32965
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Jesse Keating 7a32965
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Jesse Keating 7a32965
+ *  GNU General Public License for more details.
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ *  You should have received a copy of the GNU General Public License
Jesse Keating 7a32965
+ *  along with this program; if not, write to the Free Software
Jesse Keating 7a32965
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Jesse Keating 7a32965
+ *
Jesse Keating 7a32965
+ */
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+#include <linux/module.h>
Jesse Keating 7a32965
+#include <linux/kernel.h>
Jesse Keating 7a32965
+#include <linux/sched.h>
Jesse Keating 7a32965
+#include <linux/errno.h>
Jesse Keating 7a32965
+#include <linux/ioctl.h>
Jesse Keating 7a32965
+#include <linux/fs.h>
Jesse Keating 7a32965
+#include <linux/poll.h>
Jesse Keating 7a32965
+#include <linux/completion.h>
Jesse Keating 7a32965
+#include <linux/errno.h>
Jesse Keating 7a32965
+#include <linux/mutex.h>
Jesse Keating 7a32965
+#include <linux/wait.h>
Jesse Keating 7a32965
+#include <linux/unistd.h>
Jesse Keating 7a32965
+#include <linux/kthread.h>
Jesse Keating 7a32965
+#include <linux/bitops.h>
Jesse Keating 7a32965
+#include <linux/device.h>
Jesse Keating 7a32965
+#include <linux/cdev.h>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+#include <media/lirc.h>
Jesse Keating 7a32965
+#include <media/lirc_dev.h>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static int debug;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+#define IRCTL_DEV_NAME	"BaseRemoteCtl"
Jesse Keating 7a32965
+#define NOPLUG		-1
Jesse Keating 7a32965
+#define LOGHEAD		"lirc_dev (%s[%d]): "
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static dev_t lirc_base_dev;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+struct irctl {
Jesse Keating 7a32965
+	struct lirc_driver d;
Jesse Keating 7a32965
+	int attached;
Jesse Keating 7a32965
+	int open;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	struct mutex irctl_lock;
Jesse Keating 7a32965
+	struct lirc_buffer *buf;
Jesse Keating 7a32965
+	unsigned int chunk_size;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	struct task_struct *task;
Jesse Keating 7a32965
+	long jiffies_to_wait;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	struct cdev cdev;
Jesse Keating 7a32965
+};
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static DEFINE_MUTEX(lirc_dev_lock);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static struct irctl *irctls[MAX_IRCTL_DEVICES];
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+/* Only used for sysfs but defined to void otherwise */
Jesse Keating 7a32965
+static struct class *lirc_class;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+/*  helper function
Jesse Keating 7a32965
+ *  initializes the irctl structure
Jesse Keating 7a32965
+ */
Jesse Keating 7a32965
+static void init_irctl(struct irctl *ir)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	dev_dbg(ir->d.dev, LOGHEAD "initializing irctl\n",
Jesse Keating 7a32965
+		ir->d.name, ir->d.minor);
Jesse Keating 7a32965
+	mutex_init(&ir->irctl_lock);
Jesse Keating 7a32965
+	ir->d.minor = NOPLUG;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static void cleanup(struct irctl *ir)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	dev_dbg(ir->d.dev, LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor));
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (ir->buf != ir->d.rbuf) {
Jesse Keating 7a32965
+		lirc_buffer_free(ir->buf);
Jesse Keating 7a32965
+		kfree(ir->buf);
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+	ir->buf = NULL;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+/*  helper function
Jesse Keating 7a32965
+ *  reads key codes from driver and puts them into buffer
Jesse Keating 7a32965
+ *  returns 0 on success
Jesse Keating 7a32965
+ */
Jesse Keating 7a32965
+static int add_to_buf(struct irctl *ir)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	if (ir->d.add_to_buf) {
Jesse Keating 7a32965
+		int res = -ENODATA;
Jesse Keating 7a32965
+		int got_data = 0;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		/*
Jesse Keating 7a32965
+		 * service the device as long as it is returning
Jesse Keating 7a32965
+		 * data and we have space
Jesse Keating 7a32965
+		 */
Jesse Keating 7a32965
+get_data:
Jesse Keating 7a32965
+		res = ir->d.add_to_buf(ir->d.data, ir->buf);
Jesse Keating 7a32965
+		if (res == 0) {
Jesse Keating 7a32965
+			got_data++;
Jesse Keating 7a32965
+			goto get_data;
Jesse Keating 7a32965
+		}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		if (res == -ENODEV)
Jesse Keating 7a32965
+			kthread_stop(ir->task);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		return got_data ? 0 : res;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+/* main function of the polling thread
Jesse Keating 7a32965
+ */
Jesse Keating 7a32965
+static int lirc_thread(void *irctl)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct irctl *ir = irctl;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	dev_dbg(ir->d.dev, LOGHEAD "poll thread started\n",
Jesse Keating 7a32965
+		ir->d.name, ir->d.minor);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	do {
Jesse Keating 7a32965
+		if (ir->open) {
Jesse Keating 7a32965
+			if (ir->jiffies_to_wait) {
Jesse Keating 7a32965
+				set_current_state(TASK_INTERRUPTIBLE);
Jesse Keating 7a32965
+				schedule_timeout(ir->jiffies_to_wait);
Jesse Keating 7a32965
+			}
Jesse Keating 7a32965
+			if (kthread_should_stop())
Jesse Keating 7a32965
+				break;
Jesse Keating